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