Git Inbox Mirror of the ffmpeg-devel mailing list - see https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
 help / color / mirror / Atom feed
From: IndecisiveTurtle via ffmpeg-devel <ffmpeg-devel@ffmpeg.org>
To: ffmpeg-devel@ffmpeg.org
Cc: IndecisiveTurtle <geoster3d@gmail.com>
Subject: [FFmpeg-devel] [PATCH 2/3] lavc: Split out common components used by vulkan prores encoder
Date: Thu,  4 Sep 2025 23:10:01 +0300
Message-ID: <20250904201002.10446-2-47210458+raphaelthegreat@users.noreply.github.com> (raw)
In-Reply-To: <20250904201002.10446-1-47210458+raphaelthegreat@users.noreply.github.com>

From: IndecisiveTurtle <geoster3d@gmail.com>

---
 libavcodec/Makefile                  |   2 +-
 libavcodec/proresenc_kostya.c        | 414 +--------------------------
 libavcodec/proresenc_kostya_common.c | 364 +++++++++++++++++++++++
 libavcodec/proresenc_kostya_common.h | 131 +++++++++
 4 files changed, 511 insertions(+), 400 deletions(-)
 create mode 100644 libavcodec/proresenc_kostya_common.c
 create mode 100644 libavcodec/proresenc_kostya_common.h

diff --git a/libavcodec/Makefile b/libavcodec/Makefile
index 3d036de4b6..d8e1ac5a54 100644
--- a/libavcodec/Makefile
+++ b/libavcodec/Makefile
@@ -638,7 +638,7 @@ OBJS-$(CONFIG_PPM_ENCODER)             += pnmenc.o
 OBJS-$(CONFIG_PRORES_DECODER)          += proresdec.o proresdsp.o proresdata.o
 OBJS-$(CONFIG_PRORES_ENCODER)          += proresenc_anatoliy.o proresdata.o
 OBJS-$(CONFIG_PRORES_AW_ENCODER)       += proresenc_anatoliy.o proresdata.o
-OBJS-$(CONFIG_PRORES_KS_ENCODER)       += proresenc_kostya.o proresdata.o
+OBJS-$(CONFIG_PRORES_KS_ENCODER)       += proresenc_kostya.o proresdata.o proresenc_kostya_common.o
 OBJS-$(CONFIG_PRORES_RAW_DECODER)      += prores_raw.o proresdsp.o proresdata.o
 OBJS-$(CONFIG_PRORES_VIDEOTOOLBOX_ENCODER) += videotoolboxenc.o
 OBJS-$(CONFIG_PROSUMER_DECODER)        += prosumer.o
diff --git a/libavcodec/proresenc_kostya.c b/libavcodec/proresenc_kostya.c
index b98bc5c195..31d22a14ac 100644
--- a/libavcodec/proresenc_kostya.c
+++ b/libavcodec/proresenc_kostya.c
@@ -33,179 +33,7 @@
 #include "profiles.h"
 #include "bytestream.h"
 #include "proresdata.h"
