Bug Summary

File:root/firefox-clang/media/ffvpx/libavcodec/vp8.c
Warning:line 1894, column 9
Branch condition evaluates to a garbage value

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple x86_64-pc-linux-gnu -O2 -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name vp8.c -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -analyzer-config-compatibility-mode=true -mrelocation-model pic -pic-level 2 -fhalf-no-semantic-interposition -mframe-pointer=all -relaxed-aliasing -ffp-contract=off -fno-rounding-math -mconstructor-aliases -funwind-tables=2 -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -fdebug-compilation-dir=/root/firefox-clang/obj-x86_64-pc-linux-gnu/media/ffvpx/libavcodec -fcoverage-compilation-dir=/root/firefox-clang/obj-x86_64-pc-linux-gnu/media/ffvpx/libavcodec -resource-dir /usr/lib/llvm-23/lib/clang/23 -include /root/firefox-clang/obj-x86_64-pc-linux-gnu/mozilla-config.h -include libavutil_visibility.h -U _FORTIFY_SOURCE -D _FORTIFY_SOURCE=2 -D DEBUG=1 -D HAVE_AV_CONFIG_H -D ASSERT_LEVEL=2 -I /root/firefox-clang/media/ffvpx/libavcodec -I /root/firefox-clang/obj-x86_64-pc-linux-gnu/media/ffvpx/libavcodec -I /root/firefox-clang/modules/fdlibm/inexact-math-override -I /root/firefox-clang/third_party/khronos/vulkan-headers/include -I /root/firefox-clang/media/mozva -I /root/firefox-clang/media/libopus/include -I /root/firefox-clang/media/libvorbis -I /root/firefox-clang/media/libvpx -I /root/firefox-clang/media/ffvpx -I /root/firefox-clang/obj-x86_64-pc-linux-gnu/dist/include -I /root/firefox-clang/obj-x86_64-pc-linux-gnu/dist/include/nspr -I /root/firefox-clang/obj-x86_64-pc-linux-gnu/dist/include/nss -D MOZILLA_CLIENT -internal-isystem /usr/lib/llvm-23/lib/clang/23/include -internal-isystem /usr/local/include -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/16/../../../../x86_64-linux-gnu/include -internal-externc-isystem /usr/include/x86_64-linux-gnu -internal-externc-isystem /include -internal-externc-isystem /usr/include -Wno-error=tautological-type-limit-compare -Wno-range-loop-analysis -Wno-error=deprecated-declarations -Wno-error=array-bounds -Wno-error=free-nonheap-object -Wno-error=atomic-alignment -Wno-error=deprecated-builtins -Wno-psabi -Wno-error=builtin-macro-redefined -Wno-unknown-warning-option -Wno-character-conversion -Wno-parentheses -Wno-pointer-sign -Wno-sign-compare -Wno-switch -Wno-type-limits -Wno-unused-function -Wno-deprecated-declarations -Wno-absolute-value -Wno-incompatible-pointer-types -Wno-string-conversion -Wno-visibility -ferror-limit 19 -fstrict-flex-arrays=1 -stack-protector 2 -fstack-clash-protection -ftrivial-auto-var-init=pattern -fgnuc-version=4.2.1 -fskip-odr-check-in-gmf -fdiagnostics-absolute-paths -vectorize-loops -vectorize-slp -analyzer-checker optin.performance.Padding -analyzer-output=html -analyzer-config stable-report-filename=true -mllvm -dwarf-linkage-names=Abstract -faddrsig -fdwarf2-cfi-asm -o /tmp/scan-build-2026-09-01-224014-2642839-1 -x c /root/firefox-clang/media/ffvpx/libavcodec/vp8.c
1/*
2 * VP7/VP8 compatible video decoder
3 *
4 * Copyright (C) 2010 David Conrad
5 * Copyright (C) 2010 Ronald S. Bultje
6 * Copyright (C) 2010 Fiona Glaser
7 * Copyright (C) 2012 Daniel Kang
8 * Copyright (C) 2014 Peter Ross
9 *
10 * This file is part of FFmpeg.
11 *
12 * FFmpeg is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU Lesser General Public
14 * License as published by the Free Software Foundation; either
15 * version 2.1 of the License, or (at your option) any later version.
16 *
17 * FFmpeg is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
20 * Lesser General Public License for more details.
21 *
22 * You should have received a copy of the GNU Lesser General Public
23 * License along with FFmpeg; if not, write to the Free Software
24 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
25 */
26
27#include "config_components.h"
28
29#include "libavutil/mem.h"
30#include "libavutil/mem_internal.h"
31
32#include "avcodec.h"
33#include "codec_internal.h"
34#include "decode.h"
35#include "hwaccel_internal.h"
36#include "hwconfig.h"
37#include "mathops.h"
38#include "progressframe.h"
39#include "libavutil/refstruct.h"
40#include "thread.h"
41#include "vp8.h"
42#include "vp89_rac.h"
43#include "vp8data.h"
44#include "vpx_rac.h"
45
46#if ARCH_ARM0
47# include "arm/vp8.h"
48#endif
49
50// fixme: add 1 bit to all the calls to this?
51static int vp8_rac_get_sint(VPXRangeCoder *c, int bits)
52{
53 int v;
54
55 if (!vp89_rac_get(c))
56 return 0;
57
58 v = vp89_rac_get_uint(c, bits);
59
60 if (vp89_rac_get(c))
61 v = -v;
62
63 return v;
64}
65
66static int vp8_rac_get_nn(VPXRangeCoder *c)
67{
68 int v = vp89_rac_get_uint(c, 7) << 1;
69 return v + !v;
70}
71
72// DCTextra
73static int vp8_rac_get_coeff(VPXRangeCoder *c, const uint8_t *prob)
74{
75 int v = 0;
76
77 do {
78 v = (v<<1) + vpx_rac_get_probvpx_rac_get_prob(c, *prob++);
79 } while (*prob);
80
81 return v;
82}
83
84static void free_buffers(VP8Context *s)
85{
86 int i;
87 if (s->thread_data)
88 for (i = 0; i < MAX_THREADS8; i++) {
89#if HAVE_THREADS1
90 pthread_cond_destroystrict_pthread_cond_destroy(&s->thread_data[i].cond);
91 pthread_mutex_destroystrict_pthread_mutex_destroy(&s->thread_data[i].lock);
92#endif
93 av_freep(&s->thread_data[i].filter_strength);
94 }
95 av_freep(&s->thread_data);
96 av_freep(&s->macroblocks_base);
97 av_freep(&s->intra4x4_pred_mode_top);
98 av_freep(&s->top_nnz);
99 av_freep(&s->top_border);
100
101 s->macroblocks = NULL((void*)0);
102}
103
104static int vp8_alloc_frame(VP8Context *s, VP8Frame *f, int ref)
105{
106 int ret = ff_progress_frame_get_buffer(s->avctx, &f->tf,
107 ref ? AV_GET_BUFFER_FLAG_REF(1 << 0) : 0);
108 if (ret < 0)
109 return ret;
110 f->seg_map = av_refstruct_allocz(s->mb_width * s->mb_height);
111 if (!f->seg_map) {
112 ret = AVERROR(ENOMEM)(-(12));
113 goto fail;
114 }
115 ret = ff_hwaccel_frame_priv_alloc(s->avctx, &f->hwaccel_picture_private);
116 if (ret < 0)
117 goto fail;
118
119 return 0;
120
121fail:
122 av_refstruct_unref(&f->seg_map);
123 ff_progress_frame_unref(&f->tf);
124 return ret;
125}
126
127static void vp8_release_frame(VP8Frame *f)
128{
129 av_refstruct_unref(&f->seg_map);
130 av_refstruct_unref(&f->hwaccel_picture_private);
131 ff_progress_frame_unref(&f->tf);
132}
133
134static av_cold__attribute__((cold)) void vp8_decode_flush_impl(AVCodecContext *avctx, int free_mem)
135{
136 VP8Context *s = avctx->priv_data;
137 int i;
138
139 for (i = 0; i < FF_ARRAY_ELEMS(s->frames)(sizeof(s->frames) / sizeof((s->frames)[0])); i++)
140 vp8_release_frame(&s->frames[i]);
141 memset(s->framep, 0, sizeof(s->framep));
142
143 if (free_mem)
144 free_buffers(s);
145
146 if (FF_HW_HAS_CB(avctx, flush)((avctx)->hwaccel && ffhwaccel((avctx)->hwaccel
)->flush)
)
147 FF_HW_SIMPLE_CALL(avctx, flush)(ffhwaccel((avctx)->hwaccel)->flush(avctx));
148}
149
150static av_cold__attribute__((cold)) void vp8_decode_flush(AVCodecContext *avctx)
151{
152 vp8_decode_flush_impl(avctx, 0);
153}
154
155static VP8Frame *vp8_find_free_buffer(VP8Context *s)
156{
157 VP8Frame *frame = NULL((void*)0);
158 int i;
159
160 // find a free buffer
161 for (i = 0; i < 5; i++)
162 if (&s->frames[i] != s->framep[VP8_FRAME_CURRENT] &&
163 &s->frames[i] != s->framep[VP8_FRAME_PREVIOUS] &&
164 &s->frames[i] != s->framep[VP8_FRAME_GOLDEN] &&
165 &s->frames[i] != s->framep[VP8_FRAME_ALTREF]) {
166 frame = &s->frames[i];
167 break;
168 }
169 if (i == 5) {
170 av_log(s->avctx, AV_LOG_FATAL8, "Ran out of free frames!\n");
171 abort();
172 }
173 if (frame->tf.f)
174 vp8_release_frame(frame);
175
176 return frame;
177}
178
179static enum AVPixelFormat get_pixel_format(VP8Context *s)
180{
181 enum AVPixelFormat pix_fmts[] = {
182#if CONFIG_VP8_VAAPI_HWACCEL1
183 AV_PIX_FMT_VAAPI,
184#endif
185#if CONFIG_VP8_NVDEC_HWACCEL0
186 AV_PIX_FMT_CUDA,
187#endif
188 AV_PIX_FMT_YUV420P,
189 AV_PIX_FMT_NONE,
190 };
191
192 return ff_get_format(s->avctx, pix_fmts);
193}
194
195static av_always_inline__attribute__((always_inline)) inline
196int update_dimensions(VP8Context *s, int width, int height, int is_vp7)
197{
198 AVCodecContext *avctx = s->avctx;
199 int i, ret, dim_reset = 0;
200
201 if (width != s->avctx->width || ((width+15)/16 != s->mb_width || (height+15)/16 != s->mb_height) && s->macroblocks_base ||
202 height != s->avctx->height) {
203 vp8_decode_flush_impl(s->avctx, 1);
204
205 ret = ff_set_dimensions(s->avctx, width, height);
206 if (ret < 0)
207 return ret;
208
209 dim_reset = (s->macroblocks_base != NULL((void*)0));
210 }
211
212 if ((s->pix_fmt == AV_PIX_FMT_NONE || dim_reset) &&
213 !s->actually_webp && !is_vp7) {
214 s->pix_fmt = get_pixel_format(s);
215 if (s->pix_fmt < 0)
216 return AVERROR(EINVAL)(-(22));
217 avctx->pix_fmt = s->pix_fmt;
218 }
219
220 s->mb_width = (s->avctx->coded_width + 15) / 16;
221 s->mb_height = (s->avctx->coded_height + 15) / 16;
222
223 s->mb_layout = is_vp7 || avctx->active_thread_type == FF_THREAD_SLICE2 &&
224 avctx->thread_count > 1;
225 if (!s->mb_layout) { // Frame threading and one thread
226 s->macroblocks_base = av_mallocz((s->mb_width + s->mb_height * 2 + 1) *
227 sizeof(*s->macroblocks));
228 s->intra4x4_pred_mode_top = av_mallocz(s->mb_width * 4);
229 } else // Sliced threading
230 s->macroblocks_base = av_mallocz((s->mb_width + 2) * (s->mb_height + 2) *
231 sizeof(*s->macroblocks));
232 s->top_nnz = av_mallocz(s->mb_width * sizeof(*s->top_nnz));
233 s->top_border = av_mallocz((s->mb_width + 1) * sizeof(*s->top_border));
234 s->thread_data = av_mallocz(MAX_THREADS8 * sizeof(VP8ThreadData));
235
236 if (!s->macroblocks_base || !s->top_nnz || !s->top_border ||
237 !s->thread_data || (!s->intra4x4_pred_mode_top && !s->mb_layout)) {
238 free_buffers(s);
239 return AVERROR(ENOMEM)(-(12));
240 }
241
242 for (i = 0; i < MAX_THREADS8; i++) {
243 s->thread_data[i].filter_strength =
244 av_mallocz(s->mb_width * sizeof(*s->thread_data[0].filter_strength));
245 if (!s->thread_data[i].filter_strength) {
246 free_buffers(s);
247 return AVERROR(ENOMEM)(-(12));
248 }
249#if HAVE_THREADS1
250 ret = pthread_mutex_initstrict_pthread_mutex_init(&s->thread_data[i].lock, NULL((void*)0));
251 if (ret) {
252 free_buffers(s);
253 return AVERROR(ret)(-(ret));
254 }
255 ret = pthread_cond_initstrict_pthread_cond_init(&s->thread_data[i].cond, NULL((void*)0));
256 if (ret) {
257 free_buffers(s);
258 return AVERROR(ret)(-(ret));
259 }
260#endif
261 }
262
263 s->macroblocks = s->macroblocks_base + 1;
264
265 return 0;
266}
267
268static int vp7_update_dimensions(VP8Context *s, int width, int height)
269{
270 return update_dimensions(s, width, height, IS_VP71);
271}
272
273static int vp8_update_dimensions(VP8Context *s, int width, int height)
274{
275 return update_dimensions(s, width, height, IS_VP80);
276}
277
278
279static void parse_segment_info(VP8Context *s)
280{
281 VPXRangeCoder *c = &s->c;
282 int i;
283
284 s->segmentation.update_map = vp89_rac_get(c);
285 s->segmentation.update_feature_data = vp89_rac_get(c);
286
287 if (s->segmentation.update_feature_data) {
288 s->segmentation.absolute_vals = vp89_rac_get(c);
289
290 for (i = 0; i < 4; i++)
291 s->segmentation.base_quant[i] = vp8_rac_get_sint(c, 7);
292
293 for (i = 0; i < 4; i++)
294 s->segmentation.filter_level[i] = vp8_rac_get_sint(c, 6);
295 }
296 if (s->segmentation.update_map)
297 for (i = 0; i < 3; i++)
298 s->prob->segmentid[i] = vp89_rac_get(c) ? vp89_rac_get_uint(c, 8) : 255;
299}
300
301static void update_lf_deltas(VP8Context *s)
302{
303 VPXRangeCoder *c = &s->c;
304 int i;
305
306 for (i = 0; i < 4; i++) {
307 if (vp89_rac_get(c)) {
308 s->lf_delta.ref[i] = vp89_rac_get_uint(c, 6);
309
310 if (vp89_rac_get(c))
311 s->lf_delta.ref[i] = -s->lf_delta.ref[i];
312 }
313 }
314
315 for (i = MODE_I4x44; i <= VP8_MVMODE_SPLIT; i++) {
316 if (vp89_rac_get(c)) {
317 s->lf_delta.mode[i] = vp89_rac_get_uint(c, 6);
318
319 if (vp89_rac_get(c))
320 s->lf_delta.mode[i] = -s->lf_delta.mode[i];
321 }
322 }
323}
324
325static int setup_partitions(VP8Context *s, const uint8_t *buf, int buf_size)
326{
327 const uint8_t *sizes = buf;
328 int i;
329 int ret;
330
331 s->num_coeff_partitions = 1 << vp89_rac_get_uint(&s->c, 2);
332
333 buf += 3 * (s->num_coeff_partitions - 1);
334 buf_size -= 3 * (s->num_coeff_partitions - 1);
335 if (buf_size < 0)
336 return -1;
337
338 for (i = 0; i < s->num_coeff_partitions - 1; i++) {
339 int size = AV_RL24(sizes + 3 * i)((((const uint8_t*)(sizes + 3 * i))[2] << 16) | (((const
uint8_t*)(sizes + 3 * i))[1] << 8) | ((const uint8_t*)
(sizes + 3 * i))[0])
;
340 if (buf_size - size < 0)
341 return -1;
342 s->coeff_partition_size[i] = size;
343
344 ret = ff_vpx_init_range_decoder(&s->coeff_partition[i], buf, size);
345 if (ret < 0)
346 return ret;
347 buf += size;
348 buf_size -= size;
349 }
350
351 s->coeff_partition_size[i] = buf_size;
352
353 return ff_vpx_init_range_decoder(&s->coeff_partition[i], buf, buf_size);
354}
355
356static void vp7_get_quants(VP8Context *s)
357{
358 VPXRangeCoder *c = &s->c;
359
360 int yac_qi = vp89_rac_get_uint(c, 7);
361 int ydc_qi = vp89_rac_get(c) ? vp89_rac_get_uint(c, 7) : yac_qi;
362 int y2dc_qi = vp89_rac_get(c) ? vp89_rac_get_uint(c, 7) : yac_qi;
363 int y2ac_qi = vp89_rac_get(c) ? vp89_rac_get_uint(c, 7) : yac_qi;
364 int uvdc_qi = vp89_rac_get(c) ? vp89_rac_get_uint(c, 7) : yac_qi;
365 int uvac_qi = vp89_rac_get(c) ? vp89_rac_get_uint(c, 7) : yac_qi;
366
367 s->qmat[0].luma_qmul[0] = vp7_ydc_qlookup[ydc_qi];
368 s->qmat[0].luma_qmul[1] = vp7_yac_qlookup[yac_qi];
369 s->qmat[0].luma_dc_qmul[0] = vp7_y2dc_qlookup[y2dc_qi];
370 s->qmat[0].luma_dc_qmul[1] = vp7_y2ac_qlookup[y2ac_qi];
371 s->qmat[0].chroma_qmul[0] = FFMIN(vp7_ydc_qlookup[uvdc_qi], 132)((vp7_ydc_qlookup[uvdc_qi]) > (132) ? (132) : (vp7_ydc_qlookup
[uvdc_qi]))
;
372 s->qmat[0].chroma_qmul[1] = vp7_yac_qlookup[uvac_qi];
373}
374
375static void vp8_get_quants(VP8Context *s)
376{
377 VPXRangeCoder *c = &s->c;
378 int i, base_qi;
379
380 s->quant.yac_qi = vp89_rac_get_uint(c, 7);
381 s->quant.ydc_delta = vp8_rac_get_sint(c, 4);
382 s->quant.y2dc_delta = vp8_rac_get_sint(c, 4);
383 s->quant.y2ac_delta = vp8_rac_get_sint(c, 4);
384 s->quant.uvdc_delta = vp8_rac_get_sint(c, 4);
385 s->quant.uvac_delta = vp8_rac_get_sint(c, 4);
386
387 for (i = 0; i < 4; i++) {
388 if (s->segmentation.enabled) {
389 base_qi = s->segmentation.base_quant[i];
390 if (!s->segmentation.absolute_vals)
391 base_qi += s->quant.yac_qi;
392 } else
393 base_qi = s->quant.yac_qi;
394
395 s->qmat[i].luma_qmul[0] = vp8_dc_qlookup[av_clip_uintp2av_clip_uintp2_c(base_qi + s->quant.ydc_delta, 7)];
396 s->qmat[i].luma_qmul[1] = vp8_ac_qlookup[av_clip_uintp2av_clip_uintp2_c(base_qi, 7)];
397 s->qmat[i].luma_dc_qmul[0] = vp8_dc_qlookup[av_clip_uintp2av_clip_uintp2_c(base_qi + s->quant.y2dc_delta, 7)] * 2;
398 /* 101581>>16 is equivalent to 155/100 */
399 s->qmat[i].luma_dc_qmul[1] = vp8_ac_qlookup[av_clip_uintp2av_clip_uintp2_c(base_qi + s->quant.y2ac_delta, 7)] * 101581 >> 16;
400 s->qmat[i].chroma_qmul[0] = vp8_dc_qlookup[av_clip_uintp2av_clip_uintp2_c(base_qi + s->quant.uvdc_delta, 7)];
401 s->qmat[i].chroma_qmul[1] = vp8_ac_qlookup[av_clip_uintp2av_clip_uintp2_c(base_qi + s->quant.uvac_delta, 7)];
402
403 s->qmat[i].luma_dc_qmul[1] = FFMAX(s->qmat[i].luma_dc_qmul[1], 8)((s->qmat[i].luma_dc_qmul[1]) > (8) ? (s->qmat[i].luma_dc_qmul
[1]) : (8))
;
404 s->qmat[i].chroma_qmul[0] = FFMIN(s->qmat[i].chroma_qmul[0], 132)((s->qmat[i].chroma_qmul[0]) > (132) ? (132) : (s->qmat
[i].chroma_qmul[0]))
;
405 }
406}
407
408/**
409 * Determine which buffers golden and altref should be updated with after this frame.
410 * The spec isn't clear here, so I'm going by my understanding of what libvpx does
411 *
412 * Intra frames update all 3 references
413 * Inter frames update VP8_FRAME_PREVIOUS if the update_last flag is set
414 * If the update (golden|altref) flag is set, it's updated with the current frame
415 * if update_last is set, and VP8_FRAME_PREVIOUS otherwise.
416 * If the flag is not set, the number read means:
417 * 0: no update
418 * 1: VP8_FRAME_PREVIOUS
419 * 2: update golden with altref, or update altref with golden
420 */
421static VP8FrameType ref_to_update(VP8Context *s, int update, VP8FrameType ref)
422{
423 VPXRangeCoder *c = &s->c;
424
425 if (update)
426 return VP8_FRAME_CURRENT;
427
428 switch (vp89_rac_get_uint(c, 2)) {
429 case 1:
430 return VP8_FRAME_PREVIOUS;
431 case 2:
432 return (ref == VP8_FRAME_GOLDEN) ? VP8_FRAME_ALTREF : VP8_FRAME_GOLDEN;
433 }
434 return VP8_FRAME_NONE;
435}
436
437static void vp78_reset_probability_tables(VP8Context *s)
438{
439 int i, j;
440 for (i = 0; i < 4; i++)
441 for (j = 0; j < 16; j++)
442 memcpy(s->prob->token[i][j], vp8_token_default_probs[i][vp8_coeff_band[j]],
443 sizeof(s->prob->token[i][j]));
444}
445
446static void vp78_update_probability_tables(VP8Context *s)
447{
448 VPXRangeCoder *c = &s->c;
449 int i, j, k, l, m;
450
451 for (i = 0; i < 4; i++)
452 for (j = 0; j < 8; j++)
453 for (k = 0; k < 3; k++)
454 for (l = 0; l < NUM_DCT_TOKENS-1; l++)
455 if (vpx_rac_get_prob_branchy(c, ff_vp8_token_update_probs[i][j][k][l])) {
456 int prob = vp89_rac_get_uint(c, 8);
457 for (m = 0; vp8_coeff_band_indexes[j][m] >= 0; m++)
458 s->prob->token[i][vp8_coeff_band_indexes[j][m]][k][l] = prob;
459 }
460}
461
462#define VP7_MVC_SIZE17 17
463#define VP8_MVC_SIZE19 19
464
465static void vp78_update_pred16x16_pred8x8_mvc_probabilities(VP8Context *s,
466 int mvc_size)
467{
468 VPXRangeCoder *c = &s->c;
469 int i, j;
470
471 if (vp89_rac_get(c))
472 for (i = 0; i < 4; i++)
473 s->prob->pred16x16[i] = vp89_rac_get_uint(c, 8);
474 if (vp89_rac_get(c))
475 for (i = 0; i < 3; i++)
476 s->prob->pred8x8c[i] = vp89_rac_get_uint(c, 8);
477
478 // 17.2 MV probability update
479 for (i = 0; i < 2; i++)
480 for (j = 0; j < mvc_size; j++)
481 if (vpx_rac_get_prob_branchy(c, vp8_mv_update_prob[i][j]))
482 s->prob->mvc[i][j] = vp8_rac_get_nn(c);
483}
484
485static void update_refs(VP8Context *s)
486{
487 VPXRangeCoder *c = &s->c;
488
489 int update_golden = vp89_rac_get(c);
490 int update_altref = vp89_rac_get(c);
491
492 s->update_golden = ref_to_update(s, update_golden, VP8_FRAME_GOLDEN);
493 s->update_altref = ref_to_update(s, update_altref, VP8_FRAME_ALTREF);
494}
495
496static void copy_chroma(AVFrame *dst, const AVFrame *src, int width, int height)
497{
498 int i, j;
499
500 for (j = 1; j < 3; j++) {
501 for (i = 0; i < height / 2; i++)
502 memcpy(dst->data[j] + i * dst->linesize[j],
503 src->data[j] + i * src->linesize[j], width / 2);
504 }
505}
506
507static void fade(uint8_t *dst, ptrdiff_t dst_linesize,
508 const uint8_t *src, ptrdiff_t src_linesize,
509 int width, int height,
510 int alpha, int beta)
511{
512 int i, j;
513 for (j = 0; j < height; j++) {
514 const uint8_t *src2 = src + j * src_linesize;
515 uint8_t *dst2 = dst + j * dst_linesize;
516 for (i = 0; i < width; i++) {
517 uint8_t y = src2[i];
518 dst2[i] = av_clip_uint8av_clip_uint8_c(y + ((y * beta) >> 8) + alpha);
519 }
520 }
521}
522
523static int vp7_fade_frame(VP8Context *s, int alpha, int beta)
524{
525 int ret;
526
527 if (!s->keyframe && (alpha || beta)) {
528 int width = s->mb_width * 16;
529 int height = s->mb_height * 16;
530 const AVFrame *src;
531 AVFrame *dst;
532
533 if (!s->framep[VP8_FRAME_PREVIOUS] ||
534 !s->framep[VP8_FRAME_GOLDEN]) {
535 av_log(s->avctx, AV_LOG_WARNING24, "Discarding interframe without a prior keyframe!\n");
536 return AVERROR_INVALIDDATA(-(int)(('I') | (('N') << 8) | (('D') << 16) | ((
unsigned)('A') << 24)))
;
537 }
538
539 src =
540 dst = s->framep[VP8_FRAME_PREVIOUS]->tf.f;
541
542 /* preserve the golden frame, write a new previous frame */
543 if (s->framep[VP8_FRAME_GOLDEN] == s->framep[VP8_FRAME_PREVIOUS]) {
544 VP8Frame *prev_frame = vp8_find_free_buffer(s);
545
546 ret = vp8_alloc_frame(s, prev_frame, 1);
547 if (ret < 0)
548 return ret;
549 s->framep[VP8_FRAME_PREVIOUS] = prev_frame;
550
551 dst = s->framep[VP8_FRAME_PREVIOUS]->tf.f;
552
553 copy_chroma(dst, src, width, height);
554 }
555
556 fade(dst->data[0], dst->linesize[0],
557 src->data[0], src->linesize[0],
558 width, height, alpha, beta);
559 }
560
561 return 0;
562}
563
564static int vp7_decode_frame_header(VP8Context *s, const uint8_t *buf, int buf_size)
565{
566 VPXRangeCoder *c = &s->c;
567 int part1_size, hscale, vscale, i, j, ret;
568 int width = s->avctx->width;
569 int height = s->avctx->height;
570 int alpha = 0;
571 int beta = 0;
572 int fade_present = 1;
573
574 if (buf_size < 4) {
575 return AVERROR_INVALIDDATA(-(int)(('I') | (('N') << 8) | (('D') << 16) | ((
unsigned)('A') << 24)))
;
576 }
577
578 s->profile = (buf[0] >> 1) & 7;
579 if (s->profile > 1) {
580 avpriv_request_sample(s->avctx, "Unknown profile %d", s->profile);
581 return AVERROR_INVALIDDATA(-(int)(('I') | (('N') << 8) | (('D') << 16) | ((
unsigned)('A') << 24)))
;
582 }
583
584 s->keyframe = !(buf[0] & 1);
585 s->invisible = 0;
586 part1_size = AV_RL24(buf)((((const uint8_t*)(buf))[2] << 16) | (((const uint8_t*
)(buf))[1] << 8) | ((const uint8_t*)(buf))[0])
>> 4;
587
588 if (buf_size < 4 - s->profile + part1_size) {
589 av_log(s->avctx, AV_LOG_ERROR16, "Buffer size %d is too small, needed : %d\n", buf_size, 4 - s->profile + part1_size);
590 return AVERROR_INVALIDDATA(-(int)(('I') | (('N') << 8) | (('D') << 16) | ((
unsigned)('A') << 24)))
;
591 }
592
593 buf += 4 - s->profile;
594 buf_size -= 4 - s->profile;
595
596 memcpy(s->put_pixels_tab, s->vp8dsp.put_vp8_epel_pixels_tab, sizeof(s->put_pixels_tab));
597
598 ret = ff_vpx_init_range_decoder(c, buf, part1_size);
599 if (ret < 0)
600 return ret;
601 buf += part1_size;
602 buf_size -= part1_size;
603
604 /* A. Dimension information (keyframes only) */
605 if (s->keyframe) {
606 width = vp89_rac_get_uint(c, 12);
607 height = vp89_rac_get_uint(c, 12);
608 hscale = vp89_rac_get_uint(c, 2);
609 vscale = vp89_rac_get_uint(c, 2);
610 if (hscale || vscale)
611 avpriv_request_sample(s->avctx, "Upscaling");
612
613 s->update_golden = s->update_altref = VP8_FRAME_CURRENT;
614 vp78_reset_probability_tables(s);
615 memcpy(s->prob->pred16x16, vp8_pred16x16_prob_inter,
616 sizeof(s->prob->pred16x16));
617 memcpy(s->prob->pred8x8c, vp8_pred8x8c_prob_inter,
618 sizeof(s->prob->pred8x8c));
619 for (i = 0; i < 2; i++)
620 memcpy(s->prob->mvc[i], vp7_mv_default_prob[i],
621 sizeof(vp7_mv_default_prob[i]));
622 memset(&s->segmentation, 0, sizeof(s->segmentation));
623 memset(&s->lf_delta, 0, sizeof(s->lf_delta));
624 memcpy(s->prob[0].scan, ff_zigzag_scan, sizeof(s->prob[0].scan));
625 }
626
627 if (s->keyframe || s->profile > 0)
628 memset(s->inter_dc_pred, 0 , sizeof(s->inter_dc_pred));
629
630 /* B. Decoding information for all four macroblock-level features */
631 for (i = 0; i < 4; i++) {
632 s->feature_enabled[i] = vp89_rac_get(c);
633 if (s->feature_enabled[i]) {
634 s->feature_present_prob[i] = vp89_rac_get_uint(c, 8);
635
636 for (j = 0; j < 3; j++)
637 s->feature_index_prob[i][j] =
638 vp89_rac_get(c) ? vp89_rac_get_uint(c, 8) : 255;
639
640 if (vp7_feature_value_size[s->profile][i])
641 for (j = 0; j < 4; j++)
642 s->feature_value[i][j] =
643 vp89_rac_get(c) ? vp89_rac_get_uint(c, vp7_feature_value_size[s->profile][i]) : 0;
644 }
645 }
646
647 s->segmentation.enabled = 0;
648 s->segmentation.update_map = 0;
649 s->lf_delta.enabled = 0;
650
651 s->num_coeff_partitions = 1;
652 ret = ff_vpx_init_range_decoder(&s->coeff_partition[0], buf, buf_size);
653 if (ret < 0)
654 return ret;
655
656 if (!s->macroblocks_base || /* first frame */
657 width != s->avctx->width || height != s->avctx->height ||
658 (width + 15) / 16 != s->mb_width || (height + 15) / 16 != s->mb_height) {
659 if ((ret = vp7_update_dimensions(s, width, height)) < 0)
660 return ret;
661 }
662
663 /* C. Dequantization indices */
664 vp7_get_quants(s);
665
666 /* D. Golden frame update flag (a Flag) for interframes only */
667 if (!s->keyframe) {
668 s->update_golden = vp89_rac_get(c) ? VP8_FRAME_CURRENT : VP8_FRAME_NONE;
669 s->sign_bias[VP8_FRAME_GOLDEN] = 0;
670 }
671
672 s->update_last = 1;
673 s->update_probabilities = 1;
674
675 if (s->profile > 0) {
676 s->update_probabilities = vp89_rac_get(c);
677 if (!s->update_probabilities)
678 s->prob[1] = s->prob[0];
679
680 if (!s->keyframe)
681 fade_present = vp89_rac_get(c);
682 }
683
684 if (vpx_rac_is_end(c))
685 return AVERROR_INVALIDDATA(-(int)(('I') | (('N') << 8) | (('D') << 16) | ((
unsigned)('A') << 24)))
;
686 /* E. Fading information for previous frame */
687 if (fade_present && vp89_rac_get(c)) {
688 alpha = (int8_t) vp89_rac_get_uint(c, 8);
689 beta = (int8_t) vp89_rac_get_uint(c, 8);
690 }
691
692 /* F. Loop filter type */
693 if (!s->profile)
694 s->filter.simple = vp89_rac_get(c);
695
696 /* G. DCT coefficient ordering specification */
697 if (vp89_rac_get(c))
698 for (i = 1; i < 16; i++)
699 s->prob[0].scan[i] = ff_zigzag_scan[vp89_rac_get_uint(c, 4)];
700
701 /* H. Loop filter levels */
702 if (s->profile > 0)
703 s->filter.simple = vp89_rac_get(c);
704 s->filter.level = vp89_rac_get_uint(c, 6);
705 s->filter.sharpness = vp89_rac_get_uint(c, 3);
706
707 /* I. DCT coefficient probability update; 13.3 Token Probability Updates */
708 vp78_update_probability_tables(s);
709
710 s->mbskip_enabled = 0;
711
712 /* J. The remaining frame header data occurs ONLY FOR INTERFRAMES */
713 if (!s->keyframe) {
714 s->prob->intra = vp89_rac_get_uint(c, 8);
715 s->prob->last = vp89_rac_get_uint(c, 8);
716 vp78_update_pred16x16_pred8x8_mvc_probabilities(s, VP7_MVC_SIZE17);
717 }
718
719 if (vpx_rac_is_end(c))
720 return AVERROR_INVALIDDATA(-(int)(('I') | (('N') << 8) | (('D') << 16) | ((
unsigned)('A') << 24)))
;
721
722 if ((ret = vp7_fade_frame(s, alpha, beta)) < 0)
723 return ret;
724
725 return 0;
726}
727
728static int vp8_decode_frame_header(VP8Context *s, const uint8_t *buf, int buf_size)
729{
730 VPXRangeCoder *c = &s->c;
731 int header_size, hscale, vscale, ret;
732 int width = s->avctx->width;
733 int height = s->avctx->height;
734
735 if (buf_size < 3) {
736 av_log(s->avctx, AV_LOG_ERROR16, "Insufficient data (%d) for header\n", buf_size);
737 return AVERROR_INVALIDDATA(-(int)(('I') | (('N') << 8) | (('D') << 16) | ((
unsigned)('A') << 24)))
;
738 }
739
740 s->keyframe = !(buf[0] & 1);
741 s->profile = (buf[0]>>1) & 7;
742 s->invisible = !(buf[0] & 0x10);
743 header_size = AV_RL24(buf)((((const uint8_t*)(buf))[2] << 16) | (((const uint8_t*
)(buf))[1] << 8) | ((const uint8_t*)(buf))[0])
>> 5;
744 buf += 3;
745 buf_size -= 3;
746
747 s->header_partition_size = header_size;
748
749 if (s->profile > 3)
750 av_log(s->avctx, AV_LOG_WARNING24, "Unknown profile %d\n", s->profile);
751
752 if (!s->profile)
753 memcpy(s->put_pixels_tab, s->vp8dsp.put_vp8_epel_pixels_tab,
754 sizeof(s->put_pixels_tab));
755 else // profile 1-3 use bilinear, 4+ aren't defined so whatever
756 memcpy(s->put_pixels_tab, s->vp8dsp.put_vp8_bilinear_pixels_tab,
757 sizeof(s->put_pixels_tab));
758
759 if (header_size > buf_size - 7 * s->keyframe) {
760 av_log(s->avctx, AV_LOG_ERROR16, "Header size larger than data provided\n");
761 return AVERROR_INVALIDDATA(-(int)(('I') | (('N') << 8) | (('D') << 16) | ((
unsigned)('A') << 24)))
;
762 }
763
764 if (s->keyframe) {
765 if (AV_RL24(buf)((((const uint8_t*)(buf))[2] << 16) | (((const uint8_t*
)(buf))[1] << 8) | ((const uint8_t*)(buf))[0])
!= 0x2a019d) {
766 av_log(s->avctx, AV_LOG_ERROR16,
767 "Invalid start code 0x%x\n", AV_RL24(buf)((((const uint8_t*)(buf))[2] << 16) | (((const uint8_t*
)(buf))[1] << 8) | ((const uint8_t*)(buf))[0])
);
768 return AVERROR_INVALIDDATA(-(int)(('I') | (('N') << 8) | (('D') << 16) | ((
unsigned)('A') << 24)))
;
769 }
770 width = AV_RL16(buf + 3)(((const union unaligned_16 *) (buf + 3))->l) & 0x3fff;
771 height = AV_RL16(buf + 5)(((const union unaligned_16 *) (buf + 5))->l) & 0x3fff;
772 hscale = buf[4] >> 6;
773 vscale = buf[6] >> 6;
774 buf += 7;
775 buf_size -= 7;
776
777 if (hscale || vscale)
778 avpriv_request_sample(s->avctx, "Upscaling");
779
780 s->update_golden = s->update_altref = VP8_FRAME_CURRENT;
781 vp78_reset_probability_tables(s);
782 memcpy(s->prob->pred16x16, vp8_pred16x16_prob_inter,
783 sizeof(s->prob->pred16x16));
784 memcpy(s->prob->pred8x8c, vp8_pred8x8c_prob_inter,
785 sizeof(s->prob->pred8x8c));
786 memcpy(s->prob->mvc, vp8_mv_default_prob,
787 sizeof(s->prob->mvc));
788 memset(&s->segmentation, 0, sizeof(s->segmentation));
789 memset(&s->lf_delta, 0, sizeof(s->lf_delta));
790 }
791
792 ret = ff_vpx_init_range_decoder(c, buf, header_size);
793 if (ret < 0)
794 return ret;
795 buf += header_size;
796 buf_size -= header_size;
797
798 if (s->keyframe) {
799 s->colorspace = vp89_rac_get(c);
800 if (s->colorspace)
801 av_log(s->avctx, AV_LOG_WARNING24, "Unspecified colorspace\n");
802 s->fullrange = vp89_rac_get(c);
803 }
804
805 if ((s->segmentation.enabled = vp89_rac_get(c)))
806 parse_segment_info(s);
807 else
808 s->segmentation.update_map = 0; // FIXME: move this to some init function?
809
810 s->filter.simple = vp89_rac_get(c);
811 s->filter.level = vp89_rac_get_uint(c, 6);
812 s->filter.sharpness = vp89_rac_get_uint(c, 3);
813
814 if ((s->lf_delta.enabled = vp89_rac_get(c))) {
815 s->lf_delta.update = vp89_rac_get(c);
816 if (s->lf_delta.update)
817 update_lf_deltas(s);
818 }
819
820 if (setup_partitions(s, buf, buf_size)) {
821 av_log(s->avctx, AV_LOG_ERROR16, "Invalid partitions\n");
822 return AVERROR_INVALIDDATA(-(int)(('I') | (('N') << 8) | (('D') << 16) | ((
unsigned)('A') << 24)))
;
823 }
824
825 if (!s->macroblocks_base || /* first frame */
826 width != s->avctx->width || height != s->avctx->height ||
827 (width+15)/16 != s->mb_width || (height+15)/16 != s->mb_height)
828 if ((ret = vp8_update_dimensions(s, width, height)) < 0)
829 return ret;
830
831 vp8_get_quants(s);
832
833 if (!s->keyframe) {
834 update_refs(s);
835 s->sign_bias[VP8_FRAME_GOLDEN] = vp89_rac_get(c);
836 s->sign_bias[VP8_FRAME_ALTREF] = vp89_rac_get(c);
837 }
838
839 // if we aren't saving this frame's probabilities for future frames,
840 // make a copy of the current probabilities
841 if (!(s->update_probabilities = vp89_rac_get(c)))
842 s->prob[1] = s->prob[0];
843
844 s->update_last = s->keyframe || vp89_rac_get(c);
845
846 vp78_update_probability_tables(s);
847
848 if ((s->mbskip_enabled = vp89_rac_get(c)))
849 s->prob->mbskip = vp89_rac_get_uint(c, 8);
850
851 if (!s->keyframe) {
852 s->prob->intra = vp89_rac_get_uint(c, 8);
853 s->prob->last = vp89_rac_get_uint(c, 8);
854 s->prob->golden = vp89_rac_get_uint(c, 8);
855 vp78_update_pred16x16_pred8x8_mvc_probabilities(s, VP8_MVC_SIZE19);
856 }
857
858 // Record the entropy coder state here so that hwaccels can use it.
859 s->c.code_word = vpx_rac_renorm(&s->c);
860 s->coder_state_at_header_end.input = s->c.buffer - (-s->c.bits / 8);
861 s->coder_state_at_header_end.range = s->c.high;
862 s->coder_state_at_header_end.value = s->c.code_word >> 16;
863 s->coder_state_at_header_end.bit_count = -s->c.bits % 8;
864
865 return 0;
866}
867
868static av_always_inline__attribute__((always_inline)) inline
869void clamp_mv(const VP8mvbounds *s, VP8mv *dst, const VP8mv *src)
870{
871 dst->x = av_clipav_clip_c(src->x, av_clipav_clip_c(s->mv_min.x, INT16_MIN(-32767-1), INT16_MAX(32767)),
872 av_clipav_clip_c(s->mv_max.x, INT16_MIN(-32767-1), INT16_MAX(32767)));
873 dst->y = av_clipav_clip_c(src->y, av_clipav_clip_c(s->mv_min.y, INT16_MIN(-32767-1), INT16_MAX(32767)),
874 av_clipav_clip_c(s->mv_max.y, INT16_MIN(-32767-1), INT16_MAX(32767)));
875}
876
877/**
878 * Motion vector coding, 17.1.
879 */
880static av_always_inline__attribute__((always_inline)) inline int read_mv_component(VPXRangeCoder *c, const uint8_t *p, int vp7)
881{
882 int bit, x = 0;
883
884 if (vpx_rac_get_prob_branchy(c, p[0])) {
885 int i;
886
887 for (i = 0; i < 3; i++)
888 x += vpx_rac_get_probvpx_rac_get_prob(c, p[9 + i]) << i;
889 for (i = (vp7 ? 7 : 9); i > 3; i--)
890 x += vpx_rac_get_probvpx_rac_get_prob(c, p[9 + i]) << i;
891 if (!(x & (vp7 ? 0xF0 : 0xFFF0)) || vpx_rac_get_probvpx_rac_get_prob(c, p[12]))
892 x += 8;
893 } else {
894 // small_mvtree
895 const uint8_t *ps = p + 2;
896 bit = vpx_rac_get_probvpx_rac_get_prob(c, *ps);
897 ps += 1 + 3 * bit;
898 x += 4 * bit;
899 bit = vpx_rac_get_probvpx_rac_get_prob(c, *ps);
900 ps += 1 + bit;
901 x += 2 * bit;
902 x += vpx_rac_get_probvpx_rac_get_prob(c, *ps);
903 }
904
905 return (x && vpx_rac_get_probvpx_rac_get_prob(c, p[1])) ? -x : x;
906}
907
908static int vp7_read_mv_component(VPXRangeCoder *c, const uint8_t *p)
909{
910 return read_mv_component(c, p, 1);
911}
912
913static int vp8_read_mv_component(VPXRangeCoder *c, const uint8_t *p)
914{
915 return read_mv_component(c, p, 0);
916}
917
918static av_always_inline__attribute__((always_inline)) inline
919const uint8_t *get_submv_prob(uint32_t left, uint32_t top, int is_vp7)
920{
921 if (is_vp7)
922 return vp7_submv_prob;
923
924 if (left == top)
925 return vp8_submv_prob[4 - !!left];
926 if (!top)
927 return vp8_submv_prob[2];
928 return vp8_submv_prob[1 - !!left];
929}
930
931/**
932 * Split motion vector prediction, 16.4.
933 * @returns the number of motion vectors parsed (2, 4 or 16)
934 */
935static av_always_inline__attribute__((always_inline)) inline
936int decode_splitmvs(const VP8Context *s, VPXRangeCoder *c, VP8Macroblock *mb,
937 int layout, int is_vp7)
938{
939 int part_idx;
940 int n, num;
941 const VP8Macroblock *top_mb;
942 const VP8Macroblock *left_mb = &mb[-1];
943 const uint8_t *mbsplits_left = vp8_mbsplits[left_mb->partitioning];
944 const uint8_t *mbsplits_top, *mbsplits_cur, *firstidx;
945 const VP8mv *top_mv;
946 const VP8mv *left_mv = left_mb->bmv;
947 const VP8mv *cur_mv = mb->bmv;
948
949 if (!layout) // layout is inlined, s->mb_layout is not
950 top_mb = &mb[2];
951 else
952 top_mb = &mb[-s->mb_width - 1];
953 mbsplits_top = vp8_mbsplits[top_mb->partitioning];
954 top_mv = top_mb->bmv;
955
956 if (vpx_rac_get_prob_branchy(c, vp8_mbsplit_prob[0])) {
957 if (vpx_rac_get_prob_branchy(c, vp8_mbsplit_prob[1]))
958 part_idx = VP8_SPLITMVMODE_16x8 + vpx_rac_get_probvpx_rac_get_prob(c, vp8_mbsplit_prob[2]);
959 else
960 part_idx = VP8_SPLITMVMODE_8x8;
961 } else {
962 part_idx = VP8_SPLITMVMODE_4x4;
963 }
964
965 num = vp8_mbsplit_count[part_idx];
966 mbsplits_cur = vp8_mbsplits[part_idx],
967 firstidx = vp8_mbfirstidx[part_idx];
968 mb->partitioning = part_idx;
969
970 for (n = 0; n < num; n++) {
971 int k = firstidx[n];
972 uint32_t left, above;
973 const uint8_t *submv_prob;
974
975 if (!(k & 3))
976 left = AV_RN32A(&left_mv[mbsplits_left[k + 3]])(((const av_alias32*)(&left_mv[mbsplits_left[k + 3]]))->
u32)
;
977 else
978 left = AV_RN32A(&cur_mv[mbsplits_cur[k - 1]])(((const av_alias32*)(&cur_mv[mbsplits_cur[k - 1]]))->
u32)
;
979 if (k <= 3)
980 above = AV_RN32A(&top_mv[mbsplits_top[k + 12]])(((const av_alias32*)(&top_mv[mbsplits_top[k + 12]]))->
u32)
;
981 else
982 above = AV_RN32A(&cur_mv[mbsplits_cur[k - 4]])(((const av_alias32*)(&cur_mv[mbsplits_cur[k - 4]]))->
u32)
;
983
984 submv_prob = get_submv_prob(left, above, is_vp7);
985
986 if (vpx_rac_get_prob_branchy(c, submv_prob[0])) {
987 if (vpx_rac_get_prob_branchy(c, submv_prob[1])) {
988 if (vpx_rac_get_prob_branchy(c, submv_prob[2])) {
989 mb->bmv[n].y = mb->mv.y +
990 read_mv_component(c, s->prob->mvc[0], is_vp7);
991 mb->bmv[n].x = mb->mv.x +
992 read_mv_component(c, s->prob->mvc[1], is_vp7);
993 } else {
994 AV_ZERO32(&mb->bmv[n])(((av_alias32*)(&mb->bmv[n]))->u32 = 0);
995 }
996 } else {
997 AV_WN32A(&mb->bmv[n], above)(((av_alias32*)(&mb->bmv[n]))->u32 = (above));
998 }
999 } else {
1000 AV_WN32A(&mb->bmv[n], left)(((av_alias32*)(&mb->bmv[n]))->u32 = (left));
1001 }
1002 }
1003
1004 return num;
1005}
1006
1007/**
1008 * The vp7 reference decoder uses a padding macroblock column (added to right
1009 * edge of the frame) to guard against illegal macroblock offsets. The
1010 * algorithm has bugs that permit offsets to straddle the padding column.
1011 * This function replicates those bugs.
1012 *
1013 * @param[out] edge_x macroblock x address
1014 * @param[out] edge_y macroblock y address
1015 *
1016 * @return macroblock offset legal (boolean)
1017 */
1018static int vp7_calculate_mb_offset(int mb_x, int mb_y, int mb_width,
1019 int xoffset, int yoffset, int boundary,
1020 int *edge_x, int *edge_y)
1021{
1022 int vwidth = mb_width + 1;
1023 int new = (mb_y + yoffset) * vwidth + mb_x + xoffset;
1024 if (new < boundary || new % vwidth == vwidth - 1)
1025 return 0;
1026 *edge_y = new / vwidth;
1027 *edge_x = new % vwidth;
1028 return 1;
1029}
1030
1031static const VP8mv *get_bmv_ptr(const VP8Macroblock *mb, int subblock)
1032{
1033 return &mb->bmv[mb->mode == VP8_MVMODE_SPLIT ? vp8_mbsplits[mb->partitioning][subblock] : 0];
1034}
1035
1036static av_always_inline__attribute__((always_inline)) inline
1037void vp7_decode_mvs(VP8Context *s, VP8Macroblock *mb,
1038 int mb_x, int mb_y, int layout)
1039{
1040 enum { CNT_ZERO, CNT_NEAREST, CNT_NEAR };
1041 enum { VP8_EDGE_TOP, VP8_EDGE_LEFT, VP8_EDGE_TOPLEFT };
1042 int idx = CNT_ZERO;
1043 VP8mv near_mv[3];
1044 uint8_t cnt[3] = { 0 };
1045 VPXRangeCoder *c = &s->c;
1046 int i;
1047
1048 AV_ZERO32(&near_mv[0])(((av_alias32*)(&near_mv[0]))->u32 = 0);
1049 AV_ZERO32(&near_mv[1])(((av_alias32*)(&near_mv[1]))->u32 = 0);
1050 AV_ZERO32(&near_mv[2])(((av_alias32*)(&near_mv[2]))->u32 = 0);
1051
1052 for (i = 0; i < VP7_MV_PRED_COUNT12; i++) {
1053 const VP7MVPred * pred = &vp7_mv_pred[i];
1054 int edge_x, edge_y;
1055
1056 if (vp7_calculate_mb_offset(mb_x, mb_y, s->mb_width, pred->xoffset,
1057 pred->yoffset, !s->profile, &edge_x, &edge_y)) {
1058 const VP8Macroblock *edge = (s->mb_layout == 1)
1059 ? s->macroblocks_base + 1 + edge_x +
1060 (s->mb_width + 1) * (edge_y + 1)
1061 : s->macroblocks + edge_x +
1062 (s->mb_height - edge_y - 1) * 2;
1063 uint32_t mv = AV_RN32A(get_bmv_ptr(edge, vp7_mv_pred[i].subblock))(((const av_alias32*)(get_bmv_ptr(edge, vp7_mv_pred[i].subblock
)))->u32)
;
1064 if (mv) {
1065 if (AV_RN32A(&near_mv[CNT_NEAREST])(((const av_alias32*)(&near_mv[CNT_NEAREST]))->u32)) {
1066 if (mv == AV_RN32A(&near_mv[CNT_NEAREST])(((const av_alias32*)(&near_mv[CNT_NEAREST]))->u32)) {
1067 idx = CNT_NEAREST;
1068 } else if (AV_RN32A(&near_mv[CNT_NEAR])(((const av_alias32*)(&near_mv[CNT_NEAR]))->u32)) {
1069 if (mv != AV_RN32A(&near_mv[CNT_NEAR])(((const av_alias32*)(&near_mv[CNT_NEAR]))->u32))
1070 continue;
1071 idx = CNT_NEAR;
1072 } else {
1073 AV_WN32A(&near_mv[CNT_NEAR], mv)(((av_alias32*)(&near_mv[CNT_NEAR]))->u32 = (mv));
1074 idx = CNT_NEAR;
1075 }
1076 } else {
1077 AV_WN32A(&near_mv[CNT_NEAREST], mv)(((av_alias32*)(&near_mv[CNT_NEAREST]))->u32 = (mv));
1078 idx = CNT_NEAREST;
1079 }
1080 } else {
1081 idx = CNT_ZERO;
1082 }
1083 } else {
1084 idx = CNT_ZERO;
1085 }
1086 cnt[idx] += vp7_mv_pred[i].score;
1087 }
1088
1089 mb->partitioning = VP8_SPLITMVMODE_NONE;
1090
1091 if (vpx_rac_get_prob_branchy(c, vp7_mode_contexts[cnt[CNT_ZERO]][0])) {
1092 mb->mode = VP8_MVMODE_MV;
1093
1094 if (vpx_rac_get_prob_branchy(c, vp7_mode_contexts[cnt[CNT_NEAREST]][1])) {
1095
1096 if (vpx_rac_get_prob_branchy(c, vp7_mode_contexts[cnt[CNT_NEAR]][2])) {
1097
1098 if (cnt[CNT_NEAREST] > cnt[CNT_NEAR])
1099 AV_WN32A(&mb->mv, cnt[CNT_ZERO] > cnt[CNT_NEAREST] ? 0 : AV_RN32A(&near_mv[CNT_NEAREST]))(((av_alias32*)(&mb->mv))->u32 = (cnt[CNT_ZERO] >
cnt[CNT_NEAREST] ? 0 : (((const av_alias32*)(&near_mv[CNT_NEAREST
]))->u32)))
;
1100 else
1101 AV_WN32A(&mb->mv, cnt[CNT_ZERO] > cnt[CNT_NEAR] ? 0 : AV_RN32A(&near_mv[CNT_NEAR]))(((av_alias32*)(&mb->mv))->u32 = (cnt[CNT_ZERO] >
cnt[CNT_NEAR] ? 0 : (((const av_alias32*)(&near_mv[CNT_NEAR
]))->u32)))
;
1102
1103 if (vpx_rac_get_prob_branchy(c, vp7_mode_contexts[cnt[CNT_NEAR]][3])) {
1104 mb->mode = VP8_MVMODE_SPLIT;
1105 mb->mv = mb->bmv[decode_splitmvs(s, c, mb, layout, IS_VP71) - 1];
1106 } else {
1107 mb->mv.y += vp7_read_mv_component(c, s->prob->mvc[0]);
1108 mb->mv.x += vp7_read_mv_component(c, s->prob->mvc[1]);
1109 mb->bmv[0] = mb->mv;
1110 }
1111 } else {
1112 mb->mv = near_mv[CNT_NEAR];
1113 mb->bmv[0] = mb->mv;
1114 }
1115 } else {
1116 mb->mv = near_mv[CNT_NEAREST];
1117 mb->bmv[0] = mb->mv;
1118 }
1119 } else {
1120 mb->mode = VP8_MVMODE_ZERO;
1121 AV_ZERO32(&mb->mv)(((av_alias32*)(&mb->mv))->u32 = 0);
1122 mb->bmv[0] = mb->mv;
1123 }
1124}
1125
1126static av_always_inline__attribute__((always_inline)) inline
1127void vp8_decode_mvs(VP8Context *s, const VP8mvbounds *mv_bounds, VP8Macroblock *mb,
1128 int mb_x, int mb_y, int layout)
1129{
1130 VP8Macroblock *mb_edge[3] = { 0 /* top */,
1131 mb - 1 /* left */,
1132 0 /* top-left */ };
1133 enum { CNT_ZERO, CNT_NEAREST, CNT_NEAR, CNT_SPLITMV };
1134 enum { VP8_EDGE_TOP, VP8_EDGE_LEFT, VP8_EDGE_TOPLEFT };
1135 int idx = CNT_ZERO;
1136 int cur_sign_bias = s->sign_bias[mb->ref_frame];
1137 const int8_t *sign_bias = s->sign_bias;
1138 VP8mv near_mv[4];
1139 uint8_t cnt[4] = { 0 };
1140 VPXRangeCoder *c = &s->c;
1141
1142 if (!layout) { // layout is inlined (s->mb_layout is not)
1143 mb_edge[0] = mb + 2;
1144 mb_edge[2] = mb + 1;
1145 } else {
1146 mb_edge[0] = mb - s->mb_width - 1;
1147 mb_edge[2] = mb - s->mb_width - 2;
1148 }
1149
1150 AV_ZERO32(&near_mv[0])(((av_alias32*)(&near_mv[0]))->u32 = 0);
1151 AV_ZERO32(&near_mv[1])(((av_alias32*)(&near_mv[1]))->u32 = 0);
1152 AV_ZERO32(&near_mv[2])(((av_alias32*)(&near_mv[2]))->u32 = 0);
1153
1154 /* Process MB on top, left and top-left */
1155#define MV_EDGE_CHECK(n){ const VP8Macroblock *edge = mb_edge[n]; int edge_ref = edge
->ref_frame; if (edge_ref != VP8_FRAME_CURRENT) { uint32_t
mv = (((const av_alias32*)(&edge->mv))->u32); if (
mv) { if (cur_sign_bias != sign_bias[edge_ref]) { mv = ~mv; mv
= ((mv & 0x7fff7fff) + 0x00010001) ^ (mv & 0x80008000
); } if (!n || mv != (((const av_alias32*)(&near_mv[idx])
)->u32)) (((av_alias32*)(&near_mv[++idx]))->u32 = (
mv)); cnt[idx] += 1 + (n != 2); } else cnt[CNT_ZERO] += 1 + (
n != 2); } }
\
1156 { \
1157 const VP8Macroblock *edge = mb_edge[n]; \
1158 int edge_ref = edge->ref_frame; \
1159 if (edge_ref != VP8_FRAME_CURRENT) { \
1160 uint32_t mv = AV_RN32A(&edge->mv)(((const av_alias32*)(&edge->mv))->u32); \
1161 if (mv) { \
1162 if (cur_sign_bias != sign_bias[edge_ref]) { \
1163 /* SWAR negate of the values in mv. */ \
1164 mv = ~mv; \
1165 mv = ((mv & 0x7fff7fff) + \
1166 0x00010001) ^ (mv & 0x80008000); \
1167 } \
1168 if (!n || mv != AV_RN32A(&near_mv[idx])(((const av_alias32*)(&near_mv[idx]))->u32)) \
1169 AV_WN32A(&near_mv[++idx], mv)(((av_alias32*)(&near_mv[++idx]))->u32 = (mv)); \
1170 cnt[idx] += 1 + (n != 2); \
1171 } else \
1172 cnt[CNT_ZERO] += 1 + (n != 2); \
1173 } \
1174 }
1175
1176 MV_EDGE_CHECK(0){ const VP8Macroblock *edge = mb_edge[0]; int edge_ref = edge
->ref_frame; if (edge_ref != VP8_FRAME_CURRENT) { uint32_t
mv = (((const av_alias32*)(&edge->mv))->u32); if (
mv) { if (cur_sign_bias != sign_bias[edge_ref]) { mv = ~mv; mv
= ((mv & 0x7fff7fff) + 0x00010001) ^ (mv & 0x80008000
); } if (!0 || mv != (((const av_alias32*)(&near_mv[idx])
)->u32)) (((av_alias32*)(&near_mv[++idx]))->u32 = (
mv)); cnt[idx] += 1 + (0 != 2); } else cnt[CNT_ZERO] += 1 + (
0 != 2); } }
1177 MV_EDGE_CHECK(1){ const VP8Macroblock *edge = mb_edge[1]; int edge_ref = edge
->ref_frame; if (edge_ref != VP8_FRAME_CURRENT) { uint32_t
mv = (((const av_alias32*)(&edge->mv))->u32); if (
mv) { if (cur_sign_bias != sign_bias[edge_ref]) { mv = ~mv; mv
= ((mv & 0x7fff7fff) + 0x00010001) ^ (mv & 0x80008000
); } if (!1 || mv != (((const av_alias32*)(&near_mv[idx])
)->u32)) (((av_alias32*)(&near_mv[++idx]))->u32 = (
mv)); cnt[idx] += 1 + (1 != 2); } else cnt[CNT_ZERO] += 1 + (
1 != 2); } }
1178 MV_EDGE_CHECK(2){ const VP8Macroblock *edge = mb_edge[2]; int edge_ref = edge
->ref_frame; if (edge_ref != VP8_FRAME_CURRENT) { uint32_t
mv = (((const av_alias32*)(&edge->mv))->u32); if (
mv) { if (cur_sign_bias != sign_bias[edge_ref]) { mv = ~mv; mv
= ((mv & 0x7fff7fff) + 0x00010001) ^ (mv & 0x80008000
); } if (!2 || mv != (((const av_alias32*)(&near_mv[idx])
)->u32)) (((av_alias32*)(&near_mv[++idx]))->u32 = (
mv)); cnt[idx] += 1 + (2 != 2); } else cnt[CNT_ZERO] += 1 + (
2 != 2); } }
1179
1180 mb->partitioning = VP8_SPLITMVMODE_NONE;
1181 if (vpx_rac_get_prob_branchy(c, vp8_mode_contexts[cnt[CNT_ZERO]][0])) {
1182 mb->mode = VP8_MVMODE_MV;
1183
1184 /* If we have three distinct MVs, merge first and last if they're the same */
1185 if (cnt[CNT_SPLITMV] &&
1186 AV_RN32A(&near_mv[1 + VP8_EDGE_TOP])(((const av_alias32*)(&near_mv[1 + VP8_EDGE_TOP]))->u32
)
== AV_RN32A(&near_mv[1 + VP8_EDGE_TOPLEFT])(((const av_alias32*)(&near_mv[1 + VP8_EDGE_TOPLEFT]))->
u32)
)
1187 cnt[CNT_NEAREST] += 1;
1188
1189 /* Swap near and nearest if necessary */
1190 if (cnt[CNT_NEAR] > cnt[CNT_NEAREST]) {
1191 FFSWAP(uint8_t, cnt[CNT_NEAREST], cnt[CNT_NEAR])do{uint8_t SWAP_tmp= cnt[CNT_NEAR]; cnt[CNT_NEAR]= cnt[CNT_NEAREST
]; cnt[CNT_NEAREST]= SWAP_tmp;}while(0)
;
1192 FFSWAP(VP8mv, near_mv[CNT_NEAREST], near_mv[CNT_NEAR])do{VP8mv SWAP_tmp= near_mv[CNT_NEAR]; near_mv[CNT_NEAR]= near_mv
[CNT_NEAREST]; near_mv[CNT_NEAREST]= SWAP_tmp;}while(0)
;
1193 }
1194
1195 if (vpx_rac_get_prob_branchy(c, vp8_mode_contexts[cnt[CNT_NEAREST]][1])) {
1196 if (vpx_rac_get_prob_branchy(c, vp8_mode_contexts[cnt[CNT_NEAR]][2])) {
1197 /* Choose the best mv out of 0,0 and the nearest mv */
1198 clamp_mv(mv_bounds, &mb->mv, &near_mv[CNT_ZERO + (cnt[CNT_NEAREST] >= cnt[CNT_ZERO])]);
1199 cnt[CNT_SPLITMV] = ((mb_edge[VP8_EDGE_LEFT]->mode == VP8_MVMODE_SPLIT) +
1200 (mb_edge[VP8_EDGE_TOP]->mode == VP8_MVMODE_SPLIT)) * 2 +
1201 (mb_edge[VP8_EDGE_TOPLEFT]->mode == VP8_MVMODE_SPLIT);
1202
1203 if (vpx_rac_get_prob_branchy(c, vp8_mode_contexts[cnt[CNT_SPLITMV]][3])) {
1204 mb->mode = VP8_MVMODE_SPLIT;
1205 mb->mv = mb->bmv[decode_splitmvs(s, c, mb, layout, IS_VP80) - 1];
1206 } else {
1207 mb->mv.y += vp8_read_mv_component(c, s->prob->mvc[0]);
1208 mb->mv.x += vp8_read_mv_component(c, s->prob->mvc[1]);
1209 mb->bmv[0] = mb->mv;
1210 }
1211 } else {
1212 clamp_mv(mv_bounds, &mb->mv, &near_mv[CNT_NEAR]);
1213 mb->bmv[0] = mb->mv;
1214 }
1215 } else {
1216 clamp_mv(mv_bounds, &mb->mv, &near_mv[CNT_NEAREST]);
1217 mb->bmv[0] = mb->mv;
1218 }
1219 } else {
1220 mb->mode = VP8_MVMODE_ZERO;
1221 AV_ZERO32(&mb->mv)(((av_alias32*)(&mb->mv))->u32 = 0);
1222 mb->bmv[0] = mb->mv;
1223 }
1224}
1225
1226static av_always_inline__attribute__((always_inline)) inline
1227void decode_intra4x4_modes(VP8Context *s, VPXRangeCoder *c, VP8Macroblock *mb,
1228 int mb_x, int keyframe, int layout)
1229{
1230 uint8_t *intra4x4 = mb->intra4x4_pred_mode_mb;
1231
1232 if (layout) {
1233 VP8Macroblock *mb_top = mb - s->mb_width - 1;
1234 memcpy(mb->intra4x4_pred_mode_top, mb_top->intra4x4_pred_mode_top, 4);
1235 }
1236 if (keyframe) {
1237 int x, y;
1238 uint8_t *top;
1239 uint8_t *const left = s->intra4x4_pred_mode_left;
1240 if (layout)
1241 top = mb->intra4x4_pred_mode_top;
1242 else
1243 top = s->intra4x4_pred_mode_top + 4 * mb_x;
1244 for (y = 0; y < 4; y++) {
1245 for (x = 0; x < 4; x++) {
1246 const uint8_t *ctx;
1247 ctx = vp8_pred4x4_prob_intra[top[x]][left[y]];
1248 *intra4x4 = vp89_rac_get_tree(c, vp8_pred4x4_tree, ctx);
1249 left[y] = top[x] = *intra4x4;
1250 intra4x4++;
1251 }
1252 }
1253 } else {
1254 int i;
1255 for (i = 0; i < 16; i++)
1256 intra4x4[i] = vp89_rac_get_tree(c, vp8_pred4x4_tree,
1257 vp8_pred4x4_prob_inter);
1258 }
1259}
1260
1261static av_always_inline__attribute__((always_inline)) inline
1262void decode_mb_mode(VP8Context *s, const VP8mvbounds *mv_bounds,
1263 VP8Macroblock *mb, int mb_x, int mb_y,
1264 uint8_t *segment, const uint8_t *ref, int layout, int is_vp7)
1265{
1266 VPXRangeCoder *c = &s->c;
1267 static const char * const vp7_feature_name[] = { "q-index",
1268 "lf-delta",
1269 "partial-golden-update",
1270 "blit-pitch" };
1271 if (is_vp7) {
1272 int i;
1273 *segment = 0;
1274 for (i = 0; i < 4; i++) {
1275 if (s->feature_enabled[i]) {
1276 if (vpx_rac_get_prob_branchy(c, s->feature_present_prob[i])) {
1277 int index = vp89_rac_get_tree(c, vp7_feature_index_tree,
1278 s->feature_index_prob[i]);
1279 av_log(s->avctx, AV_LOG_WARNING24,
1280 "Feature %s present in macroblock (value 0x%x)\n",
1281 vp7_feature_name[i], s->feature_value[i][index]);
1282 }
1283 }
1284 }
1285 } else if (s->segmentation.update_map) {
1286 int bit = vpx_rac_get_probvpx_rac_get_prob(c, s->prob->segmentid[0]);
1287 *segment = vpx_rac_get_probvpx_rac_get_prob(c, s->prob->segmentid[1+bit]) + 2*bit;
1288 } else if (s->segmentation.enabled)
1289 *segment = ref ? *ref : *segment;
1290 mb->segment = *segment;
1291
1292 mb->skip = s->mbskip_enabled ? vpx_rac_get_probvpx_rac_get_prob(c, s->prob->mbskip) : 0;
1293
1294 if (s->keyframe) {
1295 mb->mode = vp89_rac_get_tree(c, vp8_pred16x16_tree_intra,
1296 vp8_pred16x16_prob_intra);
1297
1298 if (mb->mode == MODE_I4x44) {
1299 decode_intra4x4_modes(s, c, mb, mb_x, 1, layout);
1300 } else {
1301 const uint32_t modes = (is_vp7 ? vp7_pred4x4_mode
1302 : vp8_pred4x4_mode)[mb->mode] * 0x01010101u;
1303 if (s->mb_layout)
1304 AV_WN32A(mb->intra4x4_pred_mode_top, modes)(((av_alias32*)(mb->intra4x4_pred_mode_top))->u32 = (modes
))
;
1305 else
1306 AV_WN32A(s->intra4x4_pred_mode_top + 4 * mb_x, modes)(((av_alias32*)(s->intra4x4_pred_mode_top + 4 * mb_x))->
u32 = (modes))
;
1307 AV_WN32A(s->intra4x4_pred_mode_left, modes)(((av_alias32*)(s->intra4x4_pred_mode_left))->u32 = (modes
))
;
1308 }
1309
1310 mb->chroma_pred_mode = vp89_rac_get_tree(c, vp8_pred8x8c_tree,
1311 vp8_pred8x8c_prob_intra);
1312 mb->ref_frame = VP8_FRAME_CURRENT;
1313 } else if (vpx_rac_get_prob_branchy(c, s->prob->intra)) {
1314 // inter MB, 16.2
1315 if (vpx_rac_get_prob_branchy(c, s->prob->last))
1316 mb->ref_frame =
1317 (!is_vp7 && vpx_rac_get_probvpx_rac_get_prob(c, s->prob->golden)) ? VP8_FRAME_ALTREF
1318 : VP8_FRAME_GOLDEN;
1319 else
1320 mb->ref_frame = VP8_FRAME_PREVIOUS;
1321 s->ref_count[mb->ref_frame - 1]++;
1322
1323 // motion vectors, 16.3
1324 if (is_vp7)
1325 vp7_decode_mvs(s, mb, mb_x, mb_y, layout);
1326 else
1327 vp8_decode_mvs(s, mv_bounds, mb, mb_x, mb_y, layout);
1328 } else {
1329 // intra MB, 16.1
1330 mb->mode = vp89_rac_get_tree(c, vp8_pred16x16_tree_inter,
1331 s->prob->pred16x16);
1332
1333 if (mb->mode == MODE_I4x44)
1334 decode_intra4x4_modes(s, c, mb, mb_x, 0, layout);
1335
1336 mb->chroma_pred_mode = vp89_rac_get_tree(c, vp8_pred8x8c_tree,
1337 s->prob->pred8x8c);
1338 mb->ref_frame = VP8_FRAME_CURRENT;
1339 mb->partitioning = VP8_SPLITMVMODE_NONE;
1340 AV_ZERO32(&mb->bmv[0])(((av_alias32*)(&mb->bmv[0]))->u32 = 0);
1341 }
1342}
1343
1344/**
1345 * @param r arithmetic bitstream reader context
1346 * @param block destination for block coefficients
1347 * @param probs probabilities to use when reading trees from the bitstream
1348 * @param i initial coeff index, 0 unless a separate DC block is coded
1349 * @param qmul array holding the dc/ac dequant factor at position 0/1
1350 *
1351 * @return 0 if no coeffs were decoded
1352 * otherwise, the index of the last coeff decoded plus one
1353 */
1354static av_always_inline__attribute__((always_inline)) inline
1355int decode_block_coeffs_internal(VPXRangeCoder *r, int16_t block[16],
1356 uint8_t probs[16][3][NUM_DCT_TOKENS - 1],
1357 int i, const uint8_t *token_prob, const int16_t qmul[2],
1358 const uint8_t scan[16], int vp7)
1359{
1360 VPXRangeCoder c = *r;
1361 goto skip_eob;
1362 do {
1363 int coeff;
1364restart:
1365 if (!vpx_rac_get_prob_branchy(&c, token_prob[0])) // DCT_EOB
1366 break;
1367
1368skip_eob:
1369 if (!vpx_rac_get_prob_branchy(&c, token_prob[1])) { // DCT_0
1370 if (++i == 16)
1371 break; // invalid input; blocks should end with EOB
1372 token_prob = probs[i][0];
1373 if (vp7)
1374 goto restart;
1375 goto skip_eob;
1376 }
1377
1378 if (!vpx_rac_get_prob_branchy(&c, token_prob[2])) { // DCT_1
1379 coeff = 1;
1380 token_prob = probs[i + 1][1];
1381 } else {
1382 if (!vpx_rac_get_prob_branchy(&c, token_prob[3])) { // DCT 2,3,4
1383 coeff = vpx_rac_get_prob_branchy(&c, token_prob[4]);
1384 if (coeff)
1385 coeff += vpx_rac_get_probvpx_rac_get_prob(&c, token_prob[5]);
1386 coeff += 2;
1387 } else {
1388 // DCT_CAT*
1389 if (!vpx_rac_get_prob_branchy(&c, token_prob[6])) {
1390 if (!vpx_rac_get_prob_branchy(&c, token_prob[7])) { // DCT_CAT1
1391 coeff = 5 + vpx_rac_get_probvpx_rac_get_prob(&c, vp8_dct_cat1_prob[0]);
1392 } else { // DCT_CAT2
1393 coeff = 7;
1394 coeff += vpx_rac_get_probvpx_rac_get_prob(&c, vp8_dct_cat2_prob[0]) << 1;
1395 coeff += vpx_rac_get_probvpx_rac_get_prob(&c, vp8_dct_cat2_prob[1]);
1396 }
1397 } else { // DCT_CAT3 and up
1398 int a = vpx_rac_get_probvpx_rac_get_prob(&c, token_prob[8]);
1399 int b = vpx_rac_get_probvpx_rac_get_prob(&c, token_prob[9 + a]);
1400 int cat = (a << 1) + b;
1401 coeff = 3 + (8 << cat);
1402 coeff += vp8_rac_get_coeff(&c, ff_vp8_dct_cat_prob[cat]);
1403 }
1404 }
1405 token_prob = probs[i + 1][2];
1406 }
1407 block[scan[i]] = (vp89_rac_get(&c) ? -coeff : coeff) * qmul[!!i];
1408 } while (++i < 16);
1409
1410 *r = c;
1411 return i;
1412}
1413
1414static av_always_inline__attribute__((always_inline)) inline
1415int inter_predict_dc(int16_t block[16], int16_t pred[2])
1416{
1417 int16_t dc = block[0];
1418 int ret = 0;
1419
1420 if (pred[1] > 3) {
1421 dc += pred[0];
1422 ret = 1;
1423 }
1424
1425 if (!pred[0] | !dc | ((int32_t)pred[0] ^ (int32_t)dc) >> 31) {
1426 block[0] = pred[0] = dc;
1427 pred[1] = 0;
1428 } else {
1429 if (pred[0] == dc)
1430 pred[1]++;
1431 block[0] = pred[0] = dc;
1432 }
1433
1434 return ret;
1435}
1436
1437static int vp7_decode_block_coeffs_internal(VPXRangeCoder *r,
1438 int16_t block[16],
1439 uint8_t probs[16][3][NUM_DCT_TOKENS - 1],
1440 int i, const uint8_t *token_prob,
1441 const int16_t qmul[2],
1442 const uint8_t scan[16])
1443{
1444 return decode_block_coeffs_internal(r, block, probs, i,
1445 token_prob, qmul, scan, IS_VP71);
1446}
1447
1448#ifndef vp8_decode_block_coeffs_internal
1449static int vp8_decode_block_coeffs_internal(VPXRangeCoder *r,
1450 int16_t block[16],
1451 uint8_t probs[16][3][NUM_DCT_TOKENS - 1],
1452 int i, const uint8_t *token_prob,
1453 const int16_t qmul[2])
1454{
1455 return decode_block_coeffs_internal(r, block, probs, i,
1456 token_prob, qmul, ff_zigzag_scan, IS_VP80);
1457}
1458#endif
1459
1460/**
1461 * @param c arithmetic bitstream reader context
1462 * @param block destination for block coefficients
1463 * @param probs probabilities to use when reading trees from the bitstream
1464 * @param i initial coeff index, 0 unless a separate DC block is coded
1465 * @param zero_nhood the initial prediction context for number of surrounding
1466 * all-zero blocks (only left/top, so 0-2)
1467 * @param qmul array holding the dc/ac dequant factor at position 0/1
1468 * @param scan scan pattern (VP7 only)
1469 *
1470 * @return 0 if no coeffs were decoded
1471 * otherwise, the index of the last coeff decoded plus one
1472 */
1473static av_always_inline__attribute__((always_inline)) inline
1474int decode_block_coeffs(VPXRangeCoder *c, int16_t block[16],
1475 uint8_t probs[16][3][NUM_DCT_TOKENS - 1],
1476 int i, int zero_nhood, const int16_t qmul[2],
1477 const uint8_t scan[16], int vp7)
1478{
1479 const uint8_t *token_prob = probs[i][zero_nhood];
1480 if (!vpx_rac_get_prob_branchy(c, token_prob[0])) // DCT_EOB
1481 return 0;
1482 return vp7 ? vp7_decode_block_coeffs_internal(c, block, probs, i,
1483 token_prob, qmul, scan)
1484 : vp8_decode_block_coeffs_internal(c, block, probs, i,
1485 token_prob, qmul);
1486}
1487
1488static av_always_inline__attribute__((always_inline)) inline
1489void decode_mb_coeffs(VP8Context *s, VP8ThreadData *td, VPXRangeCoder *c,
1490 VP8Macroblock *mb, uint8_t t_nnz[9], uint8_t l_nnz[9],
1491 int is_vp7)
1492{
1493 int i, x, y, luma_start = 0, luma_ctx = 3;
1494 int nnz_pred, nnz, nnz_total = 0;
1495 int segment = mb->segment;
1496 int block_dc = 0;
1497
1498 if (mb->mode != MODE_I4x44 && (is_vp7 || mb->mode != VP8_MVMODE_SPLIT)) {
1499 nnz_pred = t_nnz[8] + l_nnz[8];
1500
1501 // decode DC values and do hadamard
1502 nnz = decode_block_coeffs(c, td->block_dc, s->prob->token[1], 0,
1503 nnz_pred, s->qmat[segment].luma_dc_qmul,
1504 ff_zigzag_scan, is_vp7);
1505 l_nnz[8] = t_nnz[8] = !!nnz;
1506
1507 if (is_vp7 && mb->mode > MODE_I4x44) {
1508 nnz |= inter_predict_dc(td->block_dc,
1509 s->inter_dc_pred[mb->ref_frame - 1]);
1510 }
1511
1512 if (nnz) {
1513 nnz_total += nnz;
1514 block_dc = 1;
1515 if (nnz == 1)
1516 s->vp8dsp.vp8_luma_dc_wht_dc(td->block, td->block_dc);
1517 else
1518 s->vp8dsp.vp8_luma_dc_wht(td->block, td->block_dc);
1519 }
1520 luma_start = 1;
1521 luma_ctx = 0;
1522 }
1523
1524 // luma blocks
1525 for (y = 0; y < 4; y++)
1526 for (x = 0; x < 4; x++) {
1527 nnz_pred = l_nnz[y] + t_nnz[x];
1528 nnz = decode_block_coeffs(c, td->block[y][x],
1529 s->prob->token[luma_ctx],
1530 luma_start, nnz_pred,
1531 s->qmat[segment].luma_qmul,
1532 s->prob[0].scan, is_vp7);
1533 /* nnz+block_dc may be one more than the actual last index,
1534 * but we don't care */
1535 td->non_zero_count_cache[y][x] = nnz + block_dc;
1536 t_nnz[x] = l_nnz[y] = !!nnz;
1537 nnz_total += nnz;
1538 }
1539
1540 // chroma blocks
1541 // TODO: what to do about dimensions? 2nd dim for luma is x,
1542 // but for chroma it's (y<<1)|x
1543 for (i = 4; i < 6; i++)
1544 for (y = 0; y < 2; y++)
1545 for (x = 0; x < 2; x++) {
1546 nnz_pred = l_nnz[i + 2 * y] + t_nnz[i + 2 * x];
1547 nnz = decode_block_coeffs(c, td->block[i][(y << 1) + x],
1548 s->prob->token[2], 0, nnz_pred,
1549 s->qmat[segment].chroma_qmul,
1550 s->prob[0].scan, is_vp7);
1551 td->non_zero_count_cache[i][(y << 1) + x] = nnz;
1552 t_nnz[i + 2 * x] = l_nnz[i + 2 * y] = !!nnz;
1553 nnz_total += nnz;
1554 }
1555
1556 // if there were no coded coeffs despite the macroblock not being marked skip,
1557 // we MUST not do the inner loop filter and should not do IDCT
1558 // Since skip isn't used for bitstream prediction, just manually set it.
1559 if (!nnz_total)
1560 mb->skip = 1;
1561}
1562
1563static av_always_inline__attribute__((always_inline)) inline
1564void backup_mb_border(uint8_t *top_border, const uint8_t *src_y,
1565 const uint8_t *src_cb, const uint8_t *src_cr,
1566 ptrdiff_t linesize, ptrdiff_t uvlinesize, int simple)
1567{
1568 AV_COPY128(top_border, src_y + 15 * linesize)do { (((av_alias64*)(top_border))->u64 = ((const av_alias64
*)(src_y + 15 * linesize))->u64); (((av_alias64*)((char*)(
top_border)+8))->u64 = ((const av_alias64*)((char*)(src_y +
15 * linesize)+8))->u64); } while(0)
;
1569 if (!simple) {
1570 AV_COPY64(top_border + 16, src_cb + 7 * uvlinesize)(((av_alias64*)(top_border + 16))->u64 = ((const av_alias64
*)(src_cb + 7 * uvlinesize))->u64)
;
1571 AV_COPY64(top_border + 24, src_cr + 7 * uvlinesize)(((av_alias64*)(top_border + 24))->u64 = ((const av_alias64
*)(src_cr + 7 * uvlinesize))->u64)
;
1572 }
1573}
1574
1575static av_always_inline__attribute__((always_inline)) inline
1576void xchg_mb_border(uint8_t *top_border, uint8_t *src_y, uint8_t *src_cb,
1577 uint8_t *src_cr, ptrdiff_t linesize, ptrdiff_t uvlinesize, int mb_x,
1578 int mb_y, int mb_width, int simple, int xchg)
1579{
1580 uint8_t *top_border_m1 = top_border - 32; // for TL prediction
1581 src_y -= linesize;
1582 src_cb -= uvlinesize;
1583 src_cr -= uvlinesize;
1584
1585#define XCHG(a, b, xchg)do { if (xchg) do{av_alias64 SWAP_tmp= *(av_alias64*)(a); *(av_alias64
*)(a)= *(av_alias64*)(b); *(av_alias64*)(b)= SWAP_tmp;}while(
0); else (((av_alias64*)(b))->u64 = ((const av_alias64*)(a
))->u64); } while (0)
\
1586 do { \
1587 if (xchg) \
1588 AV_SWAP64(b, a)do{av_alias64 SWAP_tmp= *(av_alias64*)(a); *(av_alias64*)(a)=
*(av_alias64*)(b); *(av_alias64*)(b)= SWAP_tmp;}while(0)
; \
1589 else \
1590 AV_COPY64(b, a)(((av_alias64*)(b))->u64 = ((const av_alias64*)(a))->u64
)
; \
1591 } while (0)
1592
1593 XCHG(top_border_m1 + 8, src_y - 8, xchg)do { if (xchg) do{av_alias64 SWAP_tmp= *(av_alias64*)(top_border_m1
+ 8); *(av_alias64*)(top_border_m1 + 8)= *(av_alias64*)(src_y
- 8); *(av_alias64*)(src_y - 8)= SWAP_tmp;}while(0); else ((
(av_alias64*)(src_y - 8))->u64 = ((const av_alias64*)(top_border_m1
+ 8))->u64); } while (0)
;
1594 XCHG(top_border, src_y, xchg)do { if (xchg) do{av_alias64 SWAP_tmp= *(av_alias64*)(top_border
); *(av_alias64*)(top_border)= *(av_alias64*)(src_y); *(av_alias64
*)(src_y)= SWAP_tmp;}while(0); else (((av_alias64*)(src_y))->
u64 = ((const av_alias64*)(top_border))->u64); } while (0)
;
1595 XCHG(top_border + 8, src_y + 8, 1)do { if (1) do{av_alias64 SWAP_tmp= *(av_alias64*)(top_border
+ 8); *(av_alias64*)(top_border + 8)= *(av_alias64*)(src_y +
8); *(av_alias64*)(src_y + 8)= SWAP_tmp;}while(0); else (((av_alias64
*)(src_y + 8))->u64 = ((const av_alias64*)(top_border + 8)
)->u64); } while (0)
;
1596 if (mb_x < mb_width - 1)
1597 XCHG(top_border + 32, src_y + 16, 1)do { if (1) do{av_alias64 SWAP_tmp= *(av_alias64*)(top_border
+ 32); *(av_alias64*)(top_border + 32)= *(av_alias64*)(src_y
+ 16); *(av_alias64*)(src_y + 16)= SWAP_tmp;}while(0); else (
((av_alias64*)(src_y + 16))->u64 = ((const av_alias64*)(top_border
+ 32))->u64); } while (0)
;
1598
1599 // only copy chroma for normal loop filter
1600 // or to initialize the top row to 127
1601 if (!simple || !mb_y) {
1602 XCHG(top_border_m1 + 16, src_cb - 8, xchg)do { if (xchg) do{av_alias64 SWAP_tmp= *(av_alias64*)(top_border_m1
+ 16); *(av_alias64*)(top_border_m1 + 16)= *(av_alias64*)(src_cb
- 8); *(av_alias64*)(src_cb - 8)= SWAP_tmp;}while(0); else (
((av_alias64*)(src_cb - 8))->u64 = ((const av_alias64*)(top_border_m1
+ 16))->u64); } while (0)
;
1603 XCHG(top_border_m1 + 24, src_cr - 8, xchg)do { if (xchg) do{av_alias64 SWAP_tmp= *(av_alias64*)(top_border_m1
+ 24); *(av_alias64*)(top_border_m1 + 24)= *(av_alias64*)(src_cr
- 8); *(av_alias64*)(src_cr - 8)= SWAP_tmp;}while(0); else (
((av_alias64*)(src_cr - 8))->u64 = ((const av_alias64*)(top_border_m1
+ 24))->u64); } while (0)
;
1604 XCHG(top_border + 16, src_cb, 1)do { if (1) do{av_alias64 SWAP_tmp= *(av_alias64*)(top_border
+ 16); *(av_alias64*)(top_border + 16)= *(av_alias64*)(src_cb
); *(av_alias64*)(src_cb)= SWAP_tmp;}while(0); else (((av_alias64
*)(src_cb))->u64 = ((const av_alias64*)(top_border + 16))->
u64); } while (0)
;
1605 XCHG(top_border + 24, src_cr, 1)do { if (1) do{av_alias64 SWAP_tmp= *(av_alias64*)(top_border
+ 24); *(av_alias64*)(top_border + 24)= *(av_alias64*)(src_cr
); *(av_alias64*)(src_cr)= SWAP_tmp;}while(0); else (((av_alias64
*)(src_cr))->u64 = ((const av_alias64*)(top_border + 24))->
u64); } while (0)
;
1606 }
1607}
1608
1609static av_always_inline__attribute__((always_inline)) inline
1610int check_dc_pred8x8_mode(int mode, int mb_x, int mb_y)
1611{
1612 if (!mb_x)
1613 return mb_y ? TOP_DC_PRED8x85 : DC_128_PRED8x86;
1614 else
1615 return mb_y ? mode : LEFT_DC_PRED8x84;
1616}
1617
1618static av_always_inline__attribute__((always_inline)) inline
1619int check_tm_pred8x8_mode(int mode, int mb_x, int mb_y, int vp7)
1620{
1621 if (!mb_x)
1622 return mb_y ? VERT_PRED8x82 : (vp7 ? DC_128_PRED8x86 : DC_129_PRED8x88);
1623 else
1624 return mb_y ? mode : HOR_PRED8x81;
1625}
1626
1627static av_always_inline__attribute__((always_inline)) inline
1628int check_intra_pred8x8_mode_emuedge(int mode, int mb_x, int mb_y, int vp7)
1629{
1630 switch (mode) {
1631 case DC_PRED8x80:
1632 return check_dc_pred8x8_mode(mode, mb_x, mb_y);
1633 case VERT_PRED8x82:
1634 return !mb_y ? (vp7 ? DC_128_PRED8x86 : DC_127_PRED8x87) : mode;
1635 case HOR_PRED8x81:
1636 return !mb_x ? (vp7 ? DC_128_PRED8x86 : DC_129_PRED8x88) : mode;
1637 case PLANE_PRED8x83: /* TM */
1638 return check_tm_pred8x8_mode(mode, mb_x, mb_y, vp7);
1639 }
1640 return mode;
1641}
1642
1643static av_always_inline__attribute__((always_inline)) inline
1644int check_tm_pred4x4_mode(int mode, int mb_x, int mb_y, int vp7)
1645{
1646 if (!mb_x) {
1647 return mb_y ? VERT_VP8_PRED10 : (vp7 ? DC_128_PRED11 : DC_129_PRED13);
1648 } else {
1649 return mb_y ? mode : HOR_VP8_PRED14;
1650 }
1651}
1652
1653static av_always_inline__attribute__((always_inline)) inline
1654int check_intra_pred4x4_mode_emuedge(int mode, int mb_x, int mb_y,
1655 int *copy_buf, int vp7)
1656{
1657 switch (mode) {
1658 case VERT_PRED0:
1659 if (!mb_x && mb_y) {
1660 *copy_buf = 1;
1661 return mode;
1662 }
1663 /* fall-through */
1664 case DIAG_DOWN_LEFT_PRED3:
1665 case VERT_LEFT_PRED7:
1666 return !mb_y ? (vp7 ? DC_128_PRED11 : DC_127_PRED12) : mode;
1667 case HOR_PRED1:
1668 if (!mb_y) {
1669 *copy_buf = 1;
1670 return mode;
1671 }
1672 /* fall-through */
1673 case HOR_UP_PRED8:
1674 return !mb_x ? (vp7 ? DC_128_PRED11 : DC_129_PRED13) : mode;
1675 case TM_VP8_PRED9:
1676 return check_tm_pred4x4_mode(mode, mb_x, mb_y, vp7);
1677 case DC_PRED2: /* 4x4 DC doesn't use the same "H.264-style" exceptions
1678 * as 16x16/8x8 DC */
1679 case DIAG_DOWN_RIGHT_PRED4:
1680 case VERT_RIGHT_PRED5:
1681 case HOR_DOWN_PRED6:
1682 if (!mb_y || !mb_x)
1683 *copy_buf = 1;
1684 return mode;
1685 }
1686 return mode;
1687}
1688
1689static av_always_inline__attribute__((always_inline)) inline
1690void intra_predict(VP8Context *s, VP8ThreadData *td, uint8_t *const dst[3],
1691 VP8Macroblock *mb, int mb_x, int mb_y, int is_vp7)
1692{
1693 int x, y, mode, nnz;
1694 uint32_t tr;
1695
1696 /* for the first row, we need to run xchg_mb_border to init the top edge
1697 * to 127 otherwise, skip it if we aren't going to deblock */
1698 if (mb_y && (s->deblock_filter || !mb_y) && td->thread_nr == 0)
1699 xchg_mb_border(s->top_border[mb_x + 1], dst[0], dst[1], dst[2],
1700 s->linesize, s->uvlinesize, mb_x, mb_y, s->mb_width,
1701 s->filter.simple, 1);
1702
1703 if (mb->mode < MODE_I4x44) {
1704 mode = check_intra_pred8x8_mode_emuedge(mb->mode, mb_x, mb_y, is_vp7);
1705 s->hpc.pred16x16[mode](dst[0], s->linesize);
1706 } else {
1707 uint8_t *ptr = dst[0];
1708 const uint8_t *intra4x4 = mb->intra4x4_pred_mode_mb;
1709 const uint8_t lo = is_vp7 ? 128 : 127;
1710 const uint8_t hi = is_vp7 ? 128 : 129;
1711 const uint8_t tr_top[4] = { lo, lo, lo, lo };
1712
1713 // all blocks on the right edge of the macroblock use bottom edge
1714 // the top macroblock for their topright edge
1715 const uint8_t *tr_right = ptr - s->linesize + 16;
1716
1717 // if we're on the right edge of the frame, said edge is extended
1718 // from the top macroblock
1719 if (mb_y && mb_x == s->mb_width - 1) {
1720 tr = tr_right[-1] * 0x01010101u;
1721 tr_right = (uint8_t *) &tr;
1722 }
1723
1724 if (mb->skip)
1725 AV_ZERO128(td->non_zero_count_cache)do { (((av_alias64*)(td->non_zero_count_cache))->u64 = 0
); (((av_alias64*)((char*)(td->non_zero_count_cache)+8))->
u64 = 0); } while(0)
;
1726
1727 for (y = 0; y < 4; y++) {
1728 const uint8_t *topright = ptr + 4 - s->linesize;
1729 for (x = 0; x < 4; x++) {
1730 int copy = 0;
1731 ptrdiff_t linesize = s->linesize;
1732 uint8_t *dst = ptr + 4 * x;
1733 LOCAL_ALIGNED(4, uint8_t, copy_dst, [5 * 8])_Alignas(4) uint8_t la_copy_dst [5 * 8] ; uint8_t (*copy_dst)
= la_copy_dst
;
1734
1735 if ((y == 0 || x == 3) && mb_y == 0) {
1736 topright = tr_top;
1737 } else if (x == 3)
1738 topright = tr_right;
1739
1740 mode = check_intra_pred4x4_mode_emuedge(intra4x4[x], mb_x + x,
1741 mb_y + y, &copy, is_vp7);
1742 if (copy) {
1743 dst = copy_dst + 12;
1744 linesize = 8;
1745 if (!(mb_y + y)) {
1746 copy_dst[3] = lo;
1747 AV_WN32A(copy_dst + 4, lo * 0x01010101U)(((av_alias32*)(copy_dst + 4))->u32 = (lo * 0x01010101U));
1748 } else {
1749 AV_COPY32(copy_dst + 4, ptr + 4 * x - s->linesize)(((av_alias32*)(copy_dst + 4))->u32 = ((const av_alias32*)
(ptr + 4 * x - s->linesize))->u32)
;
1750 if (!(mb_x + x)) {
1751 copy_dst[3] = hi;
1752 } else {
1753 copy_dst[3] = ptr[4 * x - s->linesize - 1];
1754 }
1755 }
1756 if (!(mb_x + x)) {
1757 copy_dst[11] =
1758 copy_dst[19] =
1759 copy_dst[27] =
1760 copy_dst[35] = hi;
1761 } else {
1762 copy_dst[11] = ptr[4 * x - 1];
1763 copy_dst[19] = ptr[4 * x + s->linesize - 1];
1764 copy_dst[27] = ptr[4 * x + s->linesize * 2 - 1];
1765 copy_dst[35] = ptr[4 * x + s->linesize * 3 - 1];
1766 }
1767 }
1768 s->hpc.pred4x4[mode](dst, topright, linesize);
1769 if (copy) {
1770 AV_COPY32(ptr + 4 * x, copy_dst + 12)(((av_alias32*)(ptr + 4 * x))->u32 = ((const av_alias32*)(
copy_dst + 12))->u32)
;
1771 AV_COPY32(ptr + 4 * x + s->linesize, copy_dst + 20)(((av_alias32*)(ptr + 4 * x + s->linesize))->u32 = ((const
av_alias32*)(copy_dst + 20))->u32)
;
1772 AV_COPY32(ptr + 4 * x + s->linesize * 2, copy_dst + 28)(((av_alias32*)(ptr + 4 * x + s->linesize * 2))->u32 = (
(const av_alias32*)(copy_dst + 28))->u32)
;
1773 AV_COPY32(ptr + 4 * x + s->linesize * 3, copy_dst + 36)(((av_alias32*)(ptr + 4 * x + s->linesize * 3))->u32 = (
(const av_alias32*)(copy_dst + 36))->u32)
;
1774 }
1775
1776 nnz = td->non_zero_count_cache[y][x];
1777 if (nnz) {
1778 if (nnz == 1)
1779 s->vp8dsp.vp8_idct_dc_add(ptr + 4 * x,
1780 td->block[y][x], s->linesize);
1781 else
1782 s->vp8dsp.vp8_idct_add(ptr + 4 * x,
1783 td->block[y][x], s->linesize);
1784 }
1785 topright += 4;
1786 }
1787
1788 ptr += 4 * s->linesize;
1789 intra4x4 += 4;
1790 }
1791 }
1792
1793 mode = check_intra_pred8x8_mode_emuedge(mb->chroma_pred_mode,
1794 mb_x, mb_y, is_vp7);
1795 s->hpc.pred8x8[mode](dst[1], s->uvlinesize);
1796 s->hpc.pred8x8[mode](dst[2], s->uvlinesize);
1797
1798 if (mb_y && (s->deblock_filter || !mb_y) && td->thread_nr == 0)
1799 xchg_mb_border(s->top_border[mb_x + 1], dst[0], dst[1], dst[2],
1800 s->linesize, s->uvlinesize, mb_x, mb_y, s->mb_width,
1801 s->filter.simple, 0);
1802}
1803
1804static const uint8_t subpel_idx[3][8] = {
1805 { 0, 1, 2, 1, 2, 1, 2, 1 }, // nr. of left extra pixels,
1806 // also function pointer index
1807 { 0, 3, 5, 3, 5, 3, 5, 3 }, // nr. of extra pixels required
1808 { 0, 2, 3, 2, 3, 2, 3, 2 }, // nr. of right extra pixels
1809};
1810
1811/**
1812 * luma MC function
1813 *
1814 * @param s VP8 decoding context
1815 * @param dst target buffer for block data at block position
1816 * @param ref reference picture buffer at origin (0, 0)
1817 * @param mv motion vector (relative to block position) to get pixel data from
1818 * @param x_off horizontal position of block from origin (0, 0)
1819 * @param y_off vertical position of block from origin (0, 0)
1820 * @param block_w width of block (16, 8 or 4)
1821 * @param block_h height of block (always same as block_w)
1822 * @param width width of src/dst plane data
1823 * @param height height of src/dst plane data
1824 * @param linesize size of a single line of plane data, including padding
1825 * @param mc_func motion compensation function pointers (bilinear or sixtap MC)
1826 */
1827static av_always_inline__attribute__((always_inline)) inline
1828void vp8_mc_luma(VP8Context *s, VP8ThreadData *td, uint8_t *dst,
1829 const ProgressFrame *ref, const VP8mv *mv,
1830 int x_off, int y_off, int block_w, int block_h,
1831 int width, int height, ptrdiff_t linesize,
1832 vp8_mc_func mc_func[3][3])
1833{
1834 const uint8_t *src = ref->f->data[0];
1835
1836 if (AV_RN32A(mv)(((const av_alias32*)(mv))->u32)) {
1837 ptrdiff_t src_linesize = linesize;
1838
1839 int mx = (mv->x * 2) & 7, mx_idx = subpel_idx[0][mx];
1840 int my = (mv->y * 2) & 7, my_idx = subpel_idx[0][my];
1841
1842 x_off += mv->x >> 2;
1843 y_off += mv->y >> 2;
1844
1845 // edge emulation
1846 ff_progress_frame_await(ref, (3 + y_off + block_h + subpel_idx[2][my]) >> 4);
1847 src += y_off * linesize + x_off;
1848 if (x_off < mx_idx || x_off >= width - block_w - subpel_idx[2][mx] ||
1849 y_off < my_idx || y_off >= height - block_h - subpel_idx[2][my]) {
1850 s->vdsp.emulated_edge_mc(td->edge_emu_buffer,
1851 src - my_idx * linesize - mx_idx,
1852 EDGE_EMU_LINESIZE32, linesize,
1853 block_w + subpel_idx[1][mx],
1854 block_h + subpel_idx[1][my],
1855 x_off - mx_idx, y_off - my_idx,
1856 width, height);
1857 src = td->edge_emu_buffer + mx_idx + EDGE_EMU_LINESIZE32 * my_idx;
1858 src_linesize = EDGE_EMU_LINESIZE32;
1859 }
1860 mc_func[my_idx][mx_idx](dst, linesize, src, src_linesize, block_h, mx, my);
1861 } else {
1862 ff_progress_frame_await(ref, (3 + y_off + block_h) >> 4);
1863 mc_func[0][0](dst, linesize, src + y_off * linesize + x_off,
1864 linesize, block_h, 0, 0);
1865 }
1866}
1867
1868/**
1869 * chroma MC function
1870 *
1871 * @param s VP8 decoding context
1872 * @param dst1 target buffer for block data at block position (U plane)
1873 * @param dst2 target buffer for block data at block position (V plane)
1874 * @param ref reference picture buffer at origin (0, 0)
1875 * @param mv motion vector (relative to block position) to get pixel data from
1876 * @param x_off horizontal position of block from origin (0, 0)
1877 * @param y_off vertical position of block from origin (0, 0)
1878 * @param block_w width of block (16, 8 or 4)
1879 * @param block_h height of block (always same as block_w)
1880 * @param width width of src/dst plane data
1881 * @param height height of src/dst plane data
1882 * @param linesize size of a single line of plane data, including padding
1883 * @param mc_func motion compensation function pointers (bilinear or sixtap MC)
1884 */
1885static av_always_inline__attribute__((always_inline)) inline
1886void vp8_mc_chroma(VP8Context *s, VP8ThreadData *td, uint8_t *dst1,
1887 uint8_t *dst2, const ProgressFrame *ref, const VP8mv *mv,
1888 int x_off, int y_off, int block_w, int block_h,
1889 int width, int height, ptrdiff_t linesize,
1890 vp8_mc_func mc_func[3][3])
1891{
1892 const uint8_t *src1 = ref->f->data[1], *src2 = ref->f->data[2];
1893
1894 if (AV_RN32A(mv)(((const av_alias32*)(mv))->u32)) {
27
Branch condition evaluates to a garbage value
1895 int mx = mv->x & 7, mx_idx = subpel_idx[0][mx];
1896 int my = mv->y & 7, my_idx = subpel_idx[0][my];
1897
1898 x_off += mv->x >> 3;
1899 y_off += mv->y >> 3;
1900
1901 // edge emulation
1902 src1 += y_off * linesize + x_off;
1903 src2 += y_off * linesize + x_off;
1904 ff_progress_frame_await(ref, (3 + y_off + block_h + subpel_idx[2][my]) >> 3);
1905 if (x_off < mx_idx || x_off >= width - block_w - subpel_idx[2][mx] ||
1906 y_off < my_idx || y_off >= height - block_h - subpel_idx[2][my]) {
1907 s->vdsp.emulated_edge_mc(td->edge_emu_buffer,
1908 src1 - my_idx * linesize - mx_idx,
1909 EDGE_EMU_LINESIZE32, linesize,
1910 block_w + subpel_idx[1][mx],
1911 block_h + subpel_idx[1][my],
1912 x_off - mx_idx, y_off - my_idx, width, height);
1913 src1 = td->edge_emu_buffer + mx_idx + EDGE_EMU_LINESIZE32 * my_idx;
1914 mc_func[my_idx][mx_idx](dst1, linesize, src1, EDGE_EMU_LINESIZE32, block_h, mx, my);
1915
1916 s->vdsp.emulated_edge_mc(td->edge_emu_buffer,
1917 src2 - my_idx * linesize - mx_idx,
1918 EDGE_EMU_LINESIZE32, linesize,
1919 block_w + subpel_idx[1][mx],
1920 block_h + subpel_idx[1][my],
1921 x_off - mx_idx, y_off - my_idx, width, height);
1922 src2 = td->edge_emu_buffer + mx_idx + EDGE_EMU_LINESIZE32 * my_idx;
1923 mc_func[my_idx][mx_idx](dst2, linesize, src2, EDGE_EMU_LINESIZE32, block_h, mx, my);
1924 } else {
1925 mc_func[my_idx][mx_idx](dst1, linesize, src1, linesize, block_h, mx, my);
1926 mc_func[my_idx][mx_idx](dst2, linesize, src2, linesize, block_h, mx, my);
1927 }
1928 } else {
1929 ff_progress_frame_await(ref, (3 + y_off + block_h) >> 3);
1930 mc_func[0][0](dst1, linesize, src1 + y_off * linesize + x_off, linesize, block_h, 0, 0);
1931 mc_func[0][0](dst2, linesize, src2 + y_off * linesize + x_off, linesize, block_h, 0, 0);
1932 }
1933}
1934
1935static av_always_inline__attribute__((always_inline)) inline
1936void vp8_mc_part(VP8Context *s, VP8ThreadData *td, uint8_t *const dst[3],
1937 const ProgressFrame *ref_frame, int x_off, int y_off,
1938 int bx_off, int by_off, int block_w, int block_h,
1939 int width, int height, const VP8mv *mv)
1940{
1941 VP8mv uvmv = *mv;
1942
1943 /* Y */
1944 vp8_mc_luma(s, td, dst[0] + by_off * s->linesize + bx_off,
1945 ref_frame, mv, x_off + bx_off, y_off + by_off,
1946 block_w, block_h, width, height, s->linesize,
1947 s->put_pixels_tab[block_w == 8]);
1948
1949 /* U/V */
1950 if (s->profile == 3) {
24
Assuming field 'profile' is not equal to 3
25
Taking false branch
1951 /* this block only applies VP8; it is safe to check
1952 * only the profile, as VP7 profile <= 1 */
1953 uvmv.x &= ~7;
1954 uvmv.y &= ~7;
1955 }
1956 x_off >>= 1;
1957 y_off >>= 1;
1958 bx_off >>= 1;
1959 by_off >>= 1;
1960 width >>= 1;
1961 height >>= 1;
1962 block_w >>= 1;
1963 block_h >>= 1;
1964 vp8_mc_chroma(s, td, dst[1] + by_off * s->uvlinesize + bx_off,
26
Calling 'vp8_mc_chroma'
1965 dst[2] + by_off * s->uvlinesize + bx_off, ref_frame,
1966 &uvmv, x_off + bx_off, y_off + by_off,
1967 block_w, block_h, width, height, s->uvlinesize,
1968 s->put_pixels_tab[1 + (block_w == 4)]);
1969}
1970
1971/* Fetch pixels for estimated mv 4 macroblocks ahead.
1972 * Optimized for 64-byte cache lines. Inspired by ffh264 prefetch_motion. */
1973static av_always_inline__attribute__((always_inline)) inline
1974void prefetch_motion(const VP8Context *s, const VP8Macroblock *mb,
1975 int mb_x, int mb_y, int mb_xy, int ref)
1976{
1977 /* Don't prefetch refs that haven't been used very often this frame. */
1978 if (s->ref_count[ref - 1] > (mb_xy >> 5)) {
1979 int x_off = mb_x << 4, y_off = mb_y << 4;
1980 int mx = (mb->mv.x >> 2) + x_off + 8;
1981 int my = (mb->mv.y >> 2) + y_off;
1982 uint8_t **src = s->framep[ref]->tf.f->data;
1983 int off = mx + (my + (mb_x & 3) * 4) * s->linesize + 64;
1984 /* For threading, a ff_thread_await_progress here might be useful, but
1985 * it actually slows down the decoder. Since a bad prefetch doesn't
1986 * generate bad decoder output, we don't run it here. */
1987 s->vdsp.prefetch(src[0] + off, s->linesize, 4);
1988 off = (mx >> 1) + ((my >> 1) + (mb_x & 7)) * s->uvlinesize + 64;
1989 s->vdsp.prefetch(src[1] + off, src[2] - src[1], 2);
1990 }
1991}
1992
1993/**
1994 * Apply motion vectors to prediction buffer, chapter 18.
1995 */
1996static av_always_inline__attribute__((always_inline)) inline
1997void inter_predict(VP8Context *s, VP8ThreadData *td, uint8_t *const dst[3],
1998 VP8Macroblock *mb, int mb_x, int mb_y)
1999{
2000 int x_off = mb_x << 4, y_off = mb_y << 4;
2001 int width = 16 * s->mb_width, height = 16 * s->mb_height;
2002 const ProgressFrame *ref = &s->framep[mb->ref_frame]->tf;
2003 const VP8mv *bmv = mb->bmv;
2004
2005 switch (mb->partitioning) {
22
Control jumps to 'case VP8_SPLITMVMODE_8x8:' at line 2067
2006 case VP8_SPLITMVMODE_NONE:
2007 vp8_mc_part(s, td, dst, ref, x_off, y_off,
2008 0, 0, 16, 16, width, height, &mb->mv);
2009 break;
2010 case VP8_SPLITMVMODE_4x4: {
2011 int x, y;
2012 VP8mv uvmv;
2013
2014 /* Y */
2015 for (y = 0; y < 4; y++) {
2016 for (x = 0; x < 4; x++) {
2017 vp8_mc_luma(s, td, dst[0] + 4 * y * s->linesize + x * 4,
2018 ref, &bmv[4 * y + x],
2019 4 * x + x_off, 4 * y + y_off, 4, 4,
2020 width, height, s->linesize,
2021 s->put_pixels_tab[2]);
2022 }
2023 }
2024
2025 /* U/V */
2026 x_off >>= 1;
2027 y_off >>= 1;
2028 width >>= 1;
2029 height >>= 1;
2030 for (y = 0; y < 2; y++) {
2031 for (x = 0; x < 2; x++) {
2032 uvmv.x = mb->bmv[2 * y * 4 + 2 * x ].x +
2033 mb->bmv[2 * y * 4 + 2 * x + 1].x +
2034 mb->bmv[(2 * y + 1) * 4 + 2 * x ].x +
2035 mb->bmv[(2 * y + 1) * 4 + 2 * x + 1].x;
2036 uvmv.y = mb->bmv[2 * y * 4 + 2 * x ].y +
2037 mb->bmv[2 * y * 4 + 2 * x + 1].y +
2038 mb->bmv[(2 * y + 1) * 4 + 2 * x ].y +
2039 mb->bmv[(2 * y + 1) * 4 + 2 * x + 1].y;
2040 uvmv.x = (uvmv.x + 2 + FF_SIGNBIT(uvmv.x)((uvmv.x) >> 8 * sizeof(uvmv.x) - 1)) >> 2;
2041 uvmv.y = (uvmv.y + 2 + FF_SIGNBIT(uvmv.y)((uvmv.y) >> 8 * sizeof(uvmv.y) - 1)) >> 2;
2042 if (s->profile == 3) {
2043 uvmv.x &= ~7;
2044 uvmv.y &= ~7;
2045 }
2046 vp8_mc_chroma(s, td, dst[1] + 4 * y * s->uvlinesize + x * 4,
2047 dst[2] + 4 * y * s->uvlinesize + x * 4, ref,
2048 &uvmv, 4 * x + x_off, 4 * y + y_off, 4, 4,
2049 width, height, s->uvlinesize,
2050 s->put_pixels_tab[2]);
2051 }
2052 }
2053 break;
2054 }
2055 case VP8_SPLITMVMODE_16x8:
2056 vp8_mc_part(s, td, dst, ref, x_off, y_off,
2057 0, 0, 16, 8, width, height, &bmv[0]);
2058 vp8_mc_part(s, td, dst, ref, x_off, y_off,
2059 0, 8, 16, 8, width, height, &bmv[1]);
2060 break;
2061 case VP8_SPLITMVMODE_8x16:
2062 vp8_mc_part(s, td, dst, ref, x_off, y_off,
2063 0, 0, 8, 16, width, height, &bmv[0]);
2064 vp8_mc_part(s, td, dst, ref, x_off, y_off,
2065 8, 0, 8, 16, width, height, &bmv[1]);
2066 break;
2067 case VP8_SPLITMVMODE_8x8:
2068 vp8_mc_part(s, td, dst, ref, x_off, y_off,
23
Calling 'vp8_mc_part'
2069 0, 0, 8, 8, width, height, &bmv[0]);
2070 vp8_mc_part(s, td, dst, ref, x_off, y_off,
2071 8, 0, 8, 8, width, height, &bmv[1]);
2072 vp8_mc_part(s, td, dst, ref, x_off, y_off,
2073 0, 8, 8, 8, width, height, &bmv[2]);
2074 vp8_mc_part(s, td, dst, ref, x_off, y_off,
2075 8, 8, 8, 8, width, height, &bmv[3]);
2076 break;
2077 }
2078}
2079
2080static av_always_inline__attribute__((always_inline)) inline
2081void idct_mb(VP8Context *s, VP8ThreadData *td, uint8_t *const dst[3],
2082 const VP8Macroblock *mb)
2083{
2084 int x, y, ch;
2085
2086 if (mb->mode != MODE_I4x44) {
2087 uint8_t *y_dst = dst[0];
2088 for (y = 0; y < 4; y++) {
2089 uint32_t nnz4 = AV_RL32(td->non_zero_count_cache[y])(((const union unaligned_32 *) (td->non_zero_count_cache[y
]))->l)
;
2090 if (nnz4) {
2091 if (nnz4 & ~0x01010101) {
2092 for (x = 0; x < 4; x++) {
2093 if ((uint8_t) nnz4 == 1)
2094 s->vp8dsp.vp8_idct_dc_add(y_dst + 4 * x,
2095 td->block[y][x],
2096 s->linesize);
2097 else if ((uint8_t) nnz4 > 1)
2098 s->vp8dsp.vp8_idct_add(y_dst + 4 * x,
2099 td->block[y][x],
2100 s->linesize);
2101 nnz4 >>= 8;
2102 if (!nnz4)
2103 break;
2104 }
2105 } else {
2106 s->vp8dsp.vp8_idct_dc_add4y(y_dst, td->block[y], s->linesize);
2107 }
2108 }
2109 y_dst += 4 * s->linesize;
2110 }
2111 }
2112
2113 for (ch = 0; ch < 2; ch++) {
2114 uint32_t nnz4 = AV_RL32(td->non_zero_count_cache[4 + ch])(((const union unaligned_32 *) (td->non_zero_count_cache[4
+ ch]))->l)
;
2115 if (nnz4) {
2116 uint8_t *ch_dst = dst[1 + ch];
2117 if (nnz4 & ~0x01010101) {
2118 for (y = 0; y < 2; y++) {
2119 for (x = 0; x < 2; x++) {
2120 if ((uint8_t) nnz4 == 1)
2121 s->vp8dsp.vp8_idct_dc_add(ch_dst + 4 * x,
2122 td->block[4 + ch][(y << 1) + x],
2123 s->uvlinesize);
2124 else if ((uint8_t) nnz4 > 1)
2125 s->vp8dsp.vp8_idct_add(ch_dst + 4 * x,
2126 td->block[4 + ch][(y << 1) + x],
2127 s->uvlinesize);
2128 nnz4 >>= 8;
2129 if (!nnz4)
2130 goto chroma_idct_end;
2131 }
2132 ch_dst += 4 * s->uvlinesize;
2133 }
2134 } else {
2135 s->vp8dsp.vp8_idct_dc_add4uv(ch_dst, td->block[4 + ch], s->uvlinesize);
2136 }
2137 }
2138chroma_idct_end:
2139 ;
2140 }
2141}
2142
2143static av_always_inline__attribute__((always_inline)) inline
2144void filter_level_for_mb(const VP8Context *s, const VP8Macroblock *mb,
2145 VP8FilterStrength *f, int is_vp7)
2146{
2147 int interior_limit, filter_level;
2148
2149 if (s->segmentation.enabled) {
2150 filter_level = s->segmentation.filter_level[mb->segment];
2151 if (!s->segmentation.absolute_vals)
2152 filter_level += s->filter.level;
2153 } else
2154 filter_level = s->filter.level;
2155
2156 if (s->lf_delta.enabled) {
2157 filter_level += s->lf_delta.ref[mb->ref_frame];
2158 filter_level += s->lf_delta.mode[mb->mode];
2159 }
2160
2161 filter_level = av_clip_uintp2av_clip_uintp2_c(filter_level, 6);
2162
2163 interior_limit = filter_level;
2164 if (s->filter.sharpness) {
2165 interior_limit >>= (s->filter.sharpness + 3) >> 2;
2166 interior_limit = FFMIN(interior_limit, 9 - s->filter.sharpness)((interior_limit) > (9 - s->filter.sharpness) ? (9 - s->
filter.sharpness) : (interior_limit))
;
2167 }
2168 interior_limit = FFMAX(interior_limit, 1)((interior_limit) > (1) ? (interior_limit) : (1));
2169
2170 f->filter_level = filter_level;
2171 f->inner_limit = interior_limit;
2172 f->inner_filter = is_vp7 || !mb->skip || mb->mode == MODE_I4x44 ||
2173 mb->mode == VP8_MVMODE_SPLIT;
2174}
2175
2176static av_always_inline__attribute__((always_inline)) inline
2177void filter_mb(const VP8Context *s, uint8_t *const dst[3], const VP8FilterStrength *f,
2178 int mb_x, int mb_y, int is_vp7)
2179{
2180 int mbedge_lim, bedge_lim_y, bedge_lim_uv, hev_thresh;
2181 int filter_level = f->filter_level;
2182 int inner_limit = f->inner_limit;
2183 int inner_filter = f->inner_filter;
2184 ptrdiff_t linesize = s->linesize;
2185 ptrdiff_t uvlinesize = s->uvlinesize;
2186 static const uint8_t hev_thresh_lut[2][64] = {
2187 { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1,
2188 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2189 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
2190 3, 3, 3, 3 },
2191 { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1,
2192 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
2193 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2194 2, 2, 2, 2 }
2195 };
2196
2197 if (!filter_level)
2198 return;
2199
2200 if (is_vp7) {
2201 bedge_lim_y = filter_level;
2202 bedge_lim_uv = filter_level * 2;
2203 mbedge_lim = filter_level + 2;
2204 } else {
2205 bedge_lim_y =
2206 bedge_lim_uv = filter_level * 2 + inner_limit;
2207 mbedge_lim = bedge_lim_y + 4;
2208 }
2209
2210 hev_thresh = hev_thresh_lut[s->keyframe][filter_level];
2211
2212 if (mb_x) {
2213 s->vp8dsp.vp8_h_loop_filter16y(dst[0], linesize,
2214 mbedge_lim, inner_limit, hev_thresh);
2215 s->vp8dsp.vp8_h_loop_filter8uv(dst[1], dst[2], uvlinesize,
2216 mbedge_lim, inner_limit, hev_thresh);
2217 }
2218
2219#define H_LOOP_FILTER_16Y_INNER(cond)if (cond && inner_filter) { s->vp8dsp.vp8_h_loop_filter16y_inner
(dst[0] + 4, linesize, bedge_lim_y, inner_limit, hev_thresh);
s->vp8dsp.vp8_h_loop_filter16y_inner(dst[0] + 8, linesize
, bedge_lim_y, inner_limit, hev_thresh); s->vp8dsp.vp8_h_loop_filter16y_inner
(dst[0] + 12, linesize, bedge_lim_y, inner_limit, hev_thresh)
; s->vp8dsp.vp8_h_loop_filter8uv_inner(dst[1] + 4, dst[2] +
4, uvlinesize, bedge_lim_uv, inner_limit, hev_thresh); }
\
2220 if (cond && inner_filter) { \
2221 s->vp8dsp.vp8_h_loop_filter16y_inner(dst[0] + 4, linesize, \
2222 bedge_lim_y, inner_limit, \
2223 hev_thresh); \
2224 s->vp8dsp.vp8_h_loop_filter16y_inner(dst[0] + 8, linesize, \
2225 bedge_lim_y, inner_limit, \
2226 hev_thresh); \
2227 s->vp8dsp.vp8_h_loop_filter16y_inner(dst[0] + 12, linesize, \
2228 bedge_lim_y, inner_limit, \
2229 hev_thresh); \
2230 s->vp8dsp.vp8_h_loop_filter8uv_inner(dst[1] + 4, dst[2] + 4, \
2231 uvlinesize, bedge_lim_uv, \
2232 inner_limit, hev_thresh); \
2233 }
2234
2235 H_LOOP_FILTER_16Y_INNER(!is_vp7)if (!is_vp7 && inner_filter) { s->vp8dsp.vp8_h_loop_filter16y_inner
(dst[0] + 4, linesize, bedge_lim_y, inner_limit, hev_thresh);
s->vp8dsp.vp8_h_loop_filter16y_inner(dst[0] + 8, linesize
, bedge_lim_y, inner_limit, hev_thresh); s->vp8dsp.vp8_h_loop_filter16y_inner
(dst[0] + 12, linesize, bedge_lim_y, inner_limit, hev_thresh)
; s->vp8dsp.vp8_h_loop_filter8uv_inner(dst[1] + 4, dst[2] +
4, uvlinesize, bedge_lim_uv, inner_limit, hev_thresh); }
2236
2237 if (mb_y) {
2238 s->vp8dsp.vp8_v_loop_filter16y(dst[0], linesize,
2239 mbedge_lim, inner_limit, hev_thresh);
2240 s->vp8dsp.vp8_v_loop_filter8uv(dst[1], dst[2], uvlinesize,
2241 mbedge_lim, inner_limit, hev_thresh);
2242 }
2243
2244 if (inner_filter) {
2245 s->vp8dsp.vp8_v_loop_filter16y_inner(dst[0] + 4 * linesize,
2246 linesize, bedge_lim_y,
2247 inner_limit, hev_thresh);
2248 s->vp8dsp.vp8_v_loop_filter16y_inner(dst[0] + 8 * linesize,
2249 linesize, bedge_lim_y,
2250 inner_limit, hev_thresh);
2251 s->vp8dsp.vp8_v_loop_filter16y_inner(dst[0] + 12 * linesize,
2252 linesize, bedge_lim_y,
2253 inner_limit, hev_thresh);
2254 s->vp8dsp.vp8_v_loop_filter8uv_inner(dst[1] + 4 * uvlinesize,
2255 dst[2] + 4 * uvlinesize,
2256 uvlinesize, bedge_lim_uv,
2257 inner_limit, hev_thresh);
2258 }
2259
2260 H_LOOP_FILTER_16Y_INNER(is_vp7)if (is_vp7 && inner_filter) { s->vp8dsp.vp8_h_loop_filter16y_inner
(dst[0] + 4, linesize, bedge_lim_y, inner_limit, hev_thresh);
s->vp8dsp.vp8_h_loop_filter16y_inner(dst[0] + 8, linesize
, bedge_lim_y, inner_limit, hev_thresh); s->vp8dsp.vp8_h_loop_filter16y_inner
(dst[0] + 12, linesize, bedge_lim_y, inner_limit, hev_thresh)
; s->vp8dsp.vp8_h_loop_filter8uv_inner(dst[1] + 4, dst[2] +
4, uvlinesize, bedge_lim_uv, inner_limit, hev_thresh); }
2261}
2262
2263static av_always_inline__attribute__((always_inline)) inline
2264void filter_mb_simple(const VP8Context *s, uint8_t *dst, const VP8FilterStrength *f,
2265 int mb_x, int mb_y)
2266{
2267 int mbedge_lim, bedge_lim;
2268 int filter_level = f->filter_level;
2269 int inner_limit = f->inner_limit;
2270 int inner_filter = f->inner_filter;
2271 ptrdiff_t linesize = s->linesize;
2272
2273 if (!filter_level)
2274 return;
2275
2276 bedge_lim = 2 * filter_level + inner_limit;
2277 mbedge_lim = bedge_lim + 4;
2278
2279 if (mb_x)
2280 s->vp8dsp.vp8_h_loop_filter_simple(dst, linesize, mbedge_lim);
2281 if (inner_filter) {
2282 s->vp8dsp.vp8_h_loop_filter_simple(dst + 4, linesize, bedge_lim);
2283 s->vp8dsp.vp8_h_loop_filter_simple(dst + 8, linesize, bedge_lim);
2284 s->vp8dsp.vp8_h_loop_filter_simple(dst + 12, linesize, bedge_lim);
2285 }
2286
2287 if (mb_y)
2288 s->vp8dsp.vp8_v_loop_filter_simple(dst, linesize, mbedge_lim);
2289 if (inner_filter) {
2290 s->vp8dsp.vp8_v_loop_filter_simple(dst + 4 * linesize, linesize, bedge_lim);
2291 s->vp8dsp.vp8_v_loop_filter_simple(dst + 8 * linesize, linesize, bedge_lim);
2292 s->vp8dsp.vp8_v_loop_filter_simple(dst + 12 * linesize, linesize, bedge_lim);
2293 }
2294}
2295
2296#define MARGIN(16 << 2) (16 << 2)
2297static av_always_inline__attribute__((always_inline)) inline
2298int vp78_decode_mv_mb_modes(AVCodecContext *avctx, VP8Frame *curframe,
2299 const VP8Frame *prev_frame, int is_vp7)
2300{
2301 VP8Context *s = avctx->priv_data;
2302 int mb_x, mb_y;
2303
2304 s->mv_bounds.mv_min.y = -MARGIN(16 << 2);
2305 s->mv_bounds.mv_max.y = ((s->mb_height - 1) << 6) + MARGIN(16 << 2);
2306 for (mb_y = 0; mb_y < s->mb_height; mb_y++) {
2307 VP8Macroblock *mb = s->macroblocks_base +
2308 ((s->mb_width + 1) * (mb_y + 1) + 1);
2309 int mb_xy = mb_y * s->mb_width;
2310
2311 AV_WN32A(s->intra4x4_pred_mode_left, DC_PRED * 0x01010101)(((av_alias32*)(s->intra4x4_pred_mode_left))->u32 = (2 *
0x01010101))
;
2312
2313 s->mv_bounds.mv_min.x = -MARGIN(16 << 2);
2314 s->mv_bounds.mv_max.x = ((s->mb_width - 1) << 6) + MARGIN(16 << 2);
2315
2316 for (mb_x = 0; mb_x < s->mb_width; mb_x++, mb_xy++, mb++) {
2317 if (vpx_rac_is_end(&s->c)) {
2318 return AVERROR_INVALIDDATA(-(int)(('I') | (('N') << 8) | (('D') << 16) | ((
unsigned)('A') << 24)))
;
2319 }
2320 if (mb_y == 0)
2321 AV_WN32A((mb - s->mb_width - 1)->intra4x4_pred_mode_top,(((av_alias32*)((mb - s->mb_width - 1)->intra4x4_pred_mode_top
))->u32 = (2 * 0x01010101))
2322 DC_PRED * 0x01010101)(((av_alias32*)((mb - s->mb_width - 1)->intra4x4_pred_mode_top
))->u32 = (2 * 0x01010101))
;
2323 decode_mb_mode(s, &s->mv_bounds, mb, mb_x, mb_y, curframe->seg_map + mb_xy,
2324 prev_frame && prev_frame->seg_map ?
2325 prev_frame->seg_map + mb_xy : NULL((void*)0), 1, is_vp7);
2326 s->mv_bounds.mv_min.x -= 64;
2327 s->mv_bounds.mv_max.x -= 64;
2328 }
2329 s->mv_bounds.mv_min.y -= 64;
2330 s->mv_bounds.mv_max.y -= 64;
2331 }
2332 return 0;
2333}
2334
2335static int vp7_decode_mv_mb_modes(AVCodecContext *avctx, VP8Frame *cur_frame,
2336 const VP8Frame *prev_frame)
2337{
2338 return vp78_decode_mv_mb_modes(avctx, cur_frame, prev_frame, IS_VP71);
2339}
2340
2341static int vp8_decode_mv_mb_modes(AVCodecContext *avctx, VP8Frame *cur_frame,
2342 const VP8Frame *prev_frame)
2343{
2344 return vp78_decode_mv_mb_modes(avctx, cur_frame, prev_frame, IS_VP80);
2345}
2346
2347#if HAVE_THREADS1
2348#define check_thread_pos(td, otd, mb_x_check, mb_y_check)do { int tmp = (mb_y_check << 16) | (mb_x_check & 0xFFFF
); if (__c11_atomic_load(&otd->thread_mb_pos, 5) < tmp
) { strict_pthread_mutex_lock(&otd->lock); __c11_atomic_store
(&td->wait_mb_pos, tmp, 5); do { if (__c11_atomic_load
(&otd->thread_mb_pos, 5) >= tmp) break; strict_pthread_cond_wait
(&otd->cond, &otd->lock); } while (1); __c11_atomic_store
(&td->wait_mb_pos, 2147483647, 5); strict_pthread_mutex_unlock
(&otd->lock); } } while (0)
\
2349 do { \
2350 int tmp = (mb_y_check << 16) | (mb_x_check & 0xFFFF); \
2351 if (atomic_load(&otd->thread_mb_pos)__c11_atomic_load(&otd->thread_mb_pos, 5) < tmp) { \
2352 pthread_mutex_lockstrict_pthread_mutex_lock(&otd->lock); \
2353 atomic_store(&td->wait_mb_pos, tmp)__c11_atomic_store(&td->wait_mb_pos, tmp, 5); \
2354 do { \
2355 if (atomic_load(&otd->thread_mb_pos)__c11_atomic_load(&otd->thread_mb_pos, 5) >= tmp) \
2356 break; \
2357 pthread_cond_waitstrict_pthread_cond_wait(&otd->cond, &otd->lock); \
2358 } while (1); \
2359 atomic_store(&td->wait_mb_pos, INT_MAX)__c11_atomic_store(&td->wait_mb_pos, 2147483647, 5); \
2360 pthread_mutex_unlockstrict_pthread_mutex_unlock(&otd->lock); \
2361 } \
2362 } while (0)
2363
2364#define update_pos(td, mb_y, mb_x)do { int pos = (mb_y << 16) | (mb_x & 0xFFFF); int sliced_threading
= (avctx->active_thread_type == 2) && (num_jobs >
1); int is_null = !next_td || !prev_td; int pos_check = (is_null
) ? 1 : (next_td != td && pos >= __c11_atomic_load
(&next_td->wait_mb_pos, 5)) || (prev_td != td &&
pos >= __c11_atomic_load(&prev_td->wait_mb_pos, 5)
); __c11_atomic_store(&td->thread_mb_pos, pos, 5); if (
sliced_threading && pos_check) { strict_pthread_mutex_lock
(&td->lock); strict_pthread_cond_broadcast(&td->
cond); strict_pthread_mutex_unlock(&td->lock); } } while
(0)
\
2365 do { \
2366 int pos = (mb_y << 16) | (mb_x & 0xFFFF); \
2367 int sliced_threading = (avctx->active_thread_type == FF_THREAD_SLICE2) && \
2368 (num_jobs > 1); \
2369 int is_null = !next_td || !prev_td; \
2370 int pos_check = (is_null) ? 1 : \
2371 (next_td != td && pos >= atomic_load(&next_td->wait_mb_pos)__c11_atomic_load(&next_td->wait_mb_pos, 5)) || \
2372 (prev_td != td && pos >= atomic_load(&prev_td->wait_mb_pos)__c11_atomic_load(&prev_td->wait_mb_pos, 5)); \
2373 atomic_store(&td->thread_mb_pos, pos)__c11_atomic_store(&td->thread_mb_pos, pos, 5); \
2374 if (sliced_threading && pos_check) { \
2375 pthread_mutex_lockstrict_pthread_mutex_lock(&td->lock); \
2376 pthread_cond_broadcaststrict_pthread_cond_broadcast(&td->cond); \
2377 pthread_mutex_unlockstrict_pthread_mutex_unlock(&td->lock); \
2378 } \
2379 } while (0)
2380#else
2381#define check_thread_pos(td, otd, mb_x_check, mb_y_check)do { int tmp = (mb_y_check << 16) | (mb_x_check & 0xFFFF
); if (__c11_atomic_load(&otd->thread_mb_pos, 5) < tmp
) { strict_pthread_mutex_lock(&otd->lock); __c11_atomic_store
(&td->wait_mb_pos, tmp, 5); do { if (__c11_atomic_load
(&otd->thread_mb_pos, 5) >= tmp) break; strict_pthread_cond_wait
(&otd->cond, &otd->lock); } while (1); __c11_atomic_store
(&td->wait_mb_pos, 2147483647, 5); strict_pthread_mutex_unlock
(&otd->lock); } } while (0)
while(0)
2382#define update_pos(td, mb_y, mb_x)do { int pos = (mb_y << 16) | (mb_x & 0xFFFF); int sliced_threading
= (avctx->active_thread_type == 2) && (num_jobs >
1); int is_null = !next_td || !prev_td; int pos_check = (is_null
) ? 1 : (next_td != td && pos >= __c11_atomic_load
(&next_td->wait_mb_pos, 5)) || (prev_td != td &&
pos >= __c11_atomic_load(&prev_td->wait_mb_pos, 5)
); __c11_atomic_store(&td->thread_mb_pos, pos, 5); if (
sliced_threading && pos_check) { strict_pthread_mutex_lock
(&td->lock); strict_pthread_cond_broadcast(&td->
cond); strict_pthread_mutex_unlock(&td->lock); } } while
(0)
while(0)
2383#endif
2384
2385static av_always_inline__attribute__((always_inline)) inline int decode_mb_row_no_filter(AVCodecContext *avctx, void *tdata,
2386 int jobnr, int threadnr, int is_vp7)
2387{
2388 VP8Context *s = avctx->priv_data;
2389 VP8ThreadData *prev_td, *next_td, *td = &s->thread_data[threadnr];
2390 int mb_y = atomic_load(&td->thread_mb_pos)__c11_atomic_load(&td->thread_mb_pos, 5) >> 16;
2391 int mb_x, mb_xy = mb_y * s->mb_width;
2392 int num_jobs = s->num_jobs;
2393 const VP8Frame *prev_frame = s->prev_frame;
2394 VP8Frame *curframe = s->curframe;
2395 VPXRangeCoder *coeff_c = &s->coeff_partition[mb_y & (s->num_coeff_partitions - 1)];
2396
2397 VP8Macroblock *mb;
2398 uint8_t *dst[3] = {
2399 curframe->tf.f->data[0] + 16 * mb_y * s->linesize,
2400 curframe->tf.f->data[1] + 8 * mb_y * s->uvlinesize,
2401 curframe->tf.f->data[2] + 8 * mb_y * s->uvlinesize
2402 };
2403
2404 if (vpx_rac_is_end(&s->c))
1
Taking false branch
2405 return AVERROR_INVALIDDATA(-(int)(('I') | (('N') << 8) | (('D') << 16) | ((
unsigned)('A') << 24)))
;
2406
2407 if (mb_y == 0)
2
Assuming 'mb_y' is not equal to 0
3
Taking false branch
2408 prev_td = td;
2409 else
2410 prev_td = &s->thread_data[(jobnr + num_jobs - 1) % num_jobs];
2411 if (mb_y == s->mb_height - 1)
4
Assuming the condition is false
5
Taking false branch
2412 next_td = td;
2413 else
2414 next_td = &s->thread_data[(jobnr + 1) % num_jobs];
2415 if (s->mb_layout == 1)
6
Assuming field 'mb_layout' is not equal to 1
2416 mb = s->macroblocks_base + ((s->mb_width + 1) * (mb_y + 1) + 1);
2417 else {
2418 // Make sure the previous frame has read its segmentation map,
2419 // if we reuse the same map.
2420 if (prev_frame && s->segmentation.enabled &&
7
Assuming 'prev_frame' is null
2421 !s->segmentation.update_map)
2422 ff_progress_frame_await(&prev_frame->tf, mb_y);
2423 mb = s->macroblocks + (s->mb_height - mb_y - 1) * 2;
2424 memset(mb - 1, 0, sizeof(*mb)); // zero left macroblock
2425 AV_WN32A(s->intra4x4_pred_mode_left, DC_PRED * 0x01010101)(((av_alias32*)(s->intra4x4_pred_mode_left))->u32 = (2 *
0x01010101))
;
2426 }
2427
2428 if (!is_vp7 || mb_y
8.1
'mb_y' is not equal to 0
== 0)
8
Assuming 'is_vp7' is not equal to 0
9
Taking false branch
2429 memset(td->left_nnz, 0, sizeof(td->left_nnz));
2430
2431 td->mv_bounds.mv_min.x = -MARGIN(16 << 2);
2432 td->mv_bounds.mv_max.x = ((s->mb_width - 1) << 6) + MARGIN(16 << 2);
2433
2434 for (mb_x = 0; mb_x < s->mb_width; mb_x++, mb_xy++, mb++) {
10
Assuming 'mb_x' is < field 'mb_width'
11
Loop condition is true. Entering loop body
2435 if (vpx_rac_is_end(&s->c))
12
Taking false branch
2436 return AVERROR_INVALIDDATA(-(int)(('I') | (('N') << 8) | (('D') << 16) | ((
unsigned)('A') << 24)))
;
2437 // Wait for previous thread to read mb_x+2, and reach mb_y-1.
2438 if (prev_td != td) {
13
Assuming 'prev_td' is equal to 'td'
14
Taking false branch
2439 if (threadnr != 0) {
2440 check_thread_pos(td, prev_td,do { int tmp = (mb_y - (is_vp7 ? 2 : 1) << 16) | (mb_x +
(is_vp7 ? 2 : 1) & 0xFFFF); if (__c11_atomic_load(&prev_td
->thread_mb_pos, 5) < tmp) { strict_pthread_mutex_lock(
&prev_td->lock); __c11_atomic_store(&td->wait_mb_pos
, tmp, 5); do { if (__c11_atomic_load(&prev_td->thread_mb_pos
, 5) >= tmp) break; strict_pthread_cond_wait(&prev_td->
cond, &prev_td->lock); } while (1); __c11_atomic_store
(&td->wait_mb_pos, 2147483647, 5); strict_pthread_mutex_unlock
(&prev_td->lock); } } while (0)
2441 mb_x + (is_vp7 ? 2 : 1),do { int tmp = (mb_y - (is_vp7 ? 2 : 1) << 16) | (mb_x +
(is_vp7 ? 2 : 1) & 0xFFFF); if (__c11_atomic_load(&prev_td
->thread_mb_pos, 5) < tmp) { strict_pthread_mutex_lock(
&prev_td->lock); __c11_atomic_store(&td->wait_mb_pos
, tmp, 5); do { if (__c11_atomic_load(&prev_td->thread_mb_pos
, 5) >= tmp) break; strict_pthread_cond_wait(&prev_td->
cond, &prev_td->lock); } while (1); __c11_atomic_store
(&td->wait_mb_pos, 2147483647, 5); strict_pthread_mutex_unlock
(&prev_td->lock); } } while (0)
2442 mb_y - (is_vp7 ? 2 : 1))do { int tmp = (mb_y - (is_vp7 ? 2 : 1) << 16) | (mb_x +
(is_vp7 ? 2 : 1) & 0xFFFF); if (__c11_atomic_load(&prev_td
->thread_mb_pos, 5) < tmp) { strict_pthread_mutex_lock(
&prev_td->lock); __c11_atomic_store(&td->wait_mb_pos
, tmp, 5); do { if (__c11_atomic_load(&prev_td->thread_mb_pos
, 5) >= tmp) break; strict_pthread_cond_wait(&prev_td->
cond, &prev_td->lock); } while (1); __c11_atomic_store
(&td->wait_mb_pos, 2147483647, 5); strict_pthread_mutex_unlock
(&prev_td->lock); } } while (0)
;
2443 } else {
2444 check_thread_pos(td, prev_td,do { int tmp = (mb_y - (is_vp7 ? 2 : 1) << 16) | (mb_x +
(is_vp7 ? 2 : 1) + s->mb_width + 3 & 0xFFFF); if (__c11_atomic_load
(&prev_td->thread_mb_pos, 5) < tmp) { strict_pthread_mutex_lock
(&prev_td->lock); __c11_atomic_store(&td->wait_mb_pos
, tmp, 5); do { if (__c11_atomic_load(&prev_td->thread_mb_pos
, 5) >= tmp) break; strict_pthread_cond_wait(&prev_td->
cond, &prev_td->lock); } while (1); __c11_atomic_store
(&td->wait_mb_pos, 2147483647, 5); strict_pthread_mutex_unlock
(&prev_td->lock); } } while (0)
2445 mb_x + (is_vp7 ? 2 : 1) + s->mb_width + 3,do { int tmp = (mb_y - (is_vp7 ? 2 : 1) << 16) | (mb_x +
(is_vp7 ? 2 : 1) + s->mb_width + 3 & 0xFFFF); if (__c11_atomic_load
(&prev_td->thread_mb_pos, 5) < tmp) { strict_pthread_mutex_lock
(&prev_td->lock); __c11_atomic_store(&td->wait_mb_pos
, tmp, 5); do { if (__c11_atomic_load(&prev_td->thread_mb_pos
, 5) >= tmp) break; strict_pthread_cond_wait(&prev_td->
cond, &prev_td->lock); } while (1); __c11_atomic_store
(&td->wait_mb_pos, 2147483647, 5); strict_pthread_mutex_unlock
(&prev_td->lock); } } while (0)
2446 mb_y - (is_vp7 ? 2 : 1))do { int tmp = (mb_y - (is_vp7 ? 2 : 1) << 16) | (mb_x +
(is_vp7 ? 2 : 1) + s->mb_width + 3 & 0xFFFF); if (__c11_atomic_load
(&prev_td->thread_mb_pos, 5) < tmp) { strict_pthread_mutex_lock
(&prev_td->lock); __c11_atomic_store(&td->wait_mb_pos
, tmp, 5); do { if (__c11_atomic_load(&prev_td->thread_mb_pos
, 5) >= tmp) break; strict_pthread_cond_wait(&prev_td->
cond, &prev_td->lock); } while (1); __c11_atomic_store
(&td->wait_mb_pos, 2147483647, 5); strict_pthread_mutex_unlock
(&prev_td->lock); } } while (0)
;
2447 }
2448 }
2449
2450 s->vdsp.prefetch(dst[0] + (mb_x & 3) * 4 * s->linesize + 64,
2451 s->linesize, 4);
2452 s->vdsp.prefetch(dst[1] + (mb_x & 7) * s->uvlinesize + 64,
2453 dst[2] - dst[1], 2);
2454
2455 if (!s->mb_layout)
15
Assuming field 'mb_layout' is not equal to 0
16
Taking false branch
2456 decode_mb_mode(s, &td->mv_bounds, mb, mb_x, mb_y, curframe->seg_map + mb_xy,
2457 prev_frame && prev_frame->seg_map ?
2458 prev_frame->seg_map + mb_xy : NULL((void*)0), 0, is_vp7);
2459
2460 prefetch_motion(s, mb, mb_x, mb_y, mb_xy, VP8_FRAME_PREVIOUS);
2461
2462 if (!mb->skip) {
17
Assuming field 'skip' is not equal to 0
18
Taking false branch
2463 if (vpx_rac_is_end(coeff_c))
2464 return AVERROR_INVALIDDATA(-(int)(('I') | (('N') << 8) | (('D') << 16) | ((
unsigned)('A') << 24)))
;
2465 decode_mb_coeffs(s, td, coeff_c, mb, s->top_nnz[mb_x], td->left_nnz, is_vp7);
2466 }
2467
2468 if (mb->mode <= MODE_I4x44)
19
Assuming field 'mode' is > MODE_I4x4
20
Taking false branch
2469 intra_predict(s, td, dst, mb, mb_x, mb_y, is_vp7);
2470 else
2471 inter_predict(s, td, dst, mb, mb_x, mb_y);
21
Calling 'inter_predict'
2472
2473 prefetch_motion(s, mb, mb_x, mb_y, mb_xy, VP8_FRAME_GOLDEN);
2474
2475 if (!mb->skip) {
2476 idct_mb(s, td, dst, mb);
2477 } else {
2478 AV_ZERO64(td->left_nnz)(((av_alias64*)(td->left_nnz))->u64 = 0);
2479 AV_WN64(s->top_nnz[mb_x], 0)((((union unaligned_64 *) (s->top_nnz[mb_x]))->l) = (0)
)
; // array of 9, so unaligned
2480
2481 /* Reset DC block predictors if they would exist
2482 * if the mb had coefficients */
2483 if (mb->mode != MODE_I4x44 && mb->mode != VP8_MVMODE_SPLIT) {
2484 td->left_nnz[8] = 0;
2485 s->top_nnz[mb_x][8] = 0;
2486 }
2487 }
2488
2489 if (s->deblock_filter)
2490 filter_level_for_mb(s, mb, &td->filter_strength[mb_x], is_vp7);
2491
2492 if (s->deblock_filter && num_jobs != 1 && threadnr == num_jobs - 1) {
2493 if (s->filter.simple)
2494 backup_mb_border(s->top_border[mb_x + 1], dst[0],
2495 NULL((void*)0), NULL((void*)0), s->linesize, 0, 1);
2496 else
2497 backup_mb_border(s->top_border[mb_x + 1], dst[0],
2498 dst[1], dst[2], s->linesize, s->uvlinesize, 0);
2499 }
2500
2501 prefetch_motion(s, mb, mb_x, mb_y, mb_xy, VP8_FRAME_ALTREF);
2502
2503 dst[0] += 16;
2504 dst[1] += 8;
2505 dst[2] += 8;
2506 td->mv_bounds.mv_min.x -= 64;
2507 td->mv_bounds.mv_max.x -= 64;
2508
2509 if (mb_x == s->mb_width + 1) {
2510 update_pos(td, mb_y, s->mb_width + 3)do { int pos = (mb_y << 16) | (s->mb_width + 3 &
0xFFFF); int sliced_threading = (avctx->active_thread_type
== 2) && (num_jobs > 1); int is_null = !next_td ||
!prev_td; int pos_check = (is_null) ? 1 : (next_td != td &&
pos >= __c11_atomic_load(&next_td->wait_mb_pos, 5)
) || (prev_td != td && pos >= __c11_atomic_load(&
prev_td->wait_mb_pos, 5)); __c11_atomic_store(&td->
thread_mb_pos, pos, 5); if (sliced_threading && pos_check
) { strict_pthread_mutex_lock(&td->lock); strict_pthread_cond_broadcast
(&td->cond); strict_pthread_mutex_unlock(&td->lock
); } } while (0)
;
2511 } else {
2512 update_pos(td, mb_y, mb_x)do { int pos = (mb_y << 16) | (mb_x & 0xFFFF); int sliced_threading
= (avctx->active_thread_type == 2) && (num_jobs >
1); int is_null = !next_td || !prev_td; int pos_check = (is_null
) ? 1 : (next_td != td && pos >= __c11_atomic_load
(&next_td->wait_mb_pos, 5)) || (prev_td != td &&
pos >= __c11_atomic_load(&prev_td->wait_mb_pos, 5)
); __c11_atomic_store(&td->thread_mb_pos, pos, 5); if (
sliced_threading && pos_check) { strict_pthread_mutex_lock
(&td->lock); strict_pthread_cond_broadcast(&td->
cond); strict_pthread_mutex_unlock(&td->lock); } } while
(0)
;
2513 }
2514 }
2515 return 0;
2516}
2517
2518static av_always_inline__attribute__((always_inline)) inline void filter_mb_row(AVCodecContext *avctx, void *tdata,
2519 int jobnr, int threadnr, int is_vp7)
2520{
2521 VP8Context *s = avctx->priv_data;
2522 VP8ThreadData *td = &s->thread_data[threadnr];
2523 int mb_x, mb_y = atomic_load(&td->thread_mb_pos)__c11_atomic_load(&td->thread_mb_pos, 5) >> 16, num_jobs = s->num_jobs;
2524 AVFrame *curframe = s->curframe->tf.f;
2525 VP8ThreadData *prev_td, *next_td;
2526 uint8_t *dst[3] = {
2527 curframe->data[0] + 16 * mb_y * s->linesize,
2528 curframe->data[1] + 8 * mb_y * s->uvlinesize,
2529 curframe->data[2] + 8 * mb_y * s->uvlinesize
2530 };
2531
2532 if (mb_y == 0)
2533 prev_td = td;
2534 else
2535 prev_td = &s->thread_data[(jobnr + num_jobs - 1) % num_jobs];
2536 if (mb_y == s->mb_height - 1)
2537 next_td = td;
2538 else
2539 next_td = &s->thread_data[(jobnr + 1) % num_jobs];
2540
2541 for (mb_x = 0; mb_x < s->mb_width; mb_x++) {
2542 const VP8FilterStrength *f = &td->filter_strength[mb_x];
2543 if (prev_td != td)
2544 check_thread_pos(td, prev_td,do { int tmp = (mb_y - 1 << 16) | ((mb_x + 1) + (s->
mb_width + 3) & 0xFFFF); if (__c11_atomic_load(&prev_td
->thread_mb_pos, 5) < tmp) { strict_pthread_mutex_lock(
&prev_td->lock); __c11_atomic_store(&td->wait_mb_pos
, tmp, 5); do { if (__c11_atomic_load(&prev_td->thread_mb_pos
, 5) >= tmp) break; strict_pthread_cond_wait(&prev_td->
cond, &prev_td->lock); } while (1); __c11_atomic_store
(&td->wait_mb_pos, 2147483647, 5); strict_pthread_mutex_unlock
(&prev_td->lock); } } while (0)
2545 (mb_x + 1) + (s->mb_width + 3), mb_y - 1)do { int tmp = (mb_y - 1 << 16) | ((mb_x + 1) + (s->
mb_width + 3) & 0xFFFF); if (__c11_atomic_load(&prev_td
->thread_mb_pos, 5) < tmp) { strict_pthread_mutex_lock(
&prev_td->lock); __c11_atomic_store(&td->wait_mb_pos
, tmp, 5); do { if (__c11_atomic_load(&prev_td->thread_mb_pos
, 5) >= tmp) break; strict_pthread_cond_wait(&prev_td->
cond, &prev_td->lock); } while (1); __c11_atomic_store
(&td->wait_mb_pos, 2147483647, 5); strict_pthread_mutex_unlock
(&prev_td->lock); } } while (0)
;
2546 if (next_td != td)
2547 if (next_td != &s->thread_data[0])
2548 check_thread_pos(td, next_td, mb_x + 1, mb_y + 1)do { int tmp = (mb_y + 1 << 16) | (mb_x + 1 & 0xFFFF
); if (__c11_atomic_load(&next_td->thread_mb_pos, 5) <
tmp) { strict_pthread_mutex_lock(&next_td->lock); __c11_atomic_store
(&td->wait_mb_pos, tmp, 5); do { if (__c11_atomic_load
(&next_td->thread_mb_pos, 5) >= tmp) break; strict_pthread_cond_wait
(&next_td->cond, &next_td->lock); } while (1); __c11_atomic_store
(&td->wait_mb_pos, 2147483647, 5); strict_pthread_mutex_unlock
(&next_td->lock); } } while (0)
;
2549
2550 if (num_jobs == 1) {
2551 if (s->filter.simple)
2552 backup_mb_border(s->top_border[mb_x + 1], dst[0],
2553 NULL((void*)0), NULL((void*)0), s->linesize, 0, 1);
2554 else
2555 backup_mb_border(s->top_border[mb_x + 1], dst[0],
2556 dst[1], dst[2], s->linesize, s->uvlinesize, 0);
2557 }
2558
2559 if (s->filter.simple)
2560 filter_mb_simple(s, dst[0], f, mb_x, mb_y);
2561 else
2562 filter_mb(s, dst, f, mb_x, mb_y, is_vp7);
2563 dst[0] += 16;
2564 dst[1] += 8;
2565 dst[2] += 8;
2566
2567 update_pos(td, mb_y, (s->mb_width + 3) + mb_x)do { int pos = (mb_y << 16) | ((s->mb_width + 3) + mb_x
& 0xFFFF); int sliced_threading = (avctx->active_thread_type
== 2) && (num_jobs > 1); int is_null = !next_td ||
!prev_td; int pos_check = (is_null) ? 1 : (next_td != td &&
pos >= __c11_atomic_load(&next_td->wait_mb_pos, 5)
) || (prev_td != td && pos >= __c11_atomic_load(&
prev_td->wait_mb_pos, 5)); __c11_atomic_store(&td->
thread_mb_pos, pos, 5); if (sliced_threading && pos_check
) { strict_pthread_mutex_lock(&td->lock); strict_pthread_cond_broadcast
(&td->cond); strict_pthread_mutex_unlock(&td->lock
); } } while (0)
;
2568 }
2569}
2570
2571static av_always_inline__attribute__((always_inline)) inline
2572int vp78_decode_mb_row_sliced(AVCodecContext *avctx, void *tdata, int jobnr,
2573 int threadnr, int is_vp7)
2574{
2575 const VP8Context *s = avctx->priv_data;
2576 VP8ThreadData *td = &s->thread_data[jobnr];
2577 VP8ThreadData *next_td = NULL((void*)0), *prev_td = NULL((void*)0);
2578 VP8Frame *curframe = s->curframe;
2579 int mb_y, num_jobs = s->num_jobs;
2580 int ret;
2581
2582 td->thread_nr = threadnr;
2583 td->mv_bounds.mv_min.y = -MARGIN(16 << 2) - 64 * threadnr;
2584 td->mv_bounds.mv_max.y = ((s->mb_height - 1) << 6) + MARGIN(16 << 2) - 64 * threadnr;
2585 for (mb_y = jobnr; mb_y < s->mb_height; mb_y += num_jobs) {
2586 atomic_store(&td->thread_mb_pos, mb_y << 16)__c11_atomic_store(&td->thread_mb_pos, mb_y << 16
, 5)
;
2587 ret = s->decode_mb_row_no_filter(avctx, tdata, jobnr, threadnr);
2588 if (ret < 0) {
2589 update_pos(td, s->mb_height, INT_MAX & 0xFFFF)do { int pos = (s->mb_height << 16) | (2147483647 &
0xFFFF & 0xFFFF); int sliced_threading = (avctx->active_thread_type
== 2) && (num_jobs > 1); int is_null = !next_td ||
!prev_td; int pos_check = (is_null) ? 1 : (next_td != td &&
pos >= __c11_atomic_load(&next_td->wait_mb_pos, 5)
) || (prev_td != td && pos >= __c11_atomic_load(&
prev_td->wait_mb_pos, 5)); __c11_atomic_store(&td->
thread_mb_pos, pos, 5); if (sliced_threading && pos_check
) { strict_pthread_mutex_lock(&td->lock); strict_pthread_cond_broadcast
(&td->cond); strict_pthread_mutex_unlock(&td->lock
); } } while (0)
;
2590 return ret;
2591 }
2592 if (s->deblock_filter)
2593 s->filter_mb_row(avctx, tdata, jobnr, threadnr);
2594 update_pos(td, mb_y, INT_MAX & 0xFFFF)do { int pos = (mb_y << 16) | (2147483647 & 0xFFFF &
0xFFFF); int sliced_threading = (avctx->active_thread_type
== 2) && (num_jobs > 1); int is_null = !next_td ||
!prev_td; int pos_check = (is_null) ? 1 : (next_td != td &&
pos >= __c11_atomic_load(&next_td->wait_mb_pos, 5)
) || (prev_td != td && pos >= __c11_atomic_load(&
prev_td->wait_mb_pos, 5)); __c11_atomic_store(&td->
thread_mb_pos, pos, 5); if (sliced_threading && pos_check
) { strict_pthread_mutex_lock(&td->lock); strict_pthread_cond_broadcast
(&td->cond); strict_pthread_mutex_unlock(&td->lock
); } } while (0)
;
2595
2596 td->mv_bounds.mv_min.y -= 64 * num_jobs;
2597 td->mv_bounds.mv_max.y -= 64 * num_jobs;
2598
2599 if (avctx->active_thread_type == FF_THREAD_FRAME1)
2600 ff_progress_frame_report(&curframe->tf, mb_y);
2601 }
2602
2603 return 0;
2604}
2605
2606static int vp7_decode_mb_row_sliced(AVCodecContext *avctx, void *tdata,
2607 int jobnr, int threadnr)
2608{
2609 return vp78_decode_mb_row_sliced(avctx, tdata, jobnr, threadnr, IS_VP71);
2610}
2611
2612static int vp8_decode_mb_row_sliced(AVCodecContext *avctx, void *tdata,
2613 int jobnr, int threadnr)
2614{
2615 return vp78_decode_mb_row_sliced(avctx, tdata, jobnr, threadnr, IS_VP80);
2616}
2617
2618static av_always_inline__attribute__((always_inline)) inline
2619int vp78_decode_frame(AVCodecContext *avctx, AVFrame *rframe, int *got_frame,
2620 const AVPacket *avpkt, int is_vp7)
2621{
2622 VP8Context *s = avctx->priv_data;
2623 int ret, i, referenced, num_jobs;
2624 enum AVDiscard skip_thresh;
2625 VP8Frame *av_uninit(curframe)curframe=curframe, *prev_frame;
2626
2627 if (is_vp7)
2628 ret = vp7_decode_frame_header(s, avpkt->data, avpkt->size);
2629 else
2630 ret = vp8_decode_frame_header(s, avpkt->data, avpkt->size);
2631
2632 if (ret < 0)
2633 goto err;
2634
2635 if (!is_vp7 && s->actually_webp) {
2636 // VP8 in WebP is supposed to be intra-only. Enforce this here
2637 // to ensure that output is reproducible with frame-threading.
2638 if (!s->keyframe)
2639 return AVERROR_INVALIDDATA(-(int)(('I') | (('N') << 8) | (('D') << 16) | ((
unsigned)('A') << 24)))
;
2640 // avctx->pix_fmt already set in caller.
2641 } else if (!is_vp7 && s->pix_fmt == AV_PIX_FMT_NONE) {
2642 s->pix_fmt = get_pixel_format(s);
2643 if (s->pix_fmt < 0) {
2644 ret = AVERROR(EINVAL)(-(22));
2645 goto err;
2646 }
2647 avctx->pix_fmt = s->pix_fmt;
2648 }
2649
2650 prev_frame = s->framep[VP8_FRAME_CURRENT];
2651
2652 referenced = s->update_last || s->update_golden == VP8_FRAME_CURRENT ||
2653 s->update_altref == VP8_FRAME_CURRENT;
2654
2655 skip_thresh = !referenced ? AVDISCARD_NONREF
2656 : !s->keyframe ? AVDISCARD_NONKEY
2657 : AVDISCARD_ALL;
2658
2659 if (avctx->skip_frame >= skip_thresh) {
2660 s->invisible = 1;
2661 memcpy(&s->next_framep[0], &s->framep[0], sizeof(s->framep[0]) * 4);
2662 goto skip_decode;
2663 }
2664 s->deblock_filter = s->filter.level && avctx->skip_loop_filter < skip_thresh;
2665
2666 // release no longer referenced frames
2667 for (i = 0; i < 5; i++)
2668 if (s->frames[i].tf.f &&
2669 &s->frames[i] != prev_frame &&
2670 &s->frames[i] != s->framep[VP8_FRAME_PREVIOUS] &&
2671 &s->frames[i] != s->framep[VP8_FRAME_GOLDEN] &&
2672 &s->frames[i] != s->framep[VP8_FRAME_ALTREF])
2673 vp8_release_frame(&s->frames[i]);
2674
2675 if (!s->colorspace)
2676 avctx->colorspace = AVCOL_SPC_BT470BG;
2677 if (s->fullrange)
2678 avctx->color_range = AVCOL_RANGE_JPEG;
2679 else
2680 avctx->color_range = AVCOL_RANGE_MPEG;
2681
2682 /* Given that arithmetic probabilities are updated every frame, it's quite
2683 * likely that the values we have on a random interframe are complete
2684 * junk if we didn't start decode on a keyframe. So just don't display
2685 * anything rather than junk. */
2686 if (!s->keyframe && (!s->framep[VP8_FRAME_PREVIOUS] ||
2687 !s->framep[VP8_FRAME_GOLDEN] ||
2688 !s->framep[VP8_FRAME_ALTREF])) {
2689 av_log(avctx, AV_LOG_WARNING24,
2690 "Discarding interframe without a prior keyframe!\n");
2691 ret = AVERROR_INVALIDDATA(-(int)(('I') | (('N') << 8) | (('D') << 16) | ((
unsigned)('A') << 24)))
;
2692 goto err;
2693 }
2694
2695 curframe = vp8_find_free_buffer(s);
2696 if ((ret = vp8_alloc_frame(s, curframe, referenced)) < 0)
2697 goto err;
2698 s->framep[VP8_FRAME_CURRENT] = curframe;
2699 if (s->keyframe)
2700 curframe->tf.f->flags |= AV_FRAME_FLAG_KEY(1 << 1);
2701 else
2702 curframe->tf.f->flags &= ~AV_FRAME_FLAG_KEY(1 << 1);
2703 curframe->tf.f->pict_type = s->keyframe ? AV_PICTURE_TYPE_I
2704 : AV_PICTURE_TYPE_P;
2705
2706 // check if golden and altref are swapped
2707 if (s->update_altref != VP8_FRAME_NONE)
2708 s->next_framep[VP8_FRAME_ALTREF] = s->framep[s->update_altref];
2709 else
2710 s->next_framep[VP8_FRAME_ALTREF] = s->framep[VP8_FRAME_ALTREF];
2711
2712 if (s->update_golden != VP8_FRAME_NONE)
2713 s->next_framep[VP8_FRAME_GOLDEN] = s->framep[s->update_golden];
2714 else
2715 s->next_framep[VP8_FRAME_GOLDEN] = s->framep[VP8_FRAME_GOLDEN];
2716
2717 if (s->update_last)
2718 s->next_framep[VP8_FRAME_PREVIOUS] = curframe;
2719 else
2720 s->next_framep[VP8_FRAME_PREVIOUS] = s->framep[VP8_FRAME_PREVIOUS];
2721
2722 s->next_framep[VP8_FRAME_CURRENT] = curframe;
2723
2724 if (!is_vp7 && !s->actually_webp)
2725 ff_thread_finish_setup(avctx);
2726
2727 if (!is_vp7 && avctx->hwaccel) {
2728 const FFHWAccel *hwaccel = ffhwaccel(avctx->hwaccel);
2729 ret = hwaccel->start_frame(avctx, avpkt->buf, avpkt->data, avpkt->size);
2730 if (ret < 0)
2731 goto err;
2732
2733 ret = hwaccel->decode_slice(avctx, avpkt->data, avpkt->size);
2734 if (ret < 0)
2735 goto err;
2736
2737 ret = hwaccel->end_frame(avctx);
2738 if (ret < 0)
2739 goto err;
2740
2741 } else {
2742 s->linesize = curframe->tf.f->linesize[0];
2743 s->uvlinesize = curframe->tf.f->linesize[1];
2744
2745 memset(s->top_nnz, 0, s->mb_width * sizeof(*s->top_nnz));
2746 /* Zero macroblock structures for top/top-left prediction
2747 * from outside the frame. */
2748 if (!s->mb_layout)
2749 memset(s->macroblocks + s->mb_height * 2 - 1, 0,
2750 (s->mb_width + 1) * sizeof(*s->macroblocks));
2751 if (!s->mb_layout && s->keyframe)
2752 memset(s->intra4x4_pred_mode_top, DC_PRED2, s->mb_width * 4);
2753
2754 memset(s->ref_count, 0, sizeof(s->ref_count));
2755
2756 if (s->mb_layout == 1) {
2757 // Make sure the previous frame has read its segmentation map,
2758 // if we reuse the same map.
2759 if (prev_frame && s->segmentation.enabled &&
2760 !s->segmentation.update_map)
2761 ff_progress_frame_await(&prev_frame->tf, 1);
2762 if (is_vp7)
2763 ret = vp7_decode_mv_mb_modes(avctx, curframe, prev_frame);
2764 else
2765 ret = vp8_decode_mv_mb_modes(avctx, curframe, prev_frame);
2766 if (ret < 0)
2767 goto err;
2768 }
2769
2770 if (avctx->active_thread_type == FF_THREAD_FRAME1)
2771 num_jobs = 1;
2772 else
2773 num_jobs = FFMIN(s->num_coeff_partitions, avctx->thread_count)((s->num_coeff_partitions) > (avctx->thread_count) ?
(avctx->thread_count) : (s->num_coeff_partitions))
;
2774 s->num_jobs = num_jobs;
2775 s->curframe = curframe;
2776 s->prev_frame = prev_frame;
2777 s->mv_bounds.mv_min.y = -MARGIN(16 << 2);
2778 s->mv_bounds.mv_max.y = ((s->mb_height - 1) << 6) + MARGIN(16 << 2);
2779 for (i = 0; i < MAX_THREADS8; i++) {
2780 VP8ThreadData *td = &s->thread_data[i];
2781 atomic_init__c11_atomic_init(&td->thread_mb_pos, 0);
2782 atomic_init__c11_atomic_init(&td->wait_mb_pos, INT_MAX2147483647);
2783 }
2784 if (is_vp7)
2785 avctx->execute2(avctx, vp7_decode_mb_row_sliced, s->thread_data, NULL((void*)0),
2786 num_jobs);
2787 else
2788 avctx->execute2(avctx, vp8_decode_mb_row_sliced, s->thread_data, NULL((void*)0),
2789 num_jobs);
2790 }
2791
2792 ff_progress_frame_report(&curframe->tf, INT_MAX2147483647);
2793 memcpy(&s->framep[0], &s->next_framep[0], sizeof(s->framep[0]) * 4);
2794
2795skip_decode:
2796 // if future frames don't use the updated probabilities,
2797 // reset them to the values we saved
2798 if (!s->update_probabilities)
2799 s->prob[0] = s->prob[1];
2800
2801 if (!s->invisible) {
2802 if ((ret = av_frame_ref(rframe, curframe->tf.f)) < 0)
2803 return ret;
2804 *got_frame = 1;
2805 }
2806
2807 return avpkt->size;
2808err:
2809 memcpy(&s->next_framep[0], &s->framep[0], sizeof(s->framep[0]) * 4);
2810 return ret;
2811}
2812
2813av_cold__attribute__((cold)) int ff_vp8_decode_free(AVCodecContext *avctx)
2814{
2815 vp8_decode_flush_impl(avctx, 1);
2816
2817 return 0;
2818}
2819
2820static av_cold__attribute__((cold)) void vp78_decode_init(AVCodecContext *avctx)
2821{
2822 VP8Context *s = avctx->priv_data;
2823
2824 s->avctx = avctx;
2825 s->pix_fmt = AV_PIX_FMT_NONE;
2826 avctx->pix_fmt = AV_PIX_FMT_YUV420P;
2827
2828 ff_videodsp_init(&s->vdsp, 8);
2829
2830 ff_vp78dsp_init(&s->vp8dsp);
2831
2832 /* does not change for VP8 */
2833 memcpy(s->prob[0].scan, ff_zigzag_scan, sizeof(s->prob[0].scan));
2834}
2835
2836#if CONFIG_VP8_DECODER1
2837static int vp8_decode_mb_row_no_filter(AVCodecContext *avctx, void *tdata,
2838 int jobnr, int threadnr)
2839{
2840 return decode_mb_row_no_filter(avctx, tdata, jobnr, threadnr, 0);
2841}
2842
2843static void vp8_filter_mb_row(AVCodecContext *avctx, void *tdata,
2844 int jobnr, int threadnr)
2845{
2846 filter_mb_row(avctx, tdata, jobnr, threadnr, 0);
2847}
2848
2849int ff_vp8_decode_frame(AVCodecContext *avctx, AVFrame *frame,
2850 int *got_frame, AVPacket *avpkt)
2851{
2852 return vp78_decode_frame(avctx, frame, got_frame, avpkt, IS_VP80);
2853}
2854
2855av_cold__attribute__((cold)) int ff_vp8_decode_init(AVCodecContext *avctx)
2856{
2857 VP8Context *s = avctx->priv_data;
2858
2859 vp78_decode_init(avctx);
2860 ff_h264_pred_init(&s->hpc, AV_CODEC_ID_VP8, 8, 1);
2861 ff_vp8dsp_init(&s->vp8dsp);
2862 s->decode_mb_row_no_filter = vp8_decode_mb_row_no_filter;
2863 s->filter_mb_row = vp8_filter_mb_row;
2864
2865 return 0;
2866}
2867
2868#if HAVE_THREADS1
2869static void vp8_replace_frame(VP8Frame *dst, const VP8Frame *src)
2870{
2871 ff_progress_frame_replace(&dst->tf, &src->tf);
2872 av_refstruct_replace(&dst->seg_map, src->seg_map);
2873 av_refstruct_replace(&dst->hwaccel_picture_private,
2874 src->hwaccel_picture_private);
2875}
2876
2877#define REBASE(pic)((pic) ? (pic) - &s_src->frames[0] + &s->frames
[0] : ((void*)0))
((pic) ? (pic) - &s_src->frames[0] + &s->frames[0] : NULL((void*)0))
2878
2879static int vp8_decode_update_thread_context(AVCodecContext *dst,
2880 const AVCodecContext *src)
2881{
2882 VP8Context *s = dst->priv_data, *s_src = src->priv_data;
2883
2884 if (s->macroblocks_base &&
2885 (s_src->mb_width != s->mb_width || s_src->mb_height != s->mb_height)) {
2886 free_buffers(s);
2887 s->mb_width = s_src->mb_width;
2888 s->mb_height = s_src->mb_height;
2889 }
2890
2891 s->pix_fmt = s_src->pix_fmt;
2892 s->prob[0] = s_src->prob[!s_src->update_probabilities];
2893 s->segmentation = s_src->segmentation;
2894 s->lf_delta = s_src->lf_delta;
2895 memcpy(s->sign_bias, s_src->sign_bias, sizeof(s->sign_bias));
2896
2897 for (int i = 0; i < FF_ARRAY_ELEMS(s_src->frames)(sizeof(s_src->frames) / sizeof((s_src->frames)[0])); i++)
2898 vp8_replace_frame(&s->frames[i], &s_src->frames[i]);
2899
2900 s->framep[0] = REBASE(s_src->next_framep[0])((s_src->next_framep[0]) ? (s_src->next_framep[0]) - &
s_src->frames[0] + &s->frames[0] : ((void*)0))
;
2901 s->framep[1] = REBASE(s_src->next_framep[1])((s_src->next_framep[1]) ? (s_src->next_framep[1]) - &
s_src->frames[0] + &s->frames[0] : ((void*)0))
;
2902 s->framep[2] = REBASE(s_src->next_framep[2])((s_src->next_framep[2]) ? (s_src->next_framep[2]) - &
s_src->frames[0] + &s->frames[0] : ((void*)0))
;
2903 s->framep[3] = REBASE(s_src->next_framep[3])((s_src->next_framep[3]) ? (s_src->next_framep[3]) - &
s_src->frames[0] + &s->frames[0] : ((void*)0))
;
2904
2905 return 0;
2906}
2907#endif /* HAVE_THREADS */
2908#endif /* CONFIG_VP8_DECODER */
2909
2910#if CONFIG_VP7_DECODER0
2911static int vp7_decode_mb_row_no_filter(AVCodecContext *avctx, void *tdata,
2912 int jobnr, int threadnr)
2913{
2914 return decode_mb_row_no_filter(avctx, tdata, jobnr, threadnr, 1);
2915}
2916
2917static void vp7_filter_mb_row(AVCodecContext *avctx, void *tdata,
2918 int jobnr, int threadnr)
2919{
2920 filter_mb_row(avctx, tdata, jobnr, threadnr, 1);
2921}
2922
2923static int vp7_decode_frame(AVCodecContext *avctx, AVFrame *frame,
2924 int *got_frame, AVPacket *avpkt)
2925{
2926 return vp78_decode_frame(avctx, frame, got_frame, avpkt, IS_VP71);
2927}
2928
2929av_cold__attribute__((cold)) static int vp7_decode_init(AVCodecContext *avctx)
2930{
2931 VP8Context *s = avctx->priv_data;
2932
2933 vp78_decode_init(avctx);
2934 ff_h264_pred_init(&s->hpc, AV_CODEC_ID_VP7, 8, 1);
2935 ff_vp7dsp_init(&s->vp8dsp);
2936 s->decode_mb_row_no_filter = vp7_decode_mb_row_no_filter;
2937 s->filter_mb_row = vp7_filter_mb_row;
2938
2939 return 0;
2940}
2941
2942const FFCodec ff_vp7_decoder = {
2943 .p.name = "vp7",
2944 CODEC_LONG_NAME("On2 VP7").p.long_name = "On2 VP7",
2945 .p.type = AVMEDIA_TYPE_VIDEO,
2946 .p.id = AV_CODEC_ID_VP7,
2947 .priv_data_size = sizeof(VP8Context),
2948 .init = vp7_decode_init,
2949 .close = ff_vp8_decode_free,
2950 FF_CODEC_DECODE_CB(vp7_decode_frame).is_decoder = 1, .cb_type = FF_CODEC_CB_TYPE_DECODE, .cb.decode
= (vp7_decode_frame)
,
2951 .p.capabilities = AV_CODEC_CAP_DR1(1 << 1),
2952 .flush = vp8_decode_flush,
2953 .caps_internal = FF_CODEC_CAP_USES_PROGRESSFRAMES(1 << 6),
2954};
2955#endif /* CONFIG_VP7_DECODER */
2956
2957#if CONFIG_VP8_DECODER1
2958const FFCodec ff_vp8_decoder = {
2959 .p.name = "vp8",
2960 CODEC_LONG_NAME("On2 VP8").p.long_name = "On2 VP8",
2961 .p.type = AVMEDIA_TYPE_VIDEO,
2962 .p.id = AV_CODEC_ID_VP8,
2963 .priv_data_size = sizeof(VP8Context),
2964 .init = ff_vp8_decode_init,
2965 .close = ff_vp8_decode_free,
2966 FF_CODEC_DECODE_CB(ff_vp8_decode_frame).is_decoder = 1, .cb_type = FF_CODEC_CB_TYPE_DECODE, .cb.decode
= (ff_vp8_decode_frame)
,
2967 .p.capabilities = AV_CODEC_CAP_DR1(1 << 1) | AV_CODEC_CAP_FRAME_THREADS(1 << 12) |
2968 AV_CODEC_CAP_SLICE_THREADS(1 << 13),
2969 .caps_internal = FF_CODEC_CAP_USES_PROGRESSFRAMES(1 << 6),
2970 .flush = vp8_decode_flush,
2971 UPDATE_THREAD_CONTEXT(vp8_decode_update_thread_context).update_thread_context = (vp8_decode_update_thread_context),
2972 .hw_configs = (const AVCodecHWConfigInternal *const []) {
2973#if CONFIG_VP8_VAAPI_HWACCEL1
2974 HWACCEL_VAAPI(vp8)&(const AVCodecHWConfigInternal) { .public = { .pix_fmt =
AV_PIX_FMT_VAAPI, .methods = (1 ? AV_CODEC_HW_CONFIG_METHOD_HW_DEVICE_CTX
: 0) | (1 ? AV_CODEC_HW_CONFIG_METHOD_HW_FRAMES_CTX : 0) | (
1 ? AV_CODEC_HW_CONFIG_METHOD_AD_HOC : 0), .device_type = AV_HWDEVICE_TYPE_VAAPI
, }, .hwaccel = &ff_vp8_vaapi_hwaccel, }
,
2975#endif
2976#if CONFIG_VP8_NVDEC_HWACCEL0
2977 HWACCEL_NVDEC(vp8)&(const AVCodecHWConfigInternal) { .public = { .pix_fmt =
AV_PIX_FMT_CUDA, .methods = (1 ? AV_CODEC_HW_CONFIG_METHOD_HW_DEVICE_CTX
: 0) | (1 ? AV_CODEC_HW_CONFIG_METHOD_HW_FRAMES_CTX : 0) | (
0 ? AV_CODEC_HW_CONFIG_METHOD_AD_HOC : 0), .device_type = AV_HWDEVICE_TYPE_CUDA
, }, .hwaccel = &ff_vp8_nvdec_hwaccel, }
,
2978#endif
2979 NULL((void*)0)
2980 },
2981};
2982#endif /* CONFIG_VP8_DECODER */