Bug 855130 - Integrate MediaSource into HTMLMediaElement. r=roc

This commit is contained in:
Matthew Gregan 2013-06-21 15:15:47 +12:00
Родитель 03b6f26ca7
Коммит fb07677353
2 изменённых файлов: 53 добавлений и 2 удалений

Просмотреть файл

@ -50,6 +50,7 @@ namespace mozilla {
namespace dom {
class MediaError;
class MediaSource;
class HTMLMediaElement : public nsGenericHTMLElement,
public nsIObserver,
@ -867,6 +868,9 @@ protected:
// Holds a reference to the MediaStreamListener attached to mSrcStream.
nsRefPtr<StreamListener> mSrcStreamListener;
// Holds a reference to the MediaSource supplying data for playback.
nsRefPtr<MediaSource> mMediaSource;
// Holds a reference to the first channel we open to the media resource.
// Once the decoder is created, control over the channel passes to the
// decoder, and we null out this reference. We must store this in case

Просмотреть файл

@ -66,6 +66,7 @@
#include "MediaStreamGraph.h"
#include "nsIScriptError.h"
#include "nsHostObjectProtocolHandler.h"
#include "mozilla/dom/MediaSource.h"
#include "MediaMetadataManager.h"
#include "AudioChannelService.h"
@ -402,6 +403,7 @@ NS_IMPL_ADDREF_INHERITED(HTMLMediaElement, nsGenericHTMLElement)
NS_IMPL_RELEASE_INHERITED(HTMLMediaElement, nsGenericHTMLElement)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(HTMLMediaElement, nsGenericHTMLElement)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mMediaSource)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mSrcStream)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mSrcAttrStream)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mSourcePointer)
@ -423,6 +425,7 @@ NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(HTMLMediaElement, nsGenericHTMLE
tmp->EndSrcMediaStreamPlayback();
}
NS_IMPL_CYCLE_COLLECTION_UNLINK(mSrcAttrStream)
NS_IMPL_CYCLE_COLLECTION_UNLINK(mMediaSource)
NS_IMPL_CYCLE_COLLECTION_UNLINK(mSourcePointer)
NS_IMPL_CYCLE_COLLECTION_UNLINK(mLoadBlockedDoc)
NS_IMPL_CYCLE_COLLECTION_UNLINK(mSourceLoadCandidate)
@ -590,6 +593,10 @@ void HTMLMediaElement::AbortExistingLoads()
if (mSrcStream) {
EndSrcMediaStreamPlayback();
}
if (mMediaSource) {
mMediaSource->DetachElement();
mMediaSource = nullptr;
}
if (mAudioStream) {
mAudioStream->Shutdown();
mAudioStream = nullptr;
@ -1111,6 +1118,30 @@ nsresult HTMLMediaElement::LoadResource()
return NS_OK;
}
if (IsMediaSourceURI(mLoadingSrc)) {
nsRefPtr<MediaSource> source;
rv = NS_GetSourceForMediaSourceURI(mLoadingSrc, getter_AddRefs(source));
if (NS_FAILED(rv)) {
nsCString specUTF8;
mLoadingSrc->GetSpec(specUTF8);
NS_ConvertUTF8toUTF16 spec(specUTF8);
const PRUnichar* params[] = { spec.get() };
ReportLoadError("MediaLoadInvalidURI", params, ArrayLength(params));
return rv;
}
mMediaSource = source.forget();
if (!mMediaSource->AttachElement(this)) {
// XXX(kinetik): Handle failure: run "If the media data cannot be
// fetched at all, due to network errors, causing the user agent to
// give up trying to fetch the resource" section of resource fetch
// algorithm.
return NS_ERROR_FAILURE;
}
// XXX(kinetik): Bug 881512. Wire this up properly; return from here (as
// MediaStreams setup does) rather than relying on mediasource->channel
// conversion.
}
nsCOMPtr<nsILoadGroup> loadGroup = GetDocumentLoadGroup();
// check for a Content Security Policy to pass down to the channel
@ -1357,7 +1388,17 @@ already_AddRefed<TimeRanges>
HTMLMediaElement::Seekable() const
{
nsRefPtr<TimeRanges> ranges = new TimeRanges();
if (mDecoder && mReadyState > nsIDOMHTMLMediaElement::HAVE_NOTHING) {
if (mMediaSource) {
double duration = mMediaSource->Duration();
if (IsNaN(duration)) {
// Return empty range.
} else if (duration > 0 && IsInfinite(duration)) {
nsRefPtr<TimeRanges> bufferedRanges = Buffered();
ranges->Add(0, bufferedRanges->GetFinalEndTime());
} else {
ranges->Add(0, duration);
}
} else if (mDecoder && mReadyState > nsIDOMHTMLMediaElement::HAVE_NOTHING) {
mDecoder->GetSeekable(ranges);
}
return ranges.forget();
@ -1942,6 +1983,10 @@ HTMLMediaElement::~HTMLMediaElement()
if (mSrcStream) {
EndSrcMediaStreamPlayback();
}
if (mMediaSource) {
mMediaSource->DetachElement();
mMediaSource = nullptr;
}
NS_ASSERTION(MediaElementTableCount(this, mLoadingSrc) == 0,
"Destroyed media element should no longer be in element table");
@ -3494,7 +3539,9 @@ already_AddRefed<TimeRanges>
HTMLMediaElement::Buffered() const
{
nsRefPtr<TimeRanges> ranges = new TimeRanges();
if (mReadyState > nsIDOMHTMLMediaElement::HAVE_NOTHING && mDecoder) {
if (mMediaSource) {
mMediaSource->GetBuffered(ranges);
} else if (mDecoder && mReadyState > nsIDOMHTMLMediaElement::HAVE_NOTHING) {
// If GetBuffered fails we ignore the error result and just return the
// time ranges we found up till the error.
mDecoder->GetBuffered(ranges);