| @@ -17,6 +17,7 @@ · 16 unmodified lines |
| 17 | 17 | */ |
| 18 | 18 | |
| 19 | 19 | #include "film_grain_params.h" |
| 20 | +#include "pixdesc.h" |
| 20 | 21 | |
| 21 | 22 | AVFilmGrainParams *av_film_grain_params_alloc(size_t *size) |
| 22 | 23 | { |
| @@ -47,3 +48,63 @@ AVFilmGrainParams *av_film_grain_params_create_side_data(AVFrame *frame) · 24 unmodified lines |
| 47 | 48 | |
| 48 | 49 | return fgp; |
| 49 | 50 | } |
| 51 | + |
| 52 | +const AVFilmGrainParams *av_film_grain_params_select(const AVFrame *frame) |
| 53 | +{ |
| 54 | + const AVFilmGrainParams *fgp, *best = NULL; |
| 55 | + const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(frame->format); |
| 56 | + const AVFilmGrainAOMParams *aom; |
| 57 | + const AVFilmGrainH274Params *h274; |
| 58 | + int bit_depth_luma, bit_depth_chroma; |
| 59 | + if (!desc) |
| 60 | + return NULL; |
| 61 | + |
| 62 | + /* There are no YUV formats with different bit depth per component, |
| 63 | + * so just check both against the first component for simplicity */ |
| 64 | + bit_depth_luma = bit_depth_chroma = desc->comp[0].depth; |
| 65 | + |
| 66 | + for (int i = 0; i < frame->nb_side_data; i++) { |
| 67 | + if (frame->side_data[i]->type != AV_FRAME_DATA_FILM_GRAIN_PARAMS) |
| 68 | + continue; |
| 69 | + fgp = (const AVFilmGrainParams*)frame->side_data[i]->data; |
| 70 | + if (fgp->width && fgp->width > frame->width || |
| 71 | + fgp->height && fgp->height > frame->height) |
| 72 | + continue; |
| 73 | + |
| 74 | +#define CHECK(a, b, unspec) \ |
| 75 | + do { \ |
| 76 | + if ((a) != (unspec) && (b) != (unspec) && (a) != (b)) \ |
| 77 | + continue; \ |
| 78 | + } while (0) |
| 79 | + |
| 80 | + CHECK(fgp->bit_depth_luma, bit_depth_luma, 0); |
| 81 | + CHECK(fgp->bit_depth_chroma, bit_depth_chroma, 0); |
| 82 | + CHECK(fgp->color_range, frame->color_range, AVCOL_RANGE_UNSPECIFIED); |
| 83 | + CHECK(fgp->color_primaries, frame->color_primaries, AVCOL_PRI_UNSPECIFIED); |
| 84 | + CHECK(fgp->color_trc, frame->color_trc, AVCOL_TRC_UNSPECIFIED); |
| 85 | + CHECK(fgp->color_space, frame->colorspace, AVCOL_SPC_UNSPECIFIED); |
| 86 | + |
| 87 | + switch (fgp->type) { |
| 88 | + case AV_FILM_GRAIN_PARAMS_NONE: |
| 89 | + continue; |
| 90 | + case AV_FILM_GRAIN_PARAMS_AV1: |
| 91 | + aom = &fgp->codec.aom; |
| 92 | + /* AOM FGS needs an exact match for the chroma resolution */ |
| 93 | + if (fgp->subsampling_x != desc->log2_chroma_w || |
| 94 | + fgp->subsampling_y != desc->log2_chroma_h) |
| 95 | + continue; |
| 96 | + break; |
| 97 | + case AV_FILM_GRAIN_PARAMS_H274: |
| 98 | + /* H.274 FGS can be adapted to any lower chroma resolution */ |
| 99 | + if (fgp->subsampling_x > desc->log2_chroma_w || |
| 100 | + fgp->subsampling_y > desc->log2_chroma_h) |
| 101 | + continue; |
| 102 | + break; |
| 103 | + } |
| 104 | + |
| 105 | + if (!best || best->width < fgp->width || best->height < fgp->height) |
| 106 | + best = fgp; |
| 107 | + } |
| 108 | + |
| 109 | + return best; |
| 110 | +} |