Loading include/media/stagefright/MetaData.h +2 −0 Original line number Diff line number Diff line Loading @@ -53,6 +53,7 @@ enum { kKeyESDS = 'esds', // raw data kKeyAACProfile = 'aacp', // int32_t kKeyAVCC = 'avcc', // raw data kKeyHVCC = 'hvcc', // raw data kKeyD263 = 'd263', // raw data kKeyVorbisInfo = 'vinf', // raw data kKeyVorbisBooks = 'vboo', // raw data Loading Loading @@ -170,6 +171,7 @@ enum { enum { kTypeESDS = 'esds', kTypeAVCC = 'avcc', kTypeHVCC = 'hvcc', kTypeD263 = 'd263', }; Loading include/media/stagefright/OMXCodec.h +3 −0 Original line number Diff line number Diff line Loading @@ -352,6 +352,9 @@ private: int64_t getDecodingTimeUs(); status_t parseHEVCCodecSpecificData( const void *data, size_t size, unsigned *profile, unsigned *level); status_t parseAVCCodecSpecificData( const void *data, size_t size, unsigned *profile, unsigned *level); Loading media/libstagefright/MPEG4Extractor.cpp +46 −4 Original line number Diff line number Diff line Loading @@ -95,6 +95,7 @@ private: uint64_t* mCurrentSampleInfoOffsets; bool mIsAVC; bool mIsHEVC; size_t mNALLengthSize; bool mStarted; Loading Loading @@ -317,6 +318,9 @@ static const char *FourCC2MIME(uint32_t fourcc) { case FOURCC('a', 'v', 'c', '1'): return MEDIA_MIMETYPE_VIDEO_AVC; case FOURCC('h', 'v', 'c', '1'): case FOURCC('h', 'e', 'v', '1'): return MEDIA_MIMETYPE_VIDEO_HEVC; default: CHECK(!"should not be here."); return NULL; Loading Loading @@ -1288,6 +1292,8 @@ status_t MPEG4Extractor::parseChunk(off64_t *offset, int depth) { case FOURCC('H', '2', '6', '3'): case FOURCC('h', '2', '6', '3'): case FOURCC('a', 'v', 'c', '1'): case FOURCC('h', 'v', 'c', '1'): case FOURCC('h', 'e', 'v', '1'): { mHasVideo = true; Loading Loading @@ -1580,6 +1586,21 @@ status_t MPEG4Extractor::parseChunk(off64_t *offset, int depth) { break; } case FOURCC('h', 'v', 'c', 'C'): { sp<ABuffer> buffer = new ABuffer(chunk_data_size); if (mDataSource->readAt( data_offset, buffer->data(), chunk_data_size) < chunk_data_size) { return ERROR_IO; } mLastTrack->meta->setData( kKeyHVCC, kTypeHVCC, buffer->data(), chunk_data_size); *offset += chunk_size; break; } case FOURCC('d', '2', '6', '3'): { Loading Loading @@ -2452,6 +2473,11 @@ status_t MPEG4Extractor::verifyTrack(Track *track) { || type != kTypeAVCC) { return ERROR_MALFORMED; } } else if (!strcasecmp(mime, MEDIA_MIMETYPE_VIDEO_HEVC)) { if (!track->meta->findData(kKeyHVCC, &type, &data, &size) || type != kTypeHVCC) { return ERROR_MALFORMED; } } else if (!strcasecmp(mime, MEDIA_MIMETYPE_VIDEO_MPEG4) || !strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AAC)) { if (!track->meta->findData(kKeyESDS, &type, &data, &size) Loading Loading @@ -2776,6 +2802,7 @@ MPEG4Source::MPEG4Source( mCurrentSampleInfoOffsetsAllocSize(0), mCurrentSampleInfoOffsets(NULL), mIsAVC(false), mIsHEVC(false), mNALLengthSize(0), mStarted(false), mGroup(NULL), Loading @@ -2800,6 +2827,7 @@ MPEG4Source::MPEG4Source( CHECK(success); mIsAVC = !strcasecmp(mime, MEDIA_MIMETYPE_VIDEO_AVC); mIsHEVC = !strcasecmp(mime, MEDIA_MIMETYPE_VIDEO_HEVC); if (mIsAVC) { uint32_t type; Loading @@ -2814,6 +2842,18 @@ MPEG4Source::MPEG4Source( // The number of bytes used to encode the length of a NAL unit. mNALLengthSize = 1 + (ptr[4] & 3); } else if (mIsHEVC) { uint32_t type; const void *data; size_t size; CHECK(format->findData(kKeyHVCC, &type, &data, &size)); const uint8_t *ptr = (const uint8_t *)data; CHECK(size >= 7); CHECK_EQ((unsigned)ptr[0], 1u); // configurationVersion == 1 mNALLengthSize = 1 + (ptr[14 + 7] & 3); } CHECK(format->findInt32(kKeyTrackID, &mTrackId)); Loading Loading @@ -3562,7 +3602,7 @@ status_t MPEG4Source::read( } } if (!mIsAVC || mWantsNALFragments) { if ((!mIsAVC && !mIsHEVC) || mWantsNALFragments) { if (newBuffer) { ssize_t num_bytes_read = mDataSource->readAt(offset, (uint8_t *)mBuffer->data(), size); Loading Loading @@ -3594,7 +3634,7 @@ status_t MPEG4Source::read( ++mCurrentSampleIndex; } if (!mIsAVC) { if (!mIsAVC && !mIsHEVC) { *out = mBuffer; mBuffer = NULL; Loading Loading @@ -3837,7 +3877,7 @@ status_t MPEG4Source::fragmentedRead( bufmeta->setData(kKeyCryptoKey, 0, mCryptoKey, 16); } if (!mIsAVC || mWantsNALFragments) { if ((!mIsAVC && !mIsHEVC)|| mWantsNALFragments) { if (newBuffer) { ssize_t num_bytes_read = mDataSource->readAt(offset, (uint8_t *)mBuffer->data(), size); Loading Loading @@ -3869,7 +3909,7 @@ status_t MPEG4Source::fragmentedRead( ++mCurrentSampleIndex; } if (!mIsAVC) { if (!mIsAVC && !mIsHEVC) { *out = mBuffer; mBuffer = NULL; Loading Loading @@ -4043,6 +4083,8 @@ static bool isCompatibleBrand(uint32_t fourcc) { FOURCC('i', 's', 'o', 'm'), FOURCC('i', 's', 'o', '2'), FOURCC('a', 'v', 'c', '1'), FOURCC('h', 'v', 'c', '1'), FOURCC('h', 'e', 'v', '1'), FOURCC('3', 'g', 'p', '4'), FOURCC('m', 'p', '4', '1'), FOURCC('m', 'p', '4', '2'), Loading media/libstagefright/OMXCodec.cpp +73 −1 Original line number Diff line number Diff line Loading @@ -381,6 +381,57 @@ sp<MediaSource> OMXCodec::Create( return NULL; } status_t OMXCodec::parseHEVCCodecSpecificData( const void *data, size_t size, unsigned *profile, unsigned *level) { const uint8_t *ptr = (const uint8_t *)data; // verify minimum size and configurationVersion == 1. if (size < 7 || ptr[0] != 1) { return ERROR_MALFORMED; } *profile = (ptr[1] & 31); *level = ptr[12]; ptr += 22; size -= 22; size_t numofArrays = (char)ptr[0]; ptr += 1; size -= 1; size_t j = 0, i = 0; for (i = 0; i < numofArrays; i++) { ptr += 1; size -= 1; // Num of nals size_t numofNals = U16_AT(ptr); ptr += 2; size -= 2; for (j = 0;j < numofNals;j++) { if (size < 2) { return ERROR_MALFORMED; } size_t length = U16_AT(ptr); ptr += 2; size -= 2; if (size < length) { return ERROR_MALFORMED; } addCodecSpecificData(ptr, length); ptr += length; size -= length; } } return OK; } status_t OMXCodec::parseAVCCodecSpecificData( const void *data, size_t size, unsigned *profile, unsigned *level) { Loading Loading @@ -493,6 +544,20 @@ status_t OMXCodec::configureCodec(const sp<MetaData> &meta) { CODEC_LOGI( "AVC profile = %u (%s), level = %u", profile, AVCProfileToString(profile), level); } else if (meta->findData(kKeyHVCC, &type, &data, &size)) { // Parse the HEVCDecoderConfigurationRecord unsigned profile, level; status_t err; if ((err = parseHEVCCodecSpecificData( data, size, &profile, &level)) != OK) { ALOGE("Malformed HEVC codec specific data."); return err; } CODEC_LOGI( "HEVC profile = %u , level = %u", profile, level); } else if (meta->findData(kKeyVorbisInfo, &type, &data, &size)) { addCodecSpecificData(data, size); Loading Loading @@ -822,6 +887,8 @@ void OMXCodec::setVideoInputFormat( OMX_VIDEO_CODINGTYPE compressionFormat = OMX_VIDEO_CodingUnused; if (!strcasecmp(MEDIA_MIMETYPE_VIDEO_AVC, mime)) { compressionFormat = OMX_VIDEO_CodingAVC; } else if (!strcasecmp(MEDIA_MIMETYPE_VIDEO_HEVC, mime)) { compressionFormat = OMX_VIDEO_CodingHEVC; } else if (!strcasecmp(MEDIA_MIMETYPE_VIDEO_MPEG4, mime)) { compressionFormat = OMX_VIDEO_CodingMPEG4; } else if (!strcasecmp(MEDIA_MIMETYPE_VIDEO_H263, mime)) { Loading Loading @@ -1217,6 +1284,8 @@ status_t OMXCodec::setVideoOutputFormat( compressionFormat = OMX_VIDEO_CodingAVC; } else if (!strcasecmp(MEDIA_MIMETYPE_VIDEO_MPEG4, mime)) { compressionFormat = OMX_VIDEO_CodingMPEG4; } else if (!strcasecmp(MEDIA_MIMETYPE_VIDEO_HEVC, mime)) { compressionFormat = OMX_VIDEO_CodingHEVC; } else if (!strcasecmp(MEDIA_MIMETYPE_VIDEO_H263, mime)) { compressionFormat = OMX_VIDEO_CodingH263; } else if (!strcasecmp(MEDIA_MIMETYPE_VIDEO_VP8, mime)) { Loading Loading @@ -1411,6 +1480,8 @@ void OMXCodec::setComponentRole( "audio_decoder.g711alaw", "audio_encoder.g711alaw" }, { MEDIA_MIMETYPE_VIDEO_AVC, "video_decoder.avc", "video_encoder.avc" }, { MEDIA_MIMETYPE_VIDEO_HEVC, "video_decoder.hevc", "video_encoder.hevc" }, { MEDIA_MIMETYPE_VIDEO_MPEG4, "video_decoder.mpeg4", "video_encoder.mpeg4" }, { MEDIA_MIMETYPE_VIDEO_H263, Loading Loading @@ -3009,7 +3080,8 @@ bool OMXCodec::drainInputBuffer(BufferInfo *info) { size_t size = specific->mSize; if (!strcasecmp(MEDIA_MIMETYPE_VIDEO_AVC, mMIME) if ((!strcasecmp(MEDIA_MIMETYPE_VIDEO_AVC, mMIME) || !strcasecmp(MEDIA_MIMETYPE_VIDEO_HEVC, mMIME)) && !(mQuirks & kWantsNALFragments)) { static const uint8_t kNALStartCode[4] = { 0x00, 0x00, 0x00, 0x01 }; Loading media/libstagefright/Utils.cpp +50 −0 Original line number Diff line number Diff line Loading @@ -217,6 +217,56 @@ status_t convertMetaDataToMessage( buffer->meta()->setInt32("csd", true); buffer->meta()->setInt64("timeUs", 0); msg->setBuffer("csd-1", buffer); } else if (meta->findData(kKeyHVCC, &type, &data, &size)) { const uint8_t *ptr = (const uint8_t *)data; CHECK(size >= 7); CHECK_EQ((unsigned)ptr[0], 1u); // configurationVersion == 1 uint8_t profile = ptr[1] & 31; uint8_t level = ptr[12]; ptr += 22; size -= 22; size_t numofArrays = (char)ptr[0]; ptr += 1; size -= 1; size_t j = 0, i = 0; sp<ABuffer> buffer = new ABuffer(1024); buffer->setRange(0, 0); for (i = 0; i < numofArrays; i++) { ptr += 1; size -= 1; //Num of nals size_t numofNals = U16_AT(ptr); ptr += 2; size -= 2; for (j = 0; j < numofNals; j++) { CHECK(size >= 2); size_t length = U16_AT(ptr); ptr += 2; size -= 2; CHECK(size >= length); memcpy(buffer->data() + buffer->size(), "\x00\x00\x00\x01", 4); memcpy(buffer->data() + buffer->size() + 4, ptr, length); buffer->setRange(0, buffer->size() + 4 + length); ptr += length; size -= length; } } buffer->meta()->setInt32("csd", true); buffer->meta()->setInt64("timeUs", 0); msg->setBuffer("csd-0", buffer); } else if (meta->findData(kKeyESDS, &type, &data, &size)) { ESDS esds((const char *)data, size); CHECK_EQ(esds.InitCheck(), (status_t)OK); Loading Loading
include/media/stagefright/MetaData.h +2 −0 Original line number Diff line number Diff line Loading @@ -53,6 +53,7 @@ enum { kKeyESDS = 'esds', // raw data kKeyAACProfile = 'aacp', // int32_t kKeyAVCC = 'avcc', // raw data kKeyHVCC = 'hvcc', // raw data kKeyD263 = 'd263', // raw data kKeyVorbisInfo = 'vinf', // raw data kKeyVorbisBooks = 'vboo', // raw data Loading Loading @@ -170,6 +171,7 @@ enum { enum { kTypeESDS = 'esds', kTypeAVCC = 'avcc', kTypeHVCC = 'hvcc', kTypeD263 = 'd263', }; Loading
include/media/stagefright/OMXCodec.h +3 −0 Original line number Diff line number Diff line Loading @@ -352,6 +352,9 @@ private: int64_t getDecodingTimeUs(); status_t parseHEVCCodecSpecificData( const void *data, size_t size, unsigned *profile, unsigned *level); status_t parseAVCCodecSpecificData( const void *data, size_t size, unsigned *profile, unsigned *level); Loading
media/libstagefright/MPEG4Extractor.cpp +46 −4 Original line number Diff line number Diff line Loading @@ -95,6 +95,7 @@ private: uint64_t* mCurrentSampleInfoOffsets; bool mIsAVC; bool mIsHEVC; size_t mNALLengthSize; bool mStarted; Loading Loading @@ -317,6 +318,9 @@ static const char *FourCC2MIME(uint32_t fourcc) { case FOURCC('a', 'v', 'c', '1'): return MEDIA_MIMETYPE_VIDEO_AVC; case FOURCC('h', 'v', 'c', '1'): case FOURCC('h', 'e', 'v', '1'): return MEDIA_MIMETYPE_VIDEO_HEVC; default: CHECK(!"should not be here."); return NULL; Loading Loading @@ -1288,6 +1292,8 @@ status_t MPEG4Extractor::parseChunk(off64_t *offset, int depth) { case FOURCC('H', '2', '6', '3'): case FOURCC('h', '2', '6', '3'): case FOURCC('a', 'v', 'c', '1'): case FOURCC('h', 'v', 'c', '1'): case FOURCC('h', 'e', 'v', '1'): { mHasVideo = true; Loading Loading @@ -1580,6 +1586,21 @@ status_t MPEG4Extractor::parseChunk(off64_t *offset, int depth) { break; } case FOURCC('h', 'v', 'c', 'C'): { sp<ABuffer> buffer = new ABuffer(chunk_data_size); if (mDataSource->readAt( data_offset, buffer->data(), chunk_data_size) < chunk_data_size) { return ERROR_IO; } mLastTrack->meta->setData( kKeyHVCC, kTypeHVCC, buffer->data(), chunk_data_size); *offset += chunk_size; break; } case FOURCC('d', '2', '6', '3'): { Loading Loading @@ -2452,6 +2473,11 @@ status_t MPEG4Extractor::verifyTrack(Track *track) { || type != kTypeAVCC) { return ERROR_MALFORMED; } } else if (!strcasecmp(mime, MEDIA_MIMETYPE_VIDEO_HEVC)) { if (!track->meta->findData(kKeyHVCC, &type, &data, &size) || type != kTypeHVCC) { return ERROR_MALFORMED; } } else if (!strcasecmp(mime, MEDIA_MIMETYPE_VIDEO_MPEG4) || !strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AAC)) { if (!track->meta->findData(kKeyESDS, &type, &data, &size) Loading Loading @@ -2776,6 +2802,7 @@ MPEG4Source::MPEG4Source( mCurrentSampleInfoOffsetsAllocSize(0), mCurrentSampleInfoOffsets(NULL), mIsAVC(false), mIsHEVC(false), mNALLengthSize(0), mStarted(false), mGroup(NULL), Loading @@ -2800,6 +2827,7 @@ MPEG4Source::MPEG4Source( CHECK(success); mIsAVC = !strcasecmp(mime, MEDIA_MIMETYPE_VIDEO_AVC); mIsHEVC = !strcasecmp(mime, MEDIA_MIMETYPE_VIDEO_HEVC); if (mIsAVC) { uint32_t type; Loading @@ -2814,6 +2842,18 @@ MPEG4Source::MPEG4Source( // The number of bytes used to encode the length of a NAL unit. mNALLengthSize = 1 + (ptr[4] & 3); } else if (mIsHEVC) { uint32_t type; const void *data; size_t size; CHECK(format->findData(kKeyHVCC, &type, &data, &size)); const uint8_t *ptr = (const uint8_t *)data; CHECK(size >= 7); CHECK_EQ((unsigned)ptr[0], 1u); // configurationVersion == 1 mNALLengthSize = 1 + (ptr[14 + 7] & 3); } CHECK(format->findInt32(kKeyTrackID, &mTrackId)); Loading Loading @@ -3562,7 +3602,7 @@ status_t MPEG4Source::read( } } if (!mIsAVC || mWantsNALFragments) { if ((!mIsAVC && !mIsHEVC) || mWantsNALFragments) { if (newBuffer) { ssize_t num_bytes_read = mDataSource->readAt(offset, (uint8_t *)mBuffer->data(), size); Loading Loading @@ -3594,7 +3634,7 @@ status_t MPEG4Source::read( ++mCurrentSampleIndex; } if (!mIsAVC) { if (!mIsAVC && !mIsHEVC) { *out = mBuffer; mBuffer = NULL; Loading Loading @@ -3837,7 +3877,7 @@ status_t MPEG4Source::fragmentedRead( bufmeta->setData(kKeyCryptoKey, 0, mCryptoKey, 16); } if (!mIsAVC || mWantsNALFragments) { if ((!mIsAVC && !mIsHEVC)|| mWantsNALFragments) { if (newBuffer) { ssize_t num_bytes_read = mDataSource->readAt(offset, (uint8_t *)mBuffer->data(), size); Loading Loading @@ -3869,7 +3909,7 @@ status_t MPEG4Source::fragmentedRead( ++mCurrentSampleIndex; } if (!mIsAVC) { if (!mIsAVC && !mIsHEVC) { *out = mBuffer; mBuffer = NULL; Loading Loading @@ -4043,6 +4083,8 @@ static bool isCompatibleBrand(uint32_t fourcc) { FOURCC('i', 's', 'o', 'm'), FOURCC('i', 's', 'o', '2'), FOURCC('a', 'v', 'c', '1'), FOURCC('h', 'v', 'c', '1'), FOURCC('h', 'e', 'v', '1'), FOURCC('3', 'g', 'p', '4'), FOURCC('m', 'p', '4', '1'), FOURCC('m', 'p', '4', '2'), Loading
media/libstagefright/OMXCodec.cpp +73 −1 Original line number Diff line number Diff line Loading @@ -381,6 +381,57 @@ sp<MediaSource> OMXCodec::Create( return NULL; } status_t OMXCodec::parseHEVCCodecSpecificData( const void *data, size_t size, unsigned *profile, unsigned *level) { const uint8_t *ptr = (const uint8_t *)data; // verify minimum size and configurationVersion == 1. if (size < 7 || ptr[0] != 1) { return ERROR_MALFORMED; } *profile = (ptr[1] & 31); *level = ptr[12]; ptr += 22; size -= 22; size_t numofArrays = (char)ptr[0]; ptr += 1; size -= 1; size_t j = 0, i = 0; for (i = 0; i < numofArrays; i++) { ptr += 1; size -= 1; // Num of nals size_t numofNals = U16_AT(ptr); ptr += 2; size -= 2; for (j = 0;j < numofNals;j++) { if (size < 2) { return ERROR_MALFORMED; } size_t length = U16_AT(ptr); ptr += 2; size -= 2; if (size < length) { return ERROR_MALFORMED; } addCodecSpecificData(ptr, length); ptr += length; size -= length; } } return OK; } status_t OMXCodec::parseAVCCodecSpecificData( const void *data, size_t size, unsigned *profile, unsigned *level) { Loading Loading @@ -493,6 +544,20 @@ status_t OMXCodec::configureCodec(const sp<MetaData> &meta) { CODEC_LOGI( "AVC profile = %u (%s), level = %u", profile, AVCProfileToString(profile), level); } else if (meta->findData(kKeyHVCC, &type, &data, &size)) { // Parse the HEVCDecoderConfigurationRecord unsigned profile, level; status_t err; if ((err = parseHEVCCodecSpecificData( data, size, &profile, &level)) != OK) { ALOGE("Malformed HEVC codec specific data."); return err; } CODEC_LOGI( "HEVC profile = %u , level = %u", profile, level); } else if (meta->findData(kKeyVorbisInfo, &type, &data, &size)) { addCodecSpecificData(data, size); Loading Loading @@ -822,6 +887,8 @@ void OMXCodec::setVideoInputFormat( OMX_VIDEO_CODINGTYPE compressionFormat = OMX_VIDEO_CodingUnused; if (!strcasecmp(MEDIA_MIMETYPE_VIDEO_AVC, mime)) { compressionFormat = OMX_VIDEO_CodingAVC; } else if (!strcasecmp(MEDIA_MIMETYPE_VIDEO_HEVC, mime)) { compressionFormat = OMX_VIDEO_CodingHEVC; } else if (!strcasecmp(MEDIA_MIMETYPE_VIDEO_MPEG4, mime)) { compressionFormat = OMX_VIDEO_CodingMPEG4; } else if (!strcasecmp(MEDIA_MIMETYPE_VIDEO_H263, mime)) { Loading Loading @@ -1217,6 +1284,8 @@ status_t OMXCodec::setVideoOutputFormat( compressionFormat = OMX_VIDEO_CodingAVC; } else if (!strcasecmp(MEDIA_MIMETYPE_VIDEO_MPEG4, mime)) { compressionFormat = OMX_VIDEO_CodingMPEG4; } else if (!strcasecmp(MEDIA_MIMETYPE_VIDEO_HEVC, mime)) { compressionFormat = OMX_VIDEO_CodingHEVC; } else if (!strcasecmp(MEDIA_MIMETYPE_VIDEO_H263, mime)) { compressionFormat = OMX_VIDEO_CodingH263; } else if (!strcasecmp(MEDIA_MIMETYPE_VIDEO_VP8, mime)) { Loading Loading @@ -1411,6 +1480,8 @@ void OMXCodec::setComponentRole( "audio_decoder.g711alaw", "audio_encoder.g711alaw" }, { MEDIA_MIMETYPE_VIDEO_AVC, "video_decoder.avc", "video_encoder.avc" }, { MEDIA_MIMETYPE_VIDEO_HEVC, "video_decoder.hevc", "video_encoder.hevc" }, { MEDIA_MIMETYPE_VIDEO_MPEG4, "video_decoder.mpeg4", "video_encoder.mpeg4" }, { MEDIA_MIMETYPE_VIDEO_H263, Loading Loading @@ -3009,7 +3080,8 @@ bool OMXCodec::drainInputBuffer(BufferInfo *info) { size_t size = specific->mSize; if (!strcasecmp(MEDIA_MIMETYPE_VIDEO_AVC, mMIME) if ((!strcasecmp(MEDIA_MIMETYPE_VIDEO_AVC, mMIME) || !strcasecmp(MEDIA_MIMETYPE_VIDEO_HEVC, mMIME)) && !(mQuirks & kWantsNALFragments)) { static const uint8_t kNALStartCode[4] = { 0x00, 0x00, 0x00, 0x01 }; Loading
media/libstagefright/Utils.cpp +50 −0 Original line number Diff line number Diff line Loading @@ -217,6 +217,56 @@ status_t convertMetaDataToMessage( buffer->meta()->setInt32("csd", true); buffer->meta()->setInt64("timeUs", 0); msg->setBuffer("csd-1", buffer); } else if (meta->findData(kKeyHVCC, &type, &data, &size)) { const uint8_t *ptr = (const uint8_t *)data; CHECK(size >= 7); CHECK_EQ((unsigned)ptr[0], 1u); // configurationVersion == 1 uint8_t profile = ptr[1] & 31; uint8_t level = ptr[12]; ptr += 22; size -= 22; size_t numofArrays = (char)ptr[0]; ptr += 1; size -= 1; size_t j = 0, i = 0; sp<ABuffer> buffer = new ABuffer(1024); buffer->setRange(0, 0); for (i = 0; i < numofArrays; i++) { ptr += 1; size -= 1; //Num of nals size_t numofNals = U16_AT(ptr); ptr += 2; size -= 2; for (j = 0; j < numofNals; j++) { CHECK(size >= 2); size_t length = U16_AT(ptr); ptr += 2; size -= 2; CHECK(size >= length); memcpy(buffer->data() + buffer->size(), "\x00\x00\x00\x01", 4); memcpy(buffer->data() + buffer->size() + 4, ptr, length); buffer->setRange(0, buffer->size() + 4 + length); ptr += length; size -= length; } } buffer->meta()->setInt32("csd", true); buffer->meta()->setInt64("timeUs", 0); msg->setBuffer("csd-0", buffer); } else if (meta->findData(kKeyESDS, &type, &data, &size)) { ESDS esds((const char *)data, size); CHECK_EQ(esds.InitCheck(), (status_t)OK); Loading