Loading media/extractors/mkv/MatroskaExtractor.cpp +207 −4 Original line number Original line Diff line number Diff line Loading @@ -958,6 +958,59 @@ media_status_t MatroskaSource::read( //////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////// // trans all FOURCC to lower char static uint32_t FourCCtoLower(uint32_t fourcc) { uint8_t ch_1 = tolower((fourcc >> 24) & 0xff); uint8_t ch_2 = tolower((fourcc >> 16) & 0xff); uint8_t ch_3 = tolower((fourcc >> 8) & 0xff); uint8_t ch_4 = tolower((fourcc) & 0xff); uint32_t fourcc_out = ch_1 << 24 | ch_2 << 16 | ch_3 << 8 | ch_4; return fourcc_out; } static const char *MKVFourCC2MIME(uint32_t fourcc) { ALOGV("MKVFourCC2MIME fourcc 0x%8.8x", fourcc); uint32_t lowerFourcc = FourCCtoLower(fourcc); switch (lowerFourcc) { case FOURCC("mp4v"): return MEDIA_MIMETYPE_VIDEO_MPEG4; case FOURCC("s263"): case FOURCC("h263"): return MEDIA_MIMETYPE_VIDEO_H263; case FOURCC("avc1"): case FOURCC("h264"): return MEDIA_MIMETYPE_VIDEO_AVC; case FOURCC("mpg2"): return MEDIA_MIMETYPE_VIDEO_MPEG2; case FOURCC("xvid"): return MEDIA_MIMETYPE_VIDEO_XVID; case FOURCC("divx"): case FOURCC("dx50"): return MEDIA_MIMETYPE_VIDEO_DIVX; case FOURCC("div3"): case FOURCC("div4"): return MEDIA_MIMETYPE_VIDEO_DIVX3; case FOURCC("mjpg"): case FOURCC("mppg"): return MEDIA_MIMETYPE_VIDEO_MJPEG; default: char fourccString[5]; MakeFourCCString(fourcc, fourccString); ALOGW("mkv unsupport fourcc %s", fourccString); return ""; } } MatroskaExtractor::MatroskaExtractor(DataSourceHelper *source) MatroskaExtractor::MatroskaExtractor(DataSourceHelper *source) : mDataSource(source), : mDataSource(source), mReader(new DataSourceBaseReader(mDataSource)), mReader(new DataSourceBaseReader(mDataSource)), Loading Loading @@ -1308,6 +1361,89 @@ status_t MatroskaExtractor::synthesizeAVCC(TrackInfo *trackInfo, size_t index) { return OK; return OK; } } status_t MatroskaExtractor::synthesizeMPEG2(TrackInfo *trackInfo, size_t index) { ALOGV("synthesizeMPEG2"); BlockIterator iter(this, trackInfo->mTrackNum, index); if (iter.eos()) { return ERROR_MALFORMED; } const mkvparser::Block *block = iter.block(); if (block->GetFrameCount() <= 0) { return ERROR_MALFORMED; } const mkvparser::Block::Frame &frame = block->GetFrame(0); auto tmpData = heapbuffer<unsigned char>(frame.len); long n = frame.Read(mReader, tmpData.get()); if (n != 0) { return ERROR_MALFORMED; } size_t header_start = 0; size_t header_lenth = 0; for (header_start = 0; header_start < frame.len - 4; header_start++) { if (ntohl(0x000001b3) == *(uint32_t*)((uint8_t*)tmpData.get() + header_start)) { break; } } bool isComplete_csd = false; for (header_lenth = 0; header_lenth < frame.len - 4 - header_start; header_lenth++) { if (ntohl(0x000001b8) == *(uint32_t*)((uint8_t*)tmpData.get() + header_start + header_lenth)) { isComplete_csd = true; break; } } if (!isComplete_csd) { ALOGE("can't parse complete csd for MPEG2!"); return ERROR_MALFORMED; } addESDSFromCodecPrivate(trackInfo->mMeta, false, (uint8_t*)(tmpData.get()) + header_start, header_lenth); return OK; } status_t MatroskaExtractor::synthesizeMPEG4(TrackInfo *trackInfo, size_t index) { ALOGV("synthesizeMPEG4"); BlockIterator iter(this, trackInfo->mTrackNum, index); if (iter.eos()) { return ERROR_MALFORMED; } const mkvparser::Block *block = iter.block(); if (block->GetFrameCount() <= 0) { return ERROR_MALFORMED; } const mkvparser::Block::Frame &frame = block->GetFrame(0); auto tmpData = heapbuffer<unsigned char>(frame.len); long n = frame.Read(mReader, tmpData.get()); if (n != 0) { return ERROR_MALFORMED; } size_t vosend; bool isComplete_csd = false; for (vosend = 0; (long)vosend < frame.len - 4; vosend++) { if (ntohl(0x000001b6) == *(uint32_t*)((uint8_t*)tmpData.get() + vosend)) { isComplete_csd = true; break; // Send VOS until VOP } } if (!isComplete_csd) { ALOGE("can't parse complete csd for MPEG4!"); return ERROR_MALFORMED; } addESDSFromCodecPrivate(trackInfo->mMeta, false, tmpData.get(), vosend); return OK; } static inline bool isValidInt32ColourValue(long long value) { static inline bool isValidInt32ColourValue(long long value) { return value != mkvparser::Colour::kValueNotPresent return value != mkvparser::Colour::kValueNotPresent && value >= INT32_MIN && value >= INT32_MIN Loading Loading @@ -1490,6 +1626,8 @@ void MatroskaExtractor::addTracks() { status_t err = OK; status_t err = OK; int32_t nalSize = -1; int32_t nalSize = -1; bool isSetCsdFrom1stFrame = false; switch (track->GetType()) { switch (track->GetType()) { case VIDEO_TRACK: case VIDEO_TRACK: { { Loading @@ -1516,15 +1654,15 @@ void MatroskaExtractor::addTracks() { continue; continue; } } } else if (!strcmp("V_MPEG4/ISO/ASP", codecID)) { } else if (!strcmp("V_MPEG4/ISO/ASP", codecID)) { if (codecPrivateSize > 0) { AMediaFormat_setString(meta, AMediaFormat_setString(meta, AMEDIAFORMAT_KEY_MIME, MEDIA_MIMETYPE_VIDEO_MPEG4); AMEDIAFORMAT_KEY_MIME, MEDIA_MIMETYPE_VIDEO_MPEG4); if (codecPrivateSize > 0) { addESDSFromCodecPrivate( addESDSFromCodecPrivate( meta, false, codecPrivate, codecPrivateSize); meta, false, codecPrivate, codecPrivateSize); } else { } else { ALOGW("%s is detected, but does not have configuration.", ALOGW("%s is detected, but does not have configuration.", codecID); codecID); continue; isSetCsdFrom1stFrame = true; } } } else if (!strcmp("V_VP8", codecID)) { } else if (!strcmp("V_VP8", codecID)) { AMediaFormat_setString(meta, AMEDIAFORMAT_KEY_MIME, MEDIA_MIMETYPE_VIDEO_VP8); AMediaFormat_setString(meta, AMEDIAFORMAT_KEY_MIME, MEDIA_MIMETYPE_VIDEO_VP8); Loading @@ -1538,6 +1676,49 @@ void MatroskaExtractor::addTracks() { } } } else if (!strcmp("V_AV1", codecID)) { } else if (!strcmp("V_AV1", codecID)) { AMediaFormat_setString(meta, AMEDIAFORMAT_KEY_MIME, MEDIA_MIMETYPE_VIDEO_AV1); AMediaFormat_setString(meta, AMEDIAFORMAT_KEY_MIME, MEDIA_MIMETYPE_VIDEO_AV1); } else if (!strcmp("V_MPEG2", codecID) || !strcmp("V_MPEG1", codecID)) { AMediaFormat_setString(meta, AMEDIAFORMAT_KEY_MIME, MEDIA_MIMETYPE_VIDEO_MPEG2); if (codecPrivate != NULL) { addESDSFromCodecPrivate(meta, false, codecPrivate, codecPrivateSize); } else { ALOGW("No specific codec private data, find it from the first frame"); isSetCsdFrom1stFrame = true; } } else if (!strcmp("V_MJPEG", codecID)) { AMediaFormat_setString(meta, AMEDIAFORMAT_KEY_MIME, MEDIA_MIMETYPE_VIDEO_MJPEG); } else if (!strcmp("V_MS/VFW/FOURCC", codecID)) { if (NULL == codecPrivate ||codecPrivateSize < 20) { ALOGE("V_MS/VFW/FOURCC has no valid private data(%p),codecPrivateSize:%zu", codecPrivate, codecPrivateSize); continue; } else { uint32_t fourcc = *(uint32_t *)(codecPrivate + 16); fourcc = ntohl(fourcc); const char* mime = MKVFourCC2MIME(fourcc); ALOGV("V_MS/VFW/FOURCC type is %s", mime); if (!strncasecmp("video/", mime, 6)) { AMediaFormat_setString(meta, AMEDIAFORMAT_KEY_MIME, mime); } else { ALOGE("V_MS/VFW/FOURCC continue,unsupport video type=%s,fourcc=0x%08x.", mime, fourcc); continue; } if (!strcmp(mime, MEDIA_MIMETYPE_VIDEO_AVC) || !strcmp(mime, MEDIA_MIMETYPE_VIDEO_MPEG4) || !strcmp(mime, MEDIA_MIMETYPE_VIDEO_XVID) || !strcmp(mime, MEDIA_MIMETYPE_VIDEO_DIVX) || !strcmp(mime, MEDIA_MIMETYPE_VIDEO_DIVX3) || !strcmp(mime, MEDIA_MIMETYPE_VIDEO_MPEG2) || !strcmp(mime, MEDIA_MIMETYPE_VIDEO_H263)) { isSetCsdFrom1stFrame = true; } else { ALOGW("FourCC have unsupport codec, type=%s,fourcc=0x%08x.", mime, fourcc); continue; } } } else { } else { ALOGW("%s is not supported.", codecID); ALOGW("%s is not supported.", codecID); continue; continue; Loading Loading @@ -1681,13 +1862,35 @@ void MatroskaExtractor::addTracks() { initTrackInfo(track, meta, trackInfo); initTrackInfo(track, meta, trackInfo); trackInfo->mNalLengthSize = nalSize; trackInfo->mNalLengthSize = nalSize; if (!strcmp("V_MPEG4/ISO/AVC", codecID) && codecPrivateSize == 0) { const char *mimetype = ""; AMediaFormat_getString(meta, AMEDIAFORMAT_KEY_MIME, &mimetype); if ((!strcmp("V_MPEG4/ISO/AVC", codecID) && codecPrivateSize == 0) || (!strcmp(mimetype, MEDIA_MIMETYPE_VIDEO_AVC) && isSetCsdFrom1stFrame)) { // Attempt to recover from AVC track without codec private data // Attempt to recover from AVC track without codec private data err = synthesizeAVCC(trackInfo, n); err = synthesizeAVCC(trackInfo, n); if (err != OK) { if (err != OK) { mTracks.pop(); mTracks.pop(); } } } else if ((!strcmp("V_MPEG2", codecID) && codecPrivateSize == 0) || (!strcmp(mimetype, MEDIA_MIMETYPE_VIDEO_MPEG2) && isSetCsdFrom1stFrame)) { // Attempt to recover from MPEG2 track without codec private data err = synthesizeMPEG2(trackInfo, n); if (err != OK) { mTracks.pop(); } } } else if ((!strcmp("V_MPEG4/ISO/ASP", codecID) && codecPrivateSize == 0) || (!strcmp(mimetype, MEDIA_MIMETYPE_VIDEO_MPEG4) && isSetCsdFrom1stFrame) || (!strcmp(mimetype, MEDIA_MIMETYPE_VIDEO_XVID) && isSetCsdFrom1stFrame) || (!strcmp(mimetype, MEDIA_MIMETYPE_VIDEO_DIVX) && isSetCsdFrom1stFrame) || (!strcmp(mimetype, MEDIA_MIMETYPE_VIDEO_DIVX3) && isSetCsdFrom1stFrame)) { // Attempt to recover from MPEG4 track without codec private data err = synthesizeMPEG4(trackInfo, n); if (err != OK) { mTracks.pop(); } } } } } } Loading media/extractors/mkv/MatroskaExtractor.h +2 −0 Original line number Original line Diff line number Diff line Loading @@ -95,6 +95,8 @@ private: int64_t mSeekPreRollNs; int64_t mSeekPreRollNs; status_t synthesizeAVCC(TrackInfo *trackInfo, size_t index); status_t synthesizeAVCC(TrackInfo *trackInfo, size_t index); status_t synthesizeMPEG2(TrackInfo *trackInfo, size_t index); status_t synthesizeMPEG4(TrackInfo *trackInfo, size_t index); status_t initTrackInfo( status_t initTrackInfo( const mkvparser::Track *track, const mkvparser::Track *track, AMediaFormat *meta, AMediaFormat *meta, Loading media/libstagefright/foundation/MediaDefs.cpp +4 −0 Original line number Original line Diff line number Diff line Loading @@ -32,6 +32,10 @@ const char *MEDIA_MIMETYPE_VIDEO_MPEG2 = "video/mpeg2"; const char *MEDIA_MIMETYPE_VIDEO_RAW = "video/raw"; const char *MEDIA_MIMETYPE_VIDEO_RAW = "video/raw"; const char *MEDIA_MIMETYPE_VIDEO_DOLBY_VISION = "video/dolby-vision"; const char *MEDIA_MIMETYPE_VIDEO_DOLBY_VISION = "video/dolby-vision"; const char *MEDIA_MIMETYPE_VIDEO_SCRAMBLED = "video/scrambled"; const char *MEDIA_MIMETYPE_VIDEO_SCRAMBLED = "video/scrambled"; const char *MEDIA_MIMETYPE_VIDEO_DIVX = "video/divx"; const char *MEDIA_MIMETYPE_VIDEO_DIVX3 = "video/divx3"; const char *MEDIA_MIMETYPE_VIDEO_XVID = "video/xvid"; const char *MEDIA_MIMETYPE_VIDEO_MJPEG = "video/x-motion-jpeg"; const char *MEDIA_MIMETYPE_AUDIO_AMR_NB = "audio/3gpp"; const char *MEDIA_MIMETYPE_AUDIO_AMR_NB = "audio/3gpp"; const char *MEDIA_MIMETYPE_AUDIO_AMR_WB = "audio/amr-wb"; const char *MEDIA_MIMETYPE_AUDIO_AMR_WB = "audio/amr-wb"; Loading media/libstagefright/foundation/include/media/stagefright/foundation/MediaDefs.h +4 −0 Original line number Original line Diff line number Diff line Loading @@ -34,6 +34,10 @@ extern const char *MEDIA_MIMETYPE_VIDEO_MPEG2; extern const char *MEDIA_MIMETYPE_VIDEO_RAW; extern const char *MEDIA_MIMETYPE_VIDEO_RAW; extern const char *MEDIA_MIMETYPE_VIDEO_DOLBY_VISION; extern const char *MEDIA_MIMETYPE_VIDEO_DOLBY_VISION; extern const char *MEDIA_MIMETYPE_VIDEO_SCRAMBLED; extern const char *MEDIA_MIMETYPE_VIDEO_SCRAMBLED; extern const char *MEDIA_MIMETYPE_VIDEO_DIVX; extern const char *MEDIA_MIMETYPE_VIDEO_DIVX3; extern const char *MEDIA_MIMETYPE_VIDEO_XVID; extern const char *MEDIA_MIMETYPE_VIDEO_MJPEG; extern const char *MEDIA_MIMETYPE_AUDIO_AMR_NB; extern const char *MEDIA_MIMETYPE_AUDIO_AMR_NB; extern const char *MEDIA_MIMETYPE_AUDIO_AMR_WB; extern const char *MEDIA_MIMETYPE_AUDIO_AMR_WB; Loading Loading
media/extractors/mkv/MatroskaExtractor.cpp +207 −4 Original line number Original line Diff line number Diff line Loading @@ -958,6 +958,59 @@ media_status_t MatroskaSource::read( //////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////// // trans all FOURCC to lower char static uint32_t FourCCtoLower(uint32_t fourcc) { uint8_t ch_1 = tolower((fourcc >> 24) & 0xff); uint8_t ch_2 = tolower((fourcc >> 16) & 0xff); uint8_t ch_3 = tolower((fourcc >> 8) & 0xff); uint8_t ch_4 = tolower((fourcc) & 0xff); uint32_t fourcc_out = ch_1 << 24 | ch_2 << 16 | ch_3 << 8 | ch_4; return fourcc_out; } static const char *MKVFourCC2MIME(uint32_t fourcc) { ALOGV("MKVFourCC2MIME fourcc 0x%8.8x", fourcc); uint32_t lowerFourcc = FourCCtoLower(fourcc); switch (lowerFourcc) { case FOURCC("mp4v"): return MEDIA_MIMETYPE_VIDEO_MPEG4; case FOURCC("s263"): case FOURCC("h263"): return MEDIA_MIMETYPE_VIDEO_H263; case FOURCC("avc1"): case FOURCC("h264"): return MEDIA_MIMETYPE_VIDEO_AVC; case FOURCC("mpg2"): return MEDIA_MIMETYPE_VIDEO_MPEG2; case FOURCC("xvid"): return MEDIA_MIMETYPE_VIDEO_XVID; case FOURCC("divx"): case FOURCC("dx50"): return MEDIA_MIMETYPE_VIDEO_DIVX; case FOURCC("div3"): case FOURCC("div4"): return MEDIA_MIMETYPE_VIDEO_DIVX3; case FOURCC("mjpg"): case FOURCC("mppg"): return MEDIA_MIMETYPE_VIDEO_MJPEG; default: char fourccString[5]; MakeFourCCString(fourcc, fourccString); ALOGW("mkv unsupport fourcc %s", fourccString); return ""; } } MatroskaExtractor::MatroskaExtractor(DataSourceHelper *source) MatroskaExtractor::MatroskaExtractor(DataSourceHelper *source) : mDataSource(source), : mDataSource(source), mReader(new DataSourceBaseReader(mDataSource)), mReader(new DataSourceBaseReader(mDataSource)), Loading Loading @@ -1308,6 +1361,89 @@ status_t MatroskaExtractor::synthesizeAVCC(TrackInfo *trackInfo, size_t index) { return OK; return OK; } } status_t MatroskaExtractor::synthesizeMPEG2(TrackInfo *trackInfo, size_t index) { ALOGV("synthesizeMPEG2"); BlockIterator iter(this, trackInfo->mTrackNum, index); if (iter.eos()) { return ERROR_MALFORMED; } const mkvparser::Block *block = iter.block(); if (block->GetFrameCount() <= 0) { return ERROR_MALFORMED; } const mkvparser::Block::Frame &frame = block->GetFrame(0); auto tmpData = heapbuffer<unsigned char>(frame.len); long n = frame.Read(mReader, tmpData.get()); if (n != 0) { return ERROR_MALFORMED; } size_t header_start = 0; size_t header_lenth = 0; for (header_start = 0; header_start < frame.len - 4; header_start++) { if (ntohl(0x000001b3) == *(uint32_t*)((uint8_t*)tmpData.get() + header_start)) { break; } } bool isComplete_csd = false; for (header_lenth = 0; header_lenth < frame.len - 4 - header_start; header_lenth++) { if (ntohl(0x000001b8) == *(uint32_t*)((uint8_t*)tmpData.get() + header_start + header_lenth)) { isComplete_csd = true; break; } } if (!isComplete_csd) { ALOGE("can't parse complete csd for MPEG2!"); return ERROR_MALFORMED; } addESDSFromCodecPrivate(trackInfo->mMeta, false, (uint8_t*)(tmpData.get()) + header_start, header_lenth); return OK; } status_t MatroskaExtractor::synthesizeMPEG4(TrackInfo *trackInfo, size_t index) { ALOGV("synthesizeMPEG4"); BlockIterator iter(this, trackInfo->mTrackNum, index); if (iter.eos()) { return ERROR_MALFORMED; } const mkvparser::Block *block = iter.block(); if (block->GetFrameCount() <= 0) { return ERROR_MALFORMED; } const mkvparser::Block::Frame &frame = block->GetFrame(0); auto tmpData = heapbuffer<unsigned char>(frame.len); long n = frame.Read(mReader, tmpData.get()); if (n != 0) { return ERROR_MALFORMED; } size_t vosend; bool isComplete_csd = false; for (vosend = 0; (long)vosend < frame.len - 4; vosend++) { if (ntohl(0x000001b6) == *(uint32_t*)((uint8_t*)tmpData.get() + vosend)) { isComplete_csd = true; break; // Send VOS until VOP } } if (!isComplete_csd) { ALOGE("can't parse complete csd for MPEG4!"); return ERROR_MALFORMED; } addESDSFromCodecPrivate(trackInfo->mMeta, false, tmpData.get(), vosend); return OK; } static inline bool isValidInt32ColourValue(long long value) { static inline bool isValidInt32ColourValue(long long value) { return value != mkvparser::Colour::kValueNotPresent return value != mkvparser::Colour::kValueNotPresent && value >= INT32_MIN && value >= INT32_MIN Loading Loading @@ -1490,6 +1626,8 @@ void MatroskaExtractor::addTracks() { status_t err = OK; status_t err = OK; int32_t nalSize = -1; int32_t nalSize = -1; bool isSetCsdFrom1stFrame = false; switch (track->GetType()) { switch (track->GetType()) { case VIDEO_TRACK: case VIDEO_TRACK: { { Loading @@ -1516,15 +1654,15 @@ void MatroskaExtractor::addTracks() { continue; continue; } } } else if (!strcmp("V_MPEG4/ISO/ASP", codecID)) { } else if (!strcmp("V_MPEG4/ISO/ASP", codecID)) { if (codecPrivateSize > 0) { AMediaFormat_setString(meta, AMediaFormat_setString(meta, AMEDIAFORMAT_KEY_MIME, MEDIA_MIMETYPE_VIDEO_MPEG4); AMEDIAFORMAT_KEY_MIME, MEDIA_MIMETYPE_VIDEO_MPEG4); if (codecPrivateSize > 0) { addESDSFromCodecPrivate( addESDSFromCodecPrivate( meta, false, codecPrivate, codecPrivateSize); meta, false, codecPrivate, codecPrivateSize); } else { } else { ALOGW("%s is detected, but does not have configuration.", ALOGW("%s is detected, but does not have configuration.", codecID); codecID); continue; isSetCsdFrom1stFrame = true; } } } else if (!strcmp("V_VP8", codecID)) { } else if (!strcmp("V_VP8", codecID)) { AMediaFormat_setString(meta, AMEDIAFORMAT_KEY_MIME, MEDIA_MIMETYPE_VIDEO_VP8); AMediaFormat_setString(meta, AMEDIAFORMAT_KEY_MIME, MEDIA_MIMETYPE_VIDEO_VP8); Loading @@ -1538,6 +1676,49 @@ void MatroskaExtractor::addTracks() { } } } else if (!strcmp("V_AV1", codecID)) { } else if (!strcmp("V_AV1", codecID)) { AMediaFormat_setString(meta, AMEDIAFORMAT_KEY_MIME, MEDIA_MIMETYPE_VIDEO_AV1); AMediaFormat_setString(meta, AMEDIAFORMAT_KEY_MIME, MEDIA_MIMETYPE_VIDEO_AV1); } else if (!strcmp("V_MPEG2", codecID) || !strcmp("V_MPEG1", codecID)) { AMediaFormat_setString(meta, AMEDIAFORMAT_KEY_MIME, MEDIA_MIMETYPE_VIDEO_MPEG2); if (codecPrivate != NULL) { addESDSFromCodecPrivate(meta, false, codecPrivate, codecPrivateSize); } else { ALOGW("No specific codec private data, find it from the first frame"); isSetCsdFrom1stFrame = true; } } else if (!strcmp("V_MJPEG", codecID)) { AMediaFormat_setString(meta, AMEDIAFORMAT_KEY_MIME, MEDIA_MIMETYPE_VIDEO_MJPEG); } else if (!strcmp("V_MS/VFW/FOURCC", codecID)) { if (NULL == codecPrivate ||codecPrivateSize < 20) { ALOGE("V_MS/VFW/FOURCC has no valid private data(%p),codecPrivateSize:%zu", codecPrivate, codecPrivateSize); continue; } else { uint32_t fourcc = *(uint32_t *)(codecPrivate + 16); fourcc = ntohl(fourcc); const char* mime = MKVFourCC2MIME(fourcc); ALOGV("V_MS/VFW/FOURCC type is %s", mime); if (!strncasecmp("video/", mime, 6)) { AMediaFormat_setString(meta, AMEDIAFORMAT_KEY_MIME, mime); } else { ALOGE("V_MS/VFW/FOURCC continue,unsupport video type=%s,fourcc=0x%08x.", mime, fourcc); continue; } if (!strcmp(mime, MEDIA_MIMETYPE_VIDEO_AVC) || !strcmp(mime, MEDIA_MIMETYPE_VIDEO_MPEG4) || !strcmp(mime, MEDIA_MIMETYPE_VIDEO_XVID) || !strcmp(mime, MEDIA_MIMETYPE_VIDEO_DIVX) || !strcmp(mime, MEDIA_MIMETYPE_VIDEO_DIVX3) || !strcmp(mime, MEDIA_MIMETYPE_VIDEO_MPEG2) || !strcmp(mime, MEDIA_MIMETYPE_VIDEO_H263)) { isSetCsdFrom1stFrame = true; } else { ALOGW("FourCC have unsupport codec, type=%s,fourcc=0x%08x.", mime, fourcc); continue; } } } else { } else { ALOGW("%s is not supported.", codecID); ALOGW("%s is not supported.", codecID); continue; continue; Loading Loading @@ -1681,13 +1862,35 @@ void MatroskaExtractor::addTracks() { initTrackInfo(track, meta, trackInfo); initTrackInfo(track, meta, trackInfo); trackInfo->mNalLengthSize = nalSize; trackInfo->mNalLengthSize = nalSize; if (!strcmp("V_MPEG4/ISO/AVC", codecID) && codecPrivateSize == 0) { const char *mimetype = ""; AMediaFormat_getString(meta, AMEDIAFORMAT_KEY_MIME, &mimetype); if ((!strcmp("V_MPEG4/ISO/AVC", codecID) && codecPrivateSize == 0) || (!strcmp(mimetype, MEDIA_MIMETYPE_VIDEO_AVC) && isSetCsdFrom1stFrame)) { // Attempt to recover from AVC track without codec private data // Attempt to recover from AVC track without codec private data err = synthesizeAVCC(trackInfo, n); err = synthesizeAVCC(trackInfo, n); if (err != OK) { if (err != OK) { mTracks.pop(); mTracks.pop(); } } } else if ((!strcmp("V_MPEG2", codecID) && codecPrivateSize == 0) || (!strcmp(mimetype, MEDIA_MIMETYPE_VIDEO_MPEG2) && isSetCsdFrom1stFrame)) { // Attempt to recover from MPEG2 track without codec private data err = synthesizeMPEG2(trackInfo, n); if (err != OK) { mTracks.pop(); } } } else if ((!strcmp("V_MPEG4/ISO/ASP", codecID) && codecPrivateSize == 0) || (!strcmp(mimetype, MEDIA_MIMETYPE_VIDEO_MPEG4) && isSetCsdFrom1stFrame) || (!strcmp(mimetype, MEDIA_MIMETYPE_VIDEO_XVID) && isSetCsdFrom1stFrame) || (!strcmp(mimetype, MEDIA_MIMETYPE_VIDEO_DIVX) && isSetCsdFrom1stFrame) || (!strcmp(mimetype, MEDIA_MIMETYPE_VIDEO_DIVX3) && isSetCsdFrom1stFrame)) { // Attempt to recover from MPEG4 track without codec private data err = synthesizeMPEG4(trackInfo, n); if (err != OK) { mTracks.pop(); } } } } } } Loading
media/extractors/mkv/MatroskaExtractor.h +2 −0 Original line number Original line Diff line number Diff line Loading @@ -95,6 +95,8 @@ private: int64_t mSeekPreRollNs; int64_t mSeekPreRollNs; status_t synthesizeAVCC(TrackInfo *trackInfo, size_t index); status_t synthesizeAVCC(TrackInfo *trackInfo, size_t index); status_t synthesizeMPEG2(TrackInfo *trackInfo, size_t index); status_t synthesizeMPEG4(TrackInfo *trackInfo, size_t index); status_t initTrackInfo( status_t initTrackInfo( const mkvparser::Track *track, const mkvparser::Track *track, AMediaFormat *meta, AMediaFormat *meta, Loading
media/libstagefright/foundation/MediaDefs.cpp +4 −0 Original line number Original line Diff line number Diff line Loading @@ -32,6 +32,10 @@ const char *MEDIA_MIMETYPE_VIDEO_MPEG2 = "video/mpeg2"; const char *MEDIA_MIMETYPE_VIDEO_RAW = "video/raw"; const char *MEDIA_MIMETYPE_VIDEO_RAW = "video/raw"; const char *MEDIA_MIMETYPE_VIDEO_DOLBY_VISION = "video/dolby-vision"; const char *MEDIA_MIMETYPE_VIDEO_DOLBY_VISION = "video/dolby-vision"; const char *MEDIA_MIMETYPE_VIDEO_SCRAMBLED = "video/scrambled"; const char *MEDIA_MIMETYPE_VIDEO_SCRAMBLED = "video/scrambled"; const char *MEDIA_MIMETYPE_VIDEO_DIVX = "video/divx"; const char *MEDIA_MIMETYPE_VIDEO_DIVX3 = "video/divx3"; const char *MEDIA_MIMETYPE_VIDEO_XVID = "video/xvid"; const char *MEDIA_MIMETYPE_VIDEO_MJPEG = "video/x-motion-jpeg"; const char *MEDIA_MIMETYPE_AUDIO_AMR_NB = "audio/3gpp"; const char *MEDIA_MIMETYPE_AUDIO_AMR_NB = "audio/3gpp"; const char *MEDIA_MIMETYPE_AUDIO_AMR_WB = "audio/amr-wb"; const char *MEDIA_MIMETYPE_AUDIO_AMR_WB = "audio/amr-wb"; Loading
media/libstagefright/foundation/include/media/stagefright/foundation/MediaDefs.h +4 −0 Original line number Original line Diff line number Diff line Loading @@ -34,6 +34,10 @@ extern const char *MEDIA_MIMETYPE_VIDEO_MPEG2; extern const char *MEDIA_MIMETYPE_VIDEO_RAW; extern const char *MEDIA_MIMETYPE_VIDEO_RAW; extern const char *MEDIA_MIMETYPE_VIDEO_DOLBY_VISION; extern const char *MEDIA_MIMETYPE_VIDEO_DOLBY_VISION; extern const char *MEDIA_MIMETYPE_VIDEO_SCRAMBLED; extern const char *MEDIA_MIMETYPE_VIDEO_SCRAMBLED; extern const char *MEDIA_MIMETYPE_VIDEO_DIVX; extern const char *MEDIA_MIMETYPE_VIDEO_DIVX3; extern const char *MEDIA_MIMETYPE_VIDEO_XVID; extern const char *MEDIA_MIMETYPE_VIDEO_MJPEG; extern const char *MEDIA_MIMETYPE_AUDIO_AMR_NB; extern const char *MEDIA_MIMETYPE_AUDIO_AMR_NB; extern const char *MEDIA_MIMETYPE_AUDIO_AMR_WB; extern const char *MEDIA_MIMETYPE_AUDIO_AMR_WB; Loading