1 /********************************************************************
3 * THIS FILE IS PART OF THE Ogg Vorbis SOFTWARE CODEC SOURCE CODE. *
4 * USE, DISTRIBUTION AND REPRODUCTION OF THIS SOURCE IS GOVERNED BY *
5 * THE GNU PUBLIC LICENSE 2, WHICH IS INCLUDED WITH THIS SOURCE. *
6 * PLEASE READ THESE TERMS DISTRIBUTING. *
8 * THE OggSQUISH SOURCE CODE IS (C) COPYRIGHT 1994-1999 *
9 * by 1999 Monty <monty@xiph.org> and The XIPHOPHORUS Company *
10 * http://www.xiph.org/ *
12 ********************************************************************
14 function: code raw Vorbis packets into framed vorbis stream and
15 decode vorbis streams back into raw packets
16 author: Monty <xiphmont@mit.edu>
17 modifications by: Monty
18 last modification date: Jul 10 1999
20 note: The CRC code is directly derived from public domain code by
21 Ross Williams (ross@guest.adelaide.edu.au). See framing.txt for
24 ********************************************************************/
26 static const char rcsid[] = "$Id";
32 /* A complete description of Vorbis framing exists in docs/framing.txt */
34 /* helper to initialize lookup for direct-table CRC */
35 static unsigned size32 _vorbis_crc_entry(unsigned long index){
42 r = (r << 1) ^ 0x04c11db7; /* The same as the ethernet generator
43 polynomial, although we use an
44 unreflected alg and an init/final
45 of 0, not 0xffffffff */
48 return (r & 0xffffffffUL);
51 int vorbis_stream_init(vorbis_stream_state *vs,int serialno){
54 memset(vs,0,sizeof(vorbis_stream_state));
55 vs->body_storage=16*1024;
56 vs->body_data=malloc(vs->body_storage*sizeof(char));
58 vs->lacing_storage=1024;
59 vs->lacing_vals=malloc(vs->lacing_storage*sizeof(int));
60 vs->pcm_vals=malloc(vs->lacing_storage*sizeof(size64));
62 /* initialize the crc_lookup table */
64 vs->crc_lookup[i]=_vorbis_crc_entry((unsigned long)i);
66 vs->serialno=serialno;
73 /* _clear does not free vs, only the non-flat storage within */
74 int vorbis_stream_clear(vorbis_stream_state *vs){
76 if(vs->body_data)free(vs->body_data);
77 if(vs->lacing_vals)free(vs->lacing_vals);
78 if(vs->pcm_vals)free(vs->pcm_vals);
80 memset(vs,0,sizeof(vorbis_stream_state));
85 int vorbis_stream_destroy(vorbis_stream_state *vs){
87 vorbis_stream_clear(vs);
93 /* Helpers for vorbis_stream_encode; this keeps the structure and
94 what's happening fairly clear */
96 /* checksum the page */
97 /* Direct table CRC; note that this will be faster in the future if we
98 perform the checksum silmultaneously with other copies */
100 static void _vs_checksum(vorbis_stream_state *vs,vorbis_page *vg){
101 unsigned size32 crc_reg=0;
102 unsigned size32 *lookup=vs->crc_lookup;
105 for(i=0;i<vg->header_len;i++)
106 crc_reg=(crc_reg<<8)^lookup[((crc_reg >> 24)&0xff)^vg->header[i]];
107 for(i=0;i<vg->body_len;i++)
108 crc_reg=(crc_reg<<8)^lookup[((crc_reg >> 24)&0xff)^vg->body[i]];
110 vg->header[22]=crc_reg&0xff;
111 vg->header[23]=(crc_reg>>8)&0xff;
112 vg->header[24]=(crc_reg>>16)&0xff;
113 vg->header[25]=(crc_reg>>24)&0xff;
116 /* submit data to the internal buffer of the framing engine */
117 int vorbis_stream_encode(vorbis_stream_state *vs,vorbis_packet *vp){
118 int lacing_vals=vp->bytes/255+1,i;
120 /* make sure we have the buffer storage */
121 if(vs->body_storage<=vs->body_fill+vp->bytes){
122 vs->body_storage+=(vp->bytes+1024);
123 vs->body_data=realloc(vs->body_data,vs->body_storage);
125 if(vs->lacing_storage<=vs->lacing_fill+lacing_vals){
126 vs->lacing_storage+=(lacing_vals+32);
127 vs->lacing_vals=realloc(vs->lacing_vals,vs->lacing_storage*sizeof(int));
128 vs->pcm_vals=realloc(vs->pcm_vals,vs->lacing_storage*sizeof(size64));
131 /* Copy in the submitted packet. Yes, the copy is a waste; this is
132 the liability of overly clean abstraction for the time being. It
133 will actually be fairly easy to eliminate the extra copy in the
136 memcpy(vs->body_data+vs->body_fill,vp->packet,vp->bytes);
137 vs->body_fill+=vp->bytes;
139 /* Store lacing vals for this packet */
140 for(i=0;i<lacing_vals-1;i++){
141 vs->lacing_vals[vs->lacing_fill+i]=255;
142 vs->pcm_vals[vs->lacing_fill+i]=vp->pcm_pos;
144 vs->lacing_vals[vs->lacing_fill+i]=(vp->bytes)%255;
145 vs->pcm_vals[vs->lacing_fill+i]=vp->pcm_pos;
147 /* flag the first segment as the beginning of the packet */
148 vs->lacing_vals[vs->lacing_fill]|= 0x100;
150 vs->lacing_fill+=lacing_vals;
152 if(vp->e_o_s)vs->e_o_s=1;
157 /* This constructs pages from buffered packet segments. The pointers
158 returned are to static buffers; do not free. The returned buffers are
159 good only until the next call (using the same vs) */
161 int vorbis_stream_page(vorbis_stream_state *vs, vorbis_page *vg){
164 if(vs->body_returned){
165 /* advance packet data according to the body_returned pointer. We
166 had to keep it around to return a pointer into the buffer last
169 vs->body_fill-=vs->body_returned;
170 memmove(vs->body_data,vs->body_data+vs->body_returned,
171 vs->body_fill*sizeof(char));
175 if((vs->e_o_s&&vs->lacing_fill) ||
176 vs->body_fill > 4096 ||
177 vs->lacing_fill>=255){
179 int maxvals=(vs->lacing_fill>255?255:vs->lacing_fill);
182 /* construct a page */
183 /* decide how many segments to include */
184 for(vals=0;vals<maxvals;vals++){
186 acc+=vs->lacing_vals[vals]&0x0ff;
189 /* construct the header in temp storage */
190 memcpy(vs->header,"OggS",4);
192 /* stream structure version */
196 /* Ah, this is the first page */
199 if(vs->lacing_vals[0]&0x100){
200 /* The first packet segment is the beginning of a packet */
208 /* 64 bits of PCM position */
210 size64 pcm_pos=vs->pcm_vals[vals-1];
213 vs->header[i]=(pcm_pos&0xff);
218 /* 32 bits of stream serial number */
220 long serialno=vs->serialno;
222 vs->header[i]=(serialno&0xff);
227 /* 32 bits of page counter (we have both counter and page header
228 because this val can roll over) */
230 long pageno=vs->pageno++;
232 vs->header[i]=(pageno&0xff);
237 /* zero for computation; filled in later */
244 vs->header[26]=vals&0xff;
246 bytes+=vs->header[i+27]=(vs->lacing_vals[i]&0xff);
248 /* advance the lacing data and set the body_returned pointer */
250 vs->lacing_fill-=vals;
251 memmove(vs->lacing_vals,vs->lacing_vals+vals,vs->lacing_fill*sizeof(int));
252 memmove(vs->pcm_vals,vs->pcm_vals+vals,vs->lacing_fill*sizeof(size64));
253 vs->body_returned=bytes;
255 /* set pointers in the vorbis_page struct */
256 vg->header=vs->header;
257 vg->header_len=vs->headerbytes=vals+27;
258 vg->body=vs->body_data;
261 /* calculate the checksum */
268 /* not enough data to construct a page and not end of stream */
272 int vorbis_stream_eof(vorbis_stream_state *vs){
276 /* DECODING PRIMITIVES: packet streaming layer **********************/
278 /* Accepts data for decoding; syncs and frames the bitstream, then
279 decodes pages into packets. Works through errors and dropouts,
280 reporting holes/errors in the bitstream when the missing/corrupt
281 packet is requested by vorbis_stream_packet(). Call with size=-1
284 /* all below: <0 error, 0 not enough data, >0 success */
286 int vorbis_stream_decode(vorbis_stream_state *vs,char *stream,int size){
287 /* beginning a page? ie, no header started yet?*/
295 size64 vorbis_stream_pcmpos(vorbis_stream_state *vs){
298 size64 vorbis_stream_pageno(vorbis_stream_state *vs){
301 int vorbis_stream_skippage(vorbis_stream_state *vs){
304 int vorbis_stream_clearbuf(vorbis_stream_state *vs){
307 int vorbis_stream_packet(vorbis_stream_state *vs,vorbis_packet *vp){
313 void test_pack(vorbis_stream_state *vs,int *pl, int **headers){
314 unsigned char *data=malloc(1024*1024); /* for scripted test cases only */
318 int i,j,packets,pageno=0;
320 for(packets=0;;packets++)if(pl[packets]==-1)break;
322 for(i=0;i<packets;i++){
323 /* construct a test packet */
327 vp.packet=data+inptr;
329 vp.e_o_s=(pl[i+1]<0?1:0);
334 for(j=0;j<len;j++)data[inptr++]=i+j;
336 /* submit the test packet */
337 vorbis_stream_encode(vs,&vp);
339 /* retrieve any finished pages */
343 while(vorbis_stream_page(vs,&vg)){
344 /* We have a page. Check it carefully */
346 fprintf(stderr,"%d, ",pageno);
348 if(headers[pageno]==NULL){
349 fprintf(stderr,"coded too many pages!\n");
354 for(j=0;j<vg.body_len;j++)
355 if(vg.body[j]!=(data+outptr)[j]){
356 fprintf(stderr,"body data mismatch at pos %ld: %x!=%x!\n\n",
357 outptr+j,(data+outptr)[j],vg.body[j]);
363 for(j=0;j<vg.header_len;j++){
364 if(vg.header[j]!=headers[pageno][j]){
365 fprintf(stderr,"header content mismatch at pos %ld:\n",j);
366 for(j=0;j<headers[pageno][26]+27;j++)
367 fprintf(stderr," (%d)%02x:%02x",j,headers[pageno][j],vg.header[j]);
368 fprintf(stderr,"\n");
372 if(vg.header_len!=headers[pageno][26]+27){
373 fprintf(stderr,"header length incorrect! (%ld!=%d)\n",
374 vg.header_len,headers[pageno][26]+27);
382 if(headers[pageno]!=NULL){
383 fprintf(stderr,"did not write last page!\n");
387 fprintf(stderr,"packet data incomplete!\n");
390 fprintf(stderr,"ok.\n");
394 vorbis_stream_state vs;
396 /* Exercise each code path in the framing code. Also verify that
397 the checksums are working. */
400 /* 17, 254, 255, 256, 500, 510, 600 byte, pad */
401 int packets[]={17, 254, 255, 256, 500, 510, 600, -1};
402 int head1[] = {0x4f,0x67,0x67,0x53,0,0,
403 0x00,0x18,0x00,0x00,0x00,0x00,0x00,0x00,
404 0x01,0x02,0x03,0x04,0,0,0,0,
407 17,254,255,0,255,1,255,245,255,255,0,
409 int *headret[]={head1,NULL};
411 vorbis_stream_init(&vs,0x04030201);
412 fprintf(stderr,"testing basic page encoding... ");
413 test_pack(&vs,packets,headret);
414 vorbis_stream_clear(&vs);
418 /* nil packets; beginning,middle,end */
419 int packets[]={0,17, 254, 255, 0, 256, 0, 500, 510, 600, 0, -1};
421 int head1[] = {0x4f,0x67,0x67,0x53,0,0,
422 0x00,0x28,0x00,0x00,0x00,0x00,0x00,0x00,
423 0x01,0x02,0x03,0x04,0,0,0,0,
426 0,17,254,255,0,0,255,1,0,255,245,255,255,0,
428 int *headret[]={head1,NULL};
430 vorbis_stream_init(&vs,0x04030201);
431 fprintf(stderr,"testing basic nil packets... ");
432 test_pack(&vs,packets,headret);
433 vorbis_stream_clear(&vs);
437 /* starting new page with first segment */
438 int packets[]={4345,259,255,-1};
440 int head1[] = {0x4f,0x67,0x67,0x53,0,0,
441 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
442 0x01,0x02,0x03,0x04,0,0,0,0,
445 255,255,255,255,255,255,255,255,
446 255,255,255,255,255,255,255,255,255};
448 int head2[] = {0x4f,0x67,0x67,0x53,0,0x02,
449 0x00,0x08,0x00,0x00,0x00,0x00,0x00,0x00,
450 0x01,0x02,0x03,0x04,1,0,0,0,
454 int *headret[]={head1,head2,NULL};
456 vorbis_stream_init(&vs,0x04030201);
457 fprintf(stderr,"testing single-packet page span... ");
458 test_pack(&vs,packets,headret);
459 vorbis_stream_clear(&vs);
463 /* starting new page with first segment */
464 int packets[]={100,4345,259,255,-1};
466 int head1[] = {0x4f,0x67,0x67,0x53,0,0x00,
467 0x00,0x04,0x00,0x00,0x00,0x00,0x00,0x00,
468 0x01,0x02,0x03,0x04,0,0,0,0,
471 100,255,255,255,255,255,255,255,255,
472 255,255,255,255,255,255,255,255};
474 int head2[] = {0x4f,0x67,0x67,0x53,0,0x02,
475 0x00,0x0c,0x00,0x00,0x00,0x00,0x00,0x00,
476 0x01,0x02,0x03,0x04,1,0,0,0,
480 int *headret[]={head1,head2,NULL};
482 vorbis_stream_init(&vs,0x04030201);
483 fprintf(stderr,"testing multi-packet page span... ");
484 test_pack(&vs,packets,headret);
485 vorbis_stream_clear(&vs);
489 /* page with the 255 segment limit */
492 int packets[]={10,10,10,10,10,10,10,10,
493 10,10,10,10,10,10,10,10,
494 10,10,10,10,10,10,10,10,
495 10,10,10,10,10,10,10,10,
496 10,10,10,10,10,10,10,10,
497 10,10,10,10,10,10,10,10,
498 10,10,10,10,10,10,10,10,
499 10,10,10,10,10,10,10,10,
500 10,10,10,10,10,10,10,10,
501 10,10,10,10,10,10,10,10,
502 10,10,10,10,10,10,10,10,
503 10,10,10,10,10,10,10,10,
504 10,10,10,10,10,10,10,10,
505 10,10,10,10,10,10,10,10,
506 10,10,10,10,10,10,10,10,
507 10,10,10,10,10,10,10,10,
508 10,10,10,10,10,10,10,10,
509 10,10,10,10,10,10,10,10,
510 10,10,10,10,10,10,10,10,
511 10,10,10,10,10,10,10,10,
512 10,10,10,10,10,10,10,10,
513 10,10,10,10,10,10,10,10,
514 10,10,10,10,10,10,10,10,
515 10,10,10,10,10,10,10,10,
516 10,10,10,10,10,10,10,10,
517 10,10,10,10,10,10,10,10,
518 10,10,10,10,10,10,10,10,
519 10,10,10,10,10,10,10,10,
520 10,10,10,10,10,10,10,10,
521 10,10,10,10,10,10,10,10,
522 10,10,10,10,10,10,10,10,
523 10,10,10,10,10,10,10,50,-1};
525 int head1[] = {0x4f,0x67,0x67,0x53,0,0x00,
526 0x00,0xf8,0x03,0x00,0x00,0x00,0x00,0x00,
527 0x01,0x02,0x03,0x04,0,0,0,0,
530 10,10,10,10,10,10,10,10,
531 10,10,10,10,10,10,10,10,
532 10,10,10,10,10,10,10,10,
533 10,10,10,10,10,10,10,10,
534 10,10,10,10,10,10,10,10,
535 10,10,10,10,10,10,10,10,
536 10,10,10,10,10,10,10,10,
537 10,10,10,10,10,10,10,10,
538 10,10,10,10,10,10,10,10,
539 10,10,10,10,10,10,10,10,
540 10,10,10,10,10,10,10,10,
541 10,10,10,10,10,10,10,10,
542 10,10,10,10,10,10,10,10,
543 10,10,10,10,10,10,10,10,
544 10,10,10,10,10,10,10,10,
545 10,10,10,10,10,10,10,10,
546 10,10,10,10,10,10,10,10,
547 10,10,10,10,10,10,10,10,
548 10,10,10,10,10,10,10,10,
549 10,10,10,10,10,10,10,10,
550 10,10,10,10,10,10,10,10,
551 10,10,10,10,10,10,10,10,
552 10,10,10,10,10,10,10,10,
553 10,10,10,10,10,10,10,10,
554 10,10,10,10,10,10,10,10,
555 10,10,10,10,10,10,10,10,
556 10,10,10,10,10,10,10,10,
557 10,10,10,10,10,10,10,10,
558 10,10,10,10,10,10,10,10,
559 10,10,10,10,10,10,10,10,
560 10,10,10,10,10,10,10,10,
561 10,10,10,10,10,10,10};
563 int head2[] = {0x4f,0x67,0x67,0x53,0,0x01,
564 0x00,0xfc,0x03,0x00,0x00,0x00,0x00,0x00,
565 0x01,0x02,0x03,0x04,1,0,0,0,
569 int *headret[]={head1,head2,NULL};
571 vorbis_stream_init(&vs,0x04030201);
572 fprintf(stderr,"testing max packet segments... ");
573 test_pack(&vs,packets,headret);
574 vorbis_stream_clear(&vs);
578 /* packet that overspans over an entire page */
580 int packets[]={100,9000,259,255,-1};
582 int head1[] = {0x4f,0x67,0x67,0x53,0,0x00,
583 0x00,0x04,0x00,0x00,0x00,0x00,0x00,0x00,
584 0x01,0x02,0x03,0x04,0,0,0,0,
587 100,255,255,255,255,255,255,255,255,
588 255,255,255,255,255,255,255,255};
590 int head2[] = {0x4f,0x67,0x67,0x53,0,0x02,
591 0x00,0x04,0x00,0x00,0x00,0x00,0x00,0x00,
592 0x01,0x02,0x03,0x04,1,0,0,0,
595 255,255,255,255,255,255,255,255,
596 255,255,255,255,255,255,255,255,255};
598 int head3[] = {0x4f,0x67,0x67,0x53,0,0x02,
599 0x00,0x0c,0x00,0x00,0x00,0x00,0x00,0x00,
600 0x01,0x02,0x03,0x04,2,0,0,0,
603 255,255,75,255,4,255,0};
604 int *headret[]={head1,head2,head3,NULL};
606 vorbis_stream_init(&vs,0x04030201);
607 fprintf(stderr,"testing very large packets... ");
608 test_pack(&vs,packets,headret);
609 vorbis_stream_clear(&vs);
613 /* nil page. why not? */
615 int packets[]={100,4080,-1};
617 int head1[] = {0x4f,0x67,0x67,0x53,0,0x00,
618 0x00,0x04,0x00,0x00,0x00,0x00,0x00,0x00,
619 0x01,0x02,0x03,0x04,0,0,0,0,
622 100,255,255,255,255,255,255,255,255,
623 255,255,255,255,255,255,255,255};
625 int head2[] = {0x4f,0x67,0x67,0x53,0,0x02,
626 0x00,0x04,0x00,0x00,0x00,0x00,0x00,0x00,
627 0x01,0x02,0x03,0x04,1,0,0,0,
631 int *headret[]={head1,head2,NULL};
633 vorbis_stream_init(&vs,0x04030201);
634 fprintf(stderr,"testing nil page... ");
635 test_pack(&vs,packets,headret);
636 vorbis_stream_clear(&vs);