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.m0k.org/>.
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 LookForAC3AndDCA( hb_title_t * title, hb_buffer_t * b );
27 static int AllAC3AndDCAOK( 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 );
137 // Stream based processing uses PID's to handle the different audio options for a given title
138 for( j = 0; j < hb_list_count( title->list_audio ); j++ )
140 audio = hb_list_item( title->list_audio, j );
141 hb_stream_update_audio(data->stream, audio);
146 /* Make sure we found AC3 rates and bitrates */
147 for( j = 0; j < hb_list_count( title->list_audio ); )
149 audio = hb_list_item( title->list_audio, j );
150 if( audio->codec == HB_ACODEC_AC3 &&
153 hb_list_rem( title->list_audio, audio );
161 /* Make sure we found AC3 / DCA rates and bitrates */
162 for( j = 0; j < hb_list_count( title->list_audio ); )
164 audio = hb_list_item( title->list_audio, j );
165 if( ( audio->codec == HB_ACODEC_AC3 || audio->codec == HB_ACODEC_DCA ) &&
168 hb_log( "scan: removing audio with codec of 0x%x because of no bitrate",
170 hb_list_rem( title->list_audio, audio );
177 /* Do we still have audio */
178 if( !hb_list_count( title->list_audio ) )
180 hb_list_rem( data->list_title, title );
185 /* set a default input channel layout of stereo for LPCM or MPEG2 audio */
186 /* AC3 and DCA will already have had their layout set via DecodePreviews above, */
187 /* which calls LookForAC3AndDCA */
188 for( j = 0; j < hb_list_count( title->list_audio ); j++ )
190 audio = hb_list_item( title->list_audio, j );
191 if( audio->codec == HB_ACODEC_LPCM || audio->codec == HB_ACODEC_MPGA )
193 audio->input_channel_layout = HB_INPUT_CH_LAYOUT_STEREO;
200 /* Init jobs templates */
201 for( i = 0; i < hb_list_count( data->list_title ); i++ )
205 title = hb_list_item( data->list_title, i );
206 job = calloc( sizeof( hb_job_t ), 1 );
211 /* Set defaults settings */
212 job->chapter_start = 1;
213 job->chapter_end = hb_list_count( title->list_chapter );
215 /* Autocrop by default. Gnark gnark */
216 memcpy( job->crop, title->crop, 4 * sizeof( int ) );
218 if( title->aspect == 16 )
220 hb_reduce( &job->pixel_aspect_width, &job->pixel_aspect_height,
221 16 * title->height, 9 * title->width );
225 hb_reduce( &job->pixel_aspect_width, &job->pixel_aspect_height,
226 4 * title->height, 3 * title->width );
229 job->width = title->width - job->crop[2] - job->crop[3];
230 // job->height = title->height - job->crop[0] - job->crop[1];
231 hb_fix_aspect( job, HB_KEEP_WIDTH );
232 if( job->height > title->height - job->crop[0] - job->crop[1] )
234 job->height = title->height - job->crop[0] - job->crop[1];
235 hb_fix_aspect( job, HB_KEEP_HEIGHT );
238 hb_log( "scan: title (%d) job->width:%d, job->height:%d",
239 i,job->width, job->height );
243 job->vcodec = HB_VCODEC_FFMPEG;
244 job->vquality = -1.0;
245 job->vbitrate = 1000;
247 job->vrate = title->rate;
248 job->vrate_base = title->rate_base;
253 job->acodec = HB_ACODEC_FAAC;
259 job->mux = HB_MUX_MP4;
264 hb_dvd_close( &data->dvd );
268 hb_stream_close(&data->stream);
275 /***********************************************************************
277 ***********************************************************************
278 * Decode 10 pictures for the given title.
279 * It assumes that data->reader and data->vts have successfully been
280 * DVDOpen()ed and ifoOpen()ed.
281 **********************************************************************/
282 static int DecodePreviews( hb_scan_t * data, hb_title_t * title )
284 int i, npreviews = 0;
285 hb_buffer_t * buf_ps, * buf_es, * buf_raw;
286 hb_list_t * list_es, * list_raw;
287 hb_libmpeg2_t * mpeg2;
288 int progressive_count = 0;
289 int interlaced_preview_count = 0;
291 int ar16_count = 0, ar4_count = 0;
293 buf_ps = hb_buffer_init( HB_DVD_READ_BUFFER_SIZE );
294 list_es = hb_list_init();
295 list_raw = hb_list_init();
297 hb_log( "scan: decoding previews for title %d", title->index );
300 hb_dvd_start( data->dvd, title->index, 1 );
302 for( i = 0; i < 10; i++ )
308 //hb_log("Seeking to: %f", (float) ( i + 1 ) / 11.0 );
312 if( !hb_dvd_seek( data->dvd, (float) ( i + 1 ) / 11.0 ) )
317 else if (data->stream)
319 if (!hb_stream_seek(data->stream, (float) ( i + 1 ) / 11.0 ) )
325 hb_log( "scan: preview %d", i + 1 );
327 mpeg2 = hb_libmpeg2_init();
329 for( j = 0; j < 10240 ; j++ )
333 if( !hb_dvd_read( data->dvd, buf_ps ) )
335 hb_log( "Warning: Could not read data for preview %d, skipped", i + 1 );
339 else if (data->stream)
341 if ( !hb_stream_read(data->stream,buf_ps) )
343 hb_log( "Warning: Could not read data for preview %d, skipped", i + 1 );
347 hb_demux_ps( buf_ps, list_es );
349 while( ( buf_es = hb_list_item( list_es, 0 ) ) )
351 hb_list_rem( list_es, buf_es );
352 if( buf_es->id == 0xE0 && !hb_list_count( list_raw ) )
354 hb_libmpeg2_decode( mpeg2, buf_es, list_raw );
355 int ar = hb_libmpeg2_clear_aspect_ratio( mpeg2 );
358 ( ar == (HB_ASPECT_BASE * 4 / 3) ) ?
359 ++ar4_count : ++ar16_count ;
364 LookForAC3AndDCA( title, buf_es );
366 hb_buffer_close( &buf_es );
368 if( hb_list_count( list_raw ) &&
369 ( i || AllAC3AndDCAOK( title ) ) )
371 /* We got a picture */
376 if( hb_list_count( list_raw ) &&
377 ( i || AllAC3AndDCAOK( title ) ) )
383 if( !hb_list_count( list_raw ) )
385 hb_log( "scan: could not get a decoded picture" );
389 /* Get size and rate infos */
390 title->rate = 27000000;
392 hb_libmpeg2_info( mpeg2, &title->width, &title->height,
393 &title->rate_base, &ar );
395 /* if we found mostly 4:3 previews use that as the aspect ratio otherwise
397 title->aspect = ar4_count > ar16_count ?
398 HB_ASPECT_BASE * 4 / 3 : HB_ASPECT_BASE * 16 / 9;
400 if( title->rate_base == 1126125 )
402 /* Frame FPS is 23.976 (meaning it's progressive), so
403 start keeping track of how many are reporting at
404 that speed. When enough show up that way, we want
405 to make that the overall title FPS.
409 if( progressive_count < 6 )
411 /* Not enough frames are reporting as progressive,
412 which means we should be conservative and use
413 29.97 as the title's FPS for now.
415 title->rate_base = 900900;
419 /* A majority of the scan frames are progressive. Make that
420 the title's FPS, and announce it once to the log.
422 if( progressive_count == 6 )
424 hb_log("Title's mostly NTSC Film, setting fps to 23.976");
426 title->rate_base = 1126125;
429 else if( title->rate_base == 900900 && progressive_count >= 6 )
432 * We've already deduced that the frame rate is 23.976, so set it
435 title->rate_base = 1126125;
438 // start from third frame to skip opening logos
441 title->crop[0] = title->crop[1] = title->height / 2;
442 title->crop[2] = title->crop[3] = title->width / 2;
445 hb_libmpeg2_close( &mpeg2 );
447 while( ( buf_es = hb_list_item( list_es, 0 ) ) )
449 hb_list_rem( list_es, buf_es );
450 hb_buffer_close( &buf_es );
453 buf_raw = hb_list_item( list_raw, 0 );
455 /* Check preview for interlacing artifacts */
456 if( hb_detect_comb( buf_raw, title->width, title->height, 10, 30, 9 ) )
458 hb_log("Interlacing detected in preview frame %i", i);
459 interlaced_preview_count++;
462 hb_get_tempory_filename( data->h, filename, "%x%d",
463 (intptr_t)title, i );
465 file_preview = fopen( filename, "w" );
468 fwrite( buf_raw->data, title->width * title->height * 3 / 2,
470 fclose( file_preview );
474 hb_log( "scan: fopen failed (%s)", filename );
477 #define Y buf_raw->data
480 /* Detect black borders */
482 for( j = 0; j < title->width; j++ )
484 for( k = 0; k < title->crop[0]; k++ )
485 if( Y[ k * title->width + j ] > DARK )
490 for( k = 0; k < title->crop[1]; k++ )
491 if( Y[ ( title->height - k - 1 ) *
492 title->width + j ] > DARK )
498 for( j = 0; j < title->height; j++ )
500 for( k = 0; k < title->crop[2]; k++ )
501 if( Y[ j * title->width + k ] > DARK )
506 for( k = 0; k < title->crop[3]; k++ )
507 if( Y[ j * title->width +
508 title->width - k - 1 ] > DARK )
517 while( ( buf_raw = hb_list_item( list_raw, 0 ) ) )
519 hb_list_rem( list_raw, buf_raw );
520 hb_buffer_close( &buf_raw );
524 title->crop[0] = EVEN( title->crop[0] );
525 title->crop[1] = EVEN( title->crop[1] );
526 title->crop[2] = EVEN( title->crop[2] );
527 title->crop[3] = EVEN( title->crop[3] );
529 hb_log( "scan: %d previews, %dx%d, %.3f fps, autocrop = %d/%d/%d/%d, aspect %s",
530 npreviews, title->width, title->height, (float) title->rate /
531 (float) title->rate_base, title->crop[0], title->crop[1],
532 title->crop[2], title->crop[3],
533 title->aspect == HB_ASPECT_BASE * 16 / 9 ? "16:9" :
534 title->aspect == HB_ASPECT_BASE * 4 / 3 ? "4:3" : "none" );
536 if( interlaced_preview_count >= ( npreviews / 2 ) )
538 hb_log("Title is likely interlaced or telecined (%i out of %i previews). You should do something about that.",
539 interlaced_preview_count, npreviews);
540 title->detected_interlacing = 1;
544 title->detected_interlacing = 0;
553 hb_buffer_close( &buf_ps );
554 while( ( buf_es = hb_list_item( list_es, 0 ) ) )
556 hb_list_rem( list_es, buf_es );
557 hb_buffer_close( &buf_es );
559 hb_list_close( &list_es );
560 while( ( buf_raw = hb_list_item( list_raw, 0 ) ) )
562 hb_list_rem( list_raw, buf_raw );
563 hb_buffer_close( &buf_raw );
565 hb_list_close( &list_raw );
567 hb_dvd_stop( data->dvd );
572 static void LookForAC3AndDCA( hb_title_t * title, hb_buffer_t * b )
581 /* Figure out if this is a AC3 or DCA buffer for a known track */
582 hb_audio_t * audio = NULL;
583 for( i = 0; i < hb_list_count( title->list_audio ); i++ )
585 audio = hb_list_item( title->list_audio, i );
586 /* check if we have an AC3 or DCA which we recognise */
587 if( ( audio->codec == HB_ACODEC_AC3 || audio->codec == HB_ACODEC_DCA ) &&
604 /* Already done for this track */
608 for( i = 0; i < b->size - 7; i++ )
611 if ( audio->codec == HB_ACODEC_AC3 )
615 if( a52_syncinfo( &b->data[i], &flags, &rate, &bitrate ) )
617 hb_log( "scan: AC3, rate=%dHz, bitrate=%d", rate, bitrate );
619 audio->bitrate = bitrate;
620 switch( flags & A52_CHANNEL_MASK )
626 audio->input_channel_layout = HB_INPUT_CH_LAYOUT_MONO;
631 audio->input_channel_layout = HB_INPUT_CH_LAYOUT_STEREO;
633 /* dolby (DPL1 aka Dolby Surround = 4.0 matrix-encoded) input */
635 audio->input_channel_layout = HB_INPUT_CH_LAYOUT_DOLBY;
639 audio->input_channel_layout = HB_INPUT_CH_LAYOUT_3F2R;
643 audio->input_channel_layout = HB_INPUT_CH_LAYOUT_3F1R;
647 audio->input_channel_layout = HB_INPUT_CH_LAYOUT_3F;
650 audio->input_channel_layout = HB_INPUT_CH_LAYOUT_2F1R;
653 audio->input_channel_layout = HB_INPUT_CH_LAYOUT_2F2R;
657 audio->input_channel_layout = HB_INPUT_CH_LAYOUT_STEREO;
660 /* add in our own LFE flag if the source has LFE */
663 audio->input_channel_layout = audio->input_channel_layout | HB_INPUT_CH_LAYOUT_HAS_LFE;
666 /* store the AC3 flags for future reference
667 This enables us to find out if we had a stereo or Dolby source later on */
668 audio->config.a52.ac3flags = flags;
670 /* store the ac3 flags in the public ac3flags property too, so we can access it from the GUI */
671 audio->ac3flags = audio->config.a52.ac3flags;
674 if ( (flags & A52_CHANNEL_MASK) == A52_DOLBY ) {
675 sprintf( audio->lang + strlen( audio->lang ),
676 " (Dolby Surround)" );
678 sprintf( audio->lang + strlen( audio->lang ),
680 HB_INPUT_CH_LAYOUT_GET_DISCRETE_FRONT_COUNT(audio->input_channel_layout) +
681 HB_INPUT_CH_LAYOUT_GET_DISCRETE_REAR_COUNT(audio->input_channel_layout),
682 HB_INPUT_CH_LAYOUT_GET_DISCRETE_LFE_COUNT(audio->input_channel_layout));
690 else if ( audio->codec == HB_ACODEC_DCA )
693 hb_log( "scan: checking for DCA syncinfo" );
696 state = dca_init( 0 );
697 if( dca_syncinfo( state, &b->data[i], &flags, &rate, &bitrate, &frame_length ) )
699 hb_log( "scan: DCA, rate=%dHz, bitrate=%d", rate, bitrate );
701 audio->bitrate = bitrate;
702 switch( flags & DCA_CHANNEL_MASK )
706 audio->input_channel_layout = HB_INPUT_CH_LAYOUT_MONO;
711 case DCA_STEREO_SUMDIFF:
712 case DCA_STEREO_TOTAL:
713 audio->input_channel_layout = HB_INPUT_CH_LAYOUT_STEREO;
717 audio->input_channel_layout = HB_INPUT_CH_LAYOUT_3F2R;
721 audio->input_channel_layout = HB_INPUT_CH_LAYOUT_3F1R;
725 audio->input_channel_layout = HB_INPUT_CH_LAYOUT_3F;
728 audio->input_channel_layout = HB_INPUT_CH_LAYOUT_2F1R;
731 audio->input_channel_layout = HB_INPUT_CH_LAYOUT_2F2R;
734 audio->input_channel_layout = HB_INPUT_CH_LAYOUT_4F2R;
738 audio->input_channel_layout = HB_INPUT_CH_LAYOUT_STEREO;
741 /* add in our own LFE flag if the source has LFE */
744 audio->input_channel_layout = audio->input_channel_layout | HB_INPUT_CH_LAYOUT_HAS_LFE;
747 /* store the DCA flags for future reference
748 This enables us to find out if we had a stereo or Dolby source later on */
749 audio->config.dca.dcaflags = flags;
751 /* store the dca flags in the public dcaflags property too, so we can access it from the GUI */
752 audio->dcaflags = audio->config.dca.dcaflags;
755 if ( (flags & DCA_CHANNEL_MASK) == DCA_DOLBY ) {
756 sprintf( audio->lang + strlen( audio->lang ),
757 " (Dolby Surround)" );
759 sprintf( audio->lang + strlen( audio->lang ),
761 HB_INPUT_CH_LAYOUT_GET_DISCRETE_FRONT_COUNT(audio->input_channel_layout) +
762 HB_INPUT_CH_LAYOUT_GET_DISCRETE_REAR_COUNT(audio->input_channel_layout),
763 HB_INPUT_CH_LAYOUT_GET_DISCRETE_LFE_COUNT(audio->input_channel_layout));
773 static int AllAC3AndDCAOK( hb_title_t * title )
778 for( i = 0; i < hb_list_count( title->list_audio ); i++ )
780 audio = hb_list_item( title->list_audio, i );
781 if( ( audio->codec == HB_ACODEC_AC3 || audio->codec == HB_ACODEC_DCA ) &&