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