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 |
|
3097200 |
static av_always_inline int RENAME(encode_line)(FFV1Context *s, int w, |
24 |
|
|
TYPE *sample[3], |
25 |
|
|
int plane_index, int bits) |
26 |
|
|
{ |
27 |
|
3097200 |
PlaneContext *const p = &s->plane[plane_index]; |
28 |
|
3097200 |
RangeCoder *const c = &s->c; |
29 |
|
|
int x; |
30 |
|
3097200 |
int run_index = s->run_index; |
31 |
|
3097200 |
int run_count = 0; |
32 |
|
3097200 |
int run_mode = 0; |
33 |
|
|
|
34 |
✓✓ |
3097200 |
if (s->ac != AC_GOLOMB_RICE) { |
35 |
✗✓ |
1659600 |
if (c->bytestream_end - c->bytestream < w * 35) { |
36 |
|
|
av_log(s->avctx, AV_LOG_ERROR, "encoded frame too large\n"); |
37 |
|
|
return AVERROR_INVALIDDATA; |
38 |
|
|
} |
39 |
|
|
} else { |
40 |
✗✓ |
1437600 |
if (put_bytes_left(&s->pb, 0) < w * 4) { |
41 |
|
|
av_log(s->avctx, AV_LOG_ERROR, "encoded frame too large\n"); |
42 |
|
|
return AVERROR_INVALIDDATA; |
43 |
|
|
} |
44 |
|
|
} |
45 |
|
|
|
46 |
✗✓ |
3097200 |
if (s->slice_coding_mode == 1) { |
47 |
|
|
for (x = 0; x < w; x++) { |
48 |
|
|
int i; |
49 |
|
|
int v = sample[0][x]; |
50 |
|
|
for (i = bits-1; i>=0; i--) { |
51 |
|
|
uint8_t state = 128; |
52 |
|
|
put_rac(c, &state, (v>>i) & 1); |
53 |
|
|
} |
54 |
|
|
} |
55 |
|
|
return 0; |
56 |
|
|
} |
57 |
|
|
|
58 |
✓✓ |
494740200 |
for (x = 0; x < w; x++) { |
59 |
|
|
int diff, context; |
60 |
|
|
|
61 |
|
491643000 |
context = RENAME(get_context)(p, sample[0] + x, sample[1] + x, sample[2] + x); |
62 |
|
491643000 |
diff = sample[0][x] - RENAME(predict)(sample[0] + x, sample[1] + x); |
63 |
|
|
|
64 |
✓✓ |
491643000 |
if (context < 0) { |
65 |
|
194838466 |
context = -context; |
66 |
|
194838466 |
diff = -diff; |
67 |
|
|
} |
68 |
|
|
|
69 |
|
491643000 |
diff = fold(diff, bits); |
70 |
|
|
|
71 |
✓✓ |
491643000 |
if (s->ac != AC_GOLOMB_RICE) { |
72 |
✗✓ |
262666000 |
if (s->flags & AV_CODEC_FLAG_PASS1) { |
73 |
|
|
put_symbol_inline(c, p->state[context], diff, 1, s->rc_stat, |
74 |
|
|
s->rc_stat2[p->quant_table_index][context]); |
75 |
|
|
} else { |
76 |
|
262666000 |
put_symbol_inline(c, p->state[context], diff, 1, NULL, NULL); |
77 |
|
|
} |
78 |
|
|
} else { |
79 |
✓✓ |
228977000 |
if (context == 0) |
80 |
|
5982346 |
run_mode = 1; |
81 |
|
|
|
82 |
✓✓ |
228977000 |
if (run_mode) { |
83 |
✓✓ |
9646060 |
if (diff) { |
84 |
✓✓ |
5032674 |
while (run_count >= 1 << ff_log2_run[run_index]) { |
85 |
|
2388242 |
run_count -= 1 << ff_log2_run[run_index]; |
86 |
|
2388242 |
run_index++; |
87 |
|
2388242 |
put_bits(&s->pb, 1, 1); |
88 |
|
|
} |
89 |
|
|
|
90 |
|
2644432 |
put_bits(&s->pb, 1 + ff_log2_run[run_index], run_count); |
91 |
✓✓ |
2644432 |
if (run_index) |
92 |
|
2442634 |
run_index--; |
93 |
|
2644432 |
run_count = 0; |
94 |
|
2644432 |
run_mode = 0; |
95 |
✓✓ |
2644432 |
if (diff > 0) |
96 |
|
1234600 |
diff--; |
97 |
|
|
} else { |
98 |
|
7001628 |
run_count++; |
99 |
|
|
} |
100 |
|
|
} |
101 |
|
|
|
102 |
|
|
ff_dlog(s->avctx, "count:%d index:%d, mode:%d, x:%d pos:%d\n", |
103 |
|
|
run_count, run_index, run_mode, x, |
104 |
|
|
(int)put_bits_count(&s->pb)); |
105 |
|
|
|
106 |
✓✓ |
228977000 |
if (run_mode == 0) |
107 |
|
221975372 |
put_vlc_symbol(&s->pb, &p->vlc_state[context], diff, bits); |
108 |
|
|
} |
109 |
|
|
} |
110 |
✓✓ |
3097200 |
if (run_mode) { |
111 |
✓✓ |
179600 |
while (run_count >= 1 << ff_log2_run[run_index]) { |
112 |
|
75690 |
run_count -= 1 << ff_log2_run[run_index]; |
113 |
|
75690 |
run_index++; |
114 |
|
75690 |
put_bits(&s->pb, 1, 1); |
115 |
|
|
} |
116 |
|
|
|
117 |
✓✓ |
103910 |
if (run_count) |
118 |
|
68520 |
put_bits(&s->pb, 1, 1); |
119 |
|
|
} |
120 |
|
3097200 |
s->run_index = run_index; |
121 |
|
|
|
122 |
|
3097200 |
return 0; |
123 |
|
|
} |
124 |
|
|
|
125 |
|
1600 |
static int RENAME(encode_rgb_frame)(FFV1Context *s, const uint8_t *src[4], |
126 |
|
|
int w, int h, const int stride[4]) |
127 |
|
|
{ |
128 |
|
|
int x, y, p, i; |
129 |
|
1600 |
const int ring_size = s->context_model ? 3 : 2; |
130 |
|
|
TYPE *sample[4][3]; |
131 |
|
1600 |
int lbd = s->bits_per_raw_sample <= 8; |
132 |
|
1600 |
int packed = !src[1]; |
133 |
|
1600 |
int bits = s->bits_per_raw_sample > 0 ? s->bits_per_raw_sample : 8; |
134 |
|
1600 |
int offset = 1 << bits; |
135 |
|
1600 |
int transparency = s->transparency; |
136 |
|
1600 |
int packed_size = (3 + transparency)*2; |
137 |
|
|
|
138 |
|
1600 |
s->run_index = 0; |
139 |
|
|
|
140 |
|
1600 |
memset(RENAME(s->sample_buffer), 0, ring_size * MAX_PLANES * |
141 |
|
1600 |
(w + 6) * sizeof(*RENAME(s->sample_buffer))); |
142 |
|
|
|
143 |
|
181200 |
for (y = 0; y < h; y++) { |
144 |
|
538800 |
for (i = 0; i < ring_size; i++) |
145 |
|
1796000 |
for (p = 0; p < MAX_PLANES; p++) |
146 |
|
1436800 |
sample[p][i]= RENAME(s->sample_buffer) + p*ring_size*(w+6) + ((h+i-y)%ring_size)*(w+6) + 3; |
147 |
|
|
|
148 |
|
30708000 |
for (x = 0; x < w; x++) { |
149 |
|
30528400 |
int b, g, r, av_uninit(a); |
150 |
|
30528400 |
if (lbd) { |
151 |
|
15264200 |
unsigned v = *((const uint32_t*)(src[0] + x*4 + stride[0]*y)); |
152 |
|
15264200 |
b = v & 0xFF; |
153 |
|
15264200 |
g = (v >> 8) & 0xFF; |
154 |
|
15264200 |
r = (v >> 16) & 0xFF; |
155 |
|
15264200 |
a = v >> 24; |
156 |
|
15264200 |
} else if (packed) { |
157 |
|
15264200 |
const uint16_t *p = ((const uint16_t*)(src[0] + x*packed_size + stride[0]*y)); |
158 |
|
15264200 |
r = p[0]; |
159 |
|
15264200 |
g = p[1]; |
160 |
|
15264200 |
b = p[2]; |
161 |
|
15264200 |
if (transparency) |
162 |
|
|
a = p[3]; |
163 |
|
|
} else if (sizeof(TYPE) == 4 || transparency) { |
164 |
|
|
g = *((const uint16_t *)(src[0] + x*2 + stride[0]*y)); |
165 |
|
|
b = *((const uint16_t *)(src[1] + x*2 + stride[1]*y)); |
166 |
|
|
r = *((const uint16_t *)(src[2] + x*2 + stride[2]*y)); |
167 |
|
|
if (transparency) |
168 |
|
|
a = *((const uint16_t *)(src[3] + x*2 + stride[3]*y)); |
169 |
|
|
} else { |
170 |
|
|
b = *((const uint16_t *)(src[0] + x*2 + stride[0]*y)); |
171 |
|
|
g = *((const uint16_t *)(src[1] + x*2 + stride[1]*y)); |
172 |
|
|
r = *((const uint16_t *)(src[2] + x*2 + stride[2]*y)); |
173 |
|
|
} |
174 |
|
|
|
175 |
|
30528400 |
if (s->slice_coding_mode != 1) { |
176 |
|
30528400 |
b -= g; |
177 |
|
30528400 |
r -= g; |
178 |
|
30528400 |
g += (b * s->slice_rct_by_coef + r * s->slice_rct_ry_coef) >> 2; |
179 |
|
30528400 |
b += offset; |
180 |
|
30528400 |
r += offset; |
181 |
|
|
} |
182 |
|
|
|
183 |
|
30528400 |
sample[0][0][x] = g; |
184 |
|
30528400 |
sample[1][0][x] = b; |
185 |
|
30528400 |
sample[2][0][x] = r; |
186 |
|
30528400 |
sample[3][0][x] = a; |
187 |
|
|
} |
188 |
|
718400 |
for (p = 0; p < 3 + transparency; p++) { |
189 |
|
|
int ret; |
190 |
|
538800 |
sample[p][0][-1] = sample[p][1][0 ]; |
191 |
|
538800 |
sample[p][1][ w] = sample[p][1][w-1]; |
192 |
|
538800 |
if (lbd && s->slice_coding_mode == 0) |
193 |
|
269400 |
ret = RENAME(encode_line)(s, w, sample[p], (p + 1) / 2, 9); |
194 |
|
|
else |
195 |
|
269400 |
ret = RENAME(encode_line)(s, w, sample[p], (p + 1) / 2, bits + (s->slice_coding_mode != 1)); |
196 |
|
538800 |
if (ret < 0) |
197 |
|
|
return ret; |
198 |
|
|
} |
199 |
|
|
} |
200 |
|
1600 |
return 0; |
201 |
|
|
} |
202 |
|
|
|