📄 framing.c
字号:
ogg_stream_state os_en, os_de;ogg_sync_state oy;void checkpacket(ogg_packet *op,int len, int no, int pos){ long j; static int sequence=0; static int lastno=0; if(op->bytes!=len){ fprintf(stderr,"incorrect packet length!\n"); exit(1); } if(op->granulepos!=pos){ fprintf(stderr,"incorrect packet position!\n"); exit(1); } /* packet number just follows sequence/gap; adjust the input number for that */ if(no==0){ sequence=0; }else{ sequence++; if(no>lastno+1) sequence++; } lastno=no; if(op->packetno!=sequence){ fprintf(stderr,"incorrect packet sequence %ld != %d\n", (long)(op->packetno),sequence); exit(1); } /* Test data */ for(j=0;j<op->bytes;j++) if(op->packet[j]!=((j+no)&0xff)){ fprintf(stderr,"body data mismatch (1) at pos %ld: %x!=%lx!\n\n", j,op->packet[j],(j+no)&0xff); exit(1); }}void check_page(unsigned char *data,const int *header,ogg_page *og){ long j; /* Test data */ for(j=0;j<og->body_len;j++) if(og->body[j]!=data[j]){ fprintf(stderr,"body data mismatch (2) at pos %ld: %x!=%x!\n\n", j,data[j],og->body[j]); exit(1); } /* Test header */ for(j=0;j<og->header_len;j++){ if(og->header[j]!=header[j]){ fprintf(stderr,"header content mismatch at pos %ld:\n",j); for(j=0;j<header[26]+27;j++) fprintf(stderr," (%ld)%02x:%02x",j,header[j],og->header[j]); fprintf(stderr,"\n"); exit(1); } } if(og->header_len!=header[26]+27){ fprintf(stderr,"header length incorrect! (%ld!=%d)\n", og->header_len,header[26]+27); exit(1); }}void print_header(ogg_page *og){ int j; fprintf(stderr,"\nHEADER:\n"); fprintf(stderr," capture: %c %c %c %c version: %d flags: %x\n", og->header[0],og->header[1],og->header[2],og->header[3], (int)og->header[4],(int)og->header[5]); fprintf(stderr," granulepos: %d serialno: %d pageno: %ld\n", (og->header[9]<<24)|(og->header[8]<<16)| (og->header[7]<<8)|og->header[6], (og->header[17]<<24)|(og->header[16]<<16)| (og->header[15]<<8)|og->header[14], ((long)(og->header[21])<<24)|(og->header[20]<<16)| (og->header[19]<<8)|og->header[18]); fprintf(stderr," checksum: %02x:%02x:%02x:%02x\n segments: %d (", (int)og->header[22],(int)og->header[23], (int)og->header[24],(int)og->header[25], (int)og->header[26]); for(j=27;j<og->header_len;j++) fprintf(stderr,"%d ",(int)og->header[j]); fprintf(stderr,")\n\n");}void copy_page(ogg_page *og){ unsigned char *temp=_ogg_malloc(og->header_len); memcpy(temp,og->header,og->header_len); og->header=temp; temp=_ogg_malloc(og->body_len); memcpy(temp,og->body,og->body_len); og->body=temp;}void free_page(ogg_page *og){ _ogg_free (og->header); _ogg_free (og->body);}void error(void){ fprintf(stderr,"error!\n"); exit(1);}/* 17 only */const int head1_0[] = {0x4f,0x67,0x67,0x53,0,0x06, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x01,0x02,0x03,0x04,0,0,0,0, 0x15,0xed,0xec,0x91, 1, 17};/* 17, 254, 255, 256, 500, 510, 600 byte, pad */const int head1_1[] = {0x4f,0x67,0x67,0x53,0,0x02, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x01,0x02,0x03,0x04,0,0,0,0, 0x59,0x10,0x6c,0x2c, 1, 17};const int head2_1[] = {0x4f,0x67,0x67,0x53,0,0x04, 0x07,0x18,0x00,0x00,0x00,0x00,0x00,0x00, 0x01,0x02,0x03,0x04,1,0,0,0, 0x89,0x33,0x85,0xce, 13, 254,255,0,255,1,255,245,255,255,0, 255,255,90};/* nil packets; beginning,middle,end */const int head1_2[] = {0x4f,0x67,0x67,0x53,0,0x02, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x01,0x02,0x03,0x04,0,0,0,0, 0xff,0x7b,0x23,0x17, 1, 0};const int head2_2[] = {0x4f,0x67,0x67,0x53,0,0x04, 0x07,0x28,0x00,0x00,0x00,0x00,0x00,0x00, 0x01,0x02,0x03,0x04,1,0,0,0, 0x5c,0x3f,0x66,0xcb, 17, 17,254,255,0,0,255,1,0,255,245,255,255,0, 255,255,90,0};/* large initial packet */const int head1_3[] = {0x4f,0x67,0x67,0x53,0,0x02, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x01,0x02,0x03,0x04,0,0,0,0, 0x01,0x27,0x31,0xaa, 18, 255,255,255,255,255,255,255,255, 255,255,255,255,255,255,255,255,255,10};const int head2_3[] = {0x4f,0x67,0x67,0x53,0,0x04, 0x07,0x08,0x00,0x00,0x00,0x00,0x00,0x00, 0x01,0x02,0x03,0x04,1,0,0,0, 0x7f,0x4e,0x8a,0xd2, 4, 255,4,255,0};/* continuing packet test */const int head1_4[] = {0x4f,0x67,0x67,0x53,0,0x02, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x01,0x02,0x03,0x04,0,0,0,0, 0xff,0x7b,0x23,0x17, 1, 0};const int head2_4[] = {0x4f,0x67,0x67,0x53,0,0x00, 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, 0x01,0x02,0x03,0x04,1,0,0,0, 0x54,0x05,0x51,0xc8, 17, 255,255,255,255,255,255,255,255, 255,255,255,255,255,255,255,255,255};const int head3_4[] = {0x4f,0x67,0x67,0x53,0,0x05, 0x07,0x0c,0x00,0x00,0x00,0x00,0x00,0x00, 0x01,0x02,0x03,0x04,2,0,0,0, 0xc8,0xc3,0xcb,0xed, 5, 10,255,4,255,0};/* page with the 255 segment limit */const int head1_5[] = {0x4f,0x67,0x67,0x53,0,0x02, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x01,0x02,0x03,0x04,0,0,0,0, 0xff,0x7b,0x23,0x17, 1, 0};const int head2_5[] = {0x4f,0x67,0x67,0x53,0,0x00, 0x07,0xfc,0x03,0x00,0x00,0x00,0x00,0x00, 0x01,0x02,0x03,0x04,1,0,0,0, 0xed,0x2a,0x2e,0xa7, 255, 10,10,10,10,10,10,10,10, 10,10,10,10,10,10,10,10, 10,10,10,10,10,10,10,10, 10,10,10,10,10,10,10,10, 10,10,10,10,10,10,10,10, 10,10,10,10,10,10,10,10, 10,10,10,10,10,10,10,10, 10,10,10,10,10,10,10,10, 10,10,10,10,10,10,10,10, 10,10,10,10,10,10,10,10, 10,10,10,10,10,10,10,10, 10,10,10,10,10,10,10,10, 10,10,10,10,10,10,10,10, 10,10,10,10,10,10,10,10, 10,10,10,10,10,10,10,10, 10,10,10,10,10,10,10,10, 10,10,10,10,10,10,10,10, 10,10,10,10,10,10,10,10, 10,10,10,10,10,10,10,10, 10,10,10,10,10,10,10,10, 10,10,10,10,10,10,10,10, 10,10,10,10,10,10,10,10, 10,10,10,10,10,10,10,10, 10,10,10,10,10,10,10,10, 10,10,10,10,10,10,10,10, 10,10,10,10,10,10,10,10, 10,10,10,10,10,10,10,10, 10,10,10,10,10,10,10,10, 10,10,10,10,10,10,10,10, 10,10,10,10,10,10,10,10, 10,10,10,10,10,10,10,10, 10,10,10,10,10,10,10};const int head3_5[] = {0x4f,0x67,0x67,0x53,0,0x04, 0x07,0x00,0x04,0x00,0x00,0x00,0x00,0x00, 0x01,0x02,0x03,0x04,2,0,0,0, 0x6c,0x3b,0x82,0x3d, 1, 50};/* packet that overspans over an entire page */const int head1_6[] = {0x4f,0x67,0x67,0x53,0,0x02, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x01,0x02,0x03,0x04,0,0,0,0, 0xff,0x7b,0x23,0x17, 1, 0};const int head2_6[] = {0x4f,0x67,0x67,0x53,0,0x00, 0x07,0x04,0x00,0x00,0x00,0x00,0x00,0x00, 0x01,0x02,0x03,0x04,1,0,0,0, 0x3c,0xd9,0x4d,0x3f, 17, 100,255,255,255,255,255,255,255,255, 255,255,255,255,255,255,255,255};const int head3_6[] = {0x4f,0x67,0x67,0x53,0,0x01, 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, 0x01,0x02,0x03,0x04,2,0,0,0, 0x01,0xd2,0xe5,0xe5, 17, 255,255,255,255,255,255,255,255, 255,255,255,255,255,255,255,255,255};const int head4_6[] = {0x4f,0x67,0x67,0x53,0,0x05, 0x07,0x10,0x00,0x00,0x00,0x00,0x00,0x00, 0x01,0x02,0x03,0x04,3,0,0,0, 0xef,0xdd,0x88,0xde, 7, 255,255,75,255,4,255,0};/* packet that overspans over an entire page */const int head1_7[] = {0x4f,0x67,0x67,0x53,0,0x02, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x01,0x02,0x03,0x04,0,0,0,0, 0xff,0x7b,0x23,0x17, 1, 0};const int head2_7[] = {0x4f,0x67,0x67,0x53,0,0x00, 0x07,0x04,0x00,0x00,0x00,0x00,0x00,0x00, 0x01,0x02,0x03,0x04,1,0,0,0, 0x3c,0xd9,0x4d,0x3f, 17, 100,255,255,255,255,255,255,255,255, 255,255,255,255,255,255,255,255};const int head3_7[] = {0x4f,0x67,0x67,0x53,0,0x05, 0x07,0x08,0x00,0x00,0x00,0x00,0x00,0x00, 0x01,0x02,0x03,0x04,2,0,0,0, 0xd4,0xe0,0x60,0xe5, 1,0};void test_pack(const int *pl, const int **headers, int byteskip, int pageskip, int packetskip){ unsigned char *data=_ogg_malloc(1024*1024); /* for scripted test cases only */ long inptr=0; long outptr=0; long deptr=0; long depacket=0; long granule_pos=7,pageno=0; int i,j,packets,pageout=pageskip; int eosflag=0; int bosflag=0; int byteskipcount=0; ogg_stream_reset(&os_en); ogg_stream_reset(&os_de); ogg_sync_reset(&oy); for(packets=0;packets<packetskip;packets++) depacket+=pl[packets]; for(packets=0;;packets++)if(pl[packets]==-1)break; for(i=0;i<packets;i++){ /* construct a test packet */ ogg_packet op; int len=pl[i]; op.packet=data+inptr; op.bytes=len; op.e_o_s=(pl[i+1]<0?1:0); op.granulepos=granule_pos; granule_pos+=1024; for(j=0;j<len;j++)data[inptr++]=i+j; /* submit the test packet */ ogg_stream_packetin(&os_en,&op); /* retrieve any finished pages */ { ogg_page og; while(ogg_stream_pageout(&os_en,&og)){ /* We have a page. Check it carefully */ fprintf(stderr,"%ld, ",pageno); if(headers[pageno]==NULL){ fprintf(stderr,"coded too many pages!\n"); exit(1); } check_page(data+outptr,headers[pageno],&og); outptr+=og.body_len; pageno++; if(pageskip){ bosflag=1; pageskip--; deptr+=og.body_len; } /* have a complete page; submit it to sync/decode */ { ogg_page og_de; ogg_packet op_de,op_de2; char *buf=ogg_sync_buffer(&oy,og.header_len+og.body_len); char *next=buf; byteskipcount+=og.header_len; if(byteskipcount>byteskip){ memcpy(next,og.header,byteskipcount-byteskip); next+=byteskipcount-byteskip; byteskipcount=byteskip; } byteskipcount+=og.body_len; if(byteskipcount>byteskip){ memcpy(next,og.body,byteskipcount-byteskip); next+=byteskipcount-byteskip; byteskipcount=byteskip; } ogg_sync_wrote(&oy,next-buf); while(1){ int ret=ogg_sync_pageout(&oy,&og_de); if(ret==0)break; if(ret<0)continue; /* got a page. Happy happy. Verify that it's good. */ fprintf(stderr,"(%ld), ",pageout); check_page(data+deptr,headers[pageout],&og_de); deptr+=og_de.body_len; pageout++; /* submit it to deconstitution */ ogg_stream_pagein(&os_de,&og_de); /* packets out? */ while(ogg_stream_packetpeek(&os_de,&op_de2)>0){ ogg_stream_packetpeek(&os_de,NULL); ogg_stream_packetout(&os_de,&op_de); /* just catching them all */ /* verify peek and out match */ if(memcmp(&op_de,&op_de2,sizeof(op_de))){ fprintf(stderr,"packetout != packetpeek! pos=%ld\n", depacket); exit(1); } /* verify the packet! */ /* check data */ if(memcmp(data+depacket,op_de.packet,op_de.bytes)){ fprintf(stderr,"packet data mismatch in decode! pos=%ld\n", depacket); exit(1); } /* check bos flag */ if(bosflag==0 && op_de.b_o_s==0){ fprintf(stderr,"b_o_s flag not set on packet!\n"); exit(1); } if(bosflag && op_de.b_o_s){ fprintf(stderr,"b_o_s flag incorrectly set on packet!\n"); exit(1); } bosflag=1; depacket+=op_de.bytes; /* check eos flag */ if(eosflag){ fprintf(stderr,"Multiple decoded packets with eos flag!\n"); exit(1); } if(op_de.e_o_s)eosflag=1; /* check granulepos flag */ if(op_de.granulepos!=-1){ fprintf(stderr," granule:%ld ",(long)op_de.granulepos); } } } } } }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -