]> git.sesse.net Git - x264/blob - x264.c
58bb8d394f5d63822fb40af2fd74c247d22a6a10
[x264] / x264.c
1 /*****************************************************************************
2  * x264: h264 encoder/decoder testing program.
3  *****************************************************************************
4  * Copyright (C) 2003 Laurent Aimar
5  * $Id: x264.c,v 1.1 2004/06/03 19:24:12 fenrir Exp $
6  *
7  * Authors: Laurent Aimar <fenrir@via.ecp.fr>
8  *
9  * This program is free software; you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License as published by
11  * the Free Software Foundation; either version 2 of the License, or
12  * (at your option) any later version.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with this program; if not, write to the Free Software
21  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA.
22  *****************************************************************************/
23
24 #include <stdlib.h>
25 #include <stdio.h>
26 #include <string.h>
27
28 #include <math.h>
29
30 #include <signal.h>
31 #define _GNU_SOURCE
32 #include <getopt.h>
33
34 #ifdef _MSC_VER
35 #include <io.h>     /* _setmode() */
36 #include <fcntl.h>  /* _O_BINARY */
37 #endif
38
39 #include "common/common.h"
40 #include "x264.h"
41
42 #define DATA_MAX 3000000
43 uint8_t data[DATA_MAX];
44
45 /* Ctrl-C handler */
46 static int     i_ctrl_c = 0;
47 static void    SigIntHandler( int a )
48 {
49     i_ctrl_c = 1;
50 }
51
52 static void Help( x264_param_t *defaults );
53 static int  Parse( int argc, char **argv, x264_param_t  *param, FILE **p_fin, FILE **p_fout, int *pb_decompress );
54 static int  Encode( x264_param_t  *param, FILE *fyuv,  FILE *fout );
55 static int  Decode( x264_param_t  *param, FILE *fh26l, FILE *fout );
56
57 /****************************************************************************
58  * main:
59  ****************************************************************************/
60 int main( int argc, char **argv )
61 {
62     x264_param_t param;
63
64     FILE    *fout;
65     FILE    *fin;
66
67     int     b_decompress;
68     int     i_ret;
69
70 #ifdef _MSC_VER
71     _setmode(_fileno(stdin), _O_BINARY);    /* thanks to Marcos Morais <morais at dee.ufcg.edu.br> */
72     _setmode(_fileno(stdout), _O_BINARY);
73 #endif
74
75     x264_param_default( &param );
76     param.b_cabac = 0;
77
78     /* Parse command line */
79     if( Parse( argc, argv, &param, &fin, &fout, &b_decompress ) < 0 )
80     {
81         return -1;
82     }
83
84     /* Control-C handler */
85     signal( SIGINT, SigIntHandler );
86
87     if( b_decompress )
88         i_ret = Decode( &param, fin, fout );
89     else
90         i_ret = Encode( &param, fin, fout );
91
92     return i_ret;
93 }
94
95 /*****************************************************************************
96  * Help:
97  *****************************************************************************/
98 static void Help( x264_param_t *defaults )
99 {
100     fprintf( stderr,
101              "x264 build:%d\n"
102              "Syntax: x264 [options] [-o out.h26l] in.yuv widthxheigh\n"
103              "\n"
104              "  -h, --help                  Print this help\n"
105              "\n"
106              "  -I, --keyint <integer  >    Maximum GOP size [%d]\n"
107              "  -i, --min-keyint <integer>  Minimum GOP size [%d]\n"
108              "      --scenecut <integer>    How aggresively to insert extra I frames [%d]\n"
109              "  -b, --bframe <integer>      Number of B-frames between I and P [%d]\n"
110              "      --no-b-adapt            Disable adaptive B-frame decision\n"
111              "      --b-bias <integer>      Influences how often B-frames are used [%d]\n"
112              "      --b-pyramid             Keep some B-frames as references\n"
113              "\n"
114              "  -c, --cabac                 Enable CABAC\n"
115              "  -r, --ref <integer>         Number of reference frames [%d]\n"
116              "  -n, --nf                    Disable loop filter\n"
117              "  -f, --filter <alpha:beta>   Loop filter AplhaCO and Beta parameters [%d]\n"
118              "\n"
119              "  -q, --qp <integer>          Set QP [%d]\n"
120              "  -B, --bitrate <integer>     Set bitrate\n"
121              "      --qpmin <integer>       Set min QP [%d]\n"
122              "      --qpmax <integer>       Set max QP [%d]\n"
123              "      --qpstep <integer>      Set max QP step [%d]\n"
124              "      --rcsens <integer>      CBR ratecontrol sensitivity [%d]\n"
125              "      --rcbuf <integer>       Size of VBV buffer [%d]\n"
126              "      --rcinitbuf <integer>   Initial VBV buffer occupancy [%d]\n"
127              "      --ipratio <float>       QP factor between I and P [%.2f]\n"
128              "      --pbratio <float>       QP factor between P and B [%.2f]\n"
129              "      --chroma-qp-offset <integer>  QP difference between chroma and luma [%d]\n"
130              "\n"
131              "  -p, --pass <1|2>            Enable 2 pass ratecontrol\n"
132              "      --stats <string>        Filename for 2 pass stats [\"%s\"]\n"
133              "      --rceq <string>         Ratecontrol equation [\"%s\"]\n"
134              "      --qcomp <float>         0.0 => CBR, 1.0 => CQP [%.2f]\n"
135              "      --cplxblur <float>      reduce fluctuations in QP (before curve compression) [%.1f]\n"
136              "      --qblur <float>         reduce fluctuations in QP (after curve compression) [%.1f]\n"
137              "\n"
138
139              "  -A, --analyse <string>      Analyse options: [\"i4x4|psub16x16|bsub16x16\"]\n"
140              "                                  - i4x4\n"
141              "                                  - psub16x16, psub8x8, bsub16x16\n"
142              "                                  - none, all\n"
143              "      --direct <string>       Direct MV prediction mode [\"temporal\"]\n"
144              "                                  - none, spatial, temporal\n"
145              "  -w, --weightb               Weighted prediction for B-frames\n"
146              "  -m, --subme <integer>       Subpixel motion estimation quality: 1=fast, 5=best. [%d]\n"
147              "\n"
148              "      --level <integer>       Specify IDC level\n"
149              "  -s, --sar width:height      Specify Sample Aspect Ratio\n"
150              "      --fps <float|rational>  Specify framerate\n"
151              "      --frames <integer>      Maximum number of frames to encode\n"
152              "  -o, --output                Specify output file\n"
153              "\n"
154              "      --no-asm                Disable any CPU optims\n"
155              "      --no-psnr               Disable PSNR computaion\n"
156              "      --quiet                 Quiet Mode\n"
157              "  -v, --verbose               Print stats for each frame\n"
158              "\n",
159             X264_BUILD,
160             defaults->i_keyint_max,
161             defaults->i_keyint_min,
162             defaults->i_scenecut_threshold,
163             defaults->i_bframe,
164             defaults->i_bframe_bias,
165             defaults->i_frame_reference,
166             defaults->i_deblocking_filter_alphac0,
167             defaults->rc.i_qp_constant,
168             defaults->rc.i_qp_min,
169             defaults->rc.i_qp_max,
170             defaults->rc.i_qp_step,
171             defaults->rc.i_rc_sens,
172             defaults->rc.i_rc_buffer_size,
173             defaults->rc.i_rc_init_buffer,
174             defaults->rc.f_ip_factor,
175             defaults->rc.f_pb_factor,
176             defaults->analyse.i_chroma_qp_offset,
177             defaults->rc.psz_stat_out,
178             defaults->rc.psz_rc_eq,
179             defaults->rc.f_qcompress,
180             defaults->rc.f_complexity_blur,
181             defaults->rc.f_qblur,
182             defaults->analyse.i_subpel_refine
183            );
184 }
185
186 /*****************************************************************************
187  * Parse:
188  *****************************************************************************/
189 static int  Parse( int argc, char **argv,
190                    x264_param_t  *param,
191                    FILE **p_fin, FILE **p_fout, int *pb_decompress )
192 {
193     char *psz_filename = NULL;
194     x264_param_t defaults = *param;
195
196     /* Default output */
197     *p_fout = stdout;
198     *p_fin  = stdin;
199     *pb_decompress = 0;
200
201     /* Parse command line options */
202     opterr = 0; // no error message
203     for( ;; )
204     {
205         int long_options_index;
206 #define OPT_QPMIN 256
207 #define OPT_QPMAX 257
208 #define OPT_QPSTEP 258
209 #define OPT_RCSENS 259
210 #define OPT_IPRATIO 260
211 #define OPT_PBRATIO 261
212 #define OPT_RCBUF 262
213 #define OPT_RCIBUF 263
214 #define OPT_RCSTATS 264
215 #define OPT_RCEQ 265
216 #define OPT_QCOMP 266
217 #define OPT_NOPSNR 267
218 #define OPT_QUIET 268
219 #define OPT_SCENECUT 270
220 #define OPT_QBLUR 271
221 #define OPT_CPLXBLUR 272
222 #define OPT_FRAMES 273
223 #define OPT_FPS 274
224 #define OPT_DIRECT 275
225 #define OPT_LEVEL 276
226 #define OPT_NOBADAPT 277
227 #define OPT_BBIAS 278
228 #define OPT_BPYRAMID 279
229 #define OPT_CHROMA_QP 280
230
231         static struct option long_options[] =
232         {
233             { "help",    no_argument,       NULL, 'h' },
234             { "bitrate", required_argument, NULL, 'B' },
235             { "bframe",  required_argument, NULL, 'b' },
236             { "no-b-adapt", no_argument,    NULL, OPT_NOBADAPT },
237             { "b-bias",  required_argument, NULL, OPT_BBIAS },
238             { "b-pyramid", no_argument,     NULL, OPT_BPYRAMID },
239             { "min-keyint",required_argument,NULL,'i' },
240             { "keyint",  required_argument, NULL, 'I' },
241             { "scenecut",required_argument, NULL, OPT_SCENECUT },
242             { "nf",      no_argument,       NULL, 'n' },
243             { "filter",  required_argument, NULL, 'f' },
244             { "cabac",   no_argument,       NULL, 'c' },
245             { "qp",      required_argument, NULL, 'q' },
246             { "qpmin",   required_argument, NULL, OPT_QPMIN },
247             { "qpmax",   required_argument, NULL, OPT_QPMAX },
248             { "qpstep",  required_argument, NULL, OPT_QPSTEP },
249             { "ref",     required_argument, NULL, 'r' },
250             { "no-asm",  no_argument,       NULL, 'C' },
251             { "sar",     required_argument, NULL, 's' },
252             { "fps",     required_argument, NULL, OPT_FPS },
253             { "frames",  required_argument, NULL, OPT_FRAMES },
254             { "output",  required_argument, NULL, 'o' },
255             { "analyse", required_argument, NULL, 'A' },
256             { "direct",  required_argument, NULL, OPT_DIRECT },
257             { "weightb", no_argument,       NULL, 'w' },
258             { "subme",   required_argument, NULL, 'm' },
259             { "level",   required_argument, NULL, OPT_LEVEL },
260             { "rcsens",  required_argument, NULL, OPT_RCSENS },
261             { "rcbuf",   required_argument, NULL, OPT_RCBUF },
262             { "rcinitbuf",required_argument,NULL, OPT_RCIBUF },
263             { "ipratio", required_argument, NULL, OPT_IPRATIO },
264             { "pbratio", required_argument, NULL, OPT_PBRATIO },
265             { "chroma-qp-offset", required_argument, NULL, OPT_CHROMA_QP },
266             { "pass",    required_argument, NULL, 'p' },
267             { "stats",   required_argument, NULL, OPT_RCSTATS },
268             { "rceq",    required_argument, NULL, OPT_RCEQ },
269             { "qcomp",   required_argument, NULL, OPT_QCOMP },
270             { "qblur",   required_argument, NULL, OPT_QBLUR },
271             { "cplxblur",required_argument, NULL, OPT_CPLXBLUR },
272             { "no-psnr", no_argument,       NULL, OPT_NOPSNR },
273             { "quiet",   no_argument,       NULL, OPT_QUIET },
274             { "verbose", no_argument,       NULL, 'v' },
275             {0, 0, 0, 0}
276         };
277
278         int c;
279
280         c = getopt_long( argc, argv, "hi:I:b:r:cxB:q:nf:o:s:A:m:p:vw",
281                          long_options, &long_options_index);
282
283         if( c == -1 )
284         {
285             break;
286         }
287
288         switch( c )
289         {
290             case 'h':
291                 Help( &defaults );
292                 return -1;
293
294             case 0:
295                 break;
296             case 'B':
297                 param->rc.i_bitrate = atol( optarg );
298                 param->rc.b_cbr = 1;
299                 break;
300             case 'b':
301                 param->i_bframe = atol( optarg );
302                 break;
303             case OPT_NOBADAPT:
304                 param->b_bframe_adaptive = 0;
305                 break;
306             case OPT_BBIAS:
307                 param->i_bframe_bias = atol( optarg );
308                 break;
309             case OPT_BPYRAMID:
310                 param->b_bframe_pyramid = 1;
311                 break;
312             case 'i':
313                 param->i_keyint_min = atol( optarg );
314                 break;
315             case 'I':
316                 param->i_keyint_max = atol( optarg );
317                 break;
318             case OPT_SCENECUT:
319                 param->i_scenecut_threshold = atol( optarg );
320                 break;
321             case 'n':
322                 param->b_deblocking_filter = 0;
323                 break;
324             case 'f':
325             {
326                 char *p = strchr( optarg, ':' );
327                 if( p )
328                 {
329                     param->i_deblocking_filter_alphac0 = atoi( optarg );
330                     param->i_deblocking_filter_beta = atoi( p );
331                 }
332                 break;
333             }
334             case 'q':
335                 param->rc.i_qp_constant = atoi( optarg );
336                 break;
337             case OPT_QPMIN:
338                 param->rc.i_qp_min = atoi( optarg );
339                 break;
340             case OPT_QPMAX:
341                 param->rc.i_qp_max = atoi( optarg );
342                 break;
343             case OPT_QPSTEP:
344                 param->rc.i_qp_step = atoi( optarg );
345                 break;
346             case 'r':
347                 param->i_frame_reference = atoi( optarg );
348                 break;
349             case 'c':
350                 param->b_cabac = 1;
351                 break;
352             case 'x':
353                 *pb_decompress = 1;
354                 break;
355             case 'C':
356                 param->cpu = 0;
357                 break;
358             case OPT_FRAMES:
359                 param->i_maxframes = atoi( optarg );
360                 break;
361             case'o':
362                 if( ( *p_fout = fopen( optarg, "wb" ) ) == NULL )
363                 {
364                     fprintf( stderr, "cannot open output file `%s'\n", optarg );
365                     return -1;
366                 }
367                 break;
368             case 's':
369             {
370                 char *p = strchr( optarg, ':' );
371                 if( p )
372                 {
373                     param->vui.i_sar_width = atoi( optarg );
374                     param->vui.i_sar_height = atoi( p + 1 );
375                 }
376                 break;
377             }
378             case OPT_FPS:
379             {
380                 float fps;
381                 if( sscanf( optarg, "%d/%d", &param->i_fps_num, &param->i_fps_den ) == 2 )
382                     ;
383                 else if( sscanf( optarg, "%f", &fps ) )
384                 {
385                     param->i_fps_num = (int)(fps * 1000 + .5);
386                     param->i_fps_den = 1000;
387                 }
388                 else
389                 {
390                     fprintf( stderr, "bad fps `%s'\n", optarg );
391                     return -1;
392                 }
393             }
394             case 'A':
395                 param->analyse.inter = 0;
396                 if( strstr( optarg, "none" ) )  param->analyse.inter = 0x000000;
397                 if( strstr( optarg, "all" ) )   param->analyse.inter = X264_ANALYSE_I4x4|X264_ANALYSE_PSUB16x16|X264_ANALYSE_PSUB8x8|X264_ANALYSE_BSUB16x16;
398
399                 if( strstr( optarg, "i4x4" ) )      param->analyse.inter |= X264_ANALYSE_I4x4;
400                 if( strstr( optarg, "psub16x16" ) ) param->analyse.inter |= X264_ANALYSE_PSUB16x16;
401                 if( strstr( optarg, "psub8x8" ) )   param->analyse.inter |= X264_ANALYSE_PSUB8x8;
402                 if( strstr( optarg, "bsub16x16" ) ) param->analyse.inter |= X264_ANALYSE_BSUB16x16;
403                 break;
404             case OPT_DIRECT:
405                 if( strstr( optarg, "temporal" ) )
406                     param->analyse.i_direct_mv_pred = X264_DIRECT_PRED_TEMPORAL;
407                 else if( strstr( optarg, "spatial" ) )
408                     param->analyse.i_direct_mv_pred = X264_DIRECT_PRED_SPATIAL;
409                 else if( strstr( optarg, "none" ) )
410                     param->analyse.i_direct_mv_pred = X264_DIRECT_PRED_NONE;
411                 else
412                     param->analyse.i_direct_mv_pred = atoi( optarg );
413                 break;
414             case 'w':
415                 param->analyse.b_weighted_bipred = 1;
416                 break;
417             case 'm':
418                 param->analyse.i_subpel_refine = atoi(optarg);
419                 break;
420             case OPT_LEVEL:
421                 param->i_level_idc = atoi(optarg);
422                 break;
423             case OPT_RCBUF:
424                 param->rc.i_rc_buffer_size = atoi(optarg);
425                 break;
426             case OPT_RCIBUF:
427                 param->rc.i_rc_init_buffer = atoi(optarg);
428                 break;
429             case OPT_RCSENS:
430                 param->rc.i_rc_sens = atoi(optarg);
431                 break;
432             case OPT_IPRATIO:
433                 param->rc.f_ip_factor = atof(optarg);
434                 break;
435             case OPT_PBRATIO:
436                 param->rc.f_pb_factor = atof(optarg);
437                 break;
438             case OPT_CHROMA_QP:
439                 param->analyse.i_chroma_qp_offset = atoi(optarg);
440                 break;
441             case 'p':
442             {
443                 int i_pass = atoi(optarg);
444                 if( i_pass == 1 )
445                     param->rc.b_stat_write = 1;
446                 else if( i_pass == 2 )
447                     param->rc.b_stat_read = 1;
448                 else if( i_pass > 2 )
449                     param->rc.b_stat_read =
450                     param->rc.b_stat_write = 1;
451                 break;
452             }
453             case OPT_RCSTATS:
454                 param->rc.psz_stat_in = optarg;
455                 param->rc.psz_stat_out = optarg;
456                 break;
457             case OPT_RCEQ:
458                 param->rc.psz_rc_eq = optarg;
459                break;
460             case OPT_QCOMP:
461                 param->rc.f_qcompress = atof(optarg);
462                 break;
463             case OPT_QBLUR:
464                 param->rc.f_qblur = atof(optarg);
465                 break;
466             case OPT_CPLXBLUR:
467                 param->rc.f_complexity_blur = atof(optarg);
468                 break;
469             case OPT_NOPSNR:
470                 param->analyse.b_psnr = 0;
471                 break;
472             case OPT_QUIET:
473                 param->i_log_level = X264_LOG_NONE;
474                 break;
475             case 'v':
476                 param->i_log_level = X264_LOG_DEBUG;
477                 break;
478             default:
479                 fprintf( stderr, "unknown option (%c)\n", optopt );
480                 return -1;
481         }
482     }
483
484     /* Get the file name */
485     if( optind > argc - 1 )
486     {
487         Help( &defaults );
488         return -1;
489     }
490     psz_filename = argv[optind++];
491
492     if( !(*pb_decompress) )
493     {
494         if( optind > argc - 1 )
495         {
496             char *psz;
497             /* try to parse the file name */
498             for( psz = psz_filename; *psz; psz++ )
499             {
500                 if( *psz >= '0' && *psz <= '9'
501                     && sscanf( psz, "%ux%u", &param->i_width, &param->i_height ) == 2 )
502                 {
503                     fprintf( stderr, "x264: file name gives %dx%d\n", param->i_width, param->i_height );
504                     break;
505                 }
506             }
507         }
508         else
509         {
510             sscanf( argv[optind++], "%ux%u", &param->i_width, &param->i_height );
511         }
512
513         if( !param->i_width || !param->i_height )
514         {
515             Help( &defaults );
516             return -1;
517         }
518     }
519
520     /* open the input */
521     if( !strcmp( psz_filename, "-" ) )
522     {
523         *p_fin = stdin;
524         optind++;
525     }
526     else if( ( *p_fin = fopen( psz_filename, "rb" ) ) == NULL )
527     {
528         fprintf( stderr, "could not open input file '%s'\n", psz_filename );
529         return -1;
530     }
531
532     return 0;
533 }
534
535 /*****************************************************************************
536  * Decode:
537  *****************************************************************************/
538 static int  Decode( x264_param_t  *param, FILE *fh26l, FILE *fout )
539 {
540     fprintf( stderr, "decompressor not working (help is welcome)\n" );
541     return -1;
542 #if 0
543     x264_nal_t nal;
544     int i_data;
545     int b_eof;
546
547     //param.cpu = 0;
548     if( ( h = x264_decoder_open( &param ) ) == NULL )
549     {
550         fprintf( stderr, "x264_decoder_open failed\n" );
551         return -1;
552     }
553
554     i_start = x264_mdate();
555     b_eof = 0;
556     i_frame = 0;
557     i_data  = 0;
558     nal.p_payload = malloc( DATA_MAX );
559
560     while( !i_ctrl_c )
561     {
562         uint8_t *p, *p_next, *end;
563         int i_size;
564         /* fill buffer */
565         if( i_data < DATA_MAX && !b_eof )
566         {
567             int i_read = fread( &data[i_data], 1, DATA_MAX - i_data, fh26l );
568             if( i_read <= 0 )
569             {
570                 b_eof = 1;
571             }
572             else
573             {
574                 i_data += i_read;
575             }
576         }
577
578         if( i_data < 3 )
579         {
580             break;
581         }
582
583         end = &data[i_data];
584
585         /* extract one nal */
586         p = &data[0];
587         while( p < end - 3 )
588         {
589             if( p[0] == 0x00 && p[1] == 0x00 && p[2] == 0x01 )
590             {
591                 break;
592             }
593             p++;
594         }
595
596         if( p >= end - 3 )
597         {
598             fprintf( stderr, "garbage (i_data = %d)\n", i_data );
599             i_data = 0;
600             continue;
601         }
602
603         p_next = p + 3;
604         while( p_next < end - 3 )
605         {
606             if( p_next[0] == 0x00 && p_next[1] == 0x00 && p_next[2] == 0x01 )
607             {
608                 break;
609             }
610             p_next++;
611         }
612
613         if( p_next == end - 3 && i_data < DATA_MAX )
614         {
615             p_next = end;
616         }
617
618         /* decode this nal */
619         i_size = p_next - p - 3;
620         if( i_size <= 0 )
621         {
622             if( b_eof )
623             {
624                 break;
625             }
626             fprintf( stderr, "nal too large (FIXME) ?\n" );
627             i_data = 0;
628             continue;
629         }
630
631         x264_nal_decode( &nal, p +3, i_size );
632
633         /* decode the content of the nal */
634         x264_decoder_decode( h, &pic, &nal );
635
636         if( pic != NULL )
637         {
638             int i;
639
640             i_frame++;
641
642             for( i = 0; i < pic->i_plane;i++ )
643             {
644                 int i_line;
645                 int i_div;
646
647                 i_div = i==0 ? 1 : 2;
648                 for( i_line = 0; i_line < pic->i_height/i_div; i_line++ )
649                 {
650                     fwrite( pic->plane[i]+i_line*pic->i_stride[i], 1, pic->i_width/i_div, fout );
651                 }
652             }
653         }
654
655         memmove( &data[0], p_next, end - p_next );
656         i_data -= p_next - &data[0];
657     }
658
659     i_end = x264_mdate();
660     free( nal.p_payload );
661     fprintf( stderr, "\n" );
662
663     x264_decoder_close( h );
664
665     fclose( fh26l );
666     if( fout != stdout )
667     {
668         fclose( fout );
669     }
670     if( i_frame > 0 )
671     {
672         double fps = (double)i_frame * (double)1000000 /
673                      (double)( i_end - i_start );
674         fprintf( stderr, "decoded %d frames %ffps\n", i_frame, fps );
675     }
676 #endif
677 }
678
679 /*****************************************************************************
680  * Encode:
681  *****************************************************************************/
682 static int  Encode( x264_param_t  *param, FILE *fyuv, FILE *fout )
683 {
684     x264_t *h;
685     x264_picture_t pic;
686
687     int     i_frame, i_frame_total;
688     int64_t i_start, i_end;
689     int64_t i_file;
690
691     i_frame_total = 0;
692     if( !fseek( fyuv, 0, SEEK_END ) )
693     {
694         int64_t i_size = ftell( fyuv );
695         fseek( fyuv, 0, SEEK_SET );
696         i_frame_total = (int)(i_size / ( param->i_width * param->i_height * 3 / 2 ));
697     }
698
699     if( ( h = x264_encoder_open( param ) ) == NULL )
700     {
701         fprintf( stderr, "x264_encoder_open failed\n" );
702         return -1;
703     }
704
705     /* Create a new pic */
706     x264_picture_alloc( &pic, X264_CSP_I420, param->i_width, param->i_height );
707
708     i_start = x264_mdate();
709     for( i_frame = 0, i_file = 0; i_ctrl_c == 0 ; i_frame++ )
710     {
711         int         i_nal;
712         x264_nal_t  *nal;
713
714         int         i;
715
716         if (param->i_maxframes!=0 && i_frame>=param->i_maxframes)
717             break;
718
719         /* read a frame */
720         if( fread( pic.img.plane[0], 1, param->i_width * param->i_height, fyuv ) <= 0 ||
721             fread( pic.img.plane[1], 1, param->i_width * param->i_height / 4, fyuv ) <= 0 ||
722             fread( pic.img.plane[2], 1, param->i_width * param->i_height / 4, fyuv ) <= 0 )
723         {
724             break;
725         }
726
727         /* Do not force any parameters */
728         pic.i_type = X264_TYPE_AUTO;
729         if( x264_encoder_encode( h, &nal, &i_nal, &pic, &pic ) < 0 )
730         {
731             fprintf( stderr, "x264_encoder_encode failed\n" );
732         }
733
734         for( i = 0; i < i_nal; i++ )
735         {
736             int i_size;
737             int i_data;
738
739             i_data = DATA_MAX;
740             if( ( i_size = x264_nal_encode( data, &i_data, 1, &nal[i] ) ) > 0 )
741             {
742                 i_file += fwrite( data, 1, i_size, fout );
743             }
744             else if( i_size < 0 )
745             {
746                 fprintf( stderr,
747                          "need to increase buffer size (size=%d)\n", -i_size );
748             }
749         }
750     }
751     i_end = x264_mdate();
752     x264_picture_clean( &pic );
753     x264_encoder_close( h );
754     fprintf( stderr, "\n" );
755
756     fclose( fyuv );
757     if( fout != stdout )
758     {
759         fclose( fout );
760     }
761
762     if( i_frame > 0 )
763     {
764         double fps = (double)i_frame * (double)1000000 /
765                      (double)( i_end - i_start );
766
767         fprintf( stderr, "encoded %d frames, %.2f fps, %.2f kb/s\n", i_frame, fps, (double) i_file * 8 * param->i_fps_num / ( param->i_fps_den * i_frame * 1000 ) );
768     }
769
770     return 0;
771 }
772
773