summaryrefslogtreecommitdiffstats
path: root/media/ffvpx/libavutil/film_grain_params.c
diff options
context:
space:
mode:
Diffstat (limited to 'media/ffvpx/libavutil/film_grain_params.c')
-rw-r--r--media/ffvpx/libavutil/film_grain_params.c68
1 files changed, 66 insertions, 2 deletions
diff --git a/media/ffvpx/libavutil/film_grain_params.c b/media/ffvpx/libavutil/film_grain_params.c
index 930d23c7fe..0a6004b6b3 100644
--- a/media/ffvpx/libavutil/film_grain_params.c
+++ b/media/ffvpx/libavutil/film_grain_params.c
@@ -17,6 +17,8 @@
*/
#include "film_grain_params.h"
+#include "mem.h"
+#include "pixdesc.h"
AVFilmGrainParams *av_film_grain_params_alloc(size_t *size)
{
@@ -30,13 +32,75 @@ AVFilmGrainParams *av_film_grain_params_alloc(size_t *size)
AVFilmGrainParams *av_film_grain_params_create_side_data(AVFrame *frame)
{
+ AVFilmGrainParams *fgp;
AVFrameSideData *side_data = av_frame_new_side_data(frame,
AV_FRAME_DATA_FILM_GRAIN_PARAMS,
sizeof(AVFilmGrainParams));
if (!side_data)
return NULL;
- memset(side_data->data, 0, sizeof(AVFilmGrainParams));
+ fgp = (AVFilmGrainParams *) side_data->data;
+ *fgp = (AVFilmGrainParams) {
+ .color_range = AVCOL_RANGE_UNSPECIFIED,
+ .color_primaries = AVCOL_PRI_UNSPECIFIED,
+ .color_trc = AVCOL_TRC_UNSPECIFIED,
+ .color_space = AVCOL_SPC_UNSPECIFIED,
+ };
- return (AVFilmGrainParams *)side_data->data;
+ return fgp;
+}
+
+const AVFilmGrainParams *av_film_grain_params_select(const AVFrame *frame)
+{
+ const AVFilmGrainParams *fgp, *best = NULL;
+ const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(frame->format);
+ int bit_depth_luma, bit_depth_chroma;
+ if (!desc)
+ return NULL;
+
+ /* There are no YUV formats with different bit depth per component,
+ * so just check both against the first component for simplicity */
+ bit_depth_luma = bit_depth_chroma = desc->comp[0].depth;
+
+ for (int i = 0; i < frame->nb_side_data; i++) {
+ if (frame->side_data[i]->type != AV_FRAME_DATA_FILM_GRAIN_PARAMS)
+ continue;
+ fgp = (const AVFilmGrainParams*)frame->side_data[i]->data;
+ if (fgp->width && fgp->width > frame->width ||
+ fgp->height && fgp->height > frame->height)
+ continue;
+
+#define CHECK(a, b, unspec) \
+ if ((a) != (unspec) && (b) != (unspec) && (a) != (b)) \
+ continue
+
+ CHECK(fgp->bit_depth_luma, bit_depth_luma, 0);
+ CHECK(fgp->bit_depth_chroma, bit_depth_chroma, 0);
+ CHECK(fgp->color_range, frame->color_range, AVCOL_RANGE_UNSPECIFIED);
+ CHECK(fgp->color_primaries, frame->color_primaries, AVCOL_PRI_UNSPECIFIED);
+ CHECK(fgp->color_trc, frame->color_trc, AVCOL_TRC_UNSPECIFIED);
+ CHECK(fgp->color_space, frame->colorspace, AVCOL_SPC_UNSPECIFIED);
+
+ switch (fgp->type) {
+ case AV_FILM_GRAIN_PARAMS_NONE:
+ continue;
+ case AV_FILM_GRAIN_PARAMS_AV1:
+ /* AOM FGS needs an exact match for the chroma resolution */
+ if (fgp->subsampling_x != desc->log2_chroma_w ||
+ fgp->subsampling_y != desc->log2_chroma_h)
+ continue;
+ break;
+ case AV_FILM_GRAIN_PARAMS_H274:
+ /* H.274 FGS can be adapted to any lower chroma resolution */
+ if (fgp->subsampling_x > desc->log2_chroma_w ||
+ fgp->subsampling_y > desc->log2_chroma_h)
+ continue;
+ break;
+ }
+
+ if (!best || best->width < fgp->width || best->height < fgp->height)
+ best = fgp;
+ }
+
+ return best;
}