Allow matroska mime types for video element and MSE

Allow avc (h.264) content in matroska/webm containers
This commit is contained in:
Jeroen Vreeken 2019-07-10 11:05:38 +02:00 • committed by Roy Tam
commit a960d679d5
8 changed files with 44 additions and 5 deletions

View file

@ -180,7 +180,8 @@ bool
MP4Decoder::IsH264(const nsACString& aMimeType) MP4Decoder::IsH264(const nsACString& aMimeType)
{ {
return aMimeType.EqualsLiteral("video/mp4") || return aMimeType.EqualsLiteral("video/mp4") ||
aMimeType.EqualsLiteral("video/avc"); aMimeType.EqualsLiteral("video/avc") ||
aMimeType.EqualsLiteral("video/webm; codecs=avc1");
} }
/* static */ /* static */

View file

@ -697,6 +697,9 @@ ContainerParser::CreateForMIMEType(const nsACString& aType)
if (aType.LowerCaseEqualsLiteral("video/webm") || aType.LowerCaseEqualsLiteral("audio/webm")) { if (aType.LowerCaseEqualsLiteral("video/webm") || aType.LowerCaseEqualsLiteral("audio/webm")) {
return new WebMContainerParser(aType); return new WebMContainerParser(aType);
} }
if (aType.LowerCaseEqualsLiteral("video/x-matroska")) {
return new WebMContainerParser(aType);
}
#ifdef MOZ_FMP4 #ifdef MOZ_FMP4
if (aType.LowerCaseEqualsLiteral("video/mp4") || aType.LowerCaseEqualsLiteral("audio/mp4")) { if (aType.LowerCaseEqualsLiteral("video/mp4") || aType.LowerCaseEqualsLiteral("audio/mp4")) {

View file

@ -110,7 +110,8 @@ MediaSource::IsTypeSupported(const nsAString& aType, DecoderDoctorDiagnostics* a
} }
return NS_OK; 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) || if (!(Preferences::GetBool("media.mediasource.webm.enabled", false) ||
IsWebMForced(aDiagnostics))) { IsWebMForced(aDiagnostics))) {
return NS_ERROR_DOM_NOT_SUPPORTED_ERR; return NS_ERROR_DOM_NOT_SUPPORTED_ERR;

View file

@ -814,6 +814,7 @@ TrackBuffersManager::CreateDemuxerforMIMEType()
ShutdownDemuxers(); ShutdownDemuxers();
if (mType.LowerCaseEqualsLiteral("video/webm") || if (mType.LowerCaseEqualsLiteral("video/webm") ||
mType.LowerCaseEqualsLiteral("video/x-matroska") ||
mType.LowerCaseEqualsLiteral("audio/webm")) { mType.LowerCaseEqualsLiteral("audio/webm")) {
mInputDemuxer = new WebMDemuxer(mCurrentInputBuffer, true /* IsMediaSource*/ ); mInputDemuxer = new WebMDemuxer(mCurrentInputBuffer, true /* IsMediaSource*/ );
return; return;

View file

@ -41,7 +41,7 @@ WebMDecoder::CanHandleMediaType(const nsACString& aMIMETypeExcludingCodecs,
} }
const bool isWebMAudio = aMIMETypeExcludingCodecs.EqualsASCII("audio/webm"); 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) { if (!isWebMAudio && !isWebMVideo) {
return false; return false;
} }
@ -74,6 +74,11 @@ WebMDecoder::CanHandleMediaType(const nsACString& aMIMETypeExcludingCodecs,
continue; continue;
} }
#endif #endif
if (IsH264CodecString(codec)) {
continue;
}
// Some unsupported codec. // Some unsupported codec.
return false; return false;
} }

View file

