X-Git-Url: http://git.osdn.jp/view?a=blobdiff_plain;f=libhb%2Fscan.c;h=272f03ffbd72923ed342e1fb1fccb6fd1d56bd20;hb=5dc7807a9d52d7e907bb39c3c45a9eeb150c3ae6;hp=9d229b6cf742146818262e89ad62517cbf64a00a;hpb=9fc90d029706f970a16553ce5a55ba31d838173a;p=handbrake-jp%2Fhandbrake-jp-git.git diff --git a/libhb/scan.c b/libhb/scan.c index 9d229b6c..272f03ff 100644 --- a/libhb/scan.c +++ b/libhb/scan.c @@ -17,7 +17,8 @@ typedef struct hb_list_t * list_title; hb_dvd_t * dvd; - + hb_stream_t * stream; + } hb_scan_t; static void ScanFunc( void * ); @@ -44,6 +45,9 @@ static void ScanFunc( void * _data ) hb_title_t * title; int i; + data->dvd = NULL; + data->stream = NULL; + /* Try to open the path as a DVD. If it fails, try as a file */ hb_log( "scan: trying to open with libdvdread" ); if( ( data->dvd = hb_dvd_init( data->path ) ) ) @@ -68,18 +72,15 @@ static void ScanFunc( void * _data ) } else { - /* Open as a VOB file */ - FILE * file; - hb_log( "scan: trying to open as VOB file" ); - file = fopen( data->path, "rb" ); - if( file ) + if ( hb_stream_is_stream_type(data->path) ) { - /* XXX */ - fclose( file ); + hb_log( "scan: trying to open as MPEG-2 Stream"); + data->stream = hb_stream_open (data->path); + hb_list_add( data->list_title, hb_stream_title_scan( data->stream ) ); } else { - hb_log( "scan: fopen failed" ); + hb_log( "scan: unrecognized file type" ); return; } } @@ -123,7 +124,7 @@ static void ScanFunc( void * _data ) /* Update the UI */ state.state = HB_STATE_SCANNING; p.title_cur = title->index; - p.title_count = hb_dvd_title_count( data->dvd ); + p.title_count = data->dvd ? hb_dvd_title_count( data->dvd ) : hb_list_count(data->list_title); hb_set_state( data->h, &state ); #undef p @@ -135,7 +136,33 @@ static void ScanFunc( void * _data ) hb_list_rem( data->list_title, title ); continue; } - + + if (data->stream) + { + // Stream based processing uses PID's to handle the different audio options for a given title + for( j = 0; j < hb_list_count( title->list_audio ); j++ ) + { + audio = hb_list_item( title->list_audio, j ); + hb_stream_update_audio(data->stream, audio); + } + } + else if (data->dvd) + { + /* Make sure we found AC3 rates and bitrates */ + for( j = 0; j < hb_list_count( title->list_audio ); ) + { + audio = hb_list_item( title->list_audio, j ); + if( audio->codec == HB_ACODEC_AC3 && + !audio->bitrate ) + { + hb_list_rem( title->list_audio, audio ); + free( audio ); + continue; + } + j++; + } + } + /* Make sure we found AC3 / DCA rates and bitrates */ for( j = 0; j < hb_list_count( title->list_audio ); ) { @@ -159,6 +186,18 @@ static void ScanFunc( void * _data ) free( title ); continue; } + + /* set a default input channel layout of stereo for LPCM or MPEG2 audio */ + /* AC3 and DCA will already have had their layout set via DecodePreviews above, */ + /* which calls LookForAC3AndDCA */ + for( j = 0; j < hb_list_count( title->list_audio ); j++ ) + { + audio = hb_list_item( title->list_audio, j ); + if( audio->codec == HB_ACODEC_LPCM || audio->codec == HB_ACODEC_MPGA ) + { + audio->input_channel_layout = HB_INPUT_CH_LAYOUT_STEREO; + } + } i++; } @@ -229,6 +268,10 @@ static void ScanFunc( void * _data ) { hb_dvd_close( &data->dvd ); } + if (data->stream) + { + hb_stream_close(&data->stream); + } free( data->path ); free( data ); _data = NULL; @@ -247,35 +290,61 @@ static int DecodePreviews( hb_scan_t * data, hb_title_t * title ) hb_buffer_t * buf_ps, * buf_es, * buf_raw; hb_list_t * list_es, * list_raw; hb_libmpeg2_t * mpeg2; - - buf_ps = hb_buffer_init( 2048 ); + int progressive_count = 0; + + buf_ps = hb_buffer_init( HB_DVD_READ_BUFFER_SIZE ); list_es = hb_list_init(); list_raw = hb_list_init(); hb_log( "scan: decoding previews for title %d", title->index ); - hb_dvd_start( data->dvd, title->index, 1 ); - + if (data->dvd) + hb_dvd_start( data->dvd, title->index, 1 ); + for( i = 0; i < 10; i++ ) { int j, k; FILE * file_preview; char filename[1024]; - if( !hb_dvd_seek( data->dvd, (float) ( i + 1 ) / 11.0 ) ) + //hb_log("Seeking to: %f", (float) ( i + 1 ) / 11.0 ); + + if (data->dvd) + { + if( !hb_dvd_seek( data->dvd, (float) ( i + 1 ) / 11.0 ) ) + { + goto error; + } + } + else if (data->stream) { + if (!hb_stream_seek(data->stream, (float) ( i + 1 ) / 11.0 ) ) + { goto error; + } } - + hb_log( "scan: preview %d", i + 1 ); mpeg2 = hb_libmpeg2_init(); for( j = 0; j < 10240 ; j++ ) { - if( !hb_dvd_read( data->dvd, buf_ps ) ) + if (data->dvd) + { + if( !hb_dvd_read( data->dvd, buf_ps ) ) + { + hb_log( "Warning: Could not read data for preview %d, skipped", i + 1 ); + goto skip_preview; + } + } + else if (data->stream) { - goto error; + if ( !hb_stream_read(data->stream,buf_ps) ) + { + hb_log( "Warning: Could not read data for preview %d, skipped", i + 1 ); + goto skip_preview; + } } hb_demux_ps( buf_ps, list_es ); @@ -313,12 +382,56 @@ static int DecodePreviews( hb_scan_t * data, hb_title_t * title ) goto error; } - if( !i ) + /* Get size and rate infos */ + title->rate = 27000000; + int ar; + hb_libmpeg2_info( mpeg2, &title->width, &title->height, + &title->rate_base, &ar ); + + if( title->rate_base == 1126125 ) + { + /* Frame FPS is 23.976 (meaning it's progressive), so + start keeping track of how many are reporting at + that speed. When enough show up that way, we want + to make that the overall title FPS. + */ + progressive_count++; + + if( progressive_count < 6 ) + { + /* Not enough frames are reporting as progressive, + which means we should be conservative and use + 29.97 as the title's FPS for now. + */ + title->rate_base = 900900; + } + else + { + /* A majority of the scan frames are progressive. Make that + the title's FPS, and announce it once to the log. + */ + if( progressive_count == 6 ) + { + hb_log("Title's mostly progressive NTSC, setting fps to 23.976"); + } + title->rate_base = 1126125; + } + } + else if( title->rate_base == 900900 && progressive_count >= 6 ) + { + /* + * We've already deduced that the frame rate is 23.976, so set it + * back again. + */ + title->rate_base = 1126125; + } + + if( i == 2) // Use the third frame's info, so as to skip opening logos { - /* Get size and rate infos */ - title->rate = 27000000; - hb_libmpeg2_info( mpeg2, &title->width, &title->height, - &title->rate_base ); + // The aspect ratio may have already been set by parsing the VOB/IFO details on a DVD, however + // if we're working with program/transport streams that data needs to come from within the stream. + if (title->aspect <= 0) + title->aspect = ar; title->crop[0] = title->crop[1] = title->height / 2; title->crop[2] = title->crop[3] = title->width / 2; } @@ -386,6 +499,7 @@ static int DecodePreviews( hb_scan_t * data, hb_title_t * title ) } } +skip_preview: while( ( buf_raw = hb_list_item( list_raw, 0 ) ) ) { hb_list_rem( list_raw, buf_raw ); @@ -423,7 +537,9 @@ cleanup: hb_buffer_close( &buf_raw ); } hb_list_close( &list_raw ); - hb_dvd_stop( data->dvd ); + if (data->dvd) + hb_dvd_stop( data->dvd ); + return ret; } @@ -441,6 +557,7 @@ static void LookForAC3AndDCA( hb_title_t * title, hb_buffer_t * b ) for( i = 0; i < hb_list_count( title->list_audio ); i++ ) { audio = hb_list_item( title->list_audio, i ); + /* check if we have an AC3 or DCA which we recognise */ if( ( audio->codec == HB_ACODEC_AC3 || audio->codec == HB_ACODEC_DCA ) && audio->id == b->id ) { @@ -476,65 +593,50 @@ static void LookForAC3AndDCA( hb_title_t * title, hb_buffer_t * b ) audio->bitrate = bitrate; switch( flags & A52_CHANNEL_MASK ) { + /* mono sources */ case A52_MONO: case A52_CHANNEL1: case A52_CHANNEL2: - audio->src_discrete_front_channels = 1; - audio->src_discrete_rear_channels = 0; - audio->src_encoded_front_channels = 1; - audio->src_encoded_rear_channels = 0; + audio->input_channel_layout = HB_INPUT_CH_LAYOUT_MONO; break; - case A52_STEREO: + /* stereo input */ case A52_CHANNEL: - audio->src_discrete_front_channels = 2; - audio->src_discrete_rear_channels = 0; - audio->src_encoded_front_channels = 2; - audio->src_encoded_rear_channels = 0; + case A52_STEREO: + audio->input_channel_layout = HB_INPUT_CH_LAYOUT_STEREO; break; + /* dolby (DPL1 aka Dolby Surround = 4.0 matrix-encoded) input */ case A52_DOLBY: - audio->src_discrete_front_channels = 2; - audio->src_discrete_rear_channels = 0; - audio->src_encoded_front_channels = 3; - audio->src_encoded_rear_channels = 1; + audio->input_channel_layout = HB_INPUT_CH_LAYOUT_DOLBY; + break; + /* 3F/2R input */ + case A52_3F2R: + audio->input_channel_layout = HB_INPUT_CH_LAYOUT_3F2R; + break; + /* 3F/1R input */ + case A52_3F1R: + audio->input_channel_layout = HB_INPUT_CH_LAYOUT_3F1R; break; + /* other inputs */ case A52_3F: - audio->src_discrete_front_channels = 3; - audio->src_discrete_rear_channels = 0; - audio->src_encoded_front_channels = 3; - audio->src_encoded_rear_channels = 0; + audio->input_channel_layout = HB_INPUT_CH_LAYOUT_3F; break; case A52_2F1R: - audio->src_discrete_front_channels = 2; - audio->src_discrete_rear_channels = 1; - audio->src_encoded_front_channels = 2; - audio->src_encoded_rear_channels = 1; - break; - case A52_3F1R: - audio->src_discrete_front_channels = 3; - audio->src_discrete_rear_channels = 1; - audio->src_encoded_front_channels = 3; - audio->src_encoded_rear_channels = 1; + audio->input_channel_layout = HB_INPUT_CH_LAYOUT_2F1R; break; case A52_2F2R: - audio->src_discrete_front_channels = 2; - audio->src_discrete_rear_channels = 2; - audio->src_encoded_front_channels = 2; - audio->src_encoded_rear_channels = 2; - break; - case A52_3F2R: - audio->src_discrete_front_channels = 3; - audio->src_discrete_rear_channels = 2; - audio->src_encoded_front_channels = 3; - audio->src_encoded_rear_channels = 2; + audio->input_channel_layout = HB_INPUT_CH_LAYOUT_2F2R; break; - } - - if (flags & A52_LFE) { - audio->src_discrete_lfe_channels = 1; - } else { - audio->src_discrete_lfe_channels = 0; + /* unknown */ + default: + audio->input_channel_layout = HB_INPUT_CH_LAYOUT_STEREO; } + /* add in our own LFE flag if the source has LFE */ + if (flags & A52_LFE) + { + audio->input_channel_layout = audio->input_channel_layout | HB_INPUT_CH_LAYOUT_HAS_LFE; + } + /* store the AC3 flags for future reference This enables us to find out if we had a stereo or Dolby source later on */ audio->config.a52.ac3flags = flags; @@ -549,7 +651,9 @@ static void LookForAC3AndDCA( hb_title_t * title, hb_buffer_t * b ) } else { sprintf( audio->lang + strlen( audio->lang ), " (%d.%d ch)", - audio->src_discrete_front_channels + audio->src_discrete_rear_channels, audio->src_discrete_lfe_channels ); + HB_INPUT_CH_LAYOUT_GET_DISCRETE_FRONT_COUNT(audio->input_channel_layout) + + HB_INPUT_CH_LAYOUT_GET_DISCRETE_REAR_COUNT(audio->input_channel_layout), + HB_INPUT_CH_LAYOUT_GET_DISCRETE_LFE_COUNT(audio->input_channel_layout)); } break; @@ -571,71 +675,49 @@ static void LookForAC3AndDCA( hb_title_t * title, hb_buffer_t * b ) audio->bitrate = bitrate; switch( flags & DCA_CHANNEL_MASK ) { + /* mono sources */ case DCA_MONO: - audio->src_discrete_front_channels = 1; - audio->src_discrete_rear_channels = 0; - audio->src_encoded_front_channels = 1; - audio->src_encoded_rear_channels = 0; + audio->input_channel_layout = HB_INPUT_CH_LAYOUT_MONO; break; + /* stereo input */ case DCA_CHANNEL: case DCA_STEREO: case DCA_STEREO_SUMDIFF: case DCA_STEREO_TOTAL: - audio->src_discrete_front_channels = 2; - audio->src_discrete_rear_channels = 0; - audio->src_encoded_front_channels = 2; - audio->src_encoded_rear_channels = 0; + audio->input_channel_layout = HB_INPUT_CH_LAYOUT_STEREO; break; - case DCA_DOLBY: - audio->src_discrete_front_channels = 2; - audio->src_discrete_rear_channels = 0; - audio->src_encoded_front_channels = 3; - audio->src_encoded_rear_channels = 1; + /* 3F/2R input */ + case DCA_3F2R: + audio->input_channel_layout = HB_INPUT_CH_LAYOUT_3F2R; break; + /* 3F/1R input */ + case DCA_3F1R: + audio->input_channel_layout = HB_INPUT_CH_LAYOUT_3F1R; + break; + /* other inputs */ case DCA_3F: - audio->src_discrete_front_channels = 3; - audio->src_discrete_rear_channels = 0; - audio->src_encoded_front_channels = 3; - audio->src_encoded_rear_channels = 0; + audio->input_channel_layout = HB_INPUT_CH_LAYOUT_3F; break; case DCA_2F1R: - audio->src_discrete_front_channels = 2; - audio->src_discrete_rear_channels = 1; - audio->src_encoded_front_channels = 2; - audio->src_encoded_rear_channels = 1; - break; - case DCA_3F1R: - audio->src_discrete_front_channels = 3; - audio->src_discrete_rear_channels = 1; - audio->src_encoded_front_channels = 3; - audio->src_encoded_rear_channels = 1; + audio->input_channel_layout = HB_INPUT_CH_LAYOUT_2F1R; break; case DCA_2F2R: - audio->src_discrete_front_channels = 2; - audio->src_discrete_rear_channels = 2; - audio->src_encoded_front_channels = 2; - audio->src_encoded_rear_channels = 2; - break; - case DCA_3F2R: - audio->src_discrete_front_channels = 3; - audio->src_discrete_rear_channels = 2; - audio->src_encoded_front_channels = 3; - audio->src_encoded_rear_channels = 2; + audio->input_channel_layout = HB_INPUT_CH_LAYOUT_2F2R; break; case DCA_4F2R: - audio->src_discrete_front_channels = 4; - audio->src_discrete_rear_channels = 2; - audio->src_encoded_front_channels = 4; - audio->src_encoded_rear_channels = 2; + audio->input_channel_layout = HB_INPUT_CH_LAYOUT_4F2R; break; + /* unknown */ + default: + audio->input_channel_layout = HB_INPUT_CH_LAYOUT_STEREO; } - if (flags & DCA_LFE) { - audio->src_discrete_lfe_channels = 1; - } else { - audio->src_discrete_lfe_channels = 0; + /* add in our own LFE flag if the source has LFE */ + if (flags & DCA_LFE) + { + audio->input_channel_layout = audio->input_channel_layout | HB_INPUT_CH_LAYOUT_HAS_LFE; } - + /* store the DCA flags for future reference This enables us to find out if we had a stereo or Dolby source later on */ audio->config.dca.dcaflags = flags; @@ -650,13 +732,16 @@ static void LookForAC3AndDCA( hb_title_t * title, hb_buffer_t * b ) } else { sprintf( audio->lang + strlen( audio->lang ), " (%d.%d ch)", - audio->src_discrete_front_channels + audio->src_discrete_rear_channels, audio->src_discrete_lfe_channels ); + HB_INPUT_CH_LAYOUT_GET_DISCRETE_FRONT_COUNT(audio->input_channel_layout) + + HB_INPUT_CH_LAYOUT_GET_DISCRETE_REAR_COUNT(audio->input_channel_layout), + HB_INPUT_CH_LAYOUT_GET_DISCRETE_LFE_COUNT(audio->input_channel_layout)); } break; } } } + } static int AllAC3AndDCAOK( hb_title_t * title )