status_t MyVorbisExtractor::seekToTime(int64_t timeUs) { if (mTableOfContents.isEmpty()) { // Perform approximate seeking based on avg. bitrate. off64_t pos = timeUs * approxBitrate() / 8000000ll; LOGV("seeking to offset %lld", pos); return seekToOffset(pos); } size_t left = 0; size_t right = mTableOfContents.size(); while (left < right) { size_t center = left / 2 + right / 2 + (left & right & 1); const TOCEntry &entry = mTableOfContents.itemAt(center); if (timeUs < entry.mTimeUs) { right = center; } else if (timeUs > entry.mTimeUs) { left = center + 1; } else { left = right = center; break; } } const TOCEntry &entry = mTableOfContents.itemAt(left); LOGV("seeking to entry %d / %d at offset %lld", left, mTableOfContents.size(), entry.mPageOffset); return seekToOffset(entry.mPageOffset); }
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; } }