Loading media/libstagefright/AMRExtractor.cpp +158 −22 Original line number Diff line number Diff line Loading @@ -36,7 +36,9 @@ public: AMRSource(const sp<DataSource> &source, const sp<MetaData> &meta, size_t frameSize, bool isWide); bool isWide, List<AMRFrameTableEntry> mAMRFrameTableEntries, uint64_t mTotalFrames); virtual status_t start(MetaData *params = NULL); virtual status_t stop(); Loading @@ -52,6 +54,9 @@ protected: private: sp<DataSource> mDataSource; sp<MetaData> mMeta; uint64_t mTotalFrames; List<AMRFrameTableEntry> mAMRFrameTableEntries; size_t mFrameSize; bool mIsWide; Loading @@ -65,20 +70,46 @@ private: }; //////////////////////////////////////////////////////////////////////////////// #define MAX_AMRMODE 16 static size_t getFrameSize(bool isWide, unsigned FT) { static const size_t kFrameSizeNB[8] = { 95, 103, 118, 134, 148, 159, 204, 244 //RFC 4867 static const size_t kFrameSizeNB[MAX_AMRMODE] = { 13 // AMR 4.75 Kbps , 14 // AMR 5.15 Kbps , 16 // AMR 5.90 Kbps , 18 // AMR 6.70 Kbps , 20 // AMR 7.40 Kbps , 21 // AMR 7.95 Kbps , 27 // AMR 10.2 Kbps , 32 // AMR 12.2 Kbps , 6 // GsmAmr comfort noise , 7 // Gsm-Efr comfort noise , 6 // IS-641 comfort noise , 6 // Pdc-Efr comfort noise , 1 // future use; 0 length but set to 1 to skip the frame type byte , 1 // future use; 0 length but set to 1 to skip the frame type byte , 1 // future use; 0 length but set to 1 to skip the frame type byte , 1 // AMR Frame No Data }; static const size_t kFrameSizeWB[9] = { 132, 177, 253, 285, 317, 365, 397, 461, 477 static const size_t kFrameSizeWB[MAX_AMRMODE] = { 18 // AMR-WB 6.60 Kbps , 24 // AMR-WB 8.85 Kbps , 33 // AMR-WB 12.65 Kbps , 37 // AMR-WB 14.25 Kbps , 41 // AMR-WB 15.85 Kbps , 47 // AMR-WB 18.25 Kbps , 51 // AMR-WB 19.85 Kbps , 59 // AMR-WB 23.05 Kbps , 61 // AMR-WB 23.85 Kbps , 6 // AMR-WB SID , 1 , 1 , 1 , 1 , 1 // WBAMR Frame No Data , 1 // WBAMR Frame No Data }; size_t frameSize = isWide ? kFrameSizeWB[FT] : kFrameSizeNB[FT]; // Round up bits to bytes and add 1 for the header byte. frameSize = (frameSize + 7) / 8 + 1; return frameSize; } Loading @@ -101,27 +132,101 @@ AMRExtractor::AMRExtractor(const sp<DataSource> &source) mMeta->setInt32(kKeyChannelCount, 1); mMeta->setInt32(kKeySampleRate, mIsWide ? 16000 : 8000); size_t offset = mIsWide ? 9 : 6; off_t offset = mIsWide ? 9 : 6; uint32_t mFrmNumber; //add first sample entry mIsWide ? 9 : 6; { AMRFrameTableEntry amrframetableentry(1, offset, 0); mAMRFrameTableEntries.push_back(amrframetableentry); } ssize_t n = 0; mFrmNumber = 0; mTotalFrames = 0; uint8_t header; if (mDataSource->readAt(offset, &header, 1) != 1) { n = mDataSource->readAt(offset, &header, 1); if (header & 0x83) { LOGE("padding bits must be 0, header is 0x%02x", header); return; } if(n<1){ LOGE("AMRxtractor: header incorrect"); return; } unsigned FT = (header >> 3) & 0x0f; if (FT > 8 || (!mIsWide && FT > 7)) { if (FT > MAX_AMRMODE || (!mIsWide && FT > MAX_AMRMODE)) { LOGE("UnSupported AMR FrameType(%d) ERROR",FT); return; } mFrameSize = getFrameSize(mIsWide, FT); off_t streamSize; if (mDataSource->getSize(&streamSize) == OK) { off_t numFrames = streamSize / mFrameSize; size_t framesize = mFrameSize; size_t numframes = 1; size_t framerate = FT; mFrmNumber++; offset = offset+mFrameSize; mMeta->setInt64(kKeyDuration, 20000ll * numFrames); while(n) { n = mDataSource->readAt(offset, &header, 1); if(n<1){ LOGI("EOF reached"); break; } if (header & 0x83) { LOGE("padding bits must be 0, header is 0x%02x", header); return; //ERROR_MALFORMED; } unsigned FT = (header >> 3) & 0x0f; if (FT > MAX_AMRMODE) { LOGE("UnSupported AMR FrameType(%d) ERROR",FT); return; } mFrameSize = getFrameSize(mIsWide, FT); size_t framesize1 = mFrameSize; size_t framerate1 = FT; mFrmNumber++; offset = offset+mFrameSize; if(framerate1 != framerate) { /* When framerate is different then we store the chunk back on the * list */ AMRFrameTableEntry amrframetableentry(numframes, framesize, framerate); mAMRFrameTableEntries.push_back(amrframetableentry); framesize = framesize1; framerate = framerate1; numframes = 1; } else numframes++; } { AMRFrameTableEntry amrframetableentry(numframes, framesize, framerate); mAMRFrameTableEntries.push_back(amrframetableentry); mTotalFrames = mFrmNumber; } uint32_t numFrames = mFrmNumber; int64_t duration = 20000ll * ((int64_t)numFrames+1); mMeta->setInt64(kKeyDuration, duration); mInitCheck = OK; } Loading Loading @@ -149,7 +254,7 @@ sp<MediaSource> AMRExtractor::getTrack(size_t index) { return NULL; } return new AMRSource(mDataSource, mMeta, mFrameSize, mIsWide); return new AMRSource(mDataSource, mMeta, mFrameSize, mIsWide, mAMRFrameTableEntries, mTotalFrames); } sp<MetaData> AMRExtractor::getTrackMetaData(size_t index, uint32_t flags) { Loading @@ -164,9 +269,12 @@ sp<MetaData> AMRExtractor::getTrackMetaData(size_t index, uint32_t flags) { AMRSource::AMRSource( const sp<DataSource> &source, const sp<MetaData> &meta, size_t frameSize, bool isWide) size_t frameSize, bool isWide, List<AMRFrameTableEntry> AMRFrameTableEntries, uint64_t TotalFrames) : mDataSource(source), mMeta(meta), mTotalFrames(TotalFrames), mAMRFrameTableEntries(AMRFrameTableEntries), mFrameSize(frameSize), mIsWide(isWide), mOffset(mIsWide ? 9 : 6), Loading @@ -187,6 +295,7 @@ status_t AMRSource::start(MetaData *params) { mOffset = mIsWide ? 9 : 6; mCurrentTimeUs = 0; mGroup = new MediaBufferGroup; //if crash observed during playback then the size needs to be increased mGroup->add_buffer(new MediaBuffer(128)); mStarted = true; Loading Loading @@ -214,9 +323,37 @@ status_t AMRSource::read( int64_t seekTimeUs; ReadOptions::SeekMode mode; if (options && options->getSeekTo(&seekTimeUs, &mode)) { int64_t seekFrame = seekTimeUs / 20000ll; // 20ms per frame. uint64_t seekFrame = seekTimeUs / 20000ll; // 20ms per frame. mCurrentTimeUs = seekFrame * 20000ll; mOffset = seekFrame * mFrameSize + (mIsWide ? 9 : 6); uint32_t framesize=0; uint64_t offset = 0, numframes = 0; seekFrame = seekFrame + 1; //why seekframe+1, since the array starts from zero LOGI("seekframe %lld", seekFrame); for (List<AMRFrameTableEntry>::iterator it = mAMRFrameTableEntries.begin(); it != mAMRFrameTableEntries.end(); ++it) { numframes = it->mNumFrames; framesize = it->mFrameSize; if(seekFrame >= mTotalFrames) { LOGE("seek beyond EOF"); return ERROR_OUT_OF_RANGE; } if(seekFrame > numframes) { offset = offset + (numframes * framesize); seekFrame = seekFrame - numframes; LOGV("> offset %lld seekFrame %lld numframes %lld framesize %d", offset, seekFrame, numframes, framesize); } else { offset = offset + (seekFrame * framesize); LOGV("!> offset %lld numframes %lld framesize %d", offset, numframes, framesize); break; } } mOffset = offset; } uint8_t header; Loading @@ -236,7 +373,7 @@ status_t AMRSource::read( unsigned FT = (header >> 3) & 0x0f; if (FT > 8 || (!mIsWide && FT > 7)) { if (FT > MAX_AMRMODE) { LOGE("illegal AMR frame type %d", FT); Loading @@ -244,7 +381,6 @@ status_t AMRSource::read( } size_t frameSize = getFrameSize(mIsWide, FT); CHECK_EQ(frameSize, mFrameSize); MediaBuffer *buffer; status_t err = mGroup->acquire_buffer(&buffer); Loading media/libstagefright/codecs/amrwb/AMRWBDecoder.cpp +16 −5 Original line number Diff line number Diff line Loading @@ -116,15 +116,26 @@ sp<MetaData> AMRWBDecoder::getFormat() { } static size_t getFrameSize(unsigned FT) { static const size_t kFrameSizeWB[9] = { 132, 177, 253, 285, 317, 365, 397, 461, 477 static const size_t kFrameSizeWB[16] = { 18 // AMR-WB 6.60 Kbps , 24 // AMR-WB 8.85 Kbps , 33 // AMR-WB 12.65 Kbps , 37 // AMR-WB 14.25 Kbps , 41 // AMR-WB 15.85 Kbps , 47 // AMR-WB 18.25 Kbps , 51 // AMR-WB 19.85 Kbps , 59 // AMR-WB 23.05 Kbps , 61 // AMR-WB 23.85 Kbps , 6 // AMR-WB SID , 1 , 1 , 1 , 1 , 1 // WBAMR Frame No Data , 1 // WBAMR Frame No Data }; size_t frameSize = kFrameSizeWB[FT]; // Round up bits to bytes and add 1 for the header byte. frameSize = (frameSize + 7) / 8 + 1; return frameSize; } Loading media/libstagefright/include/AMRExtractor.h +14 −2 Original line number Diff line number Diff line Loading @@ -19,11 +19,22 @@ #define AMR_EXTRACTOR_H_ #include <media/stagefright/MediaExtractor.h> #include <utils/List.h> namespace android { struct AMessage; class String8; struct AMRFrameTableEntry { AMRFrameTableEntry(uint32_t numframes, uint32_t framesize, uint32_t framerate) : mNumFrames(numframes), mFrameSize(framesize), mFrameRate(framerate) {} uint64_t mNumFrames; uint32_t mFrameSize; uint32_t mFrameRate; }; class AMRExtractor : public MediaExtractor { public: Loading @@ -44,7 +55,8 @@ private: status_t mInitCheck; size_t mFrameSize; bool mIsWide; uint64_t mTotalFrames; List<AMRFrameTableEntry> mAMRFrameTableEntries; AMRExtractor(const AMRExtractor &); AMRExtractor &operator=(const AMRExtractor &); }; Loading Loading
media/libstagefright/AMRExtractor.cpp +158 −22 Original line number Diff line number Diff line Loading @@ -36,7 +36,9 @@ public: AMRSource(const sp<DataSource> &source, const sp<MetaData> &meta, size_t frameSize, bool isWide); bool isWide, List<AMRFrameTableEntry> mAMRFrameTableEntries, uint64_t mTotalFrames); virtual status_t start(MetaData *params = NULL); virtual status_t stop(); Loading @@ -52,6 +54,9 @@ protected: private: sp<DataSource> mDataSource; sp<MetaData> mMeta; uint64_t mTotalFrames; List<AMRFrameTableEntry> mAMRFrameTableEntries; size_t mFrameSize; bool mIsWide; Loading @@ -65,20 +70,46 @@ private: }; //////////////////////////////////////////////////////////////////////////////// #define MAX_AMRMODE 16 static size_t getFrameSize(bool isWide, unsigned FT) { static const size_t kFrameSizeNB[8] = { 95, 103, 118, 134, 148, 159, 204, 244 //RFC 4867 static const size_t kFrameSizeNB[MAX_AMRMODE] = { 13 // AMR 4.75 Kbps , 14 // AMR 5.15 Kbps , 16 // AMR 5.90 Kbps , 18 // AMR 6.70 Kbps , 20 // AMR 7.40 Kbps , 21 // AMR 7.95 Kbps , 27 // AMR 10.2 Kbps , 32 // AMR 12.2 Kbps , 6 // GsmAmr comfort noise , 7 // Gsm-Efr comfort noise , 6 // IS-641 comfort noise , 6 // Pdc-Efr comfort noise , 1 // future use; 0 length but set to 1 to skip the frame type byte , 1 // future use; 0 length but set to 1 to skip the frame type byte , 1 // future use; 0 length but set to 1 to skip the frame type byte , 1 // AMR Frame No Data }; static const size_t kFrameSizeWB[9] = { 132, 177, 253, 285, 317, 365, 397, 461, 477 static const size_t kFrameSizeWB[MAX_AMRMODE] = { 18 // AMR-WB 6.60 Kbps , 24 // AMR-WB 8.85 Kbps , 33 // AMR-WB 12.65 Kbps , 37 // AMR-WB 14.25 Kbps , 41 // AMR-WB 15.85 Kbps , 47 // AMR-WB 18.25 Kbps , 51 // AMR-WB 19.85 Kbps , 59 // AMR-WB 23.05 Kbps , 61 // AMR-WB 23.85 Kbps , 6 // AMR-WB SID , 1 , 1 , 1 , 1 , 1 // WBAMR Frame No Data , 1 // WBAMR Frame No Data }; size_t frameSize = isWide ? kFrameSizeWB[FT] : kFrameSizeNB[FT]; // Round up bits to bytes and add 1 for the header byte. frameSize = (frameSize + 7) / 8 + 1; return frameSize; } Loading @@ -101,27 +132,101 @@ AMRExtractor::AMRExtractor(const sp<DataSource> &source) mMeta->setInt32(kKeyChannelCount, 1); mMeta->setInt32(kKeySampleRate, mIsWide ? 16000 : 8000); size_t offset = mIsWide ? 9 : 6; off_t offset = mIsWide ? 9 : 6; uint32_t mFrmNumber; //add first sample entry mIsWide ? 9 : 6; { AMRFrameTableEntry amrframetableentry(1, offset, 0); mAMRFrameTableEntries.push_back(amrframetableentry); } ssize_t n = 0; mFrmNumber = 0; mTotalFrames = 0; uint8_t header; if (mDataSource->readAt(offset, &header, 1) != 1) { n = mDataSource->readAt(offset, &header, 1); if (header & 0x83) { LOGE("padding bits must be 0, header is 0x%02x", header); return; } if(n<1){ LOGE("AMRxtractor: header incorrect"); return; } unsigned FT = (header >> 3) & 0x0f; if (FT > 8 || (!mIsWide && FT > 7)) { if (FT > MAX_AMRMODE || (!mIsWide && FT > MAX_AMRMODE)) { LOGE("UnSupported AMR FrameType(%d) ERROR",FT); return; } mFrameSize = getFrameSize(mIsWide, FT); off_t streamSize; if (mDataSource->getSize(&streamSize) == OK) { off_t numFrames = streamSize / mFrameSize; size_t framesize = mFrameSize; size_t numframes = 1; size_t framerate = FT; mFrmNumber++; offset = offset+mFrameSize; mMeta->setInt64(kKeyDuration, 20000ll * numFrames); while(n) { n = mDataSource->readAt(offset, &header, 1); if(n<1){ LOGI("EOF reached"); break; } if (header & 0x83) { LOGE("padding bits must be 0, header is 0x%02x", header); return; //ERROR_MALFORMED; } unsigned FT = (header >> 3) & 0x0f; if (FT > MAX_AMRMODE) { LOGE("UnSupported AMR FrameType(%d) ERROR",FT); return; } mFrameSize = getFrameSize(mIsWide, FT); size_t framesize1 = mFrameSize; size_t framerate1 = FT; mFrmNumber++; offset = offset+mFrameSize; if(framerate1 != framerate) { /* When framerate is different then we store the chunk back on the * list */ AMRFrameTableEntry amrframetableentry(numframes, framesize, framerate); mAMRFrameTableEntries.push_back(amrframetableentry); framesize = framesize1; framerate = framerate1; numframes = 1; } else numframes++; } { AMRFrameTableEntry amrframetableentry(numframes, framesize, framerate); mAMRFrameTableEntries.push_back(amrframetableentry); mTotalFrames = mFrmNumber; } uint32_t numFrames = mFrmNumber; int64_t duration = 20000ll * ((int64_t)numFrames+1); mMeta->setInt64(kKeyDuration, duration); mInitCheck = OK; } Loading Loading @@ -149,7 +254,7 @@ sp<MediaSource> AMRExtractor::getTrack(size_t index) { return NULL; } return new AMRSource(mDataSource, mMeta, mFrameSize, mIsWide); return new AMRSource(mDataSource, mMeta, mFrameSize, mIsWide, mAMRFrameTableEntries, mTotalFrames); } sp<MetaData> AMRExtractor::getTrackMetaData(size_t index, uint32_t flags) { Loading @@ -164,9 +269,12 @@ sp<MetaData> AMRExtractor::getTrackMetaData(size_t index, uint32_t flags) { AMRSource::AMRSource( const sp<DataSource> &source, const sp<MetaData> &meta, size_t frameSize, bool isWide) size_t frameSize, bool isWide, List<AMRFrameTableEntry> AMRFrameTableEntries, uint64_t TotalFrames) : mDataSource(source), mMeta(meta), mTotalFrames(TotalFrames), mAMRFrameTableEntries(AMRFrameTableEntries), mFrameSize(frameSize), mIsWide(isWide), mOffset(mIsWide ? 9 : 6), Loading @@ -187,6 +295,7 @@ status_t AMRSource::start(MetaData *params) { mOffset = mIsWide ? 9 : 6; mCurrentTimeUs = 0; mGroup = new MediaBufferGroup; //if crash observed during playback then the size needs to be increased mGroup->add_buffer(new MediaBuffer(128)); mStarted = true; Loading Loading @@ -214,9 +323,37 @@ status_t AMRSource::read( int64_t seekTimeUs; ReadOptions::SeekMode mode; if (options && options->getSeekTo(&seekTimeUs, &mode)) { int64_t seekFrame = seekTimeUs / 20000ll; // 20ms per frame. uint64_t seekFrame = seekTimeUs / 20000ll; // 20ms per frame. mCurrentTimeUs = seekFrame * 20000ll; mOffset = seekFrame * mFrameSize + (mIsWide ? 9 : 6); uint32_t framesize=0; uint64_t offset = 0, numframes = 0; seekFrame = seekFrame + 1; //why seekframe+1, since the array starts from zero LOGI("seekframe %lld", seekFrame); for (List<AMRFrameTableEntry>::iterator it = mAMRFrameTableEntries.begin(); it != mAMRFrameTableEntries.end(); ++it) { numframes = it->mNumFrames; framesize = it->mFrameSize; if(seekFrame >= mTotalFrames) { LOGE("seek beyond EOF"); return ERROR_OUT_OF_RANGE; } if(seekFrame > numframes) { offset = offset + (numframes * framesize); seekFrame = seekFrame - numframes; LOGV("> offset %lld seekFrame %lld numframes %lld framesize %d", offset, seekFrame, numframes, framesize); } else { offset = offset + (seekFrame * framesize); LOGV("!> offset %lld numframes %lld framesize %d", offset, numframes, framesize); break; } } mOffset = offset; } uint8_t header; Loading @@ -236,7 +373,7 @@ status_t AMRSource::read( unsigned FT = (header >> 3) & 0x0f; if (FT > 8 || (!mIsWide && FT > 7)) { if (FT > MAX_AMRMODE) { LOGE("illegal AMR frame type %d", FT); Loading @@ -244,7 +381,6 @@ status_t AMRSource::read( } size_t frameSize = getFrameSize(mIsWide, FT); CHECK_EQ(frameSize, mFrameSize); MediaBuffer *buffer; status_t err = mGroup->acquire_buffer(&buffer); Loading
media/libstagefright/codecs/amrwb/AMRWBDecoder.cpp +16 −5 Original line number Diff line number Diff line Loading @@ -116,15 +116,26 @@ sp<MetaData> AMRWBDecoder::getFormat() { } static size_t getFrameSize(unsigned FT) { static const size_t kFrameSizeWB[9] = { 132, 177, 253, 285, 317, 365, 397, 461, 477 static const size_t kFrameSizeWB[16] = { 18 // AMR-WB 6.60 Kbps , 24 // AMR-WB 8.85 Kbps , 33 // AMR-WB 12.65 Kbps , 37 // AMR-WB 14.25 Kbps , 41 // AMR-WB 15.85 Kbps , 47 // AMR-WB 18.25 Kbps , 51 // AMR-WB 19.85 Kbps , 59 // AMR-WB 23.05 Kbps , 61 // AMR-WB 23.85 Kbps , 6 // AMR-WB SID , 1 , 1 , 1 , 1 , 1 // WBAMR Frame No Data , 1 // WBAMR Frame No Data }; size_t frameSize = kFrameSizeWB[FT]; // Round up bits to bytes and add 1 for the header byte. frameSize = (frameSize + 7) / 8 + 1; return frameSize; } Loading
media/libstagefright/include/AMRExtractor.h +14 −2 Original line number Diff line number Diff line Loading @@ -19,11 +19,22 @@ #define AMR_EXTRACTOR_H_ #include <media/stagefright/MediaExtractor.h> #include <utils/List.h> namespace android { struct AMessage; class String8; struct AMRFrameTableEntry { AMRFrameTableEntry(uint32_t numframes, uint32_t framesize, uint32_t framerate) : mNumFrames(numframes), mFrameSize(framesize), mFrameRate(framerate) {} uint64_t mNumFrames; uint32_t mFrameSize; uint32_t mFrameRate; }; class AMRExtractor : public MediaExtractor { public: Loading @@ -44,7 +55,8 @@ private: status_t mInitCheck; size_t mFrameSize; bool mIsWide; uint64_t mTotalFrames; List<AMRFrameTableEntry> mAMRFrameTableEntries; AMRExtractor(const AMRExtractor &); AMRExtractor &operator=(const AMRExtractor &); }; Loading