示例#1
0
文件: info.c 项目: granberro/uLoader
int vorbis_synthesis_headerin(vorbis_info *vi,vorbis_comment *vc,ogg_packet *op){
  oggpack_buffer opb;
  
  if(op){
    oggpack_readinit(&opb,op->packet);

    /* Which of the three types of header is this? */
    /* Also verify header-ness, vorbis */
    {
      char buffer[6];
      int packtype=oggpack_read(&opb,8);
      memset(buffer,0,6);
      _v_readstring(&opb,buffer,6);
      if(memcmp(buffer,"vorbis",6)){
	/* not a vorbis header */
	return(OV_ENOTVORBIS);
      }
      switch(packtype){
      case 0x01: /* least significant *bit* is read first */
	if(!op->b_o_s){
	  /* Not the initial packet */
	  return(OV_EBADHEADER);
	}
	if(vi->rate!=0){
	  /* previously initialized info header */
	  return(OV_EBADHEADER);
	}

	return(_vorbis_unpack_info(vi,&opb));

      case 0x03: /* least significant *bit* is read first */
	if(vi->rate==0){
	  /* um... we didn't get the initial header */
	  return(OV_EBADHEADER);
	}

	return(_vorbis_unpack_comment(vc,&opb));

      case 0x05: /* least significant *bit* is read first */
	if(vi->rate==0 || vc->vendor==NULL){
	  /* um... we didn;t get the initial header or comments yet */
	  return(OV_EBADHEADER);
	}

	return(_vorbis_unpack_books(vi,&opb));

      default:
	/* Not a valid vorbis header type */
	return(OV_EBADHEADER);
	break;
      }
    }
  }
  return(OV_EBADHEADER);
}
示例#2
0
int vorbis_synthesis_headerin(vorbis_info *vi,vorbis_comment *vc,ogg_packet *op,unsigned int newpack)
{
 int packtype;
 oggpack_buffer opb;
 char buffer[6];

 if(op){
  if(newpack)
   oggpack_readinit(&opb,op->packet,op->bytes);

  packtype=oggpack_read24(&opb,8);
  _v_readstring(&opb,buffer,6);
  if(memcmp(buffer,"vorbis",6)!=0)
   return(OV_ENOTVORBIS);

  switch(packtype){
   case 0x01:
	if(!op->b_o_s)
	  return(OV_EBADHEADER);
	if(vi->rate!=0)
	  return(OV_EBADHEADER);

	return(_vorbis_unpack_info(vi,&opb));

   case 0x03:
	if(vi->rate==0)
	  return(OV_EBADHEADER);

#ifdef MPXPLAY
        if(!newpack)
         _vorbis_skip_comment(&opb);
        return(0); // comments are readed at Ogg demuxing in Mpxplay
#else
	return(_vorbis_unpack_comment(vc,&opb));
#endif

   case 0x05:
	if(vi->rate==0)
	  return(OV_EBADHEADER);
#ifndef MPXPLAY
        if(vc->vendor==NULL)
	  return(OV_EBADHEADER);
#endif

	return(_vorbis_unpack_books(vi,&opb));

   default:
	return(OV_EBADHEADER);
	break;
  }
 }
 return(OV_EBADHEADER);
}
示例#3
0
status_t MyVorbisExtractor::verifyHeader(
        MediaBuffer *buffer, uint8_t type) {
    const uint8_t *data =
        (const uint8_t *)buffer->data() + buffer->range_offset();

    size_t size = buffer->range_length();

    if (size < 7 || data[0] != type || memcmp(&data[1], "vorbis", 6)) {
        return ERROR_MALFORMED;
    }

    ogg_buffer buf;
    buf.data = (uint8_t *)data;
    buf.size = size;
    buf.refcount = 1;
    buf.ptr.owner = NULL;

    ogg_reference ref;
    ref.buffer = &buf;
    ref.begin = 0;
    ref.length = size;
    ref.next = NULL;

    oggpack_buffer bits;
    oggpack_readinit(&bits, &ref);

    CHECK_EQ(oggpack_read(&bits, 8), type);
    for (size_t i = 0; i < 6; ++i) {
        oggpack_read(&bits, 8);  // skip 'vorbis'
    }

    switch (type) {
        case 1:
        {
            CHECK_EQ(0, _vorbis_unpack_info(&mVi, &bits));

            mMeta->setData(kKeyVorbisInfo, 0, data, size);
            mMeta->setInt32(kKeySampleRate, mVi.rate);
            mMeta->setInt32(kKeyChannelCount, mVi.channels);

            LOGV("lower-bitrate = %ld", mVi.bitrate_lower);
            LOGV("upper-bitrate = %ld", mVi.bitrate_upper);
            LOGV("nominal-bitrate = %ld", mVi.bitrate_nominal);
            LOGV("window-bitrate = %ld", mVi.bitrate_window);

            off64_t size;
            if (mSource->getSize(&size) == OK) {
                   uint64_t bps = approxBitrate();
	     	     if(0 != bps && bps < 10000000)
		     {
				mMeta->setInt64(kKeyDuration, size * 8000000ll / bps);  
		     } else 
		     {   
				uint64_t lastGranule, tDuration;                             
				lastGranule= findLastGranule();                              
				tDuration = lastGranule*1000000/mVi.rate;                    
				mMeta->setInt64(kKeyDuration, tDuration);    
				bps = size * 8000000ll / tDuration;                
				mMeta->setInt64(kKeyBitRate, size * 8000000ll / tDuration);  
				mVi.bitrate_nominal = bps;                             
			}

            }
            break;
        }

        case 3:
        {
            if (0 != _vorbis_unpack_comment(&mVc, &bits)) {
                return ERROR_MALFORMED;
            }

            parseFileMetaData();
            break;
        }

        case 5:
        {
            if (0 != _vorbis_unpack_books(&mVi, &bits)) {
                return ERROR_MALFORMED;
            }

            mMeta->setData(kKeyVorbisBooks, 0, data, size);
            break;
        }
    }

    return OK;
}
示例#4
0
void MyVorbisExtractor::buildTableOfContents() {
    off64_t offset = mFirstDataOffset;
    Page page;
    ssize_t pageSize;
#ifndef MTK_AOSP_ENHANCEMENT
    while ((pageSize = readPage(offset, &page)) > 0) {
#else
	struct timeval tb,te;
	gettimeofday(&tb,NULL);
    while (mTocStarted && ((pageSize = readPage(offset, &page)) > 0)) {
        if(page.mGranulePosition < 0xFFFFFFFFFFFF)
        {
#endif
        mTableOfContents.push();

        TOCEntry &entry =
            mTableOfContents.editItemAt(mTableOfContents.size() - 1);

        entry.mPageOffset = offset;
        entry.mTimeUs = page.mGranulePosition * 1000000ll / mVi.rate;
#ifdef MTK_AOSP_ENHANCEMENT
        //sleep 100ms for consumes over 2s
        gettimeofday(&te,NULL);
        if((te.tv_sec - tb.tv_sec) > 2)
         {
        	  gettimeofday(&tb,NULL);
	          usleep(100000);	  
         }
        }
#endif
        offset += (size_t)pageSize;
    }

    // Limit the maximum amount of RAM we spend on the table of contents,
    // if necessary thin out the table evenly to trim it down to maximum
    // size.

    static const size_t kMaxTOCSize = 8192;
    static const size_t kMaxNumTOCEntries = kMaxTOCSize / sizeof(TOCEntry);

    size_t numerator = mTableOfContents.size();

    if (numerator > kMaxNumTOCEntries) {
        size_t denom = numerator - kMaxNumTOCEntries;

        size_t accum = 0;
        for (ssize_t i = mTableOfContents.size() - 1; i >= 0; --i) {
            accum += denom;
            if (accum >= numerator) {
                mTableOfContents.removeAt(i);
                accum -= numerator;
            }
        }
    }
#ifdef MTK_AOSP_ENHANCEMENT
    mTocDone = true;
#endif
}

status_t MyVorbisExtractor::verifyHeader(
        MediaBuffer *buffer, uint8_t type) {
    const uint8_t *data =
        (const uint8_t *)buffer->data() + buffer->range_offset();

    size_t size = buffer->range_length();

    if (size < 7 || data[0] != type || memcmp(&data[1], "vorbis", 6)) {
        return ERROR_MALFORMED;
    }

    ogg_buffer buf;
    buf.data = (uint8_t *)data;
    buf.size = size;
    buf.refcount = 1;
    buf.ptr.owner = NULL;

    ogg_reference ref;
    ref.buffer = &buf;
    ref.begin = 0;
    ref.length = size;
    ref.next = NULL;

    oggpack_buffer bits;
    oggpack_readinit(&bits, &ref);

    CHECK_EQ(oggpack_read(&bits, 8), type);
    for (size_t i = 0; i < 6; ++i) {
        oggpack_read(&bits, 8);  // skip 'vorbis'
    }

    switch (type) {
        case 1:
        {
#ifndef MTK_AOSP_ENHANCEMENT    	
            CHECK_EQ(0, _vorbis_unpack_info(&mVi, &bits));
#else
            _vorbis_unpack_info(&mVi, &bits);//skip the CHECK
#endif
            mMeta->setData(kKeyVorbisInfo, 0, data, size);
            mMeta->setInt32(kKeySampleRate, mVi.rate);
            mMeta->setInt32(kKeyChannelCount, mVi.channels);
            
#ifdef MTK_AOSP_ENHANCEMENT
            if(mVi.channels > 2)
            {
#ifndef MTK_SWIP_VORBIS
                SXLOGE("Tremolo does not support multi channel");
                return ERROR_UNSUPPORTED;
#endif
            }
#endif 

            ALOGV("lower-bitrate = %ld", mVi.bitrate_lower);
            ALOGV("upper-bitrate = %ld", mVi.bitrate_upper);
            ALOGV("nominal-bitrate = %ld", mVi.bitrate_nominal);
            ALOGV("window-bitrate = %ld", mVi.bitrate_window);

            off64_t size;
            if (mSource->getSize(&size) == OK) {
                uint64_t bps = approxBitrate();
                if (bps != 0) {
                    mMeta->setInt64(kKeyDuration, size * 8000000ll / bps);
                }
            }
            break;
        }

        case 3:
        {
            if (0 != _vorbis_unpack_comment(&mVc, &bits)) {
                return ERROR_MALFORMED;
            }

            parseFileMetaData();
            break;
        }

        case 5:
        {
            if (0 != _vorbis_unpack_books(&mVi, &bits)) {
                return ERROR_MALFORMED;
            }

            mMeta->setData(kKeyVorbisBooks, 0, data, size);
            break;
        }
    }

    return OK;
}

uint64_t MyVorbisExtractor::approxBitrate() {
    if (mVi.bitrate_nominal != 0) {
        return mVi.bitrate_nominal;
    }

    return (mVi.bitrate_lower + mVi.bitrate_upper) / 2;
}

void MyVorbisExtractor::parseFileMetaData() {
    mFileMeta = new MetaData;
#ifdef MTK_AOSP_ENHANCEMENT
    if(mFileMeta.get() == NULL)  return;
#endif
    mFileMeta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_CONTAINER_OGG);

    for (int i = 0; i < mVc.comments; ++i) {
        const char *comment = mVc.user_comments[i];
        size_t commentLength = mVc.comment_lengths[i];
        parseVorbisComment(mFileMeta, comment, commentLength);
        //ALOGI("comment #%d: '%s'", i + 1, mVc.user_comments[i]);
    }
}