Coverage Report

Created: 2026-02-14 06:59

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/ffmpeg/libavcodec/huffyuvenc.c
Line
Count
Source
1
/*
2
 * Copyright (c) 2002-2014 Michael Niedermayer <michaelni@gmx.at>
3
 *
4
 * see https://multimedia.cx/huffyuv.txt for a description of
5
 * the algorithm used
6
 *
7
 * This file is part of FFmpeg.
8
 *
9
 * FFmpeg is free software; you can redistribute it and/or
10
 * modify it under the terms of the GNU Lesser General Public
11
 * License as published by the Free Software Foundation; either
12
 * version 2.1 of the License, or (at your option) any later version.
13
 *
14
 * FFmpeg is distributed in the hope that it will be useful,
15
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
17
 * Lesser General Public License for more details.
18
 *
19
 * You should have received a copy of the GNU Lesser General Public
20
 * License along with FFmpeg; if not, write to the Free Software
21
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
22
 *
23
 * yuva, gray, 4:4:4, 4:1:1, 4:1:0 and >8 bit per sample support sponsored by NOA
24
 */
25
26
/**
27
 * @file
28
 * huffyuv encoder
29
 */
30
31
#include "config_components.h"
32
33
#include "avcodec.h"
34
#include "bswapdsp.h"
35
#include "codec_internal.h"
36
#include "encode.h"
37
#include "huffyuv.h"
38
#include "huffman.h"
39
#include "huffyuvencdsp.h"
40
#include "lossless_videoencdsp.h"
41
#include "put_bits.h"
42
#include "libavutil/emms.h"
43
#include "libavutil/mem.h"
44
#include "libavutil/opt.h"
45
#include "libavutil/pixdesc.h"
46
47
typedef struct HYuvEncContext {
48
    AVClass *class;
49
    AVCodecContext *avctx;
50
    PutBitContext pb;
51
    Predictor predictor;
52
    int interlaced;
53
    int decorrelate;
54
    int bitstream_bpp;
55
    int version;
56
    int bps;
57
    int n;                                  // 1<<bps
58
    int vlc_n;                              // number of vlc codes (FFMIN(1<<bps, MAX_VLC_N))
59
    int alpha;
60
    int chroma;
61
    int yuv;
62
    int chroma_h_shift;
63
    int chroma_v_shift;
64
    int flags;
65
    int context;
66
    int picture_number;
67
68
    union {
69
        uint8_t  *temp[3];
70
        uint16_t *temp16[3];
71
    };
72
    uint64_t stats[4][MAX_VLC_N];
73
    uint8_t len[4][MAX_VLC_N];
74
    uint32_t bits[4][MAX_VLC_N];
75
    BswapDSPContext bdsp;
76
    HuffYUVEncDSPContext hencdsp;
77
    LLVidEncDSPContext llvidencdsp;
78
    int non_determ; // non-deterministic, multi-threaded encoder allowed
79
} HYuvEncContext;
80
81
static inline void diff_bytes(HYuvEncContext *s, uint8_t *dst,
82
                              const uint8_t *src0, const uint8_t *src1, int w)
83
0
{
84
0
    if (s->bps <= 8) {
85
0
        s->llvidencdsp.diff_bytes(dst, src0, src1, w);
86
0
    } else {
87
0
        s->hencdsp.diff_int16((uint16_t *)dst, (const uint16_t *)src0, (const uint16_t *)src1, s->n - 1, w);
88
0
    }
89
0
}
90
91
static inline int sub_left_prediction(HYuvEncContext *s, uint8_t *dst,
92
                                      const uint8_t *src, int w, int left)
93
10.4M
{
94
10.4M
    int i;
95
10.4M
    int min_width = FFMIN(w, 32);
96
97
10.4M
    if (s->bps <= 8) {
98
19.6M
        for (i = 0; i < min_width; i++) { /* scalar loop before dsp call */
99
14.5M
            const int temp = src[i];
100
14.5M
            dst[i] = temp - left;
101
14.5M
            left   = temp;
102
14.5M
        }
103
5.13M
        if (w < 32)
104
5.08M
            return left;
105
49.8k
        s->llvidencdsp.diff_bytes(dst + 32, src + 32, src + 31, w - 32);
106
49.8k
        return src[w-1];
107
5.28M
    } else {
108
5.28M
        const uint16_t *src16 = (const uint16_t *)src;
109
5.28M
        uint16_t       *dst16 = (      uint16_t *)dst;
110
20.6M
        for (i = 0; i < min_width; i++) { /* scalar loop before dsp call */
111
15.3M
            const int temp = src16[i];
112
15.3M
            dst16[i] = temp - left;
113
15.3M
            left   = temp;
114
15.3M
        }
115
5.28M
        if (w < 32)
116
5.27M
            return left;
117
10.1k
        s->hencdsp.diff_int16(dst16 + 32, src16 + 32, src16 + 31, s->n - 1, w - 32);
118
10.1k
        return src16[w-1];
119
5.28M
    }
120
10.4M
}
121
122
static inline void sub_left_prediction_bgr32(HYuvEncContext *s, uint8_t *dst,
123
                                             const uint8_t *src, int w,
124
                                             int *red, int *green, int *blue,
125
                                             int *alpha)
126
1.23M
{
127
1.23M
    int i;
128
1.23M
    int r, g, b, a;
129
1.23M
    int min_width = FFMIN(w, 8);
130
1.23M
    r = *red;
131
1.23M
    g = *green;
132
1.23M
    b = *blue;
133
1.23M
    a = *alpha;
134
135
4.48M
    for (i = 0; i < min_width; i++) {
136
3.24M
        const int rt = src[i * 4 + R];
137
3.24M
        const int gt = src[i * 4 + G];
138
3.24M
        const int bt = src[i * 4 + B];
139
3.24M
        const int at = src[i * 4 + A];
140
3.24M
        dst[i * 4 + R] = rt - r;
141
3.24M
        dst[i * 4 + G] = gt - g;
142
3.24M
        dst[i * 4 + B] = bt - b;
143
3.24M
        dst[i * 4 + A] = at - a;
144
3.24M
        r = rt;
145
3.24M
        g = gt;
146
3.24M
        b = bt;
147
3.24M
        a = at;
148
3.24M
    }
149
150
1.23M
    s->llvidencdsp.diff_bytes(dst + 32, src + 32, src + 32 - 4, w * 4 - 32);
151
152
1.23M
    *red   = src[(w - 1) * 4 + R];
153
1.23M
    *green = src[(w - 1) * 4 + G];
154
1.23M
    *blue  = src[(w - 1) * 4 + B];
155
1.23M
    *alpha = src[(w - 1) * 4 + A];
156
1.23M
}
157
158
static inline void sub_left_prediction_rgb24(HYuvEncContext *s, uint8_t *dst,
159
                                             const uint8_t *src, int w,
160
                                             int *red, int *green, int *blue)
