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

📄 vorbisfile.c

📁 au1200 linux2.6.11 硬件解码mae驱动和maiplayer播放器源码
💻 C
📖 第 1 页 / 共 4 页
字号:
  }  ogg_page_release(&og);}static void _make_decode_ready(OggVorbis_File *vf){         if (vf->ready_state != STREAMSET)    return;  if (vf->seekable)  {    vorbis_synthesis_init(&vf->vd, vf->vi + vf->current_link);  }  else   {    vorbis_synthesis_init(&vf->vd, vf->vi);  }  vorbis_block_init(&vf->vd, &vf->vb);  vf->ready_state = INITSET;  vf->bittrack = 0;  vf->samptrack = 0;  return;}static int _open_seekable2(OggVorbis_File *vf){         ogg_uint32_t    serialno = vf->current_serialno;  ogg_uint32_t    tempserialno;  ogg_int64_t     dataoffset = vf->offset, end;  ogg_page og =   {0, 0, 0, 0};  /* we're partially open and have a first link header state in storage in vf */  /* we can seek, so set out learning all about this file */  (vf->callbacks.seek_func)(vf->datasource, 0, SEEK_END);  vf->offset = vf->end = (vf->callbacks.tell_func)(vf->datasource);  /* We get the offset for the last page of the physical bitstream.     Most OggVorbis files will contain a single logical bitstream */  end = _get_prev_page(vf, &og);  if (end < 0)    return (int)(end);  /* more than one logical bitstream? */  tempserialno = ogg_page_serialno(&og);  ogg_page_release(&og);  if (tempserialno != serialno)  {     /* Chained bitstream. Bisect-search each logical bitstream        section.  Do so based on serial number only */    if (_bisect_forward_serialno(vf, 0, 0, end + 1, serialno, 0) < 0)      return (OV_EREAD);  }  else   {    /* Only one logical bitstream */    if (_bisect_forward_serialno(vf, 0, end, end + 1, serialno, 0))      return (OV_EREAD);  }  /* the initial header memory is referenced by vf after; don't free it */  _prefetch_all_headers(vf, dataoffset);  return (ov_raw_seek(vf, 0));}/* clear out the current logical bitstream decoder */static void _decode_clear(OggVorbis_File *vf){         vorbis_dsp_clear(&vf->vd);  vorbis_block_clear(&vf->vb);  vf->ready_state = OPENED;}/* fetch and process a packet.  Handles the case where we're at a   bitstream boundary and dumps the decoding machine.  If the decoding   machine is unloaded, it loads it.  It also keeps pcm_offset up to   date (seek and read both use this.  seek uses a special hack with   readp).    return: <0) error, OV_HOLE (lost packet) or OV_EOF            0) need more data (only if readp==0)     1) got a packet */static int _fetch_and_process_packet(OggVorbis_File *vf, int readp, int spanp){         ogg_page og =   {0, 0, 0, 0};  ogg_packet op =   {0, 0, 0, 0, 0, 0};  int             ret = 0;  /* handle one packet.  Try to fetch it from current stream state */  /* extract packets from page */  while (1)  {     /* process a packet if we can.  If the machine isn't loaded,        neither is a page */    if (vf->ready_state == INITSET)    {      while (1)      {        int             result = ogg_stream_packetout(vf->os, &op);        ogg_int64_t     granulepos;        if (result < 0)        {          ret = OV_HOLE; /* hole in the data. */          goto cleanup;        }        if (result > 0)        {          /* got a packet.  process it */          granulepos = op.granulepos;          if (!vorbis_synthesis(&vf->vb, &op, 1))          {  /* lazy check for lazy                         header handling.  The                         header packets aren't                         audio, so if/when we                         submit them,                         vorbis_synthesis will                         reject them */            /* suck in the synthesis data and track bitrate */            {              int             oldsamples = vorbis_synthesis_pcmout(&vf->vd, NULL);              /* for proper use of libvorbis within libvorbisfile,                 oldsamples will always be zero. */              if (oldsamples)              {                ret = OV_EFAULT;                goto cleanup;              }              vorbis_synthesis_blockin(&vf->vd, &vf->vb);              vf->samptrack += vorbis_synthesis_pcmout(&vf->vd, NULL) - oldsamples;              vf->bittrack += op.bytes *8;            }     /* update the pcm offset. */            if (granulepos != - 1 && !op.e_o_s)            {              int link = (vf->seekable ? vf->current_link : 0);              int             i, samples;       /* this packet has a pcm_offset on it (the last packet          completed on a page carries the offset) After processing          (above), we know the pcm position of the *last* sample          ready to be returned. Find the offset of the *first*          As an aside, this trick is inaccurate if we begin          reading anew right at the last page; the end-of-stream          granulepos declares the last frame in the stream, and the          last packet of the last page may be a partial frame.          So, we need a previous granulepos from an in-sequence page          to have a reference point.  Thus the !op.e_o_s clause          above */              if (vf->seekable && link > 0)                granulepos -= vf->pcmlengths[link *2];              if (granulepos < 0)                granulepos = 0; /* actually, this                                   should not be possible                                   here unless the stream                                   is very broken */              samples = vorbis_synthesis_pcmout(&vf->vd, NULL);              granulepos -= samples;              for (i = 0; i < link; i++)              granulepos += vf->pcmlengths[i *2 + 1];              vf->pcm_offset = granulepos;            }            ret = 1;            goto cleanup;          }        }        else          break;      }    }    if (vf->ready_state >= OPENED)    {      int             ret;      if (!readp)      {        ret = 0;        goto cleanup;      }      if ((ret = (int)_get_next_page(vf, &og, - 1)) < 0)      {        ret = OV_EOF; /* eof. leave unitialized */        goto cleanup;      }      /* bitrate tracking; add the header's bytes here, the body bytes         are done by packet above */      vf->bittrack += og.header_len *8;      /* has our decoding just traversed a bitstream boundary? */      if (vf->ready_state == INITSET)      {        if (vf->current_serialno != ogg_page_serialno(&og))        {          if (!spanp)          {            ret = OV_EOF;            goto cleanup;          }          _decode_clear(vf);          if (!vf->seekable)          {            vorbis_info_clear(vf->vi);            vorbis_comment_clear(vf->vc);          }        }      }    }    /* Do we need to load a new machine before submitting the page? */    /* This is different in the seekable and non-seekable cases.         In the seekable case, we already have all the header       information loaded and cached; we just initialize the machine       with it and continue on our merry way.       In the non-seekable (streaming) case, we'll only be at a       boundary if we just left the previous logical bitstream and       we're now nominally at the header of the next bitstream    */    if (vf->ready_state != INITSET)    {int              link;      if (vf->ready_state < STREAMSET)      {        if (vf->seekable)        {          vf->current_serialno = ogg_page_serialno(&og);          /* match the serialno to bitstream section.  We use this rather than             offset positions to avoid problems near logical bitstream             boundaries */          for (link = 0; link < vf->links; link++)          if (vf->serialnos[link] == vf->current_serialno)            break;          if (link == vf->links)          {            ret = OV_EBADLINK; /* sign of a bogus stream.  error out, leave machine uninitialized */            goto cleanup;          }          vf->current_link = link;          ogg_stream_reset_serialno(vf->os, vf->current_serialno);          vf->ready_state = STREAMSET;        }        else         {          /* we're streaming */          /* fetch the three header packets, build the info struct */          int ret = _fetch_headers(vf, vf->vi, vf->vc, &vf->current_serialno, &og);          if (ret)            goto cleanup;          vf->current_link++;          link = 0;        }      }      _make_decode_ready(vf);    }    ogg_stream_pagein(vf->os, &og);  }cleanup:  ogg_packet_release(&op);  ogg_page_release(&og);  return ret;}/* if, eg, 64 bit stdio is configured by default, this will build with fseek64 */static int _ov_open1(void *f, OggVorbis_File *vf, char *initial, long ibytes, ov_callbacks callbacks){         int offsettest = (f ? callbacks.seek_func(f, 0, SEEK_CUR) : - 1);  int             ret;  memset(vf, 0, sizeof(*vf));  vf->datasource = f;  vf->callbacks = callbacks;  /* init the framing state */  vf->oy = ogg_sync_create();  /* perhaps some data was previously read into a buffer for testing     against other stream types.  Allow initialization from this     previously read data (as we may be reading from a non-seekable     stream) */  if (initial)  {    char            *buffer = ogg_sync_bufferin(vf->oy, ibytes);    memcpy(buffer, initial, ibytes);    ogg_sync_wrote(vf->oy, ibytes);  }  /* can we seek? Stevens suggests the seek test was portable */  if (offsettest != - 1)    vf->seekable = 1;  /* No seeking yet; Set up a 'single' (current) logical bitstream     entry for partial open */  vf->links = 1;  vf->vi = _ogg_calloc(vf->links, sizeof(*vf->vi));  vf->vc = _ogg_calloc(vf->links, sizeof(*vf->vc));  vf->os = ogg_stream_create(- 1); /* fill in the serialno later */  /* Try to fetch the headers, maintaining all the storage */  if ((ret = _fetch_headers(vf, vf->vi, vf->vc, &vf->current_serialno, NULL)) < 0)  {    vf->datasource = NULL;    ov_clear(vf);  }  else if (vf->ready_state < PARTOPEN)    vf->ready_state = PARTOPEN;  return (ret);}static int _ov_open2(OggVorbis_File *vf){         if (vf->ready_state < OPENED)    vf->ready_state = OPENED;  if (vf->seekable)  {    int             ret = _open_seekable2(vf);    if (ret)    {      vf->datasource = NULL;      ov_clear(vf);    }    return (ret);  }  return 0;}/* clear out the OggVorbis_File struct */int ov_clear(OggVorbis_File *vf){         if (vf)  {    vorbis_block_clear(&vf->vb);    vorbis_dsp_clear(&vf->vd);    ogg_stream_destroy(vf->os);    if (vf->vi && vf->links)    {      int             i;      for (i = 0; i < vf->links; i++)      {        vorbis_info_clear(vf->vi + i);        vorbis_comment_clear(vf->vc + i);      }      _ogg_free(vf->vi);      _ogg_free(vf->vc);    }    if (vf->dataoffsets)      _ogg_free(vf->dataoffsets);    if (vf->pcmlengths)      _ogg_free(vf->pcmlengths);    if (vf->serialnos)      _ogg_free(vf->serialnos);    if (vf->offsets)      _ogg_free(vf->offsets);    ogg_sync_destroy(vf->oy);    if (vf->datasource)      (vf->callbacks.close_func)(vf->datasource);    memset(vf, 0, sizeof(*vf));  }#ifdef DEBUG_LEAKS  _VDBG_dump();#endif  return (0);}/* inspects the OggVorbis file and finds/documents all the logical   bitstreams contained in it.  Tries to be tolerant of logical   bitstream sections that are truncated/woogie.    return: -1  error            0  OK*/int ov_open_callbacks(void *f, OggVorbis_File *vf, char *initial, long ibytes, ov_callbacks callbacks){         int ret = _ov_open1(f, vf, initial, ibytes, callbacks);  if (ret)    return ret;  return _ov_open2(vf);}int ov_open(FILE *f, OggVorbis_File *vf, char *initial, long ibytes){         ov_callbacks callbacks =   {    (size_t(*)(void *, size_t, size_t, void *)) wrap_fread, (int (*)(void *, ogg_int64_t, int)) fseek64_wrap, (int (*)(void *)) wrap_fclose, (long (*)(void *)) wrap_ftell  };  return ov_open_callbacks((void *) f, vf, initial, ibytes, callbacks);}/* Only partially open the vorbis file; test for Vorbisness, and load   the headers for the first chain.  Do not seek (although test for   seekability).  Use ov_test_open to finish opening the file, else   ov_clear to close/free it. Same return codes as open. */int ov_test_callbacks(void *f, OggVorbis_File *vf, char *initial, long ibytes, ov_callbacks callbacks){         return _ov_open1(f, vf, initial, ibytes, callbacks);}int ov_test(FILE *f, OggVorbis_File *vf, char *initial, long ibytes){         ov_callbacks callbacks =   {    (size_t(*)(void *, size_t, size_t, void *)) wrap_fread, (int (*)(void *, ogg_int64_t, int)) fseek64_wrap, (int (*)(void *)) wrap_fclose, (long (*)(void *)) wrap_ftell  };  return ov_test_callbacks((void *) f, vf, initial, ibytes, callbacks);}int ov_test_open(OggVorbis_File *vf){         if (vf->ready_state != PARTOPEN)    return (OV_EINVAL);  return _ov_open2(vf);}/* How many logical bitstreams in this physical bitstream? */long ov_streams(OggVorbis_File *vf){         return vf->links;}/* Is the FILE * associated with vf seekable? */long ov_seekable(OggVorbis_File *vf){         return vf->seekable;}/* returns the bitrate for a given logical bitstream or the entire   physical bitstream.  If the file is open for random access, it will   find the *actual* average bitrate.  If the file is streaming, it   returns the nominal bitrate (if set) else the average of the   upper/lower bounds (if set) else -1 (unset).   If you want the actual bitrate field settings, get them from the   vorbis_info structs */long ov_bitrate(OggVorbis_File *vf, int i){         if (vf->ready_state < OPENED)    return (OV_EINVAL);  if (i >= vf->links)    return (OV_EINVAL);  if (!vf->seekable && i != 0)    return (ov_bitrate(vf, 0));  if (i < 0)  {    ogg_int64_t     bits = 0;    int             i;    for (i = 0; i < vf->links; i++)    bits += (vf->offsets[i + 1] - vf->dataoffsets[i]) *8;

⌨️ 快捷键说明

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