示例#1
0
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);
}
示例#2
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;    
    }
}