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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 920 - (view) (download)

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

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