The two functions are identical. Use the shared LumaCoeffients type too.tags/n4.1
@@ -365,7 +365,7 @@ OBJS-$(CONFIG_TILE_FILTER) += vf_tile.o | |||||
OBJS-$(CONFIG_TINTERLACE_FILTER) += vf_tinterlace.o | OBJS-$(CONFIG_TINTERLACE_FILTER) += vf_tinterlace.o | ||||
OBJS-$(CONFIG_TLUT2_FILTER) += vf_lut2.o framesync.o | OBJS-$(CONFIG_TLUT2_FILTER) += vf_lut2.o framesync.o | ||||
OBJS-$(CONFIG_TMIX_FILTER) += vf_mix.o framesync.o | OBJS-$(CONFIG_TMIX_FILTER) += vf_mix.o framesync.o | ||||
OBJS-$(CONFIG_TONEMAP_FILTER) += vf_tonemap.o | |||||
OBJS-$(CONFIG_TONEMAP_FILTER) += vf_tonemap.o colorspace.o | |||||
OBJS-$(CONFIG_TONEMAP_OPENCL_FILTER) += vf_tonemap_opencl.o colorspace.o opencl.o \ | OBJS-$(CONFIG_TONEMAP_OPENCL_FILTER) += vf_tonemap_opencl.o colorspace.o opencl.o \ | ||||
opencl/tonemap.o opencl/colorspace_common.o | opencl/tonemap.o opencl/colorspace_common.o | ||||
OBJS-$(CONFIG_TRANSPOSE_FILTER) += vf_transpose.o | OBJS-$(CONFIG_TRANSPOSE_FILTER) += vf_transpose.o | ||||
@@ -17,6 +17,10 @@ | |||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA | ||||
*/ | */ | ||||
#include "libavutil/frame.h" | |||||
#include "libavutil/mastering_display_metadata.h" | |||||
#include "libavutil/pixdesc.h" | |||||
#include "colorspace.h" | #include "colorspace.h" | ||||
@@ -89,3 +93,28 @@ void ff_fill_rgb2xyz_table(const struct PrimaryCoefficients *coeffs, | |||||
rgb2xyz[2][1] *= sg; | rgb2xyz[2][1] *= sg; | ||||
rgb2xyz[2][2] *= sb; | rgb2xyz[2][2] *= sb; | ||||
} | } | ||||
double ff_determine_signal_peak(AVFrame *in) | |||||
{ | |||||
AVFrameSideData *sd = av_frame_get_side_data(in, AV_FRAME_DATA_CONTENT_LIGHT_LEVEL); | |||||
double peak = 0; | |||||
if (sd) { | |||||
AVContentLightMetadata *clm = (AVContentLightMetadata *)sd->data; | |||||
peak = clm->MaxCLL / REFERENCE_WHITE; | |||||
} | |||||
sd = av_frame_get_side_data(in, AV_FRAME_DATA_MASTERING_DISPLAY_METADATA); | |||||
if (!peak && sd) { | |||||
AVMasteringDisplayMetadata *metadata = (AVMasteringDisplayMetadata *)sd->data; | |||||
if (metadata->has_luminance) | |||||
peak = av_q2d(metadata->max_luminance) / REFERENCE_WHITE; | |||||
} | |||||
// For untagged source, use peak of 10000 if SMPTE ST.2084 | |||||
// otherwise assume HLG with reference display peak 1000. | |||||
if (!peak) | |||||
peak = in->color_trc == AVCOL_TRC_SMPTE2084 ? 100.0f : 10.0f; | |||||
return peak; | |||||
} |
@@ -21,6 +21,9 @@ | |||||
#define AVFILTER_COLORSPACE_H | #define AVFILTER_COLORSPACE_H | ||||
#include "libavutil/common.h" | #include "libavutil/common.h" | ||||
#include "libavutil/frame.h" | |||||
#define REFERENCE_WHITE 100.0f | |||||
struct LumaCoefficients { | struct LumaCoefficients { | ||||
double cr, cg, cb; | double cr, cg, cb; | ||||
@@ -40,4 +43,7 @@ void ff_matrix_mul_3x3(double dst[3][3], | |||||
void ff_fill_rgb2xyz_table(const struct PrimaryCoefficients *coeffs, | void ff_fill_rgb2xyz_table(const struct PrimaryCoefficients *coeffs, | ||||
const struct WhitepointCoefficients *wp, | const struct WhitepointCoefficients *wp, | ||||
double rgb2xyz[3][3]); | double rgb2xyz[3][3]); | ||||
double ff_determine_signal_peak(AVFrame *in); | |||||
#endif | #endif |
@@ -30,17 +30,15 @@ | |||||
#include "libavutil/imgutils.h" | #include "libavutil/imgutils.h" | ||||
#include "libavutil/internal.h" | #include "libavutil/internal.h" | ||||
#include "libavutil/intreadwrite.h" | #include "libavutil/intreadwrite.h" | ||||
#include "libavutil/mastering_display_metadata.h" | |||||
#include "libavutil/opt.h" | #include "libavutil/opt.h" | ||||
#include "libavutil/pixdesc.h" | #include "libavutil/pixdesc.h" | ||||
#include "avfilter.h" | #include "avfilter.h" | ||||
#include "colorspace.h" | |||||
#include "formats.h" | #include "formats.h" | ||||
#include "internal.h" | #include "internal.h" | ||||
#include "video.h" | #include "video.h" | ||||
#define REFERENCE_WHITE 100.0f | |||||
enum TonemapAlgorithm { | enum TonemapAlgorithm { | ||||
TONEMAP_NONE, | TONEMAP_NONE, | ||||
TONEMAP_LINEAR, | TONEMAP_LINEAR, | ||||
@@ -52,11 +50,6 @@ enum TonemapAlgorithm { | |||||
TONEMAP_MAX, | TONEMAP_MAX, | ||||
}; | }; | ||||
typedef struct LumaCoefficients { | |||||
double cr, cg, cb; | |||||
} LumaCoefficients; | |||||
static const struct LumaCoefficients luma_coefficients[AVCOL_SPC_NB] = { | static const struct LumaCoefficients luma_coefficients[AVCOL_SPC_NB] = { | ||||
[AVCOL_SPC_FCC] = { 0.30, 0.59, 0.11 }, | [AVCOL_SPC_FCC] = { 0.30, 0.59, 0.11 }, | ||||
[AVCOL_SPC_BT470BG] = { 0.299, 0.587, 0.114 }, | [AVCOL_SPC_BT470BG] = { 0.299, 0.587, 0.114 }, | ||||
@@ -75,7 +68,7 @@ typedef struct TonemapContext { | |||||
double desat; | double desat; | ||||
double peak; | double peak; | ||||
const LumaCoefficients *coeffs; | |||||
const struct LumaCoefficients *coeffs; | |||||
} TonemapContext; | } TonemapContext; | ||||
static const enum AVPixelFormat pix_fmts[] = { | static const enum AVPixelFormat pix_fmts[] = { | ||||
@@ -114,31 +107,6 @@ static av_cold int init(AVFilterContext *ctx) | |||||
return 0; | return 0; | ||||
} | } | ||||
static double determine_signal_peak(AVFrame *in) | |||||
{ | |||||
AVFrameSideData *sd = av_frame_get_side_data(in, AV_FRAME_DATA_CONTENT_LIGHT_LEVEL); | |||||
double peak = 0; | |||||
if (sd) { | |||||
AVContentLightMetadata *clm = (AVContentLightMetadata *)sd->data; | |||||
peak = clm->MaxCLL / REFERENCE_WHITE; | |||||
} | |||||
sd = av_frame_get_side_data(in, AV_FRAME_DATA_MASTERING_DISPLAY_METADATA); | |||||
if (!peak && sd) { | |||||
AVMasteringDisplayMetadata *metadata = (AVMasteringDisplayMetadata *)sd->data; | |||||
if (metadata->has_luminance) | |||||
peak = av_q2d(metadata->max_luminance) / REFERENCE_WHITE; | |||||
} | |||||
// For untagged source, use peak of 10000 if SMPTE ST.2084 | |||||
// otherwise assume HLG with reference display peak 1000. | |||||
if (!peak) | |||||
peak = in->color_trc == AVCOL_TRC_SMPTE2084 ? 100.0f : 10.0f; | |||||
return peak; | |||||
} | |||||
static float hable(float in) | static float hable(float in) | ||||
{ | { | ||||
float a = 0.15f, b = 0.50f, c = 0.10f, d = 0.20f, e = 0.02f, f = 0.30f; | float a = 0.15f, b = 0.50f, c = 0.10f, d = 0.20f, e = 0.02f, f = 0.30f; | ||||
@@ -260,7 +228,7 @@ static int filter_frame(AVFilterLink *link, AVFrame *in) | |||||
/* read peak from side data if not passed in */ | /* read peak from side data if not passed in */ | ||||
if (!peak) { | if (!peak) { | ||||
peak = determine_signal_peak(in); | |||||
peak = ff_determine_signal_peak(in); | |||||
av_log(s, AV_LOG_DEBUG, "Computed signal peak: %f\n", peak); | av_log(s, AV_LOG_DEBUG, "Computed signal peak: %f\n", peak); | ||||
} | } | ||||
@@ -40,7 +40,6 @@ | |||||
// - more format support | // - more format support | ||||
#define DETECTION_FRAMES 63 | #define DETECTION_FRAMES 63 | ||||
#define REFERENCE_WHITE 100.0f | |||||
enum TonemapAlgorithm { | enum TonemapAlgorithm { | ||||
TONEMAP_NONE, | TONEMAP_NONE, | ||||
@@ -343,31 +342,6 @@ fail: | |||||
return err; | return err; | ||||
} | } | ||||
static double determine_signal_peak(AVFrame *in) | |||||
{ | |||||
AVFrameSideData *sd = av_frame_get_side_data(in, AV_FRAME_DATA_CONTENT_LIGHT_LEVEL); | |||||
double peak = 0; | |||||
if (sd) { | |||||
AVContentLightMetadata *clm = (AVContentLightMetadata *)sd->data; | |||||
peak = clm->MaxCLL / REFERENCE_WHITE; | |||||
} | |||||
sd = av_frame_get_side_data(in, AV_FRAME_DATA_MASTERING_DISPLAY_METADATA); | |||||
if (!peak && sd) { | |||||
AVMasteringDisplayMetadata *metadata = (AVMasteringDisplayMetadata *)sd->data; | |||||
if (metadata->has_luminance) | |||||
peak = av_q2d(metadata->max_luminance) / REFERENCE_WHITE; | |||||
} | |||||
// For untagged source, use peak of 10000 if SMPTE ST.2084 | |||||
// otherwise assume HLG with reference display peak 1000. | |||||
if (!peak) | |||||
peak = in->color_trc == AVCOL_TRC_SMPTE2084 ? 100.0f : 10.0f; | |||||
return peak; | |||||
} | |||||
static void update_metadata(AVFrame *in, double peak) { | static void update_metadata(AVFrame *in, double peak) { | ||||
AVFrameSideData *sd = av_frame_get_side_data(in, AV_FRAME_DATA_CONTENT_LIGHT_LEVEL); | AVFrameSideData *sd = av_frame_get_side_data(in, AV_FRAME_DATA_CONTENT_LIGHT_LEVEL); | ||||
@@ -415,7 +389,7 @@ static int tonemap_opencl_filter_frame(AVFilterLink *inlink, AVFrame *input) | |||||
goto fail; | goto fail; | ||||
if (!peak) | if (!peak) | ||||
peak = determine_signal_peak(input); | |||||
peak = ff_determine_signal_peak(input); | |||||
if (ctx->trc != -1) | if (ctx->trc != -1) | ||||
output->color_trc = ctx->trc; | output->color_trc = ctx->trc; | ||||