Parent Directory | Revision Log
Revision 392 - (view) (download)
1 : | chl | 376 | /************************************************************************** |
2 : | * | ||
3 : | * XVID MPEG-4 VIDEO CODEC - Example for encoding and decoding | ||
4 : | * | ||
5 : | * This program is free software; you can redistribute it and/or modify | ||
6 : | * it under the terms of the GNU General Public License as published by | ||
7 : | * the Free Software Foundation; either version 2 of the License, or | ||
8 : | * (at your option) any later version. | ||
9 : | * | ||
10 : | * This program is distributed in the hope that it will be useful, | ||
11 : | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
12 : | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
13 : | * GNU General Public License for more details. | ||
14 : | * | ||
15 : | * You should have received a copy of the GNU General Public License | ||
16 : | * along with this program; if not, write to the Free Software | ||
17 : | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
18 : | * | ||
19 : | *************************************************************************/ | ||
20 : | |||
21 : | /************************************************************************ | ||
22 : | * | ||
23 : | * Test routine for XviD decoding | ||
24 : | * (C) Christoph Lampert, 2002/08/17 | ||
25 : | * | ||
26 : | * An MPEG-4 bitstream is read from stdin and decoded, | ||
27 : | * the speed for this is measured | ||
28 : | * | ||
29 : | * The program is plain C and needs no libraries except for libxvidcore, | ||
30 : | * and maths-lib, so with UN*X you simply compile by | ||
31 : | * | ||
32 : | * gcc xvid_decraw.c -lxvidcore -lm -o xvid_decraw | ||
33 : | * | ||
34 : | * You have to specify the image dimensions (until the add the feature | ||
35 : | * to read this from the bitstream) | ||
36 : | * | ||
37 : | * Parameters are: xvid_stat XDIM YDIM | ||
38 : | * | ||
39 : | * output and indivual m4v-files are saved, if corresponding flags are set | ||
40 : | * | ||
41 : | ************************************************************************/ | ||
42 : | |||
43 : | #include <stdio.h> | ||
44 : | #include <stdlib.h> | ||
45 : | #include <math.h> // needed for log10 | ||
46 : | #include <sys/time.h> // only needed for gettimeofday | ||
47 : | |||
48 : | #include "../src/xvid.h" | ||
49 : | |||
50 : | #define ABS_MAXFRAMENR 9999 // max number of frames | ||
51 : | |||
52 : | int XDIM=720; | ||
53 : | int YDIM=576; | ||
54 : | int i,filenr = 0; | ||
55 : | |||
56 : | int save_dec_flag = 1; // save decompressed bytestream? | ||
57 : | int save_m4v_flag = 0; // save bytestream itself? | ||
58 : | |||
59 : | char filepath[256] = "./"; // the path where to save output | ||
60 : | |||
61 : | void *dec_handle = NULL; // handle for decoding | ||
62 : | |||
63 : | /*********************************************************************/ | ||
64 : | /* "statistical" functions */ | ||
65 : | /* */ | ||
66 : | /* these are not needed for decoding itself, but for measuring */ | ||
67 : | /* time (and maybe later quality), there in nothing specific to */ | ||
68 : | /* XviD in these */ | ||
69 : | /* */ | ||
70 : | /*********************************************************************/ | ||
71 : | |||
72 : | double msecond() | ||
73 : | /* return the current time in seconds(!) */ | ||
74 : | { | ||
75 : | struct timeval tv; | ||
76 : | gettimeofday(&tv, 0); | ||
77 : | return tv.tv_sec + tv.tv_usec * 1.0e-6; | ||
78 : | } | ||
79 : | |||
80 : | |||
81 : | /*********************************************************************/ | ||
82 : | /* input and output functions */ | ||
83 : | /* */ | ||
84 : | /* the are small and simple routines for writing image */ | ||
85 : | /* image. It's just for convenience, again nothing specific to XviD */ | ||
86 : | /* */ | ||
87 : | /*********************************************************************/ | ||
88 : | |||
89 : | int write_pgm(char *filename, unsigned char *image) | ||
90 : | { | ||
91 : | FILE *filehandle; | ||
92 : | filehandle=fopen(filename,"wb"); | ||
93 : | if (filehandle) | ||
94 : | { | ||
95 : | fprintf(filehandle,"P5\n\n"); // | ||
96 : | fprintf(filehandle,"%d %d 255\n",XDIM,YDIM*3/2); | ||
97 : | fwrite(image,XDIM,YDIM*3/2,filehandle); | ||
98 : | |||
99 : | fclose(filehandle); | ||
100 : | return 0; | ||
101 : | } | ||
102 : | else | ||
103 : | return 1; | ||
104 : | } | ||
105 : | |||
106 : | |||
107 : | int write_ppm(char *filename, unsigned char *image) | ||
108 : | { | ||
109 : | FILE *filehandle; | ||
110 : | filehandle=fopen(filename,"wb"); | ||
111 : | if (filehandle) | ||
112 : | { | ||
113 : | fprintf(filehandle,"P6\n\n"); // | ||
114 : | fprintf(filehandle,"%d %d 255\n",XDIM,YDIM); | ||
115 : | fwrite(image,XDIM,YDIM*3,filehandle); | ||
116 : | |||
117 : | fclose(filehandle); | ||
118 : | return 0; | ||
119 : | } | ||
120 : | else | ||
121 : | return 1; | ||
122 : | } | ||
123 : | |||
124 : | /*********************************************************************/ | ||
125 : | /* Routines for decoding: init encoder, frame step, release encoder */ | ||
126 : | /*********************************************************************/ | ||
127 : | |||
128 : | int dec_init(int use_assembler) /* init decoder before first run */ | ||
129 : | { | ||
130 : | int xerr; | ||
131 : | |||
132 : | XVID_INIT_PARAM xinit; | ||
133 : | XVID_DEC_PARAM xparam; | ||
134 : | |||
135 : | if(use_assembler) | ||
136 : | #ifdef ARCH_IA64 | ||
137 : | xinit.cpu_flags = XVID_CPU_FORCE | XVID_CPU_IA64; | ||
138 : | #else | ||
139 : | xinit.cpu_flags = 0; | ||
140 : | #endif | ||
141 : | else | ||
142 : | xinit.cpu_flags = XVID_CPU_FORCE; | ||
143 : | |||
144 : | xvid_init(NULL, 0, &xinit, NULL); | ||
145 : | xparam.width = XDIM; | ||
146 : | xparam.height = YDIM; | ||
147 : | |||
148 : | xerr = xvid_decore(NULL, XVID_DEC_CREATE, &xparam, NULL); | ||
149 : | dec_handle = xparam.handle; | ||
150 : | |||
151 : | return xerr; | ||
152 : | } | ||
153 : | |||
154 : | int dec_main(unsigned char *m4v_buffer, unsigned char *out_buffer,int *m4v_size) | ||
155 : | { /* decode one frame */ | ||
156 : | |||
157 : | int xerr; | ||
158 : | XVID_DEC_FRAME xframe; | ||
159 : | |||
160 : | xframe.bitstream = m4v_buffer; | ||
161 : | xframe.length = 9999; | ||
162 : | xframe.image = out_buffer; | ||
163 : | xframe.stride = XDIM; | ||
164 : | xframe.colorspace = XVID_CSP_YV12; | ||
165 : | |||
166 : | do { | ||
167 : | xerr = xvid_decore(dec_handle, XVID_DEC_DECODE, &xframe, NULL); | ||
168 : | |||
169 : | *m4v_size = xframe.length; | ||
170 : | xframe.bitstream += *m4v_size; | ||
171 : | |||
172 : | } while (*m4v_size<7); /* this skips N-VOPs */ | ||
173 : | |||
174 : | return xerr; | ||
175 : | } | ||
176 : | |||
177 : | int dec_stop() /* close decoder to release resources */ | ||
178 : | { | ||
179 : | int xerr; | ||
180 : | xerr = xvid_decore(dec_handle, XVID_DEC_DESTROY, NULL, NULL); | ||
181 : | |||
182 : | return xerr; | ||
183 : | } | ||
184 : | |||
185 : | |||
186 : | /*********************************************************************/ | ||
187 : | /* Main program */ | ||
188 : | /*********************************************************************/ | ||
189 : | |||
190 : | int main(int argc, char *argv[]) | ||
191 : | { | ||
192 : | unsigned char *divx_buffer = NULL; | ||
193 : | unsigned char *divx_ptr = NULL; | ||
194 : | unsigned char *out_buffer = NULL; | ||
195 : | |||
196 : | double dectime; | ||
197 : | double totaldectime=0.; | ||
198 : | |||
199 : | long totalsize=0; | ||
200 : | int status; | ||
201 : | |||
202 : | int m4v_size; | ||
203 : | int frame_type[ABS_MAXFRAMENR]; | ||
204 : | int use_assembler=1; | ||
205 : | |||
206 : | char filename[256]; | ||
207 : | |||
208 : | FILE *filehandle; | ||
209 : | |||
210 : | if (argc>=3) | ||
211 : | { XDIM = atoi(argv[1]); | ||
212 : | YDIM = atoi(argv[2]); | ||
213 : | if ( (XDIM <= 0) || (XDIM >= 2048) || (YDIM <=0) || (YDIM >= 2048) ) | ||
214 : | { fprintf(stderr,"Wrong frames size %d %d, trying PGM \n",XDIM, YDIM); | ||
215 : | } | ||
216 : | } | ||
217 : | if (argc>=4 && !strcmp(argv[3],"noasm")) | ||
218 : | use_assembler = 0; | ||
219 : | |||
220 : | |||
221 : | /* allocate memory */ | ||
222 : | |||
223 : | divx_buffer = (unsigned char *) malloc(10*XDIM*YDIM); | ||
224 : | // this should really be enough memory! | ||
225 : | if (!divx_buffer) | ||
226 : | goto free_all_memory; | ||
227 : | divx_ptr = divx_buffer+10*XDIM*YDIM; | ||
228 : | |||
229 : | out_buffer = (unsigned char *) malloc(4*XDIM*YDIM); /* YUV needs less */ | ||
230 : | if (!out_buffer) | ||
231 : | goto free_all_memory; | ||
232 : | |||
233 : | |||
234 : | /*********************************************************************/ | ||
235 : | /* XviD PART Start */ | ||
236 : | /*********************************************************************/ | ||
237 : | |||
238 : | status = dec_init(use_assembler); | ||
239 : | if (status) | ||
240 : | { | ||
241 : | printf("Decore INIT problem, return value %d\n", status); | ||
242 : | goto release_all; | ||
243 : | } | ||
244 : | |||
245 : | |||
246 : | /*********************************************************************/ | ||
247 : | /* Main loop */ | ||
248 : | /*********************************************************************/ | ||
249 : | |||
250 : | do | ||
251 : | { | ||
252 : | |||
253 : | if (divx_ptr > divx_buffer+5*XDIM*YDIM) /* buffer more than half empty */ | ||
254 : | { int rest=(divx_buffer+10*XDIM*YDIM-divx_ptr); | ||
255 : | if (rest) | ||
256 : | memcpy(divx_buffer, divx_ptr, rest); | ||
257 : | divx_ptr = divx_buffer; | ||
258 : | fread(divx_buffer+rest, 1, 5*XDIM*YDIM, stdin); /* read new data */ | ||
259 : | } | ||
260 : | |||
261 : | dectime = -msecond(); | ||
262 : | status = dec_main(divx_ptr, out_buffer, &m4v_size); | ||
263 : | |||
264 : | if (status) | ||
265 : | { | ||
266 : | break; | ||
267 : | } | ||
268 : | dectime += msecond(); | ||
269 : | divx_ptr += m4v_size; | ||
270 : | |||
271 : | totalsize += m4v_size; | ||
272 : | |||
273 : | printf("Frame %5d: dectime =%6.1f ms length=%7d bytes \n", | ||
274 : | filenr, dectime*1000, m4v_size); | ||
275 : | |||
276 : | if (save_m4v_flag) | ||
277 : | { | ||
278 : | sprintf(filename, "%sframe%05d.m4v", filepath, filenr); | ||
279 : | filehandle = fopen(filename, "wb"); | ||
280 : | fwrite(divx_buffer, m4v_size, 1, filehandle); | ||
281 : | fclose(filehandle); | ||
282 : | } | ||
283 : | totaldectime += dectime; | ||
284 : | |||
285 : | |||
286 : | /*********************************************************************/ | ||
287 : | /* analyse the decoded frame and compare to original */ | ||
288 : | /*********************************************************************/ | ||
289 : | |||
290 : | if (save_dec_flag) | ||
291 : | { | ||
292 : | sprintf(filename, "%sdec%05d.pgm", filepath, filenr); | ||
293 : | write_pgm(filename,out_buffer); | ||
294 : | } | ||
295 : | |||
296 : | filenr++; | ||
297 : | |||
298 : | } while ( (status>=0) && (filenr<ABS_MAXFRAMENR) ); | ||
299 : | |||
300 : | |||
301 : | /*********************************************************************/ | ||
302 : | /* calculate totals and averages for output, print results */ | ||
303 : | /*********************************************************************/ | ||
304 : | |||
305 : | totalsize /= filenr; | ||
306 : | totaldectime /= filenr; | ||
307 : | |||
308 : | fprintf(stderr,"Avg: dectime %5.2f ms, %5.2f fps, filesize =%d\n", | ||
309 : | 1000*totaldectime, 1./totaldectime, totalsize); | ||
310 : | |||
311 : | /*********************************************************************/ | ||
312 : | /* XviD PART Stop */ | ||
313 : | /*********************************************************************/ | ||
314 : | |||
315 : | release_all: | ||
316 : | |||
317 : | if (dec_handle) | ||
318 : | { | ||
319 : | status = dec_stop(); | ||
320 : | if (status) | ||
321 : | printf("Decore RELEASE problem return value %d\n", status); | ||
322 : | } | ||
323 : | |||
324 : | free_all_memory: | ||
325 : | free(out_buffer); | ||
326 : | free(divx_buffer); | ||
327 : | |||
328 : | return 0; | ||
329 : | } |
No admin address has been configured | ViewVC Help |
Powered by ViewVC 1.0.4 |