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 ) );
75 if ( hb_stream_is_stream_type(data->path) )
77 hb_log( "scan: trying to open as MPEG-2 Stream");
78 data->stream = hb_stream_open (data->path);
79 hb_list_add( data->list_title, hb_stream_title_scan( data->stream ) );
83 hb_log( "scan: unrecognized file type" );
88 for( i = 0; i < hb_list_count( data->list_title ); )
93 hb_title_t * title_tmp = NULL;
95 title = hb_list_item( data->list_title, i );
97 /* I've seen a DVD with strictly identical titles. Check this
98 here and ignore it if redundant */
99 for( j = 0; j < i; j++ )
101 title_tmp = hb_list_item( data->list_title, j );
102 if( title->vts == title_tmp->vts &&
103 title->block_start == title_tmp->block_start &&
104 title->block_end == title_tmp->block_end &&
105 title->block_count == title_tmp->block_count )
116 hb_log( "scan: title %d is duplicate with title %d",
117 title->index, title_tmp->index );
118 hb_list_rem( data->list_title, title );
119 free( title ); /* This _will_ leak! */
123 #define p state.param.scanning
125 state.state = HB_STATE_SCANNING;
126 p.title_cur = title->index;
127 p.title_count = data->dvd ? hb_dvd_title_count( data->dvd ) : hb_list_count(data->list_title);
128 hb_set_state( data->h, &state );
131 /* Decode previews */
132 /* this will also detect more AC3 / DTS information */
133 if( !DecodePreviews( data, title ) )
135 /* TODO: free things */
136 hb_list_rem( data->list_title, title );
142 // Stream based processing uses PID's to handle the different audio options for a given title
143 for( j = 0; j < hb_list_count( title->list_audio ); j++ )
145 audio = hb_list_item( title->list_audio, j );
146 hb_stream_update_audio(data->stream, audio);
151 /* Make sure we found AC3 rates and bitrates */
152 for( j = 0; j < hb_list_count( title->list_audio ); )
154 audio = hb_list_item( title->list_audio, j );
155 if( audio->codec == HB_ACODEC_AC3 &&
158 hb_list_rem( title->list_audio, audio );
166 /* Make sure we found AC3 / DCA rates and bitrates */
167 for( j = 0; j < hb_list_count( title->list_audio ); )
169 audio = hb_list_item( title->list_audio, j );
170 if( ( audio->codec == HB_ACODEC_AC3 || audio->codec == HB_ACODEC_DCA ) &&
173 hb_log( "scan: removing audio with codec of 0x%x because of no bitrate",
175 hb_list_rem( title->list_audio, audio );
182 /* Do we still have audio */
183 if( !hb_list_count( title->list_audio ) )
185 hb_list_rem( data->list_title, title );
190 /* set a default input channel layout of stereo for LPCM or MPEG2 audio */
191 /* AC3 and DCA will already have had their layout set via DecodePreviews above, */
192 /* which calls LookForAC3AndDCA */
193 for( j = 0; j < hb_list_count( title->list_audio ); j++ )
195 audio = hb_list_item( title->list_audio, j );
196 if( audio->codec == HB_ACODEC_LPCM || audio->codec == HB_ACODEC_MPGA )
198 audio->input_channel_layout = HB_INPUT_CH_LAYOUT_STEREO;
205 /* Init jobs templates */
206 for( i = 0; i < hb_list_count( data->list_title ); i++ )
210 title = hb_list_item( data->list_title, i );
211 job = calloc( sizeof( hb_job_t ), 1 );
216 /* Set defaults settings */
217 job->chapter_start = 1;
218 job->chapter_end = hb_list_count( title->list_chapter );
220 /* Autocrop by default. Gnark gnark */
221 memcpy( job->crop, title->crop, 4 * sizeof( int ) );
223 if( title->aspect == 16 )
225 hb_reduce( &job->pixel_aspect_width, &job->pixel_aspect_height,
226 16 * title->height, 9 * title->width );
230 hb_reduce( &job->pixel_aspect_width, &job->pixel_aspect_height,
231 4 * title->height, 3 * title->width );
234 job->width = title->width - job->crop[2] - job->crop[3];
235 // job->height = title->height - job->crop[0] - job->crop[1];
236 hb_fix_aspect( job, HB_KEEP_WIDTH );
237 if( job->height > title->height - job->crop[0] - job->crop[1] )
239 job->height = title->height - job->crop[0] - job->crop[1];
240 hb_fix_aspect( job, HB_KEEP_HEIGHT );
243 hb_log( "scan: title (%d) job->width:%d, job->height:%d",
244 i,job->width, job->height );
248 job->vcodec = HB_VCODEC_FFMPEG;
249 job->vquality = -1.0;
250 job->vbitrate = 1000;
252 job->vrate = title->rate;
253 job->vrate_base = title->rate_base;
258 job->acodec = HB_ACODEC_FAAC;
264 job->mux = HB_MUX_MP4;
269 hb_dvd_close( &data->dvd );
273 hb_stream_close(&data->stream);
280 /***********************************************************************
282 ***********************************************************************
283 * Decode 10 pictures for the given title.
284 * It assumes that data->reader and data->vts have successfully been
285 * DVDOpen()ed and ifoOpen()ed.
286 **********************************************************************/
287 static int DecodePreviews( hb_scan_t * data, hb_title_t * title )
290 hb_buffer_t * buf_ps, * buf_es, * buf_raw;
291 hb_list_t * list_es, * list_raw;
292 hb_libmpeg2_t * mpeg2;
293 int progressive_count = 0;
295 buf_ps = hb_buffer_init( HB_DVD_READ_BUFFER_SIZE );
296 list_es = hb_list_init();
297 list_raw = hb_list_init();
299 hb_log( "scan: decoding previews for title %d", title->index );
302 hb_dvd_start( data->dvd, title->index, 1 );
304 for( i = 0; i < 10; i++ )
310 //hb_log("Seeking to: %f", (float) ( i + 1 ) / 11.0 );
314 if( !hb_dvd_seek( data->dvd, (float) ( i + 1 ) / 11.0 ) )
319 else if (data->stream)
321 if (!hb_stream_seek(data->stream, (float) ( i + 1 ) / 11.0 ) )
327 hb_log( "scan: preview %d", i + 1 );
329 mpeg2 = hb_libmpeg2_init();
331 for( j = 0; j < 10240 ; j++ )
335 if( !hb_dvd_read( data->dvd, buf_ps ) )
340 else if (data->stream)
342 if ( !hb_stream_read(data->stream,buf_ps) )
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 );
358 LookForAC3AndDCA( title, buf_es );
360 hb_buffer_close( &buf_es );
362 if( hb_list_count( list_raw ) &&
363 ( i || AllAC3AndDCAOK( title ) ) )
365 /* We got a picture */
370 if( hb_list_count( list_raw ) &&
371 ( i || AllAC3AndDCAOK( title ) ) )
377 if( !hb_list_count( list_raw ) )
379 hb_log( "scan: could not get a decoded picture" );
383 /* Get size and rate infos */
384 title->rate = 27000000;
386 hb_libmpeg2_info( mpeg2, &title->width, &title->height,
387 &title->rate_base, &ar );
389 if( title->rate_base == 1126125 )
391 /* Frame FPS is 23.976 (meaning it's progressive), so
392 start keeping track of how many are reporting at
393 that speed. When enough show up that way, we want
394 to make that the overall title FPS.
398 if( progressive_count < 6 )
400 /* Not enough frames are reporting as progressive,
401 which means we should be conservative and use
402 29.97 as the title's FPS for now.
404 title->rate_base = 900900;
408 /* A majority of the scan frames are progressive. Make that
409 the title's FPS, and announce it once to the log.
411 if( progressive_count == 6 )
413 hb_log("Title's mostly progressive NTSC, setting fps to 23.976");
415 title->rate_base = 1126125;
418 else if( title->rate_base == 900900 && progressive_count >= 6 )
421 * We've already deduced that the frame rate is 23.976, so set it
424 title->rate_base = 1126125;
427 if( i == 2) // Use the third frame's info, so as to skip opening logos
429 // The aspect ratio may have already been set by parsing the VOB/IFO details on a DVD, however
430 // if we're working with program/transport streams that data needs to come from within the stream.
431 if (title->aspect <= 0)
433 title->crop[0] = title->crop[1] = title->height / 2;
434 title->crop[2] = title->crop[3] = title->width / 2;
437 hb_libmpeg2_close( &mpeg2 );
439 while( ( buf_es = hb_list_item( list_es, 0 ) ) )
441 hb_list_rem( list_es, buf_es );
442 hb_buffer_close( &buf_es );
445 buf_raw = hb_list_item( list_raw, 0 );
447 hb_get_tempory_filename( data->h, filename, "%x%d",
448 (intptr_t)title, i );
450 file_preview = fopen( filename, "w" );
453 fwrite( buf_raw->data, title->width * title->height * 3 / 2,
455 fclose( file_preview );
459 hb_log( "scan: fopen failed (%s)", filename );
462 #define Y buf_raw->data
465 /* Detect black borders */
467 for( j = 0; j < title->width; j++ )
469 for( k = 0; k < title->crop[0]; k++ )
470 if( Y[ k * title->width + j ] > DARK )
475 for( k = 0; k < title->crop[1]; k++ )
476 if( Y[ ( title->height - k - 1 ) *
477 title->width + j ] > DARK )
483 for( j = 0; j < title->height; j++ )
485 for( k = 0; k < title->crop[2]; k++ )
486 if( Y[ j * title->width + k ] > DARK )
491 for( k = 0; k < title->crop[3]; k++ )
492 if( Y[ j * title->width +
493 title->width - k - 1 ] > DARK )
500 while( ( buf_raw = hb_list_item( list_raw, 0 ) ) )
502 hb_list_rem( list_raw, buf_raw );
503 hb_buffer_close( &buf_raw );
507 title->crop[0] = EVEN( title->crop[0] );
508 title->crop[1] = EVEN( title->crop[1] );
509 title->crop[2] = EVEN( title->crop[2] );
510 title->crop[3] = EVEN( title->crop[3] );
512 hb_log( "scan: %dx%d, %.3f fps, autocrop = %d/%d/%d/%d",
513 title->width, title->height, (float) title->rate /
514 (float) title->rate_base, title->crop[0], title->crop[1],
515 title->crop[2], title->crop[3] );
524 hb_buffer_close( &buf_ps );
525 while( ( buf_es = hb_list_item( list_es, 0 ) ) )
527 hb_list_rem( list_es, buf_es );
528 hb_buffer_close( &buf_es );
530 hb_list_close( &list_es );
531 while( ( buf_raw = hb_list_item( list_raw, 0 ) ) )
533 hb_list_rem( list_raw, buf_raw );
534 hb_buffer_close( &buf_raw );
536 hb_list_close( &list_raw );
538 hb_dvd_stop( data->dvd );
543 static void LookForAC3AndDCA( hb_title_t * title, hb_buffer_t * b )
552 /* Figure out if this is a AC3 or DCA buffer for a known track */
553 hb_audio_t * audio = NULL;
554 for( i = 0; i < hb_list_count( title->list_audio ); i++ )
556 audio = hb_list_item( title->list_audio, i );
557 /* check if we have an AC3 or DCA which we recognise */
558 if( ( audio->codec == HB_ACODEC_AC3 || audio->codec == HB_ACODEC_DCA ) &&
575 /* Already done for this track */
579 for( i = 0; i < b->size - 7; i++ )
582 if ( audio->codec == HB_ACODEC_AC3 )
586 if( a52_syncinfo( &b->data[i], &flags, &rate, &bitrate ) )
588 hb_log( "scan: AC3, rate=%dHz, bitrate=%d", rate, bitrate );
590 audio->bitrate = bitrate;
591 switch( flags & A52_CHANNEL_MASK )
597 audio->input_channel_layout = HB_INPUT_CH_LAYOUT_MONO;
602 audio->input_channel_layout = HB_INPUT_CH_LAYOUT_STEREO;
604 /* dolby (DPL1 aka Dolby Surround = 4.0 matrix-encoded) input */
606 audio->input_channel_layout = HB_INPUT_CH_LAYOUT_DOLBY;
610 audio->input_channel_layout = HB_INPUT_CH_LAYOUT_3F2R;
614 audio->input_channel_layout = HB_INPUT_CH_LAYOUT_3F1R;
618 audio->input_channel_layout = HB_INPUT_CH_LAYOUT_3F;
621 audio->input_channel_layout = HB_INPUT_CH_LAYOUT_2F1R;
624 audio->input_channel_layout = HB_INPUT_CH_LAYOUT_2F2R;
628 audio->input_channel_layout = HB_INPUT_CH_LAYOUT_STEREO;
631 /* add in our own LFE flag if the source has LFE */
634 audio->input_channel_layout = audio->input_channel_layout | HB_INPUT_CH_LAYOUT_HAS_LFE;
637 /* store the AC3 flags for future reference
638 This enables us to find out if we had a stereo or Dolby source later on */
639 audio->config.a52.ac3flags = flags;
641 /* store the ac3 flags in the public ac3flags property too, so we can access it from the GUI */
642 audio->ac3flags = audio->config.a52.ac3flags;
645 if ( (flags & A52_CHANNEL_MASK) == A52_DOLBY ) {
646 sprintf( audio->lang + strlen( audio->lang ),
647 " (Dolby Surround)" );
649 sprintf( audio->lang + strlen( audio->lang ),
651 HB_INPUT_CH_LAYOUT_GET_DISCRETE_FRONT_COUNT(audio->input_channel_layout) +
652 HB_INPUT_CH_LAYOUT_GET_DISCRETE_REAR_COUNT(audio->input_channel_layout),
653 HB_INPUT_CH_LAYOUT_GET_DISCRETE_LFE_COUNT(audio->input_channel_layout));
661 else if ( audio->codec == HB_ACODEC_DCA )
664 hb_log( "scan: checking for DCA syncinfo" );
667 state = dca_init( 0 );
668 if( dca_syncinfo( state, &b->data[i], &flags, &rate, &bitrate, &frame_length ) )
670 hb_log( "scan: DCA, rate=%dHz, bitrate=%d", rate, bitrate );
672 audio->bitrate = bitrate;
673 switch( flags & DCA_CHANNEL_MASK )
677 audio->input_channel_layout = HB_INPUT_CH_LAYOUT_MONO;
682 case DCA_STEREO_SUMDIFF:
683 case DCA_STEREO_TOTAL:
684 audio->input_channel_layout = HB_INPUT_CH_LAYOUT_STEREO;
688 audio->input_channel_layout = HB_INPUT_CH_LAYOUT_3F2R;
692 audio->input_channel_layout = HB_INPUT_CH_LAYOUT_3F1R;
696 audio->input_channel_layout = HB_INPUT_CH_LAYOUT_3F;
699 audio->input_channel_layout = HB_INPUT_CH_LAYOUT_2F1R;
702 audio->input_channel_layout = HB_INPUT_CH_LAYOUT_2F2R;
705 audio->input_channel_layout = HB_INPUT_CH_LAYOUT_4F2R;
709 audio->input_channel_layout = HB_INPUT_CH_LAYOUT_STEREO;
712 /* add in our own LFE flag if the source has LFE */
715 audio->input_channel_layout = audio->input_channel_layout | HB_INPUT_CH_LAYOUT_HAS_LFE;
718 /* store the DCA flags for future reference
719 This enables us to find out if we had a stereo or Dolby source later on */
720 audio->config.dca.dcaflags = flags;
722 /* store the dca flags in the public dcaflags property too, so we can access it from the GUI */
723 audio->dcaflags = audio->config.dca.dcaflags;
726 if ( (flags & DCA_CHANNEL_MASK) == DCA_DOLBY ) {
727 sprintf( audio->lang + strlen( audio->lang ),
728 " (Dolby Surround)" );
730 sprintf( audio->lang + strlen( audio->lang ),
732 HB_INPUT_CH_LAYOUT_GET_DISCRETE_FRONT_COUNT(audio->input_channel_layout) +
733 HB_INPUT_CH_LAYOUT_GET_DISCRETE_REAR_COUNT(audio->input_channel_layout),
734 HB_INPUT_CH_LAYOUT_GET_DISCRETE_LFE_COUNT(audio->input_channel_layout));
744 static int AllAC3AndDCAOK( hb_title_t * title )
749 for( i = 0; i < hb_list_count( title->list_audio ); i++ )
751 audio = hb_list_item( title->list_audio, i );
752 if( ( audio->codec == HB_ACODEC_AC3 || audio->codec == HB_ACODEC_DCA ) &&