OSDN Git Service

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