annotate vp8.c @ 12266:48d6738904a9 libavcodec

Fix SPLATB_REG mess. Used to be a if/elseif/elseif/elseif spaghetti, so this splits it into small optimization-specific macros which are selected for each DSP function. The advantage of this approach is that the sse4 functions now use the ssse3 codepath also without needing an explicit sse4 codepath.
author rbultje
date Sat, 24 Jul 2010 19:33:05 +0000
parents 7db147ea02c4
children 161c205dcdd2
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
12249
35ee666e4496 Add myself to VP8 copyright and maintainers.
darkshikari
parents: 12248
diff changeset
6 * Copyright (C) 2010 Jason Garrett-Glaser
11921
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
7 *
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
8 * This file is part of FFmpeg.
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
9 *
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
10 * FFmpeg is free software; you can redistribute it and/or
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
11 * modify it under the terms of the GNU Lesser General Public
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
12 * License as published by the Free Software Foundation; either
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
13 * version 2.1 of the License, or (at your option) any later version.
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
14 *
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
15 * FFmpeg is distributed in the hope that it will be useful,
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
18 * Lesser General Public License for more details.
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
19 *
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
20 * You should have received a copy of the GNU Lesser General Public
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
21 * License along with FFmpeg; if not, write to the Free Software
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
22 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
23 */
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
24
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
25 #include "avcodec.h"
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
26 #include "vp56.h"
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
27 #include "vp8data.h"
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
28 #include "vp8dsp.h"
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
29 #include "h264pred.h"
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
30 #include "rectangle.h"
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
31
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
32 typedef struct {
12222
7acdbfd2a222 Calculate deblock strength per-MB instead of per-row
darkshikari
parents: 12221
diff changeset
33 uint8_t filter_level;
7acdbfd2a222 Calculate deblock strength per-MB instead of per-row
darkshikari
parents: 12221
diff changeset
34 uint8_t inner_limit;
12223
93e27a5401de Convert VP8 macroblock structures to a ring buffer.
darkshikari
parents: 12222
diff changeset
35 uint8_t inner_filter;
12222
7acdbfd2a222 Calculate deblock strength per-MB instead of per-row
darkshikari
parents: 12221
diff changeset
36 } VP8FilterStrength;
7acdbfd2a222 Calculate deblock strength per-MB instead of per-row
darkshikari
parents: 12221
diff changeset
37
7acdbfd2a222 Calculate deblock strength per-MB instead of per-row
darkshikari
parents: 12221
diff changeset
38 typedef struct {
11921
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
39 uint8_t skip;
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
40 // todo: make it possible to check for at least (i4x4 or split_mv)
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
41 // in one op. are others needed?
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
42 uint8_t mode;
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
43 uint8_t ref_frame;
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
44 uint8_t partitioning;
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
45 VP56mv mv;
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
46 VP56mv bmv[16];
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
47 } VP8Macroblock;
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
48
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
49 typedef struct {
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
50 AVCodecContext *avctx;
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
51 DSPContext dsp;
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
52 VP8DSPContext vp8dsp;
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
53 H264PredContext hpc;
11974
356b20a6566d VP8 bilinear filter
conrad
parents: 11970
diff changeset
54 vp8_mc_func put_pixels_tab[3][3][3];
11921
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
55 AVFrame frames[4];
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
56 AVFrame *framep[4];
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
57 uint8_t *edge_emu_buffer;
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
58 VP56RangeCoder c; ///< header context, includes mb modes and motion vectors
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
59 int profile;
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
60
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
61 int mb_width; /* number of horizontal MB */
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
62 int mb_height; /* number of vertical MB */
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
63 int linesize;
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
64 int uvlinesize;
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
65
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
66 int keyframe;
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
67 int invisible;
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
68 int update_last; ///< update VP56_FRAME_PREVIOUS with the current one
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
69 int update_golden; ///< VP56_FRAME_NONE if not updated, or which frame to copy if so
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
70 int update_altref;
12170
6f0db2eeaf70 vp8: Save mb border needed for intra prediction so that loop filter can run
conrad
parents: 12169
diff changeset
71 int deblock_filter;
11921
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 * If this flag is not set, all the probability updates
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
75 * are discarded after this frame is decoded.
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
76 */
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
77 int update_probabilities;
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
78
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
79 /**
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
80 * All coefficients are contained in separate arith coding contexts.
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
81 * There can be 1, 2, 4, or 8 of these after the header context.
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
82 */
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
83 int num_coeff_partitions;
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
84 VP56RangeCoder coeff_partition[8];
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
85
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
86 VP8Macroblock *macroblocks;
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
87 VP8Macroblock *macroblocks_base;
12222
7acdbfd2a222 Calculate deblock strength per-MB instead of per-row
darkshikari
parents: 12221
diff changeset
88 VP8FilterStrength *filter_strength;
11921
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
89 int mb_stride;
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
90
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
91 uint8_t *intra4x4_pred_mode;
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
92 uint8_t *intra4x4_pred_mode_base;
12223
93e27a5401de Convert VP8 macroblock structures to a ring buffer.
darkshikari
parents: 12222
diff changeset
93 uint8_t *segmentation_map;
11921
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
94 int b4_stride;
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
95
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
96 /**
12170
6f0db2eeaf70 vp8: Save mb border needed for intra prediction so that loop filter can run
conrad
parents: 12169
diff changeset
97 * 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
98 * 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
99 */
6f0db2eeaf70 vp8: Save mb border needed for intra prediction so that loop filter can run
conrad
parents: 12169
diff changeset
100 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
101
6f0db2eeaf70 vp8: Save mb border needed for intra prediction so that loop filter can run
conrad
parents: 12169
diff changeset
102 /**
11921
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
103 * For coeff decode, we need to know whether the above block had non-zero
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
104 * coefficients. This means for each macroblock, we need data for 4 luma
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
105 * 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
106 * per macroblock. We keep the last row in top_nnz.
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
107 */
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
108 uint8_t (*top_nnz)[9];
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
109 DECLARE_ALIGNED(8, uint8_t, left_nnz)[9];
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
110
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
111 /**
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
112 * This is the index plus one of the last non-zero coeff
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
113 * for each of the blocks in the current macroblock.
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
114 * So, 0 -> no coeffs
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
115 * 1 -> dc-only (special transform)
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
116 * 2+-> full transform
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
117 */
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
118 DECLARE_ALIGNED(16, uint8_t, non_zero_count_cache)[6][4];
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
119 DECLARE_ALIGNED(16, DCTELEM, block)[6][4][16];
12221
45852dac8338 Avoid tracking i4x4 modes in P-frames in VP8
darkshikari
parents: 12220
diff changeset
120 uint8_t intra4x4_pred_mode_mb[16];
11921
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
121
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
122 int chroma_pred_mode; ///< 8x8c pred mode of the current macroblock
12224
5b7d690b761b VP8: Don't store segment in macroblock struct anymore.
darkshikari
parents: 12223
diff changeset
123 int segment; ///< segment of the current macroblock
11921
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
124
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
125 int mbskip_enabled;
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
126 int sign_bias[4]; ///< one state [0, 1] per ref frame type
12231
d3f3897ddb5c Smarter VP8 prefetching
darkshikari
parents: 12230
diff changeset
127 int ref_count[3];
11921
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
128
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
129 /**
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
130 * Base parameters for segmentation, i.e. per-macroblock parameters.
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
131 * These must be kept unchanged even if segmentation is not used for
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
132 * a frame, since the values persist between interframes.
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
133 */
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
134 struct {
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
135 int enabled;
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
136 int absolute_vals;
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
137 int update_map;
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
138 int8_t base_quant[4];
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
139 int8_t filter_level[4]; ///< base loop filter level
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
140 } segmentation;
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
141
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
142 /**
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
143 * Macroblocks can have one of 4 different quants in a frame when
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
144 * segmentation is enabled.
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
145 * If segmentation is disabled, only the first segment's values are used.
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
146 */
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
147 struct {
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
148 // [0] - DC qmul [1] - AC qmul
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
149 int16_t luma_qmul[2];
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
150 int16_t luma_dc_qmul[2]; ///< luma dc-only block quant
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
151 int16_t chroma_qmul[2];
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
152 } qmat[4];
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
153
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
154 struct {
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
155 int simple;
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
156 int level;
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
157 int sharpness;
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
158 } filter;
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
159
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
160 struct {
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
161 int enabled; ///< whether each mb can have a different strength based on mode/ref
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
162
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
163 /**
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
164 * filter strength adjustment for the following macroblock modes:
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
165 * [0] - i4x4
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
166 * [1] - zero mv
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
167 * [2] - inter modes except for zero or split mv
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
168 * [3] - split mv
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
169 * i16x16 modes never have any adjustment
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
170 */
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
171 int8_t mode[4];
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
172
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
173 /**
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
174 * filter strength adjustment for macroblocks that reference:
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
175 * [0] - intra / VP56_FRAME_CURRENT
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
176 * [1] - VP56_FRAME_PREVIOUS
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
177 * [2] - VP56_FRAME_GOLDEN
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
178 * [3] - altref / VP56_FRAME_GOLDEN2
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
179 */
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
180 int8_t ref[4];
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
181 } lf_delta;
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
182
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
183 /**
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
184 * These are all of the updatable probabilities for binary decisions.
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
185 * They are only implictly reset on keyframes, making it quite likely
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
186 * for an interframe to desync if a prior frame's header was corrupt
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
187 * or missing outright!
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
188 */
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
189 struct {
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
190 uint8_t segmentid[3];
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
191 uint8_t mbskip;
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
192 uint8_t intra;
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
193 uint8_t last;
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
194 uint8_t golden;
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
195 uint8_t pred16x16[4];
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
196 uint8_t pred8x8c[3];
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
197 uint8_t token[4][8][3][NUM_DCT_TOKENS-1];
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
198 uint8_t mvc[2][19];
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
199 } prob[2];
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
200 } VP8Context;
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
201
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
202 static void vp8_decode_flush(AVCodecContext *avctx)
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
203 {
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
204 VP8Context *s = avctx->priv_data;
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
205 int i;
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
206
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
207 for (i = 0; i < 4; i++)
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
208 if (s->frames[i].data[0])
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
209 avctx->release_buffer(avctx, &s->frames[i]);
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
210 memset(s->framep, 0, sizeof(s->framep));
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
211
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
212 av_freep(&s->macroblocks_base);
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
213 av_freep(&s->intra4x4_pred_mode_base);
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
214 av_freep(&s->top_nnz);
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
215 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
216 av_freep(&s->top_border);
12223
93e27a5401de Convert VP8 macroblock structures to a ring buffer.
darkshikari
parents: 12222
diff changeset
217 av_freep(&s->segmentation_map);
11921
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
218
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
219 s->macroblocks = NULL;
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
220 s->intra4x4_pred_mode = NULL;
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
221 }
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
222
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
223 static int update_dimensions(VP8Context *s, int width, int height)
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
224 {
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
225 int i;
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
226
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
227 if (avcodec_check_dimensions(s->avctx, width, height))
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
228 return AVERROR_INVALIDDATA;
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
229
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
230 vp8_decode_flush(s->avctx);
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
231
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
232 avcodec_set_dimensions(s->avctx, width, height);
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
233
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
234 s->mb_width = (s->avctx->coded_width +15) / 16;
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
235 s->mb_height = (s->avctx->coded_height+15) / 16;
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
236
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
237 // we allocate a border around the top/left of intra4x4 modes
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
238 // this is 4 blocks for intra4x4 to keep 4-byte alignment for fill_rectangle
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
239 s->mb_stride = s->mb_width+1;
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
240 s->b4_stride = 4*s->mb_stride;
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
241
12223
93e27a5401de Convert VP8 macroblock structures to a ring buffer.
darkshikari
parents: 12222
diff changeset
242 s->macroblocks_base = av_mallocz((s->mb_stride+s->mb_height*2+2)*sizeof(*s->macroblocks));
12222
7acdbfd2a222 Calculate deblock strength per-MB instead of per-row
darkshikari
parents: 12221
diff changeset
243 s->filter_strength = av_mallocz(s->mb_stride*sizeof(*s->filter_strength));
11921
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
244 s->intra4x4_pred_mode_base = av_mallocz(s->b4_stride*(4*s->mb_height+1));
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
245 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
246 s->top_border = av_mallocz((s->mb_width+1)*sizeof(*s->top_border));
12223
93e27a5401de Convert VP8 macroblock structures to a ring buffer.
darkshikari
parents: 12222
diff changeset
247 s->segmentation_map = av_mallocz(s->mb_stride*s->mb_height);
11921
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
248
12223
93e27a5401de Convert VP8 macroblock structures to a ring buffer.
darkshikari
parents: 12222
diff changeset
249 if (!s->macroblocks_base || !s->filter_strength || !s->intra4x4_pred_mode_base ||
93e27a5401de Convert VP8 macroblock structures to a ring buffer.
darkshikari
parents: 12222
diff changeset
250 !s->top_nnz || !s->top_border || !s->segmentation_map)
12169
7501f327cfd1 vp8: Check for malloc failure
conrad
parents: 12115
diff changeset
251 return AVERROR(ENOMEM);
7501f327cfd1 vp8: Check for malloc failure
conrad
parents: 12115
diff changeset
252
12223
93e27a5401de Convert VP8 macroblock structures to a ring buffer.
darkshikari
parents: 12222
diff changeset
253 s->macroblocks = s->macroblocks_base + 1;
11921
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
254 s->intra4x4_pred_mode = s->intra4x4_pred_mode_base + 4 + s->b4_stride;
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
255
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
256 memset(s->intra4x4_pred_mode_base, DC_PRED, s->b4_stride);
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
257 for (i = 0; i < 4*s->mb_height; i++)
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
258 s->intra4x4_pred_mode[i*s->b4_stride-1] = DC_PRED;
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
259
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
260 return 0;
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
261 }
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
262
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
263 static void parse_segment_info(VP8Context *s)
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
264 {
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
265 VP56RangeCoder *c = &s->c;
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
266 int i;
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
267
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
268 s->segmentation.update_map = vp8_rac_get(c);
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
269
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
270 if (vp8_rac_get(c)) { // update segment feature data
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
271 s->segmentation.absolute_vals = vp8_rac_get(c);
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
272
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
273 for (i = 0; i < 4; i++)
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
274 s->segmentation.base_quant[i] = vp8_rac_get_sint(c, 7);
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->segmentation.filter_level[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 if (s->segmentation.update_map)
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
280 for (i = 0; i < 3; i++)
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
281 s->prob->segmentid[i] = vp8_rac_get(c) ? vp8_rac_get_uint(c, 8) : 255;
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
282 }
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
283
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
284 static void update_lf_deltas(VP8Context *s)
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
285 {
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
286 VP56RangeCoder *c = &s->c;
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
287 int i;
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
288
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
289 for (i = 0; i < 4; i++)
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
290 s->lf_delta.ref[i] = vp8_rac_get_sint(c, 6);
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
291
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
292 for (i = 0; i < 4; i++)
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
293 s->lf_delta.mode[i] = vp8_rac_get_sint(c, 6);
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
294 }
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
295
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
296 static int setup_partitions(VP8Context *s, const uint8_t *buf, int buf_size)
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
297 {
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
298 const uint8_t *sizes = buf;
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
299 int i;
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
300
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
301 s->num_coeff_partitions = 1 << vp8_rac_get_uint(&s->c, 2);
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
302
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
303 buf += 3*(s->num_coeff_partitions-1);
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
304 buf_size -= 3*(s->num_coeff_partitions-1);
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
305 if (buf_size < 0)
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
306 return -1;
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
307
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
308 for (i = 0; i < s->num_coeff_partitions-1; i++) {
12247
50a96623366b VP8: use AV_RL24 instead of defining a new RL24.
darkshikari
parents: 12246
diff changeset
309 int size = AV_RL24(sizes + 3*i);
11921
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
310 if (buf_size - size < 0)
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
311 return -1;
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
312
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
313 vp56_init_range_decoder(&s->coeff_partition[i], buf, size);
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
314 buf += size;
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
315 buf_size -= size;
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
316 }
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
317 vp56_init_range_decoder(&s->coeff_partition[i], buf, buf_size);
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
318
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
319 return 0;
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
320 }
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
321
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
322 static void get_quants(VP8Context *s)
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
323 {
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
324 VP56RangeCoder *c = &s->c;
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
325 int i, base_qi;
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
326
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
327 int yac_qi = vp8_rac_get_uint(c, 7);
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
328 int ydc_delta = vp8_rac_get_sint(c, 4);
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
329 int y2dc_delta = vp8_rac_get_sint(c, 4);
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
330 int y2ac_delta = vp8_rac_get_sint(c, 4);
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
331 int uvdc_delta = vp8_rac_get_sint(c, 4);
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
332 int uvac_delta = vp8_rac_get_sint(c, 4);
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
333
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
334 for (i = 0; i < 4; i++) {
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
335 if (s->segmentation.enabled) {
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
336 base_qi = s->segmentation.base_quant[i];
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
337 if (!s->segmentation.absolute_vals)
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
338 base_qi += yac_qi;
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
339 } else
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
340 base_qi = yac_qi;
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
341
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
342 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
343 s->qmat[i].luma_qmul[1] = vp8_ac_qlookup[av_clip(base_qi , 0, 127)];
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
344 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
345 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
346 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
347 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
348
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
349 s->qmat[i].luma_dc_qmul[1] = FFMAX(s->qmat[i].luma_dc_qmul[1], 8);
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
350 s->qmat[i].chroma_qmul[0] = FFMIN(s->qmat[i].chroma_qmul[0], 132);
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
351 }
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
352 }
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
353
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
354 /**
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
355 * Determine which buffers golden and altref should be updated with after this frame.
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
356 * 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
357 *
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
358 * Intra frames update all 3 references
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
359 * Inter frames update VP56_FRAME_PREVIOUS if the update_last flag is set
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
360 * If the update (golden|altref) flag is set, it's updated with the current frame
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
361 * if update_last is set, and VP56_FRAME_PREVIOUS otherwise.
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
362 * If the flag is not set, the number read means:
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
363 * 0: no update
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
364 * 1: VP56_FRAME_PREVIOUS
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
365 * 2: update golden with altref, or update altref with golden
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
366 */
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
367 static VP56Frame ref_to_update(VP8Context *s, int update, VP56Frame ref)
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
368 {
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
369 VP56RangeCoder *c = &s->c;
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
370
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
371 if (update)
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
372 return VP56_FRAME_CURRENT;
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
373
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
374 switch (vp8_rac_get_uint(c, 2)) {
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
375 case 1:
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
376 return VP56_FRAME_PREVIOUS;
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
377 case 2:
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
378 return (ref == VP56_FRAME_GOLDEN) ? VP56_FRAME_GOLDEN2 : VP56_FRAME_GOLDEN;
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
379 }
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
380 return VP56_FRAME_NONE;
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
381 }
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
382
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
383 static void update_refs(VP8Context *s)
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
384 {
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
385 VP56RangeCoder *c = &s->c;
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
386
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
387 int update_golden = vp8_rac_get(c);
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
388 int update_altref = vp8_rac_get(c);
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
389
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
390 s->update_golden = ref_to_update(s, update_golden, VP56_FRAME_GOLDEN);
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
391 s->update_altref = ref_to_update(s, update_altref, VP56_FRAME_GOLDEN2);
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
392 }
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
393
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
394 static int decode_frame_header(VP8Context *s, const uint8_t *buf, int buf_size)
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
395 {
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
396 VP56RangeCoder *c = &s->c;
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
397 int header_size, hscale, vscale, i, j, k, l, ret;
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
398 int width = s->avctx->width;
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
399 int height = s->avctx->height;
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
400
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
401 s->keyframe = !(buf[0] & 1);
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
402 s->profile = (buf[0]>>1) & 7;
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
403 s->invisible = !(buf[0] & 0x10);
12247
50a96623366b VP8: use AV_RL24 instead of defining a new RL24.
darkshikari
parents: 12246
diff changeset
404 header_size = AV_RL24(buf) >> 5;
11921
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
405 buf += 3;
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
406 buf_size -= 3;
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
407
11974
356b20a6566d VP8 bilinear filter
conrad
parents: 11970
diff changeset
408 if (s->profile > 3)
356b20a6566d VP8 bilinear filter
conrad
parents: 11970
diff changeset
409 av_log(s->avctx, AV_LOG_WARNING, "Unknown profile %d\n", s->profile);
356b20a6566d VP8 bilinear filter
conrad
parents: 11970
diff changeset
410
356b20a6566d VP8 bilinear filter
conrad
parents: 11970
diff changeset
411 if (!s->profile)
356b20a6566d VP8 bilinear filter
conrad
parents: 11970
diff changeset
412 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
413 else // profile 1-3 use bilinear, 4+ aren't defined so whatever
356b20a6566d VP8 bilinear filter
conrad
parents: 11970
diff changeset
414 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
415
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
416 if (header_size > buf_size - 7*s->keyframe) {
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
417 av_log(s->avctx, AV_LOG_ERROR, "Header size larger than data provided\n");
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
418 return AVERROR_INVALIDDATA;
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
419 }
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
420
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
421 if (s->keyframe) {
12247
50a96623366b VP8: use AV_RL24 instead of defining a new RL24.
darkshikari
parents: 12246
diff changeset
422 if (AV_RL24(buf) != 0x2a019d) {
50a96623366b VP8: use AV_RL24 instead of defining a new RL24.
darkshikari
parents: 12246
diff changeset
423 av_log(s->avctx, AV_LOG_ERROR, "Invalid start code 0x%x\n", AV_RL24(buf));
11921
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
424 return AVERROR_INVALIDDATA;
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
425 }
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
426 width = AV_RL16(buf+3) & 0x3fff;
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
427 height = AV_RL16(buf+5) & 0x3fff;
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
428 hscale = buf[4] >> 6;
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
429 vscale = buf[6] >> 6;
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
430 buf += 7;
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
431 buf_size -= 7;
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
432
11970
c7953ee47af4 vp8: warn and request sample if upscaling specified in header
mru
parents: 11950
diff changeset
433 if (hscale || vscale)
c7953ee47af4 vp8: warn and request sample if upscaling specified in header
mru
parents: 11950
diff changeset
434 av_log_missing_feature(s->avctx, "Upscaling", 1);
c7953ee47af4 vp8: warn and request sample if upscaling specified in header
mru
parents: 11950
diff changeset
435
11921
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
436 s->update_golden = s->update_altref = VP56_FRAME_CURRENT;
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
437 memcpy(s->prob->token , vp8_token_default_probs , sizeof(s->prob->token));
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
438 memcpy(s->prob->pred16x16, vp8_pred16x16_prob_inter, sizeof(s->prob->pred16x16));
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
439 memcpy(s->prob->pred8x8c , vp8_pred8x8c_prob_inter , sizeof(s->prob->pred8x8c));
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
440 memcpy(s->prob->mvc , vp8_mv_default_prob , sizeof(s->prob->mvc));
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
441 memset(&s->segmentation, 0, sizeof(s->segmentation));
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
442 }
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
443
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
444 if (!s->macroblocks_base || /* first frame */
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
445 width != s->avctx->width || height != s->avctx->height) {
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
446 if ((ret = update_dimensions(s, width, height) < 0))
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
447 return ret;
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
448 }
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
449
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
450 vp56_init_range_decoder(c, buf, header_size);
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
451 buf += header_size;
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
452 buf_size -= header_size;
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
453
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
454 if (s->keyframe) {
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
455 if (vp8_rac_get(c))
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
456 av_log(s->avctx, AV_LOG_WARNING, "Unspecified colorspace\n");
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
457 vp8_rac_get(c); // whether we can skip clamping in dsp functions
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
458 }
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
459
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
460 if ((s->segmentation.enabled = vp8_rac_get(c)))
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
461 parse_segment_info(s);
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
462 else
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
463 s->segmentation.update_map = 0; // FIXME: move this to some init function?
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
464
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
465 s->filter.simple = vp8_rac_get(c);
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
466 s->filter.level = vp8_rac_get_uint(c, 6);
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
467 s->filter.sharpness = vp8_rac_get_uint(c, 3);
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
468
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
469 if ((s->lf_delta.enabled = vp8_rac_get(c)))
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
470 if (vp8_rac_get(c))
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
471 update_lf_deltas(s);
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
472
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
473 if (setup_partitions(s, buf, buf_size)) {
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
474 av_log(s->avctx, AV_LOG_ERROR, "Invalid partitions\n");
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
475 return AVERROR_INVALIDDATA;
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
476 }
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
477
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
478 get_quants(s);
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
479
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
480 if (!s->keyframe) {
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
481 update_refs(s);
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
482 s->sign_bias[VP56_FRAME_GOLDEN] = vp8_rac_get(c);
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
483 s->sign_bias[VP56_FRAME_GOLDEN2 /* altref */] = vp8_rac_get(c);
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
484 }
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
485
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
486 // if we aren't saving this frame's probabilities for future frames,
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
487 // make a copy of the current probabilities
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
488 if (!(s->update_probabilities = vp8_rac_get(c)))
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
489 s->prob[1] = s->prob[0];
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
490
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
491 s->update_last = s->keyframe || vp8_rac_get(c);
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
492
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
493 for (i = 0; i < 4; i++)
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
494 for (j = 0; j < 8; j++)
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
495 for (k = 0; k < 3; k++)
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
496 for (l = 0; l < NUM_DCT_TOKENS-1; l++)
12254
17c151e1280a VP8: Use vp56_rac_get_prob_branchy when the bit is only used by an if()
conrad
parents: 12253
diff changeset
497 if (vp56_rac_get_prob_branchy(c, vp8_token_update_probs[i][j][k][l]))
11921
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
498 s->prob->token[i][j][k][l] = vp8_rac_get_uint(c, 8);
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
499
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
500 if ((s->mbskip_enabled = vp8_rac_get(c)))
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
501 s->prob->mbskip = vp8_rac_get_uint(c, 8);
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
502
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
503 if (!s->keyframe) {
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
504 s->prob->intra = vp8_rac_get_uint(c, 8);
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
505 s->prob->last = vp8_rac_get_uint(c, 8);
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
506 s->prob->golden = vp8_rac_get_uint(c, 8);
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
507
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
508 if (vp8_rac_get(c))
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
509 for (i = 0; i < 4; i++)
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
510 s->prob->pred16x16[i] = vp8_rac_get_uint(c, 8);
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
511 if (vp8_rac_get(c))
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
512 for (i = 0; i < 3; i++)
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
513 s->prob->pred8x8c[i] = vp8_rac_get_uint(c, 8);
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
514
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
515 // 17.2 MV probability update
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
516 for (i = 0; i < 2; i++)
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
517 for (j = 0; j < 19; j++)
12254
17c151e1280a VP8: Use vp56_rac_get_prob_branchy when the bit is only used by an if()
conrad
parents: 12253
diff changeset
518 if (vp56_rac_get_prob_branchy(c, vp8_mv_update_prob[i][j]))
11921
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
519 s->prob->mvc[i][j] = vp8_rac_get_nn(c);
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 return 0;
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
523 }
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
524
12248
121272849def VP8: always_inline some things to force gcc to do the right thing
darkshikari
parents: 12247
diff changeset
525 static av_always_inline
121272849def VP8: always_inline some things to force gcc to do the right thing
darkshikari
parents: 12247
diff changeset
526 void clamp_mv(VP8Context *s, VP56mv *dst, const VP56mv *src, int mb_x, int mb_y)
11921
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
527 {
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
528 #define MARGIN (16 << 2)
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
529 dst->x = av_clip(src->x, -((mb_x << 6) + MARGIN),
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
530 ((s->mb_width - 1 - mb_x) << 6) + MARGIN);
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
531 dst->y = av_clip(src->y, -((mb_y << 6) + MARGIN),
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
532 ((s->mb_height - 1 - mb_y) << 6) + MARGIN);
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
533 }
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
534
12248
121272849def VP8: always_inline some things to force gcc to do the right thing
darkshikari
parents: 12247
diff changeset
535 static av_always_inline
121272849def VP8: always_inline some things to force gcc to do the right thing
darkshikari
parents: 12247
diff changeset
536 void find_near_mvs(VP8Context *s, VP8Macroblock *mb, int mb_x, int mb_y,
121272849def VP8: always_inline some things to force gcc to do the right thing
darkshikari
parents: 12247
diff changeset
537 VP56mv near[2], VP56mv *best, uint8_t cnt[4])
11921
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
538 {
12223
93e27a5401de Convert VP8 macroblock structures to a ring buffer.
darkshikari
parents: 12222
diff changeset
539 VP8Macroblock *mb_edge[3] = { mb + 2 /* top */,
93e27a5401de Convert VP8 macroblock structures to a ring buffer.
darkshikari
parents: 12222
diff changeset
540 mb - 1 /* left */,
93e27a5401de Convert VP8 macroblock structures to a ring buffer.
darkshikari
parents: 12222
diff changeset
541 mb + 1 /* top-left */ };
11921
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
542 enum { EDGE_TOP, EDGE_LEFT, EDGE_TOPLEFT };
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
543 VP56mv near_mv[4] = {{ 0 }};
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
544 enum { CNT_ZERO, CNT_NEAREST, CNT_NEAR, CNT_SPLITMV };
12217
f6b229456bdf Much faster VP8 mv and mode prediction
darkshikari
parents: 12215
diff changeset
545 int idx = CNT_ZERO;
11921
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
546 int best_idx = CNT_ZERO;
12217
f6b229456bdf Much faster VP8 mv and mode prediction
darkshikari
parents: 12215
diff changeset
547 int cur_sign_bias = s->sign_bias[mb->ref_frame];
f6b229456bdf Much faster VP8 mv and mode prediction
darkshikari
parents: 12215
diff changeset
548 int *sign_bias = s->sign_bias;
11921
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
549
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
550 /* Process MB on top, left and top-left */
12217
f6b229456bdf Much faster VP8 mv and mode prediction
darkshikari
parents: 12215
diff changeset
551 #define MV_EDGE_CHECK(n)\
f6b229456bdf Much faster VP8 mv and mode prediction
darkshikari
parents: 12215
diff changeset
552 {\
f6b229456bdf Much faster VP8 mv and mode prediction
darkshikari
parents: 12215
diff changeset
553 VP8Macroblock *edge = mb_edge[n];\
f6b229456bdf Much faster VP8 mv and mode prediction
darkshikari
parents: 12215
diff changeset
554 int edge_ref = edge->ref_frame;\
f6b229456bdf Much faster VP8 mv and mode prediction
darkshikari
parents: 12215
diff changeset
555 if (edge_ref != VP56_FRAME_CURRENT) {\
f6b229456bdf Much faster VP8 mv and mode prediction
darkshikari
parents: 12215
diff changeset
556 uint32_t mv = AV_RN32A(&edge->mv);\
f6b229456bdf Much faster VP8 mv and mode prediction
darkshikari
parents: 12215
diff changeset
557 if (mv) {\
f6b229456bdf Much faster VP8 mv and mode prediction
darkshikari
parents: 12215
diff changeset
558 if (cur_sign_bias != sign_bias[edge_ref]) {\
f6b229456bdf Much faster VP8 mv and mode prediction
darkshikari
parents: 12215
diff changeset
559 /* SWAR negate of the values in mv. */\
12242
a2f6d8c61b9c VP8: fix broken sign bias code in MV pred
darkshikari
parents: 12241
diff changeset
560 mv = ~mv;\
a2f6d8c61b9c VP8: fix broken sign bias code in MV pred
darkshikari
parents: 12241
diff changeset
561 mv = ((mv&0x7fff7fff) + 0x00010001) ^ (mv&0x80008000);\
12217
f6b229456bdf Much faster VP8 mv and mode prediction
darkshikari
parents: 12215
diff changeset
562 }\
f6b229456bdf Much faster VP8 mv and mode prediction
darkshikari
parents: 12215
diff changeset
563 if (!n || mv != AV_RN32A(&near_mv[idx]))\
f6b229456bdf Much faster VP8 mv and mode prediction
darkshikari
parents: 12215
diff changeset
564 AV_WN32A(&near_mv[++idx], mv);\
f6b229456bdf Much faster VP8 mv and mode prediction
darkshikari
parents: 12215
diff changeset
565 cnt[idx] += 1 + (n != 2);\
f6b229456bdf Much faster VP8 mv and mode prediction
darkshikari
parents: 12215
diff changeset
566 } else\
f6b229456bdf Much faster VP8 mv and mode prediction
darkshikari
parents: 12215
diff changeset
567 cnt[CNT_ZERO] += 1 + (n != 2);\
f6b229456bdf Much faster VP8 mv and mode prediction
darkshikari
parents: 12215
diff changeset
568 }\
11921
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
569 }
12217
f6b229456bdf Much faster VP8 mv and mode prediction
darkshikari
parents: 12215
diff changeset
570 MV_EDGE_CHECK(0)
f6b229456bdf Much faster VP8 mv and mode prediction
darkshikari
parents: 12215
diff changeset
571 MV_EDGE_CHECK(1)
f6b229456bdf Much faster VP8 mv and mode prediction
darkshikari
parents: 12215
diff changeset
572 MV_EDGE_CHECK(2)
11921
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
573
12217
f6b229456bdf Much faster VP8 mv and mode prediction
darkshikari
parents: 12215
diff changeset
574 /* If we have three distinct MVs, merge first and last if they're the same */
f6b229456bdf Much faster VP8 mv and mode prediction
darkshikari
parents: 12215
diff changeset
575 if (cnt[CNT_SPLITMV] && AV_RN32A(&near_mv[1+EDGE_TOP]) == AV_RN32A(&near_mv[1+EDGE_TOPLEFT]))
11921
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
576 cnt[CNT_NEAREST] += 1;
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
577
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
578 cnt[CNT_SPLITMV] = ((mb_edge[EDGE_LEFT]->mode == VP8_MVMODE_SPLIT) +
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
579 (mb_edge[EDGE_TOP]->mode == VP8_MVMODE_SPLIT)) * 2 +
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
580 (mb_edge[EDGE_TOPLEFT]->mode == VP8_MVMODE_SPLIT);
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
581
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
582 /* Swap near and nearest if necessary */
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
583 if (cnt[CNT_NEAR] > cnt[CNT_NEAREST]) {
12217
f6b229456bdf Much faster VP8 mv and mode prediction
darkshikari
parents: 12215
diff changeset
584 FFSWAP(uint8_t, cnt[CNT_NEAREST], cnt[CNT_NEAR]);
f6b229456bdf Much faster VP8 mv and mode prediction
darkshikari
parents: 12215
diff changeset
585 FFSWAP( VP56mv, near_mv[CNT_NEAREST], near_mv[CNT_NEAR]);
11921
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
586 }
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
587
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
588 /* Choose the best mv out of 0,0 and the nearest mv */
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
589 if (cnt[CNT_NEAREST] >= cnt[CNT_ZERO])
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
590 best_idx = CNT_NEAREST;
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
591
12246
3c841933cf78 VP8: Slightly faster MV selection
darkshikari
parents: 12245
diff changeset
592 mb->mv = near_mv[best_idx];
11921
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
593 near[0] = near_mv[CNT_NEAREST];
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
594 near[1] = near_mv[CNT_NEAR];
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
595 }
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
596
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
597 /**
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
598 * Motion vector coding, 17.1.
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
599 */
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
600 static int read_mv_component(VP56RangeCoder *c, const uint8_t *p)
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
601 {
12255
7db147ea02c4 VP8: Inline traversing vp8_small_mvtree
conrad
parents: 12254
diff changeset
602 int bit, x = 0;
11921
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
603
12254
17c151e1280a VP8: Use vp56_rac_get_prob_branchy when the bit is only used by an if()
conrad
parents: 12253
diff changeset
604 if (vp56_rac_get_prob_branchy(c, p[0])) {
11921
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
605 int i;
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
606
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
607 for (i = 0; i < 3; i++)
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
608 x += vp56_rac_get_prob(c, p[9 + i]) << i;
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
609 for (i = 9; i > 3; i--)
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
610 x += vp56_rac_get_prob(c, p[9 + i]) << i;
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
611 if (!(x & 0xFFF0) || vp56_rac_get_prob(c, p[12]))
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
612 x += 8;
12255
7db147ea02c4 VP8: Inline traversing vp8_small_mvtree
conrad
parents: 12254
diff changeset
613 } else {
7db147ea02c4 VP8: Inline traversing vp8_small_mvtree
conrad
parents: 12254
diff changeset
614 // small_mvtree
7db147ea02c4 VP8: Inline traversing vp8_small_mvtree
conrad
parents: 12254
diff changeset
615 const uint8_t *ps = p+2;
7db147ea02c4 VP8: Inline traversing vp8_small_mvtree
conrad
parents: 12254
diff changeset
616 bit = vp56_rac_get_prob(c, *ps);
7db147ea02c4 VP8: Inline traversing vp8_small_mvtree
conrad
parents: 12254
diff changeset
617 ps += 1 + 3*bit;
7db147ea02c4 VP8: Inline traversing vp8_small_mvtree
conrad
parents: 12254
diff changeset
618 x += 4*bit;
7db147ea02c4 VP8: Inline traversing vp8_small_mvtree
conrad
parents: 12254
diff changeset
619 bit = vp56_rac_get_prob(c, *ps);
7db147ea02c4 VP8: Inline traversing vp8_small_mvtree
conrad
parents: 12254
diff changeset
620 ps += 1 + bit;
7db147ea02c4 VP8: Inline traversing vp8_small_mvtree
conrad
parents: 12254
diff changeset
621 x += 2*bit;
7db147ea02c4 VP8: Inline traversing vp8_small_mvtree
conrad
parents: 12254
diff changeset
622 x += vp56_rac_get_prob(c, *ps);
7db147ea02c4 VP8: Inline traversing vp8_small_mvtree
conrad
parents: 12254
diff changeset
623 }
11921
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
624
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
625 return (x && vp56_rac_get_prob(c, p[1])) ? -x : x;
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
626 }
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
627
12248
121272849def VP8: always_inline some things to force gcc to do the right thing
darkshikari
parents: 12247
diff changeset
628 static av_always_inline
121272849def VP8: always_inline some things to force gcc to do the right thing
darkshikari
parents: 12247
diff changeset
629 const uint8_t *get_submv_prob(uint32_t left, uint32_t top)
11921
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
630 {
12219
274633916f8c Optimize partition mv decoding in VP8
darkshikari
parents: 12218
diff changeset
631 if (left == top)
274633916f8c Optimize partition mv decoding in VP8
darkshikari
parents: 12218
diff changeset
632 return vp8_submv_prob[4-!!left];
274633916f8c Optimize partition mv decoding in VP8
darkshikari
parents: 12218
diff changeset
633 if (!top)
11921
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
634 return vp8_submv_prob[2];
12219
274633916f8c Optimize partition mv decoding in VP8
darkshikari
parents: 12218
diff changeset
635 return vp8_submv_prob[1-!!left];
11921
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
636 }
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
637
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
638 /**
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
639 * 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
640 * @returns the number of motion vectors parsed (2, 4 or 16)
11921
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
641 */
12248
121272849def VP8: always_inline some things to force gcc to do the right thing
darkshikari
parents: 12247
diff changeset
642 static av_always_inline
121272849def VP8: always_inline some things to force gcc to do the right thing
darkshikari
parents: 12247
diff changeset
643 int decode_splitmvs(VP8Context *s, VP56RangeCoder *c, VP8Macroblock *mb)
11921
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
644 {
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
645 int part_idx = mb->partitioning =
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
646 vp8_rac_get_tree(c, vp8_mbsplit_tree, vp8_mbsplit_prob);
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
647 int n, num = vp8_mbsplit_count[part_idx];
12223
93e27a5401de Convert VP8 macroblock structures to a ring buffer.
darkshikari
parents: 12222
diff changeset
648 VP8Macroblock *top_mb = &mb[2];
12219
274633916f8c Optimize partition mv decoding in VP8
darkshikari
parents: 12218
diff changeset
649 VP8Macroblock *left_mb = &mb[-1];
274633916f8c Optimize partition mv decoding in VP8
darkshikari
parents: 12218
diff changeset
650 const uint8_t *mbsplits_left = vp8_mbsplits[left_mb->partitioning],
274633916f8c Optimize partition mv decoding in VP8
darkshikari
parents: 12218
diff changeset
651 *mbsplits_top = vp8_mbsplits[top_mb->partitioning],
274633916f8c Optimize partition mv decoding in VP8
darkshikari
parents: 12218
diff changeset
652 *mbsplits_cur = vp8_mbsplits[part_idx],
11990
3c51d7ac41c9 Simplify MV parsing, removes laying out 2 or 4 (16x8/8x8/8x16) MVs over all
rbultje
parents: 11989
diff changeset
653 *firstidx = vp8_mbfirstidx[part_idx];
12223
93e27a5401de Convert VP8 macroblock structures to a ring buffer.
darkshikari
parents: 12222
diff changeset
654 VP56mv *top_mv = top_mb->bmv;
93e27a5401de Convert VP8 macroblock structures to a ring buffer.
darkshikari
parents: 12222
diff changeset
655 VP56mv *left_mv = left_mb->bmv;
93e27a5401de Convert VP8 macroblock structures to a ring buffer.
darkshikari
parents: 12222
diff changeset
656 VP56mv *cur_mv = mb->bmv;
11921
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
657
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
658 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
659 int k = firstidx[n];
12219
274633916f8c Optimize partition mv decoding in VP8
darkshikari
parents: 12218
diff changeset
660 uint32_t left, above;
11990
3c51d7ac41c9 Simplify MV parsing, removes laying out 2 or 4 (16x8/8x8/8x16) MVs over all
rbultje
parents: 11989
diff changeset
661 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
662
12219
274633916f8c Optimize partition mv decoding in VP8
darkshikari
parents: 12218
diff changeset
663 if (!(k & 3))
274633916f8c Optimize partition mv decoding in VP8
darkshikari
parents: 12218
diff changeset
664 left = AV_RN32A(&left_mv[mbsplits_left[k + 3]]);
274633916f8c Optimize partition mv decoding in VP8
darkshikari
parents: 12218
diff changeset
665 else
274633916f8c Optimize partition mv decoding in VP8
darkshikari
parents: 12218
diff changeset
666 left = AV_RN32A(&cur_mv[mbsplits_cur[k - 1]]);
274633916f8c Optimize partition mv decoding in VP8
darkshikari
parents: 12218
diff changeset
667 if (k <= 3)
274633916f8c Optimize partition mv decoding in VP8
darkshikari
parents: 12218
diff changeset
668 above = AV_RN32A(&top_mv[mbsplits_top[k + 12]]);
274633916f8c Optimize partition mv decoding in VP8
darkshikari
parents: 12218
diff changeset
669 else
274633916f8c Optimize partition mv decoding in VP8
darkshikari
parents: 12218
diff changeset
670 above = AV_RN32A(&cur_mv[mbsplits_cur[k - 4]]);
11990
3c51d7ac41c9 Simplify MV parsing, removes laying out 2 or 4 (16x8/8x8/8x16) MVs over all
rbultje
parents: 11989
diff changeset
671
3c51d7ac41c9 Simplify MV parsing, removes laying out 2 or 4 (16x8/8x8/8x16) MVs over all
rbultje
parents: 11989
diff changeset
672 submv_prob = get_submv_prob(left, above);
11921
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
673
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
674 switch (vp8_rac_get_tree(c, vp8_submv_ref_tree, submv_prob)) {
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
675 case VP8_SUBMVMODE_NEW4X4:
12246
3c841933cf78 VP8: Slightly faster MV selection
darkshikari
parents: 12245
diff changeset
676 mb->bmv[n].y = mb->mv.y + read_mv_component(c, s->prob->mvc[0]);
3c841933cf78 VP8: Slightly faster MV selection
darkshikari
parents: 12245
diff changeset
677 mb->bmv[n].x = mb->mv.x + read_mv_component(c, s->prob->mvc[1]);
11921
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
678 break;
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
679 case VP8_SUBMVMODE_ZERO4X4:
12245
ca82c3ce90c1 VP8: use AV_ZERO32 instead of AV_WN32A where relevant
darkshikari
parents: 12244
diff changeset
680 AV_ZERO32(&mb->bmv[n]);
11921
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
681 break;
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
682 case VP8_SUBMVMODE_LEFT4X4:
12219
274633916f8c Optimize partition mv decoding in VP8
darkshikari
parents: 12218
diff changeset
683 AV_WN32A(&mb->bmv[n], left);
11921
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
684 break;
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
685 case VP8_SUBMVMODE_TOP4X4:
12219
274633916f8c Optimize partition mv decoding in VP8
darkshikari
parents: 12218
diff changeset
686 AV_WN32A(&mb->bmv[n], above);
11921
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
687 break;
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
688 }
11990
3c51d7ac41c9 Simplify MV parsing, removes laying out 2 or 4 (16x8/8x8/8x16) MVs over all
rbultje
parents: 11989
diff changeset
689 }
11921
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
690
11990
3c51d7ac41c9 Simplify MV parsing, removes laying out 2 or 4 (16x8/8x8/8x16) MVs over all
rbultje
parents: 11989
diff changeset
691 return num;
11921
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
692 }
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
693
12248
121272849def VP8: always_inline some things to force gcc to do the right thing
darkshikari
parents: 12247
diff changeset
694 static av_always_inline
121272849def VP8: always_inline some things to force gcc to do the right thing
darkshikari
parents: 12247
diff changeset
695 void decode_intra4x4_modes(VP56RangeCoder *c, uint8_t *intra4x4,
121272849def VP8: always_inline some things to force gcc to do the right thing
darkshikari
parents: 12247
diff changeset
696 int stride, int keyframe)
11921
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
697 {
12221
45852dac8338 Avoid tracking i4x4 modes in P-frames in VP8
darkshikari
parents: 12220
diff changeset
698 int x, y, t, l, i;
11921
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
699
12221
45852dac8338 Avoid tracking i4x4 modes in P-frames in VP8
darkshikari
parents: 12220
diff changeset
700 if (keyframe) {
45852dac8338 Avoid tracking i4x4 modes in P-frames in VP8
darkshikari
parents: 12220
diff changeset
701 const uint8_t *ctx;
45852dac8338 Avoid tracking i4x4 modes in P-frames in VP8
darkshikari
parents: 12220
diff changeset
702 for (y = 0; y < 4; y++) {
45852dac8338 Avoid tracking i4x4 modes in P-frames in VP8
darkshikari
parents: 12220
diff changeset
703 for (x = 0; x < 4; x++) {
11921
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
704 t = intra4x4[x - stride];
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
705 l = intra4x4[x - 1];
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
706 ctx = vp8_pred4x4_prob_intra[t][l];
12221
45852dac8338 Avoid tracking i4x4 modes in P-frames in VP8
darkshikari
parents: 12220
diff changeset
707 intra4x4[x] = vp8_rac_get_tree(c, vp8_pred4x4_tree, ctx);
11921
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
708 }
12221
45852dac8338 Avoid tracking i4x4 modes in P-frames in VP8
darkshikari
parents: 12220
diff changeset
709 intra4x4 += stride;
11921
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
710 }
12221
45852dac8338 Avoid tracking i4x4 modes in P-frames in VP8
darkshikari
parents: 12220
diff changeset
711 } else {
45852dac8338 Avoid tracking i4x4 modes in P-frames in VP8
darkshikari
parents: 12220
diff changeset
712 for (i = 0; i < 16; i++)
45852dac8338 Avoid tracking i4x4 modes in P-frames in VP8
darkshikari
parents: 12220
diff changeset
713 intra4x4[i] = vp8_rac_get_tree(c, vp8_pred4x4_tree, vp8_pred4x4_prob_inter);
11921
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
714 }
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
715 }
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
716
12248
121272849def VP8: always_inline some things to force gcc to do the right thing
darkshikari
parents: 12247
diff changeset
717 static av_always_inline
121272849def VP8: always_inline some things to force gcc to do the right thing
darkshikari
parents: 12247
diff changeset
718 void decode_mb_mode(VP8Context *s, VP8Macroblock *mb, int mb_x, int mb_y,
121272849def VP8: always_inline some things to force gcc to do the right thing
darkshikari
parents: 12247
diff changeset
719 uint8_t *intra4x4, uint8_t *segment)
11921
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
720 {
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
721 VP56RangeCoder *c = &s->c;
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
722
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
723 if (s->segmentation.update_map)
12223
93e27a5401de Convert VP8 macroblock structures to a ring buffer.
darkshikari
parents: 12222
diff changeset
724 *segment = vp8_rac_get_tree(c, vp8_segmentid_tree, s->prob->segmentid);
12224
5b7d690b761b VP8: Don't store segment in macroblock struct anymore.
darkshikari
parents: 12223
diff changeset
725 s->segment = *segment;
11921
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
726
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
727 mb->skip = s->mbskip_enabled ? vp56_rac_get_prob(c, s->prob->mbskip) : 0;
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
728
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
729 if (s->keyframe) {
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
730 mb->mode = vp8_rac_get_tree(c, vp8_pred16x16_tree_intra, vp8_pred16x16_prob_intra);
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
731
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
732 if (mb->mode == MODE_I4x4) {
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
733 decode_intra4x4_modes(c, intra4x4, s->b4_stride, 1);
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
734 } else
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
735 fill_rectangle(intra4x4, 4, 4, s->b4_stride, vp8_pred4x4_mode[mb->mode], 1);
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
736
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
737 s->chroma_pred_mode = vp8_rac_get_tree(c, vp8_pred8x8c_tree, vp8_pred8x8c_prob_intra);
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
738 mb->ref_frame = VP56_FRAME_CURRENT;
12254
17c151e1280a VP8: Use vp56_rac_get_prob_branchy when the bit is only used by an if()
conrad
parents: 12253
diff changeset
739 } else if (vp56_rac_get_prob_branchy(c, s->prob->intra)) {
11921
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
740 VP56mv near[2], best;
12217
f6b229456bdf Much faster VP8 mv and mode prediction
darkshikari
parents: 12215
diff changeset
741 uint8_t cnt[4] = { 0 };
11921
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
742 uint8_t p[4];
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
743
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
744 // inter MB, 16.2
12254
17c151e1280a VP8: Use vp56_rac_get_prob_branchy when the bit is only used by an if()
conrad
parents: 12253
diff changeset
745 if (vp56_rac_get_prob_branchy(c, s->prob->last))
11921
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
746 mb->ref_frame = vp56_rac_get_prob(c, s->prob->golden) ?
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
747 VP56_FRAME_GOLDEN2 /* altref */ : VP56_FRAME_GOLDEN;
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
748 else
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
749 mb->ref_frame = VP56_FRAME_PREVIOUS;
12231
d3f3897ddb5c Smarter VP8 prefetching
darkshikari
parents: 12230
diff changeset
750 s->ref_count[mb->ref_frame-1]++;
11921
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
751
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
752 // motion vectors, 16.3
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
753 find_near_mvs(s, mb, mb_x, mb_y, near, &best, cnt);
12217
f6b229456bdf Much faster VP8 mv and mode prediction
darkshikari
parents: 12215
diff changeset
754 p[0] = vp8_mode_contexts[cnt[0]][0];
f6b229456bdf Much faster VP8 mv and mode prediction
darkshikari
parents: 12215
diff changeset
755 p[1] = vp8_mode_contexts[cnt[1]][1];
f6b229456bdf Much faster VP8 mv and mode prediction
darkshikari
parents: 12215
diff changeset
756 p[2] = vp8_mode_contexts[cnt[2]][2];
f6b229456bdf Much faster VP8 mv and mode prediction
darkshikari
parents: 12215
diff changeset
757 p[3] = vp8_mode_contexts[cnt[3]][3];
11921
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
758 mb->mode = vp8_rac_get_tree(c, vp8_pred16x16_tree_mvinter, p);
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
759 switch (mb->mode) {
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
760 case VP8_MVMODE_SPLIT:
12246
3c841933cf78 VP8: Slightly faster MV selection
darkshikari
parents: 12245
diff changeset
761 clamp_mv(s, &mb->mv, &mb->mv, mb_x, mb_y);
3c841933cf78 VP8: Slightly faster MV selection
darkshikari
parents: 12245
diff changeset
762 mb->mv = mb->bmv[decode_splitmvs(s, c, mb) - 1];
11921
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
763 break;
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
764 case VP8_MVMODE_ZERO:
12245
ca82c3ce90c1 VP8: use AV_ZERO32 instead of AV_WN32A where relevant
darkshikari
parents: 12244
diff changeset
765 AV_ZERO32(&mb->mv);
11921
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
766 break;
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
767 case VP8_MVMODE_NEAREST:
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
768 clamp_mv(s, &mb->mv, &near[0], mb_x, mb_y);
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
769 break;
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
770 case VP8_MVMODE_NEAR:
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
771 clamp_mv(s, &mb->mv, &near[1], mb_x, mb_y);
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
772 break;
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
773 case VP8_MVMODE_NEW:
12246
3c841933cf78 VP8: Slightly faster MV selection
darkshikari
parents: 12245
diff changeset
774 clamp_mv(s, &mb->mv, &mb->mv, mb_x, mb_y);
3c841933cf78 VP8: Slightly faster MV selection
darkshikari
parents: 12245
diff changeset
775 mb->mv.y += + read_mv_component(c, s->prob->mvc[0]);
3c841933cf78 VP8: Slightly faster MV selection
darkshikari
parents: 12245
diff changeset
776 mb->mv.x += + read_mv_component(c, s->prob->mvc[1]);
11921
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
777 break;
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
778 }
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
779 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
780 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
781 mb->bmv[0] = mb->mv;
11921
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
782 }
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
783 } else {
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
784 // intra MB, 16.1
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
785 mb->mode = vp8_rac_get_tree(c, vp8_pred16x16_tree_inter, s->prob->pred16x16);
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
786
12220
0f635b1f7861 Avoid useless fill_rectangle in P-frames in VP8
darkshikari
parents: 12219
diff changeset
787 if (mb->mode == MODE_I4x4)
12221
45852dac8338 Avoid tracking i4x4 modes in P-frames in VP8
darkshikari
parents: 12220
diff changeset
788 decode_intra4x4_modes(c, intra4x4, 4, 0);
11921
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
789
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
790 s->chroma_pred_mode = vp8_rac_get_tree(c, vp8_pred8x8c_tree, s->prob->pred8x8c);
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
791 mb->ref_frame = VP56_FRAME_CURRENT;
12225
c3e11b3108d7 Eliminate a pointless memset for intra blocks in P-frames in VP8
darkshikari
parents: 12224
diff changeset
792 mb->partitioning = VP8_SPLITMVMODE_NONE;
12245
ca82c3ce90c1 VP8: use AV_ZERO32 instead of AV_WN32A where relevant
darkshikari
parents: 12244
diff changeset
793 AV_ZERO32(&mb->bmv[0]);
11921
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
794 }
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
795 }
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
796
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
797 /**
12115
e97aba4d16ea Add missing doxy for function arguments.
rbultje
parents: 12081
diff changeset
798 * @param c arithmetic bitstream reader context
e97aba4d16ea Add missing doxy for function arguments.
rbultje
parents: 12081
diff changeset
799 * @param block destination for block coefficients
e97aba4d16ea Add missing doxy for function arguments.
rbultje
parents: 12081
diff changeset
800 * @param probs probabilities to use when reading trees from the bitstream
11921
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
801 * @param i initial coeff index, 0 unless a separate DC block is coded
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
802 * @param zero_nhood the initial prediction context for number of surrounding
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
803 * 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
804 * @param qmul array holding the dc/ac dequant factor at position 0/1
11921
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
805 * @return 0 if no coeffs were decoded
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
806 * otherwise, the index of the last coeff decoded plus one
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
807 */
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
808 static int decode_block_coeffs(VP56RangeCoder *c, DCTELEM block[16],
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
809 uint8_t probs[8][3][NUM_DCT_TOKENS-1],
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
810 int i, int zero_nhood, int16_t qmul[2])
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
811 {
12253
112b3a0db187 Decode DCT tokens by branching to a different code path for each branch
conrad
parents: 12249
diff changeset
812 uint8_t *token_prob;
112b3a0db187 Decode DCT tokens by branching to a different code path for each branch
conrad
parents: 12249
diff changeset
813 int nonzero = 0;
112b3a0db187 Decode DCT tokens by branching to a different code path for each branch
conrad
parents: 12249
diff changeset
814 int coeff;
11921
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
815
12253
112b3a0db187 Decode DCT tokens by branching to a different code path for each branch
conrad
parents: 12249
diff changeset
816 do {
112b3a0db187 Decode DCT tokens by branching to a different code path for each branch
conrad
parents: 12249
diff changeset
817 token_prob = probs[vp8_coeff_band[i]][zero_nhood];
11921
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
818
12253
112b3a0db187 Decode DCT tokens by branching to a different code path for each branch
conrad
parents: 12249
diff changeset
819 if (!vp56_rac_get_prob_branchy(c, token_prob[0])) // DCT_EOB
112b3a0db187 Decode DCT tokens by branching to a different code path for each branch
conrad
parents: 12249
diff changeset
820 return nonzero;
112b3a0db187 Decode DCT tokens by branching to a different code path for each branch
conrad
parents: 12249
diff changeset
821
112b3a0db187 Decode DCT tokens by branching to a different code path for each branch
conrad
parents: 12249
diff changeset
822 skip_eob:
112b3a0db187 Decode DCT tokens by branching to a different code path for each branch
conrad
parents: 12249
diff changeset
823 if (!vp56_rac_get_prob_branchy(c, token_prob[1])) { // DCT_0
112b3a0db187 Decode DCT tokens by branching to a different code path for each branch
conrad
parents: 12249
diff changeset
824 zero_nhood = 0;
112b3a0db187 Decode DCT tokens by branching to a different code path for each branch
conrad
parents: 12249
diff changeset
825 token_prob = probs[vp8_coeff_band[++i]][0];
112b3a0db187 Decode DCT tokens by branching to a different code path for each branch
conrad
parents: 12249
diff changeset
826 if (i < 16)
112b3a0db187 Decode DCT tokens by branching to a different code path for each branch
conrad
parents: 12249
diff changeset
827 goto skip_eob;
112b3a0db187 Decode DCT tokens by branching to a different code path for each branch
conrad
parents: 12249
diff changeset
828 return nonzero; // invalid input; blocks should end with EOB
11921
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
829 }
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
830
12253
112b3a0db187 Decode DCT tokens by branching to a different code path for each branch
conrad
parents: 12249
diff changeset
831 if (!vp56_rac_get_prob_branchy(c, token_prob[2])) { // DCT_1
112b3a0db187 Decode DCT tokens by branching to a different code path for each branch
conrad
parents: 12249
diff changeset
832 coeff = 1;
11921
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
833 zero_nhood = 1;
12253
112b3a0db187 Decode DCT tokens by branching to a different code path for each branch
conrad
parents: 12249
diff changeset
834 } else {
11921
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
835 zero_nhood = 2;
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
836
12253
112b3a0db187 Decode DCT tokens by branching to a different code path for each branch
conrad
parents: 12249
diff changeset
837 if (!vp56_rac_get_prob_branchy(c, token_prob[3])) { // DCT 2,3,4
112b3a0db187 Decode DCT tokens by branching to a different code path for each branch
conrad
parents: 12249
diff changeset
838 coeff = vp56_rac_get_prob(c, token_prob[4]);
112b3a0db187 Decode DCT tokens by branching to a different code path for each branch
conrad
parents: 12249
diff changeset
839 if (coeff)
112b3a0db187 Decode DCT tokens by branching to a different code path for each branch
conrad
parents: 12249
diff changeset
840 coeff += vp56_rac_get_prob(c, token_prob[5]);
112b3a0db187 Decode DCT tokens by branching to a different code path for each branch
conrad
parents: 12249
diff changeset
841 coeff += 2;
112b3a0db187 Decode DCT tokens by branching to a different code path for each branch
conrad
parents: 12249
diff changeset
842 } else {
112b3a0db187 Decode DCT tokens by branching to a different code path for each branch
conrad
parents: 12249
diff changeset
843 // DCT_CAT*
112b3a0db187 Decode DCT tokens by branching to a different code path for each branch
conrad
parents: 12249
diff changeset
844 if (!vp56_rac_get_prob_branchy(c, token_prob[6])) {
112b3a0db187 Decode DCT tokens by branching to a different code path for each branch
conrad
parents: 12249
diff changeset
845 if (!vp56_rac_get_prob_branchy(c, token_prob[7])) { // DCT_CAT1
112b3a0db187 Decode DCT tokens by branching to a different code path for each branch
conrad
parents: 12249
diff changeset
846 coeff = 5 + vp56_rac_get_prob(c, vp8_dct_cat1_prob[0]);
112b3a0db187 Decode DCT tokens by branching to a different code path for each branch
conrad
parents: 12249
diff changeset
847 } else { // DCT_CAT2
112b3a0db187 Decode DCT tokens by branching to a different code path for each branch
conrad
parents: 12249
diff changeset
848 coeff = 7;
112b3a0db187 Decode DCT tokens by branching to a different code path for each branch
conrad
parents: 12249
diff changeset
849 coeff += vp56_rac_get_prob(c, vp8_dct_cat2_prob[0]) << 1;
112b3a0db187 Decode DCT tokens by branching to a different code path for each branch
conrad
parents: 12249
diff changeset
850 coeff += vp56_rac_get_prob(c, vp8_dct_cat2_prob[1]);
112b3a0db187 Decode DCT tokens by branching to a different code path for each branch
conrad
parents: 12249
diff changeset
851 }
112b3a0db187 Decode DCT tokens by branching to a different code path for each branch
conrad
parents: 12249
diff changeset
852 } else { // DCT_CAT3 and up
112b3a0db187 Decode DCT tokens by branching to a different code path for each branch
conrad
parents: 12249
diff changeset
853 int a = vp56_rac_get_prob(c, token_prob[8]);
112b3a0db187 Decode DCT tokens by branching to a different code path for each branch
conrad
parents: 12249
diff changeset
854 int b = vp56_rac_get_prob(c, token_prob[9+a]);
112b3a0db187 Decode DCT tokens by branching to a different code path for each branch
conrad
parents: 12249
diff changeset
855 int cat = (a<<1) + b;
112b3a0db187 Decode DCT tokens by branching to a different code path for each branch
conrad
parents: 12249
diff changeset
856 coeff = 3 + (8<<cat);
112b3a0db187 Decode DCT tokens by branching to a different code path for each branch
conrad
parents: 12249
diff changeset
857 coeff += vp8_rac_get_coeff(c, vp8_dct_cat_prob[cat]);
112b3a0db187 Decode DCT tokens by branching to a different code path for each branch
conrad
parents: 12249
diff changeset
858 }
112b3a0db187 Decode DCT tokens by branching to a different code path for each branch
conrad
parents: 12249
diff changeset
859 }
112b3a0db187 Decode DCT tokens by branching to a different code path for each branch
conrad
parents: 12249
diff changeset
860 }
112b3a0db187 Decode DCT tokens by branching to a different code path for each branch
conrad
parents: 12249
diff changeset
861
11921
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
862 // todo: full [16] qmat? load into register?
12253
112b3a0db187 Decode DCT tokens by branching to a different code path for each branch
conrad
parents: 12249
diff changeset
863 block[zigzag_scan[i]] = (vp8_rac_get(c) ? -coeff : coeff) * qmul[!!i];
112b3a0db187 Decode DCT tokens by branching to a different code path for each branch
conrad
parents: 12249
diff changeset
864 nonzero = ++i;
112b3a0db187 Decode DCT tokens by branching to a different code path for each branch
conrad
parents: 12249
diff changeset
865 } while (i < 16);
112b3a0db187 Decode DCT tokens by branching to a different code path for each branch
conrad
parents: 12249
diff changeset
866
11921
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
867 return nonzero;
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
868 }
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
869
12248
121272849def VP8: always_inline some things to force gcc to do the right thing
darkshikari
parents: 12247
diff changeset
870 static av_always_inline
121272849def VP8: always_inline some things to force gcc to do the right thing
darkshikari
parents: 12247
diff changeset
871 void decode_mb_coeffs(VP8Context *s, VP56RangeCoder *c, VP8Macroblock *mb,
121272849def VP8: always_inline some things to force gcc to do the right thing
darkshikari
parents: 12247
diff changeset
872 uint8_t t_nnz[9], uint8_t l_nnz[9])
11921
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
873 {
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
874 LOCAL_ALIGNED_16(DCTELEM, dc,[16]);
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
875 int i, x, y, luma_start = 0, luma_ctx = 3;
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
876 int nnz_pred, nnz, nnz_total = 0;
12224
5b7d690b761b VP8: Don't store segment in macroblock struct anymore.
darkshikari
parents: 12223
diff changeset
877 int segment = s->segment;
11921
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
878
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
879 if (mb->mode != MODE_I4x4 && mb->mode != VP8_MVMODE_SPLIT) {
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
880 AV_ZERO128(dc);
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
881 AV_ZERO128(dc+8);
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
882 nnz_pred = t_nnz[8] + l_nnz[8];
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
883
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
884 // decode DC values and do hadamard
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
885 nnz = decode_block_coeffs(c, dc, s->prob->token[1], 0, nnz_pred,
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
886 s->qmat[segment].luma_dc_qmul);
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
887 l_nnz[8] = t_nnz[8] = !!nnz;
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
888 nnz_total += nnz;
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
889 s->vp8dsp.vp8_luma_dc_wht(s->block, dc);
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
890 luma_start = 1;
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
891 luma_ctx = 0;
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
892 }
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
893
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
894 // luma blocks
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
895 for (y = 0; y < 4; y++)
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
896 for (x = 0; x < 4; x++) {
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
897 nnz_pred = l_nnz[y] + t_nnz[x];
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
898 nnz = decode_block_coeffs(c, s->block[y][x], s->prob->token[luma_ctx], luma_start,
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
899 nnz_pred, s->qmat[segment].luma_qmul);
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
900 // 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
901 s->non_zero_count_cache[y][x] = nnz + luma_start;
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
902 t_nnz[x] = l_nnz[y] = !!nnz;
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
903 nnz_total += nnz;
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
904 }
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
905
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
906 // chroma blocks
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
907 // TODO: what to do about dimensions? 2nd dim for luma is x,
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
908 // but for chroma it's (y<<1)|x
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
909 for (i = 4; i < 6; i++)
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
910 for (y = 0; y < 2; y++)
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
911 for (x = 0; x < 2; x++) {
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
912 nnz_pred = l_nnz[i+2*y] + t_nnz[i+2*x];
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
913 nnz = decode_block_coeffs(c, s->block[i][(y<<1)+x], s->prob->token[2], 0,
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
914 nnz_pred, s->qmat[segment].chroma_qmul);
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
915 s->non_zero_count_cache[i][(y<<1)+x] = nnz;
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
916 t_nnz[i+2*x] = l_nnz[i+2*y] = !!nnz;
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
917 nnz_total += nnz;
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
918 }
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
919
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
920 // if there were no coded coeffs despite the macroblock not being marked skip,
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
921 // we MUST not do the inner loop filter and should not do IDCT
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
922 // Since skip isn't used for bitstream prediction, just manually set it.
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
923 if (!nnz_total)
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
924 mb->skip = 1;
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
925 }
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
926
12170
6f0db2eeaf70 vp8: Save mb border needed for intra prediction so that loop filter can run
conrad
parents: 12169
diff changeset
927 static av_always_inline
6f0db2eeaf70 vp8: Save mb border needed for intra prediction so that loop filter can run
conrad
parents: 12169
diff changeset
928 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
929 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
930 {
6f0db2eeaf70 vp8: Save mb border needed for intra prediction so that loop filter can run
conrad
parents: 12169
diff changeset
931 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
932 if (!simple) {
6f0db2eeaf70 vp8: Save mb border needed for intra prediction so that loop filter can run
conrad
parents: 12169
diff changeset
933 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
934 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
935 }
6f0db2eeaf70 vp8: Save mb border needed for intra prediction so that loop filter can run
conrad
parents: 12169
diff changeset
936 }
6f0db2eeaf70 vp8: Save mb border needed for intra prediction so that loop filter can run
conrad
parents: 12169
diff changeset
937
6f0db2eeaf70 vp8: Save mb border needed for intra prediction so that loop filter can run
conrad
parents: 12169
diff changeset
938 static av_always_inline
6f0db2eeaf70 vp8: Save mb border needed for intra prediction so that loop filter can run
conrad
parents: 12169
diff changeset
939 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
940 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
941 int simple, int xchg)
6f0db2eeaf70 vp8: Save mb border needed for intra prediction so that loop filter can run
conrad
parents: 12169
diff changeset
942 {
6f0db2eeaf70 vp8: Save mb border needed for intra prediction so that loop filter can run
conrad
parents: 12169
diff changeset
943 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
944 src_y -= linesize;
6f0db2eeaf70 vp8: Save mb border needed for intra prediction so that loop filter can run
conrad
parents: 12169
diff changeset
945 src_cb -= uvlinesize;
6f0db2eeaf70 vp8: Save mb border needed for intra prediction so that loop filter can run
conrad
parents: 12169
diff changeset
946 src_cr -= uvlinesize;
6f0db2eeaf70 vp8: Save mb border needed for intra prediction so that loop filter can run
conrad
parents: 12169
diff changeset
947
12202
3465e53116e5 vp8: indent
mru
parents: 12201
diff changeset
948 #define XCHG(a,b,xchg) do { \
3465e53116e5 vp8: indent
mru
parents: 12201
diff changeset
949 if (xchg) AV_SWAP64(b,a); \
3465e53116e5 vp8: indent
mru
parents: 12201
diff changeset
950 else AV_COPY64(b,a); \
3465e53116e5 vp8: indent
mru
parents: 12201
diff changeset
951 } while (0)
12170
6f0db2eeaf70 vp8: Save mb border needed for intra prediction so that loop filter can run
conrad
parents: 12169
diff changeset
952
6f0db2eeaf70 vp8: Save mb border needed for intra prediction so that loop filter can run
conrad
parents: 12169
diff changeset
953 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
954 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
955 XCHG(top_border+8, src_y+8, 1);
12201
c4b53914f286 vp8: add do { } while(0) around XCHG() macro to avoid confusing if/else
mru
parents: 12200
diff changeset
956 if (mb_x < mb_width-1)
12170
6f0db2eeaf70 vp8: Save mb border needed for intra prediction so that loop filter can run
conrad
parents: 12169
diff changeset
957 XCHG(top_border+32, src_y+16, 1);
12201
c4b53914f286 vp8: add do { } while(0) around XCHG() macro to avoid confusing if/else
mru
parents: 12200
diff changeset
958
12170
6f0db2eeaf70 vp8: Save mb border needed for intra prediction so that loop filter can run
conrad
parents: 12169
diff changeset
959 // 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
960 // 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
961 if (!simple || !mb_y) {
6f0db2eeaf70 vp8: Save mb border needed for intra prediction so that loop filter can run
conrad
parents: 12169
diff changeset
962 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
963 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
964 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
965 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
966 }
6f0db2eeaf70 vp8: Save mb border needed for intra prediction so that loop filter can run
conrad
parents: 12169
diff changeset
967 }
6f0db2eeaf70 vp8: Save mb border needed for intra prediction so that loop filter can run
conrad
parents: 12169
diff changeset
968
12248
121272849def VP8: always_inline some things to force gcc to do the right thing
darkshikari
parents: 12247
diff changeset
969 static av_always_inline
121272849def VP8: always_inline some things to force gcc to do the right thing
darkshikari
parents: 12247
diff changeset
970 int check_intra_pred_mode(int mode, int mb_x, int mb_y)
11921
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
971 {
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
972 if (mode == DC_PRED8x8) {
12243
788445bf10c0 VP8: shave a few clocks off check_intra_pred_mode
darkshikari
parents: 12242
diff changeset
973 if (!mb_x) {
788445bf10c0 VP8: shave a few clocks off check_intra_pred_mode
darkshikari
parents: 12242
diff changeset
974 mode = mb_y ? TOP_DC_PRED8x8 : DC_128_PRED8x8;
788445bf10c0 VP8: shave a few clocks off check_intra_pred_mode
darkshikari
parents: 12242
diff changeset
975 } else if (!mb_y) {
12244
49c9a10309dd VP8: eliminate redundant code in r24458
darkshikari
parents: 12243
diff changeset
976 mode = LEFT_DC_PRED8x8;
12243
788445bf10c0 VP8: shave a few clocks off check_intra_pred_mode
darkshikari
parents: 12242
diff changeset
977 }
11921
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
978 }
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
979 return mode;
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
980 }
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
981
12248
121272849def VP8: always_inline some things to force gcc to do the right thing
darkshikari
parents: 12247
diff changeset
982 static av_always_inline
121272849def VP8: always_inline some things to force gcc to do the right thing
darkshikari
parents: 12247
diff changeset
983 void intra_predict(VP8Context *s, uint8_t *dst[3], VP8Macroblock *mb,
121272849def VP8: always_inline some things to force gcc to do the right thing
darkshikari
parents: 12247
diff changeset
984 uint8_t *intra4x4, int mb_x, int mb_y)
11921
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
985 {
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
986 int x, y, mode, nnz, tr;
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
987
12170
6f0db2eeaf70 vp8: Save mb border needed for intra prediction so that loop filter can run
conrad
parents: 12169
diff changeset
988 // 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
989 // 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
990 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
991 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
992 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
993 s->filter.simple, 1);
6f0db2eeaf70 vp8: Save mb border needed for intra prediction so that loop filter can run
conrad
parents: 12169
diff changeset
994
11921
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
995 if (mb->mode < MODE_I4x4) {
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
996 mode = check_intra_pred_mode(mb->mode, mb_x, mb_y);
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
997 s->hpc.pred16x16[mode](dst[0], s->linesize);
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
998 } else {
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
999 uint8_t *ptr = dst[0];
12221
45852dac8338 Avoid tracking i4x4 modes in P-frames in VP8
darkshikari
parents: 12220
diff changeset
1000 int stride = s->keyframe ? s->b4_stride : 4;
11921
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1001
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1002 // all blocks on the right edge of the macroblock use bottom edge
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1003 // the top macroblock for their topright edge
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1004 uint8_t *tr_right = ptr - s->linesize + 16;
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1005
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1006 // if we're on the right edge of the frame, said edge is extended
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1007 // from the top macroblock
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1008 if (mb_x == s->mb_width-1) {
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1009 tr = tr_right[-1]*0x01010101;
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1010 tr_right = (uint8_t *)&tr;
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1011 }
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1012
12234
bba849c2a113 VP8: avoid a memset for non-i4x4 blocks with no coefficients
darkshikari
parents: 12233
diff changeset
1013 if (mb->skip)
bba849c2a113 VP8: avoid a memset for non-i4x4 blocks with no coefficients
darkshikari
parents: 12233
diff changeset
1014 AV_ZERO128(s->non_zero_count_cache);
bba849c2a113 VP8: avoid a memset for non-i4x4 blocks with no coefficients
darkshikari
parents: 12233
diff changeset
1015
11921
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1016 for (y = 0; y < 4; y++) {
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1017 uint8_t *topright = ptr + 4 - s->linesize;
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1018 for (x = 0; x < 4; x++) {
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1019 if (x == 3)
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1020 topright = tr_right;
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1021
12221
45852dac8338 Avoid tracking i4x4 modes in P-frames in VP8
darkshikari
parents: 12220
diff changeset
1022 s->hpc.pred4x4[intra4x4[x]](ptr+4*x, topright, s->linesize);
11921
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1023
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1024 nnz = s->non_zero_count_cache[y][x];
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1025 if (nnz) {
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1026 if (nnz == 1)
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1027 s->vp8dsp.vp8_idct_dc_add(ptr+4*x, s->block[y][x], s->linesize);
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1028 else
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1029 s->vp8dsp.vp8_idct_add(ptr+4*x, s->block[y][x], s->linesize);
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1030 }
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1031 topright += 4;
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1032 }
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1033
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1034 ptr += 4*s->linesize;
12221
45852dac8338 Avoid tracking i4x4 modes in P-frames in VP8
darkshikari
parents: 12220
diff changeset
1035 intra4x4 += stride;
11921
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1036 }
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1037 }
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1038
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1039 mode = check_intra_pred_mode(s->chroma_pred_mode, mb_x, mb_y);
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1040 s->hpc.pred8x8[mode](dst[1], s->uvlinesize);
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1041 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
1042
6f0db2eeaf70 vp8: Save mb border needed for intra prediction so that loop filter can run
conrad
parents: 12169
diff changeset
1043 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
1044 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
1045 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
1046 s->filter.simple, 0);
11921
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1047 }
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1048
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1049 /**
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1050 * Generic MC function.
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1051 *
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1052 * @param s VP8 decoding context
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1053 * @param luma 1 for luma (Y) planes, 0 for chroma (Cb/Cr) planes
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1054 * @param dst target buffer for block data at block position
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1055 * @param src reference picture buffer at origin (0, 0)
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1056 * @param mv motion vector (relative to block position) to get pixel data from
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1057 * @param x_off horizontal position of block from origin (0, 0)
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1058 * @param y_off vertical position of block from origin (0, 0)
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1059 * @param block_w width of block (16, 8 or 4)
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1060 * @param block_h height of block (always same as block_w)
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1061 * @param width width of src/dst plane data
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1062 * @param height height of src/dst plane data
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1063 * @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
1064 * @param mc_func motion compensation function pointers (bilinear or sixtap MC)
11921
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1065 */
12248
121272849def VP8: always_inline some things to force gcc to do the right thing
darkshikari
parents: 12247
diff changeset
1066 static av_always_inline
121272849def VP8: always_inline some things to force gcc to do the right thing
darkshikari
parents: 12247
diff changeset
1067 void vp8_mc(VP8Context *s, int luma,
121272849def VP8: always_inline some things to force gcc to do the right thing
darkshikari
parents: 12247
diff changeset
1068 uint8_t *dst, uint8_t *src, const VP56mv *mv,
121272849def VP8: always_inline some things to force gcc to do the right thing
darkshikari
parents: 12247
diff changeset
1069 int x_off, int y_off, int block_w, int block_h,
121272849def VP8: always_inline some things to force gcc to do the right thing
darkshikari
parents: 12247
diff changeset
1070 int width, int height, int linesize,
121272849def VP8: always_inline some things to force gcc to do the right thing
darkshikari
parents: 12247
diff changeset
1071 vp8_mc_func mc_func[3][3])
11921
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1072 {
12218
1696e915ae2e Take shortcuts for mv0 case in VP8 MC
darkshikari
parents: 12217
diff changeset
1073 if (AV_RN32A(mv)) {
1696e915ae2e Take shortcuts for mv0 case in VP8 MC
darkshikari
parents: 12217
diff changeset
1074 static const uint8_t idx[8] = { 0, 1, 2, 1, 2, 1, 2, 1 };
1696e915ae2e Take shortcuts for mv0 case in VP8 MC
darkshikari
parents: 12217
diff changeset
1075 int mx = (mv->x << luma)&7, mx_idx = idx[mx];
1696e915ae2e Take shortcuts for mv0 case in VP8 MC
darkshikari
parents: 12217
diff changeset
1076 int my = (mv->y << luma)&7, my_idx = idx[my];
11921
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1077
12218
1696e915ae2e Take shortcuts for mv0 case in VP8 MC
darkshikari
parents: 12217
diff changeset
1078 x_off += mv->x >> (3 - luma);
1696e915ae2e Take shortcuts for mv0 case in VP8 MC
darkshikari
parents: 12217
diff changeset
1079 y_off += mv->y >> (3 - luma);
11921
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1080
12218
1696e915ae2e Take shortcuts for mv0 case in VP8 MC
darkshikari
parents: 12217
diff changeset
1081 // edge emulation
1696e915ae2e Take shortcuts for mv0 case in VP8 MC
darkshikari
parents: 12217
diff changeset
1082 src += y_off * linesize + x_off;
1696e915ae2e Take shortcuts for mv0 case in VP8 MC
darkshikari
parents: 12217
diff changeset
1083 if (x_off < 2 || x_off >= width - block_w - 3 ||
1696e915ae2e Take shortcuts for mv0 case in VP8 MC
darkshikari
parents: 12217
diff changeset
1084 y_off < 2 || y_off >= height - block_h - 3) {
1696e915ae2e Take shortcuts for mv0 case in VP8 MC
darkshikari
parents: 12217
diff changeset
1085 ff_emulated_edge_mc(s->edge_emu_buffer, src - 2 * linesize - 2, linesize,
1696e915ae2e Take shortcuts for mv0 case in VP8 MC
darkshikari
parents: 12217
diff changeset
1086 block_w + 5, block_h + 5,
1696e915ae2e Take shortcuts for mv0 case in VP8 MC
darkshikari
parents: 12217
diff changeset
1087 x_off - 2, y_off - 2, width, height);
1696e915ae2e Take shortcuts for mv0 case in VP8 MC
darkshikari
parents: 12217
diff changeset
1088 src = s->edge_emu_buffer + 2 + linesize * 2;
1696e915ae2e Take shortcuts for mv0 case in VP8 MC
darkshikari
parents: 12217
diff changeset
1089 }
1696e915ae2e Take shortcuts for mv0 case in VP8 MC
darkshikari
parents: 12217
diff changeset
1090 mc_func[my_idx][mx_idx](dst, linesize, src, linesize, block_h, mx, my);
1696e915ae2e Take shortcuts for mv0 case in VP8 MC
darkshikari
parents: 12217
diff changeset
1091 } else
1696e915ae2e Take shortcuts for mv0 case in VP8 MC
darkshikari
parents: 12217
diff changeset
1092 mc_func[0][0](dst, linesize, src + y_off * linesize + x_off, linesize, block_h, 0, 0);
11921
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1093 }
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1094
12248
121272849def VP8: always_inline some things to force gcc to do the right thing
darkshikari
parents: 12247
diff changeset
1095 static av_always_inline
121272849def VP8: always_inline some things to force gcc to do the right thing
darkshikari
parents: 12247
diff changeset
1096 void vp8_mc_part(VP8Context *s, uint8_t *dst[3],
121272849def VP8: always_inline some things to force gcc to do the right thing
darkshikari
parents: 12247
diff changeset
1097 AVFrame *ref_frame, int x_off, int y_off,
121272849def VP8: always_inline some things to force gcc to do the right thing
darkshikari
parents: 12247
diff changeset
1098 int bx_off, int by_off,
121272849def VP8: always_inline some things to force gcc to do the right thing
darkshikari
parents: 12247
diff changeset
1099 int block_w, int block_h,
121272849def VP8: always_inline some things to force gcc to do the right thing
darkshikari
parents: 12247
diff changeset
1100 int width, int height, VP56mv *mv)
11989
176c5deb6756 Optimize split MC, so we don't always do 4x4 blocks of 4x4pixels each, but
rbultje
parents: 11974
diff changeset
1101 {
176c5deb6756 Optimize split MC, so we don't always do 4x4 blocks of 4x4pixels each, but
rbultje
parents: 11974
diff changeset
1102 VP56mv uvmv = *mv;
176c5deb6756 Optimize split MC, so we don't always do 4x4 blocks of 4x4pixels each, but
rbultje
parents: 11974
diff changeset
1103
176c5deb6756 Optimize split MC, so we don't always do 4x4 blocks of 4x4pixels each, but
rbultje
parents: 11974
diff changeset
1104 /* Y */
176c5deb6756 Optimize split MC, so we don't always do 4x4 blocks of 4x4pixels each, but
rbultje
parents: 11974
diff changeset
1105 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
1106 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
1107 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
1108 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
1109
176c5deb6756 Optimize split MC, so we don't always do 4x4 blocks of 4x4pixels each, but
rbultje
parents: 11974
diff changeset
1110 /* U/V */
176c5deb6756 Optimize split MC, so we don't always do 4x4 blocks of 4x4pixels each, but
rbultje
parents: 11974
diff changeset
1111 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
1112 uvmv.x &= ~7;
176c5deb6756 Optimize split MC, so we don't always do 4x4 blocks of 4x4pixels each, but
rbultje
parents: 11974
diff changeset
1113 uvmv.y &= ~7;
176c5deb6756 Optimize split MC, so we don't always do 4x4 blocks of 4x4pixels each, but
rbultje
parents: 11974
diff changeset
1114 }
176c5deb6756 Optimize split MC, so we don't always do 4x4 blocks of 4x4pixels each, but
rbultje
parents: 11974
diff changeset
1115 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
1116 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
1117 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
1118 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
1119 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
1120 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
1121 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
1122 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
1123 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
1124 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
1125 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
1126 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
1127 }
176c5deb6756 Optimize split MC, so we don't always do 4x4 blocks of 4x4pixels each, but
rbultje
parents: 11974
diff changeset
1128
12215
58d828f9810f Add prefetching to VP8 decoder
darkshikari
parents: 12202
diff changeset
1129 /* Fetch pixels for estimated mv 4 macroblocks ahead.
58d828f9810f Add prefetching to VP8 decoder
darkshikari
parents: 12202
diff changeset
1130 * Optimized for 64-byte cache lines. Inspired by ffh264 prefetch_motion. */
12248
121272849def VP8: always_inline some things to force gcc to do the right thing
darkshikari
parents: 12247
diff changeset
1131 static av_always_inline void prefetch_motion(VP8Context *s, VP8Macroblock *mb, int mb_x, int mb_y, int mb_xy, int ref)
12215
58d828f9810f Add prefetching to VP8 decoder
darkshikari
parents: 12202
diff changeset
1132 {
12237
f0c4dc49c8f1 VP8: smarter prefetching
darkshikari
parents: 12235
diff changeset
1133 /* Don't prefetch refs that haven't been used very often this frame. */
f0c4dc49c8f1 VP8: smarter prefetching
darkshikari
parents: 12235
diff changeset
1134 if (s->ref_count[ref-1] > (mb_xy >> 5)) {
12231
d3f3897ddb5c Smarter VP8 prefetching
darkshikari
parents: 12230
diff changeset
1135 int x_off = mb_x << 4, y_off = mb_y << 4;
d3f3897ddb5c Smarter VP8 prefetching
darkshikari
parents: 12230
diff changeset
1136 int mx = mb->mv.x + x_off + 8;
d3f3897ddb5c Smarter VP8 prefetching
darkshikari
parents: 12230
diff changeset
1137 int my = mb->mv.y + y_off;
d3f3897ddb5c Smarter VP8 prefetching
darkshikari
parents: 12230
diff changeset
1138 uint8_t **src= s->framep[ref]->data;
d3f3897ddb5c Smarter VP8 prefetching
darkshikari
parents: 12230
diff changeset
1139 int off= mx + (my + (mb_x&3)*4)*s->linesize + 64;
d3f3897ddb5c Smarter VP8 prefetching
darkshikari
parents: 12230
diff changeset
1140 s->dsp.prefetch(src[0]+off, s->linesize, 4);
d3f3897ddb5c Smarter VP8 prefetching
darkshikari
parents: 12230
diff changeset
1141 off= (mx>>1) + ((my>>1) + (mb_x&7))*s->uvlinesize + 64;
d3f3897ddb5c Smarter VP8 prefetching
darkshikari
parents: 12230
diff changeset
1142 s->dsp.prefetch(src[1]+off, src[2]-src[1], 2);
d3f3897ddb5c Smarter VP8 prefetching
darkshikari
parents: 12230
diff changeset
1143 }
12215
58d828f9810f Add prefetching to VP8 decoder
darkshikari
parents: 12202
diff changeset
1144 }
58d828f9810f Add prefetching to VP8 decoder
darkshikari
parents: 12202
diff changeset
1145
11921
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1146 /**
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1147 * Apply motion vectors to prediction buffer, chapter 18.
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1148 */
12248
121272849def VP8: always_inline some things to force gcc to do the right thing
darkshikari
parents: 12247
diff changeset
1149 static av_always_inline
121272849def VP8: always_inline some things to force gcc to do the right thing
darkshikari
parents: 12247
diff changeset
1150 void inter_predict(VP8Context *s, uint8_t *dst[3], VP8Macroblock *mb,
121272849def VP8: always_inline some things to force gcc to do the right thing
darkshikari
parents: 12247
diff changeset
1151 int mb_x, int mb_y)
11921
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1152 {
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1153 int x_off = mb_x << 4, y_off = mb_y << 4;
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1154 int width = 16*s->mb_width, height = 16*s->mb_height;
12228
9c63566f623f Eliminate some repeated dereferences in VP8 inter_predict
darkshikari
parents: 12225
diff changeset
1155 AVFrame *ref = s->framep[mb->ref_frame];
9c63566f623f Eliminate some repeated dereferences in VP8 inter_predict
darkshikari
parents: 12225
diff changeset
1156 VP56mv *bmv = mb->bmv;
11921
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1157
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1158 if (mb->mode < VP8_MVMODE_SPLIT) {
12228
9c63566f623f Eliminate some repeated dereferences in VP8 inter_predict
darkshikari
parents: 12225
diff changeset
1159 vp8_mc_part(s, dst, ref, x_off, y_off,
11989
176c5deb6756 Optimize split MC, so we don't always do 4x4 blocks of 4x4pixels each, but
rbultje
parents: 11974
diff changeset
1160 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
1161 } 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
1162 case VP8_SPLITMVMODE_4x4: {
11921
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1163 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
1164 VP56mv uvmv;
11921
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1165
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1166 /* Y */
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1167 for (y = 0; y < 4; y++) {
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1168 for (x = 0; x < 4; x++) {
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1169 vp8_mc(s, 1, dst[0] + 4*y*s->linesize + x*4,
12228
9c63566f623f Eliminate some repeated dereferences in VP8 inter_predict
darkshikari
parents: 12225
diff changeset
1170 ref->data[0], &bmv[4*y + x],
11921
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1171 4*x + x_off, 4*y + y_off, 4, 4,
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1172 width, height, s->linesize,
11974
356b20a6566d VP8 bilinear filter
conrad
parents: 11970
diff changeset
1173 s->put_pixels_tab[2]);
11921
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1174 }
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1175 }
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1176
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1177 /* U/V */
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1178 x_off >>= 1; y_off >>= 1; width >>= 1; height >>= 1;
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1179 for (y = 0; y < 2; y++) {
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1180 for (x = 0; x < 2; x++) {
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1181 uvmv.x = mb->bmv[ 2*y * 4 + 2*x ].x +
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1182 mb->bmv[ 2*y * 4 + 2*x+1].x +
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1183 mb->bmv[(2*y+1) * 4 + 2*x ].x +
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1184 mb->bmv[(2*y+1) * 4 + 2*x+1].x;
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1185 uvmv.y = mb->bmv[ 2*y * 4 + 2*x ].y +
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1186 mb->bmv[ 2*y * 4 + 2*x+1].y +
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1187 mb->bmv[(2*y+1) * 4 + 2*x ].y +
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1188 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
1189 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
1190 uvmv.y = (uvmv.y + 2 + (uvmv.y >> (INT_BIT-1))) >> 2;
11921
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1191 if (s->profile == 3) {
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1192 uvmv.x &= ~7;
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1193 uvmv.y &= ~7;
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1194 }
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1195 vp8_mc(s, 0, dst[1] + 4*y*s->uvlinesize + x*4,
12228
9c63566f623f Eliminate some repeated dereferences in VP8 inter_predict
darkshikari
parents: 12225
diff changeset
1196 ref->data[1], &uvmv,
11921
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1197 4*x + x_off, 4*y + y_off, 4, 4,
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1198 width, height, s->uvlinesize,
11974
356b20a6566d VP8 bilinear filter
conrad
parents: 11970
diff changeset
1199 s->put_pixels_tab[2]);
11921
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1200 vp8_mc(s, 0, dst[2] + 4*y*s->uvlinesize + x*4,
12228
9c63566f623f Eliminate some repeated dereferences in VP8 inter_predict
darkshikari
parents: 12225
diff changeset
1201 ref->data[2], &uvmv,
11921
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1202 4*x + x_off, 4*y + y_off, 4, 4,
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1203 width, height, s->uvlinesize,
11974
356b20a6566d VP8 bilinear filter
conrad
parents: 11970
diff changeset
1204 s->put_pixels_tab[2]);
11921
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1205 }
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1206 }
11989
176c5deb6756 Optimize split MC, so we don't always do 4x4 blocks of 4x4pixels each, but
rbultje
parents: 11974
diff changeset
1207 break;
176c5deb6756 Optimize split MC, so we don't always do 4x4 blocks of 4x4pixels each, but
rbultje
parents: 11974
diff changeset
1208 }
176c5deb6756 Optimize split MC, so we don't always do 4x4 blocks of 4x4pixels each, but
rbultje
parents: 11974
diff changeset
1209 case VP8_SPLITMVMODE_16x8:
12228
9c63566f623f Eliminate some repeated dereferences in VP8 inter_predict
darkshikari
parents: 12225
diff changeset
1210 vp8_mc_part(s, dst, ref, x_off, y_off,
9c63566f623f Eliminate some repeated dereferences in VP8 inter_predict
darkshikari
parents: 12225
diff changeset
1211 0, 0, 16, 8, width, height, &bmv[0]);
9c63566f623f Eliminate some repeated dereferences in VP8 inter_predict
darkshikari
parents: 12225
diff changeset
1212 vp8_mc_part(s, dst, ref, x_off, y_off,
9c63566f623f Eliminate some repeated dereferences in VP8 inter_predict
darkshikari
parents: 12225
diff changeset
1213 0, 8, 16, 8, width, height, &bmv[1]);
11989
176c5deb6756 Optimize split MC, so we don't always do 4x4 blocks of 4x4pixels each, but
rbultje
parents: 11974
diff changeset
1214 break;
176c5deb6756 Optimize split MC, so we don't always do 4x4 blocks of 4x4pixels each, but
rbultje
parents: 11974
diff changeset
1215 case VP8_SPLITMVMODE_8x16:
12228
9c63566f623f Eliminate some repeated dereferences in VP8 inter_predict
darkshikari
parents: 12225
diff changeset
1216 vp8_mc_part(s, dst, ref, x_off, y_off,
9c63566f623f Eliminate some repeated dereferences in VP8 inter_predict
darkshikari
parents: 12225
diff changeset
1217 0, 0, 8, 16, width, height, &bmv[0]);
9c63566f623f Eliminate some repeated dereferences in VP8 inter_predict
darkshikari
parents: 12225
diff changeset
1218 vp8_mc_part(s, dst, ref, x_off, y_off,
9c63566f623f Eliminate some repeated dereferences in VP8 inter_predict
darkshikari
parents: 12225
diff changeset
1219 8, 0, 8, 16, width, height, &bmv[1]);
11989
176c5deb6756 Optimize split MC, so we don't always do 4x4 blocks of 4x4pixels each, but
rbultje
parents: 11974
diff changeset
1220 break;
176c5deb6756 Optimize split MC, so we don't always do 4x4 blocks of 4x4pixels each, but
rbultje
parents: 11974
diff changeset
1221 case VP8_SPLITMVMODE_8x8:
12228
9c63566f623f Eliminate some repeated dereferences in VP8 inter_predict
darkshikari
parents: 12225
diff changeset
1222 vp8_mc_part(s, dst, ref, x_off, y_off,
9c63566f623f Eliminate some repeated dereferences in VP8 inter_predict
darkshikari
parents: 12225
diff changeset
1223 0, 0, 8, 8, width, height, &bmv[0]);
9c63566f623f Eliminate some repeated dereferences in VP8 inter_predict
darkshikari
parents: 12225
diff changeset
1224 vp8_mc_part(s, dst, ref, x_off, y_off,
9c63566f623f Eliminate some repeated dereferences in VP8 inter_predict
darkshikari
parents: 12225
diff changeset
1225 8, 0, 8, 8, width, height, &bmv[1]);
9c63566f623f Eliminate some repeated dereferences in VP8 inter_predict
darkshikari
parents: 12225
diff changeset
1226 vp8_mc_part(s, dst, ref, x_off, y_off,
9c63566f623f Eliminate some repeated dereferences in VP8 inter_predict
darkshikari
parents: 12225
diff changeset
1227 0, 8, 8, 8, width, height, &bmv[2]);
9c63566f623f Eliminate some repeated dereferences in VP8 inter_predict
darkshikari
parents: 12225
diff changeset
1228 vp8_mc_part(s, dst, ref, x_off, y_off,
9c63566f623f Eliminate some repeated dereferences in VP8 inter_predict
darkshikari
parents: 12225
diff changeset
1229 8, 8, 8, 8, width, height, &bmv[3]);
11989
176c5deb6756 Optimize split MC, so we don't always do 4x4 blocks of 4x4pixels each, but
rbultje
parents: 11974
diff changeset
1230 break;
11921
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1231 }
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1232 }
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1233
12248
121272849def VP8: always_inline some things to force gcc to do the right thing
darkshikari
parents: 12247
diff changeset
1234 static av_always_inline void idct_mb(VP8Context *s, uint8_t *dst[3], VP8Macroblock *mb)
11921
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1235 {
12240
e6ade5e849c9 VP8: Clean up some variable shadowing.
darkshikari
parents: 12238
diff changeset
1236 int x, y, ch;
11921
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1237
12238
1a7903913e9b VP8: 30% faster idct_mb
darkshikari
parents: 12237
diff changeset
1238 if (mb->mode != MODE_I4x4) {
1a7903913e9b VP8: 30% faster idct_mb
darkshikari
parents: 12237
diff changeset
1239 uint8_t *y_dst = dst[0];
11921
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1240 for (y = 0; y < 4; y++) {
12240
e6ade5e849c9 VP8: Clean up some variable shadowing.
darkshikari
parents: 12238
diff changeset
1241 uint32_t nnz4 = AV_RN32A(s->non_zero_count_cache[y]);
e6ade5e849c9 VP8: Clean up some variable shadowing.
darkshikari
parents: 12238
diff changeset
1242 if (nnz4) {
e6ade5e849c9 VP8: Clean up some variable shadowing.
darkshikari
parents: 12238
diff changeset
1243 if (nnz4&~0x01010101) {
12238
1a7903913e9b VP8: 30% faster idct_mb
darkshikari
parents: 12237
diff changeset
1244 for (x = 0; x < 4; x++) {
12240
e6ade5e849c9 VP8: Clean up some variable shadowing.
darkshikari
parents: 12238
diff changeset
1245 int nnz = s->non_zero_count_cache[y][x];
12238
1a7903913e9b VP8: 30% faster idct_mb
darkshikari
parents: 12237
diff changeset
1246 if (nnz) {
1a7903913e9b VP8: 30% faster idct_mb
darkshikari
parents: 12237
diff changeset
1247 if (nnz == 1)
1a7903913e9b VP8: 30% faster idct_mb
darkshikari
parents: 12237
diff changeset
1248 s->vp8dsp.vp8_idct_dc_add(y_dst+4*x, s->block[y][x], s->linesize);
1a7903913e9b VP8: 30% faster idct_mb
darkshikari
parents: 12237
diff changeset
1249 else
1a7903913e9b VP8: 30% faster idct_mb
darkshikari
parents: 12237
diff changeset
1250 s->vp8dsp.vp8_idct_add(y_dst+4*x, s->block[y][x], s->linesize);
1a7903913e9b VP8: 30% faster idct_mb
darkshikari
parents: 12237
diff changeset
1251 }
1a7903913e9b VP8: 30% faster idct_mb
darkshikari
parents: 12237
diff changeset
1252 }
1a7903913e9b VP8: 30% faster idct_mb
darkshikari
parents: 12237
diff changeset
1253 } else {
12241
c7f6ddcc5c01 VP8: optimize DC-only chroma case in the same way as luma.
darkshikari
parents: 12240
diff changeset
1254 s->vp8dsp.vp8_idct_dc_add4y(y_dst, s->block[y], s->linesize);
11921
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1255 }
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1256 }
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1257 y_dst += 4*s->linesize;
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1258 }
12238
1a7903913e9b VP8: 30% faster idct_mb
darkshikari
parents: 12237
diff changeset
1259 }
11921
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1260
12238
1a7903913e9b VP8: 30% faster idct_mb
darkshikari
parents: 12237
diff changeset
1261 for (ch = 0; ch < 2; ch++) {
12241
c7f6ddcc5c01 VP8: optimize DC-only chroma case in the same way as luma.
darkshikari
parents: 12240
diff changeset
1262 uint32_t nnz4 = AV_RN32A(s->non_zero_count_cache[4+ch]);
c7f6ddcc5c01 VP8: optimize DC-only chroma case in the same way as luma.
darkshikari
parents: 12240
diff changeset
1263 if (nnz4) {
12238
1a7903913e9b VP8: 30% faster idct_mb
darkshikari
parents: 12237
diff changeset
1264 uint8_t *ch_dst = dst[1+ch];
12241
c7f6ddcc5c01 VP8: optimize DC-only chroma case in the same way as luma.
darkshikari
parents: 12240
diff changeset
1265 if (nnz4&~0x01010101) {
c7f6ddcc5c01 VP8: optimize DC-only chroma case in the same way as luma.
darkshikari
parents: 12240
diff changeset
1266 for (y = 0; y < 2; y++) {
c7f6ddcc5c01 VP8: optimize DC-only chroma case in the same way as luma.
darkshikari
parents: 12240
diff changeset
1267 for (x = 0; x < 2; x++) {
c7f6ddcc5c01 VP8: optimize DC-only chroma case in the same way as luma.
darkshikari
parents: 12240
diff changeset
1268 int nnz = s->non_zero_count_cache[4+ch][(y<<1)+x];
c7f6ddcc5c01 VP8: optimize DC-only chroma case in the same way as luma.
darkshikari
parents: 12240
diff changeset
1269 if (nnz) {
c7f6ddcc5c01 VP8: optimize DC-only chroma case in the same way as luma.
darkshikari
parents: 12240
diff changeset
1270 if (nnz == 1)
c7f6ddcc5c01 VP8: optimize DC-only chroma case in the same way as luma.
darkshikari
parents: 12240
diff changeset
1271 s->vp8dsp.vp8_idct_dc_add(ch_dst+4*x, s->block[4+ch][(y<<1)+x], s->uvlinesize);
c7f6ddcc5c01 VP8: optimize DC-only chroma case in the same way as luma.
darkshikari
parents: 12240
diff changeset
1272 else
c7f6ddcc5c01 VP8: optimize DC-only chroma case in the same way as luma.
darkshikari
parents: 12240
diff changeset
1273 s->vp8dsp.vp8_idct_add(ch_dst+4*x, s->block[4+ch][(y<<1)+x], s->uvlinesize);
c7f6ddcc5c01 VP8: optimize DC-only chroma case in the same way as luma.
darkshikari
parents: 12240
diff changeset
1274 }
12238
1a7903913e9b VP8: 30% faster idct_mb
darkshikari
parents: 12237
diff changeset
1275 }
12241
c7f6ddcc5c01 VP8: optimize DC-only chroma case in the same way as luma.
darkshikari
parents: 12240
diff changeset
1276 ch_dst += 4*s->uvlinesize;
12238
1a7903913e9b VP8: 30% faster idct_mb
darkshikari
parents: 12237
diff changeset
1277 }
12241
c7f6ddcc5c01 VP8: optimize DC-only chroma case in the same way as luma.
darkshikari
parents: 12240
diff changeset
1278 } else {
c7f6ddcc5c01 VP8: optimize DC-only chroma case in the same way as luma.
darkshikari
parents: 12240
diff changeset
1279 s->vp8dsp.vp8_idct_dc_add4uv(ch_dst, s->block[4+ch], s->uvlinesize);
11921
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1280 }
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1281 }
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1282 }
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1283 }
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1284
12248
121272849def VP8: always_inline some things to force gcc to do the right thing
darkshikari
parents: 12247
diff changeset
1285 static av_always_inline void filter_level_for_mb(VP8Context *s, VP8Macroblock *mb, VP8FilterStrength *f )
11921
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1286 {
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1287 int interior_limit, filter_level;
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1288
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1289 if (s->segmentation.enabled) {
12224
5b7d690b761b VP8: Don't store segment in macroblock struct anymore.
darkshikari
parents: 12223
diff changeset
1290 filter_level = s->segmentation.filter_level[s->segment];
11921
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1291 if (!s->segmentation.absolute_vals)
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1292 filter_level += s->filter.level;
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1293 } else
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1294 filter_level = s->filter.level;
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1295
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1296 if (s->lf_delta.enabled) {
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1297 filter_level += s->lf_delta.ref[mb->ref_frame];
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1298
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1299 if (mb->ref_frame == VP56_FRAME_CURRENT) {
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1300 if (mb->mode == MODE_I4x4)
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1301 filter_level += s->lf_delta.mode[0];
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1302 } else {
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1303 if (mb->mode == VP8_MVMODE_ZERO)
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1304 filter_level += s->lf_delta.mode[1];
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1305 else if (mb->mode == VP8_MVMODE_SPLIT)
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1306 filter_level += s->lf_delta.mode[3];
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1307 else
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1308 filter_level += s->lf_delta.mode[2];
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1309 }
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1310 }
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1311 filter_level = av_clip(filter_level, 0, 63);
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1312
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1313 interior_limit = filter_level;
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1314 if (s->filter.sharpness) {
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1315 interior_limit >>= s->filter.sharpness > 4 ? 2 : 1;
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1316 interior_limit = FFMIN(interior_limit, 9 - s->filter.sharpness);
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1317 }
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1318 interior_limit = FFMAX(interior_limit, 1);
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1319
12222
7acdbfd2a222 Calculate deblock strength per-MB instead of per-row
darkshikari
parents: 12221
diff changeset
1320 f->filter_level = filter_level;
7acdbfd2a222 Calculate deblock strength per-MB instead of per-row
darkshikari
parents: 12221
diff changeset
1321 f->inner_limit = interior_limit;
12223
93e27a5401de Convert VP8 macroblock structures to a ring buffer.
darkshikari
parents: 12222
diff changeset
1322 f->inner_filter = !mb->skip || mb->mode == MODE_I4x4 || mb->mode == VP8_MVMODE_SPLIT;
11921
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1323 }
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1324
12248
121272849def VP8: always_inline some things to force gcc to do the right thing
darkshikari
parents: 12247
diff changeset
1325 static av_always_inline void filter_mb(VP8Context *s, uint8_t *dst[3], VP8FilterStrength *f, int mb_x, int mb_y)
11921
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1326 {
12222
7acdbfd2a222 Calculate deblock strength per-MB instead of per-row
darkshikari
parents: 12221
diff changeset
1327 int mbedge_lim, bedge_lim, hev_thresh;
7acdbfd2a222 Calculate deblock strength per-MB instead of per-row
darkshikari
parents: 12221
diff changeset
1328 int filter_level = f->filter_level;
7acdbfd2a222 Calculate deblock strength per-MB instead of per-row
darkshikari
parents: 12221
diff changeset
1329 int inner_limit = f->inner_limit;
12223
93e27a5401de Convert VP8 macroblock structures to a ring buffer.
darkshikari
parents: 12222
diff changeset
1330 int inner_filter = f->inner_filter;
12233
10b02cbc3cc2 Get rid of more unnecessary dereferences in VP8 deblocking
darkshikari
parents: 12232
diff changeset
1331 int linesize = s->linesize;
10b02cbc3cc2 Get rid of more unnecessary dereferences in VP8 deblocking
darkshikari
parents: 12232
diff changeset
1332 int uvlinesize = s->uvlinesize;
11921
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1333
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1334 if (!filter_level)
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1335 return;
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1336
12081
812e23197d64 VP8: Move calculation of outer filter limit out of dsp functions for normal
conrad
parents: 12062
diff changeset
1337 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
1338 bedge_lim = 2* filter_level + inner_limit;
12222
7acdbfd2a222 Calculate deblock strength per-MB instead of per-row
darkshikari
parents: 12221
diff changeset
1339 hev_thresh = filter_level >= 15;
7acdbfd2a222 Calculate deblock strength per-MB instead of per-row
darkshikari
parents: 12221
diff changeset
1340
7acdbfd2a222 Calculate deblock strength per-MB instead of per-row
darkshikari
parents: 12221
diff changeset
1341 if (s->keyframe) {
7acdbfd2a222 Calculate deblock strength per-MB instead of per-row
darkshikari
parents: 12221
diff changeset
1342 if (filter_level >= 40)
7acdbfd2a222 Calculate deblock strength per-MB instead of per-row
darkshikari
parents: 12221
diff changeset
1343 hev_thresh = 2;
7acdbfd2a222 Calculate deblock strength per-MB instead of per-row
darkshikari
parents: 12221
diff changeset
1344 } else {
7acdbfd2a222 Calculate deblock strength per-MB instead of per-row
darkshikari
parents: 12221
diff changeset
1345 if (filter_level >= 40)
7acdbfd2a222 Calculate deblock strength per-MB instead of per-row
darkshikari
parents: 12221
diff changeset
1346 hev_thresh = 3;
7acdbfd2a222 Calculate deblock strength per-MB instead of per-row
darkshikari
parents: 12221
diff changeset
1347 else if (filter_level >= 20)
7acdbfd2a222 Calculate deblock strength per-MB instead of per-row
darkshikari
parents: 12221
diff changeset
1348 hev_thresh = 2;
7acdbfd2a222 Calculate deblock strength per-MB instead of per-row
darkshikari
parents: 12221
diff changeset
1349 }
12081
812e23197d64 VP8: Move calculation of outer filter limit out of dsp functions for normal
conrad
parents: 12062
diff changeset
1350
11921
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1351 if (mb_x) {
12233
10b02cbc3cc2 Get rid of more unnecessary dereferences in VP8 deblocking
darkshikari
parents: 12232
diff changeset
1352 s->vp8dsp.vp8_h_loop_filter16y(dst[0], linesize,
12194
80b142c2e9f7 Change function prototypes for width=8 inner and mbedge loopfilter functions
rbultje
parents: 12170
diff changeset
1353 mbedge_lim, inner_limit, hev_thresh);
12233
10b02cbc3cc2 Get rid of more unnecessary dereferences in VP8 deblocking
darkshikari
parents: 12232
diff changeset
1354 s->vp8dsp.vp8_h_loop_filter8uv(dst[1], dst[2], uvlinesize,
12194
80b142c2e9f7 Change function prototypes for width=8 inner and mbedge loopfilter functions
rbultje
parents: 12170
diff changeset
1355 mbedge_lim, inner_limit, hev_thresh);
11921
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1356 }
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1357
12223
93e27a5401de Convert VP8 macroblock structures to a ring buffer.
darkshikari
parents: 12222
diff changeset
1358 if (inner_filter) {
12233
10b02cbc3cc2 Get rid of more unnecessary dereferences in VP8 deblocking
darkshikari
parents: 12232
diff changeset
1359 s->vp8dsp.vp8_h_loop_filter16y_inner(dst[0]+ 4, linesize, bedge_lim,
10b02cbc3cc2 Get rid of more unnecessary dereferences in VP8 deblocking
darkshikari
parents: 12232
diff changeset
1360 inner_limit, hev_thresh);
10b02cbc3cc2 Get rid of more unnecessary dereferences in VP8 deblocking
darkshikari
parents: 12232
diff changeset
1361 s->vp8dsp.vp8_h_loop_filter16y_inner(dst[0]+ 8, linesize, bedge_lim,
10b02cbc3cc2 Get rid of more unnecessary dereferences in VP8 deblocking
darkshikari
parents: 12232
diff changeset
1362 inner_limit, hev_thresh);
10b02cbc3cc2 Get rid of more unnecessary dereferences in VP8 deblocking
darkshikari
parents: 12232
diff changeset
1363 s->vp8dsp.vp8_h_loop_filter16y_inner(dst[0]+12, linesize, bedge_lim,
10b02cbc3cc2 Get rid of more unnecessary dereferences in VP8 deblocking
darkshikari
parents: 12232
diff changeset
1364 inner_limit, hev_thresh);
10b02cbc3cc2 Get rid of more unnecessary dereferences in VP8 deblocking
darkshikari
parents: 12232
diff changeset
1365 s->vp8dsp.vp8_h_loop_filter8uv_inner(dst[1] + 4, dst[2] + 4,
10b02cbc3cc2 Get rid of more unnecessary dereferences in VP8 deblocking
darkshikari
parents: 12232
diff changeset
1366 uvlinesize, bedge_lim,
10b02cbc3cc2 Get rid of more unnecessary dereferences in VP8 deblocking
darkshikari
parents: 12232
diff changeset
1367 inner_limit, hev_thresh);
11921
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1368 }
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1369
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1370 if (mb_y) {
12233
10b02cbc3cc2 Get rid of more unnecessary dereferences in VP8 deblocking
darkshikari
parents: 12232
diff changeset
1371 s->vp8dsp.vp8_v_loop_filter16y(dst[0], linesize,
12194
80b142c2e9f7 Change function prototypes for width=8 inner and mbedge loopfilter functions
rbultje
parents: 12170
diff changeset
1372 mbedge_lim, inner_limit, hev_thresh);
12233
10b02cbc3cc2 Get rid of more unnecessary dereferences in VP8 deblocking
darkshikari
parents: 12232
diff changeset
1373 s->vp8dsp.vp8_v_loop_filter8uv(dst[1], dst[2], uvlinesize,
12194
80b142c2e9f7 Change function prototypes for width=8 inner and mbedge loopfilter functions
rbultje
parents: 12170
diff changeset
1374 mbedge_lim, inner_limit, hev_thresh);
11921
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1375 }
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1376
12223
93e27a5401de Convert VP8 macroblock structures to a ring buffer.
darkshikari
parents: 12222
diff changeset
1377 if (inner_filter) {
12233
10b02cbc3cc2 Get rid of more unnecessary dereferences in VP8 deblocking
darkshikari
parents: 12232
diff changeset
1378 s->vp8dsp.vp8_v_loop_filter16y_inner(dst[0]+ 4*linesize,
10b02cbc3cc2 Get rid of more unnecessary dereferences in VP8 deblocking
darkshikari
parents: 12232
diff changeset
1379 linesize, bedge_lim,
10b02cbc3cc2 Get rid of more unnecessary dereferences in VP8 deblocking
darkshikari
parents: 12232
diff changeset
1380 inner_limit, hev_thresh);
10b02cbc3cc2 Get rid of more unnecessary dereferences in VP8 deblocking
darkshikari
parents: 12232
diff changeset
1381 s->vp8dsp.vp8_v_loop_filter16y_inner(dst[0]+ 8*linesize,
10b02cbc3cc2 Get rid of more unnecessary dereferences in VP8 deblocking
darkshikari
parents: 12232
diff changeset
1382 linesize, bedge_lim,
12194
80b142c2e9f7 Change function prototypes for width=8 inner and mbedge loopfilter functions
rbultje
parents: 12170
diff changeset
1383 inner_limit, hev_thresh);
12233
10b02cbc3cc2 Get rid of more unnecessary dereferences in VP8 deblocking
darkshikari
parents: 12232
diff changeset
1384 s->vp8dsp.vp8_v_loop_filter16y_inner(dst[0]+12*linesize,
10b02cbc3cc2 Get rid of more unnecessary dereferences in VP8 deblocking
darkshikari
parents: 12232
diff changeset
1385 linesize, bedge_lim,
10b02cbc3cc2 Get rid of more unnecessary dereferences in VP8 deblocking
darkshikari
parents: 12232
diff changeset
1386 inner_limit, hev_thresh);
10b02cbc3cc2 Get rid of more unnecessary dereferences in VP8 deblocking
darkshikari
parents: 12232
diff changeset
1387 s->vp8dsp.vp8_v_loop_filter8uv_inner(dst[1] + 4 * uvlinesize,
10b02cbc3cc2 Get rid of more unnecessary dereferences in VP8 deblocking
darkshikari
parents: 12232
diff changeset
1388 dst[2] + 4 * uvlinesize,
10b02cbc3cc2 Get rid of more unnecessary dereferences in VP8 deblocking
darkshikari
parents: 12232
diff changeset
1389 uvlinesize, bedge_lim,
10b02cbc3cc2 Get rid of more unnecessary dereferences in VP8 deblocking
darkshikari
parents: 12232
diff changeset
1390 inner_limit, hev_thresh);
11921
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1391 }
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1392 }
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1393
12248
121272849def VP8: always_inline some things to force gcc to do the right thing
darkshikari
parents: 12247
diff changeset
1394 static av_always_inline void filter_mb_simple(VP8Context *s, uint8_t *dst, VP8FilterStrength *f, int mb_x, int mb_y)
11921
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1395 {
12222
7acdbfd2a222 Calculate deblock strength per-MB instead of per-row
darkshikari
parents: 12221
diff changeset
1396 int mbedge_lim, bedge_lim;
7acdbfd2a222 Calculate deblock strength per-MB instead of per-row
darkshikari
parents: 12221
diff changeset
1397 int filter_level = f->filter_level;
7acdbfd2a222 Calculate deblock strength per-MB instead of per-row
darkshikari
parents: 12221
diff changeset
1398 int inner_limit = f->inner_limit;
12223
93e27a5401de Convert VP8 macroblock structures to a ring buffer.
darkshikari
parents: 12222
diff changeset
1399 int inner_filter = f->inner_filter;
12233
10b02cbc3cc2 Get rid of more unnecessary dereferences in VP8 deblocking
darkshikari
parents: 12232
diff changeset
1400 int linesize = s->linesize;
11921
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1401
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1402 if (!filter_level)
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1403 return;
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1404
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1405 mbedge_lim = 2*(filter_level+2) + inner_limit;
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1406 bedge_lim = 2* filter_level + inner_limit;
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1407
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1408 if (mb_x)
12233
10b02cbc3cc2 Get rid of more unnecessary dereferences in VP8 deblocking
darkshikari
parents: 12232
diff changeset
1409 s->vp8dsp.vp8_h_loop_filter_simple(dst, linesize, mbedge_lim);
12223
93e27a5401de Convert VP8 macroblock structures to a ring buffer.
darkshikari
parents: 12222
diff changeset
1410 if (inner_filter) {
12233
10b02cbc3cc2 Get rid of more unnecessary dereferences in VP8 deblocking
darkshikari
parents: 12232
diff changeset
1411 s->vp8dsp.vp8_h_loop_filter_simple(dst+ 4, linesize, bedge_lim);
10b02cbc3cc2 Get rid of more unnecessary dereferences in VP8 deblocking
darkshikari
parents: 12232
diff changeset
1412 s->vp8dsp.vp8_h_loop_filter_simple(dst+ 8, linesize, bedge_lim);
10b02cbc3cc2 Get rid of more unnecessary dereferences in VP8 deblocking
darkshikari
parents: 12232
diff changeset
1413 s->vp8dsp.vp8_h_loop_filter_simple(dst+12, linesize, bedge_lim);
11921
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1414 }
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1415
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1416 if (mb_y)
12233
10b02cbc3cc2 Get rid of more unnecessary dereferences in VP8 deblocking
darkshikari
parents: 12232
diff changeset
1417 s->vp8dsp.vp8_v_loop_filter_simple(dst, linesize, mbedge_lim);
12223
93e27a5401de Convert VP8 macroblock structures to a ring buffer.
darkshikari
parents: 12222
diff changeset
1418 if (inner_filter) {
12233
10b02cbc3cc2 Get rid of more unnecessary dereferences in VP8 deblocking
darkshikari
parents: 12232
diff changeset
1419 s->vp8dsp.vp8_v_loop_filter_simple(dst+ 4*linesize, linesize, bedge_lim);
10b02cbc3cc2 Get rid of more unnecessary dereferences in VP8 deblocking
darkshikari
parents: 12232
diff changeset
1420 s->vp8dsp.vp8_v_loop_filter_simple(dst+ 8*linesize, linesize, bedge_lim);
10b02cbc3cc2 Get rid of more unnecessary dereferences in VP8 deblocking
darkshikari
parents: 12232
diff changeset
1421 s->vp8dsp.vp8_v_loop_filter_simple(dst+12*linesize, linesize, bedge_lim);
11921
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1422 }
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1423 }
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1424
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1425 static void filter_mb_row(VP8Context *s, int mb_y)
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1426 {
12222
7acdbfd2a222 Calculate deblock strength per-MB instead of per-row
darkshikari
parents: 12221
diff changeset
1427 VP8FilterStrength *f = s->filter_strength;
11921
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1428 uint8_t *dst[3] = {
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1429 s->framep[VP56_FRAME_CURRENT]->data[0] + 16*mb_y*s->linesize,
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1430 s->framep[VP56_FRAME_CURRENT]->data[1] + 8*mb_y*s->uvlinesize,
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1431 s->framep[VP56_FRAME_CURRENT]->data[2] + 8*mb_y*s->uvlinesize
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1432 };
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1433 int mb_x;
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1434
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1435 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
1436 backup_mb_border(s->top_border[mb_x+1], dst[0], dst[1], dst[2], s->linesize, s->uvlinesize, 0);
12223
93e27a5401de Convert VP8 macroblock structures to a ring buffer.
darkshikari
parents: 12222
diff changeset
1437 filter_mb(s, dst, f++, mb_x, mb_y);
11921
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1438 dst[0] += 16;
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1439 dst[1] += 8;
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1440 dst[2] += 8;
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1441 }
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1442 }
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1443
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1444 static void filter_mb_row_simple(VP8Context *s, int mb_y)
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1445 {
12222
7acdbfd2a222 Calculate deblock strength per-MB instead of per-row
darkshikari
parents: 12221
diff changeset
1446 VP8FilterStrength *f = s->filter_strength;
11921
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1447 uint8_t *dst = s->framep[VP56_FRAME_CURRENT]->data[0] + 16*mb_y*s->linesize;
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1448 int mb_x;
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1449
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1450 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
1451 backup_mb_border(s->top_border[mb_x+1], dst, NULL, NULL, s->linesize, 0, 1);
12223
93e27a5401de Convert VP8 macroblock structures to a ring buffer.
darkshikari
parents: 12222
diff changeset
1452 filter_mb_simple(s, dst, f++, mb_x, mb_y);
11921
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1453 dst += 16;
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1454 }
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1455 }
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1456
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1457 static int vp8_decode_frame(AVCodecContext *avctx, void *data, int *data_size,
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1458 AVPacket *avpkt)
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1459 {
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1460 VP8Context *s = avctx->priv_data;
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1461 int ret, mb_x, mb_y, i, y, referenced;
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1462 enum AVDiscard skip_thresh;
12232
870599d1eb36 Shut up a GCC warning in VP8
darkshikari
parents: 12231
diff changeset
1463 AVFrame *curframe = NULL;
11921
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1464
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1465 if ((ret = decode_frame_header(s, avpkt->data, avpkt->size)) < 0)
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1466 return ret;
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1467
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1468 referenced = s->update_last || s->update_golden == VP56_FRAME_CURRENT
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1469 || s->update_altref == VP56_FRAME_CURRENT;
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1470
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1471 skip_thresh = !referenced ? AVDISCARD_NONREF :
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1472 !s->keyframe ? AVDISCARD_NONKEY : AVDISCARD_ALL;
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1473
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1474 if (avctx->skip_frame >= skip_thresh) {
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1475 s->invisible = 1;
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1476 goto skip_decode;
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1477 }
12170
6f0db2eeaf70 vp8: Save mb border needed for intra prediction so that loop filter can run
conrad
parents: 12169
diff changeset
1478 s->deblock_filter = s->filter.level && avctx->skip_loop_filter < skip_thresh;
11921
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1479
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1480 for (i = 0; i < 4; i++)
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1481 if (&s->frames[i] != s->framep[VP56_FRAME_PREVIOUS] &&
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1482 &s->frames[i] != s->framep[VP56_FRAME_GOLDEN] &&
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1483 &s->frames[i] != s->framep[VP56_FRAME_GOLDEN2]) {
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1484 curframe = s->framep[VP56_FRAME_CURRENT] = &s->frames[i];
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1485 break;
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1486 }
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1487 if (curframe->data[0])
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1488 avctx->release_buffer(avctx, curframe);
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1489
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1490 curframe->key_frame = s->keyframe;
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1491 curframe->pict_type = s->keyframe ? FF_I_TYPE : FF_P_TYPE;
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1492 curframe->reference = referenced ? 3 : 0;
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1493 if ((ret = avctx->get_buffer(avctx, curframe))) {
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1494 av_log(avctx, AV_LOG_ERROR, "get_buffer() failed!\n");
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1495 return ret;
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1496 }
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1497
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1498 // Given that arithmetic probabilities are updated every frame, it's quite likely
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1499 // that the values we have on a random interframe are complete junk if we didn't
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1500 // start decode on a keyframe. So just don't display anything rather than junk.
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1501 if (!s->keyframe && (!s->framep[VP56_FRAME_PREVIOUS] ||
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1502 !s->framep[VP56_FRAME_GOLDEN] ||
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1503 !s->framep[VP56_FRAME_GOLDEN2])) {
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1504 av_log(avctx, AV_LOG_WARNING, "Discarding interframe without a prior keyframe!\n");
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1505 return AVERROR_INVALIDDATA;
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1506 }
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1507
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1508 s->linesize = curframe->linesize[0];
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1509 s->uvlinesize = curframe->linesize[1];
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1510
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1511 if (!s->edge_emu_buffer)
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1512 s->edge_emu_buffer = av_malloc(21*s->linesize);
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1513
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1514 memset(s->top_nnz, 0, s->mb_width*sizeof(*s->top_nnz));
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1515
12223
93e27a5401de Convert VP8 macroblock structures to a ring buffer.
darkshikari
parents: 12222
diff changeset
1516 /* Zero macroblock structures for top/left prediction from outside the frame. */
93e27a5401de Convert VP8 macroblock structures to a ring buffer.
darkshikari
parents: 12222
diff changeset
1517 memset(s->macroblocks, 0, (s->mb_width + s->mb_height*2)*sizeof(*s->macroblocks));
93e27a5401de Convert VP8 macroblock structures to a ring buffer.
darkshikari
parents: 12222
diff changeset
1518
11921
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1519 // 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
1520 memset(s->top_border, 127, (s->mb_width+1)*sizeof(*s->top_border));
12231
d3f3897ddb5c Smarter VP8 prefetching
darkshikari
parents: 12230
diff changeset
1521 memset(s->ref_count, 0, sizeof(s->ref_count));
11921
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1522
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1523 for (mb_y = 0; mb_y < s->mb_height; mb_y++) {
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1524 VP56RangeCoder *c = &s->coeff_partition[mb_y & (s->num_coeff_partitions-1)];
12223
93e27a5401de Convert VP8 macroblock structures to a ring buffer.
darkshikari
parents: 12222
diff changeset
1525 VP8Macroblock *mb = s->macroblocks + (s->mb_height - mb_y - 1)*2;
11921
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1526 uint8_t *intra4x4 = s->intra4x4_pred_mode + 4*mb_y*s->b4_stride;
12223
93e27a5401de Convert VP8 macroblock structures to a ring buffer.
darkshikari
parents: 12222
diff changeset
1527 uint8_t *segment_map = s->segmentation_map + mb_y*s->mb_stride;
12237
f0c4dc49c8f1 VP8: smarter prefetching
darkshikari
parents: 12235
diff changeset
1528 int mb_xy = mb_y * s->mb_stride;
11921
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1529 uint8_t *dst[3] = {
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1530 curframe->data[0] + 16*mb_y*s->linesize,
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1531 curframe->data[1] + 8*mb_y*s->uvlinesize,
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1532 curframe->data[2] + 8*mb_y*s->uvlinesize
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1533 };
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1534
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1535 memset(s->left_nnz, 0, sizeof(s->left_nnz));
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1536
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1537 // left edge of 129 for intra prediction
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1538 if (!(avctx->flags & CODEC_FLAG_EMU_EDGE))
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1539 for (i = 0; i < 3; i++)
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1540 for (y = 0; y < 16>>!!i; y++)
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1541 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
1542 if (mb_y)
6f0db2eeaf70 vp8: Save mb border needed for intra prediction so that loop filter can run
conrad
parents: 12169
diff changeset
1543 memset(s->top_border, 129, sizeof(*s->top_border));
11921
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1544
12237
f0c4dc49c8f1 VP8: smarter prefetching
darkshikari
parents: 12235
diff changeset
1545 for (mb_x = 0; mb_x < s->mb_width; mb_x++, mb_xy++, mb++) {
12221
45852dac8338 Avoid tracking i4x4 modes in P-frames in VP8
darkshikari
parents: 12220
diff changeset
1546 uint8_t *intra4x4_mb = s->keyframe ? intra4x4 + 4*mb_x : s->intra4x4_pred_mode_mb;
12223
93e27a5401de Convert VP8 macroblock structures to a ring buffer.
darkshikari
parents: 12222
diff changeset
1547 uint8_t *segment_mb = segment_map+mb_x;
12221
45852dac8338 Avoid tracking i4x4 modes in P-frames in VP8
darkshikari
parents: 12220
diff changeset
1548
12215
58d828f9810f Add prefetching to VP8 decoder
darkshikari
parents: 12202
diff changeset
1549 /* Prefetch the current frame, 4 MBs ahead */
58d828f9810f Add prefetching to VP8 decoder
darkshikari
parents: 12202
diff changeset
1550 s->dsp.prefetch(dst[0] + (mb_x&3)*4*s->linesize + 64, s->linesize, 4);
58d828f9810f Add prefetching to VP8 decoder
darkshikari
parents: 12202
diff changeset
1551 s->dsp.prefetch(dst[1] + (mb_x&7)*s->uvlinesize + 64, dst[2] - dst[1], 2);
58d828f9810f Add prefetching to VP8 decoder
darkshikari
parents: 12202
diff changeset
1552
12223
93e27a5401de Convert VP8 macroblock structures to a ring buffer.
darkshikari
parents: 12222
diff changeset
1553 decode_mb_mode(s, mb, mb_x, mb_y, intra4x4_mb, segment_mb);
11921
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1554
12237
f0c4dc49c8f1 VP8: smarter prefetching
darkshikari
parents: 12235
diff changeset
1555 prefetch_motion(s, mb, mb_x, mb_y, mb_xy, VP56_FRAME_PREVIOUS);
12231
d3f3897ddb5c Smarter VP8 prefetching
darkshikari
parents: 12230
diff changeset
1556
11921
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1557 if (!mb->skip)
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1558 decode_mb_coeffs(s, c, mb, s->top_nnz[mb_x], s->left_nnz);
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1559
12225
c3e11b3108d7 Eliminate a pointless memset for intra blocks in P-frames in VP8
darkshikari
parents: 12224
diff changeset
1560 if (mb->mode <= MODE_I4x4)
12221
45852dac8338 Avoid tracking i4x4 modes in P-frames in VP8
darkshikari
parents: 12220
diff changeset
1561 intra_predict(s, dst, mb, intra4x4_mb, mb_x, mb_y);
12225
c3e11b3108d7 Eliminate a pointless memset for intra blocks in P-frames in VP8
darkshikari
parents: 12224
diff changeset
1562 else
11921
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1563 inter_predict(s, dst, mb, mb_x, mb_y);
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1564
12237
f0c4dc49c8f1 VP8: smarter prefetching
darkshikari
parents: 12235
diff changeset
1565 prefetch_motion(s, mb, mb_x, mb_y, mb_xy, VP56_FRAME_GOLDEN);
12231
d3f3897ddb5c Smarter VP8 prefetching
darkshikari
parents: 12230
diff changeset
1566
11921
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1567 if (!mb->skip) {
12238
1a7903913e9b VP8: 30% faster idct_mb
darkshikari
parents: 12237
diff changeset
1568 idct_mb(s, dst, mb);
11921
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1569 } else {
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1570 AV_ZERO64(s->left_nnz);
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1571 AV_WN64(s->top_nnz[mb_x], 0); // array of 9, so unaligned
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1572
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1573 // Reset DC block predictors if they would exist if the mb had coefficients
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1574 if (mb->mode != MODE_I4x4 && mb->mode != VP8_MVMODE_SPLIT) {
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1575 s->left_nnz[8] = 0;
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1576 s->top_nnz[mb_x][8] = 0;
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1577 }
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1578 }
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1579
12222
7acdbfd2a222 Calculate deblock strength per-MB instead of per-row
darkshikari
parents: 12221
diff changeset
1580 if (s->deblock_filter)
7acdbfd2a222 Calculate deblock strength per-MB instead of per-row
darkshikari
parents: 12221
diff changeset
1581 filter_level_for_mb(s, mb, &s->filter_strength[mb_x]);
7acdbfd2a222 Calculate deblock strength per-MB instead of per-row
darkshikari
parents: 12221
diff changeset
1582
12237
f0c4dc49c8f1 VP8: smarter prefetching
darkshikari
parents: 12235
diff changeset
1583 prefetch_motion(s, mb, mb_x, mb_y, mb_xy, VP56_FRAME_GOLDEN2);
12231
d3f3897ddb5c Smarter VP8 prefetching
darkshikari
parents: 12230
diff changeset
1584
11921
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1585 dst[0] += 16;
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1586 dst[1] += 8;
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1587 dst[2] += 8;
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1588 }
12170
6f0db2eeaf70 vp8: Save mb border needed for intra prediction so that loop filter can run
conrad
parents: 12169
diff changeset
1589 if (s->deblock_filter) {
11921
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1590 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
1591 filter_mb_row_simple(s, mb_y);
11921
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1592 else
12170
6f0db2eeaf70 vp8: Save mb border needed for intra prediction so that loop filter can run
conrad
parents: 12169
diff changeset
1593 filter_mb_row(s, mb_y);
11921
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1594 }
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1595 }
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1596
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1597 skip_decode:
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1598 // if future frames don't use the updated probabilities,
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1599 // reset them to the values we saved
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1600 if (!s->update_probabilities)
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1601 s->prob[0] = s->prob[1];
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1602
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1603 // check if golden and altref are swapped
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1604 if (s->update_altref == VP56_FRAME_GOLDEN &&
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1605 s->update_golden == VP56_FRAME_GOLDEN2)
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1606 FFSWAP(AVFrame *, s->framep[VP56_FRAME_GOLDEN], s->framep[VP56_FRAME_GOLDEN2]);
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1607 else {
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1608 if (s->update_altref != VP56_FRAME_NONE)
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1609 s->framep[VP56_FRAME_GOLDEN2] = s->framep[s->update_altref];
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1610
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1611 if (s->update_golden != VP56_FRAME_NONE)
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1612 s->framep[VP56_FRAME_GOLDEN] = s->framep[s->update_golden];
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1613 }
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1614
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1615 if (s->update_last) // move cur->prev
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1616 s->framep[VP56_FRAME_PREVIOUS] = s->framep[VP56_FRAME_CURRENT];
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1617
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1618 // release no longer referenced frames
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1619 for (i = 0; i < 4; i++)
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1620 if (s->frames[i].data[0] &&
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1621 &s->frames[i] != s->framep[VP56_FRAME_CURRENT] &&
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1622 &s->frames[i] != s->framep[VP56_FRAME_PREVIOUS] &&
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1623 &s->frames[i] != s->framep[VP56_FRAME_GOLDEN] &&
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1624 &s->frames[i] != s->framep[VP56_FRAME_GOLDEN2])
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1625 avctx->release_buffer(avctx, &s->frames[i]);
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1626
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1627 if (!s->invisible) {
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1628 *(AVFrame*)data = *s->framep[VP56_FRAME_CURRENT];
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1629 *data_size = sizeof(AVFrame);
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1630 }
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1631
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1632 return avpkt->size;
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1633 }
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1634
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1635 static av_cold int vp8_decode_init(AVCodecContext *avctx)
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1636 {
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1637 VP8Context *s = avctx->priv_data;
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1638
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1639 s->avctx = avctx;
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1640 avctx->pix_fmt = PIX_FMT_YUV420P;
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1641
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1642 dsputil_init(&s->dsp, avctx);
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1643 ff_h264_pred_init(&s->hpc, CODEC_ID_VP8);
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1644 ff_vp8dsp_init(&s->vp8dsp);
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1645
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1646 // intra pred needs edge emulation among other things
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1647 if (avctx->flags&CODEC_FLAG_EMU_EDGE) {
11947
fc9e4874a12c fix typo in vp8 decoder error message
darkshikari
parents: 11937
diff changeset
1648 av_log(avctx, AV_LOG_ERROR, "Edge emulation not supported\n");
11921
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1649 return AVERROR_PATCHWELCOME;
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1650 }
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1651
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1652 return 0;
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1653 }
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1654
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1655 static av_cold int vp8_decode_free(AVCodecContext *avctx)
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1656 {
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1657 vp8_decode_flush(avctx);
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1658 return 0;
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1659 }
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1660
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1661 AVCodec vp8_decoder = {
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1662 "vp8",
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1663 AVMEDIA_TYPE_VIDEO,
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1664 CODEC_ID_VP8,
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1665 sizeof(VP8Context),
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1666 vp8_decode_init,
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1667 NULL,
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1668 vp8_decode_free,
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1669 vp8_decode_frame,
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1670 CODEC_CAP_DR1,
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1671 .flush = vp8_decode_flush,
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1672 .long_name = NULL_IF_CONFIG_SMALL("On2 VP8"),
f2007d7c3f1d Native VP8 decoder.
rbultje
parents:
diff changeset
1673 };