summaryrefslogtreecommitdiffstats
path: root/libhb
diff options
context:
space:
mode:
authorBradley Sepos <[email protected]>2015-08-29 18:55:32 -0400
committerBradley Sepos <[email protected]>2015-09-10 15:33:06 -0400
commit400bb38bf8ebc7dbe1c8eb5f525983ebdfd5d3b0 (patch)
tree59c3e86962ff23c5d42efaca242257cf9b2ef487 /libhb
parentcbb6fbdbdf2fec70a4d06bf8742c95dfb060f2ed (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.c10
-rw-r--r--libhb/common.h1
-rw-r--r--libhb/decavcodec.c7
-rw-r--r--libhb/encavcodec.c10
-rw-r--r--libhb/muxavformat.c9
-rw-r--r--libhb/preset.c59
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));