1 |
/******************************************************************************* |
/******************************************************************************* |
2 |
* This file is a example for how to use the xvid core to compress YUV file |
* This file is a example for how to use the xvid core to compress YUV file |
3 |
* |
* |
4 |
|
* 0.02 11.07.2002 chenm001<chenm001@163.com> |
5 |
|
* add the decode examples |
6 |
* 0.01b 28.05.2002 chenm001<chenm001@163.com> |
* 0.01b 28.05.2002 chenm001<chenm001@163.com> |
7 |
* fix a little bug for encode only codec I frame |
* fix a little bug for encode only codec I frame |
8 |
* 0.01a 27.05.2002 chenm001<chenm001@163.com> |
* 0.01a 27.05.2002 chenm001<chenm001@163.com> |
9 |
* fix a little bug for BFRAMES define locate |
* fix a little bug for BFRAMES define locate |
10 |
* 0.01 23.05.2002 chenm001<chenm001@163.com> |
* 0.01 23.05.2002 chenm001<chenm001@163.com> |
11 |
|
* Initialize version only support encode examples |
12 |
* the BFRAME option must be match to core compile option |
* the BFRAME option must be match to core compile option |
13 |
*******************************************************************************/ |
*******************************************************************************/ |
14 |
|
|
15 |
#define BFRAMES |
#define BFRAMES |
16 |
|
#define BFRAMES_DEC |
17 |
#include "ex1.h" |
#include "ex1.h" |
18 |
|
|
19 |
int Encode(char *, int, int, char *); |
int Encode(char *, int, int, char *); |
20 |
int Decode(char *, int, int, char *); |
int Decode(char *, char *); |
21 |
|
|
22 |
int main(int argc, char *argv[]) |
int main(int argc, char *argv[]) |
23 |
{ |
{ |
24 |
if (argc<6){ |
if (argc<4){ |
25 |
printf("Usage:\n\t%s {Encode|Decode} infile width heigh outfile\n",argv[0]); |
printf("Usage:\n\t%s Encode infile width heigh outfile\n",argv[0]); |
26 |
|
printf("\t%s Decode infile outfile\n",argv[0]); |
27 |
return(ERR_NO_OPT); |
return(ERR_NO_OPT); |
28 |
} |
} |
29 |
switch(toupper(argv[1][0])){ |
switch(toupper(argv[1][0])){ |
31 |
Encode(argv[2], atoi(argv[3]), atoi(argv[4]), argv[5]); |
Encode(argv[2], atoi(argv[3]), atoi(argv[4]), argv[5]); |
32 |
break; |
break; |
33 |
case 'D': |
case 'D': |
34 |
Decode(argv[2], atoi(argv[3]), atoi(argv[4]), argv[5]); |
Decode(argv[2], argv[3]); |
35 |
break; |
break; |
36 |
default: |
default: |
37 |
printf("Error option: %c",argv[1][0]); |
printf("Error option: %c",argv[1][0]); |
60 |
param->max_quantizer = 31; |
param->max_quantizer = 31; |
61 |
param->max_key_interval = 100; |
param->max_key_interval = 100; |
62 |
|
|
63 |
|
#ifdef BFRAMES |
64 |
param->max_bframes = 0; // Disable B-frame |
param->max_bframes = 0; // Disable B-frame |
65 |
|
#endif |
66 |
} |
} |
67 |
|
|
68 |
void set_enc_frame(XVID_ENC_FRAME *frame) |
void set_enc_frame(XVID_ENC_FRAME *frame) |
77 |
frame->colorspace = XVID_CSP_YV12; // the test.yuv format is YV12 |
frame->colorspace = XVID_CSP_YV12; // the test.yuv format is YV12 |
78 |
frame->quant = 0; // CBR mode |
frame->quant = 0; // CBR mode |
79 |
|
|
|
frame->general = 0; |
|
80 |
frame->general |= XVID_MPEGQUANT; // Use MPEG quant |
frame->general |= XVID_MPEGQUANT; // Use MPEG quant |
81 |
frame->quant_inter_matrix = NULL; // Use default quant matrix |
frame->quant_inter_matrix = NULL; // Use default quant matrix |
82 |
frame->quant_intra_matrix = NULL; |
frame->quant_intra_matrix = NULL; |
109 |
} |
} |
110 |
|
|
111 |
// get Xvid core status |
// get Xvid core status |
112 |
|
init_param.cpu_flags = 0; |
113 |
xvid_init(0, 0, &init_param, NULL); |
xvid_init(0, 0, &init_param, NULL); |
114 |
// Check API Version is 2.1? |
// Check API Version is 2.1? |
115 |
if (init_param.api_version != ((2<<16)|(1))) |
if (init_param.api_version != ((2<<16)|(1))) |
126 |
// Encode Frame |
// Encode Frame |
127 |
temp=fread(inBuf, 1, width*height*3/2, fpi); // Read YUV data |
temp=fread(inBuf, 1, width*height*3/2, fpi); // Read YUV data |
128 |
while(temp == width*height*3/2){ |
while(temp == width*height*3/2){ |
129 |
//printf("Frames=%d\n",num); |
printf("Frames=%d\n",num); |
130 |
set_enc_frame(&frame); |
set_enc_frame(&frame); |
131 |
if (!(num%param.max_key_interval)) |
if (!(num%param.max_key_interval)) |
132 |
frame.intra = 1; // Encode as I-frame |
frame.intra = 1; // Encode as I-frame |
147 |
return(ERR_OK); |
return(ERR_OK); |
148 |
} |
} |
149 |
|
|
150 |
int Decode(char *in, int width, int height, char *out) |
void set_dec_param(XVID_DEC_PARAM *param) |
151 |
{ |
{ |
152 |
|
// set to 0 will auto set width & height from encoded bitstream |
153 |
|
param->height = param->width = 0; |
154 |
|
} |
155 |
|
|
156 |
|
int Decode(char *in, char *out) |
157 |
|
{ |
158 |
|
int width, height,i=0; |
159 |
|
uint32_t temp; |
160 |
|
long readed; |
161 |
|
XVID_DEC_PARAM param; |
162 |
|
XVID_INIT_PARAM init_param; |
163 |
|
DECODER *dec; |
164 |
|
XVID_DEC_FRAME frame; |
165 |
|
Bitstream bs; |
166 |
|
|
167 |
FILE *fpi=fopen(in,"rb"), |
FILE *fpi=fopen(in,"rb"), |
168 |
*fpo=fopen(out,"wb"); |
*fpo=fopen(out,"wb"); |
169 |
if (fpi == NULL || fpo==NULL){ |
if (fpi == NULL || fpo==NULL){ |
173 |
fclose(fpo); |
fclose(fpo); |
174 |
return(ERR_FILE); |
return(ERR_FILE); |
175 |
} |
} |
176 |
|
|
177 |
|
|
178 |
|
init_param.cpu_flags = 0; |
179 |
|
xvid_init(0, 0, &init_param, NULL); |
180 |
|
// Check API Version is 2.1? |
181 |
|
if (init_param.api_version != ((2<<16)|(1))) |
182 |
|
return(ERR_VERSION); |
183 |
|
|
184 |
|
set_dec_param(¶m); |
185 |
|
|
186 |
|
temp = xvid_decore(0, XVID_DEC_CREATE, ¶m, NULL); |
187 |
|
dec = param.handle; |
188 |
|
|
189 |
|
if (dec != NULL){ |
190 |
|
// to Get Video width & height |
191 |
|
readed = fread(inBuf, 1, MAX_FRAME_SIZE, fpi); |
192 |
|
BitstreamInit(&bs, inBuf, readed); |
193 |
|
BitstreamReadHeaders(&bs, dec, &temp, &temp, &temp, &temp, &temp); |
194 |
|
width = dec->width; |
195 |
|
height = dec->height; |
196 |
|
xvid_decore(dec, XVID_DEC_DESTROY, NULL, NULL); |
197 |
|
|
198 |
|
// recreate new decoder because width & height changed! |
199 |
|
param.width = width; |
200 |
|
param.height = height; |
201 |
|
temp = xvid_decore(0, XVID_DEC_CREATE, ¶m, NULL); |
202 |
|
dec = param.handle; |
203 |
|
|
204 |
|
// because START_CODE must be 32bit |
205 |
|
while(readed >= 4){ |
206 |
|
printf("Decode Frame %d\n",i++); |
207 |
|
frame.bitstream = inBuf; |
208 |
|
frame.length = readed; |
209 |
|
frame.image = outBuf; |
210 |
|
frame.stride = width; |
211 |
|
frame.colorspace = XVID_CSP_YV12; // for input video clip color space |
212 |
|
|
213 |
|
temp = xvid_decore(dec, XVID_DEC_DECODE, &frame, NULL); |
214 |
|
|
215 |
|
// undo unused byte |
216 |
|
fseek(fpi, frame.length - readed - 2, SEEK_CUR); |
217 |
|
|
218 |
|
// Write decoded YUV image, size = width * height * 3 / 2 because in I420 CSP |
219 |
|
fwrite(outBuf, 1, width * height * 3 / 2, fpo); |
220 |
|
|
221 |
|
// read next frame data |
222 |
|
readed = fread(inBuf, 1, MAX_FRAME_SIZE, fpi); |
223 |
|
} |
224 |
|
|
225 |
|
// free decoder |
226 |
|
xvid_decore(dec, XVID_DEC_DESTROY, NULL, NULL); |
227 |
|
} |
228 |
|
|
229 |
fclose(fpi); |
fclose(fpi); |
230 |
fclose(fpo); |
fclose(fpo); |
231 |
return(ERR_OK); |
return(ERR_OK); |