diff options
author | Bradley Sepos <[email protected]> | 2015-08-29 18:55:32 -0400 |
---|---|---|
committer | Bradley Sepos <[email protected]> | 2015-09-10 15:33:06 -0400 |
commit | 400bb38bf8ebc7dbe1c8eb5f525983ebdfd5d3b0 (patch) | |
tree | 59c3e86962ff23c5d42efaca242257cf9b2ef487 /libhb | |
parent | cbb6fbdbdf2fec70a4d06bf8742c95dfb060f2ed (diff) |
libhb: Clock/frame rate handling improvements.
Allows for arbitrary frame rates between 1 and 1000 fps.
Adds min/max frame rates to CLI help.
Removes hardcoded instances of the internal clock rate in favor of hb_video_framerate_get_limits().
Unfortunately, much of the codebase generally refers to clock rate as frame rate, so a little extra care is still necessary going forward.
Diffstat (limited to 'libhb')
-rw-r--r-- | libhb/common.c | 10 | ||||
-rw-r--r-- | libhb/common.h | 1 | ||||
-rw-r--r-- | libhb/decavcodec.c | 7 | ||||
-rw-r--r-- | libhb/encavcodec.c | 10 | ||||
-rw-r--r-- | libhb/muxavformat.c | 9 | ||||
-rw-r--r-- | libhb/preset.c | 59 |
6 files changed, 63 insertions, 33 deletions
diff --git a/libhb/common.c b/libhb/common.c index b63b1cfff..092d6d306 100644 --- a/libhb/common.c +++ b/libhb/common.c @@ -96,6 +96,9 @@ hb_rate_internal_t hb_video_rates[] = { { "60", 450000, }, NULL, 1, }, }; int hb_video_rates_count = sizeof(hb_video_rates) / sizeof(hb_video_rates[0]); +const int hb_video_rate_clock = 27000000; // 27MHz clock +int hb_video_rate_min = hb_video_rate_clock / 1000; // Min clock rate from *max* frame rate +int hb_video_rate_max = hb_video_rate_clock / 1; // Max clock rate from *min* frame rate hb_rate_t *hb_audio_rates_first_item = NULL; hb_rate_t *hb_audio_rates_last_item = NULL; @@ -670,6 +673,13 @@ const char* hb_video_framerate_sanitize_name(const char *name) return hb_video_framerate_get_name(hb_video_framerate_get_from_name(name)); } +void hb_video_framerate_get_limits(int *low, int *high, int *clock) +{ + *low = hb_video_rate_min; + *high = hb_video_rate_max; + *clock = hb_video_rate_clock; +} + const hb_rate_t* hb_video_framerate_get_next(const hb_rate_t *last) { if (last == NULL) diff --git a/libhb/common.h b/libhb/common.h index d1fe73335..9cf51b3e2 100644 --- a/libhb/common.h +++ b/libhb/common.h @@ -339,6 +339,7 @@ void hb_common_global_init(); int hb_video_framerate_get_from_name(const char *name); const char* hb_video_framerate_get_name(int framerate); const char* hb_video_framerate_sanitize_name(const char *name); +void hb_video_framerate_get_limits(int *low, int *high, int *clock); const hb_rate_t* hb_video_framerate_get_next(const hb_rate_t *last); int hb_audio_samplerate_get_best(uint32_t codec, int samplerate, int *sr_shift); diff --git a/libhb/decavcodec.c b/libhb/decavcodec.c index f81205ada..ae9806f95 100644 --- a/libhb/decavcodec.c +++ b/libhb/decavcodec.c @@ -2019,6 +2019,9 @@ static int decavcodecvInfo( hb_work_object_t *w, hb_work_info_t *info ) { hb_work_private_t *pv = w->private_data; + int clock_min, clock_max, clock; + hb_video_framerate_get_limits(&clock_min, &clock_max, &clock); + memset( info, 0, sizeof(*info) ); if (pv->context == NULL) @@ -2035,8 +2038,8 @@ static int decavcodecvInfo( hb_work_object_t *w, hb_work_info_t *info ) info->geometry.par.den = pv->context->sample_aspect_ratio.den; compute_frame_duration( pv ); - info->rate.num = 27000000; - info->rate.den = pv->duration * 300.; + info->rate.num = clock; + info->rate.den = pv->duration * (clock / 90000.); info->profile = pv->context->profile; info->level = pv->context->level; diff --git a/libhb/encavcodec.c b/libhb/encavcodec.c index 856fff31a..5063e43f1 100644 --- a/libhb/encavcodec.c +++ b/libhb/encavcodec.c @@ -64,9 +64,11 @@ int encavcodecInit( hb_work_object_t * w, hb_job_t * job ) hb_work_private_t * pv = calloc( 1, sizeof( hb_work_private_t ) ); w->private_data = pv; - pv->job = job; + int clock_min, clock_max, clock; + hb_video_framerate_get_limits(&clock_min, &clock_max, &clock); + switch ( w->codec_param ) { case AV_CODEC_ID_MPEG4: @@ -111,13 +113,13 @@ int encavcodecInit( hb_work_object_t * w, hb_job_t * job ) fps.num = job->vrate.num; } - // If the fps.num is 27000000, there's a good chance this is - // a standard rate that we have in our hb_video_rates table. + // If the fps.num is the internal clock rate, there's a good chance + // this is a standard rate that we have in our hb_video_rates table. // Because of rounding errors and approximations made while // measuring framerate, the actual value may not be exact. So // we look for rates that are "close" and make an adjustment // to fps.den. - if (fps.num == 27000000) + if (fps.num == clock) { const hb_rate_t *video_framerate = NULL; while ((video_framerate = hb_video_framerate_get_next(video_framerate)) != NULL) diff --git a/libhb/muxavformat.c b/libhb/muxavformat.c index d54200e1a..e6ad4ae23 100644 --- a/libhb/muxavformat.c +++ b/libhb/muxavformat.c @@ -123,6 +123,9 @@ static int avformatInit( hb_mux_object_t * m ) int max_tracks; int ii, ret; + int clock_min, clock_max, clock; + hb_video_framerate_get_limits(&clock_min, &clock_max, &clock); + const char *muxer_name = NULL; uint8_t default_track_flag = 1; @@ -362,13 +365,13 @@ static int avformatInit( hb_mux_object_t * m ) vrate = job->vrate; } - // If the vrate is 27000000, there's a good chance this is - // a standard rate that we have in our hb_video_rates table. + // If the vrate is the internal clock rate, there's a good chance + // this is a standard rate that we have in our hb_video_rates table. // Because of rounding errors and approximations made while // measuring framerate, the actual value may not be exact. So // we look for rates that are "close" and make an adjustment // to fps.den. - if (vrate.num == 27000000) + if (vrate.num == clock) { const hb_rate_t *video_framerate = NULL; while ((video_framerate = hb_video_framerate_get_next(video_framerate)) != NULL) diff --git a/libhb/preset.c b/libhb/preset.c index ec0c9b26c..b7074feb0 100644 --- a/libhb/preset.c +++ b/libhb/preset.c @@ -1018,39 +1018,47 @@ int hb_preset_job_add_subtitles(hb_handle_t *h, int title_index, static int get_video_framerate(hb_value_t *rate_value) { - int rate = 0; - if (hb_value_type(rate_value) != HB_VALUE_TYPE_STRING) + // Predefined by name + if (hb_value_type(rate_value) == HB_VALUE_TYPE_STRING) { - double d; - d = hb_value_get_double(rate_value); - if (d != 0 && d <= 600) + int rate = 0; + const char *rate_name = hb_value_get_string(rate_value); + if (!strcasecmp(rate_name, "source") || + !strcasecmp(rate_name, "auto") || + !strcasecmp(rate_name, "same as source")) { - // Assume the value is an actual framerate and compute - // 27Mhz based denominator - rate = (int)(27000000 / d); + return rate; } else { - // Assume the value is a 27Mhz based denominator - rate = (int)d; - } - } - else - { - const char *rate_name = hb_value_get_string(rate_value); - if (strcasecmp(rate_name, "source") && - strcasecmp(rate_name, "auto") && - strcasecmp(rate_name, "same as source")) - { rate = hb_video_framerate_get_from_name(rate_name); - if (rate < 0) + if (rate != -1) { - // No matching rate found. Error out. - rate = -1; + return rate; } } } - return rate; + + // Arbitrary + int clock_min, clock_max, clock, + frame_min, frame_max; + hb_video_framerate_get_limits(&clock_min, &clock_max, &clock); + frame_min = clock / clock_max; + frame_max = clock / clock_min; + double rate_d = hb_value_get_double(rate_value); + if (rate_d >= frame_min && rate_d <= frame_max) + { + // Value is a framerate, return clockrate + return (int)(clock / rate_d); + } + else if (rate_d >= clock_min && rate_d <= clock_max) + { + // Value is already a clockrate + return (int)(rate_d); + } + + // Value out of bounds + return -1; } int hb_preset_apply_filters(const hb_dict_t *preset, hb_dict_t *job_dict) @@ -1058,6 +1066,9 @@ int hb_preset_apply_filters(const hb_dict_t *preset, hb_dict_t *job_dict) hb_value_t *filters_dict, *filter_list, *filter_dict; char *filter_str; + int clock_min, clock_max, clock; + hb_video_framerate_get_limits(&clock_min, &clock_max, &clock); + // Create new filters filters_dict = hb_dict_init(); hb_dict_set(job_dict, "Filters", filters_dict); @@ -1282,7 +1293,7 @@ int hb_preset_apply_filters(const hb_dict_t *preset, hb_dict_t *job_dict) if (vrate_den == 0) filter_str = hb_strdup_printf("%d", fr_mode); else - filter_str = hb_strdup_printf("%d:%d:%d", fr_mode, 27000000, vrate_den); + filter_str = hb_strdup_printf("%d:%d:%d", fr_mode, clock, vrate_den); filter_dict = hb_dict_init(); hb_dict_set(filter_dict, "ID", hb_value_int(HB_FILTER_VFR)); |