| /* |
| * Copyright (C) 2024 Niklas Haas |
| * |
| * This file is part of FFmpeg. |
| * |
| * FFmpeg is free software; you can redistribute it and/or |
| * modify it under the terms of the GNU Lesser General Public |
| * License as published by the Free Software Foundation; either |
| * version 2.1 of the License, or (at your option) any later version. |
| * |
| * FFmpeg is distributed in the hope that it will be useful, |
| * but WITHOUT ANY WARRANTY; without even the implied warranty of |
| * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
| * Lesser General Public License for more details. |
| * |
| * You should have received a copy of the GNU Lesser General Public |
| * License along with FFmpeg; if not, write to the Free Software |
| * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
| */ |
| |
| #ifndef SWSCALE_FORMAT_H |
| #define SWSCALE_FORMAT_H |
| |
| #include <stdbool.h> |
| |
| #include "libavutil/csp.h" |
| #include "libavutil/pixdesc.h" |
| |
| #include "swscale.h" |
| |
| static inline int ff_q_isnan(const AVRational a) |
| { |
| return !a.num && !a.den; |
| } |
| |
| /* Like av_cmp_q but considers NaN == NaN */ |
| static inline int ff_q_equal(const AVRational a, const AVRational b) |
| { |
| return (ff_q_isnan(a) && ff_q_isnan(b)) || !av_cmp_q(a, b); |
| } |
| |
| static inline int ff_cie_xy_equal(const AVCIExy a, const AVCIExy b) |
| { |
| return ff_q_equal(a.x, b.x) && ff_q_equal(a.y, b.y); |
| } |
| |
| static inline int ff_prim_equal(const AVPrimaryCoefficients *a, |
| const AVPrimaryCoefficients *b) |
| { |
| return ff_cie_xy_equal(a->r, b->r) && |
| ff_cie_xy_equal(a->g, b->g) && |
| ff_cie_xy_equal(a->b, b->b); |
| } |
| |
| enum { |
| FIELD_TOP, /* top/even rows, or progressive */ |
| FIELD_BOTTOM, /* bottom/odd rows */ |
| }; |
| |
| typedef struct SwsColor { |
| enum AVColorPrimaries prim; |
| enum AVColorTransferCharacteristic trc; |
| AVPrimaryCoefficients gamut; /* mastering display gamut */ |
| AVRational min_luma; /* minimum luminance in nits */ |
| AVRational max_luma; /* maximum luminance in nits */ |
| AVRational frame_peak; /* per-frame/scene peak luminance, or 0 */ |
| 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; |
| int interlaced; |
| enum AVPixelFormat format; |
| enum AVColorRange range; |
| enum AVColorSpace csp; |
| enum AVChromaLocation loc; |
| const AVPixFmtDescriptor *desc; /* convenience */ |
| SwsColor color; |
| } SwsFormat; |
| |
| static inline void ff_fmt_clear(SwsFormat *fmt) |
| { |
| *fmt = (SwsFormat) { |
| .format = AV_PIX_FMT_NONE, |
| .range = AVCOL_RANGE_UNSPECIFIED, |
| .csp = AVCOL_SPC_UNSPECIFIED, |
| .loc = AVCHROMA_LOC_UNSPECIFIED, |
| .color = { |
| .prim = AVCOL_PRI_UNSPECIFIED, |
| .trc = AVCOL_TRC_UNSPECIFIED, |
| }, |
| }; |
| } |
| |
| /** |
| * This function also sanitizes and strips the input data, removing irrelevant |
| * fields for certain formats. |
| */ |
| SwsFormat ff_fmt_from_frame(const AVFrame *frame, int field); |
| |
| static inline int ff_color_equal(const SwsColor *c1, const SwsColor *c2) |
| { |
| return c1->prim == c2->prim && |
| c1->trc == c2->trc && |
| ff_q_equal(c1->min_luma, c2->min_luma) && |
| ff_q_equal(c1->max_luma, c2->max_luma) && |
| ff_prim_equal(&c1->gamut, &c2->gamut); |
| } |
| |
| /* Tests only the static components of a colorspace, ignoring dimensions and per-frame data */ |
| static inline int ff_props_equal(const SwsFormat *fmt1, const SwsFormat *fmt2) |
| { |
| return fmt1->interlaced == fmt2->interlaced && |
| fmt1->format == fmt2->format && |
| fmt1->range == fmt2->range && |
| fmt1->csp == fmt2->csp && |
| fmt1->loc == fmt2->loc && |
| ff_color_equal(&fmt1->color, &fmt2->color); |
| } |
| |
| /* Tests only the static components of a colorspace, ignoring per-frame data */ |
| static inline int ff_fmt_equal(const SwsFormat *fmt1, const SwsFormat *fmt2) |
| { |
| return fmt1->width == fmt2->width && |
| fmt1->height == fmt2->height && |
| ff_props_equal(fmt1, fmt2); |
| } |
| |
| static inline int ff_fmt_align(enum AVPixelFormat fmt) |
| { |
| const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(fmt); |
| if (desc->flags & AV_PIX_FMT_FLAG_BAYER) { |
| return 2; |
| } else { |
| return 1 << desc->log2_chroma_h; |
| } |
| } |
| |
| int ff_test_fmt(const SwsFormat *fmt, int output); |
| |
| /* Returns true if the formats are incomplete, false otherwise */ |
| bool ff_infer_colors(SwsColor *src, SwsColor *dst); |
| |
| typedef struct SwsOpList SwsOpList; |
| typedef enum SwsPixelType SwsPixelType; |
| |
| /** |
| * Append a set of operations for decoding/encoding raw pixels. This will |
| * handle input read/write, swizzling, shifting and byte swapping. |
| * |
| * Returns 0 on success, or a negative error code on failure. |
| */ |
| int ff_sws_decode_pixfmt(SwsOpList *ops, enum AVPixelFormat fmt); |
| int ff_sws_encode_pixfmt(SwsOpList *ops, enum AVPixelFormat fmt); |
| |
| /** |
| * Append a set of operations for transforming decoded pixel values to/from |
| * normalized RGB in the specified gamut and pixel type. |
| * |
| * Returns 0 on success, or a negative error code on failure. |
| */ |
| int ff_sws_decode_colors(SwsContext *ctx, SwsPixelType type, SwsOpList *ops, |
| const SwsFormat fmt, bool *incomplete); |
| int ff_sws_encode_colors(SwsContext *ctx, SwsPixelType type, SwsOpList *ops, |
| const SwsFormat fmt, bool *incomplete); |
| |
| #endif /* SWSCALE_FORMAT_H */ |