Bug 1376363. P1 - store container type in MediaDecoder.
So we can remove MediaResource::GetContentType() in the future.
MozReview-Commit-ID: zWUNF2uGpf
--- a/dom/html/HTMLMediaElement.cpp
+++ b/dom/html/HTMLMediaElement.cpp
@@ -2502,17 +2502,18 @@ nsresult HTMLMediaElement::LoadResource(
MediaDecoderInit decoderInit(
this,
mAudioChannel,
mMuted ? 0.0 : mVolume,
mPreservesPitch,
mPlaybackRate,
mPreloadAction == HTMLMediaElement::PRELOAD_METADATA,
mHasSuspendTaint,
- HasAttr(kNameSpaceID_None, nsGkAtoms::loop));
+ HasAttr(kNameSpaceID_None, nsGkAtoms::loop),
+ MediaContainerType(MEDIAMIMETYPE("application/x.mediasource")));
RefPtr<MediaSourceDecoder> decoder = new MediaSourceDecoder(decoderInit);
if (!mMediaSource->Attach(decoder)) {
// TODO: 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.
decoder->Shutdown();
return NS_ERROR_FAILURE;
@@ -4645,25 +4646,26 @@ HTMLMediaElement::InitializeDecoderAsClo
{
NS_ASSERTION(mLoadingSrc, "mLoadingSrc must already be set");
NS_ASSERTION(mDecoder == nullptr, "Shouldn't have a decoder");
MediaResource* originalResource = aOriginal->GetResource();
if (!originalResource)
return NS_ERROR_FAILURE;
- MediaDecoderInit decoderInit(
- this,
- mAudioChannel,
- mMuted ? 0.0 : mVolume,
- mPreservesPitch,
- mPlaybackRate,
- mPreloadAction == HTMLMediaElement::PRELOAD_METADATA,
- mHasSuspendTaint,
- HasAttr(kNameSpaceID_None, nsGkAtoms::loop));
+ MediaDecoderInit decoderInit(this,
+ mAudioChannel,
+ mMuted ? 0.0 : mVolume,
+ mPreservesPitch,
+ mPlaybackRate,
+ mPreloadAction ==
+ HTMLMediaElement::PRELOAD_METADATA,
+ mHasSuspendTaint,
+ HasAttr(kNameSpaceID_None, nsGkAtoms::loop),
+ aOriginal->ContainerType());
RefPtr<ChannelMediaDecoder> decoder = aOriginal->Clone(decoderInit);
if (!decoder)
return NS_ERROR_FAILURE;
LOG(LogLevel::Debug, ("%p Cloned decoder %p from %p", this, decoder.get(), aOriginal));
nsresult rv = decoder->Load(originalResource);
@@ -4678,33 +4680,43 @@ HTMLMediaElement::InitializeDecoderAsClo
}
nsresult HTMLMediaElement::InitializeDecoderForChannel(nsIChannel* aChannel,
nsIStreamListener** aListener)
{
NS_ASSERTION(mLoadingSrc, "mLoadingSrc must already be set");
nsAutoCString mimeType;
+ DecoderDoctorDiagnostics diagnostics;
aChannel->GetContentType(mimeType);
NS_ASSERTION(!mimeType.IsEmpty(), "We should have the Content-Type.");
- DecoderDoctorDiagnostics diagnostics;
- MediaDecoderInit decoderInit(
- this,
- mAudioChannel,
- mMuted ? 0.0 : mVolume,
- mPreservesPitch,
- mPlaybackRate,
- mPreloadAction == HTMLMediaElement::PRELOAD_METADATA,
- mHasSuspendTaint,
- HasAttr(kNameSpaceID_None, nsGkAtoms::loop));
+ Maybe<MediaContainerType> containerType = MakeMediaContainerType(mimeType);
+ if (!containerType) {
+ diagnostics.StoreFormatDiagnostics(OwnerDoc(),
+ NS_ConvertASCIItoUTF16(mimeType),
+ /* aCanPlay = */ false,
+ __func__);
+ return NS_ERROR_FAILURE;
+ }
+
+ MediaDecoderInit decoderInit(this,
+ mAudioChannel,
+ mMuted ? 0.0 : mVolume,
+ mPreservesPitch,
+ mPlaybackRate,
+ mPreloadAction ==
+ HTMLMediaElement::PRELOAD_METADATA,
+ mHasSuspendTaint,
+ HasAttr(kNameSpaceID_None, nsGkAtoms::loop),
+ *containerType);
RefPtr<ChannelMediaDecoder> decoder =
- DecoderTraits::CreateDecoder(mimeType, decoderInit, &diagnostics);
+ DecoderTraits::CreateDecoder(decoderInit, &diagnostics);
diagnostics.StoreFormatDiagnostics(OwnerDoc(),
NS_ConvertASCIItoUTF16(mimeType),
decoder != nullptr,
__func__);
if (!decoder) {
nsAutoString src;
GetCurrentSrc(src);
NS_ConvertUTF8toUTF16 mimeUTF16(mimeType);
--- a/dom/media/DecoderTraits.cpp
+++ b/dom/media/DecoderTraits.cpp
@@ -261,88 +261,84 @@ bool DecoderTraits::ShouldHandleMediaTyp
}
}
return CanHandleMediaType(*containerType, aDiagnostics) != CANPLAY_NO;
}
// Instantiates but does not initialize decoder.
static already_AddRefed<ChannelMediaDecoder>
-InstantiateDecoder(const MediaContainerType& aType,
- MediaDecoderInit& aInit,
+InstantiateDecoder(MediaDecoderInit& aInit,
DecoderDoctorDiagnostics* aDiagnostics)
{
MOZ_ASSERT(NS_IsMainThread());
RefPtr<ChannelMediaDecoder> decoder;
+ const MediaContainerType& type = aInit.mContainerType;
+
#ifdef MOZ_ANDROID_HLS_SUPPORT
- if (HLSDecoder::IsSupportedType(aType)) {
+ if (HLSDecoder::IsSupportedType(type)) {
decoder = new HLSDecoder(aInit);
return decoder.forget();
}
#endif
#ifdef MOZ_FMP4
- if (MP4Decoder::IsSupportedType(aType, aDiagnostics)) {
+ if (MP4Decoder::IsSupportedType(type, aDiagnostics)) {
decoder = new MP4Decoder(aInit);
return decoder.forget();
}
#endif
- if (MP3Decoder::IsSupportedType(aType)) {
+ if (MP3Decoder::IsSupportedType(type)) {
decoder = new MP3Decoder(aInit);
return decoder.forget();
}
- if (ADTSDecoder::IsSupportedType(aType)) {
+ if (ADTSDecoder::IsSupportedType(type)) {
decoder = new ADTSDecoder(aInit);
return decoder.forget();
}
- if (OggDecoder::IsSupportedType(aType)) {
+ if (OggDecoder::IsSupportedType(type)) {
decoder = new OggDecoder(aInit);
return decoder.forget();
}
- if (WaveDecoder::IsSupportedType(aType)) {
+ if (WaveDecoder::IsSupportedType(type)) {
decoder = new WaveDecoder(aInit);
return decoder.forget();
}
- if (FlacDecoder::IsSupportedType(aType)) {
+ if (FlacDecoder::IsSupportedType(type)) {
decoder = new FlacDecoder(aInit);
return decoder.forget();
}
#ifdef MOZ_ANDROID_OMX
if (MediaDecoder::IsAndroidMediaPluginEnabled() &&
- EnsureAndroidMediaPluginHost()->FindDecoder(aType, nullptr)) {
- decoder = new AndroidMediaDecoder(aInit, aType);
+ EnsureAndroidMediaPluginHost()->FindDecoder(type, nullptr)) {
+ decoder = new AndroidMediaDecoder(aInit, type);
return decoder.forget();
}
#endif
- if (WebMDecoder::IsSupportedType(aType)) {
+ if (WebMDecoder::IsSupportedType(type)) {
decoder = new WebMDecoder(aInit);
return decoder.forget();
}
- if (DecoderTraits::IsHttpLiveStreamingType(aType)) {
+ if (DecoderTraits::IsHttpLiveStreamingType(type)) {
// We don't have an HLS decoder.
Telemetry::Accumulate(Telemetry::MEDIA_HLS_DECODER_SUCCESS, false);
}
return nullptr;
}
/* static */
already_AddRefed<ChannelMediaDecoder>
-DecoderTraits::CreateDecoder(const nsACString& aType,
- MediaDecoderInit& aInit,
+DecoderTraits::CreateDecoder(MediaDecoderInit& aInit,
DecoderDoctorDiagnostics* aDiagnostics)
{
MOZ_ASSERT(NS_IsMainThread());
- Maybe<MediaContainerType> type = MakeMediaContainerType(aType);
- if (!type) {
- return nullptr;
- }
- return InstantiateDecoder(*type, aInit, aDiagnostics);
+ return InstantiateDecoder(aInit, aDiagnostics);
}
/* static */
MediaDecoderReader*
DecoderTraits::CreateReader(const MediaContainerType& aType,
AbstractMediaDecoder* aDecoder)
{
MOZ_ASSERT(NS_IsMainThread());
--- a/dom/media/DecoderTraits.h
+++ b/dom/media/DecoderTraits.h
@@ -39,17 +39,16 @@ public:
// for the type is more limited than appears in the wild, we should return
// false here even if CanHandleMediaType would return true.
static bool ShouldHandleMediaType(const char* aMIMEType,
DecoderDoctorDiagnostics* aDiagnostics);
// Create a decoder for the given aType. Returns null if we
// were unable to create the decoder.
static already_AddRefed<ChannelMediaDecoder> CreateDecoder(
- const nsACString& aType,
MediaDecoderInit& aInit,
DecoderDoctorDiagnostics* aDiagnostics);
// Create a reader for thew given MIME type aType. Returns null
// if we were unable to create the reader.
static MediaDecoderReader* CreateReader(const MediaContainerType& aType,
AbstractMediaDecoder* aDecoder);
--- a/dom/media/MediaDecoder.cpp
+++ b/dom/media/MediaDecoder.cpp
@@ -262,16 +262,17 @@ MediaDecoder::MediaDecoder(MediaDecoderI
, INIT_CANONICAL(mSameOriginMedia, false)
, INIT_CANONICAL(mMediaPrincipalHandle, PRINCIPAL_HANDLE_NONE)
, INIT_CANONICAL(mPlaybackBytesPerSecond, 0.0)
, INIT_CANONICAL(mPlaybackRateReliable, true)
, INIT_CANONICAL(mDecoderPosition, 0)
, mTelemetryReported(false)
, mIsMediaElement(!!mOwner->GetMediaElement())
, mElement(mOwner->GetMediaElement())
+ , mContainerType(aInit.mContainerType)
{
MOZ_ASSERT(NS_IsMainThread());
MOZ_ASSERT(mAbstractMainThread);
MediaMemoryTracker::AddMediaDecoder(this);
//
// Initialize watchers.
//
--- a/dom/media/MediaDecoder.h
+++ b/dom/media/MediaDecoder.h
@@ -47,43 +47,46 @@ enum class MediaEventType : int8_t;
enum class Visibility : uint8_t;
// GetCurrentTime is defined in winbase.h as zero argument macro forwarding to
// GetTickCount() and conflicts with MediaDecoder::GetCurrentTime implementation.
#ifdef GetCurrentTime
#undef GetCurrentTime
#endif
-struct MediaDecoderInit
+struct MOZ_STACK_CLASS MediaDecoderInit
{
MediaDecoderOwner* const mOwner;
const dom::AudioChannel mAudioChannel;
const double mVolume;
const bool mPreservesPitch;
const double mPlaybackRate;
const bool mMinimizePreroll;
const bool mHasSuspendTaint;
const bool mLooping;
+ const MediaContainerType mContainerType;
MediaDecoderInit(MediaDecoderOwner* aOwner,
dom::AudioChannel aAudioChannel,
double aVolume,
bool aPreservesPitch,
double aPlaybackRate,
bool aMinimizePreroll,
bool aHasSuspendTaint,
- bool aLooping)
+ bool aLooping,
+ const MediaContainerType& aContainerType)
: mOwner(aOwner)
, mAudioChannel(aAudioChannel)
, mVolume(aVolume)
, mPreservesPitch(aPreservesPitch)
, mPlaybackRate(aPlaybackRate)
, mMinimizePreroll(aMinimizePreroll)
, mHasSuspendTaint(aHasSuspendTaint)
, mLooping(aLooping)
+ , mContainerType(aContainerType)
{
}
};
class MediaDecoder : public AbstractMediaDecoder
{
public:
typedef MozPromise<bool /* aIgnored */, bool /* aIgnored */,
@@ -103,16 +106,20 @@ public:
PLAY_STATE_SHUTDOWN
};
// Must be called exactly once, on the main thread, during startup.
static void InitStatics();
explicit MediaDecoder(MediaDecoderInit& aInit);
+ // Returns the container content type of the resource.
+ // Safe to call from any thread.
+ const MediaContainerType& ContainerType() const { return mContainerType; }
+
// Create a new state machine to run this decoder.
// Subclasses must implement this.
virtual MediaDecoderStateMachine* CreateStateMachine() = 0;
// Cleanup internal data structures. Must be called on the main
// thread by the owning object before that object disposes of this object.
virtual void Shutdown();
@@ -823,13 +830,14 @@ private:
// Notify owner when the audible state changed
void NotifyAudibleStateChanged();
bool mTelemetryReported;
// Used to debug how mOwner becomes a dangling pointer in bug 1326294.
bool mIsMediaElement;
WeakPtr<dom::HTMLMediaElement> mElement;
+ const MediaContainerType mContainerType;
};
} // namespace mozilla
#endif