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

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

Parent Directory Parent Directory | Revision Log Revision Log


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

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