status_t MyVorbisExtractor::seekToOffset(off64_t offset) { if (mFirstDataOffset >= 0 && offset < mFirstDataOffset) { // Once we know where the actual audio data starts (past the headers) // don't ever seek to anywhere before that. offset = mFirstDataOffset; } off64_t pageOffset; status_t err = findNextPage(offset, &pageOffset); if (err != OK) { return err; } // We found the page we wanted to seek to, but we'll also need // the page preceding it to determine how many valid samples are on // this page. findPrevGranulePosition(pageOffset, &mPrevGranulePosition); mOffset = pageOffset; mCurrentPageSize = 0; mFirstPacketInPage = true; mCurrentPageSamples = 0; mCurrentPage.mNumSegments = 0; mNextLaceIndex = 0; // XXX what if new page continues packet from last??? return OK; }
// Given the offset of the "current" page, find the page immediately preceding // it (if any) and return its granule position. // To do this we back up from the "current" page's offset until we find any // page preceding it and then scan forward to just before the current page. status_t MyVorbisExtractor::findPrevGranulePosition( off64_t pageOffset, uint64_t *granulePos) { *granulePos = 0; off64_t prevPageOffset = 0; off64_t prevGuess = pageOffset; for (;;) { if (prevGuess >= 5000) { prevGuess -= 5000; } else { prevGuess = 0; } ALOGV("backing up %lld bytes", pageOffset - prevGuess); status_t err = findNextPage(prevGuess, &prevPageOffset); if (err != OK) { #ifdef MTK_AOSP_ENHANCEMENT if((prevGuess == 0) || ((prevGuess + 5000 * 20) < pageOffset)) return err; else continue; #else return err; #endif } if (prevPageOffset < pageOffset || prevGuess == 0) { break; } } if (prevPageOffset == pageOffset) { // We did not find a page preceding this one. return UNKNOWN_ERROR; } ALOGV("prevPageOffset at %lld, pageOffset at %lld", prevPageOffset, pageOffset); for (;;) { Page prevPage; ssize_t n = readPage(prevPageOffset, &prevPage); if (n <= 0) { return (status_t)n; } prevPageOffset += n; if (prevPageOffset == pageOffset) { *granulePos = prevPage.mGranulePosition; return OK; } } }
// Given the offset of the "current" page, find the page immediately preceding // it (if any) and return its granule position. // To do this we back up from the "current" page's offset until we find any // page preceding it and then scan forward to just before the current page. status_t MyVorbisExtractor::findPrevGranulePosition( off64_t pageOffset, uint64_t *granulePos) { *granulePos = 0; off64_t prevPageOffset = 0; off64_t prevGuess = pageOffset; for (;;) { if (prevGuess >= 5000) { prevGuess -= 5000; } else { prevGuess = 0; } status_t err = findNextPage(prevGuess, &prevPageOffset); if (err != OK) { return err; } if (prevPageOffset < pageOffset || prevGuess == 0) { break; } } if (prevPageOffset == pageOffset) { // We did not find a page preceding this one. return UNKNOWN_ERROR; } for (;;) { Page prevPage; ssize_t n = readPage(prevPageOffset, &prevPage); if (n <= 0) { return (status_t)n; } prevPageOffset += n; if (prevPageOffset == pageOffset) { *granulePos = prevPage.mGranulePosition; return OK; } } }
status_t MyVorbisExtractor::findGranulePositionofPage(off64_t offset,uint64_t *granulePositionofPage) { if (mFirstDataOffset >= 0 && offset < mFirstDataOffset) { // Once we know where the actual audio data starts (past the headers) // don't ever seek to anywhere before that. offset = mFirstDataOffset; } if(((uint64_t)offset) == mFileSize) { findPrevGranulePosition(mFileSize, granulePositionofPage); if((*granulePositionofPage) < 0xFFFFFFFFFFFF) return OK; else return UNKNOWN_ERROR; } off64_t pageOffset; status_t err = findNextPage_l(offset, &pageOffset); if (err != OK) { err = findNextPage(offset, &pageOffset); if((err == OK) && (offset == pageOffset)) { Page page; readPage(offset, &page); *granulePositionofPage = page.mGranulePosition; } else findPrevGranulePosition(mFileSize, granulePositionofPage); if((*granulePositionofPage) < 0xFFFFFFFFFFFF) return OK; else return UNKNOWN_ERROR; } // We found the page we wanted to seek to, but we'll also need // the page preceding it to determine how many valid samples are on // this page. findPrevGranulePosition(pageOffset, granulePositionofPage); if((*granulePositionofPage) < 0xFFFFFFFFFFFF) return OK; else return UNKNOWN_ERROR; }
// Given the offset of the "current" page, find the page immediately preceding // it (if any) and return its granule position. // To do this we back up from the "current" page's offset until we find any // page preceding it and then scan forward to just before the current page. uint64_t MyVorbisExtractor::findPrevGranulePosition(off_t pageOffset) { off_t prevPageOffset = 0; off_t prevGuess = pageOffset; for (;;) { if (prevGuess >= 5000) { prevGuess -= 5000; } else { prevGuess = 0; } LOGV("backing up %ld bytes", pageOffset - prevGuess); CHECK_EQ(findNextPage(prevGuess, &prevPageOffset), (status_t)OK); if (prevPageOffset < pageOffset || prevGuess == 0) { break; } } if (prevPageOffset == pageOffset) { // We did not find a page preceding this one. return 0; } LOGV("prevPageOffset at %ld, pageOffset at %ld", prevPageOffset, pageOffset); for (;;) { Page prevPage; ssize_t n = readPage(prevPageOffset, &prevPage); if (n <= 0) { return 0; } prevPageOffset += n; if (prevPageOffset == pageOffset) { return prevPage.mGranulePosition; } } }