diff options
author | Niklas Haas <git@haasn.dev> | 2024-12-01 15:00:35 +0100 |
---|---|---|
committer | Niklas Haas <git@haasn.dev> | 2024-12-23 12:33:43 +0100 |
commit | 6da940e1189af566614bdd39ca6ac2ae54615248 (patch) | |
tree | c525efdd74e0cf931ee3a4b3d184379391acf8a8 | |
parent | efff80c8f65ec3114811cc8261174ca0a81b4c75 (diff) | |
download | ffmpeg-6da940e1189af566614bdd39ca6ac2ae54615248.tar.gz |
swscale/graph: allow dynamically updating HDR metadata
Without triggering a full graph reinit.
-rw-r--r-- | libswscale/graph.c | 21 | ||||
-rw-r--r-- | libswscale/graph.h | 12 | ||||
-rw-r--r-- | libswscale/utils.h | 6 |
3 files changed, 35 insertions, 4 deletions
diff --git a/libswscale/graph.c b/libswscale/graph.c index 7160458a5f..f390e53d24 100644 --- a/libswscale/graph.c +++ b/libswscale/graph.c @@ -475,6 +475,14 @@ static void free_lut3d(void *priv) sws_lut3d_free(&lut); } +static void setup_lut3d(const SwsImg *out, const SwsImg *in, const SwsPass *pass) +{ + SwsLut3D *lut = pass->priv; + + /* Update dynamic frame metadata from the original source frame */ + sws_lut3d_update(lut, &pass->graph->src.color); +} + static void run_lut3d(const SwsImg *out_base, const SwsImg *in_base, int y, int h, const SwsPass *pass) { @@ -543,6 +551,7 @@ static int adapt_colors(SwsGraph *graph, SwsFormat src, SwsFormat dst, sws_lut3d_free(&lut); return AVERROR(ENOMEM); } + pass->setup = setup_lut3d; pass->free = free_lut3d; *output = pass; @@ -678,16 +687,26 @@ static int opts_equal(const SwsContext *c1, const SwsContext *c2) int sws_graph_reinit(SwsContext *ctx, const SwsFormat *dst, const SwsFormat *src, int field, SwsGraph **out_graph) { - const SwsGraph *graph = *out_graph; + SwsGraph *graph = *out_graph; if (graph && ff_fmt_equal(&graph->src, src) && ff_fmt_equal(&graph->dst, dst) && opts_equal(ctx, &graph->opts_copy)) + { + sws_graph_update_metadata(graph, &src->color); return 0; + } sws_graph_free(out_graph); return sws_graph_create(ctx, dst, src, field, out_graph); } +void sws_graph_update_metadata(SwsGraph *graph, const SwsColor *color) +{ + if (!color) + return; + + ff_color_update_dynamic(&graph->src.color, color); +} void sws_graph_run(SwsGraph *graph, uint8_t *const out_data[4], const int out_linesize[4], diff --git a/libswscale/graph.h b/libswscale/graph.h index 989695043d..758060ca12 100644 --- a/libswscale/graph.h +++ b/libswscale/graph.h @@ -134,9 +134,15 @@ int sws_graph_create(SwsContext *ctx, const SwsFormat *dst, const SwsFormat *src void sws_graph_free(SwsGraph **graph); /** - * Wrapper around sws_graph_create that does nothing if the format is - * unchanged. Must be called after changing any of the fields in `ctx`, or else - * they will have no effect. + * Update dynamic per-frame HDR metadata without requiring a full reinit. + */ +void sws_graph_update_metadata(SwsGraph *graph, const SwsColor *color); + +/** + * Wrapper around sws_graph_create() that reuses the existing graph if the + * format is compatible. This will also update dynamic per-frame metadata. + * Must be called after changing any of the fields in `ctx`, or else they will + * have no effect. */ int sws_graph_reinit(SwsContext *ctx, const SwsFormat *dst, const SwsFormat *src, int field, SwsGraph **graph); diff --git a/libswscale/utils.h b/libswscale/utils.h index 6ffefbf6c3..d76fea1133 100644 --- a/libswscale/utils.h +++ b/libswscale/utils.h @@ -65,6 +65,12 @@ typedef struct SwsColor { AVRational frame_avg; /* per-frame/scene average luminance, or 0 */ } SwsColor; +static inline void ff_color_update_dynamic(SwsColor *dst, const SwsColor *src) +{ + dst->frame_peak = src->frame_peak; + dst->frame_avg = src->frame_avg; +} + /* Subset of AVFrame parameters that uniquely determine pixel representation */ typedef struct SwsFormat { int width, height; |