OSDN Git Service

Don't drop subtitles when crossing PTS discontinuities by using buffer sequence numbe...
[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                   hb_log( "Warning: Could not read data for preview %d, skipped", i + 1 );
338                   goto skip_preview;
339               }
340             }
341             else if (data->stream)
342             {
343               if ( !hb_stream_read(data->stream,buf_ps) )
344               {
345                   hb_log( "Warning: Could not read data for preview %d, skipped", i + 1 );
346                   goto skip_preview;
347               }
348             }
349             hb_demux_ps( buf_ps, list_es );
350
351             while( ( buf_es = hb_list_item( list_es, 0 ) ) )
352             {
353                 hb_list_rem( list_es, buf_es );
354                 if( buf_es->id == 0xE0 && !hb_list_count( list_raw ) )
355                 {
356                     hb_libmpeg2_decode( mpeg2, buf_es, list_raw );
357                 }
358                 else if( !i )
359                 {
360                     LookForAC3AndDCA( title, buf_es );
361                 }
362                 hb_buffer_close( &buf_es );
363
364                 if( hb_list_count( list_raw ) &&
365                     ( i || AllAC3AndDCAOK( title ) ) )
366                 {
367                     /* We got a picture */
368                     break;
369                 }
370             }
371
372             if( hb_list_count( list_raw ) &&
373                 ( i || AllAC3AndDCAOK( title ) ) )
374             {
375                 break;
376             }
377         }
378
379         if( !hb_list_count( list_raw ) )
380         {
381             hb_log( "scan: could not get a decoded picture" );
382             goto error;
383         }
384
385         /* Get size and rate infos */
386         title->rate = 27000000;
387         int ar;
388         hb_libmpeg2_info( mpeg2, &title->width, &title->height,
389                           &title->rate_base, &ar );
390        
391         if( title->rate_base == 1126125 )
392         {
393             /* Frame FPS is 23.976 (meaning it's progressive), so
394                start keeping track of how many are reporting at
395                that speed. When enough show up that way, we want
396                to make that the overall title FPS.
397             */
398             progressive_count++;
399
400             if( progressive_count < 6 )
401             {
402                 /* Not enough frames are reporting as progressive,
403                    which means we should be conservative and use
404                    29.97 as the title's FPS for now.
405                 */
406                 title->rate_base = 900900;           
407             }
408             else
409             {
410                 /* A majority of the scan frames are progressive. Make that
411                     the title's FPS, and announce it once to the log.
412                 */
413                 if( progressive_count == 6 )
414                 {
415                     hb_log("Title's mostly progressive NTSC, setting fps to 23.976");
416                 }
417                 title->rate_base = 1126125;               
418             }
419         } 
420         else if( title->rate_base == 900900 && progressive_count >= 6 )
421         {
422             /*
423              * We've already deduced that the frame rate is 23.976, so set it
424              * back again.
425              */
426             title->rate_base = 1126125;
427         }
428                
429         if( i == 2) // Use the third frame's info, so as to skip opening logos
430         {
431             // The aspect ratio may have already been set by parsing the VOB/IFO details on a DVD, however
432             // if we're working with program/transport streams that data needs to come from within the stream.
433             if (title->aspect <= 0)
434               title->aspect = ar;
435             title->crop[0] = title->crop[1] = title->height / 2;
436             title->crop[2] = title->crop[3] = title->width / 2;
437         }
438
439         hb_libmpeg2_close( &mpeg2 );
440
441         while( ( buf_es = hb_list_item( list_es, 0 ) ) )
442         {
443             hb_list_rem( list_es, buf_es );
444             hb_buffer_close( &buf_es );
445         }
446
447         buf_raw = hb_list_item( list_raw, 0 );
448
449         hb_get_tempory_filename( data->h, filename, "%x%d",
450                                  (intptr_t)title, i );
451
452         file_preview = fopen( filename, "w" );
453         if( file_preview )
454         {
455             fwrite( buf_raw->data, title->width * title->height * 3 / 2,
456                     1, file_preview );
457             fclose( file_preview );
458         }
459         else
460         {
461             hb_log( "scan: fopen failed (%s)", filename );
462         }
463
464 #define Y    buf_raw->data
465 #define DARK 64
466         
467         /* Detect black borders */
468         
469         for( j = 0; j < title->width; j++ )
470         {
471             for( k = 0; k < title->crop[0]; k++ )
472                 if( Y[ k * title->width + j ] > DARK )
473                 {
474                     title->crop[0] = k;
475                     break;
476                 }
477             for( k = 0; k < title->crop[1]; k++ )
478                 if( Y[ ( title->height - k - 1 ) *
479                        title->width + j ] > DARK )
480                 {
481                     title->crop[1] = k;
482                     break;
483                 }
484         }
485         for( j = 0; j < title->height; j++ )
486         {
487             for( k = 0; k < title->crop[2]; k++ ) 
488                 if( Y[ j * title->width + k ] > DARK )
489                 {
490                     title->crop[2] = k;
491                     break;
492                 }
493             for( k = 0; k < title->crop[3]; k++ )
494                 if( Y[ j * title->width +
495                         title->width - k - 1 ] > DARK )
496                 {
497                     title->crop[3] = k;
498                     break;
499                 }
500         }
501
502 skip_preview:
503         while( ( buf_raw = hb_list_item( list_raw, 0 ) ) )
504         {
505             hb_list_rem( list_raw, buf_raw );
506             hb_buffer_close( &buf_raw );
507         }
508     }
509
510     title->crop[0] = EVEN( title->crop[0] );
511     title->crop[1] = EVEN( title->crop[1] );
512     title->crop[2] = EVEN( title->crop[2] );
513     title->crop[3] = EVEN( title->crop[3] );
514
515     hb_log( "scan: %dx%d, %.3f fps, autocrop = %d/%d/%d/%d",
516             title->width, title->height, (float) title->rate /
517             (float) title->rate_base, title->crop[0], title->crop[1],
518             title->crop[2], title->crop[3] );
519
520     ret = 1;
521     goto cleanup;
522
523 error:
524     ret = 0;
525
526 cleanup:
527     hb_buffer_close( &buf_ps );
528     while( ( buf_es = hb_list_item( list_es, 0 ) ) )
529     {
530         hb_list_rem( list_es, buf_es );
531         hb_buffer_close( &buf_es );
532     }
533     hb_list_close( &list_es );
534     while( ( buf_raw = hb_list_item( list_raw, 0 ) ) )
535     {
536         hb_list_rem( list_raw, buf_raw );
537         hb_buffer_close( &buf_raw );
538     }
539     hb_list_close( &list_raw );
540     if (data->dvd)
541       hb_dvd_stop( data->dvd );
542
543     return ret;
544 }
545
546 static void LookForAC3AndDCA( hb_title_t * title, hb_buffer_t * b ) 
547 {
548     int i;
549     int flags;
550     int rate;
551     int bitrate;
552     int frame_length;
553     dca_state_t * state;
554
555     /* Figure out if this is a AC3 or DCA buffer for a known track */
556     hb_audio_t * audio = NULL;
557     for( i = 0; i < hb_list_count( title->list_audio ); i++ )
558     {
559         audio = hb_list_item( title->list_audio, i );
560         /* check if we have an AC3 or DCA which we recognise */
561         if( ( audio->codec == HB_ACODEC_AC3 || audio->codec == HB_ACODEC_DCA ) &&
562             audio->id    == b->id )
563         {
564             break;
565         }
566         else
567         {
568             audio = NULL;
569         }
570     }
571     if( !audio )
572     {
573         return;
574     }
575
576     if( audio->bitrate )
577     {
578         /* Already done for this track */
579         return;
580     }
581
582     for( i = 0; i < b->size - 7; i++ )
583     {
584
585         if ( audio->codec == HB_ACODEC_AC3 )
586         {
587
588             /* check for a52 */
589             if( a52_syncinfo( &b->data[i], &flags, &rate, &bitrate ) )
590             {
591                 hb_log( "scan: AC3, rate=%dHz, bitrate=%d", rate, bitrate );
592                 audio->rate    = rate;
593                 audio->bitrate = bitrate;
594                 switch( flags & A52_CHANNEL_MASK )
595                 {
596                     /* mono sources */
597                     case A52_MONO:
598                     case A52_CHANNEL1:
599                     case A52_CHANNEL2:
600                         audio->input_channel_layout = HB_INPUT_CH_LAYOUT_MONO;
601                         break;
602                     /* stereo input */
603                     case A52_CHANNEL:
604                     case A52_STEREO:
605                         audio->input_channel_layout = HB_INPUT_CH_LAYOUT_STEREO;
606                         break;
607                     /* dolby (DPL1 aka Dolby Surround = 4.0 matrix-encoded) input */
608                     case A52_DOLBY:
609                         audio->input_channel_layout = HB_INPUT_CH_LAYOUT_DOLBY;
610                         break;
611                     /* 3F/2R input */
612                     case A52_3F2R:
613                         audio->input_channel_layout = HB_INPUT_CH_LAYOUT_3F2R;
614                         break;
615                     /* 3F/1R input */
616                     case A52_3F1R:
617                         audio->input_channel_layout = HB_INPUT_CH_LAYOUT_3F1R;
618                         break;
619                     /* other inputs */
620                     case A52_3F:
621                         audio->input_channel_layout = HB_INPUT_CH_LAYOUT_3F;
622                         break;
623                     case A52_2F1R:
624                         audio->input_channel_layout = HB_INPUT_CH_LAYOUT_2F1R;
625                         break;
626                     case A52_2F2R:
627                         audio->input_channel_layout = HB_INPUT_CH_LAYOUT_2F2R;
628                         break;
629                     /* unknown */
630                     default:
631                         audio->input_channel_layout = HB_INPUT_CH_LAYOUT_STEREO;
632                 }
633                 
634                 /* add in our own LFE flag if the source has LFE */
635                 if (flags & A52_LFE)
636                 {
637                     audio->input_channel_layout = audio->input_channel_layout | HB_INPUT_CH_LAYOUT_HAS_LFE;
638                 }
639
640                 /* store the AC3 flags for future reference
641                 This enables us to find out if we had a stereo or Dolby source later on */
642                 audio->config.a52.ac3flags = flags;
643
644                 /* store the ac3 flags in the public ac3flags property too, so we can access it from the GUI */
645                 audio->ac3flags = audio->config.a52.ac3flags;
646
647                 /* XXX */
648                 if ( (flags & A52_CHANNEL_MASK) == A52_DOLBY ) {
649                     sprintf( audio->lang + strlen( audio->lang ),
650                          " (Dolby Surround)" );
651                 } else {
652                     sprintf( audio->lang + strlen( audio->lang ),
653                          " (%d.%d ch)",
654                         HB_INPUT_CH_LAYOUT_GET_DISCRETE_FRONT_COUNT(audio->input_channel_layout) +
655                         HB_INPUT_CH_LAYOUT_GET_DISCRETE_REAR_COUNT(audio->input_channel_layout),
656                         HB_INPUT_CH_LAYOUT_GET_DISCRETE_LFE_COUNT(audio->input_channel_layout));
657                 }
658
659                 break;
660             
661             }
662
663         }
664         else if ( audio->codec == HB_ACODEC_DCA )
665         {
666
667             hb_log( "scan: checking for DCA syncinfo" );
668
669             /* check for dca */
670             state = dca_init( 0 );
671             if( dca_syncinfo( state, &b->data[i], &flags, &rate, &bitrate, &frame_length ) )
672             {
673                 hb_log( "scan: DCA, rate=%dHz, bitrate=%d", rate, bitrate );
674                 audio->rate    = rate;
675                 audio->bitrate = bitrate;
676                 switch( flags & DCA_CHANNEL_MASK )
677                 {
678                     /* mono sources */
679                     case DCA_MONO:
680                         audio->input_channel_layout = HB_INPUT_CH_LAYOUT_MONO;
681                         break;
682                     /* stereo input */
683                     case DCA_CHANNEL:
684                     case DCA_STEREO:
685                     case DCA_STEREO_SUMDIFF:
686                     case DCA_STEREO_TOTAL:
687                         audio->input_channel_layout = HB_INPUT_CH_LAYOUT_STEREO;
688                         break;
689                     /* 3F/2R input */
690                     case DCA_3F2R:
691                         audio->input_channel_layout = HB_INPUT_CH_LAYOUT_3F2R;
692                         break;
693                     /* 3F/1R input */
694                     case DCA_3F1R:
695                         audio->input_channel_layout = HB_INPUT_CH_LAYOUT_3F1R;
696                         break;
697                     /* other inputs */
698                     case DCA_3F:
699                         audio->input_channel_layout = HB_INPUT_CH_LAYOUT_3F;
700                         break;
701                     case DCA_2F1R:
702                         audio->input_channel_layout = HB_INPUT_CH_LAYOUT_2F1R;
703                         break;
704                     case DCA_2F2R:
705                         audio->input_channel_layout = HB_INPUT_CH_LAYOUT_2F2R;
706                         break;
707                     case DCA_4F2R:
708                         audio->input_channel_layout = HB_INPUT_CH_LAYOUT_4F2R;
709                         break;
710                     /* unknown */
711                     default:
712                         audio->input_channel_layout = HB_INPUT_CH_LAYOUT_STEREO;
713                 }
714
715                 /* add in our own LFE flag if the source has LFE */
716                 if (flags & DCA_LFE)
717                 {
718                     audio->input_channel_layout = audio->input_channel_layout | HB_INPUT_CH_LAYOUT_HAS_LFE;
719                 }
720
721                 /* store the DCA flags for future reference
722                 This enables us to find out if we had a stereo or Dolby source later on */
723                 audio->config.dca.dcaflags = flags;
724
725                 /* store the dca flags in the public dcaflags property too, so we can access it from the GUI */
726                 audio->dcaflags = audio->config.dca.dcaflags;
727
728                 /* XXX */
729                 if ( (flags & DCA_CHANNEL_MASK) == DCA_DOLBY ) {
730                     sprintf( audio->lang + strlen( audio->lang ),
731                          " (Dolby Surround)" );
732                 } else {
733                     sprintf( audio->lang + strlen( audio->lang ),
734                          " (%d.%d ch)",
735                         HB_INPUT_CH_LAYOUT_GET_DISCRETE_FRONT_COUNT(audio->input_channel_layout) +
736                         HB_INPUT_CH_LAYOUT_GET_DISCRETE_REAR_COUNT(audio->input_channel_layout),
737                         HB_INPUT_CH_LAYOUT_GET_DISCRETE_LFE_COUNT(audio->input_channel_layout));
738                 }
739
740                 break;
741             }
742         }
743     }
744
745 }
746
747 static int  AllAC3AndDCAOK( hb_title_t * title )
748 {
749     int i;
750     hb_audio_t * audio;
751
752     for( i = 0; i < hb_list_count( title->list_audio ); i++ )
753     {
754         audio = hb_list_item( title->list_audio, i );
755         if( ( audio->codec == HB_ACODEC_AC3 || audio->codec == HB_ACODEC_DCA ) &&
756             !audio->bitrate )
757         {
758             return 0;
759         }
760     }
761
762     return 1;
763 }