long vorbis_packet_blocksize(vorbis_info *vi,ogg_packet *op){ codec_setup_info *ci=vi->codec_setup; oggpack_buffer opb; int mode; oggpack_readinit(&opb,op->packet,op->bytes); /* Check the packet type */ if(oggpack_read(&opb,1)!=0){ /* Oops. This is not an audio data packet */ return(OV_ENOTAUDIO); } { int modebits=0; int v=ci->modes; while(v>1){ modebits++; v>>=1; } /* read our mode and pre/post windowsize */ mode=oggpack_read(&opb,modebits); } if(mode==-1)return(OV_EBADPACKET); return(ci->blocksizes[ci->mode_param[mode]->blockflag]); }
TarkinError tarkin_synthesis_headerin (TarkinInfo * vi, TarkinComment * vc, ogg_packet * op) { oggpack_buffer opb; if (op) { oggpack_readinit (&opb, op->packet, op->bytes); /* Which of the three types of header is this? */ /* Also verify header-ness, tarkin */ { char buffer[6]; int packtype = oggpack_read (&opb, 8); memset (buffer, 0, 6); _v_readstring (&opb, buffer, 6); if (memcmp (buffer, "tarkin", 6)) { /* not a tarkin header */ return (-TARKIN_NOT_TARKIN); } switch (packtype) { case 0x01: /* least significant *bit* is read first */ if (!op->b_o_s) { /* Not the initial packet */ return (-TARKIN_BAD_HEADER); } if (vi->inter.numerator != 0) { /* previously initialized info header */ return (-TARKIN_BAD_HEADER); } return (_tarkin_unpack_info (vi, &opb)); case 0x03: /* least significant *bit* is read first */ if (vi->inter.denominator == 0) { /* um... we didn't get the initial header */ return (-TARKIN_BAD_HEADER); } return (_tarkin_unpack_comment (vc, &opb)); case 0x05: /* least significant *bit* is read first */ if (vi->inter.numerator == 0 || vc->vendor == NULL) { /* um... we didn;t get the initial header or comments yet */ return (-TARKIN_BAD_HEADER); } return (_tarkin_unpack_layer_desc (vi, &opb)); default: /* Not a valid tarkin header type */ return (-TARKIN_BAD_HEADER); break; } } } return (-TARKIN_BAD_HEADER); }
int vorbis_synthesis(vorbis_block *vb,ogg_packet *op,int decodep){ vorbis_dsp_state *vd=vb->vd; private_state *b=(private_state *)vd->backend_state; vorbis_info *vi=vd->vi; codec_setup_info *ci=(codec_setup_info *)vi->codec_setup; oggpack_buffer *opb=&vb->opb; int type,mode,i; /* first things first. Make sure decode is ready */ _vorbis_block_ripcord(vb); oggpack_readinit(opb,op->packet); /* Check the packet type */ if(oggpack_read(opb,1)!=0){ /* Oops. This is not an audio data packet */ return(OV_ENOTAUDIO); } /* read our mode and pre/post windowsize */ mode=oggpack_read(opb,b->modebits); if(mode==-1)return(OV_EBADPACKET); vb->mode=mode; vb->W=ci->mode_param[mode]->blockflag; if(vb->W){ vb->lW=oggpack_read(opb,1); vb->nW=oggpack_read(opb,1); if(vb->nW==-1) return(OV_EBADPACKET); }else{ vb->lW=0; vb->nW=0; } /* more setup */ vb->granulepos=op->granulepos; vb->sequence=op->packetno-3; /* first block is third packet */ vb->eofflag=op->e_o_s; if(decodep){ /* alloc pcm passback storage */ vb->pcmend=ci->blocksizes[vb->W]; vb->pcm=(ogg_int32_t **)_vorbis_block_alloc(vb,sizeof(*vb->pcm)*vi->channels); for(i=0;i<vi->channels;i++) vb->pcm[i]=(ogg_int32_t *)_vorbis_block_alloc(vb,vb->pcmend*sizeof(*vb->pcm[i])); /* unpack_header enforces range checking */ type=ci->map_type[ci->mode_param[mode]->mapping]; return(_mapping_P[type]->inverse(vb,b->mode[mode])); }else{ /* no pcm */ vb->pcmend=0; vb->pcm=NULL; return(0); } }
static PyObject * py_ogg_oggpack_readinit(PyObject *self, PyObject *args) { oggpack_buffer * b; unsigned char * buf; int bytes; int size1, size2; PyArg_ParseTuple(args, "s#s#i", &b, &size1, &buf, &size2, &bytes); oggpack_readinit(b, buf, bytes); Py_INCREF(Py_None); return Py_None; };
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); }
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); }
JNIEXPORT void JNICALL Java_org_echocat_jogg_OggPackBufferJNI_readinit (JNIEnv *env, jclass thisClass, jlong handle, jbyteArray buffer) { if (Java_org_echocat_jogg_OggJNISupport_checkNotNull(env, buffer)) { jsize length = (*env)->GetArrayLength(env, buffer); char* nbuffer = (*env)->GetByteArrayElements(env, buffer, 0); if (nbuffer != NULL) { oggpack_readinit((oggpack_buffer*) handle, nbuffer, length); (*env)->ReleaseByteArrayElements(env, buffer, nbuffer, JNI_ABORT); } else { Java_org_echocat_jogg_OggJNISupport_throwOutOfMemoryError(env); } } }
static void makeBitReader( const void *data, size_t size, ogg_buffer *buf, ogg_reference *ref, oggpack_buffer *bits) { buf->data = (uint8_t *)data; buf->size = size; buf->refcount = 1; buf->ptr.owner = NULL; ref->buffer = buf; ref->begin = 0; ref->length = size; ref->next = NULL; oggpack_readinit(bits, ref); }
/* used to track pcm position without actually performing decode. Useful for sequential 'fast forward' */ int vorbis_synthesis_trackonly(vorbis_block *vb,ogg_packet *op){ vorbis_dsp_state *vd=vb->vd; private_state *b=vd->backend_state; vorbis_info *vi=vd->vi; codec_setup_info *ci=vi->codec_setup; oggpack_buffer *opb=&vb->opb; int mode; /* first things first. Make sure decode is ready */ _vorbis_block_ripcord(vb); oggpack_readinit(opb,op->packet,op->bytes); /* Check the packet type */ if(oggpack_read(opb,1)!=0){ /* Oops. This is not an audio data packet */ return(OV_ENOTAUDIO); } /* read our mode and pre/post windowsize */ mode=oggpack_read(opb,b->modebits); if(mode==-1)return(OV_EBADPACKET); vb->mode=mode; if(!ci->mode_param[mode]){ return(OV_EBADPACKET); } vb->W=ci->mode_param[mode]->blockflag; if(vb->W){ vb->lW=oggpack_read(opb,1); vb->nW=oggpack_read(opb,1); if(vb->nW==-1) return(OV_EBADPACKET); }else{ vb->lW=0; vb->nW=0; } /* more setup */ vb->granulepos=op->granulepos; vb->sequence=op->packetno; vb->eofflag=op->e_o_s; /* no pcm */ vb->pcmend=0; vb->pcm=NULL; return(0); }
/* * Class: org_tritonus_lowlevel_ogg_Buffer * Method: readInit * Signature: ([BI)V */ JNIEXPORT void JNICALL Java_org_tritonus_lowlevel_ogg_Buffer_readInit (JNIEnv* env, jobject obj, jbyteArray abBuffer, jint nBytes) { oggpack_buffer* handle; jbyte* buffer; if (debug_flag) { fprintf(debug_file, "Java_org_tritonus_lowlevel_ogg_Buffer_readInit(): begin\n"); } if (debug_flag) { fprintf(debug_file, "Java_org_tritonus_lowlevel_ogg_Buffer_readInit(): nBytes: %d\n", nBytes); } handle = getHandle(env, obj); buffer = (*env)->GetByteArrayElements(env, abBuffer, NULL); if (debug_flag) { fprintf(debug_file, "Java_org_tritonus_lowlevel_ogg_Buffer_readInit(): buffer[0]: %d\n", buffer[0]); } if (debug_flag) { fprintf(debug_file, "Java_org_tritonus_lowlevel_ogg_Buffer_readInit(): buffer[1]: %d\n", buffer[1]); } if (debug_flag) { fprintf(debug_file, "Java_org_tritonus_lowlevel_ogg_Buffer_readInit(): buffer[2]: %d\n", buffer[2]); } oggpack_readinit(handle, (unsigned char*) buffer, nBytes); (*env)->ReleaseByteArrayElements(env, abBuffer, buffer, 0); if (debug_flag) { fprintf(debug_file, "Java_org_tritonus_lowlevel_ogg_Buffer_readInit(): end\n"); } }
int vorbis_synthesis(vorbis_block *vb,ogg_packet *op) { vorbis_dsp_state *vd=vb->vd; backend_lookup_state *b=vd->backend_state; vorbis_info *vi=vd->vi; codec_setup_info *ci=vi->codec_setup; oggpack_buffer *opb=&vb->opb; int type,mode; oggpack_readinit(opb,op->packet,op->bytes); if(oggpack_read1(opb)!=0) return(OV_ENOTAUDIO); mode=oggpack_read32(opb,b->modebits); if((mode==-1) || (mode>=ci->modes)) return(OV_EBADPACKET); vb->mode=mode; vb->W=ci->mode_param[mode]->blockflag; if(vb->W){ vb->lW=oggpack_read1(opb); vb->nW=oggpack_read1(opb); if(vb->nW==-1) return(OV_EBADPACKET); }else{ vb->lW=0; vb->nW=0; } vb->granulepos=op->granulepos; vb->sequence=op->packetno-3; vb->eofflag=op->e_o_s; vb->pcmend=ci->blocksizes[vb->W]; type=ci->map_type[ci->mode_param[mode]->mapping]; return(_mapping_P[type]->inverse(vb,ci->map_param[ci->mode_param[mode]->mapping])); }
long vorbis_packet_blocksize(vorbis_info *vi,ogg_packet *op){ codec_setup_info *ci=vi->codec_setup; oggpack_buffer opb; int mode; if(ci==NULL || ci->modes<=0){ /* codec setup not properly intialized */ return(OV_EFAULT); } oggpack_readinit(&opb,op->packet,op->bytes); /* Check the packet type */ if(oggpack_read(&opb,1)!=0){ /* Oops. This is not an audio data packet */ return(OV_ENOTAUDIO); } /* read our mode and pre/post windowsize */ mode=oggpack_read(&opb,ov_ilog(ci->modes-1)); if(mode==-1 || !ci->mode_param[mode])return(OV_EBADPACKET); return(ci->blocksizes[ci->mode_param[mode]->blockflag]); }
/* Is this packet a vorbis ID header? */ int vorbis_synthesis_idheader(ogg_packet *op){ oggpack_buffer opb; char buffer[6]; if(op){ oggpack_readinit(&opb,op->packet,op->bytes); if(!op->b_o_s) return(0); /* Not the initial packet */ if(oggpack_read(&opb,8) != 1) return 0; /* not an ID header */ memset(buffer,0,6); _v_readstring(&opb,buffer,6); if(memcmp(buffer,"vorbis",6)) return 0; /* not vorbis */ return 1; } return 0; }
int vorbis_synthesis(vorbis_block *vb,ogg_packet *op){ vorbis_dsp_state *vd= vb ? vb->vd : 0; private_state *b= vd ? vd->backend_state : 0; vorbis_info *vi= vd ? vd->vi : 0; codec_setup_info *ci= vi ? vi->codec_setup : 0; oggpack_buffer *opb=vb ? &vb->opb : 0; int type,mode,i; if (!vd || !b || !vi || !ci || !opb) { return OV_EBADPACKET; } /* first things first. Make sure decode is ready */ _vorbis_block_ripcord(vb); oggpack_readinit(opb,op->packet,op->bytes); /* Check the packet type */ if(oggpack_read(opb,1)!=0){ /* Oops. This is not an audio data packet */ return(OV_ENOTAUDIO); } /* read our mode and pre/post windowsize */ mode=oggpack_read(opb,b->modebits); if(mode==-1){ return(OV_EBADPACKET); } vb->mode=mode; if(!ci->mode_param[mode]){ return(OV_EBADPACKET); } vb->W=ci->mode_param[mode]->blockflag; if(vb->W){ /* this doesn;t get mapped through mode selection as it's used only for window selection */ vb->lW=oggpack_read(opb,1); vb->nW=oggpack_read(opb,1); if(vb->nW==-1){ return(OV_EBADPACKET); } }else{ vb->lW=0; vb->nW=0; } /* more setup */ vb->granulepos=op->granulepos; vb->sequence=op->packetno; vb->eofflag=op->e_o_s; /* alloc pcm passback storage */ vb->pcmend=ci->blocksizes[vb->W]; vb->pcm=_vorbis_block_alloc(vb,sizeof(*vb->pcm)*vi->channels); for(i=0;i<vi->channels;i++) vb->pcm[i]=_vorbis_block_alloc(vb,vb->pcmend*sizeof(*vb->pcm[i])); /* unpack_header enforces range checking */ type=ci->map_type[ci->mode_param[mode]->mapping]; return(_mapping_P[type]->inverse(vb,ci->map_param[ci->mode_param[mode]-> mapping])); }
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]); } }
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; }
status_t OggVorbisSeekable::GetStreamInfo(int64 *frameCount, bigtime_t *duration, media_format *format) { TRACE("OggVorbisSeekable::GetStreamInfo\n"); status_t result = B_OK; ogg_packet packet; // get header packet if (GetHeaderPackets().size() < 1) { result = GetPacket(&packet); if (result != B_OK) { return result; } SaveHeaderPacket(packet); } packet = GetHeaderPackets()[0]; if (!packet.b_o_s) { return B_ERROR; // first packet was not beginning of stream } // parse header packet // based on libvorbis/info.c vorbis_synthesis_headerin(...) oggpack_buffer opb; oggpack_readinit(&opb, packet.packet, packet.bytes); int packtype = oggpack_read(&opb, 8); if (packtype != 0x01) { return B_ERROR; // first packet was not an info packet } // discard vorbis string for (uint i = 0 ; i < sizeof("vorbis") - 1 ; i++) { oggpack_read(&opb, 8); } vorbis_info info; if (_vorbis_unpack_info(&info, &opb) != 0) { return B_ERROR; // couldn't unpack info } // get the format for the description media_format_description description = vorbis_description(); BMediaFormats formats; result = formats.InitCheck(); if (result == B_OK) { result = formats.GetFormatFor(description, format); } if (result != B_OK) { *format = vorbis_encoded_media_format(); // ignore error, allow user to use ReadChunk interface } // fill out format from header packet if (info.bitrate_nominal > 0) { format->u.encoded_audio.bit_rate = info.bitrate_nominal; } else if (info.bitrate_upper > 0) { format->u.encoded_audio.bit_rate = info.bitrate_upper; } else if (info.bitrate_lower > 0) { format->u.encoded_audio.bit_rate = info.bitrate_lower; } if (info.channels == 1) { format->u.encoded_audio.multi_info.channel_mask = B_CHANNEL_LEFT; } else { format->u.encoded_audio.multi_info.channel_mask = B_CHANNEL_LEFT | B_CHANNEL_RIGHT; } fFrameRate = format->u.encoded_audio.output.frame_rate = (float)info.rate; format->u.encoded_audio.output.channel_count = info.channels; format->u.encoded_audio.output.buffer_size = AudioBufferSize(&format->u.encoded_audio.output); // get comment packet if (GetHeaderPackets().size() < 2) { result = GetPacket(&packet); if (result != B_OK) { return result; } SaveHeaderPacket(packet); } // get codebook packet if (GetHeaderPackets().size() < 3) { result = GetPacket(&packet); if (result != B_OK) { return result; } SaveHeaderPacket(packet); } format->SetMetaData((void*)&GetHeaderPackets(),sizeof(GetHeaderPackets())); // TODO: count the frames in the first page.. somehow.. :-/ int64 frames = 0; ogg_page page; // read the first page result = ReadPage(&page); if (result != B_OK) { return result; } int64 fFirstGranulepos = ogg_page_granulepos(&page); TRACE("OggVorbisSeekable::GetStreamInfo: first granulepos: %lld\n", fFirstGranulepos); // read our last page off_t last = inherited::Seek(GetLastPagePosition(), SEEK_SET); if (last < 0) { return last; } result = ReadPage(&page); if (result != B_OK) { return result; } int64 last_granulepos = ogg_page_granulepos(&page); // seek back to the start int64 frame = 0; bigtime_t time = 0; result = Seek(B_MEDIA_SEEK_TO_TIME, &frame, &time); if (result != B_OK) { return result; } // compute frame count and duration from sample count frames = last_granulepos - fFirstGranulepos; *frameCount = frames; *duration = (1000000LL * frames) / (long long)fFrameRate; return B_OK; }
static inline int _vorbis_synthesis1(vorbis_block *vb,ogg_packet *op,int decodep){ vorbis_dsp_state *vd= vb ? vb->vd : 0; private_state *b= vd ? (private_state *)vd->backend_state: 0; vorbis_info *vi= vd ? vd->vi : 0; codec_setup_info *ci= vi ? (codec_setup_info *)vi->codec_setup : 0; oggpack_buffer *opb=vb ? &vb->opb : 0; int type,mode,i; if (!vd || !b || !vi || !ci || !opb) { return OV_EBADPACKET; } /* first things first. Make sure decode is ready */ _vorbis_block_ripcord(vb); oggpack_readinit(opb,op->packet,op->bytes); /* Check the packet type */ if(oggpack_read(opb,1)!=0){ /* Oops. This is not an audio data packet */ return(OV_ENOTAUDIO); } /* read our mode and pre/post windowsize */ mode=oggpack_read(opb,b->modebits); if(mode==-1)return(OV_EBADPACKET); vb->mode=mode; if(!ci->mode_param[mode]){ return(OV_EBADPACKET); } vb->W=ci->mode_param[mode]->blockflag; if(vb->W){ vb->lW=oggpack_read(opb,1); vb->nW=oggpack_read(opb,1); if(vb->nW==-1) return(OV_EBADPACKET); }else{ vb->lW=0; vb->nW=0; } /* more setup */ vb->granulepos=op->granulepos; vb->sequence=op->packetno-3; /* first block is third packet */ vb->eofflag=op->e_o_s; if(decodep && vi->channels<=CHANNELS) { vb->pcm = ipcm_vect; /* set pcm end point */ vb->pcmend=ci->blocksizes[vb->W]; /* use statically allocated buffer */ if(vd->reset_pcmb || vb->pcm[0]==NULL) { /* one-time initialisation at codec start NOT for every block synthesis start allows us to flip between buffers once initialised by simply flipping pointers */ for(i=0; i<vi->channels; i++) vb->pcm[i] = &vd->first_pcm[i*ci->blocksizes[1]]; } vd->reset_pcmb = false; /* unpack_header enforces range checking */ type=ci->map_type[ci->mode_param[mode]->mapping]; return(_mapping_P[type]->inverse(vb,b->mode[mode])); }else{ /* no pcm */ vb->pcmend=0; vb->pcm=NULL; return(0); } }
TarkinError tarkin_synthesis_packetin (TarkinStream * s, ogg_packet * op) { uint32_t i, layer_id, comp, data_len; uint32_t flags, junk; int nread; oggpack_buffer opb; TarkinPacket *packet; #ifdef DBG_OGG printf ("dbg_ogg: Reading packet n? %lld, granulepos %lld, len %ld, %s%s\n", op->packetno, op->granulepos, op->bytes, op->b_o_s ? "b_o_s" : "", op->e_o_s ? "e_o_s" : ""); #endif oggpack_readinit (&opb, op->packet, op->bytes); flags = oggpack_read (&opb, 8); layer_id = oggpack_read (&opb, 12); /* Theses are required for */ comp = oggpack_read (&opb, 12); /* data hole handling (or maybe * packetno would be enough ?) */ nread = 4; if (flags) { /* This is void "infinite future features" feature ;) */ if (flags & 1 << 7) { junk = flags; while (junk & 1 << 7) junk = oggpack_read (&opb, 8); /* allow for many future flags that must be correctly ordonned. */ } /* This shows how to get a feature's data: if (flags & TARKIN_FLAGS_EXAMPLE){ tp->example = oggpack_read(&opb,32); junk = tp->example & 3<<30; tp->example &= 0x4fffffff; } */ for (junk = 1 << 31; junk & 1 << 31;) /* and many future data */ while ((junk = oggpack_read (&opb, 32)) & 1 << 30); /* That is, feature data comes in 30 bit chunks. We also have * 31 potentially useful bits in last chunk. */ } nread = (opb.ptr - opb.buffer); data_len = op->bytes - nread; #ifdef DBG_OGG printf (" layer_id %d, comp %d, meta-data %dB, w3d data %dB.\n", layer_id, comp, nread, data_len); #endif /* We now have for shure our data. */ packet = &s->layer[layer_id].packet[comp]; if (packet->data_len) return (-TARKIN_UNUSED); /* Previous data wasn't used */ if (packet->storage < data_len) { packet->storage = data_len + 255; packet->data = REALLOC (packet->data, packet->storage); } for (i = 0; i < data_len; i++) packet->data[i] = oggpack_read (&opb, 8); packet->data_len = data_len; return (TARKIN_OK); }