HeadSetDetect::~HeadSetDetect() { SXLOGV("+deconstruct"); stop(); requestExitAndWait(); SXLOGV("-deconstruct"); }
int32_t AudioVUnlockDL:: DoSRC(uint8_t *inbuf, uint32_t *datasz , uint8_t *outbuf, uint32_t *outlength) { uint8_t *inPtr = inbuf ; uint8_t *outPtr = outbuf; uint32_t outbuflen = *outlength; uint32_t dataProduce = 0; uint32_t count = 40; uint32_t dataconsumed = 0; pthread_mutex_lock(&mSRCMutex); if (mpSrcHdl == NULL) { SXLOGD("[DoSRC] SRC not created"); pthread_mutex_unlock(&mSRCMutex); return -1; } while (count) { SXLOGV("count %d ,in offset %d, datasz %d, out offset %d, outlength %d ", count,inPtr - inbuf, *datasz,outPtr - outbuf, *outlength); int consumed_this_time = *datasz; mpSrcHdl->Process((int16_t *)inPtr, datasz, (int16_t *)outPtr, outlength); consumed_this_time -= *datasz; dataconsumed += consumed_this_time; SXLOGV("after count %d , datasz %d, outlength%d ", count, *datasz,*outlength); dataProduce += *outlength; if (*datasz == 0 || *outlength == 0) { break; } else { inPtr = inbuf + dataconsumed; outPtr = outbuf + dataProduce; } // left space in output buffer *outlength = outbuflen - dataProduce; if (*outlength == 0) { break; } count --; } pthread_mutex_unlock(&mSRCMutex); /*if(count == 0 && *datasz !=0 && *outlength != 0) { SXLOGD("[DoSRC] do not finish SRC *datasz %d, &outlength %d", *datasz,*outlength ); //return -1; }*/ *outlength = dataProduce; return dataconsumed; }
bool HeadSetDetect::headsetConnect(int stateVal) { if(WIRE_HEADSET==stateVal){ SXLOGV("detect headset pluged in"); return true; }else if(BIT_HEADSET_NO_MIC==stateVal) { SXLOGV("detect headphone pluged in"); return true; }else{ SXLOGV("default headset pluged out"); return false; } }
status_t AudioTrackCenter::reset_flush(intptr_t trackId) { Mutex::Autolock autoLock(mLock); SXLOGV("%s, trackId:%p",__FUNCTION__, (void*)trackId); ssize_t index = mTrackList.indexOfKey(trackId); if (index < 0) { return UNKNOWN_ERROR; } struct TrackInfo &info = mTrackList.editValueFor(trackId); info.server = 0; info.middleServer = 0; info.ts = ALooper::GetNowUs(); info.framePlayed = 0; #ifdef AUDIO_TRACK_CENTER_DEBUG mSysTimeUs = 0; mRealTimeUs = 0; mDeltaUs = 0; #endif return OK; }
void HeadSetDetect::stop() { SXLOGV("HeadSetDetect::stop"); Mutex::Autolock _l(mLock); mActive = false; requestExit(); }
status_t MyVorbisExtractor::findNextPage( off64_t startOffset, off64_t *pageOffset) { *pageOffset = startOffset; #ifdef MTK_AOSP_ENHANCEMENT //optimize find page process char signature[2048]; for (;;) { ssize_t n = mSource->readAt(*pageOffset, &signature, 2000); if (n < 4) { *pageOffset = 0; return (n < 0) ? n : (status_t)ERROR_END_OF_STREAM; } int i = 0; int step = n-4; while(i<=step) { if (!memcmp(&signature[i], "OggS", 4)) { if ((*pageOffset + i) > startOffset) { SXLOGV("skipped %lld bytes of junk to reach next frame", (*pageOffset + i) - startOffset); } *pageOffset += i; return OK; } i++; } *pageOffset += n; } #else for (;;) { char signature[4]; ssize_t n = mSource->readAt(*pageOffset, &signature, 4); if (n < 4) { *pageOffset = 0; return (n < 0) ? n : (status_t)ERROR_END_OF_STREAM; } if (!memcmp(signature, "OggS", 4)) { if (*pageOffset > startOffset) { ALOGV("skipped %lld bytes of junk to reach next frame", *pageOffset - startOffset); } return OK; } ++*pageOffset; } #endif }
intptr_t AudioTrackCenter::getTrackId(void* trackPtr, void* sinkPtr) { Mutex::Autolock autoLock(mLock); #if defined(CONFIG_MT_ENG_BUILD) SXLOGV("%s, trackPtr:%p, sinkPtr:%p",__FUNCTION__, trackPtr, sinkPtr); #endif List<TrackMaps>::iterator it = mTrackMaps.begin(); while (it != mTrackMaps.end()) { if ((trackPtr && it->trackPtr == trackPtr) || (sinkPtr && it->sinkPtr == sinkPtr)) { SXLOGV("%s, return trackId:%p",__FUNCTION__, (void*)it->trackId); return it->trackId; } ++it; } #if defined(CONFIG_MT_ENG_BUILD) SXLOGV("%s, no valid trackId!!",__FUNCTION__); #endif return 0; }
status_t AudioTrackCenter::getRealTimePosition(intptr_t trackId, int64_t *position) { Mutex::Autolock autoLock(mLock); #if defined(CONFIG_MT_ENG_BUILD) SXLOGV("%s, trackId:%p",__FUNCTION__, (void*)trackId); #endif ssize_t index = mTrackList.indexOfKey(trackId); if (index < 0) { return UNKNOWN_ERROR; } const struct TrackInfo info = mTrackList.valueFor(trackId); int64_t delayUs = ALooper::GetNowUs() - info.ts; delayUs = delayUs/mTimeScaled; *position = info.framePlayed; if (!info.framePlayed) { SXLOGV("trackId = %p, server = %d, framePlayed = %lld", (void*)trackId, info.server, info.framePlayed); return OK; } if (info.server) { uint32_t deltaFrames = (uint32_t)((delayUs*info.sampleRate)/1000000); if (deltaFrames > info.frameCount) { deltaFrames = info.frameCount; } if (!info.active) { SXLOGV("%s, trackId = %p, track is not active , set deltaFrames to 0",__FUNCTION__, (void*)trackId); deltaFrames = 0; } *position += deltaFrames; } #ifdef AUDIO_TRACK_CENTER_DEBUG SXLOGD("trackId = %p, realTimeUs and sysTimeUs distance: %8.3f", (void*)trackId, countDeltaUs(((int64_t)(*position)*1000000)/info.sampleRate)); #endif #if defined(CONFIG_MT_ENG_BUILD) SXLOGV("trackId = %p, server = %d, framePlayed = %lld, delayUs = %lld, *position:%lld", (void*)trackId, info.server, info.framePlayed, delayUs, *position); #endif return OK; }
status_t DcRemove::close() { Mutex::Autolock _l(&mLock); SXLOGV("DcRemove::deinit"); if (mHandle) { DCR_Close(mHandle); free(mHandle); mHandle = NULL; } return NO_ERROR; }
status_t AudioTrackCenter::updateServer(intptr_t trackId, uint32_t server, bool restore) { Mutex::Autolock autoLock(mLock); #if defined(CONFIG_MT_ENG_BUILD) SXLOGV("%s, trackId:%p, server:%d",__FUNCTION__, (void*)trackId, server); #endif ssize_t index = mTrackList.indexOfKey(trackId); if (index < 0) { return UNKNOWN_ERROR; } struct TrackInfo &info = mTrackList.editValueFor(trackId); if (!info.active) { SXLOGV("%s, trackId:%p, active = %d",__FUNCTION__, (void*)trackId, info.active); return OK; } uint32_t s; s = (server > info.server) ? (server - info.server) : 0; if (s && info.middleServer && s < info.afFrameCount) { info.middleServer = server; return OK; } if (!restore && info.server) { info.framePlayed = info.framePlayed + s; info.ts = ALooper::GetNowUs(); } info.server = server; SXLOGV("trackId:%p, info.server:%d, info.framePlayed:%lld, info.ts:%lld",(void*)trackId, info.server, info.framePlayed, info.ts); info.middleServer = server; return OK; }
status_t AudioTrackCenter::setTimeStretch(uint32_t timeScaled) { Mutex::Autolock autoLock(mLock); SXLOGV("%s, timeScaled:%d",__FUNCTION__, timeScaled); if (timeScaled != 1 && timeScaled != 2 && timeScaled != 4) { return BAD_VALUE; } mTimeScaled = timeScaled; return OK; }
int HeadSetDetect::readStateFromFile() { SXLOGV("readStateFromFile"); int fd = open(HEADSET_STATE_PATH, O_RDONLY, 0); if(fd < 0) { SXLOGD("Fail to open file %s", HEADSET_STATE_PATH); return -1; } char buf[1]; if (read(fd, buf, 1) == -1){ SXLOGD("Can't read %s", HEADSET_STATE_PATH); return -1; } close(fd); return buf[0]; }
status_t AudioTrackCenter::setTrackActive(intptr_t trackId, bool active) { Mutex::Autolock autoLock(mLock); #if defined(CONFIG_MT_ENG_BUILD) SXLOGV("%s, trackId:%p, active:%d",__FUNCTION__, (void*)trackId, active); #endif ssize_t index = mTrackList.indexOfKey(trackId); if (index < 0) { return UNKNOWN_ERROR; } struct TrackInfo &info = mTrackList.editValueFor(trackId); info.active = active; return OK; }
static void *Audio_Record_thread(void *mPtr) { struct headset *hds = (struct headset *)mPtr; ALOGD(TAG "%s: Start", __FUNCTION__); usleep(100000); bool dumpFlag = read_preferred_recorddump(); // bool dumpFlag = true;//for test int magLower = 0, magUpper = 0; read_preferred_magnitude(&magUpper, &magLower); int lowFreq = 1000 * (1 - 0.1); //1k int highFreq = 1000 * (1 + 0.1); short pbuffer[8192] = {0}; short pbufferL[4096] = {0}; short pbufferR[4096] = {0}; unsigned int freqDataL[3] = {0}, magDataL[3] = {0}; unsigned int freqDataR[3] = {0}, magDataR[3] = {0}; int checkCnt = 0; uint32_t samplerate = 0; // headsetLR: Phone level test; headset: Non-Phone level test. return_data.headsetL.freqL = return_data.headsetR.freqL = return_data.headset.freqL = freqDataL[0]; return_data.headsetL.freqR = return_data.headsetR.freqR = return_data.headset.freqR = freqDataR[0]; return_data.headsetL.amplL = return_data.headsetR.amplL = return_data.headset.amplL = magDataL[0]; return_data.headsetL.amplR = return_data.headsetR.amplR = return_data.headset.amplR = magDataR[0]; recordInit(hds->recordDevice, &samplerate); while (1) { memset(pbuffer, 0, sizeof(pbuffer)); memset(pbufferL, 0, sizeof(pbufferL)); memset(pbufferR, 0, sizeof(pbufferR)); int readSize = readRecordData(pbuffer, 8192 * 2); for (int i = 0 ; i < 4096 ; i++) { pbufferL[i] = pbuffer[2 * i]; pbufferR[i] = pbuffer[2 * i + 1]; } if (dumpFlag) { char filenameL[] = "/data/record_headset_dataL.pcm"; char filenameR[] = "/data/record_headset_dataR.pcm"; FILE *fpL = fopen(filenameL, "wb+"); FILE *fpR = fopen(filenameR, "wb+"); if (fpL != NULL) { fwrite(pbufferL, readSize / 2, 1, fpL); fclose(fpL); } if (fpR != NULL) { fwrite(pbufferR, readSize / 2, 1, fpR); fclose(fpR); } } memset(freqDataL, 0, sizeof(freqDataL)); memset(freqDataR, 0, sizeof(freqDataR)); memset(magDataL, 0, sizeof(magDataL)); memset(magDataR, 0, sizeof(magDataR)); ApplyFFT256(samplerate, pbufferL, 0, freqDataL, magDataL); ApplyFFT256(samplerate, pbufferR, 0, freqDataR, magDataR); for (int i = 0; i < 3 ; i ++) { SXLOGV("%d.freqDataL[%d]:%d,magDataL[%d]:%d", i, i, freqDataL[i], i, magDataL[i]); SXLOGV("%d.freqDataR[%d]:%d,magDataR[%d]:%d", i, i, freqDataR[i], i, magDataR[i]); } if (hds->isPhoneTest) { if (headset_phonetest_state == 0) // CH1 { //CH1 Log return_data.headsetL.freqL = freqDataL[0]; return_data.headsetL.amplL = magDataL[0]; return_data.headsetL.freqR = freqDataR[0]; return_data.headsetL.amplR = magDataR[0]; if ((freqDataL[0] <= highFreq && freqDataL[0] >= lowFreq) && (magDataL[0] <= magUpper && magDataL[0] >= magLower)) { checkCnt ++; if (checkCnt >= 5) { ALOGD("[Headset-L] freqDataL:%d,magDataL:%d,freqDataR:%d,magDataR:%d", freqDataL[0], magDataL[0], freqDataR[0], magDataR[0]); checkCnt = 0; } } else { checkCnt = 0; } } else if (headset_phonetest_state == 1) // CH2 { if ((freqDataR[0] <= highFreq && freqDataR[0] >= lowFreq) && (magDataR[0] <= magUpper && magDataR[0] >= magLower)) { checkCnt ++; if (checkCnt >= 5) { ALOGD("[Headset-R] freqDataL:%d,magDataL:%d,freqDataR:%d,magDataR:%d", freqDataL[0], magDataL[0], freqDataR[0], magDataR[0]); snprintf(hds->info, sizeof(hds->info), "Check freq pass.\n"); ALOGD(" @ info : %s", hds->info); break; } } else { checkCnt = 0; } } else { break; } } else // Non Phone level test { if (((freqDataL[0] <= highFreq && freqDataL[0] >= lowFreq) && (magDataL[0] <= magUpper && magDataL[0] >= magLower)) && ((freqDataR[0] <= highFreq && freqDataR[0] >= lowFreq) && (magDataR[0] <= magUpper && magDataR[0] >= magLower))) { checkCnt ++; if (checkCnt >= 5) { snprintf(hds->info, sizeof(hds->info), "Check freq pass.\n"); ALOGD(" @ info : %s", hds->info); break; } } else { checkCnt = 0; } if (hds->exit_thd) { break; } } } // Log and ATA Return if (hds->isPhoneTest) { //CH2 Log return_data.headsetR.freqL = freqDataL[0]; return_data.headsetR.freqR = freqDataR[0]; return_data.headsetR.amplL = magDataL[0]; return_data.headsetR.amplR = magDataR[0]; ALOGD(TAG "ATA Return Data[Headset-L]: [Mic1]Freq = %d, Amp = %d, [Mic2]Freq = %d, Amp = %d", return_data.headsetL.freqL, return_data.headsetL.amplL, return_data.headsetL.freqR, return_data.headsetL.amplR); ALOGD(TAG "ATA Return Data[Headset-R]: [Mic1]Freq = %d, Amp = %d, [Mic2]Freq = %d, Amp = %d", return_data.headsetR.freqL, return_data.headsetR.amplL, return_data.headsetR.freqR, return_data.headsetR.amplR); } else { return_data.headset.freqL = freqDataL[0]; return_data.headset.freqR = freqDataR[0]; return_data.headset.amplL = magDataL[0]; return_data.headset.amplR = magDataR[0]; ALOGD(TAG "ATA Return Data: FreqL = %d, FreqR = %d, AmpL = %d, AmpR = %d", return_data.headset.freqL, return_data.headset.freqR, return_data.headset.amplL, return_data.headset.amplR); } ALOGD(TAG "%s: Stop", __FUNCTION__); pthread_exit(NULL); // thread exit return NULL; }
//#define WRITEOVER void *ReadRoutine(void *hdl) { AudioVUnlockRingBuf *ringBuf_in; AudioVUnlockRingBuf *ringBuf_out; int32_t readAmount; int32_t rwfailcount = 0; AudioVUnlockDL *VInstance = AudioVUnlockDL::getInstance(); char *tempbuffer = new char[VOICE_UNLOCK_RING_BUFFER_SIZE]; char *tempSRCbuffer = new char[6000]; uint32_t dataread = 0; int32_t datawritten = 0; SXLOGD(" [ReadRoutine] start"); // defaut setting of thread init pthread_mutex_lock(&mVUnlockReadMutex); VInstance->mReadThreadExit = false; VInstance->mReadThreadActive = true; pthread_mutex_unlock(&mVUnlockReadMutex); ringBuf_in = (AudioVUnlockRingBuf *) & (VInstance->mRingBufIn); ringBuf_out = (AudioVUnlockRingBuf *) & (VInstance->mRingBufOut); if (VInstance == NULL || ringBuf_in == NULL || ringBuf_out == NULL) { SXLOGD(" [ReadRoutine] Buffer NULL, Exit"); pthread_mutex_lock(&mVUnlockReadMutex); VInstance->mReadThreadExit = true; VInstance->mReadThreadActive = false; pthread_mutex_unlock(&mVUnlockReadMutex); } #ifdef MTK_AUDIO_ADJUST_PRIORITY int result = -1; // if set priority false , force to set priority if (result == -1) { struct sched_param sched_p; sched_getparam(0, &sched_p); sched_p.sched_priority = RTPM_PRIO_AUDIO_I2S; if (0 != sched_setscheduler(0, SCHED_RR, &sched_p)) { SXLOGE("[%s] failed, errno: %d", __func__, errno); } else { sched_p.sched_priority = RTPM_PRIO_AUDIO_I2S; sched_getparam(0, &sched_p); SXLOGD("sched_setscheduler ok, priority: %d", sched_p.sched_priority); } } #endif while (!VInstance->mReadThreadExit) { // Clear DL time if remaining data is pushed. if (VInstance->mDLtime.tv_nsec != 0 && VInstance->mNewDLtime.tv_sec != 0) { if (VInstance->mInRemaining == 0 && VInstance->mOutRemaining == 0) { VInstance->mDLtime.tv_sec = 0; VInstance->mDLtime.tv_nsec = 0; //SXLOGV("[ReadRoutine] All Data from last playback pushed"); } } // switch DL time to new DL time if (VInstance->mDLtime.tv_sec == 0 && VInstance->mNewDLtime.tv_sec != 0) { VInstance->mDLtime.tv_sec = VInstance->mNewDLtime.tv_sec ; VInstance->mDLtime.tv_nsec = VInstance->mNewDLtime.tv_nsec; VInstance->mNewDLtime.tv_sec = 0; VInstance->mNewDLtime.tv_nsec = 0; SXLOGV("[ReadRoutine] switch to new DL time %d %d", VInstance->mDLtime.tv_sec, VInstance->mDLtime.tv_nsec); } uint32_t readsz = ringBuf_in->GetBufDataSz(); dataread = ringBuf_in->ReadWithoutAdvance(tempbuffer, readsz); if (VInstance->mInRemaining != 0) { dataread = dataread > VInstance->mInRemaining ? VInstance->mInRemaining : dataread; } if (dataread <= 0 || VInstance->mDLtime.tv_sec == 0) // do not read data if mDLtime is ready. { if (VInstance->StreamOutStandBy() && ringBuf_out->GetBufDataSz() == 0) { //SXLOGV("[ReadRoutine] Standby, and all data from last playback is pushed"); VInstance->mDLtime.tv_sec = 0; VInstance->mDLtime.tv_nsec = 0; } //SXLOGV("[ReadRoutine] No data from stream out, sleep"); usleep(30 * 1000); } else { //do SRC uint32_t dataproduced = ringBuf_out->GetBufSpace(); dataproduced = dataproduced > 6000 ? 6000 : dataproduced; int32_t dataConsumed = VInstance->DoSRC((uint8_t *) tempbuffer, &dataread , (uint8_t *) tempSRCbuffer, &dataproduced); #ifdef DUMP_VPW_StreamIn_DATA //VInstance->DumpData(tempSRCbuffer, dataproduced); if (VInstance->mOutFile_1 != NULL) { VInstance->mOutFile_1 = fopen("/sdcard/audio_dump/VPW_SRC.pcm", "ab+"); fwrite(tempSRCbuffer, sizeof(char), dataproduced, VInstance->mOutFile_1); fclose(VInstance->mOutFile_1); } #endif if (dataConsumed > 0) { datawritten = ringBuf_out->Write(tempSRCbuffer, dataproduced); SXLOGV("[ReadRoutine] write to ring out, datawritten %d", datawritten); } else { datawritten = 0; } if (datawritten <= 0) // write fail { rwfailcount++; if (rwfailcount > 100) { SXLOGD("[ReadRoutine] Fail, write fail"); break; } SXLOGD("[ReadRoutine] No space to write, sleep"); usleep(10 * 1000); //10ms } else//advance read pointer according to data actually write to output buffer { ringBuf_in->AdvanceReadPointer((uint32_t)dataConsumed); if (VInstance->mInRemaining != 0) { SXLOGV("[ReadRoutine] last playback in buffer remaining %d", VInstance->mInRemaining); VInstance->mInRemaining -= dataConsumed; VInstance->mOutRemaining += datawritten; } ringBuf_out->SignalBufData(); SXLOGV("[ReadRoutine] advance Read poniter %d " , (uint32_t)dataConsumed); rwfailcount = 0; } } } delete tempbuffer; delete tempSRCbuffer; SXLOGD("[ReadRoutine] exit "); VInstance->ClearState(VPWStreamIn_READ_START); SXLOGD("stop and signal ReadRefFromRing to stop"); ringBuf_out->SignalBufData(); int cnt_val = 50; while ((VInstance->mReadFunctionActive == true) && (cnt_val > 0)) { SXLOGD("[ReadRoutine]Signal ReadRefFromRing to stop and wait (%d) ", cnt_val); cnt_val--; ringBuf_out->SignalBufData(); usleep(1000 * 10); } pthread_mutex_lock(&mVUnlockReadMutex); VInstance->mReadThreadExit = true; VInstance->mReadThreadActive = false; pthread_mutex_unlock(&mVUnlockReadMutex); return 0; }
status_t MyVorbisExtractor::seekToTime(int64_t timeUs) { #ifdef MTK_AOSP_ENHANCEMENT if(timeUs == 0) return seekToOffset(0); if (isCachingDataSource()) { off64_t pos = timeUs * approxBitrate() / 8000000ll; SXLOGV("seeking to offset %lld", pos); return seekToOffset(pos); } if (mTableOfContents.isEmpty() || (mTocDone == false)) { // Perform seekto accurate page. uint64_t ts1,ts2; if(findGranulePositionofPage(mFirstDataOffset,&ts1) != OK) return seekToOffset(0); if(findGranulePositionofPage(mFileSize,&ts2) != OK) return seekToOffset(0); SXLOGD("bitrate seek--pos:%lld,ts1:%lld,ts2:%lld",timeUs * mVi.rate /1000000,ts1,ts2); off64_t pos = findAccuratePageOffset((uint64_t)(timeUs * mVi.rate /1000000),mFirstDataOffset,mFileSize); #else if (mTableOfContents.isEmpty()) { // Perform approximate seeking based on avg. bitrate. off64_t pos = timeUs * approxBitrate() / 8000000ll; #endif ALOGV("seeking to offset %lld", pos); return seekToOffset(pos); } size_t left = 0; size_t right_plus_one = mTableOfContents.size(); while (left < right_plus_one) { size_t center = left + (right_plus_one - left) / 2; const TOCEntry &entry = mTableOfContents.itemAt(center); if (timeUs < entry.mTimeUs) { right_plus_one = center; } else if (timeUs > entry.mTimeUs) { left = center + 1; } else { left = center; break; } } if (left == mTableOfContents.size()) { --left; } #ifndef MTK_AOSP_ENHANCEMENT const TOCEntry &entry = mTableOfContents.itemAt(left); ALOGV("seeking to entry %zu / %zu at offset %lld", left, mTableOfContents.size(), entry.mPageOffset); return seekToOffset(entry.mPageOffset); #else if(mTableOfContents.itemAt(mTableOfContents.size()-1).mTimeUs <= timeUs) return seekToOffset(mTableOfContents.itemAt(mTableOfContents.size()-1).mPageOffset); off64_t os = 0,oe = 0; for(size_t i = left ; i < mTableOfContents.size() ;i ++) { if(mTableOfContents.itemAt(i).mTimeUs > timeUs) { oe = mTableOfContents.itemAt(i).mPageOffset; break; } else if(mTableOfContents.itemAt(i).mTimeUs == timeUs) return seekToOffset(mTableOfContents.itemAt(left).mPageOffset); } for(size_t i = left ; (i >= 0) && (i < mTableOfContents.size()) ;i --) { if(mTableOfContents.itemAt(i).mTimeUs < timeUs) { os = mTableOfContents.itemAt(i).mPageOffset; break; } else if(mTableOfContents.itemAt(i).mTimeUs == timeUs) return seekToOffset(mTableOfContents.itemAt(left).mPageOffset); } /*for(size_t i = 0 ; i< mTableOfContents.size() ;i ++) { uint64_t ts; findGranulePositionofPage(mTableOfContents.itemAt(i).mPageOffset,&ts); SXLOGD("mTableOfContents.itemAt(%d)--mPageOffset:%lld,mTimeUs:%lld,ts:%lld",i,mTableOfContents.itemAt(i).mPageOffset,mTableOfContents.itemAt(i).mTimeUs,ts); }*/ uint64_t ts1,ts2,ts; findGranulePositionofPage(os,&ts1); findGranulePositionofPage(oe,&ts2); off64_t pos = findAccuratePageOffset((uint64_t)(timeUs * mVi.rate /1000000),os,oe); findGranulePositionofPage(pos,&ts); SXLOGD("seektable seek--pos:%lld,ts1:%lld,ts2:%lld,pos:%lld,ts:%lld",timeUs * mVi.rate /1000000,ts1,ts2,pos,ts); return seekToOffset(pos); #endif } #ifdef MTK_AOSP_ENHANCEMENT status_t MyVorbisExtractor::findNextPage_l( off64_t startOffset, off64_t *pageOffset) { *pageOffset = startOffset; char signature[2048]; for (;;) { ssize_t n = mSource->readAt(*pageOffset, &signature, 2000); if (n < 4) { *pageOffset = 0; return (n < 0) ? n : (status_t)ERROR_END_OF_STREAM; } int i = 0; int step = n-4; while(i<=step) { if (!memcmp(&signature[i], "OggS", 4) && ((*pageOffset + i) > startOffset)) { if ((*pageOffset + i) > startOffset) { SXLOGV("skipped %lld bytes of junk to reach next frame", (*pageOffset + i) - startOffset); } *pageOffset += i; return OK; } i++; } *pageOffset += n; } }
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; }