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