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"
17 hb_list_t * list_title;
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 );
29 hb_thread_t * hb_scan_init( hb_handle_t * handle, const char * path,
30 int title_index, hb_list_t * list_title )
32 hb_scan_t * data = calloc( sizeof( hb_scan_t ), 1 );
35 data->path = strdup( path );
36 data->title_index = title_index;
37 data->list_title = list_title;
39 return hb_thread_init( "scan", ScanFunc, data, HB_NORMAL_PRIORITY );
42 static void ScanFunc( void * _data )
44 hb_scan_t * data = (hb_scan_t *) _data;
51 /* Try to open the path as a DVD. If it fails, try as a file */
52 hb_log( "scan: trying to open with libdvdread" );
53 if( ( data->dvd = hb_dvd_init( data->path ) ) )
55 hb_log( "scan: DVD has %d title(s)",
56 hb_dvd_title_count( data->dvd ) );
57 if( data->title_index )
59 /* Scan this title only */
60 hb_list_add( data->list_title, hb_dvd_title_scan( data->dvd,
61 data->title_index ) );
66 for( i = 0; i < hb_dvd_title_count( data->dvd ); i++ )
68 hb_list_add( data->list_title,
69 hb_dvd_title_scan( data->dvd, i + 1 ) );
73 else if ( (data->stream = hb_stream_open( data->path, 0 ) ) != NULL )
75 hb_list_add( data->list_title, hb_stream_title_scan( data->stream ) );
79 hb_log( "scan: unrecognized file type" );
83 for( i = 0; i < hb_list_count( data->list_title ); )
88 hb_title_t * title_tmp = NULL;
90 title = hb_list_item( data->list_title, i );
92 /* I've seen a DVD with strictly identical titles. Check this
93 here and ignore it if redundant */
94 for( j = 0; j < i; j++ )
96 title_tmp = hb_list_item( data->list_title, j );
97 if( title->vts == title_tmp->vts &&
98 title->block_start == title_tmp->block_start &&
99 title->block_end == title_tmp->block_end &&
100 title->block_count == title_tmp->block_count )
111 hb_log( "scan: title %d is duplicate with title %d",
112 title->index, title_tmp->index );
113 hb_list_rem( data->list_title, title );
114 free( title ); /* This _will_ leak! */
118 #define p state.param.scanning
120 state.state = HB_STATE_SCANNING;
121 p.title_cur = title->index;
122 p.title_count = data->dvd ? hb_dvd_title_count( data->dvd ) : hb_list_count(data->list_title);
123 hb_set_state( data->h, &state );
126 /* Decode previews */
127 /* this will also detect more AC3 / DTS information */
128 if( !DecodePreviews( data, title ) )
130 /* TODO: free things */
131 hb_list_rem( data->list_title, title );
135 /* Make sure we found audio rates and bitrates */
136 for( j = 0; j < hb_list_count( title->list_audio ); )
138 audio = hb_list_item( title->list_audio, j );
139 if( !audio->config.in.bitrate )
141 hb_log( "scan: removing audio 0x%x because no bitrate found",
143 hb_list_rem( title->list_audio, audio );
150 /* If we don't have any audio streams left, remove the title */
151 if( !hb_list_count( title->list_audio ) )
153 hb_list_rem( data->list_title, title );
161 /* Init jobs templates */
162 for( i = 0; i < hb_list_count( data->list_title ); i++ )
166 title = hb_list_item( data->list_title, i );
167 job = calloc( sizeof( hb_job_t ), 1 );
172 /* Set defaults settings */
173 job->chapter_start = 1;
174 job->chapter_end = hb_list_count( title->list_chapter );
176 /* Autocrop by default. Gnark gnark */
177 memcpy( job->crop, title->crop, 4 * sizeof( int ) );
179 if( title->aspect == 16 && !job->pixel_aspect_width && !job->pixel_aspect_height)
181 hb_reduce( &job->pixel_aspect_width, &job->pixel_aspect_height,
182 16 * title->height, 9 * title->width );
184 else if( !job->pixel_aspect_width && !job->pixel_aspect_height )
186 hb_reduce( &job->pixel_aspect_width, &job->pixel_aspect_height,
187 4 * title->height, 3 * title->width );
190 job->width = title->width - job->crop[2] - job->crop[3];
191 hb_fix_aspect( job, HB_KEEP_WIDTH );
192 if( job->height > title->height - job->crop[0] - job->crop[1] )
194 job->height = title->height - job->crop[0] - job->crop[1];
195 hb_fix_aspect( job, HB_KEEP_HEIGHT );
198 hb_log( "scan: title (%d) job->width:%d, job->height:%d",
199 i, job->width, job->height );
203 job->vcodec = HB_VCODEC_FFMPEG;
204 job->vquality = -1.0;
205 job->vbitrate = 1000;
207 job->vrate = title->rate;
208 job->vrate_base = title->rate_base;
210 job->list_audio = hb_list_init();
214 job->mux = HB_MUX_MP4;
219 hb_dvd_close( &data->dvd );
223 hb_stream_close(&data->stream);
230 /***********************************************************************
232 ***********************************************************************
233 * Decode 10 pictures for the given title.
234 * It assumes that data->reader and data->vts have successfully been
235 * DVDOpen()ed and ifoOpen()ed.
236 **********************************************************************/
237 static int DecodePreviews( hb_scan_t * data, hb_title_t * title )
239 int i, npreviews = 0;
240 hb_buffer_t * buf_ps, * buf_es;
242 int progressive_count = 0;
243 int interlaced_preview_count = 0;
245 int ar16_count = 0, ar4_count = 0;
247 buf_ps = hb_buffer_init( HB_DVD_READ_BUFFER_SIZE );
248 list_es = hb_list_init();
250 hb_log( "scan: decoding previews for title %d", title->index );
253 hb_dvd_start( data->dvd, title->index, 1 );
255 for( i = 0; i < 10; i++ )
263 if( !hb_dvd_seek( data->dvd, (float) ( i + 1 ) / 11.0 ) )
268 else if (data->stream)
270 /* we start reading streams at zero rather than 1/11 because
271 * short streams may have only one sequence header in the entire
272 * file and we need it to decode any previews. */
273 if (!hb_stream_seek(data->stream, (float) i / 11.0 ) )
279 hb_log( "scan: preview %d", i + 1 );
281 int vcodec = title->video_codec? title->video_codec : WORK_DECMPEG2;
282 hb_work_object_t *vid_decoder = hb_get_work( vcodec );
283 vid_decoder->codec_param = title->video_codec_param;
284 vid_decoder->init( vid_decoder, NULL );
285 hb_buffer_t * vid_buf = NULL;
287 for( j = 0; j < 10240 ; j++ )
291 if( !hb_dvd_read( data->dvd, buf_ps ) )
293 hb_log( "Warning: Could not read data for preview %d, skipped", i + 1 );
297 else if (data->stream)
299 if ( !hb_stream_read(data->stream,buf_ps) )
301 hb_log( "Warning: Could not read data for preview %d, skipped", i + 1 );
305 if ( title->demuxer == HB_NULL_DEMUXER )
307 hb_demux_null( buf_ps, list_es, 0 );
311 hb_demux_ps( buf_ps, list_es, 0 );
314 while( ( buf_es = hb_list_item( list_es, 0 ) ) )
316 hb_list_rem( list_es, buf_es );
317 if( buf_es->id == title->video_id && vid_buf == NULL )
319 vid_decoder->work( vid_decoder, &buf_es, &vid_buf );
321 else if( ! AllAudioOK( title ) )
323 LookForAudio( title, buf_es );
326 hb_buffer_close( &buf_es );
329 if( vid_buf && AllAudioOK( title ) )
335 hb_log( "scan: could not get a decoded picture" );
339 /* Get size and rate infos */
341 hb_work_info_t vid_info;
342 vid_decoder->info( vid_decoder, &vid_info );
343 vid_decoder->close( vid_decoder );
346 title->width = vid_info.width;
347 title->height = vid_info.height;
348 title->rate = vid_info.rate;
349 title->rate_base = vid_info.rate_base;
350 if ( vid_info.aspect != 0 )
352 if ( vid_info.aspect != last_ar && last_ar != 0 )
354 hb_log( "aspect ratio changed from %g to %g",
355 last_ar, vid_info.aspect );
357 switch ( (int)vid_info.aspect )
359 case HB_ASPECT_BASE * 4 / 3:
362 case HB_ASPECT_BASE * 16 / 9:
366 hb_log( "unknown aspect ratio %g", vid_info.aspect );
367 /* if the aspect is closer to 4:3 use that
368 * otherwise use 16:9 */
369 vid_info.aspect < HB_ASPECT_BASE * 14 / 9 ? ++ar4_count :
373 last_ar = vid_info.aspect;
376 if( title->rate_base == 1126125 )
378 /* Frame FPS is 23.976 (meaning it's progressive), so
379 start keeping track of how many are reporting at
380 that speed. When enough show up that way, we want
381 to make that the overall title FPS.
385 if( progressive_count < 6 )
387 /* Not enough frames are reporting as progressive,
388 which means we should be conservative and use
389 29.97 as the title's FPS for now.
391 title->rate_base = 900900;
395 /* A majority of the scan frames are progressive. Make that
396 the title's FPS, and announce it once to the log.
398 if( progressive_count == 6 )
400 hb_log("Title's mostly NTSC Film, setting fps to 23.976");
402 title->rate_base = 1126125;
405 else if( title->rate_base == 900900 && progressive_count >= 6 )
408 * We've already deduced that the frame rate is 23.976, so set it
411 title->rate_base = 1126125;
414 // start from third frame to skip opening logos
417 title->crop[0] = title->crop[1] = title->height / 2;
418 title->crop[2] = title->crop[3] = title->width / 2;
421 while( ( buf_es = hb_list_item( list_es, 0 ) ) )
423 hb_list_rem( list_es, buf_es );
424 hb_buffer_close( &buf_es );
427 /* Check preview for interlacing artifacts */
428 if( hb_detect_comb( vid_buf, title->width, title->height, 10, 30, 9, 10, 30, 9 ) )
430 hb_log("Interlacing detected in preview frame %i", i);
431 interlaced_preview_count++;
434 hb_get_tempory_filename( data->h, filename, "%x%d",
435 (intptr_t)title, i );
437 file_preview = fopen( filename, "w" );
440 fwrite( vid_buf->data, title->width * title->height * 3 / 2,
442 fclose( file_preview );
446 hb_log( "scan: fopen failed (%s)", filename );
449 #define Y vid_buf->data
452 /* Detect black borders */
454 for( j = 0; j < title->width; j++ )
456 for( k = 2; k < title->crop[0]; k++ )
457 if( Y[ k * title->width + j ] > DARK )
462 for( k = 0; k < title->crop[1]; k++ )
463 if( Y[ ( title->height - k - 1 ) *
464 title->width + j ] > DARK )
470 for( j = 0; j < title->height; j++ )
472 for( k = 0; k < title->crop[2]; k++ )
473 if( Y[ j * title->width + k ] > DARK )
478 for( k = 0; k < title->crop[3]; k++ )
479 if( Y[ j * title->width +
480 title->width - k - 1 ] > DARK )
490 hb_buffer_close( &vid_buf );
493 /* if we found mostly 4:3 previews use that as the aspect ratio otherwise
495 title->aspect = ar4_count > ar16_count ?
496 HB_ASPECT_BASE * 4 / 3 : HB_ASPECT_BASE * 16 / 9;
498 title->crop[0] = EVEN( title->crop[0] );
499 title->crop[1] = EVEN( title->crop[1] );
500 title->crop[2] = EVEN( title->crop[2] );
501 title->crop[3] = EVEN( title->crop[3] );
503 hb_log( "scan: %d previews, %dx%d, %.3f fps, autocrop = %d/%d/%d/%d, aspect %s",
504 npreviews, title->width, title->height, (float) title->rate /
505 (float) title->rate_base, title->crop[0], title->crop[1],
506 title->crop[2], title->crop[3],
507 title->aspect == HB_ASPECT_BASE * 16 / 9 ? "16:9" :
508 title->aspect == HB_ASPECT_BASE * 4 / 3 ? "4:3" : "none" );
510 if( interlaced_preview_count >= ( npreviews / 2 ) )
512 hb_log("Title is likely interlaced or telecined (%i out of %i previews). You should do something about that.",
513 interlaced_preview_count, npreviews);
514 title->detected_interlacing = 1;
518 title->detected_interlacing = 0;
521 hb_buffer_close( &buf_ps );
522 while( ( buf_es = hb_list_item( list_es, 0 ) ) )
524 hb_list_rem( list_es, buf_es );
525 hb_buffer_close( &buf_es );
527 hb_list_close( &list_es );
529 hb_dvd_stop( data->dvd );
535 * This routine is called for every frame from a non-video elementary stream.
536 * These are a mix of audio & subtitle streams, some of which we want & some
537 * we're ignoring. This routine checks the frame against all our audio streams
538 * to see if it's one we want and haven't identified yet. If yes, it passes the
539 * frame to a codec-specific id routine which is responsible for filling in
540 * the sample rate, bit rate, channels & other audio parameters.
542 * Since a sample rate is essential for further audio processing, any audio
543 * stream which isn't successfully id'd by is deleted at the end of the scan.
544 * This is necessary to avoid ambiguities where things that might be audio
545 * aren't (e.g., some European DVD Teletext streams use the same IDs as US ATSC
548 static void LookForAudio( hb_title_t * title, hb_buffer_t * b )
552 hb_audio_t * audio = NULL;
553 for( i = 0; i < hb_list_count( title->list_audio ); i++ )
555 audio = hb_list_item( title->list_audio, i );
556 /* check if this elementary stream is one we want */
557 if ( audio->id == b->id )
566 if( !audio || audio->config.in.bitrate != 0 )
568 /* not found or already done */
572 hb_work_object_t *w = hb_codec_decoder( audio->config.in.codec );
574 if ( w == NULL || w->bsinfo == NULL )
576 hb_log( "Internal error in scan: unhandled audio type %d for id 0x%x",
577 audio->config.in.codec, audio->id );
583 w->codec_param = audio->config.in.codec_param;
584 int ret = w->bsinfo( w, b, &info );
587 hb_log( "no info on audio type %d/0x%x for id 0x%x",
588 audio->config.in.codec, audio->config.in.codec_param,
594 /* didn't find any info */
597 audio->config.in.samplerate = info.rate;
598 audio->config.in.bitrate = info.bitrate;
599 audio->config.in.channel_layout = info.channel_layout;
600 audio->config.flags.ac3 = info.flags;
602 // update the audio description string based on the info we found
603 if ( audio->config.flags.ac3 & AUDIO_F_DOLBY )
605 strcat( audio->config.lang.description, " (Dolby Surround)" );
609 int layout = audio->config.in.channel_layout;
610 char *desc = audio->config.lang.description +
611 strlen( audio->config.lang.description );
612 sprintf( desc, " (%d.%d ch)",
613 HB_INPUT_CH_LAYOUT_GET_DISCRETE_FRONT_COUNT(layout) +
614 HB_INPUT_CH_LAYOUT_GET_DISCRETE_REAR_COUNT(layout),
615 HB_INPUT_CH_LAYOUT_GET_DISCRETE_LFE_COUNT(layout) );
618 hb_log( "scan: audio 0x%x: %s, rate=%dHz, bitrate=%d %s", audio->id,
619 info.name, audio->config.in.samplerate, audio->config.in.bitrate,
620 audio->config.lang.description );
625 // We get here if there's no hope of finding info on an audio bitstream,
626 // either because we don't have a decoder (or a decoder with a bitstream
627 // info proc) or because the decoder's info proc said that the stream
628 // wasn't something it could handle. Delete the item from the title's
629 // audio list so we won't keep reading packets while trying to get its
635 hb_list_rem( title->list_audio, audio );
639 * This routine checks to see if we've ID'd all the audio streams associated
640 * with a title. It returns 0 if there are more to ID & 1 if all are done.
642 static int AllAudioOK( hb_title_t * title )
647 for( i = 0; i < hb_list_count( title->list_audio ); i++ )
649 audio = hb_list_item( title->list_audio, i );
650 if( audio->config.in.bitrate == 0 )