-
-#define CFACTOR_Y422 2
-#define CFACTOR_Y444 3
-
-#define MAX_MBS_PER_SLICE 8
-
-#define MAX_PLANES 4
-
-enum {
-    PRORES_PROFILE_AUTO  = -1,
-    PRORES_PROFILE_PROXY = 0,
-    PRORES_PROFILE_LT,
-    PRORES_PROFILE_STANDARD,
-    PRORES_PROFILE_HQ,
-    PRORES_PROFILE_4444,
-    PRORES_PROFILE_4444XQ,
-};
-
-enum {
-    QUANT_MAT_PROXY = 0,
-    QUANT_MAT_PROXY_CHROMA,
-    QUANT_MAT_LT,
-    QUANT_MAT_STANDARD,
-    QUANT_MAT_HQ,
-    QUANT_MAT_XQ_LUMA,
-    QUANT_MAT_DEFAULT,
-};
-
-static const uint8_t prores_quant_matrices[][64] = {
-    { // proxy
-         4,  7,  9, 11, 13, 14, 15, 63,
-         7,  7, 11, 12, 14, 15, 63, 63,
-         9, 11, 13, 14, 15, 63, 63, 63,
-        11, 11, 13, 14, 63, 63, 63, 63,
-        11, 13, 14, 63, 63, 63, 63, 63,
-        13, 14, 63, 63, 63, 63, 63, 63,
-        13, 63, 63, 63, 63, 63, 63, 63,
-        63, 63, 63, 63, 63, 63, 63, 63,
-    },
-    { // proxy chromas
-        4,  7,  9, 11, 13, 14, 63, 63,
-        7,  7, 11, 12, 14, 63, 63, 63,
-        9, 11, 13, 14, 63, 63, 63, 63,
-        11, 11, 13, 14, 63, 63, 63, 63,
-        11, 13, 14, 63, 63, 63, 63, 63,
-        13, 14, 63, 63, 63, 63, 63, 63,
-        13, 63, 63, 63, 63, 63, 63, 63,
-        63, 63, 63, 63, 63, 63, 63, 63
-    },
-    { // LT
-         4,  5,  6,  7,  9, 11, 13, 15,
-         5,  5,  7,  8, 11, 13, 15, 17,
-         6,  7,  9, 11, 13, 15, 15, 17,
-         7,  7,  9, 11, 13, 15, 17, 19,
-         7,  9, 11, 13, 14, 16, 19, 23,
-         9, 11, 13, 14, 16, 19, 23, 29,
-         9, 11, 13, 15, 17, 21, 28, 35,
-        11, 13, 16, 17, 21, 28, 35, 41,
-    },
-    { // standard
-         4,  4,  5,  5,  6,  7,  7,  9,
-         4,  4,  5,  6,  7,  7,  9,  9,
-         5,  5,  6,  7,  7,  9,  9, 10,
-         5,  5,  6,  7,  7,  9,  9, 10,
-         5,  6,  7,  7,  8,  9, 10, 12,
-         6,  7,  7,  8,  9, 10, 12, 15,
-         6,  7,  7,  9, 10, 11, 14, 17,
-         7,  7,  9, 10, 11, 14, 17, 21,
-    },
-    { // high quality
-         4,  4,  4,  4,  4,  4,  4,  4,
-         4,  4,  4,  4,  4,  4,  4,  4,
-         4,  4,  4,  4,  4,  4,  4,  4,
-         4,  4,  4,  4,  4,  4,  4,  5,
-         4,  4,  4,  4,  4,  4,  5,  5,
-         4,  4,  4,  4,  4,  5,  5,  6,
-         4,  4,  4,  4,  5,  5,  6,  7,
-         4,  4,  4,  4,  5,  6,  7,  7,
-    },
-    { // XQ luma
-        2,  2,  2,  2,  2,  2,  2,  2,
-        2,  2,  2,  2,  2,  2,  2,  2,
-        2,  2,  2,  2,  2,  2,  2,  2,
-        2,  2,  2,  2,  2,  2,  2,  3,
-        2,  2,  2,  2,  2,  2,  3,  3,
-        2,  2,  2,  2,  2,  3,  3,  3,
-        2,  2,  2,  2,  3,  3,  3,  4,
-        2,  2,  2,  2,  3,  3,  4,  4,
-    },
-    { // codec default
-         4,  4,  4,  4,  4,  4,  4,  4,
-         4,  4,  4,  4,  4,  4,  4,  4,
-         4,  4,  4,  4,  4,  4,  4,  4,
-         4,  4,  4,  4,  4,  4,  4,  4,
-         4,  4,  4,  4,  4,  4,  4,  4,
-         4,  4,  4,  4,  4,  4,  4,  4,
-         4,  4,  4,  4,  4,  4,  4,  4,
-         4,  4,  4,  4,  4,  4,  4,  4,
-    },
-};
-
-#define NUM_MB_LIMITS 4
-static const int prores_mb_limits[NUM_MB_LIMITS] = {
-    1620, // up to 720x576
-    2700, // up to 960x720
-    6075, // up to 1440x1080
-    9216, // up to 2048x1152
-};
-
-static const struct prores_profile {
-    const char *full_name;
-    uint32_t    tag;
-    int         min_quant;
-    int         max_quant;
-    int         br_tab[NUM_MB_LIMITS];
-    int         quant;
-    int         quant_chroma;
-} prores_profile_info[6] = {
-    {
-        .full_name = "proxy",
-        .tag       = MKTAG('a', 'p', 'c', 'o'),
-        .min_quant = 4,
-        .max_quant = 8,
-        .br_tab    = { 300, 242, 220, 194 },
-        .quant     = QUANT_MAT_PROXY,
-        .quant_chroma = QUANT_MAT_PROXY_CHROMA,
-    },
-    {
-        .full_name = "LT",
-        .tag       = MKTAG('a', 'p', 'c', 's'),
-        .min_quant = 1,
-        .max_quant = 9,
-        .br_tab    = { 720, 560, 490, 440 },
-        .quant     = QUANT_MAT_LT,
-        .quant_chroma = QUANT_MAT_LT,
-    },
-    {
-        .full_name = "standard",
-        .tag       = MKTAG('a', 'p', 'c', 'n'),
-        .min_quant = 1,
-        .max_quant = 6,
-        .br_tab    = { 1050, 808, 710, 632 },
-        .quant     = QUANT_MAT_STANDARD,
-        .quant_chroma = QUANT_MAT_STANDARD,
-    },
-    {
-        .full_name = "high quality",
-        .tag       = MKTAG('a', 'p', 'c', 'h'),
-        .min_quant = 1,
-        .max_quant = 6,
-        .br_tab    = { 1566, 1216, 1070, 950 },
-        .quant     = QUANT_MAT_HQ,
-        .quant_chroma = QUANT_MAT_HQ,
-    },
-    {
-        .full_name = "4444",
-        .tag       = MKTAG('a', 'p', '4', 'h'),
-        .min_quant = 1,
-        .max_quant = 6,
-        .br_tab    = { 2350, 1828, 1600, 1425 },
-        .quant     = QUANT_MAT_HQ,
-        .quant_chroma = QUANT_MAT_HQ,
-    },
-    {
-        .full_name = "4444XQ",
-        .tag       = MKTAG('a', 'p', '4', 'x'),
-        .min_quant = 1,
-        .max_quant = 6,
-        .br_tab    = { 3525, 2742, 2400, 2137 },
-        .quant     = QUANT_MAT_HQ, /* Fix me : use QUANT_MAT_XQ_LUMA */
-        .quant_chroma = QUANT_MAT_HQ,
-    }
-};
+#include "proresenc_kostya_common.h"
 
 #define TRELLIS_WIDTH 16
 #define SCORE_LIMIT   INT_MAX / 2
@@ -217,8 +45,6 @@ struct TrellisNode {
     int score;
 };
 
