static int _initmpeg2(FILE *mpgfile,int *w, int *h) { static uint8_t buffer[BUFFER_SIZE]; mpeg2_state_t state; struct fbuf_s * current_fbuf; size_t size; int pixels; int i; global_mpegfile=mpgfile; if (decoder!=NULL) { mpeg2_close (decoder); decoder=NULL; } decoder = mpeg2_init (); if (decoder == NULL) { fprintf (stderr, "Could not allocate a decoder object.\n"); exit (1); } info = mpeg2_info (decoder); size = (size_t)-1; do { state = mpeg2_parse (decoder); if (state==STATE_BUFFER) { //fprintf(stderr,"Got STATE_BUFFER\n"); size = fread (buffer, 1, BUFFER_SIZE, global_mpegfile); mpeg2_buffer (decoder, buffer, buffer + size); } else if (state==STATE_SEQUENCE) { //fprintf(stderr,"Got STATE_SEQUENCE\n"); mpeg2_convert (decoder, mpeg2convert_rgb24, NULL); mpeg2_custom_fbuf (decoder, 1); if (w!=NULL) *w=info->sequence->width; if (h!=NULL) *h=info->sequence->height; pixels = info->sequence->width * info->sequence->height; for (i = 0; i < 3; i++) { fbuf[i].rgb[0] = (uint8_t *) malloc (3 * pixels); fbuf[i].rgb[1] = fbuf[i].rgb[2] = NULL; if (!fbuf[i].rgb[0]) { fprintf (stderr, "Could not allocate an output buffer.\n"); exit (1); } fbuf[i].used = 0; } for (i = 0; i < 2; i++) { current_fbuf = get_fbuf (); mpeg2_set_buf (decoder, current_fbuf->rgb, current_fbuf); } break; } else if (state==STATE_PICTURE || state==STATE_SLICE || state==STATE_END || state==STATE_INVALID_END) { //if (state==STATE_SLICE) fprintf(stderr,"Got STATE_PICTURE\n"); //if (state==STATE_SLICE) fprintf(stderr,"Got STATE_SLICE\n"); //if (state==STATE_END) fprintf(stderr,"Got STATE_END\n"); //if (state==STATE_INVALID_END) fprintf(stderr,"Got STATE_INVALID_END\n"); fprintf(stderr,"GOT unexpected state during initialization.\n"); return 0; } } while (size); return 1; }
static void sample5 (FILE * mpgfile) { #define BUFFER_SIZE 4096 #define ALIGN_16(p) ((void *)(((uintptr_t)(p) + 15) & ~((uintptr_t)15))) uint8_t buffer[BUFFER_SIZE]; mpeg2dec_t * decoder; const mpeg2_info_t * info; const mpeg2_sequence_t * sequence; mpeg2_state_t state; size_t size; int framenum = 0; int i, j; struct fbuf_s * current_fbuf; decoder = mpeg2_init (); if (decoder == NULL) { fprintf (stderr, "Could not allocate a decoder object.\n"); exit (1); } info = mpeg2_info (decoder); size = (size_t)-1; do { state = mpeg2_parse (decoder); sequence = info->sequence; switch (state) { case STATE_BUFFER: size = fread (buffer, 1, BUFFER_SIZE, mpgfile); mpeg2_buffer (decoder, buffer, buffer + size); break; case STATE_SEQUENCE: mpeg2_custom_fbuf (decoder, 1); for (i = 0; i < 3; i++) { fbuf[i].mbuf[0] = (uint8_t *) malloc (sequence->width * sequence->height + 15); fbuf[i].mbuf[1] = (uint8_t *) malloc (sequence->chroma_width * sequence->chroma_height + 15); fbuf[i].mbuf[2] = (uint8_t *) malloc (sequence->chroma_width * sequence->chroma_height + 15); if (!fbuf[i].mbuf[0] || !fbuf[i].mbuf[1] || !fbuf[i].mbuf[2]) { fprintf (stderr, "Could not allocate an output buffer.\n"); exit (1); } for (j = 0; j < 3; j++) fbuf[i].yuv[j] = ALIGN_16 (fbuf[i].mbuf[j]); fbuf[i].used = 0; } for (i = 0; i < 2; i++) { current_fbuf = get_fbuf (); mpeg2_set_buf (decoder, current_fbuf->yuv, current_fbuf); } break; case STATE_PICTURE: current_fbuf = get_fbuf (); mpeg2_set_buf (decoder, current_fbuf->yuv, current_fbuf); break; case STATE_SLICE: case STATE_END: case STATE_INVALID_END: if (info->display_fbuf) save_pgm (sequence->width, sequence->height, sequence->chroma_width, sequence->chroma_height, info->display_fbuf->buf, framenum++); if (info->discard_fbuf) ((struct fbuf_s *)info->discard_fbuf->id)->used = 0; if (state != STATE_SLICE) for (i = 0; i < 3; i++) for (j = 0; j < 3; j++) free (fbuf[i].mbuf[j]); break; default: break; } } while (size); mpeg2_close (decoder); }
int _getmpeg2frame(unsigned char *rgb,int gray) { int i; static uint8_t buffer[BUFFER_SIZE]; mpeg2_state_t state; size_t size; int pixels; struct fbuf_s * current_fbuf; int done=0; size = (size_t)-1; do { state = mpeg2_parse (decoder); if (state==STATE_BUFFER) { //fprintf(stderr,"Got STATE_BUFFER\n"); size = fread (buffer, 1, BUFFER_SIZE, global_mpegfile); mpeg2_buffer (decoder, buffer, buffer + size); } else if (state==STATE_SEQUENCE) { //fprintf(stderr,"Got STATE_SEQUENCE\n"); mpeg2_convert (decoder, mpeg2convert_rgb24, NULL); mpeg2_custom_fbuf (decoder, 1); pixels = info->sequence->width * info->sequence->height; for (i = 0; i < 3; i++) { fbuf[i].rgb[0] = (uint8_t *) malloc (3 * pixels); fbuf[i].rgb[1] = fbuf[i].rgb[2] = NULL; if (!fbuf[i].rgb[0]) { fprintf (stderr, "Could not allocate an output buffer.\n"); exit (1); } fbuf[i].used = 0; } for (i = 0; i < 2; i++) { current_fbuf = get_fbuf (); mpeg2_set_buf (decoder, current_fbuf->rgb, current_fbuf); } } else if (state==STATE_PICTURE) { //fprintf(stderr,"Got STATE_PICTURE\n"); current_fbuf = get_fbuf (); mpeg2_set_buf (decoder, current_fbuf->rgb, current_fbuf); } else if (state==STATE_SLICE || state==STATE_END || state==STATE_INVALID_END) { //if (state==STATE_SLICE) fprintf(stderr,"Got STATE_SLICE\n"); //if (state==STATE_END) fprintf(stderr,"Got STATE_END\n"); //if (state==STATE_INVALID_END) fprintf(stderr,"Got STATE_INVALID_END\n"); if (info->display_fbuf) { int jj; int pixels; uint8_t *base; base=info->display_fbuf->buf[0]; /* we have a complete image ready */ if (gray) { pixels=info->sequence->width*info->sequence->height; for (jj=0;jj<pixels;jj++) { rgb[jj]=(base[0]+base[1]+base[3])/3; base+=3; } } else { pixels=3*info->sequence->width*info->sequence->height; /* we have a complete image ready */ memcpy(rgb,base,pixels*sizeof(unsigned char)); } done=1; } if (info->discard_fbuf) ((struct fbuf_s *)info->discard_fbuf->id)->used = 0; if (state != STATE_SLICE) for (i = 0; i < 3; i++) free (fbuf[i].rgb[0]); if (state==STATE_END) { //fprintf(stderr,"Got STATE_END\n"); rewindmpeg2(); } if (state==STATE_INVALID_END) { //fprintf(stderr,"Got STATE_INVALID_END\n"); rewindmpeg2(); } /* we got a single frame */ if (done) { if (size!=0) return 1; return 0; } } } while (size); return 0; }