#include #include #include #include #include #include #include extern const char *__progname; static unsigned char *pktbuf = 0; static int pktalloc = 0; static int getpkt(ogg_packet *p) { char c; long int len; long int bos; long int eos; long long int gpos; long long int pno; c = getchar(); if (c == '.') return(0); ungetc(c,stdin); if (scanf("%ld%ld%ld%lld%lld",&len,&bos,&eos,&gpos,&pno) != 5) { fprintf(stderr,"input header scan failed\n"); exit(1); } c = getchar(); if (c != '\n') { fprintf(stderr,"input header format error\n"); exit(1); } p->bytes = len; p->b_o_s = bos; p->e_o_s = eos; p->granulepos = gpos; p->packetno = pno; if (len > pktalloc) { free(pktbuf); pktalloc = len; pktbuf = malloc(len); } p->packet = pktbuf; if (fread(pktbuf,1,len,stdin) != len) { fprintf(stderr,"input data read failed\n"); exit(1); } #if 0 { int i; fprintf(stderr,"packet: len %ld bos %ld eos %ld gpos %lld pno %lld\n", (long int)p->bytes, (long int)p->b_o_s, (long int)p->e_o_s, (long long int)p->granulepos, (long long int)p->packetno ); fprintf(stderr,"packet data:"); for (i=0;ibytes;i++) fprintf(stderr," %02x",p->packet[i]); fprintf(stderr,"\n"); } #endif return(1); } static void deplanarize(th_img_plane *ycbcr) { unsigned char *yp; unsigned char *cbp; unsigned char *crp; int y; int x; if ( (ycbcr[0].width != 640) || (ycbcr[0].height != 480) || (ycbcr[1].width != 320) || (ycbcr[1].height != 480) || (ycbcr[2].width != 320) || (ycbcr[2].height != 480) ) { fprintf(stderr,"planar sizes wrong (%dx%d %dx%d %dx%d)\n", ycbcr[0].width, ycbcr[0].height, ycbcr[1].width, ycbcr[1].height, ycbcr[2].width, ycbcr[2].height ); exit(1); } yp = ycbcr[0].data; cbp = ycbcr[1].data; crp = ycbcr[2].data; for (y=480;y>0;y--) { for (x=640;x>0;x-=2) { putchar(*yp++); putchar(*cbp++); putchar(*yp++); putchar(*crp++); } yp += ycbcr[0].stride - 640; cbp += ycbcr[1].stride - 320; crp += ycbcr[2].stride - 320; } } int main(void) { th_info thi; th_comment comm; th_setup_info *thsi; ogg_packet pkt; int e; th_dec_ctx *thdc; th_ycbcr_buffer obuf; th_info_init(&thi); /* * The documentation for th_decode_headerin doesn't mention that its * th_comment argument must be initialized! Oddly, only the vendor * field actually needs it. */ comm.vendor = 0; thsi = 0; while (1) { if (! getpkt(&pkt)) { fprintf(stderr,"end of input before data\n"); exit(1); } e = th_decode_headerin(&thi,&comm,&thsi,&pkt); if (e > 0) continue; if (e == 0) break; fprintf(stderr,"th_decode_headerin error %d\n",e); exit(1); } fprintf(stderr,"frame %dx%d picture %dx%d+%d+%d\n", thi.frame_width, thi.frame_height, thi.pic_width, thi.pic_height, thi.pic_x, thi.pic_y); fprintf(stderr,"colorspace %d pixel_fmt %d target_bitrate %d quality %d keyframe_granule_shift %d\n", (int)thi.colorspace, (int)thi.pixel_fmt, thi.target_bitrate, thi.quality, thi.keyframe_granule_shift); if ( (thi.frame_width != 640) || (thi.frame_height != 480) || (thi.pic_width != 640) || (thi.pic_height != 480) || (thi.pic_x != 0) || (thi.pic_y != 0) ) { fprintf(stderr,"size/location wrong\n"); exit(1); } thdc = th_decode_alloc(&thi,thsi); if (! thdc) { fprintf(stderr,"th_decode_alloc failed\n"); exit(1); } th_setup_free(thsi); do { e = th_decode_packetin(thdc,&pkt,0); switch (e) { case 0: case TH_DUPFRAME: break; default: fprintf(stderr,"th_decode_packetin error %d\n",e); exit(1); break; } /* XXX th_ycbcr_buffer is an array (!), hence no & */ e = th_decode_ycbcr_out(thdc,obuf); if (e != 0) { fprintf(stderr,"th_decode_ycbcr_out error %d\n",e); exit(1); } fprintf(stderr,"frame out\n"); deplanarize(&obuf[0]); } while (getpkt(&pkt)); th_decode_free(thdc); return(0); }