-#define MAX_STORED_Q 16
-
 typedef struct ProresThreadData {
     DECLARE_ALIGNED(16, int16_t, blocks)[MAX_PLANES][64 * 4 * MAX_MBS_PER_SLICE];
     DECLARE_ALIGNED(16, uint16_t, emu_buf)[16 * 16];
@@ -227,49 +53,6 @@ typedef struct ProresThreadData {
     struct TrellisNode *nodes;
 } ProresThreadData;
 
-typedef struct ProresContext {
-    AVClass *class;
-    DECLARE_ALIGNED(16, int16_t, blocks)[MAX_PLANES][64 * 4 * MAX_MBS_PER_SLICE];
-    DECLARE_ALIGNED(16, uint16_t, emu_buf)[16*16];
-    int16_t quants[MAX_STORED_Q][64];
-    int16_t quants_chroma[MAX_STORED_Q][64];
-    int16_t custom_q[64];
-    int16_t custom_chroma_q[64];
-    const uint8_t *quant_mat;
-    const uint8_t *quant_chroma_mat;
-    const uint8_t *scantable;
-
-    void (*fdct)(FDCTDSPContext *fdsp, const uint16_t *src,
-                 ptrdiff_t linesize, int16_t *block);
-    FDCTDSPContext fdsp;
-
-    const AVFrame *pic;
-    int mb_width, mb_height;
-    int mbs_per_slice;
-    int num_chroma_blocks, chroma_factor;
-    int slices_width;
-    int slices_per_picture;
-    int pictures_per_frame; // 1 for progressive, 2 for interlaced
-    int cur_picture_idx;
-    int num_planes;
-    int bits_per_mb;
-    int force_quant;
-    int alpha_bits;
-    int warn;
-
-    char *vendor;
-    int quant_sel;
-
-    int frame_size_upper_bound;
-
-    int profile;
-    const struct prores_profile *profile_info;
-
-    int *slice_q;
-
-    ProresThreadData *tdata;
-} ProresContext;
-
 static void get_slice_data(ProresContext *ctx, const uint16_t *src,
                            ptrdiff_t linesize, int x, int y, int w, int h,
                            int16_t *blocks, uint16_t *emu_buf,
@@ -369,6 +152,8 @@ static void get_alpha_data(ProresContext *ctx, const uint16_t *src,
     }
 }
 
+int slice = 0;
+
 /**
  * Write an unsigned rice/exp golomb codeword.
  */
@@ -437,7 +222,6 @@ static void encode_acs(PutBitContext *pb, int16_t *blocks,
     int prev_level = 2;
     int run = 0, level;
     int max_coeffs, abs_level;
-
     max_coeffs = blocks_per_slice << 6;
 
     for (i = 1; i < 64; i++) {
@@ -685,7 +469,6 @@ static int estimate_acs(int *error, int16_t *blocks, int blocks_per_slice,
                 bits += estimate_vlc(ff_prores_run_to_cb[prev_run], run);
                 bits += estimate_vlc(ff_prores_level_to_cb[prev_level],
                                      abs_level - 1) + 1;
-
                 prev_run   = FFMIN(run, 15);
                 prev_level = FFMIN(abs_level, 9);
                 run    = 0;
@@ -905,7 +688,6 @@ static int find_slice_quant(AVCodecContext *avctx,
 
         for (q = min_quant; q < max_quant + 2; q++) {
             cur = trellis_node + q;
-
             bits  = td->nodes[prev].bits + slice_bits[q];
             error = slice_score[q];
             if (bits > bits_limit)
@@ -965,67 +747,33 @@ static int encode_frame(AVCodecContext *avctx, AVPacket *pkt,
                         const AVFrame *pic, int *got_packet)
 {
     ProresContext *ctx = avctx->priv_data;
-    uint8_t *orig_buf, *buf, *slice_hdr, *slice_sizes, *tmp;
+    uint8_t *orig_buf, *buf, *slice_hdr, *slice_sizes;
     uint8_t *picture_size_pos;
     PutBitContext pb;
     int x, y, i, mb, q = 0;
     int sizes[4] = { 0 };
-    int slice_hdr_size = 2 + 2 * (ctx->num_planes - 1);
+    int slice_hdr_size = 2 * ctx->num_planes;
     int frame_size, picture_size, slice_size;
     int pkt_size, ret;
     int max_slice_size = (ctx->frame_size_upper_bound - 200) / (ctx->pictures_per_frame * ctx->slices_per_picture + 1);
-    uint8_t frame_flags;
+    pkt_size = ctx->frame_size_upper_bound;
 
     ctx->pic = pic;
-    pkt_size = ctx->frame_size_upper_bound;
 
     if ((ret = ff_alloc_packet(avctx, pkt, pkt_size + FF_INPUT_BUFFER_MIN_SIZE)) < 0)
         return ret;
 
     orig_buf = pkt->data;
-
-    // frame atom
-    orig_buf += 4;                              // frame size
-    bytestream_put_be32  (&orig_buf, FRAME_ID); // frame container ID
-    buf = orig_buf;
-
-    // frame header
-    tmp = buf;
-    buf += 2;                                   // frame header size will be stored here
-    bytestream_put_be16  (&buf, ctx->chroma_factor != CFACTOR_Y422 || ctx->alpha_bits ? 1 : 0);
-    bytestream_put_buffer(&buf, ctx->vendor, 4);
-    bytestream_put_be16  (&buf, avctx->width);
-    bytestream_put_be16  (&buf, avctx->height);
-
-    frame_flags = ctx->chroma_factor << 6;
-    if (avctx->flags & AV_CODEC_FLAG_INTERLACED_DCT)
-        frame_flags |= (pic->flags & AV_FRAME_FLAG_TOP_FIELD_FIRST) ? 0x04 : 0x08;
-    bytestream_put_byte  (&buf, frame_flags);
-
-    bytestream_put_byte  (&buf, 0);             // reserved
-    bytestream_put_byte  (&buf, pic->color_primaries);
-    bytestream_put_byte  (&buf, pic->color_trc);
-    bytestream_put_byte  (&buf, pic->colorspace);
-    bytestream_put_byte  (&buf, ctx->alpha_bits >> 3);
-    bytestream_put_byte  (&buf, 0);             // reserved
-    if (ctx->quant_sel != QUANT_MAT_DEFAULT) {
-        bytestream_put_byte  (&buf, 0x03);      // matrix flags - both matrices are present
-        bytestream_put_buffer(&buf, ctx->quant_mat, 64);        // luma quantisation matrix
-        bytestream_put_buffer(&buf, ctx->quant_chroma_mat, 64); // chroma quantisation matrix
-    } else {
-        bytestream_put_byte  (&buf, 0x00);      // matrix flags - default matrices are used
-    }
-    bytestream_put_be16  (&tmp, buf - orig_buf); // write back frame header size
+    buf = ff_prores_kostya_write_frame_header(avctx, ctx, &orig_buf, pic->flags,
+                              pic->color_primaries, pic->color_trc,
+                                   pic->colorspace);
 
     for (ctx->cur_picture_idx = 0;
          ctx->cur_picture_idx < ctx->pictures_per_frame;
          ctx->cur_picture_idx++) {
         // picture header
         picture_size_pos = buf + 1;
-        bytestream_put_byte  (&buf, 0x40);          // picture header size (in bits)
-        buf += 4;                                   // picture data size will be stored here
-        bytestream_put_be16  (&buf, ctx->slices_per_picture);
-        bytestream_put_byte  (&buf, av_log2(ctx->mbs_per_slice) << 4); // slice width and height in MBs
+        buf = ff_prores_kostya_write_picture_header(ctx, buf);
 
         // seek table - will be filled during slice encoding
         slice_sizes = buf;
@@ -1048,7 +796,7 @@ static int encode_frame(AVCodecContext *avctx, AVPacket *pkt,
                 while (ctx->mb_width - x < mbs_per_slice)
                     mbs_per_slice >>= 1;
 
-                bytestream_put_byte(&buf, slice_hdr_size << 3);
+                bytestream_put_byte(&buf, slice_hdr_size * 8);
                 slice_hdr = buf;
                 buf += slice_hdr_size - 1;
                 if (pkt_size <= buf - orig_buf + 2 * max_slice_size) {
@@ -1076,13 +824,11 @@ static int encode_frame(AVCodecContext *avctx, AVPacket *pkt,
                         return ret;
 
                     pkt_size += delta;
-                    // restore pointers
                     orig_buf         = pkt->data + (orig_buf         - start);
                     buf              = pkt->data + (buf              - start);
                     picture_size_pos = pkt->data + (picture_size_pos - start);
                     slice_sizes      = pkt->data + (slice_sizes      - start);
                     slice_hdr        = pkt->data + (slice_hdr        - start);
-                    tmp              = pkt->data + (tmp              - start);
                 }
                 init_put_bits(&pb, buf, (pkt_size - (buf - orig_buf)));
                 ret = encode_slice(avctx, pic, &pb, sizes, x, y, q,
@@ -1149,105 +895,18 @@ static void prores_fdct(FDCTDSPContext *fdsp, const uint16_t *src,
 static av_cold int encode_init(AVCodecContext *avctx)
 {
     ProresContext *ctx = avctx->priv_data;
-    int mps;
-    int i, j;
-    int min_quant, max_quant;
-    int interlaced = !!(avctx->flags & AV_CODEC_FLAG_INTERLACED_DCT);
+    int err = 0, i, j, min_quant, max_quant;
 
-    avctx->bits_per_raw_sample = 10;
+    err = ff_prores_kostya_encode_init(avctx, ctx, avctx->pix_fmt);
+    if (err < 0)
+        return err;
 
     ctx->fdct      = prores_fdct;
-    ctx->scantable = interlaced ? ff_prores_interlaced_scan
-                                : ff_prores_progressive_scan;
     ff_fdctdsp_init(&ctx->fdsp, avctx);
 
-    mps = ctx->mbs_per_slice;
-    if (mps & (mps - 1)) {
-        av_log(avctx, AV_LOG_ERROR,
-               "there should be an integer power of two MBs per slice\n");
-        return AVERROR(EINVAL);
-    }
-    if (ctx->profile == PRORES_PROFILE_AUTO) {
-        const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(avctx->pix_fmt);
-        ctx->profile = (desc->flags & AV_PIX_FMT_FLAG_ALPHA ||
-                        !(desc->log2_chroma_w + desc->log2_chroma_h))
-                     ? PRORES_PROFILE_4444 : PRORES_PROFILE_HQ;
-        av_log(avctx, AV_LOG_INFO, "Autoselected %s. It can be overridden "
-               "through -profile option.\n", ctx->profile == PRORES_PROFILE_4444
-               ? "4:4:4:4 profile because of the used input colorspace"
-               : "HQ profile to keep best quality");
-    }
-    if (av_pix_fmt_desc_get(avctx->pix_fmt)->flags & AV_PIX_FMT_FLAG_ALPHA) {
-        if (ctx->profile != PRORES_PROFILE_4444 &&
-            ctx->profile != PRORES_PROFILE_4444XQ) {
-            // force alpha and warn
-            av_log(avctx, AV_LOG_WARNING, "Profile selected will not "
-                   "encode alpha. Override with -profile if needed.\n");
-            ctx->alpha_bits = 0;
-        }
-        if (ctx->alpha_bits & 7) {
-            av_log(avctx, AV_LOG_ERROR, "alpha bits should be 0, 8 or 16\n");
-            return AVERROR(EINVAL);
-        }
-        avctx->bits_per_coded_sample = 32;
-    } else {
-        ctx->alpha_bits = 0;
-    }
-
-    ctx->chroma_factor = avctx->pix_fmt == AV_PIX_FMT_YUV422P10
-                         ? CFACTOR_Y422
-                         : CFACTOR_Y444;
-    ctx->profile_info  = prores_profile_info + ctx->profile;
-    ctx->num_planes    = 3 + !!ctx->alpha_bits;
-
-    ctx->mb_width      = FFALIGN(avctx->width,  16) >> 4;
-
-    if (interlaced)
-        ctx->mb_height = FFALIGN(avctx->height, 32) >> 5;
-    else
-        ctx->mb_height = FFALIGN(avctx->height, 16) >> 4;
-
-    ctx->slices_width  = ctx->mb_width / mps;
-    ctx->slices_width += av_popcount(ctx->mb_width - ctx->slices_width * mps);
-    ctx->slices_per_picture = ctx->mb_height * ctx->slices_width;
-    ctx->pictures_per_frame = 1 + interlaced;
-
-    if (ctx->quant_sel == -1) {
-        ctx->quant_mat = prores_quant_matrices[ctx->profile_info->quant];
-        ctx->quant_chroma_mat = prores_quant_matrices[ctx->profile_info->quant_chroma];
-    } else {
-        ctx->quant_mat = prores_quant_matrices[ctx->quant_sel];
-        ctx->quant_chroma_mat = prores_quant_matrices[ctx->quant_sel];
-    }
-
-    if (strlen(ctx->vendor) != 4) {
-        av_log(avctx, AV_LOG_ERROR, "vendor ID should be 4 bytes\n");
-        return AVERROR_INVALIDDATA;
-    }
-
-    ctx->force_quant = avctx->global_quality / FF_QP2LAMBDA;
     if (!ctx->force_quant) {
-        if (!ctx->bits_per_mb) {
-            for (i = 0; i < NUM_MB_LIMITS - 1; i++)
-                if (prores_mb_limits[i] >= ctx->mb_width * ctx->mb_height *
-                                           ctx->pictures_per_frame)
-                    break;
-            ctx->bits_per_mb   = ctx->profile_info->br_tab[i];
-            if (ctx->alpha_bits)
-                ctx->bits_per_mb *= 20;
-        } else if (ctx->bits_per_mb < 128) {
-            av_log(avctx, AV_LOG_ERROR, "too few bits per MB, please set at least 128\n");
-            return AVERROR_INVALIDDATA;
-        }
-
         min_quant = ctx->profile_info->min_quant;
         max_quant = ctx->profile_info->max_quant;
-        for (i = min_quant; i < MAX_STORED_Q; i++) {
-            for (j = 0; j < 64; j++) {
-                ctx->quants[i][j] = ctx->quant_mat[j] * i;
-                ctx->quants_chroma[i][j] = ctx->quant_chroma_mat[j] * i;
-            }
-        }
 
         ctx->slice_q = av_malloc_array(ctx->slices_per_picture, sizeof(*ctx->slice_q));
         if (!ctx->slice_q)
@@ -1269,51 +928,8 @@ static av_cold int encode_init(AVCodecContext *avctx)
                 ctx->tdata[j].nodes[i].score     = 0;
             }
         }
-    } else {
-        int ls = 0;
-        int ls_chroma = 0;
-
-        if (ctx->force_quant > 64) {
-            av_log(avctx, AV_LOG_ERROR, "too large quantiser, maximum is 64\n");
-            return AVERROR_INVALIDDATA;
-        }
-
-        for (j = 0; j < 64; j++) {
-            ctx->quants[0][j] = ctx->quant_mat[j] * ctx->force_quant;
-            ctx->quants_chroma[0][j] = ctx->quant_chroma_mat[j] * ctx->force_quant;
-            ls += av_log2((1 << 11)  / ctx->quants[0][j]) * 2 + 1;
-            ls_chroma += av_log2((1 << 11)  / ctx->quants_chroma[0][j]) * 2 + 1;
-        }
-
-        ctx->bits_per_mb = ls * 4 + ls_chroma * 4;
-        if (ctx->chroma_factor == CFACTOR_Y444)
-            ctx->bits_per_mb += ls_chroma * 4;
     }
 
-    ctx->frame_size_upper_bound = (ctx->pictures_per_frame *
-                                   ctx->slices_per_picture + 1) *
-                                  (2 + 2 * ctx->num_planes +
-                                   (mps * ctx->bits_per_mb) / 8)
-                                  + 200;
-
-    if (ctx->alpha_bits) {
-         // The alpha plane is run-coded and might exceed the bit budget.
-         ctx->frame_size_upper_bound += (ctx->pictures_per_frame *
-                                         ctx->slices_per_picture + 1) *
-         /* num pixels per slice */     (ctx->mbs_per_slice * 256 *
-         /* bits per pixel */            (1 + ctx->alpha_bits + 1) + 7 >> 3);
-    }
-
-    avctx->codec_tag   = ctx->profile_info->tag;
-    avctx->profile = ctx->profile;
-
-    av_log(avctx, AV_LOG_DEBUG,
-           "profile %d, %d slices, interlacing: %s, %d bits per MB\n",
-           ctx->profile, ctx->slices_per_picture * ctx->pictures_per_frame,
-           interlaced ? "yes" : "no", ctx->bits_per_mb);
-    av_log(avctx, AV_LOG_DEBUG, "frame size upper bound: %d\n",
-           ctx->frame_size_upper_bound);
-
     return 0;
 }
 
diff --git a/libavcodec/proresenc_kostya_common.c b/libavcodec/proresenc_kostya_common.c
new file mode 100644
index 0000000000..d432d10369
--- /dev/null
+++ b/libavcodec/proresenc_kostya_common.c
@@ -0,0 +1,364 @@
+/*
+ * Apple ProRes encoder
+ *
+ * Copyright (c) 2011 Anatoliy Wasserman
+ * Copyright (c) 2012 Konstantin Shishkov
+ *
+ * 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 "libavutil/pixdesc.h"
+#include "avcodec.h"
+#include "bytestream.h"
+#include "proresdata.h"
+#include <sys/types.h>
+#include "proresenc_kostya_common.h"
+
+static const uint8_t prores_quant_matrices[][64] = {
+    { // proxy
+         4,  7,  9, 11, 13, 14, 15, 63,
+         7,  7, 11, 12, 14, 15, 63, 63,
+         9, 11, 13, 14, 15, 63, 63, 63,
+        11, 11, 13, 14, 63, 63, 63, 63,
+        11, 13, 14, 63, 63, 63, 63, 63,
+        13, 14, 63, 63, 63, 63, 63, 63,
+        13, 63, 63, 63, 63, 63, 63, 63,
+        63, 63, 63, 63, 63, 63, 63, 63,
+    },
+    { // proxy chromas
+        4,  7,  9, 11, 13, 14, 63, 63,
+        7,  7, 11, 12, 14, 63, 63, 63,
+        9, 11, 13, 14, 63, 63, 63, 63,
+        11, 11, 13, 14, 63, 63, 63, 63,
+        11, 13, 14, 63, 63, 63, 63, 63,
+        13, 14, 63, 63, 63, 63, 63, 63,
+        13, 63, 63, 63, 63, 63, 63, 63,
+        63, 63, 63, 63, 63, 63, 63, 63
+    },
+    { // LT
+         4,  5,  6,  7,  9, 11, 13, 15,
+         5,  5,  7,  8, 11, 13, 15, 17,
+         6,  7,  9, 11, 13, 15, 15, 17,
+         7,  7,  9, 11, 13, 15, 17, 19,
+         7,  9, 11, 13, 14, 16, 19, 23,
+         9, 11, 13, 14, 16, 19, 23, 29,
+         9, 11, 13, 15, 17, 21, 28, 35,
+        11, 13, 16, 17, 21, 28, 35, 41,
+    },
+    { // standard
+         4,  4,  5,  5,  6,  7,  7,  9,
+         4,  4,  5,  6,  7,  7,  9,  9,
+         5,  5,  6,  7,  7,  9,  9, 10,
+         5,  5,  6,  7,  7,  9,  9, 10,
+         5,  6,  7,  7,  8,  9, 10, 12,
+         6,  7,  7,  8,  9, 10, 12, 15,
+         6,  7,  7,  9, 10, 11, 14, 17,
+         7,  7,  9, 10, 11, 14, 17, 21,
+    },
+    { // high quality
+         4,  4,  4,  4,  4,  4,  4,  4,
+         4,  4,  4,  4,  4,  4,  4,  4,
+         4,  4,  4,  4,  4,  4,  4,  4,
+         4,  4,  4,  4,  4,  4,  4,  5,
+         4,  4,  4,  4,  4,  4,  5,  5,
+         4,  4,  4,  4,  4,  5,  5,  6,
+         4,  4,  4,  4,  5,  5,  6,  7,
+         4,  4,  4,  4,  5,  6,  7,  7,
+    },
+    { // XQ luma
+        2,  2,  2,  2,  2,  2,  2,  2,
+        2,  2,  2,  2,  2,  2,  2,  2,
+        2,  2,  2,  2,  2,  2,  2,  2,
+        2,  2,  2,  2,  2,  2,  2,  3,
+        2,  2,  2,  2,  2,  2,  3,  3,
+        2,  2,  2,  2,  2,  3,  3,  3,
+        2,  2,  2,  2,  3,  3,  3,  4,
+        2,  2,  2,  2,  3,  3,  4,  4,
+    },
+    { // codec default
+         4,  4,  4,  4,  4,  4,  4,  4,
+         4,  4,  4,  4,  4,  4,  4,  4,
+         4,  4,  4,  4,  4,  4,  4,  4,
+         4,  4,  4,  4,  4,  4,  4,  4,
+         4,  4,  4,  4,  4,  4,  4,  4,
+         4,  4,  4,  4,  4,  4,  4,  4,
+         4,  4,  4,  4,  4,  4,  4,  4,
+         4,  4,  4,  4,  4,  4,  4,  4,
+    },
+};
+
+static const int prores_mb_limits[NUM_MB_LIMITS] = {
+    1620, // up to 720x576
+    2700, // up to 960x720
+    6075, // up to 1440x1080
+    9216, // up to 2048x1152
+};
+
+static const prores_profile prores_profile_info[6] = {
+    {
+        .full_name = "proxy",
+        .tag       = MKTAG('a', 'p', 'c', 'o'),
+        .min_quant = 4,
+        .max_quant = 8,
+        .br_tab    = { 300, 242, 220, 194 },
+        .quant     = QUANT_MAT_PROXY,
+        .quant_chroma = QUANT_MAT_PROXY_CHROMA,
+    },
+    {
+        .full_name = "LT",
+        .tag       = MKTAG('a', 'p', 'c', 's'),
+        .min_quant = 1,
+        .max_quant = 9,
+        .br_tab    = { 720, 560, 490, 440 },
+        .quant     = QUANT_MAT_LT,
+        .quant_chroma = QUANT_MAT_LT,
+    },
+    {
+        .full_name = "standard",
+        .tag       = MKTAG('a', 'p', 'c', 'n'),
+        .min_quant = 1,
+        .max_quant = 6,
+        .br_tab    = { 1050, 808, 710, 632 },
+        .quant     = QUANT_MAT_STANDARD,
+        .quant_chroma = QUANT_MAT_STANDARD,
+    },
+    {
+        .full_name = "high quality",
+        .tag       = MKTAG('a', 'p', 'c', 'h'),
+        .min_quant = 1,
+        .max_quant = 6,
+        .br_tab    = { 1566, 1216, 1070, 950 },
+        .quant     = QUANT_MAT_HQ,
+        .quant_chroma = QUANT_MAT_HQ,
+    },
+    {
+        .full_name = "4444",
+        .tag       = MKTAG('a', 'p', '4', 'h'),
+        .min_quant = 1,
+        .max_quant = 6,
+        .br_tab    = { 2350, 1828, 1600, 1425 },
+        .quant     = QUANT_MAT_HQ,
+        .quant_chroma = QUANT_MAT_HQ,
+    },
+    {
+        .full_name = "4444XQ",
+        .tag       = MKTAG('a', 'p', '4', 'x'),
+        .min_quant = 1,
+        .max_quant = 6,
+        .br_tab    = { 3525, 2742, 2400, 2137 },
+        .quant     = QUANT_MAT_HQ, /* Fix me : use QUANT_MAT_XQ_LUMA */
+        .quant_chroma = QUANT_MAT_HQ,
+    }
+};
+
+av_cold int ff_prores_kostya_encode_init(AVCodecContext *avctx, ProresContext *ctx,
+                                         enum AVPixelFormat pix_fmt)
+{
+    int mps, i, j, min_quant;
+    int interlaced = !!(avctx->flags & AV_CODEC_FLAG_INTERLACED_DCT);
+
+    avctx->bits_per_raw_sample = 10;
+
+    ctx->scantable = interlaced ? ff_prores_interlaced_scan
+                                : ff_prores_progressive_scan;
+
+    mps = ctx->mbs_per_slice;
+    if (mps & (mps - 1)) {
+        av_log(avctx, AV_LOG_ERROR,
+               "there should be an integer power of two MBs per slice\n");
+        return AVERROR(EINVAL);
+    }
+    if (ctx->profile == PRORES_PROFILE_AUTO) {
+        const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(pix_fmt);
+        ctx->profile = (desc->flags & AV_PIX_FMT_FLAG_ALPHA ||
+                        !(desc->log2_chroma_w + desc->log2_chroma_h))
+                     ? PRORES_PROFILE_4444 : PRORES_PROFILE_HQ;
+        av_log(avctx, AV_LOG_INFO, "Autoselected %s. It can be overridden "
+               "through -profile option.\n", ctx->profile == PRORES_PROFILE_4444
+               ? "4:4:4:4 profile because of the used input colorspace"
+               : "HQ profile to keep best quality");
+    }
+    if (av_pix_fmt_desc_get(pix_fmt)->flags & AV_PIX_FMT_FLAG_ALPHA) {
+        if (ctx->profile != PRORES_PROFILE_4444 &&
+            ctx->profile != PRORES_PROFILE_4444XQ) {
+            // force alpha and warn
+            av_log(avctx, AV_LOG_WARNING, "Profile selected will not "
+                   "encode alpha. Override with -profile if needed.\n");
+            ctx->alpha_bits = 0;
+        }
+        if (ctx->alpha_bits & 7) {
+            av_log(avctx, AV_LOG_ERROR, "alpha bits should be 0, 8 or 16\n");
+            return AVERROR(EINVAL);
+        }
+        avctx->bits_per_coded_sample = 32;
+    } else {
+        ctx->alpha_bits = 0;
+    }
+
+    ctx->chroma_factor = pix_fmt == AV_PIX_FMT_YUV422P10
+                         ? CFACTOR_Y422
+                         : CFACTOR_Y444;
+    ctx->profile_info  = prores_profile_info + ctx->profile;
+    ctx->num_planes    = 3 + !!ctx->alpha_bits;
+
+    ctx->mb_width      = FFALIGN(avctx->width,  16) >> 4;
+
+    if (interlaced)
+        ctx->mb_height = FFALIGN(avctx->height, 32) >> 5;
+    else
+        ctx->mb_height = FFALIGN(avctx->height, 16) >> 4;
+
+    ctx->slices_width  = ctx->mb_width / mps;
+    ctx->slices_width += av_popcount(ctx->mb_width - ctx->slices_width * mps);
+    ctx->slices_per_picture = ctx->mb_height * ctx->slices_width;
+    ctx->pictures_per_frame = 1 + interlaced;
+
+    if (ctx->quant_sel == -1) {
+        ctx->quant_mat = prores_quant_matrices[ctx->profile_info->quant];
+        ctx->quant_chroma_mat = prores_quant_matrices[ctx->profile_info->quant_chroma];
+    } else {
+        ctx->quant_mat = prores_quant_matrices[ctx->quant_sel];
+        ctx->quant_chroma_mat = prores_quant_matrices[ctx->quant_sel];
+    }
+
+    if (strlen(ctx->vendor) != 4) {
+        av_log(avctx, AV_LOG_ERROR, "vendor ID should be 4 bytes\n");
+        return AVERROR_INVALIDDATA;
+    }
+
+    ctx->force_quant = avctx->global_quality / FF_QP2LAMBDA;
+    if (!ctx->force_quant) {
+        if (!ctx->bits_per_mb) {
+            for (i = 0; i < NUM_MB_LIMITS - 1; i++)
+                if (prores_mb_limits[i] >= ctx->mb_width * ctx->mb_height *
+                                           ctx->pictures_per_frame)
+                    break;
+            ctx->bits_per_mb   = ctx->profile_info->br_tab[i];
+            if (ctx->alpha_bits)
+                ctx->bits_per_mb *= 20;
+        } else if (ctx->bits_per_mb < 128) {
+            av_log(avctx, AV_LOG_ERROR, "too few bits per MB, please set at least 128\n");
+            return AVERROR_INVALIDDATA;
+        }
+
+        min_quant = ctx->profile_info->min_quant;
+        for (i = min_quant; i < MAX_STORED_Q; i++) {
+            for (j = 0; j < 64; j++) {
+                ctx->quants[i][j] = ctx->quant_mat[j] * i;
+                ctx->quants_chroma[i][j] = ctx->quant_chroma_mat[j] * i;
+            }
+        }
+    } else {
+        int ls = 0;
+        int ls_chroma = 0;
+
+        if (ctx->force_quant > 64) {
+            av_log(avctx, AV_LOG_ERROR, "too large quantiser, maximum is 64\n");
+            return AVERROR_INVALIDDATA;
+        }
+
+        for (j = 0; j < 64; j++) {
+            ctx->quants[0][j] = ctx->quant_mat[j] * ctx->force_quant;
+            ctx->quants_chroma[0][j] = ctx->quant_chroma_mat[j] * ctx->force_quant;
+            ls += av_log2((1 << 11)  / ctx->quants[0][j]) * 2 + 1;
+            ls_chroma += av_log2((1 << 11)  / ctx->quants_chroma[0][j]) * 2 + 1;
+        }
+
+        ctx->bits_per_mb = ls * 4 + ls_chroma * 4;
+        if (ctx->chroma_factor == CFACTOR_Y444)
+            ctx->bits_per_mb += ls_chroma * 4;
+    }
+
+    ctx->frame_size_upper_bound = (ctx->pictures_per_frame *
+                                   ctx->slices_per_picture + 1) *
+                                  (2 + 2 * ctx->num_planes +
+                                   (mps * ctx->bits_per_mb) / 8)
+                                  + 200;
+
+    if (ctx->alpha_bits) {
+         // The alpha plane is run-coded and might exceed the bit budget.
+         ctx->frame_size_upper_bound += (ctx->pictures_per_frame *
+                                         ctx->slices_per_picture + 1) *
+         /* num pixels per slice */     (ctx->mbs_per_slice * 256 *
+         /* bits per pixel */            (1 + ctx->alpha_bits + 1) + 7 >> 3);
+    }
+
+    avctx->codec_tag   = ctx->profile_info->tag;
+    avctx->profile = ctx->profile;
+
+    av_log(avctx, AV_LOG_DEBUG,
+           "profile %d, %d slices, interlacing: %s, %d bits per MB\n",
+           ctx->profile, ctx->slices_per_picture * ctx->pictures_per_frame,
+           interlaced ? "yes" : "no", ctx->bits_per_mb);
+    av_log(avctx, AV_LOG_DEBUG, "frame size upper bound: %d\n",
+           ctx->frame_size_upper_bound);
+
+    return 0;
+}
+
+uint8_t* ff_prores_kostya_write_frame_header(AVCodecContext *avctx, ProresContext *ctx,
+                                             uint8_t **orig_buf, int flags,
+                                             enum AVColorPrimaries color_primaries,
+                                             enum AVColorTransferCharacteristic color_trc,
+                                             enum AVColorSpace colorspace)
+{
+    uint8_t *buf, *tmp;
+    uint8_t frame_flags;
+
+    // frame atom
+    *orig_buf += 4;                              // frame size
+    bytestream_put_be32  (orig_buf, FRAME_ID); // frame container ID
+    buf = *orig_buf;
+
+    // frame header
+    tmp = buf;
+    buf += 2;                                   // frame header size will be stored here
+    bytestream_put_be16  (&buf, ctx->chroma_factor != CFACTOR_Y422 || ctx->alpha_bits ? 1 : 0);
+    bytestream_put_buffer(&buf, (uint8_t*)ctx->vendor, 4);
+    bytestream_put_be16  (&buf, avctx->width);
+    bytestream_put_be16  (&buf, avctx->height);
+
+    frame_flags = ctx->chroma_factor << 6;
+    if (avctx->flags & AV_CODEC_FLAG_INTERLACED_DCT)
+        frame_flags |= (flags & AV_FRAME_FLAG_TOP_FIELD_FIRST) ? 0x04 : 0x08;
+    bytestream_put_byte  (&buf, frame_flags);
+
+    bytestream_put_byte  (&buf, 0);             // reserved
+    bytestream_put_byte  (&buf, color_primaries);
+    bytestream_put_byte  (&buf, color_trc);
+    bytestream_put_byte  (&buf, colorspace);
+    bytestream_put_byte  (&buf, ctx->alpha_bits >> 3);
+    bytestream_put_byte  (&buf, 0);             // reserved
+    if (ctx->quant_sel != QUANT_MAT_DEFAULT) {
+        bytestream_put_byte  (&buf, 0x03);      // matrix flags - both matrices are present
+        bytestream_put_buffer(&buf, ctx->quant_mat, 64);        // luma quantisation matrix
+        bytestream_put_buffer(&buf, ctx->quant_chroma_mat, 64); // chroma quantisation matrix
+    } else {
+        bytestream_put_byte  (&buf, 0x00);      // matrix flags - default matrices are used
+    }
+    bytestream_put_be16  (&tmp, buf - *orig_buf); // write back frame header size
+    return buf;
+}
+
+uint8_t* ff_prores_kostya_write_picture_header(ProresContext *ctx, uint8_t *buf)
+{
+    bytestream_put_byte  (&buf, 0x40); // picture header size (in bits)
+    buf += 4;                                   // picture data size will be stored here
+    bytestream_put_be16  (&buf, ctx->slices_per_picture);
+    bytestream_put_byte  (&buf, av_log2(ctx->mbs_per_slice) << 4); // slice width and height in MBs
+    return buf;
+}
\ No newline at end of file
diff --git a/libavcodec/proresenc_kostya_common.h b/libavcodec/proresenc_kostya_common.h
new file mode 100644
index 0000000000..f18adc36af
--- /dev/null
+++ b/libavcodec/proresenc_kostya_common.h
@@ -0,0 +1,131 @@
+/*
+ * Apple ProRes encoder
+ *
+ * Copyright (c) 2011 Anatoliy Wasserman
+ * Copyright (c) 2012 Konstantin Shishkov
+ *
+ * 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 AVCODEC_PRORESENC_KOSTYA_H
+#define AVCODEC_PRORESENC_KOSTYA_H
+
+#include "libavutil/attributes_internal.h"
+#include "libavutil/mem_internal.h"
+#include "libavutil/pixfmt.h"
+#include "fdctdsp.h"
+
+FF_VISIBILITY_PUSH_HIDDEN
+
+#define CFACTOR_Y422 2
+#define CFACTOR_Y444 3
+
+#define MAX_MBS_PER_SLICE 8
+
+#define MAX_PLANES 4
+
+#define NUM_MB_LIMITS 4
+
+#define MAX_STORED_Q 16
+
+enum {
+    PRORES_PROFILE_AUTO  = -1,
+    PRORES_PROFILE_PROXY = 0,
+    PRORES_PROFILE_LT,
+    PRORES_PROFILE_STANDARD,
+    PRORES_PROFILE_HQ,
+    PRORES_PROFILE_4444,
+    PRORES_PROFILE_4444XQ,
+};
+
+enum {
+    QUANT_MAT_PROXY = 0,
+    QUANT_MAT_PROXY_CHROMA,
+    QUANT_MAT_LT,
+    QUANT_MAT_STANDARD,
+    QUANT_MAT_HQ,
+    QUANT_MAT_XQ_LUMA,
+    QUANT_MAT_DEFAULT,
+};
+
+typedef struct prores_profile {
+    const char *full_name;
+    uint32_t    tag;
+    int         min_quant;
+    int         max_quant;
+    int         br_tab[NUM_MB_LIMITS];
+    int         quant;
+    int         quant_chroma;
+} prores_profile;
+
+typedef struct ProresContext {
+    AVClass *class;
+    DECLARE_ALIGNED(16, int16_t, blocks)[MAX_PLANES][64 * 4 * MAX_MBS_PER_SLICE];
+    DECLARE_ALIGNED(16, uint16_t, emu_buf)[16*16];
+    int16_t quants[MAX_STORED_Q][64];
+    int16_t quants_chroma[MAX_STORED_Q][64];
+    int16_t custom_q[64];
+    int16_t custom_chroma_q[64];
+    const uint8_t *quant_mat;
+    const uint8_t *quant_chroma_mat;
+    const uint8_t *scantable;
+
+    void (*fdct)(FDCTDSPContext *fdsp, const uint16_t *src,
+                 ptrdiff_t linesize, int16_t *block);
+    FDCTDSPContext fdsp;
+
+    const AVFrame *pic;
+    int mb_width, mb_height;
+    int mbs_per_slice;
+    int num_chroma_blocks, chroma_factor;
+    int slices_width;
+    int slices_per_picture;
+    int pictures_per_frame; // 1 for progressive, 2 for interlaced
+    int cur_picture_idx;
+    int num_planes;
+    int bits_per_mb;
+    int force_quant;
+    int alpha_bits;
+    int warn;
+
+    char *vendor;
+    int quant_sel;
+
+    int frame_size_upper_bound;
+
+    int profile;
+    const struct prores_profile *profile_info;
+
+    int *slice_q;
+
+    struct ProresThreadData *tdata;
+} ProresContext;
+
+av_cold int ff_prores_kostya_encode_init(AVCodecContext *avctx, ProresContext *ctx,
+                                         enum AVPixelFormat pixfmt);
+
+uint8_t* ff_prores_kostya_write_frame_header(AVCodecContext *avctx, ProresContext *ctx,
+                                             uint8_t **orig_buf, int flags,
+                                             enum AVColorPrimaries color_primaries,
+                                             enum AVColorTransferCharacteristic color_trc,
+                                             enum AVColorSpace colorspace);
+
+uint8_t* ff_prores_kostya_write_picture_header(ProresContext *ctx, uint8_t *buf);
+
+FF_VISIBILITY_POP_HIDDEN
+
+#endif
\ No newline at end of file
-- 
2.50.1

_______________________________________________
ffmpeg-devel mailing list -- ffmpeg-devel@ffmpeg.org
To unsubscribe send an email to ffmpeg-devel-leave@ffmpeg.org

  reply	other threads:[~2025-09-04 20:11 UTC|newest]

Thread overview: 3+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2025-09-04 20:10 [FFmpeg-devel] [PATCH 1/3] vulkan: Support samplerless images IndecisiveTurtle via ffmpeg-devel
2025-09-04 20:10 ` IndecisiveTurtle via ffmpeg-devel [this message]
2025-09-04 20:10 ` [FFmpeg-devel] [PATCH 3/3] lavc: implement a Vulkan-based prores encoder IndecisiveTurtle via ffmpeg-devel

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20250904201002.10446-2-47210458+raphaelthegreat@users.noreply.github.com \
    --to=ffmpeg-devel@ffmpeg.org \
    --cc=geoster3d@gmail.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link

Git Inbox Mirror of the ffmpeg-devel mailing list - see https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

This inbox may be cloned and mirrored by anyone:

	git clone --mirror https://master.gitmailbox.com/ffmpegdev/0 ffmpegdev/git/0.git

	# If you have public-inbox 1.1+ installed, you may
	# initialize and index your mirror using the following commands:
	public-inbox-init -V2 ffmpegdev ffmpegdev/ https://master.gitmailbox.com/ffmpegdev \
		ffmpegdev@gitmailbox.com
	public-inbox-index ffmpegdev

Example config snippet for mirrors.


AGPL code for this site: git clone https://public-inbox.org/public-inbox.git