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

📄 vorbisfile.c

📁 au1200 linux2.6.11 硬件解码mae驱动和maiplayer播放器源码
💻 C
📖 第 1 页 / 共 4 页
字号:
      }      else       {        vorbis_synthesis_restart(&vf->vd);      }      ogg_stream_reset_serialno(vf->os, vf->current_serialno);      ogg_stream_pagein(vf->os, &og);      /* pull out all but last packet; the one with granulepos */      while (1)      {        result = ogg_stream_packetpeek(vf->os, &op);        if (result == 0)        {          /* !!! the packet finishing this page originated on a                       preceeding page. Keep fetching previous pages until we                       get one with a granulepos or without the 'continued' flag                       set.  Then just use raw_seek for simplicity. */          _seek_helper(vf, best);          while (1)          {            result = _get_prev_page(vf, &og);            if (result < 0)              goto seek_error;            if (ogg_page_granulepos(&og) > - 1 || !ogg_page_continued(&og))            {              return ov_raw_seek(vf, result);            }            vf->offset = result;          }        }        if (result < 0)        {          result = OV_EBADPACKET;          goto seek_error;        }        if (op.granulepos != - 1)        {          vf->pcm_offset = op.granulepos - vf->pcmlengths[vf->current_link *2];          if (vf->pcm_offset < 0)            vf->pcm_offset = 0;          vf->pcm_offset += total;          break;        }        else          result = ogg_stream_packetout(vf->os, NULL);      }    }  }  /* verify result */  if (vf->pcm_offset > pos || pos > ov_pcm_total(vf, - 1))  {    result = OV_EFAULT;    goto seek_error;  }  vf->bittrack = 0;  vf->samptrack = 0;  ogg_page_release(&og);  ogg_packet_release(&op);  return (0);seek_error:  ogg_page_release(&og);  ogg_packet_release(&op);  /* dump machine so we're in a known state */  vf->pcm_offset = - 1;  _decode_clear(vf);  return (int) result;}/* seek to a sample offset relative to the decompressed pcm stream    returns zero on success, nonzero on failure */int ov_pcm_seek(OggVorbis_File *vf, ogg_int64_t pos){         ogg_packet op = {0, 0, 0, 0, 0, 0};  ogg_page og =   {0, 0, 0, 0};  int             thisblock, lastblock = 0;  int             ret = ov_pcm_seek_page(vf, pos);  if (ret < 0)    return (ret);  _make_decode_ready(vf);  /* discard leading packets we don't need for the lapping of the     position we want; don't decode them */  while (1)  {    int             ret = ogg_stream_packetpeek(vf->os, &op);    if (ret > 0)    {      thisblock = vorbis_packet_blocksize(vf->vi + vf->current_link, &op);      if (thisblock < 0)      {        ogg_stream_packetout(vf->os, NULL);        continue; /* non audio packet */      }      if (lastblock)        vf->pcm_offset += (lastblock + thisblock) >> 2;      if (vf->pcm_offset + ((thisblock + vorbis_info_blocksize(vf->vi, 1)) >> 2) >= pos)        break;      /* remove the packet from packet queue and track its granulepos */      ogg_stream_packetout(vf->os, NULL);      vorbis_synthesis(&vf->vb, &op, 0);  /* set up a vb with                                                                                            only tracking, no                                                                                            pcm_decode */      vorbis_synthesis_blockin(&vf->vd, &vf->vb);/* end of logical stream case is hard, especially with exact                                                   length positioning. */      if (op.granulepos > - 1)      {        int             i;        /* always believe the stream markers */        vf->pcm_offset = op.granulepos - vf->pcmlengths[vf->current_link *2];        if (vf->pcm_offset < 0)          vf->pcm_offset = 0;        for (i = 0; i < vf->current_link; i++)        vf->pcm_offset += vf->pcmlengths[i *2 + 1];      }      lastblock = thisblock;    }    else     {      if (ret < 0 && ret != OV_HOLE)        break;      /* suck in a new page */      if (_get_next_page(vf, &og, - 1) < 0)        break;      if (vf->current_serialno != ogg_page_serialno(&og))        _decode_clear(vf);      if (vf->ready_state < STREAMSET)      {        int             link;        vf->current_serialno = ogg_page_serialno(&og);        for (link = 0; link < vf->links; link++)        if (vf->serialnos[link] == vf->current_serialno)          break;        if (link == vf->links)        {          ogg_page_release(&og);          ogg_packet_release(&op);          return (OV_EBADLINK);        }        vf->current_link = link;        ogg_stream_reset_serialno(vf->os, vf->current_serialno);        vf->ready_state = STREAMSET;        _make_decode_ready(vf);        lastblock = 0;      }      ogg_stream_pagein(vf->os, &og);    }  }  vf->bittrack = 0;  vf->samptrack = 0;  /* discard samples until we reach the desired position. Crossing a     logical bitstream boundary with abandon is OK. */  while (vf->pcm_offset < pos)  {    ogg_int64_t     target = pos - vf->pcm_offset;    long            samples = vorbis_synthesis_pcmout(&vf->vd, NULL);    if (samples > (long)target)      samples = (long)target;    vorbis_synthesis_read(&vf->vd, samples);    vf->pcm_offset += samples;    if (samples < target)      if (_fetch_and_process_packet(vf, 1, 1) <= 0)        vf->pcm_offset = ov_pcm_total(vf, - 1); /* eof */  }  ogg_page_release(&og);  ogg_packet_release(&op);  return 0;}/* seek to a playback time relative to the decompressed pcm stream    returns zero on success, nonzero on failure */int ov_time_seek(OggVorbis_File *vf, ogg_int64_t milliseconds){                /* translate time to PCM position and call ov_pcm_seek */  int             link = - 1;  ogg_int64_t     pcm_total = ov_pcm_total(vf, - 1);  ogg_int64_t     time_total = ov_time_total(vf, - 1);  if (vf->ready_state < OPENED)    return (OV_EINVAL);  if (!vf->seekable)    return (OV_ENOSEEK);  if (milliseconds < 0 || milliseconds > time_total)    return (OV_EINVAL);  /* which bitstream section does this time offset occur in? */  for (link = vf->links - 1; link >= 0; link--)  {    pcm_total -= vf->pcmlengths[link *2 + 1];    time_total -= ov_time_total(vf, link);    if (milliseconds >= time_total)      break;  }  /* enough information to convert time offset to pcm offset */  {    ogg_int64_t     target = pcm_total + (milliseconds - time_total) *vf->vi[link].rate / 1000;    return (ov_pcm_seek(vf, target));  }}/* page-granularity version of ov_time_seek    returns zero on success, nonzero on failure */int ov_time_seek_page(OggVorbis_File *vf, ogg_int64_t milliseconds){                /* translate time to PCM position and call ov_pcm_seek */  int             link = - 1;  ogg_int64_t     pcm_total = ov_pcm_total(vf, - 1);  ogg_int64_t     time_total = ov_time_total(vf, - 1);  if (vf->ready_state < OPENED)    return (OV_EINVAL);  if (!vf->seekable)    return (OV_ENOSEEK);  if (milliseconds < 0 || milliseconds > time_total)    return (OV_EINVAL);  /* which bitstream section does this time offset occur in? */  for (link = vf->links - 1; link >= 0; link--)  {    pcm_total -= vf->pcmlengths[link *2 + 1];    time_total -= ov_time_total(vf, link);    if (milliseconds >= time_total)      break;  }  /* enough information to convert time offset to pcm offset */  {    ogg_int64_t     target = pcm_total + (milliseconds - time_total) *vf->vi[link].rate / 1000;    return (ov_pcm_seek_page(vf, target));  }}/* tell the current stream offset cursor.  Note that seek followed by   tell will likely not give the set offset due to caching */ogg_int64_t ov_raw_tell(OggVorbis_File *vf){         if (vf->ready_state < OPENED)    return (OV_EINVAL);  return (vf->offset);}/* return PCM offset (sample) of next PCM sample to be read */ogg_int64_t ov_pcm_tell(OggVorbis_File *vf){         if (vf->ready_state < OPENED)    return (OV_EINVAL);  return (vf->pcm_offset);}/* return time offset (milliseconds) of next PCM sample to be read */ogg_int64_t ov_time_tell(OggVorbis_File *vf){         int             link = 0;  ogg_int64_t     pcm_total = 0;  ogg_int64_t     time_total = 0;  if (vf->ready_state < OPENED)    return (OV_EINVAL);  if (vf->seekable)  {    pcm_total = ov_pcm_total(vf, - 1);    time_total = ov_time_total(vf, - 1);    /* which bitstream section does this time offset occur in? */    for (link = vf->links - 1; link >= 0; link--)    {      pcm_total -= vf->pcmlengths[link *2 + 1];      time_total -= ov_time_total(vf, link);      if (vf->pcm_offset >= pcm_total)        break;    }  }  return (time_total + (1000 *vf->pcm_offset - pcm_total) / vf->vi[link].rate);}/*  link:   -1) return the vorbis_info struct for the bitstream section                currently being decoded           0-n) to request information for a specific bitstream section        In the case of a non-seekable bitstream, any call returns the    current bitstream.  NULL in the case that the machine is not    initialized */vorbis_info *ov_info(OggVorbis_File *vf, int link){         if (vf->seekable)  {    if (link < 0)      if (vf->ready_state >= STREAMSET)        return vf->vi + vf->current_link;      else        return vf->vi;    else if (link >= vf->links)      return NULL;    else      return vf->vi + link;  }  else   {    return vf->vi;  }}/* grr, strong typing, grr, no templates/inheritence, grr */vorbis_comment *ov_comment(OggVorbis_File *vf, int link){         if (vf->seekable)  {    if (link < 0)      if (vf->ready_state >= STREAMSET)        return vf->vc + vf->current_link;      else        return vf->vc;    else if (link >= vf->links)      return NULL;    else      return vf->vc + link;  }  else   {    return vf->vc;  }}static int ignore;static int ramp, rampinc, normal_bufsize;#define RAMP_MAX 16776960void ov_set_discon(vorbis_info *vi){  if ((normal_bufsize > 0) && (vi != NULL) && (vi->channels != 0))  {    ignore = vi->rate / normal_bufsize;    ramp = RAMP_MAX;    rampinc = -((ramp / vi->channels) / vi->rate);  }}/* up to this point, everything could more or less hide the multiple   logical bitstream nature of chaining from the toplevel application   if the toplevel application didn't particularly care.  However, at   the point that we actually read audio back, the multiple-section   nature must surface: Multiple bitstream sections do not necessarily   have to have the same number of channels or sampling rate.   ov_read returns the sequential logical bitstream number currently   being decoded along with the PCM data in order that the toplevel   application can take action on channel/sample rate changes.  This   number will be incremented even for streamed (non-seekable) streams   (for seekable streams, it represents the actual logical bitstream   index within the physical bitstream.  Note that the accessor   functions above are aware of this dichotomy).   input values: buffer) a buffer to hold packed PCM data for return   length) the byte length requested to be placed into buffer   return values: <0) error/hole in data (OV_HOLE), partial open (OV_EINVAL)                   0) EOF     n) number of bytes of PCM actually returned.  The     below works on a packet-by-packet basis, so the     return length is not related to the 'length' passed     in, just guaranteed to fit.     *section) set to the logical bitstream number */long ov_read(OggVorbis_File *vf, char *buffer, int bytes_req, int *bitstream){         int             i, j;  ogg_int32_t     **pcm;  long            samples;  if (vf->ready_state < OPENED)    return (OV_EINVAL);  while (1)  {    if (vf->ready_state == INITSET)    {      samples = vorbis_synthesis_pcmout(&vf->vd, &pcm);      if (samples)        break;    }    /* suck in another packet */    {      int ret = _fetch_and_process_packet(vf, 1, 1);      if (ret == OV_EOF)        return (0);      if (ret <= 0)        return (ret);    }  }  if (samples > 0)  {    /* yay! proceed to pack data into the byte buffer */    long channels = ov_info(vf, - 1)->channels;    if (channels == 1)    {      if (samples > (bytes_req / 2))        samples = bytes_req / 2;}    else     {      if (samples > (bytes_req / 4))        samples = bytes_req / 4;    }    for (i = 0; i < channels; i++)    {  /* It's faster in this order */      ogg_int32_t     *src = pcm[i];      short           *dest = ((short *) buffer) + i;      for (j = 0; j < samples; j++)      {        if (!ignore && ramp)              {          *dest = (short)(((int)((RAMP_MAX - ramp) >> 8) * (int)CLIP_TO_15(src[j] >> 9)) >> 16);          ramp += rampinc;          if (ramp < 0)            ramp = 0;        }        else          *dest = (short)(CLIP_TO_15(src[j] >> 9));        dest += channels;      }    }    vorbis_synthesis_read(&vf->vd, samples);    vf->pcm_offset += samples;    if (bitstream)      *bitstream = vf->current_link;    if (ignore)    {      ignore--;      return 0;    }    normal_bufsize = samples;    return samples * 2 * channels;  }  else   {    return (samples);  }}

⌨️ 快捷键说明

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