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