X-Git-Url: http://git.osdn.jp/view?a=blobdiff_plain;f=libhb%2Fscan.c;h=74cc52adb9b96c4dda1de5cdf331b28d01c5942f;hb=033e32de9c380f54c7d1362a3979da205ebc3a29;hp=36a90cd4d0759f79cd0685be38c66265b3137b45;hpb=8ab542f1e527adc6058fde914347a556e0b5b78b;p=handbrake-jp%2Fhandbrake-jp-git.git diff --git a/libhb/scan.c b/libhb/scan.c index 36a90cd4..74cc52ad 100644 --- a/libhb/scan.c +++ b/libhb/scan.c @@ -8,6 +8,8 @@ #include "a52dec/a52.h" #include "dca.h" +#define HB_MAX_PREVIEWS 30 // 30 previews = every 5 minutes of a 2.5 hour video + typedef struct { hb_handle_t * h; @@ -18,6 +20,9 @@ typedef struct hb_dvd_t * dvd; hb_stream_t * stream; + + int preview_count; + int store_previews; } hb_scan_t; @@ -39,7 +44,8 @@ static const char *aspect_to_string( double aspect ) } hb_thread_t * hb_scan_init( hb_handle_t * handle, const char * path, - int title_index, hb_list_t * list_title ) + int title_index, hb_list_t * list_title, + int preview_count, int store_previews ) { hb_scan_t * data = calloc( sizeof( hb_scan_t ), 1 ); @@ -47,7 +53,10 @@ hb_thread_t * hb_scan_init( hb_handle_t * handle, const char * path, data->path = strdup( path ); data->title_index = title_index; data->list_title = list_title; - + + data->preview_count = preview_count; + data->store_previews = store_previews; + return hb_thread_init( "scan", ScanFunc, data, HB_NORMAL_PRIORITY ); } @@ -97,36 +106,9 @@ static void ScanFunc( void * _data ) int j; hb_state_t state; hb_audio_t * audio; - hb_title_t * title_tmp = NULL; title = hb_list_item( data->list_title, i ); - /* I've seen a DVD with strictly identical titles. Check this - here and ignore it if redundant */ - for( j = 0; j < i; j++ ) - { - title_tmp = hb_list_item( data->list_title, j ); - if( title->vts == title_tmp->vts && - title->block_start == title_tmp->block_start && - title->block_end == title_tmp->block_end && - title->block_count == title_tmp->block_count ) - { - break; - } - else - { - title_tmp = NULL; - } - } - if( title_tmp ) - { - hb_log( "scan: title %d is duplicate with title %d", - title->index, title_tmp->index ); - hb_list_rem( data->list_title, title ); - free( title ); /* This _will_ leak! */ - continue; - } - #define p state.param.scanning /* Update the UI */ state.state = HB_STATE_SCANNING; @@ -159,14 +141,6 @@ static void ScanFunc( void * _data ) j++; } - /* If we don't have any audio streams left, remove the title */ - if( !hb_list_count( title->list_audio ) ) - { - hb_list_rem( data->list_title, title ); - free( title ); - continue; - } - i++; } @@ -191,15 +165,15 @@ static void ScanFunc( void * _data ) /* Preserve a source's pixel aspect, if it's available. */ if( title->pixel_aspect_width && title->pixel_aspect_height ) { - job->pixel_aspect_width = title->pixel_aspect_width; - job->pixel_aspect_height = title->pixel_aspect_height; + job->anamorphic.par_width = title->pixel_aspect_width; + job->anamorphic.par_height = title->pixel_aspect_height; } if( title->aspect != 0 && title->aspect != 1. && - !job->pixel_aspect_width && !job->pixel_aspect_height) + !job->anamorphic.par_width && !job->anamorphic.par_height) { - hb_reduce( &job->pixel_aspect_width, &job->pixel_aspect_height, - (int)(title->aspect * title->height), title->width ); + hb_reduce( &job->anamorphic.par_width, &job->anamorphic.par_height, + (int)(title->aspect * title->height + 0.5), title->width ); } job->width = title->width - job->crop[2] - job->crop[3]; @@ -223,8 +197,7 @@ static void ScanFunc( void * _data ) job->vrate_base = title->rate_base; job->list_audio = hb_list_init(); - - job->subtitle = -1; + job->list_subtitle = hb_list_init(); job->mux = HB_MUX_MP4; } @@ -315,10 +288,10 @@ static int column_all_dark( hb_title_t *title, uint8_t* luma, int top, int botto typedef struct { int n; - int t[10]; - int b[10]; - int l[10]; - int r[10]; + int t[HB_MAX_PREVIEWS]; + int b[HB_MAX_PREVIEWS]; + int l[HB_MAX_PREVIEWS]; + int r[HB_MAX_PREVIEWS]; } crop_record_t; static void record_crop( crop_record_t *crops, int t, int b, int l, int r ) @@ -396,7 +369,7 @@ static int DecodePreviews( hb_scan_t * data, hb_title_t * title ) hb_list_t * list_es; int progressive_count = 0; int interlaced_preview_count = 0; - info_list_t * info_list = calloc( 10+1, sizeof(*info_list) ); + info_list_t * info_list = calloc( data->preview_count+1, sizeof(*info_list) ); crop_record_t *crops = calloc( 1, sizeof(*crops) ); buf_ps = hb_buffer_init( HB_DVD_READ_BUFFER_SIZE ); @@ -405,9 +378,13 @@ static int DecodePreviews( hb_scan_t * data, hb_title_t * title ) hb_log( "scan: decoding previews for title %d", title->index ); if (data->dvd) - hb_dvd_start( data->dvd, title->index, 1 ); + { + hb_dvd_start( data->dvd, title, 1 ); + title->angle_count = hb_dvd_angle_count( data->dvd ); + hb_log( "scan: title angle(s) %d", title->angle_count ); + } - for( i = 0; i < 10; i++ ) + for( i = 0; i < data->preview_count; i++ ) { int j; FILE * file_preview; @@ -415,7 +392,7 @@ static int DecodePreviews( hb_scan_t * data, hb_title_t * title ) if (data->dvd) { - if( !hb_dvd_seek( data->dvd, (float) ( i + 1 ) / 11.0 ) ) + if( !hb_dvd_seek( data->dvd, (float) ( i + 1 ) / ( data->preview_count + 1.0 ) ) ) { continue; } @@ -425,7 +402,7 @@ static int DecodePreviews( hb_scan_t * data, hb_title_t * title ) /* we start reading streams at zero rather than 1/11 because * short streams may have only one sequence header in the entire * file and we need it to decode any previews. */ - if (!hb_stream_seek(data->stream, (float) i / 11.0 ) ) + if (!hb_stream_seek(data->stream, (float) i / ( data->preview_count + 1.0 ) ) ) { continue; } @@ -436,8 +413,24 @@ static int DecodePreviews( hb_scan_t * data, hb_title_t * title ) int vcodec = title->video_codec? title->video_codec : WORK_DECMPEG2; hb_work_object_t *vid_decoder = hb_get_work( vcodec ); vid_decoder->codec_param = title->video_codec_param; + vid_decoder->title = title; vid_decoder->init( vid_decoder, NULL ); hb_buffer_t * vid_buf = NULL; + int vidskip = 0; + + if ( title->flags & HBTF_NO_IDR ) + { + // title doesn't have IDR frames so we decode but drop one second's + // worth of frames to allow the decoder to converge. + if ( ! title->rate_base ) + { + vidskip = 30; + } + else + { + vidskip = (double)title->rate / (double)title->rate_base + 0.5; + } + } for( j = 0; j < 10240 ; j++ ) { @@ -445,6 +438,10 @@ static int DecodePreviews( hb_scan_t * data, hb_title_t * title ) { if( !hb_dvd_read( data->dvd, buf_ps ) ) { + if ( vid_buf ) + { + break; + } hb_log( "Warning: Could not read data for preview %d, skipped", i + 1 ); goto skip_preview; } @@ -453,18 +450,15 @@ static int DecodePreviews( hb_scan_t * data, hb_title_t * title ) { if ( !hb_stream_read(data->stream,buf_ps) ) { + if ( vid_buf ) + { + break; + } hb_log( "Warning: Could not read data for preview %d, skipped", i + 1 ); goto skip_preview; } } - if ( title->demuxer == HB_NULL_DEMUXER ) - { - hb_demux_null( buf_ps, list_es, 0 ); - } - else - { - hb_demux_ps( buf_ps, list_es, 0 ); - } + (hb_demux[title->demuxer])(buf_ps, list_es, 0 ); while( ( buf_es = hb_list_item( list_es, 0 ) ) ) { @@ -472,6 +466,13 @@ static int DecodePreviews( hb_scan_t * data, hb_title_t * title ) if( buf_es->id == title->video_id && vid_buf == NULL ) { vid_decoder->work( vid_decoder, &buf_es, &vid_buf ); + if ( vid_buf && vidskip && --vidskip > 0 ) + { + // 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; + } } else if( ! AllAudioOK( title ) ) { @@ -566,20 +567,23 @@ static int DecodePreviews( hb_scan_t * data, hb_title_t * title ) hb_deep_log( 2, "Interlacing detected in preview frame %i", i+1); interlaced_preview_count++; } - - hb_get_tempory_filename( data->h, filename, "%x%d", - (intptr_t)title, i ); - - file_preview = fopen( filename, "w" ); - if( file_preview ) - { - fwrite( vid_buf->data, title->width * title->height * 3 / 2, - 1, file_preview ); - fclose( file_preview ); - } - else + + if( data->store_previews ) { - hb_log( "scan: fopen failed (%s)", filename ); + hb_get_tempory_filename( data->h, filename, "%" PRIxPTR "%d", + (intptr_t)title, i ); + + file_preview = fopen( filename, "wb" ); + if( file_preview ) + { + fwrite( vid_buf->data, title->width * title->height * 3 / 2, + 1, file_preview ); + fclose( file_preview ); + } + else + { + hb_log( "scan: fopen failed (%s)", filename ); + } } /* Detect black borders */ @@ -685,14 +689,14 @@ skip_preview: // aspect ratio from the DVD metadata. So, if the aspect computed // from the PAR is different from the container's aspect we use // the container's aspect & recompute the PAR from it. - if( title->container_aspect && title->aspect != title->container_aspect ) + if( title->container_aspect && (int)(title->aspect * 9) != (int)(title->container_aspect * 9) ) { hb_log("scan: content PAR gives wrong aspect %.2f; " "using container aspect %.2f", title->aspect, title->container_aspect ); title->aspect = title->container_aspect; hb_reduce( &title->pixel_aspect_width, &title->pixel_aspect_height, - (int)(title->aspect * title->height), title->width ); + (int)(title->aspect * title->height + 0.5), title->width ); } } @@ -813,6 +817,8 @@ static void LookForAudio( hb_title_t * title, hb_buffer_t * b ) audio->config.in.samplerate = info.rate; audio->config.in.bitrate = info.bitrate; audio->config.in.channel_layout = info.channel_layout; + audio->config.in.version = info.version; + audio->config.in.mode = info.mode; audio->config.flags.ac3 = info.flags; // update the audio description string based on the info we found