OSDN Git Service

Put the correct subtitle language in the Queue for the Mac GUI.
[handbrake-jp/handbrake-jp-git.git] / libhb / scan.c
1 /* $Id: scan.c,v 1.52 2005/11/25 15:05:25 titer Exp $
2
3    This file is part of the HandBrake source code.
4    Homepage: <http://handbrake.m0k.org/>.
5    It may be used under the terms of the GNU General Public License. */
6
7 #include "hb.h"
8 #include "a52dec/a52.h"
9 #include "dca.h"
10
11 typedef struct
12 {
13     hb_handle_t * h;
14     
15     char        * path;
16     int           title_index;
17     hb_list_t   * list_title;
18     
19     hb_dvd_t    * dvd;
20         hb_stream_t * stream;
21         
22 } hb_scan_t;
23
24 static void ScanFunc( void * );
25 static int  DecodePreviews( hb_scan_t *, hb_title_t * title );
26 static void LookForAC3AndDCA( hb_title_t * title, hb_buffer_t * b );
27 static int  AllAC3AndDCAOK( hb_title_t * title );
28
29 hb_thread_t * hb_scan_init( hb_handle_t * handle, const char * path,
30                             int title_index, hb_list_t * list_title )
31 {
32     hb_scan_t * data = calloc( sizeof( hb_scan_t ), 1 );
33
34     data->h            = handle;
35     data->path         = strdup( path );
36     data->title_index  = title_index;
37     data->list_title   = list_title;
38
39     return hb_thread_init( "scan", ScanFunc, data, HB_NORMAL_PRIORITY );
40 }
41
42 static void ScanFunc( void * _data )
43 {
44     hb_scan_t  * data = (hb_scan_t *) _data;
45     hb_title_t * title;
46     int          i;
47
48         data->dvd = NULL;
49         data->stream = NULL;
50         
51     /* Try to open the path as a DVD. If it fails, try as a file */
52     hb_log( "scan: trying to open with libdvdread" );
53     if( ( data->dvd = hb_dvd_init( data->path ) ) )
54     {
55         hb_log( "scan: DVD has %d title(s)",
56                 hb_dvd_title_count( data->dvd ) );
57         if( data->title_index )
58         {
59             /* Scan this title only */
60             hb_list_add( data->list_title, hb_dvd_title_scan( data->dvd,
61                             data->title_index ) );
62         }
63         else
64         {
65             /* Scan all titles */
66             for( i = 0; i < hb_dvd_title_count( data->dvd ); i++ )
67             {
68                 hb_list_add( data->list_title,
69                              hb_dvd_title_scan( data->dvd, i + 1 ) );
70             }
71         }
72     }
73     else if ( (data->stream = hb_stream_open (data->path)) != NULL )
74     {
75         hb_list_add( data->list_title, hb_stream_title_scan( data->stream ) );
76     }
77     else
78     {
79         hb_log( "scan: unrecognized file type" );
80         return;
81     }
82
83     for( i = 0; i < hb_list_count( data->list_title ); )
84     {
85         int j;
86         hb_state_t state;
87         hb_audio_t * audio;
88         hb_title_t * title_tmp = NULL;
89
90         title = hb_list_item( data->list_title, i );
91
92         /* I've seen a DVD with strictly identical titles. Check this
93            here and ignore it if redundant */
94         for( j = 0; j < i; j++ )
95         {
96             title_tmp = hb_list_item( data->list_title, j );
97             if( title->vts         == title_tmp->vts &&
98                 title->block_start == title_tmp->block_start &&
99                 title->block_end   == title_tmp->block_end &&
100                 title->block_count == title_tmp->block_count )
101             {
102                 break;
103             }
104             else
105             {
106                 title_tmp = NULL;
107             }
108         }
109         if( title_tmp )
110         {
111             hb_log( "scan: title %d is duplicate with title %d",
112                     title->index, title_tmp->index );
113             hb_list_rem( data->list_title, title );
114             free( title );      /* This _will_ leak! */
115             continue;
116         }
117
118 #define p state.param.scanning
119         /* Update the UI */
120         state.state   = HB_STATE_SCANNING;
121         p.title_cur   = title->index;
122         p.title_count = data->dvd ? hb_dvd_title_count( data->dvd ) : hb_list_count(data->list_title);
123         hb_set_state( data->h, &state );
124 #undef p
125
126         /* Decode previews */
127         /* this will also detect more AC3 / DTS information */
128         if( !DecodePreviews( data, title ) )
129         {
130             /* TODO: free things */
131             hb_list_rem( data->list_title, title );
132             continue;
133         }
134         
135                 if (data->stream)
136                 {
137                         // Stream based processing uses PID's to handle the different audio options for a given title
138                         for( j = 0; j < hb_list_count( title->list_audio ); j++ )
139                         {
140                                 audio = hb_list_item( title->list_audio, j );
141                                 hb_stream_update_audio(data->stream, audio);
142                         }
143                 }
144                 else if (data->dvd)
145                 {
146                         /* Make sure we found AC3 rates and bitrates */
147                         for( j = 0; j < hb_list_count( title->list_audio ); )
148                         {
149                                 audio = hb_list_item( title->list_audio, j );
150                                 if( audio->codec == HB_ACODEC_AC3 &&
151                                         !audio->bitrate )
152                                 {
153                                         hb_list_rem( title->list_audio, audio );
154                                         free( audio );
155                                         continue;
156                                 }
157                                 j++;
158                         }
159                 }
160                 
161         /* Make sure we found AC3 / DCA rates and bitrates */
162         for( j = 0; j < hb_list_count( title->list_audio ); )
163         {
164             audio = hb_list_item( title->list_audio, j );
165             if( ( audio->codec == HB_ACODEC_AC3 || audio->codec == HB_ACODEC_DCA ) &&
166                 !audio->bitrate )
167             {
168                 hb_log( "scan: removing audio with codec of 0x%x because of no bitrate",
169                     audio->codec );
170                 hb_list_rem( title->list_audio, audio );
171                 free( audio );
172                 continue;
173             }
174             j++;
175         }
176
177         /* Do we still have audio */
178         if( !hb_list_count( title->list_audio ) )
179         {
180             hb_list_rem( data->list_title, title );
181             free( title );
182             continue;
183         }
184
185         /* set a default input channel layout of stereo for LPCM or MPEG2 audio */
186         /* AC3 and DCA will already have had their layout set via DecodePreviews above, */
187         /* which calls LookForAC3AndDCA */
188         for( j = 0; j < hb_list_count( title->list_audio ); j++ )
189         {
190             audio = hb_list_item( title->list_audio, j );
191             if( audio->codec == HB_ACODEC_LPCM || audio->codec == HB_ACODEC_MPGA )
192             {
193                 audio->input_channel_layout = HB_INPUT_CH_LAYOUT_STEREO;
194             }
195         }
196         
197         i++;
198     }
199
200     /* Init jobs templates */
201     for( i = 0; i < hb_list_count( data->list_title ); i++ )
202     {
203         hb_job_t * job;
204
205         title      = hb_list_item( data->list_title, i );
206         job        = calloc( sizeof( hb_job_t ), 1 );
207         title->job = job;
208
209         job->title = title;
210
211         /* Set defaults settings */
212         job->chapter_start = 1;
213         job->chapter_end   = hb_list_count( title->list_chapter );
214
215         /* Autocrop by default. Gnark gnark */
216         memcpy( job->crop, title->crop, 4 * sizeof( int ) );
217
218         if( title->aspect == 16 )
219         {
220             hb_reduce( &job->pixel_aspect_width, &job->pixel_aspect_height,
221                        16 * title->height, 9 * title->width );
222         }
223         else
224         {
225             hb_reduce( &job->pixel_aspect_width, &job->pixel_aspect_height,
226                        4 * title->height, 3 * title->width );
227         }
228
229         job->width = title->width - job->crop[2] - job->crop[3];
230 //        job->height = title->height - job->crop[0] - job->crop[1];
231         hb_fix_aspect( job, HB_KEEP_WIDTH );
232         if( job->height > title->height - job->crop[0] - job->crop[1] )
233         {
234             job->height = title->height - job->crop[0] - job->crop[1];
235             hb_fix_aspect( job, HB_KEEP_HEIGHT );
236         }
237
238     hb_log( "scan: title (%d) job->width:%d, job->height:%d",
239             i,job->width, job->height );
240
241         job->keep_ratio = 1;
242
243         job->vcodec     = HB_VCODEC_FFMPEG;
244         job->vquality   = -1.0;
245         job->vbitrate   = 1000;
246         job->pass       = 0;
247         job->vrate      = title->rate;
248         job->vrate_base = title->rate_base;
249
250         job->audios[0] = 0;
251         job->audios[1] = -1;
252
253         job->acodec   = HB_ACODEC_FAAC;
254         job->abitrate = 128;
255         job->arate    = 44100;
256
257         job->subtitle = -1;
258
259         job->mux = HB_MUX_MP4;
260     }
261
262     if( data->dvd )
263     {
264         hb_dvd_close( &data->dvd );
265     }
266         if (data->stream)
267         {
268                 hb_stream_close(&data->stream);
269         }
270     free( data->path );
271     free( data );
272     _data = NULL;
273 }
274
275 /***********************************************************************
276  * DecodePreviews
277  ***********************************************************************
278  * Decode 10 pictures for the given title.
279  * It assumes that data->reader and data->vts have successfully been
280  * DVDOpen()ed and ifoOpen()ed.
281  **********************************************************************/
282 static int DecodePreviews( hb_scan_t * data, hb_title_t * title )
283 {
284     int             i, ret;
285     hb_buffer_t   * buf_ps, * buf_es, * buf_raw;
286     hb_list_t     * list_es, * list_raw;
287     hb_libmpeg2_t * mpeg2;
288     int progressive_count = 0;
289     
290     buf_ps   = hb_buffer_init( HB_DVD_READ_BUFFER_SIZE );
291     list_es  = hb_list_init();
292     list_raw = hb_list_init();
293
294     hb_log( "scan: decoding previews for title %d", title->index );
295
296     if (data->dvd)
297       hb_dvd_start( data->dvd, title->index, 1 );
298     
299     for( i = 0; i < 10; i++ )
300     {
301         int j, k;
302         FILE * file_preview;
303         char   filename[1024];
304
305         //hb_log("Seeking to: %f", (float) ( i + 1 ) / 11.0 );
306        
307         if (data->dvd)
308         {
309           if( !hb_dvd_seek( data->dvd, (float) ( i + 1 ) / 11.0 ) )
310           {
311               goto error;
312           }
313         }
314         else if (data->stream)
315         {
316           if (!hb_stream_seek(data->stream, (float) ( i + 1 ) / 11.0 ) )
317           {
318             goto error;
319           }
320         }
321         
322         hb_log( "scan: preview %d", i + 1 );
323
324         mpeg2 = hb_libmpeg2_init();
325
326         for( j = 0; j < 10240 ; j++ )
327         {
328             if (data->dvd)
329             {
330               if( !hb_dvd_read( data->dvd, buf_ps ) )
331               {
332                   hb_log( "Warning: Could not read data for preview %d, skipped", i + 1 );
333                   goto skip_preview;
334               }
335             }
336             else if (data->stream)
337             {
338               if ( !hb_stream_read(data->stream,buf_ps) )
339               {
340                   hb_log( "Warning: Could not read data for preview %d, skipped", i + 1 );
341                   goto skip_preview;
342               }
343             }
344             hb_demux_ps( buf_ps, list_es );
345
346             while( ( buf_es = hb_list_item( list_es, 0 ) ) )
347             {
348                 hb_list_rem( list_es, buf_es );
349                 if( buf_es->id == 0xE0 && !hb_list_count( list_raw ) )
350                 {
351                     hb_libmpeg2_decode( mpeg2, buf_es, list_raw );
352                 }
353                 else if( !i )
354                 {
355                     LookForAC3AndDCA( title, buf_es );
356                 }
357                 hb_buffer_close( &buf_es );
358
359                 if( hb_list_count( list_raw ) &&
360                     ( i || AllAC3AndDCAOK( title ) ) )
361                 {
362                     /* We got a picture */
363                     break;
364                 }
365             }
366
367             if( hb_list_count( list_raw ) &&
368                 ( i || AllAC3AndDCAOK( title ) ) )
369             {
370                 break;
371             }
372         }
373
374         if( !hb_list_count( list_raw ) )
375         {
376             hb_log( "scan: could not get a decoded picture" );
377             goto error;
378         }
379
380         /* Get size and rate infos */
381         title->rate = 27000000;
382         int ar;
383         hb_libmpeg2_info( mpeg2, &title->width, &title->height,
384                           &title->rate_base, &ar );
385        
386         if( title->rate_base == 1126125 )
387         {
388             /* Frame FPS is 23.976 (meaning it's progressive), so
389                start keeping track of how many are reporting at
390                that speed. When enough show up that way, we want
391                to make that the overall title FPS.
392             */
393             progressive_count++;
394
395             if( progressive_count < 6 )
396             {
397                 /* Not enough frames are reporting as progressive,
398                    which means we should be conservative and use
399                    29.97 as the title's FPS for now.
400                 */
401                 title->rate_base = 900900;           
402             }
403             else
404             {
405                 /* A majority of the scan frames are progressive. Make that
406                     the title's FPS, and announce it once to the log.
407                 */
408                 if( progressive_count == 6 )
409                 {
410                     hb_log("Title's mostly progressive NTSC, setting fps to 23.976");
411                 }
412                 title->rate_base = 1126125;               
413             }
414         } 
415         else if( title->rate_base == 900900 && progressive_count >= 6 )
416         {
417             /*
418              * We've already deduced that the frame rate is 23.976, so set it
419              * back again.
420              */
421             title->rate_base = 1126125;
422         }
423                
424         if( i == 2) // Use the third frame's info, so as to skip opening logos
425         {
426             // The aspect ratio may have already been set by parsing the VOB/IFO details on a DVD, however
427             // if we're working with program/transport streams that data needs to come from within the stream.
428             if (title->aspect <= 0)
429               title->aspect = ar;
430             title->crop[0] = title->crop[1] = title->height / 2;
431             title->crop[2] = title->crop[3] = title->width / 2;
432         }
433
434         hb_libmpeg2_close( &mpeg2 );
435
436         while( ( buf_es = hb_list_item( list_es, 0 ) ) )
437         {
438             hb_list_rem( list_es, buf_es );
439             hb_buffer_close( &buf_es );
440         }
441
442         buf_raw = hb_list_item( list_raw, 0 );
443
444         hb_get_tempory_filename( data->h, filename, "%x%d",
445                                  (intptr_t)title, i );
446
447         file_preview = fopen( filename, "w" );
448         if( file_preview )
449         {
450             fwrite( buf_raw->data, title->width * title->height * 3 / 2,
451                     1, file_preview );
452             fclose( file_preview );
453         }
454         else
455         {
456             hb_log( "scan: fopen failed (%s)", filename );
457         }
458
459 #define Y    buf_raw->data
460 #define DARK 64
461         
462         /* Detect black borders */
463         
464         for( j = 0; j < title->width; j++ )
465         {
466             for( k = 0; k < title->crop[0]; k++ )
467                 if( Y[ k * title->width + j ] > DARK )
468                 {
469                     title->crop[0] = k;
470                     break;
471                 }
472             for( k = 0; k < title->crop[1]; k++ )
473                 if( Y[ ( title->height - k - 1 ) *
474                        title->width + j ] > DARK )
475                 {
476                     title->crop[1] = k;
477                     break;
478                 }
479         }
480         for( j = 0; j < title->height; j++ )
481         {
482             for( k = 0; k < title->crop[2]; k++ ) 
483                 if( Y[ j * title->width + k ] > DARK )
484                 {
485                     title->crop[2] = k;
486                     break;
487                 }
488             for( k = 0; k < title->crop[3]; k++ )
489                 if( Y[ j * title->width +
490                         title->width - k - 1 ] > DARK )
491                 {
492                     title->crop[3] = k;
493                     break;
494                 }
495         }
496
497 skip_preview:
498         while( ( buf_raw = hb_list_item( list_raw, 0 ) ) )
499         {
500             hb_list_rem( list_raw, buf_raw );
501             hb_buffer_close( &buf_raw );
502         }
503     }
504
505     title->crop[0] = EVEN( title->crop[0] );
506     title->crop[1] = EVEN( title->crop[1] );
507     title->crop[2] = EVEN( title->crop[2] );
508     title->crop[3] = EVEN( title->crop[3] );
509
510     hb_log( "scan: %dx%d, %.3f fps, autocrop = %d/%d/%d/%d",
511             title->width, title->height, (float) title->rate /
512             (float) title->rate_base, title->crop[0], title->crop[1],
513             title->crop[2], title->crop[3] );
514
515     ret = 1;
516     goto cleanup;
517
518 error:
519     ret = 0;
520
521 cleanup:
522     hb_buffer_close( &buf_ps );
523     while( ( buf_es = hb_list_item( list_es, 0 ) ) )
524     {
525         hb_list_rem( list_es, buf_es );
526         hb_buffer_close( &buf_es );
527     }
528     hb_list_close( &list_es );
529     while( ( buf_raw = hb_list_item( list_raw, 0 ) ) )
530     {
531         hb_list_rem( list_raw, buf_raw );
532         hb_buffer_close( &buf_raw );
533     }
534     hb_list_close( &list_raw );
535     if (data->dvd)
536       hb_dvd_stop( data->dvd );
537
538     return ret;
539 }
540
541 static void LookForAC3AndDCA( hb_title_t * title, hb_buffer_t * b ) 
542 {
543     int i;
544     int flags;
545     int rate;
546     int bitrate;
547     int frame_length;
548     dca_state_t * state;
549
550     /* Figure out if this is a AC3 or DCA buffer for a known track */
551     hb_audio_t * audio = NULL;
552     for( i = 0; i < hb_list_count( title->list_audio ); i++ )
553     {
554         audio = hb_list_item( title->list_audio, i );
555         /* check if we have an AC3 or DCA which we recognise */
556         if( ( audio->codec == HB_ACODEC_AC3 || audio->codec == HB_ACODEC_DCA ) &&
557             audio->id    == b->id )
558         {
559             break;
560         }
561         else
562         {
563             audio = NULL;
564         }
565     }
566     if( !audio )
567     {
568         return;
569     }
570
571     if( audio->bitrate )
572     {
573         /* Already done for this track */
574         return;
575     }
576
577     for( i = 0; i < b->size - 7; i++ )
578     {
579
580         if ( audio->codec == HB_ACODEC_AC3 )
581         {
582
583             /* check for a52 */
584             if( a52_syncinfo( &b->data[i], &flags, &rate, &bitrate ) )
585             {
586                 hb_log( "scan: AC3, rate=%dHz, bitrate=%d", rate, bitrate );
587                 audio->rate    = rate;
588                 audio->bitrate = bitrate;
589                 switch( flags & A52_CHANNEL_MASK )
590                 {
591                     /* mono sources */
592                     case A52_MONO:
593                     case A52_CHANNEL1:
594                     case A52_CHANNEL2:
595                         audio->input_channel_layout = HB_INPUT_CH_LAYOUT_MONO;
596                         break;
597                     /* stereo input */
598                     case A52_CHANNEL:
599                     case A52_STEREO:
600                         audio->input_channel_layout = HB_INPUT_CH_LAYOUT_STEREO;
601                         break;
602                     /* dolby (DPL1 aka Dolby Surround = 4.0 matrix-encoded) input */
603                     case A52_DOLBY:
604                         audio->input_channel_layout = HB_INPUT_CH_LAYOUT_DOLBY;
605                         break;
606                     /* 3F/2R input */
607                     case A52_3F2R:
608                         audio->input_channel_layout = HB_INPUT_CH_LAYOUT_3F2R;
609                         break;
610                     /* 3F/1R input */
611                     case A52_3F1R:
612                         audio->input_channel_layout = HB_INPUT_CH_LAYOUT_3F1R;
613                         break;
614                     /* other inputs */
615                     case A52_3F:
616                         audio->input_channel_layout = HB_INPUT_CH_LAYOUT_3F;
617                         break;
618                     case A52_2F1R:
619                         audio->input_channel_layout = HB_INPUT_CH_LAYOUT_2F1R;
620                         break;
621                     case A52_2F2R:
622                         audio->input_channel_layout = HB_INPUT_CH_LAYOUT_2F2R;
623                         break;
624                     /* unknown */
625                     default:
626                         audio->input_channel_layout = HB_INPUT_CH_LAYOUT_STEREO;
627                 }
628                 
629                 /* add in our own LFE flag if the source has LFE */
630                 if (flags & A52_LFE)
631                 {
632                     audio->input_channel_layout = audio->input_channel_layout | HB_INPUT_CH_LAYOUT_HAS_LFE;
633                 }
634
635                 /* store the AC3 flags for future reference
636                 This enables us to find out if we had a stereo or Dolby source later on */
637                 audio->config.a52.ac3flags = flags;
638
639                 /* store the ac3 flags in the public ac3flags property too, so we can access it from the GUI */
640                 audio->ac3flags = audio->config.a52.ac3flags;
641
642                 /* XXX */
643                 if ( (flags & A52_CHANNEL_MASK) == A52_DOLBY ) {
644                     sprintf( audio->lang + strlen( audio->lang ),
645                          " (Dolby Surround)" );
646                 } else {
647                     sprintf( audio->lang + strlen( audio->lang ),
648                          " (%d.%d ch)",
649                         HB_INPUT_CH_LAYOUT_GET_DISCRETE_FRONT_COUNT(audio->input_channel_layout) +
650                         HB_INPUT_CH_LAYOUT_GET_DISCRETE_REAR_COUNT(audio->input_channel_layout),
651                         HB_INPUT_CH_LAYOUT_GET_DISCRETE_LFE_COUNT(audio->input_channel_layout));
652                 }
653
654                 break;
655             
656             }
657
658         }
659         else if ( audio->codec == HB_ACODEC_DCA )
660         {
661
662             hb_log( "scan: checking for DCA syncinfo" );
663
664             /* check for dca */
665             state = dca_init( 0 );
666             if( dca_syncinfo( state, &b->data[i], &flags, &rate, &bitrate, &frame_length ) )
667             {
668                 hb_log( "scan: DCA, rate=%dHz, bitrate=%d", rate, bitrate );
669                 audio->rate    = rate;
670                 audio->bitrate = bitrate;
671                 switch( flags & DCA_CHANNEL_MASK )
672                 {
673                     /* mono sources */
674                     case DCA_MONO:
675                         audio->input_channel_layout = HB_INPUT_CH_LAYOUT_MONO;
676                         break;
677                     /* stereo input */
678                     case DCA_CHANNEL:
679                     case DCA_STEREO:
680                     case DCA_STEREO_SUMDIFF:
681                     case DCA_STEREO_TOTAL:
682                         audio->input_channel_layout = HB_INPUT_CH_LAYOUT_STEREO;
683                         break;
684                     /* 3F/2R input */
685                     case DCA_3F2R:
686                         audio->input_channel_layout = HB_INPUT_CH_LAYOUT_3F2R;
687                         break;
688                     /* 3F/1R input */
689                     case DCA_3F1R:
690                         audio->input_channel_layout = HB_INPUT_CH_LAYOUT_3F1R;
691                         break;
692                     /* other inputs */
693                     case DCA_3F:
694                         audio->input_channel_layout = HB_INPUT_CH_LAYOUT_3F;
695                         break;
696                     case DCA_2F1R:
697                         audio->input_channel_layout = HB_INPUT_CH_LAYOUT_2F1R;
698                         break;
699                     case DCA_2F2R:
700                         audio->input_channel_layout = HB_INPUT_CH_LAYOUT_2F2R;
701                         break;
702                     case DCA_4F2R:
703                         audio->input_channel_layout = HB_INPUT_CH_LAYOUT_4F2R;
704                         break;
705                     /* unknown */
706                     default:
707                         audio->input_channel_layout = HB_INPUT_CH_LAYOUT_STEREO;
708                 }
709
710                 /* add in our own LFE flag if the source has LFE */
711                 if (flags & DCA_LFE)
712                 {
713                     audio->input_channel_layout = audio->input_channel_layout | HB_INPUT_CH_LAYOUT_HAS_LFE;
714                 }
715
716                 /* store the DCA flags for future reference
717                 This enables us to find out if we had a stereo or Dolby source later on */
718                 audio->config.dca.dcaflags = flags;
719
720                 /* store the dca flags in the public dcaflags property too, so we can access it from the GUI */
721                 audio->dcaflags = audio->config.dca.dcaflags;
722
723                 /* XXX */
724                 if ( (flags & DCA_CHANNEL_MASK) == DCA_DOLBY ) {
725                     sprintf( audio->lang + strlen( audio->lang ),
726                          " (Dolby Surround)" );
727                 } else {
728                     sprintf( audio->lang + strlen( audio->lang ),
729                          " (%d.%d ch)",
730                         HB_INPUT_CH_LAYOUT_GET_DISCRETE_FRONT_COUNT(audio->input_channel_layout) +
731                         HB_INPUT_CH_LAYOUT_GET_DISCRETE_REAR_COUNT(audio->input_channel_layout),
732                         HB_INPUT_CH_LAYOUT_GET_DISCRETE_LFE_COUNT(audio->input_channel_layout));
733                 }
734
735                 break;
736             }
737         }
738     }
739
740 }
741
742 static int  AllAC3AndDCAOK( hb_title_t * title )
743 {
744     int i;
745     hb_audio_t * audio;
746
747     for( i = 0; i < hb_list_count( title->list_audio ); i++ )
748     {
749         audio = hb_list_item( title->list_audio, i );
750         if( ( audio->codec == HB_ACODEC_AC3 || audio->codec == HB_ACODEC_DCA ) &&
751             !audio->bitrate )
752         {
753             return 0;
754         }
755     }
756
757     return 1;
758 }