PR #23125 opened by Lynne URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/23125 Patch URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/23125.patch
This completes the rendering pipeline for ProRes RAW. Output from the decoder is camera-specific until the side data is applied, after which it becomes a regular BT2020 linear. mpv/libplacebo will automatically tone-map down from however many stops of dynamic range the camera has to display. >From b1c03d706b414ee656453914fd6e9c449b3a222e Mon Sep 17 00:00:00 2001 From: Lynne <[email protected]> Date: Sat, 16 May 2026 17:40:14 +0900 Subject: [PATCH 1/3] lavu/frame: add camera raw codec side data Required to correctly present raw video. Codec-specific since I'd like to support ARRIRAW in the future, which has a different format. --- libavutil/Makefile | 2 + libavutil/frame.h | 7 ++ libavutil/raw_color_params.c | 47 +++++++++++ libavutil/raw_color_params.h | 158 +++++++++++++++++++++++++++++++++++ libavutil/side_data.c | 1 + libavutil/version.h | 2 +- 6 files changed, 216 insertions(+), 1 deletion(-) create mode 100644 libavutil/raw_color_params.c create mode 100644 libavutil/raw_color_params.h diff --git a/libavutil/Makefile b/libavutil/Makefile index b7d6e4906f..bb4c5cab64 100644 --- a/libavutil/Makefile +++ b/libavutil/Makefile @@ -76,6 +76,7 @@ HEADERS = adler32.h \ pixelutils.h \ pixfmt.h \ random_seed.h \ + raw_color_params.h \ rc4.h \ rational.h \ refstruct.h \ @@ -169,6 +170,7 @@ OBJS = adler32.o \ pixdesc.o \ pixelutils.o \ random_seed.o \ + raw_color_params.o \ rational.o \ refstruct.o \ reverse.o \ diff --git a/libavutil/frame.h b/libavutil/frame.h index e123668124..52adbc6288 100644 --- a/libavutil/frame.h +++ b/libavutil/frame.h @@ -292,6 +292,13 @@ enum AVFrameSideDataType { * and Formats standard. */ AV_FRAME_DATA_IAMF_RECON_GAIN_INFO_PARAM, + + /** + * Color information from a RAW camera codecs, needed to correctly process + * the video data. The payload is an AVRawColorParams struct defined in + * libavutil/raw_color_params.h. + */ + AV_FRAME_DATA_RAW_COLOR_PARAMS, }; enum AVActiveFormatDescription { diff --git a/libavutil/raw_color_params.c b/libavutil/raw_color_params.c new file mode 100644 index 0000000000..7b096fa793 --- /dev/null +++ b/libavutil/raw_color_params.c @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2026 Lynne <[email protected]> + * + * 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 + */ + +#include "raw_color_params.h" +#include "mem.h" + +AVRawColorParams *av_raw_color_params_alloc(size_t *size) +{ + AVRawColorParams *p = av_mallocz(sizeof(AVRawColorParams)); + if (!p) + return NULL; + + if (size) + *size = sizeof(*p); + + return p; +} + +AVRawColorParams *av_raw_color_params_create_side_data(AVFrame *frame) +{ + AVFrameSideData *side_data = + av_frame_new_side_data(frame, AV_FRAME_DATA_RAW_COLOR_PARAMS, + sizeof(AVRawColorParams)); + if (!side_data) + return NULL; + + memset(side_data->data, 0, side_data->size); + + return (AVRawColorParams *)side_data->data; +} diff --git a/libavutil/raw_color_params.h b/libavutil/raw_color_params.h new file mode 100644 index 0000000000..6fe5001b15 --- /dev/null +++ b/libavutil/raw_color_params.h @@ -0,0 +1,158 @@ +/* + * Copyright (c) 2026 Lynne <[email protected]> + * + * 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 AVUTIL_RAW_COLOR_PARAMS_H +#define AVUTIL_RAW_COLOR_PARAMS_H + +#include <stddef.h> +#include <stdint.h> + +#include "frame.h" +#include "pixfmt.h" +#include "rational.h" + +enum AVRawColorParamsType { + AV_RAW_COLOR_PARAMS_NONE = 0, + + /** + * The union is valid when interpreted as AVProResRawColorParams + * (codec.prores_raw). + */ + AV_RAW_COLOR_PARAMS_PRORES_RAW, +}; + +/** + * ProRes RAW per-frame color transform, parsed from the prrf frame header. + * + * The correct rendering pipeline is: + * -> (sample - black_level) / (white_level - black_level) + * -> per-channel white balance (wb_red, 1.0 for G, wb_blue) pre-debayer + * -> debayer + * -> color_matrix (camera RGB -> target primaries) + * -> gain (scene-linear scale) + * + * Black/white levels and the target primaries/transfer live on the outer + * AVRawColorParams. + * + * @note The struct must be allocated as part of AVRawColorParams using + * av_raw_color_params_alloc(). Its size is not a part of the public ABI. + */ +typedef struct AVProResRawColorParams { + /** + * White balance multiplier for the red channel, applied pre-debayer. + */ + AVRational wb_red; + + /** + * White balance multiplier for the blue channel, applied pre-debayer. + * (The green channel is implicit 1.0 for ProRes RAW) + */ + AVRational wb_blue; + + /** + * 3x3 row-major color matrix from camera RGB to the target primaries + * declared on the outer AVRawColorParams, applied post-debayer. + * out[i] = sum_j color_matrix[i][j] * in[j]. + */ + AVRational color_matrix[3][3]; + + /** + * Post-matrix scene-linear scaling factor. Encodes highlight headroom the + * encoder reserved; multiply the matrixed values by this to recover + * scene-linear light. + */ + AVRational gain; +} AVProResRawColorParams; + +/** + * Per-frame color information for a RAW camera codec. Carried as side data of + * type AV_FRAME_DATA_RAW_COLOR_PARAMS. + * + * The outer struct carries the fields every RAW codec exposes: the sensor's + * valid sample range, the target colorspace the codec-specific transform + * lands in, and the white-balance correlated color temperature. The codec + * union holds the codec-specific transform parameters; `type` selects which + * member of the union is valid. + * + * @note The struct must be allocated using av_raw_color_params_alloc() or + * av_raw_color_params_create_side_data(). Its size is not a part of the + * public ABI. + */ +typedef struct AVRawColorParams { + /** + * Selects which member of `codec` is valid. + */ + enum AVRawColorParamsType type; + + /** + * Lowest valid raw sample code (sensor black point) + */ + AVRational black_level; + + /** + * Highest valid raw sample code (sensor white point) + */ + AVRational white_level; + + /** + * Target color primaries the codec-specific transform lands in. The + * `color_matrix` (or equivalent) in the codec-specific struct converts + * camera RGB to these primaries. + */ + enum AVColorPrimaries primaries; + + /** + * Target transfer characteristic. Typically AVCOL_TRC_LINEAR, since codecs + * decode to scene-linear before any creative grading. + */ + enum AVColorTransferCharacteristic trc; + + /** + * Color temperature in Kelvin from with the camera's white balance. + * Informational; the math uses the codec-specific white-balance fields. + * 0 if not signaled. + */ + uint32_t wb_cct; + + /** + * Additional codec-specific fields. + */ + union { + AVProResRawColorParams prores_raw; + } codec; +} AVRawColorParams; + +/** + * Allocate an AVRawColorParams structure and zero-initialize it. + * + * @param size if non-NULL, set to sizeof(AVRawColorParams) + * @return the newly allocated struct or NULL on failure + */ +AVRawColorParams *av_raw_color_params_alloc(size_t *size); + +/** + * Allocate and add an AVRawColorParams structure to an existing AVFrame as + * AV_FRAME_DATA_RAW_COLOR_PARAMS side data. + * + * @return the newly allocated struct, or NULL on failure + */ +AVRawColorParams *av_raw_color_params_create_side_data(AVFrame *frame); + +#endif /* AVUTIL_RAW_COLOR_PARAMS_H */ diff --git a/libavutil/side_data.c b/libavutil/side_data.c index 64c4220ed9..762bc59d53 100644 --- a/libavutil/side_data.c +++ b/libavutil/side_data.c @@ -61,6 +61,7 @@ static const AVSideDataDescriptor sd_props[] = { [AV_FRAME_DATA_IAMF_MIX_GAIN_PARAM] = { "IAMF Mix Gain Parameter Data" }, [AV_FRAME_DATA_IAMF_DEMIXING_INFO_PARAM] = { "IAMF Demixing Info Parameter Data", AV_SIDE_DATA_PROP_CHANNEL_DEPENDENT }, [AV_FRAME_DATA_IAMF_RECON_GAIN_INFO_PARAM] = { "IAMF Recon Gain Info Parameter Data" }, + [AV_FRAME_DATA_RAW_COLOR_PARAMS] = { "RAW camera color parameters", AV_SIDE_DATA_PROP_GLOBAL | AV_SIDE_DATA_PROP_COLOR_DEPENDENT }, }; const AVSideDataDescriptor *av_frame_side_data_desc(enum AVFrameSideDataType type) diff --git a/libavutil/version.h b/libavutil/version.h index 07c47da803..e7aeab9995 100644 --- a/libavutil/version.h +++ b/libavutil/version.h @@ -79,7 +79,7 @@ */ #define LIBAVUTIL_VERSION_MAJOR 60 -#define LIBAVUTIL_VERSION_MINOR 31 +#define LIBAVUTIL_VERSION_MINOR 32 #define LIBAVUTIL_VERSION_MICRO 100 #define LIBAVUTIL_VERSION_INT AV_VERSION_INT(LIBAVUTIL_VERSION_MAJOR, \ -- 2.52.0 >From 53e805df9d03cc80c7cd1f8c2f78530c9fd5fddd Mon Sep 17 00:00:00 2001 From: Lynne <[email protected]> Date: Sat, 16 May 2026 17:40:35 +0900 Subject: [PATCH 2/3] prores_raw: export raw camera color data values --- libavcodec/prores_raw.c | 43 +++++++++++++++++++++++++++++++++++------ 1 file changed, 37 insertions(+), 6 deletions(-) diff --git a/libavcodec/prores_raw.c b/libavcodec/prores_raw.c index f386b22496..1ffabdba92 100644 --- a/libavcodec/prores_raw.c +++ b/libavcodec/prores_raw.c @@ -21,9 +21,12 @@ */ #include "libavutil/avassert.h" +#include "libavutil/intfloat.h" #include "libavutil/intreadwrite.h" #include "libavutil/mem_internal.h" #include "libavutil/mem.h" +#include "libavutil/raw_color_params.h" +#include "libavutil/rational.h" #define CACHED_BITSTREAM_READER !ARCH_X86_32 @@ -417,12 +420,22 @@ static int decode_frame(AVCodecContext *avctx, return AVERROR_PATCHWELCOME; } - bytestream2_skip(&gb_hdr, 2); /* senselValueRange (white_level = value + 0x100, black_level = 0x100) */ - bytestream2_skip(&gb_hdr, 4); /* WhiteBalanceRedFactor (float, pre-debayer R gain) */ - bytestream2_skip(&gb_hdr, 4); /* WhiteBalanceBlueFactor (float, pre-debayer B gain) */ - bytestream2_skip(&gb_hdr, 4 * 3 * 3); /* ColorMatrix (3x3 float, camera RGB -> Rec.2020 linear, row-major) */ - bytestream2_skip(&gb_hdr, 4); /* GainFactor (float, post-matrix scene-linear scale) */ - bytestream2_skip(&gb_hdr, 2); /* WhiteBalanceCCT (Kelvin, informational) */ + /* senselValueRange: black_level is hardcoded to 0x100, + * white_level = senselValueRange + 0x100 */ + uint16_t black_level = 0x100; + uint16_t white_level = bytestream2_get_be16(&gb_hdr) + 0x100; + + float wb_red = av_int2float(bytestream2_get_be32(&gb_hdr)); /* WhiteBalanceRedFactor */ + float wb_blue = av_int2float(bytestream2_get_be32(&gb_hdr)); /* WhiteBalanceBlueFactor */ + + /* ColorMatrix (3x3 float, camera RGB -> Rec.2020 linear, row-major) */ + float color_matrix[3][3]; + for (int r = 0; r < 3; r++) + for (int c = 0; c < 3; c++) + color_matrix[r][c] = av_int2float(bytestream2_get_be32(&gb_hdr)); + + float gain = av_int2float(bytestream2_get_be32(&gb_hdr)); /* GainFactor (post-matrix mult) */ + uint16_t wb_cct = bytestream2_get_be16(&gb_hdr); /* WhiteBalanceCCT (Kelvin, informational) */ /* Flags */ int flags = bytestream2_get_be16(&gb_hdr); @@ -532,6 +545,24 @@ static int decode_frame(AVCodecContext *avctx, frame->pict_type = AV_PICTURE_TYPE_I; frame->flags |= AV_FRAME_FLAG_KEY; + AVRawColorParams *rcp = av_raw_color_params_create_side_data(frame); + if (!rcp) + return AVERROR(ENOMEM); + rcp->type = AV_RAW_COLOR_PARAMS_PRORES_RAW; + rcp->black_level = av_make_q(black_level, 65535); + rcp->white_level = av_make_q(white_level, 65535); + rcp->wb_cct = av_make_q(wb_cct, 65535); + rcp->primaries = AVCOL_PRI_BT2020; + rcp->trc = AVCOL_TRC_LINEAR; + + AVProResRawColorParams *pr = &rcp->codec.prores_raw; + pr->wb_red = av_d2q(wb_red); + pr->wb_blue = av_d2q(wb_blue); + pr->gain = av_d2q(gain); + for (int r = 0; r < 3; r++) + for (int c = 0; c < 3; c++) + pr->color_matrix[r][c] = av_d2q(color_matrix[r][c]); + *got_frame_ptr = 1; return avpkt->size; -- 2.52.0 >From 5c1969240186ebbb1fad6c60f30a5cf17cd91227 Mon Sep 17 00:00:00 2001 From: Lynne <[email protected]> Date: Sat, 16 May 2026 16:42:04 +0900 Subject: [PATCH 3/3] scale_vulkan: apply camera raw data --- libavfilter/vf_scale_vulkan.c | 76 ++++++++++++++++++++++-- libavfilter/vulkan/debayer.comp.glsl | 88 +++++++++++++++++++--------- 2 files changed, 130 insertions(+), 34 deletions(-) diff --git a/libavfilter/vf_scale_vulkan.c b/libavfilter/vf_scale_vulkan.c index 19b4e5e5ac..0fc01a9638 100644 --- a/libavfilter/vf_scale_vulkan.c +++ b/libavfilter/vf_scale_vulkan.c @@ -18,8 +18,10 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ +#include "libavutil/mastering_display_metadata.h" #include "libavutil/random_seed.h" #include "libavutil/opt.h" +#include "libavutil/raw_color_params.h" #include "libavutil/vulkan_spirv.h" #include "vulkan_filter.h" #include "scale_eval.h" @@ -55,13 +57,19 @@ typedef struct ScaleVulkanContext { FFVulkanShader shd; VkSampler sampler; - /* Push constants / options */ struct { - float yuv_matrix[4][4]; + float matrix[4][4]; int crop_x; int crop_y; int crop_w; int crop_h; + + /* RAW camera color processing (debayering only) */ + float wb_red; + float wb_blue; + float gain; + float black_level_norm; + float inv_range; } opts; char *out_format_string; @@ -191,8 +199,8 @@ static int init_scale_shader(AVFilterContext *ctx, FFVulkanShader *shd, for (int y = 0; y < 3; y++) for (int x = 0; x < 3; x++) - s->opts.yuv_matrix[x][y] = tmp_mat[x][y]; - s->opts.yuv_matrix[3][3] = 1.0; + s->opts.matrix[x][y] = tmp_mat[x][y]; + s->opts.matrix[3][3] = 1.0; } return 0; @@ -268,6 +276,11 @@ static av_cold int init_filter(AVFilterContext *ctx, AVFrame *in) GLSLC(1, int crop_y; ); GLSLC(1, int crop_w; ); GLSLC(1, int crop_h; ); + GLSLC(1, float wb_red; ); + GLSLC(1, float wb_blue; ); + GLSLC(1, float gain; ); + GLSLC(1, float black_level_norm; ); + GLSLC(1, float inv_range; ); GLSLC(0, }; ); GLSLC(0, ); @@ -363,6 +376,59 @@ static int scale_vulkan_filter_frame(AVFilterLink *link, AVFrame *in) if (err < 0) goto fail; + if (s->vkctx.input_format == AV_PIX_FMT_BAYER_RGGB16) { + memset(s->opts.matrix, 0, sizeof(s->opts.matrix)); + s->opts.matrix[0][0] = 1.0f; + s->opts.matrix[1][1] = 1.0f; + s->opts.matrix[2][2] = 1.0f; + s->opts.matrix[3][3] = 1.0f; + s->opts.wb_red = 1.0f; + s->opts.wb_blue = 1.0f; + s->opts.gain = 1.0f; + s->opts.black_level_norm = 0.0f; + s->opts.inv_range = 1.0f; + + AVFrameSideData *sd = av_frame_get_side_data(in, AV_FRAME_DATA_RAW_COLOR_PARAMS); + if (sd) { + const AVRawColorParams *rcp = (const AVRawColorParams *)sd->data; + if (rcp->type == AV_RAW_COLOR_PARAMS_PRORES_RAW) { + const AVProResRawColorParams *pr = &rcp->codec.prores_raw; + + for (int r = 0; r < 3; r++) + for (int c = 0; c < 3; c++) + s->opts.matrix[r][c] = av_q2d(pr->color_matrix[r][c]); + s->opts.wb_red = av_q2d(pr->wb_red); + s->opts.wb_blue = av_q2d(pr->wb_blue); + s->opts.gain = av_q2d(pr->gain); + float black = av_q2d(rcp->black_level); + float white = av_q2d(rcp->white_level); + s->opts.black_level_norm = black; + s->opts.inv_range = 1.0 / (white - black); + + out->color_primaries = rcp->primaries; + out->color_trc = rcp->trc; + out->colorspace = AVCOL_SPC_RGB; + out->color_range = AVCOL_RANGE_JPEG; + + av_frame_side_data_remove(&out->side_data, &out->nb_side_data, + AV_FRAME_DATA_RAW_COLOR_PARAMS); + + /* Tag the source as HDR. + * Sensor headroom is pr->gain times above the 203 nits + * SDR reference white */ + AVMasteringDisplayMetadata *mdm = + av_mastering_display_metadata_create_side_data(out); + if (!mdm) + return AVERROR(ENOMEM); + + mdm->max_luminance = av_mul_q(pr->gain, + av_make_q(203, 1)); + mdm->min_luminance = av_make_q(1, 10000); + mdm->has_luminance = 1; + } + } + } + if (out->width != in->width || out->height != in->height) { av_frame_side_data_remove_by_props(&out->side_data, &out->nb_side_data, AV_SIDE_DATA_PROP_SIZE_DEPENDENT); @@ -440,7 +506,7 @@ static int scale_vulkan_config_output(AVFilterLink *outlink) if (s->vkctx.input_format == AV_PIX_FMT_BAYER_RGGB16) { if (s->vkctx.output_format == s->vkctx.input_format) { - s->vkctx.output_format = AV_PIX_FMT_RGBA64; + s->vkctx.output_format = AV_PIX_FMT_RGBAF16; } else if (!ff_vk_mt_is_np_rgb(s->vkctx.output_format)) { av_log(avctx, AV_LOG_ERROR, "Unsupported output format for debayer\n"); return AVERROR(EINVAL); diff --git a/libavfilter/vulkan/debayer.comp.glsl b/libavfilter/vulkan/debayer.comp.glsl index 0a4e22de99..264b2b37db 100644 --- a/libavfilter/vulkan/debayer.comp.glsl +++ b/libavfilter/vulkan/debayer.comp.glsl @@ -22,6 +22,7 @@ #pragma shader_stage(compute) #extension GL_EXT_shader_image_load_formatted : require +#extension GL_EXT_scalar_block_layout : require layout (local_size_x_id = 253, local_size_y_id = 254, local_size_z_id = 255) in; @@ -30,90 +31,119 @@ layout (set = 0, binding = 1) uniform writeonly image2D dst; layout (constant_id = 0) const int debayer_mode = 0; -layout(push_constant, std430) uniform pushConstants { - mat4 yuv_matrix; +layout(push_constant, scalar) uniform pushConstants { + mat4 rgb_matrix; int crop_x; int crop_y; int crop_w; int crop_h; + float wb_red; + float wb_blue; + float gain; + float black_level_norm; + float inv_range; }; -#define LD(xo, yo) \ - (imageLoad(src, pos + ivec2((xo), (yo))).r) +/* Read a sample, apply black-level, normalize, and apply white balance. + * Mirrored coords. */ +float ld_at(ivec2 base, int xo, int yo) +{ + ivec2 p = base + ivec2(xo, yo); + ivec2 cmin = ivec2(crop_x, crop_y); + ivec2 cmax = ivec2(crop_x + crop_w - 1, crop_y + crop_h - 1); + p = mix(p, 2*cmin - p, lessThan(p, cmin)); + p = mix(p, 2*cmax - p, greaterThan(p, cmax)); + + float v = imageLoad(src, p).r; + v = max(v - black_level_norm, 0.0) * inv_range; + + bool x_odd = (p.x & 1) != 0; + bool y_odd = (p.y & 1) != 0; + float wb = x_odd == y_odd ? (x_odd ? wb_blue : wb_red) : 1.0; + return v * wb; +} + +#define LD(xo, yo) ld_at(pos, (xo), (yo)) + +void write(ivec2 pos, vec4 c) +{ + /* Apply RGB conversion matrix */ + c.rgb = (c.rgb * mat3(rgb_matrix)) * gain; + imageStore(dst, pos, c); +} void debayer_bilinear(ivec2 pos) { /* R basis */ - vec4 tl = vec4(LD(0, 0), + write(pos, + vec4(LD(0, 0), (LD(1, 0) + LD(-1, 0) + LD(0, 1) + LD(0, -1)) / 4.0f, (LD(-1, -1) + LD(1, 1) + LD(-1, 1) + LD(1, -1)) / 4.0f, - 1.0f); - imageStore(dst, pos, tl); + 1.0f)); /* G1 basis */ - vec4 tr = vec4((LD(2, 0) + LD(0, 0)) / 2.0f, + write(pos + ivec2(1, 0), + vec4((LD(2, 0) + LD(0, 0)) / 2.0f, LD(1, 0), (LD(1, 1) + LD(1, -1)) / 2.0f, - 1.0f); - imageStore(dst, pos + ivec2(1, 0), tr); + 1.0f)); /* G2 basis */ - vec4 bl = vec4((LD(0, 2) + LD(0, 0)) / 2.0f, + write(pos + ivec2(0, 1), + vec4((LD(0, 2) + LD(0, 0)) / 2.0f, LD(0, 1), (LD(1, 1) + LD(-1, 1)) / 2.0f, - 1.0f); - imageStore(dst, pos + ivec2(0, 1), bl); + 1.0f)); /* B basis */ - vec4 br = vec4((LD(0, 0) + LD(2, 2) + LD(0, 2) + LD(2, 0)) / 4.0f, + write(pos + ivec2(1, 1), + vec4((LD(0, 0) + LD(2, 2) + LD(0, 2) + LD(2, 0)) / 4.0f, (LD(2, 1) + LD(0, 1) + LD(1, 2) + LD(1, 0)) / 4.0f, LD(1, 1), - 1.0f); - imageStore(dst, pos + ivec2(1, 1), br); + 1.0f)); } void debayer_bilinear_hq(ivec2 pos) { /* R basis */ - vec4 tl = vec4(LD(0, 0), + write(pos, + vec4(LD(0, 0), (4.0f*LD(0, 0) + 2.0f*(LD(0, -1) + LD(0, 1) + LD(-1, 0) + LD(1, 0)) - (LD(0, -2) + LD(0, 2) + LD(-2, 0) + LD(2, 0))) / 8.0f, (12.0f*LD(0, 0) + 4.0f*(LD(-1, -1) + LD(-1, 1) + LD(1, -1) + LD(1, 1)) - 3.0f*(LD(0, -2) + LD(0, 2) + LD(-2, 0) + LD(2, 0))) / 16.0f, - 1.0f); - imageStore(dst, pos, tl); + 1.0f)); /* G1 basis */ - vec4 tr = vec4((10.0f*LD(1, 0) + 8.0f*(LD(0, 0) + LD(2, 0)) - + write(pos + ivec2(1, 0), + vec4((10.0f*LD(1, 0) + 8.0f*(LD(0, 0) + LD(2, 0)) - 2.0f*(LD(0, -1) + LD(2, 1) + LD(0, 1) + LD(2, -1) + LD(-1, 0) + LD(3, 0)) + LD(1, -2) + LD(1, 2)) / 16.0f, LD(1, 0), (10.0f*LD(1, 0) + 8.0f*(LD(1, -1) + LD(1, 1)) - 2.0f*(LD(0, -1) + LD(0, 1) + LD(2, -1) + LD(2, 1) + LD(1, -2) + LD(1, 2)) + LD(-1, 0) + LD(3, 0)) / 16.0f, - 1.0f); - imageStore(dst, pos + ivec2(1, 0), tr); - + 1.0f)); /* G2 basis */ - vec4 bl = vec4((10.0f*LD(0, 1) + 8.0f*(LD(0, 0) + LD(0, 2)) - + write(pos + ivec2(0, 1), + vec4((10.0f*LD(0, 1) + 8.0f*(LD(0, 0) + LD(0, 2)) - 2.0f*(LD(-1, 0) + LD(-1, 2) + LD(1, 0) + LD(1, 2) + LD(0, -1) + LD(0, 3)) + LD(-2, 1) + LD(2, 1)) / 16.0f, LD(0, 1), (10.0f*LD(0, 1) + 8.0f*(LD(-1, 1) + LD(1, 1)) - 2.0f*(LD(-1, 0) + LD(1, 2) + LD(-1, 2) + LD(1, 0) + LD(-2, 1) + LD(2, 1)) + LD(0, -1) + LD(0, 3)) / 16.0f, - 1.0f); - imageStore(dst, pos + ivec2(0, 1), bl); + 1.0f)); /* B basis */ - vec4 br = vec4((12.0f*LD(1, 1) + 4.0f*(LD(0, 0) + LD(0, 2) + LD(2, 0) + LD(2, 2)) - + write(pos + ivec2(1, 1), + vec4((12.0f*LD(1, 1) + 4.0f*(LD(0, 0) + LD(0, 2) + LD(2, 0) + LD(2, 2)) - 3.0f*(LD(1, -1) + LD(1, 3) + LD(-1, 1) + LD(3, 1))) / 16.0f, (4.0f*LD(1, 1) + 2.0f*(LD(1, 0) + LD(1, 2) + LD(0, 1) + LD(2, 1)) - (LD(1, -1) + LD(1, 3) + LD(-1, 1) + LD(3, 1))) / 8.0f, LD(1, 1), - 1.0f); - imageStore(dst, pos + ivec2(1, 1), br); + 1.0f)); } void main(void) -- 2.52.0 _______________________________________________ ffmpeg-devel mailing list -- [email protected] To unsubscribe send an email to [email protected]
