annotate vp8.c @ 12043:f9a0bd0888a4 libavcodec

mpegaudio: call ff_mpegaudiodec_init_mmx() only from float decoder The mmx code is floating-point only, and this function does not know from which decoder it is called. Without this change, the integer decoder only "works" because the size of the context struct is smaller in this case, and the mmx init function writes the function pointer outside the allocated context.
author mru
date Thu, 01 Jul 2010 23:21:17 +0000
parents 3c51d7ac41c9
children 372f7fed2806
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
11921
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1 /**
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
2 * VP8 compatible video decoder
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
3 *
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
4 * Copyright (C) 2010 David Conrad
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
5 * Copyright (C) 2010 Ronald S. Bultje
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
6 *
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
7 * This file is part of FFmpeg.
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
8 *
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
9 * FFmpeg is free software; you can redistribute it and/or
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
10 * modify it under the terms of the GNU Lesser General Public
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
11 * License as published by the Free Software Foundation; either
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
12 * version 2.1 of the License, or (at your option) any later version.
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
13 *
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
14 * FFmpeg is distributed in the hope that it will be useful,
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
17 * Lesser General Public License for more details.
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
18 *
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
19 * You should have received a copy of the GNU Lesser General Public
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
20 * License along with FFmpeg; if not, write to the Free Software
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
21 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
22 */
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
23
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
24 #include "avcodec.h"
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
25 #include "vp56.h"
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
26 #include "vp8data.h"
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
27 #include "vp8dsp.h"
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
28 #include "h264pred.h"
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
29 #include "rectangle.h"
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
30
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
31 typedef struct {
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
32 uint8_t segment;
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
33 uint8_t skip;
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
34 // todo: make it possible to check for at least (i4x4 or split_mv)
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
35 // in one op. are others needed?
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
36 uint8_t mode;
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
37 uint8_t ref_frame;
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
38 uint8_t partitioning;
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
39 VP56mv mv;
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
40 VP56mv bmv[16];
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
41 } VP8Macroblock;
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
42
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
43 typedef struct {
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
44 AVCodecContext *avctx;
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
45 DSPContext dsp;
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
46 VP8DSPContext vp8dsp;
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
47 H264PredContext hpc;
11974
356b20a6566d VP8 bilinear filter
conrad
parents: 11970
diff changeset
48 vp8_mc_func put_pixels_tab[3][3][3];
11921
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
49 AVFrame frames[4];
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
50 AVFrame *framep[4];
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
51 uint8_t *edge_emu_buffer;
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
52 VP56RangeCoder c; ///< header context, includes mb modes and motion vectors
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
53 int profile;
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
54
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
55 int mb_width; /* number of horizontal MB */
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
56 int mb_height; /* number of vertical MB */
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
57 int linesize;
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
58 int uvlinesize;
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
59
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
60 int keyframe;
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
61 int invisible;
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
62 int update_last; ///< update VP56_FRAME_PREVIOUS with the current one
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
63 int update_golden; ///< VP56_FRAME_NONE if not updated, or which frame to copy if so
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
64 int update_altref;
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
65
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
66 /**
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
67 * If this flag is not set, all the probability updates
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
68 * are discarded after this frame is decoded.
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
69 */
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
70 int update_probabilities;
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
71
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
72 /**
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
73 * All coefficients are contained in separate arith coding contexts.
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
74 * There can be 1, 2, 4, or 8 of these after the header context.
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
75 */
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
76 int num_coeff_partitions;
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
77 VP56RangeCoder coeff_partition[8];
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
78
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
79 VP8Macroblock *macroblocks;
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
80 VP8Macroblock *macroblocks_base;
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
81 int mb_stride;
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
82
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
83 uint8_t *intra4x4_pred_mode;
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
84 uint8_t *intra4x4_pred_mode_base;
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
85 int b4_stride;
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
86
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
87 /**
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
88 * For coeff decode, we need to know whether the above block had non-zero
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
89 * coefficients. This means for each macroblock, we need data for 4 luma
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
90 * blocks, 2 u blocks, 2 v blocks, and the luma dc block, for a total of 9
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
91 * per macroblock. We keep the last row in top_nnz.
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
92 */
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
93 uint8_t (*top_nnz)[9];
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
94 DECLARE_ALIGNED(8, uint8_t, left_nnz)[9];
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
95
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
96 /**
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
97 * This is the index plus one of the last non-zero coeff
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
98 * for each of the blocks in the current macroblock.
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
99 * So, 0 -> no coeffs
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
100 * 1 -> dc-only (special transform)
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
101 * 2+-> full transform
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
102 */
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
103 DECLARE_ALIGNED(16, uint8_t, non_zero_count_cache)[6][4];
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
104 DECLARE_ALIGNED(16, DCTELEM, block)[6][4][16];
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
105
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
106 int chroma_pred_mode; ///< 8x8c pred mode of the current macroblock
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
107
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
108 int mbskip_enabled;
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
109 int sign_bias[4]; ///< one state [0, 1] per ref frame type
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
110
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
111 /**
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
112 * Base parameters for segmentation, i.e. per-macroblock parameters.
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
113 * These must be kept unchanged even if segmentation is not used for
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
114 * a frame, since the values persist between interframes.
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
115 */
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
116 struct {
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
117 int enabled;
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
118 int absolute_vals;
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
119 int update_map;
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
120 int8_t base_quant[4];
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
121 int8_t filter_level[4]; ///< base loop filter level
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
122 } segmentation;
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
123
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
124 /**
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
125 * Macroblocks can have one of 4 different quants in a frame when
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
126 * segmentation is enabled.
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
127 * If segmentation is disabled, only the first segment's values are used.
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
128 */
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
129 struct {
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
130 // [0] - DC qmul [1] - AC qmul
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
131 int16_t luma_qmul[2];
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
132 int16_t luma_dc_qmul[2]; ///< luma dc-only block quant
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
133 int16_t chroma_qmul[2];
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
134 } qmat[4];
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
135
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
136 struct {
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
137 int simple;
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
138 int level;
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
139 int sharpness;
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
140 } filter;
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
141
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
142 struct {
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
143 int enabled; ///< whether each mb can have a different strength based on mode/ref
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
144
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
145 /**
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
146 * filter strength adjustment for the following macroblock modes:
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
147 * [0] - i4x4
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
148 * [1] - zero mv
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
149 * [2] - inter modes except for zero or split mv
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
150 * [3] - split mv
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
151 * i16x16 modes never have any adjustment
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
152 */
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
153 int8_t mode[4];
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
154
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
155 /**
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
156 * filter strength adjustment for macroblocks that reference:
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
157 * [0] - intra / VP56_FRAME_CURRENT
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
158 * [1] - VP56_FRAME_PREVIOUS
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
159 * [2] - VP56_FRAME_GOLDEN
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
160 * [3] - altref / VP56_FRAME_GOLDEN2
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
161 */
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
162 int8_t ref[4];
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
163 } lf_delta;
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
164
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
165 /**
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
166 * These are all of the updatable probabilities for binary decisions.
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
167 * They are only implictly reset on keyframes, making it quite likely
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
168 * for an interframe to desync if a prior frame's header was corrupt
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
169 * or missing outright!
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
170 */
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
171 struct {
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
172 uint8_t segmentid[3];
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
173 uint8_t mbskip;
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
174 uint8_t intra;
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
175 uint8_t last;
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
176 uint8_t golden;
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
177 uint8_t pred16x16[4];
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
178 uint8_t pred8x8c[3];
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
179 uint8_t token[4][8][3][NUM_DCT_TOKENS-1];
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
180 uint8_t mvc[2][19];
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
181 } prob[2];
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
182 } VP8Context;
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
183
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
184 #define RL24(p) (AV_RL16(p) + ((p)[2] << 16))
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
185
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
186 static void vp8_decode_flush(AVCodecContext *avctx)
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
187 {
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
188 VP8Context *s = avctx->priv_data;
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
189 int i;
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
190
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
191 for (i = 0; i < 4; i++)
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
192 if (s->frames[i].data[0])
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
193 avctx->release_buffer(avctx, &s->frames[i]);
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
194 memset(s->framep, 0, sizeof(s->framep));
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
195
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
196 av_freep(&s->macroblocks_base);
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
197 av_freep(&s->intra4x4_pred_mode_base);
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
198 av_freep(&s->top_nnz);
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
199 av_freep(&s->edge_emu_buffer);
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
200
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
201 s->macroblocks = NULL;
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
202 s->intra4x4_pred_mode = NULL;
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
203 }
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
204
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
205 static int update_dimensions(VP8Context *s, int width, int height)
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
206 {
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
207 int i;
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
208
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
209 if (avcodec_check_dimensions(s->avctx, width, height))
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
210 return AVERROR_INVALIDDATA;
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
211
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
212 vp8_decode_flush(s->avctx);
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
213
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
214 avcodec_set_dimensions(s->avctx, width, height);
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
215
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
216 s->mb_width = (s->avctx->coded_width +15) / 16;
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
217 s->mb_height = (s->avctx->coded_height+15) / 16;
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
218
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
219 // we allocate a border around the top/left of intra4x4 modes
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
220 // this is 4 blocks for intra4x4 to keep 4-byte alignment for fill_rectangle
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
221 s->mb_stride = s->mb_width+1;
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
222 s->b4_stride = 4*s->mb_stride;
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
223
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
224 s->macroblocks_base = av_mallocz(s->mb_stride*(s->mb_height+1)*sizeof(*s->macroblocks));
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
225 s->intra4x4_pred_mode_base = av_mallocz(s->b4_stride*(4*s->mb_height+1));
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
226 s->top_nnz = av_mallocz(s->mb_width*sizeof(*s->top_nnz));
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
227
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
228 s->macroblocks = s->macroblocks_base + 1 + s->mb_stride;
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
229 s->intra4x4_pred_mode = s->intra4x4_pred_mode_base + 4 + s->b4_stride;
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
230
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
231 memset(s->intra4x4_pred_mode_base, DC_PRED, s->b4_stride);
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
232 for (i = 0; i < 4*s->mb_height; i++)
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
233 s->intra4x4_pred_mode[i*s->b4_stride-1] = DC_PRED;
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
234
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
235 return 0;
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
236 }
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
237
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
238 static void parse_segment_info(VP8Context *s)
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
239 {
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
240 VP56RangeCoder *c = &s->c;
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
241 int i;
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
242
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
243 s->segmentation.update_map = vp8_rac_get(c);
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
244
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
245 if (vp8_rac_get(c)) { // update segment feature data
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
246 s->segmentation.absolute_vals = vp8_rac_get(c);
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
247
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
248 for (i = 0; i < 4; i++)
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
249 s->segmentation.base_quant[i] = vp8_rac_get_sint(c, 7);
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
250
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
251 for (i = 0; i < 4; i++)
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
252 s->segmentation.filter_level[i] = vp8_rac_get_sint(c, 6);
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
253 }
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
254 if (s->segmentation.update_map)
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
255 for (i = 0; i < 3; i++)
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
256 s->prob->segmentid[i] = vp8_rac_get(c) ? vp8_rac_get_uint(c, 8) : 255;
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
257 }
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
258
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
259 static void update_lf_deltas(VP8Context *s)
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
260 {
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
261 VP56RangeCoder *c = &s->c;
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
262 int i;
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
263
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
264 for (i = 0; i < 4; i++)
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
265 s->lf_delta.ref[i] = vp8_rac_get_sint(c, 6);
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
266
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
267 for (i = 0; i < 4; i++)
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
268 s->lf_delta.mode[i] = vp8_rac_get_sint(c, 6);
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
269 }
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
270
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
271 static int setup_partitions(VP8Context *s, const uint8_t *buf, int buf_size)
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
272 {
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
273 const uint8_t *sizes = buf;
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
274 int i;
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
275
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
276 s->num_coeff_partitions = 1 << vp8_rac_get_uint(&s->c, 2);
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
277
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
278 buf += 3*(s->num_coeff_partitions-1);
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
279 buf_size -= 3*(s->num_coeff_partitions-1);
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
280 if (buf_size < 0)
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
281 return -1;
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
282
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
283 for (i = 0; i < s->num_coeff_partitions-1; i++) {
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
284 int size = RL24(sizes + 3*i);
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
285 if (buf_size - size < 0)
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
286 return -1;
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
287
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
288 vp56_init_range_decoder(&s->coeff_partition[i], buf, size);
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
289 buf += size;
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
290 buf_size -= size;
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
291 }
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
292 vp56_init_range_decoder(&s->coeff_partition[i], buf, buf_size);
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
293
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
294 return 0;
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
295 }
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
296
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
297 static void get_quants(VP8Context *s)
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
298 {
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
299 VP56RangeCoder *c = &s->c;
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
300 int i, base_qi;
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
301
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
302 int yac_qi = vp8_rac_get_uint(c, 7);
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
303 int ydc_delta = vp8_rac_get_sint(c, 4);
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
304 int y2dc_delta = vp8_rac_get_sint(c, 4);
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
305 int y2ac_delta = vp8_rac_get_sint(c, 4);
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
306 int uvdc_delta = vp8_rac_get_sint(c, 4);
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
307 int uvac_delta = vp8_rac_get_sint(c, 4);
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
308
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
309 for (i = 0; i < 4; i++) {
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
310 if (s->segmentation.enabled) {
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
311 base_qi = s->segmentation.base_quant[i];
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
312 if (!s->segmentation.absolute_vals)
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
313 base_qi += yac_qi;
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
314 } else
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
315 base_qi = yac_qi;
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
316
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
317 s->qmat[i].luma_qmul[0] = vp8_dc_qlookup[av_clip(base_qi + ydc_delta , 0, 127)];
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
318 s->qmat[i].luma_qmul[1] = vp8_ac_qlookup[av_clip(base_qi , 0, 127)];
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
319 s->qmat[i].luma_dc_qmul[0] = 2 * vp8_dc_qlookup[av_clip(base_qi + y2dc_delta, 0, 127)];
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
320 s->qmat[i].luma_dc_qmul[1] = 155 * vp8_ac_qlookup[av_clip(base_qi + y2ac_delta, 0, 127)] / 100;
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
321 s->qmat[i].chroma_qmul[0] = vp8_dc_qlookup[av_clip(base_qi + uvdc_delta, 0, 127)];
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
322 s->qmat[i].chroma_qmul[1] = vp8_ac_qlookup[av_clip(base_qi + uvac_delta, 0, 127)];
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
323
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
324 s->qmat[i].luma_dc_qmul[1] = FFMAX(s->qmat[i].luma_dc_qmul[1], 8);
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
325 s->qmat[i].chroma_qmul[0] = FFMIN(s->qmat[i].chroma_qmul[0], 132);
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
326 }
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
327 }
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
328
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
329 /**
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
330 * Determine which buffers golden and altref should be updated with after this frame.
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
331 * The spec isn't clear here, so I'm going by my understanding of what libvpx does
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
332 *
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
333 * Intra frames update all 3 references
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
334 * Inter frames update VP56_FRAME_PREVIOUS if the update_last flag is set
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
335 * If the update (golden|altref) flag is set, it's updated with the current frame
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
336 * if update_last is set, and VP56_FRAME_PREVIOUS otherwise.
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
337 * If the flag is not set, the number read means:
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
338 * 0: no update
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
339 * 1: VP56_FRAME_PREVIOUS
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
340 * 2: update golden with altref, or update altref with golden
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
341 */
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
342 static VP56Frame ref_to_update(VP8Context *s, int update, VP56Frame ref)
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
343 {
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
344 VP56RangeCoder *c = &s->c;
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
345
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
346 if (update)
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
347 return VP56_FRAME_CURRENT;
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
348
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
349 switch (vp8_rac_get_uint(c, 2)) {
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
350 case 1:
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
351 return VP56_FRAME_PREVIOUS;
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
352 case 2:
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
353 return (ref == VP56_FRAME_GOLDEN) ? VP56_FRAME_GOLDEN2 : VP56_FRAME_GOLDEN;
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
354 }
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
355 return VP56_FRAME_NONE;
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
356 }
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
357
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
358 static void update_refs(VP8Context *s)
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
359 {
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
360 VP56RangeCoder *c = &s->c;
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
361
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
362 int update_golden = vp8_rac_get(c);
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
363 int update_altref = vp8_rac_get(c);
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
364
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
365 s->update_golden = ref_to_update(s, update_golden, VP56_FRAME_GOLDEN);
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
366 s->update_altref = ref_to_update(s, update_altref, VP56_FRAME_GOLDEN2);
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
367 }
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
368
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
369 static int decode_frame_header(VP8Context *s, const uint8_t *buf, int buf_size)
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
370 {
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
371 VP56RangeCoder *c = &s->c;
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
372 int header_size, hscale, vscale, i, j, k, l, ret;
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
373 int width = s->avctx->width;
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
374 int height = s->avctx->height;
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
375
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
376 s->keyframe = !(buf[0] & 1);
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
377 s->profile = (buf[0]>>1) & 7;
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
378 s->invisible = !(buf[0] & 0x10);
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
379 header_size = RL24(buf) >> 5;
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
380 buf += 3;
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
381 buf_size -= 3;
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
382
11974
356b20a6566d VP8 bilinear filter
conrad
parents: 11970
diff changeset
383 if (s->profile > 3)
356b20a6566d VP8 bilinear filter
conrad
parents: 11970
diff changeset
384 av_log(s->avctx, AV_LOG_WARNING, "Unknown profile %d\n", s->profile);
356b20a6566d VP8 bilinear filter
conrad
parents: 11970
diff changeset
385
356b20a6566d VP8 bilinear filter
conrad
parents: 11970
diff changeset
386 if (!s->profile)
356b20a6566d VP8 bilinear filter
conrad
parents: 11970
diff changeset
387 memcpy(s->put_pixels_tab, s->vp8dsp.put_vp8_epel_pixels_tab, sizeof(s->put_pixels_tab));
356b20a6566d VP8 bilinear filter
conrad
parents: 11970
diff changeset
388 else // profile 1-3 use bilinear, 4+ aren't defined so whatever
356b20a6566d VP8 bilinear filter
conrad
parents: 11970
diff changeset
389 memcpy(s->put_pixels_tab, s->vp8dsp.put_vp8_bilinear_pixels_tab, sizeof(s->put_pixels_tab));
11921
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
390
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
391 if (header_size > buf_size - 7*s->keyframe) {
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
392 av_log(s->avctx, AV_LOG_ERROR, "Header size larger than data provided\n");
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
393 return AVERROR_INVALIDDATA;
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
394 }
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
395
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
396 if (s->keyframe) {
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
397 if (RL24(buf) != 0x2a019d) {
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
398 av_log(s->avctx, AV_LOG_ERROR, "Invalid start code 0x%x\n", RL24(buf));
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
399 return AVERROR_INVALIDDATA;
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
400 }
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
401 width = AV_RL16(buf+3) & 0x3fff;
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
402 height = AV_RL16(buf+5) & 0x3fff;
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
403 hscale = buf[4] >> 6;
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
404 vscale = buf[6] >> 6;
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
405 buf += 7;
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
406 buf_size -= 7;
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
407
11970
c7953ee47af4 vp8: warn and request sample if upscaling specified in header
mru
parents: 11950
diff changeset
408 if (hscale || vscale)
c7953ee47af4 vp8: warn and request sample if upscaling specified in header
mru
parents: 11950
diff changeset
409 av_log_missing_feature(s->avctx, "Upscaling", 1);
c7953ee47af4 vp8: warn and request sample if upscaling specified in header
mru
parents: 11950
diff changeset
410
11921
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
411 s->update_golden = s->update_altref = VP56_FRAME_CURRENT;
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
412 memcpy(s->prob->token , vp8_token_default_probs , sizeof(s->prob->token));
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
413 memcpy(s->prob->pred16x16, vp8_pred16x16_prob_inter, sizeof(s->prob->pred16x16));
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
414 memcpy(s->prob->pred8x8c , vp8_pred8x8c_prob_inter , sizeof(s->prob->pred8x8c));
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
415 memcpy(s->prob->mvc , vp8_mv_default_prob , sizeof(s->prob->mvc));
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
416 memset(&s->segmentation, 0, sizeof(s->segmentation));
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
417 }
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
418
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
419 if (!s->macroblocks_base || /* first frame */
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
420 width != s->avctx->width || height != s->avctx->height) {
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
421 if ((ret = update_dimensions(s, width, height) < 0))
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
422 return ret;
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
423 }
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
424
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
425 vp56_init_range_decoder(c, buf, header_size);
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
426 buf += header_size;
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
427 buf_size -= header_size;
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
428
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
429 if (s->keyframe) {
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
430 if (vp8_rac_get(c))
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
431 av_log(s->avctx, AV_LOG_WARNING, "Unspecified colorspace\n");
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
432 vp8_rac_get(c); // whether we can skip clamping in dsp functions
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
433 }
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
434
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
435 if ((s->segmentation.enabled = vp8_rac_get(c)))
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
436 parse_segment_info(s);
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
437 else
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
438 s->segmentation.update_map = 0; // FIXME: move this to some init function?
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
439
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
440 s->filter.simple = vp8_rac_get(c);
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
441 s->filter.level = vp8_rac_get_uint(c, 6);
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
442 s->filter.sharpness = vp8_rac_get_uint(c, 3);
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
443
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
444 if ((s->lf_delta.enabled = vp8_rac_get(c)))
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
445 if (vp8_rac_get(c))
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
446 update_lf_deltas(s);
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
447
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
448 if (setup_partitions(s, buf, buf_size)) {
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
449 av_log(s->avctx, AV_LOG_ERROR, "Invalid partitions\n");
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
450 return AVERROR_INVALIDDATA;
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
451 }
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
452
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
453 get_quants(s);
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
454
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
455 if (!s->keyframe) {
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
456 update_refs(s);
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
457 s->sign_bias[VP56_FRAME_GOLDEN] = vp8_rac_get(c);
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
458 s->sign_bias[VP56_FRAME_GOLDEN2 /* altref */] = vp8_rac_get(c);
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
459 }
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
460
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
461 // if we aren't saving this frame's probabilities for future frames,
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
462 // make a copy of the current probabilities
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
463 if (!(s->update_probabilities = vp8_rac_get(c)))
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
464 s->prob[1] = s->prob[0];
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
465
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
466 s->update_last = s->keyframe || vp8_rac_get(c);
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
467
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
468 for (i = 0; i < 4; i++)
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
469 for (j = 0; j < 8; j++)
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
470 for (k = 0; k < 3; k++)
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
471 for (l = 0; l < NUM_DCT_TOKENS-1; l++)
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
472 if (vp56_rac_get_prob(c, vp8_token_update_probs[i][j][k][l]))
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
473 s->prob->token[i][j][k][l] = vp8_rac_get_uint(c, 8);
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
474
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
475 if ((s->mbskip_enabled = vp8_rac_get(c)))
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
476 s->prob->mbskip = vp8_rac_get_uint(c, 8);
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
477
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
478 if (!s->keyframe) {
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
479 s->prob->intra = vp8_rac_get_uint(c, 8);
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
480 s->prob->last = vp8_rac_get_uint(c, 8);
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
481 s->prob->golden = vp8_rac_get_uint(c, 8);
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
482
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
483 if (vp8_rac_get(c))
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
484 for (i = 0; i < 4; i++)
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
485 s->prob->pred16x16[i] = vp8_rac_get_uint(c, 8);
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
486 if (vp8_rac_get(c))
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
487 for (i = 0; i < 3; i++)
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
488 s->prob->pred8x8c[i] = vp8_rac_get_uint(c, 8);
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
489
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
490 // 17.2 MV probability update
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
491 for (i = 0; i < 2; i++)
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
492 for (j = 0; j < 19; j++)
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
493 if (vp56_rac_get_prob(c, vp8_mv_update_prob[i][j]))
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
494 s->prob->mvc[i][j] = vp8_rac_get_nn(c);
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
495 }
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
496
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
497 return 0;
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
498 }
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
499
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
500 static inline void clamp_mv(VP8Context *s, VP56mv *dst, const VP56mv *src,
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
501 int mb_x, int mb_y)
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
502 {
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
503 #define MARGIN (16 << 2)
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
504 dst->x = av_clip(src->x, -((mb_x << 6) + MARGIN),
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
505 ((s->mb_width - 1 - mb_x) << 6) + MARGIN);
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
506 dst->y = av_clip(src->y, -((mb_y << 6) + MARGIN),
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
507 ((s->mb_height - 1 - mb_y) << 6) + MARGIN);
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
508 }
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
509
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
510 static void find_near_mvs(VP8Context *s, VP8Macroblock *mb, int mb_x, int mb_y,
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
511 VP56mv near[2], VP56mv *best, int cnt[4])
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
512 {
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
513 VP8Macroblock *mb_edge[3] = { mb - s->mb_stride /* top */,
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
514 mb - 1 /* left */,
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
515 mb - s->mb_stride - 1 /* top-left */ };
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
516 enum { EDGE_TOP, EDGE_LEFT, EDGE_TOPLEFT };
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
517 VP56mv near_mv[4] = {{ 0 }};
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
518 enum { CNT_ZERO, CNT_NEAREST, CNT_NEAR, CNT_SPLITMV };
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
519 int idx = CNT_ZERO, n;
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
520 int best_idx = CNT_ZERO;
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
521
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
522 /* Process MB on top, left and top-left */
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
523 for (n = 0; n < 3; n++) {
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
524 VP8Macroblock *edge = mb_edge[n];
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
525 if (edge->ref_frame != VP56_FRAME_CURRENT) {
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
526 if (edge->mv.x | edge->mv.y) {
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
527 VP56mv tmp = edge->mv;
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
528 if (s->sign_bias[mb->ref_frame] != s->sign_bias[edge->ref_frame]) {
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
529 tmp.x *= -1;
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
530 tmp.y *= -1;
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
531 }
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
532 if ((tmp.x ^ near_mv[idx].x) | (tmp.y ^ near_mv[idx].y))
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
533 near_mv[++idx] = tmp;
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
534 cnt[idx] += 1 + (n != 2);
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
535 } else
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
536 cnt[CNT_ZERO] += 1 + (n != 2);
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
537 }
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
538 }
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
539
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
540 /* If we have three distinct MV's, merge first and last if they're the same */
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
541 if (cnt[CNT_SPLITMV] &&
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
542 !((near_mv[1+EDGE_TOP].x ^ near_mv[1+EDGE_TOPLEFT].x) |
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
543 (near_mv[1+EDGE_TOP].y ^ near_mv[1+EDGE_TOPLEFT].y)))
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
544 cnt[CNT_NEAREST] += 1;
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
545
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
546 cnt[CNT_SPLITMV] = ((mb_edge[EDGE_LEFT]->mode == VP8_MVMODE_SPLIT) +
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
547 (mb_edge[EDGE_TOP]->mode == VP8_MVMODE_SPLIT)) * 2 +
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
548 (mb_edge[EDGE_TOPLEFT]->mode == VP8_MVMODE_SPLIT);
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
549
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
550 /* Swap near and nearest if necessary */
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
551 if (cnt[CNT_NEAR] > cnt[CNT_NEAREST]) {
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
552 FFSWAP(int, cnt[CNT_NEAREST], cnt[CNT_NEAR]);
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
553 FFSWAP(VP56mv, near_mv[CNT_NEAREST], near_mv[CNT_NEAR]);
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
554 }
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
555
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
556 /* Choose the best mv out of 0,0 and the nearest mv */
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
557 if (cnt[CNT_NEAREST] >= cnt[CNT_ZERO])
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
558 best_idx = CNT_NEAREST;
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
559
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
560 clamp_mv(s, best, &near_mv[best_idx], mb_x, mb_y);
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
561 near[0] = near_mv[CNT_NEAREST];
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
562 near[1] = near_mv[CNT_NEAR];
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
563 }
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
564
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
565 /**
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
566 * Motion vector coding, 17.1.
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
567 */
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
568 static int read_mv_component(VP56RangeCoder *c, const uint8_t *p)
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
569 {
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
570 int x = 0;
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
571
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
572 if (vp56_rac_get_prob(c, p[0])) {
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
573 int i;
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
574
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
575 for (i = 0; i < 3; i++)
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
576 x += vp56_rac_get_prob(c, p[9 + i]) << i;
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
577 for (i = 9; i > 3; i--)
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
578 x += vp56_rac_get_prob(c, p[9 + i]) << i;
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
579 if (!(x & 0xFFF0) || vp56_rac_get_prob(c, p[12]))
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
580 x += 8;
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
581 } else
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
582 x = vp8_rac_get_tree(c, vp8_small_mvtree, &p[2]);
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
583
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
584 return (x && vp56_rac_get_prob(c, p[1])) ? -x : x;
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
585 }
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
586
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
587 static const uint8_t *get_submv_prob(const VP56mv *left, const VP56mv *top)
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
588 {
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
589 int l_is_zero = !(left->x | left->y);
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
590 int t_is_zero = !(top->x | top->y);
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
591 int equal = !((left->x ^ top->x) | (left->y ^ top->y));
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
592
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
593 if (equal)
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
594 return l_is_zero ? vp8_submv_prob[4] : vp8_submv_prob[3];
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
595 if (t_is_zero)
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
596 return vp8_submv_prob[2];
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
597 return l_is_zero ? vp8_submv_prob[1] : vp8_submv_prob[0];
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
598 }
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
599
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
600 /**
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
601 * Split motion vector prediction, 16.4.
11990
3c51d7ac41c9 Simplify MV parsing, removes laying out 2 or 4 (16x8/8x8/8x16) MVs over all
rbultje
parents: 11989
diff changeset
602 * @returns the number of motion vectors parsed (2, 4 or 16)
11921
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
603 */
11990
3c51d7ac41c9 Simplify MV parsing, removes laying out 2 or 4 (16x8/8x8/8x16) MVs over all
rbultje
parents: 11989
diff changeset
604 static int decode_splitmvs(VP8Context *s, VP56RangeCoder *c,
11921
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
605 VP8Macroblock *mb, VP56mv *base_mv)
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
606 {
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
607 int part_idx = mb->partitioning =
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
608 vp8_rac_get_tree(c, vp8_mbsplit_tree, vp8_mbsplit_prob);
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
609 int n, num = vp8_mbsplit_count[part_idx];
11990
3c51d7ac41c9 Simplify MV parsing, removes laying out 2 or 4 (16x8/8x8/8x16) MVs over all
rbultje
parents: 11989
diff changeset
610 const uint8_t *mbsplits = vp8_mbsplits[part_idx],
3c51d7ac41c9 Simplify MV parsing, removes laying out 2 or 4 (16x8/8x8/8x16) MVs over all
rbultje
parents: 11989
diff changeset
611 *firstidx = vp8_mbfirstidx[part_idx];
11921
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
612
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
613 for (n = 0; n < num; n++) {
11990
3c51d7ac41c9 Simplify MV parsing, removes laying out 2 or 4 (16x8/8x8/8x16) MVs over all
rbultje
parents: 11989
diff changeset
614 int k = firstidx[n];
3c51d7ac41c9 Simplify MV parsing, removes laying out 2 or 4 (16x8/8x8/8x16) MVs over all
rbultje
parents: 11989
diff changeset
615 const VP56mv *left, *above;
3c51d7ac41c9 Simplify MV parsing, removes laying out 2 or 4 (16x8/8x8/8x16) MVs over all
rbultje
parents: 11989
diff changeset
616 const uint8_t *submv_prob;
3c51d7ac41c9 Simplify MV parsing, removes laying out 2 or 4 (16x8/8x8/8x16) MVs over all
rbultje
parents: 11989
diff changeset
617
3c51d7ac41c9 Simplify MV parsing, removes laying out 2 or 4 (16x8/8x8/8x16) MVs over all
rbultje
parents: 11989
diff changeset
618 if (!(k & 3)) {
3c51d7ac41c9 Simplify MV parsing, removes laying out 2 or 4 (16x8/8x8/8x16) MVs over all
rbultje
parents: 11989
diff changeset
619 VP8Macroblock *left_mb = &mb[-1];
3c51d7ac41c9 Simplify MV parsing, removes laying out 2 or 4 (16x8/8x8/8x16) MVs over all
rbultje
parents: 11989
diff changeset
620 left = &left_mb->bmv[vp8_mbsplits[left_mb->partitioning][k + 3]];
3c51d7ac41c9 Simplify MV parsing, removes laying out 2 or 4 (16x8/8x8/8x16) MVs over all
rbultje
parents: 11989
diff changeset
621 } else
3c51d7ac41c9 Simplify MV parsing, removes laying out 2 or 4 (16x8/8x8/8x16) MVs over all
rbultje
parents: 11989
diff changeset
622 left = &mb->bmv[mbsplits[k - 1]];
3c51d7ac41c9 Simplify MV parsing, removes laying out 2 or 4 (16x8/8x8/8x16) MVs over all
rbultje
parents: 11989
diff changeset
623 if (k <= 3) {
3c51d7ac41c9 Simplify MV parsing, removes laying out 2 or 4 (16x8/8x8/8x16) MVs over all
rbultje
parents: 11989
diff changeset
624 VP8Macroblock *above_mb = &mb[-s->mb_stride];
3c51d7ac41c9 Simplify MV parsing, removes laying out 2 or 4 (16x8/8x8/8x16) MVs over all
rbultje
parents: 11989
diff changeset
625 above = &above_mb->bmv[vp8_mbsplits[above_mb->partitioning][k + 12]];
3c51d7ac41c9 Simplify MV parsing, removes laying out 2 or 4 (16x8/8x8/8x16) MVs over all
rbultje
parents: 11989
diff changeset
626 } else
3c51d7ac41c9 Simplify MV parsing, removes laying out 2 or 4 (16x8/8x8/8x16) MVs over all
rbultje
parents: 11989
diff changeset
627 above = &mb->bmv[mbsplits[k - 4]];
3c51d7ac41c9 Simplify MV parsing, removes laying out 2 or 4 (16x8/8x8/8x16) MVs over all
rbultje
parents: 11989
diff changeset
628
3c51d7ac41c9 Simplify MV parsing, removes laying out 2 or 4 (16x8/8x8/8x16) MVs over all
rbultje
parents: 11989
diff changeset
629 submv_prob = get_submv_prob(left, above);
11921
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
630
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
631 switch (vp8_rac_get_tree(c, vp8_submv_ref_tree, submv_prob)) {
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
632 case VP8_SUBMVMODE_NEW4X4:
11990
3c51d7ac41c9 Simplify MV parsing, removes laying out 2 or 4 (16x8/8x8/8x16) MVs over all
rbultje
parents: 11989
diff changeset
633 mb->bmv[n].y = base_mv->y + read_mv_component(c, s->prob->mvc[0]);
3c51d7ac41c9 Simplify MV parsing, removes laying out 2 or 4 (16x8/8x8/8x16) MVs over all
rbultje
parents: 11989
diff changeset
634 mb->bmv[n].x = base_mv->x + read_mv_component(c, s->prob->mvc[1]);
11921
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
635 break;
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
636 case VP8_SUBMVMODE_ZERO4X4:
11990
3c51d7ac41c9 Simplify MV parsing, removes laying out 2 or 4 (16x8/8x8/8x16) MVs over all
rbultje
parents: 11989
diff changeset
637 mb->bmv[n].x = 0;
3c51d7ac41c9 Simplify MV parsing, removes laying out 2 or 4 (16x8/8x8/8x16) MVs over all
rbultje
parents: 11989
diff changeset
638 mb->bmv[n].y = 0;
11921
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
639 break;
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
640 case VP8_SUBMVMODE_LEFT4X4:
11990
3c51d7ac41c9 Simplify MV parsing, removes laying out 2 or 4 (16x8/8x8/8x16) MVs over all
rbultje
parents: 11989
diff changeset
641 mb->bmv[n] = *left;
11921
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
642 break;
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
643 case VP8_SUBMVMODE_TOP4X4:
11990
3c51d7ac41c9 Simplify MV parsing, removes laying out 2 or 4 (16x8/8x8/8x16) MVs over all
rbultje
parents: 11989
diff changeset
644 mb->bmv[n] = *above;
11921
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
645 break;
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
646 }
11990
3c51d7ac41c9 Simplify MV parsing, removes laying out 2 or 4 (16x8/8x8/8x16) MVs over all
rbultje
parents: 11989
diff changeset
647 }
11921
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
648
11990
3c51d7ac41c9 Simplify MV parsing, removes laying out 2 or 4 (16x8/8x8/8x16) MVs over all
rbultje
parents: 11989
diff changeset
649 return num;
11921
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
650 }
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
651
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
652 static inline void decode_intra4x4_modes(VP56RangeCoder *c, uint8_t *intra4x4,
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
653 int stride, int keyframe)
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
654 {
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
655 int x, y, t, l;
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
656 const uint8_t *ctx = vp8_pred4x4_prob_inter;
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
657
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
658 for (y = 0; y < 4; y++) {
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
659 for (x = 0; x < 4; x++) {
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
660 if (keyframe) {
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
661 t = intra4x4[x - stride];
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
662 l = intra4x4[x - 1];
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
663 ctx = vp8_pred4x4_prob_intra[t][l];
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
664 }
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
665 intra4x4[x] = vp8_rac_get_tree(c, vp8_pred4x4_tree, ctx);
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
666 }
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
667 intra4x4 += stride;
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
668 }
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
669 }
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
670
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
671 static void decode_mb_mode(VP8Context *s, VP8Macroblock *mb, int mb_x, int mb_y,
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
672 uint8_t *intra4x4)
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
673 {
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
674 VP56RangeCoder *c = &s->c;
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
675 int n;
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
676
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
677 if (s->segmentation.update_map)
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
678 mb->segment = vp8_rac_get_tree(c, vp8_segmentid_tree, s->prob->segmentid);
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
679
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
680 mb->skip = s->mbskip_enabled ? vp56_rac_get_prob(c, s->prob->mbskip) : 0;
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
681
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
682 if (s->keyframe) {
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
683 mb->mode = vp8_rac_get_tree(c, vp8_pred16x16_tree_intra, vp8_pred16x16_prob_intra);
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
684
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
685 if (mb->mode == MODE_I4x4) {
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
686 decode_intra4x4_modes(c, intra4x4, s->b4_stride, 1);
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
687 } else
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
688 fill_rectangle(intra4x4, 4, 4, s->b4_stride, vp8_pred4x4_mode[mb->mode], 1);
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
689
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
690 s->chroma_pred_mode = vp8_rac_get_tree(c, vp8_pred8x8c_tree, vp8_pred8x8c_prob_intra);
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
691 mb->ref_frame = VP56_FRAME_CURRENT;
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
692 } else if (vp56_rac_get_prob(c, s->prob->intra)) {
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
693 VP56mv near[2], best;
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
694 int cnt[4] = { 0 };
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
695 uint8_t p[4];
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
696
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
697 // inter MB, 16.2
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
698 if (vp56_rac_get_prob(c, s->prob->last))
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
699 mb->ref_frame = vp56_rac_get_prob(c, s->prob->golden) ?
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
700 VP56_FRAME_GOLDEN2 /* altref */ : VP56_FRAME_GOLDEN;
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
701 else
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
702 mb->ref_frame = VP56_FRAME_PREVIOUS;
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
703
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
704 // motion vectors, 16.3
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
705 find_near_mvs(s, mb, mb_x, mb_y, near, &best, cnt);
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
706 for (n = 0; n < 4; n++)
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
707 p[n] = vp8_mode_contexts[cnt[n]][n];
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
708 mb->mode = vp8_rac_get_tree(c, vp8_pred16x16_tree_mvinter, p);
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
709 switch (mb->mode) {
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
710 case VP8_MVMODE_SPLIT:
11990
3c51d7ac41c9 Simplify MV parsing, removes laying out 2 or 4 (16x8/8x8/8x16) MVs over all
rbultje
parents: 11989
diff changeset
711 mb->mv = mb->bmv[decode_splitmvs(s, c, mb, &best) - 1];
11921
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
712 break;
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
713 case VP8_MVMODE_ZERO:
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
714 mb->mv.x = 0;
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
715 mb->mv.y = 0;
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
716 break;
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
717 case VP8_MVMODE_NEAREST:
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
718 clamp_mv(s, &mb->mv, &near[0], mb_x, mb_y);
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
719 break;
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
720 case VP8_MVMODE_NEAR:
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
721 clamp_mv(s, &mb->mv, &near[1], mb_x, mb_y);
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
722 break;
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
723 case VP8_MVMODE_NEW:
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
724 mb->mv.y = best.y + read_mv_component(c, s->prob->mvc[0]);
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
725 mb->mv.x = best.x + read_mv_component(c, s->prob->mvc[1]);
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
726 break;
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
727 }
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
728 if (mb->mode != VP8_MVMODE_SPLIT) {
11990
3c51d7ac41c9 Simplify MV parsing, removes laying out 2 or 4 (16x8/8x8/8x16) MVs over all
rbultje
parents: 11989
diff changeset
729 mb->partitioning = VP8_SPLITMVMODE_NONE;
3c51d7ac41c9 Simplify MV parsing, removes laying out 2 or 4 (16x8/8x8/8x16) MVs over all
rbultje
parents: 11989
diff changeset
730 mb->bmv[0] = mb->mv;
11921
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
731 }
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
732 } else {
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
733 // intra MB, 16.1
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
734 mb->mode = vp8_rac_get_tree(c, vp8_pred16x16_tree_inter, s->prob->pred16x16);
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
735
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
736 if (mb->mode == MODE_I4x4) {
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
737 decode_intra4x4_modes(c, intra4x4, s->b4_stride, 0);
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
738 } else
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
739 fill_rectangle(intra4x4, 4, 4, s->b4_stride, vp8_pred4x4_mode[mb->mode], 1);
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
740
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
741 s->chroma_pred_mode = vp8_rac_get_tree(c, vp8_pred8x8c_tree, s->prob->pred8x8c);
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
742 mb->ref_frame = VP56_FRAME_CURRENT;
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
743 }
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
744 }
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
745
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
746 /**
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
747 * @param i initial coeff index, 0 unless a separate DC block is coded
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
748 * @param zero_nhood the initial prediction context for number of surrounding
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
749 * all-zero blocks (only left/top, so 0-2)
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
750 * @param qmul[0] dc dequant factor
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
751 * @param qmul[1] ac dequant factor
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
752 * @return 0 if no coeffs were decoded
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
753 * otherwise, the index of the last coeff decoded plus one
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
754 */
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
755 static int decode_block_coeffs(VP56RangeCoder *c, DCTELEM block[16],
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
756 uint8_t probs[8][3][NUM_DCT_TOKENS-1],
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
757 int i, int zero_nhood, int16_t qmul[2])
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
758 {
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
759 int token, nonzero = 0;
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
760 int offset = 0;
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
761
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
762 for (; i < 16; i++) {
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
763 token = vp8_rac_get_tree_with_offset(c, vp8_coeff_tree, probs[vp8_coeff_band[i]][zero_nhood], offset);
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
764
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
765 if (token == DCT_EOB)
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
766 break;
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
767 else if (token >= DCT_CAT1) {
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
768 int cat = token-DCT_CAT1;
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
769 token = vp8_rac_get_coeff(c, vp8_dct_cat_prob[cat]);
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
770 token += vp8_dct_cat_offset[cat];
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
771 }
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
772
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
773 // after the first token, the non-zero prediction context becomes
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
774 // based on the last decoded coeff
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
775 if (!token) {
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
776 zero_nhood = 0;
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
777 offset = 1;
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
778 continue;
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
779 } else if (token == 1)
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
780 zero_nhood = 1;
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
781 else
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
782 zero_nhood = 2;
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
783
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
784 // todo: full [16] qmat? load into register?
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
785 block[zigzag_scan[i]] = (vp8_rac_get(c) ? -token : token) * qmul[!!i];
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
786 nonzero = i+1;
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
787 offset = 0;
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
788 }
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
789 return nonzero;
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
790 }
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
791
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
792 static void decode_mb_coeffs(VP8Context *s, VP56RangeCoder *c, VP8Macroblock *mb,
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
793 uint8_t t_nnz[9], uint8_t l_nnz[9])
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
794 {
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
795 LOCAL_ALIGNED_16(DCTELEM, dc,[16]);
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
796 int i, x, y, luma_start = 0, luma_ctx = 3;
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
797 int nnz_pred, nnz, nnz_total = 0;
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
798 int segment = s->segmentation.enabled ? mb->segment : 0;
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
799
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
800 s->dsp.clear_blocks((DCTELEM *)s->block);
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
801
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
802 if (mb->mode != MODE_I4x4 && mb->mode != VP8_MVMODE_SPLIT) {
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
803 AV_ZERO128(dc);
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
804 AV_ZERO128(dc+8);
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
805 nnz_pred = t_nnz[8] + l_nnz[8];
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
806
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
807 // decode DC values and do hadamard
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
808 nnz = decode_block_coeffs(c, dc, s->prob->token[1], 0, nnz_pred,
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
809 s->qmat[segment].luma_dc_qmul);
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
810 l_nnz[8] = t_nnz[8] = !!nnz;
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
811 nnz_total += nnz;
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
812 s->vp8dsp.vp8_luma_dc_wht(s->block, dc);
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
813 luma_start = 1;
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
814 luma_ctx = 0;
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
815 }
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
816
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
817 // luma blocks
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
818 for (y = 0; y < 4; y++)
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
819 for (x = 0; x < 4; x++) {
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
820 nnz_pred = l_nnz[y] + t_nnz[x];
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
821 nnz = decode_block_coeffs(c, s->block[y][x], s->prob->token[luma_ctx], luma_start,
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
822 nnz_pred, s->qmat[segment].luma_qmul);
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
823 // nnz+luma_start may be one more than the actual last index, but we don't care
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
824 s->non_zero_count_cache[y][x] = nnz + luma_start;
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
825 t_nnz[x] = l_nnz[y] = !!nnz;
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
826 nnz_total += nnz;
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
827 }
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
828
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
829 // chroma blocks
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
830 // TODO: what to do about dimensions? 2nd dim for luma is x,
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
831 // but for chroma it's (y<<1)|x
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
832 for (i = 4; i < 6; i++)
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
833 for (y = 0; y < 2; y++)
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
834 for (x = 0; x < 2; x++) {
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
835 nnz_pred = l_nnz[i+2*y] + t_nnz[i+2*x];
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
836 nnz = decode_block_coeffs(c, s->block[i][(y<<1)+x], s->prob->token[2], 0,
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
837 nnz_pred, s->qmat[segment].chroma_qmul);
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
838 s->non_zero_count_cache[i][(y<<1)+x] = nnz;
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
839 t_nnz[i+2*x] = l_nnz[i+2*y] = !!nnz;
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
840 nnz_total += nnz;
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
841 }
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
842
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
843 // if there were no coded coeffs despite the macroblock not being marked skip,
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
844 // we MUST not do the inner loop filter and should not do IDCT
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
845 // Since skip isn't used for bitstream prediction, just manually set it.
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
846 if (!nnz_total)
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
847 mb->skip = 1;
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
848 }
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
849
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
850 static int check_intra_pred_mode(int mode, int mb_x, int mb_y)
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
851 {
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
852 if (mode == DC_PRED8x8) {
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
853 if (!(mb_x|mb_y))
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
854 mode = DC_128_PRED8x8;
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
855 else if (!mb_y)
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
856 mode = LEFT_DC_PRED8x8;
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
857 else if (!mb_x)
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
858 mode = TOP_DC_PRED8x8;
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
859 }
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
860 return mode;
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
861 }
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
862
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
863 static void intra_predict(VP8Context *s, uint8_t *dst[3], VP8Macroblock *mb,
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
864 uint8_t *bmode, int mb_x, int mb_y)
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
865 {
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
866 int x, y, mode, nnz, tr;
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
867
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
868 if (mb->mode < MODE_I4x4) {
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
869 mode = check_intra_pred_mode(mb->mode, mb_x, mb_y);
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
870 s->hpc.pred16x16[mode](dst[0], s->linesize);
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
871 } else {
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
872 uint8_t *ptr = dst[0];
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
873
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
874 // all blocks on the right edge of the macroblock use bottom edge
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
875 // the top macroblock for their topright edge
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
876 uint8_t *tr_right = ptr - s->linesize + 16;
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
877
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
878 // if we're on the right edge of the frame, said edge is extended
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
879 // from the top macroblock
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
880 if (mb_x == s->mb_width-1) {
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
881 tr = tr_right[-1]*0x01010101;
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
882 tr_right = (uint8_t *)&tr;
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
883 }
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
884
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
885 for (y = 0; y < 4; y++) {
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
886 uint8_t *topright = ptr + 4 - s->linesize;
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
887 for (x = 0; x < 4; x++) {
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
888 if (x == 3)
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
889 topright = tr_right;
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
890
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
891 s->hpc.pred4x4[bmode[x]](ptr+4*x, topright, s->linesize);
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
892
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
893 nnz = s->non_zero_count_cache[y][x];
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
894 if (nnz) {
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
895 if (nnz == 1)
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
896 s->vp8dsp.vp8_idct_dc_add(ptr+4*x, s->block[y][x], s->linesize);
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
897 else
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
898 s->vp8dsp.vp8_idct_add(ptr+4*x, s->block[y][x], s->linesize);
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
899 }
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
900 topright += 4;
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
901 }
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
902
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
903 ptr += 4*s->linesize;
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
904 bmode += s->b4_stride;
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
905 }
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
906 }
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
907
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
908 mode = check_intra_pred_mode(s->chroma_pred_mode, mb_x, mb_y);
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
909 s->hpc.pred8x8[mode](dst[1], s->uvlinesize);
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
910 s->hpc.pred8x8[mode](dst[2], s->uvlinesize);
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
911 }
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
912
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
913 /**
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
914 * Generic MC function.
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
915 *
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
916 * @param s VP8 decoding context
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
917 * @param luma 1 for luma (Y) planes, 0 for chroma (Cb/Cr) planes
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
918 * @param dst target buffer for block data at block position
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
919 * @param src reference picture buffer at origin (0, 0)
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
920 * @param mv motion vector (relative to block position) to get pixel data from
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
921 * @param x_off horizontal position of block from origin (0, 0)
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
922 * @param y_off vertical position of block from origin (0, 0)
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
923 * @param block_w width of block (16, 8 or 4)
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
924 * @param block_h height of block (always same as block_w)
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
925 * @param width width of src/dst plane data
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
926 * @param height height of src/dst plane data
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
927 * @param linesize size of a single line of plane data, including padding
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
928 */
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
929 static inline void vp8_mc(VP8Context *s, int luma,
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
930 uint8_t *dst, uint8_t *src, const VP56mv *mv,
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
931 int x_off, int y_off, int block_w, int block_h,
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
932 int width, int height, int linesize,
11950
56aba5a9761c Make VP8 DSP functions take two strides
darkshikari
parents: 11947
diff changeset
933 vp8_mc_func mc_func[3][3])
11921
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
934 {
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
935 static const uint8_t idx[8] = { 0, 1, 2, 1, 2, 1, 2, 1 };
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
936 int mx = (mv->x << luma)&7, mx_idx = idx[mx];
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
937 int my = (mv->y << luma)&7, my_idx = idx[my];
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
938
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
939 x_off += mv->x >> (3 - luma);
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
940 y_off += mv->y >> (3 - luma);
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
941
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
942 // edge emulation
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
943 src += y_off * linesize + x_off;
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
944 if (x_off < 2 || x_off >= width - block_w - 3 ||
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
945 y_off < 2 || y_off >= height - block_h - 3) {
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
946 ff_emulated_edge_mc(s->edge_emu_buffer, src - 2 * linesize - 2, linesize,
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
947 block_w + 5, block_h + 5,
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
948 x_off - 2, y_off - 2, width, height);
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
949 src = s->edge_emu_buffer + 2 + linesize * 2;
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
950 }
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
951
11950
56aba5a9761c Make VP8 DSP functions take two strides
darkshikari
parents: 11947
diff changeset
952 mc_func[my_idx][mx_idx](dst, linesize, src, linesize, block_h, mx, my);
11921
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
953 }
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
954
11989
176c5deb6756 Optimize split MC, so we don't always do 4x4 blocks of 4x4pixels each, but
rbultje
parents: 11974
diff changeset
955 static inline void vp8_mc_part(VP8Context *s, uint8_t *dst[3],
176c5deb6756 Optimize split MC, so we don't always do 4x4 blocks of 4x4pixels each, but
rbultje
parents: 11974
diff changeset
956 AVFrame *ref_frame, int x_off, int y_off,
176c5deb6756 Optimize split MC, so we don't always do 4x4 blocks of 4x4pixels each, but
rbultje
parents: 11974
diff changeset
957 int bx_off, int by_off,
176c5deb6756 Optimize split MC, so we don't always do 4x4 blocks of 4x4pixels each, but
rbultje
parents: 11974
diff changeset
958 int block_w, int block_h,
176c5deb6756 Optimize split MC, so we don't always do 4x4 blocks of 4x4pixels each, but
rbultje
parents: 11974
diff changeset
959 int width, int height, VP56mv *mv)
176c5deb6756 Optimize split MC, so we don't always do 4x4 blocks of 4x4pixels each, but
rbultje
parents: 11974
diff changeset
960 {
176c5deb6756 Optimize split MC, so we don't always do 4x4 blocks of 4x4pixels each, but
rbultje
parents: 11974
diff changeset
961 VP56mv uvmv = *mv;
176c5deb6756 Optimize split MC, so we don't always do 4x4 blocks of 4x4pixels each, but
rbultje
parents: 11974
diff changeset
962
176c5deb6756 Optimize split MC, so we don't always do 4x4 blocks of 4x4pixels each, but
rbultje
parents: 11974
diff changeset
963 /* Y */
176c5deb6756 Optimize split MC, so we don't always do 4x4 blocks of 4x4pixels each, but
rbultje
parents: 11974
diff changeset
964 vp8_mc(s, 1, dst[0] + by_off * s->linesize + bx_off,
176c5deb6756 Optimize split MC, so we don't always do 4x4 blocks of 4x4pixels each, but
rbultje
parents: 11974
diff changeset
965 ref_frame->data[0], mv, x_off + bx_off, y_off + by_off,
176c5deb6756 Optimize split MC, so we don't always do 4x4 blocks of 4x4pixels each, but
rbultje
parents: 11974
diff changeset
966 block_w, block_h, width, height, s->linesize,
176c5deb6756 Optimize split MC, so we don't always do 4x4 blocks of 4x4pixels each, but
rbultje
parents: 11974
diff changeset
967 s->put_pixels_tab[block_w == 8]);
176c5deb6756 Optimize split MC, so we don't always do 4x4 blocks of 4x4pixels each, but
rbultje
parents: 11974
diff changeset
968
176c5deb6756 Optimize split MC, so we don't always do 4x4 blocks of 4x4pixels each, but
rbultje
parents: 11974
diff changeset
969 /* U/V */
176c5deb6756 Optimize split MC, so we don't always do 4x4 blocks of 4x4pixels each, but
rbultje
parents: 11974
diff changeset
970 if (s->profile == 3) {
176c5deb6756 Optimize split MC, so we don't always do 4x4 blocks of 4x4pixels each, but
rbultje
parents: 11974
diff changeset
971 uvmv.x &= ~7;
176c5deb6756 Optimize split MC, so we don't always do 4x4 blocks of 4x4pixels each, but
rbultje
parents: 11974
diff changeset
972 uvmv.y &= ~7;
176c5deb6756 Optimize split MC, so we don't always do 4x4 blocks of 4x4pixels each, but
rbultje
parents: 11974
diff changeset
973 }
176c5deb6756 Optimize split MC, so we don't always do 4x4 blocks of 4x4pixels each, but
rbultje
parents: 11974
diff changeset
974 x_off >>= 1; y_off >>= 1;
176c5deb6756 Optimize split MC, so we don't always do 4x4 blocks of 4x4pixels each, but
rbultje
parents: 11974
diff changeset
975 bx_off >>= 1; by_off >>= 1;
176c5deb6756 Optimize split MC, so we don't always do 4x4 blocks of 4x4pixels each, but
rbultje
parents: 11974
diff changeset
976 width >>= 1; height >>= 1;
176c5deb6756 Optimize split MC, so we don't always do 4x4 blocks of 4x4pixels each, but
rbultje
parents: 11974
diff changeset
977 block_w >>= 1; block_h >>= 1;
176c5deb6756 Optimize split MC, so we don't always do 4x4 blocks of 4x4pixels each, but
rbultje
parents: 11974
diff changeset
978 vp8_mc(s, 0, dst[1] + by_off * s->uvlinesize + bx_off,
176c5deb6756 Optimize split MC, so we don't always do 4x4 blocks of 4x4pixels each, but
rbultje
parents: 11974
diff changeset
979 ref_frame->data[1], &uvmv, x_off + bx_off, y_off + by_off,
176c5deb6756 Optimize split MC, so we don't always do 4x4 blocks of 4x4pixels each, but
rbultje
parents: 11974
diff changeset
980 block_w, block_h, width, height, s->uvlinesize,
176c5deb6756 Optimize split MC, so we don't always do 4x4 blocks of 4x4pixels each, but
rbultje
parents: 11974
diff changeset
981 s->put_pixels_tab[1 + (block_w == 4)]);
176c5deb6756 Optimize split MC, so we don't always do 4x4 blocks of 4x4pixels each, but
rbultje
parents: 11974
diff changeset
982 vp8_mc(s, 0, dst[2] + by_off * s->uvlinesize + bx_off,
176c5deb6756 Optimize split MC, so we don't always do 4x4 blocks of 4x4pixels each, but
rbultje
parents: 11974
diff changeset
983 ref_frame->data[2], &uvmv, x_off + bx_off, y_off + by_off,
176c5deb6756 Optimize split MC, so we don't always do 4x4 blocks of 4x4pixels each, but
rbultje
parents: 11974
diff changeset
984 block_w, block_h, width, height, s->uvlinesize,
176c5deb6756 Optimize split MC, so we don't always do 4x4 blocks of 4x4pixels each, but
rbultje
parents: 11974
diff changeset
985 s->put_pixels_tab[1 + (block_w == 4)]);
176c5deb6756 Optimize split MC, so we don't always do 4x4 blocks of 4x4pixels each, but
rbultje
parents: 11974
diff changeset
986 }
176c5deb6756 Optimize split MC, so we don't always do 4x4 blocks of 4x4pixels each, but
rbultje
parents: 11974
diff changeset
987
11921
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
988 /**
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
989 * Apply motion vectors to prediction buffer, chapter 18.
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
990 */
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
991 static void inter_predict(VP8Context *s, uint8_t *dst[3], VP8Macroblock *mb,
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
992 int mb_x, int mb_y)
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
993 {
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
994 int x_off = mb_x << 4, y_off = mb_y << 4;
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
995 int width = 16*s->mb_width, height = 16*s->mb_height;
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
996
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
997 if (mb->mode < VP8_MVMODE_SPLIT) {
11989
176c5deb6756 Optimize split MC, so we don't always do 4x4 blocks of 4x4pixels each, but
rbultje
parents: 11974
diff changeset
998 vp8_mc_part(s, dst, s->framep[mb->ref_frame], x_off, y_off,
176c5deb6756 Optimize split MC, so we don't always do 4x4 blocks of 4x4pixels each, but
rbultje
parents: 11974
diff changeset
999 0, 0, 16, 16, width, height, &mb->mv);
176c5deb6756 Optimize split MC, so we don't always do 4x4 blocks of 4x4pixels each, but
rbultje
parents: 11974
diff changeset
1000 } else switch (mb->partitioning) {
176c5deb6756 Optimize split MC, so we don't always do 4x4 blocks of 4x4pixels each, but
rbultje
parents: 11974
diff changeset
1001 case VP8_SPLITMVMODE_4x4: {
11921
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1002 int x, y;
11989
176c5deb6756 Optimize split MC, so we don't always do 4x4 blocks of 4x4pixels each, but
rbultje
parents: 11974
diff changeset
1003 VP56mv uvmv;
11921
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1004
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1005 /* Y */
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1006 for (y = 0; y < 4; y++) {
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1007 for (x = 0; x < 4; x++) {
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1008 vp8_mc(s, 1, dst[0] + 4*y*s->linesize + x*4,
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1009 s->framep[mb->ref_frame]->data[0], &mb->bmv[4*y + x],
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1010 4*x + x_off, 4*y + y_off, 4, 4,
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1011 width, height, s->linesize,
11974
356b20a6566d VP8 bilinear filter
conrad
parents: 11970
diff changeset
1012 s->put_pixels_tab[2]);
11921
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1013 }
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1014 }
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1015
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1016 /* U/V */
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1017 x_off >>= 1; y_off >>= 1; width >>= 1; height >>= 1;
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1018 for (y = 0; y < 2; y++) {
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1019 for (x = 0; x < 2; x++) {
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1020 uvmv.x = mb->bmv[ 2*y * 4 + 2*x ].x +
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1021 mb->bmv[ 2*y * 4 + 2*x+1].x +
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1022 mb->bmv[(2*y+1) * 4 + 2*x ].x +
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1023 mb->bmv[(2*y+1) * 4 + 2*x+1].x;
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1024 uvmv.y = mb->bmv[ 2*y * 4 + 2*x ].y +
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1025 mb->bmv[ 2*y * 4 + 2*x+1].y +
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1026 mb->bmv[(2*y+1) * 4 + 2*x ].y +
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1027 mb->bmv[(2*y+1) * 4 + 2*x+1].y;
11937
bc617cceacb1 avoid conditional and division in chroma MV calculation
stefang
parents: 11921
diff changeset
1028 uvmv.x = (uvmv.x + 2 + (uvmv.x >> (INT_BIT-1))) >> 2;
bc617cceacb1 avoid conditional and division in chroma MV calculation
stefang
parents: 11921
diff changeset
1029 uvmv.y = (uvmv.y + 2 + (uvmv.y >> (INT_BIT-1))) >> 2;
11921
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1030 if (s->profile == 3) {
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1031 uvmv.x &= ~7;
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1032 uvmv.y &= ~7;
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1033 }
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1034 vp8_mc(s, 0, dst[1] + 4*y*s->uvlinesize + x*4,
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1035 s->framep[mb->ref_frame]->data[1], &uvmv,
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1036 4*x + x_off, 4*y + y_off, 4, 4,
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1037 width, height, s->uvlinesize,
11974
356b20a6566d VP8 bilinear filter
conrad
parents: 11970
diff changeset
1038 s->put_pixels_tab[2]);
11921
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1039 vp8_mc(s, 0, dst[2] + 4*y*s->uvlinesize + x*4,
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1040 s->framep[mb->ref_frame]->data[2], &uvmv,
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1041 4*x + x_off, 4*y + y_off, 4, 4,
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1042 width, height, s->uvlinesize,
11974
356b20a6566d VP8 bilinear filter
conrad
parents: 11970
diff changeset
1043 s->put_pixels_tab[2]);
11921
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1044 }
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1045 }
11989
176c5deb6756 Optimize split MC, so we don't always do 4x4 blocks of 4x4pixels each, but
rbultje
parents: 11974
diff changeset
1046 break;
176c5deb6756 Optimize split MC, so we don't always do 4x4 blocks of 4x4pixels each, but
rbultje
parents: 11974
diff changeset
1047 }
176c5deb6756 Optimize split MC, so we don't always do 4x4 blocks of 4x4pixels each, but
rbultje
parents: 11974
diff changeset
1048 case VP8_SPLITMVMODE_16x8:
176c5deb6756 Optimize split MC, so we don't always do 4x4 blocks of 4x4pixels each, but
rbultje
parents: 11974
diff changeset
1049 vp8_mc_part(s, dst, s->framep[mb->ref_frame], x_off, y_off,
176c5deb6756 Optimize split MC, so we don't always do 4x4 blocks of 4x4pixels each, but
rbultje
parents: 11974
diff changeset
1050 0, 0, 16, 8, width, height, &mb->bmv[0]);
176c5deb6756 Optimize split MC, so we don't always do 4x4 blocks of 4x4pixels each, but
rbultje
parents: 11974
diff changeset
1051 vp8_mc_part(s, dst, s->framep[mb->ref_frame], x_off, y_off,
11990
3c51d7ac41c9 Simplify MV parsing, removes laying out 2 or 4 (16x8/8x8/8x16) MVs over all
rbultje
parents: 11989
diff changeset
1052 0, 8, 16, 8, width, height, &mb->bmv[1]);
11989
176c5deb6756 Optimize split MC, so we don't always do 4x4 blocks of 4x4pixels each, but
rbultje
parents: 11974
diff changeset
1053 break;
176c5deb6756 Optimize split MC, so we don't always do 4x4 blocks of 4x4pixels each, but
rbultje
parents: 11974
diff changeset
1054 case VP8_SPLITMVMODE_8x16:
176c5deb6756 Optimize split MC, so we don't always do 4x4 blocks of 4x4pixels each, but
rbultje
parents: 11974
diff changeset
1055 vp8_mc_part(s, dst, s->framep[mb->ref_frame], x_off, y_off,
176c5deb6756 Optimize split MC, so we don't always do 4x4 blocks of 4x4pixels each, but
rbultje
parents: 11974
diff changeset
1056 0, 0, 8, 16, width, height, &mb->bmv[0]);
176c5deb6756 Optimize split MC, so we don't always do 4x4 blocks of 4x4pixels each, but
rbultje
parents: 11974
diff changeset
1057 vp8_mc_part(s, dst, s->framep[mb->ref_frame], x_off, y_off,
11990
3c51d7ac41c9 Simplify MV parsing, removes laying out 2 or 4 (16x8/8x8/8x16) MVs over all
rbultje
parents: 11989
diff changeset
1058 8, 0, 8, 16, width, height, &mb->bmv[1]);
11989
176c5deb6756 Optimize split MC, so we don't always do 4x4 blocks of 4x4pixels each, but
rbultje
parents: 11974
diff changeset
1059 break;
176c5deb6756 Optimize split MC, so we don't always do 4x4 blocks of 4x4pixels each, but
rbultje
parents: 11974
diff changeset
1060 case VP8_SPLITMVMODE_8x8:
176c5deb6756 Optimize split MC, so we don't always do 4x4 blocks of 4x4pixels each, but
rbultje
parents: 11974
diff changeset
1061 vp8_mc_part(s, dst, s->framep[mb->ref_frame], x_off, y_off,
176c5deb6756 Optimize split MC, so we don't always do 4x4 blocks of 4x4pixels each, but
rbultje
parents: 11974
diff changeset
1062 0, 0, 8, 8, width, height, &mb->bmv[0]);
176c5deb6756 Optimize split MC, so we don't always do 4x4 blocks of 4x4pixels each, but
rbultje
parents: 11974
diff changeset
1063 vp8_mc_part(s, dst, s->framep[mb->ref_frame], x_off, y_off,
11990
3c51d7ac41c9 Simplify MV parsing, removes laying out 2 or 4 (16x8/8x8/8x16) MVs over all
rbultje
parents: 11989
diff changeset
1064 8, 0, 8, 8, width, height, &mb->bmv[1]);
11989
176c5deb6756 Optimize split MC, so we don't always do 4x4 blocks of 4x4pixels each, but
rbultje
parents: 11974
diff changeset
1065 vp8_mc_part(s, dst, s->framep[mb->ref_frame], x_off, y_off,
11990
3c51d7ac41c9 Simplify MV parsing, removes laying out 2 or 4 (16x8/8x8/8x16) MVs over all
rbultje
parents: 11989
diff changeset
1066 0, 8, 8, 8, width, height, &mb->bmv[2]);
11989
176c5deb6756 Optimize split MC, so we don't always do 4x4 blocks of 4x4pixels each, but
rbultje
parents: 11974
diff changeset
1067 vp8_mc_part(s, dst, s->framep[mb->ref_frame], x_off, y_off,
11990
3c51d7ac41c9 Simplify MV parsing, removes laying out 2 or 4 (16x8/8x8/8x16) MVs over all
rbultje
parents: 11989
diff changeset
1068 8, 8, 8, 8, width, height, &mb->bmv[3]);
11989
176c5deb6756 Optimize split MC, so we don't always do 4x4 blocks of 4x4pixels each, but
rbultje
parents: 11974
diff changeset
1069 break;
11921
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1070 }
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1071 }
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1072
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1073 static void idct_mb(VP8Context *s, uint8_t *y_dst, uint8_t *u_dst, uint8_t *v_dst,
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1074 VP8Macroblock *mb)
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1075 {
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1076 int x, y, nnz;
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1077
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1078 if (mb->mode != MODE_I4x4)
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1079 for (y = 0; y < 4; y++) {
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1080 for (x = 0; x < 4; x++) {
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1081 nnz = s->non_zero_count_cache[y][x];
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1082 if (nnz) {
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1083 if (nnz == 1)
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1084 s->vp8dsp.vp8_idct_dc_add(y_dst+4*x, s->block[y][x], s->linesize);
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1085 else
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1086 s->vp8dsp.vp8_idct_add(y_dst+4*x, s->block[y][x], s->linesize);
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1087 }
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1088 }
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1089 y_dst += 4*s->linesize;
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1090 }
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1091
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1092 for (y = 0; y < 2; y++) {
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1093 for (x = 0; x < 2; x++) {
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1094 nnz = s->non_zero_count_cache[4][(y<<1)+x];
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1095 if (nnz) {
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1096 if (nnz == 1)
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1097 s->vp8dsp.vp8_idct_dc_add(u_dst+4*x, s->block[4][(y<<1)+x], s->uvlinesize);
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1098 else
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1099 s->vp8dsp.vp8_idct_add(u_dst+4*x, s->block[4][(y<<1)+x], s->uvlinesize);
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1100 }
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1101
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1102 nnz = s->non_zero_count_cache[5][(y<<1)+x];
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1103 if (nnz) {
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1104 if (nnz == 1)
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1105 s->vp8dsp.vp8_idct_dc_add(v_dst+4*x, s->block[5][(y<<1)+x], s->uvlinesize);
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1106 else
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1107 s->vp8dsp.vp8_idct_add(v_dst+4*x, s->block[5][(y<<1)+x], s->uvlinesize);
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1108 }
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1109 }
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1110 u_dst += 4*s->uvlinesize;
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1111 v_dst += 4*s->uvlinesize;
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1112 }
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1113 }
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1114
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1115 static void filter_level_for_mb(VP8Context *s, VP8Macroblock *mb, int *level, int *inner, int *hev_thresh)
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1116 {
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1117 int interior_limit, filter_level;
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1118
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1119 if (s->segmentation.enabled) {
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1120 filter_level = s->segmentation.filter_level[mb->segment];
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1121 if (!s->segmentation.absolute_vals)
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1122 filter_level += s->filter.level;
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1123 } else
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1124 filter_level = s->filter.level;
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1125
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1126 if (s->lf_delta.enabled) {
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1127 filter_level += s->lf_delta.ref[mb->ref_frame];
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1128
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1129 if (mb->ref_frame == VP56_FRAME_CURRENT) {
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1130 if (mb->mode == MODE_I4x4)
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1131 filter_level += s->lf_delta.mode[0];
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1132 } else {
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1133 if (mb->mode == VP8_MVMODE_ZERO)
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1134 filter_level += s->lf_delta.mode[1];
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1135 else if (mb->mode == VP8_MVMODE_SPLIT)
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1136 filter_level += s->lf_delta.mode[3];
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1137 else
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1138 filter_level += s->lf_delta.mode[2];
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1139 }
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1140 }
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1141 filter_level = av_clip(filter_level, 0, 63);
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1142
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1143 interior_limit = filter_level;
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1144 if (s->filter.sharpness) {
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1145 interior_limit >>= s->filter.sharpness > 4 ? 2 : 1;
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1146 interior_limit = FFMIN(interior_limit, 9 - s->filter.sharpness);
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1147 }
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1148 interior_limit = FFMAX(interior_limit, 1);
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1149
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1150 *level = filter_level;
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1151 *inner = interior_limit;
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1152
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1153 if (hev_thresh) {
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1154 *hev_thresh = filter_level >= 15;
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1155
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1156 if (s->keyframe) {
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1157 if (filter_level >= 40)
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1158 *hev_thresh = 2;
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1159 } else {
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1160 if (filter_level >= 40)
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1161 *hev_thresh = 3;
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1162 else if (filter_level >= 20)
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1163 *hev_thresh = 2;
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1164 }
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1165 }
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1166 }
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1167
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1168 // TODO: look at backup_mb_border / xchg_mb_border in h264.c
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1169 static void filter_mb(VP8Context *s, uint8_t *dst[3], VP8Macroblock *mb, int mb_x, int mb_y)
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1170 {
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1171 int filter_level, inner_limit, hev_thresh;
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1172
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1173 filter_level_for_mb(s, mb, &filter_level, &inner_limit, &hev_thresh);
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1174 if (!filter_level)
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1175 return;
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1176
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1177 if (mb_x) {
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1178 s->vp8dsp.vp8_h_loop_filter16(dst[0], s->linesize, filter_level+2, inner_limit, hev_thresh);
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1179 s->vp8dsp.vp8_h_loop_filter8 (dst[1], s->uvlinesize, filter_level+2, inner_limit, hev_thresh);
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1180 s->vp8dsp.vp8_h_loop_filter8 (dst[2], s->uvlinesize, filter_level+2, inner_limit, hev_thresh);
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1181 }
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1182
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1183 if (!mb->skip || mb->mode == MODE_I4x4 || mb->mode == VP8_MVMODE_SPLIT) {
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1184 s->vp8dsp.vp8_h_loop_filter16_inner(dst[0]+ 4, s->linesize, filter_level, inner_limit, hev_thresh);
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1185 s->vp8dsp.vp8_h_loop_filter16_inner(dst[0]+ 8, s->linesize, filter_level, inner_limit, hev_thresh);
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1186 s->vp8dsp.vp8_h_loop_filter16_inner(dst[0]+12, s->linesize, filter_level, inner_limit, hev_thresh);
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1187 s->vp8dsp.vp8_h_loop_filter8_inner (dst[1]+ 4, s->uvlinesize, filter_level, inner_limit, hev_thresh);
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1188 s->vp8dsp.vp8_h_loop_filter8_inner (dst[2]+ 4, s->uvlinesize, filter_level, inner_limit, hev_thresh);
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1189 }
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1190
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1191 if (mb_y) {
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1192 s->vp8dsp.vp8_v_loop_filter16(dst[0], s->linesize, filter_level+2, inner_limit, hev_thresh);
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1193 s->vp8dsp.vp8_v_loop_filter8 (dst[1], s->uvlinesize, filter_level+2, inner_limit, hev_thresh);
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1194 s->vp8dsp.vp8_v_loop_filter8 (dst[2], s->uvlinesize, filter_level+2, inner_limit, hev_thresh);
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1195 }
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1196
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1197 if (!mb->skip || mb->mode == MODE_I4x4 || mb->mode == VP8_MVMODE_SPLIT) {
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1198 s->vp8dsp.vp8_v_loop_filter16_inner(dst[0]+ 4*s->linesize, s->linesize, filter_level, inner_limit, hev_thresh);
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1199 s->vp8dsp.vp8_v_loop_filter16_inner(dst[0]+ 8*s->linesize, s->linesize, filter_level, inner_limit, hev_thresh);
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1200 s->vp8dsp.vp8_v_loop_filter16_inner(dst[0]+12*s->linesize, s->linesize, filter_level, inner_limit, hev_thresh);
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1201 s->vp8dsp.vp8_v_loop_filter8_inner (dst[1]+ 4*s->uvlinesize, s->uvlinesize, filter_level, inner_limit, hev_thresh);
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1202 s->vp8dsp.vp8_v_loop_filter8_inner (dst[2]+ 4*s->uvlinesize, s->uvlinesize, filter_level, inner_limit, hev_thresh);
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1203 }
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1204 }
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1205
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1206 static void filter_mb_simple(VP8Context *s, uint8_t *dst, VP8Macroblock *mb, int mb_x, int mb_y)
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1207 {
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1208 int filter_level, inner_limit, mbedge_lim, bedge_lim;
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1209
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1210 filter_level_for_mb(s, mb, &filter_level, &inner_limit, NULL);
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1211 if (!filter_level)
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1212 return;
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1213
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1214 mbedge_lim = 2*(filter_level+2) + inner_limit;
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1215 bedge_lim = 2* filter_level + inner_limit;
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1216
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1217 if (mb_x)
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1218 s->vp8dsp.vp8_h_loop_filter_simple(dst, s->linesize, mbedge_lim);
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1219 if (!mb->skip || mb->mode == MODE_I4x4 || mb->mode == VP8_MVMODE_SPLIT) {
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1220 s->vp8dsp.vp8_h_loop_filter_simple(dst+ 4, s->linesize, bedge_lim);
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1221 s->vp8dsp.vp8_h_loop_filter_simple(dst+ 8, s->linesize, bedge_lim);
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1222 s->vp8dsp.vp8_h_loop_filter_simple(dst+12, s->linesize, bedge_lim);
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1223 }
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1224
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1225 if (mb_y)
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1226 s->vp8dsp.vp8_v_loop_filter_simple(dst, s->linesize, mbedge_lim);
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1227 if (!mb->skip || mb->mode == MODE_I4x4 || mb->mode == VP8_MVMODE_SPLIT) {
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1228 s->vp8dsp.vp8_v_loop_filter_simple(dst+ 4*s->linesize, s->linesize, bedge_lim);
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1229 s->vp8dsp.vp8_v_loop_filter_simple(dst+ 8*s->linesize, s->linesize, bedge_lim);
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1230 s->vp8dsp.vp8_v_loop_filter_simple(dst+12*s->linesize, s->linesize, bedge_lim);
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1231 }
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1232 }
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1233
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1234 static void filter_mb_row(VP8Context *s, int mb_y)
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1235 {
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1236 VP8Macroblock *mb = s->macroblocks + mb_y*s->mb_stride;
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1237 uint8_t *dst[3] = {
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1238 s->framep[VP56_FRAME_CURRENT]->data[0] + 16*mb_y*s->linesize,
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1239 s->framep[VP56_FRAME_CURRENT]->data[1] + 8*mb_y*s->uvlinesize,
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1240 s->framep[VP56_FRAME_CURRENT]->data[2] + 8*mb_y*s->uvlinesize
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1241 };
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1242 int mb_x;
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1243
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1244 for (mb_x = 0; mb_x < s->mb_width; mb_x++) {
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1245 filter_mb(s, dst, mb++, mb_x, mb_y);
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1246 dst[0] += 16;
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1247 dst[1] += 8;
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1248 dst[2] += 8;
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1249 }
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1250 }
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1251
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1252 static void filter_mb_row_simple(VP8Context *s, int mb_y)
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1253 {
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1254 uint8_t *dst = s->framep[VP56_FRAME_CURRENT]->data[0] + 16*mb_y*s->linesize;
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1255 VP8Macroblock *mb = s->macroblocks + mb_y*s->mb_stride;
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1256 int mb_x;
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1257
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1258 for (mb_x = 0; mb_x < s->mb_width; mb_x++) {
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1259 filter_mb_simple(s, dst, mb++, mb_x, mb_y);
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1260 dst += 16;
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1261 }
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1262 }
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1263
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1264 static int vp8_decode_frame(AVCodecContext *avctx, void *data, int *data_size,
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1265 AVPacket *avpkt)
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1266 {
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1267 VP8Context *s = avctx->priv_data;
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1268 int ret, mb_x, mb_y, i, y, referenced;
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1269 enum AVDiscard skip_thresh;
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1270 AVFrame *curframe;
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1271
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1272 if ((ret = decode_frame_header(s, avpkt->data, avpkt->size)) < 0)
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1273 return ret;
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1274
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1275 referenced = s->update_last || s->update_golden == VP56_FRAME_CURRENT
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1276 || s->update_altref == VP56_FRAME_CURRENT;
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1277
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1278 skip_thresh = !referenced ? AVDISCARD_NONREF :
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1279 !s->keyframe ? AVDISCARD_NONKEY : AVDISCARD_ALL;
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1280
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1281 if (avctx->skip_frame >= skip_thresh) {
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1282 s->invisible = 1;
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1283 goto skip_decode;
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1284 }
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1285
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1286 for (i = 0; i < 4; i++)
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1287 if (&s->frames[i] != s->framep[VP56_FRAME_PREVIOUS] &&
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1288 &s->frames[i] != s->framep[VP56_FRAME_GOLDEN] &&
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1289 &s->frames[i] != s->framep[VP56_FRAME_GOLDEN2]) {
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1290 curframe = s->framep[VP56_FRAME_CURRENT] = &s->frames[i];
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1291 break;
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1292 }
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1293 if (curframe->data[0])
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1294 avctx->release_buffer(avctx, curframe);
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1295
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1296 curframe->key_frame = s->keyframe;
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1297 curframe->pict_type = s->keyframe ? FF_I_TYPE : FF_P_TYPE;
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1298 curframe->reference = referenced ? 3 : 0;
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1299 if ((ret = avctx->get_buffer(avctx, curframe))) {
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1300 av_log(avctx, AV_LOG_ERROR, "get_buffer() failed!\n");
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1301 return ret;
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1302 }
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1303
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1304 // Given that arithmetic probabilities are updated every frame, it's quite likely
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1305 // that the values we have on a random interframe are complete junk if we didn't
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1306 // start decode on a keyframe. So just don't display anything rather than junk.
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1307 if (!s->keyframe && (!s->framep[VP56_FRAME_PREVIOUS] ||
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1308 !s->framep[VP56_FRAME_GOLDEN] ||
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1309 !s->framep[VP56_FRAME_GOLDEN2])) {
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1310 av_log(avctx, AV_LOG_WARNING, "Discarding interframe without a prior keyframe!\n");
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1311 return AVERROR_INVALIDDATA;
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1312 }
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1313
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1314 s->linesize = curframe->linesize[0];
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1315 s->uvlinesize = curframe->linesize[1];
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1316
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1317 if (!s->edge_emu_buffer)
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1318 s->edge_emu_buffer = av_malloc(21*s->linesize);
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1319
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1320 memset(s->top_nnz, 0, s->mb_width*sizeof(*s->top_nnz));
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1321
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1322 // top edge of 127 for intra prediction
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1323 if (!(avctx->flags & CODEC_FLAG_EMU_EDGE)) {
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1324 memset(curframe->data[0] - s->linesize -1, 127, s->linesize +1);
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1325 memset(curframe->data[1] - s->uvlinesize-1, 127, s->uvlinesize+1);
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1326 memset(curframe->data[2] - s->uvlinesize-1, 127, s->uvlinesize+1);
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1327 }
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1328
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1329 for (mb_y = 0; mb_y < s->mb_height; mb_y++) {
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1330 VP56RangeCoder *c = &s->coeff_partition[mb_y & (s->num_coeff_partitions-1)];
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1331 VP8Macroblock *mb = s->macroblocks + mb_y*s->mb_stride;
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1332 uint8_t *intra4x4 = s->intra4x4_pred_mode + 4*mb_y*s->b4_stride;
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1333 uint8_t *dst[3] = {
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1334 curframe->data[0] + 16*mb_y*s->linesize,
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1335 curframe->data[1] + 8*mb_y*s->uvlinesize,
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1336 curframe->data[2] + 8*mb_y*s->uvlinesize
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1337 };
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1338
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1339 memset(s->left_nnz, 0, sizeof(s->left_nnz));
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1340
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1341 // left edge of 129 for intra prediction
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1342 if (!(avctx->flags & CODEC_FLAG_EMU_EDGE))
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1343 for (i = 0; i < 3; i++)
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1344 for (y = 0; y < 16>>!!i; y++)
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1345 dst[i][y*curframe->linesize[i]-1] = 129;
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1346
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1347 for (mb_x = 0; mb_x < s->mb_width; mb_x++) {
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1348 decode_mb_mode(s, mb, mb_x, mb_y, intra4x4 + 4*mb_x);
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1349
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1350 if (!mb->skip)
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1351 decode_mb_coeffs(s, c, mb, s->top_nnz[mb_x], s->left_nnz);
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1352 else {
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1353 AV_ZERO128(s->non_zero_count_cache); // luma
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1354 AV_ZERO64(s->non_zero_count_cache[4]); // chroma
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1355 }
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1356
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1357 if (mb->mode <= MODE_I4x4) {
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1358 intra_predict(s, dst, mb, intra4x4 + 4*mb_x, mb_x, mb_y);
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1359 memset(mb->bmv, 0, sizeof(mb->bmv));
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1360 } else {
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1361 inter_predict(s, dst, mb, mb_x, mb_y);
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1362 }
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1363
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1364 if (!mb->skip) {
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1365 idct_mb(s, dst[0], dst[1], dst[2], mb);
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1366 } else {
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1367 AV_ZERO64(s->left_nnz);
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1368 AV_WN64(s->top_nnz[mb_x], 0); // array of 9, so unaligned
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1369
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1370 // Reset DC block predictors if they would exist if the mb had coefficients
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1371 if (mb->mode != MODE_I4x4 && mb->mode != VP8_MVMODE_SPLIT) {
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1372 s->left_nnz[8] = 0;
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1373 s->top_nnz[mb_x][8] = 0;
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1374 }
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1375 }
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1376
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1377 dst[0] += 16;
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1378 dst[1] += 8;
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1379 dst[2] += 8;
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1380 mb++;
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1381 }
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1382 if (mb_y && s->filter.level && avctx->skip_loop_filter < skip_thresh) {
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1383 if (s->filter.simple)
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1384 filter_mb_row_simple(s, mb_y-1);
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1385 else
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1386 filter_mb_row(s, mb_y-1);
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1387 }
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1388 }
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1389 if (s->filter.level && avctx->skip_loop_filter < skip_thresh) {
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1390 if (s->filter.simple)
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1391 filter_mb_row_simple(s, mb_y-1);
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1392 else
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1393 filter_mb_row(s, mb_y-1);
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1394 }
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1395
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1396 skip_decode:
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1397 // if future frames don't use the updated probabilities,
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1398 // reset them to the values we saved
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1399 if (!s->update_probabilities)
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1400 s->prob[0] = s->prob[1];
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1401
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1402 // check if golden and altref are swapped
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1403 if (s->update_altref == VP56_FRAME_GOLDEN &&
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1404 s->update_golden == VP56_FRAME_GOLDEN2)
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1405 FFSWAP(AVFrame *, s->framep[VP56_FRAME_GOLDEN], s->framep[VP56_FRAME_GOLDEN2]);
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1406 else {
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1407 if (s->update_altref != VP56_FRAME_NONE)
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1408 s->framep[VP56_FRAME_GOLDEN2] = s->framep[s->update_altref];
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1409
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1410 if (s->update_golden != VP56_FRAME_NONE)
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1411 s->framep[VP56_FRAME_GOLDEN] = s->framep[s->update_golden];
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1412 }
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1413
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1414 if (s->update_last) // move cur->prev
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1415 s->framep[VP56_FRAME_PREVIOUS] = s->framep[VP56_FRAME_CURRENT];
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1416
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1417 // release no longer referenced frames
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1418 for (i = 0; i < 4; i++)
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1419 if (s->frames[i].data[0] &&
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1420 &s->frames[i] != s->framep[VP56_FRAME_CURRENT] &&
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1421 &s->frames[i] != s->framep[VP56_FRAME_PREVIOUS] &&
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1422 &s->frames[i] != s->framep[VP56_FRAME_GOLDEN] &&
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1423 &s->frames[i] != s->framep[VP56_FRAME_GOLDEN2])
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1424 avctx->release_buffer(avctx, &s->frames[i]);
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1425
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1426 if (!s->invisible) {
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1427 *(AVFrame*)data = *s->framep[VP56_FRAME_CURRENT];
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1428 *data_size = sizeof(AVFrame);
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1429 }
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1430
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1431 return avpkt->size;
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1432 }
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1433
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1434 static av_cold int vp8_decode_init(AVCodecContext *avctx)
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1435 {
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1436 VP8Context *s = avctx->priv_data;
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1437
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1438 s->avctx = avctx;
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1439 avctx->pix_fmt = PIX_FMT_YUV420P;
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1440
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1441 dsputil_init(&s->dsp, avctx);
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1442 ff_h264_pred_init(&s->hpc, CODEC_ID_VP8);
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1443 ff_vp8dsp_init(&s->vp8dsp);
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1444
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1445 // intra pred needs edge emulation among other things
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1446 if (avctx->flags&CODEC_FLAG_EMU_EDGE) {
11947
fc9e4874a12c fix typo in vp8 decoder error message
darkshikari
parents: 11937
diff changeset
1447 av_log(avctx, AV_LOG_ERROR, "Edge emulation not supported\n");
11921
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1448 return AVERROR_PATCHWELCOME;
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1449 }
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1450
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1451 return 0;
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1452 }
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1453
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1454 static av_cold int vp8_decode_free(AVCodecContext *avctx)
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1455 {
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1456 vp8_decode_flush(avctx);
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1457 return 0;
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1458 }
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1459
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1460 AVCodec vp8_decoder = {
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1461 "vp8",
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1462 AVMEDIA_TYPE_VIDEO,
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1463 CODEC_ID_VP8,
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1464 sizeof(VP8Context),
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1465 vp8_decode_init,
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1466 NULL,
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1467 vp8_decode_free,
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1468 vp8_decode_frame,
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1469 CODEC_CAP_DR1,
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1470 .flush = vp8_decode_flush,
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1471 .long_name = NULL_IF_CONFIG_SMALL("On2 VP8"),
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1472 };