Bug Summary

File:root/firefox-clang/media/ffvpx/libavcodec/vp8.c
Warning:line 2626, column 15
Assigned value is uninitialized

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