--- trunk/xvidcore/examples/ex1/ex1.c 2002/05/28 01:16:06 185 +++ trunk/xvidcore/examples/ex1/ex1.c 2002/07/12 00:46:26 293 @@ -1,24 +1,29 @@ /******************************************************************************* * This file is a example for how to use the xvid core to compress YUV file * +* 0.02 11.07.2002 chenm001 +* add the decode examples * 0.01b 28.05.2002 chenm001 * fix a little bug for encode only codec I frame * 0.01a 27.05.2002 chenm001 * fix a little bug for BFRAMES define locate * 0.01 23.05.2002 chenm001 +* Initialize version only support encode examples * the BFRAME option must be match to core compile option *******************************************************************************/ -#define BFRAMES +#define BFRAMES +#define BFRAMES_DEC #include "ex1.h" int Encode(char *, int, int, char *); -int Decode(char *, int, int, char *); +int Decode(char *, char *); int main(int argc, char *argv[]) { - if (argc<6){ - printf("Usage:\n\t%s {Encode|Decode} infile width heigh outfile\n",argv[0]); + if (argc<4){ + printf("Usage:\n\t%s Encode infile width heigh outfile\n",argv[0]); + printf("\t%s Decode infile outfile\n",argv[0]); return(ERR_NO_OPT); } switch(toupper(argv[1][0])){ @@ -26,7 +31,7 @@ Encode(argv[2], atoi(argv[3]), atoi(argv[4]), argv[5]); break; case 'D': - Decode(argv[2], atoi(argv[3]), atoi(argv[4]), argv[5]); + Decode(argv[2], argv[3]); break; default: printf("Error option: %c",argv[1][0]); @@ -55,7 +60,9 @@ param->max_quantizer = 31; param->max_key_interval = 100; +#ifdef BFRAMES param->max_bframes = 0; // Disable B-frame +#endif } void set_enc_frame(XVID_ENC_FRAME *frame) @@ -70,7 +77,6 @@ frame->colorspace = XVID_CSP_YV12; // the test.yuv format is YV12 frame->quant = 0; // CBR mode - frame->general = 0; frame->general |= XVID_MPEGQUANT; // Use MPEG quant frame->quant_inter_matrix = NULL; // Use default quant matrix frame->quant_intra_matrix = NULL; @@ -103,6 +109,7 @@ } // get Xvid core status + init_param.cpu_flags = 0; xvid_init(0, 0, &init_param, NULL); // Check API Version is 2.1? if (init_param.api_version != ((2<<16)|(1))) @@ -119,7 +126,7 @@ // Encode Frame temp=fread(inBuf, 1, width*height*3/2, fpi); // Read YUV data while(temp == width*height*3/2){ - //printf("Frames=%d\n",num); + printf("Frames=%d\n",num); set_enc_frame(&frame); if (!(num%param.max_key_interval)) frame.intra = 1; // Encode as I-frame @@ -140,8 +147,23 @@ return(ERR_OK); } -int Decode(char *in, int width, int height, char *out) +void set_dec_param(XVID_DEC_PARAM *param) { + // set to 0 will auto set width & height from encoded bitstream + param->height = param->width = 0; +} + +int Decode(char *in, char *out) +{ + int width, height,i=0; + uint32_t temp; + long readed; + XVID_DEC_PARAM param; + XVID_INIT_PARAM init_param; + DECODER *dec; + XVID_DEC_FRAME frame; + Bitstream bs; + FILE *fpi=fopen(in,"rb"), *fpo=fopen(out,"wb"); if (fpi == NULL || fpo==NULL){ @@ -151,6 +173,59 @@ fclose(fpo); return(ERR_FILE); } + + + init_param.cpu_flags = 0; + xvid_init(0, 0, &init_param, NULL); + // Check API Version is 2.1? + if (init_param.api_version != ((2<<16)|(1))) + return(ERR_VERSION); + + set_dec_param(¶m); + + temp = xvid_decore(0, XVID_DEC_CREATE, ¶m, NULL); + dec = param.handle; + + if (dec != NULL){ + // to Get Video width & height + readed = fread(inBuf, 1, MAX_FRAME_SIZE, fpi); + BitstreamInit(&bs, inBuf, readed); + BitstreamReadHeaders(&bs, dec, &temp, &temp, &temp, &temp, &temp); + width = dec->width; + height = dec->height; + xvid_decore(dec, XVID_DEC_DESTROY, NULL, NULL); + + // recreate new decoder because width & height changed! + param.width = width; + param.height = height; + temp = xvid_decore(0, XVID_DEC_CREATE, ¶m, NULL); + dec = param.handle; + + // because START_CODE must be 32bit + while(readed >= 4){ + printf("Decode Frame %d\n",i++); + frame.bitstream = inBuf; + frame.length = readed; + frame.image = outBuf; + frame.stride = width; + frame.colorspace = XVID_CSP_YV12; // for input video clip color space + + temp = xvid_decore(dec, XVID_DEC_DECODE, &frame, NULL); + + // undo unused byte + fseek(fpi, frame.length - readed - 2, SEEK_CUR); + + // Write decoded YUV image, size = width * height * 3 / 2 because in I420 CSP + fwrite(outBuf, 1, width * height * 3 / 2, fpo); + + // read next frame data + readed = fread(inBuf, 1, MAX_FRAME_SIZE, fpi); + } + + // free decoder + xvid_decore(dec, XVID_DEC_DESTROY, NULL, NULL); + } + fclose(fpi); fclose(fpo); return(ERR_OK);