@ -326,6 +326,20 @@ WebMDemuxer::ReadMetadata()
case NESTEGG_CODEC_AV1: case NESTEGG_CODEC_AV1:
mInfo.mVideo.mMimeType = "video/webm; codecs=av1"; mInfo.mVideo.mMimeType = "video/webm; codecs=av1";
break; 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: default:
NS_WARNING("Unknown WebM video codec"); NS_WARNING("Unknown WebM video codec");
return NS_ERROR_FAILURE; return NS_ERROR_FAILURE;
@ -662,6 +676,9 @@ WebMDemuxer::GetNextPacket(TrackInfo::TrackType aType, MediaRawDataQueue *aSampl
isKeyframe = AOMDecoder::IsKeyframe(sample); isKeyframe = AOMDecoder::IsKeyframe(sample);
break; break;
#endif #endif
case NESTEGG_CODEC_AVC1:
isKeyframe = nestegg_packet_has_keyframe(holder->Packet());
break;
default: default:
NS_WARNING("Cannot detect keyframes in unknown WebM video codec"); NS_WARNING("Cannot detect keyframes in unknown WebM video codec");
return NS_ERROR_FAILURE; return NS_ERROR_FAILURE;
@ -682,7 +699,7 @@ WebMDemuxer::GetNextPacket(TrackInfo::TrackType aType, MediaRawDataQueue *aSampl
dimensions = AOMDecoder::GetFrameSize(sample); dimensions = AOMDecoder::GetFrameSize(sample);
break; break;
#endif #endif
} }
if (mLastSeenFrameSize.isSome() if (mLastSeenFrameSize.isSome()
&& (dimensions != mLastSeenFrameSize.value())) { && (dimensions != mLastSeenFrameSize.value())) {
mInfo.mVideo.mDisplay = dimensions; mInfo.mVideo.mDisplay = dimensions;
@ -749,6 +766,11 @@ WebMDemuxer::GetNextPacket(TrackInfo::TrackType aType, MediaRawDataQueue *aSampl
if (aType == TrackInfo::kVideoTrack) { if (aType == TrackInfo::kVideoTrack) {
sample->mTrackInfo = mSharedVideoTrackInfo; sample->mTrackInfo = mSharedVideoTrackInfo;
} }
if (mVideoCodec == NESTEGG_CODEC_AVC1) {
sample->mExtraData = mInfo.mVideo.mExtraData;
}
aSamples->Push(sample); aSamples->Push(sample);
} }
return NS_OK; return NS_OK;

View file

@ -72,6 +72,7 @@ extern "C" {
#define NESTEGG_CODEC_VP9 2 /**< Track uses Google On2 VP9 codec. */ #define NESTEGG_CODEC_VP9 2 /**< Track uses Google On2 VP9 codec. */
#define NESTEGG_CODEC_OPUS 3 /**< Track uses Xiph Opus codec. */ #define NESTEGG_CODEC_OPUS 3 /**< Track uses Xiph Opus codec. */
#define NESTEGG_CODEC_AV1 4 /**< Track uses AOMedia AV1 codec. */ #define NESTEGG_CODEC_AV1 4 /**< Track uses AOMedia AV1 codec. */
#define NESTEGG_CODEC_AVC1 5 /**< Track uses AVC1 'h264' */
#define NESTEGG_CODEC_UNKNOWN INT_MAX /**< Track uses unknown codec. */ #define NESTEGG_CODEC_UNKNOWN INT_MAX /**< Track uses unknown codec. */
#define NESTEGG_VIDEO_MONO 0 /**< Track is mono video. */ #define NESTEGG_VIDEO_MONO 0 /**< Track is mono video. */

View file

@ -157,6 +157,7 @@ enum ebml_type_enum {
#define TRACK_ID_AV1 "V_AV1" #define TRACK_ID_AV1 "V_AV1"
#define TRACK_ID_VORBIS "A_VORBIS" #define TRACK_ID_VORBIS "A_VORBIS"
#define TRACK_ID_OPUS "A_OPUS" #define TRACK_ID_OPUS "A_OPUS"
#define TRACK_ID_AVC1 "V_MPEG4/ISO/AVC"
/* Track Encryption */ /* Track Encryption */
#define CONTENT_ENC_ALGO_AES 5 #define CONTENT_ENC_ALGO_AES 5
@ -2401,6 +2402,9 @@ nestegg_track_codec_id(nestegg * ctx, unsigned int track)
if (strcmp(codec_id, TRACK_ID_OPUS) == 0) if (strcmp(codec_id, TRACK_ID_OPUS) == 0)
return NESTEGG_CODEC_OPUS; return NESTEGG_CODEC_OPUS;
if (strcmp(codec_id, TRACK_ID_AVC1) == 0)
return NESTEGG_CODEC_AVC1;
return NESTEGG_CODEC_UNKNOWN; return NESTEGG_CODEC_UNKNOWN;
} }
@ -2459,7 +2463,8 @@ nestegg_track_codec_data(nestegg * ctx, unsigned int track, unsigned int item,
return -1; return -1;
if (nestegg_track_codec_id(ctx, track) != NESTEGG_CODEC_VORBIS && if (nestegg_track_codec_id(ctx, track) != NESTEGG_CODEC_VORBIS &&
nestegg_track_codec_id(ctx, track) != NESTEGG_CODEC_OPUS) nestegg_track_codec_id(ctx, track) != NESTEGG_CODEC_OPUS &&
nestegg_track_codec_id(ctx, track) != NESTEGG_CODEC_AVC1)
return -1; return -1;
if (ne_get_binary(entry->codec_private, &codec_private) != 0) if (ne_get_binary(entry->codec_private, &codec_private) != 0)