OSDN Git Service

c84b5730aecd3f506f755c60a50dd59b5508369b
[handbrake-jp/handbrake-jp-git.git] / test / test.c
1 /* $Id: test.c,v 1.82 2005/11/19 08:25:54 titer Exp $
2
3    This file is part of the HandBrake source code.
4    Homepage: <http://handbrake.m0k.org/>.
5    It may be used under the terms of the GNU General Public License. */
6
7 #include <signal.h>
8 #include <getopt.h>
9 #include <sys/time.h>
10 #include <time.h>
11 #include <unistd.h>
12
13 #include "hb.h"
14
15 /* Options */
16 static int    debug       = HB_DEBUG_NONE;
17 static int    update      = 0;
18 static char * input       = NULL;
19 static char * output      = NULL;
20 static char * format      = NULL;
21 static int    titleindex  = 1;
22 static int    twoPass     = 0;
23 static int    deinterlace = 0;
24 static int    grayscale   = 0;
25 static int    vcodec      = HB_VCODEC_FFMPEG;
26 static int    h264_13     = 0;
27 static int    h264_30     = 0;
28 static char * audios      = NULL;
29 static int    surround    = 0;
30 static int    sub         = 0;
31 static int    width       = 0;
32 static int    height      = 0;
33 static int    crop[4]     = { -1,-1,-1,-1 };
34 static int    cpu         = 0;
35 static int    vrate       = 0;
36 static int    arate       = 0;
37 static float  vquality    = -1.0;
38 static int    vbitrate    = 0;
39 static int    size        = 0;
40 static int    abitrate    = 0;
41 static int    mux         = 0;
42 static int    acodec      = 0;
43 static int    pixelratio  = 0;
44 static int    chapter_start = 0;
45 static int    chapter_end   = 0;
46 static int        crf                   = 0;
47 static char       *x264opts             = NULL;
48 static char       *x264opts2    = NULL;
49 static int        maxHeight             = 0;
50 static int        maxWidth              = 0;
51
52 /* Exit cleanly on Ctrl-C */
53 static volatile int die = 0;
54 static void SigHandler( int );
55
56 /* Utils */
57 static void ShowCommands();
58 static void ShowHelp();
59 static int  ParseOptions( int argc, char ** argv );
60 static int  CheckOptions( int argc, char ** argv );
61 static int  HandleEvents( hb_handle_t * h );
62
63 int main( int argc, char ** argv )
64 {
65     hb_handle_t * h;
66     int           build;
67     char        * version;
68
69     /* Parse command line */
70     if( ParseOptions( argc, argv ) ||
71         CheckOptions( argc, argv ) )
72     {
73         return 1;
74     }
75
76     /* Init libhb */
77     h = hb_init( debug, update );
78
79     /* Show version */
80     fprintf( stderr, "HandBrake %s (%d) - http://handbrake.m0k.org/\n",
81              hb_get_version( h ), hb_get_build( h ) );
82
83     /* Check for update */
84     if( update )
85     {
86         if( ( build = hb_check_update( h, &version ) ) > -1 )
87         {
88             fprintf( stderr, "You are using an old version of "
89                      "HandBrake.\nLatest is %s (build %d).\n", version,
90                      build );
91         }
92         else
93         {
94             fprintf( stderr, "Your version of HandBrake is up to "
95                      "date.\n" );
96         }
97         hb_close( &h );
98         return 0;
99     }
100
101     /* Geeky */
102     fprintf( stderr, "%d CPU%s detected\n", hb_get_cpu_count(),
103              hb_get_cpu_count( h ) > 1 ? "s" : "" );
104     if( cpu )
105     {
106         fprintf( stderr, "Forcing %d CPU%s\n", cpu,
107                  cpu > 1 ? "s" : "" );
108         hb_set_cpu_count( h, cpu );
109     }
110
111     /* Exit ASAP on Ctrl-C */
112     signal( SIGINT, SigHandler );
113
114     /* Feed libhb with a DVD to scan */
115     fprintf( stderr, "Opening %s...\n", input );
116     hb_scan( h, input, titleindex );
117
118     /* Wait... */
119     while( !die )
120     {
121 #if !defined(SYS_BEOS)
122         fd_set         fds;
123         struct timeval tv;
124         int            ret;
125         char           buf[257];
126
127         tv.tv_sec  = 0;
128         tv.tv_usec = 100000;
129
130         FD_ZERO( &fds );
131         FD_SET( STDIN_FILENO, &fds );
132         ret = select( STDIN_FILENO + 1, &fds, NULL, NULL, &tv );
133
134         if( ret > 0 )
135         {
136             int size = 0;
137
138             while( size < 256 &&
139                    read( STDIN_FILENO, &buf[size], 1 ) > 0 )
140             {
141                 if( buf[size] == '\n' )
142                 {
143                     break;
144                 }
145                 size++;
146             }
147
148             if( size >= 256 || buf[size] == '\n' )
149             {
150                 switch( buf[0] )
151                 {
152                     case 'q':
153                         die = 1;
154                         break;
155                     case 'p':
156                         hb_pause( h );
157                         break;
158                     case 'r':
159                         hb_resume( h );
160                         break;
161                     case 'h':
162                         ShowCommands();
163                         break;
164                 }
165             }
166         }
167         hb_snooze( 200 );
168 #else
169         hb_snooze( 200 );
170 #endif
171
172         HandleEvents( h );
173     }
174
175     /* Clean up */
176     hb_close( &h );
177     if( input )  free( input );
178     if( output ) free( output );
179     if( format ) free( format );
180     if( audios ) free( audios );
181         if( x264opts ) free (x264opts );
182         if( x264opts2 ) free (x264opts2 );
183         
184     fprintf( stderr, "HandBrake has exited.\n" );
185
186     return 0;
187 }
188
189 static void ShowCommands()
190 {
191     fprintf( stderr, "Commands:\n" );
192     fprintf( stderr, " [h]elp    Show this message\n" );
193     fprintf( stderr, " [q]uit    Exit HandBrakeCLI\n" );
194     fprintf( stderr, " [p]ause   Pause encoding\n" );
195     fprintf( stderr, " [r]esume  Resume encoding\n" );
196 }
197
198 static void PrintTitleInfo( hb_title_t * title )
199 {
200     hb_chapter_t  * chapter;
201     hb_audio_t    * audio;
202     hb_subtitle_t * subtitle;
203     int i;
204
205     fprintf( stderr, "+ title %d:\n", title->index );
206     fprintf( stderr, "  + vts %d, ttn %d, cells %d->%d (%d blocks)\n",
207              title->vts, title->ttn, title->cell_start, title->cell_end,
208              title->block_count );
209     fprintf( stderr, "  + duration: %02d:%02d:%02d\n",
210              title->hours, title->minutes, title->seconds );
211     fprintf( stderr, "  + size: %dx%d, aspect: %.2f, %.3f fps\n",
212              title->width, title->height,
213              (float) title->aspect / HB_ASPECT_BASE,
214              (float) title->rate / title->rate_base );
215     fprintf( stderr, "  + autocrop: %d/%d/%d/%d\n", title->crop[0],
216              title->crop[1], title->crop[2], title->crop[3] );
217     fprintf( stderr, "  + chapters:\n" );
218     for( i = 0; i < hb_list_count( title->list_chapter ); i++ )
219     {
220         chapter = hb_list_item( title->list_chapter, i );
221         fprintf( stderr, "    + %d: cells %d->%d, %d blocks, duration "
222                  "%02d:%02d:%02d\n", chapter->index,
223                  chapter->cell_start, chapter->cell_end,
224                  chapter->block_count, chapter->hours, chapter->minutes,
225                  chapter->seconds );
226     }
227     fprintf( stderr, "  + audio tracks:\n" );
228     for( i = 0; i < hb_list_count( title->list_audio ); i++ )
229     {
230         audio = hb_list_item( title->list_audio, i );
231         if( audio->codec & HB_ACODEC_AC3 )
232         {
233             fprintf( stderr, "    + %x, %s, %dHz, %dbps\n", audio->id,
234                      audio->lang, audio->rate, audio->bitrate );
235         }
236         else
237         {
238             fprintf( stderr, "    + %x, %s\n", audio->id, audio->lang );
239         }
240     }
241     fprintf( stderr, "  + subtitle tracks:\n" );
242     for( i = 0; i < hb_list_count( title->list_subtitle ); i++ )
243     {
244         subtitle = hb_list_item( title->list_subtitle, i );
245         fprintf( stderr, "    + %x, %s\n", subtitle->id, subtitle->lang );
246     }
247 }
248
249 static int HandleEvents( hb_handle_t * h )
250 {
251     hb_state_t s;
252     hb_get_state( h, &s );
253     switch( s.state )
254     {
255         case HB_STATE_IDLE:
256             /* Nothing to do */
257             break;
258
259 #define p s.param.scanning
260         case HB_STATE_SCANNING:
261             /* Show what title is currently being scanned */
262             fprintf( stderr, "Scanning title %d", p.title_cur );
263             if( !titleindex )
264                 fprintf( stderr, " of %d", p.title_count );
265             fprintf( stderr, "...\n" );
266             break;
267 #undef p
268
269         case HB_STATE_SCANDONE:
270         {
271             hb_list_t  * list;
272             hb_title_t * title;
273             hb_job_t   * job;
274
275             list = hb_get_titles( h );
276
277             if( !hb_list_count( list ) )
278             {
279                 /* No valid title, stop right there */
280                 fprintf( stderr, "No title found.\n" );
281                 die = 1;
282                 break;
283             }
284             if( !titleindex )
285             {
286                 /* Scan-only mode, print infos and exit */
287                 int i;
288                 for( i = 0; i < hb_list_count( list ); i++ )
289                 {
290                     title = hb_list_item( list, i );
291                     PrintTitleInfo( title );
292                 }
293                 die = 1;
294                 break;
295             }
296
297             /* Set job settings */
298             title = hb_list_item( list, 0 );
299             job   = title->job;
300
301             PrintTitleInfo( title );
302
303             if( chapter_start && chapter_end )
304             {
305                 job->chapter_start = MAX( job->chapter_start,
306                                           chapter_start );
307                 job->chapter_end   = MIN( job->chapter_end,
308                                           chapter_end );
309                 job->chapter_end   = MAX( job->chapter_start,
310                                           job->chapter_end );
311             }
312
313             if( crop[0] >= 0 && crop[1] >= 0 &&
314                 crop[2] >= 0 && crop[3] >= 0 )
315             {
316                 memcpy( job->crop, crop, 4 * sizeof( int ) );
317             }
318
319             job->deinterlace = deinterlace;
320             job->grayscale   = grayscale;
321             job->pixel_ratio = pixelratio;
322
323             if( width && height )
324             {
325                 job->width  = width;
326                 job->height = height;
327             }
328             else if( width )
329             {
330                 job->width = width;
331                 hb_fix_aspect( job, HB_KEEP_WIDTH );
332             }
333             else if( height )
334             {
335                 job->height = height;
336                 hb_fix_aspect( job, HB_KEEP_HEIGHT );
337             }
338             else if( !width && !height && !pixelratio )
339             {
340                 hb_fix_aspect( job, HB_KEEP_WIDTH );
341             }
342
343             if( vquality >= 0.0 && vquality <= 1.0 )
344             {
345                 job->vquality = vquality;
346                 job->vbitrate = 0;
347             }
348             else if( vbitrate )
349             {
350                 job->vquality = -1.0;
351                 job->vbitrate = vbitrate;
352             }
353             if( vcodec )
354             {
355                 job->vcodec = vcodec;
356             }
357             if( h264_13 ) 
358             { 
359                 job->h264_level = 13; 
360             }
361                 if( h264_30 )
362                 {
363                     job->h264_level = 30;
364             }
365             if( vrate )
366             {
367                 job->vrate = 27000000;
368                 job->vrate_base = vrate;
369             }
370             if( arate )
371             {
372                 job->arate = arate;
373             }
374
375             if( audios )
376             {
377                 if( strcasecmp( audios, "none" ) )
378                 {
379                     int    audio_count = 0;
380                     char * tmp         = audios;
381                     while( *tmp )
382                     {
383                         if( *tmp < '0' || *tmp > '9' )
384                         {
385                             /* Skip non numeric char */
386                             tmp++;
387                             continue;
388                         }
389                         job->audios[audio_count++] =
390                             strtol( tmp, &tmp, 0 ) - 1;
391                     }
392                     job->audios[audio_count] = -1;
393                 }
394                 else
395                 {
396                     job->audios[0] = -1;
397                 }
398             }
399                         if( surround )
400                         {
401                                 job->surround = 1;
402                         }
403             if( abitrate )
404             {
405                 job->abitrate = abitrate;
406             }
407             if( acodec )
408             {
409                 job->acodec = acodec;
410             }
411
412             if( size )
413             {
414                 job->vbitrate = hb_calc_bitrate( job, size );
415                 fprintf( stderr, "Calculated bitrate: %d kbps\n",
416                          job->vbitrate );
417             }
418
419             if( sub )
420             {
421                 job->subtitle = sub - 1;
422             }
423
424             if( job->mux )
425             {
426                 job->mux = mux;
427             }
428             job->file = strdup( output );
429
430                         if( crf )
431                         {
432                                 job->crf = 1;
433                         }
434
435                         if (x264opts != NULL && *x264opts != '\0' )
436                         {
437                                 hb_log("Applying the following x264 options: %s", x264opts);
438                                 job->x264opts = x264opts;
439                         }
440                         else /*avoids a bus error crash when options aren't specified*/
441                         {
442                                 job->x264opts =  NULL;
443                         }
444                         if (maxWidth)
445                                 job->maxWidth = maxWidth;
446                         if (maxHeight)
447                                 job->maxHeight = maxHeight;
448                                 
449             if( twoPass )
450             {
451                 job->pass = 1;
452                 hb_add( h, job );
453                 job->pass = 2;
454                                 job->x264opts = x264opts2;
455                 hb_add( h, job );
456             }
457             else
458             {
459                 job->pass = 0;
460                 hb_add( h, job );
461             }
462             hb_start( h );
463             break;
464         }
465
466 #define p s.param.working
467         case HB_STATE_WORKING:
468             fprintf( stderr, "\rEncoding: task %d of %d, %.2f %%",
469                      p.job_cur, p.job_count, 100.0 * p.progress );
470             if( p.seconds > -1 )
471             {
472                 fprintf( stderr, " (%.2f fps, avg %.2f fps, ETA "
473                          "%02dh%02dm%02ds)", p.rate_cur, p.rate_avg,
474                          p.hours, p.minutes, p.seconds );
475             }
476             break;
477 #undef p
478
479 #define p s.param.muxing
480         case HB_STATE_MUXING:
481         {
482             fprintf( stderr, "\rMuxing: %.2f %%", 100.0 * p.progress );
483             break;
484         }
485 #undef p
486
487 #define p s.param.workdone
488         case HB_STATE_WORKDONE:
489             /* Print error if any, then exit */
490             switch( p.error )
491             {
492                 case HB_ERROR_NONE:
493                     fprintf( stderr, "\nRip done!\n" );
494                     break;
495                 case HB_ERROR_CANCELED:
496                     fprintf( stderr, "\nRip canceled.\n" );
497                     break;
498                 default:
499                     fprintf( stderr, "\nRip failed (error %x).\n",
500                              p.error );
501             }
502             die = 1;
503             break;
504 #undef p
505     }
506     return 0;
507 }
508
509 /****************************************************************************
510  * SigHandler:
511  ****************************************************************************/
512 static volatile int64_t i_die_date = 0;
513 void SigHandler( int i_signal )
514 {
515     if( die == 0 )
516     {
517         die = 1;
518         i_die_date = hb_get_date();
519         fprintf( stderr, "Signal %d received, terminating - do it "
520                  "again in case it gets stuck\n", i_signal );
521     }
522     else if( i_die_date + 500 < hb_get_date() )
523     {
524         fprintf( stderr, "Dying badly, files might remain in your /tmp\n" );
525         exit( 1 );
526     }
527 }
528
529 /****************************************************************************
530  * ShowHelp:
531  ****************************************************************************/
532 static void ShowHelp()
533 {
534     int i;
535     
536     fprintf( stderr,
537     "Syntax: HandBrakeCLI [options] -i <device> -o <file>\n"
538     "\n"
539     "    -h, --help              Print help\n"
540     "    -u, --update            Check for updates and exit\n"
541     "    -v, --verbose           Be verbose\n"
542     "    -C, --cpu               Set CPU count (default: autodetected)\n"
543     "\n"
544     "    -f, --format <string>   Set output format (avi/mp4/ogm, default:\n"
545     "                            autodetected from file name)\n"
546     "    -i, --input <string>    Set input device\n"
547     "    -o, --output <string>   Set output file name\n"
548     "\n"
549     "    -t, --title <number>    Select a title to encode (0 to scan only,\n"
550     "                            default: 1)\n"
551     "    -c, --chapters <string> Select chapters (e.g. \"1-3\" for chapters\n"
552     "                            1 to 3, or \"3\" for chapter 3 only,\n"
553     "                            default: all chapters)\n"
554     "    -a, --audio <string>    Select audio channel(s) (\"none\" for no \n"
555     "                            audio, default: first one)\n"
556     "    -6, --surround          Export 5.1 surround as 6-channel AAC\n"
557     "\n"
558     "    -s, --subtitle <number> Select subtitle (default: none)\n"
559     "    -e, --encoder <string>  Set video library encoder (ffmpeg,xvid,\n"
560     "                            x264,x264b13,x264b30 default: ffmpeg)\n"
561     "    -E, --aencoder <string> Set audio encoder (faac/lame/vorbis/ac3, ac3\n"
562     "                            meaning passthrough, default: guessed)\n"
563     "    -2, --two-pass          Use two-pass mode\n"
564     "    -d, --deinterlace       Deinterlace video\n"
565     "    -g, --grayscale         Grayscale encoding\n"
566     "    -p, --pixelratio        Store pixel aspect ratio in video stream\n"
567     "\n"
568     "    -r, --rate              Set video framerate (" );
569     for( i = 0; i < hb_video_rates_count; i++ )
570     {
571         fprintf( stderr, hb_video_rates[i].string );
572         if( i != hb_video_rates_count - 1 )
573             fprintf( stderr, "/" );
574     }
575     fprintf( stderr, ")\n"
576     "    -R, --arate             Set audio samplerate (" );
577     for( i = 0; i < hb_audio_rates_count; i++ )
578     {
579         fprintf( stderr, hb_audio_rates[i].string );
580         if( i != hb_audio_rates_count - 1 )
581             fprintf( stderr, "/" );
582     }
583     fprintf( stderr, " kHz)\n"
584     "    -b, --vb <kb/s>         Set video bitrate (default: 1000)\n"
585     "    -q, --quality <float>   Set video quality (0.0..1.0)\n"
586         "    -Q, --crf               Use with -q for CRF instead of CQP\n"
587     "    -S, --size <MB>         Set target size\n"
588     "    -B, --ab <kb/s>         Set audio bitrate (default: 128)\n"
589     "    -w, --width <number>    Set picture width\n"
590     "    -l, --height <number>   Set picture height\n"
591     "        --crop <T:B:L:R>    Set cropping values (default: autocrop)\n"
592         "    -Y, --maxHeight <#>     Set maximum height\n"
593         "    -X, --maxWidth <#>      Set maximum width\n"
594         "\n"
595         "    -x, --x264opts <string> Specify advanced x264 options in the\n"
596         "                            same style as mencoder:\n"
597         "                            option1=value1:option2=value2\n" );
598 }
599
600 /****************************************************************************
601  * ParseOptions:
602  ****************************************************************************/
603 static int ParseOptions( int argc, char ** argv )
604 {
605     for( ;; )
606     {
607         static struct option long_options[] =
608           {
609             { "help",        no_argument,       NULL,    'h' },
610             { "update",      no_argument,       NULL,    'u' },
611             { "verbose",     no_argument,       NULL,    'v' },
612             { "cpu",         required_argument, NULL,    'C' },
613
614             { "format",      required_argument, NULL,    'f' },
615             { "input",       required_argument, NULL,    'i' },
616             { "output",      required_argument, NULL,    'o' },
617
618             { "title",       required_argument, NULL,    't' },
619             { "chapters",    required_argument, NULL,    'c' },
620             { "audio",       required_argument, NULL,    'a' },
621             { "surround",    no_argument,       NULL,    '6' },
622             { "subtitle",    required_argument, NULL,    's' },
623
624             { "encoder",     required_argument, NULL,    'e' },
625             { "aencoder",    required_argument, NULL,    'E' },
626             { "two-pass",    no_argument,       NULL,    '2' },
627             { "deinterlace", no_argument,       NULL,    'd' },
628             { "grayscale",   no_argument,       NULL,    'g' },
629             { "pixelratio",  no_argument,       NULL,    'p' },
630             { "width",       required_argument, NULL,    'w' },
631             { "height",      required_argument, NULL,    'l' },
632             { "crop",        required_argument, NULL,    'n' },
633
634             { "vb",          required_argument, NULL,    'b' },
635             { "quality",     required_argument, NULL,    'q' },
636             { "size",        required_argument, NULL,    'S' },
637             { "ab",          required_argument, NULL,    'B' },
638             { "rate",        required_argument, NULL,    'r' },
639             { "arate",       required_argument, NULL,    'R' },
640                         { "crf",                 no_argument,           NULL,    'Q' },
641                         { "x264opts",    required_argument, NULL,    'x' },
642                         { "maxHeight",   required_argument, NULL,        'Y' },
643                         { "maxWidth",    required_argument, NULL,        'X' },
644                         
645             { 0, 0, 0, 0 }
646           };
647
648         int option_index = 0;
649         int c;
650
651         c = getopt_long( argc, argv,
652                          "hvuC:f:i:o:t:c:a:6s:e:E:2dgpw:l:n:b:q:S:B:r:R:Qx:Y:X:",
653                          long_options, &option_index );
654         if( c < 0 )
655         {
656             break;
657         }
658
659         switch( c )
660         {
661             case 'h':
662                 ShowHelp();
663                 exit( 0 );
664             case 'u':
665                 update = 1;
666                 break;
667             case 'v':
668                 debug = HB_DEBUG_ALL;
669                 break;
670             case 'C':
671                 cpu = atoi( optarg );
672                 break;
673
674             case 'f':
675                 format = strdup( optarg );
676                 break;
677             case 'i':
678                 input = strdup( optarg );
679                 break;
680             case 'o':
681                 output = strdup( optarg );
682                 break;
683
684             case 't':
685                 titleindex = atoi( optarg );
686                 break;
687             case 'c':
688             {
689                 int start, end;
690                 if( sscanf( optarg, "%d-%d", &start, &end ) == 2 )
691                 {
692                     chapter_start = start;
693                     chapter_end   = end;
694                 }
695                 else if( sscanf( optarg, "%d", &start ) == 1 )
696                 {
697                     chapter_start = start;
698                     chapter_end   = chapter_start;
699                 }
700                 else
701                 {
702                     fprintf( stderr, "chapters: invalid syntax (%s)\n",
703                              optarg );
704                     return -1;
705                 }
706                 break;
707             }
708             case 'a':
709                 audios = strdup( optarg );
710                 break;
711             case '6':
712                 surround = 1;
713                 break;
714             case 's':
715                 sub = atoi( optarg );
716                 break;
717
718             case '2':
719                 twoPass = 1;
720                 break;
721             case 'd':
722                 deinterlace = 1;
723                 break;
724             case 'g':
725                 grayscale = 1;
726                 break;
727             case 'p':
728                 pixelratio = 1;
729                 break;
730             case 'e':
731                 if( !strcasecmp( optarg, "ffmpeg" ) )
732                 {
733                     vcodec = HB_VCODEC_FFMPEG;
734                 }
735                 else if( !strcasecmp( optarg, "xvid" ) )
736                 {
737                     vcodec = HB_VCODEC_XVID;
738                 }
739                 else if( !strcasecmp( optarg, "x264" ) )
740                 {
741                     vcodec = HB_VCODEC_X264;
742                 }
743                 else if( !strcasecmp( optarg, "x264b13" ) )
744                 {
745                     vcodec = HB_VCODEC_X264;
746                     h264_13 = 1;
747                 }
748                 else if( !strcasecmp( optarg, "x264b30" ) )
749                 {
750                     vcodec = HB_VCODEC_X264;
751                     h264_30 = 1;
752                 }
753                 else
754                 {
755                     fprintf( stderr, "invalid codec (%s)\n", optarg );
756                     return -1;
757                 }
758                 break;
759             case 'E':
760                 if( !strcasecmp( optarg, "ac3" ) )
761                 {
762                     acodec = HB_ACODEC_AC3;
763                 }
764                 else if( !strcasecmp( optarg, "lame" ) )
765                 {
766                     acodec = HB_ACODEC_LAME;
767                 }
768                 break;
769             case 'w':
770                 width = atoi( optarg );
771                 break;
772             case 'l':
773                 height = atoi( optarg );
774                 break;
775             case 'n':
776             {
777                 int    i;
778                 char * tmp = optarg;
779                 for( i = 0; i < 4; i++ )
780                 {
781                     if( !*tmp )
782                         break;
783                     crop[i] = strtol( tmp, &tmp, 0 );
784                     tmp++;
785                 }
786                 break;
787             }
788             case 'r':
789             {
790                 int i;
791                 vrate = 0;
792                 for( i = 0; i < hb_video_rates_count; i++ )
793                 {
794                     if( !strcmp( optarg, hb_video_rates[i].string ) )
795                     {
796                         vrate = hb_video_rates[i].rate;
797                         break;
798                     }
799                 }
800                 if( !vrate )
801                 {
802                     fprintf( stderr, "invalid framerate %s\n", optarg );
803                 }
804                 break;
805             }
806             case 'R':
807             {
808                 int i;
809                 arate = 0;
810                 for( i = 0; i < hb_audio_rates_count; i++ )
811                 {
812                     if( !strcmp( optarg, hb_audio_rates[i].string ) )
813                     {
814                         arate = hb_audio_rates[i].rate;
815                         break;
816                     }
817                 }
818                 if( !arate )
819                 {
820                     fprintf( stderr, "invalid framerate %s\n", optarg );
821                 }
822                 break;
823             }
824             case 'b':
825                 vbitrate = atoi( optarg );
826                 break;
827             case 'q':
828                 vquality = atof( optarg );
829                 break;
830             case 'S':
831                 size = atoi( optarg );
832                 break;
833             case 'B':
834                 abitrate = atoi( optarg );
835                 break;
836                         case 'Q':
837                                 crf = 1;
838                                 break;
839                         case 'x':
840                                 x264opts = strdup( optarg );
841                                 x264opts2 = strdup( optarg );
842                             break;
843                         case 'Y':
844                                 maxHeight = atoi( optarg );
845                                 break;
846                         case 'X':
847                                 maxWidth = atoi (optarg );
848                                 break;
849                                 
850             default:
851                 fprintf( stderr, "unknown option (%s)\n", argv[optind] );
852                 return -1;
853         }
854     }
855
856     return 0;
857 }
858
859 static int CheckOptions( int argc, char ** argv )
860 {
861     if( update )
862     {
863         return 0;
864     }
865
866     if( input == NULL || *input == '\0' )
867     {
868         fprintf( stderr, "Missing input device. Run %s --help for "
869                  "syntax.\n", argv[0] );
870         return 1;
871     }
872
873     /* Parse format */
874     if( titleindex > 0 )
875     {
876         if( output == NULL || *output == '\0' )
877         {
878             fprintf( stderr, "Missing output file name. Run %s --help "
879                      "for syntax.\n", argv[0] );
880             return 1;
881         }
882
883         if( !format )
884         {
885             char * p = strrchr( output, '.' );
886
887             /* autodetect */
888             if( p && !strcasecmp( p, ".avi" ) )
889             {
890                 mux = HB_MUX_AVI;
891             }
892             else if( p && !strcasecmp( p, ".mp4" ) )
893             {
894                 if ( h264_30 == 1 )
895                     mux = HB_MUX_IPOD;
896                 else
897                     mux = HB_MUX_MP4;
898             }
899             else if( p && ( !strcasecmp( p, ".ogm" ) ||
900                             !strcasecmp( p, ".ogg" ) ) )
901             {
902                 mux = HB_MUX_OGM;
903             }
904             else
905             {
906                 fprintf( stderr, "Output format couldn't be guessed "
907                          "from file name, using default.\n" );
908                 return 0;
909             }
910         }
911         else if( !strcasecmp( format, "avi" ) )
912         {
913             mux = HB_MUX_AVI;
914         }
915         else if( !strcasecmp( format, "mp4" ) )
916         {
917             if ( h264_30 == 1)
918                 mux = HB_MUX_IPOD;
919             else
920                 mux = HB_MUX_MP4;
921         }
922         else if( !strcasecmp( format, "ogm" ) ||
923                  !strcasecmp( format, "ogg" ) )
924         {
925             mux = HB_MUX_OGM;
926         }
927         else
928         {
929             fprintf( stderr, "Invalid output format (%s). Possible "
930                      "choices are avi, mp4 and ogm\n.", format );
931             return 1;
932         }
933
934         if( !acodec )
935         {
936             if( mux == HB_MUX_MP4 || mux == HB_MUX_IPOD )
937             {
938                 acodec = HB_ACODEC_FAAC;
939             }
940             else if( mux == HB_MUX_AVI )
941             {
942                 acodec = HB_ACODEC_LAME;
943             }
944             else if( mux == HB_MUX_OGM )
945             {
946                 acodec = HB_ACODEC_VORBIS;
947             }
948         }
949                 
950                 if (acodec != HB_ACODEC_FAAC)
951                 {
952                         /* only attempt 5.1 export if exporting to AAC */
953                         surround = 0;
954                 }
955                 
956     }
957
958     return 0;
959 }
960