diff options
author | John Stebbins <[email protected]> | 2019-03-15 15:27:01 -0600 |
---|---|---|
committer | John Stebbins <[email protected]> | 2019-04-08 07:44:09 -0600 |
commit | 3712b297c3487780d31151362b85c49ca27ff8ad (patch) | |
tree | 71f449d83c224bc2ff5cad824560c2730759540e /libhb | |
parent | 248c880fc86ee07d23d62135e002940f16364eb6 (diff) |
libhb: propagate color matrix info through the pipeline
Propagates pix_fmt, range, primaries, transfer, and matrix everywhere.
Everything that passes or creates video frames tags the frames with
their color matrix info.
All filters know the expected color matrix info of input frames.
Diffstat (limited to 'libhb')
-rw-r--r-- | libhb/avfilter.c | 117 | ||||
-rw-r--r-- | libhb/common.c | 132 | ||||
-rw-r--r-- | libhb/common.h | 35 | ||||
-rw-r--r-- | libhb/deblock.c | 12 | ||||
-rw-r--r-- | libhb/decavcodec.c | 17 | ||||
-rw-r--r-- | libhb/decomb.c | 9 | ||||
-rw-r--r-- | libhb/denoise.c | 13 | ||||
-rw-r--r-- | libhb/detelecine.c | 16 | ||||
-rw-r--r-- | libhb/hb.c | 2 | ||||
-rw-r--r-- | libhb/hb_json.c | 16 | ||||
-rw-r--r-- | libhb/hbffmpeg.c | 238 | ||||
-rw-r--r-- | libhb/hbffmpeg.h | 8 | ||||
-rw-r--r-- | libhb/internal.h | 5 | ||||
-rw-r--r-- | libhb/lapsharp.c | 12 | ||||
-rw-r--r-- | libhb/nlmeans.c | 23 | ||||
-rw-r--r-- | libhb/rendersub.c | 24 | ||||
-rw-r--r-- | libhb/scan.c | 2 | ||||
-rw-r--r-- | libhb/unsharp.c | 13 | ||||
-rw-r--r-- | libhb/work.c | 3 |
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; |