Bug 1150305 - sourcebuffer.buffered returns the same object if not changed. r=roc, r=bz, r=jya

--HG--
extra : rebase_source : ffacfcb39b567a6cd034b081f4330d88aacb98f4
This commit is contained in:
Guang-De Lin 2015-10-19 14:10:47 +08:00
parent 95218a96a0
commit 5fc8c948b4
7 changed files with 62 additions and 26 deletions

View File

@ -1333,10 +1333,6 @@ DOMInterfaces = {
'implicitJSContext': ['readHeapSnapshot', 'saveHeapSnapshot']
},
'TimeRanges': {
'wrapperCache': False
},
'TouchList': {
'headerFile': 'mozilla/dom/TouchEvent.h',
},

View File

@ -1521,7 +1521,7 @@ HTMLMediaElement::Seek(double aTime,
}
// Clamp the seek target to inside the seekable ranges.
RefPtr<dom::TimeRanges> seekable = new dom::TimeRanges();
RefPtr<dom::TimeRanges> seekable = new dom::TimeRanges(ToSupports(OwnerDoc()));
media::TimeIntervals seekableIntervals = mDecoder->GetSeekable();
if (seekableIntervals.IsInvalid()) {
aRv.Throw(NS_ERROR_DOM_INVALID_STATE_ERR);
@ -1638,7 +1638,7 @@ NS_IMETHODIMP HTMLMediaElement::GetDuration(double* aDuration)
already_AddRefed<TimeRanges>
HTMLMediaElement::Seekable() const
{
RefPtr<TimeRanges> ranges = new TimeRanges();
RefPtr<TimeRanges> ranges = new TimeRanges(ToSupports(OwnerDoc()));
if (mDecoder && mReadyState > nsIDOMHTMLMediaElement::HAVE_NOTHING) {
mDecoder->GetSeekable().ToTimeRanges(ranges);
}
@ -1662,7 +1662,7 @@ NS_IMETHODIMP HTMLMediaElement::GetPaused(bool* aPaused)
already_AddRefed<TimeRanges>
HTMLMediaElement::Played()
{
RefPtr<TimeRanges> ranges = new TimeRanges();
RefPtr<TimeRanges> ranges = new TimeRanges(ToSupports(OwnerDoc()));
uint32_t timeRangeCount = 0;
if (mPlayed) {
@ -2067,7 +2067,7 @@ HTMLMediaElement::HTMLMediaElement(already_AddRefed<mozilla::dom::NodeInfo>& aNo
mDefaultPlaybackRate(1.0),
mPlaybackRate(1.0),
mPreservesPitch(true),
mPlayed(new TimeRanges),
mPlayed(new TimeRanges(ToSupports(OwnerDoc()))),
mCurrentPlayRangeStart(-1.0),
mBegun(false),
mLoadedDataFired(false),
@ -4477,7 +4477,7 @@ HTMLMediaElement::CopyInnerTo(Element* aDest)
already_AddRefed<TimeRanges>
HTMLMediaElement::Buffered() const
{
RefPtr<TimeRanges> ranges = new TimeRanges();
RefPtr<TimeRanges> ranges = new TimeRanges(ToSupports(OwnerDoc()));
if (mReadyState > nsIDOMHTMLMediaElement::HAVE_NOTHING) {
if (mDecoder) {
media::TimeIntervals buffered = mDecoder->GetBuffered();

View File

@ -12,16 +12,27 @@
namespace mozilla {
namespace dom {
NS_IMPL_ISUPPORTS(TimeRanges, nsIDOMTimeRanges)
NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(TimeRanges, mParent)
NS_IMPL_CYCLE_COLLECTING_ADDREF(TimeRanges)
NS_IMPL_CYCLE_COLLECTING_RELEASE(TimeRanges)
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(TimeRanges)
NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
NS_INTERFACE_MAP_ENTRY(nsIDOMTimeRanges)
NS_INTERFACE_MAP_ENTRY(nsISupports)
NS_INTERFACE_MAP_END
TimeRanges::TimeRanges()
: mParent(nullptr)
{
}
TimeRanges::TimeRanges(nsISupports* aParent)
: mParent(aParent)
{
MOZ_COUNT_CTOR(TimeRanges);
}
TimeRanges::~TimeRanges()
{
MOZ_COUNT_DTOR(TimeRanges);
}
NS_IMETHODIMP
@ -166,10 +177,16 @@ TimeRanges::Find(double aTime, double aTolerance /* = 0 */)
return NoIndex;
}
bool
TimeRanges::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto, JS::MutableHandle<JSObject*> aReflector)
JSObject*
TimeRanges::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
{
return TimeRangesBinding::Wrap(aCx, this, aGivenProto, aReflector);
return TimeRangesBinding::Wrap(aCx, this, aGivenProto);
}
nsISupports*
TimeRanges::GetParentObject() const
{
return mParent;
}
void

View File

@ -25,13 +25,16 @@ namespace dom {
// Implements media TimeRanges:
// http://www.whatwg.org/specs/web-apps/current-work/multipage/video.html#timeranges
class TimeRanges final : public nsIDOMTimeRanges
class TimeRanges final : public nsIDOMTimeRanges,
public nsWrapperCache
{
public:
NS_DECL_ISUPPORTS
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(TimeRanges)
NS_DECL_NSIDOMTIMERANGES
TimeRanges();
explicit TimeRanges(nsISupports* aParent);
void Add(double aStart, double aEnd);
@ -50,7 +53,9 @@ public:
// Mutate this TimeRange to be the intersection of this and aOtherRanges.
void Intersection(const TimeRanges* aOtherRanges);
bool WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto, JS::MutableHandle<JSObject*> aReflector);
virtual JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) override;
nsISupports* GetParentObject() const;
uint32_t Length() const
{
@ -90,6 +95,8 @@ private:
nsAutoTArray<TimeRange,4> mRanges;
nsCOMPtr<nsISupports> mParent;
public:
typedef nsTArray<TimeRange>::index_type index_type;
static const index_type NoIndex = index_type(-1);

View File

@ -118,19 +118,31 @@ SourceBuffer::SetTimestampOffset(double aTimestampOffset, ErrorResult& aRv)
}
}
already_AddRefed<TimeRanges>
TimeRanges*
SourceBuffer::GetBuffered(ErrorResult& aRv)
{
MOZ_ASSERT(NS_IsMainThread());
// http://w3c.github.io/media-source/index.html#widl-SourceBuffer-buffered
// 1. If this object has been removed from the sourceBuffers attribute of the parent media source then throw an InvalidStateError exception and abort these steps.
if (!IsAttached()) {
aRv.Throw(NS_ERROR_DOM_INVALID_STATE_ERR);
return nullptr;
}
media::TimeIntervals ranges = mContentManager->Buffered();
MSE_DEBUGV("ranges=%s", DumpTimeRanges(ranges).get());
RefPtr<dom::TimeRanges> tr = new dom::TimeRanges();
ranges.ToTimeRanges(tr);
return tr.forget();
bool rangeChanged = true;
media::TimeIntervals intersection = mContentManager->Buffered();
MSE_DEBUGV("intersection=%s", DumpTimeRanges(intersection).get());
if (mBuffered) {
media::TimeIntervals currentValue(mBuffered);
rangeChanged = (intersection != currentValue);
MSE_DEBUGV("currentValue=%s", DumpTimeRanges(currentValue).get());
}
// 5. If intersection ranges does not contain the exact same range information as the current value of this attribute, then update the current value of this attribute to intersection ranges.
if (rangeChanged) {
mBuffered = new TimeRanges(ToSupports(this));
intersection.ToTimeRanges(mBuffered);
}
// 6. Return the current value of this attribute.
return mBuffered;
}
media::TimeIntervals
@ -634,11 +646,13 @@ NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(SourceBuffer)
manager->Detach();
}
NS_IMPL_CYCLE_COLLECTION_UNLINK(mMediaSource)
NS_IMPL_CYCLE_COLLECTION_UNLINK(mBuffered)
NS_IMPL_CYCLE_COLLECTION_UNLINK_END_INHERITED(DOMEventTargetHelper)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(SourceBuffer,
DOMEventTargetHelper)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mMediaSource)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mBuffered)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
NS_IMPL_ADDREF_INHERITED(SourceBuffer, DOMEventTargetHelper)

View File

@ -147,7 +147,7 @@ public:
return mUpdating;
}
already_AddRefed<TimeRanges> GetBuffered(ErrorResult& aRv);
TimeRanges* GetBuffered(ErrorResult& aRv);
media::TimeIntervals GetTimeIntervals();
double TimestampOffset() const
@ -274,6 +274,8 @@ private:
MozPromiseRequestHolder<SourceBufferContentManager::AppendPromise> mPendingAppend;
const nsCString mType;
RefPtr<TimeRanges> mBuffered;
};
} // namespace dom

View File

@ -20,7 +20,7 @@ interface SourceBuffer : EventTarget {
[SetterThrows]
attribute SourceBufferAppendMode mode;
readonly attribute boolean updating;
[NewObject, Throws]
[Throws]
readonly attribute TimeRanges buffered;
[SetterThrows]
attribute double timestampOffset;