[cvs] / xvidcore / examples / xvid_decraw.c Repository:
ViewVC logotype

Annotation of /xvidcore/examples/xvid_decraw.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.4 - (view) (download)

1 : edgomez 1.2 /*****************************************************************************
2 : chl 1.1 *
3 : edgomez 1.2 * XVID MPEG-4 VIDEO CODEC
4 :     * - Console based decoding test application -
5 : chl 1.1 *
6 : edgomez 1.2 * Copyright(C) 2002 Christoph Lampert
7 : chl 1.1 *
8 : edgomez 1.2 * 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 1.1 *
13 : edgomez 1.2 * 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 1.1 *
18 : edgomez 1.2 * 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 1.4 * $Id: xvid_decraw.c,v 1.3 2002/09/27 20:58:30 edgomez Exp $
23 : edgomez 1.2 *
24 :     ****************************************************************************/
25 : chl 1.1
26 : edgomez 1.2 /*****************************************************************************
27 : chl 1.1 *
28 : edgomez 1.2 * Application notes :
29 : chl 1.1 *
30 : edgomez 1.2 * An MPEG-4 bitstream is read from an input file (or stdin) and decoded,
31 :     * the speed for this is measured.
32 : chl 1.1 *
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 1.2 *
36 : chl 1.1 * 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 1.2 *
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 1.1 *
53 : edgomez 1.2 ****************************************************************************/
54 : chl 1.1
55 :     #include <stdio.h>
56 :     #include <stdlib.h>
57 : edgomez 1.2 #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 :    
65 :     #include "xvid.h"
66 :    
67 :     /*****************************************************************************
68 :     * Global vars in module and constants
69 :     ****************************************************************************/
70 :    
71 :     /* max number of frames */
72 :     #define ABS_MAXFRAMENR 9999
73 :    
74 :     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 :    
81 :    
82 :     static char filepath[256] = "./";
83 :     static void *dec_handle = NULL;
84 :    
85 :     # define BUFFER_SIZE 10*XDIM*YDIM
86 :    
87 :     #define LONG_PACK(a,b,c,d) ((long) (((long)(a))<<24) | (((long)(b))<<16) | \
88 :     (((long)(c))<<8) |((long)(d)))
89 :    
90 :     #define SWAP(a) ( (((a)&0x000000ff)<<24) | (((a)&0x0000ff00)<<8) | \
91 :     (((a)&0x00ff0000)>>8) | (((a)&0xff000000)>>24) )
92 :    
93 :     /*****************************************************************************
94 :     * Local prototypes
95 :     ****************************************************************************/
96 :    
97 :     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 :     {
114 :     unsigned char *mp4_buffer = NULL;
115 :     unsigned char *mp4_ptr = NULL;
116 :     unsigned char *out_buffer = NULL;
117 :     int bigendian = 0;
118 :    
119 :     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 :     }
178 :    
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 : chl 1.1
216 : edgomez 1.2 /*****************************************************************************
217 :     * XviD PART Start
218 :     ****************************************************************************/
219 : chl 1.1
220 : edgomez 1.2 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 : edgomez 1.4 totalsize = LONG_PACK('M','P','4','U');
233 :     mp4_ptr = (unsigned char *)&totalsize;
234 :     if(*mp4_ptr == 'M')
235 :     bigendian = 1;
236 :     else
237 :     bigendian = 0;
238 :    
239 : edgomez 1.2 if(ARG_STREAMTYPE) {
240 :    
241 :     unsigned char header[4];
242 :    
243 :     /* MP4U format : read header */
244 :     if(feof(in_file))
245 :     goto release_all;
246 :     fread(header, 4, 1, in_file);
247 :    
248 : edgomez 1.4 if(header[0] != 'M' || header[1] != 'P' ||
249 :     header[2] != '4' || header[3] != 'U') {
250 : edgomez 1.2 fprintf(stderr, "Error, this not a mp4u container file\n");
251 :     goto release_all;
252 :     }
253 :    
254 :     }
255 : edgomez 1.4 else {
256 :     fread(mp4_buffer, BUFFER_SIZE, 1, in_file);
257 :     }
258 : edgomez 1.2
259 :     totaldectime = 0;
260 :     totalsize = 0;
261 :     filenr = 0;
262 :     mp4_ptr = mp4_buffer;
263 :    
264 :     do {
265 :    
266 :     int mp4_size = (mp4_buffer + BUFFER_SIZE - mp4_ptr);
267 :     int used_bytes = 0;
268 :     double dectime;
269 :    
270 :     /* Read data from input file */
271 :     if(ARG_STREAMTYPE) {
272 :    
273 :     /* MP4U container */
274 :    
275 :     /* Read stream size first */
276 :     if(feof(in_file))
277 :     break;
278 :     fread(&mp4_size, sizeof(long), 1, in_file);
279 :    
280 : edgomez 1.4 /* Mp4U container is big endian */
281 :     if(!bigendian)
282 : edgomez 1.2 mp4_size = SWAP(mp4_size);
283 :    
284 :     /* Read mp4_size_bytes */
285 :     if(feof(in_file))
286 :     break;
287 :     fread(mp4_buffer, mp4_size, 1, in_file);
288 :    
289 :     /*
290 :     * When reading mp4u, we don't have to care about buffer
291 :     * filling as we know exactly how much bytes there are in
292 :     * next frame
293 :     */
294 :     mp4_ptr = mp4_buffer;
295 :    
296 :     }
297 :     else {
298 :    
299 :     /* Real raw stream */
300 :    
301 :     /* buffer more than half empty -> Fill it */
302 :     if (mp4_ptr > mp4_buffer + BUFFER_SIZE/2) {
303 :     int rest = (mp4_buffer + BUFFER_SIZE - mp4_ptr);
304 :    
305 :     /* Move data if needed */
306 :     if (rest)
307 :     memcpy(mp4_buffer, mp4_ptr, rest);
308 :    
309 :     /* Update mp4_ptr */
310 :     mp4_ptr = mp4_buffer;
311 :    
312 :     /* read new data */
313 :     if(feof(in_file))
314 :     break;
315 :     fread(mp4_buffer + rest, BUFFER_SIZE - rest, 1, in_file);
316 : edgomez 1.4
317 : edgomez 1.2 }
318 :    
319 :     }
320 :    
321 :     /* Decode frame */
322 :     dectime = msecond();
323 :     status = dec_main(mp4_ptr, out_buffer, mp4_size, &used_bytes);
324 :     dectime = msecond() - dectime;
325 :    
326 :     if (status) {
327 :     break;
328 :     }
329 :    
330 :     /*
331 :     * Only needed for real raw stream, mp4u uses
332 :     * mp4_ptr = mp4_buffer for each frame
333 :     */
334 :     mp4_ptr += used_bytes;
335 :    
336 :     /* Updated data */
337 :     totalsize += used_bytes;
338 :     totaldectime += dectime;
339 :    
340 :     /* Prints some decoding stats */
341 :     printf("Frame %5d: dectime =%6.1f ms length=%7d bytes \n",
342 :     filenr, dectime, used_bytes);
343 :    
344 :     /* Save individual mpeg4 strean if required */
345 :     if (ARG_SAVEMPEGSTREAM) {
346 :     FILE *filehandle = NULL;
347 :    
348 :     sprintf(filename, "%sframe%05d.m4v", filepath, filenr);
349 :     filehandle = fopen(filename, "wb");
350 :     if(!filehandle) {
351 :     fprintf(stderr,
352 :     "Error writing single mpeg4 stream to file %s\n",
353 :     filename);
354 :     }
355 :     else {
356 :     fwrite(mp4_buffer, used_bytes, 1, filehandle);
357 :     fclose(filehandle);
358 :     }
359 :     }
360 :    
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 :     } while ( (status>=0) && (filenr<ABS_MAXFRAMENR) );
375 :    
376 :    
377 :     /*****************************************************************************
378 :     * Calculate totals and averages for output, print results
379 :     ****************************************************************************/
380 : chl 1.1
381 : edgomez 1.2 totalsize /= filenr;
382 :     totaldectime /= filenr;
383 :    
384 :     printf("Avg: dectime %5.2f ms, %5.2f fps, mp4 stream size =%d\n",
385 : edgomez 1.4 totaldectime, 1000/totaldectime, (int)totalsize);
386 : edgomez 1.2
387 :     /*****************************************************************************
388 :     * XviD PART Stop
389 : edgomez 1.4 ****************************************************************************/
390 : chl 1.1
391 : edgomez 1.2 release_all:
392 :     if (dec_handle) {
393 :     status = dec_stop();
394 :     if (status)
395 :     fprintf(stderr, "decore RELEASE problem return value %d\n", status);
396 :     }
397 : chl 1.1
398 : edgomez 1.2 free_all_memory:
399 :     free(out_buffer);
400 :     free(mp4_buffer);
401 : chl 1.1
402 : edgomez 1.2 return 0;
403 :     }
404 : chl 1.1
405 : edgomez 1.2 /*****************************************************************************
406 :     * Usage function
407 :     ****************************************************************************/
408 : chl 1.1
409 : edgomez 1.2 static void usage()
410 :     {
411 :    
412 :     fprintf(stderr, "Usage : xvid_decraw <-w width> <-h height> [OPTIONS]\n");
413 :     fprintf(stderr, "Options :\n");
414 :     fprintf(stderr, " -asm : use assembly optimizations (default=disabled)\n");
415 :     fprintf(stderr, " -w integer : frame width ([1.2048])\n");
416 :     fprintf(stderr, " -h integer : frame height ([1.2048])\n");
417 :     fprintf(stderr, " -i string : input filename (default=stdin)\n");
418 :     fprintf(stderr, " -t integer : input data type (raw=0, mp4u=1)\n");
419 :     fprintf(stderr, " -d boolean : save decoder output (0 False*, !=0 True)\n");
420 :     fprintf(stderr, " -m boolean : save mpeg4 raw stream to individual files (0 False*, !=0 True)\n");
421 :     fprintf(stderr, " -help : This help message\n");
422 :     fprintf(stderr, " (* means default)\n");
423 :    
424 :     }
425 :    
426 :     /*****************************************************************************
427 :     * "helper" functions
428 :     ****************************************************************************/
429 :    
430 :     /* return the current time in milli seconds */
431 :     static double
432 :     msecond()
433 : chl 1.1 {
434 : edgomez 1.2 #ifndef _MSC_VER
435 : chl 1.1 struct timeval tv;
436 :     gettimeofday(&tv, 0);
437 : edgomez 1.3 return (double)tv.tv_sec*1.0e3 + (double)tv.tv_usec*1.0e-3;
438 : edgomez 1.2 #else
439 :     clock_t clk;
440 :     clk = clock();
441 :     return clk * 1000 / CLOCKS_PER_SEC;
442 :     #endif
443 : chl 1.1 }
444 :    
445 : edgomez 1.2 /*****************************************************************************
446 :     * output functions
447 :     ****************************************************************************/
448 :    
449 :     static int
450 :     write_pgm(char *filename,
451 :     unsigned char *image)
452 :     {
453 :     int loop;
454 :    
455 :     unsigned char *y = image;
456 :     unsigned char *u = image + XDIM*YDIM;
457 :     unsigned char *v = image + XDIM*YDIM + XDIM/2*YDIM/2;
458 : chl 1.1
459 :     FILE *filehandle;
460 : edgomez 1.2 filehandle=fopen(filename,"w+b");
461 :     if (filehandle) {
462 :    
463 :     /* Write header */
464 :     fprintf(filehandle,"P5\n\n%d %d 255\n", XDIM,YDIM*3/2);
465 : chl 1.1
466 : edgomez 1.2 /* Write Y data */
467 :     fwrite(y, 1, XDIM*YDIM, filehandle);
468 : chl 1.1
469 : edgomez 1.2 for(loop=0; loop<YDIM/2; loop++)
470 :     {
471 :     /* Write U scanline */
472 :     fwrite(u, 1, XDIM/2, filehandle);
473 :    
474 :     /* Write V scanline */
475 :     fwrite(v, 1, XDIM/2, filehandle);
476 :    
477 :     /* Update pointers */
478 :     u += XDIM/2;
479 :     v += XDIM/2;
480 : chl 1.1
481 : edgomez 1.2 }
482 : chl 1.1
483 : edgomez 1.2 /* Close file */
484 : chl 1.1 fclose(filehandle);
485 : edgomez 1.2
486 : chl 1.1 return 0;
487 :     }
488 :     else
489 :     return 1;
490 :     }
491 :    
492 : edgomez 1.2 /*****************************************************************************
493 :     * Routines for decoding: init decoder, use, and stop decoder
494 :     ****************************************************************************/
495 :    
496 :     /* init decoder before first run */
497 :     static int
498 :     dec_init(int use_assembler)
499 : chl 1.1 {
500 :     int xerr;
501 :    
502 :     XVID_INIT_PARAM xinit;
503 :     XVID_DEC_PARAM xparam;
504 :    
505 :     if(use_assembler)
506 :     #ifdef ARCH_IA64
507 :     xinit.cpu_flags = XVID_CPU_FORCE | XVID_CPU_IA64;
508 :     #else
509 :     xinit.cpu_flags = 0;
510 :     #endif
511 :     else
512 :     xinit.cpu_flags = XVID_CPU_FORCE;
513 :    
514 :     xvid_init(NULL, 0, &xinit, NULL);
515 :     xparam.width = XDIM;
516 :     xparam.height = YDIM;
517 :    
518 :     xerr = xvid_decore(NULL, XVID_DEC_CREATE, &xparam, NULL);
519 :     dec_handle = xparam.handle;
520 :    
521 :     return xerr;
522 :     }
523 :    
524 : edgomez 1.2 /* decode one frame */
525 :     static int
526 :     dec_main(unsigned char *istream,
527 :     unsigned char *ostream,
528 :     int istream_size,
529 :     int *ostream_size)
530 :     {
531 : chl 1.1
532 :     int xerr;
533 :     XVID_DEC_FRAME xframe;
534 :    
535 : edgomez 1.2 xframe.bitstream = istream;
536 :     xframe.length = istream_size;
537 :     xframe.image = ostream;
538 : chl 1.1 xframe.stride = XDIM;
539 : edgomez 1.2 xframe.colorspace = XVID_CSP_YV12;
540 : chl 1.1
541 : edgomez 1.2 xerr = xvid_decore(dec_handle, XVID_DEC_DECODE, &xframe, NULL);
542 : chl 1.1
543 : edgomez 1.2 *ostream_size = xframe.length;
544 : chl 1.1
545 :     return xerr;
546 :     }
547 :    
548 : edgomez 1.2 /* close decoder to release resources */
549 :     static int
550 :     dec_stop()
551 : chl 1.1 {
552 :     int xerr;
553 : edgomez 1.2
554 : chl 1.1 xerr = xvid_decore(dec_handle, XVID_DEC_DESTROY, NULL, NULL);
555 :    
556 :     return xerr;
557 :     }

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