OSDN Git Service

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