OSDN Git Service

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