Allow matroska mime types for video element and MSE.
parent
4c5ca3dbe6
commit
a619b6c51f
|
@ -174,7 +174,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 */
|
||||||
|
|
|
@ -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") || aType.LowerCaseEqualsLiteral("audio/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")) {
|
||||||
|
|
|
@ -110,14 +110,16 @@ 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;
|
||||||
}
|
}
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
if (mimeType.EqualsASCII("audio/webm")) {
|
if (mimeType.EqualsASCII("audio/webm") ||
|
||||||
|
mimeType.EqualsASCII("audio/x-matroska")) {
|
||||||
if (!(Preferences::GetBool("media.mediasource.webm.enabled", false) ||
|
if (!(Preferences::GetBool("media.mediasource.webm.enabled", false) ||
|
||||||
Preferences::GetBool("media.mediasource.webm.audio.enabled", true))) {
|
Preferences::GetBool("media.mediasource.webm.audio.enabled", true))) {
|
||||||
return NS_ERROR_DOM_NOT_SUPPORTED_ERR;
|
return NS_ERROR_DOM_NOT_SUPPORTED_ERR;
|
||||||
|
|
|
@ -814,6 +814,8 @@ TrackBuffersManager::CreateDemuxerforMIMEType()
|
||||||
ShutdownDemuxers();
|
ShutdownDemuxers();
|
||||||
|
|
||||||
if (mType.LowerCaseEqualsLiteral("video/webm") ||
|
if (mType.LowerCaseEqualsLiteral("video/webm") ||
|
||||||
|
mType.LowerCaseEqualsLiteral("video/x-matroska") ||
|
||||||
|
mType.LowerCaseEqualsLiteral("audio/x-matroska") ||
|
||||||
mType.LowerCaseEqualsLiteral("audio/webm")) {
|
mType.LowerCaseEqualsLiteral("audio/webm")) {
|
||||||
mInputDemuxer = new WebMDemuxer(mCurrentInputBuffer, true /* IsMediaSource*/ );
|
mInputDemuxer = new WebMDemuxer(mCurrentInputBuffer, true /* IsMediaSource*/ );
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -42,7 +42,10 @@ 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");
|
||||||
if (!isWebMAudio && !isWebMVideo) {
|
const bool isMatroskaAudio = aMIMETypeExcludingCodecs.EqualsASCII("audio/x-matroska") ;
|
||||||
|
const bool isMatroskaVideo = aMIMETypeExcludingCodecs.EqualsASCII("video/x-matroska") ;
|
||||||
|
|
||||||
|
if (!isWebMAudio && !isWebMVideo && !isMatroskaAudio && !isMatroskaVideo) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -63,7 +66,7 @@ WebMDecoder::CanHandleMediaType(const nsACString& aMIMETypeExcludingCodecs,
|
||||||
}
|
}
|
||||||
// Note: Only accept VP8/VP9 in a video content type, not in an audio
|
// Note: Only accept VP8/VP9 in a video content type, not in an audio
|
||||||
// content type.
|
// content type.
|
||||||
if (isWebMVideo &&
|
if ((isWebMVideo || isMatroskaVideo) &&
|
||||||
(codec.EqualsLiteral("vp8") || codec.EqualsLiteral("vp8.0") ||
|
(codec.EqualsLiteral("vp8") || codec.EqualsLiteral("vp8.0") ||
|
||||||
codec.EqualsLiteral("vp9") || codec.EqualsLiteral("vp9.0"))) {
|
codec.EqualsLiteral("vp9") || codec.EqualsLiteral("vp9.0"))) {
|
||||||
|
|
||||||
|
@ -74,6 +77,15 @@ WebMDecoder::CanHandleMediaType(const nsACString& aMIMETypeExcludingCodecs,
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
if (IsH264CodecString(codec)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (IsAACCodecString(codec)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
// Some unsupported codec.
|
// Some unsupported codec.
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
|
@ -408,6 +422,8 @@ WebMDemuxer::ReadMetadata()
|
||||||
mInfo.mAudio.mMimeType = "audio/opus";
|
mInfo.mAudio.mMimeType = "audio/opus";
|
||||||
OpusDataDecoder::AppendCodecDelay(mInfo.mAudio.mCodecSpecificConfig,
|
OpusDataDecoder::AppendCodecDelay(mInfo.mAudio.mCodecSpecificConfig,
|
||||||
media::TimeUnit::FromNanoseconds(params.codec_delay).ToMicroseconds());
|
media::TimeUnit::FromNanoseconds(params.codec_delay).ToMicroseconds());
|
||||||
|
} else if (mAudioCodec == NESTEGG_CODEC_AAC) {
|
||||||
|
mInfo.mAudio.mMimeType = "audio/mp4a-latm";
|
||||||
}
|
}
|
||||||
mSeekPreroll = params.seek_preroll;
|
mSeekPreroll = params.seek_preroll;
|
||||||
mInfo.mAudio.mRate = params.rate;
|
mInfo.mAudio.mRate = params.rate;
|
||||||
|
@ -662,6 +678,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 +701,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 +768,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;
|
||||||
|
|
|
@ -72,6 +72,8 @@ 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_AAC 6 /**< Track uses AAC 'mp4a' */
|
||||||
#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. */
|
||||||
|
|
|
@ -157,6 +157,8 @@ 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"
|
||||||
|
#define TRACK_ID_AAC "A_AAC"
|
||||||
|
|
||||||
/* Track Encryption */
|
/* Track Encryption */
|
||||||
#define CONTENT_ENC_ALGO_AES 5
|
#define CONTENT_ENC_ALGO_AES 5
|
||||||
|
@ -2401,6 +2403,12 @@ 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;
|
||||||
|
|
||||||
|
if (strcmp(codec_id, TRACK_ID_AAC) == 0)
|
||||||
|
return NESTEGG_CODEC_AAC;
|
||||||
|
|
||||||
return NESTEGG_CODEC_UNKNOWN;
|
return NESTEGG_CODEC_UNKNOWN;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2421,7 +2429,8 @@ nestegg_track_codec_data_count(nestegg * ctx, unsigned int track,
|
||||||
|
|
||||||
codec_id = nestegg_track_codec_id(ctx, track);
|
codec_id = nestegg_track_codec_id(ctx, track);
|
||||||
|
|
||||||
if (codec_id == NESTEGG_CODEC_OPUS) {
|
if (codec_id == NESTEGG_CODEC_OPUS ||
|
||||||
|
codec_id == NESTEGG_CODEC_AAC) {
|
||||||
*count = 1;
|
*count = 1;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -2459,7 +2468,9 @@ 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 &&
|
||||||
|
nestegg_track_codec_id(ctx, track) != NESTEGG_CODEC_AAC)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
if (ne_get_binary(entry->codec_private, &codec_private) != 0)
|
if (ne_get_binary(entry->codec_private, &codec_private) != 0)
|
||||||
|
@ -2772,6 +2783,19 @@ nestegg_read_packet(nestegg * ctx, nestegg_packet ** pkt)
|
||||||
if (r != 1)
|
if (r != 1)
|
||||||
return r;
|
return r;
|
||||||
|
|
||||||
|
/* Some files have a crc32 element, since it also has to be first it
|
||||||
|
conflicts with the timecode spec. Just ignore it */
|
||||||
|
if (id == ID_CRC32) {
|
||||||
|
ctx->log(ctx, NESTEGG_LOG_DEBUG,
|
||||||
|
"read_packet: skipping crc element in a cluster");
|
||||||
|
r = ne_io_read_skip(ctx->io, size);
|
||||||
|
if (r != 1)
|
||||||
|
return r;
|
||||||
|
r = ne_read_element(ctx, &id, &size);
|
||||||
|
if (r != 1)
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
/* Timecode must be the first element in a Cluster, per spec. */
|
/* Timecode must be the first element in a Cluster, per spec. */
|
||||||
if (id != ID_TIMECODE)
|
if (id != ID_TIMECODE)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
Loading…
Reference in New Issue