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