Loading cmds/stagefright/stagefright.cpp +2 −1 Original line number Diff line number Diff line Loading @@ -650,7 +650,8 @@ static void dumpCodecProfiles(bool queryDecoders) { MEDIA_MIMETYPE_AUDIO_MPEG, MEDIA_MIMETYPE_AUDIO_G711_MLAW, MEDIA_MIMETYPE_AUDIO_G711_ALAW, MEDIA_MIMETYPE_AUDIO_VORBIS, MEDIA_MIMETYPE_VIDEO_VP8, MEDIA_MIMETYPE_VIDEO_VP9, MEDIA_MIMETYPE_VIDEO_DOLBY_VISION, MEDIA_MIMETYPE_AUDIO_AC4 MEDIA_MIMETYPE_VIDEO_DOLBY_VISION, MEDIA_MIMETYPE_AUDIO_EAC3, MEDIA_MIMETYPE_AUDIO_AC4 }; const char *codecType = queryDecoders? "decoder" : "encoder"; Loading media/extractors/mp4/MPEG4Extractor.cpp +196 −44 Original line number Diff line number Diff line Loading @@ -313,6 +313,9 @@ static const char *FourCC2MIME(uint32_t fourcc) { case FOURCC('s', 'a', 'w', 'b'): return MEDIA_MIMETYPE_AUDIO_AMR_WB; case FOURCC('e', 'c', '-', '3'): return MEDIA_MIMETYPE_AUDIO_EAC3; case FOURCC('m', 'p', '4', 'v'): return MEDIA_MIMETYPE_VIDEO_MPEG4; Loading Loading @@ -2438,13 +2441,19 @@ status_t MPEG4Extractor::parseChunk(off64_t *offset, int depth) { case FOURCC('a', 'c', '-', '3'): { *offset += chunk_size; return parseAC3SampleEntry(data_offset); return parseAC3SpecificBox(data_offset); } case FOURCC('e', 'c', '-', '3'): { *offset += chunk_size; return parseEAC3SpecificBox(data_offset); } case FOURCC('a', 'c', '-', '4'): { *offset += chunk_size; return parseAC4SampleEntry(data_offset); return parseAC4SpecificBox(data_offset); } case FOURCC('f', 't', 'y', 'p'): Loading Loading @@ -2518,43 +2527,43 @@ status_t MPEG4Extractor::parseChunk(off64_t *offset, int depth) { return OK; } status_t MPEG4Extractor::parseAC4SampleEntry(off64_t offset) { status_t MPEG4Extractor::parseChannelCountSampleRate( off64_t *offset, uint16_t *channelCount, uint16_t *sampleRate) { // skip 16 bytes: // + 6-byte reserved, // + 2-byte data reference index, // + 8-byte reserved offset += 16; uint16_t channelCount; if (!mDataSource->getUInt16(offset, &channelCount)) { ALOGE("MPEG4Extractor: error while reading ac-4 block: cannot read channel count"); *offset += 16; if (!mDataSource->getUInt16(*offset, channelCount)) { ALOGE("MPEG4Extractor: error while reading sample entry box: cannot read channel count"); return ERROR_MALFORMED; } // skip 8 bytes: // + 2-byte channelCount, // + 2-byte sample size, // + 4-byte reserved offset += 8; uint16_t sampleRate; if (!mDataSource->getUInt16(offset, &sampleRate)) { ALOGE("MPEG4Extractor: error while reading ac-4 block: cannot read sample rate"); *offset += 8; if (!mDataSource->getUInt16(*offset, sampleRate)) { ALOGE("MPEG4Extractor: error while reading sample entry box: cannot read sample rate"); return ERROR_MALFORMED; } // skip 4 bytes: // + 2-byte sampleRate, // + 2-byte reserved offset += 4; *offset += 4; return OK; } status_t MPEG4Extractor::parseAC4SpecificBox(off64_t offset) { if (mLastTrack == NULL) { return ERROR_MALFORMED; } mLastTrack->meta.setCString(kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_AC4); mLastTrack->meta.setInt32(kKeyChannelCount, channelCount); mLastTrack->meta.setInt32(kKeySampleRate, sampleRate); return parseAC4SpecificBox(offset); } status_t MPEG4Extractor::parseAC4SpecificBox(off64_t offset) { uint16_t sampleRate, channelCount; status_t status; if ((status = parseChannelCountSampleRate(&offset, &channelCount, &sampleRate)) != OK) { return status; } uint32_t size; // + 4-byte size // + 4-byte type Loading Loading @@ -2593,39 +2602,185 @@ status_t MPEG4Extractor::parseAC4SpecificBox(off64_t offset) { return ERROR_MALFORMED; } mLastTrack->meta.setCString(kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_AC4); mLastTrack->meta.setInt32(kKeyChannelCount, channelCount); mLastTrack->meta.setInt32(kKeySampleRate, sampleRate); return OK; } status_t MPEG4Extractor::parseAC3SampleEntry(off64_t offset) { // skip 16 bytes: // + 6-byte reserved, // + 2-byte data reference index, // + 8-byte reserved offset += 16; uint16_t channelCount; if (!mDataSource->getUInt16(offset, &channelCount)) { status_t MPEG4Extractor::parseEAC3SpecificBox(off64_t offset) { if (mLastTrack == NULL) { return ERROR_MALFORMED; } // skip 8 bytes: // + 2-byte channelCount, // + 2-byte sample size, // + 4-byte reserved offset += 8; uint16_t sampleRate; if (!mDataSource->getUInt16(offset, &sampleRate)) { ALOGE("MPEG4Extractor: error while reading ac-3 block: cannot read sample rate"); uint16_t sampleRate, channels; status_t status; if ((status = parseChannelCountSampleRate(&offset, &channels, &sampleRate)) != OK) { return status; } uint32_t size; // + 4-byte size // + 4-byte type // + 3-byte payload const uint32_t kEAC3SpecificBoxMinSize = 11; // 13 + 3 + (8 * (2 + 5 + 5 + 3 + 1 + 3 + 4 + (14 * 9 + 1))) bits == 152 bytes theoretical max // calculated from the required bits read below as well as the maximum number of independent // and dependant sub streams you can have const uint32_t kEAC3SpecificBoxMaxSize = 152; if (!mDataSource->getUInt32(offset, &size) || size < kEAC3SpecificBoxMinSize || size > kEAC3SpecificBoxMaxSize) { ALOGE("MPEG4Extractor: error while reading eac-3 block: cannot read specific box size"); return ERROR_MALFORMED; } // skip 4 bytes: // + 2-byte sampleRate, // + 2-byte reserved offset += 4; return parseAC3SpecificBox(offset, sampleRate); uint32_t type; if (!mDataSource->getUInt32(offset, &type) || type != FOURCC('d', 'e', 'c', '3')) { ALOGE("MPEG4Extractor: error while reading eac-3 specific block: header not dec3"); return ERROR_MALFORMED; } offset += 4; uint8_t* chunk = new (std::nothrow) uint8_t[size]; if (chunk == NULL) { return ERROR_MALFORMED; } if (mDataSource->readAt(offset, chunk, size) != (ssize_t)size) { ALOGE("MPEG4Extractor: error while reading eac-3 specific block: bitstream fields"); delete[] chunk; return ERROR_MALFORMED; } ABitReader br(chunk, size); static const unsigned channelCountTable[] = {2, 1, 2, 3, 3, 4, 4, 5}; static const unsigned sampleRateTable[] = {48000, 44100, 32000}; if (br.numBitsLeft() < 16) { delete[] chunk; return ERROR_MALFORMED; } unsigned data_rate = br.getBits(13); ALOGV("EAC3 data rate = %d", data_rate); status_t MPEG4Extractor::parseAC3SpecificBox( off64_t offset, uint16_t sampleRate) { unsigned num_ind_sub = br.getBits(3) + 1; ALOGV("EAC3 independant substreams = %d", num_ind_sub); if (br.numBitsLeft() < (num_ind_sub * 23)) { delete[] chunk; return ERROR_MALFORMED; } unsigned channelCount = 0; for (unsigned i = 0; i < num_ind_sub; i++) { unsigned fscod = br.getBits(2); if (fscod == 3) { ALOGE("Incorrect fscod (3) in EAC3 header"); delete[] chunk; return ERROR_MALFORMED; } unsigned boxSampleRate = sampleRateTable[fscod]; if (boxSampleRate != sampleRate) { ALOGE("sample rate mismatch: boxSampleRate = %d, sampleRate = %d", boxSampleRate, sampleRate); delete[] chunk; return ERROR_MALFORMED; } unsigned bsid = br.getBits(5); if (bsid < 8) { ALOGW("Incorrect bsid in EAC3 header. Possibly AC-3?"); delete[] chunk; return ERROR_MALFORMED; } // skip br.skipBits(2); unsigned bsmod = br.getBits(3); unsigned acmod = br.getBits(3); unsigned lfeon = br.getBits(1); // we currently only support the first stream if (i == 0) channelCount = channelCountTable[acmod] + lfeon; ALOGV("bsmod = %d, acmod = %d, lfeon = %d", bsmod, acmod, lfeon); br.skipBits(3); unsigned num_dep_sub = br.getBits(4); ALOGV("EAC3 dependant substreams = %d", num_dep_sub); if (num_dep_sub != 0) { if (br.numBitsLeft() < 9) { delete[] chunk; return ERROR_MALFORMED; } static const char* chan_loc_tbl[] = { "Lc/Rc","Lrs/Rrs","Cs","Ts","Lsd/Rsd", "Lw/Rw","Lvh/Rvh","Cvh","Lfe2" }; unsigned chan_loc = br.getBits(9); unsigned mask = 1; for (unsigned j = 0; j < 9; j++, mask <<= 1) { if ((chan_loc & mask) != 0) { // we currently only support the first stream if (i == 0) { channelCount++; // these are 2 channels in the mask if (j == 0 || j == 1 || j == 4 || j == 5 || j == 6) { channelCount++; } } ALOGV(" %s", chan_loc_tbl[j]); } } } else { if (br.numBitsLeft() == 0) { delete[] chunk; return ERROR_MALFORMED; } br.skipBits(1); } } if (br.numBitsLeft() != 0) { if (br.numBitsLeft() < 8) { delete[] chunk; return ERROR_MALFORMED; } unsigned mask = br.getBits(8); for (unsigned i = 0; i < 8; i++) { if (((0x1 << i) && mask) == 0) continue; if (br.numBitsLeft() < 8) { delete[] chunk; return ERROR_MALFORMED; } switch (i) { case 0: { unsigned complexity = br.getBits(8); ALOGV("Found a JOC stream with complexity = %d", complexity); }break; default: { br.skipBits(8); }break; } } } mLastTrack->meta.setCString(kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_EAC3); mLastTrack->meta.setInt32(kKeyChannelCount, channelCount); mLastTrack->meta.setInt32(kKeySampleRate, sampleRate); delete[] chunk; return OK; } status_t MPEG4Extractor::parseAC3SpecificBox(off64_t offset) { if (mLastTrack == NULL) { return ERROR_MALFORMED; } uint16_t sampleRate, channels; status_t status; if ((status = parseChannelCountSampleRate(&offset, &channels, &sampleRate)) != OK) { return status; } uint32_t size; // + 4-byte size // + 4-byte type Loading Loading @@ -2680,9 +2835,6 @@ status_t MPEG4Extractor::parseAC3SpecificBox( unsigned lfeon = br.getBits(1); unsigned channelCount = channelCountTable[acmod] + lfeon; if (mLastTrack == NULL) { return ERROR_MALFORMED; } mLastTrack->meta.setCString(kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_AC3); mLastTrack->meta.setInt32(kKeyChannelCount, channelCount); mLastTrack->meta.setInt32(kKeySampleRate, sampleRate); Loading media/extractors/mp4/MPEG4Extractor.h +4 −3 Original line number Diff line number Diff line Loading @@ -139,9 +139,10 @@ private: Track *findTrackByMimePrefix(const char *mimePrefix); status_t parseAC3SampleEntry(off64_t offset); status_t parseAC3SpecificBox(off64_t offset, uint16_t sampleRate); status_t parseAC4SampleEntry(off64_t offset); status_t parseChannelCountSampleRate( off64_t *offset, uint16_t *channelCount, uint16_t *sampleRate); status_t parseAC3SpecificBox(off64_t offset); status_t parseEAC3SpecificBox(off64_t offset); status_t parseAC4SpecificBox(off64_t offset); MPEG4Extractor(const MPEG4Extractor &); Loading media/libstagefright/Utils.cpp +1 −1 Original line number Diff line number Diff line Loading @@ -1577,6 +1577,7 @@ static const struct mime_conv_t mimeLookup[] = { { MEDIA_MIMETYPE_AUDIO_VORBIS, AUDIO_FORMAT_VORBIS }, { MEDIA_MIMETYPE_AUDIO_OPUS, AUDIO_FORMAT_OPUS}, { MEDIA_MIMETYPE_AUDIO_AC3, AUDIO_FORMAT_AC3}, { MEDIA_MIMETYPE_AUDIO_EAC3, AUDIO_FORMAT_E_AC3}, { MEDIA_MIMETYPE_AUDIO_AC4, AUDIO_FORMAT_AC4}, { MEDIA_MIMETYPE_AUDIO_FLAC, AUDIO_FORMAT_FLAC}, { 0, AUDIO_FORMAT_INVALID } Loading Loading @@ -1868,4 +1869,3 @@ AString nameForFd(int fd) { } } // namespace android media/libstagefright/mpeg2ts/ATSParser.cpp +5 −0 Original line number Diff line number Diff line Loading @@ -815,6 +815,10 @@ ATSParser::Stream::Stream( mode = ElementaryStreamQueue::AC3; break; case STREAMTYPE_EAC3: mode = ElementaryStreamQueue::EAC3; break; case STREAMTYPE_PES_PRIVATE_DATA: if (mStreamTypeExt == EXT_DESCRIPTOR_DVB_AC4) { mode = ElementaryStreamQueue::AC4; Loading Loading @@ -1026,6 +1030,7 @@ bool ATSParser::Stream::isAudio() const { case STREAMTYPE_MPEG2_AUDIO_ADTS: case STREAMTYPE_LPCM_AC3: case STREAMTYPE_AC3: case STREAMTYPE_EAC3: case STREAMTYPE_AAC_ENCRYPTED: case STREAMTYPE_AC3_ENCRYPTED: return true; Loading Loading
cmds/stagefright/stagefright.cpp +2 −1 Original line number Diff line number Diff line Loading @@ -650,7 +650,8 @@ static void dumpCodecProfiles(bool queryDecoders) { MEDIA_MIMETYPE_AUDIO_MPEG, MEDIA_MIMETYPE_AUDIO_G711_MLAW, MEDIA_MIMETYPE_AUDIO_G711_ALAW, MEDIA_MIMETYPE_AUDIO_VORBIS, MEDIA_MIMETYPE_VIDEO_VP8, MEDIA_MIMETYPE_VIDEO_VP9, MEDIA_MIMETYPE_VIDEO_DOLBY_VISION, MEDIA_MIMETYPE_AUDIO_AC4 MEDIA_MIMETYPE_VIDEO_DOLBY_VISION, MEDIA_MIMETYPE_AUDIO_EAC3, MEDIA_MIMETYPE_AUDIO_AC4 }; const char *codecType = queryDecoders? "decoder" : "encoder"; Loading
media/extractors/mp4/MPEG4Extractor.cpp +196 −44 Original line number Diff line number Diff line Loading @@ -313,6 +313,9 @@ static const char *FourCC2MIME(uint32_t fourcc) { case FOURCC('s', 'a', 'w', 'b'): return MEDIA_MIMETYPE_AUDIO_AMR_WB; case FOURCC('e', 'c', '-', '3'): return MEDIA_MIMETYPE_AUDIO_EAC3; case FOURCC('m', 'p', '4', 'v'): return MEDIA_MIMETYPE_VIDEO_MPEG4; Loading Loading @@ -2438,13 +2441,19 @@ status_t MPEG4Extractor::parseChunk(off64_t *offset, int depth) { case FOURCC('a', 'c', '-', '3'): { *offset += chunk_size; return parseAC3SampleEntry(data_offset); return parseAC3SpecificBox(data_offset); } case FOURCC('e', 'c', '-', '3'): { *offset += chunk_size; return parseEAC3SpecificBox(data_offset); } case FOURCC('a', 'c', '-', '4'): { *offset += chunk_size; return parseAC4SampleEntry(data_offset); return parseAC4SpecificBox(data_offset); } case FOURCC('f', 't', 'y', 'p'): Loading Loading @@ -2518,43 +2527,43 @@ status_t MPEG4Extractor::parseChunk(off64_t *offset, int depth) { return OK; } status_t MPEG4Extractor::parseAC4SampleEntry(off64_t offset) { status_t MPEG4Extractor::parseChannelCountSampleRate( off64_t *offset, uint16_t *channelCount, uint16_t *sampleRate) { // skip 16 bytes: // + 6-byte reserved, // + 2-byte data reference index, // + 8-byte reserved offset += 16; uint16_t channelCount; if (!mDataSource->getUInt16(offset, &channelCount)) { ALOGE("MPEG4Extractor: error while reading ac-4 block: cannot read channel count"); *offset += 16; if (!mDataSource->getUInt16(*offset, channelCount)) { ALOGE("MPEG4Extractor: error while reading sample entry box: cannot read channel count"); return ERROR_MALFORMED; } // skip 8 bytes: // + 2-byte channelCount, // + 2-byte sample size, // + 4-byte reserved offset += 8; uint16_t sampleRate; if (!mDataSource->getUInt16(offset, &sampleRate)) { ALOGE("MPEG4Extractor: error while reading ac-4 block: cannot read sample rate"); *offset += 8; if (!mDataSource->getUInt16(*offset, sampleRate)) { ALOGE("MPEG4Extractor: error while reading sample entry box: cannot read sample rate"); return ERROR_MALFORMED; } // skip 4 bytes: // + 2-byte sampleRate, // + 2-byte reserved offset += 4; *offset += 4; return OK; } status_t MPEG4Extractor::parseAC4SpecificBox(off64_t offset) { if (mLastTrack == NULL) { return ERROR_MALFORMED; } mLastTrack->meta.setCString(kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_AC4); mLastTrack->meta.setInt32(kKeyChannelCount, channelCount); mLastTrack->meta.setInt32(kKeySampleRate, sampleRate); return parseAC4SpecificBox(offset); } status_t MPEG4Extractor::parseAC4SpecificBox(off64_t offset) { uint16_t sampleRate, channelCount; status_t status; if ((status = parseChannelCountSampleRate(&offset, &channelCount, &sampleRate)) != OK) { return status; } uint32_t size; // + 4-byte size // + 4-byte type Loading Loading @@ -2593,39 +2602,185 @@ status_t MPEG4Extractor::parseAC4SpecificBox(off64_t offset) { return ERROR_MALFORMED; } mLastTrack->meta.setCString(kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_AC4); mLastTrack->meta.setInt32(kKeyChannelCount, channelCount); mLastTrack->meta.setInt32(kKeySampleRate, sampleRate); return OK; } status_t MPEG4Extractor::parseAC3SampleEntry(off64_t offset) { // skip 16 bytes: // + 6-byte reserved, // + 2-byte data reference index, // + 8-byte reserved offset += 16; uint16_t channelCount; if (!mDataSource->getUInt16(offset, &channelCount)) { status_t MPEG4Extractor::parseEAC3SpecificBox(off64_t offset) { if (mLastTrack == NULL) { return ERROR_MALFORMED; } // skip 8 bytes: // + 2-byte channelCount, // + 2-byte sample size, // + 4-byte reserved offset += 8; uint16_t sampleRate; if (!mDataSource->getUInt16(offset, &sampleRate)) { ALOGE("MPEG4Extractor: error while reading ac-3 block: cannot read sample rate"); uint16_t sampleRate, channels; status_t status; if ((status = parseChannelCountSampleRate(&offset, &channels, &sampleRate)) != OK) { return status; } uint32_t size; // + 4-byte size // + 4-byte type // + 3-byte payload const uint32_t kEAC3SpecificBoxMinSize = 11; // 13 + 3 + (8 * (2 + 5 + 5 + 3 + 1 + 3 + 4 + (14 * 9 + 1))) bits == 152 bytes theoretical max // calculated from the required bits read below as well as the maximum number of independent // and dependant sub streams you can have const uint32_t kEAC3SpecificBoxMaxSize = 152; if (!mDataSource->getUInt32(offset, &size) || size < kEAC3SpecificBoxMinSize || size > kEAC3SpecificBoxMaxSize) { ALOGE("MPEG4Extractor: error while reading eac-3 block: cannot read specific box size"); return ERROR_MALFORMED; } // skip 4 bytes: // + 2-byte sampleRate, // + 2-byte reserved offset += 4; return parseAC3SpecificBox(offset, sampleRate); uint32_t type; if (!mDataSource->getUInt32(offset, &type) || type != FOURCC('d', 'e', 'c', '3')) { ALOGE("MPEG4Extractor: error while reading eac-3 specific block: header not dec3"); return ERROR_MALFORMED; } offset += 4; uint8_t* chunk = new (std::nothrow) uint8_t[size]; if (chunk == NULL) { return ERROR_MALFORMED; } if (mDataSource->readAt(offset, chunk, size) != (ssize_t)size) { ALOGE("MPEG4Extractor: error while reading eac-3 specific block: bitstream fields"); delete[] chunk; return ERROR_MALFORMED; } ABitReader br(chunk, size); static const unsigned channelCountTable[] = {2, 1, 2, 3, 3, 4, 4, 5}; static const unsigned sampleRateTable[] = {48000, 44100, 32000}; if (br.numBitsLeft() < 16) { delete[] chunk; return ERROR_MALFORMED; } unsigned data_rate = br.getBits(13); ALOGV("EAC3 data rate = %d", data_rate); status_t MPEG4Extractor::parseAC3SpecificBox( off64_t offset, uint16_t sampleRate) { unsigned num_ind_sub = br.getBits(3) + 1; ALOGV("EAC3 independant substreams = %d", num_ind_sub); if (br.numBitsLeft() < (num_ind_sub * 23)) { delete[] chunk; return ERROR_MALFORMED; } unsigned channelCount = 0; for (unsigned i = 0; i < num_ind_sub; i++) { unsigned fscod = br.getBits(2); if (fscod == 3) { ALOGE("Incorrect fscod (3) in EAC3 header"); delete[] chunk; return ERROR_MALFORMED; } unsigned boxSampleRate = sampleRateTable[fscod]; if (boxSampleRate != sampleRate) { ALOGE("sample rate mismatch: boxSampleRate = %d, sampleRate = %d", boxSampleRate, sampleRate); delete[] chunk; return ERROR_MALFORMED; } unsigned bsid = br.getBits(5); if (bsid < 8) { ALOGW("Incorrect bsid in EAC3 header. Possibly AC-3?"); delete[] chunk; return ERROR_MALFORMED; } // skip br.skipBits(2); unsigned bsmod = br.getBits(3); unsigned acmod = br.getBits(3); unsigned lfeon = br.getBits(1); // we currently only support the first stream if (i == 0) channelCount = channelCountTable[acmod] + lfeon; ALOGV("bsmod = %d, acmod = %d, lfeon = %d", bsmod, acmod, lfeon); br.skipBits(3); unsigned num_dep_sub = br.getBits(4); ALOGV("EAC3 dependant substreams = %d", num_dep_sub); if (num_dep_sub != 0) { if (br.numBitsLeft() < 9) { delete[] chunk; return ERROR_MALFORMED; } static const char* chan_loc_tbl[] = { "Lc/Rc","Lrs/Rrs","Cs","Ts","Lsd/Rsd", "Lw/Rw","Lvh/Rvh","Cvh","Lfe2" }; unsigned chan_loc = br.getBits(9); unsigned mask = 1; for (unsigned j = 0; j < 9; j++, mask <<= 1) { if ((chan_loc & mask) != 0) { // we currently only support the first stream if (i == 0) { channelCount++; // these are 2 channels in the mask if (j == 0 || j == 1 || j == 4 || j == 5 || j == 6) { channelCount++; } } ALOGV(" %s", chan_loc_tbl[j]); } } } else { if (br.numBitsLeft() == 0) { delete[] chunk; return ERROR_MALFORMED; } br.skipBits(1); } } if (br.numBitsLeft() != 0) { if (br.numBitsLeft() < 8) { delete[] chunk; return ERROR_MALFORMED; } unsigned mask = br.getBits(8); for (unsigned i = 0; i < 8; i++) { if (((0x1 << i) && mask) == 0) continue; if (br.numBitsLeft() < 8) { delete[] chunk; return ERROR_MALFORMED; } switch (i) { case 0: { unsigned complexity = br.getBits(8); ALOGV("Found a JOC stream with complexity = %d", complexity); }break; default: { br.skipBits(8); }break; } } } mLastTrack->meta.setCString(kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_EAC3); mLastTrack->meta.setInt32(kKeyChannelCount, channelCount); mLastTrack->meta.setInt32(kKeySampleRate, sampleRate); delete[] chunk; return OK; } status_t MPEG4Extractor::parseAC3SpecificBox(off64_t offset) { if (mLastTrack == NULL) { return ERROR_MALFORMED; } uint16_t sampleRate, channels; status_t status; if ((status = parseChannelCountSampleRate(&offset, &channels, &sampleRate)) != OK) { return status; } uint32_t size; // + 4-byte size // + 4-byte type Loading Loading @@ -2680,9 +2835,6 @@ status_t MPEG4Extractor::parseAC3SpecificBox( unsigned lfeon = br.getBits(1); unsigned channelCount = channelCountTable[acmod] + lfeon; if (mLastTrack == NULL) { return ERROR_MALFORMED; } mLastTrack->meta.setCString(kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_AC3); mLastTrack->meta.setInt32(kKeyChannelCount, channelCount); mLastTrack->meta.setInt32(kKeySampleRate, sampleRate); Loading
media/extractors/mp4/MPEG4Extractor.h +4 −3 Original line number Diff line number Diff line Loading @@ -139,9 +139,10 @@ private: Track *findTrackByMimePrefix(const char *mimePrefix); status_t parseAC3SampleEntry(off64_t offset); status_t parseAC3SpecificBox(off64_t offset, uint16_t sampleRate); status_t parseAC4SampleEntry(off64_t offset); status_t parseChannelCountSampleRate( off64_t *offset, uint16_t *channelCount, uint16_t *sampleRate); status_t parseAC3SpecificBox(off64_t offset); status_t parseEAC3SpecificBox(off64_t offset); status_t parseAC4SpecificBox(off64_t offset); MPEG4Extractor(const MPEG4Extractor &); Loading
media/libstagefright/Utils.cpp +1 −1 Original line number Diff line number Diff line Loading @@ -1577,6 +1577,7 @@ static const struct mime_conv_t mimeLookup[] = { { MEDIA_MIMETYPE_AUDIO_VORBIS, AUDIO_FORMAT_VORBIS }, { MEDIA_MIMETYPE_AUDIO_OPUS, AUDIO_FORMAT_OPUS}, { MEDIA_MIMETYPE_AUDIO_AC3, AUDIO_FORMAT_AC3}, { MEDIA_MIMETYPE_AUDIO_EAC3, AUDIO_FORMAT_E_AC3}, { MEDIA_MIMETYPE_AUDIO_AC4, AUDIO_FORMAT_AC4}, { MEDIA_MIMETYPE_AUDIO_FLAC, AUDIO_FORMAT_FLAC}, { 0, AUDIO_FORMAT_INVALID } Loading Loading @@ -1868,4 +1869,3 @@ AString nameForFd(int fd) { } } // namespace android
media/libstagefright/mpeg2ts/ATSParser.cpp +5 −0 Original line number Diff line number Diff line Loading @@ -815,6 +815,10 @@ ATSParser::Stream::Stream( mode = ElementaryStreamQueue::AC3; break; case STREAMTYPE_EAC3: mode = ElementaryStreamQueue::EAC3; break; case STREAMTYPE_PES_PRIVATE_DATA: if (mStreamTypeExt == EXT_DESCRIPTOR_DVB_AC4) { mode = ElementaryStreamQueue::AC4; Loading Loading @@ -1026,6 +1030,7 @@ bool ATSParser::Stream::isAudio() const { case STREAMTYPE_MPEG2_AUDIO_ADTS: case STREAMTYPE_LPCM_AC3: case STREAMTYPE_AC3: case STREAMTYPE_EAC3: case STREAMTYPE_AAC_ENCRYPTED: case STREAMTYPE_AC3_ENCRYPTED: return true; Loading