OSDN Git Service

Don't let cropping get fooled by dark content - make sure that we only crop a row...
[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.fr/>.
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 LookForAudio( hb_title_t * title, hb_buffer_t * b );
27 static int  AllAudioOK( hb_title_t * title );
28
29 static const char *aspect_to_string( int aspect )
30 {
31     switch ( aspect )
32     {
33         case HB_ASPECT_BASE * 1 / 1:    return "1:1";
34         case HB_ASPECT_BASE * 4 / 3:    return "4:3";
35         case HB_ASPECT_BASE * 16 / 9:   return "16:9";
36         case HB_ASPECT_BASE * 221 / 100:   return "2.21:1";
37     }
38     static char arstr[32];
39     double a = (double)aspect / HB_ASPECT_BASE;
40     sprintf( arstr, aspect >= 1.? "%.2f:1" : "1:%.2f", a );
41     return arstr;
42 }
43
44 hb_thread_t * hb_scan_init( hb_handle_t * handle, const char * path,
45                             int title_index, hb_list_t * list_title )
46 {
47     hb_scan_t * data = calloc( sizeof( hb_scan_t ), 1 );
48
49     data->h            = handle;
50     data->path         = strdup( path );
51     data->title_index  = title_index;
52     data->list_title   = list_title;
53
54     return hb_thread_init( "scan", ScanFunc, data, HB_NORMAL_PRIORITY );
55 }
56
57 static void ScanFunc( void * _data )
58 {
59     hb_scan_t  * data = (hb_scan_t *) _data;
60     hb_title_t * title;
61     int          i;
62
63         data->dvd = NULL;
64         data->stream = NULL;
65
66     /* Try to open the path as a DVD. If it fails, try as a file */
67     hb_log( "scan: trying to open with libdvdread" );
68     if( ( data->dvd = hb_dvd_init( data->path ) ) )
69     {
70         hb_log( "scan: DVD has %d title(s)",
71                 hb_dvd_title_count( data->dvd ) );
72         if( data->title_index )
73         {
74             /* Scan this title only */
75             hb_list_add( data->list_title, hb_dvd_title_scan( data->dvd,
76                             data->title_index ) );
77         }
78         else
79         {
80             /* Scan all titles */
81             for( i = 0; i < hb_dvd_title_count( data->dvd ); i++ )
82             {
83                 hb_list_add( data->list_title,
84                              hb_dvd_title_scan( data->dvd, i + 1 ) );
85             }
86         }
87     }
88     else if ( (data->stream = hb_stream_open( data->path, 0 ) ) != NULL )
89     {
90         hb_list_add( data->list_title, hb_stream_title_scan( data->stream ) );
91     }
92     else
93     {
94         hb_log( "scan: unrecognized file type" );
95         return;
96     }
97
98     for( i = 0; i < hb_list_count( data->list_title ); )
99     {
100         int j;
101         hb_state_t state;
102         hb_audio_t * audio;
103         hb_title_t * title_tmp = NULL;
104
105         title = hb_list_item( data->list_title, i );
106
107         /* I've seen a DVD with strictly identical titles. Check this
108            here and ignore it if redundant */
109         for( j = 0; j < i; j++ )
110         {
111             title_tmp = hb_list_item( data->list_title, j );
112             if( title->vts         == title_tmp->vts &&
113                 title->block_start == title_tmp->block_start &&
114                 title->block_end   == title_tmp->block_end &&
115                 title->block_count == title_tmp->block_count )
116             {
117                 break;
118             }
119             else
120             {
121                 title_tmp = NULL;
122             }
123         }
124         if( title_tmp )
125         {
126             hb_log( "scan: title %d is duplicate with title %d",
127                     title->index, title_tmp->index );
128             hb_list_rem( data->list_title, title );
129             free( title );      /* This _will_ leak! */
130             continue;
131         }
132
133 #define p state.param.scanning
134         /* Update the UI */
135         state.state   = HB_STATE_SCANNING;
136         p.title_cur   = title->index;
137         p.title_count = data->dvd ? hb_dvd_title_count( data->dvd ) : hb_list_count(data->list_title);
138         hb_set_state( data->h, &state );
139 #undef p
140
141         /* Decode previews */
142         /* this will also detect more AC3 / DTS information */
143         if( !DecodePreviews( data, title ) )
144         {
145             /* TODO: free things */
146             hb_list_rem( data->list_title, title );
147             continue;
148         }
149
150         /* Make sure we found audio rates and bitrates */
151         for( j = 0; j < hb_list_count( title->list_audio ); )
152         {
153             audio = hb_list_item( title->list_audio, j );
154             if( !audio->config.in.bitrate )
155             {
156                 hb_log( "scan: removing audio 0x%x because no bitrate found",
157                         audio->id );
158                 hb_list_rem( title->list_audio, audio );
159                 free( audio );
160                 continue;
161             }
162             j++;
163         }
164
165         /* If we don't have any audio streams left, remove the title */
166         if( !hb_list_count( title->list_audio ) )
167         {
168             hb_list_rem( data->list_title, title );
169             free( title );
170             continue;
171         }
172
173         i++;
174     }
175
176     /* Init jobs templates */
177     for( i = 0; i < hb_list_count( data->list_title ); i++ )
178     {
179         hb_job_t * job;
180
181         title      = hb_list_item( data->list_title, i );
182         job        = calloc( sizeof( hb_job_t ), 1 );
183         title->job = job;
184
185         job->title = title;
186
187         /* Set defaults settings */
188         job->chapter_start = 1;
189         job->chapter_end   = hb_list_count( title->list_chapter );
190
191         /* Autocrop by default. Gnark gnark */
192         memcpy( job->crop, title->crop, 4 * sizeof( int ) );
193
194         /* Preserve a source's pixel aspect, if it's available. */
195         if( title->pixel_aspect_width && title->pixel_aspect_height )
196         {
197             job->pixel_aspect_width  = title->pixel_aspect_width;
198             job->pixel_aspect_height = title->pixel_aspect_height;
199         }
200
201         if( title->aspect == 16 && !job->pixel_aspect_width && !job->pixel_aspect_height)
202         {
203             hb_reduce( &job->pixel_aspect_width, &job->pixel_aspect_height,
204                        16 * title->height, 9 * title->width );
205         }
206         else if( !job->pixel_aspect_width && !job->pixel_aspect_height )
207         {
208             hb_reduce( &job->pixel_aspect_width, &job->pixel_aspect_height,
209                        4 * title->height, 3 * title->width );
210         }
211
212         job->width = title->width - job->crop[2] - job->crop[3];
213         hb_fix_aspect( job, HB_KEEP_WIDTH );
214         if( job->height > title->height - job->crop[0] - job->crop[1] )
215         {
216             job->height = title->height - job->crop[0] - job->crop[1];
217             hb_fix_aspect( job, HB_KEEP_HEIGHT );
218         }
219
220         hb_log( "scan: title (%d) job->width:%d, job->height:%d",
221                 i, job->width, job->height );
222
223         job->keep_ratio = 1;
224
225         job->vcodec     = HB_VCODEC_FFMPEG;
226         job->vquality   = -1.0;
227         job->vbitrate   = 1000;
228         job->pass       = 0;
229         job->vrate      = title->rate;
230         job->vrate_base = title->rate_base;
231
232         job->list_audio = hb_list_init();
233
234         job->subtitle = -1;
235
236         job->mux = HB_MUX_MP4;
237     }
238
239     if( data->dvd )
240     {
241         hb_dvd_close( &data->dvd );
242     }
243         if (data->stream)
244         {
245                 hb_stream_close(&data->stream);
246         }
247     free( data->path );
248     free( data );
249     _data = NULL;
250 }
251
252 // -----------------------------------------------
253 // stuff related to cropping
254
255 #define DARK 32
256
257 static inline int absdiff( int x, int y )
258 {
259     return x < y ? y - x : x - y;
260 }
261
262 static inline int clampBlack( int x ) 
263 {
264     // luma 'black' is 16 and anything less should be clamped at 16
265     return x < 16 ? 16 : x;
266 }
267
268 static int row_all_dark( hb_title_t *title, uint8_t* luma, int row )
269 {
270     luma += title->width * row;
271
272     // compute the average luma value of the row
273     int i, avg = 0;
274     for ( i = 0; i < title->width; ++i )
275     {
276         avg += clampBlack( luma[i] );
277     }
278     avg /= title->width;
279     if ( avg >= DARK )
280         return 0;
281
282     // since we're trying to detect smooth borders, only take the row if
283     // all pixels are within +-16 of the average (this range is fairly coarse
284     // but there's a lot of quantization noise for luma values near black
285     // so anything less will fail to crop because of the noise).
286     for ( i = 0; i < title->width; ++i )
287     {
288         if ( absdiff( avg, clampBlack( luma[i] ) ) > 16 )
289             return 0;
290     }
291     return 1;
292 }
293
294 static int column_all_dark( hb_title_t *title, uint8_t* luma, int top, int col )
295 {
296     int stride = title->width;
297     luma += stride * top + col;
298
299     // compute the average value of the column
300     int i = title->height - top, avg = 0, row = 0;
301     for ( ; --i >= 0; row += stride )
302     {
303         avg += clampBlack( luma[row] );
304     }
305     avg /= title->height - top;
306     if ( avg >= DARK )
307         return 0;
308
309     // since we're trying to detect smooth borders, only take the column if
310     // all pixels are within +-16 of the average.
311     i = title->height - top, row = 0;
312     for ( ; --i >= 0; row += stride )
313     {
314         if ( absdiff( avg, clampBlack( luma[row] ) ) > 16 )
315             return 0;
316     }
317     return 1;
318 }
319 #undef DARK
320
321 typedef struct {
322     int n;
323     int t[10];
324     int b[10];
325     int l[10];
326     int r[10];
327 } crop_record_t;
328
329 static void record_crop( crop_record_t *crops, int t, int b, int l, int r )
330 {
331     crops->t[crops->n] = t;
332     crops->b[crops->n] = b;
333     crops->l[crops->n] = l;
334     crops->r[crops->n] = r;
335     ++crops->n;
336 }
337
338 static int compare_int( const void *a, const void *b )
339 {
340     return *(const int *)a - *(const int *)b;
341 }
342
343 static void sort_crops( crop_record_t *crops )
344 {
345     qsort( crops->t, crops->n, sizeof(crops->t[0]), compare_int );
346     qsort( crops->b, crops->n, sizeof(crops->t[0]), compare_int );
347     qsort( crops->l, crops->n, sizeof(crops->t[0]), compare_int );
348     qsort( crops->r, crops->n, sizeof(crops->t[0]), compare_int );
349 }
350
351 // -----------------------------------------------
352 // stuff related to title width/height/aspect info
353
354 typedef struct {
355     int count;              /* number of times we've seen this info entry */
356     hb_work_info_t info;    /* copy of info entry */
357 } info_list_t;
358
359 static void remember_info( info_list_t *info_list, hb_work_info_t *info )
360 {
361     for ( ; info_list->count; ++info_list )
362     {
363         if ( memcmp( &info_list->info, info, sizeof(*info) ) == 0 )
364         {
365             // we found a match - bump its count
366             ++info_list->count;
367             return;
368         }
369     }
370     // no match found - add new entry to list (info_list points to
371     // the first free slot). NB - we assume that info_list was allocated
372     // so that it's big enough even if there are no dups. I.e., 10 slots
373     // allocated if there are 10 previews.
374     info_list->count = 1;
375     info_list->info = *info;
376 }
377
378 static void most_common_info( info_list_t *info_list, hb_work_info_t *info )
379 {
380     int i, biggest = 0;
381     for ( i = 1; info_list[i].count; ++i )
382     {
383         if ( info_list[i].count > info_list[biggest].count )
384             biggest = i;
385     }
386     *info = info_list[biggest].info;
387     free( info_list );
388 }
389
390 /***********************************************************************
391  * DecodePreviews
392  ***********************************************************************
393  * Decode 10 pictures for the given title.
394  * It assumes that data->reader and data->vts have successfully been
395  * DVDOpen()ed and ifoOpen()ed.
396  **********************************************************************/
397 static int DecodePreviews( hb_scan_t * data, hb_title_t * title )
398 {
399     int             i, npreviews = 0;
400     hb_buffer_t   * buf_ps, * buf_es;
401     hb_list_t     * list_es;
402     int progressive_count = 0;
403     int interlaced_preview_count = 0;
404     info_list_t * info_list = calloc( 10+1, sizeof(*info_list) );
405     crop_record_t *crops = calloc( 1, sizeof(*crops) );
406
407     buf_ps   = hb_buffer_init( HB_DVD_READ_BUFFER_SIZE );
408     list_es  = hb_list_init();
409
410     hb_log( "scan: decoding previews for title %d", title->index );
411
412     if (data->dvd)
413       hb_dvd_start( data->dvd, title->index, 1 );
414
415     for( i = 0; i < 10; i++ )
416     {
417         int j;
418         FILE * file_preview;
419         char   filename[1024];
420
421         if (data->dvd)
422         {
423           if( !hb_dvd_seek( data->dvd, (float) ( i + 1 ) / 11.0 ) )
424           {
425               continue;
426           }
427         }
428         else if (data->stream)
429         {
430           /* we start reading streams at zero rather than 1/11 because
431            * short streams may have only one sequence header in the entire
432            * file and we need it to decode any previews. */
433           if (!hb_stream_seek(data->stream, (float) i / 11.0 ) )
434           {
435               continue;
436           }
437         }
438
439         hb_log( "scan: preview %d", i + 1 );
440
441         int vcodec = title->video_codec? title->video_codec : WORK_DECMPEG2;
442         hb_work_object_t *vid_decoder = hb_get_work( vcodec );
443         vid_decoder->codec_param = title->video_codec_param;
444         vid_decoder->init( vid_decoder, NULL );
445         hb_buffer_t * vid_buf = NULL;
446
447         for( j = 0; j < 10240 ; j++ )
448         {
449             if (data->dvd)
450             {
451               if( !hb_dvd_read( data->dvd, buf_ps ) )
452               {
453                   hb_log( "Warning: Could not read data for preview %d, skipped", i + 1 );
454                   goto skip_preview;
455               }
456             }
457             else if (data->stream)
458             {
459               if ( !hb_stream_read(data->stream,buf_ps) )
460               {
461                   hb_log( "Warning: Could not read data for preview %d, skipped", i + 1 );
462                   goto skip_preview;
463               }
464             }
465             if ( title->demuxer == HB_NULL_DEMUXER )
466             {
467                 hb_demux_null( buf_ps, list_es, 0 );
468             }
469             else
470             {
471                 hb_demux_ps( buf_ps, list_es, 0 );
472             }
473
474             while( ( buf_es = hb_list_item( list_es, 0 ) ) )
475             {
476                 hb_list_rem( list_es, buf_es );
477                 if( buf_es->id == title->video_id && vid_buf == NULL )
478                 {
479                     vid_decoder->work( vid_decoder, &buf_es, &vid_buf );
480                 }
481                 else if( ! AllAudioOK( title ) )
482                 {
483                     LookForAudio( title, buf_es );
484                 }
485                 if ( buf_es )
486                     hb_buffer_close( &buf_es );
487             }
488
489             if( vid_buf && AllAudioOK( title ) )
490                 break;
491         }
492
493         if( ! vid_buf )
494         {
495             hb_log( "scan: could not get a decoded picture" );
496             continue;
497         }
498
499         /* Get size and rate infos */
500
501         hb_work_info_t vid_info;
502         vid_decoder->info( vid_decoder, &vid_info );
503         vid_decoder->close( vid_decoder );
504         free( vid_decoder );
505
506         remember_info( info_list, &vid_info );
507
508         title->width = vid_info.width;
509         title->height = vid_info.height;
510         title->rate = vid_info.rate;
511         title->rate_base = vid_info.rate_base;
512
513         if( title->rate_base == 1126125 )
514         {
515             /* Frame FPS is 23.976 (meaning it's progressive), so
516                start keeping track of how many are reporting at
517                that speed. When enough show up that way, we want
518                to make that the overall title FPS.
519             */
520             progressive_count++;
521
522             if( progressive_count < 6 )
523             {
524                 /* Not enough frames are reporting as progressive,
525                    which means we should be conservative and use
526                    29.97 as the title's FPS for now.
527                 */
528                 title->rate_base = 900900;
529             }
530             else
531             {
532                 /* A majority of the scan frames are progressive. Make that
533                     the title's FPS, and announce it once to the log.
534                 */
535                 if( progressive_count == 6 )
536                 {
537                     hb_log("Title's mostly NTSC Film, setting fps to 23.976");
538                 }
539                 title->rate_base = 1126125;
540             }
541         }
542         else if( title->rate_base == 900900 && progressive_count >= 6 )
543         {
544             /*
545              * We've already deduced that the frame rate is 23.976, so set it
546              * back again.
547              */
548             title->rate_base = 1126125;
549         }
550
551         while( ( buf_es = hb_list_item( list_es, 0 ) ) )
552         {
553             hb_list_rem( list_es, buf_es );
554             hb_buffer_close( &buf_es );
555         }
556
557         /* Check preview for interlacing artifacts */
558         if( hb_detect_comb( vid_buf, title->width, title->height, 10, 30, 9, 10, 30, 9 ) )
559         {
560             hb_log("Interlacing detected in preview frame %i", i+1);
561             interlaced_preview_count++;
562         }
563
564         hb_get_tempory_filename( data->h, filename, "%x%d",
565                                  (intptr_t)title, i );
566
567         file_preview = fopen( filename, "w" );
568         if( file_preview )
569         {
570             fwrite( vid_buf->data, title->width * title->height * 3 / 2,
571                     1, file_preview );
572             fclose( file_preview );
573         }
574         else
575         {
576             hb_log( "scan: fopen failed (%s)", filename );
577         }
578
579         /* Detect black borders */
580
581 #define Y    vid_buf->data
582         int top, bottom, left, right;
583         int h4 = title->height / 4, w4 = title->width / 4;
584         for ( top = 4; top < h4; ++top )
585         {
586             if ( ! row_all_dark( title, Y, top ) )
587                 break;
588         }
589         if ( top < 5 )
590         {
591             // we started at row 4 to avoid the "line 21" noise that shows
592             // up on row 0 & 1 of some TV shows. Since we stopped before row 4
593             // check if the missed rows are dark or if we shouldn't crop at all.
594             for ( top = 0; top < 4; ++top )
595             {
596                 if ( ! row_all_dark( title, Y, top ) )
597                     break;
598             }
599             if ( top >= 4 )
600             {
601                 top = 0;
602             }
603         }
604         for ( bottom = 0; bottom < h4; ++bottom )
605         {
606             if ( ! row_all_dark( title, Y, title->height - 1 - bottom ) )
607                 break;
608         }
609         for ( left = 0; left < w4; ++left )
610         {
611             if ( ! column_all_dark( title, Y, top, left ) )
612                 break;
613         }
614         for ( right = 0; right < w4; ++right )
615         {
616             if ( ! column_all_dark( title, Y, top, title->width - 1 - right ) )
617                 break;
618         }
619
620         // only record the result if all the crops are less than a quarter of
621         // the frame otherwise we can get fooled by frames with a lot of black
622         // like titles, credits & fade-thru-black transitions.
623         if ( top < h4 && bottom < h4 && left < w4 && right < w4 )
624         {
625             record_crop( crops, top, bottom, left, right );
626         }
627         ++npreviews;
628
629 skip_preview:
630         if ( vid_buf )
631             hb_buffer_close( &vid_buf );
632     }
633
634     if ( npreviews )
635     {
636         // use the most common frame info for our final title dimensions
637         hb_work_info_t vid_info;
638         most_common_info( info_list, &vid_info );
639
640         title->width = vid_info.width;
641         title->height = vid_info.height;
642         title->pixel_aspect_width = vid_info.pixel_aspect_width;
643         title->pixel_aspect_height = vid_info.pixel_aspect_height;
644
645         // compute the aspect ratio based on the storage dimensions and the
646         // pixel aspect ratio (if supplied) or just storage dimensions if no PAR.
647         title->aspect = ( (double)title->width / (double)title->height + 0.05 ) *
648                         HB_ASPECT_BASE;
649
650         double aspect = (double)title->width / (double)title->height;
651         if( title->pixel_aspect_width && title->pixel_aspect_height )
652         {
653             aspect *= (double)title->pixel_aspect_width /
654                       (double)title->pixel_aspect_height;
655         }
656         title->aspect = ( aspect + 0.05 ) * HB_ASPECT_BASE;
657
658         // don't try to crop unless we got at least 3 previews
659         if ( crops->n > 2 )
660         {
661             sort_crops( crops );
662             // The next line selects median cropping - at least
663             // 50% of the frames will have their borders removed.
664             // Other possible choices are loose cropping (i = 0) where 
665             // no non-black pixels will be cropped from any frame and a
666             // tight cropping (i = crops->n - (crops->n >> 2)) where at
667             // least 75% of the frames will have their borders removed.
668             i = crops->n >> 1;
669             title->crop[0] = EVEN( crops->t[i] );
670             title->crop[1] = EVEN( crops->b[i] );
671             title->crop[2] = EVEN( crops->l[i] );
672             title->crop[3] = EVEN( crops->r[i] );
673         }
674         free( crops );
675
676         hb_log( "scan: %d previews, %dx%d, %.3f fps, autocrop = %d/%d/%d/%d, "
677                 "aspect %s, PAR %d:%d",
678                 npreviews, title->width, title->height, (float) title->rate /
679                 (float) title->rate_base,
680                 title->crop[0], title->crop[1], title->crop[2], title->crop[3],
681                 aspect_to_string( title->aspect ), title->pixel_aspect_width,
682                 title->pixel_aspect_height );
683
684         if( interlaced_preview_count >= ( npreviews / 2 ) )
685         {
686             hb_log("Title is likely interlaced or telecined (%i out of %i previews). You should do something about that.",
687                    interlaced_preview_count, npreviews);
688             title->detected_interlacing = 1;
689         }
690         else
691         {
692             title->detected_interlacing = 0;
693         }
694     }
695
696     hb_buffer_close( &buf_ps );
697     while( ( buf_es = hb_list_item( list_es, 0 ) ) )
698     {
699         hb_list_rem( list_es, buf_es );
700         hb_buffer_close( &buf_es );
701     }
702     hb_list_close( &list_es );
703     if (data->dvd)
704       hb_dvd_stop( data->dvd );
705
706     return npreviews;
707 }
708
709 /*
710  * This routine is called for every frame from a non-video elementary stream.
711  * These are a mix of audio & subtitle streams, some of which we want & some
712  * we're ignoring. This routine checks the frame against all our audio streams
713  * to see if it's one we want and haven't identified yet. If yes, it passes the
714  * frame to a codec-specific id routine which is responsible for filling in
715  * the sample rate, bit rate, channels & other audio parameters.
716  *
717  * Since a sample rate is essential for further audio processing, any audio
718  * stream which isn't successfully id'd by is deleted at the end of the scan.
719  * This is necessary to avoid ambiguities where things that might be audio
720  * aren't (e.g., some European DVD Teletext streams use the same IDs as US ATSC
721  * AC-3 audio).
722  */
723 static void LookForAudio( hb_title_t * title, hb_buffer_t * b )
724 {
725     int i;
726
727     hb_audio_t * audio = NULL;
728     for( i = 0; i < hb_list_count( title->list_audio ); i++ )
729     {
730         audio = hb_list_item( title->list_audio, i );
731         /* check if this elementary stream is one we want */
732         if ( audio->id == b->id )
733         {
734             break;
735         }
736         else
737         {
738             audio = NULL;
739         }
740     }
741     if( !audio || audio->config.in.bitrate != 0 )
742     {
743         /* not found or already done */
744         return;
745     }
746
747     hb_work_object_t *w = hb_codec_decoder( audio->config.in.codec );
748
749     if ( w == NULL || w->bsinfo == NULL )
750     {
751         hb_log( "Internal error in scan: unhandled audio type %d for id 0x%x",
752                 audio->config.in.codec, audio->id );
753         goto drop_audio;
754     }
755
756     hb_work_info_t info;
757     w->audio = audio;
758     w->codec_param = audio->config.in.codec_param;
759     int ret = w->bsinfo( w, b, &info );
760     if ( ret < 0 )
761     {
762         hb_log( "no info on audio type %d/0x%x for id 0x%x",
763                 audio->config.in.codec, audio->config.in.codec_param,
764                 audio->id );
765         goto drop_audio;
766     }
767     if ( !info.bitrate )
768     {
769         /* didn't find any info */
770         return;
771     }
772     audio->config.in.samplerate = info.rate;
773     audio->config.in.bitrate = info.bitrate;
774     audio->config.in.channel_layout = info.channel_layout;
775     audio->config.flags.ac3 = info.flags;
776
777     // update the audio description string based on the info we found
778     if ( audio->config.flags.ac3 & AUDIO_F_DOLBY )
779     {
780         strcat( audio->config.lang.description, " (Dolby Surround)" );
781     }
782     else
783     {
784         int layout = audio->config.in.channel_layout;
785         char *desc = audio->config.lang.description +
786                         strlen( audio->config.lang.description );
787         sprintf( desc, " (%d.%d ch)",
788                  HB_INPUT_CH_LAYOUT_GET_DISCRETE_FRONT_COUNT(layout) +
789                      HB_INPUT_CH_LAYOUT_GET_DISCRETE_REAR_COUNT(layout),
790                  HB_INPUT_CH_LAYOUT_GET_DISCRETE_LFE_COUNT(layout) );
791     }
792
793     hb_log( "scan: audio 0x%x: %s, rate=%dHz, bitrate=%d %s", audio->id,
794             info.name, audio->config.in.samplerate, audio->config.in.bitrate,
795             audio->config.lang.description );
796  
797     free( w );
798     return;
799
800     // We get here if there's no hope of finding info on an audio bitstream,
801     // either because we don't have a decoder (or a decoder with a bitstream
802     // info proc) or because the decoder's info proc said that the stream
803     // wasn't something it could handle. Delete the item from the title's
804     // audio list so we won't keep reading packets while trying to get its
805     // bitstream info.
806  drop_audio:
807     if ( w )
808         free( w );
809
810     hb_list_rem( title->list_audio, audio );
811 }
812
813 /*
814  * This routine checks to see if we've ID'd all the audio streams associated
815  * with a title. It returns 0 if there are more to ID & 1 if all are done.
816  */
817 static int  AllAudioOK( hb_title_t * title )
818 {
819     int i;
820     hb_audio_t * audio;
821
822     for( i = 0; i < hb_list_count( title->list_audio ); i++ )
823     {
824         audio = hb_list_item( title->list_audio, i );
825         if( audio->config.in.bitrate == 0 )
826         {
827             return 0;
828         }
829     }
830     return 1;
831 }