]> git.sesse.net Git - ffmpeg/blob - libavcodec/mobiclip.c
avcodec/mobiclip: Use get_ue_golomb_31() where possible
[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 uint8_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     int     qtab[2][64];
320     uint8_t pre[32];
321     MotionXY *motion;
322     int     motion_size;
323
324     BswapDSPContext bdsp;
325 } MobiClipContext;
326
327 static VLC rl_vlc[2];
328 static VLC mv_vlc[2][16];
329
330 static av_cold int mobiclip_init(AVCodecContext *avctx)
331 {
332     MobiClipContext *s = avctx->priv_data;
333
334     if (avctx->width & 15 || avctx->height & 15) {
335         av_log(avctx, AV_LOG_ERROR, "width/height not multiple of 16\n");
336         return AVERROR_INVALIDDATA;
337     }
338
339     ff_bswapdsp_init(&s->bdsp);
340
341     avctx->pix_fmt = AV_PIX_FMT_YUV420P;
342
343     s->motion = av_calloc(avctx->width / 16 + 3, sizeof(MotionXY));
344     if (!s->motion)
345         return AVERROR(ENOMEM);
346     s->motion_size = (avctx->width / 16 + 3) * sizeof(MotionXY);
347
348     for (int i = 0; i < 6; i++) {
349         s->pic[i] = av_frame_alloc();
350         if (!s->pic[i])
351             return AVERROR(ENOMEM);
352     }
353
354     INIT_VLC_SPARSE_STATIC(&rl_vlc[0], MOBI_RL_VLC_BITS, 104,
355                            bits0,  sizeof(*bits0),  sizeof(*bits0),
356                            codes0, sizeof(*codes0), sizeof(*codes0),
357                            syms0,  sizeof(*syms0),  sizeof(*syms0),
358                            1 << MOBI_RL_VLC_BITS);
359     INIT_VLC_SPARSE_STATIC(&rl_vlc[1], MOBI_RL_VLC_BITS, 104,
360                            bits0,  sizeof(*bits0),  sizeof(*bits0),
361                            codes0, sizeof(*codes0), sizeof(*codes0),
362                            syms1,  sizeof(*syms1),  sizeof(*syms1),
363                            1 << MOBI_RL_VLC_BITS);
364     for (int j = 0; j < 16; j++) {
365         static VLC_TYPE vlc_buf[2 * 16 << MOBI_MV_VLC_BITS][2];
366         mv_vlc[0][j].table           = &vlc_buf[2 * j << MOBI_MV_VLC_BITS];
367         mv_vlc[0][j].table_allocated = 1 << MOBI_MV_VLC_BITS;
368         ff_init_vlc_sparse(&mv_vlc[0][j], MOBI_MV_VLC_BITS, mv_len[j],
369                            mv_bits_mods[j],  sizeof(*mv_bits_mods[j]),  sizeof(*mv_bits_mods[j]),
370                            mv_codes_mods[j], sizeof(*mv_codes_mods[j]), sizeof(*mv_codes_mods[j]),
371                            mv_syms_mods[j],  sizeof(*mv_syms_mods[j]),  sizeof(*mv_syms_mods[j]), INIT_VLC_USE_NEW_STATIC);
372         mv_vlc[1][j].table           = &vlc_buf[(2 * j + 1) << MOBI_MV_VLC_BITS];
373         mv_vlc[1][j].table_allocated = 1 << MOBI_MV_VLC_BITS;
374         ff_init_vlc_sparse(&mv_vlc[1][j], MOBI_MV_VLC_BITS, mv_len[j],
375                            mv_bits[j],  sizeof(*mv_bits[j]),  sizeof(*mv_bits[j]),
376                            mv_codes[j], sizeof(*mv_codes[j]), sizeof(*mv_codes[j]),
377                            mv_syms[j],  sizeof(*mv_syms[j]),  sizeof(*mv_syms[j]), INIT_VLC_USE_NEW_STATIC);
378     }
379
380     return 0;
381 }
382
383 static int setup_qtables(AVCodecContext *avctx, int quantizer)
384 {
385     MobiClipContext *s = avctx->priv_data;
386     int qx, qy;
387
388     if (quantizer < 12 || quantizer > 161)
389         return AVERROR_INVALIDDATA;
390
391     s->quantizer = quantizer;
392
393     qx = quantizer % 6;
394     qy = quantizer / 6;
395
396     for (int i = 0; i < 16; i++)
397         s->qtab[0][i] = quant4x4_tab[qx][i] << qy;
398
399     for (int i = 0; i < 64; i++)
400         s->qtab[1][i] = quant8x8_tab[qx][i] << (qy - 2);
401
402     for (int i = 0; i < 20; i++)
403         s->pre[i] = 9;
404
405     return 0;
406 }
407
408 static void inverse4(unsigned *rs)
409 {
410     unsigned a = rs[0] + rs[2];
411     unsigned b = rs[0] - rs[2];
412     unsigned c = rs[1] + ((int)rs[3] >> 1);
413     unsigned d = ((int)rs[1] >> 1) - rs[3];
414
415     rs[0] = a + c;
416     rs[1] = b + d;
417     rs[2] = b - d;
418     rs[3] = a - c;
419 }
420
421 static void idct(int *arr, int size)
422 {
423     int e, f, g, h;
424     unsigned x3, x2, x1, x0;
425     int tmp[4];
426
427     if (size == 4) {
428         inverse4(arr);
429         return;
430     }
431
432     tmp[0] = arr[0];
433     tmp[1] = arr[2];
434     tmp[2] = arr[4];
435     tmp[3] = arr[6];
436
437     inverse4(tmp);
438
439     e = (unsigned)arr[7] + arr[1] - arr[3] - (arr[3] >> 1);
440     f = (unsigned)arr[7] - arr[1] + arr[5] + (arr[5] >> 1);
441     g = (unsigned)arr[5] - arr[3] - arr[7] - (arr[7] >> 1);
442     h = (unsigned)arr[5] + arr[3] + arr[1] + (arr[1] >> 1);
443     x3 = (unsigned)g + (h >> 2);
444     x2 = (unsigned)e + (f >> 2);
445     x1 = (e >> 2) - (unsigned)f;
446     x0 = (unsigned)h - (g >> 2);
447
448     arr[0] = tmp[0] + x0;
449     arr[1] = tmp[1] + x1;
450     arr[2] = tmp[2] + x2;
451     arr[3] = tmp[3] + x3;
452     arr[4] = tmp[3] - x3;
453     arr[5] = tmp[2] - x2;
454     arr[6] = tmp[1] - x1;
455     arr[7] = tmp[0] - x0;
456 }
457
458 static void read_run_encoding(AVCodecContext *avctx,
459                               int *last, int *run, int *level)
460 {
461     MobiClipContext *s = avctx->priv_data;
462     GetBitContext *gb = &s->gb;
463     int n = get_vlc2(gb, rl_vlc[s->dct_tab_idx].table,
464                      MOBI_RL_VLC_BITS, 1);
465
466     *last = (n >> 11) == 1;
467     *run  = (n >> 5) & 0x3F;
468     *level = n & 0x1F;
469 }
470
471 static int add_coefficients(AVCodecContext *avctx, AVFrame *frame,
472                             int bx, int by, int size, int plane)
473 {
474     MobiClipContext *s = avctx->priv_data;
475     GetBitContext *gb = &s->gb;
476     int mat[64] = { 0 };
477     const uint8_t *ztab = size == 8 ? ff_zigzag_direct : zigzag4x4_tab;
478     const int *qtab = s->qtab[size == 8];
479     uint8_t *dst = frame->data[plane] + by * frame->linesize[plane] + bx;
480
481     for (int pos = 0; get_bits_left(gb) > 0; pos++) {
482         int qval, last, run, level;
483
484         read_run_encoding(avctx, &last, &run, &level);
485
486         if (level) {
487             if (get_bits1(gb))
488                 level = -level;
489         } else if (!get_bits1(gb)) {
490             read_run_encoding(avctx, &last, &run, &level);
491             level += run_residue[s->dct_tab_idx][(last ? 64 : 0) + run];
492             if (get_bits1(gb))
493                 level = -level;
494         } else if (!get_bits1(gb)) {
495             read_run_encoding(avctx, &last, &run, &level);
496             run += run_residue[s->dct_tab_idx][128 + (last ? 64 : 0) + level];
497             if (get_bits1(gb))
498                 level = -level;
499         } else {
500             last  = get_bits1(gb);
501             run   = get_bits(gb, 6);
502             level = get_sbits(gb, 12);
503         }
504
505         pos += run;
506         if (pos >= size * size)
507             return AVERROR_INVALIDDATA;
508         qval = qtab[pos];
509         mat[ztab[pos]] = qval *(unsigned)level;
510
511         if (last)
512             break;
513     }
514
515     mat[0] += 32;
516     for (int y = 0; y < size; y++)
517         idct(&mat[y * size], size);
518
519     for (int y = 0; y < size; y++) {
520         for (int x = y + 1; x < size; x++) {
521             int a = mat[x * size + y];
522             int b = mat[y * size + x];
523
524             mat[y * size + x] = a;
525             mat[x * size + y] = b;
526         }
527
528         idct(&mat[y * size], size);
529         for (int x = 0; x < size; x++)
530             dst[x] = av_clip_uint8(dst[x] + (mat[y * size + x] >> 6));
531         dst += frame->linesize[plane];
532     }
533
534     return 0;
535 }
536
537 static int add_pframe_coefficients(AVCodecContext *avctx, AVFrame *frame,
538                                    int bx, int by, int size, int plane)
539 {
540     MobiClipContext *s = avctx->priv_data;
541     GetBitContext *gb = &s->gb;
542     int ret, idx = get_ue_golomb_31(gb);
543
544     if (idx == 0) {
545         ret = add_coefficients(avctx, frame, bx, by, size, plane);
546     } else if ((unsigned)idx < FF_ARRAY_ELEMS(pframe_block4x4_coefficients_tab)) {
547         int flags = pframe_block4x4_coefficients_tab[idx];
548
549         for (int y = by; y < by + 8; y += 4) {
550             for (int x = bx; x < bx + 8; x += 4) {
551                 if (flags & 1) {
552                     ret = add_coefficients(avctx, frame, x, y, 4, plane);
553                     if (ret < 0)
554                         return ret;
555                 }
556                 flags >>= 1;
557             }
558         }
559     } else {
560         ret = AVERROR_INVALIDDATA;
561     }
562
563     return ret;
564 }
565
566 static int adjust(int x, int size)
567 {
568     return size == 16 ? (x + 1) >> 1 : x;
569 }
570
571 static uint8_t pget(BlockXY b)
572 {
573     BlockXY ret = b;
574     int x, y;
575
576     if (b.x == -1 && b.y >= b.size) {
577         ret.x = -1, ret.y = b.size - 1;
578     } else if (b.x >= -1 && b.y >= -1) {
579         ret.x = b.x, ret.y = b.y;
580     } else if (b.x == -1 && b.y == -2) {
581         ret.x = 0, ret.y = -1;
582     } else if (b.x == -2 && b.y == -1) {
583         ret.x = -1, ret.y = 0;
584     }
585
586     y = av_clip(ret.ay + ret.y, 0, ret.h - 1);
587     x = av_clip(ret.ax + ret.x, 0, ret.w - 1);
588
589     return ret.block[y * ret.linesize + x];
590 }
591
592 static uint8_t half(int a, int b)
593 {
594     return ((a + b) + 1) / 2;
595 }
596
597 static uint8_t half3(int a, int b, int c)
598 {
599     return ((a + b + b + c) * 2 / 4 + 1) / 2;;
600 }
601
602 static uint8_t pick_above(BlockXY bxy)
603 {
604     bxy.y = bxy.y - 1;
605
606     return pget(bxy);
607 }
608
609 static uint8_t pick_left(BlockXY bxy)
610 {
611     bxy.x = bxy.x - 1;
612
613     return pget(bxy);
614 }
615
616 static uint8_t half_horz(BlockXY bxy)
617 {
618     BlockXY a = bxy, b = bxy, c = bxy;
619
620     a.x -= 1;
621     c.x += 1;
622
623     return half3(pget(a), pget(b), pget(c));
624 }
625
626 static uint8_t half_vert(BlockXY bxy)
627 {
628     BlockXY a = bxy, b = bxy, c = bxy;
629
630     a.y -= 1;
631     c.y += 1;
632
633     return half3(pget(a), pget(b), pget(c));
634 }
635
636 static uint8_t pick_4(BlockXY bxy)
637 {
638     int val;
639
640     if ((bxy.x % 2) == 0) {
641         BlockXY ba, bb;
642         int a, b;
643
644         ba = bxy;
645         ba.x = -1;
646         ba.y = bxy.y + bxy.x / 2;
647         a = pget(ba);
648
649         bb = bxy;
650         bb.x = -1;
651         bb.y = bxy.y + bxy.x / 2 + 1;
652         b = pget(bb);
653
654         val = half(a, b);
655     } else {
656         BlockXY ba;
657
658         ba = bxy;
659         ba.x = -1;
660         ba.y = bxy.y + bxy.x / 2 + 1;
661         val = half_vert(ba);
662     }
663
664     return val;
665 }
666
667 static uint8_t pick_5(BlockXY bxy)
668 {
669     int val;
670
671     if (bxy.x == 0) {
672         BlockXY a = bxy;
673         BlockXY b = bxy;
674
675         a.x = -1;
676         a.y -= 1;
677
678         b.x = -1;
679
680         val = half(pget(a), pget(b));
681     } else if (bxy.y == 0) {
682         BlockXY a = bxy;
683
684         a.x -= 2;
685         a.y -= 1;
686
687         val = half_horz(a);
688     } else if (bxy.x == 1) {
689         BlockXY a = bxy;
690
691         a.x -= 2;
692         a.y -= 1;
693
694         val = half_vert(a);
695     } else {
696         BlockXY a = bxy;
697
698         a.x -= 2;
699         a.y -= 1;
700
701         val = pget(a);
702     }
703
704     return val;
705 }
706
707 static uint8_t pick_6(BlockXY bxy)
708 {
709     int val;
710
711     if (bxy.y == 0) {
712         BlockXY a = bxy;
713         BlockXY b = bxy;
714
715         a.x -= 1;
716         a.y = -1;
717
718         b.y = -1;
719
720         val = half(pget(a), pget(b));
721     } else if (bxy.x == 0) {
722         BlockXY a = bxy;
723
724         a.x -= 1;
725         a.y -= 2;
726
727         val = half_vert(a);
728     } else if (bxy.y == 1) {
729         BlockXY a = bxy;
730
731         a.x -= 1;
732         a.y -= 2;
733
734         val = half_horz(a);
735     } else {
736         BlockXY a = bxy;
737
738         a.x -= 1;
739         a.y -= 2;
740
741         val = pget(a);
742     }
743
744     return val;
745 }
746
747 static uint8_t pick_7(BlockXY bxy)
748 {
749     int clr, acc1, acc2;
750     BlockXY a = bxy;
751
752     a.x -= 1;
753     a.y -= 1;
754     clr = pget(a);
755     if (bxy.x && bxy.y)
756         return clr;
757
758     if (bxy.x == 0) {
759         a.x = -1;
760         a.y = bxy.y;
761     } else {
762         a.x = bxy.x - 2;
763         a.y = -1;
764     }
765     acc1 = pget(a);
766
767     if (bxy.y == 0) {
768         a.x = bxy.x;
769         a.y = -1;
770     } else {
771         a.x = -1;
772         a.y = bxy.y - 2;
773     }
774     acc2 = pget(a);
775
776     return half3(acc1, clr, acc2);
777 }
778
779 static uint8_t pick_8(BlockXY bxy)
780 {
781     BlockXY ba = bxy;
782     BlockXY bb = bxy;
783     int val;
784
785     if (bxy.y == 0) {
786         int a, b;
787
788         ba.y = -1;
789         a = pget(ba);
790
791         bb.x += 1;
792         bb.y = -1;
793
794         b = pget(bb);
795
796         val = half(a, b);
797     } else if (bxy.y == 1) {
798         ba.x += 1;
799         ba.y -= 2;
800
801         val = half_horz(ba);
802     } else if (bxy.x < bxy.size - 1) {
803         ba.x += 1;
804         ba.y -= 2;
805
806         val = pget(ba);
807     } else if (bxy.y % 2 == 0) {
808         int a, b;
809
810         ba.x = bxy.y / 2 + bxy.size - 1;
811         ba.y = -1;
812         a = pget(ba);
813
814         bb.x = bxy.y / 2 + bxy.size;
815         bb.y = -1;
816
817         b = pget(bb);
818
819         val = half(a, b);
820     } else {
821         ba.x = bxy.y / 2 + bxy.size;
822         ba.y = -1;
823
824         val = half_horz(ba);
825     }
826
827     return val;
828 }
829
830 static void block_fill_simple(uint8_t *block, int size, int linesize, int fill)
831 {
832     for (int y = 0; y < size; y++) {
833         memset(block, fill, size);
834         block += linesize;
835     }
836 }
837
838 static void block_fill(uint8_t *block, int size, int linesize,
839                        int w, int h, int ax, int ay,
840                        uint8_t (*pick)(BlockXY bxy))
841 {
842     BlockXY bxy;
843
844     bxy.size = size;
845     bxy.block = block;
846     bxy.linesize = linesize;
847     bxy.w = w;
848     bxy.h = h;
849     bxy.ay = ay;
850     bxy.ax = ax;
851
852     for (int y = 0; y < size; y++) {
853         bxy.y = y;
854         for (int x = 0; x < size; x++) {
855             uint8_t val;
856
857             bxy.x = x;
858
859             val = pick(bxy);
860
861             block[ax + x + (ay + y) * linesize] = val;
862         }
863     }
864 }
865
866 static int block_sum(const uint8_t *block, int w, int h, int linesize)
867 {
868     int sum = 0;
869
870     for (int y = 0; y < h; y++) {
871         for (int x = 0; x < w; x++) {
872             sum += block[x];
873         }
874         block += linesize;
875     }
876
877     return sum;
878 }
879
880 static int predict_intra(AVCodecContext *avctx, AVFrame *frame, int ax, int ay,
881                           int pmode, int add_coeffs, int size, int plane)
882 {
883     MobiClipContext *s = avctx->priv_data;
884     GetBitContext *gb = &s->gb;
885     int w = avctx->width >> !!plane, h = avctx->height >> !!plane;
886     int ret = 0;
887
888     switch (pmode) {
889     case 0:
890         block_fill(frame->data[plane], size, frame->linesize[plane], w, h, ax, ay, pick_above);
891         break;
892     case 1:
893         block_fill(frame->data[plane], size, frame->linesize[plane], w, h, ax, ay, pick_left);
894         break;
895     case 2:
896         {
897             int arr1[16];
898             int arr2[16];
899             uint8_t *top = frame->data[plane] + FFMAX(ay - 1, 0) * frame->linesize[plane] + ax;
900             uint8_t *left = frame->data[plane] + ay * frame->linesize[plane] + FFMAX(ax - 1, 0);
901             int bottommost = frame->data[plane][(ay + size - 1) * frame->linesize[plane] + FFMAX(ax - 1, 0)];
902             int rightmost = frame->data[plane][FFMAX(ay - 1, 0) * frame->linesize[plane] + ax + size - 1];
903             int avg = (bottommost + rightmost + 1) / 2 + 2 * get_se_golomb(gb);
904             int r6 = adjust(avg - bottommost, size);
905             int r9 = adjust(avg - rightmost, size);
906             int shift = adjust(size, size) == 8 ? 3 : 2;
907             uint8_t *block;
908
909             for (int x = 0; x < size; x++) {
910                 int val = top[x];
911                 arr1[x] = adjust(((bottommost - val) * (1 << shift)) + r6 * (x + 1), size);
912             }
913
914             for (int y = 0; y < size; y++) {
915                 int val = left[y * frame->linesize[plane]];
916                 arr2[y] = adjust(((rightmost - val) * (1 << shift)) + r9 * (y + 1), size);
917             }
918
919             block = frame->data[plane] + ay * frame->linesize[plane] + ax;
920             for (int y = 0; y < size; y++) {
921                 for (int x = 0; x < size; x++) {
922                     block[x] = (((top[x] + left[0] + ((arr1[x] * (y + 1) +
923                                                        arr2[y] * (x + 1)) >> 2 * shift)) + 1) / 2) & 0xFF;
924                 }
925                 block += frame->linesize[plane];
926                 left  += frame->linesize[plane];
927             }
928         }
929         break;
930     case 3:
931         {
932             uint8_t fill;
933
934             if (ax == 0 && ay == 0) {
935                 fill = 0x80;
936             } else if (ax >= 1 && ay >= 1) {
937                 int left = block_sum(frame->data[plane] + ay * frame->linesize[plane] + ax - 1,
938                                      1, size, frame->linesize[plane]);
939                 int top  = block_sum(frame->data[plane] + (ay - 1) * frame->linesize[plane] + ax,
940                                      size, 1, frame->linesize[plane]);
941
942                 fill = ((left + top) * 2 / (2 * size) + 1) / 2;
943             } else if (ax >= 1) {
944                 fill = (block_sum(frame->data[plane] + ay * frame->linesize[plane] + ax - 1,
945                                   1, size, frame->linesize[plane]) * 2 / size + 1) / 2;
946             } else if (ay >= 1) {
947                 fill = (block_sum(frame->data[plane] + (ay - 1) * frame->linesize[plane] + ax,
948                                   size, 1, frame->linesize[plane]) * 2 / size + 1) / 2;
949             } else {
950                 return -1;
951             }
952
953             block_fill_simple(frame->data[plane] + ay * frame->linesize[plane] + ax,
954                               size, frame->linesize[plane], fill);
955         }
956         break;
957     case 4:
958         block_fill(frame->data[plane], size, frame->linesize[plane], w, h, ax, ay, pick_4);
959         break;
960     case 5:
961         block_fill(frame->data[plane], size, frame->linesize[plane], w, h, ax, ay, pick_5);
962         break;
963     case 6:
964         block_fill(frame->data[plane], size, frame->linesize[plane], w, h, ax, ay, pick_6);
965         break;
966     case 7:
967         block_fill(frame->data[plane], size, frame->linesize[plane], w, h, ax, ay, pick_7);
968         break;
969     case 8:
970         block_fill(frame->data[plane], size, frame->linesize[plane], w, h, ax, ay, pick_8);
971         break;
972     }
973
974     if (add_coeffs)
975         ret = add_coefficients(avctx, frame, ax, ay, size, plane);
976
977     return ret;
978 }
979
980 static int get_prediction(AVCodecContext *avctx, int x, int y, int size)
981 {
982     MobiClipContext *s = avctx->priv_data;
983     GetBitContext *gb = &s->gb;
984     int index = (y & 0xC) | (x / 4 % 4);
985
986     uint8_t val = FFMIN(s->pre[index], index % 4 == 0 ? 9 : s->pre[index + 3]);
987     if (val == 9)
988         val = 3;
989
990     if (!get_bits1(gb)) {
991         int x = get_bits(gb, 3);
992         val = x + (x >= val ? 1 : 0);
993     }
994
995     s->pre[index + 4] = val;
996     if (size == 8)
997         s->pre[index + 5] = s->pre[index + 8] = s->pre[index + 9] = val;
998
999     return val;
1000 }
1001
1002 static int process_block(AVCodecContext *avctx, AVFrame *frame,
1003                          int x, int y, int pmode, int has_coeffs, int plane)
1004 {
1005     MobiClipContext *s = avctx->priv_data;
1006     GetBitContext *gb = &s->gb;
1007     int tmp, ret;
1008
1009     if (!has_coeffs) {
1010         if (pmode < 0)
1011             pmode = get_prediction(avctx, x, y, 8);
1012         return predict_intra(avctx, frame, x, y, pmode, 0, 8, plane);
1013     }
1014
1015     tmp = get_ue_golomb_31(gb);
1016     if ((unsigned)tmp > FF_ARRAY_ELEMS(block4x4_coefficients_tab))
1017         return AVERROR_INVALIDDATA;
1018
1019     if (tmp == 0) {
1020         if (pmode < 0)
1021             pmode = get_prediction(avctx, x, y, 8);
1022         ret = predict_intra(avctx, frame, x, y, pmode, 1, 8, plane);
1023     } else {
1024         int flags = block4x4_coefficients_tab[tmp - 1];
1025
1026         for (int by = y; by < y + 8; by += 4) {
1027             for (int bx = x; bx < x + 8; bx += 4) {
1028                 int new_pmode = pmode;
1029
1030                 if (new_pmode < 0)
1031                     new_pmode = get_prediction(avctx, bx, by, 4);
1032                 ret = predict_intra(avctx, frame, bx, by, new_pmode, flags & 1, 4, plane);
1033                 if (ret < 0)
1034                     return ret;
1035                 flags >>= 1;
1036             }
1037         }
1038     }
1039
1040     return ret;
1041 }
1042
1043 static int decode_macroblock(AVCodecContext *avctx, AVFrame *frame,
1044                              int x, int y, int predict)
1045 {
1046     MobiClipContext *s = avctx->priv_data;
1047     GetBitContext *gb = &s->gb;
1048     int flags, pmode_uv, idx = get_ue_golomb(gb);
1049     int ret = 0;
1050
1051     if (idx < 0 || idx >= FF_ARRAY_ELEMS(block8x8_coefficients_tab))
1052         return AVERROR_INVALIDDATA;
1053
1054     flags = block8x8_coefficients_tab[idx];
1055
1056     if (predict) {
1057         ret = process_block(avctx, frame, x, y, -1, flags & 1, 0);
1058         if (ret < 0)
1059             return ret;
1060         flags >>= 1;
1061         ret = process_block(avctx, frame, x + 8, y, -1, flags & 1, 0);
1062         if (ret < 0)
1063             return ret;
1064         flags >>= 1;
1065         ret = process_block(avctx, frame, x, y + 8, -1, flags & 1, 0);
1066         if (ret < 0)
1067             return ret;
1068         flags >>= 1;
1069         ret = process_block(avctx, frame, x + 8, y + 8, -1, flags & 1, 0);
1070         if (ret < 0)
1071             return ret;
1072         flags >>= 1;
1073     } else {
1074         int pmode = get_bits(gb, 3);
1075
1076         if (pmode == 2) {
1077             ret = predict_intra(avctx, frame, x, y, pmode, 0, 16, 0);
1078             if (ret < 0)
1079                 return ret;
1080             pmode = 9;
1081         }
1082
1083         ret = process_block(avctx, frame, x, y, pmode, flags & 1, 0);
1084         if (ret < 0)
1085             return ret;
1086         flags >>= 1;
1087         ret = process_block(avctx, frame, x + 8, y, pmode, flags & 1, 0);
1088         if (ret < 0)
1089             return ret;
1090         flags >>= 1;
1091         ret = process_block(avctx, frame, x, y + 8, pmode, flags & 1, 0);
1092         if (ret < 0)
1093             return ret;
1094         flags >>= 1;
1095         ret = process_block(avctx, frame, x + 8, y + 8, pmode, flags & 1, 0);
1096         if (ret < 0)
1097             return ret;
1098         flags >>= 1;
1099     }
1100
1101     pmode_uv = get_bits(gb, 3);
1102     if (pmode_uv == 2) {
1103         ret = predict_intra(avctx, frame, x >> 1, y >> 1, pmode_uv, 0, 8, 1 + !s->moflex);
1104         if (ret < 0)
1105             return ret;
1106         ret = predict_intra(avctx, frame, x >> 1, y >> 1, pmode_uv, 0, 8, 2 - !s->moflex);
1107         if (ret < 0)
1108             return ret;
1109         pmode_uv = 9;
1110     }
1111
1112     ret = process_block(avctx, frame, x >> 1, y >> 1, pmode_uv, flags & 1, 1 + !s->moflex);
1113     if (ret < 0)
1114         return ret;
1115     flags >>= 1;
1116     ret = process_block(avctx, frame, x >> 1, y >> 1, pmode_uv, flags & 1, 2 - !s->moflex);
1117     if (ret < 0)
1118         return ret;
1119
1120     return 0;
1121 }
1122
1123 static int get_index(int x)
1124 {
1125     return x == 16 ? 0 : x == 8 ? 1 : x == 4 ? 2 : x == 2 ? 3 : 0;
1126 }
1127
1128 static int predict_motion(AVCodecContext *avctx,
1129                           int width, int height, int index,
1130                           int offsetm, int offsetx, int offsety)
1131 {
1132     MobiClipContext *s = avctx->priv_data;
1133     MotionXY *motion = s->motion;
1134     GetBitContext *gb = &s->gb;
1135     int fheight = avctx->height;
1136     int fwidth = avctx->width;
1137
1138     if (index <= 5) {
1139         int sidx = -FFMAX(1, index) + s->current_pic;
1140         MotionXY mv = s->motion[0];
1141
1142         if (sidx < 0)
1143             sidx += 6;
1144
1145         if (index > 0) {
1146             mv.x = mv.x + get_se_golomb(gb);
1147             mv.y = mv.y + get_se_golomb(gb);
1148         }
1149
1150         motion[offsetm].x = mv.x;
1151         motion[offsetm].y = mv.y;
1152
1153         for (int i = 0; i < 3; i++) {
1154             int method, src_linesize, dst_linesize;
1155             uint8_t *src, *dst;
1156
1157             if (i == 1) {
1158                 offsetx = offsetx >> 1;
1159                 offsety = offsety >> 1;
1160                 mv.x = mv.x >> 1;
1161                 mv.y = mv.y >> 1;
1162                 width = width >> 1;
1163                 height = height >> 1;
1164                 fwidth = fwidth >> 1;
1165                 fheight = fheight >> 1;
1166             }
1167
1168             av_assert0(s->pic[sidx]);
1169             av_assert0(s->pic[s->current_pic]);
1170             av_assert0(s->pic[s->current_pic]->data[i]);
1171             if (!s->pic[sidx]->data[i])
1172                 return AVERROR_INVALIDDATA;
1173
1174             method = (mv.x & 1) | ((mv.y & 1) << 1);
1175             src_linesize = s->pic[sidx]->linesize[i];
1176             dst_linesize = s->pic[s->current_pic]->linesize[i];
1177             dst = s->pic[s->current_pic]->data[i] + offsetx + offsety * dst_linesize;
1178
1179             if (offsetx + (mv.x >> 1) < 0 ||
1180                 offsety + (mv.y >> 1) < 0 ||
1181                 offsetx + width  + (mv.x + 1 >> 1) > fwidth ||
1182                 offsety + height + (mv.y + 1 >> 1) > fheight)
1183                 return AVERROR_INVALIDDATA;
1184
1185             switch (method) {
1186             case 0:
1187                 src = s->pic[sidx]->data[i] + offsetx + (mv.x >> 1) +
1188                                (offsety + (mv.y >> 1)) * src_linesize;
1189                 for (int y = 0; y < height; y++) {
1190                     for (int x = 0; x < width; x++)
1191                         dst[x] = src[x];
1192                     dst += dst_linesize;
1193                     src += src_linesize;
1194                 }
1195                 break;
1196             case 1:
1197                 src = s->pic[sidx]->data[i] + offsetx + (mv.x >> 1) +
1198                                (offsety + (mv.y >> 1)) * src_linesize;
1199                 for (int y = 0; y < height; y++) {
1200                     for (int x = 0; x < width; x++) {
1201                         dst[x] = (uint8_t)((src[x] >> 1) + (src[x + 1] >> 1));
1202                     }
1203
1204                     dst += dst_linesize;
1205                     src += src_linesize;
1206                 }
1207                 break;
1208             case 2:
1209                 src = s->pic[sidx]->data[i] + offsetx + (mv.x >> 1) +
1210                                (offsety + (mv.y >> 1)) * src_linesize;
1211                 for (int y = 0; y < height; y++) {
1212                     for (int x = 0; x < width; x++) {
1213                         dst[x] = (uint8_t)((src[x] >> 1) + (src[x + src_linesize] >> 1));
1214                     }
1215
1216                     dst += dst_linesize;
1217                     src += src_linesize;
1218                 }
1219                 break;
1220             case 3:
1221                 src = s->pic[sidx]->data[i] + offsetx + (mv.x >> 1) +
1222                                (offsety + (mv.y >> 1)) * src_linesize;
1223                 for (int y = 0; y < height; y++) {
1224                     for (int x = 0; x < width; x++) {
1225                         dst[x] = (uint8_t)((((src[x] >> 1) + (src[x + 1] >> 1)) >> 1) +
1226                                            (((src[x + src_linesize] >> 1) + (src[x + 1 + src_linesize] >> 1)) >> 1));
1227                     }
1228
1229                     dst += dst_linesize;
1230                     src += src_linesize;
1231                 }
1232                 break;
1233             }
1234         }
1235     } else {
1236         int tidx;
1237         int adjx = index == 8 ? 0 :  width / 2;
1238         int adjy = index == 8 ? height / 2 : 0;
1239
1240         width  = width  - adjx;
1241         height = height - adjy;
1242         tidx = get_index(height) * 4 + get_index(width);
1243
1244         for (int i = 0; i < 2; i++) {
1245             int ret, idx2;
1246
1247             idx2 = get_vlc2(gb, mv_vlc[s->moflex][tidx].table,
1248                             MOBI_MV_VLC_BITS, 1);
1249
1250             ret = predict_motion(avctx, width, height, idx2,
1251                                  offsetm, offsetx + i * adjx, offsety + i * adjy);
1252             if (ret < 0)
1253                 return ret;
1254         }
1255     }
1256
1257     return 0;
1258 }
1259
1260 static int mobiclip_decode(AVCodecContext *avctx, void *data,
1261                             int *got_frame, AVPacket *pkt)
1262 {
1263     MobiClipContext *s = avctx->priv_data;
1264     GetBitContext *gb = &s->gb;
1265     AVFrame *frame = s->pic[s->current_pic];
1266     int ret;
1267
1268     av_fast_padded_malloc(&s->bitstream, &s->bitstream_size,
1269                           pkt->size);
1270
1271     if ((ret = ff_reget_buffer(avctx, frame, 0)) < 0)
1272         return ret;
1273
1274     s->bdsp.bswap16_buf((uint16_t *)s->bitstream,
1275                         (uint16_t *)pkt->data,
1276                         (pkt->size + 1) >> 1);
1277
1278     ret = init_get_bits8(gb, s->bitstream, FFALIGN(pkt->size, 2));
1279     if (ret < 0)
1280         return ret;
1281
1282     if (get_bits1(gb)) {
1283         frame->pict_type = AV_PICTURE_TYPE_I;
1284         frame->key_frame = 1;
1285         s->moflex = get_bits1(gb);
1286         s->dct_tab_idx = get_bits1(gb);
1287
1288         ret = setup_qtables(avctx, get_bits(gb, 6));
1289         if (ret < 0)
1290             return ret;
1291
1292         for (int y = 0; y < avctx->height; y += 16) {
1293             for (int x = 0; x < avctx->width; x += 16) {
1294                 ret = decode_macroblock(avctx, frame, x, y, get_bits1(gb));
1295                 if (ret < 0)
1296                     return ret;
1297             }
1298         }
1299     } else {
1300         MotionXY *motion = s->motion;
1301
1302         memset(motion, 0, s->motion_size);
1303
1304         frame->pict_type = AV_PICTURE_TYPE_P;
1305         frame->key_frame = 0;
1306         s->dct_tab_idx = 0;
1307
1308         ret = setup_qtables(avctx, s->quantizer + get_se_golomb(gb));
1309         if (ret < 0)
1310             return ret;
1311
1312         for (int y = 0; y < avctx->height; y += 16) {
1313             for (int x = 0; x < avctx->width; x += 16) {
1314                 int idx;
1315
1316                 motion[0].x = mid_pred(motion[x / 16 + 1].x, motion[x / 16 + 2].x, motion[x / 16 + 3].x);
1317                 motion[0].y = mid_pred(motion[x / 16 + 1].y, motion[x / 16 + 2].y, motion[x / 16 + 3].y);
1318                 motion[x / 16 + 2].x = 0;
1319                 motion[x / 16 + 2].y = 0;
1320
1321                 idx = get_vlc2(gb, mv_vlc[s->moflex][0].table,
1322                                    MOBI_MV_VLC_BITS, 1);
1323
1324                 if (idx == 6 || idx == 7) {
1325                     ret = decode_macroblock(avctx, frame, x, y, idx == 7);
1326                     if (ret < 0)
1327                         return ret;
1328                 } else {
1329                     int flags, idx2;
1330                     ret = predict_motion(avctx, 16, 16, idx, x / 16 + 2, x, y);
1331                     if (ret < 0)
1332                         return ret;
1333                     idx2 = get_ue_golomb(gb);
1334                     if (idx2 >= FF_ARRAY_ELEMS(pframe_block8x8_coefficients_tab))
1335                         return AVERROR_INVALIDDATA;
1336                     flags = pframe_block8x8_coefficients_tab[idx2];
1337
1338                     for (int sy = y; sy < y + 16; sy += 8) {
1339                         for (int sx = x; sx < x + 16; sx += 8) {
1340                             if (flags & 1)
1341                                 add_pframe_coefficients(avctx, frame, sx, sy, 8, 0);
1342                             flags >>= 1;
1343                         }
1344                     }
1345
1346                     if (flags & 1)
1347                         add_pframe_coefficients(avctx, frame, x >> 1, y >> 1, 8, 1 + !s->moflex);
1348                     flags >>= 1;
1349                     if (flags & 1)
1350                         add_pframe_coefficients(avctx, frame, x >> 1, y >> 1, 8, 2 - !s->moflex);
1351                 }
1352             }
1353         }
1354     }
1355
1356     if (!s->moflex)
1357         avctx->colorspace = AVCOL_SPC_YCGCO;
1358
1359     s->current_pic = (s->current_pic + 1) % 6;
1360     ret = av_frame_ref(data, frame);
1361     if (ret < 0)
1362         return ret;
1363     *got_frame = 1;
1364
1365     return 0;
1366 }
1367
1368 static void mobiclip_flush(AVCodecContext *avctx)
1369 {
1370     MobiClipContext *s = avctx->priv_data;
1371
1372     for (int i = 0; i < 6; i++)
1373         av_frame_unref(s->pic[i]);
1374 }
1375
1376 static av_cold int mobiclip_close(AVCodecContext *avctx)
1377 {
1378     MobiClipContext *s = avctx->priv_data;
1379
1380     av_freep(&s->bitstream);
1381     s->bitstream_size = 0;
1382     av_freep(&s->motion);
1383     s->motion_size = 0;
1384
1385     for (int i = 0; i < 6; i++) {
1386         av_frame_free(&s->pic[i]);
1387     }
1388
1389     return 0;
1390 }
1391
1392 AVCodec ff_mobiclip_decoder = {
1393     .name           = "mobiclip",
1394     .long_name      = NULL_IF_CONFIG_SMALL("MobiClip Video"),
1395     .type           = AVMEDIA_TYPE_VIDEO,
1396     .id             = AV_CODEC_ID_MOBICLIP,
1397     .priv_data_size = sizeof(MobiClipContext),
1398     .init           = mobiclip_init,
1399     .decode         = mobiclip_decode,
1400     .flush          = mobiclip_flush,
1401     .close          = mobiclip_close,
1402     .capabilities   = AV_CODEC_CAP_DR1,
1403     .caps_internal  = FF_CODEC_CAP_INIT_CLEANUP,
1404 };