[svn] / branches / release-1_0-branch / xvidcore / examples / xvid_decraw.c Repository:
ViewVC logotype

Annotation of /branches/release-1_0-branch/xvidcore/examples/xvid_decraw.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 851 - (view) (download)
Original Path: trunk/xvidcore/examples/xvid_decraw.c

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 : edgomez 851 * $Id: xvid_decraw.c,v 1.6 2003-02-15 15:22:17 edgomez 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 :     * -w integer : frame width ([1.2048])
45 :     * -h integer : frame height ([1.2048])
46 :     * -i string : input filename (default=stdin)
47 :     * -t integer : input data type (raw=0, mp4u=1)
48 :     * -d boolean : save decoder output (0 False*, !=0 True)
49 :     * -m boolean : save mpeg4 raw stream to single files (0 False*, !=0 True)
50 :     * -help : This help message
51 :     * (* means default)
52 : chl 376 *
53 : edgomez 547 ****************************************************************************/
54 : chl 376
55 :     #include <stdio.h>
56 :     #include <stdlib.h>
57 : edgomez 547 #include <string.h>
58 :     #include <math.h>
59 : edgomez 824 #ifndef WIN32
60 : edgomez 547 #include <sys/time.h>
61 :     #else
62 :     #include <time.h>
63 :     #endif
64 : chl 376
65 : edgomez 547 #include "xvid.h"
66 : chl 376
67 : edgomez 547 /*****************************************************************************
68 :     * Global vars in module and constants
69 :     ****************************************************************************/
70 : chl 376
71 : edgomez 547 /* max number of frames */
72 :     #define ABS_MAXFRAMENR 9999
73 : chl 376
74 : edgomez 547 static int XDIM = 0;
75 :     static int YDIM = 0;
76 :     static int ARG_SAVEDECOUTPUT = 0;
77 :     static int ARG_SAVEMPEGSTREAM = 0;
78 :     static char *ARG_INPUTFILE = NULL;
79 : chl 376
80 :    
81 : edgomez 547 static char filepath[256] = "./";
82 :     static void *dec_handle = NULL;
83 : chl 376
84 : edgomez 547 # define BUFFER_SIZE 10*XDIM*YDIM
85 : chl 376
86 : edgomez 547 /*****************************************************************************
87 :     * Local prototypes
88 :     ****************************************************************************/
89 : chl 376
90 : edgomez 547 static double msecond();
91 :     static int write_pgm(char *filename,
92 :     unsigned char *image);
93 :     static int dec_init(int use_assembler);
94 :     static int dec_main(unsigned char *istream,
95 : edgomez 851 unsigned char *ostream,
96 :     int istream_size,
97 :     int *ostream_size,
98 :     int *isframe);
99 : edgomez 547 static int dec_stop();
100 :     static void usage();
101 :    
102 :     /*****************************************************************************
103 :     * Main program
104 :     ****************************************************************************/
105 :    
106 :     int main(int argc, char *argv[])
107 : chl 376 {
108 : edgomez 547 unsigned char *mp4_buffer = NULL;
109 :     unsigned char *mp4_ptr = NULL;
110 :     unsigned char *out_buffer = NULL;
111 :     int bigendian = 0;
112 : edgomez 851 int still_left_in_buffer;
113 :     int delayed_frames;
114 :    
115 : edgomez 547 double totaldectime;
116 :    
117 :     long totalsize;
118 :     int status;
119 :    
120 :     int use_assembler = 0;
121 :    
122 :     char filename[256];
123 :    
124 :     FILE *in_file;
125 :     int filenr;
126 :     int i;
127 :    
128 :     printf("xvid_decraw - raw mpeg4 bitstream decoder ");
129 : edgomez 851 printf("written by Christoph Lampert 2002-2003\n\n");
130 : edgomez 547
131 :     /*****************************************************************************
132 :     * Command line parsing
133 :     ****************************************************************************/
134 :    
135 :     for (i=1; i< argc; i++) {
136 :    
137 :     if (strcmp("-asm", argv[i]) == 0 ) {
138 :     use_assembler = 1;
139 :     }
140 :     else if (strcmp("-w", argv[i]) == 0 && i < argc - 1 ) {
141 :     i++;
142 :     XDIM = atoi(argv[i]);
143 :     }
144 :     else if (strcmp("-h", argv[i]) == 0 && i < argc - 1 ) {
145 :     i++;
146 :     YDIM = atoi(argv[i]);
147 :     }
148 :     else if (strcmp("-d", argv[i]) == 0 && i < argc - 1 ) {
149 :     i++;
150 :     ARG_SAVEDECOUTPUT = atoi(argv[i]);
151 :     }
152 :     else if (strcmp("-i", argv[i]) == 0 && i < argc - 1 ) {
153 :     i++;
154 :     ARG_INPUTFILE = argv[i];
155 :     }
156 :     else if (strcmp("-m", argv[i]) == 0 && i < argc - 1 ) {
157 :     i++;
158 :     ARG_SAVEMPEGSTREAM = atoi(argv[i]);
159 :     }
160 :     else if (strcmp("-help", argv[i])) {
161 :     usage();
162 :     return(0);
163 :     }
164 :     else {
165 :     usage();
166 :     exit(-1);
167 :     }
168 :    
169 : chl 376 }
170 : edgomez 547
171 :     /*****************************************************************************
172 :     * Values checking
173 :     ****************************************************************************/
174 :    
175 :     if(XDIM <= 0 || XDIM > 2048 || YDIM <= 0 || YDIM > 2048) {
176 :     usage();
177 :     return -1;
178 :     }
179 :    
180 :     if ( ARG_INPUTFILE == NULL || strcmp(ARG_INPUTFILE, "stdin") == 0) {
181 :     in_file = stdin;
182 :     }
183 :     else {
184 :    
185 :     in_file = fopen(ARG_INPUTFILE, "rb");
186 :     if (in_file == NULL) {
187 :     fprintf(stderr, "Error opening input file %s\n", ARG_INPUTFILE);
188 :     return -1;
189 :     }
190 :     }
191 :    
192 :     /*****************************************************************************
193 :     * Memory allocation
194 :     ****************************************************************************/
195 :    
196 :     /* Memory for encoded mp4 stream */
197 :     mp4_buffer = (unsigned char *) malloc(BUFFER_SIZE);
198 :     mp4_ptr = mp4_buffer;
199 :     if (!mp4_buffer)
200 :     goto free_all_memory;
201 :    
202 :     /* Memory for frame output */
203 :     out_buffer = (unsigned char *) malloc(XDIM*YDIM*4);
204 :     if (!out_buffer)
205 :     goto free_all_memory;
206 :    
207 :    
208 :     /*****************************************************************************
209 :     * XviD PART Start
210 :     ****************************************************************************/
211 :    
212 :     status = dec_init(use_assembler);
213 :     if (status) {
214 :     fprintf(stderr,
215 :     "Decore INIT problem, return value %d\n", status);
216 :     goto release_all;
217 :     }
218 :    
219 :    
220 :     /*****************************************************************************
221 :     * Main loop
222 :     ****************************************************************************/
223 :    
224 : edgomez 851 /* Fill the buffer */
225 :     still_left_in_buffer = fread(mp4_buffer, 1, BUFFER_SIZE, in_file);
226 : edgomez 559
227 : edgomez 547 totaldectime = 0;
228 :     totalsize = 0;
229 :     filenr = 0;
230 : edgomez 851 delayed_frames = 0;
231 : edgomez 547 mp4_ptr = mp4_buffer;
232 :    
233 :     do {
234 :    
235 :     int mp4_size = (mp4_buffer + BUFFER_SIZE - mp4_ptr);
236 :     int used_bytes = 0;
237 :     double dectime;
238 : edgomez 851 int notification;
239 : edgomez 547
240 : edgomez 851 /*
241 :     * If the buffer is half empty or there are no more bytes in it
242 :     * then fill it.
243 :     */
244 :     if (mp4_ptr > mp4_buffer + BUFFER_SIZE/2 ||
245 :     still_left_in_buffer <= 0) {
246 :     int rest = (mp4_buffer + BUFFER_SIZE - mp4_ptr);
247 : edgomez 547
248 : edgomez 851 /* Move data if needed */
249 :     if (rest)
250 :     memcpy(mp4_buffer, mp4_ptr, rest);
251 : edgomez 547
252 : edgomez 851 /* Update mp4_ptr */
253 :     mp4_ptr = mp4_buffer;
254 : edgomez 547
255 : edgomez 851 /* read new data */
256 : edgomez 547 if(feof(in_file))
257 :     break;
258 :    
259 : edgomez 851 still_left_in_buffer = fread(mp4_buffer + rest,
260 :     1,
261 :     BUFFER_SIZE - rest,
262 :     in_file);
263 : edgomez 547
264 :     }
265 :    
266 :    
267 : edgomez 851 /* This loop flushes N_VOPS (with vop_coded bit set to 0) */
268 :     do {
269 : edgomez 547
270 : edgomez 851 /* Decode frame */
271 :     dectime = msecond();
272 :     status = dec_main(mp4_ptr, out_buffer, mp4_size, &used_bytes, &notification);
273 :     dectime = msecond() - dectime;
274 : edgomez 547
275 : edgomez 851 if (status) {
276 :     break;
277 :     }
278 : edgomez 547
279 : edgomez 851 /* Update buffer pointers */
280 :     mp4_ptr += used_bytes;
281 :     still_left_in_buffer -= used_bytes;
282 : edgomez 559
283 : edgomez 851 /* Total size */
284 :     totalsize += used_bytes;
285 : edgomez 547
286 : edgomez 851 }while(used_bytes <= 7 && still_left_in_buffer > 0); /* <= 7 bytes is a NVOPS */
287 : edgomez 547
288 : edgomez 851 /* Negative buffer would mean we went too far */
289 :     if(still_left_in_buffer < 0) break;
290 :    
291 :     /* Skip when decoder is buffering images or decoding VOL information */
292 :     if(notification != XVID_DEC_VOP) {
293 :     /* It's a delay only if it notifies NOTHING */
294 :     if(notification == XVID_DEC_NOTHING)
295 :     delayed_frames++;
296 :     continue;
297 : edgomez 547 }
298 :    
299 : edgomez 851 /* Updated data - Count only usefull decode time */
300 :     totaldectime += dectime;
301 : edgomez 547
302 :     /* Prints some decoding stats */
303 : edgomez 851 printf("Frame %5d: dectime(ms) =%6.1f, length(bytes) =%7d\n",
304 :     filenr, dectime, used_bytes);
305 :    
306 :     /* Save individual mpeg4 stream if required */
307 : edgomez 547 if (ARG_SAVEMPEGSTREAM) {
308 :     FILE *filehandle = NULL;
309 :    
310 :     sprintf(filename, "%sframe%05d.m4v", filepath, filenr);
311 :     filehandle = fopen(filename, "wb");
312 :     if(!filehandle) {
313 :     fprintf(stderr,
314 : edgomez 851 "Error writing single mpeg4 stream to file %s\n",
315 :     filename);
316 : edgomez 547 }
317 :     else {
318 : edgomez 851 fwrite(mp4_buffer, 1, used_bytes, filehandle);
319 : edgomez 547 fclose(filehandle);
320 :     }
321 :     }
322 : edgomez 851
323 : edgomez 547 /* Save output frame if required */
324 :     if (ARG_SAVEDECOUTPUT) {
325 :     sprintf(filename, "%sdec%05d.pgm", filepath, filenr);
326 :     if(write_pgm(filename,out_buffer)) {
327 :     fprintf(stderr,
328 : edgomez 851 "Error writing decoded PGM frame %s\n",
329 :     filename);
330 : edgomez 547 }
331 :     }
332 :    
333 :     filenr++;
334 :    
335 : edgomez 851 } while ( (status>=0) && (filenr<ABS_MAXFRAMENR));
336 : edgomez 547
337 :     /*****************************************************************************
338 : edgomez 851 * Flush decoder buffers
339 :     ****************************************************************************/
340 :     while(delayed_frames--) {
341 :    
342 :     /* Fake vars */
343 :     int used_bytes, isframe;
344 :     double dectime;
345 :    
346 :     /* Decode frame */
347 :     dectime = msecond();
348 :     status = dec_main(NULL, out_buffer, -1, &used_bytes, &isframe);
349 :     dectime = msecond() - dectime;
350 :    
351 :     if (status) {
352 :     break;
353 :     }
354 :    
355 :     /* Updated data - Count only usefull decode time */
356 :     totaldectime += dectime;
357 :    
358 :     /* Prints some decoding stats */
359 :     printf("Frame %5d: dectime(ms) =%6.1f, length(bytes) =%7d\n",
360 :     filenr, dectime, used_bytes);
361 :    
362 :     /* Save output frame if required */
363 :     if (ARG_SAVEDECOUTPUT) {
364 :     sprintf(filename, "%sdec%05d.pgm", filepath, filenr);
365 :     if(write_pgm(filename,out_buffer)) {
366 :     fprintf(stderr,
367 :     "Error writing decoded PGM frame %s\n",
368 :     filename);
369 :     }
370 :     }
371 :    
372 :     filenr++;
373 :    
374 :     }
375 :    
376 :     /*****************************************************************************
377 : edgomez 547 * Calculate totals and averages for output, print results
378 :     ****************************************************************************/
379 :    
380 :     totalsize /= filenr;
381 :     totaldectime /= filenr;
382 :    
383 : edgomez 851 printf("Avg: dectime(ms) =%7.2f, fps =%7.2f, length(bytes) =%7d\n",
384 : edgomez 559 totaldectime, 1000/totaldectime, (int)totalsize);
385 : edgomez 547
386 :     /*****************************************************************************
387 :     * XviD PART Stop
388 : edgomez 559 ****************************************************************************/
389 : edgomez 547
390 :     release_all:
391 :     if (dec_handle) {
392 :     status = dec_stop();
393 :     if (status)
394 :     fprintf(stderr, "decore RELEASE problem return value %d\n", status);
395 :     }
396 :    
397 :     free_all_memory:
398 :     free(out_buffer);
399 :     free(mp4_buffer);
400 :    
401 :     return 0;
402 : chl 376 }
403 :    
404 : edgomez 547 /*****************************************************************************
405 :     * Usage function
406 :     ****************************************************************************/
407 : chl 376
408 : edgomez 547 static void usage()
409 : chl 376 {
410 : edgomez 547
411 :     fprintf(stderr, "Usage : xvid_decraw <-w width> <-h height> [OPTIONS]\n");
412 :     fprintf(stderr, "Options :\n");
413 :     fprintf(stderr, " -asm : use assembly optimizations (default=disabled)\n");
414 :     fprintf(stderr, " -w integer : frame width ([1.2048])\n");
415 :     fprintf(stderr, " -h integer : frame height ([1.2048])\n");
416 :     fprintf(stderr, " -i string : input filename (default=stdin)\n");
417 :     fprintf(stderr, " -t integer : input data type (raw=0, mp4u=1)\n");
418 :     fprintf(stderr, " -d boolean : save decoder output (0 False*, !=0 True)\n");
419 :     fprintf(stderr, " -m boolean : save mpeg4 raw stream to individual files (0 False*, !=0 True)\n");
420 :     fprintf(stderr, " -help : This help message\n");
421 :     fprintf(stderr, " (* means default)\n");
422 :    
423 :     }
424 :    
425 :     /*****************************************************************************
426 :     * "helper" functions
427 :     ****************************************************************************/
428 :    
429 :     /* return the current time in milli seconds */
430 :     static double
431 :     msecond()
432 :     {
433 : edgomez 824 #ifndef WIN32
434 : edgomez 547 struct timeval tv;
435 :     gettimeofday(&tv, 0);
436 : edgomez 551 return (double)tv.tv_sec*1.0e3 + (double)tv.tv_usec*1.0e-3;
437 : edgomez 547 #else
438 :     clock_t clk;
439 :     clk = clock();
440 :     return clk * 1000 / CLOCKS_PER_SEC;
441 :     #endif
442 :     }
443 :    
444 :     /*****************************************************************************
445 :     * output functions
446 :     ****************************************************************************/
447 :    
448 :     static int
449 :     write_pgm(char *filename,
450 :     unsigned char *image)
451 :     {
452 :     int loop;
453 :    
454 :     unsigned char *y = image;
455 :     unsigned char *u = image + XDIM*YDIM;
456 :     unsigned char *v = image + XDIM*YDIM + XDIM/2*YDIM/2;
457 :    
458 : chl 376 FILE *filehandle;
459 : edgomez 547 filehandle=fopen(filename,"w+b");
460 :     if (filehandle) {
461 : chl 376
462 : edgomez 547 /* Write header */
463 :     fprintf(filehandle,"P5\n\n%d %d 255\n", XDIM,YDIM*3/2);
464 :    
465 :     /* Write Y data */
466 :     fwrite(y, 1, XDIM*YDIM, filehandle);
467 :    
468 :     for(loop=0; loop<YDIM/2; loop++)
469 :     {
470 :     /* Write U scanline */
471 :     fwrite(u, 1, XDIM/2, filehandle);
472 :    
473 :     /* Write V scanline */
474 :     fwrite(v, 1, XDIM/2, filehandle);
475 :    
476 :     /* Update pointers */
477 :     u += XDIM/2;
478 :     v += XDIM/2;
479 :    
480 :     }
481 :    
482 :     /* Close file */
483 : chl 376 fclose(filehandle);
484 : edgomez 547
485 : chl 376 return 0;
486 :     }
487 :     else
488 :     return 1;
489 :     }
490 :    
491 : edgomez 547 /*****************************************************************************
492 :     * Routines for decoding: init decoder, use, and stop decoder
493 :     ****************************************************************************/
494 : chl 376
495 : edgomez 547 /* init decoder before first run */
496 :     static int
497 :     dec_init(int use_assembler)
498 : chl 376 {
499 :     int xerr;
500 :    
501 :     XVID_INIT_PARAM xinit;
502 :     XVID_DEC_PARAM xparam;
503 :    
504 :     if(use_assembler)
505 :     #ifdef ARCH_IA64
506 :     xinit.cpu_flags = XVID_CPU_FORCE | XVID_CPU_IA64;
507 :     #else
508 :     xinit.cpu_flags = 0;
509 :     #endif
510 :     else
511 :     xinit.cpu_flags = XVID_CPU_FORCE;
512 :    
513 :     xvid_init(NULL, 0, &xinit, NULL);
514 :     xparam.width = XDIM;
515 :     xparam.height = YDIM;
516 :    
517 :     xerr = xvid_decore(NULL, XVID_DEC_CREATE, &xparam, NULL);
518 : edgomez 851
519 : chl 376 dec_handle = xparam.handle;
520 :    
521 :     return xerr;
522 :     }
523 :    
524 : edgomez 547 /* decode one frame */
525 :     static int
526 :     dec_main(unsigned char *istream,
527 : edgomez 851 unsigned char *ostream,
528 :     int istream_size,
529 :     int *ostream_size,
530 :     int *notification)
531 : edgomez 547 {
532 : chl 376
533 :     int xerr;
534 :     XVID_DEC_FRAME xframe;
535 : edgomez 851 XVID_DEC_STATS xstats;
536 : chl 376
537 : edgomez 851 xframe.general = 0;
538 :     xframe.bitstream = istream;
539 :     xframe.length = istream_size;
540 :     xframe.image = ostream;
541 :     xframe.stride = XDIM;
542 :     xframe.colorspace = XVID_CSP_YV12;
543 : chl 376
544 : edgomez 851 xerr = xvid_decore(dec_handle, XVID_DEC_DECODE, &xframe, &xstats);
545 : chl 376
546 : edgomez 851 *ostream_size = xframe.length;
547 : chl 376
548 : edgomez 851 *notification = xstats.notify;
549 :    
550 : chl 376 return xerr;
551 :     }
552 :    
553 : edgomez 547 /* close decoder to release resources */
554 :     static int
555 :     dec_stop()
556 : chl 376 {
557 :     int xerr;
558 : edgomez 547
559 : chl 376 xerr = xvid_decore(dec_handle, XVID_DEC_DESTROY, NULL, NULL);
560 :    
561 :     return xerr;
562 :     }

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