161
1.33M
{
162
1.33M
    int i;
163
1.33M
    int r, g, b;
164
1.33M
    r = *red;
165
1.33M
    g = *green;
166
1.33M
    b = *blue;
167
5.04M
    for (i = 0; i < FFMIN(w, 16); i++) {
168
3.71M
        const int rt = src[i * 3 + 0];
169
3.71M
        const int gt = src[i * 3 + 1];
170
3.71M
        const int bt = src[i * 3 + 2];
171
3.71M
        dst[i * 3 + 0] = rt - r;
172
3.71M
        dst[i * 3 + 1] = gt - g;
173
3.71M
        dst[i * 3 + 2] = bt - b;
174
3.71M
        r = rt;
175
3.71M
        g = gt;
176
3.71M
        b = bt;
177
3.71M
    }
178
179
1.33M
    s->llvidencdsp.diff_bytes(dst + 48, src + 48, src + 48 - 3, w * 3 - 48);
180
181
1.33M
    *red   = src[(w - 1) * 3 + 0];
182
1.33M
    *green = src[(w - 1) * 3 + 1];
183
1.33M
    *blue  = src[(w - 1) * 3 + 2];
184
1.33M
}
185
186
static void sub_median_prediction(HYuvEncContext *s, uint8_t *dst,
187
                                  const uint8_t *src1, const uint8_t *src2,
188
                                  int w, int *left, int *left_top)
