OSDN Git Service

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