]> git.sesse.net Git - ffmpeg/blob - libavcodec/mobiclip.c
avcodec/mobiclip: Avoid redundant codes table to initialize VLCs
[ffmpeg] / libavcodec / mobiclip.c
1 /*
2  * MobiClip Video decoder
3  * Copyright (c) 2017 Adib Surani
4  * Copyright (c) 2020 Paul B Mahol
5  *
6  * This file is part of FFmpeg.
7  *
8  * FFmpeg is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU Lesser General Public
10  * License as published by the Free Software Foundation; either
11  * version 2.1 of the License, or (at your option) any later version.
12  *
13  * FFmpeg is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16  * Lesser General Public License for more details.
17  *
18  * You should have received a copy of the GNU Lesser General Public
19  * License along with FFmpeg; if not, write to the Free Software
20  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
21  */
22
23 #include <inttypes.h>
24
25 #include "libavutil/avassert.h"
26
27 #include "avcodec.h"
28 #include "bytestream.h"
29 #include "bswapdsp.h"
30 #include "get_bits.h"
31 #include "golomb.h"
32 #include "internal.h"
33
34 #define MOBI_RL_VLC_BITS 12
35 #define MOBI_MV_VLC_BITS 6
36
37 static const uint8_t zigzag4x4_tab[] =
38 {
39     0x00, 0x04, 0x01, 0x02, 0x05, 0x08, 0x0C, 0x09, 0x06, 0x03, 0x07, 0x0A,
40     0x0D, 0x0E, 0x0B, 0x0F
41 };
42
43 static const uint8_t quant4x4_tab[][16] =
44 {
45     { 10, 13, 13, 10, 16, 10, 13, 13, 13, 13, 16, 10, 16, 13, 13, 16 },
46     { 11, 14, 14, 11, 18, 11, 14, 14, 14, 14, 18, 11, 18, 14, 14, 18 },
47     { 13, 16, 16, 13, 20, 13, 16, 16, 16, 16, 20, 13, 20, 16, 16, 20 },
48     { 14, 18, 18, 14, 23, 14, 18, 18, 18, 18, 23, 14, 23, 18, 18, 23 },
49     { 16, 20, 20, 16, 25, 16, 20, 20, 20, 20, 25, 16, 25, 20, 20, 25 },
50     { 18, 23, 23, 18, 29, 18, 23, 23, 23, 23, 29, 18, 29, 23, 23, 29 },
51 };
52
53 static const uint8_t quant8x8_tab[][64] =
54 {
55     { 20, 19, 19, 25, 18, 25, 19, 24, 24, 19, 20, 18, 32, 18, 20, 19, 19, 24, 24, 19, 19, 25, 18, 25, 18, 25, 18, 25, 19, 24, 24, 19,
56       19, 24, 24, 19, 18, 32, 18, 20, 18, 32, 18, 24, 24, 19, 19, 24, 24, 18, 25, 18, 25, 18, 19, 24, 24, 19, 18, 32, 18, 24, 24, 18,},
57     { 22, 21, 21, 28, 19, 28, 21, 26, 26, 21, 22, 19, 35, 19, 22, 21, 21, 26, 26, 21, 21, 28, 19, 28, 19, 28, 19, 28, 21, 26, 26, 21,
58       21, 26, 26, 21, 19, 35, 19, 22, 19, 35, 19, 26, 26, 21, 21, 26, 26, 19, 28, 19, 28, 19, 21, 26, 26, 21, 19, 35, 19, 26, 26, 19,},
59     { 26, 24, 24, 33, 23, 33, 24, 31, 31, 24, 26, 23, 42, 23, 26, 24, 24, 31, 31, 24, 24, 33, 23, 33, 23, 33, 23, 33, 24, 31, 31, 24,
60       24, 31, 31, 24, 23, 42, 23, 26, 23, 42, 23, 31, 31, 24, 24, 31, 31, 23, 33, 23, 33, 23, 24, 31, 31, 24, 23, 42, 23, 31, 31, 23,},
61     { 28, 26, 26, 35, 25, 35, 26, 33, 33, 26, 28, 25, 45, 25, 28, 26, 26, 33, 33, 26, 26, 35, 25, 35, 25, 35, 25, 35, 26, 33, 33, 26,
62       26, 33, 33, 26, 25, 45, 25, 28, 25, 45, 25, 33, 33, 26, 26, 33, 33, 25, 35, 25, 35, 25, 26, 33, 33, 26, 25, 45, 25, 33, 33, 25,},
63     { 32, 30, 30, 40, 28, 40, 30, 38, 38, 30, 32, 28, 51, 28, 32, 30, 30, 38, 38, 30, 30, 40, 28, 40, 28, 40, 28, 40, 30, 38, 38, 30,
64       30, 38, 38, 30, 28, 51, 28, 32, 28, 51, 28, 38, 38, 30, 30, 38, 38, 28, 40, 28, 40, 28, 30, 38, 38, 30, 28, 51, 28, 38, 38, 28,},
65     { 36, 34, 34, 46, 32, 46, 34, 43, 43, 34, 36, 32, 58, 32, 36, 34, 34, 43, 43, 34, 34, 46, 32, 46, 32, 46, 32, 46, 34, 43, 43, 34,
66       34, 43, 43, 34, 32, 58, 32, 36, 32, 58, 32, 43, 43, 34, 34, 43, 43, 32, 46, 32, 46, 32, 34, 43, 43, 34, 32, 58, 32, 43, 43, 32,},
67 };
68
69 static const uint8_t block4x4_coefficients_tab[] =
70 {
71     15, 0, 2, 1, 4, 8, 12, 3, 11, 13, 14, 7, 10, 5, 9, 6,
72 };
73
74 static const uint8_t pframe_block4x4_coefficients_tab[] =
75 {
76     0, 4, 1, 8, 2, 12, 3, 5, 10, 15, 7, 13, 14, 11, 9, 6,
77 };
78
79 static const uint8_t block8x8_coefficients_tab[] =
80 {
81     0x00, 0x1F, 0x3F, 0x0F, 0x08, 0x04, 0x02, 0x01, 0x0B, 0x0E, 0x1B, 0x0D,
82     0x03, 0x07, 0x0C, 0x17, 0x1D, 0x0A, 0x1E, 0x05, 0x10, 0x2F, 0x37, 0x3B,
83     0x13, 0x3D, 0x3E, 0x09, 0x1C, 0x06, 0x15, 0x1A, 0x33, 0x11, 0x12, 0x14,
84     0x18, 0x20, 0x3C, 0x35, 0x19, 0x16, 0x3A, 0x30, 0x31, 0x32, 0x27, 0x34,
85     0x2B, 0x2D, 0x39, 0x38, 0x23, 0x36, 0x2E, 0x21, 0x25, 0x22, 0x24, 0x2C,
86     0x2A, 0x28, 0x29, 0x26,
87 };
88
89 static const uint8_t pframe_block8x8_coefficients_tab[] =
90 {
91     0x00, 0x0F, 0x04, 0x01, 0x08, 0x02, 0x0C, 0x03, 0x05, 0x0A, 0x0D, 0x07, 0x0E, 0x0B, 0x1F, 0x09,
92     0x06, 0x10, 0x3F, 0x1E, 0x17, 0x1D, 0x1B, 0x1C, 0x13, 0x18, 0x1A, 0x12, 0x11, 0x14, 0x15, 0x20,
93     0x2F, 0x16, 0x19, 0x37, 0x3D, 0x3E, 0x3B, 0x3C, 0x33, 0x35, 0x21, 0x24, 0x22, 0x28, 0x23, 0x2C,
94     0x30, 0x27, 0x2D, 0x25, 0x3A, 0x2B, 0x2E, 0x2A, 0x31, 0x34, 0x38, 0x32, 0x29, 0x26, 0x39, 0x36
95 };
96
97 static const uint8_t run_residue[2][256] =
98 {
99     {
100        12,  6,  4,  3,  3,  3,  3,  2,  2,  2,  2,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,
101         0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
102         3,  2,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,
103         1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
104         1, 27, 11,  7,  3,  2,  2,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,
105         1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,
106         1, 41,  2,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,
107         1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,
108     },
109     {
110        27, 10,  5,  4,  3,  3,  3,  3,  2,  2,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
111         0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
112         8,  3,  2,  2,  2,  2,  2,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
113         0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
114         1, 15, 10,  8,  4,  3,  2,  2,  2,  2,  2,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,
115         1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,
116         1, 21,  7,  2,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,
117         1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,
118     },
119 };
120
121 static const uint8_t bits0[] = {
122      9, 11, 11, 11, 11, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10,
123     10, 10, 11, 11, 11, 11, 11, 11, 11, 11, 12, 12, 12, 12, 12,
124     12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,  7, 10, 10,  9,
125      9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,
126      9,  9,  9,  9,  9,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,
127      8,  8,  8,  7,  7,  7,  7,  7,  7,  7,  7,  6,  6,  6,  6,
128      6,  6,  6,  6,  6,  6,  5,  5,  5,  4,  2,  3,  4,  4,
129 };
130
131 static const uint16_t syms0[] = {
132     0x0, 0x822, 0x803, 0xB, 0xA, 0xB81, 0xB61, 0xB41, 0xB21, 0x122,
133     0x102, 0xE2, 0xC2, 0xA2, 0x63, 0x43, 0x24, 0xC, 0x25, 0x2E1, 0x301,
134     0xBA1, 0xBC1, 0xBE1, 0xC01, 0x26, 0x44, 0x83, 0xA3, 0xC3, 0x142,
135     0x321, 0x341, 0xC21, 0xC41, 0xC61, 0xC81, 0xCA1, 0xCC1, 0xCE1, 0xD01,
136     0x0, 0x9, 0x8, 0xB01, 0xAE1, 0xAC1, 0xAA1, 0xA81, 0xA61, 0xA41, 0xA21,
137     0x802, 0x2C1, 0x2A1, 0x281, 0x261, 0x241, 0x221, 0x201, 0x1E1, 0x82,
138     0x62, 0x7, 0x6, 0xA01, 0x9E1, 0x9C1, 0x9A1, 0x981, 0x961, 0x941, 0x921,
139     0x1C1, 0x1A1, 0x42, 0x23, 0x5, 0x901, 0x8E1, 0x8C1, 0x8A1, 0x181, 0x161,
140     0x141, 0x4, 0x881, 0x861, 0x841, 0x821, 0x121, 0x101, 0xE1, 0xC1, 0x22,
141     0x3, 0xA1, 0x81, 0x61, 0x801, 0x1, 0x21, 0x41, 0x2,
142 };
143
144 static const uint16_t syms1[] = {
145     0x0, 0x807, 0x806, 0x16, 0x15, 0x842, 0x823, 0x805, 0x1A1, 0xA3, 0x102, 0x83,
146     0x64, 0x44, 0x27, 0x14, 0x13, 0x17, 0x18, 0x28, 0x122, 0x862, 0x882, 0x9E1, 0xA01,
147     0x19, 0x1A, 0x1B, 0x29, 0xC3, 0x2A, 0x45, 0xE3, 0x1C1, 0x808, 0x8A2, 0x8C2, 0xA21,
148     0xA41, 0xA61, 0xA81, 0x0, 0x12, 0x11, 0x9C1, 0x9A1, 0x981, 0x961, 0x941, 0x822, 0x804,
149     0x181, 0x161, 0xE2, 0xC2, 0xA2, 0x63, 0x43, 0x26, 0x25, 0x10, 0x82, 0xF, 0xE, 0xD, 0x901,
150     0x8E1, 0x8C1, 0x803, 0x141, 0x121, 0x101, 0x921, 0x62, 0x24, 0xC, 0xB, 0xA, 0x881, 0x861,
151     0xC1, 0x8A1, 0xE1, 0x42, 0x23, 0x9, 0x802, 0xA1, 0x841, 0x821, 0x81, 0x61, 0x8, 0x7, 0x22,
152     0x6, 0x41, 0x5, 0x4, 0x801, 0x1, 0x2, 0x21, 0x3,
153 };
154
155 static const uint8_t mv_len[16] =
156 {
157     10, 8, 8, 7, 8, 8, 8, 7, 8, 8, 8, 7, 7, 7, 7, 6,
158 };
159
160 static const uint8_t mv_bits[16][10] =
161 {
162     { 3, 4, 5, 5, 3, 5, 6, 6, 4, 1 },
163     { 2, 3, 4, 5, 5, 2, 3, 3 },
164     { 2, 4, 4, 3, 3, 4, 4, 2 },
165     { 1, 4, 4, 3, 4, 4, 3 },
166     { 3, 3, 2, 4, 5, 5, 3, 2 },
167     { 3, 4, 4, 3, 3, 3, 3, 2 },
168     { 1, 3, 3, 4, 4, 4, 5, 5 },
169     { 1, 4, 4, 3, 3, 4, 4 },
170     { 2, 4, 4, 3, 3, 4, 4, 2 },
171     { 1, 3, 3, 4, 4, 4, 5, 5 },
172     { 2, 3, 4, 4, 4, 4, 3, 2 },
173     { 2, 3, 3, 4, 4, 3, 2 },
174     { 1, 4, 4, 3, 3, 4, 4 },
175     { 1, 4, 4, 3, 3, 4, 4 },
176     { 2, 3, 3, 4, 4, 3, 2 },
177     { 2, 3, 3, 3, 3, 2 },
178 };
179
180 static const uint8_t mv_syms[16][10] =
181 {
182     { 8, 2, 3, 6, 1, 7, 5, 4, 9, 0 },
183     { 9, 2, 3, 5, 4, 1, 8, 0 },
184     { 0, 5, 4, 2, 9, 3, 8, 1 },
185     { 1, 5, 4, 2, 8, 3, 0 },
186     { 2, 9, 8, 3, 5, 4, 0, 1 },
187     { 3, 5, 4, 2, 9, 8, 0, 1 },
188     { 1, 2, 0, 9, 8, 3, 5, 4 },
189     { 1, 8, 5, 2, 0, 4, 3 },
190     { 0, 5, 4, 2, 8, 3, 9, 1 },
191     { 1, 2, 0, 9, 8, 3, 5, 4 },
192     { 0, 3, 9, 8, 5, 4, 2, 1 },
193     { 0, 4, 3, 8, 5, 2, 1 },
194     { 1, 5, 4, 2, 0, 9, 3 },
195     { 1, 9, 5, 2, 0, 4, 3 },
196     { 0, 5, 3, 9, 4, 2, 1 },
197     { 0, 4, 5, 3, 2, 1 },
198 };
199
200 static const uint8_t mv_bits_mods[16][10] =
201 {
202     { 2, 3, 3, 5, 5, 4, 4, 5, 5, 2 },
203     { 2, 3, 4, 4, 3, 4, 4, 2 },
204     { 3, 4, 4, 2, 4, 4, 3, 2 },
205     { 1, 3, 4, 5, 5, 3, 3 },
206     { 2, 4, 4, 3, 3, 4, 4, 2 },
207     { 2, 3, 4, 4, 4, 4, 3, 2 },
208     { 2, 3, 4, 4, 4, 4, 3, 2 },
209     { 2, 2, 3, 4, 5, 5, 2 },
210     { 2, 3, 4, 4, 3, 4, 4, 2 },
211     { 2, 4, 4, 3, 4, 4, 3, 2 },
212     { 2, 3, 3, 5, 5, 4, 3, 2 },
213     { 2, 3, 4, 4, 3, 3, 2 },
214     { 1, 4, 4, 3, 3, 4, 4 },
215     { 2, 3, 4, 4, 3, 3, 2 },
216     { 2, 3, 4, 4, 3, 3, 2 },
217     { 3, 3, 2, 2, 3, 3 },
218 };
219
220 static const uint8_t mv_syms_mods[16][10] =
221 {
222     { 1, 8, 9, 4, 3, 2, 7, 5, 6, 0 },
223     { 0, 9, 5, 4, 2, 3, 8, 1 },
224     { 3, 9, 5, 0, 4, 8, 2, 1 },
225     { 1, 3, 4, 8, 5, 2, 0 },
226     { 0, 5, 4, 8, 2, 3, 9, 1 },
227     { 0, 3, 5, 9, 4, 8, 2, 1 },
228     { 0, 3, 9, 5, 8, 4, 2, 1 },
229     { 0, 2, 3, 4, 8, 5, 1 },
230     { 0, 3, 8, 4, 2, 5, 9, 1 },
231     { 2, 8, 9, 3, 5, 4, 0, 1 },
232     { 0, 4, 3, 8, 9, 5, 2, 1 },
233     { 0, 4, 8, 5, 3, 2, 1 },
234     { 1, 9, 4, 2, 0, 5, 3 },
235     { 2, 4, 9, 5, 3, 0, 1 },
236     { 0, 4, 9, 5, 3, 2, 1 },
237     { 5, 4, 1, 0, 3, 2 },
238 };
239
240 typedef struct BlockXY {
241     int w, h;
242     int ax, ay;
243     int x, y;
244     int size;
245     uint8_t *block;
246     int linesize;
247 } BlockXY;
248
249 typedef struct MotionXY {
250     int x, y;
251 } MotionXY;
252
253 typedef struct MobiClipContext {
254     AVFrame *pic[6];
255
256     int current_pic;
257     int moflex;
258     int dct_tab_idx;
259     int quantizer;
260
261     GetBitContext gb;
262
263     uint8_t *bitstream;
264     int bitstream_size;
265
266     int     qtab[2][64];
267     uint8_t pre[32];
268     MotionXY *motion;
269     int     motion_size;
270
271     BswapDSPContext bdsp;
272 } MobiClipContext;
273
274 static VLC rl_vlc[2];
275 static VLC mv_vlc[2][16];
276
277 static av_cold int mobiclip_init(AVCodecContext *avctx)
278 {
279     MobiClipContext *s = avctx->priv_data;
280
281     if (avctx->width & 15 || avctx->height & 15) {
282         av_log(avctx, AV_LOG_ERROR, "width/height not multiple of 16\n");
283         return AVERROR_INVALIDDATA;
284     }
285
286     ff_bswapdsp_init(&s->bdsp);
287
288     avctx->pix_fmt = AV_PIX_FMT_YUV420P;
289
290     s->motion = av_calloc(avctx->width / 16 + 3, sizeof(MotionXY));
291     if (!s->motion)
292         return AVERROR(ENOMEM);
293     s->motion_size = (avctx->width / 16 + 3) * sizeof(MotionXY);
294
295     for (int i = 0; i < 6; i++) {
296         s->pic[i] = av_frame_alloc();
297         if (!s->pic[i])
298             return AVERROR(ENOMEM);
299     }
300
301     INIT_VLC_STATIC_FROM_LENGTHS(&rl_vlc[0], MOBI_RL_VLC_BITS, 104,
302                                  bits0, sizeof(*bits0),
303                            syms0,  sizeof(*syms0),  sizeof(*syms0),
304                                  0, 0, 1 << MOBI_RL_VLC_BITS);
305     INIT_VLC_STATIC_FROM_LENGTHS(&rl_vlc[1], MOBI_RL_VLC_BITS, 104,
306                                  bits0, sizeof(*bits0),
307                            syms1,  sizeof(*syms1),  sizeof(*syms1),
308                                  0, 0, 1 << MOBI_RL_VLC_BITS);
309     for (int j = 0; j < 16; j++) {
310         static VLC_TYPE vlc_buf[2 * 16 << MOBI_MV_VLC_BITS][2];
311         mv_vlc[0][j].table           = &vlc_buf[2 * j << MOBI_MV_VLC_BITS];
312         mv_vlc[0][j].table_allocated = 1 << MOBI_MV_VLC_BITS;
313         ff_init_vlc_from_lengths(&mv_vlc[0][j], MOBI_MV_VLC_BITS, mv_len[j],
314                                  mv_bits_mods[j], sizeof(*mv_bits_mods[j]),
315                                  mv_syms_mods[j], sizeof(*mv_syms_mods[j]),
316                                  sizeof(*mv_syms_mods[j]), 0,
317                                  INIT_VLC_USE_NEW_STATIC, NULL);
318         mv_vlc[1][j].table           = &vlc_buf[(2 * j + 1) << MOBI_MV_VLC_BITS];
319         mv_vlc[1][j].table_allocated = 1 << MOBI_MV_VLC_BITS;
320         ff_init_vlc_from_lengths(&mv_vlc[1][j], MOBI_MV_VLC_BITS, mv_len[j],
321                                  mv_bits[j], sizeof(*mv_bits[j]),
322                                  mv_syms[j], sizeof(*mv_syms[j]), sizeof(*mv_syms[j]),
323                                  0, INIT_VLC_USE_NEW_STATIC, NULL);
324     }
325
326     return 0;
327 }
328
329 static int setup_qtables(AVCodecContext *avctx, int quantizer)
330 {
331     MobiClipContext *s = avctx->priv_data;
332     int qx, qy;
333
334     if (quantizer < 12 || quantizer > 161)
335         return AVERROR_INVALIDDATA;
336
337     s->quantizer = quantizer;
338
339     qx = quantizer % 6;
340     qy = quantizer / 6;
341
342     for (int i = 0; i < 16; i++)
343         s->qtab[0][i] = quant4x4_tab[qx][i] << qy;
344
345     for (int i = 0; i < 64; i++)
346         s->qtab[1][i] = quant8x8_tab[qx][i] << (qy - 2);
347
348     for (int i = 0; i < 20; i++)
349         s->pre[i] = 9;
350
351     return 0;
352 }
353
354 static void inverse4(unsigned *rs)
355 {
356     unsigned a = rs[0] + rs[2];
357     unsigned b = rs[0] - rs[2];
358     unsigned c = rs[1] + ((int)rs[3] >> 1);
359     unsigned d = ((int)rs[1] >> 1) - rs[3];
360
361     rs[0] = a + c;
362     rs[1] = b + d;
363     rs[2] = b - d;
364     rs[3] = a - c;
365 }
366
367 static void idct(int *arr, int size)
368 {
369     int e, f, g, h;
370     unsigned x3, x2, x1, x0;
371     int tmp[4];
372
373     if (size == 4) {
374         inverse4(arr);
375         return;
376     }
377
378     tmp[0] = arr[0];
379     tmp[1] = arr[2];
380     tmp[2] = arr[4];
381     tmp[3] = arr[6];
382
383     inverse4(tmp);
384
385     e = (unsigned)arr[7] + arr[1] - arr[3] - (arr[3] >> 1);
386     f = (unsigned)arr[7] - arr[1] + arr[5] + (arr[5] >> 1);
387     g = (unsigned)arr[5] - arr[3] - arr[7] - (arr[7] >> 1);
388     h = (unsigned)arr[5] + arr[3] + arr[1] + (arr[1] >> 1);
389     x3 = (unsigned)g + (h >> 2);
390     x2 = (unsigned)e + (f >> 2);
391     x1 = (e >> 2) - (unsigned)f;
392     x0 = (unsigned)h - (g >> 2);
393
394     arr[0] = tmp[0] + x0;
395     arr[1] = tmp[1] + x1;
396     arr[2] = tmp[2] + x2;
397     arr[3] = tmp[3] + x3;
398     arr[4] = tmp[3] - x3;
399     arr[5] = tmp[2] - x2;
400     arr[6] = tmp[1] - x1;
401     arr[7] = tmp[0] - x0;
402 }
403
404 static void read_run_encoding(AVCodecContext *avctx,
405                               int *last, int *run, int *level)
406 {
407     MobiClipContext *s = avctx->priv_data;
408     GetBitContext *gb = &s->gb;
409     int n = get_vlc2(gb, rl_vlc[s->dct_tab_idx].table,
410                      MOBI_RL_VLC_BITS, 1);
411
412     *last = (n >> 11) == 1;
413     *run  = (n >> 5) & 0x3F;
414     *level = n & 0x1F;
415 }
416
417 static int add_coefficients(AVCodecContext *avctx, AVFrame *frame,
418                             int bx, int by, int size, int plane)
419 {
420     MobiClipContext *s = avctx->priv_data;
421     GetBitContext *gb = &s->gb;
422     int mat[64] = { 0 };
423     const uint8_t *ztab = size == 8 ? ff_zigzag_direct : zigzag4x4_tab;
424     const int *qtab = s->qtab[size == 8];
425     uint8_t *dst = frame->data[plane] + by * frame->linesize[plane] + bx;
426
427     for (int pos = 0; get_bits_left(gb) > 0; pos++) {
428         int qval, last, run, level;
429
430         read_run_encoding(avctx, &last, &run, &level);
431
432         if (level) {
433             if (get_bits1(gb))
434                 level = -level;
435         } else if (!get_bits1(gb)) {
436             read_run_encoding(avctx, &last, &run, &level);
437             level += run_residue[s->dct_tab_idx][(last ? 64 : 0) + run];
438             if (get_bits1(gb))
439                 level = -level;
440         } else if (!get_bits1(gb)) {
441             read_run_encoding(avctx, &last, &run, &level);
442             run += run_residue[s->dct_tab_idx][128 + (last ? 64 : 0) + level];
443             if (get_bits1(gb))
444                 level = -level;
445         } else {
446             last  = get_bits1(gb);
447             run   = get_bits(gb, 6);
448             level = get_sbits(gb, 12);
449         }
450
451         pos += run;
452         if (pos >= size * size)
453             return AVERROR_INVALIDDATA;
454         qval = qtab[pos];
455         mat[ztab[pos]] = qval *(unsigned)level;
456
457         if (last)
458             break;
459     }
460
461     mat[0] += 32;
462     for (int y = 0; y < size; y++)
463         idct(&mat[y * size], size);
464
465     for (int y = 0; y < size; y++) {
466         for (int x = y + 1; x < size; x++) {
467             int a = mat[x * size + y];
468             int b = mat[y * size + x];
469
470             mat[y * size + x] = a;
471             mat[x * size + y] = b;
472         }
473
474         idct(&mat[y * size], size);
475         for (int x = 0; x < size; x++)
476             dst[x] = av_clip_uint8(dst[x] + (mat[y * size + x] >> 6));
477         dst += frame->linesize[plane];
478     }
479
480     return 0;
481 }
482
483 static int add_pframe_coefficients(AVCodecContext *avctx, AVFrame *frame,
484                                    int bx, int by, int size, int plane)
485 {
486     MobiClipContext *s = avctx->priv_data;
487     GetBitContext *gb = &s->gb;
488     int ret, idx = get_ue_golomb_31(gb);
489
490     if (idx == 0) {
491         ret = add_coefficients(avctx, frame, bx, by, size, plane);
492     } else if ((unsigned)idx < FF_ARRAY_ELEMS(pframe_block4x4_coefficients_tab)) {
493         int flags = pframe_block4x4_coefficients_tab[idx];
494
495         for (int y = by; y < by + 8; y += 4) {
496             for (int x = bx; x < bx + 8; x += 4) {
497                 if (flags & 1) {
498                     ret = add_coefficients(avctx, frame, x, y, 4, plane);
499                     if (ret < 0)
500                         return ret;
501                 }
502                 flags >>= 1;
503             }
504         }
505     } else {
506         ret = AVERROR_INVALIDDATA;
507     }
508
509     return ret;
510 }
511
512 static int adjust(int x, int size)
513 {
514     return size == 16 ? (x + 1) >> 1 : x;
515 }
516
517 static uint8_t pget(BlockXY b)
518 {
519     BlockXY ret = b;
520     int x, y;
521
522     if (b.x == -1 && b.y >= b.size) {
523         ret.x = -1, ret.y = b.size - 1;
524     } else if (b.x >= -1 && b.y >= -1) {
525         ret.x = b.x, ret.y = b.y;
526     } else if (b.x == -1 && b.y == -2) {
527         ret.x = 0, ret.y = -1;
528     } else if (b.x == -2 && b.y == -1) {
529         ret.x = -1, ret.y = 0;
530     }
531
532     y = av_clip(ret.ay + ret.y, 0, ret.h - 1);
533     x = av_clip(ret.ax + ret.x, 0, ret.w - 1);
534
535     return ret.block[y * ret.linesize + x];
536 }
537
538 static uint8_t half(int a, int b)
539 {
540     return ((a + b) + 1) / 2;
541 }
542
543 static uint8_t half3(int a, int b, int c)
544 {
545     return ((a + b + b + c) * 2 / 4 + 1) / 2;;
546 }
547
548 static uint8_t pick_above(BlockXY bxy)
549 {
550     bxy.y = bxy.y - 1;
551
552     return pget(bxy);
553 }
554
555 static uint8_t pick_left(BlockXY bxy)
556 {
557     bxy.x = bxy.x - 1;
558
559     return pget(bxy);
560 }
561
562 static uint8_t half_horz(BlockXY bxy)
563 {
564     BlockXY a = bxy, b = bxy, c = bxy;
565
566     a.x -= 1;
567     c.x += 1;
568
569     return half3(pget(a), pget(b), pget(c));
570 }
571
572 static uint8_t half_vert(BlockXY bxy)
573 {
574     BlockXY a = bxy, b = bxy, c = bxy;
575
576     a.y -= 1;
577     c.y += 1;
578
579     return half3(pget(a), pget(b), pget(c));
580 }
581
582 static uint8_t pick_4(BlockXY bxy)
583 {
584     int val;
585
586     if ((bxy.x % 2) == 0) {
587         BlockXY ba, bb;
588         int a, b;
589
590         ba = bxy;
591         ba.x = -1;
592         ba.y = bxy.y + bxy.x / 2;
593         a = pget(ba);
594
595         bb = bxy;
596         bb.x = -1;
597         bb.y = bxy.y + bxy.x / 2 + 1;
598         b = pget(bb);
599
600         val = half(a, b);
601     } else {
602         BlockXY ba;
603
604         ba = bxy;
605         ba.x = -1;
606         ba.y = bxy.y + bxy.x / 2 + 1;
607         val = half_vert(ba);
608     }
609
610     return val;
611 }
612
613 static uint8_t pick_5(BlockXY bxy)
614 {
615     int val;
616
617     if (bxy.x == 0) {
618         BlockXY a = bxy;
619         BlockXY b = bxy;
620
621         a.x = -1;
622         a.y -= 1;
623
624         b.x = -1;
625
626         val = half(pget(a), pget(b));
627     } else if (bxy.y == 0) {
628         BlockXY a = bxy;
629
630         a.x -= 2;
631         a.y -= 1;
632
633         val = half_horz(a);
634     } else if (bxy.x == 1) {
635         BlockXY a = bxy;
636
637         a.x -= 2;
638         a.y -= 1;
639
640         val = half_vert(a);
641     } else {
642         BlockXY a = bxy;
643
644         a.x -= 2;
645         a.y -= 1;
646
647         val = pget(a);
648     }
649
650     return val;
651 }
652
653 static uint8_t pick_6(BlockXY bxy)
654 {
655     int val;
656
657     if (bxy.y == 0) {
658         BlockXY a = bxy;
659         BlockXY b = bxy;
660
661         a.x -= 1;
662         a.y = -1;
663
664         b.y = -1;
665
666         val = half(pget(a), pget(b));
667     } else if (bxy.x == 0) {
668         BlockXY a = bxy;
669
670         a.x -= 1;
671         a.y -= 2;
672
673         val = half_vert(a);
674     } else if (bxy.y == 1) {
675         BlockXY a = bxy;
676
677         a.x -= 1;
678         a.y -= 2;
679
680         val = half_horz(a);
681     } else {
682         BlockXY a = bxy;
683
684         a.x -= 1;
685         a.y -= 2;
686
687         val = pget(a);
688     }
689
690     return val;
691 }
692
693 static uint8_t pick_7(BlockXY bxy)
694 {
695     int clr, acc1, acc2;
696     BlockXY a = bxy;
697
698     a.x -= 1;
699     a.y -= 1;
700     clr = pget(a);
701     if (bxy.x && bxy.y)
702         return clr;
703
704     if (bxy.x == 0) {
705         a.x = -1;
706         a.y = bxy.y;
707     } else {
708         a.x = bxy.x - 2;
709         a.y = -1;
710     }
711     acc1 = pget(a);
712
713     if (bxy.y == 0) {
714         a.x = bxy.x;
715         a.y = -1;
716     } else {
717         a.x = -1;
718         a.y = bxy.y - 2;
719     }
720     acc2 = pget(a);
721
722     return half3(acc1, clr, acc2);
723 }
724
725 static uint8_t pick_8(BlockXY bxy)
726 {
727     BlockXY ba = bxy;
728     BlockXY bb = bxy;
729     int val;
730
731     if (bxy.y == 0) {
732         int a, b;
733
734         ba.y = -1;
735         a = pget(ba);
736
737         bb.x += 1;
738         bb.y = -1;
739
740         b = pget(bb);
741
742         val = half(a, b);
743     } else if (bxy.y == 1) {
744         ba.x += 1;
745         ba.y -= 2;
746
747         val = half_horz(ba);
748     } else if (bxy.x < bxy.size - 1) {
749         ba.x += 1;
750         ba.y -= 2;
751
752         val = pget(ba);
753     } else if (bxy.y % 2 == 0) {
754         int a, b;
755
756         ba.x = bxy.y / 2 + bxy.size - 1;
757         ba.y = -1;
758         a = pget(ba);
759
760         bb.x = bxy.y / 2 + bxy.size;
761         bb.y = -1;
762
763         b = pget(bb);
764
765         val = half(a, b);
766     } else {
767         ba.x = bxy.y / 2 + bxy.size;
768         ba.y = -1;
769
770         val = half_horz(ba);
771     }
772
773     return val;
774 }
775
776 static void block_fill_simple(uint8_t *block, int size, int linesize, int fill)
777 {
778     for (int y = 0; y < size; y++) {
779         memset(block, fill, size);
780         block += linesize;
781     }
782 }
783
784 static void block_fill(uint8_t *block, int size, int linesize,
785                        int w, int h, int ax, int ay,
786                        uint8_t (*pick)(BlockXY bxy))
787 {
788     BlockXY bxy;
789
790     bxy.size = size;
791     bxy.block = block;
792     bxy.linesize = linesize;
793     bxy.w = w;
794     bxy.h = h;
795     bxy.ay = ay;
796     bxy.ax = ax;
797
798     for (int y = 0; y < size; y++) {
799         bxy.y = y;
800         for (int x = 0; x < size; x++) {
801             uint8_t val;
802
803             bxy.x = x;
804
805             val = pick(bxy);
806
807             block[ax + x + (ay + y) * linesize] = val;
808         }
809     }
810 }
811
812 static int block_sum(const uint8_t *block, int w, int h, int linesize)
813 {
814     int sum = 0;
815
816     for (int y = 0; y < h; y++) {
817         for (int x = 0; x < w; x++) {
818             sum += block[x];
819         }
820         block += linesize;
821     }
822
823     return sum;
824 }
825
826 static int predict_intra(AVCodecContext *avctx, AVFrame *frame, int ax, int ay,
827                           int pmode, int add_coeffs, int size, int plane)
828 {
829     MobiClipContext *s = avctx->priv_data;
830     GetBitContext *gb = &s->gb;
831     int w = avctx->width >> !!plane, h = avctx->height >> !!plane;
832     int ret = 0;
833
834     switch (pmode) {
835     case 0:
836         block_fill(frame->data[plane], size, frame->linesize[plane], w, h, ax, ay, pick_above);
837         break;
838     case 1:
839         block_fill(frame->data[plane], size, frame->linesize[plane], w, h, ax, ay, pick_left);
840         break;
841     case 2:
842         {
843             int arr1[16];
844             int arr2[16];
845             uint8_t *top = frame->data[plane] + FFMAX(ay - 1, 0) * frame->linesize[plane] + ax;
846             uint8_t *left = frame->data[plane] + ay * frame->linesize[plane] + FFMAX(ax - 1, 0);
847             int bottommost = frame->data[plane][(ay + size - 1) * frame->linesize[plane] + FFMAX(ax - 1, 0)];
848             int rightmost = frame->data[plane][FFMAX(ay - 1, 0) * frame->linesize[plane] + ax + size - 1];
849             int avg = (bottommost + rightmost + 1) / 2 + 2 * get_se_golomb(gb);
850             int r6 = adjust(avg - bottommost, size);
851             int r9 = adjust(avg - rightmost, size);
852             int shift = adjust(size, size) == 8 ? 3 : 2;
853             uint8_t *block;
854
855             for (int x = 0; x < size; x++) {
856                 int val = top[x];
857                 arr1[x] = adjust(((bottommost - val) * (1 << shift)) + r6 * (x + 1), size);
858             }
859
860             for (int y = 0; y < size; y++) {
861                 int val = left[y * frame->linesize[plane]];
862                 arr2[y] = adjust(((rightmost - val) * (1 << shift)) + r9 * (y + 1), size);
863             }
864
865             block = frame->data[plane] + ay * frame->linesize[plane] + ax;
866             for (int y = 0; y < size; y++) {
867                 for (int x = 0; x < size; x++) {
868                     block[x] = (((top[x] + left[0] + ((arr1[x] * (y + 1) +
869                                                        arr2[y] * (x + 1)) >> 2 * shift)) + 1) / 2) & 0xFF;
870                 }
871                 block += frame->linesize[plane];
872                 left  += frame->linesize[plane];
873             }
874         }
875         break;
876     case 3:
877         {
878             uint8_t fill;
879
880             if (ax == 0 && ay == 0) {
881                 fill = 0x80;
882             } else if (ax >= 1 && ay >= 1) {
883                 int left = block_sum(frame->data[plane] + ay * frame->linesize[plane] + ax - 1,
884                                      1, size, frame->linesize[plane]);
885                 int top  = block_sum(frame->data[plane] + (ay - 1) * frame->linesize[plane] + ax,
886                                      size, 1, frame->linesize[plane]);
887
888                 fill = ((left + top) * 2 / (2 * size) + 1) / 2;
889             } else if (ax >= 1) {
890                 fill = (block_sum(frame->data[plane] + ay * frame->linesize[plane] + ax - 1,
891                                   1, size, frame->linesize[plane]) * 2 / size + 1) / 2;
892             } else if (ay >= 1) {
893                 fill = (block_sum(frame->data[plane] + (ay - 1) * frame->linesize[plane] + ax,
894                                   size, 1, frame->linesize[plane]) * 2 / size + 1) / 2;
895             } else {
896                 return -1;
897             }
898
899             block_fill_simple(frame->data[plane] + ay * frame->linesize[plane] + ax,
900                               size, frame->linesize[plane], fill);
901         }
902         break;
903     case 4:
904         block_fill(frame->data[plane], size, frame->linesize[plane], w, h, ax, ay, pick_4);
905         break;
906     case 5:
907         block_fill(frame->data[plane], size, frame->linesize[plane], w, h, ax, ay, pick_5);
908         break;
909     case 6:
910         block_fill(frame->data[plane], size, frame->linesize[plane], w, h, ax, ay, pick_6);
911         break;
912     case 7:
913         block_fill(frame->data[plane], size, frame->linesize[plane], w, h, ax, ay, pick_7);
914         break;
915     case 8:
916         block_fill(frame->data[plane], size, frame->linesize[plane], w, h, ax, ay, pick_8);
917         break;
918     }
919
920     if (add_coeffs)
921         ret = add_coefficients(avctx, frame, ax, ay, size, plane);
922
923     return ret;
924 }
925
926 static int get_prediction(AVCodecContext *avctx, int x, int y, int size)
927 {
928     MobiClipContext *s = avctx->priv_data;
929     GetBitContext *gb = &s->gb;
930     int index = (y & 0xC) | (x / 4 % 4);
931
932     uint8_t val = FFMIN(s->pre[index], index % 4 == 0 ? 9 : s->pre[index + 3]);
933     if (val == 9)
934         val = 3;
935
936     if (!get_bits1(gb)) {
937         int x = get_bits(gb, 3);
938         val = x + (x >= val ? 1 : 0);
939     }
940
941     s->pre[index + 4] = val;
942     if (size == 8)
943         s->pre[index + 5] = s->pre[index + 8] = s->pre[index + 9] = val;
944
945     return val;
946 }
947
948 static int process_block(AVCodecContext *avctx, AVFrame *frame,
949                          int x, int y, int pmode, int has_coeffs, int plane)
950 {
951     MobiClipContext *s = avctx->priv_data;
952     GetBitContext *gb = &s->gb;
953     int tmp, ret;
954
955     if (!has_coeffs) {
956         if (pmode < 0)
957             pmode = get_prediction(avctx, x, y, 8);
958         return predict_intra(avctx, frame, x, y, pmode, 0, 8, plane);
959     }
960
961     tmp = get_ue_golomb_31(gb);
962     if ((unsigned)tmp > FF_ARRAY_ELEMS(block4x4_coefficients_tab))
963         return AVERROR_INVALIDDATA;
964
965     if (tmp == 0) {
966         if (pmode < 0)
967             pmode = get_prediction(avctx, x, y, 8);
968         ret = predict_intra(avctx, frame, x, y, pmode, 1, 8, plane);
969     } else {
970         int flags = block4x4_coefficients_tab[tmp - 1];
971
972         for (int by = y; by < y + 8; by += 4) {
973             for (int bx = x; bx < x + 8; bx += 4) {
974                 int new_pmode = pmode;
975
976                 if (new_pmode < 0)
977                     new_pmode = get_prediction(avctx, bx, by, 4);
978                 ret = predict_intra(avctx, frame, bx, by, new_pmode, flags & 1, 4, plane);
979                 if (ret < 0)
980                     return ret;
981                 flags >>= 1;
982             }
983         }
984     }
985
986     return ret;
987 }
988
989 static int decode_macroblock(AVCodecContext *avctx, AVFrame *frame,
990                              int x, int y, int predict)
991 {
992     MobiClipContext *s = avctx->priv_data;
993     GetBitContext *gb = &s->gb;
994     int flags, pmode_uv, idx = get_ue_golomb(gb);
995     int ret = 0;
996
997     if (idx < 0 || idx >= FF_ARRAY_ELEMS(block8x8_coefficients_tab))
998         return AVERROR_INVALIDDATA;
999
1000     flags = block8x8_coefficients_tab[idx];
1001
1002     if (predict) {
1003         ret = process_block(avctx, frame, x, y, -1, flags & 1, 0);
1004         if (ret < 0)
1005             return ret;
1006         flags >>= 1;
1007         ret = process_block(avctx, frame, x + 8, y, -1, flags & 1, 0);
1008         if (ret < 0)
1009             return ret;
1010         flags >>= 1;
1011         ret = process_block(avctx, frame, x, y + 8, -1, flags & 1, 0);
1012         if (ret < 0)
1013             return ret;
1014         flags >>= 1;
1015         ret = process_block(avctx, frame, x + 8, y + 8, -1, flags & 1, 0);
1016         if (ret < 0)
1017             return ret;
1018         flags >>= 1;
1019     } else {
1020         int pmode = get_bits(gb, 3);
1021
1022         if (pmode == 2) {
1023             ret = predict_intra(avctx, frame, x, y, pmode, 0, 16, 0);
1024             if (ret < 0)
1025                 return ret;
1026             pmode = 9;
1027         }
1028
1029         ret = process_block(avctx, frame, x, y, pmode, flags & 1, 0);
1030         if (ret < 0)
1031             return ret;
1032         flags >>= 1;
1033         ret = process_block(avctx, frame, x + 8, y, pmode, flags & 1, 0);
1034         if (ret < 0)
1035             return ret;
1036         flags >>= 1;
1037         ret = process_block(avctx, frame, x, y + 8, pmode, flags & 1, 0);
1038         if (ret < 0)
1039             return ret;
1040         flags >>= 1;
1041         ret = process_block(avctx, frame, x + 8, y + 8, pmode, flags & 1, 0);
1042         if (ret < 0)
1043             return ret;
1044         flags >>= 1;
1045     }
1046
1047     pmode_uv = get_bits(gb, 3);
1048     if (pmode_uv == 2) {
1049         ret = predict_intra(avctx, frame, x >> 1, y >> 1, pmode_uv, 0, 8, 1 + !s->moflex);
1050         if (ret < 0)
1051             return ret;
1052         ret = predict_intra(avctx, frame, x >> 1, y >> 1, pmode_uv, 0, 8, 2 - !s->moflex);
1053         if (ret < 0)
1054             return ret;
1055         pmode_uv = 9;
1056     }
1057
1058     ret = process_block(avctx, frame, x >> 1, y >> 1, pmode_uv, flags & 1, 1 + !s->moflex);
1059     if (ret < 0)
1060         return ret;
1061     flags >>= 1;
1062     ret = process_block(avctx, frame, x >> 1, y >> 1, pmode_uv, flags & 1, 2 - !s->moflex);
1063     if (ret < 0)
1064         return ret;
1065
1066     return 0;
1067 }
1068
1069 static int get_index(int x)
1070 {
1071     return x == 16 ? 0 : x == 8 ? 1 : x == 4 ? 2 : x == 2 ? 3 : 0;
1072 }
1073
1074 static int predict_motion(AVCodecContext *avctx,
1075                           int width, int height, int index,
1076                           int offsetm, int offsetx, int offsety)
1077 {
1078     MobiClipContext *s = avctx->priv_data;
1079     MotionXY *motion = s->motion;
1080     GetBitContext *gb = &s->gb;
1081     int fheight = avctx->height;
1082     int fwidth = avctx->width;
1083
1084     if (index <= 5) {
1085         int sidx = -FFMAX(1, index) + s->current_pic;
1086         MotionXY mv = s->motion[0];
1087
1088         if (sidx < 0)
1089             sidx += 6;
1090
1091         if (index > 0) {
1092             mv.x = mv.x + get_se_golomb(gb);
1093             mv.y = mv.y + get_se_golomb(gb);
1094         }
1095         if (mv.x >= INT_MAX || mv.y >= INT_MAX)
1096             return AVERROR_INVALIDDATA;
1097
1098         motion[offsetm].x = mv.x;
1099         motion[offsetm].y = mv.y;
1100
1101         for (int i = 0; i < 3; i++) {
1102             int method, src_linesize, dst_linesize;
1103             uint8_t *src, *dst;
1104
1105             if (i == 1) {
1106                 offsetx = offsetx >> 1;
1107                 offsety = offsety >> 1;
1108                 mv.x = mv.x >> 1;
1109                 mv.y = mv.y >> 1;
1110                 width = width >> 1;
1111                 height = height >> 1;
1112                 fwidth = fwidth >> 1;
1113                 fheight = fheight >> 1;
1114             }
1115
1116             av_assert0(s->pic[sidx]);
1117             av_assert0(s->pic[s->current_pic]);
1118             av_assert0(s->pic[s->current_pic]->data[i]);
1119             if (!s->pic[sidx]->data[i])
1120                 return AVERROR_INVALIDDATA;
1121
1122             method = (mv.x & 1) | ((mv.y & 1) << 1);
1123             src_linesize = s->pic[sidx]->linesize[i];
1124             dst_linesize = s->pic[s->current_pic]->linesize[i];
1125             dst = s->pic[s->current_pic]->data[i] + offsetx + offsety * dst_linesize;
1126
1127             if (offsetx + (mv.x >> 1) < 0 ||
1128                 offsety + (mv.y >> 1) < 0 ||
1129                 offsetx + width  + (mv.x + 1 >> 1) > fwidth ||
1130                 offsety + height + (mv.y + 1 >> 1) > fheight)
1131                 return AVERROR_INVALIDDATA;
1132
1133             switch (method) {
1134             case 0:
1135                 src = s->pic[sidx]->data[i] + offsetx + (mv.x >> 1) +
1136                                (offsety + (mv.y >> 1)) * src_linesize;
1137                 for (int y = 0; y < height; y++) {
1138                     for (int x = 0; x < width; x++)
1139                         dst[x] = src[x];
1140                     dst += dst_linesize;
1141                     src += src_linesize;
1142                 }
1143                 break;
1144             case 1:
1145                 src = s->pic[sidx]->data[i] + offsetx + (mv.x >> 1) +
1146                                (offsety + (mv.y >> 1)) * src_linesize;
1147                 for (int y = 0; y < height; y++) {
1148                     for (int x = 0; x < width; x++) {
1149                         dst[x] = (uint8_t)((src[x] >> 1) + (src[x + 1] >> 1));
1150                     }
1151
1152                     dst += dst_linesize;
1153                     src += src_linesize;
1154                 }
1155                 break;
1156             case 2:
1157                 src = s->pic[sidx]->data[i] + offsetx + (mv.x >> 1) +
1158                                (offsety + (mv.y >> 1)) * src_linesize;
1159                 for (int y = 0; y < height; y++) {
1160                     for (int x = 0; x < width; x++) {
1161                         dst[x] = (uint8_t)((src[x] >> 1) + (src[x + src_linesize] >> 1));
1162                     }
1163
1164                     dst += dst_linesize;
1165                     src += src_linesize;
1166                 }
1167                 break;
1168             case 3:
1169                 src = s->pic[sidx]->data[i] + offsetx + (mv.x >> 1) +
1170                                (offsety + (mv.y >> 1)) * src_linesize;
1171                 for (int y = 0; y < height; y++) {
1172                     for (int x = 0; x < width; x++) {
1173                         dst[x] = (uint8_t)((((src[x] >> 1) + (src[x + 1] >> 1)) >> 1) +
1174                                            (((src[x + src_linesize] >> 1) + (src[x + 1 + src_linesize] >> 1)) >> 1));
1175                     }
1176
1177                     dst += dst_linesize;
1178                     src += src_linesize;
1179                 }
1180                 break;
1181             }
1182         }
1183     } else {
1184         int tidx;
1185         int adjx = index == 8 ? 0 :  width / 2;
1186         int adjy = index == 8 ? height / 2 : 0;
1187
1188         width  = width  - adjx;
1189         height = height - adjy;
1190         tidx = get_index(height) * 4 + get_index(width);
1191
1192         for (int i = 0; i < 2; i++) {
1193             int ret, idx2;
1194
1195             idx2 = get_vlc2(gb, mv_vlc[s->moflex][tidx].table,
1196                             MOBI_MV_VLC_BITS, 1);
1197
1198             ret = predict_motion(avctx, width, height, idx2,
1199                                  offsetm, offsetx + i * adjx, offsety + i * adjy);
1200             if (ret < 0)
1201                 return ret;
1202         }
1203     }
1204
1205     return 0;
1206 }
1207
1208 static int mobiclip_decode(AVCodecContext *avctx, void *data,
1209                             int *got_frame, AVPacket *pkt)
1210 {
1211     MobiClipContext *s = avctx->priv_data;
1212     GetBitContext *gb = &s->gb;
1213     AVFrame *frame = s->pic[s->current_pic];
1214     int ret;
1215
1216     av_fast_padded_malloc(&s->bitstream, &s->bitstream_size,
1217                           pkt->size);
1218
1219     if ((ret = ff_reget_buffer(avctx, frame, 0)) < 0)
1220         return ret;
1221
1222     s->bdsp.bswap16_buf((uint16_t *)s->bitstream,
1223                         (uint16_t *)pkt->data,
1224                         (pkt->size + 1) >> 1);
1225
1226     ret = init_get_bits8(gb, s->bitstream, FFALIGN(pkt->size, 2));
1227     if (ret < 0)
1228         return ret;
1229
1230     if (get_bits1(gb)) {
1231         frame->pict_type = AV_PICTURE_TYPE_I;
1232         frame->key_frame = 1;
1233         s->moflex = get_bits1(gb);
1234         s->dct_tab_idx = get_bits1(gb);
1235
1236         ret = setup_qtables(avctx, get_bits(gb, 6));
1237         if (ret < 0)
1238             return ret;
1239
1240         for (int y = 0; y < avctx->height; y += 16) {
1241             for (int x = 0; x < avctx->width; x += 16) {
1242                 ret = decode_macroblock(avctx, frame, x, y, get_bits1(gb));
1243                 if (ret < 0)
1244                     return ret;
1245             }
1246         }
1247     } else {
1248         MotionXY *motion = s->motion;
1249
1250         memset(motion, 0, s->motion_size);
1251
1252         frame->pict_type = AV_PICTURE_TYPE_P;
1253         frame->key_frame = 0;
1254         s->dct_tab_idx = 0;
1255
1256         ret = setup_qtables(avctx, s->quantizer + get_se_golomb(gb));
1257         if (ret < 0)
1258             return ret;
1259
1260         for (int y = 0; y < avctx->height; y += 16) {
1261             for (int x = 0; x < avctx->width; x += 16) {
1262                 int idx;
1263
1264                 motion[0].x = mid_pred(motion[x / 16 + 1].x, motion[x / 16 + 2].x, motion[x / 16 + 3].x);
1265                 motion[0].y = mid_pred(motion[x / 16 + 1].y, motion[x / 16 + 2].y, motion[x / 16 + 3].y);
1266                 motion[x / 16 + 2].x = 0;
1267                 motion[x / 16 + 2].y = 0;
1268
1269                 idx = get_vlc2(gb, mv_vlc[s->moflex][0].table,
1270                                    MOBI_MV_VLC_BITS, 1);
1271
1272                 if (idx == 6 || idx == 7) {
1273                     ret = decode_macroblock(avctx, frame, x, y, idx == 7);
1274                     if (ret < 0)
1275                         return ret;
1276                 } else {
1277                     int flags, idx2;
1278                     ret = predict_motion(avctx, 16, 16, idx, x / 16 + 2, x, y);
1279                     if (ret < 0)
1280                         return ret;
1281                     idx2 = get_ue_golomb(gb);
1282                     if (idx2 >= FF_ARRAY_ELEMS(pframe_block8x8_coefficients_tab))
1283                         return AVERROR_INVALIDDATA;
1284                     flags = pframe_block8x8_coefficients_tab[idx2];
1285
1286                     for (int sy = y; sy < y + 16; sy += 8) {
1287                         for (int sx = x; sx < x + 16; sx += 8) {
1288                             if (flags & 1)
1289                                 add_pframe_coefficients(avctx, frame, sx, sy, 8, 0);
1290                             flags >>= 1;
1291                         }
1292                     }
1293
1294                     if (flags & 1)
1295                         add_pframe_coefficients(avctx, frame, x >> 1, y >> 1, 8, 1 + !s->moflex);
1296                     flags >>= 1;
1297                     if (flags & 1)
1298                         add_pframe_coefficients(avctx, frame, x >> 1, y >> 1, 8, 2 - !s->moflex);
1299                 }
1300             }
1301         }
1302     }
1303
1304     if (!s->moflex)
1305         avctx->colorspace = AVCOL_SPC_YCGCO;
1306
1307     s->current_pic = (s->current_pic + 1) % 6;
1308     ret = av_frame_ref(data, frame);
1309     if (ret < 0)
1310         return ret;
1311     *got_frame = 1;
1312
1313     return 0;
1314 }
1315
1316 static void mobiclip_flush(AVCodecContext *avctx)
1317 {
1318     MobiClipContext *s = avctx->priv_data;
1319
1320     for (int i = 0; i < 6; i++)
1321         av_frame_unref(s->pic[i]);
1322 }
1323
1324 static av_cold int mobiclip_close(AVCodecContext *avctx)
1325 {
1326     MobiClipContext *s = avctx->priv_data;
1327
1328     av_freep(&s->bitstream);
1329     s->bitstream_size = 0;
1330     av_freep(&s->motion);
1331     s->motion_size = 0;
1332
1333     for (int i = 0; i < 6; i++) {
1334         av_frame_free(&s->pic[i]);
1335     }
1336
1337     return 0;
1338 }
1339
1340 AVCodec ff_mobiclip_decoder = {
1341     .name           = "mobiclip",
1342     .long_name      = NULL_IF_CONFIG_SMALL("MobiClip Video"),
1343     .type           = AVMEDIA_TYPE_VIDEO,
1344     .id             = AV_CODEC_ID_MOBICLIP,
1345     .priv_data_size = sizeof(MobiClipContext),
1346     .init           = mobiclip_init,
1347     .decode         = mobiclip_decode,
1348     .flush          = mobiclip_flush,
1349     .close          = mobiclip_close,
1350     .capabilities   = AV_CODEC_CAP_DR1,
1351     .caps_internal  = FF_CODEC_CAP_INIT_CLEANUP,
1352 };