189
0
{
190
0
    if (s->bps <= 8) {
191
0
        s->llvidencdsp.sub_median_pred(dst, src1, src2, w , left, left_top);
192
0
    } else {
193
0
        s->hencdsp.sub_hfyu_median_pred_int16((uint16_t *)dst, (const uint16_t *)src1, (const uint16_t *)src2, s->n - 1, w , left, left_top);
194
0
    }
195
0
}
196
197
static int store_table(HYuvEncContext *s, const uint8_t *len, uint8_t *buf)
198
2.79k
{
199
2.79k
    int i;
200
2.79k
    int index = 0;
201
2.79k
    int n = s->vlc_n;
202
203
95.0k
    for (i = 0; i < n;) {
204
92.2k
        int val = len[i];
205
92.2k
        int repeat = 0;
206
207
4.80M
        for (; i < n && len[i] == val && repeat < 255; i++)
208
4.70M
            repeat++;
209
210
92.2k
        av_assert0(val < 32 && val >0 && repeat < 256 && repeat>0);
211
92.2k
        if (repeat > 7) {
212
45.9k
            buf[index++] = val;
213
45.9k
            buf[index++] = repeat;
214
46.2k
        } else {
215
46.2k
            buf[index++] = val | (repeat << 5);
216
46.2k
        }
217
92.2k
    }
218
219
2.79k
    return index;
220
2.79k
}
221
222
static int store_huffman_tables(HYuvEncContext *s, uint8_t *buf)
223
944
{
224
944
    int i, ret;
225
944
    int size = 0;
226
944
    int count = 3;
227
228
944
    if (s->version > 2)
229
241
        count = 1 + s->alpha + 2*s->chroma;
230
231
3.73k
    for (i = 0; i < count; i++) {
232
2.79k
        if ((ret = ff_huff_gen_len_table(s->len[i], s->stats[i], s->vlc_n, 0)) < 0)
233
0
            return ret;
234
235
2.79k
        ret = ff_huffyuv_generate_bits_table(s->bits[i], s->len[i], s->vlc_n);
236
2.79k
        if (ret < 0)
237
0
            return ret;
238
239
2.79k
        size += store_table(s, s->len[i], buf + size);
240
2.79k
    }
241
944
    return size;
242
944
}
243
244
static av_cold int encode_init(AVCodecContext *avctx)
245
947
{
246
947
    HYuvEncContext *s = avctx->priv_data;
247
947
    int i, j;
248
947
    int ret;
249
947
    const AVPixFmtDescriptor *desc;
250
251
947
    s->avctx = avctx;
252
947
    s->flags = avctx->flags;
253
254
947
    ff_bswapdsp_init(&s->bdsp);
255
947
    ff_huffyuvencdsp_init(&s->hencdsp, avctx->pix_fmt);
256
947
    ff_llvidencdsp_init(&s->llvidencdsp);
257
258
947
    avctx->extradata = av_mallocz(3*MAX_N + 4);
259
947
    if (!avctx->extradata)
260
0
        return AVERROR(ENOMEM);
261
947
    if (s->flags&AV_CODEC_FLAG_PASS1) {
262
0
#define STATS_OUT_SIZE 21*MAX_N*3 + 4
263
0
        avctx->stats_out = av_mallocz(STATS_OUT_SIZE); // 21*256*3(%llu ) + 3(\n) + 1(0) = 16132
264
0
        if (!avctx->stats_out)
265
0
            return AVERROR(ENOMEM);
266
0
    }
267
947
    s->version = 2;
268
269
947
    desc   = av_pix_fmt_desc_get(avctx->pix_fmt);
270
947
    s->bps = desc->comp[0].depth;
271
947
    s->yuv = !(desc->flags & AV_PIX_FMT_FLAG_RGB) && desc->nb_components >= 2;
272
947
    s->chroma = desc->nb_components > 2;
273
947
    s->alpha = !!(desc->flags & AV_PIX_FMT_FLAG_ALPHA);
274
947
    s->chroma_h_shift = desc->log2_chroma_w;
275
947
    s->chroma_v_shift = desc->log2_chroma_h;
276
277
947
    switch (avctx->pix_fmt) {
278
102
    case AV_PIX_FMT_YUV420P:
279
223
    case AV_PIX_FMT_YUV422P:
280
223
        if (avctx->width & 1) {
281
3
            av_log(avctx, AV_LOG_ERROR, "Width must be even for this colorspace.\n");
282
3
            return AVERROR(EINVAL);
283
3
        }
284
220
        s->bitstream_bpp = avctx->pix_fmt == AV_PIX_FMT_YUV420P ? 12 : 16;
285
220
        break;
286
2
    case AV_PIX_FMT_YUV444P:
287
28
    case AV_PIX_FMT_YUV410P:
288
38
    case AV_PIX_FMT_YUV411P:
289
48
    case AV_PIX_FMT_YUV440P:
290
50
    case AV_PIX_FMT_GBRP:
291
52
    case AV_PIX_FMT_GBRP9:
292
53
    case AV_PIX_FMT_GBRP10:
293
55
    case AV_PIX_FMT_GBRP12:
294
57
    case AV_PIX_FMT_GBRP14:
295
58
    case AV_PIX_FMT_GBRP16:
296
99
    case AV_PIX_FMT_GRAY8:
297
109
    case AV_PIX_FMT_GRAY16:
298
110
    case AV_PIX_FMT_YUVA444P:
299
118
    case AV_PIX_FMT_YUVA420P:
300
121
    case AV_PIX_FMT_YUVA422P:
301
123
    case AV_PIX_FMT_GBRAP:
302
125
    case AV_PIX_FMT_YUV420P9:
303
130
    case AV_PIX_FMT_YUV420P10:
304
132
    case AV_PIX_FMT_YUV420P12:
305
136
    case AV_PIX_FMT_YUV420P14:
306
145
    case AV_PIX_FMT_YUV420P16:
307
147
    case AV_PIX_FMT_YUV422P9:
308
148
    case AV_PIX_FMT_YUV422P10:
309
154
    case AV_PIX_FMT_YUV422P12:
310
156
    case AV_PIX_FMT_YUV422P14:
311
170
    case AV_PIX_FMT_YUV422P16:
312
172
    case AV_PIX_FMT_YUV444P9:
313
173
    case AV_PIX_FMT_YUV444P10:
314
185
    case AV_PIX_FMT_YUV444P12:
315
186
    case AV_PIX_FMT_YUV444P14:
316
195
    case AV_PIX_FMT_YUV444P16:
317
198
    case AV_PIX_FMT_YUVA420P9:
318
201
    case AV_PIX_FMT_YUVA420P10:
319
210
    case AV_PIX_FMT_YUVA420P16:
320
214
    case AV_PIX_FMT_YUVA422P9:
321
217
    case AV_PIX_FMT_YUVA422P10:
322
223
    case AV_PIX_FMT_YUVA422P16:
323
231
    case AV_PIX_FMT_YUVA444P9:
324
233
    case AV_PIX_FMT_YUVA444P10:
325
241
    case AV_PIX_FMT_YUVA444P16:
326
241
        s->version = 3;
327
241
        break;
328
355
    case AV_PIX_FMT_RGB32:
329
355
        s->bitstream_bpp = 32;
330
355
        break;
331
128
    case AV_PIX_FMT_RGB24:
332
128
        s->bitstream_bpp = 24;
333
128
        break;
334
0
    default:
335
0
        av_log(avctx, AV_LOG_ERROR, "format not supported\n");
336
0
        return AVERROR(EINVAL);
337
947
    }
338
944
    s->n = 1<<s->bps;
339
944
    s->vlc_n = FFMIN(s->n, MAX_VLC_N);
340
341
944
    avctx->bits_per_coded_sample = s->bitstream_bpp;
342
944
    s->decorrelate = s->bitstream_bpp >= 24 && !s->yuv && !(desc->flags & AV_PIX_FMT_FLAG_PLANAR);
343
944
    s->interlaced = avctx->flags & AV_CODEC_FLAG_INTERLACED_ME ? 1 : 0;
344
944
    if (s->context) {
345
0
        if (s->flags & (AV_CODEC_FLAG_PASS1 | AV_CODEC_FLAG_PASS2)) {
346
0
            av_log(avctx, AV_LOG_ERROR,
347
0
                   "context=1 is not compatible with "
348
0
                   "2 pass huffyuv encoding\n");
349
0
            return AVERROR(EINVAL);
350
0
        }
351
0
    }
352
353
944
    if (avctx->codec->id == AV_CODEC_ID_HUFFYUV) {
354
383
        if (s->interlaced != ( avctx->height > 288 ))
355
56
            av_log(avctx, AV_LOG_INFO,
356
56
                   "using huffyuv 2.2.0 or newer interlacing flag\n");
357
383
    }
358
359
944
    if (s->version > 3 && avctx->strict_std_compliance > FF_COMPLIANCE_EXPERIMENTAL) {
360
0
        av_log(avctx, AV_LOG_ERROR, "Ver > 3 is under development, files encoded with it may not be decodable with future versions!!!\n"
361
0
               "Use vstrict=-2 / -strict -2 to use it anyway.\n");
362
0
        return AVERROR(EINVAL);
363
0
    }
364
365
944
    if (s->bitstream_bpp >= 24 && s->predictor == MEDIAN && s->version <= 2) {
366
0
        av_log(avctx, AV_LOG_ERROR,
367
0
               "Error: RGB is incompatible with median predictor\n");
368
0
        return AVERROR(EINVAL);
369
0
    }
370
371
944
    avctx->extradata[0] = s->predictor | (s->decorrelate << 6);
372
944
    avctx->extradata[2] = s->interlaced ? 0x10 : 0x20;
373
944
    if (s->context)
374
0
        avctx->extradata[2] |= 0x40;
375
944
    if (s->version < 3) {
376
703
        avctx->extradata[1] = s->bitstream_bpp;
377
703
        avctx->extradata[3] = 0;
378
703
    } else {
379
241
        avctx->extradata[1] = ((s->bps-1)<<4) | s->chroma_h_shift | (s->chroma_v_shift<<2);
380
241
        if (s->chroma)
381
190
            avctx->extradata[2] |= s->yuv ? 1 : 2;
382
241
        if (s->alpha)
383
60
            avctx->extradata[2] |= 4;
384
241
        avctx->extradata[3] = 1;
385
241
    }
386
944
    avctx->extradata_size = 4;
387
388
944
    if (avctx->stats_in) {
389
0
        char *p = avctx->stats_in;
390
391
0
        for (i = 0; i < 4; i++)
392
0
            for (j = 0; j < s->vlc_n; j++)
393
0
                s->stats[i][j] = 1;
394
395
0
        for (;;) {
396
0
            for (i = 0; i < 4; i++) {
397
0
                char *next;
398
399
0
                for (j = 0; j < s->vlc_n; j++) {
400
0
                    s->stats[i][j] += strtol(p, &next, 0);
401
0
                    if (next == p) return -1;
402
0
                    p = next;
403
0
                }
404
0
            }
405
0
            if (p[0] == 0 || p[1] == 0 || p[2] == 0) break;
406
0
        }
407
944
    } else {
408
4.72k
        for (i = 0; i < 4; i++)
409
6.21M
            for (j = 0; j < s->vlc_n; j++) {
410
6.21M
                int d = FFMIN(j, s->vlc_n - j);
411
412
6.21M
                s->stats[i][j] = 100000000 / (d*d + 1);
413
6.21M
            }
414
944
    }
415
416
944
    ret = store_huffman_tables(s, avctx->extradata + avctx->extradata_size);
417
944
    if (ret < 0)
418
0
        return ret;
419
944
    avctx->extradata_size += ret;
420
421
944
    if (s->context) {
422
0
        for (i = 0; i < 4; i++) {
423
0
            int pels = avctx->width * avctx->height / (i ? 40 : 10);
424
0
            for (j = 0; j < s->vlc_n; j++) {
425
0
                int d = FFMIN(j, s->vlc_n - j);
426
0
                s->stats[i][j] = pels/(d*d + 1);
427
0
            }
428
0
        }
429
944
    } else {
430
4.72k
        for (i = 0; i < 4; i++)
431
6.21M
            for (j = 0; j < s->vlc_n; j++)
432
6.21M
                s->stats[i][j]= 0;
433
944
    }
434
435
944
    s->picture_number=0;
436
437
3.77k
    for (int i = 0; i < 3; i++) {
438
2.83k
        s->temp[i] = av_malloc(4 * avctx->width + 16);
439
2.83k
        if (!s->temp[i])
440
0
            return AVERROR(ENOMEM);
441
2.83k
    }
442
443
944
    return 0;
444
944
}
445
static int encode_422_bitstream(HYuvEncContext *s, int offset, int count)
446
1.25M
{
447
1.25M
    int i;
448
1.25M
    const uint8_t *y = s->temp[0] + offset;
449
1.25M
    const uint8_t *u = s->temp[1] + offset / 2;
450
1.25M
    const uint8_t *v = s->temp[2] + offset / 2;
451
452
1.25M
    if (put_bytes_left(&s->pb, 0) < 2 * 4 * count) {
453
0
        av_log(s->avctx, AV_LOG_ERROR, "encoded frame too large\n");
454
0
        return -1;
455
0
    }
456
457
1.25M
#define LOAD4\
458
4.77M
            int y0 = y[2 * i];\
459
4.77M
            int y1 = y[2 * i + 1];\
460
4.77M
            int u0 = u[i];\
461
4.77M
            int v0 = v[i];
462
463
1.25M
    count /= 2;
464
465
1.25M
    if (s->flags & AV_CODEC_FLAG_PASS1) {
466
0
        for(i = 0; i < count; i++) {
467
0
            LOAD4;
468
0
            s->stats[0][y0]++;
469
0
            s->stats[1][u0]++;
470
0
            s->stats[0][y1]++;
471
0
            s->stats[2][v0]++;
472
0
        }
473
0
    }
474
1.25M
    if (s->avctx->flags2 & AV_CODEC_FLAG2_NO_OUTPUT)
475
0
        return 0;
476
1.25M
    if (s->context) {
477
0
        for (i = 0; i < count; i++) {
478
0
            LOAD4;
479
0
            s->stats[0][y0]++;
480
0
            put_bits(&s->pb, s->len[0][y0], s->bits[0][y0]);
481
0
            s->stats[1][u0]++;
482
0
            put_bits(&s->pb, s->len[1][u0], s->bits[1][u0]);
483
0
            s->stats[0][y1]++;
484
0
            put_bits(&s->pb, s->len[0][y1], s->bits[0][y1]);
485
0
            s->stats[2][v0]++;
486
0
            put_bits(&s->pb, s->len[2][v0], s->bits[2][v0]);
487
0
        }
488
1.25M
    } else {
489
6.03M
        for(i = 0; i < count; i++) {
490
4.77M
            LOAD4;
491
4.77M
            put_bits(&s->pb, s->len[0][y0], s->bits[0][y0]);
492
4.77M
            put_bits(&s->pb, s->len[1][u0], s->bits[1][u0]);
493
4.77M
            put_bits(&s->pb, s->len[0][y1], s->bits[0][y1]);
494
4.77M
            put_bits(&s->pb, s->len[2][v0], s->bits[2][v0]);
495
4.77M
        }
496
1.25M
    }
497
1.25M
    return 0;
498
1.25M
}
499
500
static int encode_plane_bitstream(HYuvEncContext *s, int width, int plane)
501
6.26M
{
502
6.26M
    int count = width/2;
503
504
6.26M
    if (put_bytes_left(&s->pb, 0) < count * s->bps / 2) {
505
0
        av_log(s->avctx, AV_LOG_ERROR, "encoded frame too large\n");
506
0
        return -1;
507
0
    }
508
509
6.26M
#define LOADEND\
510
6.26M
            int y0 = s->temp[0][width-1];
511
6.26M
#define LOADEND_14\
512
6.26M
            int y0 = s->temp16[0][width-1] & mask;
513
6.26M
#define LOADEND_16\
514
6.26M
            int y0 = s->temp16[0][width-1];
515
6.26M
#define STATEND\
516
6.26M
            s->stats[plane][y0]++;
517
6.26M
#define STATEND_16\
518
6.26M
            s->stats[plane][y0>>2]++;
519
6.26M
#define WRITEEND\
520
6.26M
            put_bits(&s->pb, s->len[plane][y0], s->bits[plane][y0]);
521
6.26M
#define WRITEEND_16\
522
6.26M
            put_bits(&s->pb, s->len[plane][y0>>2], s->bits[plane][y0>>2]);\
523
6.26M
            put_bits(&s->pb, 2, y0&3);
524
525
6.26M
#define LOAD2\
526
6.26M
            int y0 = s->temp[0][2 * i];\
527
6.26M
            int y1 = s->temp[0][2 * i + 1];
528
6.26M
#define LOAD2_14\
529
6.26M
            int y0 = s->temp16[0][2 * i] & mask;\
530
6.26M
            int y1 = s->temp16[0][2 * i + 1] & mask;
531
6.26M
#define LOAD2_16\
532
6.26M
            int y0 = s->temp16[0][2 * i];\
533
6.26M
            int y1 = s->temp16[0][2 * i + 1];
534
6.26M
#define STAT2\
535
6.26M
            s->stats[plane][y0]++;\
536
6.26M
            s->stats[plane][y1]++;
537
6.26M
#define STAT2_16\
538
6.26M
            s->stats[plane][y0>>2]++;\
539
6.26M
            s->stats[plane][y1>>2]++;
540
6.26M
#define WRITE2\
541
6.26M
            put_bits(&s->pb, s->len[plane][y0], s->bits[plane][y0]);\
542
6.26M
            put_bits(&s->pb, s->len[plane][y1], s->bits[plane][y1]);
543
6.26M
#define WRITE2_16\
544
6.26M
            put_bits(&s->pb, s->len[plane][y0>>2], s->bits[plane][y0>>2]);\
545
6.26M
            put_bits(&s->pb, 2, y0&3);\
546
6.26M
            put_bits(&s->pb, s->len[plane][y1>>2], s->bits[plane][y1>>2]);\
547
6.26M
            put_bits(&s->pb, 2, y1&3);
548
549
6.26M
#define ENCODE_PLANE(LOAD, LOADEND, WRITE, WRITEEND, STAT, STATEND)   \
550
6.26M
do {                                                                  \
551
6.26M
    if (s->flags & AV_CODEC_FLAG_PASS1) {                             \
552
0
        for (int i = 0; i < count; i++) {                             \
553
0
            LOAD;                                                     \
554
0
            STAT;                                                     \
555
0
        }                                                             \
556
0
        if (width & 1) {                                              \
557
0
            LOADEND;                                                  \
558
0
            STATEND;                                                  \
559
0
        }                                                             \
560
0
    }                                                                 \
561
6.26M
    if (s->avctx->flags2 & AV_CODEC_FLAG2_NO_OUTPUT)                  \
562
6.26M
        return 0;                                                     \
563
6.26M
                                                                      \
564
6.26M
    if (s->context) {                                                 \
565
0
        for (int i = 0; i < count; i++) {                             \
566
0
            LOAD;                                                     \
567
0
            STAT;                                                     \
568
0
            WRITE;                                                    \
569
0
        }                                                             \
570
0
        if (width & 1) {                                              \
571
0
            LOADEND;                                                  \
572
0
            STATEND;                                                  \
573
0
            WRITEEND;                                                 \
574
0
        }                                                             \
575
6.26M
    } else {                                                          \
576
21.5M
        for (int i = 0; i < count; i++) {                             \
577
15.2M
            LOAD;                                                     \
578
15.2M
            WRITE;                                                    \
579
15.2M
        }                                                             \
580
6.26M
        if (width & 1) {                                              \
581
3.60M
            LOADEND;                                                  \
582
3.60M
            WRITEEND;                                                 \
583
3.60M
        }                                                             \
584
6.26M
    }                                                                 \
585
6.26M
} while (0)
586
587
6.26M
    if (s->bps <= 8) {
588
976k
        ENCODE_PLANE(LOAD2, LOADEND, WRITE2, WRITEEND, STAT2, STATEND);
589
5.28M
    } else if (s->bps <= 14) {
590
2.32M
        int mask = s->n - 1;
591
592
2.32M
        ENCODE_PLANE(LOAD2_14, LOADEND_14, WRITE2, WRITEEND, STAT2, STATEND);
593
2.96M
    } else {
594
2.96M
        ENCODE_PLANE(LOAD2_16, LOADEND_16, WRITE2_16, WRITEEND_16, STAT2_16, STATEND_16);
595
2.96M
    }
596
6.26M
#undef LOAD2
597
6.26M
#undef STAT2
598
6.26M
#undef WRITE2
599
6.26M
    return 0;
600
6.26M
}
601
602
static int encode_gray_bitstream(HYuvEncContext *s, int count)
603
383k
{
604
383k
    int i;
605
606
383k
    if (put_bytes_left(&s->pb, 0) < 4 * count) {
607
0
        av_log(s->avctx, AV_LOG_ERROR, "encoded frame too large\n");
608
0
        return -1;
609
0
    }
610
611
383k
#define LOAD2\
612
1.49M
            int y0 = s->temp[0][2 * i];\
613
1.49M
            int y1 = s->temp[0][2 * i + 1];
614
383k
#define STAT2\
615
383k
            s->stats[0][y0]++;\
616
0
            s->stats[0][y1]++;
617
383k
#define WRITE2\
618
1.49M
            put_bits(&s->pb, s->len[0][y0], s->bits[0][y0]);\
619
1.49M
            put_bits(&s->pb, s->len[0][y1], s->bits[0][y1]);
620
621
383k
    count /= 2;
622
623
383k
    if (s->flags & AV_CODEC_FLAG_PASS1) {
624
0
        for (i = 0; i < count; i++) {
625
0
            LOAD2;
626
0
            STAT2;
627
0
        }
628
0
    }
629
383k
    if (s->avctx->flags2 & AV_CODEC_FLAG2_NO_OUTPUT)
630
0
        return 0;
631
632
383k
    if (s->context) {
633
0
        for (i = 0; i < count; i++) {
634
0
            LOAD2;
635
0
            STAT2;
636
0
            WRITE2;
637
0
        }
638
383k
    } else {
639
1.87M
        for (i = 0; i < count; i++) {
640
1.49M
            LOAD2;
641
1.49M
            WRITE2;
642
1.49M
        }
643
383k
    }
644
383k
    return 0;
645
383k
}
646
647
static inline int encode_bgra_bitstream(HYuvEncContext *s, int count, int planes)
648
2.56M
{
649
2.56M
    int i;
650
651
2.56M
    if (put_bytes_left(&s->pb, 0) < 4 * planes * count) {
652
37
        av_log(s->avctx, AV_LOG_ERROR, "encoded frame too large\n");
653
37
        return -1;
654
37
    }
655
656
2.56M
#define LOAD_GBRA                                                       \
657
22.2M
    int g = s->temp[0][planes == 3 ? 3 * i + 1 : 4 * i + G];            \
658
22.2M
    int b =(s->temp[0][planes == 3 ? 3 * i + 2 : 4 * i + B] - g) & 0xFF;\
659
22.2M
    int r =(s->temp[0][planes == 3 ? 3 * i + 0 : 4 * i + R] - g) & 0xFF;\
660
22.2M
    int a = s->temp[0][planes * i + A];
661
662
2.56M
#define STAT_BGRA                                                       \
663
2.56M
    s->stats[0][b]++;                                                   \
664
0
    s->stats[1][g]++;                                                   \
665
0
    s->stats[2][r]++;                                                   \
666
0
    if (planes == 4)                                                    \
667
0
        s->stats[2][a]++;
668
669
2.56M
#define WRITE_GBRA                                                      \
670
22.2M
    put_bits(&s->pb, s->len[1][g], s->bits[1][g]);                      \
671
22.2M
    put_bits(&s->pb, s->len[0][b], s->bits[0][b]);                      \
672
22.2M
    put_bits(&s->pb, s->len[2][r], s->bits[2][r]);                      \
673
22.2M
    if (planes == 4)                                                    \
674
22.2M
        put_bits(&s->pb, s->len[2][a], s->bits[2][a]);
675
676
2.56M
    if ((s->flags & AV_CODEC_FLAG_PASS1) &&
677
0
        (s->avctx->flags2 & AV_CODEC_FLAG2_NO_OUTPUT)) {
678
0
        for (i = 0; i < count; i++) {
679
0
            LOAD_GBRA;
680
0
            STAT_BGRA;
681
0
        }
682
2.56M
    } else if (s->context || (s->flags & AV_CODEC_FLAG_PASS1)) {
683
0
        for (i = 0; i < count; i++) {
684
0
            LOAD_GBRA;
685
0
            STAT_BGRA;
686
0
            WRITE_GBRA;
687
0
        }
688
2.56M
    } else {
689
24.8M
        for (i = 0; i < count; i++) {
690
22.2M
            LOAD_GBRA;
691
22.2M
            WRITE_GBRA;
692
22.2M
        }
693
2.56M
    }
694
2.56M
    return 0;
695
2.56M
}
696
697
static int encode_frame(AVCodecContext *avctx, AVPacket *pkt,
698
                        const AVFrame *p, int *got_packet)
