FFmpeg
Loading...
Searching...
No Matches
ffv1enc_template.c
Go to the documentation of this file.
1/*
2 * FFV1 encoder template
3 *
4 * Copyright (c) 2003-2016 Michael Niedermayer <michaelni@gmx.at>
5 *
6 * This file is part of FFmpeg.
7 *
8 * FFmpeg is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License as published by the Free Software Foundation; either
11 * version 2.1 of the License, or (at your option) any later version.
12 *
13 * FFmpeg is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
17 *
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with FFmpeg; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
21 */
22
23#include "ffv1_template.c"
24
25static av_always_inline int
27 void *logctx,
28 int w, TYPE *const sample[3], int plane_index, int bits,
29 int ac, int pass1)
30{
31 PlaneContext *const p = &sc->plane[plane_index];
32 RangeCoder *const c = &sc->c;
33 int x;
34 int run_index = sc->run_index;
35 int run_count = 0;
36 int run_mode = 0;
37
38 if (bits == 0)
39 return 0;
40
41 if (sc->slice_coding_mode == 1) {
43 if (c->bytestream_end - c->bytestream < (w * bits + 7LL)>>3) {
44 av_log(logctx, AV_LOG_ERROR, "encoded Range Coder frame too large\n");
46 }
47
48 for (x = 0; x < w; x++) {
49 int i;
50 int v = sample[0][x];
51 for (i = bits-1; i>=0; i--) {
52 uint8_t state = 128;
53 put_rac(c, &state, (v>>i) & 1);
54 }
55 }
56 return 0;
57 }
58
59 if (ac != AC_GOLOMB_RICE) {
60 if (c->bytestream_end - c->bytestream < w * 35) {
61 av_log(logctx, AV_LOG_ERROR, "encoded Range Coder frame too large\n");
63 }
64 } else {
65 if (put_bytes_left(&sc->pb, 0) < w * 4) {
66 av_log(logctx, AV_LOG_ERROR, "encoded Golomb Rice frame too large\n");
68 }
69 }
70
71 for (x = 0; x < w; x++) {
72 int diff, context;
73
74 context = RENAME(get_context)(f->quant_tables[p->quant_table_index],
75 sample[0] + x, sample[1] + x, sample[2] + x);
76 diff = sample[0][x] - RENAME(predict)(sample[0] + x, sample[1] + x);
77
78 if (context < 0) {
79 context = -context;
80 diff = -diff;
81 }
82
83 diff = fold(diff, bits);
84
85 if (ac != AC_GOLOMB_RICE) {
86 if (pass1) {
87 put_symbol_inline(c, p->state[context], diff, 1, sc->rc_stat,
88 sc->rc_stat2[p->quant_table_index][context]);
89 } else {
90 put_symbol_inline(c, p->state[context], diff, 1, NULL, NULL);
91 }
92 } else {
93 if (context == 0)
94 run_mode = 1;
95
96 if (run_mode) {
97 if (diff) {
98 while (run_count >= 1 << ff_log2_run[run_index]) {
99 run_count -= 1 << ff_log2_run[run_index];
100 run_index++;
101 put_bits(&sc->pb, 1, 1);
102 }
103
104 put_bits(&sc->pb, 1 + ff_log2_run[run_index], run_count);
105 if (run_index)
106 run_index--;
107 run_count = 0;
108 run_mode = 0;
109 if (diff > 0)
110 diff--;
111 } else {
112 run_count++;
113 }
114 }
115
116 ff_dlog(logctx, "count:%d index:%d, mode:%d, x:%d pos:%d\n",
117 run_count, run_index, run_mode, x,
118 (int)put_bits_count(&sc->pb));
119
120 if (run_mode == 0)
121 put_vlc_symbol(&sc->pb, &p->vlc_state[context], diff, bits);
122 }
123 }
124 if (run_mode) {
125 while (run_count >= 1 << ff_log2_run[run_index]) {
126 run_count -= 1 << ff_log2_run[run_index];
127 run_index++;
128 put_bits(&sc->pb, 1, 1);
129 }
130
131 if (run_count)
132 put_bits(&sc->pb, 1, 1);
133 }
134 sc->run_index = run_index;
135
136 return 0;
137}
138
139static void RENAME(load_rgb_frame)(FFV1Context *f, FFV1SliceContext *sc,
140 const uint8_t *src[4],
141 int w, int h, const int stride[4])
142{
143 int x, y;
144 int transparency = f->transparency;
145
146 for (int p = 0; p<3 + transparency; p++)
147 memset(sc->fltmap[p], 0, 65536 * sizeof(**sc->fltmap));
148
149 for (y = 0; y < h; y++) {
150 for (x = 0; x < w; x++) {
151 int b, g, r, av_uninit(a);
152
153 if (sizeof(TYPE) == 4 || transparency) {
154 g = *((const uint16_t *)(src[0] + x*2 + stride[0]*y));
155 b = *((const uint16_t *)(src[1] + x*2 + stride[1]*y));
156 r = *((const uint16_t *)(src[2] + x*2 + stride[2]*y));
157 if (transparency)
158 a = *((const uint16_t *)(src[3] + x*2 + stride[3]*y));
159 } else {
160 b = *((const uint16_t *)(src[0] + x*2 + stride[0]*y));
161 g = *((const uint16_t *)(src[1] + x*2 + stride[1]*y));
162 r = *((const uint16_t *)(src[2] + x*2 + stride[2]*y));
163 }
164
165 sc->fltmap[0][g] = 1;
166 sc->fltmap[1][b] = 1;
167 sc->fltmap[2][r] = 1;
168 if (transparency)
169 sc->fltmap[3][a] = 1;
170 }
171 }
172}
173
174static int RENAME(encode_rgb_frame)(FFV1Context *f, FFV1SliceContext *sc,
175 const uint8_t *src[4],
176 int w, int h, const int stride[4], int ac)
177{
178 int x, y, p, i;
179 const int ring_size = f->context_model ? 3 : 2;
180 TYPE *sample[4][3];
181 const int pass1 = !!(f->avctx->flags & AV_CODEC_FLAG_PASS1);
182 int lbd = f->bits_per_raw_sample <= 8;
183 int packed = !src[1];
184 int bits[4], offset;
185 int transparency = f->transparency;
186 int packed_size = (3 + transparency)*2;
187
188 ff_ffv1_compute_bits_per_plane(f, sc, bits, &offset, NULL, f->bits_per_raw_sample);
189
190 sc->run_index = 0;
191
192 for (int p = 0; p < MAX_PLANES; ++p)
193 sample[p][2] = RENAME(sc->sample_buffer);
194
195 memset(RENAME(sc->sample_buffer), 0, ring_size * MAX_PLANES *
196 (w + 6) * sizeof(*RENAME(sc->sample_buffer)));
197
198 for (y = 0; y < h; y++) {
199 for (i = 0; i < ring_size; i++)
200 for (p = 0; p < MAX_PLANES; p++)
201 sample[p][i]= RENAME(sc->sample_buffer) + p*ring_size*(w+6) + ((h+i-y)%ring_size)*(w+6) + 3;
202
203 for (x = 0; x < w; x++) {
204 int b, g, r, av_uninit(a);
205 if (lbd) {
206 unsigned v = *((const uint32_t*)(src[0] + x*4 + stride[0]*y));
207 b = v & 0xFF;
208 g = (v >> 8) & 0xFF;
209 r = (v >> 16) & 0xFF;
210 a = v >> 24;
211 } else if (packed) {
212 const uint16_t *p = ((const uint16_t*)(src[0] + x*packed_size + stride[0]*y));
213 r = p[0];
214 g = p[1];
215 b = p[2];
216 if (transparency)
217 a = p[3];
218 } else if (sizeof(TYPE) == 4 || transparency) {
219 g = *((const uint16_t *)(src[0] + x*2 + stride[0]*y));
220 b = *((const uint16_t *)(src[1] + x*2 + stride[1]*y));
221 r = *((const uint16_t *)(src[2] + x*2 + stride[2]*y));
222 if (transparency)
223 a = *((const uint16_t *)(src[3] + x*2 + stride[3]*y));
224 } else {
225 b = *((const uint16_t *)(src[0] + x*2 + stride[0]*y));
226 g = *((const uint16_t *)(src[1] + x*2 + stride[1]*y));
227 r = *((const uint16_t *)(src[2] + x*2 + stride[2]*y));
228 }
229
230 if (sc->remap) {
231 g = sc->fltmap[0][g];
232 b = sc->fltmap[1][b];
233 r = sc->fltmap[2][r];
234 if (transparency)
235 a = sc->fltmap[3][a];
236 }
237
238 if (sc->slice_coding_mode != 1) {
239 b -= g;
240 r -= g;
241 g += (b * sc->slice_rct_by_coef + r * sc->slice_rct_ry_coef) >> 2;
242 b += offset;
243 r += offset;
244 }
245
246 sample[0][0][x] = g;
247 sample[1][0][x] = b;
248 sample[2][0][x] = r;
249 sample[3][0][x] = a;
250 }
251 for (p = 0; p < 3 + transparency; p++) {
252 int ret;
253 sample[p][0][-1] = sample[p][1][0 ];
254 sample[p][1][ w] = sample[p][1][w-1];
255 if (bits[p] == 9)
256 ret = RENAME(encode_line)(f, sc, f->avctx, w, sample[p], (p + 1) / 2, 9, ac, pass1);
257 else
258 ret = RENAME(encode_line)(f, sc, f->avctx, w, sample[p], (p + 1) / 2,
259 bits[p], ac, pass1);
260 if (ret < 0)
261 return ret;
262 }
263 }
264 return 0;
265}
static av_always_inline void predict(PredictorState *ps, int *coef, int output_enable)
#define RENAME(element)
static int ring_size(RingBuffer *ring)
Definition async.c:107
#define av_assert0(cond)
assert() equivalent, that is always enabled.
Definition avassert.h:42
#define i(width, name, range_min, range_max)
Definition cbs_h264.c:63
#define f(width, name)
Definition cbs_vp8.c:236
#define NULL
Definition coverity.c:32
static struct @346255127015250356166251341105367306144006377143 state
static const uint8_t bits[8]
Definition fastaudio.c:100
void ff_ffv1_compute_bits_per_plane(const FFV1Context *f, FFV1SliceContext *sc, int bits[4], int *offset, int mask[4], int bits_per_raw_sample)
Definition ffv1.c:224
#define MAX_PLANES
Definition ffv1.h:44
#define AC_GOLOMB_RICE
Definition ffv1.h:52
static av_always_inline int fold(int diff, int bits)
Definition ffv1.h:216
#define TYPE
Definition ffv1dec.c:90
static void put_vlc_symbol(PutBitContext *pb, VlcState *const state, int v, int bits)
Definition ffv1enc.c:240
#define put_rac(C, S, B)
static av_always_inline av_flatten void put_symbol_inline(RangeCoder *c, uint8_t *state, int v, int is_signed, uint64_t rc_stat[256][2], uint64_t rc_stat2[32][2])
Definition ffv1enc.c:185
#define sample
#define AV_CODEC_FLAG_PASS1
Use internal 2pass ratecontrol in first pass mode.
Definition avcodec.h:290
#define AVERROR_INVALIDDATA
Invalid data found when processing input.
Definition error.h:61
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition log.h:210
int a
#define r
Definition input.c:42
#define b
Definition input.c:43
static void put_bits(Jpeg2000EncoderContext *s, int val, int n)
put n times val bit
Definition j2kenc.c:154
unsigned offset
Definition libaomenc.c:763
#define av_always_inline
Definition attributes.h:72
#define av_uninit(x)
Definition attributes.h:187
uint8_t w
Definition llvidencdsp.c:39
const uint8_t ff_log2_run[41]
Definition mathtables.c:155
static void encode_line(AVCodecContext *avctx, uint8_t **data, const uint8_t *line, int length)
Definition msrleenc.c:142
static int put_bits_count(PutBitContext *s)
Definition put_bits.h:90
static int put_bytes_left(const PutBitContext *s, int round_up)
Definition put_bits.h:145
#define stride
#define ff_dlog(a,...)
#define av_log(a,...)
#define src
Definition vp8dsp.c:248
const char * g
Definition vf_curves.c:128
static av_always_inline int diff(const struct color_info *a, const struct color_info *b, const int trans_thresh)
static double c[64]