From 18f9b185b67120ba88f5e643b7413ca06c497383 Mon Sep 17 00:00:00 2001 From: Jeroen Vreeken Date: Wed, 10 Jul 2019 11:05:38 +0200 Subject: Allow matroska mime types for video element and MSE Allow avc (h.264) content in matroska/webm containers --- dom/media/fmp4/MP4Decoder.cpp | 3 ++- dom/media/mediasource/ContainerParser.cpp | 3 +++ dom/media/mediasource/MediaSource.cpp | 3 ++- dom/media/mediasource/TrackBuffersManager.cpp | 1 + dom/media/webm/WebMDecoder.cpp | 7 ++++++- dom/media/webm/WebMDemuxer.cpp | 24 +++++++++++++++++++++++- 6 files changed, 37 insertions(+), 4 deletions(-) (limited to 'dom') diff --git a/dom/media/fmp4/MP4Decoder.cpp b/dom/media/fmp4/MP4Decoder.cpp index 6954e9757..b293c251b 100644 --- a/dom/media/fmp4/MP4Decoder.cpp +++ b/dom/media/fmp4/MP4Decoder.cpp @@ -172,7 +172,8 @@ bool MP4Decoder::IsH264(const nsACString& aMimeType) { return aMimeType.EqualsLiteral("video/mp4") || - aMimeType.EqualsLiteral("video/avc"); + aMimeType.EqualsLiteral("video/avc") || + aMimeType.EqualsLiteral("video/webm; codecs=avc1"); } /* static */ diff --git a/dom/media/mediasource/ContainerParser.cpp b/dom/media/mediasource/ContainerParser.cpp index 4ae37d7e9..46f2e9557 100644 --- a/dom/media/mediasource/ContainerParser.cpp +++ b/dom/media/mediasource/ContainerParser.cpp @@ -697,6 +697,9 @@ ContainerParser::CreateForMIMEType(const nsACString& aType) if (aType.LowerCaseEqualsLiteral("video/webm") || aType.LowerCaseEqualsLiteral("audio/webm")) { return new WebMContainerParser(aType); } + if (aType.LowerCaseEqualsLiteral("video/x-matroska")) { + return new WebMContainerParser(aType); + } #ifdef MOZ_FMP4 if (aType.LowerCaseEqualsLiteral("video/mp4") || aType.LowerCaseEqualsLiteral("audio/mp4")) { diff --git a/dom/media/mediasource/MediaSource.cpp b/dom/media/mediasource/MediaSource.cpp index 152c0085a..a262ff52c 100644 --- a/dom/media/mediasource/MediaSource.cpp +++ b/dom/media/mediasource/MediaSource.cpp @@ -110,7 +110,8 @@ MediaSource::IsTypeSupported(const nsAString& aType, DecoderDoctorDiagnostics* a } return NS_OK; } - if (mimeType.EqualsASCII("video/webm")) { + if (mimeType.EqualsASCII("video/webm") || + mimeType.EqualsASCII("video/x-matroska")) { if (!(Preferences::GetBool("media.mediasource.webm.enabled", false) || IsWebMForced(aDiagnostics))) { return NS_ERROR_DOM_NOT_SUPPORTED_ERR; diff --git a/dom/media/mediasource/TrackBuffersManager.cpp b/dom/media/mediasource/TrackBuffersManager.cpp index ac6d82411..3a6f2a5c8 100644 --- a/dom/media/mediasource/TrackBuffersManager.cpp +++ b/dom/media/mediasource/TrackBuffersManager.cpp @@ -814,6 +814,7 @@ TrackBuffersManager::CreateDemuxerforMIMEType() ShutdownDemuxers(); if (mType.LowerCaseEqualsLiteral("video/webm") || + mType.LowerCaseEqualsLiteral("video/x-matroska") || mType.LowerCaseEqualsLiteral("audio/webm")) { mInputDemuxer = new WebMDemuxer(mCurrentInputBuffer, true /* IsMediaSource*/ ); return; diff --git a/dom/media/webm/WebMDecoder.cpp b/dom/media/webm/WebMDecoder.cpp index 9575d6e42..37e1e4a33 100644 --- a/dom/media/webm/WebMDecoder.cpp +++ b/dom/media/webm/WebMDecoder.cpp @@ -41,7 +41,7 @@ WebMDecoder::CanHandleMediaType(const nsACString& aMIMETypeExcludingCodecs, } const bool isWebMAudio = aMIMETypeExcludingCodecs.EqualsASCII("audio/webm"); - const bool isWebMVideo = aMIMETypeExcludingCodecs.EqualsASCII("video/webm"); + const bool isWebMVideo = aMIMETypeExcludingCodecs.EqualsASCII("video/webm") || aMIMETypeExcludingCodecs.EqualsASCII("video/x-matroska") ; if (!isWebMAudio && !isWebMVideo) { return false; } @@ -74,6 +74,11 @@ WebMDecoder::CanHandleMediaType(const nsACString& aMIMETypeExcludingCodecs, continue; } #endif + + if (IsH264CodecString(codec)) { + continue; + } + // Some unsupported codec. return false; } diff --git a/dom/media/webm/WebMDemuxer.cpp b/dom/media/webm/WebMDemuxer.cpp index 013da9b2c..2b6d46186 100644 --- a/dom/media/webm/WebMDemuxer.cpp +++ b/dom/media/webm/WebMDemuxer.cpp @@ -326,6 +326,20 @@ WebMDemuxer::ReadMetadata() case NESTEGG_CODEC_AV1: mInfo.mVideo.mMimeType = "video/webm; codecs=av1"; break; + case NESTEGG_CODEC_AVC1: { + mInfo.mVideo.mMimeType = "video/webm; codecs=avc1"; + + unsigned char* data = 0; + size_t length = 0; + r = nestegg_track_codec_data(context, track, 0, &data, &length); + if (r == -1) { + return NS_ERROR_FAILURE; + } + + mInfo.mVideo.mExtraData = new MediaByteBuffer(length); + mInfo.mVideo.mExtraData->AppendElements(data, length); + break; + } default: NS_WARNING("Unknown WebM video codec"); return NS_ERROR_FAILURE; @@ -662,6 +676,9 @@ WebMDemuxer::GetNextPacket(TrackInfo::TrackType aType, MediaRawDataQueue *aSampl isKeyframe = AOMDecoder::IsKeyframe(sample); break; #endif + case NESTEGG_CODEC_AVC1: + isKeyframe = nestegg_packet_has_keyframe(holder->Packet()); + break; default: NS_WARNING("Cannot detect keyframes in unknown WebM video codec"); return NS_ERROR_FAILURE; @@ -682,7 +699,7 @@ WebMDemuxer::GetNextPacket(TrackInfo::TrackType aType, MediaRawDataQueue *aSampl dimensions = AOMDecoder::GetFrameSize(sample); break; #endif - } + } if (mLastSeenFrameSize.isSome() && (dimensions != mLastSeenFrameSize.value())) { mInfo.mVideo.mDisplay = dimensions; @@ -749,6 +766,11 @@ WebMDemuxer::GetNextPacket(TrackInfo::TrackType aType, MediaRawDataQueue *aSampl if (aType == TrackInfo::kVideoTrack) { sample->mTrackInfo = mSharedVideoTrackInfo; } + + if (mVideoCodec == NESTEGG_CODEC_AVC1) { + sample->mExtraData = mInfo.mVideo.mExtraData; + } + aSamples->Push(sample); } return NS_OK; -- cgit v1.2.3