699
20.5k
{
700
20.5k
    HYuvEncContext *s = avctx->priv_data;
701
20.5k
    const int width = avctx->width;
702
20.5k
    const int width2 = avctx->width >> 1;
703
20.5k
    const int height = avctx->height;
704
20.5k
    const int fake_ystride = (1 + s->interlaced) * p->linesize[0];
705
20.5k
    const int fake_ustride = (1 + s->interlaced) * p->linesize[1];
706
20.5k
    const int fake_vstride = (1 + s->interlaced) * p->linesize[2];
707
20.5k
    int i, j, size = 0, ret;
708
709
20.5k
    if ((ret = ff_alloc_packet(avctx, pkt, width * height * 3 * 4 + FF_INPUT_BUFFER_MIN_SIZE)) < 0)
710
0
        return ret;
711
712
20.5k
    if (s->context) {
713
0
        size = store_huffman_tables(s, pkt->data);
714
0
        if (size < 0)
715
0
            return size;
716
717
0
        for (i = 0; i < 4; i++)
718
0
            for (j = 0; j < s->vlc_n; j++)
719
0
                s->stats[i][j] >>= 1;
720
0
    }
721
722
20.5k
    init_put_bits(&s->pb, pkt->data + size, pkt->size - size);
723
724
20.5k
    if (avctx->pix_fmt == AV_PIX_FMT_YUV422P ||
725
19.0k
        avctx->pix_fmt == AV_PIX_FMT_YUV420P) {
726
2.63k
        int lefty, leftu, leftv, y, cy;
727
728
2.63k
        put_bits(&s->pb, 8, leftv = p->data[2][0]);
729
2.63k
        put_bits(&s->pb, 8, lefty = p->data[0][1]);
730
2.63k
        put_bits(&s->pb, 8, leftu = p->data[1][0]);
731
2.63k
        put_bits(&s->pb, 8,         p->data[0][0]);
732
733
2.63k
        lefty = sub_left_prediction(s, s->temp[0], p->data[0], width , 0);
734
2.63k
        leftu = sub_left_prediction(s, s->temp[1], p->data[1], width2, 0);
735
2.63k
        leftv = sub_left_prediction(s, s->temp[2], p->data[2], width2, 0);
736
737
2.63k
        encode_422_bitstream(s, 2, width-2);
738
739
2.63k
        if (s->predictor==MEDIAN) {
740
0
            int lefttopy, lefttopu, lefttopv;
741
0
            cy = y = 1;
742
0
            if (s->interlaced) {
743
0
                lefty = sub_left_prediction(s, s->temp[0], p->data[0] + p->linesize[0], width , lefty);
744
0
                leftu = sub_left_prediction(s, s->temp[1], p->data[1] + p->linesize[1], width2, leftu);
745
0
                leftv = sub_left_prediction(s, s->temp[2], p->data[2] + p->linesize[2], width2, leftv);
746
747
0
                encode_422_bitstream(s, 0, width);
748
0
                y++; cy++;
749
0
            }
750
751
0
            lefty = sub_left_prediction(s, s->temp[0], p->data[0] + fake_ystride, 4, lefty);
752
0
            leftu = sub_left_prediction(s, s->temp[1], p->data[1] + fake_ustride, 2, leftu);
753
0
            leftv = sub_left_prediction(s, s->temp[2], p->data[2] + fake_vstride, 2, leftv);
754
755
0
            encode_422_bitstream(s, 0, 4);
756
757
0
            lefttopy = p->data[0][3];
758
0
            lefttopu = p->data[1][1];
759
0
            lefttopv = p->data[2][1];
760
0
            s->llvidencdsp.sub_median_pred(s->temp[0], p->data[0] + 4, p->data[0] + fake_ystride + 4, width  - 4, &lefty, &lefttopy);
761
0
            s->llvidencdsp.sub_median_pred(s->temp[1], p->data[1] + 2, p->data[1] + fake_ustride + 2, width2 - 2, &leftu, &lefttopu);
762
0
            s->llvidencdsp.sub_median_pred(s->temp[2], p->data[2] + 2, p->data[2] + fake_vstride + 2, width2 - 2, &leftv, &lefttopv);
763
0
            encode_422_bitstream(s, 0, width - 4);
764
0
            y++; cy++;
765
766
0
            for (; y < height; y++,cy++) {
767
0
                const uint8_t *ydst, *udst, *vdst;
768
769
0
                if (s->bitstream_bpp == 12) {
770
0
                    while (2 * cy > y) {
771
0
                        ydst = p->data[0] + p->linesize[0] * y;
772
0
                        s->llvidencdsp.sub_median_pred(s->temp[0], ydst - fake_ystride, ydst, width, &lefty, &lefttopy);
773
0
                        encode_gray_bitstream(s, width);
774
0
                        y++;
775
0
                    }
776
0
                    if (y >= height) break;
777
0
                }
778
0
                ydst = p->data[0] + p->linesize[0] * y;
779
0
                udst = p->data[1] + p->linesize[1] * cy;
780
0
                vdst = p->data[2] + p->linesize[2] * cy;
781
782
0
                s->llvidencdsp.sub_median_pred(s->temp[0], ydst - fake_ystride, ydst, width,  &lefty, &lefttopy);
783
0
                s->llvidencdsp.sub_median_pred(s->temp[1], udst - fake_ustride, udst, width2, &leftu, &lefttopu);
784
0
                s->llvidencdsp.sub_median_pred(s->temp[2], vdst - fake_vstride, vdst, width2, &leftv, &lefttopv);
785
786
0
                encode_422_bitstream(s, 0, width);
787
0
            }
788
2.63k
        } else {
789
1.25M
            for (cy = y = 1; y < height; y++, cy++) {
790
1.25M
                const uint8_t *ydst, *udst, *vdst;
791
792
                /* encode a luma only line & y++ */
793
1.25M
                if (s->bitstream_bpp == 12) {
794
383k
                    ydst = p->data[0] + p->linesize[0] * y;
795
796
383k
                    if (s->predictor == PLANE && s->interlaced < y) {
797
0
                        s->llvidencdsp.diff_bytes(s->temp[1], ydst, ydst - fake_ystride, width);
798
799
0
                        lefty = sub_left_prediction(s, s->temp[0], s->temp[1], width , lefty);
800
383k
                    } else {
801
383k
                        lefty = sub_left_prediction(s, s->temp[0], ydst, width , lefty);
802
383k
                    }
803
383k
                    encode_gray_bitstream(s, width);
804
383k
                    y++;
805
383k
                    if (y >= height) break;
806
383k
                }
807
808
1.25M
                ydst = p->data[0] + p->linesize[0] * y;
809
1.25M
                udst = p->data[1] + p->linesize[1] * cy;
810
1.25M
                vdst = p->data[2] + p->linesize[2] * cy;
811
812
1.25M
                if (s->predictor == PLANE && s->interlaced < cy) {
813
0
                    s->llvidencdsp.diff_bytes(s->temp[1],          ydst, ydst - fake_ystride, width);
814
0
                    s->llvidencdsp.diff_bytes(s->temp[2],          udst, udst - fake_ustride, width2);
815
0
                    s->llvidencdsp.diff_bytes(s->temp[2] + width2, vdst, vdst - fake_vstride, width2);
816
817
0
                    lefty = sub_left_prediction(s, s->temp[0], s->temp[1], width , lefty);
818
0
                    leftu = sub_left_prediction(s, s->temp[1], s->temp[2], width2, leftu);
819
0
                    leftv = sub_left_prediction(s, s->temp[2], s->temp[2] + width2, width2, leftv);
820
1.25M
                } else {
821
1.25M
                    lefty = sub_left_prediction(s, s->temp[0], ydst, width , lefty);
822
1.25M
                    leftu = sub_left_prediction(s, s->temp[1], udst, width2, leftu);
823
1.25M
                    leftv = sub_left_prediction(s, s->temp[2], vdst, width2, leftv);
824
1.25M
                }
825
826
1.25M
                encode_422_bitstream(s, 0, width);
827
1.25M
            }
828
2.63k
        }
829
17.8k
    } else if(avctx->pix_fmt == AV_PIX_FMT_RGB32) {
830
13.2k
        const uint8_t *data = p->data[0] + (height - 1) * p->linesize[0];
831
13.2k
        const int stride = -p->linesize[0];
832
13.2k
        const int fake_stride = -fake_ystride;
833
13.2k
        int leftr, leftg, leftb, lefta;
834
835
13.2k
        put_bits(&s->pb, 8, lefta = data[A]);
836
13.2k
        put_bits(&s->pb, 8, leftr = data[R]);
837
13.2k
        put_bits(&s->pb, 8, leftg = data[G]);
838
13.2k
        put_bits(&s->pb, 8, leftb = data[B]);
839
840
13.2k
        sub_left_prediction_bgr32(s, s->temp[0], data + 4, width - 1,
841
13.2k
                                  &leftr, &leftg, &leftb, &lefta);
842
13.2k
        encode_bgra_bitstream(s, width - 1, 4);
843
844
1.23M
        for (int y = 1; y < height; y++) {
845
1.21M
            const uint8_t *dst = data + y*stride;
846
1.21M
            if (s->predictor == PLANE && s->interlaced < y) {
847
0
                s->llvidencdsp.diff_bytes(s->temp[1], dst, dst - fake_stride, width * 4);
848
0
                sub_left_prediction_bgr32(s, s->temp[0], s->temp[1], width,
849
0
                                          &leftr, &leftg, &leftb, &lefta);
850
1.21M
            } else {
851
1.21M
                sub_left_prediction_bgr32(s, s->temp[0], dst, width,
852
1.21M
                                          &leftr, &leftg, &leftb, &lefta);
853
1.21M
            }
854
1.21M
            encode_bgra_bitstream(s, width, 4);
855
1.21M
        }
856
13.2k
    } else if (avctx->pix_fmt == AV_PIX_FMT_RGB24) {
857
1.05k
        const uint8_t *data = p->data[0] + (height - 1) * p->linesize[0];
858
1.05k
        const int stride = -p->linesize[0];
859
1.05k
        const int fake_stride = -fake_ystride;
860
1.05k
        int leftr, leftg, leftb;
861
862
1.05k
        put_bits(&s->pb, 8, leftr = data[0]);
863
1.05k
        put_bits(&s->pb, 8, leftg = data[1]);
864
1.05k
        put_bits(&s->pb, 8, leftb = data[2]);
865
1.05k
        put_bits(&s->pb, 8, 0);
866
867
1.05k
        sub_left_prediction_rgb24(s, s->temp[0], data + 3, width - 1,
868
1.05k
                                  &leftr, &leftg, &leftb);
869
1.05k
        encode_bgra_bitstream(s, width-1, 3);
870
871
1.33M
        for (int y = 1; y < height; y++) {
872
1.32M
            const uint8_t *dst = data + y * stride;
873
1.32M
            if (s->predictor == PLANE && s->interlaced < y) {
874
0
                s->llvidencdsp.diff_bytes(s->temp[1], dst, dst - fake_stride,
875
0
                                      width * 3);
876
0
                sub_left_prediction_rgb24(s, s->temp[0], s->temp[1], width,
877
0
                                          &leftr, &leftg, &leftb);
878
1.32M
            } else {
879
1.32M
                sub_left_prediction_rgb24(s, s->temp[0], dst, width,
880
1.32M
                                          &leftr, &leftg, &leftb);
881
1.32M
            }
882
1.32M
            encode_bgra_bitstream(s, width, 3);
883
1.32M
        }
884
3.55k
    } else if (s->version > 2) {
885
3.55k
        int plane;
886
10.5k
        for (plane = 0; plane < 1 + 2*s->chroma + s->alpha; plane++) {
887
7.01k
            int left, y;
888
7.01k
            int w = width;
889
7.01k
            int h = height;
890
7.01k
            int fake_stride = fake_ystride;
891
892
7.01k
            if (s->chroma && (plane == 1 || plane == 2)) {
893
2.89k
                w >>= s->chroma_h_shift;
894
2.89k
                h >>= s->chroma_v_shift;
895
2.89k
                fake_stride = plane == 1 ? fake_ustride : fake_vstride;
896
2.89k
            }
897
898
7.01k
            left = sub_left_prediction(s, s->temp[0], p->data[plane], w , 0);
899
900
7.01k
            encode_plane_bitstream(s, w, plane);
901
902
7.01k
            if (s->predictor==MEDIAN) {
903
0
                int lefttop;
904
0
                y = 1;
905
0
                if (s->interlaced) {
906
0
                    left = sub_left_prediction(s, s->temp[0], p->data[plane] + p->linesize[plane], w , left);
907
908
0
                    encode_plane_bitstream(s, w, plane);
909
0
                    y++;
910
0
                }
911
912
0
                lefttop = p->data[plane][0];
913
914
0
                for (; y < h; y++) {
915
0
                    const uint8_t *dst = p->data[plane] + p->linesize[plane] * y;
916
917
0
                    sub_median_prediction(s, s->temp[0], dst - fake_stride, dst, w , &left, &lefttop);
918
919
0
                    encode_plane_bitstream(s, w, plane);
920
0
                }
921
7.01k
            } else {
922
6.26M
                for (y = 1; y < h; y++) {
923
6.25M
                    const uint8_t *dst = p->data[plane] + p->linesize[plane] * y;
924
925
6.25M
                    if (s->predictor == PLANE && s->interlaced < y) {
926
0
                        diff_bytes(s, s->temp[1], dst, dst - fake_stride, w);
927
928
0
                        left = sub_left_prediction(s, s->temp[0], s->temp[1], w , left);
929
6.25M
                    } else {
930
6.25M
                        left = sub_left_prediction(s, s->temp[0], dst, w , left);
931
6.25M
                    }
932
933
6.25M
                    encode_plane_bitstream(s, w, plane);
934
6.25M
                }
935
7.01k
            }
936
7.01k
        }
937
3.55k
    } else {
938
0
        av_log(avctx, AV_LOG_ERROR, "Format not supported!\n");
939
0
    }
940
20.5k
    emms_c();
941
942
20.5k
    size += (put_bits_count(&s->pb) + 31) / 8;
943
20.5k
    put_bits(&s->pb, 16, 0);
944
20.5k
    put_bits(&s->pb, 15, 0);
945
20.5k
    size /= 4;
946
947
20.5k
    if ((s->flags & AV_CODEC_FLAG_PASS1) && (s->picture_number & 31) == 0) {
948
0
        int j;
949
0
        char *p = avctx->stats_out;
950
0
        char *end = p + STATS_OUT_SIZE;
951
0
        for (i = 0; i < 4; i++) {
952
0
            for (j = 0; j < s->vlc_n; j++) {
953
0
                snprintf(p, end-p, "%"PRIu64" ", s->stats[i][j]);
954
0
                p += strlen(p);
955
0
                s->stats[i][j]= 0;
956
0
            }
957
0
            snprintf(p, end-p, "\n");
958
0
            p++;
959
0
            if (end <= p)
960
0
                return AVERROR(ENOMEM);
961
0
        }
962
20.5k
    } else if (avctx->stats_out)
963
0
        avctx->stats_out[0] = '\0';
964
20.5k
    if (!(s->avctx->flags2 & AV_CODEC_FLAG2_NO_OUTPUT)) {
965
20.5k
        flush_put_bits(&s->pb);
966
20.5k
        s->bdsp.bswap_buf((uint32_t *) pkt->data, (uint32_t *) pkt->data, size);
967
20.5k
    }
968
969
20.5k
    s->picture_number++;
970
971
20.5k
    pkt->size   = size * 4;
972
20.5k
    *got_packet = 1;
973
974
20.5k
    return 0;
975
20.5k
}
976
977
static av_cold int encode_end(AVCodecContext *avctx)
978
947
{
979
947
    HYuvEncContext *s = avctx->priv_data;
980
981
947
    av_freep(&avctx->stats_out);
982
983
3.78k
    for (int i = 0; i < 3; i++)
984
2.84k
        av_freep(&s->temp[i]);
985
986
947
    return 0;
987
947
}
988
989
#define OFFSET(x) offsetof(HYuvEncContext, x)
990
#define VE AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_ENCODING_PARAM
991
992
static const AVOption options[] = {
993
    /* ffvhuff-only options */
994
    { "context", "Set per-frame huffman tables", OFFSET(context), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 1, VE },
995
    /* Common options */
996
    { "non_deterministic", "Allow multithreading for e.g. context=1 at the expense of determinism",
997
      OFFSET(non_determ), AV_OPT_TYPE_BOOL, { .i64 = 0 },
998
      0, 1, VE },
999
    { "pred", "Prediction method", OFFSET(predictor), AV_OPT_TYPE_INT, { .i64 = LEFT }, LEFT, MEDIAN, VE, .unit = "pred" },
1000
        { "left",   NULL, 0, AV_OPT_TYPE_CONST, { .i64 = LEFT },   INT_MIN, INT_MAX, VE, .unit = "pred" },
1001
        { "plane",  NULL, 0, AV_OPT_TYPE_CONST, { .i64 = PLANE },  INT_MIN, INT_MAX, VE, .unit = "pred" },
1002
        { "median", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = MEDIAN }, INT_MIN, INT_MAX, VE, .unit = "pred" },
