X-Git-Url: http://git.osdn.jp/view?a=blobdiff_plain;f=libhb%2Fscan.c;h=445314bcd8695ee5faf7e717a59e23e888c1a8b0;hb=4b72a63eb61a01275493c4bfb51ba02152d1c5e1;hp=ea15fc512eb32230d8faf293bc943c9319cce7f8;hpb=7dc534bc87accdf2d58a0a6e8e209fdf9c46f41a;p=handbrake-jp%2Fhandbrake-jp-git.git diff --git a/libhb/scan.c b/libhb/scan.c index ea15fc51..445314bc 100644 --- a/libhb/scan.c +++ b/libhb/scan.c @@ -19,13 +19,16 @@ typedef struct int title_index; hb_list_t * list_title; + hb_bd_t * bd; hb_dvd_t * dvd; hb_stream_t * stream; hb_batch_t * batch; - + int preview_count; int store_previews; + uint64_t min_title_duration; + } hb_scan_t; static void ScanFunc( void * ); @@ -48,7 +51,7 @@ static const char *aspect_to_string( double aspect ) hb_thread_t * hb_scan_init( hb_handle_t * handle, volatile int * die, const char * path, int title_index, hb_list_t * list_title, int preview_count, - int store_previews ) + int store_previews, uint64_t min_duration ) { hb_scan_t * data = calloc( sizeof( hb_scan_t ), 1 ); @@ -60,6 +63,7 @@ hb_thread_t * hb_scan_init( hb_handle_t * handle, volatile int * die, data->preview_count = preview_count; data->store_previews = store_previews; + data->min_title_duration = min_duration; return hb_thread_init( "scan", ScanFunc, data, HB_NORMAL_PRIORITY ); } @@ -69,13 +73,35 @@ static void ScanFunc( void * _data ) hb_scan_t * data = (hb_scan_t *) _data; hb_title_t * title; int i; + int feature = 0; - data->dvd = NULL; - data->stream = NULL; + data->bd = NULL; + 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 ) ) ) + if( ( data->bd = hb_bd_init( data->path ) ) ) + { + hb_log( "scan: BD has %d title(s)", + hb_bd_title_count( data->bd ) ); + if( data->title_index ) + { + /* Scan this title only */ + hb_list_add( data->list_title, hb_bd_title_scan( data->bd, + data->title_index, 0 ) ); + } + else + { + /* Scan all titles */ + for( i = 0; i < hb_bd_title_count( data->bd ); i++ ) + { + hb_list_add( data->list_title, hb_bd_title_scan( data->bd, + i + 1, data->min_title_duration ) ); + } + feature = hb_bd_main_feature( data->bd, data->list_title ); + } + } + else if( ( data->dvd = hb_dvd_init( data->path ) ) ) { hb_log( "scan: DVD has %d title(s)", hb_dvd_title_count( data->dvd ) ); @@ -83,31 +109,44 @@ static void ScanFunc( void * _data ) { /* Scan this title only */ hb_list_add( data->list_title, hb_dvd_title_scan( data->dvd, - data->title_index ) ); + data->title_index, 0 ) ); } else { /* Scan all titles */ for( i = 0; i < hb_dvd_title_count( data->dvd ); i++ ) { - hb_list_add( data->list_title, - hb_dvd_title_scan( data->dvd, i + 1 ) ); + hb_list_add( data->list_title, hb_dvd_title_scan( data->dvd, + i + 1, data->min_title_duration ) ); } + feature = hb_dvd_main_feature( data->dvd, data->list_title ); } } else if ( ( data->batch = hb_batch_init( data->path ) ) ) { - /* Scan all titles */ - for( i = 0; i < hb_batch_title_count( data->batch ); i++ ) + if( data->title_index ) { - hb_title_t * title; - - title = hb_batch_title_scan( data->batch, i + 1 ); - if ( title != NULL ) + /* Scan this title only */ + title = hb_batch_title_scan( data->batch, data->title_index ); + if ( title ) { hb_list_add( data->list_title, title ); } } + else + { + /* Scan all titles */ + for( i = 0; i < hb_batch_title_count( data->batch ); i++ ) + { + hb_title_t * title; + + title = hb_batch_title_scan( data->batch, i + 1 ); + if ( title != NULL ) + { + hb_list_add( data->list_title, title ); + } + } + } } else if ( (data->stream = hb_stream_open( data->path, 0 ) ) != NULL ) { @@ -127,7 +166,7 @@ static void ScanFunc( void * _data ) if ( *data->die ) { - goto finish; + goto finish; } title = hb_list_item( data->list_title, i ); @@ -135,7 +174,9 @@ static void ScanFunc( void * _data ) /* Update the UI */ state.state = HB_STATE_SCANNING; p.title_cur = title->index; - p.title_count = data->dvd ? hb_dvd_title_count( data->dvd ) : hb_list_count(data->list_title); + p.title_count = data->dvd ? hb_dvd_title_count( data->dvd ) : + data->bd ? hb_bd_title_count( data->bd ) : + hb_list_count(data->list_title); hb_set_state( data->h, &state ); #undef p @@ -160,9 +201,30 @@ static void ScanFunc( void * _data ) free( audio ); continue; } + if ( audio->priv.scan_cache ) + { + hb_fifo_flush( audio->priv.scan_cache ); + hb_fifo_close( &audio->priv.scan_cache ); + } j++; } + if ( data->dvd || data->bd ) + { + // The subtitle width and height needs to be set to the + // title widht and height for DVDs. title width and + // height don't get set until we decode previews, so + // we can't set subtitle width/height till we get here. + for( j = 0; j < hb_list_count( title->list_subtitle ); j++ ) + { + hb_subtitle_t *subtitle = hb_list_item( title->list_subtitle, j ); + if ( subtitle->source == VOBSUB ) + { + subtitle->width = title->width; + subtitle->height = title->height; + } + } + } i++; } @@ -176,6 +238,7 @@ static void ScanFunc( void * _data ) title->job = job; job->title = title; + job->feature = feature; /* Set defaults settings */ job->chapter_start = 1; @@ -226,14 +289,18 @@ static void ScanFunc( void * _data ) finish: + if( data->bd ) + { + hb_bd_close( &data->bd ); + } if( data->dvd ) { hb_dvd_close( &data->dvd ); } - if (data->stream) - { - hb_stream_close(&data->stream); - } + if (data->stream) + { + hb_stream_close(&data->stream); + } if( data->batch ) { hb_batch_close( &data->batch ); @@ -405,7 +472,12 @@ static int DecodePreviews( hb_scan_t * data, hb_title_t * title ) hb_log( "scan: decoding previews for title %d", title->index ); - if (data->dvd) + if (data->bd) + { + hb_bd_start( data->bd, title ); + hb_log( "scan: title angle(s) %d", title->angle_count ); + } + else if (data->dvd) { hb_dvd_start( data->dvd, title, 1 ); title->angle_count = hb_dvd_angle_count( data->dvd ); @@ -426,9 +498,16 @@ static int DecodePreviews( hb_scan_t * data, hb_title_t * title ) { return 0; } + if (data->bd) + { + if( !hb_bd_seek( data->bd, (float) ( i + 1 ) / ( data->preview_count + 1.0 ) ) ) + { + continue; + } + } if (data->dvd) { - if( !hb_dvd_seek( data->dvd, (float) ( i + 1 ) / ( data->preview_count + 1.0 ) ) ) + if( !hb_dvd_seek( data->dvd, (float) ( i + 1 ) / ( data->preview_count + 1.0 ) ) ) { continue; } @@ -466,10 +545,26 @@ static int DecodePreviews( hb_scan_t * data, hb_title_t * title ) { vidskip = (double)title->rate / (double)title->rate_base + 0.5; } + // If it's a BD, we can relax this a bit. Since seeks will + // at least get us to a recovery point. + if (data->bd) + vidskip = 4; } for( j = 0; j < 10240 ; j++ ) { + if (data->bd) + { + if( !hb_bd_read( data->bd, buf_ps ) ) + { + if ( vid_buf ) + { + break; + } + hb_log( "Warning: Could not read data for preview %d, skipped", i + 1 ); + goto skip_preview; + } + } if (data->dvd) { if( !hb_dvd_read( data->dvd, buf_ps ) ) @@ -506,13 +601,19 @@ static int DecodePreviews( hb_scan_t * data, hb_title_t * title ) { // we're dropping frames to get the video decoder in sync // when the video stream doesn't contain IDR frames - hb_buffer_close( &vid_buf ); - vid_buf = NULL; + while (vid_buf && --vidskip >= 0) + { + hb_buffer_t * next = vid_buf->next; + vid_buf->next = NULL; + hb_buffer_close( &vid_buf ); + vid_buf = next; + } } } - else if( ! AllAudioOK( title ) ) + else if( ! AllAudioOK( title ) ) { LookForAudio( title, buf_es ); + buf_es = NULL; } if ( buf_es ) hb_buffer_close( &buf_es ); @@ -537,6 +638,10 @@ static int DecodePreviews( hb_scan_t * data, hb_title_t * title ) * Could not fill vid_info, don't continue and try to use vid_info * in this case. */ + if (vid_buf) + { + hb_buffer_close( &vid_buf ); + } vid_decoder->close( vid_decoder ); free( vid_decoder ); continue; @@ -606,8 +711,8 @@ static int DecodePreviews( hb_scan_t * data, hb_title_t * title ) if( data->store_previews ) { - hb_get_tempory_filename( data->h, filename, "%" PRIxPTR "%d", - (intptr_t)title, i ); + hb_get_tempory_filename( data->h, filename, "%d_%d_%d", + hb_get_instance_id(data->h), title->index, i ); file_preview = fopen( filename, "wb" ); if( file_preview ) @@ -695,8 +800,19 @@ static int DecodePreviews( hb_scan_t * data, hb_title_t * title ) ++npreviews; skip_preview: - if ( vid_buf ) + /* Make sure we found audio rates and bitrates */ + for( j = 0; j < hb_list_count( title->list_audio ); j++ ) + { + hb_audio_t * audio = hb_list_item( title->list_audio, j ); + if ( audio->priv.scan_cache ) + { + hb_fifo_flush( audio->priv.scan_cache ); + } + } + if (vid_buf) + { hb_buffer_close( &vid_buf ); + } } if ( data->batch && data->stream ) @@ -786,6 +902,8 @@ skip_preview: hb_buffer_close( &buf_es ); } hb_list_close( &list_es ); + if (data->bd) + hb_bd_stop( data->bd ); if (data->dvd) hb_dvd_stop( data->dvd ); @@ -827,9 +945,21 @@ static void LookForAudio( hb_title_t * title, hb_buffer_t * b ) if( !audio || audio->config.in.bitrate != 0 ) { /* not found or already done */ + hb_buffer_close( &b ); return; } + if ( audio->priv.scan_cache == NULL ) + audio->priv.scan_cache = hb_fifo_init( 16, 16 ); + + if ( hb_fifo_size_bytes( audio->priv.scan_cache ) >= 4096 ) + { + hb_buffer_t * tmp; + tmp = hb_fifo_get( audio->priv.scan_cache ); + hb_buffer_close( &tmp ); + } + hb_fifo_push( audio->priv.scan_cache, b ); + hb_work_object_t *w = hb_codec_decoder( audio->config.in.codec ); if ( w == NULL || w->bsinfo == NULL ) @@ -842,6 +972,7 @@ static void LookForAudio( hb_title_t * title, hb_buffer_t * b ) hb_work_info_t info; w->audio = audio; w->codec_param = audio->config.in.codec_param; + b = hb_fifo_see( audio->priv.scan_cache ); int ret = w->bsinfo( w, b, &info ); if ( ret < 0 ) { @@ -855,6 +986,9 @@ static void LookForAudio( hb_title_t * title, hb_buffer_t * b ) /* didn't find any info */ return; } + hb_fifo_flush( audio->priv.scan_cache ); + hb_fifo_close( &audio->priv.scan_cache ); + audio->config.in.samplerate = info.rate; audio->config.in.bitrate = info.bitrate; audio->config.in.channel_layout = info.channel_layout; @@ -895,7 +1029,10 @@ static void LookForAudio( hb_title_t * title, hb_buffer_t * b ) if ( w ) free( w ); + hb_fifo_flush( audio->priv.scan_cache ); + hb_fifo_close( &audio->priv.scan_cache ); hb_list_rem( title->list_audio, audio ); + return; } /*