summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--libhb/avfilter.c117
-rw-r--r--libhb/common.c132
-rw-r--r--libhb/common.h35
-rw-r--r--libhb/deblock.c12
-rw-r--r--libhb/decavcodec.c17
-rw-r--r--libhb/decomb.c9
-rw-r--r--libhb/denoise.c13
-rw-r--r--libhb/detelecine.c16
-rw-r--r--libhb/hb.c2
-rw-r--r--libhb/hb_json.c16
-rw-r--r--libhb/hbffmpeg.c238
-rw-r--r--libhb/hbffmpeg.h8
-rw-r--r--libhb/internal.h5
-rw-r--r--libhb/lapsharp.c12
-rw-r--r--libhb/nlmeans.c23
-rw-r--r--libhb/rendersub.c24
-rw-r--r--libhb/scan.c2
-rw-r--r--libhb/unsharp.c13
-rw-r--r--libhb/work.c3
19 files changed, 650 insertions, 47 deletions
diff --git a/libhb/avfilter.c b/libhb/avfilter.c
index 5f98f310c..febd239c9 100644
--- a/libhb/avfilter.c
+++ b/libhb/avfilter.c
@@ -68,6 +68,9 @@ static int rotate_init(hb_filter_object_t * filter, hb_filter_init_t * init);
static int deinterlace_init(hb_filter_object_t * filter,
hb_filter_init_t * init);
+static int colorspace_init(hb_filter_object_t * filter,
+ hb_filter_init_t * init);
+
hb_filter_object_t hb_filter_avfilter =
{
.id = HB_FILTER_AVFILTER,
@@ -149,6 +152,23 @@ hb_filter_object_t hb_filter_deinterlace =
.settings_template = deint_template,
};
+const char colorspace_template[] =
+ "format=^"HB_ALL_REG"$:range=^"HB_ALL_REG"$:primaries=^"HB_ALL_REG"$:"
+ "matrix=^"HB_ALL_REG"$:transfer=^"HB_ALL_REG"$";
+
+hb_filter_object_t hb_filter_colorspace =
+{
+ .id = HB_FILTER_COLORSPACE,
+ .enforce_order = 1,
+ .skip = 1,
+ .name = "Colorspace",
+ .settings = NULL,
+ .init = colorspace_init,
+ .work = null_work,
+ .close = avfilter_alias_close,
+ .settings_template = colorspace_template,
+};
+
static int null_work( hb_filter_object_t * filter,
hb_buffer_t ** buf_in, hb_buffer_t ** buf_out )
{
@@ -241,14 +261,6 @@ hb_avfilter_graph_init(hb_value_t * settings, hb_filter_init_t * init)
}
graph->input = avfilter;
- // Convert input to pix fmt YUV420P
- avfilter = append_filter(graph, "format", "yuv420p");
- if (avfilter == NULL)
- {
- hb_error("hb_avfilter_graph_init: failed to create pix format filter");
- goto fail;
- }
-
// Link input to filter chain created by avfilter_graph_parse2
result = avfilter_link(graph->last, 0, in->filter_ctx, 0);
if (result < 0)
@@ -267,8 +279,8 @@ hb_avfilter_graph_init(hb_value_t * settings, hb_filter_init_t * init)
#if 0
// Set output pix fmt to YUV420P
enum AVPixelFormat pix_fmts[2] = {AV_PIX_FMT_YUV420P, AV_PIX_FMT_NONE};
- if ((ret = av_opt_set_int_list(avfilter, "pix_fmts", pix_fmts,
- AV_PIX_FMT_NONE, AV_OPT_SEARCH_CHILDREN)) < 0)
+ if (av_opt_set_int_list(avfilter, "pix_fmts", pix_fmts,
+ AV_PIX_FMT_NONE, AV_OPT_SEARCH_CHILDREN) < 0)
{
hb_error("hb_avfilter_graph_init: failed to set buffersink pix_fmt");
goto fail;
@@ -697,7 +709,7 @@ void hb_append_filter_dict(hb_value_array_t * filters,
hb_value_array_append(filters, filter_dict);
}
-static const char * color_format_range(enum AVPixelFormat format)
+static const char * color_format_range(enum AVPixelFormat format, int range)
{
switch (format)
{
@@ -707,7 +719,7 @@ static const char * color_format_range(enum AVPixelFormat format)
case AV_PIX_FMT_YUVJ440P:
return "full";
default:
- return "limited";
+ return range == AVCOL_RANGE_JPEG ? "full" : "limited";
}
}
@@ -772,28 +784,34 @@ static int crop_scale_init(hb_filter_object_t * filter, hb_filter_init_t * init)
case HB_COLR_MAT_BT709:
matrix = "bt709";
break;
- case HB_COLR_MAT_SMPTE170M:
- matrix = "smpte170m";
+ case HB_COLR_MAT_FCC:
+ matrix = "fcc";
break;
case HB_COLR_MAT_SMPTE240M:
matrix = "smpte240m";
break;
+ case HB_COLR_MAT_BT470BG:
+ case HB_COLR_MAT_SMPTE170M:
+ matrix = "smpte170m";
+ break;
case HB_COLR_MAT_BT2020_NCL:
case HB_COLR_MAT_BT2020_CL:
matrix = "bt2020";
break;
default:
case HB_COLR_MAT_UNDEF:
- matrix = "bt601";
+ matrix = NULL;
break;
}
- hb_dict_set_string(avsettings, "in_color_matrix", matrix);
- hb_dict_set_string(avsettings, "out_color_matrix", matrix);
+ if (matrix != NULL)
+ {
+ hb_dict_set_string(avsettings, "in_color_matrix", matrix);
+ hb_dict_set_string(avsettings, "out_color_matrix", matrix);
+ }
hb_dict_set_string(avsettings, "in_range",
- color_format_range(init->pix_fmt));
- hb_dict_set_string(avsettings, "out_range",
- color_format_range(AV_PIX_FMT_YUV420P));
+ color_format_range(init->pix_fmt, init->color_range));
+ hb_dict_set_string(avsettings, "out_range", "limited");
hb_dict_set(avfilter, "scale", avsettings);
hb_value_array_append(avfilters, avfilter);
@@ -1147,3 +1165,62 @@ static int deinterlace_init(hb_filter_object_t * filter,
return 0;
}
+
+static int colorspace_init(hb_filter_object_t * filter, hb_filter_init_t * init)
+{
+ hb_filter_private_t * pv = NULL;
+
+ pv = calloc(1, sizeof(struct hb_filter_private_s));
+ filter->private_data = pv;
+ if (pv == NULL)
+ {
+ return 1;
+ }
+ pv->input = *init;
+
+ hb_dict_t * settings = filter->settings;
+
+ char * format = NULL, * range = NULL;
+ char * primaries = NULL, * transfer = NULL, * matrix = NULL;
+
+ hb_dict_extract_string(&format, settings, "format");
+ hb_dict_extract_string(&range, settings, "range");
+ hb_dict_extract_string(&primaries, settings, "primaries");
+ hb_dict_extract_string(&transfer, settings, "transfer");
+ hb_dict_extract_string(&matrix, settings, "matrix");
+
+ if (!(format || range || primaries || transfer || matrix))
+ {
+ return 0;
+ }
+
+ hb_dict_t * avfilter = hb_dict_init();
+ hb_dict_t * avsettings = hb_dict_init();
+
+ if (format)
+ {
+ hb_dict_set_string(avsettings, "format", format);
+ }
+ if (range)
+ {
+ hb_dict_set_string(avsettings, "range", range);
+ }
+ if (primaries)
+ {
+ hb_dict_set_string(avsettings, "primaries", primaries);
+ }
+ if (transfer)
+ {
+ hb_dict_set_string(avsettings, "trc", transfer);
+ }
+ if (matrix)
+ {
+ hb_dict_set_string(avsettings, "space", matrix);
+ }
+ hb_dict_set(avfilter, "colorspace", avsettings);
+ pv->avfilters = avfilter;
+
+ pv->output = *init;
+
+ return 0;
+}
diff --git a/libhb/common.c b/libhb/common.c
index 8bc47adbe..cffca581b 100644
--- a/libhb/common.c
+++ b/libhb/common.c
@@ -3786,9 +3786,11 @@ static void job_setup(hb_job_t * job, hb_title_t * title)
job->pass_id = HB_PASS_ENCODE;
job->vrate = title->vrate;
+ job->pix_fmt = AV_PIX_FMT_YUV420P;
job->color_prim = title->color_prim;
job->color_transfer = title->color_transfer;
job->color_matrix = title->color_matrix;
+ job->color_range = title->color_range;
job->mux = HB_MUX_MP4;
@@ -4085,6 +4087,10 @@ hb_filter_object_t * hb_filter_get( int filter_id )
filter = &hb_filter_deinterlace;
break;
+ case HB_FILTER_COLORSPACE:
+ filter = &hb_filter_colorspace;
+ break;
+
case HB_FILTER_VFR:
filter = &hb_filter_vfr;
break;
@@ -5724,3 +5730,129 @@ void hb_chapter_dequeue(hb_chapter_queue_t *q, hb_buffer_t *buf)
free(item);
}
}
+
+// Only return values supported by 'colorspace' avfilter:
+const char * hb_get_format_name(int format)
+{
+ switch (format)
+ {
+ case AV_PIX_FMT_YUV420P:
+ return "yuv420p";
+ case AV_PIX_FMT_YUV420P10:
+ return "yuv420p10";
+ case AV_PIX_FMT_YUV420P12:
+ return "yuv420p12";
+ case AV_PIX_FMT_YUV422P:
+ return "yuv422p";
+ case AV_PIX_FMT_YUV422P10:
+ return "yuv422p10";
+ case AV_PIX_FMT_YUV422P12:
+ return "yuv422p12";
+ case AV_PIX_FMT_YUV444P:
+ return "yuv444p";
+ case AV_PIX_FMT_YUV444P10:
+ return "yuv444p10";
+ default:
+ return NULL;
+ }
+}
+
+// Only return values supported by 'colorspace' avfilter:
+const char * hb_get_primaries_name(int primaries)
+{
+ switch (primaries)
+ {
+ case HB_COLR_PRI_BT709:
+ return "bt709";
+ case HB_COLR_PRI_BT470M:
+ return "bt470m";
+ case HB_COLR_PRI_EBUTECH:
+ return "bt470bg";
+ case HB_COLR_PRI_SMPTEC:
+ return "smpte170m";
+ case HB_COLR_PRI_SMPTE240M:
+ return "smpte240m";
+ case HB_COLR_PRI_SMPTE428:
+ return "smpte428";
+ case HB_COLR_PRI_FILM:
+ return "film";
+ case HB_COLR_PRI_SMPTE431:
+ return "smpte431";
+ case HB_COLR_PRI_SMPTE432:
+ return "smpte432";
+ case HB_COLR_PRI_BT2020:
+ return "bt2020";
+ case HB_COLR_PRI_JEDEC_P22:
+ return "jedec-p22";
+ default:
+ return NULL;
+ }
+}
+
+// Only return values supported by 'colorspace' avfilter:
+const char * hb_get_transfer_name(int transfer)
+{
+ switch (transfer)
+ {
+ case HB_COLR_TRA_BT709:
+ return "bt709";
+ case HB_COLR_TRA_GAMMA22:
+ return "gamma22";
+ case HB_COLR_TRA_GAMMA28:
+ return "gamma28";
+ case HB_COLR_TRA_SMPTE170M:
+ return "smpte170m";
+ case HB_COLR_TRA_SMPTE240M:
+ return "smpte240m";
+ case HB_COLR_TRA_IEC61966_2_1:
+ return "iec61966-2-1";
+ case HB_COLR_TRA_IEC61966_2_4:
+ return "iec61966-2-4";
+ case HB_COLR_TRA_BT2020_10:
+ return "bt2020-10";
+ case HB_COLR_TRA_BT2020_12:
+ return "bt2020-12";
+ default:
+ return NULL;
+ }
+}
+
+// Only return values supported by 'colorspace' avfilter:
+const char * hb_get_matrix_name(int matrix)
+{
+ switch (matrix)
+ {
+ case HB_COLR_MAT_BT709:
+ return "bt709";
+ case HB_COLR_MAT_FCC:
+ return "fcc";
+ case HB_COLR_MAT_BT470BG:
+ return "bt470bg";
+ case HB_COLR_MAT_SMPTE170M:
+ return "smpte170m";
+ case HB_COLR_MAT_SMPTE240M:
+ return "smpte240m";
+ case HB_COLR_MAT_YCGCO:
+ return "ycgco";
+ case HB_COLR_MAT_RGB:
+ return "gbr";
+ case HB_COLR_MAT_BT2020_NCL:
+ return "bt2020ncl";
+ default:
+ return NULL;
+ }
+}
+
+// Only return values supported by 'colorspace' avfilter:
+const char * hb_get_color_range_name(int range)
+{
+ switch (range)
+ {
+ case AVCOL_RANGE_MPEG:
+ return "mpeg";
+ case AVCOL_RANGE_JPEG:
+ return "jpeg";
+ default:
+ return "mpeg";
+ }
+}
diff --git a/libhb/common.h b/libhb/common.h
index bc65e9cbb..bdbf5c539 100644
--- a/libhb/common.h
+++ b/libhb/common.h
@@ -560,32 +560,59 @@ struct hb_job_s
char *encoder_level;
int areBframes;
+ int pix_fmt;
int color_prim;
int color_transfer;
int color_matrix;
+ int color_range;
// see https://developer.apple.com/library/content/technotes/tn2162/_index.html
// https://developer.apple.com/library/content/documentation/QuickTime/QTFF/QTFFChap3/qtff3.html#//apple_ref/doc/uid/TP40000939-CH205-125526
// libav pixfmt.h
#define HB_COLR_PRI_BT709 1
#define HB_COLR_PRI_UNDEF 2
+#define HB_COLR_PRI_BT470M 4
#define HB_COLR_PRI_EBUTECH 5 // use for bt470bg
-#define HB_COLR_PRI_SMPTEC 6 // smpte170m; also use for bt470m and smpte240m
+#define HB_COLR_PRI_SMPTEC 6 // smpte170m
+#define HB_COLR_PRI_SMPTE240M 7
+#define HB_COLR_PRI_FILM 8 // Illuminant C
#define HB_COLR_PRI_BT2020 9
+#define HB_COLR_PRI_SMPTE428 10
+#define HB_COLR_PRI_SMPTE431 11
+#define HB_COLR_PRI_SMPTE432 12
+#define HB_COLR_PRI_JEDEC_P22 22
// 0, 3-4, 7-8, 10-65535: reserved/not implemented
#define HB_COLR_TRA_BT709 1 // also use for bt470m, bt470bg, smpte170m, bt2020_10 and bt2020_12
#define HB_COLR_TRA_UNDEF 2
+#define HB_COLR_TRA_GAMMA22 4
+#define HB_COLR_TRA_GAMMA28 5
+#define HB_COLR_TRA_SMPTE170M 6
#define HB_COLR_TRA_SMPTE240M 7
+#define HB_COLR_TRA_LINEAR 8
+#define HB_COLR_TRA_LOG 9
+#define HB_COLR_TRA_LOG_SQRT 10
+#define HB_COLR_TRA_IEC61966_2_4 11
+#define HB_COLR_TRA_BT1361_ECG 12
+#define HB_COLR_TRA_IEC61966_2_1 13
#define HB_COLR_TRA_BT2020_10 14
#define HB_COLR_TRA_BT2020_12 15
#define HB_COLR_TRA_SMPTEST2084 16
+#define HB_COLR_TRA_SMPTE428 17
#define HB_COLR_TRA_ARIB_STD_B67 18 //known as "Hybrid log-gamma"
// 0, 3-6, 8-15, 17-65535: reserved/not implemented
+#define HB_COLR_MAT_RGB 0
#define HB_COLR_MAT_BT709 1
#define HB_COLR_MAT_UNDEF 2
+#define HB_COLR_MAT_FCC 4
+#define HB_COLR_MAT_BT470BG 5
#define HB_COLR_MAT_SMPTE170M 6 // also use for fcc and bt470bg
#define HB_COLR_MAT_SMPTE240M 7
+#define HB_COLR_MAT_YCGCO 8
#define HB_COLR_MAT_BT2020_NCL 9
#define HB_COLR_MAT_BT2020_CL 10
+#define HB_COLR_MAT_SMPTE2085 11
+#define HB_COLR_MAT_CD_NCL 12 // chromaticity derived non-constant lum
+#define HB_COLR_MAT_CD_CL 13 // chromaticity derived constant lum
+#define HB_COLR_MAT_ICTCP 14 // ITU-R BT.2100-0, ICtCp
// 0, 3-5, 8, 11-65535: reserved/not implemented
hb_list_t * list_chapter;
@@ -1044,9 +1071,11 @@ struct hb_title_s
hb_geometry_t geometry;
hb_rational_t dar; // aspect ratio for the title's video
hb_rational_t container_dar; // aspect ratio from container (0 if none)
+ int pix_fmt;
int color_prim;
int color_transfer;
int color_matrix;
+ int color_range;
hb_rational_t vrate;
int crop[4];
enum {HB_DVD_DEMUXER, HB_TS_DEMUXER, HB_PS_DEMUXER, HB_NULL_DEMUXER} demuxer;
@@ -1149,9 +1178,11 @@ typedef struct hb_work_info_s
struct
{ // info only valid for video decoders
hb_geometry_t geometry;
+ int pix_fmt;
int color_prim;
int color_transfer;
int color_matrix;
+ int color_range;
int video_decode_support;
};
struct
@@ -1254,6 +1285,7 @@ typedef struct hb_filter_init_s
int color_prim;
int color_transfer;
int color_matrix;
+ int color_range;
hb_geometry_t geometry;
int crop[4];
hb_rational_t vrate;
@@ -1337,6 +1369,7 @@ enum
HB_FILTER_ROTATE,
HB_FILTER_GRAYSCALE,
HB_FILTER_PAD,
+ HB_FILTER_COLORSPACE,
// Finally filters that don't care what order they are in,
// except that they must be after the above filters
diff --git a/libhb/deblock.c b/libhb/deblock.c
index 64cf277bb..c334b4ef2 100644
--- a/libhb/deblock.c
+++ b/libhb/deblock.c
@@ -47,6 +47,9 @@ struct hb_filter_private_s
int pp7_mpeg2;
int pp7_temp_stride;
uint8_t * pp7_src;
+
+ hb_filter_init_t input;
+ hb_filter_init_t output;
};
static int hb_deblock_init( hb_filter_object_t * filter,
@@ -346,6 +349,7 @@ static int hb_deblock_init( hb_filter_object_t * filter,
filter->private_data = calloc( sizeof(struct hb_filter_private_s), 1 );
hb_filter_private_t * pv = filter->private_data;
+ pv->input = *init;
pv->pp7_qp = PP7_QP_DEFAULT;
pv->pp7_mode = PP7_MODE_DEFAULT;
pv->pp7_mpeg2 = 1; /*mpi->qscale_type;*/
@@ -378,6 +382,7 @@ static int hb_deblock_init( hb_filter_object_t * filter,
pv->pp7_temp_stride = (init->geometry.width + 16 + 15) & (~15);
pv->pp7_src = (uint8_t*)malloc( pv->pp7_temp_stride*(h+8)*sizeof(uint8_t) );
+ pv->output = *init;
return 0;
}
@@ -411,7 +416,12 @@ static int hb_deblock_work( hb_filter_object_t * filter,
if( /*TODO: mpi->qscale ||*/ pv->pp7_qp )
{
- out = hb_video_buffer_init( in->f.width, in->f.height );
+ out = hb_frame_buffer_init(pv->output.pix_fmt,
+ in->f.width, in->f.height );
+ out->f.color_prim = pv->output.color_prim;
+ out->f.color_transfer = pv->output.color_transfer;
+ out->f.color_matrix = pv->output.color_matrix;
+ out->f.color_range = pv->output.color_range ;
pp7_filter( pv,
out->plane[0].data,
diff --git a/libhb/decavcodec.c b/libhb/decavcodec.c
index f93a24878..85237d1d9 100644
--- a/libhb/decavcodec.c
+++ b/libhb/decavcodec.c
@@ -1118,6 +1118,7 @@ int reinit_video_filters(hb_work_private_t * pv)
hb_value_array_t * filters;
hb_dict_t * settings;
hb_filter_init_t filter_init;
+ enum AVPixelFormat pix_fmt;
#ifdef USE_QSV
if (pv->qsv.decode &&
@@ -1134,6 +1135,7 @@ int reinit_video_filters(hb_work_private_t * pv)
// of incoming video if not even.
orig_width = pv->context->width & ~1;
orig_height = pv->context->height & ~1;
+ pix_fmt = AV_PIX_FMT_YUV420P;
}
else
{
@@ -1148,9 +1150,10 @@ int reinit_video_filters(hb_work_private_t * pv)
orig_width = pv->job->title->geometry.width;
orig_height = pv->job->title->geometry.height;
}
+ pix_fmt = pv->job->pix_fmt;
}
- if (AV_PIX_FMT_YUV420P == pv->frame->format &&
+ if (pix_fmt == pv->frame->format &&
orig_width == pv->frame->width &&
orig_height == pv->frame->height &&
HB_ROTATION_0 == pv->title->rotation)
@@ -1184,7 +1187,7 @@ int reinit_video_filters(hb_work_private_t * pv)
vrate.den = pv->duration * (clock / 90000.);
filters = hb_value_array_init();
- if (AV_PIX_FMT_YUV420P != pv->frame->format ||
+ if (pix_fmt != pv->frame->format ||
orig_width != pv->frame->width ||
orig_height != pv->frame->height)
{
@@ -1222,9 +1225,9 @@ int reinit_video_filters(hb_work_private_t * pv)
}
}
+ filter_init.pix_fmt = pv->frame->format;
filter_init.geometry.width = pv->frame->width;
filter_init.geometry.height = pv->frame->height;
- filter_init.pix_fmt = pv->frame->format;
filter_init.geometry.par.num = pv->frame->sample_aspect_ratio.num;
filter_init.geometry.par.den = pv->frame->sample_aspect_ratio.den;
filter_init.time_base.num = 1;
@@ -2027,9 +2030,13 @@ static int decavcodecvInfo( hb_work_object_t *w, hb_work_info_t *info )
info->level = pv->context->level;
info->name = pv->context->codec->name;
- info->color_prim = get_color_prim(pv->context->color_primaries, info->geometry, info->rate);
+ info->pix_fmt = pv->context->pix_fmt;
+ info->color_prim = get_color_prim(pv->context->color_primaries,
+ info->geometry, info->rate);
info->color_transfer = get_color_transfer(pv->context->color_trc);
- info->color_matrix = get_color_matrix(pv->context->colorspace, info->geometry);
+ info->color_matrix = get_color_matrix(pv->context->colorspace,
+ info->geometry);
+ info->color_range = pv->context->color_range;
info->video_decode_support = HB_DECODE_SUPPORT_SW;
diff --git a/libhb/decomb.c b/libhb/decomb.c
index 6f1cf62a1..d6589c3ad 100644
--- a/libhb/decomb.c
+++ b/libhb/decomb.c
@@ -150,6 +150,9 @@ struct hb_filter_private_s
taskset_t eedi2_taskset; // Threads for eedi2 - one per plane
hb_buffer_list_t out_list;
+
+ hb_filter_init_t input;
+ hb_filter_init_t output;
};
typedef struct
@@ -935,6 +938,7 @@ static int hb_decomb_init( hb_filter_object_t * filter,
{
filter->private_data = calloc( 1, sizeof(struct hb_filter_private_s) );
hb_filter_private_t * pv = filter->private_data;
+ pv->input = *init;
hb_buffer_list_clear(&pv->out_list);
pv->deinterlaced = 0;
@@ -1118,6 +1122,7 @@ static int hb_decomb_init( hb_filter_object_t * filter,
}
}
+ pv->output = *init;
init->job->use_decomb = 1;
return 0;
@@ -1249,6 +1254,10 @@ static void process_frame( hb_filter_private_t * pv )
buf = hb_frame_buffer_init(pv->ref[1]->f.fmt,
pv->ref[1]->f.width,
pv->ref[1]->f.height);
+ buf->f.color_prim = pv->output.color_prim;
+ buf->f.color_transfer = pv->output.color_transfer;
+ buf->f.color_matrix = pv->output.color_matrix;
+ buf->f.color_range = pv->output.color_range ;
yadif_filter(pv, buf, parity, tff);
/* Copy buffered settings to output buffer settings */
diff --git a/libhb/denoise.c b/libhb/denoise.c
index 208d399a5..58c7935c1 100644
--- a/libhb/denoise.c
+++ b/libhb/denoise.c
@@ -29,6 +29,9 @@ struct hb_filter_private_s
short hqdn3d_coef[6][512*16];
unsigned short * hqdn3d_line;
unsigned short * hqdn3d_frame[3];
+
+ hb_filter_init_t input;
+ hb_filter_init_t output;
};
static int hb_denoise_init( hb_filter_object_t * filter,
@@ -227,6 +230,7 @@ static int hb_denoise_init( hb_filter_object_t * filter,
double spatial_luma, spatial_chroma_b, spatial_chroma_r;
double temporal_luma, temporal_chroma_b, temporal_chroma_r;
+ pv->input = *init;
if (!hb_dict_extract_double(&spatial_luma, filter->settings, "y-spatial"))
{
spatial_luma = HQDN3D_SPATIAL_LUMA_DEFAULT;
@@ -261,6 +265,8 @@ static int hb_denoise_init( hb_filter_object_t * filter,
hqdn3d_precalc_coef( pv->hqdn3d_coef[4], spatial_chroma_r );
hqdn3d_precalc_coef( pv->hqdn3d_coef[5], temporal_chroma_r );
+ pv->output = *init;
+
return 0;
}
@@ -312,7 +318,12 @@ static int hb_denoise_work( hb_filter_object_t * filter,
return HB_FILTER_DONE;
}
- out = hb_video_buffer_init( in->f.width, in->f.height );
+ out = hb_frame_buffer_init(pv->output.pix_fmt, in->f.width, in->f.height);
+ out->f.color_prim = pv->output.color_prim;
+ out->f.color_transfer = pv->output.color_transfer;
+ out->f.color_matrix = pv->output.color_matrix;
+ out->f.color_range = pv->output.color_range ;
+
if( !pv->hqdn3d_line )
{
diff --git a/libhb/detelecine.c b/libhb/detelecine.c
index a0a5367f1..a9abf8601 100644
--- a/libhb/detelecine.c
+++ b/libhb/detelecine.c
@@ -92,6 +92,9 @@ struct hb_filter_private_s
struct pullup_context * pullup_ctx;
int pullup_fakecount;
int pullup_skipflag;
+
+ hb_filter_init_t input;
+ hb_filter_init_t output;
};
static int hb_detelecine_init( hb_filter_object_t * filter,
@@ -821,10 +824,12 @@ void pullup_flush_fields( struct pullup_context * c )
static int hb_detelecine_init( hb_filter_object_t * filter,
hb_filter_init_t * init )
{
- filter->private_data = calloc( sizeof(struct hb_filter_private_s), 1 );
- hb_filter_private_t * pv = filter->private_data;
+ filter->private_data = calloc(sizeof(struct hb_filter_private_s), 1);
+ hb_filter_private_t * pv = filter->private_data;
struct pullup_context * ctx;
+
+ pv->input = *init;
pv->pullup_ctx = ctx = pullup_alloc_context();
ctx->junk_left = ctx->junk_right = 1;
@@ -877,6 +882,7 @@ static int hb_detelecine_init( hb_filter_object_t * filter,
pv->pullup_skipflag = 0;
init->job->use_detelecine = 1;
+ pv->output = *init;
return 0;
}
@@ -1017,7 +1023,11 @@ static int hb_detelecine_work( hb_filter_object_t * filter,
pullup_pack_frame( ctx, frame );
}
- out = hb_video_buffer_init( in->f.width, in->f.height );
+ out = hb_frame_buffer_init(pv->output.pix_fmt, in->f.width, in->f.height);
+ out->f.color_prim = pv->output.color_prim;
+ out->f.color_transfer = pv->output.color_transfer;
+ out->f.color_matrix = pv->output.color_matrix;
+ out->f.color_range = pv->output.color_range ;
/* Copy pullup frame buffer into output buffer */
memcpy( out->plane[0].data, frame->buffer->planes[0], frame->buffer->size[0] );
diff --git a/libhb/hb.c b/libhb/hb.c
index a9dc2cdc6..2032a42ee 100644
--- a/libhb/hb.c
+++ b/libhb/hb.c
@@ -630,7 +630,7 @@ hb_image_t* hb_get_preview2(hb_handle_t * h, int title_idx, int picture,
geo->crop[0], geo->crop[2] );
}
- int colorspace = hb_ff_get_colorspace(title->color_matrix);
+ int colorspace = hb_sws_get_colorspace(title->color_matrix);
// Get scaling context
context = hb_sws_get_context(
diff --git a/libhb/hb_json.c b/libhb/hb_json.c
index 2399adf45..ce93444d9 100644
--- a/libhb/hb_json.c
+++ b/libhb/hb_json.c
@@ -231,8 +231,8 @@ static hb_dict_t* hb_title_to_dict_internal( hb_title_t *title )
"s:{s:o, s:o, s:{s:o, s:o}},"
// Crop[Top, Bottom, Left, Right]}
"s:[oooo],"
- // Color {Primary, Transfer, Matrix}
- "s:{s:o, s:o, s:o},"
+ // Color {Format, Range, Primary, Transfer, Matrix}
+ "s:{s:o, s:o, s:o, s:o, s:o},"
// FrameRate {Num, Den}
"s:{s:o, s:o},"
// InterlaceDetected, VideoCodec
@@ -262,6 +262,8 @@ static hb_dict_t* hb_title_to_dict_internal( hb_title_t *title )
hb_value_int(title->crop[2]),
hb_value_int(title->crop[3]),
"Color",
+ "Format", hb_value_int(title->pix_fmt),
+ "Range", hb_value_int(title->color_range),
"Primary", hb_value_int(title->color_prim),
"Transfer", hb_value_int(title->color_transfer),
"Matrix", hb_value_int(title->color_matrix),
@@ -645,6 +647,10 @@ hb_dict_t* hb_job_to_dict( const hb_job_t * job )
hb_dict_set(source_dict, "Range", range_dict);
hb_dict_t *video_dict = hb_dict_get(dict, "Video");
+ hb_dict_set(video_dict, "ColorFormat",
+ hb_value_int(job->pix_fmt));
+ hb_dict_set(video_dict, "ColorRange",
+ hb_value_int(job->color_range));
hb_dict_set(video_dict, "ColorPrimaries",
hb_value_int(job->color_prim));
hb_dict_set(video_dict, "ColorTransfer",
@@ -1004,10 +1010,12 @@ hb_job_t* hb_dict_to_job( hb_handle_t * h, hb_dict_t *dict )
// PAR {Num, Den}
"s?{s:i, s:i},"
// Video {Codec, Quality, Bitrate, Preset, Tune, Profile, Level, Options
- // TwoPass, Turbo, ColorPrimaries, ColorTransfer, ColorMatrix,
+ // TwoPass, Turbo, ColorFormat, ColorRange, ColorPrimaries,
+ // ColorTransfer, ColorMatrix,
// QSV {Decode, AsyncDepth}}
"s:{s:o, s?f, s?i, s?s, s?s, s?s, s?s, s?s,"
" s?b, s?b, s?i, s?i, s?i,"
+ " s?i, s?i,"
" s?{s?b, s?i}},"
// Audio {CopyMask, FallbackEncoder, AudioList}
"s?{s?o, s?o, s?o},"
@@ -1051,6 +1059,8 @@ hb_job_t* hb_dict_to_job( hb_handle_t * h, hb_dict_t *dict )
"Options", unpack_s(&video_options),
"TwoPass", unpack_b(&job->twopass),
"Turbo", unpack_b(&job->fastfirstpass),
+ "ColorFormat", unpack_i(&job->pix_fmt),
+ "ColorRange", unpack_i(&job->color_range),
"ColorPrimaries", unpack_i(&job->color_prim),
"ColorTransfer", unpack_i(&job->color_transfer),
"ColorMatrix", unpack_i(&job->color_matrix),
diff --git a/libhb/hbffmpeg.c b/libhb/hbffmpeg.c
index c604bf703..e0168a8cb 100644
--- a/libhb/hbffmpeg.c
+++ b/libhb/hbffmpeg.c
@@ -37,6 +37,12 @@ void hb_video_buffer_to_avframe(AVFrame *frame, hb_buffer_t * buf)
frame->format = buf->f.fmt;
frame->interlaced_frame = !!buf->s.combed;
frame->top_field_first = !!(buf->s.flags & PIC_FLAG_TOP_FIELD_FIRST);
+
+ frame->format = buf->f.fmt;
+ frame->color_primaries = hb_colr_pri_hb_to_ff(buf->f.color_prim);
+ frame->color_trc = hb_colr_tra_hb_to_ff(buf->f.color_transfer);
+ frame->colorspace = hb_colr_mat_hb_to_ff(buf->f.color_matrix);
+ frame->color_range = buf->f.color_range;
}
void hb_avframe_set_video_buffer_flags(hb_buffer_t * buf, AVFrame *frame,
@@ -70,7 +76,12 @@ void hb_avframe_set_video_buffer_flags(hb_buffer_t * buf, AVFrame *frame,
{
buf->s.flags |= PIC_FLAG_REPEAT_FRAME;
}
- buf->s.frametype = get_frame_type(frame->pict_type);
+ buf->s.frametype = get_frame_type(frame->pict_type);
+ buf->f.fmt = frame->format;
+ buf->f.color_prim = hb_colr_pri_ff_to_hb(frame->color_primaries);
+ buf->f.color_transfer = hb_colr_tra_ff_to_hb(frame->color_trc);
+ buf->f.color_matrix = hb_colr_mat_ff_to_hb(frame->colorspace);
+ buf->f.color_range = frame->color_range;
}
hb_buffer_t * hb_avframe_to_video_buffer(AVFrame *frame, AVRational time_base)
@@ -163,7 +174,7 @@ hb_sws_get_context(int srcW, int srcH, enum AVPixelFormat srcFormat,
return ctx;
}
-int hb_ff_get_colorspace(int color_matrix)
+int hb_sws_get_colorspace(int color_matrix)
{
int color_space = SWS_CS_DEFAULT;
@@ -189,6 +200,229 @@ int hb_ff_get_colorspace(int color_matrix)
return color_space;
}
+int hb_colr_pri_hb_to_ff(int colr_prim)
+{
+ switch (colr_prim)
+ {
+ case HB_COLR_PRI_BT709:
+ return AVCOL_PRI_BT709;
+ case HB_COLR_PRI_EBUTECH:
+ return AVCOL_PRI_BT470BG;
+ case HB_COLR_PRI_BT470M:
+ return AVCOL_PRI_BT470M;
+ case HB_COLR_PRI_SMPTEC:
+ return AVCOL_PRI_SMPTE170M;
+ case HB_COLR_PRI_SMPTE240M:
+ return AVCOL_PRI_SMPTE240M;
+ case HB_COLR_PRI_BT2020:
+ return AVCOL_PRI_BT2020;
+ case HB_COLR_PRI_SMPTE428:
+ return AVCOL_PRI_SMPTE428;
+ case HB_COLR_PRI_SMPTE431:
+ return AVCOL_PRI_SMPTE431;
+ case HB_COLR_PRI_SMPTE432:
+ return AVCOL_PRI_SMPTE432;
+ case HB_COLR_PRI_JEDEC_P22:
+ return AVCOL_PRI_JEDEC_P22;
+ default:
+ case HB_COLR_PRI_UNDEF:
+ return AVCOL_PRI_UNSPECIFIED;
+ }
+}
+
+int hb_colr_tra_hb_to_ff(int colr_tra)
+{
+ switch (colr_tra)
+ {
+ case HB_COLR_TRA_BT709:
+ return AVCOL_TRC_BT709;
+ case HB_COLR_TRA_GAMMA22:
+ return AVCOL_TRC_GAMMA22;
+ case HB_COLR_TRA_GAMMA28:
+ return AVCOL_TRC_GAMMA28;
+ case HB_COLR_TRA_SMPTE170M:
+ return AVCOL_TRC_SMPTE170M;
+ case HB_COLR_TRA_SMPTE240M:
+ return AVCOL_TRC_SMPTE240M;
+ case HB_COLR_TRA_LINEAR:
+ return AVCOL_TRC_LINEAR;
+ case HB_COLR_TRA_LOG:
+ return AVCOL_TRC_LOG;
+ case HB_COLR_TRA_LOG_SQRT:
+ return AVCOL_TRC_LOG_SQRT;
+ case HB_COLR_TRA_IEC61966_2_4:
+ return AVCOL_TRC_IEC61966_2_4;
+ case HB_COLR_TRA_BT1361_ECG:
+ return AVCOL_TRC_BT1361_ECG;
+ case HB_COLR_TRA_IEC61966_2_1:
+ return AVCOL_TRC_IEC61966_2_1;
+ case HB_COLR_TRA_BT2020_10:
+ return AVCOL_TRC_BT2020_10;
+ case HB_COLR_TRA_BT2020_12:
+ return AVCOL_TRC_BT2020_12;
+ case HB_COLR_TRA_SMPTEST2084:
+ return AVCOL_TRC_SMPTE2084;
+ case HB_COLR_TRA_SMPTE428:
+ return AVCOL_TRC_SMPTE428;
+ case HB_COLR_TRA_ARIB_STD_B67:
+ return AVCOL_TRC_ARIB_STD_B67;
+ default:
+ case HB_COLR_TRA_UNDEF:
+ return AVCOL_TRC_UNSPECIFIED;
+ }
+}
+
+int hb_colr_mat_hb_to_ff(int colr_mat)
+{
+ switch (colr_mat)
+ {
+ case HB_COLR_MAT_RGB:
+ return AVCOL_SPC_RGB;
+ case HB_COLR_MAT_BT709:
+ return AVCOL_SPC_BT709;
+ case HB_COLR_MAT_FCC:
+ return AVCOL_SPC_FCC;
+ case HB_COLR_MAT_BT470BG:
+ return AVCOL_SPC_BT470BG;
+ case HB_COLR_MAT_SMPTE170M:
+ return AVCOL_SPC_SMPTE170M;
+ case HB_COLR_MAT_SMPTE240M:
+ return AVCOL_SPC_SMPTE240M;
+ case HB_COLR_MAT_YCGCO:
+ return AVCOL_SPC_YCGCO;
+ case HB_COLR_MAT_BT2020_NCL:
+ return AVCOL_SPC_BT2020_NCL;
+ case HB_COLR_MAT_BT2020_CL:
+ return AVCOL_SPC_BT2020_CL;
+ case HB_COLR_MAT_SMPTE2085:
+ return AVCOL_SPC_SMPTE2085;
+ case HB_COLR_MAT_CD_NCL:
+ return AVCOL_SPC_CHROMA_DERIVED_NCL;
+ case HB_COLR_MAT_CD_CL:
+ return AVCOL_SPC_CHROMA_DERIVED_CL;
+ case HB_COLR_MAT_ICTCP:
+ return AVCOL_SPC_ICTCP;
+ default:
+ case HB_COLR_MAT_UNDEF:
+ return AVCOL_SPC_UNSPECIFIED;
+ }
+}
+
+int hb_colr_pri_ff_to_hb(int colr_prim)
+{
+ switch (colr_prim)
+ {
+ case AVCOL_PRI_BT709:
+ return HB_COLR_PRI_BT709;
+ case AVCOL_PRI_BT470M:
+ return HB_COLR_PRI_BT470M;
+ case AVCOL_PRI_BT470BG:
+ return HB_COLR_PRI_EBUTECH;
+ case AVCOL_PRI_SMPTE170M:
+ return HB_COLR_PRI_SMPTEC;
+ case AVCOL_PRI_SMPTE240M:
+ return HB_COLR_PRI_SMPTE240M;
+ case AVCOL_PRI_FILM:
+ return HB_COLR_PRI_FILM;
+ case AVCOL_PRI_BT2020:
+ return HB_COLR_PRI_BT2020;
+ case AVCOL_PRI_SMPTE428:
+ return HB_COLR_PRI_SMPTE428;
+ case AVCOL_PRI_SMPTE431:
+ return HB_COLR_PRI_SMPTE431;
+ case AVCOL_PRI_SMPTE432:
+ return HB_COLR_PRI_SMPTE432;
+ case AVCOL_PRI_JEDEC_P22:
+ return HB_COLR_PRI_JEDEC_P22;
+ default:
+ case AVCOL_PRI_RESERVED:
+ case AVCOL_PRI_RESERVED0:
+ case AVCOL_PRI_UNSPECIFIED:
+ return HB_COLR_PRI_UNDEF;
+ }
+}
+
+int hb_colr_tra_ff_to_hb(int colr_tra)
+{
+ switch (colr_tra)
+ {
+ case AVCOL_TRC_BT709:
+ return HB_COLR_TRA_BT709;
+ case AVCOL_TRC_GAMMA22:
+ return HB_COLR_TRA_GAMMA22;
+ case AVCOL_TRC_GAMMA28:
+ return HB_COLR_TRA_GAMMA28;
+ case AVCOL_TRC_SMPTE170M:
+ return HB_COLR_TRA_SMPTE170M;
+ case AVCOL_TRC_SMPTE240M:
+ return HB_COLR_TRA_SMPTE240M;
+ case AVCOL_TRC_LINEAR:
+ return HB_COLR_TRA_LINEAR;
+ case AVCOL_TRC_LOG:
+ return HB_COLR_TRA_LOG;
+ case AVCOL_TRC_LOG_SQRT:
+ return HB_COLR_TRA_LOG_SQRT;
+ case AVCOL_TRC_IEC61966_2_4:
+ return HB_COLR_TRA_IEC61966_2_4;
+ case AVCOL_TRC_BT1361_ECG:
+ return HB_COLR_TRA_BT1361_ECG;
+ case AVCOL_TRC_IEC61966_2_1:
+ return HB_COLR_TRA_IEC61966_2_1;
+ case AVCOL_TRC_BT2020_10:
+ return HB_COLR_TRA_BT2020_10;
+ case AVCOL_TRC_BT2020_12:
+ return HB_COLR_TRA_BT2020_12;
+ case AVCOL_TRC_SMPTE2084:
+ return HB_COLR_TRA_SMPTEST2084;
+ case AVCOL_TRC_SMPTE428:
+ return HB_COLR_TRA_SMPTE428;
+ case AVCOL_TRC_ARIB_STD_B67:
+ return HB_COLR_TRA_ARIB_STD_B67;
+ default:
+ case AVCOL_TRC_UNSPECIFIED:
+ case AVCOL_TRC_RESERVED:
+ case AVCOL_TRC_RESERVED0:
+ return HB_COLR_TRA_UNDEF;
+ }
+}
+
+int hb_colr_mat_ff_to_hb(int colr_mat)
+{
+ switch (colr_mat)
+ {
+ case AVCOL_SPC_RGB:
+ return HB_COLR_MAT_RGB;
+ case AVCOL_SPC_BT709:
+ return HB_COLR_MAT_BT709;
+ case AVCOL_SPC_FCC:
+ return HB_COLR_MAT_FCC;
+ case AVCOL_SPC_BT470BG:
+ return HB_COLR_MAT_BT470BG;
+ case AVCOL_SPC_SMPTE170M:
+ return HB_COLR_MAT_SMPTE170M;
+ case AVCOL_SPC_SMPTE240M:
+ return HB_COLR_MAT_SMPTE240M;
+ case AVCOL_SPC_YCGCO:
+ return HB_COLR_MAT_YCGCO;
+ case AVCOL_SPC_BT2020_NCL:
+ return HB_COLR_MAT_BT2020_NCL;
+ case AVCOL_SPC_BT2020_CL:
+ return HB_COLR_MAT_BT2020_CL;
+ case AVCOL_SPC_SMPTE2085:
+ return HB_COLR_MAT_SMPTE2085;
+ case AVCOL_SPC_CHROMA_DERIVED_NCL:
+ return HB_COLR_MAT_CD_NCL;
+ case AVCOL_SPC_CHROMA_DERIVED_CL:
+ return HB_COLR_MAT_CD_CL;
+ case AVCOL_SPC_ICTCP:
+ return HB_COLR_MAT_ICTCP;
+ default:
+ case AVCOL_SPC_UNSPECIFIED:
+ case AVCOL_SPC_RESERVED:
+ return HB_COLR_MAT_UNDEF;
+ }
+}
+
uint64_t hb_ff_mixdown_xlat(int hb_mixdown, int *downmix_mode)
{
uint64_t ff_layout = 0;
diff --git a/libhb/hbffmpeg.h b/libhb/hbffmpeg.h
index 648089c37..119347153 100644
--- a/libhb/hbffmpeg.h
+++ b/libhb/hbffmpeg.h
@@ -33,7 +33,13 @@ const char* const* hb_av_preset_get_names(int encoder);
uint64_t hb_ff_mixdown_xlat(int hb_mixdown, int *downmix_mode);
void hb_ff_set_sample_fmt(AVCodecContext *, AVCodec *, enum AVSampleFormat);
-int hb_ff_get_colorspace(int color_matrix);
+int hb_sws_get_colorspace(int color_matrix);
+int hb_colr_pri_hb_to_ff(int colr_prim);
+int hb_colr_tra_hb_to_ff(int colr_tra);
+int hb_colr_mat_hb_to_ff(int colr_mat);
+int hb_colr_pri_ff_to_hb(int colr_prim);
+int hb_colr_tra_ff_to_hb(int colr_tra);
+int hb_colr_mat_ff_to_hb(int colr_mat);
struct SwsContext*
hb_sws_get_context(int srcW, int srcH, enum AVPixelFormat srcFormat,
diff --git a/libhb/internal.h b/libhb/internal.h
index fb121a9bf..eea87b0e9 100644
--- a/libhb/internal.h
+++ b/libhb/internal.h
@@ -113,6 +113,10 @@ struct hb_image_format_s
int width;
int height;
int fmt;
+ int color_prim;
+ int color_transfer;
+ int color_matrix;
+ int color_range;
int max_plane;
int window_width;
int window_height;
@@ -464,6 +468,7 @@ extern hb_filter_object_t hb_filter_lapsharp;
extern hb_filter_object_t hb_filter_unsharp;
extern hb_filter_object_t hb_filter_avfilter;
extern hb_filter_object_t hb_filter_mt_frame;
+extern hb_filter_object_t hb_filter_colorspace;
#ifdef USE_QSV
extern hb_filter_object_t hb_filter_qsv;
diff --git a/libhb/lapsharp.c b/libhb/lapsharp.c
index d7146c031..e80a8480b 100644
--- a/libhb/lapsharp.c
+++ b/libhb/lapsharp.c
@@ -85,6 +85,9 @@ static kernel_t kernels[] =
struct hb_filter_private_s
{
lapsharp_plane_context_t plane_ctx[3];
+
+ hb_filter_init_t input;
+ hb_filter_init_t output;
};
static int hb_lapsharp_init(hb_filter_object_t *filter,
@@ -163,6 +166,8 @@ static int hb_lapsharp_init(hb_filter_object_t *filter,
char *kernel_string[3];
+ pv->input = *init;
+
// Mark parameters unset
for (int c = 0; c < 3; c++)
{
@@ -252,6 +257,7 @@ static int hb_lapsharp_init(hb_filter_object_t *filter,
ctx->kernel = c ? LAPSHARP_KERNEL_CHROMA_DEFAULT : LAPSHARP_KERNEL_LUMA_DEFAULT;
}
}
+ pv->output = *init;
return 0;
}
@@ -284,7 +290,11 @@ static int hb_lapsharp_work(hb_filter_object_t *filter,
}
hb_frame_buffer_mirror_stride(in);
- out = hb_frame_buffer_init(in->f.fmt, in->f.width, in->f.height);
+ out = hb_frame_buffer_init(pv->output.pix_fmt, in->f.width, in->f.height);
+ out->f.color_prim = pv->output.color_prim;
+ out->f.color_transfer = pv->output.color_transfer;
+ out->f.color_matrix = pv->output.color_matrix;
+ out->f.color_range = pv->output.color_range ;
int c;
for (c = 0; c < 3; c++)
diff --git a/libhb/nlmeans.c b/libhb/nlmeans.c
index d8e5aa01a..e68e24739 100644
--- a/libhb/nlmeans.c
+++ b/libhb/nlmeans.c
@@ -143,7 +143,10 @@ struct hb_filter_private_s
int max_frames;
taskset_t taskset;
- nlmeans_thread_arg_t **thread_data;
+ nlmeans_thread_arg_t ** thread_data;
+
+ hb_filter_init_t input;
+ hb_filter_init_t output;
};
static int nlmeans_init(hb_filter_object_t *filter, hb_filter_init_t *init);
@@ -895,6 +898,8 @@ static int nlmeans_init(hb_filter_object_t *filter,
hb_filter_private_t *pv = filter->private_data;
NLMeansFunctions *functions = &pv->functions;
+ pv->input = *init;
+
functions->build_integral = build_integral_scalar;
#if defined(ARCH_X86)
nlmeans_init_x86(functions);
@@ -1041,6 +1046,7 @@ static int nlmeans_init(hb_filter_object_t *filter,
goto fail;
}
}
+ pv->output = *init;
return 0;
@@ -1113,7 +1119,13 @@ static void nlmeans_filter_thread(void *thread_args_v)
Frame *frame = &pv->frame[segment];
hb_buffer_t *buf;
- buf = hb_frame_buffer_init(frame->fmt, frame->width, frame->height);
+ buf = hb_frame_buffer_init(pv->output.pix_fmt,
+ frame->width, frame->height);
+ buf->f.color_prim = pv->output.color_prim;
+ buf->f.color_transfer = pv->output.color_transfer;
+ buf->f.color_matrix = pv->output.color_matrix;
+ buf->f.color_range = pv->output.color_range ;
+
NLMeansFunctions *functions = &pv->functions;
@@ -1244,7 +1256,12 @@ static hb_buffer_t * nlmeans_filter_flush(hb_filter_private_t *pv)
{
Frame *frame = &pv->frame[f];
hb_buffer_t *buf;
- buf = hb_frame_buffer_init(frame->fmt, frame->width, frame->height);
+ buf = hb_frame_buffer_init(pv->output.pix_fmt,
+ frame->width, frame->height);
+ buf->f.color_prim = pv->output.color_prim;
+ buf->f.color_transfer = pv->output.color_transfer;
+ buf->f.color_matrix = pv->output.color_matrix;
+ buf->f.color_range = pv->output.color_range ;
NLMeansFunctions *functions = &pv->functions;
diff --git a/libhb/rendersub.c b/libhb/rendersub.c
index 866e277f4..68ba4d8e5 100644
--- a/libhb/rendersub.c
+++ b/libhb/rendersub.c
@@ -34,6 +34,9 @@ struct hb_filter_private_s
// SRT
int line;
hb_buffer_t * current_sub;
+
+ hb_filter_init_t input;
+ hb_filter_init_t output;
};
// VOBSUB
@@ -224,7 +227,14 @@ static hb_buffer_t * ScaleSubtitle(hb_filter_private_t *pv,
width = sub->f.width * xfactor;
height = sub->f.height * yfactor;
- scaled = hb_frame_buffer_init(AV_PIX_FMT_YUVA420P, width, height);
+ scaled = hb_frame_buffer_init(pv->output.pix_fmt, width, height);
+ if (scaled == NULL)
+ return NULL;
+ scaled->f.color_prim = pv->output.color_prim;
+ scaled->f.color_transfer = pv->output.color_transfer;
+ scaled->f.color_matrix = pv->output.color_matrix;
+ scaled->f.color_range = pv->output.color_range ;
+
scaled->f.x = sub->f.x * xfactor;
scaled->f.y = sub->f.y * yfactor;
@@ -456,9 +466,13 @@ static hb_buffer_t * RenderSSAFrame( hb_filter_private_t * pv, ASS_Image * frame
unsigned frameV = (yuv >> 8 ) & 0xff;
unsigned frameU = (yuv >> 0 ) & 0xff;
- sub = hb_frame_buffer_init( AV_PIX_FMT_YUVA420P, frame->w, frame->h );
- if( sub == NULL )
+ sub = hb_frame_buffer_init(pv->output.pix_fmt, frame->w, frame->h);
+ if (sub == NULL)
return NULL;
+ sub->f.color_prim = pv->output.color_prim;
+ sub->f.color_transfer = pv->output.color_transfer;
+ sub->f.color_matrix = pv->output.color_matrix;
+ sub->f.color_range = pv->output.color_range ;
uint8_t *y_out, *u_out, *v_out, *a_out;
y_out = sub->plane[0].data;
@@ -940,6 +954,8 @@ static int hb_rendersub_init( hb_filter_object_t * filter,
hb_subtitle_t *subtitle;
int ii;
+ pv->input = *init;
+
// Find the subtitle we need
for( ii = 0; ii < hb_list_count(init->job->list_subtitle); ii++ )
{
@@ -957,6 +973,8 @@ static int hb_rendersub_init( hb_filter_object_t * filter,
hb_log("rendersub: no subtitle marked for burn");
return 1;
}
+ pv->output = *init;
+
return 0;
}
diff --git a/libhb/scan.c b/libhb/scan.c
index 74a5add7b..640ffdddb 100644
--- a/libhb/scan.c
+++ b/libhb/scan.c
@@ -1005,9 +1005,11 @@ skip_preview:
{
title->geometry.par = vid_info.geometry.par;
}
+ title->pix_fmt = vid_info.pix_fmt;
title->color_prim = vid_info.color_prim;
title->color_transfer = vid_info.color_transfer;
title->color_matrix = vid_info.color_matrix;
+ title->color_range = vid_info.color_range;
title->video_decode_support = vid_info.video_decode_support;
diff --git a/libhb/unsharp.c b/libhb/unsharp.c
index 058440872..0206283c4 100644
--- a/libhb/unsharp.c
+++ b/libhb/unsharp.c
@@ -42,6 +42,9 @@ struct hb_filter_private_s
unsharp_plane_context_t plane_ctx[3];
unsharp_thread_context3_t * thread_ctx;
int threads;
+
+ hb_filter_init_t input;
+ hb_filter_init_t output;
};
static int unsharp_init(hb_filter_object_t *filter,
@@ -167,6 +170,8 @@ static int unsharp_init(hb_filter_object_t *filter,
}
hb_filter_private_t * pv = filter->private_data;
+ pv->input = *init;
+
// Mark parameters unset
for (int c = 0; c < 3; c++)
{
@@ -236,6 +241,8 @@ static int unsharp_init(hb_filter_object_t *filter,
return -1;
}
+ pv->output = *init;
+
return 0;
}
@@ -318,7 +325,11 @@ static int unsharp_work_thread(hb_filter_object_t *filter,
return HB_FILTER_DONE;
}
- out = hb_frame_buffer_init(in->f.fmt, in->f.width, in->f.height);
+ out = hb_frame_buffer_init(pv->output.pix_fmt, in->f.width, in->f.height);
+ out->f.color_prim = pv->output.color_prim;
+ out->f.color_transfer = pv->output.color_transfer;
+ out->f.color_matrix = pv->output.color_matrix;
+ out->f.color_range = pv->output.color_range ;
int c;
for (c = 0; c < 3; c++)
diff --git a/libhb/work.c b/libhb/work.c
index f5654b45d..e22fbaca9 100644
--- a/libhb/work.c
+++ b/libhb/work.c
@@ -1464,10 +1464,11 @@ static void do_job(hb_job_t *job)
init.time_base.num = 1;
init.time_base.den = 90000;
init.job = job;
- init.pix_fmt = AV_PIX_FMT_YUV420P;
+ init.pix_fmt = title->pix_fmt;
init.color_prim = title->color_prim;
init.color_transfer = title->color_transfer;
init.color_matrix = title->color_matrix;
+ init.color_range = title->color_range;
init.geometry.width = title->geometry.width;
init.geometry.height = title->geometry.height;