⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 bitrate.c

📁 在x86平台上运行不可信任代码的sandbox。
💻 C
📖 第 1 页 / 共 2 页
字号:
/******************************************************************** *                                                                  * * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE.   * * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS     * * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE * * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING.       * *                                                                  * * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2002             * * by the XIPHOPHORUS Company http://www.xiph.org/                  * *                                                                  * ******************************************************************** function: bitrate tracking and management last mod: $Id: bitrate.c 1919 2005-07-24 14:18:04Z baford $ ********************************************************************/#include <stdio.h>#include <stdlib.h>#include <string.h>#include <math.h>#include <ogg/ogg.h>#include "vorbis/codec.h"#include "codec_internal.h"#include "os.h"#include "misc.h"#include "bitrate.h"static long BINBYTES(bitrate_manager_state *bm,long pos,long bin){  int bins=bm->queue_bins;  return(bm->queue_binned[pos*bins+bin]);}#define LIMITBYTES(pos,bin) (bm->minmax_binstack[(pos)*bins*2+((bin)+bins)])static long LACING_ADJUST(long bytes){  int addto=bytes/255+1;  return(bytes+addto);}static int floater_interpolate(bitrate_manager_state *bm,vorbis_info *vi,				  double desired_rate){  int bin=rint(bm->avgfloat);  double lobitrate,hibitrate;  lobitrate=(double)(bm->avg_binacc[bin]*8)/bm->avg_sampleacc*vi->rate;  while(lobitrate>desired_rate && bin>0){    bin--;    lobitrate=(double)(bm->avg_binacc[bin]*8)/bm->avg_sampleacc*vi->rate;  }  if(bin+1<bm->queue_bins){    hibitrate=(double)(bm->avg_binacc[bin+1]*8)/bm->avg_sampleacc*vi->rate;    if(fabs(hibitrate-desired_rate) < fabs(lobitrate-desired_rate))bin++;  }  return(bin);}/* try out a new limit */static long limit_sum(bitrate_manager_state *bm,int limit){  int i=bm->minmax_stackptr;  long acc=bm->minmax_acctotal;  long bins=bm->queue_bins;    acc-=LIMITBYTES(i,0);  acc+=LIMITBYTES(i,limit);  while(i-->0){    if(bm->minmax_limitstack[i]<=limit)break;    acc-=LIMITBYTES(i,bm->minmax_limitstack[i]);    acc+=LIMITBYTES(i,limit);  }  return(acc);}/* compute bitrate tracking setup, allocate circular packet size queue */void vorbis_bitrate_init(vorbis_info *vi,bitrate_manager_state *bm){  int i;  codec_setup_info *ci=vi->codec_setup;  bitrate_manager_info *bi=&ci->bi;  long maxlatency;  memset(bm,0,sizeof(*bm));    if(bi){        bm->avg_sampledesired=bi->queue_avg_time*vi->rate;    bm->avg_centerdesired=bi->queue_avg_time*vi->rate*bi->queue_avg_center;    bm->minmax_sampledesired=bi->queue_minmax_time*vi->rate;        /* first find the max possible needed queue size */    maxlatency=max(bm->avg_sampledesired-bm->avg_centerdesired,		   bm->minmax_sampledesired)+bm->avg_centerdesired;        if(maxlatency>0 &&       (bi->queue_avgmin>0 || bi->queue_avgmax>0 || bi->queue_hardmax>0 ||	bi->queue_hardmin>0)){      long maxpackets=maxlatency/(ci->blocksizes[0]>>1)+3;      long bins=PACKETBLOBS;            bm->queue_size=maxpackets;      bm->queue_bins=bins;      bm->queue_binned=_ogg_calloc(maxpackets,bins*sizeof(*bm->queue_binned));      bm->queue_actual=_ogg_calloc(maxpackets,sizeof(*bm->queue_actual));            if((bi->queue_avgmin>0 || bi->queue_avgmax>0) &&	 bi->queue_avg_time>0){		bm->avg_binacc=_ogg_calloc(bins,sizeof(*bm->avg_binacc));	bm->avgfloat=PACKETBLOBS/2;	      }else{	bm->avg_tail= -1;      }            if((bi->queue_hardmin>0 || bi->queue_hardmax>0) &&	 bi->queue_minmax_time>0){		bm->minmax_binstack=_ogg_calloc((bins*2+1)*bins*2,					sizeof(*bm->minmax_binstack));	bm->minmax_posstack=_ogg_calloc((bins*2+1),				      sizeof(*bm->minmax_posstack));	bm->minmax_limitstack=_ogg_calloc((bins*2+1),					  sizeof(*bm->minmax_limitstack));      }else{	bm->minmax_tail= -1;      }            /* space for the packet queueing */      bm->packetbuffers=_ogg_calloc(maxpackets,sizeof(*bm->packetbuffers));      bm->packets=_ogg_calloc(maxpackets,sizeof(*bm->packets));      for(i=0;i<maxpackets;i++)	oggpack_writeinit(bm->packetbuffers+i);          }else{      bm->packetbuffers=_ogg_calloc(1,sizeof(*bm->packetbuffers));      bm->packets=_ogg_calloc(1,sizeof(*bm->packets));      oggpack_writeinit(bm->packetbuffers);    }        }}void vorbis_bitrate_clear(bitrate_manager_state *bm){  int i;  if(bm){    if(bm->queue_binned)_ogg_free(bm->queue_binned);    if(bm->queue_actual)_ogg_free(bm->queue_actual);    if(bm->avg_binacc)_ogg_free(bm->avg_binacc);    if(bm->minmax_binstack)_ogg_free(bm->minmax_binstack);    if(bm->minmax_posstack)_ogg_free(bm->minmax_posstack);    if(bm->minmax_limitstack)_ogg_free(bm->minmax_limitstack);    if(bm->packetbuffers){      if(bm->queue_size==0){	oggpack_writeclear(bm->packetbuffers);      }else{	for(i=0;i<bm->queue_size;i++)	  oggpack_writeclear(bm->packetbuffers+i);	      }      _ogg_free(bm->packetbuffers);    }    if(bm->packets)_ogg_free(bm->packets);        memset(bm,0,sizeof(*bm));  }}int vorbis_bitrate_managed(vorbis_block *vb){  vorbis_dsp_state      *vd=vb->vd;  private_state         *b=vd->backend_state;   bitrate_manager_state *bm=&b->bms;  if(bm->queue_binned)return(1);  return(0);}/* finish taking in the block we just processed */int vorbis_bitrate_addblock(vorbis_block *vb){  int i;   vorbis_block_internal *vbi=vb->internal;  vorbis_dsp_state      *vd=vb->vd;  private_state         *b=vd->backend_state;   bitrate_manager_state *bm=&b->bms;  vorbis_info           *vi=vd->vi;  codec_setup_info      *ci=vi->codec_setup;  bitrate_manager_info  *bi=&ci->bi;  int                    eofflag=vb->eofflag;  int                    head=bm->queue_head;  int                    next_head=head+1;  int                    bins=bm->queue_bins;  int                    minmax_head,new_minmax_head;    ogg_uint32_t           *head_ptr;  oggpack_buffer          temp;  if(!bm->queue_binned){    oggpack_buffer temp;    /* not a bitrate managed stream, but for API simplicity, we'll       buffer one packet to keep the code path clean */        if(bm->queue_head)return(-1); /* one has been submitted without                                     being claimed */    bm->queue_head++;    bm->packets[0].packet=oggpack_get_buffer(&vb->opb);    bm->packets[0].bytes=oggpack_bytes(&vb->opb);    bm->packets[0].b_o_s=0;    bm->packets[0].e_o_s=vb->eofflag;    bm->packets[0].granulepos=vb->granulepos;    bm->packets[0].packetno=vb->sequence; /* for sake of completeness */    memcpy(&temp,bm->packetbuffers,sizeof(vb->opb));    memcpy(bm->packetbuffers,&vb->opb,sizeof(vb->opb));    memcpy(&vb->opb,&temp,sizeof(vb->opb));    return(0);  }  /* add encoded packet to head */  if(next_head>=bm->queue_size)next_head=0;  head_ptr=bm->queue_binned+bins*head;  /* is there room to add a block? In proper use of the API, this will     never come up... but guard it anyway */  if(next_head==bm->avg_tail || next_head==bm->minmax_tail)return(-1);  /* add the block to the toplevel queue */  bm->queue_head=next_head;  bm->queue_actual[head]=(vb->W?0x80000000UL:0);  /* buffer packet fields */  bm->packets[head].packet=oggpack_get_buffer(&vb->opb);  bm->packets[head].bytes=oggpack_bytes(&vb->opb);  bm->packets[head].b_o_s=0;  bm->packets[head].e_o_s=vb->eofflag;  bm->packets[head].granulepos=vb->granulepos;  bm->packets[head].packetno=vb->sequence; /* for sake of completeness */  /* swap packet buffers */  memcpy(&temp,bm->packetbuffers+head,sizeof(vb->opb));  memcpy(bm->packetbuffers+head,&vb->opb,sizeof(vb->opb));  memcpy(&vb->opb,&temp,sizeof(vb->opb));  /* save markers */  head_ptr[0]=vbi->packetblob_markers[0];  for(i=1;i<PACKETBLOBS;i++){    head_ptr[i]=vbi->packetblob_markers[i]-vbi->packetblob_markers[i-1];  }  if(bm->avg_binacc)    new_minmax_head=minmax_head=bm->avg_center;  else    new_minmax_head=minmax_head=head;  /* the average tracking queue is updated first; its results (if it's     in use) are taken into account by the min/max limiter (if min/max     is in use) */  if(bm->avg_binacc){    unsigned long desired_center=bm->avg_centerdesired;    if(eofflag)desired_center=0;    /* update the avg head */    for(i=0;i<bins;i++)

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -