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

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