OSDN Git Service

Organizes anamorphic parameters in a struct, requiring some minor search and replace...
[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.fr/>.
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 #include <inttypes.h>
13
14 #include "hb.h"
15 #include "parsecsv.h"
16
17 #ifdef __APPLE_CC__
18 #import <CoreServices/CoreServices.h>
19 #include <IOKit/IOKitLib.h>
20 #include <IOKit/storage/IOMedia.h>
21 #include <IOKit/storage/IODVDMedia.h>
22 #endif
23
24 /* Options */
25 static int    debug       = HB_DEBUG_NONE;
26 static int    update      = 0;
27 static char * input       = NULL;
28 static char * output      = NULL;
29 static char * format      = NULL;
30 static int    titleindex  = 1;
31 static int    longest_title = 0;
32 static int    subtitle_scan = 0;
33 static int    subtitle_force = 0;
34 static char * native_language = NULL;
35 static int    twoPass     = 0;
36 static int    deinterlace           = 0;
37 static char * deinterlace_opt       = 0;
38 static int    deblock               = 0;
39 static char * deblock_opt           = 0;
40 static int    denoise               = 0;
41 static char * denoise_opt           = 0;
42 static int    detelecine            = 0;
43 static char * detelecine_opt        = 0;
44 static int    decomb                = 0;
45 static char * decomb_opt            = 0;
46 static int    grayscale   = 0;
47 static int    vcodec      = HB_VCODEC_FFMPEG;
48 static int    h264_13     = 0;
49 static int    h264_30     = 0;
50 static hb_list_t * audios = NULL;
51 static hb_audio_config_t * audio = NULL;
52 static int    num_audio_tracks = 0;
53 static char * mixdowns    = NULL;
54 static char * dynamic_range_compression = NULL;
55 static char * atracks     = NULL;
56 static char * arates      = NULL;
57 static char * abitrates   = NULL;
58 static char * acodecs     = NULL;
59 static char * anames      = NULL;
60 static int    default_acodec = HB_ACODEC_FAAC;
61 static int    default_arate = 48000;
62 static int    default_abitrate = 160;
63 static int    sub         = 0;
64 static int    width       = 0;
65 static int    height      = 0;
66 static int    crop[4]     = { -1,-1,-1,-1 };
67 static int    cpu         = 0;
68 static int    vrate       = 0;
69 static float  vquality    = -1.0;
70 static int    vbitrate    = 0;
71 static int    size        = 0;
72 static int    mux         = 0;
73 static int    pixelratio  = 0;
74 static int    loosePixelratio = 0;
75 static int    modulus       = 0;
76 static int    par_height    = 0;
77 static int    par_width     = 0;
78 static int    chapter_start = 0;
79 static int    chapter_end   = 0;
80 static int    chapter_markers = 0;
81 static char * marker_file   = NULL;
82 static int        crf                   = 1;
83 static char       *x264opts             = NULL;
84 static char       *x264opts2    = NULL;
85 static int        maxHeight             = 0;
86 static int        maxWidth              = 0;
87 static int    turbo_opts_enabled = 0;
88 static char * turbo_opts = "ref=1:subme=1:me=dia:analyse=none:trellis=0:no-fast-pskip=0:8x8dct=0:weightb=0";
89 static int    largeFileSize = 0;
90 static int    preset        = 0;
91 static char * preset_name   = 0;
92 static int    cfr           = 0;
93 static int    mp4_optimize  = 0;
94 static int    ipod_atom     = 0;
95 static int    color_matrix  = 0;
96 static int    preview_count = 10;
97 static int    store_previews = 0;
98 static int    start_at_preview = 0;
99 static int64_t stop_at_pts    = 0;
100
101 /* Exit cleanly on Ctrl-C */
102 static volatile int die = 0;
103 static void SigHandler( int );
104
105 /* Utils */
106 static void ShowCommands();
107 static void ShowHelp();
108 static void ShowPresets();
109
110 static int  ParseOptions( int argc, char ** argv );
111 static int  CheckOptions( int argc, char ** argv );
112 static int  HandleEvents( hb_handle_t * h );
113
114 static int get_acodec_for_string( char *codec );
115 static int is_sample_rate_valid(int rate);
116
117 #ifdef __APPLE_CC__
118 static char* bsd_name_for_path(char *path);
119 static int device_is_dvd(char *device);
120 static io_service_t get_iokit_service( char *device );
121 static int is_dvd_service( io_service_t service );
122 static is_whole_media_service( io_service_t service );
123 #endif
124
125 /* Only print the "Muxing..." message once */
126 static int show_mux_warning = 1;
127
128 /****************************************************************************
129  * hb_error_handler
130  *
131  * When using the CLI just display using hb_log as we always did in the past
132  * make sure that we prefix with a nice ERROR message to catch peoples eyes.
133  ****************************************************************************/
134 static void hb_cli_error_handler ( const char *errmsg )
135 {
136     fprintf( stderr, "ERROR: %s\n", errmsg );
137 }
138
139 int main( int argc, char ** argv )
140 {
141     hb_handle_t * h;
142     int           build;
143     char        * version;
144
145     audios = hb_list_init();
146
147     /* Parse command line */
148     if( ParseOptions( argc, argv ) ||
149         CheckOptions( argc, argv ) )
150     {
151         return 1;
152     }
153
154     /* Register our error handler */
155     hb_register_error_handler(&hb_cli_error_handler);
156
157     /* Init libhb */
158     h = hb_init( debug, update );
159
160     /* Show version */
161     fprintf( stderr, "HandBrake %s (%d) - http://handbrake.fr/\n",
162              hb_get_version( h ), hb_get_build( h ) );
163
164     /* Check for update */
165     if( update )
166     {
167         if( ( build = hb_check_update( h, &version ) ) > -1 )
168         {
169             fprintf( stderr, "You are using an old version of "
170                      "HandBrake.\nLatest is %s (build %d).\n", version,
171                      build );
172         }
173         else
174         {
175             fprintf( stderr, "Your version of HandBrake is up to "
176                      "date.\n" );
177         }
178         hb_close( &h );
179         return 0;
180     }
181
182     /* Geeky */
183     fprintf( stderr, "%d CPU%s detected\n", hb_get_cpu_count(),
184              hb_get_cpu_count( h ) > 1 ? "s" : "" );
185     if( cpu )
186     {
187         fprintf( stderr, "Forcing %d CPU%s\n", cpu,
188                  cpu > 1 ? "s" : "" );
189         hb_set_cpu_count( h, cpu );
190     }
191
192     /* Exit ASAP on Ctrl-C */
193     signal( SIGINT, SigHandler );
194
195     /* Feed libhb with a DVD to scan */
196     fprintf( stderr, "Opening %s...\n", input );
197
198     if (longest_title) {
199         /*
200          * We need to scan for all the titles in order to find the longest
201          */
202         titleindex = 0;
203     }
204
205     hb_scan( h, input, titleindex, preview_count, store_previews );
206
207     /* Wait... */
208     while( !die )
209     {
210 #if !defined(SYS_BEOS)
211         fd_set         fds;
212         struct timeval tv;
213         int            ret;
214         char           buf[257];
215
216         tv.tv_sec  = 0;
217         tv.tv_usec = 100000;
218
219         FD_ZERO( &fds );
220         FD_SET( STDIN_FILENO, &fds );
221         ret = select( STDIN_FILENO + 1, &fds, NULL, NULL, &tv );
222
223         if( ret > 0 )
224         {
225             int size = 0;
226
227             while( size < 256 &&
228                    read( STDIN_FILENO, &buf[size], 1 ) > 0 )
229             {
230                 if( buf[size] == '\n' )
231                 {
232                     break;
233                 }
234                 size++;
235             }
236
237             if( size >= 256 || buf[size] == '\n' )
238             {
239                 switch( buf[0] )
240                 {
241                     case 'q':
242                         fprintf( stdout, "\nEncoding Quit by user command\n" );
243                         die = 1;
244                         break;
245                     case 'p':
246                         fprintf( stdout, "\nEncoding Paused by user command, 'r' to resume\n" );
247                         hb_pause( h );
248                         break;
249                     case 'r':
250                         hb_resume( h );
251                         break;
252                     case 'h':
253                         ShowCommands();
254                         break;
255                 }
256             }
257         }
258         hb_snooze( 200 );
259 #else
260         hb_snooze( 200 );
261 #endif
262
263         HandleEvents( h );
264     }
265
266     /* Clean up */
267     hb_close( &h );
268     if( input )  free( input );
269     if( output ) free( output );
270     if( format ) free( format );
271     if( audios )
272     {
273         while( ( audio = hb_list_item( audios, 0 ) ) )
274         {
275             hb_list_rem( audios, audio );
276             if( audio->out.name )
277             {
278                 free( audio->out.name );
279             }
280             free( audio );
281         }
282         hb_list_close( &audios );
283     }
284     if( mixdowns ) free( mixdowns );
285     if( dynamic_range_compression ) free( dynamic_range_compression );
286     if( atracks ) free( atracks );
287     if( arates ) free( arates );
288     if( abitrates ) free( abitrates );
289     if( acodecs ) free( acodecs );
290     if( anames ) free( anames );
291     if (native_language ) free (native_language );
292         if( x264opts ) free (x264opts );
293         if( x264opts2 ) free (x264opts2 );
294     if (preset_name) free (preset_name);
295
296     fprintf( stderr, "HandBrake has exited.\n" );
297
298     return 0;
299 }
300
301 static void ShowCommands()
302 {
303     fprintf( stdout, "\nCommands:\n" );
304     fprintf( stdout, " [h]elp    Show this message\n" );
305     fprintf( stdout, " [q]uit    Exit HandBrakeCLI\n" );
306     fprintf( stdout, " [p]ause   Pause encoding\n" );
307     fprintf( stdout, " [r]esume  Resume encoding\n" );
308 }
309
310 static void PrintTitleInfo( hb_title_t * title )
311 {
312     hb_chapter_t  * chapter;
313     hb_audio_config_t    * audio;
314     hb_subtitle_t * subtitle;
315     int i;
316
317     fprintf( stderr, "+ title %d:\n", title->index );
318     fprintf( stderr, "  + vts %d, ttn %d, cells %d->%d (%d blocks)\n",
319              title->vts, title->ttn, title->cell_start, title->cell_end,
320              title->block_count );
321     fprintf( stderr, "  + duration: %02d:%02d:%02d\n",
322              title->hours, title->minutes, title->seconds );
323     fprintf( stderr, "  + size: %dx%d, aspect: %.2f, %.3f fps\n",
324              title->width, title->height,
325              (float) title->aspect,
326              (float) title->rate / title->rate_base );
327     fprintf( stderr, "  + autocrop: %d/%d/%d/%d\n", title->crop[0],
328              title->crop[1], title->crop[2], title->crop[3] );
329     fprintf( stderr, "  + chapters:\n" );
330     for( i = 0; i < hb_list_count( title->list_chapter ); i++ )
331     {
332         chapter = hb_list_item( title->list_chapter, i );
333         fprintf( stderr, "    + %d: cells %d->%d, %d blocks, duration "
334                  "%02d:%02d:%02d\n", chapter->index,
335                  chapter->cell_start, chapter->cell_end,
336                  chapter->block_count, chapter->hours, chapter->minutes,
337                  chapter->seconds );
338     }
339     fprintf( stderr, "  + audio tracks:\n" );
340     for( i = 0; i < hb_list_count( title->list_audio ); i++ )
341     {
342         audio = hb_list_audio_config_item( title->list_audio, i );
343         if( ( audio->in.codec == HB_ACODEC_AC3 ) || ( audio->in.codec == HB_ACODEC_DCA) )
344         {
345             fprintf( stderr, "    + %d, %s, %dHz, %dbps\n", i + 1,
346                      audio->lang.description, audio->in.samplerate, audio->in.bitrate );
347         }
348         else
349         {
350             fprintf( stderr, "    + %d, %s\n", i + 1, audio->lang.description );
351         }
352     }
353     fprintf( stderr, "  + subtitle tracks:\n" );
354     for( i = 0; i < hb_list_count( title->list_subtitle ); i++ )
355     {
356         subtitle = hb_list_item( title->list_subtitle, i );
357         fprintf( stderr, "    + %d, %s (iso639-2: %s)\n", i + 1, subtitle->lang,
358             subtitle->iso639_2);
359     }
360
361     if(title->detected_interlacing)
362     {
363         /* Interlacing was found in half or more of the preview frames */
364         fprintf( stderr, "  + combing detected, may be interlaced or telecined\n");
365     }
366
367 }
368
369 static int HandleEvents( hb_handle_t * h )
370 {
371     hb_state_t s;
372     int tmp_num_audio_tracks;
373
374     hb_get_state( h, &s );
375     switch( s.state )
376     {
377         case HB_STATE_IDLE:
378             /* Nothing to do */
379             break;
380
381 #define p s.param.scanning
382         case HB_STATE_SCANNING:
383             /* Show what title is currently being scanned */
384             fprintf( stderr, "Scanning title %d", p.title_cur );
385             if( !titleindex )
386                 fprintf( stderr, " of %d", p.title_count );
387             fprintf( stderr, "...\n" );
388             break;
389 #undef p
390
391         case HB_STATE_SCANDONE:
392         {
393             hb_list_t  * list;
394             hb_title_t * title;
395             hb_job_t   * job;
396             int i;
397
398             /* Audio argument string parsing variables */
399             int acodec = 0;
400             int abitrate = 0;
401             int arate = 0;
402             int mixdown = HB_AMIXDOWN_DOLBYPLII;
403             double d_r_c = 0;
404             /* Audio argument string parsing variables */
405
406             list = hb_get_titles( h );
407
408             if( !hb_list_count( list ) )
409             {
410                 /* No valid title, stop right there */
411                 fprintf( stderr, "No title found.\n" );
412                 die = 1;
413                 break;
414             }
415             if( longest_title )
416             {
417                 int i;
418                 int longest_title_idx=0;
419                 int longest_title_pos=-1;
420                 int longest_title_time=0;
421                 int title_time;
422
423                 fprintf( stderr, "Searching for longest title...\n" );
424
425                 for( i = 0; i < hb_list_count( list ); i++ )
426                 {
427                     title = hb_list_item( list, i );
428                     title_time = (title->hours*60*60 ) + (title->minutes *60) + (title->seconds);
429                     fprintf( stderr, " + Title (%d) index %d has length %dsec\n",
430                              i, title->index, title_time );
431                     if( longest_title_time < title_time )
432                     {
433                         longest_title_time = title_time;
434                         longest_title_pos = i;
435                         longest_title_idx = title->index;
436                     }
437                 }
438                 if( longest_title_pos == -1 )
439                 {
440                     fprintf( stderr, "No longest title found.\n" );
441                     die = 1;
442                     break;
443                 }
444                 titleindex = longest_title_idx;
445                 fprintf( stderr, "Found longest title, setting title to %d\n",
446                          longest_title_idx);
447
448                 title = hb_list_item( list, longest_title_pos);
449             } else {
450                 title = hb_list_item( list, 0 );
451             }
452
453             if( !titleindex )
454             {
455                 /* Scan-only mode, print infos and exit */
456                 int i;
457                 for( i = 0; i < hb_list_count( list ); i++ )
458                 {
459                     title = hb_list_item( list, i );
460                     PrintTitleInfo( title );
461                 }
462                 die = 1;
463                 break;
464             }
465
466             /* Set job settings */
467             job   = title->job;
468
469             PrintTitleInfo( title );
470
471             if( chapter_start && chapter_end && !stop_at_pts && !start_at_preview )
472             {
473                 job->chapter_start = MAX( job->chapter_start,
474                                           chapter_start );
475                 job->chapter_end   = MIN( job->chapter_end,
476                                           chapter_end );
477                 job->chapter_end   = MAX( job->chapter_start,
478                                           job->chapter_end );
479             }
480
481             if (preset)
482             {
483                 fprintf( stderr, "+ Using preset: %s", preset_name);
484
485                 if (!strcmp(preset_name, "Universal"))
486                 {
487                     mux = HB_MUX_MP4;
488                     vcodec = HB_VCODEC_X264;
489                     job->vquality = 0.589999973773956;
490                     job->crf = 1;
491                     if( !atracks )
492                     {
493                         atracks = strdup("1,1");
494                     }
495                     if( !abitrates )
496                     {
497                         abitrates = strdup("160,auto");
498                     }
499                     if( !arates )
500                     {
501                         arates = strdup("48,Auto");
502                     }
503                     if( !acodecs )
504                     {
505                         acodecs = strdup("faac,ac3");
506                     }
507                     if( !mixdowns )
508                     {
509                         mixdowns = strdup("dpl2,auto");
510                     }
511                     maxWidth = 720;
512                     if( !x264opts )
513                     {
514                         x264opts = strdup("level=30:cabac=0:ref=3:mixed-refs=1:analyse=all:me=umh:no-fast-pskip=1");
515                     }
516                     pixelratio = 2;
517                     job->chapter_markers = 1;
518                 }
519
520                 if (!strcmp(preset_name, "iPod"))
521                 {
522                     mux = HB_MUX_MP4;
523                     job->ipod_atom = 1;
524                     vcodec = HB_VCODEC_X264;
525                     job->vbitrate = 700;
526                     if( !atracks )
527                     {
528                         atracks = strdup("1");
529                     }
530                     if( !abitrates )
531                     {
532                         abitrates = strdup("160");
533                     }
534                     if( !arates )
535                     {
536                         arates = strdup("48");
537                     }
538                     if( !acodecs )
539                     {
540                         acodecs = strdup("faac");
541                     }
542                     if( !mixdowns )
543                     {
544                         mixdowns = strdup("dpl2");
545                     }
546                     maxWidth = 320;
547                     if( !x264opts )
548                     {
549                         x264opts = strdup("level=30:bframes=0:cabac=0:ref=1:vbv-maxrate=768:vbv-bufsize=2000:analyse=all:me=umh:no-fast-pskip=1");
550                     }
551                     job->chapter_markers = 1;
552                 }
553
554                 if (!strcmp(preset_name, "iPhone & iPod Touch"))
555                 {
556                     mux = HB_MUX_MP4;
557                     vcodec = HB_VCODEC_X264;
558                     job->vquality = 0.589999973773956;
559                     job->crf = 1;
560                     if( !atracks )
561                     {
562                         atracks = strdup("1");
563                     }
564                     if( !abitrates )
565                     {
566                         abitrates = strdup("128");
567                     }
568                     if( !arates )
569                     {
570                         arates = strdup("48");
571                     }
572                     if( !acodecs )
573                     {
574                         acodecs = strdup("faac");
575                     }
576                     if( !mixdowns )
577                     {
578                         mixdowns = strdup("dpl2");
579                     }
580                     maxWidth = 480;
581                     if( !x264opts )
582                     {
583                         x264opts = strdup("level=30:cabac=0:ref=2:mixed-refs:analyse=all:me=umh:no-fast-pskip=1");
584                     }
585                     job->chapter_markers = 1;
586                 }
587
588                 if (!strcmp(preset_name, "AppleTV"))
589                 {
590                     mux = HB_MUX_MP4;
591                     job->largeFileSize = 1;
592                     vcodec = HB_VCODEC_X264;
593                     job->vquality = 0.589999973773956;
594                     job->crf = 1;
595                     if( !atracks )
596                     {
597                         atracks = strdup("1,1");
598                     }
599                     if( !abitrates )
600                     {
601                         abitrates = strdup("160,auto");
602                     }
603                     if( !arates )
604                     {
605                         arates = strdup("48,Auto");
606                     }
607                     if( !acodecs )
608                     {
609                         acodecs = strdup("faac,ac3");
610                     }
611                     if( !mixdowns )
612                     {
613                         mixdowns = strdup("dpl2,auto");
614                     }
615                     maxWidth = 960;
616                     if( !x264opts )
617                     {
618                         x264opts = strdup("level=30:cabac=0:ref=3:mixed-refs=1:bframes=6:weightb=1:direct=auto:no-fast-pskip=1:me=umh:subq=7:analyse=all");
619                     }
620                     pixelratio = 2;
621                     job->chapter_markers = 1;
622                 }
623
624                 if (!strcmp(preset_name, "QuickTime"))
625                 {
626                     mux = HB_MUX_MP4;
627                     vcodec = HB_VCODEC_X264;
628                     job->vbitrate = 1800;
629                     if( !atracks )
630                     {
631                         atracks = strdup("1");
632                     }
633                     if( !abitrates )
634                     {
635                         abitrates = strdup("160");
636                     }
637                     if( !arates )
638                     {
639                         arates = strdup("Auto");
640                     }
641                     if( !acodecs )
642                     {
643                         acodecs = strdup("faac");
644                     }
645                     if( !mixdowns )
646                     {
647                         mixdowns = strdup("dpl2");
648                     }
649                     if( !x264opts )
650                     {
651                         x264opts = strdup("ref=3:mixed-refs:bframes=3:weightb:direct=auto:me=umh:subme=7:analyse=all:8x8dct:trellis=1:no-fast-pskip=1:psy-rd=1,1");
652                     }
653                     pixelratio = 1;
654                     job->chapter_markers = 1;
655                     twoPass = 1;
656                     turbo_opts_enabled = 1;
657                 }
658
659                 if (!strcmp(preset_name, "AppleTV Legacy"))
660                 {
661                     mux = HB_MUX_MP4;
662                     job->largeFileSize = 1;
663                     vcodec = HB_VCODEC_X264;
664                     job->vbitrate = 2500;
665                     if( !atracks )
666                     {
667                         atracks = strdup("1,1");
668                     }
669                     if( !abitrates )
670                     {
671                         abitrates = strdup("160,auto");
672                     }
673                     if( !arates )
674                     {
675                         arates = strdup("48,Auto");
676                     }
677                     if( !acodecs )
678                     {
679                         acodecs = strdup("faac,ac3");
680                     }
681                     if( !mixdowns )
682                     {
683                         mixdowns = strdup("dpl2,auto");
684                     }
685                     if( !x264opts )
686                     {
687                         x264opts = strdup("bframes=3:ref=1:subme=5:me=umh:no-fast-pskip=1:trellis=1:cabac=0");
688                     }
689                     pixelratio = 1;
690                     job->chapter_markers = 1;
691                 }
692
693                 if (!strcmp(preset_name, "iPhone Legacy"))
694                 {
695                     mux = HB_MUX_MP4;
696                     job->ipod_atom = 1;
697                     vcodec = HB_VCODEC_X264;
698                     job->vbitrate = 960;
699                     if( !atracks )
700                     {
701                         atracks = strdup("1");
702                     }
703                     if( !abitrates )
704                     {
705                         abitrates = strdup("128");
706                     }
707                     if( !arates )
708                     {
709                         arates = strdup("48");
710                     }
711                     if( !acodecs )
712                     {
713                         acodecs = strdup("faac");
714                     }
715                     if( !mixdowns )
716                     {
717                         mixdowns = strdup("dpl2");
718                     }
719                     maxWidth = 480;
720                     if( !x264opts )
721                     {
722                         x264opts = strdup("level=30:cabac=0:ref=1:analyse=all:me=umh:no-fast-pskip=1:trellis=1");
723                     }
724                     job->chapter_markers = 1;
725                 }
726
727                 if (!strcmp(preset_name, "iPod Legacy"))
728                 {
729                     mux = HB_MUX_MP4;
730                     job->ipod_atom = 1;
731                     vcodec = HB_VCODEC_X264;
732                     job->vbitrate = 1500;
733                     if( !atracks )
734                     {
735                         atracks = strdup("1");
736                     }
737                     if( !abitrates )
738                     {
739                         abitrates = strdup("160");
740                     }
741                     if( !arates )
742                     {
743                         arates = strdup("48");
744                     }
745                     if( !acodecs )
746                     {
747                         acodecs = strdup("faac");
748                     }
749                     if( !mixdowns )
750                     {
751                         mixdowns = strdup("dpl2");
752                     }
753                     maxWidth = 640;
754                     if( !x264opts )
755                     {
756                         x264opts = strdup("level=30:bframes=0:cabac=0:ref=1:vbv-maxrate=1500:vbv-bufsize=2000:analyse=all:me=umh:no-fast-pskip=1");
757                     }
758                     job->chapter_markers = 1;
759                 }
760
761                 if (!strcmp(preset_name, "Normal"))
762                 {
763                     mux = HB_MUX_MP4;
764                     vcodec = HB_VCODEC_X264;
765                     job->vbitrate = 1500;
766                     if( !atracks )
767                     {
768                         atracks = strdup("1");
769                     }
770                     if( !abitrates )
771                     {
772                         abitrates = strdup("160");
773                     }
774                     if( !arates )
775                     {
776                         arates = strdup("Auto");
777                     }
778                     if( !acodecs )
779                     {
780                         acodecs = strdup("faac");
781                     }
782                     if( !mixdowns )
783                     {
784                         mixdowns = strdup("dpl2");
785                     }
786                     if( !x264opts )
787                     {
788                         x264opts = strdup("ref=2:bframes=2:me=umh");
789                     }
790                     pixelratio = 1;
791                     job->chapter_markers = 1;
792                     twoPass = 1;
793                     turbo_opts_enabled = 1;
794                 }
795
796                 if (!strcmp(preset_name, "Classic"))
797                 {
798                     mux = HB_MUX_MP4;
799                     job->vbitrate = 1000;
800                     if( !atracks )
801                     {
802                         atracks = strdup("1");
803                     }
804                     if( !abitrates )
805                     {
806                         abitrates = strdup("160");
807                     }
808                     if( !arates )
809                     {
810                         arates = strdup("Auto");
811                     }
812                     if( !acodecs )
813                     {
814                         acodecs = strdup("faac");
815                     }
816                     if( !mixdowns )
817                     {
818                         mixdowns = strdup("dpl2");
819                     }
820                 }
821
822                 if (!strcmp(preset_name, "Animation"))
823                 {
824                     mux = HB_MUX_MKV;
825                     vcodec = HB_VCODEC_X264;
826                     job->vbitrate = 1000;
827                     if( !atracks )
828                     {
829                         atracks = strdup("1");
830                     }
831                     if( !abitrates )
832                     {
833                         abitrates = strdup("160");
834                     }
835                     if( !arates )
836                     {
837                         arates = strdup("Auto");
838                     }
839                     if( !acodecs )
840                     {
841                         acodecs = strdup("faac");
842                     }
843                     if( !mixdowns )
844                     {
845                         mixdowns = strdup("dpl2");
846                     }
847                     if( !x264opts )
848                     {
849                         x264opts = strdup("ref=5:mixed-refs:bframes=6:weightb:direct=auto:b-pyramid:me=umh:analyse=all:8x8dct:trellis=1:nr=150:no-fast-pskip:filter=2,2:psy-rd=1,1:subme=9");
850                     }
851                     detelecine = 1;
852                     decomb = 1;
853                     pixelratio = 1;
854                     job->chapter_markers = 1;
855                     twoPass = 1;
856                     turbo_opts_enabled = 1;
857                 }
858
859                 if (!strcmp(preset_name, "Constant Quality Rate"))
860                 {
861                     mux = HB_MUX_MKV;
862                     vcodec = HB_VCODEC_X264;
863                     job->vquality = 0.600000023841858;
864                     job->crf = 1;
865                     if( !atracks )
866                     {
867                         atracks = strdup("1");
868                     }
869                     if( !abitrates )
870                     {
871                         abitrates = strdup("auto");
872                     }
873                     if( !arates )
874                     {
875                         arates = strdup("Auto");
876                     }
877                     if( !acodecs )
878                     {
879                         acodecs = strdup("ac3");
880                     }
881                     if( !mixdowns )
882                     {
883                         mixdowns = strdup("auto");
884                     }
885                     if( !x264opts )
886                     {
887                         x264opts = strdup("ref=3:mixed-refs:bframes=3:b-pyramid:weightb:filter=-2,-1:trellis=1:analyse=all:8x8dct:me=umh:subme=9:psy-rd=1,1");
888                     }
889                     pixelratio = 1;
890                     job->chapter_markers = 1;
891                 }
892
893                 if (!strcmp(preset_name, "Film"))
894                 {
895                     mux = HB_MUX_MKV;
896                     vcodec = HB_VCODEC_X264;
897                     job->vbitrate = 1800;
898                     if( !atracks )
899                     {
900                         atracks = strdup("1");
901                     }
902                     if( !abitrates )
903                     {
904                         abitrates = strdup("auto");
905                     }
906                     if( !arates )
907                     {
908                         arates = strdup("Auto");
909                     }
910                     if( !acodecs )
911                     {
912                         acodecs = strdup("ac3");
913                     }
914                     if( !mixdowns )
915                     {
916                         mixdowns = strdup("auto");
917                     }
918                     if( !x264opts )
919                     {
920                         x264opts = strdup("ref=3:mixed-refs:bframes=6:weightb:direct=auto:b-pyramid:me=umh:subme=9:analyse=all:8x8dct:trellis=1:no-fast-pskip:psy-rd=1,1");
921                     }
922                     pixelratio = 1;
923                     job->chapter_markers = 1;
924                     twoPass = 1;
925                     turbo_opts_enabled = 1;
926                 }
927
928                 if (!strcmp(preset_name, "Television"))
929                 {
930                     mux = HB_MUX_MKV;
931                     vcodec = HB_VCODEC_X264;
932                     job->vbitrate = 1300;
933                     if( !atracks )
934                     {
935                         atracks = strdup("1");
936                     }
937                     if( !abitrates )
938                     {
939                         abitrates = strdup("160");
940                     }
941                     if( !arates )
942                     {
943                         arates = strdup("Auto");
944                     }
945                     if( !acodecs )
946                     {
947                         acodecs = strdup("faac");
948                     }
949                     if( !mixdowns )
950                     {
951                         mixdowns = strdup("dpl2");
952                     }
953                     if( !x264opts )
954                     {
955                         x264opts = strdup("ref=3:mixed-refs:bframes=6:weightb:direct=auto:b-pyramid:me=umh:subme=9:analyse=all:8x8dct:trellis=1:nr=150:no-fast-pskip=1:psy-rd=1,1");
956                     }
957                     detelecine = 1;
958                     decomb = 1;
959                     pixelratio = 1;
960                     job->chapter_markers = 1;
961                     twoPass = 1;
962                     turbo_opts_enabled = 1;
963                 }
964
965                 if (!strcmp(preset_name, "PSP"))
966                 {
967                     mux = HB_MUX_MP4;
968                     job->vbitrate = 1024;
969                     if( !atracks )
970                     {
971                         atracks = strdup("1");
972                     }
973                     if( !abitrates )
974                     {
975                         abitrates = strdup("128");
976                     }
977                     if( !arates )
978                     {
979                         arates = strdup("48");
980                     }
981                     if( !acodecs )
982                     {
983                         acodecs = strdup("faac");
984                     }
985                     if( !mixdowns )
986                     {
987                         mixdowns = strdup("dpl2");
988                     }
989                     maxWidth = 368;
990                     maxHeight = 208;
991                     job->chapter_markers = 1;
992                 }
993
994                 if (!strcmp(preset_name, "PS3"))
995                 {
996                     mux = HB_MUX_MP4;
997                     vcodec = HB_VCODEC_X264;
998                     job->vbitrate = 2500;
999                     if( !atracks )
1000                     {
1001                         atracks = strdup("1");
1002                     }
1003                     if( !abitrates )
1004                     {
1005                         abitrates = strdup("160");
1006                     }
1007                     if( !arates )
1008                     {
1009                         arates = strdup("48");
1010                     }
1011                     if( !acodecs )
1012                     {
1013                         acodecs = strdup("faac");
1014                     }
1015                     if( !mixdowns )
1016                     {
1017                         mixdowns = strdup("dpl2");
1018                     }
1019                     job->crop[0] = 0;
1020                     job->crop[1] = 0;
1021                     job->crop[2] = 0;
1022                     job->crop[4] - 0;
1023                     if( !x264opts )
1024                     {
1025                         x264opts = strdup("level=41:me=umh");
1026                     }
1027                     pixelratio = 1;
1028                 }
1029
1030                 if (!strcmp(preset_name, "Xbox 360"))
1031                 {
1032                     mux = HB_MUX_MP4;
1033                     vcodec = HB_VCODEC_X264;
1034                     job->vbitrate = 2000;
1035                     if( !atracks )
1036                     {
1037                         atracks = strdup("1");
1038                     }
1039                     if( !abitrates )
1040                     {
1041                         abitrates = strdup("160");
1042                     }
1043                     if( !arates )
1044                     {
1045                         arates = strdup("48");
1046                     }
1047                     if( !acodecs )
1048                     {
1049                         acodecs = strdup("faac");
1050                     }
1051                     if( !mixdowns )
1052                     {
1053                         mixdowns = strdup("dpl2");
1054                     }
1055                     if( !x264opts )
1056                     {
1057                         x264opts = strdup("level=40:ref=2:mixed-refs:bframes=3:weightb:subme=9:direct=auto:b-pyramid:me=umh:analyse=all:no-fast-pskip:filter=-2,-1");
1058                     }
1059                     pixelratio = 1;
1060                     }
1061             }
1062
1063                         if ( chapter_markers )
1064                         {
1065                                 job->chapter_markers = chapter_markers;
1066
1067                 if( marker_file != NULL )
1068                 {
1069                     hb_csv_file_t * file = hb_open_csv_file( marker_file );
1070                     hb_csv_cell_t * cell;
1071                     int row = 0;
1072                     int chapter = 0;
1073
1074                     fprintf( stderr, "Reading chapter markers from file %s\n", marker_file );
1075
1076                     if( file == NULL )
1077                     {
1078                          fprintf( stderr, "Cannot open chapter marker file, using defaults\n" );
1079                     }
1080                     else
1081                     {
1082                         /* Parse the cells */
1083                         while( NULL != ( cell = hb_read_next_cell( file ) ) )
1084                         {
1085                             /* We have a chapter number */
1086                             if( cell->cell_col == 0 )
1087                             {
1088                                 row = cell->cell_row;
1089                                 chapter = atoi( cell->cell_text );
1090                             }
1091
1092                             /* We have a chapter name */
1093                             if( cell->cell_col == 1 && row == cell->cell_row )
1094                             {
1095                                 /* If we have a valid chapter, copy the string an terminate it */
1096                                 if( chapter >= job->chapter_start && chapter <= job->chapter_end )
1097                                 {
1098                                     hb_chapter_t * chapter_s;
1099
1100                                     chapter_s = hb_list_item( job->title->list_chapter, chapter - 1);
1101                                     strncpy(chapter_s->title, cell->cell_text, 1023);
1102                                     chapter_s->title[1023] = '\0';
1103                                 }
1104                             }
1105
1106
1107                             hb_dispose_cell( cell );
1108                         }
1109
1110                         hb_close_csv_file( file );
1111                     }
1112                 }
1113                 else
1114                 {
1115                     /* No marker file */
1116
1117                     int number_of_chapters = hb_list_count(job->title->list_chapter);
1118                     int chapter;
1119
1120                     for(chapter = 0; chapter <= number_of_chapters - 1 ; chapter++)
1121                     {
1122                         hb_chapter_t * chapter_s;
1123                         chapter_s = hb_list_item( job->title->list_chapter, chapter);
1124                         snprintf( chapter_s->title, 1023, "Chapter %i", chapter + 1 );
1125                         chapter_s->title[1023] = '\0';
1126                     }
1127                 }
1128                         }
1129
1130             if( crop[0] >= 0 && crop[1] >= 0 &&
1131                 crop[2] >= 0 && crop[3] >= 0 )
1132             {
1133                 memcpy( job->crop, crop, 4 * sizeof( int ) );
1134             }
1135
1136             job->deinterlace = deinterlace;
1137             job->grayscale   = grayscale;
1138             if (loosePixelratio)
1139             {
1140                 job->anamorphic.mode = 2;
1141                 if (modulus)
1142                 {
1143                     job->anamorphic.modulus = modulus;
1144                 }
1145                 if( par_width && par_height )
1146                 {
1147                     job->anamorphic.mode = 3;
1148                     job->anamorphic.par_width = par_width;
1149                     job->anamorphic.par_height = par_height;
1150                 }
1151             }
1152             else
1153             {
1154                 job->anamorphic.mode = pixelratio;
1155             }
1156
1157             /* Add selected filters */
1158             job->filters = hb_list_init();
1159             if( detelecine )
1160             {
1161                 hb_filter_detelecine.settings = detelecine_opt;
1162                 hb_list_add( job->filters, &hb_filter_detelecine );
1163                 
1164                 if( !vrate )
1165                 {
1166                     /* No framerate specified, so using same as source.
1167                        That means VFR, so set detelecine up to drop frames. */
1168                            job->vfr = 1;
1169                 }
1170             }
1171             if( decomb )
1172             {
1173                 hb_filter_decomb.settings = decomb_opt;
1174                 hb_list_add( job->filters, &hb_filter_decomb );
1175             }
1176             if( deinterlace )
1177             {
1178                 hb_filter_deinterlace.settings = deinterlace_opt;
1179                 hb_list_add( job->filters, &hb_filter_deinterlace );
1180             }
1181             if( deblock )
1182             {
1183                 hb_filter_deblock.settings = deblock_opt;
1184                 hb_list_add( job->filters, &hb_filter_deblock );
1185             }
1186             if( denoise )
1187             {
1188                 hb_filter_denoise.settings = denoise_opt;
1189                 hb_list_add( job->filters, &hb_filter_denoise );
1190             }
1191
1192             if( width && height )
1193             {
1194                 job->width  = width;
1195                 job->height = height;
1196             }
1197             else if( width )
1198             {
1199                 job->width = width;
1200                 hb_fix_aspect( job, HB_KEEP_WIDTH );
1201             }
1202             else if( height && !loosePixelratio)
1203             {
1204                 job->height = height;
1205                 hb_fix_aspect( job, HB_KEEP_HEIGHT );
1206             }
1207             else if( !width && !height && !pixelratio && !loosePixelratio )
1208             {
1209                 hb_fix_aspect( job, HB_KEEP_WIDTH );
1210             }
1211             else if (!width && loosePixelratio)
1212             {
1213                 /* Default to full width when one isn't specified for loose anamorphic */
1214                 job->width = title->width - job->crop[2] - job->crop[3];
1215                 /* The height will be thrown away in hb.c but calculate it anyway */
1216                 hb_fix_aspect( job, HB_KEEP_WIDTH );
1217             }
1218
1219             if( vquality >= 0.0 && ( ( vquality <= 1.0 ) || ( vcodec == HB_VCODEC_X264 ) || (vcodec == HB_VCODEC_FFMPEG) ) )
1220             {
1221                 job->vquality = vquality;
1222                 job->vbitrate = 0;
1223             }
1224             else if( vbitrate )
1225             {
1226                 job->vquality = -1.0;
1227                 job->vbitrate = vbitrate;
1228             }
1229             if( vcodec )
1230             {
1231                 job->vcodec = vcodec;
1232             }
1233             if( h264_13 )
1234             {
1235                 job->h264_level = 13;
1236             }
1237                 if( h264_30 )
1238                 {
1239                     job->h264_level = 30;
1240             }
1241             if( vrate )
1242             {
1243                 job->cfr = 1;
1244                 job->vrate = 27000000;
1245                 job->vrate_base = vrate;
1246             }
1247
1248             /* Grab audio tracks */
1249             if( atracks )
1250             {
1251                 char * token = strtok(atracks, ",");
1252                 if (token == NULL)
1253                     token = optarg;
1254                 int track_start, track_end;
1255                 while( token != NULL )
1256                 {
1257                     audio = calloc(1, sizeof(*audio));
1258                     hb_audio_config_init(audio);
1259                     if (strlen(token) >= 3)
1260                     {
1261                         if (sscanf(token, "%d-%d", &track_start, &track_end) == 2)
1262                         {
1263                             int i;
1264                             for (i = track_start - 1; i < track_end; i++)
1265                             {
1266                                 if (i != track_start - 1)
1267                                 {
1268                                     audio = calloc(1, sizeof(*audio));
1269                                     hb_audio_config_init(audio);
1270                                 }
1271                                 audio->in.track = i;
1272                                 audio->out.track = num_audio_tracks++;
1273                                 hb_list_add(audios, audio);
1274                             }
1275                         }
1276                         else if( !strcasecmp(token, "none" ) )
1277                         {
1278                             audio->in.track = audio->out.track = -1;
1279                             audio->out.codec = 0;
1280                             hb_list_add(audios, audio);
1281                             break;
1282                         }
1283                         else
1284                         {
1285                             fprintf(stderr, "ERROR: Unable to parse audio input \"%s\", skipping.",
1286                                     token);
1287                             free(audio);
1288                         }
1289                     }
1290                     else
1291                     {
1292                         audio->in.track = atoi(token) - 1;
1293                         audio->out.track = num_audio_tracks++;
1294                         hb_list_add(audios, audio);
1295                     }
1296                     token = strtok(NULL, ",");
1297                 }
1298             }
1299
1300             /* Parse audio tracks */
1301             if( hb_list_count(audios) == 0 )
1302             {
1303                 /* Create a new audio track with default settings */
1304                 audio = calloc(1, sizeof(*audio));
1305                 hb_audio_config_init(audio);
1306                 /* Add it to our audios */
1307                 hb_list_add(audios, audio);
1308             }
1309
1310             tmp_num_audio_tracks = num_audio_tracks = hb_list_count(audios);
1311             for (i = 0; i < tmp_num_audio_tracks; i++)
1312             {
1313                 audio = hb_list_item(audios, 0);
1314                 if( (audio == NULL) || (audio->in.track == -1) ||
1315                     (audio->out.track == -1) || (audio->out.codec == 0) )
1316                 {
1317                     num_audio_tracks--;
1318                 }
1319                 else
1320                 {
1321                     if( hb_audio_add( job, audio ) == 0 )
1322                     {
1323                         fprintf(stderr, "ERROR: Invalid audio input track '%u', exiting.\n", 
1324                                 audio->in.track + 1 );
1325                         num_audio_tracks--;
1326                         exit(3);
1327                     }
1328                 }
1329                 hb_list_rem(audios, audio);
1330                 if( audio != NULL)
1331                     if( audio->out.name )
1332                     {
1333                         free( audio->out.name);
1334                     }
1335                     free( audio );
1336             }
1337
1338             /* Audio Codecs */
1339             i = 0;
1340             if( acodecs )
1341             {
1342                 char * token = strtok(acodecs, ",");
1343                 if( token == NULL )
1344                     token = acodecs;
1345                 while ( token != NULL )
1346                 {
1347                     if ((acodec = get_acodec_for_string(token)) == -1)
1348                     {
1349                         fprintf(stderr, "Invalid codec %s, using default for container.\n", token);
1350                         acodec = default_acodec;
1351                     }
1352                     if( i < num_audio_tracks )
1353                     {
1354                         audio = hb_list_audio_config_item(job->list_audio, i);
1355                         audio->out.codec = acodec;
1356                     }
1357                     else
1358                     {
1359                         hb_audio_config_t * last_audio = hb_list_audio_config_item( job->list_audio, i - 1 );
1360                         hb_audio_config_t audio;
1361
1362                         if( last_audio )
1363                         {
1364                             fprintf(stderr, "More audio codecs than audio tracks, copying track %i and using encoder %s\n",
1365                                     i, token);
1366                             hb_audio_config_init(&audio);
1367                             audio.in.track = last_audio->in.track;
1368                             audio.out.track = num_audio_tracks++;
1369                             audio.out.codec = acodec;
1370                             hb_audio_add(job, &audio);
1371                         }
1372                         else
1373                         {
1374                             fprintf(stderr, "Audio codecs and no valid audio tracks, skipping codec %s\n", token);
1375                         }
1376                     }
1377                     token = strtok(NULL, ",");
1378                     i++;
1379                 }
1380             }
1381             if( i < num_audio_tracks )
1382             {
1383                 /* We have fewer inputs than audio tracks, use the default codec for
1384                  * this container for the remaining tracks. Unless we only have one input
1385                  * then use that codec instead.
1386                  */
1387                 if (i != 1)
1388                     acodec = default_acodec;
1389                 for ( ; i < num_audio_tracks; i++)
1390                 {
1391                     audio = hb_list_audio_config_item(job->list_audio, i);
1392                     audio->out.codec = acodec;
1393                 }
1394             }
1395             /* Audio Codecs */
1396
1397             /* Sample Rate */
1398             i = 0;
1399             if( arates )
1400             {
1401                 char * token = strtok(arates, ",");
1402                 if (token == NULL)
1403                     token = arates;
1404                 while ( token != NULL )
1405                 {
1406                     arate = atoi(token);
1407                     audio = hb_list_audio_config_item(job->list_audio, i);
1408                     int j;
1409
1410                     for( j = 0; j < hb_audio_rates_count; j++ )
1411                     {
1412                         if( !strcmp( token, hb_audio_rates[j].string ) )
1413                         {
1414                             arate = hb_audio_rates[j].rate;
1415                             break;
1416                         }
1417                     }
1418
1419                     if( audio != NULL )
1420                     {
1421                         if (!is_sample_rate_valid(arate))
1422                         {
1423                             fprintf(stderr, "Invalid sample rate %d, using input rate %d\n", arate, audio->in.samplerate);
1424                             arate = audio->in.samplerate;
1425                         }
1426                         
1427                         audio->out.samplerate = arate;
1428                         if( (++i) >= num_audio_tracks )
1429                             break;  /* We have more inputs than audio tracks, oops */
1430                     }
1431                     else 
1432                     {
1433                         fprintf(stderr, "Ignoring sample rate %d, no audio tracks\n", arate);
1434                     }
1435                     token = strtok(NULL, ",");
1436                 }
1437             }
1438             if (i < num_audio_tracks)
1439             {
1440                 /* We have fewer inputs than audio tracks, use default sample rate.
1441                  * Unless we only have one input, then use that for all tracks.
1442                  */
1443                 if (i != 1)
1444                     arate = audio->in.samplerate;
1445                 for ( ; i < num_audio_tracks; i++)
1446                 {
1447                     audio = hb_list_audio_config_item(job->list_audio, i);
1448                     audio->out.samplerate = arate;
1449                 }
1450             }
1451             /* Sample Rate */
1452
1453             /* Audio Bitrate */
1454             i = 0;
1455             if( abitrates )
1456             {
1457                 char * token = strtok(abitrates, ",");
1458                 if (token == NULL)
1459                     token = abitrates;
1460                 while ( token != NULL )
1461                 {
1462                     abitrate = atoi(token);
1463                     audio = hb_list_audio_config_item(job->list_audio, i);
1464
1465                     if( audio != NULL )
1466                     {
1467                         audio->out.bitrate = abitrate;
1468                         if( (++i) >= num_audio_tracks )
1469                             break;  /* We have more inputs than audio tracks, oops */
1470                     }
1471                     else 
1472                     {
1473                         fprintf(stderr, "Ignoring bitrate %d, no audio tracks\n", abitrate);
1474                     }
1475                     token = strtok(NULL, ",");
1476                 }
1477             }
1478             if (i < num_audio_tracks)
1479             {
1480                 /* We have fewer inputs than audio tracks, use the default bitrate
1481                  * for the remaining tracks. Unless we only have one input, then use
1482                  * that for all tracks.
1483                  */
1484                 if (i != 1)
1485                     abitrate = default_abitrate;
1486                 for (; i < num_audio_tracks; i++)
1487                 {
1488                     audio = hb_list_audio_config_item(job->list_audio, i);
1489                     audio->out.bitrate = abitrate;
1490                 }
1491             }
1492             /* Audio Bitrate */
1493
1494             /* Audio DRC */
1495             i = 0;
1496             if ( dynamic_range_compression )
1497             {
1498                 char * token = strtok(dynamic_range_compression, ",");
1499                 if (token == NULL)
1500                     token = dynamic_range_compression;
1501                 while ( token != NULL )
1502                 {
1503                     d_r_c = atof(token);
1504                     audio = hb_list_audio_config_item(job->list_audio, i);
1505                     if( audio != NULL )
1506                     {
1507                         audio->out.dynamic_range_compression = d_r_c;
1508                         if( (++i) >= num_audio_tracks )
1509                             break;  /* We have more inputs than audio tracks, oops */
1510                     } 
1511                     else
1512                     {
1513                         fprintf(stderr, "Ignoring drc, no audio tracks\n");
1514                     }
1515                     token = strtok(NULL, ",");
1516                 }
1517             }
1518             if (i < num_audio_tracks)
1519             {
1520                 /* We have fewer inputs than audio tracks, use no DRC for the remaining
1521                  * tracks. Unless we only have one input, then use the same DRC for all
1522                  * tracks.
1523                  */
1524                 if (i != 1)
1525                     d_r_c = 0;
1526                 for (; i < num_audio_tracks; i++)
1527                 {
1528                     audio = hb_list_audio_config_item(job->list_audio, i);
1529                     audio->out.dynamic_range_compression = d_r_c;
1530                 }
1531             }
1532             /* Audio DRC */
1533
1534             /* Audio Mixdown */
1535             i = 0;
1536             if ( mixdowns )
1537             {
1538                 char * token = strtok(mixdowns, ",");
1539                 if (token == NULL)
1540                     token = mixdowns;
1541                 while ( token != NULL )
1542                 {
1543                     mixdown = hb_mixdown_get_mixdown_from_short_name(token);
1544                     audio = hb_list_audio_config_item(job->list_audio, i);
1545                     if( audio != NULL )
1546                     {
1547                         audio->out.mixdown = mixdown;
1548                         if( (++i) >= num_audio_tracks )
1549                             break;  /* We have more inputs than audio tracks, oops */
1550                     }
1551                     else
1552                     {
1553                         fprintf(stderr, "Ignoring mixdown, no audio tracks\n");
1554                     }
1555                     token = strtok(NULL, ",");
1556                 }
1557             }
1558             if (i < num_audio_tracks)
1559             {
1560                 /* We have fewer inputs than audio tracks, use DPLII for the rest. Unless
1561                  * we only have one input, then use that.
1562                  */
1563                 if (i != 1)
1564                     mixdown = HB_AMIXDOWN_DOLBYPLII;
1565                 for (; i < num_audio_tracks; i++)
1566                 {
1567                    audio = hb_list_audio_config_item(job->list_audio, i);
1568                    audio->out.mixdown = mixdown;
1569                 }
1570             }
1571             /* Audio Mixdown */
1572
1573             /* Audio Track Names */
1574             i = 0;
1575             if ( anames )
1576             {
1577                 char * token = strtok(anames, ",");
1578                 if (token == NULL)
1579                     token = anames;
1580                 while ( token != NULL )
1581                 {
1582                     audio = hb_list_audio_config_item(job->list_audio, i);
1583                     if( audio != NULL )
1584                     {
1585                         audio->out.name = strdup(token);
1586                         if( (++i) >= num_audio_tracks )
1587                             break;  /* We have more names than audio tracks, oops */
1588                     }
1589                     else
1590                     {
1591                         fprintf(stderr, "Ignoring aname '%s', no audio track\n",
1592                                 token);
1593                     }
1594                     token = strtok(NULL, ",");
1595                 }
1596             }
1597             if( i < num_audio_tracks && i == 1 )
1598             {
1599                 /* We have exactly one name and more than one audio track. Use the same
1600                  * name for all tracks. */
1601                 for ( ; i < num_audio_tracks; i++)
1602                 {
1603                     audio = hb_list_audio_config_item(job->list_audio, i);
1604                     audio->out.name = strdup(anames);
1605                 }
1606             }
1607             /* Audio Track Names */
1608
1609             if( size )
1610             {
1611                 job->vbitrate = hb_calc_bitrate( job, size );
1612                 fprintf( stderr, "Calculated bitrate: %d kbps\n",
1613                          job->vbitrate );
1614             }
1615
1616             if( sub )
1617             {
1618                 job->subtitle = sub - 1;
1619             }
1620
1621             if( native_language )
1622             {
1623                 job->native_language = strdup( native_language );
1624             }
1625
1626             if( job->mux )
1627             {
1628                 job->mux = mux;
1629             }
1630
1631             if ( largeFileSize )
1632             {
1633                 job->largeFileSize = 1;
1634             }
1635             if ( mp4_optimize )
1636             {
1637                 job->mp4_optimize = 1;
1638             }
1639             if ( ipod_atom )
1640             {
1641                 job->ipod_atom = 1;
1642             }
1643
1644             job->file = strdup( output );
1645
1646             if( crf )
1647             {
1648                 job->crf = 1;
1649             }
1650             
1651             if( color_matrix )
1652             {
1653                 job->color_matrix = color_matrix;
1654             }
1655
1656             if( x264opts != NULL && *x264opts != '\0' )
1657             {
1658                 job->x264opts = x264opts;
1659             }
1660             else /*avoids a bus error crash when options aren't specified*/
1661             {
1662                 job->x264opts =  NULL;
1663             }
1664             if (maxWidth)
1665                 job->maxWidth = maxWidth;
1666             if (maxHeight)
1667                 job->maxHeight = maxHeight;
1668
1669             if( subtitle_force )
1670             {
1671                 job->subtitle_force = subtitle_force;
1672             }
1673
1674             if( start_at_preview )
1675             {
1676                 job->start_at_preview = start_at_preview - 1;
1677                 job->seek_points = preview_count;
1678             }
1679             
1680             if( stop_at_pts )
1681             {
1682                 job->pts_to_stop = stop_at_pts;
1683                 subtitle_scan = 0;
1684             }
1685             
1686             if( subtitle_scan )
1687             {
1688                 char *x264opts_tmp;
1689
1690                 /*
1691                  * When subtitle scan is enabled do a fast pre-scan job
1692                  * which will determine which subtitles to enable, if any.
1693                  */
1694                 job->pass = -1;
1695
1696                 x264opts_tmp = job->x264opts;
1697
1698                 job->x264opts = NULL;
1699
1700                 job->indepth_scan = subtitle_scan;
1701                 fprintf( stderr, "Subtitle Scan Enabled - enabling "
1702                          "subtitles if found for foreign language segments\n");
1703                 job->select_subtitle = malloc(sizeof(hb_subtitle_t*));
1704                 *(job->select_subtitle) = NULL;
1705
1706                 /*
1707                  * Add the pre-scan job
1708                  */
1709                 hb_add( h, job );
1710
1711                 job->x264opts = x264opts_tmp;
1712             }
1713
1714             if( twoPass )
1715             {
1716                 /*
1717                  * If subtitle_scan is enabled then only turn it on
1718                  * for the first pass and then off again for the
1719                  * second.
1720                  */
1721                 hb_subtitle_t **subtitle_tmp = job->select_subtitle;
1722
1723                 job->select_subtitle = NULL;
1724
1725                 job->pass = 1;
1726
1727                 job->indepth_scan = 0;
1728
1729                 if (x264opts)
1730                 {
1731                     x264opts2 = strdup(x264opts);
1732                 }
1733
1734                 /*
1735                  * If turbo options have been selected then append them
1736                  * to the x264opts now (size includes one ':' and the '\0')
1737                  */
1738                 if( turbo_opts_enabled )
1739                 {
1740                     int size = (x264opts ? strlen(x264opts) : 0) + strlen(turbo_opts) + 2;
1741                     char *tmp_x264opts;
1742
1743                     tmp_x264opts = malloc(size * sizeof(char));
1744                     if( x264opts )
1745                     {
1746                         snprintf( tmp_x264opts, size, "%s:%s",
1747                                   x264opts, turbo_opts );
1748                         free( x264opts );
1749                     } else {
1750                         /*
1751                          * No x264opts to modify, but apply the turbo options
1752                          * anyway as they may be modifying defaults
1753                          */
1754                         snprintf( tmp_x264opts, size, "%s",
1755                                   turbo_opts );
1756                     }
1757                     x264opts = tmp_x264opts;
1758
1759                     fprintf( stderr, "Modified x264 options for pass 1 to append turbo options: %s\n",
1760                              x264opts );
1761
1762                     job->x264opts = x264opts;
1763                 }
1764                 hb_add( h, job );
1765
1766                 job->select_subtitle = subtitle_tmp;
1767
1768                 job->pass = 2;
1769                 /*
1770                  * On the second pass we turn off subtitle scan so that we
1771                  * can actually encode using any subtitles that were auto
1772                  * selected in the first pass (using the whacky select-subtitle
1773                  * attribute of the job).
1774                  */
1775                 job->indepth_scan = 0;
1776
1777                 job->x264opts = x264opts2;
1778
1779                 hb_add( h, job );
1780             }
1781             else
1782             {
1783                 /*
1784                  * Turn on subtitle scan if requested, note that this option
1785                  * precludes encoding of any actual subtitles.
1786                  */
1787
1788                 job->indepth_scan = 0;
1789                 job->pass = 0;
1790                 hb_add( h, job );
1791             }
1792             hb_start( h );
1793             break;
1794         }
1795
1796 #define p s.param.working
1797         case HB_STATE_WORKING:
1798             fprintf( stdout, "\rEncoding: task %d of %d, %.2f %%",
1799                      p.job_cur, p.job_count, 100.0 * p.progress );
1800             if( p.seconds > -1 )
1801             {
1802                 fprintf( stdout, " (%.2f fps, avg %.2f fps, ETA "
1803                          "%02dh%02dm%02ds)", p.rate_cur, p.rate_avg,
1804                          p.hours, p.minutes, p.seconds );
1805             }
1806             fflush(stdout);
1807             break;
1808 #undef p
1809
1810 #define p s.param.muxing
1811         case HB_STATE_MUXING:
1812         {
1813             if (show_mux_warning)
1814             {
1815                 fprintf( stdout, "\rMuxing: this may take awhile..." );
1816                 fflush(stdout);
1817                 show_mux_warning = 0;
1818             }
1819             break;
1820         }
1821 #undef p
1822
1823 #define p s.param.workdone
1824         case HB_STATE_WORKDONE:
1825             /* Print error if any, then exit */
1826             switch( p.error )
1827             {
1828                 case HB_ERROR_NONE:
1829                     fprintf( stderr, "\nRip done!\n" );
1830                     break;
1831                 case HB_ERROR_CANCELED:
1832                     fprintf( stderr, "\nRip canceled.\n" );
1833                     break;
1834                 default:
1835                     fprintf( stderr, "\nRip failed (error %x).\n",
1836                              p.error );
1837             }
1838             die = 1;
1839             break;
1840 #undef p
1841     }
1842     return 0;
1843 }
1844
1845 /****************************************************************************
1846  * SigHandler:
1847  ****************************************************************************/
1848 static volatile int64_t i_die_date = 0;
1849 void SigHandler( int i_signal )
1850 {
1851     if( die == 0 )
1852     {
1853         die = 1;
1854         i_die_date = hb_get_date();
1855         fprintf( stderr, "Signal %d received, terminating - do it "
1856                  "again in case it gets stuck\n", i_signal );
1857     }
1858     else if( i_die_date + 500 < hb_get_date() )
1859     {
1860         fprintf( stderr, "Dying badly, files might remain in your /tmp\n" );
1861         exit( 1 );
1862     }
1863 }
1864
1865 /****************************************************************************
1866  * ShowHelp:
1867  ****************************************************************************/
1868 static void ShowHelp()
1869 {
1870     int i;
1871
1872     fprintf( stderr,
1873     "Syntax: HandBrakeCLI [options] -i <device> -o <file>\n"
1874     "\n"
1875     "### General Handbrake Options------------------------------------------------\n\n"
1876     "    -h, --help              Print help\n"
1877     "    -u, --update            Check for updates and exit\n"
1878     "    -v, --verbose <#>       Be verbose (optional argument: logging level)\n"
1879     "    -C, --cpu               Set CPU count (default: autodetected)\n"
1880     "    -Z. --preset <string>   Use a built-in preset. Capitalization matters, and\n"
1881     "                            if the preset name has spaces, surround it with\n"
1882     "                            double quotation marks\n"
1883     "    -z, --preset-list       See a list of available built-in presets\n"
1884     "\n"
1885
1886     "### Source Options-----------------------------------------------------------\n\n"
1887     "    -i, --input <string>    Set input device\n"
1888     "    -t, --title <number>    Select a title to encode (0 to scan only,\n"
1889     "                            default: 1)\n"
1890     "    -L, --longest           Select the longest title\n"
1891     "    -c, --chapters <string> Select chapters (e.g. \"1-3\" for chapters\n"
1892     "                            1 to 3, or \"3\" for chapter 3 only,\n"
1893     "                            default: all chapters)\n"
1894     "        --previews <#:B>    Select how many preview images are generated (max 30),\n"
1895     "                            and whether or not they're stored to disk (0 or 1).\n"
1896     "                            (default: 10:0)\n"
1897     "    --start-at-preview <#>  Start encoding at a given preview.\n"
1898     "    --stop-at-duration <#>  Stop encoding after a given duration in seconds.\n"
1899     "    --stop-at-pts      <#>  Stop encoding at a given timestamp (90,000Hz clock).\n"
1900     "      (--stop-at-pts and --stop-at-duration are mutually exclusive options)\n"
1901     "\n"
1902
1903     "### Destination Options------------------------------------------------------\n\n"
1904     "    -o, --output <string>   Set output file name\n"
1905     "    -f, --format <string>   Set output format (avi/mp4/ogm/mkv, default:\n"
1906     "                            autodetected from file name)\n"
1907     "    -m, --markers           Add chapter markers (mp4 and mkv output formats only)\n"
1908     "    -4, --large-file        Use 64-bit mp4 files that can hold more than\n"
1909     "                            4 GB. Note: Breaks iPod, PS3 compatibility.\n"""
1910     "    -O, --optimize          Optimize mp4 files for HTTP streaming\n"
1911     "    -I, --ipod-atom         Mark mp4 files so 5.5G iPods will accept them\n"
1912     "\n"
1913
1914
1915     "### Video Options------------------------------------------------------------\n\n"
1916     "    -e, --encoder <string>  Set video library encoder (ffmpeg,xvid,\n"
1917     "                            x264,theora default: ffmpeg)\n"
1918     "    -x, --x264opts <string> Specify advanced x264 options in the\n"
1919     "                            same style as mencoder:\n"
1920     "                            option1=value1:option2=value2\n"
1921     "    -q, --quality <float>   Set video quality (0.0..1.0)\n"
1922     "    -Q, --cqp               Use with -q for CQP instead of CRF\n"
1923     "    -S, --size <MB>         Set target size\n"
1924     "    -b, --vb <kb/s>         Set video bitrate (default: 1000)\n"
1925     "    -2, --two-pass          Use two-pass mode\n"
1926     "    -T, --turbo             When using 2-pass use the turbo options\n"
1927     "                            on the first pass to improve speed\n"
1928     "                            (only works with x264, affects PSNR by about 0.05dB,\n"
1929     "                            and increases first pass speed two to four times)\n"
1930     "    -r, --rate              Set video framerate (" );
1931     for( i = 0; i < hb_video_rates_count; i++ )
1932     {
1933         fprintf( stderr, hb_video_rates[i].string );
1934         if( i != hb_video_rates_count - 1 )
1935             fprintf( stderr, "/" );
1936     }
1937     fprintf( stderr, ")\n"
1938     "                            Be aware that not specifying a framerate lets\n"
1939     "                            HandBrake preserve a source's time stamps,\n"
1940     "                            potentially creating variable framerate video\n"
1941
1942     "\n"
1943     "### Audio Options-----------------------------------------------------------\n\n"
1944     "    -a, --audio <string>    Select audio track(s), separated by commas\n"
1945     "                            More than one output track can be used for one\n"
1946     "                            input.\n"
1947     "                            (\"none\" for no audio, \"1,2,3\" for multiple\n"
1948     "                             tracks, default: first one)\n"
1949     "    -E, --aencoder <string> Audio encoder(s) (faac/lame/vorbis/ac3) \n"
1950     "                            ac3 meaning passthrough\n"
1951     "                            Separated by commas for more than one audio track.\n"
1952     "                            (default: guessed)\n"
1953     "    -B, --ab <kb/s>         Set audio bitrate(s)  (default: 160)\n"
1954     "                            Separated by commas for more than one audio track.\n"
1955     "    -6, --mixdown <string>  Format(s) for surround sound downmixing\n"
1956     "                            Separated by commas for more than one audio track.\n"
1957     "                            (mono/stereo/dpl1/dpl2/6ch, default: dpl2)\n"
1958     "    -R, --arate             Set audio samplerate(s) (" );
1959     for( i = 0; i < hb_audio_rates_count; i++ )
1960     {
1961         fprintf( stderr, hb_audio_rates[i].string );
1962         if( i != hb_audio_rates_count - 1 )
1963             fprintf( stderr, "/" );
1964     }
1965     fprintf( stderr, " kHz)\n"
1966     "                            Separated by commas for more than one audio track.\n"
1967     "    -D, --drc <float>       Apply extra dynamic range compression to the audio,\n"
1968     "                            making soft sounds louder. Range is 1.0 to 4.0\n"
1969     "                            (too loud), with 1.5 - 2.5 being a useful range.\n"
1970     "                            Separated by commas for more than one audio track.\n"
1971     "    -A, --aname <string>    Audio track name(s),\n"
1972     "                            Separated by commas for more than one audio track.\n"
1973     "\n"
1974
1975     "### Picture Settings---------------------------------------------------------\n\n"
1976     "    -w, --width <number>    Set picture width\n"
1977     "    -l, --height <number>   Set picture height\n"
1978     "        --crop <T:B:L:R>    Set cropping values (default: autocrop)\n"
1979     "    -Y, --maxHeight <#>     Set maximum height\n"
1980     "    -X, --maxWidth <#>      Set maximum width\n"
1981     "    -p, --pixelratio        Store pixel aspect ratio in video stream\n"
1982     "    -P, --loosePixelratio   Store pixel aspect ratio with specified width\n"
1983     "          <MOD:PARX:PARY>   Takes as optional arguments what number you want\n"
1984     "                            the dimensions to divide cleanly by (default 16)\n"
1985     "                            and the pixel ratio to use (default autodetected)\n"
1986     "    -M  --color-matrix      Set the color space signaled by the output\n"
1987     "          <601 or 709>      (Bt.601 is mostly for SD content, Bt.709 for HD,\n"
1988     "                             default: set by resolution)\n"
1989     "\n"
1990
1991     "### Filters---------------------------------------------------------\n\n"
1992
1993      "    -d, --deinterlace       Deinterlace video with yadif/mcdeint filter\n"
1994      "          <YM:FD:MM:QP>     (default 0:-1:-1:1)\n"
1995      "           or\n"
1996      "          <fast/slow/slower>\n"
1997      "    -5, --decomb            Selectively deinterlaces when it detects combing\n"
1998      "          <MO:ME:MT:ST:BT:BX:BY>     (default: 1:2:6:9:80:16:16)\n"
1999      "    -9, --detelecine        Detelecine (ivtc) video with pullup filter\n"
2000      "                            Note: this filter drops duplicate frames to\n"
2001      "                            restore the pre-telecine framerate, unless you\n"
2002      "                            specify a constant framerate (--rate 29.97)\n"
2003      "          <L:R:T:B:SB:MP>   (default 1:1:4:4:0:0)\n"
2004      "    -8, --denoise           Denoise video with hqdn3d filter\n"
2005      "          <SL:SC:TL:TC>     (default 4:3:6:4.5)\n"
2006      "           or\n"
2007      "          <weak/medium/strong>\n"
2008      "    -7, --deblock           Deblock video with pp7 filter\n"
2009      "          <QP:M>            (default 5:2)\n"
2010     "    -g, --grayscale         Grayscale encoding\n"
2011     "\n"
2012
2013     "### Subtitle Options------------------------------------------------------------\n\n"
2014     "    -s, --subtitle <number> Select subtitle (default: none)\n"
2015     "    -U, --subtitle-scan     Scan for subtitles in an extra 1st pass, and choose\n"
2016     "                            the one that's only used 10 percent of the time\n"
2017     "                            or less. This should locate subtitles for short\n"
2018     "                            foreign language segments. Best used in conjunction\n"
2019     "                            with --subtitle-forced.\n"
2020     "    -F, --subtitle-forced   Only display subtitles from the selected stream if\n"
2021     "                            the subtitle has the forced flag set. May be used in\n"
2022     "                            conjunction with --subtitle-scan to auto-select\n"
2023     "                            a stream if it contains forced subtitles.\n"
2024     "    -N, --native-language   Select subtitles with this language if it does not\n"
2025     "          <string>          match the Audio language. Provide the language's\n"
2026     "                            iso639-2 code (fre, eng, spa, dut, et cetera)\n"
2027
2028
2029     "\n"
2030
2031
2032     );
2033 }
2034
2035 /****************************************************************************
2036  * ShowPresets:
2037  ****************************************************************************/
2038 static void ShowPresets()
2039 {
2040     printf("\n< Apple\n");
2041
2042     printf("\n   + Universal:  -e x264  -q 0.589999973773956 -a 1,1 -E faac,ac3 -B 160,auto -R 48,Auto -6 dpl2,auto -f mp4 -X 720 -P -m -x level=30:cabac=0:ref=3:mixed-refs=1:analyse=all:me=umh:no-fast-pskip=1\n");
2043
2044     printf("\n   + iPod:  -e x264  -b 700 -a 1 -E faac -B 160 -R 48 -6 dpl2 -f mp4 -I -X 320 -m -x level=30:bframes=0:cabac=0:ref=1:vbv-maxrate=768:vbv-bufsize=2000:analyse=all:me=umh:no-fast-pskip=1\n");
2045
2046     printf("\n   + iPhone & iPod Touch:  -e x264  -q 0.589999973773956 -a 1 -E faac -B 128 -R 48 -6 dpl2 -f mp4 -X 480 -m -x level=30:cabac=0:ref=2:mixed-refs:analyse=all:me=umh:no-fast-pskip=1\n");
2047
2048     printf("\n   + AppleTV:  -e x264  -q 0.589999973773956 -a 1,1 -E faac,ac3 -B 160,auto -R 48,Auto -6 dpl2,auto -f mp4 -4 -X 960 -P -m -x level=30:cabac=0:ref=3:mixed-refs=1:bframes=6:weightb=1:direct=auto:no-fast-pskip=1:me=umh:subq=7:analyse=all\n");
2049
2050     printf("\n   + QuickTime:  -e x264  -b 1800 -a 1 -E faac -B 160 -R Auto -6 dpl2 -f mp4 -p -m -2 -T -x ref=3:mixed-refs:bframes=3:weightb:direct=auto:me=umh:subme=7:analyse=all:8x8dct:trellis=1:no-fast-pskip=1:psy-rd=1,1\n");
2051
2052     printf("\n   << Legacy\n");
2053
2054     printf("\n      + AppleTV Legacy:  -e x264  -b 2500 -a 1,1 -E faac,ac3 -B 160,auto -R 48,Auto -6 dpl2,auto -f mp4 -4 -p -m -x bframes=3:ref=1:subme=5:me=umh:no-fast-pskip=1:trellis=1:cabac=0\n");
2055
2056     printf("\n      + iPhone Legacy:  -e x264  -b 960 -a 1 -E faac -B 128 -R 48 -6 dpl2 -f mp4 -I -X 480 -m -x level=30:cabac=0:ref=1:analyse=all:me=umh:no-fast-pskip=1:trellis=1\n");
2057
2058     printf("\n      + iPod Legacy:  -e x264  -b 1500 -a 1 -E faac -B 160 -R 48 -6 dpl2 -f mp4 -I -X 640 -m -x level=30:bframes=0:cabac=0:ref=1:vbv-maxrate=1500:vbv-bufsize=2000:analyse=all:me=umh:no-fast-pskip=1\n");
2059
2060     printf("\n   >>\n");
2061
2062     printf("\n>\n");
2063
2064     printf("\n< Basic\n");
2065
2066     printf("\n   + Normal:  -e x264  -b 1500 -a 1 -E faac -B 160 -R Auto -6 dpl2 -f mp4 -p -m -2 -T -x ref=2:bframes=2:me=umh\n");
2067
2068     printf("\n   + Classic:  -b 1000 -a 1 -E faac -B 160 -R Auto -6 dpl2 -f mp4\n");
2069
2070     printf("\n>\n");
2071
2072     printf("\n< High Profile\n");
2073
2074     printf("\n   + Animation:  -e x264  -b 1000 -a 1 -E faac -B 160 -R Auto -6 dpl2 -f mkv --detelecine --decomb -p -m -2 -T -x ref=5:mixed-refs:bframes=6:weightb:direct=auto:b-pyramid:me=umh:analyse=all:8x8dct:trellis=1:nr=150:no-fast-pskip:filter=2,2:psy-rd=1,1:subme=9\n");
2075
2076     printf("\n   + Constant Quality Rate:  -e x264  -q 0.600000023841858 -a 1 -E ac3 -B 160 -R Auto -6 auto -f mkv -p -m -x ref=3:mixed-refs:bframes=3:b-pyramid:weightb:filter=-2,-1:trellis=1:analyse=all:8x8dct:me=umh:subme=9:psy-rd=1,1\n");
2077
2078     printf("\n   + Film:  -e x264  -b 1800 -a 1 -E ac3 -B 160 -R Auto -6 auto -f mkv -p -m -2 -T -x ref=3:mixed-refs:bframes=6:weightb:direct=auto:b-pyramid:me=umh:subme=9:analyse=all:8x8dct:trellis=1:no-fast-pskip:psy-rd=1,1\n");
2079
2080     printf("\n   + Television:  -e x264  -b 1300 -a 1 -E faac -B 160 -R Auto -6 dpl2 -f mkv --detelecine --decomb -p -m -2 -T -x ref=3:mixed-refs:bframes=6:weightb:direct=auto:b-pyramid:me=umh:subme=9:analyse=all:8x8dct:trellis=1:nr=150:no-fast-pskip=1:psy-rd=1,1\n");
2081
2082     printf("\n>\n");
2083
2084     printf("\n< Gaming Consoles\n");
2085
2086     printf("\n   + PSP:  -b 1024 -a 1 -E faac -B 128 -R 48 -6 dpl2 -f mp4 -X 368 -Y 208 -m\n");
2087
2088     printf("\n   + PS3:  -e x264  -b 2500 -a 1 -E faac -B 160 -R 48 -6 dpl2 -f mp4 --crop 0:0:0:0 -p -x level=41:me=umh\n");
2089
2090     printf("\n   + Xbox 360:  -e x264  -b 2000 -a 1 -E faac -B 160 -R 48 -6 dpl2 -f mp4 -p -x level=40:ref=2:mixed-refs:bframes=3:weightb:subme=9:direct=auto:b-pyramid:me=umh:analyse=all:no-fast-pskip:filter=-2,-1\n");
2091
2092     printf("\n>\n");
2093
2094 }
2095
2096 /****************************************************************************
2097  * ParseOptions:
2098  ****************************************************************************/
2099 static int ParseOptions( int argc, char ** argv )
2100 {
2101     
2102     #define PREVIEWS 257
2103     #define START_AT_PREVIEW 258
2104     #define STOP_AT_PTS 259
2105     #define STOP_AT_DURATION 260
2106     
2107     for( ;; )
2108     {
2109         static struct option long_options[] =
2110           {
2111             { "help",        no_argument,       NULL,    'h' },
2112             { "update",      no_argument,       NULL,    'u' },
2113             { "verbose",     optional_argument, NULL,    'v' },
2114             { "cpu",         required_argument, NULL,    'C' },
2115
2116             { "format",      required_argument, NULL,    'f' },
2117             { "input",       required_argument, NULL,    'i' },
2118             { "output",      required_argument, NULL,    'o' },
2119             { "large-file",  no_argument,       NULL,    '4' },
2120             { "optimize",    no_argument,       NULL,    'O' },
2121             { "ipod-atom",   no_argument,       NULL,    'I' },
2122
2123             { "title",       required_argument, NULL,    't' },
2124             { "longest",     no_argument,       NULL,    'L' },
2125             { "chapters",    required_argument, NULL,    'c' },
2126             { "markers",     optional_argument, NULL,    'm' },
2127             { "audio",       required_argument, NULL,    'a' },
2128             { "mixdown",     required_argument, NULL,    '6' },
2129             { "drc",         required_argument, NULL,    'D' },
2130             { "subtitle",    required_argument, NULL,    's' },
2131             { "subtitle-scan", no_argument,     NULL,    'U' },
2132             { "subtitle-forced", no_argument,   NULL,    'F' },
2133             { "native-language", required_argument, NULL,'N' },
2134
2135             { "encoder",     required_argument, NULL,    'e' },
2136             { "aencoder",    required_argument, NULL,    'E' },
2137             { "two-pass",    no_argument,       NULL,    '2' },
2138             { "deinterlace", optional_argument, NULL,    'd' },
2139             { "deblock",     optional_argument, NULL,    '7' },
2140             { "denoise",     optional_argument, NULL,    '8' },
2141             { "detelecine",  optional_argument, NULL,    '9' },
2142             { "decomb",      optional_argument, NULL,    '5' },
2143             { "grayscale",   no_argument,       NULL,    'g' },
2144             { "pixelratio",  no_argument,       NULL,    'p' },
2145             { "loosePixelratio", optional_argument,   NULL,    'P' },
2146             { "width",       required_argument, NULL,    'w' },
2147             { "height",      required_argument, NULL,    'l' },
2148             { "crop",        required_argument, NULL,    'n' },
2149
2150             { "vb",          required_argument, NULL,    'b' },
2151             { "quality",     required_argument, NULL,    'q' },
2152             { "size",        required_argument, NULL,    'S' },
2153             { "ab",          required_argument, NULL,    'B' },
2154             { "rate",        required_argument, NULL,    'r' },
2155             { "arate",       required_argument, NULL,    'R' },
2156             { "cqp",         no_argument,       NULL,    'Q' },
2157             { "x264opts",    required_argument, NULL,    'x' },
2158             { "turbo",       no_argument,       NULL,    'T' },
2159             { "maxHeight",   required_argument, NULL,    'Y' },
2160             { "maxWidth",    required_argument, NULL,    'X' },
2161             { "preset",      required_argument, NULL,    'Z' },
2162             { "preset-list", no_argument,       NULL,    'z' },
2163
2164             { "aname",       required_argument, NULL,    'A' },
2165             { "color-matrix",required_argument, NULL,    'M' },
2166             { "previews",    required_argument, NULL,    PREVIEWS },
2167             { "start-at-preview", required_argument, NULL, START_AT_PREVIEW },
2168             { "stop-at-pts", required_argument, NULL,    STOP_AT_PTS },
2169             { "stop-at-duration", required_argument, NULL, STOP_AT_DURATION },
2170
2171             { 0, 0, 0, 0 }
2172           };
2173
2174         int option_index = 0;
2175         int c;
2176
2177                 c = getopt_long( argc, argv,
2178                                                  "hv::uC:f:4i:Io:t:Lc:m::M:a:A:6:s:UFN:e:E:2dD:7895gpOP::w:l:n:b:q:S:B:r:R:Qx:TY:X:Z:z",
2179                          long_options, &option_index );
2180         if( c < 0 )
2181         {
2182             break;
2183         }
2184
2185         switch( c )
2186         {
2187             case 'h':
2188                 ShowHelp();
2189                 exit( 0 );
2190             case 'u':
2191                 update = 1;
2192                 break;
2193             case 'v':
2194                 if( optarg != NULL )
2195                 {
2196                     debug = atoi( optarg );
2197                 }
2198                 else
2199                 {
2200                     debug = 1;
2201                 }
2202                 break;
2203             case 'C':
2204                 cpu = atoi( optarg );
2205                 break;
2206
2207             case 'Z':
2208                 preset = 1;
2209                 preset_name = strdup(optarg);
2210                 break;
2211             case 'z':
2212                 ShowPresets();
2213                 exit ( 0 );
2214
2215             case 'f':
2216                 format = strdup( optarg );
2217                 break;
2218             case 'i':
2219                 input = strdup( optarg );
2220                 #ifdef __APPLE_CC__
2221                 char *devName = bsd_name_for_path( input );
2222                 if( devName == NULL )
2223                 {
2224                     break;
2225                 }
2226                 if( device_is_dvd( devName ) )
2227                 {
2228                     char *newInput = malloc( strlen("/dev/") + strlen( devName ) + 1);
2229                     sprintf( newInput, "/dev/%s", devName );
2230                     free(input);
2231                     input = newInput;
2232                 }
2233                 #endif
2234                 break;
2235             case 'o':
2236                 output = strdup( optarg );
2237                 break;
2238             case '4':
2239                 largeFileSize = 1;
2240                 break;
2241             case 'O':
2242                 mp4_optimize = 1;
2243                 break;
2244             case 'I':
2245                 ipod_atom = 1;
2246                 break;
2247
2248             case 't':
2249                 titleindex = atoi( optarg );
2250                 break;
2251             case 'L':
2252                 longest_title = 1;
2253                 break;
2254             case 'c':
2255             {
2256                 int start, end;
2257                 if( sscanf( optarg, "%d-%d", &start, &end ) == 2 )
2258                 {
2259                     chapter_start = start;
2260                     chapter_end   = end;
2261                 }
2262                 else if( sscanf( optarg, "%d", &start ) == 1 )
2263                 {
2264                     chapter_start = start;
2265                     chapter_end   = chapter_start;
2266                 }
2267                 else
2268                 {
2269                     fprintf( stderr, "chapters: invalid syntax (%s)\n",
2270                              optarg );
2271                     return -1;
2272                 }
2273                 break;
2274             }
2275             case 'm':
2276                 if( optarg != NULL )
2277                 {
2278                     marker_file = strdup( optarg );
2279                 }
2280                 chapter_markers = 1;
2281                 break;
2282             case 'a':
2283                 if( optarg != NULL )
2284                 {
2285                     atracks = strdup( optarg );
2286                 }
2287                 else
2288                 {
2289                     atracks = "1" ;
2290                 }
2291                 break;
2292             case '6':
2293                 if( optarg != NULL )
2294                 {
2295                     mixdowns = strdup( optarg );
2296                 }
2297                 break;
2298             case 'D':
2299                 if( optarg != NULL )
2300                 {
2301                     dynamic_range_compression = strdup( optarg );
2302                 }
2303                 break;
2304             case 's':
2305                 sub = atoi( optarg );
2306                 break;
2307             case 'U':
2308                 subtitle_scan = 1;
2309                 break;
2310             case 'F':
2311                 subtitle_force = 1;
2312                 break;
2313             case 'N':
2314                 native_language = strdup( optarg );
2315                 break;
2316             case '2':
2317                 twoPass = 1;
2318                 break;
2319             case 'd':
2320                 if( optarg != NULL )
2321                 {
2322                     if (!( strcmp( optarg, "fast" ) ))
2323                     {
2324                         deinterlace_opt = "-1";
2325                     }
2326                     else if (!( strcmp( optarg, "slow" ) ))
2327                     {
2328                         deinterlace_opt = "2";
2329                     }
2330                     else if (!( strcmp( optarg, "slower" ) ))
2331                     {
2332                         deinterlace_opt = "0";
2333                     }
2334                     else
2335                     {
2336                         deinterlace_opt = strdup( optarg );
2337                     }
2338                 }
2339                 deinterlace = 1;
2340                 break;
2341             case '7':
2342                 if( optarg != NULL )
2343                 {
2344                     deblock_opt = strdup( optarg );
2345                 }
2346                 deblock = 1;
2347                 break;
2348             case '8':
2349                 if( optarg != NULL )
2350                 {
2351                     if (!( strcmp( optarg, "weak" ) ))
2352                     {
2353                         denoise_opt = "2:1:2:3";
2354                     }
2355                     else if (!( strcmp( optarg, "medium" ) ))
2356                     {
2357                         denoise_opt = "3:2:2:3";
2358                     }
2359                     else if (!( strcmp( optarg, "strong" ) ))
2360                     {
2361                         denoise_opt = "7:7:5:5";
2362                     }
2363                     else
2364                     {
2365                         denoise_opt = strdup( optarg );
2366                     }
2367                 }
2368                 denoise = 1;
2369                 break;
2370             case '9':
2371                 if( optarg != NULL )
2372                 {
2373                     detelecine_opt = strdup( optarg );
2374                 }
2375                 detelecine = 1;
2376                 break;
2377             case '5':
2378                 if( optarg != NULL )
2379                 {
2380                     decomb_opt = strdup( optarg );
2381                 }
2382                 decomb = 1;
2383                 break;
2384             case 'g':
2385                 grayscale = 1;
2386                 break;
2387             case 'p':
2388                 pixelratio = 1;
2389                 break;
2390             case 'P':
2391                 loosePixelratio = 1;
2392                 if( optarg != NULL )
2393                 {
2394                     sscanf( optarg, "%i:%i:%i", &modulus, &par_width, &par_height );
2395                 }
2396                 break;
2397             case 'e':
2398                 if( !strcasecmp( optarg, "ffmpeg" ) )
2399                 {
2400                     vcodec = HB_VCODEC_FFMPEG;
2401                 }
2402                 else if( !strcasecmp( optarg, "xvid" ) )
2403                 {
2404                     vcodec = HB_VCODEC_XVID;
2405                 }
2406                 else if( !strcasecmp( optarg, "x264" ) )
2407                 {
2408                     vcodec = HB_VCODEC_X264;
2409                 }
2410                 else if( !strcasecmp( optarg, "x264b13" ) )
2411                 {
2412                     vcodec = HB_VCODEC_X264;
2413                     h264_13 = 1;
2414                 }
2415                 else if( !strcasecmp( optarg, "x264b30" ) )
2416                 {
2417                     vcodec = HB_VCODEC_X264;
2418                     h264_30 = 1;
2419                 }
2420                 else if( !strcasecmp( optarg, "theora" ) )
2421                 {
2422                     vcodec = HB_VCODEC_THEORA;
2423                 }
2424                 else
2425                 {
2426                     fprintf( stderr, "invalid codec (%s)\n", optarg );
2427                     return -1;
2428                 }
2429                 break;
2430             case 'E':
2431                 if( optarg != NULL )
2432                 {
2433                     acodecs = strdup( optarg );
2434                 }
2435                 break;
2436             case 'w':
2437                 width = atoi( optarg );
2438                 break;
2439             case 'l':
2440                 height = atoi( optarg );
2441                 break;
2442             case 'n':
2443             {
2444                 int    i;
2445                 char * tmp = optarg;
2446                 for( i = 0; i < 4; i++ )
2447                 {
2448                     if( !*tmp )
2449                         break;
2450                     crop[i] = strtol( tmp, &tmp, 0 );
2451                     tmp++;
2452                 }
2453                 break;
2454             }
2455             case 'r':
2456             {
2457                 int i;
2458                 vrate = 0;
2459                 for( i = 0; i < hb_video_rates_count; i++ )
2460                 {
2461                     if( !strcmp( optarg, hb_video_rates[i].string ) )
2462                     {
2463                         vrate = hb_video_rates[i].rate;
2464                         break;
2465                     }
2466                 }
2467                 if( !vrate )
2468                 {
2469                     fprintf( stderr, "invalid framerate %s\n", optarg );
2470                 }
2471                 break;
2472             }
2473             case 'R':
2474                 if( optarg != NULL )
2475                 {
2476                     arates = strdup( optarg );
2477                 }
2478                 break;
2479             case 'b':
2480                 vbitrate = atoi( optarg );
2481                 break;
2482             case 'q':
2483                 vquality = atof( optarg );
2484                 break;
2485             case 'S':
2486                 size = atoi( optarg );
2487                 break;
2488             case 'B':
2489                 if( optarg != NULL )
2490                 {
2491                     abitrates = strdup( optarg );
2492                 }
2493                 break;
2494             case 'Q':
2495                 crf = 0;
2496                 break;
2497             case 'x':
2498                 x264opts = strdup( optarg );
2499                 break;
2500             case 'T':
2501                 turbo_opts_enabled = 1;
2502                 break;
2503             case 'Y':
2504                 maxHeight = atoi( optarg );
2505                 break;
2506             case 'X':
2507                 maxWidth = atoi (optarg );
2508                 break;
2509             case 'A':
2510                 if( optarg != NULL )
2511                 {
2512                     anames = strdup( optarg );
2513                 }
2514                 break;
2515             case PREVIEWS:
2516                 sscanf( optarg, "%i:%i", &preview_count, &store_previews );
2517                 break;
2518             case START_AT_PREVIEW:
2519                 start_at_preview = atoi( optarg );
2520                 break;
2521             case STOP_AT_PTS:
2522                 sscanf( optarg, "%"SCNd64, &stop_at_pts );
2523                 break;
2524             case STOP_AT_DURATION:
2525                 sscanf( optarg, "%"SCNd64, &stop_at_pts );
2526                 stop_at_pts *= 90000LL;
2527                 break;
2528             case 'M':
2529                 if( atoi( optarg ) == 601 )
2530                     color_matrix = 1;
2531                 else if( atoi( optarg ) == 709 )
2532                     color_matrix = 2;
2533                 break;
2534             default:
2535                 fprintf( stderr, "unknown option (%s)\n", argv[optind] );
2536                 return -1;
2537         }
2538     }
2539
2540     return 0;
2541 }
2542
2543 static int CheckOptions( int argc, char ** argv )
2544 {
2545     if( update )
2546     {
2547         return 0;
2548     }
2549
2550     if( input == NULL || *input == '\0' )
2551     {
2552         fprintf( stderr, "Missing input device. Run %s --help for "
2553                  "syntax.\n", argv[0] );
2554         return 1;
2555     }
2556
2557     /* Parse format */
2558     if( titleindex > 0 )
2559     {
2560         if( output == NULL || *output == '\0' )
2561         {
2562             fprintf( stderr, "Missing output file name. Run %s --help "
2563                      "for syntax.\n", argv[0] );
2564             return 1;
2565         }
2566
2567         if( !format )
2568         {
2569             char * p = strrchr( output, '.' );
2570
2571             /* autodetect */
2572             if( p && !strcasecmp( p, ".avi" ) )
2573             {
2574                 mux = HB_MUX_AVI;
2575                 default_acodec = HB_ACODEC_LAME;
2576             }
2577             else if( p && ( !strcasecmp( p, ".mp4" )  ||
2578                             !strcasecmp( p, ".m4v" ) ) )
2579             {
2580                 if ( h264_30 == 1 )
2581                     mux = HB_MUX_IPOD;
2582                 else
2583                     mux = HB_MUX_MP4;
2584                 default_acodec = HB_ACODEC_FAAC;
2585             }
2586             else if( p && ( !strcasecmp( p, ".ogm" ) ||
2587                             !strcasecmp( p, ".ogg" ) ) )
2588             {
2589                 mux = HB_MUX_OGM;
2590                 default_acodec = HB_ACODEC_VORBIS;
2591             }
2592             else if( p && !strcasecmp(p, ".mkv" ) )
2593             {
2594                 mux = HB_MUX_MKV;
2595                 default_acodec = HB_ACODEC_AC3;
2596             }
2597             else
2598             {
2599                 fprintf( stderr, "Output format couldn't be guessed "
2600                          "from file name, using default.\n" );
2601                 return 0;
2602             }
2603         }
2604         else if( !strcasecmp( format, "avi" ) )
2605         {
2606             mux = HB_MUX_AVI;
2607             default_acodec = HB_ACODEC_LAME;
2608         }
2609         else if( !strcasecmp( format, "mp4" ) ||
2610                  !strcasecmp( format, "m4v" ) )
2611         {
2612             if ( h264_30 == 1)
2613                 mux = HB_MUX_IPOD;
2614             else
2615                 mux = HB_MUX_MP4;
2616             default_acodec = HB_ACODEC_FAAC;
2617         }
2618         else if( !strcasecmp( format, "ogm" ) ||
2619                  !strcasecmp( format, "ogg" ) )
2620         {
2621             mux = HB_MUX_OGM;
2622             default_acodec = HB_ACODEC_VORBIS;
2623         }
2624         else if( !strcasecmp( format, "mkv" ) )
2625         {
2626             mux = HB_MUX_MKV;
2627             default_acodec = HB_ACODEC_AC3;
2628         }
2629         else
2630         {
2631             fprintf( stderr, "Invalid output format (%s). Possible "
2632                      "choices are avi, mp4, m4v, ogm, ogg and mkv\n.", format );
2633             return 1;
2634         }
2635     }
2636
2637     return 0;
2638 }
2639
2640 static int get_acodec_for_string( char *codec )
2641 {
2642     if( !strcasecmp( codec, "ac3" ) )
2643     {
2644         return HB_ACODEC_AC3;
2645     }
2646     else if( !strcasecmp( codec, "dts" ) || !strcasecmp( codec, "dca" ) )
2647     {
2648         return HB_ACODEC_DCA;
2649     }
2650     else if( !strcasecmp( codec, "lame" ) )
2651     {
2652         return HB_ACODEC_LAME;
2653     }
2654     else if( !strcasecmp( codec, "faac" ) )
2655     {
2656         return HB_ACODEC_FAAC;
2657     }
2658     else if( !strcasecmp( codec, "vorbis") )
2659     {
2660         return HB_ACODEC_VORBIS;
2661     }
2662     else
2663     {
2664         return -1;
2665     }
2666 }
2667
2668 static int is_sample_rate_valid(int rate)
2669 {
2670     int i;
2671     for( i = 0; i < hb_audio_rates_count; i++ )
2672     {
2673             if (rate == hb_audio_rates[i].rate)
2674                 return 1;
2675     }
2676     return 0;
2677 }
2678
2679 #ifdef __APPLE_CC__
2680 /****************************************************************************
2681  * bsd_name_for_path
2682  *
2683  * Returns the BSD device name for the block device that contains the
2684  * passed-in path. Returns NULL on failure.
2685  ****************************************************************************/
2686 static char* bsd_name_for_path(char *path)
2687 {
2688     OSStatus err;
2689     FSRef ref;
2690     err = FSPathMakeRef( (const UInt8 *) input, &ref, NULL );
2691     if( err != noErr )
2692     {
2693         return NULL;
2694     }
2695
2696     // Get the volume reference number.
2697     FSCatalogInfo catalogInfo;
2698     err = FSGetCatalogInfo( &ref, kFSCatInfoVolume, &catalogInfo, NULL, NULL,
2699                             NULL);
2700     if( err != noErr )
2701     {
2702         return NULL;
2703     }
2704     FSVolumeRefNum volRefNum = catalogInfo.volume;
2705
2706     // Now let's get the device name
2707     GetVolParmsInfoBuffer volumeParms;
2708     err = FSGetVolumeParms( volRefNum, &volumeParms, sizeof( volumeParms ) );
2709     if( err != noErr )
2710     {
2711         return NULL;
2712     }
2713
2714     // A version 4 GetVolParmsInfoBuffer contains the BSD node name in the
2715     // vMDeviceID field. It is actually a char * value. This is mentioned in the
2716     // header CoreServices/CarbonCore/Files.h.
2717     return volumeParms.vMDeviceID;
2718 }
2719
2720 /****************************************************************************
2721  * device_is_dvd
2722  *
2723  * Returns whether or not the passed in BSD device represents a DVD, or other
2724  * optical media.
2725  ****************************************************************************/
2726 static int device_is_dvd(char *device)
2727 {
2728     io_service_t service = get_iokit_service(device);
2729     if( service == IO_OBJECT_NULL )
2730     {
2731         return 0;
2732     }
2733     int result = is_dvd_service(service);
2734     IOObjectRelease(service);
2735     return result;
2736 }
2737
2738 /****************************************************************************
2739  * get_iokit_service
2740  *
2741  * Returns the IOKit service object for the passed in BSD device name.
2742  ****************************************************************************/
2743 static io_service_t get_iokit_service( char *device )
2744 {
2745     CFMutableDictionaryRef matchingDict;
2746     matchingDict = IOBSDNameMatching( kIOMasterPortDefault, 0, device );
2747     if( matchingDict == NULL )
2748     {
2749         return IO_OBJECT_NULL;
2750     }
2751     // Fetch the object with the matching BSD node name. There should only be
2752     // one match, so IOServiceGetMatchingService is used instead of
2753     // IOServiceGetMatchingServices to simplify the code.
2754     return IOServiceGetMatchingService( kIOMasterPortDefault, matchingDict );
2755 }
2756
2757 /****************************************************************************
2758  * is_dvd_service
2759  *
2760  * Returns whether or not the service passed in is a DVD.
2761  *
2762  * Searches for an IOMedia object that represents the entire (whole) media that
2763  * the volume is on. If the volume is on partitioned media, the whole media
2764  * object will be a parent of the volume's media object. If the media is not
2765  * partitioned, the volume's media object will be the whole media object.
2766  ****************************************************************************/
2767 static int is_dvd_service( io_service_t service )
2768 {
2769     kern_return_t  kernResult;
2770     io_iterator_t  iter;
2771
2772     // Create an iterator across all parents of the service object passed in.
2773     kernResult = IORegistryEntryCreateIterator( service,
2774                                                 kIOServicePlane,
2775                                                 kIORegistryIterateRecursively | kIORegistryIterateParents,
2776                                                 &iter );
2777     if( kernResult != KERN_SUCCESS )
2778     {
2779         return 0;
2780     }
2781     if( iter == IO_OBJECT_NULL )
2782     {
2783         return 0;
2784     }
2785
2786     // A reference on the initial service object is released in the do-while
2787     // loop below, so add a reference to balance.
2788     IOObjectRetain( service );
2789
2790     int result = 0;
2791     do
2792     {
2793         if( is_whole_media_service( service ) &&
2794             IOObjectConformsTo( service, kIODVDMediaClass) )
2795         {
2796             result = 1;
2797         }
2798         IOObjectRelease( service );
2799     } while( !result && (service = IOIteratorNext( iter )) );
2800     IOObjectRelease( iter );
2801
2802     return result;
2803 }
2804
2805 /****************************************************************************
2806  * is_whole_media_service
2807  *
2808  * Returns whether or not the service passed in is an IOMedia service and
2809  * represents the "whole" media instead of just a partition.
2810  *
2811  * The whole media object is indicated in the IORegistry by the presence of a
2812  * property with the key "Whole" and value "Yes".
2813  ****************************************************************************/
2814 static is_whole_media_service( io_service_t service )
2815 {
2816     int result = 0;
2817
2818     if( IOObjectConformsTo( service, kIOMediaClass ) )
2819     {
2820         CFTypeRef wholeMedia = IORegistryEntryCreateCFProperty( service,
2821                                                                 CFSTR( kIOMediaWholeKey ),
2822                                                                 kCFAllocatorDefault,
2823                                                                 0 );
2824         if ( !wholeMedia )
2825         {
2826             return 0;
2827         }
2828         result = CFBooleanGetValue( (CFBooleanRef)wholeMedia );
2829         CFRelease( wholeMedia );
2830     }
2831
2832     return result;
2833 }
2834 #endif // __APPLE_CC__