X-Git-Url: http://git.osdn.jp/view?a=blobdiff_plain;f=libhb%2Fhb.c;h=11b80357e26c9ff777c6fabdc818c2b150b83c3f;hb=4b72a63eb61a01275493c4bfb51ba02152d1c5e1;hp=e26c670ef3f6235c6707678acc8218cca2e9f065;hpb=0f6d45f5115f5337764104727651664fe5c6e90a;p=handbrake-jp%2Fhandbrake-jp-git.git diff --git a/libhb/hb.c b/libhb/hb.c index e26c670e..11b80357 100644 --- a/libhb/hb.c +++ b/libhb/hb.c @@ -2,12 +2,14 @@ #include "hbffmpeg.h" #include #include -#include #include -#if defined( SYS_MINGW ) && defined( PTW32_STATIC_LIB ) +#if defined( SYS_MINGW ) +#include +#if defined( PTW32_STATIC_LIB ) #include #endif +#endif struct hb_handle_s { @@ -63,6 +65,7 @@ int hb_instance_counter = 0; int hb_process_initialized = 0; static void thread_func( void * ); +hb_title_t * hb_get_title_by_index( hb_handle_t *, int ); void hb_avcodec_init() { @@ -90,47 +93,95 @@ int hb_avcodec_close(AVCodecContext *avctx) int hb_ff_layout_xlat(int64_t ff_channel_layout, int channels) { + int hb_layout; + switch (ff_channel_layout) { case CH_LAYOUT_MONO: - return HB_INPUT_CH_LAYOUT_MONO; + hb_layout = HB_INPUT_CH_LAYOUT_MONO; + break; case CH_LAYOUT_STEREO: - return HB_INPUT_CH_LAYOUT_STEREO; + hb_layout = HB_INPUT_CH_LAYOUT_STEREO; + break; case CH_LAYOUT_SURROUND: - return HB_INPUT_CH_LAYOUT_3F; + hb_layout = HB_INPUT_CH_LAYOUT_3F; + break; case CH_LAYOUT_4POINT0: - return HB_INPUT_CH_LAYOUT_3F1R; + hb_layout = HB_INPUT_CH_LAYOUT_3F1R; + break; case CH_LAYOUT_2_2: - return HB_INPUT_CH_LAYOUT_2F2R; + hb_layout = HB_INPUT_CH_LAYOUT_2F2R; + break; case CH_LAYOUT_QUAD: - return HB_INPUT_CH_LAYOUT_2F2R; + hb_layout = HB_INPUT_CH_LAYOUT_2F2R; + break; case CH_LAYOUT_5POINT0: - // ffmpeg like to neglect to signal LFE - if (channels == 6) - return HB_INPUT_CH_LAYOUT_3F2R|HB_INPUT_CH_LAYOUT_HAS_LFE; - return HB_INPUT_CH_LAYOUT_3F2R; + hb_layout = HB_INPUT_CH_LAYOUT_3F2R; + break; case CH_LAYOUT_5POINT1: - return HB_INPUT_CH_LAYOUT_3F2R|HB_INPUT_CH_LAYOUT_HAS_LFE; + hb_layout = HB_INPUT_CH_LAYOUT_3F2R|HB_INPUT_CH_LAYOUT_HAS_LFE; + break; case CH_LAYOUT_5POINT0_BACK: - // ffmpeg like to neglect to signal LFE - if (channels == 6) - return HB_INPUT_CH_LAYOUT_3F2R|HB_INPUT_CH_LAYOUT_HAS_LFE; - return HB_INPUT_CH_LAYOUT_3F2R; + hb_layout = HB_INPUT_CH_LAYOUT_3F2R; + break; case CH_LAYOUT_5POINT1_BACK: - return HB_INPUT_CH_LAYOUT_3F2R|HB_INPUT_CH_LAYOUT_HAS_LFE; + hb_layout = HB_INPUT_CH_LAYOUT_3F2R|HB_INPUT_CH_LAYOUT_HAS_LFE; + break; case CH_LAYOUT_7POINT0: - // ffmpeg like to neglect to signal LFE - if (channels == 8) - return HB_INPUT_CH_LAYOUT_3F4R|HB_INPUT_CH_LAYOUT_HAS_LFE; - return HB_INPUT_CH_LAYOUT_3F4R; + hb_layout = HB_INPUT_CH_LAYOUT_3F4R; + break; case CH_LAYOUT_7POINT1: - return HB_INPUT_CH_LAYOUT_3F4R|HB_INPUT_CH_LAYOUT_HAS_LFE; + hb_layout = HB_INPUT_CH_LAYOUT_3F4R|HB_INPUT_CH_LAYOUT_HAS_LFE; + break; case CH_LAYOUT_STEREO_DOWNMIX: - return HB_INPUT_CH_LAYOUT_STEREO; + hb_layout = HB_INPUT_CH_LAYOUT_STEREO; + break; default: - return HB_INPUT_CH_LAYOUT_STEREO; + hb_layout = HB_INPUT_CH_LAYOUT_STEREO; + break; } - return HB_INPUT_CH_LAYOUT_STEREO; + // Now make sure the chosen layout agrees with the number of channels + // ffmpeg tells us there are. It seems ffmpeg is sometimes confused + // about this. So we will make a best guess based on the number + // of channels. + int chans = HB_INPUT_CH_LAYOUT_GET_DISCRETE_COUNT( hb_layout ); + if ( chans == channels ) + { + return hb_layout; + } + hb_log( "Channels reported by ffmpeg (%d) != computed layout channels (%d).", channels, chans ); + switch (channels) + { + case 1: + hb_layout = HB_INPUT_CH_LAYOUT_MONO; + break; + case 2: + hb_layout = HB_INPUT_CH_LAYOUT_STEREO; + break; + case 3: + hb_layout = HB_INPUT_CH_LAYOUT_3F; + break; + case 4: + hb_layout = HB_INPUT_CH_LAYOUT_3F1R; + break; + case 5: + hb_layout = HB_INPUT_CH_LAYOUT_3F2R; + break; + case 6: + hb_layout = HB_INPUT_CH_LAYOUT_3F2R|HB_INPUT_CH_LAYOUT_HAS_LFE; + break; + case 7: + hb_layout = HB_INPUT_CH_LAYOUT_3F4R; + break; + case 8: + hb_layout = HB_INPUT_CH_LAYOUT_3F4R|HB_INPUT_CH_LAYOUT_HAS_LFE; + break; + default: + hb_log("Unsupported number of audio channels (%d).\n", channels); + hb_layout = 0; + break; + } + return hb_layout; } /** @@ -165,7 +216,10 @@ static void process_init() void (*hb_log_callback)(const char* message); static void redirect_thread_func(void *); + +#if defined( SYS_MINGW ) #define pipe(phandles) _pipe (phandles, 4096, _O_BINARY) +#endif /** * Registers the given function as a logger. All logs will be passed to it. @@ -262,6 +316,9 @@ hb_handle_t * hb_init( int verbose, int update_check ) hb_register( &hb_encvobsub ); hb_register( &hb_deccc608 ); hb_register( &hb_decsrtsub ); + hb_register( &hb_decutf8sub ); + hb_register( &hb_dectx3gsub ); + hb_register( &hb_decssasub ); hb_register( &hb_render ); hb_register( &hb_encavcodec ); hb_register( &hb_encx264 ); @@ -363,6 +420,9 @@ hb_handle_t * hb_init_dl( int verbose, int update_check ) hb_register( &hb_encvobsub ); hb_register( &hb_deccc608 ); hb_register( &hb_decsrtsub ); + hb_register( &hb_decutf8sub ); + hb_register( &hb_dectx3gsub ); + hb_register( &hb_decssasub ); hb_register( &hb_render ); hb_register( &hb_encavcodec ); hb_register( &hb_encx264 ); @@ -479,7 +539,7 @@ void hb_remove_previews( hb_handle_t * h ) * @param store_previews Whether or not to write previews to disk. */ void hb_scan( hb_handle_t * h, const char * path, int title_index, - int preview_count, int store_previews ) + int preview_count, int store_previews, uint64_t min_duration ) { hb_title_t * title; @@ -496,7 +556,7 @@ void hb_scan( hb_handle_t * h, const char * path, int title_index, hb_log( "hb_scan: path=%s, title_index=%d", path, title_index ); h->scan_thread = hb_scan_init( h, &h->scan_die, path, title_index, h->list_title, preview_count, - store_previews ); + store_previews, min_duration ); } /** @@ -520,7 +580,7 @@ void hb_get_preview_by_index( hb_handle_t * h, int title_index, int picture, uin { hb_title_t * title; - title = hb_list_item( h->list_title, title_index - 1 ); + title = hb_get_title_by_index( h, title_index ); if ( title != NULL ) { hb_get_preview( h, title, picture, buffer ); @@ -763,7 +823,7 @@ void hb_set_anamorphic_size_by_index( hb_handle_t * h, int title_index, int *output_par_width, int *output_par_height ) { hb_title_t * title; - title = hb_list_item( h->list_title, title_index - 1 ); + title = hb_get_title_by_index( h, title_index ); hb_set_anamorphic_size( title->job, output_width, output_height, output_par_width, output_par_height ); } @@ -847,6 +907,11 @@ void hb_set_anamorphic_size( hb_job_t * job, - 3: Power user anamorphic, specify everything */ int width, height; + int maxWidth, maxHeight; + + maxWidth = MULTIPLE_MOD_DOWN( job->maxWidth, mod ); + maxHeight = MULTIPLE_MOD_DOWN( job->maxHeight, mod ); + switch( job->anamorphic.mode ) { case 1: @@ -873,27 +938,24 @@ void hb_set_anamorphic_size( hb_job_t * job, If not, set job height to job width divided by storage aspect. */ - if ( job->maxWidth && (job->maxWidth < job->width) ) - width = job->maxWidth; - /* Time to get picture width that divide cleanly.*/ width = MULTIPLE_MOD( width, mod); - /* Verify these new dimensions don't violate max height and width settings */ - if ( job->maxWidth && (job->maxWidth < job->width) ) - width = job->maxWidth; + if ( maxWidth && (maxWidth < job->width) ) + width = maxWidth; + /* Verify these new dimensions don't violate max height and width settings */ height = ((double)width / storage_aspect) + 0.5; - - if ( job->maxHeight && (job->maxHeight < height) ) - height = job->maxHeight; /* Time to get picture height that divide cleanly.*/ height = MULTIPLE_MOD( height, mod); - - /* Verify these new dimensions don't violate max height and width settings */ - if ( job->maxHeight && (job->maxHeight < height) ) - height = job->maxHeight; + + if ( maxHeight && (maxHeight < height) ) + { + height = maxHeight; + width = ((double)height * storage_aspect) + 0.5; + width = MULTIPLE_MOD( width, mod); + } /* The film AR is the source's display width / cropped source height. The output display width is the output height * film AR. @@ -911,28 +973,42 @@ void hb_set_anamorphic_size( hb_job_t * job, - Set everything based on specified values */ /* Use specified storage dimensions */ + storage_aspect = (double)job->width / (double)job->height; width = job->width; height = job->height; - /* Bind to max dimensions */ - if( job->maxWidth && width > job->maxWidth ) - width = job->maxWidth; - if( job->maxHeight && height > job->maxHeight ) - height = job->maxHeight; - /* Time to get picture dimensions that divide cleanly.*/ width = MULTIPLE_MOD( width, mod); height = MULTIPLE_MOD( height, mod); - /* Verify we're still within max dimensions */ - if( job->maxWidth && width > job->maxWidth ) - width = job->maxWidth - (mod/2); - if( job->maxHeight && height > job->maxHeight ) - height = job->maxHeight - (mod/2); - - /* Re-ensure we have picture dimensions that divide cleanly. */ - width = MULTIPLE_MOD( width, mod ); - height = MULTIPLE_MOD( height, mod ); + /* Bind to max dimensions */ + if( maxWidth && width > maxWidth ) + { + width = maxWidth; + // If we are keeping the display aspect, then we are going + // to be modifying the PAR anyway. So it's preferred + // to let the width/height stray some from the original + // requested storage aspect. + // + // But otherwise, PAR and DAR will change the least + // if we stay as close as possible to the requested + // storage aspect. + if ( !job->anamorphic.keep_display_aspect ) + { + height = ((double)width / storage_aspect) + 0.5; + height = MULTIPLE_MOD( height, mod); + } + } + if( maxHeight && height > maxHeight ) + { + height = maxHeight; + // Ditto, see comment above + if ( !job->anamorphic.keep_display_aspect ) + { + width = ((double)height * storage_aspect) + 0.5; + width = MULTIPLE_MOD( width, mod); + } + } /* That finishes the storage dimensions. On to display. */ if( job->anamorphic.dar_width && job->anamorphic.dar_height ) @@ -1100,7 +1176,7 @@ hb_job_t * hb_current_job( hb_handle_t * h ) void hb_set_chapter_name( hb_handle_t * h, int title_index, int chapter_index, const char * chapter_name ) { hb_title_t * title; - title = hb_list_item( h->list_title, title_index - 1 ); + title = hb_get_title_by_index( h, title_index ); hb_chapter_t * chapter = hb_list_item( title->list_chapter, chapter_index - 1 ); @@ -1120,7 +1196,7 @@ void hb_set_job( hb_handle_t * h, int title_index, hb_job_t * job ) int i; hb_title_t * title; - title = hb_list_item( h->list_title, title_index - 1 ); + title = hb_get_title_by_index( h, title_index ); hb_job_t * job_target = title->job; @@ -1453,39 +1529,40 @@ hb_filter_object_t * hb_get_filter_object(int filter_id, const char * settings) { if (filter_id == HB_FILTER_ROTATE) { - hb_filter_rotate.settings = strdup(settings); + hb_filter_rotate.settings = (char*)settings; return &hb_filter_rotate; } if (filter_id == HB_FILTER_DETELECINE) { - hb_filter_detelecine.settings = strdup(settings); + hb_filter_detelecine.settings = (char*)settings; return &hb_filter_detelecine; } if (filter_id == HB_FILTER_DECOMB) { - hb_filter_decomb.settings = strdup(settings); + hb_filter_decomb.settings = (char*)settings; return &hb_filter_decomb; } if (filter_id == HB_FILTER_DEINTERLACE) { - hb_filter_deinterlace.settings = strdup(settings); + hb_filter_deinterlace.settings = (char*)settings; return &hb_filter_deinterlace; } if (filter_id == HB_FILTER_DEBLOCK) { - hb_filter_deblock.settings = strdup(settings); + hb_filter_deblock.settings = (char*)settings; return &hb_filter_deblock; } if (filter_id == HB_FILTER_DENOISE) { - hb_filter_denoise.settings = strdup(settings); + hb_filter_denoise.settings = (char*)settings; return &hb_filter_denoise; } + return NULL; } /** @@ -1691,7 +1768,12 @@ static void redirect_thread_func(void * _data) { int pfd[2]; pipe(pfd); +#if defined( SYS_MINGW ) + // dup2 doesn't work on windows for some stupid reason stderr->_file = pfd[1]; +#else + dup2(pfd[1], /*stderr*/ 2); +#endif FILE * log_f = fdopen(pfd[0], "rb"); char line_buffer[500]; @@ -1721,6 +1803,29 @@ int hb_get_instance_id( hb_handle_t * h ) } /** + * Returns the title with the given title index. + * @param h Handle to hb_handle_t + * @param title_index the index of the title to get + * @returns The requested title + */ +hb_title_t * hb_get_title_by_index( hb_handle_t * h, int title_index ) +{ + hb_title_t * title; + int i; + int count = hb_list_count( h->list_title ); + for (i = 0; i < count; i++) + { + title = hb_list_item( h->list_title, i ); + if (title->index == title_index) + { + return title; + } + } + + return NULL; +} + +/** * Sets the current state. * @param h Handle to hb_handle_t * @param s Handle to new hb_state_t