annotate vp8.c @ 12194:80b142c2e9f7 libavcodec

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