Line | Branch | Exec | Source |
---|---|---|---|
1 | /* | ||
2 | * FFV1 decoder | ||
3 | * | ||
4 | * Copyright (c) 2003-2013 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 | /** | ||
24 | * @file | ||
25 | * FF Video Codec 1 (a lossless codec) decoder | ||
26 | */ | ||
27 | |||
28 | #include "libavutil/avassert.h" | ||
29 | #include "libavutil/crc.h" | ||
30 | #include "libavutil/mem.h" | ||
31 | #include "libavutil/imgutils.h" | ||
32 | #include "libavutil/pixdesc.h" | ||
33 | #include "avcodec.h" | ||
34 | #include "codec_internal.h" | ||
35 | #include "get_bits.h" | ||
36 | #include "rangecoder.h" | ||
37 | #include "golomb.h" | ||
38 | #include "mathops.h" | ||
39 | #include "ffv1.h" | ||
40 | #include "progressframe.h" | ||
41 | #include "libavutil/refstruct.h" | ||
42 | #include "thread.h" | ||
43 | #include "decode.h" | ||
44 | |||
45 | 167385877 | static inline int get_vlc_symbol(GetBitContext *gb, VlcState *const state, | |
46 | int bits) | ||
47 | { | ||
48 | int k, i, v, ret; | ||
49 | |||
50 | 167385877 | i = state->count; | |
51 | 167385877 | k = 0; | |
52 |
2/2✓ Branch 0 taken 280052558 times.
✓ Branch 1 taken 167385877 times.
|
447438435 | while (i < state->error_sum) { // FIXME: optimize |
53 | 280052558 | k++; | |
54 | 280052558 | i += i; | |
55 | } | ||
56 | |||
57 | 167385877 | v = get_sr_golomb(gb, k, 12, bits); | |
58 | ff_dlog(NULL, "v:%d bias:%d error:%d drift:%d count:%d k:%d", | ||
59 | v, state->bias, state->error_sum, state->drift, state->count, k); | ||
60 | |||
61 | 167385877 | v ^= ((2 * state->drift + state->count) >> 31); | |
62 | |||
63 | 167385877 | ret = fold(v + state->bias, bits); | |
64 | |||
65 | 167385877 | update_vlc_state(state, v); | |
66 | |||
67 | 167385877 | return ret; | |
68 | } | ||
69 | |||
70 | 4596384 | static int is_input_end(RangeCoder *c, GetBitContext *gb, int ac) | |
71 | { | ||
72 |
2/2✓ Branch 0 taken 2582376 times.
✓ Branch 1 taken 2014008 times.
|
4596384 | if (ac != AC_GOLOMB_RICE) { |
73 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 2582376 times.
|
2582376 | if (c->overread > MAX_OVERREAD) |
74 | ✗ | return AVERROR_INVALIDDATA; | |
75 | } else { | ||
76 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 2014008 times.
|
2014008 | if (get_bits_left(gb) < 1) |
77 | ✗ | return AVERROR_INVALIDDATA; | |
78 | } | ||
79 | 4596384 | return 0; | |
80 | } | ||
81 | |||
82 | #define TYPE int16_t | ||
83 | #define RENAME(name) name | ||
84 | #include "ffv1dec_template.c" | ||
85 | #undef TYPE | ||
86 | #undef RENAME | ||
87 | |||
88 | #define TYPE int32_t | ||
89 | #define RENAME(name) name ## 32 | ||
90 | #include "ffv1dec_template.c" | ||
91 | |||
92 | 18249 | static int decode_plane(FFV1Context *f, FFV1SliceContext *sc, | |
93 | GetBitContext *gb, | ||
94 | uint8_t *src, int w, int h, int stride, int plane_index, | ||
95 | int pixel_stride, int ac) | ||
96 | { | ||
97 | int x, y; | ||
98 | int16_t *sample[2]; | ||
99 | 18249 | sample[0] = sc->sample_buffer + 3; | |
100 | 18249 | sample[1] = sc->sample_buffer + w + 6 + 3; | |
101 | |||
102 | 18249 | sc->run_index = 0; | |
103 | |||
104 | 18249 | memset(sc->sample_buffer, 0, 2 * (w + 6) * sizeof(*sc->sample_buffer)); | |
105 | |||
106 |
2/2✓ Branch 0 taken 1748616 times.
✓ Branch 1 taken 18249 times.
|
1766865 | for (y = 0; y < h; y++) { |
107 | 1748616 | int16_t *temp = sample[0]; // FIXME: try a normal buffer | |
108 | |||
109 | 1748616 | sample[0] = sample[1]; | |
110 | 1748616 | sample[1] = temp; | |
111 | |||
112 | 1748616 | sample[1][-1] = sample[0][0]; | |
113 | 1748616 | sample[0][w] = sample[0][w - 1]; | |
114 | |||
115 |
2/2✓ Branch 0 taken 915612 times.
✓ Branch 1 taken 833004 times.
|
1748616 | if (f->avctx->bits_per_raw_sample <= 8) { |
116 | 915612 | int ret = decode_line(f, sc, gb, w, sample, plane_index, 8, ac); | |
117 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 915612 times.
|
915612 | if (ret < 0) |
118 | ✗ | return ret; | |
119 |
2/2✓ Branch 0 taken 148622082 times.
✓ Branch 1 taken 915612 times.
|
149537694 | for (x = 0; x < w; x++) |
120 | 148622082 | src[x*pixel_stride + stride * y] = sample[1][x]; | |
121 | } else { | ||
122 | 833004 | int ret = decode_line(f, sc, gb, w, sample, plane_index, f->avctx->bits_per_raw_sample, ac); | |
123 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 833004 times.
|
833004 | if (ret < 0) |
124 | ✗ | return ret; | |
125 |
1/2✓ Branch 0 taken 833004 times.
✗ Branch 1 not taken.
|
833004 | if (f->packed_at_lsb) { |
126 |
2/2✓ Branch 0 taken 112679724 times.
✓ Branch 1 taken 833004 times.
|
113512728 | for (x = 0; x < w; x++) { |
127 | 112679724 | ((uint16_t*)(src + stride*y))[x*pixel_stride] = sample[1][x]; | |
128 | } | ||
129 | } else { | ||
130 | ✗ | for (x = 0; x < w; x++) { | |
131 | ✗ | ((uint16_t*)(src + stride*y))[x*pixel_stride] = sample[1][x] << (16 - f->avctx->bits_per_raw_sample) | ((uint16_t **)sample)[1][x] >> (2 * f->avctx->bits_per_raw_sample - 16); | |
132 | } | ||
133 | } | ||
134 | } | ||
135 | } | ||
136 | 18249 | return 0; | |
137 | } | ||
138 | |||
139 | 6644 | static int decode_slice_header(const FFV1Context *f, | |
140 | FFV1SliceContext *sc, AVFrame *frame) | ||
141 | { | ||
142 | 6644 | RangeCoder *c = &sc->c; | |
143 | uint8_t state[CONTEXT_SIZE]; | ||
144 | unsigned ps, context_count; | ||
145 | int sx, sy, sw, sh; | ||
146 | |||
147 | 6644 | memset(state, 128, sizeof(state)); | |
148 | 6644 | sx = ff_ffv1_get_symbol(c, state, 0); | |
149 | 6644 | sy = ff_ffv1_get_symbol(c, state, 0); | |
150 | 6644 | sw = ff_ffv1_get_symbol(c, state, 0) + 1U; | |
151 | 6644 | sh = ff_ffv1_get_symbol(c, state, 0) + 1U; | |
152 | |||
153 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 6644 times.
|
6644 | av_assert0(f->version > 2); |
154 | |||
155 | |||
156 |
4/8✓ Branch 0 taken 6644 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 6644 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 6644 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✓ Branch 7 taken 6644 times.
|
6644 | if (sx < 0 || sy < 0 || sw <= 0 || sh <= 0) |
157 | ✗ | return AVERROR_INVALIDDATA; | |
158 |
2/4✓ Branch 0 taken 6644 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 6644 times.
|
6644 | if (sx > f->num_h_slices - sw || sy > f->num_v_slices - sh) |
159 | ✗ | return AVERROR_INVALIDDATA; | |
160 | |||
161 | 6644 | sc->slice_x = ff_slice_coord(f, f->width , sx , f->num_h_slices, f->chroma_h_shift); | |
162 | 6644 | sc->slice_y = ff_slice_coord(f, f->height, sy , f->num_v_slices, f->chroma_v_shift); | |
163 | 6644 | sc->slice_width = ff_slice_coord(f, f->width , sx + sw, f->num_h_slices, f->chroma_h_shift) - sc->slice_x; | |
164 | 6644 | sc->slice_height = ff_slice_coord(f, f->height, sy + sh, f->num_v_slices, f->chroma_v_shift) - sc->slice_y; | |
165 | |||
166 |
2/4✓ Branch 0 taken 6644 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 6644 times.
|
6644 | av_assert0((unsigned)sc->slice_width <= f->width && |
167 | (unsigned)sc->slice_height <= f->height); | ||
168 |
2/4✓ Branch 0 taken 6644 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 6644 times.
|
6644 | av_assert0 ( (unsigned)sc->slice_x + (uint64_t)sc->slice_width <= f->width |
169 | && (unsigned)sc->slice_y + (uint64_t)sc->slice_height <= f->height); | ||
170 | |||
171 |
3/4✓ Branch 0 taken 2556 times.
✓ Branch 1 taken 4088 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 2556 times.
|
6644 | if (f->ac == AC_GOLOMB_RICE && sc->slice_width >= (1<<23)) |
172 | ✗ | return AVERROR_INVALIDDATA; | |
173 | |||
174 |
2/2✓ Branch 0 taken 13288 times.
✓ Branch 1 taken 6644 times.
|
19932 | for (unsigned i = 0; i < f->plane_count; i++) { |
175 | 13288 | PlaneContext * const p = &sc->plane[i]; | |
176 | 13288 | int idx = ff_ffv1_get_symbol(c, state, 0); | |
177 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 13288 times.
|
13288 | if (idx >= (unsigned)f->quant_table_count) { |
178 | ✗ | av_log(f->avctx, AV_LOG_ERROR, "quant_table_index out of range\n"); | |
179 | ✗ | return -1; | |
180 | } | ||
181 | 13288 | p->quant_table_index = idx; | |
182 | 13288 | context_count = f->context_count[idx]; | |
183 | |||
184 |
2/2✓ Branch 0 taken 1592 times.
✓ Branch 1 taken 11696 times.
|
13288 | if (p->context_count < context_count) { |
185 | 1592 | av_freep(&p->state); | |
186 | 1592 | av_freep(&p->vlc_state); | |
187 | } | ||
188 | 13288 | p->context_count = context_count; | |
189 | } | ||
190 | |||
191 | 6644 | ps = ff_ffv1_get_symbol(c, state, 0); | |
192 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 6644 times.
|
6644 | if (ps == 1) { |
193 | ✗ | frame->flags |= AV_FRAME_FLAG_INTERLACED; | |
194 | ✗ | frame->flags |= AV_FRAME_FLAG_TOP_FIELD_FIRST; | |
195 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 6644 times.
|
6644 | } else if (ps == 2) { |
196 | ✗ | frame->flags |= AV_FRAME_FLAG_INTERLACED; | |
197 | ✗ | frame->flags &= ~AV_FRAME_FLAG_TOP_FIELD_FIRST; | |
198 |
1/2✓ Branch 0 taken 6644 times.
✗ Branch 1 not taken.
|
6644 | } else if (ps == 3) { |
199 | 6644 | frame->flags &= ~AV_FRAME_FLAG_INTERLACED; | |
200 | } | ||
201 | 6644 | frame->sample_aspect_ratio.num = ff_ffv1_get_symbol(c, state, 0); | |
202 | 6644 | frame->sample_aspect_ratio.den = ff_ffv1_get_symbol(c, state, 0); | |
203 | |||
204 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 6644 times.
|
6644 | if (av_image_check_sar(f->width, f->height, |
205 | frame->sample_aspect_ratio) < 0) { | ||
206 | ✗ | av_log(f->avctx, AV_LOG_WARNING, "ignoring invalid SAR: %u/%u\n", | |
207 | frame->sample_aspect_ratio.num, | ||
208 | frame->sample_aspect_ratio.den); | ||
209 | ✗ | frame->sample_aspect_ratio = (AVRational){ 0, 1 }; | |
210 | } | ||
211 | |||
212 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 6644 times.
|
6644 | if (f->version > 3) { |
213 | ✗ | sc->slice_reset_contexts = get_rac(c, state); | |
214 | ✗ | sc->slice_coding_mode = ff_ffv1_get_symbol(c, state, 0); | |
215 | ✗ | if (sc->slice_coding_mode != 1 && f->colorspace == 1) { | |
216 | ✗ | sc->slice_rct_by_coef = ff_ffv1_get_symbol(c, state, 0); | |
217 | ✗ | sc->slice_rct_ry_coef = ff_ffv1_get_symbol(c, state, 0); | |
218 | ✗ | if ((uint64_t)sc->slice_rct_by_coef + (uint64_t)sc->slice_rct_ry_coef > 4) { | |
219 | ✗ | av_log(f->avctx, AV_LOG_ERROR, "slice_rct_y_coef out of range\n"); | |
220 | ✗ | return AVERROR_INVALIDDATA; | |
221 | } | ||
222 | } | ||
223 | } | ||
224 | |||
225 | 6644 | return 0; | |
226 | } | ||
227 | |||
228 | ✗ | static void slice_set_damaged(FFV1Context *f, FFV1SliceContext *sc) | |
229 | { | ||
230 | ✗ | sc->slice_damaged = 1; | |
231 | |||
232 | // only set this for frame threading, as for slice threading its value is | ||
233 | // not used and setting it would be a race | ||
234 | ✗ | if (f->avctx->active_thread_type & FF_THREAD_FRAME) | |
235 | ✗ | f->frame_damaged = 1; | |
236 | ✗ | } | |
237 | |||
238 | 7715 | static int decode_slice(AVCodecContext *c, void *arg) | |
239 | { | ||
240 | 7715 | FFV1Context *f = c->priv_data; | |
241 | 7715 | FFV1SliceContext *sc = arg; | |
242 | int width, height, x, y, ret; | ||
243 | 7715 | const int ps = av_pix_fmt_desc_get(f->pix_fmt)->comp[0].step; | |
244 | 7715 | AVFrame * const p = f->picture.f; | |
245 | 7715 | const int si = sc - f->slices; | |
246 | GetBitContext gb; | ||
247 |
3/4✓ Branch 0 taken 3627 times.
✓ Branch 1 taken 4088 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 3627 times.
|
7715 | int ac = f->ac || sc->slice_coding_mode == 1; |
248 | |||
249 |
3/4✓ Branch 0 taken 6793 times.
✓ Branch 1 taken 922 times.
✓ Branch 2 taken 6793 times.
✗ Branch 3 not taken.
|
7715 | if (!(p->flags & AV_FRAME_FLAG_KEY) && f->last_picture.f) |
250 | 6793 | ff_progress_frame_await(&f->last_picture, si); | |
251 | |||
252 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 7715 times.
|
7715 | if (f->slice_damaged[si]) |
253 | ✗ | slice_set_damaged(f, sc); | |
254 | |||
255 | 7715 | sc->slice_rct_by_coef = 1; | |
256 | 7715 | sc->slice_rct_ry_coef = 1; | |
257 | |||
258 |
2/2✓ Branch 0 taken 6644 times.
✓ Branch 1 taken 1071 times.
|
7715 | if (f->version > 2) { |
259 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 6644 times.
|
6644 | if (ff_ffv1_init_slice_state(f, sc) < 0) |
260 | ✗ | return AVERROR(ENOMEM); | |
261 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 6644 times.
|
6644 | if (decode_slice_header(f, sc, p) < 0) { |
262 | ✗ | sc->slice_x = sc->slice_y = sc->slice_height = sc->slice_width = 0; | |
263 | ✗ | slice_set_damaged(f, sc); | |
264 | ✗ | return AVERROR_INVALIDDATA; | |
265 | } | ||
266 | } | ||
267 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 7715 times.
|
7715 | if ((ret = ff_ffv1_init_slice_state(f, sc)) < 0) |
268 | ✗ | return ret; | |
269 |
3/4✓ Branch 0 taken 6793 times.
✓ Branch 1 taken 922 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 6793 times.
|
7715 | if ((p->flags & AV_FRAME_FLAG_KEY) || sc->slice_reset_contexts) { |
270 | 922 | ff_ffv1_clear_slice_state(f, sc); | |
271 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 6793 times.
|
6793 | } else if (sc->slice_damaged) { |
272 | ✗ | return AVERROR_INVALIDDATA; | |
273 | } | ||
274 | |||
275 | 7715 | width = sc->slice_width; | |
276 | 7715 | height = sc->slice_height; | |
277 | 7715 | x = sc->slice_x; | |
278 | 7715 | y = sc->slice_y; | |
279 | |||
280 |
2/2✓ Branch 0 taken 3627 times.
✓ Branch 1 taken 4088 times.
|
7715 | if (ac == AC_GOLOMB_RICE) { |
281 |
2/2✓ Branch 0 taken 2556 times.
✓ Branch 1 taken 1071 times.
|
3627 | if (f->combined_version >= 0x30002) |
282 | 2556 | get_rac(&sc->c, (uint8_t[]) { 129 }); | |
283 |
6/6✓ Branch 0 taken 1071 times.
✓ Branch 1 taken 2556 times.
✓ Branch 2 taken 663 times.
✓ Branch 3 taken 408 times.
✓ Branch 4 taken 459 times.
✓ Branch 5 taken 204 times.
|
3627 | sc->ac_byte_count = f->version > 2 || (!x && !y) ? sc->c.bytestream - sc->c.bytestream_start - 1 : 0; |
284 | 3627 | init_get_bits(&gb, | |
285 | 3627 | sc->c.bytestream_start + sc->ac_byte_count, | |
286 | 3627 | (sc->c.bytestream_end - sc->c.bytestream_start - sc->ac_byte_count) * 8); | |
287 | } | ||
288 | |||
289 | av_assert1(width && height); | ||
290 |
3/6✓ Branch 0 taken 6083 times.
✓ Branch 1 taken 1632 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 6083 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
|
13798 | if (f->colorspace == 0 && (f->chroma_planes || !f->transparency)) { |
291 | 6083 | const int chroma_width = AV_CEIL_RSHIFT(width, f->chroma_h_shift); | |
292 | 6083 | const int chroma_height = AV_CEIL_RSHIFT(height, f->chroma_v_shift); | |
293 | 6083 | const int cx = x >> f->chroma_h_shift; | |
294 | 6083 | const int cy = y >> f->chroma_v_shift; | |
295 | 6083 | decode_plane(f, sc, &gb, p->data[0] + ps*x + y*p->linesize[0], width, height, p->linesize[0], 0, 1, ac); | |
296 | |||
297 |
1/2✓ Branch 0 taken 6083 times.
✗ Branch 1 not taken.
|
6083 | if (f->chroma_planes) { |
298 | 6083 | decode_plane(f, sc, &gb, p->data[1] + ps*cx+cy*p->linesize[1], chroma_width, chroma_height, p->linesize[1], 1, 1, ac); | |
299 | 6083 | decode_plane(f, sc, &gb, p->data[2] + ps*cx+cy*p->linesize[2], chroma_width, chroma_height, p->linesize[2], 1, 1, ac); | |
300 | } | ||
301 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 6083 times.
|
6083 | if (f->transparency) |
302 | ✗ | decode_plane(f, sc, &gb, p->data[3] + ps*x + y*p->linesize[3], width, height, p->linesize[3], (f->version >= 4 && !f->chroma_planes) ? 1 : 2, 1, ac); | |
303 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 1632 times.
|
1632 | } else if (f->colorspace == 0) { |
304 | ✗ | decode_plane(f, sc, &gb, p->data[0] + ps*x + y*p->linesize[0] , width, height, p->linesize[0], 0, 2, ac); | |
305 | ✗ | decode_plane(f, sc, &gb, p->data[0] + ps*x + y*p->linesize[0] + 1, width, height, p->linesize[0], 1, 2, ac); | |
306 |
2/2✓ Branch 0 taken 816 times.
✓ Branch 1 taken 816 times.
|
1632 | } else if (f->use32bit) { |
307 | 816 | uint8_t *planes[4] = { p->data[0] + ps * x + y * p->linesize[0], | |
308 | 816 | p->data[1] + ps * x + y * p->linesize[1], | |
309 | 816 | p->data[2] + ps * x + y * p->linesize[2], | |
310 | 816 | p->data[3] + ps * x + y * p->linesize[3] }; | |
311 | 816 | decode_rgb_frame32(f, sc, &gb, planes, width, height, p->linesize); | |
312 | } else { | ||
313 | 816 | uint8_t *planes[4] = { p->data[0] + ps * x + y * p->linesize[0], | |
314 | 816 | p->data[1] + ps * x + y * p->linesize[1], | |
315 | 816 | p->data[2] + ps * x + y * p->linesize[2], | |
316 | 816 | p->data[3] + ps * x + y * p->linesize[3] }; | |
317 | 816 | decode_rgb_frame(f, sc, &gb, planes, width, height, p->linesize); | |
318 | } | ||
319 |
3/4✓ Branch 0 taken 4088 times.
✓ Branch 1 taken 3627 times.
✓ Branch 2 taken 4088 times.
✗ Branch 3 not taken.
|
7715 | if (ac != AC_GOLOMB_RICE && f->version > 2) { |
320 | int v; | ||
321 | 4088 | get_rac(&sc->c, (uint8_t[]) { 129 }); | |
322 |
1/2✓ Branch 0 taken 4088 times.
✗ Branch 1 not taken.
|
4088 | v = sc->c.bytestream_end - sc->c.bytestream - 2 - 5*!!f->ec; |
323 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 4088 times.
|
4088 | if (v) { |
324 | ✗ | av_log(f->avctx, AV_LOG_ERROR, "bytestream end mismatching by %d\n", v); | |
325 | ✗ | slice_set_damaged(f, sc); | |
326 | } | ||
327 | } | ||
328 | |||
329 |
1/4✗ Branch 0 not taken.
✓ Branch 1 taken 7715 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
|
7715 | if (sc->slice_damaged && (f->avctx->err_recognition & AV_EF_EXPLODE)) |
330 | ✗ | return AVERROR_INVALIDDATA; | |
331 | |||
332 |
1/4✗ Branch 0 not taken.
✓ Branch 1 taken 7715 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
|
7715 | if ((c->active_thread_type & FF_THREAD_FRAME) && !f->frame_damaged) |
333 | ✗ | ff_progress_frame_report(&f->picture, si); | |
334 | |||
335 | 7715 | return 0; | |
336 | } | ||
337 | |||
338 | 253 | static enum AVPixelFormat get_pixel_format(FFV1Context *f) | |
339 | { | ||
340 | 253 | enum AVPixelFormat pix_fmts[] = { | |
341 | 253 | f->pix_fmt, | |
342 | AV_PIX_FMT_NONE, | ||
343 | }; | ||
344 | |||
345 | 253 | return ff_get_format(f->avctx, pix_fmts); | |
346 | } | ||
347 | |||
348 | 253 | static int read_header(FFV1Context *f, RangeCoder *c) | |
349 | { | ||
350 | uint8_t state[CONTEXT_SIZE]; | ||
351 | 253 | int context_count = -1; //-1 to avoid warning | |
352 | int ret; | ||
353 | |||
354 | 253 | memset(state, 128, sizeof(state)); | |
355 | |||
356 | 253 | ret = ff_ffv1_parse_header(f, c, state); | |
357 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 253 times.
|
253 | if (ret < 0) |
358 | ✗ | return ret; | |
359 | |||
360 | 253 | f->avctx->pix_fmt = get_pixel_format(f); | |
361 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 253 times.
|
253 | if (f->avctx->pix_fmt < 0) |
362 | ✗ | return AVERROR(EINVAL); | |
363 | |||
364 | ff_dlog(f->avctx, "%d %d %d\n", | ||
365 | f->chroma_h_shift, f->chroma_v_shift, f->pix_fmt); | ||
366 |
2/2✓ Branch 0 taken 30 times.
✓ Branch 1 taken 223 times.
|
253 | if (f->version < 2) { |
367 | 30 | context_count = ff_ffv1_read_quant_tables(c, f->quant_tables[0]); | |
368 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 30 times.
|
30 | if (context_count < 0) { |
369 | ✗ | av_log(f->avctx, AV_LOG_ERROR, "read_quant_table error\n"); | |
370 | ✗ | return AVERROR_INVALIDDATA; | |
371 | } | ||
372 | 30 | f->slice_count = f->max_slice_count; | |
373 |
2/2✓ Branch 0 taken 24 times.
✓ Branch 1 taken 199 times.
|
223 | } else if (f->version < 3) { |
374 | 24 | f->slice_count = ff_ffv1_get_symbol(c, state, 0); | |
375 | } else { | ||
376 | 199 | const uint8_t *p = c->bytestream_end; | |
377 | 199 | for (f->slice_count = 0; | |
378 |
4/6✓ Branch 0 taken 995 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 995 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 796 times.
✓ Branch 5 taken 199 times.
|
995 | f->slice_count < MAX_SLICES && 3 + 5*!!f->ec < p - c->bytestream_start; |
379 | 796 | f->slice_count++) { | |
380 |
1/2✓ Branch 0 taken 796 times.
✗ Branch 1 not taken.
|
796 | int trailer = 3 + 5*!!f->ec; |
381 | 796 | int size = AV_RB24(p-trailer); | |
382 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 796 times.
|
796 | if (size + trailer > p - c->bytestream_start) |
383 | ✗ | break; | |
384 | 796 | p -= size + trailer; | |
385 | } | ||
386 | } | ||
387 |
3/6✓ Branch 0 taken 253 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 253 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 253 times.
|
253 | if (f->slice_count > (unsigned)MAX_SLICES || f->slice_count <= 0 || f->slice_count > f->max_slice_count) { |
388 | ✗ | av_log(f->avctx, AV_LOG_ERROR, "slice count %d is invalid (max=%d)\n", f->slice_count, f->max_slice_count); | |
389 | ✗ | return AVERROR_INVALIDDATA; | |
390 | } | ||
391 | |||
392 | 253 | av_refstruct_unref(&f->slice_damaged); | |
393 | 253 | f->slice_damaged = av_refstruct_allocz(f->slice_count * sizeof(*f->slice_damaged)); | |
394 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 253 times.
|
253 | if (!f->slice_damaged) |
395 | ✗ | return AVERROR(ENOMEM); | |
396 | |||
397 |
2/2✓ Branch 0 taken 922 times.
✓ Branch 1 taken 253 times.
|
1175 | for (int j = 0; j < f->slice_count; j++) { |
398 | 922 | FFV1SliceContext *sc = &f->slices[j]; | |
399 | |||
400 |
2/2✓ Branch 0 taken 96 times.
✓ Branch 1 taken 826 times.
|
922 | if (f->version == 2) { |
401 | 96 | int sx = ff_ffv1_get_symbol(c, state, 0); | |
402 | 96 | int sy = ff_ffv1_get_symbol(c, state, 0); | |
403 | 96 | int sw = ff_ffv1_get_symbol(c, state, 0) + 1U; | |
404 | 96 | int sh = ff_ffv1_get_symbol(c, state, 0) + 1U; | |
405 | |||
406 |
4/8✓ Branch 0 taken 96 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 96 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 96 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✓ Branch 7 taken 96 times.
|
96 | if (sx < 0 || sy < 0 || sw <= 0 || sh <= 0) |
407 | ✗ | return AVERROR_INVALIDDATA; | |
408 |
2/4✓ Branch 0 taken 96 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 96 times.
|
96 | if (sx > f->num_h_slices - sw || sy > f->num_v_slices - sh) |
409 | ✗ | return AVERROR_INVALIDDATA; | |
410 | |||
411 | 96 | sc->slice_x = sx * (int64_t)f->width / f->num_h_slices; | |
412 | 96 | sc->slice_y = sy * (int64_t)f->height / f->num_v_slices; | |
413 | 96 | sc->slice_width = (sx + sw) * (int64_t)f->width / f->num_h_slices - sc->slice_x; | |
414 | 96 | sc->slice_height = (sy + sh) * (int64_t)f->height / f->num_v_slices - sc->slice_y; | |
415 | |||
416 |
2/4✓ Branch 0 taken 96 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 96 times.
|
96 | av_assert0((unsigned)sc->slice_width <= f->width && |
417 | (unsigned)sc->slice_height <= f->height); | ||
418 |
2/4✓ Branch 0 taken 96 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 96 times.
|
96 | av_assert0 ( (unsigned)sc->slice_x + (uint64_t)sc->slice_width <= f->width |
419 | && (unsigned)sc->slice_y + (uint64_t)sc->slice_height <= f->height); | ||
420 | } | ||
421 | |||
422 | 922 | av_refstruct_unref(&sc->plane); | |
423 | 922 | sc->plane = ff_ffv1_planes_alloc(); | |
424 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 922 times.
|
922 | if (!sc->plane) |
425 | ✗ | return AVERROR(ENOMEM); | |
426 | |||
427 |
2/2✓ Branch 0 taken 1844 times.
✓ Branch 1 taken 922 times.
|
2766 | for (int i = 0; i < f->plane_count; i++) { |
428 | 1844 | PlaneContext *const p = &sc->plane[i]; | |
429 | |||
430 |
2/2✓ Branch 0 taken 192 times.
✓ Branch 1 taken 1652 times.
|
1844 | if (f->version == 2) { |
431 | 192 | int idx = ff_ffv1_get_symbol(c, state, 0); | |
432 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 192 times.
|
192 | if (idx >= (unsigned)f->quant_table_count) { |
433 | ✗ | av_log(f->avctx, AV_LOG_ERROR, | |
434 | "quant_table_index out of range\n"); | ||
435 | ✗ | return AVERROR_INVALIDDATA; | |
436 | } | ||
437 | 192 | p->quant_table_index = idx; | |
438 | 192 | context_count = f->context_count[idx]; | |
439 | } | ||
440 | |||
441 |
2/2✓ Branch 0 taken 252 times.
✓ Branch 1 taken 1592 times.
|
1844 | if (f->version <= 2) { |
442 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 252 times.
|
252 | av_assert0(context_count >= 0); |
443 | 252 | p->context_count = context_count; | |
444 | } | ||
445 | } | ||
446 | } | ||
447 | 253 | return 0; | |
448 | } | ||
449 | |||
450 | 88 | static av_cold int decode_init(AVCodecContext *avctx) | |
451 | { | ||
452 | 88 | FFV1Context *f = avctx->priv_data; | |
453 | int ret; | ||
454 | |||
455 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 88 times.
|
88 | if ((ret = ff_ffv1_common_init(avctx, f)) < 0) |
456 | ✗ | return ret; | |
457 | |||
458 |
3/4✓ Branch 0 taken 78 times.
✓ Branch 1 taken 10 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 78 times.
|
88 | if (avctx->extradata_size > 0 && (ret = ff_ffv1_read_extra_header(f)) < 0) |
459 | ✗ | return ret; | |
460 | |||
461 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 88 times.
|
88 | if ((ret = ff_ffv1_init_slice_contexts(f)) < 0) |
462 | ✗ | return ret; | |
463 | |||
464 | 88 | return 0; | |
465 | } | ||
466 | |||
467 | 7715 | static int find_next_slice(AVCodecContext *avctx, | |
468 | uint8_t *buf, uint8_t *buf_end, int idx, | ||
469 | uint8_t **pos, uint32_t *len) | ||
470 | { | ||
471 | 7715 | FFV1Context *f = avctx->priv_data; | |
472 | |||
473 | /* Length field */ | ||
474 | 7715 | uint32_t v = buf_end - buf; | |
475 |
4/4✓ Branch 0 taken 2120 times.
✓ Branch 1 taken 5595 times.
✓ Branch 2 taken 1661 times.
✓ Branch 3 taken 459 times.
|
7715 | if (idx || f->version > 2) { |
476 | /* Three bytes of length, plus flush bit + CRC */ | ||
477 |
2/2✓ Branch 0 taken 6644 times.
✓ Branch 1 taken 612 times.
|
7256 | uint32_t trailer = 3 + 5*!!f->ec; |
478 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 7256 times.
|
7256 | if (trailer > buf_end - buf) |
479 | ✗ | v = INT_MAX; | |
480 | else | ||
481 | 7256 | v = AV_RB24(buf_end - trailer) + trailer; | |
482 | } | ||
483 | |||
484 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 7715 times.
|
7715 | if (buf_end - buf < v) { |
485 | ✗ | av_log(avctx, AV_LOG_ERROR, "Slice pointer chain broken\n"); | |
486 | ✗ | ff_progress_frame_report(&f->picture, INT_MAX); | |
487 | ✗ | return AVERROR_INVALIDDATA; | |
488 | } | ||
489 | |||
490 | 7715 | *len = v; | |
491 |
2/2✓ Branch 0 taken 5595 times.
✓ Branch 1 taken 2120 times.
|
7715 | if (idx) |
492 | 5595 | *pos = buf_end - v; | |
493 | else | ||
494 | 2120 | *pos = buf; | |
495 | |||
496 | 7715 | return 0; | |
497 | } | ||
498 | |||
499 | 2120 | static int decode_header(AVCodecContext *avctx, RangeCoder *c, | |
500 | uint8_t *buf, size_t buf_size) | ||
501 | { | ||
502 | int ret; | ||
503 | 2120 | FFV1Context *f = avctx->priv_data; | |
504 | |||
505 | 2120 | uint8_t keystate = 128; | |
506 | 2120 | ff_init_range_decoder(c, buf, buf_size); | |
507 | 2120 | ff_build_rac_states(c, 0.05 * (1LL << 32), 256 - 8); | |
508 | |||
509 |
2/2✓ Branch 1 taken 253 times.
✓ Branch 2 taken 1867 times.
|
2120 | if (get_rac(c, &keystate)) { |
510 | 253 | f->key_frame = AV_FRAME_FLAG_KEY; | |
511 | 253 | f->key_frame_ok = 0; | |
512 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 253 times.
|
253 | if ((ret = read_header(f, c)) < 0) |
513 | ✗ | return ret; | |
514 | 253 | f->key_frame_ok = 1; | |
515 | } else { | ||
516 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 1867 times.
|
1867 | if (!f->key_frame_ok) { |
517 | ✗ | av_log(avctx, AV_LOG_ERROR, | |
518 | "Cannot decode non-keyframe without valid keyframe\n"); | ||
519 | ✗ | return AVERROR_INVALIDDATA; | |
520 | } | ||
521 | 1867 | f->key_frame = 0; | |
522 | } | ||
523 | |||
524 |
2/2✓ Branch 0 taken 1022 times.
✓ Branch 1 taken 1098 times.
|
2120 | if (f->ac != AC_GOLOMB_RICE) { |
525 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 1022 times.
|
1022 | if (buf_size < avctx->width * avctx->height / (128*8)) |
526 | ✗ | return AVERROR_INVALIDDATA; | |
527 | } else { | ||
528 | 1098 | int w = avctx->width; | |
529 | 1098 | int s = 1 + w / (1<<23); | |
530 | int i; | ||
531 | |||
532 | 1098 | w /= s; | |
533 | |||
534 |
2/2✓ Branch 0 taken 25232 times.
✓ Branch 1 taken 1098 times.
|
26330 | for (i = 0; w > (1<<ff_log2_run[i]); i++) |
535 | 25232 | w -= ff_log2_run[i]; | |
536 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 1098 times.
|
1098 | if (buf_size < (avctx->height + i + 6) / 8 * s) |
537 | ✗ | return AVERROR_INVALIDDATA; | |
538 | } | ||
539 | |||
540 | 2120 | return 0; | |
541 | } | ||
542 | |||
543 | 2120 | static int decode_slices(AVCodecContext *avctx, RangeCoder c, | |
544 | AVPacket *avpkt) | ||
545 | { | ||
546 | 2120 | FFV1Context *f = avctx->priv_data; | |
547 | 2120 | AVFrame *p = f->picture.f; | |
548 | |||
549 | 2120 | uint8_t *buf = avpkt->data; | |
550 | 2120 | size_t buf_size = avpkt->size; | |
551 | 2120 | uint8_t *buf_end = buf + buf_size; | |
552 | |||
553 |
2/2✓ Branch 0 taken 7715 times.
✓ Branch 1 taken 2120 times.
|
9835 | for (int i = f->slice_count - 1; i >= 0; i--) { |
554 | 7715 | FFV1SliceContext *sc = &f->slices[i]; | |
555 | |||
556 | uint8_t *pos; | ||
557 | uint32_t len; | ||
558 | 7715 | int err = find_next_slice(avctx, buf, buf_end, i, | |
559 | &pos, &len); | ||
560 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 7715 times.
|
7715 | if (err < 0) |
561 | ✗ | return err; | |
562 | |||
563 | 7715 | buf_end -= len; | |
564 | |||
565 | 7715 | sc->slice_damaged = 0; | |
566 | |||
567 |
2/2✓ Branch 0 taken 6644 times.
✓ Branch 1 taken 1071 times.
|
7715 | if (f->ec) { |
568 | 6644 | unsigned crc = av_crc(av_crc_get_table(AV_CRC_32_IEEE), f->crcref, pos, len); | |
569 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 6644 times.
|
6644 | if (crc != f->crcref) { |
570 | ✗ | int64_t ts = avpkt->pts != AV_NOPTS_VALUE ? avpkt->pts : avpkt->dts; | |
571 | ✗ | av_log(f->avctx, AV_LOG_ERROR, "slice CRC mismatch %X!", crc); | |
572 | ✗ | if (ts != AV_NOPTS_VALUE && avctx->pkt_timebase.num) { | |
573 | ✗ | av_log(f->avctx, AV_LOG_ERROR, "at %f seconds\n", ts*av_q2d(avctx->pkt_timebase)); | |
574 | ✗ | } else if (ts != AV_NOPTS_VALUE) { | |
575 | ✗ | av_log(f->avctx, AV_LOG_ERROR, "at %"PRId64"\n", ts); | |
576 | } else { | ||
577 | ✗ | av_log(f->avctx, AV_LOG_ERROR, "\n"); | |
578 | } | ||
579 | ✗ | slice_set_damaged(f, sc); | |
580 | } | ||
581 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 6644 times.
|
6644 | if (avctx->debug & FF_DEBUG_PICT_INFO) { |
582 | ✗ | av_log(avctx, AV_LOG_DEBUG, "slice %d, CRC: 0x%08"PRIX32"\n", i, AV_RB32(pos + len - 4)); | |
583 | } | ||
584 | } | ||
585 | |||
586 |
2/2✓ Branch 0 taken 5595 times.
✓ Branch 1 taken 2120 times.
|
7715 | if (i) { |
587 | 5595 | ff_init_range_decoder(&sc->c, pos, len); | |
588 | 5595 | ff_build_rac_states(&sc->c, 0.05 * (1LL << 32), 256 - 8); | |
589 | } else { | ||
590 | 2120 | sc->c = c; | |
591 | 2120 | sc->c.bytestream_end = pos + len; | |
592 | } | ||
593 | } | ||
594 | |||
595 | 2120 | avctx->execute(avctx, | |
596 | decode_slice, | ||
597 | 2120 | f->slices, | |
598 | NULL, | ||
599 | f->slice_count, | ||
600 | sizeof(*f->slices)); | ||
601 | |||
602 |
2/2✓ Branch 0 taken 7715 times.
✓ Branch 1 taken 2120 times.
|
9835 | for (int i = f->slice_count - 1; i >= 0; i--) { |
603 | 7715 | FFV1SliceContext *sc = &f->slices[i]; | |
604 |
1/4✗ Branch 0 not taken.
✓ Branch 1 taken 7715 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
|
7715 | if (sc->slice_damaged && f->last_picture.f) { |
605 | ✗ | const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(f->pix_fmt); | |
606 | const uint8_t *src[4]; | ||
607 | uint8_t *dst[4]; | ||
608 | ✗ | ff_progress_frame_await(&f->last_picture, INT_MAX); | |
609 | ✗ | for (int j = 0; j < desc->nb_components; j++) { | |
610 | ✗ | int pixshift = desc->comp[j].depth > 8; | |
611 | ✗ | int sh = (j == 1 || j == 2) ? f->chroma_h_shift : 0; | |
612 | ✗ | int sv = (j == 1 || j == 2) ? f->chroma_v_shift : 0; | |
613 | ✗ | dst[j] = p->data[j] + p->linesize[j] * | |
614 | ✗ | (sc->slice_y >> sv) + ((sc->slice_x >> sh) << pixshift); | |
615 | ✗ | src[j] = f->last_picture.f->data[j] + f->last_picture.f->linesize[j] * | |
616 | ✗ | (sc->slice_y >> sv) + ((sc->slice_x >> sh) << pixshift); | |
617 | |||
618 | } | ||
619 | |||
620 | ✗ | av_image_copy(dst, p->linesize, src, | |
621 | ✗ | f->last_picture.f->linesize, | |
622 | f->pix_fmt, | ||
623 | sc->slice_width, | ||
624 | sc->slice_height); | ||
625 | |||
626 | ✗ | f->slice_damaged[i] = 1; | |
627 | } | ||
628 | } | ||
629 | |||
630 | 2120 | return 0; | |
631 | } | ||
632 | |||
633 | 2120 | static int decode_frame(AVCodecContext *avctx, AVFrame *rframe, | |
634 | int *got_frame, AVPacket *avpkt) | ||
635 | { | ||
636 | 2120 | FFV1Context *f = avctx->priv_data; | |
637 | int ret; | ||
638 | AVFrame *p; | ||
639 | |||
640 | /* This is copied onto the first slice's range coder context */ | ||
641 | RangeCoder c; | ||
642 | |||
643 | 2120 | ff_progress_frame_unref(&f->last_picture); | |
644 | 2120 | FFSWAP(ProgressFrame, f->picture, f->last_picture); | |
645 | |||
646 | |||
647 | 2120 | f->avctx = avctx; | |
648 | 2120 | f->frame_damaged = 0; | |
649 | |||
650 | 2120 | ret = decode_header(avctx, &c, avpkt->data, avpkt->size); | |
651 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 2120 times.
|
2120 | if (ret < 0) |
652 | ✗ | return ret; | |
653 | |||
654 | 2120 | ret = ff_progress_frame_get_buffer(avctx, &f->picture, | |
655 | AV_GET_BUFFER_FLAG_REF); | ||
656 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 2120 times.
|
2120 | if (ret < 0) |
657 | ✗ | return ret; | |
658 | |||
659 | 2120 | p = f->picture.f; | |
660 | |||
661 | 2120 | p->pict_type = AV_PICTURE_TYPE_I; //FIXME I vs. P | |
662 | 2120 | p->flags = (p->flags & ~AV_FRAME_FLAG_KEY) | f->key_frame; | |
663 | |||
664 |
3/4✓ Branch 0 taken 459 times.
✓ Branch 1 taken 1661 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 459 times.
|
2120 | if (f->version < 3 && avctx->field_order > AV_FIELD_PROGRESSIVE) { |
665 | /* we have interlaced material flagged in container */ | ||
666 | ✗ | p->flags |= AV_FRAME_FLAG_INTERLACED; | |
667 | ✗ | if (avctx->field_order == AV_FIELD_TT || avctx->field_order == AV_FIELD_TB) | |
668 | ✗ | p->flags |= AV_FRAME_FLAG_TOP_FIELD_FIRST; | |
669 | } | ||
670 | |||
671 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 2120 times.
|
2120 | if (avctx->debug & FF_DEBUG_PICT_INFO) |
672 | ✗ | av_log(avctx, AV_LOG_DEBUG, "ver:%d keyframe:%d coder:%d ec:%d slices:%d bps:%d\n", | |
673 | ✗ | f->version, !!(p->flags & AV_FRAME_FLAG_KEY), f->ac, f->ec, f->slice_count, f->avctx->bits_per_raw_sample); | |
674 | |||
675 | 2120 | ff_thread_finish_setup(avctx); | |
676 | |||
677 | 2120 | ret = decode_slices(avctx, c, avpkt); | |
678 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 2120 times.
|
2120 | if (ret < 0) |
679 | ✗ | return ret; | |
680 | |||
681 | 2120 | ff_progress_frame_report(&f->picture, INT_MAX); | |
682 | |||
683 | 2120 | ff_progress_frame_unref(&f->last_picture); | |
684 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 2120 times.
|
2120 | if ((ret = av_frame_ref(rframe, f->picture.f)) < 0) |
685 | ✗ | return ret; | |
686 | |||
687 | 2120 | *got_frame = 1; | |
688 | |||
689 | 2120 | return avpkt->size; | |
690 | } | ||
691 | |||
692 | #if HAVE_THREADS | ||
693 | ✗ | static int update_thread_context(AVCodecContext *dst, const AVCodecContext *src) | |
694 | { | ||
695 | ✗ | FFV1Context *fsrc = src->priv_data; | |
696 | ✗ | FFV1Context *fdst = dst->priv_data; | |
697 | |||
698 | ✗ | if (dst == src) | |
699 | ✗ | return 0; | |
700 | |||
701 | ✗ | fdst->version = fsrc->version; | |
702 | ✗ | fdst->micro_version = fsrc->micro_version; | |
703 | ✗ | fdst->combined_version = fsrc->combined_version; | |
704 | ✗ | fdst->chroma_planes = fsrc->chroma_planes; | |
705 | ✗ | fdst->chroma_h_shift = fsrc->chroma_h_shift; | |
706 | ✗ | fdst->chroma_v_shift = fsrc->chroma_v_shift; | |
707 | ✗ | fdst->transparency = fsrc->transparency; | |
708 | ✗ | fdst->plane_count = fsrc->plane_count; | |
709 | ✗ | fdst->ac = fsrc->ac; | |
710 | ✗ | fdst->colorspace = fsrc->colorspace; | |
711 | ✗ | fdst->pix_fmt = fsrc->pix_fmt; | |
712 | |||
713 | ✗ | fdst->ec = fsrc->ec; | |
714 | ✗ | fdst->intra = fsrc->intra; | |
715 | ✗ | fdst->key_frame_ok = fsrc->key_frame_ok; | |
716 | |||
717 | ✗ | fdst->packed_at_lsb = fsrc->packed_at_lsb; | |
718 | ✗ | fdst->slice_count = fsrc->slice_count; | |
719 | ✗ | fdst->use32bit = fsrc->use32bit; | |
720 | ✗ | memcpy(fdst->state_transition, fsrc->state_transition, | |
721 | sizeof(fdst->state_transition)); | ||
722 | |||
723 | // in version 1 there is a single per-keyframe quant table, so | ||
724 | // we need to propagate it between threads | ||
725 | ✗ | if (fsrc->version < 2) | |
726 | ✗ | memcpy(fdst->quant_tables[0], fsrc->quant_tables[0], sizeof(fsrc->quant_tables[0])); | |
727 | |||
728 | ✗ | for (int i = 0; i < fdst->num_h_slices * fdst->num_v_slices; i++) { | |
729 | ✗ | FFV1SliceContext *sc = &fdst->slices[i]; | |
730 | ✗ | const FFV1SliceContext *sc0 = &fsrc->slices[i]; | |
731 | |||
732 | ✗ | av_refstruct_replace(&sc->plane, sc0->plane); | |
733 | |||
734 | ✗ | if (fsrc->version < 3) { | |
735 | ✗ | sc->slice_x = sc0->slice_x; | |
736 | ✗ | sc->slice_y = sc0->slice_y; | |
737 | ✗ | sc->slice_width = sc0->slice_width; | |
738 | ✗ | sc->slice_height = sc0->slice_height; | |
739 | } | ||
740 | } | ||
741 | |||
742 | ✗ | av_refstruct_replace(&fdst->slice_damaged, fsrc->slice_damaged); | |
743 | |||
744 | av_assert1(fdst->max_slice_count == fsrc->max_slice_count); | ||
745 | |||
746 | ✗ | ff_progress_frame_replace(&fdst->picture, &fsrc->picture); | |
747 | |||
748 | ✗ | return 0; | |
749 | } | ||
750 | #endif | ||
751 | |||
752 | 88 | static av_cold int ffv1_decode_close(AVCodecContext *avctx) | |
753 | { | ||
754 | 88 | FFV1Context *const s = avctx->priv_data; | |
755 | |||
756 | 88 | ff_progress_frame_unref(&s->picture); | |
757 | 88 | ff_progress_frame_unref(&s->last_picture); | |
758 | 88 | av_freep(&avctx->stats_out); | |
759 | |||
760 | 88 | ff_ffv1_close(s); | |
761 | |||
762 | 88 | return 0; | |
763 | } | ||
764 | |||
765 | const FFCodec ff_ffv1_decoder = { | ||
766 | .p.name = "ffv1", | ||
767 | CODEC_LONG_NAME("FFmpeg video codec #1"), | ||
768 | .p.type = AVMEDIA_TYPE_VIDEO, | ||
769 | .p.id = AV_CODEC_ID_FFV1, | ||
770 | .priv_data_size = sizeof(FFV1Context), | ||
771 | .init = decode_init, | ||
772 | .close = ffv1_decode_close, | ||
773 | FF_CODEC_DECODE_CB(decode_frame), | ||
774 | UPDATE_THREAD_CONTEXT(update_thread_context), | ||
775 | .p.capabilities = AV_CODEC_CAP_DR1 | | ||
776 | AV_CODEC_CAP_FRAME_THREADS | AV_CODEC_CAP_SLICE_THREADS, | ||
777 | .caps_internal = FF_CODEC_CAP_INIT_CLEANUP | | ||
778 | FF_CODEC_CAP_USES_PROGRESSFRAMES, | ||
779 | }; | ||
780 |