1 /* $Id: scan.c,v 1.52 2005/11/25 15:05:25 titer Exp $
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. */
8 #include "a52dec/a52.h"
11 #define HB_MAX_PREVIEWS 30 // 30 previews = every 5 minutes of a 2.5 hour video
20 hb_list_t * list_title;
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 );
36 static const char *aspect_to_string( double aspect )
38 switch ( (int)(aspect * 9.) )
40 case 9 * 4 / 3: return "4:3";
41 case 9 * 16 / 9: return "16:9";
43 static char arstr[32];
44 sprintf( arstr, aspect >= 1.? "%.2f:1" : "1:%.2f", aspect );
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,
53 hb_scan_t * data = calloc( sizeof( hb_scan_t ), 1 );
57 data->path = strdup( path );
58 data->title_index = title_index;
59 data->list_title = list_title;
61 data->preview_count = preview_count;
62 data->store_previews = store_previews;
64 return hb_thread_init( "scan", ScanFunc, data, HB_NORMAL_PRIORITY );
67 static void ScanFunc( void * _data )
69 hb_scan_t * data = (hb_scan_t *) _data;
77 /* Try to open the path as a DVD. If it fails, try as a file */
78 hb_log( "scan: trying to open with libdvdread" );
79 if( ( data->dvd = hb_dvd_init( data->path ) ) )
81 hb_log( "scan: DVD has %d title(s)",
82 hb_dvd_title_count( data->dvd ) );
83 if( data->title_index )
85 /* Scan this title only */
86 hb_list_add( data->list_title, hb_dvd_title_scan( data->dvd,
87 data->title_index ) );
92 for( i = 0; i < hb_dvd_title_count( data->dvd ); i++ )
94 hb_list_add( data->list_title,
95 hb_dvd_title_scan( data->dvd, i + 1 ) );
97 feature = hb_dvd_main_feature( data->dvd, data->list_title );
100 else if ( ( data->batch = hb_batch_init( data->path ) ) )
104 /* Scan all titles */
105 for( i = 0; i < hb_batch_title_count( data->batch ); i++ )
109 title = hb_batch_title_scan( data->batch, i );
113 hb_list_add( data->list_title, title );
117 else if ( (data->stream = hb_stream_open( data->path, 0 ) ) != NULL )
119 hb_list_add( data->list_title, hb_stream_title_scan( data->stream ) );
123 hb_log( "scan: unrecognized file type" );
127 for( i = 0; i < hb_list_count( data->list_title ); )
137 title = hb_list_item( data->list_title, i );
139 #define p state.param.scanning
141 state.state = HB_STATE_SCANNING;
142 p.title_cur = title->index;
143 p.title_count = data->dvd ? hb_dvd_title_count( data->dvd ) : hb_list_count(data->list_title);
144 hb_set_state( data->h, &state );
147 /* Decode previews */
148 /* this will also detect more AC3 / DTS information */
149 if( !DecodePreviews( data, title ) )
151 /* TODO: free things */
152 hb_list_rem( data->list_title, title );
156 /* Make sure we found audio rates and bitrates */
157 for( j = 0; j < hb_list_count( title->list_audio ); )
159 audio = hb_list_item( title->list_audio, j );
160 if( !audio->config.in.bitrate )
162 hb_log( "scan: removing audio 0x%x because no bitrate found",
164 hb_list_rem( title->list_audio, audio );
168 if ( audio->priv.scan_cache )
170 hb_fifo_flush( audio->priv.scan_cache );
171 hb_fifo_close( &audio->priv.scan_cache );
178 // The subtitle width and height needs to be set to the
179 // title widht and height for DVDs. title width and
180 // height don't get set until we decode previews, so
181 // we can't set subtitle width/height till we get here.
182 for( j = 0; j < hb_list_count( title->list_subtitle ); j++ )
184 hb_subtitle_t *subtitle = hb_list_item( title->list_subtitle, j );
185 if ( subtitle->source == VOBSUB )
187 subtitle->width = title->width;
188 subtitle->height = title->height;
195 /* Init jobs templates */
196 for( i = 0; i < hb_list_count( data->list_title ); i++ )
200 title = hb_list_item( data->list_title, i );
201 job = calloc( sizeof( hb_job_t ), 1 );
205 job->feature = feature;
207 /* Set defaults settings */
208 job->chapter_start = 1;
209 job->chapter_end = hb_list_count( title->list_chapter );
211 /* Autocrop by default. Gnark gnark */
212 memcpy( job->crop, title->crop, 4 * sizeof( int ) );
214 /* Preserve a source's pixel aspect, if it's available. */
215 if( title->pixel_aspect_width && title->pixel_aspect_height )
217 job->anamorphic.par_width = title->pixel_aspect_width;
218 job->anamorphic.par_height = title->pixel_aspect_height;
221 if( title->aspect != 0 && title->aspect != 1. &&
222 !job->anamorphic.par_width && !job->anamorphic.par_height)
224 hb_reduce( &job->anamorphic.par_width, &job->anamorphic.par_height,
225 (int)(title->aspect * title->height + 0.5), title->width );
228 job->width = title->width - job->crop[2] - job->crop[3];
229 hb_fix_aspect( job, HB_KEEP_WIDTH );
230 if( job->height > title->height - job->crop[0] - job->crop[1] )
232 job->height = title->height - job->crop[0] - job->crop[1];
233 hb_fix_aspect( job, HB_KEEP_HEIGHT );
236 hb_log( "scan: title (%d) job->width:%d, job->height:%d",
237 i, job->width, job->height );
241 job->vcodec = HB_VCODEC_FFMPEG;
242 job->vquality = -1.0;
243 job->vbitrate = 1000;
245 job->vrate = title->rate;
246 job->vrate_base = title->rate_base;
248 job->list_audio = hb_list_init();
249 job->list_subtitle = hb_list_init();
251 job->mux = HB_MUX_MP4;
258 hb_dvd_close( &data->dvd );
262 hb_stream_close(&data->stream);
266 hb_batch_close( &data->batch );
273 // -----------------------------------------------
274 // stuff related to cropping
278 static inline int absdiff( int x, int y )
280 return x < y ? y - x : x - y;
283 static inline int clampBlack( int x )
285 // luma 'black' is 16 and anything less should be clamped at 16
286 return x < 16 ? 16 : x;
289 static int row_all_dark( hb_title_t *title, uint8_t* luma, int row )
291 luma += title->width * row;
293 // compute the average luma value of the row
295 for ( i = 0; i < title->width; ++i )
297 avg += clampBlack( luma[i] );
303 // since we're trying to detect smooth borders, only take the row if
304 // all pixels are within +-16 of the average (this range is fairly coarse
305 // but there's a lot of quantization noise for luma values near black
306 // so anything less will fail to crop because of the noise).
307 for ( i = 0; i < title->width; ++i )
309 if ( absdiff( avg, clampBlack( luma[i] ) ) > 16 )
315 static int column_all_dark( hb_title_t *title, uint8_t* luma, int top, int bottom,
318 int stride = title->width;
319 int height = title->height - top - bottom;
320 luma += stride * top + col;
322 // compute the average value of the column
323 int i = height, avg = 0, row = 0;
324 for ( ; --i >= 0; row += stride )
326 avg += clampBlack( luma[row] );
332 // since we're trying to detect smooth borders, only take the column if
333 // all pixels are within +-16 of the average.
335 for ( ; --i >= 0; row += stride )
337 if ( absdiff( avg, clampBlack( luma[row] ) ) > 16 )
346 int t[HB_MAX_PREVIEWS];
347 int b[HB_MAX_PREVIEWS];
348 int l[HB_MAX_PREVIEWS];
349 int r[HB_MAX_PREVIEWS];
352 static void record_crop( crop_record_t *crops, int t, int b, int l, int r )
354 crops->t[crops->n] = t;
355 crops->b[crops->n] = b;
356 crops->l[crops->n] = l;
357 crops->r[crops->n] = r;
361 static int compare_int( const void *a, const void *b )
363 return *(const int *)a - *(const int *)b;
366 static void sort_crops( crop_record_t *crops )
368 qsort( crops->t, crops->n, sizeof(crops->t[0]), compare_int );
369 qsort( crops->b, crops->n, sizeof(crops->t[0]), compare_int );
370 qsort( crops->l, crops->n, sizeof(crops->t[0]), compare_int );
371 qsort( crops->r, crops->n, sizeof(crops->t[0]), compare_int );
374 // -----------------------------------------------
375 // stuff related to title width/height/aspect info
378 int count; /* number of times we've seen this info entry */
379 hb_work_info_t info; /* copy of info entry */
382 static void remember_info( info_list_t *info_list, hb_work_info_t *info )
384 for ( ; info_list->count; ++info_list )
386 if ( memcmp( &info_list->info, info, sizeof(*info) ) == 0 )
388 // we found a match - bump its count
393 // no match found - add new entry to list (info_list points to
394 // the first free slot). NB - we assume that info_list was allocated
395 // so that it's big enough even if there are no dups. I.e., 10 slots
396 // allocated if there are 10 previews.
397 info_list->count = 1;
398 info_list->info = *info;
401 static void most_common_info( info_list_t *info_list, hb_work_info_t *info )
404 for ( i = 1; info_list[i].count; ++i )
406 if ( info_list[i].count > info_list[biggest].count )
409 *info = info_list[biggest].info;
413 /***********************************************************************
415 ***********************************************************************
416 * Decode 10 pictures for the given title.
417 * It assumes that data->reader and data->vts have successfully been
418 * DVDOpen()ed and ifoOpen()ed.
419 **********************************************************************/
420 static int DecodePreviews( hb_scan_t * data, hb_title_t * title )
422 int i, npreviews = 0;
423 hb_buffer_t * buf_ps, * buf_es;
425 int progressive_count = 0;
426 int interlaced_preview_count = 0;
427 info_list_t * info_list = calloc( data->preview_count+1, sizeof(*info_list) );
428 crop_record_t *crops = calloc( 1, sizeof(*crops) );
430 buf_ps = hb_buffer_init( HB_DVD_READ_BUFFER_SIZE );
431 list_es = hb_list_init();
433 hb_log( "scan: decoding previews for title %d", title->index );
437 hb_dvd_start( data->dvd, title, 1 );
438 title->angle_count = hb_dvd_angle_count( data->dvd );
439 hb_log( "scan: title angle(s) %d", title->angle_count );
441 else if (data->batch)
443 data->stream = hb_stream_open( title->path, title );
446 for( i = 0; i < data->preview_count; i++ )
458 if( !hb_dvd_seek( data->dvd, (float) ( i + 1 ) / ( data->preview_count + 1.0 ) ) )
463 else if (data->stream)
465 /* we start reading streams at zero rather than 1/11 because
466 * short streams may have only one sequence header in the entire
467 * file and we need it to decode any previews. */
468 if (!hb_stream_seek(data->stream, (float) i / ( data->preview_count + 1.0 ) ) )
474 hb_deep_log( 2, "scan: preview %d", i + 1 );
476 int vcodec = title->video_codec? title->video_codec : WORK_DECMPEG2;
477 hb_work_object_t *vid_decoder = hb_get_work( vcodec );
478 vid_decoder->codec_param = title->video_codec_param;
479 vid_decoder->title = title;
480 vid_decoder->init( vid_decoder, NULL );
481 hb_buffer_t * vid_buf = NULL;
484 if ( title->flags & HBTF_NO_IDR )
486 // title doesn't have IDR frames so we decode but drop one second's
487 // worth of frames to allow the decoder to converge.
488 if ( ! title->rate_base )
494 vidskip = (double)title->rate / (double)title->rate_base + 0.5;
498 for( j = 0; j < 10240 ; j++ )
502 if( !hb_dvd_read( data->dvd, buf_ps ) )
508 hb_log( "Warning: Could not read data for preview %d, skipped", i + 1 );
512 else if (data->stream)
514 if ( !hb_stream_read(data->stream,buf_ps) )
520 hb_log( "Warning: Could not read data for preview %d, skipped", i + 1 );
524 (hb_demux[title->demuxer])(buf_ps, list_es, 0 );
526 while( ( buf_es = hb_list_item( list_es, 0 ) ) )
528 hb_list_rem( list_es, buf_es );
529 if( buf_es->id == title->video_id && vid_buf == NULL )
531 vid_decoder->work( vid_decoder, &buf_es, &vid_buf );
532 if ( vid_buf && vidskip && --vidskip > 0 )
534 // we're dropping frames to get the video decoder in sync
535 // when the video stream doesn't contain IDR frames
536 hb_buffer_close( &vid_buf );
540 else if( ! AllAudioOK( title ) )
542 LookForAudio( title, buf_es );
546 hb_buffer_close( &buf_es );
549 if( vid_buf && AllAudioOK( title ) )
555 hb_log( "scan: could not get a decoded picture" );
559 /* Get size and rate infos */
561 hb_work_info_t vid_info;
562 if( !vid_decoder->info( vid_decoder, &vid_info ) )
565 * Could not fill vid_info, don't continue and try to use vid_info
568 vid_decoder->close( vid_decoder );
572 vid_decoder->close( vid_decoder );
575 remember_info( info_list, &vid_info );
577 title->video_codec_name = strdup( vid_info.name );
578 title->width = vid_info.width;
579 title->height = vid_info.height;
580 title->rate = vid_info.rate;
581 title->rate_base = vid_info.rate_base;
582 title->video_bitrate = vid_info.bitrate;
584 if( title->rate_base == 1126125 )
586 /* Frame FPS is 23.976 (meaning it's progressive), so
587 start keeping track of how many are reporting at
588 that speed. When enough show up that way, we want
589 to make that the overall title FPS.
593 if( progressive_count < 6 )
595 /* Not enough frames are reporting as progressive,
596 which means we should be conservative and use
597 29.97 as the title's FPS for now.
599 title->rate_base = 900900;
603 /* A majority of the scan frames are progressive. Make that
604 the title's FPS, and announce it once to the log.
606 if( progressive_count == 6 )
608 hb_deep_log( 2, "Title's mostly NTSC Film, setting fps to 23.976");
610 title->rate_base = 1126125;
613 else if( title->rate_base == 900900 && progressive_count >= 6 )
616 * We've already deduced that the frame rate is 23.976, so set it
619 title->rate_base = 1126125;
622 while( ( buf_es = hb_list_item( list_es, 0 ) ) )
624 hb_list_rem( list_es, buf_es );
625 hb_buffer_close( &buf_es );
628 /* Check preview for interlacing artifacts */
629 if( hb_detect_comb( vid_buf, title->width, title->height, 10, 30, 9, 10, 30, 9 ) )
631 hb_deep_log( 2, "Interlacing detected in preview frame %i", i+1);
632 interlaced_preview_count++;
635 if( data->store_previews )
637 hb_get_tempory_filename( data->h, filename, "%d_%d_%d",
638 hb_get_instance_id(data->h), title->index, i );
640 file_preview = fopen( filename, "wb" );
643 fwrite( vid_buf->data, title->width * title->height * 3 / 2,
645 fclose( file_preview );
649 hb_log( "scan: fopen failed (%s)", filename );
653 /* Detect black borders */
655 #define Y vid_buf->data
656 int top, bottom, left, right;
657 int h4 = title->height / 4, w4 = title->width / 4;
659 // When widescreen content is matted to 16:9 or 4:3 there's sometimes
660 // a thin border on the outer edge of the matte. On TV content it can be
661 // "line 21" VBI data that's normally hidden in the overscan. For HD
662 // content it can just be a diagnostic added in post production so that
663 // the frame borders are visible. We try to ignore these borders so
664 // we can crop the matte. The border width depends on the resolution
665 // (12 pixels on 1080i looks visually the same as 4 pixels on 480i)
666 // so we allow the border to be up to 1% of the frame height.
667 const int border = title->height / 100;
669 for ( top = border; top < h4; ++top )
671 if ( ! row_all_dark( title, Y, top ) )
676 // we never made it past the border region - see if the rows we
677 // didn't check are dark or if we shouldn't crop at all.
678 for ( top = 0; top < border; ++top )
680 if ( ! row_all_dark( title, Y, top ) )
688 for ( bottom = border; bottom < h4; ++bottom )
690 if ( ! row_all_dark( title, Y, title->height - 1 - bottom ) )
693 if ( bottom <= border )
695 for ( bottom = 0; bottom < border; ++bottom )
697 if ( ! row_all_dark( title, Y, title->height - 1 - bottom ) )
700 if ( bottom >= border )
705 for ( left = 0; left < w4; ++left )
707 if ( ! column_all_dark( title, Y, top, bottom, left ) )
710 for ( right = 0; right < w4; ++right )
712 if ( ! column_all_dark( title, Y, top, bottom, title->width - 1 - right ) )
716 // only record the result if all the crops are less than a quarter of
717 // the frame otherwise we can get fooled by frames with a lot of black
718 // like titles, credits & fade-thru-black transitions.
719 if ( top < h4 && bottom < h4 && left < w4 && right < w4 )
721 record_crop( crops, top, bottom, left, right );
726 /* Make sure we found audio rates and bitrates */
727 for( j = 0; j < hb_list_count( title->list_audio ); j++ )
729 hb_audio_t * audio = hb_list_item( title->list_audio, j );
730 if ( audio->priv.scan_cache )
732 hb_fifo_flush( audio->priv.scan_cache );
736 hb_buffer_close( &vid_buf );
739 if ( data->batch && data->stream )
741 hb_stream_close( &data->stream );
746 // use the most common frame info for our final title dimensions
747 hb_work_info_t vid_info;
748 most_common_info( info_list, &vid_info );
750 title->width = vid_info.width;
751 title->height = vid_info.height;
752 title->pixel_aspect_width = vid_info.pixel_aspect_width;
753 title->pixel_aspect_height = vid_info.pixel_aspect_height;
755 // compute the aspect ratio based on the storage dimensions and the
756 // pixel aspect ratio (if supplied) or just storage dimensions if no PAR.
757 title->aspect = (double)title->width / (double)title->height;
758 if( title->pixel_aspect_width && title->pixel_aspect_height )
760 title->aspect *= (double)title->pixel_aspect_width /
761 (double)title->pixel_aspect_height;
763 // For unknown reasons some French PAL DVDs put the original
764 // content's aspect ratio into the mpeg PAR even though it's
765 // the wrong PAR for the DVD. Apparently they rely on the fact
766 // that DVD players ignore the content PAR and just use the
767 // aspect ratio from the DVD metadata. So, if the aspect computed
768 // from the PAR is different from the container's aspect we use
769 // the container's aspect & recompute the PAR from it.
770 if( title->container_aspect && (int)(title->aspect * 9) != (int)(title->container_aspect * 9) )
772 hb_log("scan: content PAR gives wrong aspect %.2f; "
773 "using container aspect %.2f", title->aspect,
774 title->container_aspect );
775 title->aspect = title->container_aspect;
776 hb_reduce( &title->pixel_aspect_width, &title->pixel_aspect_height,
777 (int)(title->aspect * title->height + 0.5), title->width );
781 // don't try to crop unless we got at least 3 previews
785 // The next line selects median cropping - at least
786 // 50% of the frames will have their borders removed.
787 // Other possible choices are loose cropping (i = 0) where
788 // no non-black pixels will be cropped from any frame and a
789 // tight cropping (i = crops->n - (crops->n >> 2)) where at
790 // least 75% of the frames will have their borders removed.
792 title->crop[0] = EVEN( crops->t[i] );
793 title->crop[1] = EVEN( crops->b[i] );
794 title->crop[2] = EVEN( crops->l[i] );
795 title->crop[3] = EVEN( crops->r[i] );
799 hb_log( "scan: %d previews, %dx%d, %.3f fps, autocrop = %d/%d/%d/%d, "
800 "aspect %s, PAR %d:%d",
801 npreviews, title->width, title->height, (float) title->rate /
802 (float) title->rate_base,
803 title->crop[0], title->crop[1], title->crop[2], title->crop[3],
804 aspect_to_string( title->aspect ), title->pixel_aspect_width,
805 title->pixel_aspect_height );
807 if( interlaced_preview_count >= ( npreviews / 2 ) )
809 hb_log("Title is likely interlaced or telecined (%i out of %i previews). You should do something about that.",
810 interlaced_preview_count, npreviews);
811 title->detected_interlacing = 1;
815 title->detected_interlacing = 0;
819 hb_buffer_close( &buf_ps );
820 while( ( buf_es = hb_list_item( list_es, 0 ) ) )
822 hb_list_rem( list_es, buf_es );
823 hb_buffer_close( &buf_es );
825 hb_list_close( &list_es );
827 hb_dvd_stop( data->dvd );
833 * This routine is called for every frame from a non-video elementary stream.
834 * These are a mix of audio & subtitle streams, some of which we want & some
835 * we're ignoring. This routine checks the frame against all our audio streams
836 * to see if it's one we want and haven't identified yet. If yes, it passes the
837 * frame to a codec-specific id routine which is responsible for filling in
838 * the sample rate, bit rate, channels & other audio parameters.
840 * Since a sample rate is essential for further audio processing, any audio
841 * stream which isn't successfully id'd by is deleted at the end of the scan.
842 * This is necessary to avoid ambiguities where things that might be audio
843 * aren't (e.g., some European DVD Teletext streams use the same IDs as US ATSC
846 static void LookForAudio( hb_title_t * title, hb_buffer_t * b )
850 hb_audio_t * audio = NULL;
851 for( i = 0; i < hb_list_count( title->list_audio ); i++ )
853 audio = hb_list_item( title->list_audio, i );
854 /* check if this elementary stream is one we want */
855 if ( audio->id == b->id )
864 if( !audio || audio->config.in.bitrate != 0 )
866 /* not found or already done */
867 hb_buffer_close( &b );
871 if ( audio->priv.scan_cache == NULL )
872 audio->priv.scan_cache = hb_fifo_init( 16, 16 );
874 if ( hb_fifo_size_bytes( audio->priv.scan_cache ) >= 4096 )
877 tmp = hb_fifo_get( audio->priv.scan_cache );
878 hb_buffer_close( &tmp );
880 hb_fifo_push( audio->priv.scan_cache, b );
882 hb_work_object_t *w = hb_codec_decoder( audio->config.in.codec );
884 if ( w == NULL || w->bsinfo == NULL )
886 hb_log( "Internal error in scan: unhandled audio type %d for id 0x%x",
887 audio->config.in.codec, audio->id );
893 w->codec_param = audio->config.in.codec_param;
894 b = hb_fifo_see( audio->priv.scan_cache );
895 int ret = w->bsinfo( w, b, &info );
898 hb_log( "no info on audio type %d/0x%x for id 0x%x",
899 audio->config.in.codec, audio->config.in.codec_param,
905 /* didn't find any info */
908 hb_fifo_flush( audio->priv.scan_cache );
909 hb_fifo_close( &audio->priv.scan_cache );
911 audio->config.in.samplerate = info.rate;
912 audio->config.in.bitrate = info.bitrate;
913 audio->config.in.channel_layout = info.channel_layout;
914 audio->config.in.version = info.version;
915 audio->config.in.mode = info.mode;
916 audio->config.flags.ac3 = info.flags;
918 // update the audio description string based on the info we found
919 if ( audio->config.flags.ac3 & AUDIO_F_DOLBY )
921 strcat( audio->config.lang.description, " (Dolby Surround)" );
925 int layout = audio->config.in.channel_layout;
926 char *desc = audio->config.lang.description +
927 strlen( audio->config.lang.description );
928 sprintf( desc, " (%d.%d ch)",
929 HB_INPUT_CH_LAYOUT_GET_DISCRETE_FRONT_COUNT(layout) +
930 HB_INPUT_CH_LAYOUT_GET_DISCRETE_REAR_COUNT(layout),
931 HB_INPUT_CH_LAYOUT_GET_DISCRETE_LFE_COUNT(layout) );
934 hb_log( "scan: audio 0x%x: %s, rate=%dHz, bitrate=%d %s", audio->id,
935 info.name, audio->config.in.samplerate, audio->config.in.bitrate,
936 audio->config.lang.description );
941 // We get here if there's no hope of finding info on an audio bitstream,
942 // either because we don't have a decoder (or a decoder with a bitstream
943 // info proc) or because the decoder's info proc said that the stream
944 // wasn't something it could handle. Delete the item from the title's
945 // audio list so we won't keep reading packets while trying to get its
951 hb_fifo_flush( audio->priv.scan_cache );
952 hb_fifo_close( &audio->priv.scan_cache );
953 hb_list_rem( title->list_audio, audio );
958 * This routine checks to see if we've ID'd all the audio streams associated
959 * with a title. It returns 0 if there are more to ID & 1 if all are done.
961 static int AllAudioOK( hb_title_t * title )
966 for( i = 0; i < hb_list_count( title->list_audio ); i++ )
968 audio = hb_list_item( title->list_audio, i );
969 if( audio->config.in.bitrate == 0 )