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

📄 framing.c

📁 betaplayer_0.096源码 tcpmp老版本
💻 C
📖 第 1 页 / 共 2 页
字号:
  0x89b8fd09,0x8d79e0be,0x803ac667,0x84fbdbd0,  0x9abc8bd5,0x9e7d9662,0x933eb0bb,0x97ffad0c,  0xafb010b1,0xab710d06,0xa6322bdf,0xa2f33668,  0xbcb4666d,0xb8757bda,0xb5365d03,0xb1f740b4};ogg_sync_state *ogg_sync_create(void){  ogg_sync_state *oy=_ogg_calloc(1,sizeof(*oy));  memset(oy,0,sizeof(*oy));  oy->bufferpool=ogg_buffer_create();  return oy;}int ogg_sync_destroy(ogg_sync_state *oy){  if(oy){    ogg_sync_reset(oy);    ogg_buffer_destroy(oy->bufferpool);    memset(oy,0,sizeof(*oy));    _ogg_free(oy);  }  return OGG_SUCCESS;}unsigned char *ogg_sync_bufferin(ogg_sync_state *oy, long bytes){  /* [allocate and] expose a buffer for data submission.     If there is no head fragment       allocate one and expose it     else       if the current head fragment has sufficient unused space         expose it       else         if the current head fragment is unused           resize and expose it         else           allocate new fragment and expose it  */  /* base case; fifo uninitialized */  if(!oy->fifo_head){    oy->fifo_head=oy->fifo_tail=ogg_buffer_alloc(oy->bufferpool,bytes);    return oy->fifo_head->buffer->data;  }    /* space left in current fragment case */  if(oy->fifo_head->buffer->size-     oy->fifo_head->length-     oy->fifo_head->begin >= bytes)    return oy->fifo_head->buffer->data+      oy->fifo_head->length+oy->fifo_head->begin;  /* current fragment is unused, but too small */  if(!oy->fifo_head->length){    ogg_buffer_realloc(oy->fifo_head,bytes);    return oy->fifo_head->buffer->data+oy->fifo_head->begin;  }    /* current fragment used/full; get new fragment */  {    ogg_reference *new=ogg_buffer_alloc(oy->bufferpool,bytes);    oy->fifo_head->next=new;    oy->fifo_head=new;  }  return oy->fifo_head->buffer->data;}int ogg_sync_wrote(ogg_sync_state *oy, long bytes){   if(!oy->fifo_head)return OGG_EINVAL;  if(oy->fifo_head->buffer->size-oy->fifo_head->length-oy->fifo_head->begin <      bytes)return OGG_EINVAL;  oy->fifo_head->length+=bytes;  oy->fifo_fill+=bytes;  return OGG_SUCCESS;}static ogg_uint32_t _checksum(ogg_reference *or, int bytes){  ogg_uint32_t crc_reg=0;  int j,post;  while(or){    unsigned char *data=or->buffer->data+or->begin;    post=(bytes<or->length?bytes:or->length);    for(j=0;j<post;++j)      crc_reg=(crc_reg<<8)^crc_lookup[((crc_reg >> 24)&0xff)^data[j]];    bytes-=j;    or=or->next;  }  return crc_reg;}/* sync the stream.  This is meant to be useful for finding page   boundaries.   return values for this:  -n) skipped n bytes   0) page not ready; more data (no bytes skipped)   n) page synced at current location; page length n bytes   */long ogg_sync_pageseek(ogg_sync_state *oy,ogg_page *og){  oggbyte_buffer page;  long           bytes,ret=0;  ogg_page_release(og);  bytes=oy->fifo_fill;  oggbyte_init(&page,oy->fifo_tail);  if(oy->headerbytes==0){    if(bytes<27)goto sync_out; /* not enough for even a minimal header */        /* verify capture pattern */    if(oggbyte_read1(&page,0)!=(int)'O' ||       oggbyte_read1(&page,1)!=(int)'g' ||       oggbyte_read1(&page,2)!=(int)'g' ||       oggbyte_read1(&page,3)!=(int)'S'    ) goto sync_fail;    oy->headerbytes=oggbyte_read1(&page,26)+27;  }  if(bytes<oy->headerbytes)goto sync_out; /* not enough for header +                                             seg table */  if(oy->bodybytes==0){    int i;    /* count up body length in the segment table */    for(i=0;i<oy->headerbytes-27;i++)      oy->bodybytes+=oggbyte_read1(&page,27+i);  }    if(oy->bodybytes+oy->headerbytes>bytes)goto sync_out;  /* we have what appears to be a complete page; last test: verify     checksum */  {    ogg_uint32_t chksum=oggbyte_read4(&page,22);    oggbyte_set4(&page,0,22);    /* Compare checksums; memory continues to be common access */    if(chksum!=_checksum(oy->fifo_tail,oy->bodybytes+oy->headerbytes)){            /* D'oh.  Mismatch! Corrupt page (or miscapture and not a page         at all). replace the computed checksum with the one actually         read in; remember all the memory is common access */            oggbyte_set4(&page,chksum,22);      goto sync_fail;    }    oggbyte_set4(&page,chksum,22);  }  /* We have a page.  Set up page return. */  if(og){    /* set up page output */    og->header=ogg_buffer_split(&oy->fifo_tail,&oy->fifo_head,oy->headerbytes);    og->header_len=oy->headerbytes;    og->body=ogg_buffer_split(&oy->fifo_tail,&oy->fifo_head,oy->bodybytes);    og->body_len=oy->bodybytes;  }else{    /* simply advance */    oy->fifo_tail=      ogg_buffer_pretruncate(oy->fifo_tail,oy->headerbytes+oy->bodybytes);    if(!oy->fifo_tail)oy->fifo_head=0;  }    ret=oy->headerbytes+oy->bodybytes;  oy->unsynced=0;  oy->headerbytes=0;  oy->bodybytes=0;  oy->fifo_fill-=ret;  return ret;   sync_fail:  oy->headerbytes=0;  oy->bodybytes=0;  oy->fifo_tail=ogg_buffer_pretruncate(oy->fifo_tail,1);  ret--;    /* search forward through fragments for possible capture */  while(oy->fifo_tail){    /* invariant: fifo_cursor points to a position in fifo_tail */    unsigned char *now=oy->fifo_tail->buffer->data+oy->fifo_tail->begin;    unsigned char *next=memchr(now, 'O', oy->fifo_tail->length);          if(next){      /* possible capture in this segment */      long bytes=next-now;      oy->fifo_tail=ogg_buffer_pretruncate(oy->fifo_tail,bytes);      ret-=bytes;      break;    }else{      /* no capture.  advance to next segment */      long bytes=oy->fifo_tail->length;      ret-=bytes;      oy->fifo_tail=ogg_buffer_pretruncate(oy->fifo_tail,bytes);    }  }  if(!oy->fifo_tail)oy->fifo_head=0;  oy->fifo_fill+=ret; sync_out:  return ret;}/* sync the stream and get a page.  Keep trying until we find a page.   Supress 'sync errors' after reporting the first.   return values:   OGG_HOLE) recapture (hole in data)          0) need more data          1) page returned   Returns pointers into buffered data; invalidated by next call to   _stream, _clear, _init, or _buffer */int ogg_sync_pageout(ogg_sync_state *oy, ogg_page *og){  /* all we need to do is verify a page at the head of the stream     buffer.  If it doesn't verify, we look for the next potential     frame */  while(1){    long ret=ogg_sync_pageseek(oy,og);    if(ret>0){      /* have a page */      return 1;    }    if(ret==0){      /* need more data */      return 0;    }        /* head did not start a synced page... skipped some bytes */    if(!oy->unsynced){      oy->unsynced=1;      return OGG_HOLE;    }    /* loop. keep looking */  }}/* clear things to an initial state.  Good to call, eg, before seeking */int ogg_sync_reset(ogg_sync_state *oy){  ogg_buffer_release(oy->fifo_tail);  oy->fifo_tail=0;  oy->fifo_head=0;  oy->fifo_fill=0;  oy->unsynced=0;  oy->headerbytes=0;  oy->bodybytes=0;  return OGG_SUCCESS;}ogg_stream_state *ogg_stream_create(int serialno){  ogg_stream_state *os=_ogg_calloc(1,sizeof(*os));  os->serialno=serialno;  os->pageno=-1;  return os;} int ogg_stream_destroy(ogg_stream_state *os){  if(os){    ogg_buffer_release(os->header_tail);    ogg_buffer_release(os->body_tail);    memset(os,0,sizeof(*os));      }  return OGG_SUCCESS;} #define FINFLAG 0x80000000UL#define FINMASK 0x7fffffffULstatic void _next_lace(oggbyte_buffer *ob,ogg_stream_state *os){  /* search ahead one lace */  os->body_fill_next=0;  while(os->laceptr<os->lacing_fill){    int val=oggbyte_read1(ob,27+os->laceptr++);    os->body_fill_next+=val;    if(val<255){      os->body_fill_next|=FINFLAG;      os->clearflag=1;      break;    }  }}static void _span_queued_page(ogg_stream_state *os){   while( !(os->body_fill&FINFLAG) ){        if(!os->header_tail)break;    /* first flush out preceeding page header (if any).  Body is       flushed as it's consumed, so that's not done here. */    if(os->lacing_fill>=0)      os->header_tail=ogg_buffer_pretruncate(os->header_tail,                                             os->lacing_fill+27);    os->lacing_fill=0;    os->laceptr=0;    os->clearflag=0;    if(!os->header_tail){      os->header_head=0;      break;    }else{            /* process/prepare next page, if any */      long pageno;      oggbyte_buffer ob;      ogg_page og;               /* only for parsing header values */      og.header=os->header_tail; /* only for parsing header values */      pageno=ogg_page_pageno(&og);      oggbyte_init(&ob,os->header_tail);      os->lacing_fill=oggbyte_read1(&ob,26);            /* are we in sequence? */      if(pageno!=os->pageno){        if(os->pageno==-1) /* indicates seek or reset */          os->holeflag=1;  /* set for internal use */        else          os->holeflag=2;  /* set for external reporting */        os->body_tail=ogg_buffer_pretruncate(os->body_tail,                                             os->body_fill);        if(os->body_tail==0)os->body_head=0;        os->body_fill=0;      }          if(ogg_page_continued(&og)){        if(os->body_fill==0){          /* continued packet, but no preceeding data to continue */          /* dump the first partial packet on the page */          _next_lace(&ob,os);             os->body_tail=            ogg_buffer_pretruncate(os->body_tail,os->body_fill_next&FINMASK);          if(os->body_tail==0)os->body_head=0;          /* set span flag */          if(!os->spanflag && !os->holeflag)os->spanflag=2;        }      }else{        if(os->body_fill>0){          /* preceeding data to continue, but not a continued page */          /* dump body_fill */          os->body_tail=ogg_buffer_pretruncate(os->body_tail,                                               os->body_fill);          if(os->body_tail==0)os->body_head=0;          os->body_fill=0;          /* set espan flag */          if(!os->spanflag && !os->holeflag)os->spanflag=2;        }      }      if(os->laceptr<os->lacing_fill){        os->granulepos=ogg_page_granulepos(&og);        /* get current packet size & flag */        _next_lace(&ob,os);        os->body_fill+=os->body_fill_next; /* addition handles the flag fine;                                             unsigned on purpose */        /* ...and next packet size & flag */        _next_lace(&ob,os);      }            os->pageno=pageno+1;      os->e_o_s=ogg_page_eos(&og);      os->b_o_s=ogg_page_bos(&og);        }  }}/* add the incoming page to the stream state; we decompose the page   into packet segments here as well. */int ogg_stream_pagein(ogg_stream_state *os, ogg_page *og){  int serialno=ogg_page_serialno(og);  int version=ogg_page_version(og);  /* check the serial number */  if(serialno!=os->serialno){    ogg_page_release(og);    return OGG_ESERIAL;  }  if(version>0){    ogg_page_release(og);    return OGG_EVERSION;  }  /* add to fifos */  if(!os->body_tail){    os->body_tail=og->body;    os->body_head=ogg_buffer_walk(og->body);  }else{    os->body_head=ogg_buffer_cat(os->body_head,og->body);  }  if(!os->header_tail){    os->header_tail=og->header;    os->header_head=ogg_buffer_walk(og->header);    os->lacing_fill=-27;  }else{    os->header_head=ogg_buffer_cat(os->header_head,og->header);  }  memset(og,0,sizeof(*og));  return OGG_SUCCESS;}int ogg_stream_reset(ogg_stream_state *os){  ogg_buffer_release(os->header_tail);  ogg_buffer_release(os->body_tail);  os->header_tail=os->header_head=0;  os->body_tail=os->body_head=0;  os->e_o_s=0;  os->b_o_s=0;  os->pageno=-1;  os->packetno=0;  os->granulepos=0;  os->body_fill=0;  os->lacing_fill=0;  os->holeflag=0;  os->spanflag=0;  os->clearflag=0;  os->laceptr=0;  os->body_fill_next=0;  return OGG_SUCCESS;}int ogg_stream_reset_serialno(ogg_stream_state *os,int serialno){  ogg_stream_reset(os);  os->serialno=serialno;  return OGG_SUCCESS;}static int _packetout(ogg_stream_state *os,ogg_packet *op,int adv){  ogg_packet_release(op);  _span_queued_page(os);  if(os->holeflag){    int temp=os->holeflag;    if(os->clearflag)      os->holeflag=0;    else      os->holeflag=1;    if(temp==2){      os->packetno++;      return OGG_HOLE;    }  }  if(os->spanflag){    int temp=os->spanflag;    if(os->clearflag)      os->spanflag=0;    else      os->spanflag=1;    if(temp==2){      os->packetno++;      return OGG_SPAN;    }  }  if(!(os->body_fill&FINFLAG)) return 0;  if(!op && !adv)return 1; /* just using peek as an inexpensive way                               to ask if there's a whole packet                               waiting */  if(op){    op->b_o_s=os->b_o_s;    if(os->e_o_s && os->body_fill_next==0)      op->e_o_s=os->e_o_s;    else      op->e_o_s=0;    if( (os->body_fill&FINFLAG) && !(os->body_fill_next&FINFLAG) )      op->granulepos=os->granulepos;    else      op->granulepos=-1;    op->packetno=os->packetno;  }  if(adv){    oggbyte_buffer ob;    oggbyte_init(&ob,os->header_tail);    /* split the body contents off */    if(op){      op->packet=ogg_buffer_split(&os->body_tail,&os->body_head,				  os->body_fill&FINMASK);      op->bytes=os->body_fill&FINMASK;    }else{      os->body_tail=ogg_buffer_pretruncate(os->body_tail,					   os->body_fill&FINMASK);      if(os->body_tail==0)os->body_head=0;    }    /* update lacing pointers */    os->body_fill=os->body_fill_next;    _next_lace(&ob,os);  }else{    if(op){      op->packet=ogg_buffer_sub(os->body_tail,0,os->body_fill&FINMASK);      op->bytes=os->body_fill&FINMASK;    }  }    if(adv){    os->packetno++;    os->b_o_s=0;  }  return 1;}int ogg_stream_packetout(ogg_stream_state *os,ogg_packet *op){  return _packetout(os,op,1);}int ogg_stream_packetpeek(ogg_stream_state *os,ogg_packet *op){  return _packetout(os,op,0);}int ogg_packet_release(ogg_packet *op) {  if(op){    ogg_buffer_release(op->packet);    memset(op, 0, sizeof(*op));  }  return OGG_SUCCESS;}int ogg_page_release(ogg_page *og) {  if(og){    ogg_buffer_release(og->header);    ogg_buffer_release(og->body);    memset(og, 0, sizeof(*og));  }  return OGG_SUCCESS;}void ogg_page_dup(ogg_page *dup,ogg_page *orig){  dup->header_len=orig->header_len;  dup->body_len=orig->body_len;  dup->header=ogg_buffer_dup(orig->header);  dup->body=ogg_buffer_dup(orig->body);}

⌨️ 快捷键说明

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