AMRExtractor::AMRExtractor(const sp<DataSource> &source) : mDataSource(source), mInitCheck(NO_INIT), mOffsetTableLength(0) { String8 mimeType; float confidence; if (!SniffAMR(mDataSource, &mimeType, &confidence, NULL)) { return; } mIsWide = (mimeType == MEDIA_MIMETYPE_AUDIO_AMR_WB); mMeta = new MetaData; mMeta->setCString( kKeyMIMEType, mIsWide ? MEDIA_MIMETYPE_AUDIO_AMR_WB : MEDIA_MIMETYPE_AUDIO_AMR_NB); mMeta->setInt32(kKeyChannelCount, 1); mMeta->setInt32(kKeySampleRate, mIsWide ? 16000 : 8000); off64_t offset = mIsWide ? 9 : 6; off64_t streamSize; size_t frameSize, numFrames = 0; int64_t duration = 0; if (mDataSource->getSize(&streamSize) == OK) { while (offset < streamSize) { status_t status = getFrameSizeByOffset(source, offset, mIsWide, &frameSize); if (status == ERROR_END_OF_STREAM) { break; } else if (status != OK) { return; } if ((numFrames % 50 == 0) && (numFrames / 50 < OFFSET_TABLE_LEN)) { CHECK_EQ(mOffsetTableLength, numFrames / 50); mOffsetTable[mOffsetTableLength] = offset - (mIsWide ? 9: 6); mOffsetTableLength ++; } offset += frameSize; duration += 20000; // Each frame is 20ms numFrames ++; } mMeta->setInt64(kKeyDuration, duration); } mInitCheck = OK; }
MediaExtractor::ExtractorDef GETEXTRACTORDEF() { return { MediaExtractor::EXTRACTORDEF_VERSION, UUID("c86639c9-2f31-40ac-a715-fa01b4493aaf"), 1, "AMR Extractor", []( DataSourceBase *source, float *confidence, void **, MediaExtractor::FreeMetaFunc *) -> MediaExtractor::CreatorFunc { if (SniffAMR(source, nullptr, confidence)) { return []( DataSourceBase *source, void *) -> MediaExtractor* { return new AMRExtractor(source);}; } return NULL; } }; }
AMRExtractor::AMRExtractor(const sp<DataSource> &source) : mDataSource(source), mInitCheck(NO_INIT), mOffsetTableLength(0) { String8 mimeType; float confidence; if (!SniffAMR(mDataSource, &mimeType, &confidence, NULL)) { return; } mIsWide = (mimeType == MEDIA_MIMETYPE_AUDIO_AMR_WB); mMeta = new MetaData; mMeta->setCString( kKeyMIMEType, mIsWide ? MEDIA_MIMETYPE_AUDIO_AMR_WB : MEDIA_MIMETYPE_AUDIO_AMR_NB); mMeta->setInt32(kKeyChannelCount, 1); mMeta->setInt32(kKeySampleRate, mIsWide ? 16000 : 8000); off64_t offset = mIsWide ? 9 : 6; off64_t streamSize; size_t frameSize, numFrames = 0; int64_t duration = 0; #ifdef MTK_AOSP_ENHANCEMENT status_t ret = 0; bool streamingFlag = mDataSource->flags() & DataSource::kIsCachingDataSource; char *pData = new char [Buffer_Count_Readed]; ssize_t dataLen = 0; size_t dataOffset = 0; SXLOGD("AMRExtractor--is streaming flag=%d, pData:0x%x", streamingFlag, pData); #endif if (mDataSource->getSize(&streamSize) == OK) { while (offset < streamSize) { #ifdef MTK_AOSP_ENHANCEMENT if (pData) { if (dataLen==0) { dataLen = mDataSource->readAt(offset, (void *)pData, Buffer_Count_Readed); if (dataLen < 0) { return; } dataOffset = 0; } ret = getFrameSizeByOffset_MMIO((uint8_t *)pData, dataLen, dataOffset, offset, mIsWide, &frameSize); if (ret==NO_MEMORY) { dataLen = 0; continue; } }else { ret = getFrameSizeByOffset(source, offset, mIsWide, &frameSize); } if (ret==ERROR_END_OF_STREAM) { break; }else if(ret!=OK) { if (pData) delete [] pData; pData = 0; SXLOGD("AMRExtractor--getFrameSizeByOffset is not ok!"); return; } #else if (getFrameSizeByOffset(source, offset, mIsWide, &frameSize) != OK) { return; } #endif if ((numFrames % 50 == 0) && (numFrames / 50 < OFFSET_TABLE_LEN)) { CHECK_EQ(mOffsetTableLength, numFrames / 50); mOffsetTable[mOffsetTableLength] = offset - (mIsWide ? 9: 6); mOffsetTableLength ++; } #ifdef MTK_AOSP_ENHANCEMENT else if(streamingFlag&&(numFrames>=50*OFFSET_TABLE_LEN)) { duration += 20000*(streamSize - offset)/((offset - (mIsWide ? 9: 6))/(off64_t)numFrames); SXLOGV("AMRExtractor--end duration=%lld, frame size = %lld", duration, (offset - (mIsWide ? 9: 6))/(off64_t)numFrames); break; } #endif offset += frameSize; duration += 20000; // Each frame is 20ms numFrames ++; } mMeta->setInt64(kKeyDuration, duration); } #ifdef MTK_AOSP_ENHANCEMENT if (pData) delete [] pData; pData = 0; SXLOGD("AMRExtractor--constructor out -"); #endif mInitCheck = OK; }