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

Annotation of /branches/dev-api-3/xvidcore/examples/xvid_encraw.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 782 - (view) (download)

1 : edgomez 781 /*****************************************************************************
2 : chl 376 *
3 : edgomez 781 * XVID MPEG-4 VIDEO CODEC
4 :     * - Console based test application -
5 : chl 376 *
6 : edgomez 781 * Copyright(C) 2002 Christoph Lampert
7 : chl 376 *
8 : edgomez 781 * 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 781 * 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 781 * 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 782 * $Id: xvid_encraw.c,v 1.1.2.2 2003-01-13 00:36:27 edgomez Exp $
23 : edgomez 781 *
24 :     ****************************************************************************/
25 : chl 376
26 : edgomez 781 /*****************************************************************************
27 :     * Application notes :
28 : chl 376 *
29 : edgomez 781 * A sequence of YUV pics in PGM file format is encoded and decoded
30 :     * The speed is measured and PSNR of decoded picture is calculated.
31 : chl 376 *
32 :     * The program is plain C and needs no libraries except for libxvidcore,
33 : edgomez 781 * and maths-lib.
34 : chl 376 *
35 :     ************************************************************************/
36 :    
37 :     #include <stdio.h>
38 :     #include <stdlib.h>
39 : edgomez 781 #include <string.h>
40 :     #include <math.h>
41 :     #ifndef _MSC_VER
42 :     #include <sys/time.h>
43 :     #else
44 :     #include <time.h>
45 :     #endif
46 : chl 376
47 : edgomez 781 #include "xvid.h"
48 : chl 376
49 : edgomez 781 /*****************************************************************************
50 :     * Quality presets
51 :     ****************************************************************************/
52 : chl 376
53 : edgomez 781 static int const motion_presets[7] = {
54 :     0, /* Q 0 */
55 :     PMV_EARLYSTOP16, /* Q 1 */
56 :     PMV_EARLYSTOP16, /* Q 2 */
57 :     PMV_EARLYSTOP16 | PMV_HALFPELREFINE16, /* Q 3 */
58 :     PMV_EARLYSTOP16 | PMV_HALFPELREFINE16, /* Q 4 */
59 :     PMV_EARLYSTOP16 | PMV_HALFPELREFINE16 | PMV_EARLYSTOP8 | /* Q 5 */
60 :     PMV_HALFPELREFINE8,
61 :     PMV_EARLYSTOP16 | PMV_HALFPELREFINE16 | PMV_EXTSEARCH16 | /* Q 6 */
62 :     PMV_USESQUARES16 | PMV_EARLYSTOP8 | PMV_HALFPELREFINE8
63 :     };
64 :    
65 :     static int const general_presets[7] = {
66 :     XVID_H263QUANT, /* Q 0 */
67 :     XVID_MPEGQUANT, /* Q 1 */
68 :     XVID_H263QUANT, /* Q 2 */
69 :     XVID_H263QUANT | XVID_HALFPEL, /* Q 3 */
70 :     XVID_H263QUANT | XVID_HALFPEL | XVID_INTER4V, /* Q 4 */
71 :     XVID_H263QUANT | XVID_HALFPEL | XVID_INTER4V, /* Q 5 */
72 :     XVID_H263QUANT | XVID_HALFPEL | XVID_INTER4V /* Q 6 */
73 :     };
74 : chl 376
75 :    
76 : edgomez 781 /*****************************************************************************
77 :     * Command line global variables
78 :     ****************************************************************************/
79 : chl 376
80 : edgomez 781 /* Maximum number of frames to encode */
81 :     #define ABS_MAXFRAMENR 9999
82 : chl 376
83 : edgomez 781 /* HINTMODEs */
84 :     #define HINT_MODE_NONE 0
85 :     #define HINT_MODE_GET 1
86 :     #define HINT_MODE_SET 2
87 :     #define HINT_FILE "hints.mv"
88 : chl 376
89 : edgomez 781 static int ARG_BITRATE = 900;
90 :     static int ARG_QUANTI = 0;
91 :     static int ARG_QUALITY = 6;
92 :     static int ARG_MINQUANT = 1;
93 :     static int ARG_MAXQUANT = 31;
94 :     static float ARG_FRAMERATE = 25.00f;
95 :     static int ARG_MAXFRAMENR = ABS_MAXFRAMENR;
96 :     static char *ARG_INPUTFILE = NULL;
97 :     static int ARG_INPUTTYPE = 0;
98 :     static int ARG_SAVEMPEGSTREAM = 0;
99 :     static int ARG_OUTPUTTYPE = 0;
100 :     static char *ARG_OUTPUTFILE = NULL;
101 :     static int ARG_HINTMODE = HINT_MODE_NONE;
102 :     static int XDIM = 0;
103 :     static int YDIM = 0;
104 : edgomez 782 static int ARG_BQRATIO = 150;
105 :     static int ARG_BQOFFSET = 100;
106 :     static int ARG_MAXBFRAMES = 0;
107 : edgomez 781 #define IMAGE_SIZE(x,y) ((x)*(y)*3/2)
108 : chl 376
109 : edgomez 781 #define MAX(A,B) ( ((A)>(B)) ? (A) : (B) )
110 :     #define SMALL_EPS 1e-10
111 : chl 376
112 : edgomez 781 #define LONG_PACK(a,b,c,d) ((long) (((long)(a))<<24) | (((long)(b))<<16) | \
113 :     (((long)(c))<<8) |((long)(d)))
114 : chl 376
115 : edgomez 781 #define SWAP(a) ( (((a)&0x000000ff)<<24) | (((a)&0x0000ff00)<<8) | \
116 :     (((a)&0x00ff0000)>>8) | (((a)&0xff000000)>>24) )
117 : chl 376
118 : edgomez 781 /****************************************************************************
119 :     * Nasty global vars ;-)
120 :     ***************************************************************************/
121 : chl 376
122 : edgomez 781 static int i,filenr = 0;
123 : chl 376
124 : edgomez 781 /* the path where to save output */
125 :     static char filepath[256] = "./";
126 :    
127 :     /* Internal structures (handles) for encoding and decoding */
128 :     static void *enc_handle = NULL;
129 :    
130 :     /*****************************************************************************
131 :     * Local prototypes
132 :     ****************************************************************************/
133 :    
134 :     /* Prints program usage message */
135 :     static void usage();
136 :    
137 :     /* Statistical functions */
138 :     static double msecond();
139 :    
140 :     /* PGM related functions */
141 :     static int read_pgmheader(FILE* handle);
142 :     static int read_pgmdata(FILE* handle, unsigned char *image);
143 :     static int read_yuvdata(FILE* handle, unsigned char *image);
144 :    
145 :     /* Encoder related functions */
146 :     static int enc_init(int use_assembler);
147 :     static int enc_stop();
148 :     static int enc_main(unsigned char* image, unsigned char* bitstream,
149 :     unsigned char *hints_buffer,
150 :     long *streamlength, long* frametype, long *hints_size);
151 :    
152 :     /*****************************************************************************
153 :     * Main function
154 :     ****************************************************************************/
155 :    
156 :     int main(int argc, char *argv[])
157 :     {
158 :    
159 :     unsigned char *mp4_buffer = NULL;
160 :     unsigned char *in_buffer = NULL;
161 :     unsigned char *out_buffer = NULL;
162 :     unsigned char *hints_buffer = NULL;
163 :    
164 :     double enctime;
165 :     double totalenctime=0.;
166 :    
167 :     long totalsize;
168 :     long hints_size;
169 :     int status;
170 :     long frame_type;
171 :     long bigendian;
172 :    
173 :     long m4v_size;
174 :     int use_assembler=0;
175 :    
176 :     char filename[256];
177 :    
178 :     FILE *in_file = stdin;
179 :     FILE *out_file = NULL;
180 :     FILE *hints_file = NULL;
181 :    
182 :     printf("xvid_encraw - raw mpeg4 bitstream encoder ");
183 :     printf("written by Christoph Lampert 2002\n\n");
184 :    
185 :     /*****************************************************************************
186 :     * Command line parsing
187 :     ****************************************************************************/
188 :    
189 :     for (i=1; i< argc; i++) {
190 :    
191 :     if (strcmp("-asm", argv[i]) == 0 ) {
192 :     use_assembler = 1;
193 :     }
194 :     else if (strcmp("-w", argv[i]) == 0 && i < argc - 1 ) {
195 :     i++;
196 :     XDIM = atoi(argv[i]);
197 :     }
198 :     else if (strcmp("-h", argv[i]) == 0 && i < argc - 1 ) {
199 :     i++;
200 :     YDIM = atoi(argv[i]);
201 :     }
202 :     else if (strcmp("-b", argv[i]) == 0 && i < argc - 1 ) {
203 :     i++;
204 :     ARG_BITRATE = atoi(argv[i]);
205 :     }
206 : edgomez 782 else if (strcmp("-bn", argv[i]) == 0 && i < argc - 1 ) {
207 :     i++;
208 :     ARG_MAXBFRAMES = atoi(argv[i]);
209 :     }
210 :     else if (strcmp("-bqr", argv[i]) == 0 && i < argc - 1 ) {
211 :     i++;
212 :     ARG_BQRATIO = atoi(argv[i]);
213 :     }
214 :     else if (strcmp("-bqo", argv[i]) == 0 && i < argc - 1 ) {
215 :     i++;
216 :     ARG_BQOFFSET = atoi(argv[i]);
217 :     }
218 : edgomez 781 else if (strcmp("-q", argv[i]) == 0 && i < argc - 1 ) {
219 :     i++;
220 :     ARG_QUALITY = atoi(argv[i]);
221 :     }
222 :     else if (strcmp("-f", argv[i]) == 0 && i < argc - 1 ) {
223 :     i++;
224 :     ARG_FRAMERATE = (float)atof(argv[i]);
225 :     }
226 :     else if (strcmp("-i", argv[i]) == 0 && i < argc - 1 ) {
227 :     i++;
228 :     ARG_INPUTFILE = argv[i];
229 :     }
230 :     else if (strcmp("-t", argv[i]) == 0 && i < argc - 1 ) {
231 :     i++;
232 :     ARG_INPUTTYPE = atoi(argv[i]);
233 :     }
234 :     else if(strcmp("-n", argv[i]) == 0 && i < argc - 1 ) {
235 :     i++;
236 :     ARG_MAXFRAMENR = atoi(argv[i]);
237 :     }
238 :     else if (strcmp("-quant", argv[i]) == 0 && i < argc - 1 ) {
239 :     i++;
240 :     ARG_QUANTI = atoi(argv[i]);
241 :     }
242 :     else if (strcmp("-m", argv[i]) == 0 && i < argc - 1 ) {
243 :     i++;
244 :     ARG_SAVEMPEGSTREAM = atoi(argv[i]);
245 :     }
246 :     else if (strcmp("-mt", argv[i]) == 0 && i < argc - 1 ) {
247 :     i++;
248 :     ARG_OUTPUTTYPE = atoi(argv[i]);
249 :     }
250 :     else if (strcmp("-mv", argv[i]) == 0 && i < argc - 1 ) {
251 :     i++;
252 :     ARG_HINTMODE = atoi(argv[i]);
253 :     }
254 :     else if (strcmp("-o", argv[i]) == 0 && i < argc - 1 ) {
255 :     i++;
256 :     ARG_OUTPUTFILE = argv[i];
257 :     }
258 :     else if (strcmp("-help", argv[i])) {
259 :     usage();
260 :     return(0);
261 :     }
262 :     else {
263 :     usage();
264 :     exit(-1);
265 :     }
266 :    
267 :     }
268 :    
269 :     /*****************************************************************************
270 :     * Arguments checking
271 :     ****************************************************************************/
272 :    
273 :     if (XDIM <= 0 || XDIM >= 2048 || YDIM <=0 || YDIM >= 2048 ) {
274 :     fprintf(stderr, "Trying to retreive width and height from PGM header\n");
275 :     ARG_INPUTTYPE = 1; /* pgm */
276 :     }
277 :    
278 :     if ( ARG_QUALITY < 0 || ARG_QUALITY > 6) {
279 :     fprintf(stderr,"Wrong Quality\n");
280 :     return -1;
281 :     }
282 :    
283 :     if ( ARG_BITRATE <= 0 && ARG_QUANTI == 0) {
284 :     fprintf(stderr,"Wrong Bitrate\n");
285 :     return -1;
286 :     }
287 :    
288 :     if ( ARG_FRAMERATE <= 0) {
289 :     fprintf(stderr,"Wrong Framerate %s \n",argv[5]);
290 :     return -1;
291 :     }
292 :    
293 :     if ( ARG_MAXFRAMENR <= 0) {
294 :     fprintf(stderr,"Wrong number of frames\n");
295 :     return -1;
296 :     }
297 :    
298 :     if ( ARG_HINTMODE != HINT_MODE_NONE &&
299 :     ARG_HINTMODE != HINT_MODE_GET &&
300 :     ARG_HINTMODE != HINT_MODE_SET)
301 :     ARG_HINTMODE = HINT_MODE_NONE;
302 :    
303 :     if( ARG_HINTMODE != HINT_MODE_NONE) {
304 :     char *rights = "rb";
305 :    
306 :     /*
307 :     * If we are getting hints from core, we will have to write them to
308 :     * hint file
309 :     */
310 :     if(ARG_HINTMODE == HINT_MODE_GET)
311 :     rights = "w+b";
312 :    
313 :     /* Open the hint file */
314 :     hints_file = fopen(HINT_FILE, rights);
315 :     if(hints_file == NULL) {
316 :     fprintf(stderr, "Error opening input file %s\n", HINT_FILE);
317 :     return -1;
318 :     }
319 :    
320 :     /* Allocate hint memory space, we will be using rawhints */
321 :     /* NB : Hope 1Mb is enough */
322 :     if((hints_buffer = malloc(1024*1024)) == NULL) {
323 :     fprintf(stderr, "Memory allocation error\n");
324 :     return -1;
325 :     }
326 :    
327 :     }
328 :    
329 :     if ( ARG_INPUTFILE == NULL || strcmp(ARG_INPUTFILE, "stdin") == 0) {
330 :     in_file = stdin;
331 :     }
332 :     else {
333 :    
334 :     in_file = fopen(ARG_INPUTFILE, "rb");
335 :     if (in_file == NULL) {
336 :     fprintf(stderr, "Error opening input file %s\n", ARG_INPUTFILE);
337 :     return -1;
338 :     }
339 :     }
340 :    
341 :     if (ARG_INPUTTYPE) {
342 :     if (read_pgmheader(in_file)) {
343 :     fprintf(stderr, "Wrong input format, I want YUV encapsulated in PGM\n");
344 :     return -1;
345 :     }
346 :     }
347 :    
348 :     /* now we know the sizes, so allocate memory */
349 :    
350 :     in_buffer = (unsigned char *) malloc(IMAGE_SIZE(XDIM,YDIM));
351 :     if (!in_buffer)
352 :     goto free_all_memory;
353 :    
354 :     /* this should really be enough memory ! */
355 :     mp4_buffer = (unsigned char *) malloc(IMAGE_SIZE(XDIM,YDIM)*2);
356 :     if (!mp4_buffer)
357 :     goto free_all_memory;
358 :    
359 :     /*****************************************************************************
360 :     * XviD PART Start
361 :     ****************************************************************************/
362 :    
363 :    
364 :     status = enc_init(use_assembler);
365 :     if (status)
366 :     {
367 :     fprintf(stderr, "Encore INIT problem, return value %d\n", status);
368 :     goto release_all;
369 :     }
370 :    
371 :     /*****************************************************************************
372 :     * Main loop
373 :     ****************************************************************************/
374 :    
375 :     totalsize = LONG_PACK('M','P','4','U');
376 :     if(*((char *)(&totalsize)) == 'M')
377 :     bigendian = 1;
378 :     else
379 :     bigendian = 0;
380 :    
381 :     if (ARG_SAVEMPEGSTREAM && (ARG_OUTPUTTYPE || ARG_OUTPUTFILE)) {
382 :    
383 :     if (ARG_OUTPUTFILE == NULL && ARG_OUTPUTTYPE)
384 :     ARG_OUTPUTFILE = "stream.mp4u";
385 :     else if(ARG_OUTPUTFILE == NULL && !ARG_OUTPUTTYPE)
386 :     ARG_OUTPUTFILE = "stream.m4v";
387 :    
388 :     if((out_file = fopen(ARG_OUTPUTFILE, "w+b")) == NULL) {
389 :     fprintf(stderr, "Error opening output file %s\n", ARG_OUTPUTFILE);
390 :     goto release_all;
391 :     }
392 :    
393 :     /* Write header */
394 :     if (ARG_OUTPUTTYPE) {
395 :    
396 :     long test = LONG_PACK('M','P','4','U');
397 :    
398 :     test = (!bigendian)?SWAP(test):test;
399 :    
400 :     fwrite(&test, sizeof(test), 1, out_file);
401 :    
402 :     }
403 :    
404 :     }
405 :     else {
406 :     out_file = NULL;
407 :     }
408 :    
409 :     /*****************************************************************************
410 :     * Encoding loop
411 :     ****************************************************************************/
412 :    
413 :     totalsize = 0;
414 :    
415 :     do {
416 :    
417 :     if (ARG_INPUTTYPE)
418 :     status = read_pgmdata(in_file, in_buffer); /* read PGM data (YUV-format) */
419 :     else
420 :     status = read_yuvdata(in_file, in_buffer); /* read raw data (YUV-format) */
421 :    
422 :     if (status)
423 :     {
424 :     /* Couldn't read image, most likely end-of-file */
425 :     continue;
426 :     }
427 :    
428 :     /*****************************************************************************
429 :     * Read hints from file
430 :     ****************************************************************************/
431 :    
432 :     if(ARG_HINTMODE == HINT_MODE_SET) {
433 :     fread(&hints_size, 1, sizeof(long), hints_file);
434 :     hints_size = (!bigendian)?SWAP(hints_size):hints_size;
435 :     fread(hints_buffer, 1, hints_size, hints_file);
436 :     }
437 :    
438 :     /*****************************************************************************
439 :     * Encode and decode this frame
440 :     ****************************************************************************/
441 :    
442 :     enctime = msecond();
443 :     status = enc_main(in_buffer, mp4_buffer, hints_buffer,
444 :     &m4v_size, &frame_type, &hints_size);
445 :     enctime = msecond() - enctime;
446 :    
447 :     totalenctime += enctime;
448 :     totalsize += m4v_size;
449 :    
450 : edgomez 782 {
451 :     char *type;
452 : edgomez 781
453 : edgomez 782 switch(frame_type) {
454 :     case 0: type = "P"; break;
455 :     case 1: type = "I"; break;
456 :     case 2: type = "B"; break;
457 :     default: type = "N"; break;
458 :     }
459 :    
460 :     printf("Frame %5d: type %s, enctime=%6.1f ms, size=%6d bytes\n",
461 :     (int)filenr, type, (float)enctime, (int)m4v_size);
462 :    
463 :     }
464 :    
465 : edgomez 781 /*****************************************************************************
466 :     * Save hints to file
467 :     ****************************************************************************/
468 :    
469 :     if(ARG_HINTMODE == HINT_MODE_GET) {
470 :     hints_size = (!bigendian)?SWAP(hints_size):hints_size;
471 :     fwrite(&hints_size, 1, sizeof(long), hints_file);
472 :     hints_size = (!bigendian)?SWAP(hints_size):hints_size;
473 :     fwrite(hints_buffer, 1, hints_size, hints_file);
474 :     }
475 :    
476 :     /*****************************************************************************
477 :     * Save stream to file
478 :     ****************************************************************************/
479 :    
480 :     if (ARG_SAVEMPEGSTREAM)
481 :     {
482 :     /* Save single files */
483 :     if (out_file == NULL) {
484 :     sprintf(filename, "%sframe%05d.m4v", filepath, filenr);
485 :     out_file = fopen(filename, "wb");
486 :     fwrite(mp4_buffer, m4v_size, 1, out_file);
487 :     fclose(out_file);
488 :     out_file = NULL;
489 :     }
490 :     else {
491 :     /* Using mp4u container */
492 :     if (ARG_OUTPUTTYPE) {
493 :     long size = m4v_size;
494 :     size = (!bigendian)?SWAP(size):size;
495 :     fwrite(&size, sizeof(size), 1, out_file);
496 :     }
497 :    
498 :     /* Write mp4 data */
499 :     fwrite(mp4_buffer, m4v_size, 1, out_file);
500 :    
501 :     }
502 :     }
503 :    
504 :     /* Read the header if it's pgm stream */
505 :     if (ARG_INPUTTYPE)
506 :     status = read_pgmheader(in_file);
507 :    
508 :     filenr++;
509 :    
510 :     } while ( (!status) && (filenr<ARG_MAXFRAMENR) );
511 :    
512 : chl 376
513 : edgomez 781
514 :     /*****************************************************************************
515 :     * Calculate totals and averages for output, print results
516 :     ****************************************************************************/
517 : chl 376
518 : edgomez 781 totalsize /= filenr;
519 :     totalenctime /= filenr;
520 : chl 376
521 : edgomez 782 printf("Avg: enctime %5.2f ms, %5.2f fps, size %7d bytes\n",
522 : edgomez 781 totalenctime, 1000/totalenctime, (int)totalsize);
523 : chl 376
524 : edgomez 781 /*****************************************************************************
525 :     * XviD PART Stop
526 :     ****************************************************************************/
527 : chl 376
528 : edgomez 781 release_all:
529 : chl 376
530 : edgomez 781 if (enc_handle)
531 :     {
532 :     status = enc_stop();
533 :     if (status)
534 :     fprintf(stderr, "Encore RELEASE problem return value %d\n", status);
535 :     }
536 : chl 376
537 : edgomez 781 if(in_file)
538 :     fclose(in_file);
539 :     if(out_file)
540 :     fclose(out_file);
541 :     if(hints_file)
542 :     fclose(hints_file);
543 :    
544 :     free_all_memory:
545 :     free(out_buffer);
546 :     free(mp4_buffer);
547 :     free(in_buffer);
548 :     if(hints_buffer) free(hints_buffer);
549 :    
550 :     return 0;
551 :    
552 :     }
553 :    
554 :    
555 :     /*****************************************************************************
556 :     * "statistical" functions
557 :     *
558 :     * these are not needed for encoding or decoding, but for measuring
559 :     * time and quality, there in nothing specific to XviD in these
560 :     *
561 :     *****************************************************************************/
562 :    
563 :     /* Return time elapsed time in miliseconds since the program started */
564 :     static double msecond()
565 : chl 376 {
566 : edgomez 781 #ifndef _MSC_VER
567 : chl 376 struct timeval tv;
568 :     gettimeofday(&tv, 0);
569 : edgomez 781 return tv.tv_sec*1.0e3 + tv.tv_usec * 1.0e-3;
570 :     #else
571 :     clock_t clk;
572 :     clk = clock();
573 :     return clk * 1000 / CLOCKS_PER_SEC;
574 :     #endif
575 : chl 376 }
576 :    
577 : edgomez 781 /*****************************************************************************
578 :     * Usage message
579 :     *****************************************************************************/
580 : chl 376
581 : edgomez 781 static void usage()
582 :     {
583 :    
584 :     fprintf(stderr, "Usage : xvid_stat [OPTIONS]\n");
585 :     fprintf(stderr, "Options :\n");
586 :     fprintf(stderr, " -w integer : frame width ([1.2048])\n");
587 :     fprintf(stderr, " -h integer : frame height ([1.2048])\n");
588 :     fprintf(stderr, " -b integer : target bitrate (>0 | default=900kbit)\n");
589 : edgomez 782 fprintf(stderr, " -b integer : target bitrate (>0 | default=900kbit)\n");
590 :     fprintf(stderr, " -bn integer : max bframes (default=0)\n");
591 :     fprintf(stderr, " -bqr integer : bframe quantizer ratio (default=150)\n");
592 :     fprintf(stderr, " -bqo integer : bframe quantizer offset (default=100)\n");
593 : edgomez 781 fprintf(stderr, " -f float : target framerate (>0)\n");
594 :     fprintf(stderr, " -i string : input filename (default=stdin)\n");
595 :     fprintf(stderr, " -t integer : input data type (yuv=0, pgm=1)\n");
596 :     fprintf(stderr, " -n integer : number of frames to encode\n");
597 :     fprintf(stderr, " -q integer : quality ([0..5])\n");
598 :     fprintf(stderr, " -d boolean : save decoder output (0 False*, !=0 True)\n");
599 :     fprintf(stderr, " -m boolean : save mpeg4 raw stream (0 False*, !=0 True)\n");
600 :     fprintf(stderr, " -o string : output container filename (only usefull when -m 1 is used) :\n");
601 :     fprintf(stderr, " When this option is not used : one file per encoded frame\n");
602 :     fprintf(stderr, " When this option is used :\n");
603 :     fprintf(stderr, " + stream.m4v with -mt 0\n");
604 :     fprintf(stderr, " + stream.mp4u with -mt 1\n");
605 :     fprintf(stderr, " -mt integer : output type (m4v=0, mp4u=1)\n");
606 :     fprintf(stderr, " -mv integer : Use motion vector hints (no hints=0, get hints=1, set hints=2)\n");
607 :     fprintf(stderr, " -help : prints this help message\n");
608 :     fprintf(stderr, " -quant integer : fixed quantizer (disables -b setting)\n");
609 :     fprintf(stderr, " (* means default)\n");
610 :    
611 :     }
612 :    
613 :     /*****************************************************************************
614 :     * Input and output functions
615 :     *
616 :     * the are small and simple routines to read and write PGM and YUV
617 :     * image. It's just for convenience, again nothing specific to XviD
618 :     *
619 :     *****************************************************************************/
620 :    
621 :     static int read_pgmheader(FILE* handle)
622 : chl 376 {
623 :     int bytes,xsize,ysize,depth;
624 :     char dummy[2];
625 :    
626 :     bytes = fread(dummy,1,2,handle);
627 :    
628 :     if ( (bytes < 2) || (dummy[0] != 'P') || (dummy[1] != '5' ))
629 :     return 1;
630 : edgomez 781
631 : chl 376 fscanf(handle,"%d %d %d",&xsize,&ysize,&depth);
632 :     if ( (xsize > 1440) || (ysize > 2880 ) || (depth != 255) )
633 :     {
634 : edgomez 781 fprintf(stderr,"%d %d %d\n",xsize,ysize,depth);
635 : chl 376 return 2;
636 :     }
637 :     if ( (XDIM==0) || (YDIM==0) )
638 : edgomez 781 {
639 :     XDIM=xsize;
640 :     YDIM=ysize*2/3;
641 : chl 376 }
642 :    
643 :     return 0;
644 :     }
645 :    
646 : edgomez 781 static int read_pgmdata(FILE* handle, unsigned char *image)
647 : chl 376 {
648 : edgomez 781 int i;
649 : chl 376 char dummy;
650 : edgomez 781
651 :     unsigned char *y = image;
652 :     unsigned char *u = image + XDIM*YDIM;
653 :     unsigned char *v = image + XDIM*YDIM + XDIM/2*YDIM/2;
654 : chl 376
655 : edgomez 781 /* read Y component of picture */
656 :     fread(y, 1, XDIM*YDIM, handle);
657 : chl 376
658 : edgomez 781 for (i=0;i<YDIM/2;i++)
659 : chl 376 {
660 : edgomez 781 /* read U */
661 :     fread(u, 1, XDIM/2, handle);
662 :    
663 :     /* read V */
664 :     fread(v, 1, XDIM/2, handle);
665 :    
666 :     /* Update pointers */
667 :     u += XDIM/2;
668 :     v += XDIM/2;
669 : chl 376 }
670 : edgomez 781
671 :     /* I don't know why, but this seems needed */
672 :     fread(&dummy, 1, 1, handle);
673 :    
674 : chl 376 return 0;
675 :     }
676 :    
677 : edgomez 781 static int read_yuvdata(FILE* handle, unsigned char *image)
678 :     {
679 : chl 376
680 : edgomez 781 if (fread(image, 1, IMAGE_SIZE(XDIM, YDIM), handle) != (unsigned int)IMAGE_SIZE(XDIM, YDIM))
681 : chl 376 return 1;
682 :     else
683 :     return 0;
684 :     }
685 :    
686 : edgomez 781 /*****************************************************************************
687 :     * Routines for encoding: init encoder, frame step, release encoder
688 :     ****************************************************************************/
689 : chl 376
690 :     #define FRAMERATE_INCR 1001
691 :    
692 : edgomez 781 /* Initialize encoder for first use, pass all needed parameters to the codec */
693 :     static int enc_init(int use_assembler)
694 :     {
695 : chl 376 int xerr;
696 :    
697 :     XVID_INIT_PARAM xinit;
698 :     XVID_ENC_PARAM xparam;
699 :    
700 : edgomez 781 if(use_assembler) {
701 : chl 376
702 :     #ifdef ARCH_IA64
703 :     xinit.cpu_flags = XVID_CPU_FORCE | XVID_CPU_IA64;
704 :     #else
705 :     xinit.cpu_flags = 0;
706 :     #endif
707 : edgomez 781 }
708 :     else {
709 : chl 376 xinit.cpu_flags = XVID_CPU_FORCE;
710 : edgomez 781 }
711 : chl 376
712 :     xvid_init(NULL, 0, &xinit, NULL);
713 :    
714 :     xparam.width = XDIM;
715 :     xparam.height = YDIM;
716 :     if ((ARG_FRAMERATE - (int)ARG_FRAMERATE) < SMALL_EPS)
717 :     {
718 : edgomez 781 xparam.fincr = 1;
719 :     xparam.fbase = (int)ARG_FRAMERATE;
720 : chl 376 }
721 :     else
722 :     {
723 : edgomez 781 xparam.fincr = FRAMERATE_INCR;
724 :     xparam.fbase = (int)(FRAMERATE_INCR * ARG_FRAMERATE);
725 : chl 376 }
726 :     xparam.rc_reaction_delay_factor = 16;
727 : edgomez 781 xparam.rc_averaging_period = 100;
728 :     xparam.rc_buffer = 10;
729 : chl 376 xparam.rc_bitrate = ARG_BITRATE*1000;
730 : edgomez 781 xparam.min_quantizer = ARG_MINQUANT;
731 :     xparam.max_quantizer = ARG_MAXQUANT;
732 : chl 376 xparam.max_key_interval = (int)ARG_FRAMERATE*10;
733 : edgomez 782 xparam.bquant_ratio = ARG_BQRATIO;
734 :     xparam.bquant_offset = ARG_BQOFFSET;
735 :     xparam.max_bframes = ARG_MAXBFRAMES;
736 :     xparam.frame_drop_ratio = 0;
737 : edgomez 781 xparam.global = 0;
738 : chl 376
739 : edgomez 781 /* I use a small value here, since will not encode whole movies, but short clips */
740 : chl 376
741 :     xerr = xvid_encore(NULL, XVID_ENC_CREATE, &xparam, NULL);
742 :     enc_handle=xparam.handle;
743 :    
744 :     return xerr;
745 :     }
746 :    
747 : edgomez 781 static int enc_stop()
748 :     {
749 :     int xerr;
750 : chl 376
751 :     xerr = xvid_encore(enc_handle, XVID_ENC_DESTROY, NULL, NULL);
752 : edgomez 781 return xerr;
753 :    
754 : chl 376 }
755 :    
756 : edgomez 781 static int enc_main(unsigned char* image, unsigned char* bitstream,
757 :     unsigned char* hints_buffer,
758 :     long *streamlength, long *frametype, long *hints_size)
759 :     {
760 :     int xerr;
761 : chl 376
762 :     XVID_ENC_FRAME xframe;
763 :     XVID_ENC_STATS xstats;
764 :    
765 :     xframe.bitstream = bitstream;
766 : edgomez 781 xframe.length = -1; /* this is written by the routine */
767 : chl 376
768 :     xframe.image = image;
769 : edgomez 781 xframe.colorspace = XVID_CSP_YV12; /* defined in <xvid.h> */
770 : chl 376
771 : edgomez 781 xframe.intra = -1; /* let the codec decide between I-frame (1) and P-frame (0) */
772 : chl 376
773 : edgomez 781 xframe.quant = ARG_QUANTI; /* is quant != 0, use a fixed quant (and ignore bitrate) */
774 :     xframe.bquant = 0;
775 :    
776 : chl 376 xframe.motion = motion_presets[ARG_QUALITY];
777 :     xframe.general = general_presets[ARG_QUALITY];
778 :     xframe.quant_intra_matrix = xframe.quant_inter_matrix = NULL;
779 : edgomez 781 xframe.stride = XDIM;
780 : chl 376
781 : edgomez 781 xframe.hint.hintstream = hints_buffer;
782 : chl 376
783 : edgomez 781 if(ARG_HINTMODE == HINT_MODE_SET) {
784 :     xframe.hint.hintlength = *hints_size;
785 :     xframe.hint.rawhints = 0;
786 :     xframe.general |= XVID_HINTEDME_SET;
787 :     }
788 :    
789 :     if(ARG_HINTMODE == HINT_MODE_GET) {
790 :     xframe.hint.rawhints = 0;
791 :     xframe.general |= XVID_HINTEDME_GET;
792 :     }
793 :    
794 : chl 376 xerr = xvid_encore(enc_handle, XVID_ENC_ENCODE, &xframe, &xstats);
795 :    
796 : edgomez 781 if(ARG_HINTMODE == HINT_MODE_GET)
797 :     *hints_size = xframe.hint.hintlength;
798 : chl 376
799 : edgomez 781 /*
800 :     * This is statictical data, e.g. for 2-pass. If you are not
801 :     * interested in any of this, you can use NULL instead of &xstats
802 :     */
803 : chl 376 *frametype = xframe.intra;
804 :     *streamlength = xframe.length;
805 :    
806 :     return xerr;
807 :     }

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