[svn] / branches / dev-api-4 / xvidcore / examples / xvid_decraw.c Repository:
ViewVC logotype

Annotation of /branches/dev-api-4/xvidcore/examples/xvid_decraw.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1116 - (view) (download)

1 : edgomez 547 /*****************************************************************************
2 : chl 376 *
3 : edgomez 547 * XVID MPEG-4 VIDEO CODEC
4 :     * - Console based decoding test application -
5 : chl 376 *
6 : edgomez 851 * Copyright(C) 2002-2003 Christoph Lampert
7 : edgomez 1054 * 2002-2003 Edouard Gomez <ed.gomez@free.fr>
8 : chl 376 *
9 : edgomez 547 * This program is free software; you can redistribute it and/or modify
10 :     * it under the terms of the GNU General Public License as published by
11 :     * the Free Software Foundation; either version 2 of the License, or
12 :     * (at your option) any later version.
13 : chl 376 *
14 : edgomez 547 * This program is distributed in the hope that it will be useful,
15 :     * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 :     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 :     * GNU General Public License for more details.
18 : chl 376 *
19 : edgomez 547 * You should have received a copy of the GNU General Public License
20 :     * along with this program; if not, write to the Free Software
21 :     * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22 :     *
23 : chl 1116 * $Id: xvid_decraw.c,v 1.7.2.4 2003-08-09 09:52:02 chl Exp $
24 : edgomez 547 *
25 :     ****************************************************************************/
26 : chl 376
27 : edgomez 547 /*****************************************************************************
28 : chl 376 *
29 : edgomez 547 * Application notes :
30 : chl 376 *
31 : edgomez 547 * An MPEG-4 bitstream is read from an input file (or stdin) and decoded,
32 :     * the speed for this is measured.
33 :     *
34 : edgomez 1054 * The program is plain C and needs no libraries except for libxvidcore,
35 :     * and maths-lib.
36 :     *
37 :     * Use ./xvid_decraw -help for a list of options
38 : chl 376 *
39 : edgomez 547 ****************************************************************************/
40 : chl 376
41 :     #include <stdio.h>
42 :     #include <stdlib.h>
43 : edgomez 547 #include <string.h>
44 :     #include <math.h>
45 : edgomez 824 #ifndef WIN32
46 : edgomez 547 #include <sys/time.h>
47 :     #else
48 :     #include <time.h>
49 :     #endif
50 : chl 376
51 : edgomez 547 #include "xvid.h"
52 : chl 376
53 : edgomez 547 /*****************************************************************************
54 :     * Global vars in module and constants
55 :     ****************************************************************************/
56 : chl 376
57 : edgomez 547 /* max number of frames */
58 :     #define ABS_MAXFRAMENR 9999
59 : chl 376
60 : edgomez 547 static int XDIM = 0;
61 :     static int YDIM = 0;
62 :     static int ARG_SAVEDECOUTPUT = 0;
63 :     static int ARG_SAVEMPEGSTREAM = 0;
64 :     static char *ARG_INPUTFILE = NULL;
65 : chl 376
66 :    
67 : edgomez 547 static char filepath[256] = "./";
68 :     static void *dec_handle = NULL;
69 : chl 376
70 : edgomez 918 # define BUFFER_SIZE (2*1024*1024)
71 : chl 376
72 : edgomez 547 /*****************************************************************************
73 :     * Local prototypes
74 :     ****************************************************************************/
75 : chl 376
76 : edgomez 547 static double msecond();
77 :     static int write_pgm(char *filename,
78 : edgomez 918 unsigned char *image);
79 : edgomez 547 static int dec_init(int use_assembler);
80 :     static int dec_main(unsigned char *istream,
81 : edgomez 851 unsigned char *ostream,
82 :     int istream_size,
83 : edgomez 918 xvid_dec_stats_t *xvid_dec_stats);
84 : edgomez 547 static int dec_stop();
85 :     static void usage();
86 :    
87 : suxen_drol 945
88 :     const char * type2str(int type)
89 :     {
90 :     if (type==XVID_TYPE_IVOP)
91 :     return "I";
92 :     if (type==XVID_TYPE_PVOP)
93 :     return "P";
94 :     if (type==XVID_TYPE_BVOP)
95 :     return "B";
96 :     return "S";
97 :     }
98 :    
99 : edgomez 547 /*****************************************************************************
100 :     * Main program
101 :     ****************************************************************************/
102 :    
103 :     int main(int argc, char *argv[])
104 : chl 376 {
105 : edgomez 547 unsigned char *mp4_buffer = NULL;
106 :     unsigned char *mp4_ptr = NULL;
107 :     unsigned char *out_buffer = NULL;
108 : edgomez 851 int still_left_in_buffer;
109 : edgomez 918 xvid_dec_stats_t xvid_dec_stats;
110 : edgomez 851
111 : edgomez 547 double totaldectime;
112 :    
113 :     long totalsize;
114 :     int status;
115 :    
116 :     int use_assembler = 0;
117 :    
118 :     char filename[256];
119 :    
120 :     FILE *in_file;
121 :     int filenr;
122 :     int i;
123 :    
124 :     printf("xvid_decraw - raw mpeg4 bitstream decoder ");
125 : edgomez 851 printf("written by Christoph Lampert 2002-2003\n\n");
126 : edgomez 547
127 :     /*****************************************************************************
128 :     * Command line parsing
129 :     ****************************************************************************/
130 :    
131 :     for (i=1; i< argc; i++) {
132 :    
133 :     if (strcmp("-asm", argv[i]) == 0 ) {
134 :     use_assembler = 1;
135 :     }
136 : edgomez 918 else if (strcmp("-d", argv[i]) == 0) {
137 :     ARG_SAVEDECOUTPUT = 1;
138 : edgomez 547 }
139 :     else if (strcmp("-i", argv[i]) == 0 && i < argc - 1 ) {
140 :     i++;
141 :     ARG_INPUTFILE = argv[i];
142 :     }
143 : edgomez 918 else if (strcmp("-m", argv[i]) == 0) {
144 :     ARG_SAVEMPEGSTREAM = 1;
145 : edgomez 547 }
146 : chl 1116 else if (strcmp("-help", argv[i]) == 0) {
147 : edgomez 547 usage();
148 :     return(0);
149 :     }
150 : chl 1116 else {
151 : edgomez 547 usage();
152 :     exit(-1);
153 :     }
154 :    
155 : chl 376 }
156 : edgomez 547
157 :     /*****************************************************************************
158 :     * Values checking
159 :     ****************************************************************************/
160 :    
161 :     if ( ARG_INPUTFILE == NULL || strcmp(ARG_INPUTFILE, "stdin") == 0) {
162 :     in_file = stdin;
163 :     }
164 :     else {
165 :    
166 :     in_file = fopen(ARG_INPUTFILE, "rb");
167 :     if (in_file == NULL) {
168 :     fprintf(stderr, "Error opening input file %s\n", ARG_INPUTFILE);
169 : edgomez 918 return(-1);
170 : edgomez 547 }
171 :     }
172 :    
173 :     /*****************************************************************************
174 :     * Memory allocation
175 :     ****************************************************************************/
176 :    
177 :     /* Memory for encoded mp4 stream */
178 :     mp4_buffer = (unsigned char *) malloc(BUFFER_SIZE);
179 :     mp4_ptr = mp4_buffer;
180 :     if (!mp4_buffer)
181 :     goto free_all_memory;
182 :    
183 :     /*****************************************************************************
184 :     * XviD PART Start
185 :     ****************************************************************************/
186 :    
187 :     status = dec_init(use_assembler);
188 :     if (status) {
189 :     fprintf(stderr,
190 : edgomez 918 "Decore INIT problem, return value %d\n", status);
191 : edgomez 547 goto release_all;
192 :     }
193 :    
194 :    
195 :     /*****************************************************************************
196 :     * Main loop
197 :     ****************************************************************************/
198 :    
199 : edgomez 851 /* Fill the buffer */
200 :     still_left_in_buffer = fread(mp4_buffer, 1, BUFFER_SIZE, in_file);
201 : edgomez 559
202 : edgomez 547 totaldectime = 0;
203 :     totalsize = 0;
204 :     filenr = 0;
205 :     mp4_ptr = mp4_buffer;
206 :    
207 :     do {
208 :    
209 :     int mp4_size = (mp4_buffer + BUFFER_SIZE - mp4_ptr);
210 :     int used_bytes = 0;
211 :     double dectime;
212 :    
213 : edgomez 851 /*
214 :     * If the buffer is half empty or there are no more bytes in it
215 :     * then fill it.
216 :     */
217 :     if (mp4_ptr > mp4_buffer + BUFFER_SIZE/2 ||
218 :     still_left_in_buffer <= 0) {
219 :     int rest = (mp4_buffer + BUFFER_SIZE - mp4_ptr);
220 : edgomez 547
221 : edgomez 851 /* Move data if needed */
222 :     if (rest)
223 :     memcpy(mp4_buffer, mp4_ptr, rest);
224 : edgomez 547
225 : edgomez 851 /* Update mp4_ptr */
226 :     mp4_ptr = mp4_buffer;
227 : edgomez 547
228 : edgomez 851 /* read new data */
229 : suxen_drol 945 if(feof(in_file))
230 : edgomez 547 break;
231 :    
232 : edgomez 851 still_left_in_buffer = fread(mp4_buffer + rest,
233 :     1,
234 :     BUFFER_SIZE - rest,
235 :     in_file);
236 : edgomez 547
237 :     }
238 :    
239 :    
240 : edgomez 918 /* This loop is needed to handle VOL/NVOP reading */
241 : edgomez 851 do {
242 : edgomez 547
243 : edgomez 851 /* Decode frame */
244 :     dectime = msecond();
245 : edgomez 918 used_bytes = dec_main(mp4_ptr, out_buffer, mp4_size, &xvid_dec_stats);
246 : edgomez 851 dectime = msecond() - dectime;
247 : edgomez 547
248 : edgomez 918 /* Resize image buffer if needed */
249 :     if(xvid_dec_stats.type == XVID_TYPE_VOL) {
250 :    
251 :     /* Free old output buffer*/
252 :     if(out_buffer) free(out_buffer);
253 :    
254 :     /* Copy witdh and height from the vol structure */
255 :     XDIM = xvid_dec_stats.data.vol.width;
256 :     YDIM = xvid_dec_stats.data.vol.height;
257 :    
258 :     /* Allocate the new buffer */
259 :     if((out_buffer = (unsigned char*)malloc(XDIM*YDIM*4)) == NULL)
260 :     goto free_all_memory;
261 : edgomez 851 }
262 : edgomez 547
263 : edgomez 851 /* Update buffer pointers */
264 : edgomez 918 if(used_bytes > 0) {
265 :     mp4_ptr += used_bytes;
266 :     still_left_in_buffer -= used_bytes;
267 : edgomez 559
268 : edgomez 918 /* Total size */
269 :     totalsize += used_bytes;
270 :     }
271 : edgomez 547
272 : suxen_drol 945 }while(xvid_dec_stats.type <= 0 && still_left_in_buffer > 0);
273 : edgomez 547
274 : edgomez 851 /* Negative buffer would mean we went too far */
275 : suxen_drol 945 if(still_left_in_buffer <= 0)
276 :     break;
277 : edgomez 851
278 : suxen_drol 945 /* Updated data - Count only usefull decode time */
279 : edgomez 851 totaldectime += dectime;
280 : edgomez 547
281 : edgomez 851
282 : suxen_drol 945 printf("Frame %5d: type = %s, dectime(ms) =%6.1f, length(bytes) =%7d\n",
283 :     filenr, type2str(xvid_dec_stats.type), dectime, used_bytes);
284 :    
285 : edgomez 851 /* Save individual mpeg4 stream if required */
286 : edgomez 918 if(ARG_SAVEMPEGSTREAM) {
287 : edgomez 547 FILE *filehandle = NULL;
288 :    
289 :     sprintf(filename, "%sframe%05d.m4v", filepath, filenr);
290 :     filehandle = fopen(filename, "wb");
291 :     if(!filehandle) {
292 :     fprintf(stderr,
293 : edgomez 851 "Error writing single mpeg4 stream to file %s\n",
294 :     filename);
295 : edgomez 547 }
296 :     else {
297 : edgomez 851 fwrite(mp4_buffer, 1, used_bytes, filehandle);
298 : edgomez 547 fclose(filehandle);
299 :     }
300 :     }
301 : edgomez 851
302 : edgomez 547 /* Save output frame if required */
303 :     if (ARG_SAVEDECOUTPUT) {
304 :     sprintf(filename, "%sdec%05d.pgm", filepath, filenr);
305 :     if(write_pgm(filename,out_buffer)) {
306 :     fprintf(stderr,
307 : edgomez 851 "Error writing decoded PGM frame %s\n",
308 :     filename);
309 : edgomez 547 }
310 :     }
311 :    
312 :     filenr++;
313 :    
314 : edgomez 851 } while ( (status>=0) && (filenr<ABS_MAXFRAMENR));
315 : edgomez 547
316 :     /*****************************************************************************
317 : edgomez 851 * Flush decoder buffers
318 :     ****************************************************************************/
319 : edgomez 918
320 : suxen_drol 945 do {
321 : edgomez 851
322 :     /* Fake vars */
323 : edgomez 918 int used_bytes;
324 : edgomez 851 double dectime;
325 :    
326 : suxen_drol 945 do {
327 :     dectime = msecond();
328 :     used_bytes = dec_main(NULL, out_buffer, -1, &xvid_dec_stats);
329 :     dectime = msecond() - dectime;
330 :     }while(used_bytes>=0 && xvid_dec_stats.type <= 0);
331 : edgomez 851
332 : suxen_drol 945 if (used_bytes < 0) { /* XVID_ERR_END */
333 :     break;
334 :     }
335 :    
336 : edgomez 851 /* Updated data - Count only usefull decode time */
337 :     totaldectime += dectime;
338 :    
339 :     /* Prints some decoding stats */
340 : suxen_drol 945 printf("Frame %5d: type = %s, dectime(ms) =%6.1f, length(bytes) =%7d\n",
341 :     filenr, type2str(xvid_dec_stats.type), dectime, used_bytes);
342 : edgomez 851
343 :     /* Save output frame if required */
344 :     if (ARG_SAVEDECOUTPUT) {
345 :     sprintf(filename, "%sdec%05d.pgm", filepath, filenr);
346 : edgomez 918 if(write_pgm(filename, out_buffer)) {
347 : edgomez 851 fprintf(stderr,
348 :     "Error writing decoded PGM frame %s\n",
349 :     filename);
350 :     }
351 :     }
352 :    
353 :     filenr++;
354 :    
355 : suxen_drol 945 }while(1);
356 : edgomez 851
357 :     /*****************************************************************************
358 : edgomez 547 * Calculate totals and averages for output, print results
359 :     ****************************************************************************/
360 :    
361 :     totalsize /= filenr;
362 :     totaldectime /= filenr;
363 :    
364 : edgomez 851 printf("Avg: dectime(ms) =%7.2f, fps =%7.2f, length(bytes) =%7d\n",
365 : edgomez 918 totaldectime, 1000/totaldectime, (int)totalsize);
366 : edgomez 547
367 :     /*****************************************************************************
368 :     * XviD PART Stop
369 : edgomez 559 ****************************************************************************/
370 : edgomez 547
371 :     release_all:
372 :     if (dec_handle) {
373 :     status = dec_stop();
374 :     if (status)
375 :     fprintf(stderr, "decore RELEASE problem return value %d\n", status);
376 :     }
377 :    
378 :     free_all_memory:
379 :     free(out_buffer);
380 :     free(mp4_buffer);
381 :    
382 : edgomez 918 return(0);
383 : chl 376 }
384 :    
385 : edgomez 547 /*****************************************************************************
386 :     * Usage function
387 :     ****************************************************************************/
388 : chl 376
389 : edgomez 547 static void usage()
390 : chl 376 {
391 : edgomez 547
392 : chl 1116 fprintf(stderr, "Usage : xvid_decraw [OPTIONS]\n");
393 : edgomez 547 fprintf(stderr, "Options :\n");
394 :     fprintf(stderr, " -asm : use assembly optimizations (default=disabled)\n");
395 :     fprintf(stderr, " -i string : input filename (default=stdin)\n");
396 :     fprintf(stderr, " -t integer : input data type (raw=0, mp4u=1)\n");
397 : edgomez 918 fprintf(stderr, " -d : save decoder output\n");
398 :     fprintf(stderr, " -m : save mpeg4 raw stream to individual files\n");
399 : edgomez 547 fprintf(stderr, " -help : This help message\n");
400 :     fprintf(stderr, " (* means default)\n");
401 :    
402 :     }
403 :    
404 :     /*****************************************************************************
405 :     * "helper" functions
406 :     ****************************************************************************/
407 :    
408 :     /* return the current time in milli seconds */
409 :     static double
410 :     msecond()
411 :     {
412 : edgomez 824 #ifndef WIN32
413 : edgomez 547 struct timeval tv;
414 :     gettimeofday(&tv, 0);
415 : edgomez 918 return((double)tv.tv_sec*1.0e3 + (double)tv.tv_usec*1.0e-3);
416 : edgomez 547 #else
417 :     clock_t clk;
418 :     clk = clock();
419 : edgomez 918 return(clk * 1000 / CLOCKS_PER_SEC);
420 : edgomez 547 #endif
421 :     }
422 :    
423 :     /*****************************************************************************
424 :     * output functions
425 :     ****************************************************************************/
426 :    
427 :     static int
428 :     write_pgm(char *filename,
429 : edgomez 918 unsigned char *image)
430 : edgomez 547 {
431 :     int loop;
432 :    
433 :     unsigned char *y = image;
434 :     unsigned char *u = image + XDIM*YDIM;
435 :     unsigned char *v = image + XDIM*YDIM + XDIM/2*YDIM/2;
436 :    
437 : chl 376 FILE *filehandle;
438 : edgomez 547 filehandle=fopen(filename,"w+b");
439 :     if (filehandle) {
440 : chl 376
441 : edgomez 547 /* Write header */
442 :     fprintf(filehandle,"P5\n\n%d %d 255\n", XDIM,YDIM*3/2);
443 :    
444 :     /* Write Y data */
445 :     fwrite(y, 1, XDIM*YDIM, filehandle);
446 :    
447 :     for(loop=0; loop<YDIM/2; loop++)
448 :     {
449 :     /* Write U scanline */
450 :     fwrite(u, 1, XDIM/2, filehandle);
451 :    
452 :     /* Write V scanline */
453 :     fwrite(v, 1, XDIM/2, filehandle);
454 :    
455 :     /* Update pointers */
456 :     u += XDIM/2;
457 :     v += XDIM/2;
458 :    
459 :     }
460 :    
461 :     /* Close file */
462 : chl 376 fclose(filehandle);
463 : edgomez 547
464 : edgomez 918 return(0);
465 : chl 376 }
466 :     else
467 : edgomez 918 return(1);
468 : chl 376 }
469 :    
470 : edgomez 547 /*****************************************************************************
471 :     * Routines for decoding: init decoder, use, and stop decoder
472 :     ****************************************************************************/
473 : chl 376
474 : edgomez 547 /* init decoder before first run */
475 :     static int
476 :     dec_init(int use_assembler)
477 : chl 376 {
478 : edgomez 918 int ret;
479 : chl 376
480 : edgomez 918 xvid_gbl_init_t xvid_gbl_init;
481 :     xvid_dec_create_t xvid_dec_create;
482 : chl 376
483 : edgomez 918 /*------------------------------------------------------------------------
484 :     * XviD core initialization
485 :     *----------------------------------------------------------------------*/
486 :    
487 :     /* Version */
488 :     xvid_gbl_init.version = XVID_VERSION;
489 :    
490 :     /* Assembly setting */
491 :     if(use_assembler)
492 : suxen_drol 860 #ifdef ARCH_IS_IA64
493 : edgomez 918 xvid_gbl_init.cpu_flags = XVID_CPU_FORCE | XVID_CPU_IA64;
494 : chl 376 #else
495 : edgomez 918 xvid_gbl_init.cpu_flags = 0;
496 : chl 376 #endif
497 : edgomez 918 else
498 :     xvid_gbl_init.cpu_flags = XVID_CPU_FORCE;
499 : chl 376
500 : edgomez 918 xvid_global(NULL, 0, &xvid_gbl_init, NULL);
501 : chl 376
502 : edgomez 918 /*------------------------------------------------------------------------
503 :     * XviD encoder initialization
504 :     *----------------------------------------------------------------------*/
505 : edgomez 851
506 : edgomez 918 /* Version */
507 :     xvid_dec_create.version = XVID_VERSION;
508 : chl 376
509 : edgomez 918 /*
510 :     * Image dimensions -- set to 0, xvidcore will resize when ever it is
511 :     * needed
512 :     */
513 :     xvid_dec_create.width = 0;
514 :     xvid_dec_create.height = 0;
515 :    
516 :     ret = xvid_decore(NULL, XVID_DEC_CREATE, &xvid_dec_create, NULL);
517 :    
518 :     dec_handle = xvid_dec_create.handle;
519 :    
520 :     return(ret);
521 : chl 376 }
522 :    
523 : edgomez 547 /* decode one frame */
524 :     static int
525 :     dec_main(unsigned char *istream,
526 : edgomez 851 unsigned char *ostream,
527 :     int istream_size,
528 : edgomez 918 xvid_dec_stats_t *xvid_dec_stats)
529 : edgomez 547 {
530 : chl 376
531 : edgomez 918 int ret;
532 : chl 376
533 : edgomez 918 xvid_dec_frame_t xvid_dec_frame;
534 : chl 376
535 : edgomez 918 /* Set version */
536 :     xvid_dec_frame.version = XVID_VERSION;
537 :     xvid_dec_stats->version = XVID_VERSION;
538 : chl 376
539 : edgomez 918 /* No general flags to set */
540 :     xvid_dec_frame.general = 0;
541 : chl 376
542 : edgomez 918 /* Input stream */
543 :     xvid_dec_frame.bitstream = istream;
544 :     xvid_dec_frame.length = istream_size;
545 : edgomez 851
546 : edgomez 918 /* Output frame structure */
547 :     xvid_dec_frame.output.plane[0] = ostream;
548 :     xvid_dec_frame.output.stride[0] = XDIM;
549 :     xvid_dec_frame.output.csp = XVID_CSP_I420;
550 :    
551 :     ret = xvid_decore(dec_handle, XVID_DEC_DECODE, &xvid_dec_frame, xvid_dec_stats);
552 :    
553 :     return(ret);
554 : chl 376 }
555 :    
556 : edgomez 547 /* close decoder to release resources */
557 :     static int
558 :     dec_stop()
559 : chl 376 {
560 : edgomez 918 int ret;
561 : edgomez 547
562 : edgomez 918 ret = xvid_decore(dec_handle, XVID_DEC_DESTROY, NULL, NULL);
563 : chl 376
564 : edgomez 918 return(ret);
565 : chl 376 }

No admin address has been configured
ViewVC Help
Powered by ViewVC 1.0.4