1003
    { NULL },
1004
};
1005
1006
static const AVClass normal_class = {
1007
    .class_name = "huffyuv",
1008
    .item_name  = av_default_item_name,
1009
    .option     = options + 1,
1010
    .version    = LIBAVUTIL_VERSION_INT,
1011
};
1012
1013
const FFCodec ff_huffyuv_encoder = {
1014
    .p.name         = "huffyuv",
1015
    CODEC_LONG_NAME("Huffyuv / HuffYUV"),
1016
    .p.type         = AVMEDIA_TYPE_VIDEO,
1017
    .p.id           = AV_CODEC_ID_HUFFYUV,
1018
    .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_FRAME_THREADS |
1019
                      AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE,
1020
    .priv_data_size = sizeof(HYuvEncContext),
1021
    .init           = encode_init,
1022
    FF_CODEC_ENCODE_CB(encode_frame),
1023
    .close          = encode_end,
1024
    .p.priv_class   = &normal_class,
1025
    CODEC_PIXFMTS(AV_PIX_FMT_YUV422P, AV_PIX_FMT_RGB24, AV_PIX_FMT_RGB32),
1026
    .color_ranges   = AVCOL_RANGE_MPEG,
1027
    .caps_internal  = FF_CODEC_CAP_INIT_CLEANUP,
1028
};
1029
1030
#if CONFIG_FFVHUFF_ENCODER
1031
static const AVClass ff_class = {
1032
    .class_name = "ffvhuff",
1033
    .item_name  = av_default_item_name,
1034
    .option     = options,
1035
    .version    = LIBAVUTIL_VERSION_INT,
1036
};
1037
1038
const FFCodec ff_ffvhuff_encoder = {
1039
    .p.name         = "ffvhuff",
1040
    CODEC_LONG_NAME("Huffyuv FFmpeg variant"),
1041
    .p.type         = AVMEDIA_TYPE_VIDEO,
1042
    .p.id           = AV_CODEC_ID_FFVHUFF,
1043
    .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_FRAME_THREADS |
1044
                      AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE,
1045
    .priv_data_size = sizeof(HYuvEncContext),
1046
    .init           = encode_init,
1047
    FF_CODEC_ENCODE_CB(encode_frame),
1048
    .close          = encode_end,
1049
    .p.priv_class   = &ff_class,
1050
    CODEC_PIXFMTS(
1051
        AV_PIX_FMT_YUV420P, AV_PIX_FMT_YUV422P, AV_PIX_FMT_YUV444P, AV_PIX_FMT_YUV411P,
1052
        AV_PIX_FMT_YUV410P, AV_PIX_FMT_YUV440P,
1053
        AV_PIX_FMT_GBRP,
1054
        AV_PIX_FMT_GBRP9, AV_PIX_FMT_GBRP10, AV_PIX_FMT_GBRP12, AV_PIX_FMT_GBRP14, AV_PIX_FMT_GBRP16,
1055
        AV_PIX_FMT_GRAY8, AV_PIX_FMT_GRAY16,
1056
        AV_PIX_FMT_YUVA420P, AV_PIX_FMT_YUVA422P, AV_PIX_FMT_YUVA444P,
1057
        AV_PIX_FMT_GBRAP,
1058
        AV_PIX_FMT_YUV420P9, AV_PIX_FMT_YUV420P10, AV_PIX_FMT_YUV420P12, AV_PIX_FMT_YUV420P14, AV_PIX_FMT_YUV420P16,
1059
        AV_PIX_FMT_YUV422P9, AV_PIX_FMT_YUV422P10, AV_PIX_FMT_YUV422P12, AV_PIX_FMT_YUV422P14, AV_PIX_FMT_YUV422P16,
1060
        AV_PIX_FMT_YUV444P9, AV_PIX_FMT_YUV444P10, AV_PIX_FMT_YUV444P12, AV_PIX_FMT_YUV444P14, AV_PIX_FMT_YUV444P16,
1061
        AV_PIX_FMT_YUVA420P9, AV_PIX_FMT_YUVA420P10, AV_PIX_FMT_YUVA420P16,
1062
        AV_PIX_FMT_YUVA422P9, AV_PIX_FMT_YUVA422P10, AV_PIX_FMT_YUVA422P16,
1063
        AV_PIX_FMT_YUVA444P9, AV_PIX_FMT_YUVA444P10, AV_PIX_FMT_YUVA444P16,
1064
        AV_PIX_FMT_RGB24,
1065
        AV_PIX_FMT_RGB32),
1066
    .color_ranges   = AVCOL_RANGE_MPEG,
1067
    .caps_internal  = FF_CODEC_CAP_INIT_CLEANUP,
1068
};
1069
#endif