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

📄 vorbisfile.c

📁 au1200 linux2.6.11 硬件解码mae驱动和maiplayer播放器源码
💻 C
📖 第 1 页 / 共 4 页
字号:
    /* This once read: return(rint(bits/ov_time_total(vf,-1)));     * gcc 3.x on x86 miscompiled this at optimisation level 2 and above,     * so this is slightly transformed to make it work.     */    return (long)(bits *1000 / ov_time_total(vf, - 1));  }  else   {    if (vf->seekable)    {      /* return the actual bitrate */      return (long)((vf->offsets[i + 1] - vf->dataoffsets[i]) *8000 / ov_time_total(vf, i));    }    else     {      /* return nominal if set */      if (vf->vi[i].bitrate_nominal > 0)      {        return vf->vi[i].bitrate_nominal;      }      else       {        if (vf->vi[i].bitrate_upper > 0)        {          if (vf->vi[i].bitrate_lower > 0)          {            return (vf->vi[i].bitrate_upper + vf->vi[i].bitrate_lower) / 2;          }          else           {            return vf->vi[i].bitrate_upper;          }        }        return (OV_FALSE);      }    }  }}/* returns the actual bitrate since last call.  returns -1 if no   additional data to offer since last call (or at beginning of stream),   EINVAL if stream is only partially open */long ov_bitrate_instant(OggVorbis_File *vf){         int link = (vf->seekable ? vf->current_link : 0);  long            ret;  if (vf->ready_state < OPENED)    return (OV_EINVAL);  if (vf->samptrack == 0)    return (OV_FALSE);  ret = (long)(vf->bittrack / vf->samptrack *vf->vi[link].rate);  vf->bittrack = 0;  vf->samptrack = 0;  return (ret);}/* Guess */long ov_serialnumber(OggVorbis_File *vf, int i){         if (i >= vf->links)    return (ov_serialnumber(vf, vf->links - 1));  if (!vf->seekable && i >= 0)    return (ov_serialnumber(vf, - 1));  if (i < 0)  {    return (vf->current_serialno);  }  else   {    return (vf->serialnos[i]);  }}/* returns: total raw (compressed) length of content if i==-1            raw (compressed) length of that logical bitstream for i==0 to n     OV_EINVAL if the stream is not seekable (we can't know the length)     or if stream is only partially open*/ogg_int64_t ov_raw_total(OggVorbis_File *vf, int i){         if (vf->ready_state < OPENED)    return (OV_EINVAL);  if (!vf->seekable || i >= vf->links)    return (OV_EINVAL);  if (i < 0)  {    ogg_int64_t     acc = 0;    int             i;    for (i = 0; i < vf->links; i++)    acc += ov_raw_total(vf, i);    return (acc);  }  else   {    return (vf->offsets[i + 1] - vf->offsets[i]);  }}/* returns: total PCM length (samples) of content if i==-1 PCM length     (samples) of that logical bitstream for i==0 to n     OV_EINVAL if the stream is not seekable (we can't know the     length) or only partially open */ogg_int64_t ov_pcm_total(OggVorbis_File *vf, int i){         if (vf->ready_state < OPENED)    return (OV_EINVAL);  if (!vf->seekable || i >= vf->links)    return (OV_EINVAL);  if (i < 0)  {    ogg_int64_t     acc = 0;    int             i;    for (i = 0; i < vf->links; i++)    acc += ov_pcm_total(vf, i);    return (acc);  }  else   {    return (vf->pcmlengths[i *2 + 1]);  }}/* returns: total milliseconds of content if i==-1            milliseconds in that logical bitstream for i==0 to n     OV_EINVAL if the stream is not seekable (we can't know the     length) or only partially open */ogg_int64_t ov_time_total(OggVorbis_File *vf, int i){         if (vf->ready_state < OPENED)    return (OV_EINVAL);  if (!vf->seekable || i >= vf->links)    return (OV_EINVAL);  if (i < 0)  {    ogg_int64_t     acc = 0;    int             i;    for (i = 0; i < vf->links; i++)    acc += ov_time_total(vf, i);    return (acc);  }  else   {    return (((ogg_int64_t) vf->pcmlengths[i *2 + 1]) *1000 / vf->vi[i].rate);  }}/* seek to an offset relative to the *compressed* data. This also   scans packets to update the PCM cursor. It will cross a logical   bitstream boundary, but only if it can't get any packets out of the   tail of the bitstream we seek to (so no surprises).   returns zero on success, nonzero on failure */int ov_raw_seek(OggVorbis_File *vf, ogg_int64_t pos){         ogg_stream_state *work_os = NULL;  ogg_page og =   {0, 0, 0, 0};  ogg_packet op =   {0, 0, 0, 0, 0, 0};  if (vf->ready_state < OPENED)    return (OV_EINVAL);  if (!vf->seekable)    return (OV_ENOSEEK); /* do not dump machine if we can't seek */  if (pos < 0 || pos > vf->end)    return (OV_EINVAL);  /* don't yet clear out decoding machine (if it's initialized), in     the case we're in the same link.  Restart the decode lapping, and     let _fetch_and_process_packet deal with a potential bitstream     boundary */  vf->pcm_offset = - 1;  ogg_stream_reset_serialno(vf->os, vf->current_serialno); /* must set serialno */  vorbis_synthesis_restart(&vf->vd);  _seek_helper(vf, pos);  /* we need to make sure the pcm_offset is set, but we don't want to     advance the raw cursor past good packets just to get to the first     with a granulepos.  That's not equivalent behavior to beginning     decoding as immediately after the seek position as possible.     So, a hack.  We use two stream states; a local scratch state and     the shared vf->os stream state.  We use the local state to     scan, and the shared state as a buffer for later decode.      Unfortuantely, on the last page we still advance to last packet     because the granulepos on the last page is not necessarily on a     packet boundary, and we need to make sure the granpos is     correct.   */  {    int             lastblock = 0;    int             accblock = 0;    int             thisblock;    int             eosflag;    work_os = ogg_stream_create(vf->current_serialno); /* get the memory ready */    while (1)    {      if (vf->ready_state >= STREAMSET)      {        /* snarf/scan a packet if we can */        int result = ogg_stream_packetout(work_os, &op);        if (result > 0)        {          if (vf->vi[vf->current_link].codec_setup)          {            thisblock = vorbis_packet_blocksize(vf->vi + vf->current_link, &op);            if (thisblock < 0)            {              ogg_stream_packetout(vf->os, NULL);              thisblock = 0;            }            else             {              if (eosflag)                ogg_stream_packetout(vf->os, NULL);              else if (lastblock)                accblock += (lastblock + thisblock) >> 2;            }            if (op.granulepos != - 1)            {              int             i, link = vf->current_link;              ogg_int64_t     granulepos = op.granulepos - vf->pcmlengths[link *2];              if (granulepos < 0)                granulepos = 0;              for (i = 0; i < link; i++)              granulepos += vf->pcmlengths[i *2 + 1];              vf->pcm_offset = granulepos - accblock;              break;            }            lastblock = thisblock;            continue;          }          else            ogg_stream_packetout(vf->os, NULL);        }      }      if (!lastblock)      {        if (_get_next_page(vf, &og, - 1) < 0)        {          vf->pcm_offset = ov_pcm_total(vf, - 1);          break;        }      }      else       {        /* huh?  Bogus stream with packets but no granulepos */        vf->pcm_offset = - 1;        break;      }      /* has our decoding just traversed a bitstream boundary? */      if (vf->ready_state >= STREAMSET)        if (vf->current_serialno != ogg_page_serialno(&og))        {          _decode_clear(vf); /* clear out stream state */          ogg_stream_destroy(work_os);        }      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)          goto seek_error; /* sign of a bogus stream.  error out, leave machine uninitialized */        vf->current_link = link;        ogg_stream_reset_serialno(vf->os, vf->current_serialno);        ogg_stream_reset_serialno(work_os, vf->current_serialno);        vf->ready_state = STREAMSET;      }      {        ogg_page        dup;        ogg_page_dup(&dup, &og);        eosflag = ogg_page_eos(&og);        ogg_stream_pagein(vf->os, &og);        ogg_stream_pagein(work_os, &dup);      }    }  }  ogg_packet_release(&op);  ogg_page_release(&og);  ogg_stream_destroy(work_os);  vf->bittrack = 0;  vf->samptrack = 0;  return (0);seek_error:  ogg_packet_release(&op);  ogg_page_release(&og);  /* dump the machine so we're in a known state */  vf->pcm_offset = - 1;  ogg_stream_destroy(work_os);  _decode_clear(vf);  return OV_EBADLINK;}/* Page granularity seek (faster than sample granularity because we   don't do the last bit of decode to find a specific sample).   Seek to the last [granule marked] page preceeding the specified pos   location, such that decoding past the returned point will quickly   arrive at the requested position. */int ov_pcm_seek_page(OggVorbis_File *vf, ogg_int64_t pos){         int             link = - 1;  ogg_int64_t     result = 0;  ogg_int64_t     total = ov_pcm_total(vf, - 1);  ogg_page og =   {0, 0, 0, 0};  ogg_packet op =   {0, 0, 0, 0, 0, 0};  if (vf->ready_state < OPENED)    return (OV_EINVAL);  if (!vf->seekable)    return (OV_ENOSEEK);  if (pos < 0 || pos > total)    return (OV_EINVAL);  /* which bitstream section does this pcm offset occur in? */  for (link = vf->links - 1; link >= 0; link--)  {    total -= vf->pcmlengths[link *2 + 1];    if (pos >= total)      break;  }  /* search within the logical bitstream for the page with the highest     pcm_pos preceeding (or equal to) pos.  There is a danger here;     missing pages or incorrect frame number information in the     bitstream could make our task impossible.  Account for that (it     would be an error condition) */  /* new search algorithm by HB (Nicholas Vinen) */  {    ogg_int64_t     end = vf->offsets[link + 1];    ogg_int64_t     begin = vf->offsets[link];    ogg_int64_t     begintime = vf->pcmlengths[link *2];    ogg_int64_t     endtime = vf->pcmlengths[link *2 + 1] + begintime;    ogg_int64_t     target = pos - total + begintime;    ogg_int64_t     best = begin;    while (begin < end)    {      ogg_int64_t     bisect;      if (end - begin < CHUNKSIZE)      {        bisect = begin;      }      else       {        /* take a (pretty decent) guess. */        bisect = begin + (target - begintime) *(end - begin) / (endtime - begintime) - CHUNKSIZE;        if (bisect <= begin)          bisect = begin + 1;      }      _seek_helper(vf, bisect);      while (begin < end)      {        result = _get_next_page(vf, &og, end - vf->offset);        if (result == OV_EREAD)          goto seek_error;        if (result < 0)        {          if (bisect <= begin + 1)            end = begin; /* found it */        else         {          if (bisect == 0)            goto seek_error;          bisect -= CHUNKSIZE;          if (bisect <= begin)            bisect = begin + 1;          _seek_helper(vf, bisect);        }        }        else         {          ogg_int64_t     granulepos = ogg_page_granulepos(&og);          if (granulepos == - 1)            continue;          if (granulepos < target)          {            best = result;  /* raw offset of packet with granulepos */                            begin = vf->offset; /* raw offset of next page */                            begintime = granulepos;            if (target - begintime > 44100)              break;            bisect = begin; /* *not* begin + 1 */          }          else           {            if (bisect <= begin + 1)              end = begin;  /* found it */          else           {            if (end == vf->offset)            {  /* we're pretty close - we'd be stuck in */              end = result;              bisect -= CHUNKSIZE; /* an endless loop otherwise. */              if (bisect <= begin)                bisect = begin + 1;              _seek_helper(vf, bisect);            }            else             {              end = result;              endtime = granulepos;              break;            }          }          }        }      }    }    /* found our page. seek to it, update pcm offset. Easier case than       raw_seek, don't keep packets preceeding granulepos. */    {       /* seek */       _seek_helper(vf, best);      vf->pcm_offset = - 1;      if (_get_next_page(vf, &og, - 1) < 0)      {        ogg_page_release(&og);        return (OV_EOF); /* shouldn't happen */      }      if (link != vf->current_link)      {        /* Different link; dump entire decode machine */        _decode_clear(vf);        vf->current_link = link;        vf->current_serialno = ogg_page_serialno(&og);        vf->ready_state = STREAMSET;

⌨️ 快捷键说明

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