OSDN Git Service

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