2 * MobiClip Video decoder
3 * Copyright (c) 2017 Adib Surani
4 * Copyright (c) 2020 Paul B Mahol
6 * This file is part of FFmpeg.
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.
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.
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
25 #include "libavutil/avassert.h"
28 #include "bytestream.h"
34 #define MOBI_RL_VLC_BITS 12
35 #define MOBI_MV_VLC_BITS 6
37 static const uint8_t zigzag4x4_tab[] =
39 0x00, 0x04, 0x01, 0x02, 0x05, 0x08, 0x0C, 0x09, 0x06, 0x03, 0x07, 0x0A,
40 0x0D, 0x0E, 0x0B, 0x0F
43 static const uint8_t quant4x4_tab[][16] =
45 { 10, 13, 13, 10, 16, 10, 13, 13, 13, 13, 16, 10, 16, 13, 13, 16 },
46 { 11, 14, 14, 11, 18, 11, 14, 14, 14, 14, 18, 11, 18, 14, 14, 18 },
47 { 13, 16, 16, 13, 20, 13, 16, 16, 16, 16, 20, 13, 20, 16, 16, 20 },
48 { 14, 18, 18, 14, 23, 14, 18, 18, 18, 18, 23, 14, 23, 18, 18, 23 },
49 { 16, 20, 20, 16, 25, 16, 20, 20, 20, 20, 25, 16, 25, 20, 20, 25 },
50 { 18, 23, 23, 18, 29, 18, 23, 23, 23, 23, 29, 18, 29, 23, 23, 29 },
53 static const uint8_t quant8x8_tab[][64] =
55 { 20, 19, 19, 25, 18, 25, 19, 24, 24, 19, 20, 18, 32, 18, 20, 19, 19, 24, 24, 19, 19, 25, 18, 25, 18, 25, 18, 25, 19, 24, 24, 19,
56 19, 24, 24, 19, 18, 32, 18, 20, 18, 32, 18, 24, 24, 19, 19, 24, 24, 18, 25, 18, 25, 18, 19, 24, 24, 19, 18, 32, 18, 24, 24, 18,},
57 { 22, 21, 21, 28, 19, 28, 21, 26, 26, 21, 22, 19, 35, 19, 22, 21, 21, 26, 26, 21, 21, 28, 19, 28, 19, 28, 19, 28, 21, 26, 26, 21,
58 21, 26, 26, 21, 19, 35, 19, 22, 19, 35, 19, 26, 26, 21, 21, 26, 26, 19, 28, 19, 28, 19, 21, 26, 26, 21, 19, 35, 19, 26, 26, 19,},
59 { 26, 24, 24, 33, 23, 33, 24, 31, 31, 24, 26, 23, 42, 23, 26, 24, 24, 31, 31, 24, 24, 33, 23, 33, 23, 33, 23, 33, 24, 31, 31, 24,
60 24, 31, 31, 24, 23, 42, 23, 26, 23, 42, 23, 31, 31, 24, 24, 31, 31, 23, 33, 23, 33, 23, 24, 31, 31, 24, 23, 42, 23, 31, 31, 23,},
61 { 28, 26, 26, 35, 25, 35, 26, 33, 33, 26, 28, 25, 45, 25, 28, 26, 26, 33, 33, 26, 26, 35, 25, 35, 25, 35, 25, 35, 26, 33, 33, 26,
62 26, 33, 33, 26, 25, 45, 25, 28, 25, 45, 25, 33, 33, 26, 26, 33, 33, 25, 35, 25, 35, 25, 26, 33, 33, 26, 25, 45, 25, 33, 33, 25,},
63 { 32, 30, 30, 40, 28, 40, 30, 38, 38, 30, 32, 28, 51, 28, 32, 30, 30, 38, 38, 30, 30, 40, 28, 40, 28, 40, 28, 40, 30, 38, 38, 30,
64 30, 38, 38, 30, 28, 51, 28, 32, 28, 51, 28, 38, 38, 30, 30, 38, 38, 28, 40, 28, 40, 28, 30, 38, 38, 30, 28, 51, 28, 38, 38, 28,},
65 { 36, 34, 34, 46, 32, 46, 34, 43, 43, 34, 36, 32, 58, 32, 36, 34, 34, 43, 43, 34, 34, 46, 32, 46, 32, 46, 32, 46, 34, 43, 43, 34,
66 34, 43, 43, 34, 32, 58, 32, 36, 32, 58, 32, 43, 43, 34, 34, 43, 43, 32, 46, 32, 46, 32, 34, 43, 43, 34, 32, 58, 32, 43, 43, 32,},
69 static const uint8_t block4x4_coefficients_tab[] =
71 15, 0, 2, 1, 4, 8, 12, 3, 11, 13, 14, 7, 10, 5, 9, 6,
74 static const uint8_t pframe_block4x4_coefficients_tab[] =
76 0, 4, 1, 8, 2, 12, 3, 5, 10, 15, 7, 13, 14, 11, 9, 6,
79 static const uint8_t block8x8_coefficients_tab[] =
81 0x00, 0x1F, 0x3F, 0x0F, 0x08, 0x04, 0x02, 0x01, 0x0B, 0x0E, 0x1B, 0x0D,
82 0x03, 0x07, 0x0C, 0x17, 0x1D, 0x0A, 0x1E, 0x05, 0x10, 0x2F, 0x37, 0x3B,
83 0x13, 0x3D, 0x3E, 0x09, 0x1C, 0x06, 0x15, 0x1A, 0x33, 0x11, 0x12, 0x14,
84 0x18, 0x20, 0x3C, 0x35, 0x19, 0x16, 0x3A, 0x30, 0x31, 0x32, 0x27, 0x34,
85 0x2B, 0x2D, 0x39, 0x38, 0x23, 0x36, 0x2E, 0x21, 0x25, 0x22, 0x24, 0x2C,
86 0x2A, 0x28, 0x29, 0x26,
89 static const uint8_t pframe_block8x8_coefficients_tab[] =
91 0x00, 0x0F, 0x04, 0x01, 0x08, 0x02, 0x0C, 0x03, 0x05, 0x0A, 0x0D, 0x07, 0x0E, 0x0B, 0x1F, 0x09,
92 0x06, 0x10, 0x3F, 0x1E, 0x17, 0x1D, 0x1B, 0x1C, 0x13, 0x18, 0x1A, 0x12, 0x11, 0x14, 0x15, 0x20,
93 0x2F, 0x16, 0x19, 0x37, 0x3D, 0x3E, 0x3B, 0x3C, 0x33, 0x35, 0x21, 0x24, 0x22, 0x28, 0x23, 0x2C,
94 0x30, 0x27, 0x2D, 0x25, 0x3A, 0x2B, 0x2E, 0x2A, 0x31, 0x34, 0x38, 0x32, 0x29, 0x26, 0x39, 0x36
97 static const uint8_t run_residue[2][256] =
100 12, 6, 4, 3, 3, 3, 3, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0,
101 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
102 3, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
103 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
104 1, 27, 11, 7, 3, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
105 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
106 1, 41, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
107 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
110 27, 10, 5, 4, 3, 3, 3, 3, 2, 2, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
111 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
112 8, 3, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
113 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
114 1, 15, 10, 8, 4, 3, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
115 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
116 1, 21, 7, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
117 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
121 static const uint8_t bits0[] = {
122 9, 11, 11, 11, 11, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10,
123 10, 10, 11, 11, 11, 11, 11, 11, 11, 11, 12, 12, 12, 12, 12,
124 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 7, 10, 10, 9,
125 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
126 9, 9, 9, 9, 9, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
127 8, 8, 8, 7, 7, 7, 7, 7, 7, 7, 7, 6, 6, 6, 6,
128 6, 6, 6, 6, 6, 6, 5, 5, 5, 4, 2, 3, 4, 4,
131 static const uint16_t syms0[] = {
132 0x0, 0x822, 0x803, 0xB, 0xA, 0xB81, 0xB61, 0xB41, 0xB21, 0x122,
133 0x102, 0xE2, 0xC2, 0xA2, 0x63, 0x43, 0x24, 0xC, 0x25, 0x2E1, 0x301,
134 0xBA1, 0xBC1, 0xBE1, 0xC01, 0x26, 0x44, 0x83, 0xA3, 0xC3, 0x142,
135 0x321, 0x341, 0xC21, 0xC41, 0xC61, 0xC81, 0xCA1, 0xCC1, 0xCE1, 0xD01,
136 0x0, 0x9, 0x8, 0xB01, 0xAE1, 0xAC1, 0xAA1, 0xA81, 0xA61, 0xA41, 0xA21,
137 0x802, 0x2C1, 0x2A1, 0x281, 0x261, 0x241, 0x221, 0x201, 0x1E1, 0x82,
138 0x62, 0x7, 0x6, 0xA01, 0x9E1, 0x9C1, 0x9A1, 0x981, 0x961, 0x941, 0x921,
139 0x1C1, 0x1A1, 0x42, 0x23, 0x5, 0x901, 0x8E1, 0x8C1, 0x8A1, 0x181, 0x161,
140 0x141, 0x4, 0x881, 0x861, 0x841, 0x821, 0x121, 0x101, 0xE1, 0xC1, 0x22,
141 0x3, 0xA1, 0x81, 0x61, 0x801, 0x1, 0x21, 0x41, 0x2,
144 static const uint16_t syms1[] = {
145 0x0, 0x807, 0x806, 0x16, 0x15, 0x842, 0x823, 0x805, 0x1A1, 0xA3, 0x102, 0x83,
146 0x64, 0x44, 0x27, 0x14, 0x13, 0x17, 0x18, 0x28, 0x122, 0x862, 0x882, 0x9E1, 0xA01,
147 0x19, 0x1A, 0x1B, 0x29, 0xC3, 0x2A, 0x45, 0xE3, 0x1C1, 0x808, 0x8A2, 0x8C2, 0xA21,
148 0xA41, 0xA61, 0xA81, 0x0, 0x12, 0x11, 0x9C1, 0x9A1, 0x981, 0x961, 0x941, 0x822, 0x804,
149 0x181, 0x161, 0xE2, 0xC2, 0xA2, 0x63, 0x43, 0x26, 0x25, 0x10, 0x82, 0xF, 0xE, 0xD, 0x901,
150 0x8E1, 0x8C1, 0x803, 0x141, 0x121, 0x101, 0x921, 0x62, 0x24, 0xC, 0xB, 0xA, 0x881, 0x861,
151 0xC1, 0x8A1, 0xE1, 0x42, 0x23, 0x9, 0x802, 0xA1, 0x841, 0x821, 0x81, 0x61, 0x8, 0x7, 0x22,
152 0x6, 0x41, 0x5, 0x4, 0x801, 0x1, 0x2, 0x21, 0x3,
155 static const uint8_t mv_len[16] =
157 10, 8, 8, 7, 8, 8, 8, 7, 8, 8, 8, 7, 7, 7, 7, 6,
160 static const uint8_t mv_bits[16][10] =
162 { 3, 4, 5, 5, 3, 5, 6, 6, 4, 1 },
163 { 2, 3, 4, 5, 5, 2, 3, 3 },
164 { 2, 4, 4, 3, 3, 4, 4, 2 },
165 { 1, 4, 4, 3, 4, 4, 3 },
166 { 3, 3, 2, 4, 5, 5, 3, 2 },
167 { 3, 4, 4, 3, 3, 3, 3, 2 },
168 { 1, 3, 3, 4, 4, 4, 5, 5 },
169 { 1, 4, 4, 3, 3, 4, 4 },
170 { 2, 4, 4, 3, 3, 4, 4, 2 },
171 { 1, 3, 3, 4, 4, 4, 5, 5 },
172 { 2, 3, 4, 4, 4, 4, 3, 2 },
173 { 2, 3, 3, 4, 4, 3, 2 },
174 { 1, 4, 4, 3, 3, 4, 4 },
175 { 1, 4, 4, 3, 3, 4, 4 },
176 { 2, 3, 3, 4, 4, 3, 2 },
177 { 2, 3, 3, 3, 3, 2 },
180 static const uint8_t mv_syms[16][10] =
182 { 8, 2, 3, 6, 1, 7, 5, 4, 9, 0 },
183 { 9, 2, 3, 5, 4, 1, 8, 0 },
184 { 0, 5, 4, 2, 9, 3, 8, 1 },
185 { 1, 5, 4, 2, 8, 3, 0 },
186 { 2, 9, 8, 3, 5, 4, 0, 1 },
187 { 3, 5, 4, 2, 9, 8, 0, 1 },
188 { 1, 2, 0, 9, 8, 3, 5, 4 },
189 { 1, 8, 5, 2, 0, 4, 3 },
190 { 0, 5, 4, 2, 8, 3, 9, 1 },
191 { 1, 2, 0, 9, 8, 3, 5, 4 },
192 { 0, 3, 9, 8, 5, 4, 2, 1 },
193 { 0, 4, 3, 8, 5, 2, 1 },
194 { 1, 5, 4, 2, 0, 9, 3 },
195 { 1, 9, 5, 2, 0, 4, 3 },
196 { 0, 5, 3, 9, 4, 2, 1 },
197 { 0, 4, 5, 3, 2, 1 },
200 static const uint8_t mv_bits_mods[16][10] =
202 { 2, 3, 3, 5, 5, 4, 4, 5, 5, 2 },
203 { 2, 3, 4, 4, 3, 4, 4, 2 },
204 { 3, 4, 4, 2, 4, 4, 3, 2 },
205 { 1, 3, 4, 5, 5, 3, 3 },
206 { 2, 4, 4, 3, 3, 4, 4, 2 },
207 { 2, 3, 4, 4, 4, 4, 3, 2 },
208 { 2, 3, 4, 4, 4, 4, 3, 2 },
209 { 2, 2, 3, 4, 5, 5, 2 },
210 { 2, 3, 4, 4, 3, 4, 4, 2 },
211 { 2, 4, 4, 3, 4, 4, 3, 2 },
212 { 2, 3, 3, 5, 5, 4, 3, 2 },
213 { 2, 3, 4, 4, 3, 3, 2 },
214 { 1, 4, 4, 3, 3, 4, 4 },
215 { 2, 3, 4, 4, 3, 3, 2 },
216 { 2, 3, 4, 4, 3, 3, 2 },
217 { 3, 3, 2, 2, 3, 3 },
220 static const uint8_t mv_syms_mods[16][10] =
222 { 1, 8, 9, 4, 3, 2, 7, 5, 6, 0 },
223 { 0, 9, 5, 4, 2, 3, 8, 1 },
224 { 3, 9, 5, 0, 4, 8, 2, 1 },
225 { 1, 3, 4, 8, 5, 2, 0 },
226 { 0, 5, 4, 8, 2, 3, 9, 1 },
227 { 0, 3, 5, 9, 4, 8, 2, 1 },
228 { 0, 3, 9, 5, 8, 4, 2, 1 },
229 { 0, 2, 3, 4, 8, 5, 1 },
230 { 0, 3, 8, 4, 2, 5, 9, 1 },
231 { 2, 8, 9, 3, 5, 4, 0, 1 },
232 { 0, 4, 3, 8, 9, 5, 2, 1 },
233 { 0, 4, 8, 5, 3, 2, 1 },
234 { 1, 9, 4, 2, 0, 5, 3 },
235 { 2, 4, 9, 5, 3, 0, 1 },
236 { 0, 4, 9, 5, 3, 2, 1 },
237 { 5, 4, 1, 0, 3, 2 },
240 typedef struct BlockXY {
249 typedef struct MotionXY {
253 typedef struct MobiClipContext {
271 BswapDSPContext bdsp;
274 static VLC rl_vlc[2];
275 static VLC mv_vlc[2][16];
277 static av_cold int mobiclip_init(AVCodecContext *avctx)
279 MobiClipContext *s = avctx->priv_data;
281 if (avctx->width & 15 || avctx->height & 15) {
282 av_log(avctx, AV_LOG_ERROR, "width/height not multiple of 16\n");
283 return AVERROR_INVALIDDATA;
286 ff_bswapdsp_init(&s->bdsp);
288 avctx->pix_fmt = AV_PIX_FMT_YUV420P;
290 s->motion = av_calloc(avctx->width / 16 + 3, sizeof(MotionXY));
292 return AVERROR(ENOMEM);
293 s->motion_size = (avctx->width / 16 + 3) * sizeof(MotionXY);
295 for (int i = 0; i < 6; i++) {
296 s->pic[i] = av_frame_alloc();
298 return AVERROR(ENOMEM);
301 INIT_VLC_STATIC_FROM_LENGTHS(&rl_vlc[0], MOBI_RL_VLC_BITS, 104,
302 bits0, sizeof(*bits0),
303 syms0, sizeof(*syms0), sizeof(*syms0),
304 0, 0, 1 << MOBI_RL_VLC_BITS);
305 INIT_VLC_STATIC_FROM_LENGTHS(&rl_vlc[1], MOBI_RL_VLC_BITS, 104,
306 bits0, sizeof(*bits0),
307 syms1, sizeof(*syms1), sizeof(*syms1),
308 0, 0, 1 << MOBI_RL_VLC_BITS);
309 for (int j = 0; j < 16; j++) {
310 static VLC_TYPE vlc_buf[2 * 16 << MOBI_MV_VLC_BITS][2];
311 mv_vlc[0][j].table = &vlc_buf[2 * j << MOBI_MV_VLC_BITS];
312 mv_vlc[0][j].table_allocated = 1 << MOBI_MV_VLC_BITS;
313 ff_init_vlc_from_lengths(&mv_vlc[0][j], MOBI_MV_VLC_BITS, mv_len[j],
314 mv_bits_mods[j], sizeof(*mv_bits_mods[j]),
315 mv_syms_mods[j], sizeof(*mv_syms_mods[j]),
316 sizeof(*mv_syms_mods[j]), 0,
317 INIT_VLC_USE_NEW_STATIC, NULL);
318 mv_vlc[1][j].table = &vlc_buf[(2 * j + 1) << MOBI_MV_VLC_BITS];
319 mv_vlc[1][j].table_allocated = 1 << MOBI_MV_VLC_BITS;
320 ff_init_vlc_from_lengths(&mv_vlc[1][j], MOBI_MV_VLC_BITS, mv_len[j],
321 mv_bits[j], sizeof(*mv_bits[j]),
322 mv_syms[j], sizeof(*mv_syms[j]), sizeof(*mv_syms[j]),
323 0, INIT_VLC_USE_NEW_STATIC, NULL);
329 static int setup_qtables(AVCodecContext *avctx, int quantizer)
331 MobiClipContext *s = avctx->priv_data;
334 if (quantizer < 12 || quantizer > 161)
335 return AVERROR_INVALIDDATA;
337 s->quantizer = quantizer;
342 for (int i = 0; i < 16; i++)
343 s->qtab[0][i] = quant4x4_tab[qx][i] << qy;
345 for (int i = 0; i < 64; i++)
346 s->qtab[1][i] = quant8x8_tab[qx][i] << (qy - 2);
348 for (int i = 0; i < 20; i++)
354 static void inverse4(unsigned *rs)
356 unsigned a = rs[0] + rs[2];
357 unsigned b = rs[0] - rs[2];
358 unsigned c = rs[1] + ((int)rs[3] >> 1);
359 unsigned d = ((int)rs[1] >> 1) - rs[3];
367 static void idct(int *arr, int size)
370 unsigned x3, x2, x1, x0;
385 e = (unsigned)arr[7] + arr[1] - arr[3] - (arr[3] >> 1);
386 f = (unsigned)arr[7] - arr[1] + arr[5] + (arr[5] >> 1);
387 g = (unsigned)arr[5] - arr[3] - arr[7] - (arr[7] >> 1);
388 h = (unsigned)arr[5] + arr[3] + arr[1] + (arr[1] >> 1);
389 x3 = (unsigned)g + (h >> 2);
390 x2 = (unsigned)e + (f >> 2);
391 x1 = (e >> 2) - (unsigned)f;
392 x0 = (unsigned)h - (g >> 2);
394 arr[0] = tmp[0] + x0;
395 arr[1] = tmp[1] + x1;
396 arr[2] = tmp[2] + x2;
397 arr[3] = tmp[3] + x3;
398 arr[4] = tmp[3] - x3;
399 arr[5] = tmp[2] - x2;
400 arr[6] = tmp[1] - x1;
401 arr[7] = tmp[0] - x0;
404 static void read_run_encoding(AVCodecContext *avctx,
405 int *last, int *run, int *level)
407 MobiClipContext *s = avctx->priv_data;
408 GetBitContext *gb = &s->gb;
409 int n = get_vlc2(gb, rl_vlc[s->dct_tab_idx].table,
410 MOBI_RL_VLC_BITS, 1);
412 *last = (n >> 11) == 1;
413 *run = (n >> 5) & 0x3F;
417 static int add_coefficients(AVCodecContext *avctx, AVFrame *frame,
418 int bx, int by, int size, int plane)
420 MobiClipContext *s = avctx->priv_data;
421 GetBitContext *gb = &s->gb;
423 const uint8_t *ztab = size == 8 ? ff_zigzag_direct : zigzag4x4_tab;
424 const int *qtab = s->qtab[size == 8];
425 uint8_t *dst = frame->data[plane] + by * frame->linesize[plane] + bx;
427 for (int pos = 0; get_bits_left(gb) > 0; pos++) {
428 int qval, last, run, level;
430 read_run_encoding(avctx, &last, &run, &level);
435 } else if (!get_bits1(gb)) {
436 read_run_encoding(avctx, &last, &run, &level);
437 level += run_residue[s->dct_tab_idx][(last ? 64 : 0) + run];
440 } else if (!get_bits1(gb)) {
441 read_run_encoding(avctx, &last, &run, &level);
442 run += run_residue[s->dct_tab_idx][128 + (last ? 64 : 0) + level];
446 last = get_bits1(gb);
447 run = get_bits(gb, 6);
448 level = get_sbits(gb, 12);
452 if (pos >= size * size)
453 return AVERROR_INVALIDDATA;
455 mat[ztab[pos]] = qval *(unsigned)level;
462 for (int y = 0; y < size; y++)
463 idct(&mat[y * size], size);
465 for (int y = 0; y < size; y++) {
466 for (int x = y + 1; x < size; x++) {
467 int a = mat[x * size + y];
468 int b = mat[y * size + x];
470 mat[y * size + x] = a;
471 mat[x * size + y] = b;
474 idct(&mat[y * size], size);
475 for (int x = 0; x < size; x++)
476 dst[x] = av_clip_uint8(dst[x] + (mat[y * size + x] >> 6));
477 dst += frame->linesize[plane];
483 static int add_pframe_coefficients(AVCodecContext *avctx, AVFrame *frame,
484 int bx, int by, int size, int plane)
486 MobiClipContext *s = avctx->priv_data;
487 GetBitContext *gb = &s->gb;
488 int ret, idx = get_ue_golomb_31(gb);
491 ret = add_coefficients(avctx, frame, bx, by, size, plane);
492 } else if ((unsigned)idx < FF_ARRAY_ELEMS(pframe_block4x4_coefficients_tab)) {
493 int flags = pframe_block4x4_coefficients_tab[idx];
495 for (int y = by; y < by + 8; y += 4) {
496 for (int x = bx; x < bx + 8; x += 4) {
498 ret = add_coefficients(avctx, frame, x, y, 4, plane);
506 ret = AVERROR_INVALIDDATA;
512 static int adjust(int x, int size)
514 return size == 16 ? (x + 1) >> 1 : x;
517 static uint8_t pget(BlockXY b)
522 if (b.x == -1 && b.y >= b.size) {
523 ret.x = -1, ret.y = b.size - 1;
524 } else if (b.x >= -1 && b.y >= -1) {
525 ret.x = b.x, ret.y = b.y;
526 } else if (b.x == -1 && b.y == -2) {
527 ret.x = 0, ret.y = -1;
528 } else if (b.x == -2 && b.y == -1) {
529 ret.x = -1, ret.y = 0;
532 y = av_clip(ret.ay + ret.y, 0, ret.h - 1);
533 x = av_clip(ret.ax + ret.x, 0, ret.w - 1);
535 return ret.block[y * ret.linesize + x];
538 static uint8_t half(int a, int b)
540 return ((a + b) + 1) / 2;
543 static uint8_t half3(int a, int b, int c)
545 return ((a + b + b + c) * 2 / 4 + 1) / 2;;
548 static uint8_t pick_above(BlockXY bxy)
555 static uint8_t pick_left(BlockXY bxy)
562 static uint8_t half_horz(BlockXY bxy)
564 BlockXY a = bxy, b = bxy, c = bxy;
569 return half3(pget(a), pget(b), pget(c));
572 static uint8_t half_vert(BlockXY bxy)
574 BlockXY a = bxy, b = bxy, c = bxy;
579 return half3(pget(a), pget(b), pget(c));
582 static uint8_t pick_4(BlockXY bxy)
586 if ((bxy.x % 2) == 0) {
592 ba.y = bxy.y + bxy.x / 2;
597 bb.y = bxy.y + bxy.x / 2 + 1;
606 ba.y = bxy.y + bxy.x / 2 + 1;
613 static uint8_t pick_5(BlockXY bxy)
626 val = half(pget(a), pget(b));
627 } else if (bxy.y == 0) {
634 } else if (bxy.x == 1) {
653 static uint8_t pick_6(BlockXY bxy)
666 val = half(pget(a), pget(b));
667 } else if (bxy.x == 0) {
674 } else if (bxy.y == 1) {
693 static uint8_t pick_7(BlockXY bxy)
722 return half3(acc1, clr, acc2);
725 static uint8_t pick_8(BlockXY bxy)
743 } else if (bxy.y == 1) {
748 } else if (bxy.x < bxy.size - 1) {
753 } else if (bxy.y % 2 == 0) {
756 ba.x = bxy.y / 2 + bxy.size - 1;
760 bb.x = bxy.y / 2 + bxy.size;
767 ba.x = bxy.y / 2 + bxy.size;
776 static void block_fill_simple(uint8_t *block, int size, int linesize, int fill)
778 for (int y = 0; y < size; y++) {
779 memset(block, fill, size);
784 static void block_fill(uint8_t *block, int size, int linesize,
785 int w, int h, int ax, int ay,
786 uint8_t (*pick)(BlockXY bxy))
792 bxy.linesize = linesize;
798 for (int y = 0; y < size; y++) {
800 for (int x = 0; x < size; x++) {
807 block[ax + x + (ay + y) * linesize] = val;
812 static int block_sum(const uint8_t *block, int w, int h, int linesize)
816 for (int y = 0; y < h; y++) {
817 for (int x = 0; x < w; x++) {
826 static int predict_intra(AVCodecContext *avctx, AVFrame *frame, int ax, int ay,
827 int pmode, int add_coeffs, int size, int plane)
829 MobiClipContext *s = avctx->priv_data;
830 GetBitContext *gb = &s->gb;
831 int w = avctx->width >> !!plane, h = avctx->height >> !!plane;
836 block_fill(frame->data[plane], size, frame->linesize[plane], w, h, ax, ay, pick_above);
839 block_fill(frame->data[plane], size, frame->linesize[plane], w, h, ax, ay, pick_left);
845 uint8_t *top = frame->data[plane] + FFMAX(ay - 1, 0) * frame->linesize[plane] + ax;
846 uint8_t *left = frame->data[plane] + ay * frame->linesize[plane] + FFMAX(ax - 1, 0);
847 int bottommost = frame->data[plane][(ay + size - 1) * frame->linesize[plane] + FFMAX(ax - 1, 0)];
848 int rightmost = frame->data[plane][FFMAX(ay - 1, 0) * frame->linesize[plane] + ax + size - 1];
849 int avg = (bottommost + rightmost + 1) / 2 + 2 * get_se_golomb(gb);
850 int r6 = adjust(avg - bottommost, size);
851 int r9 = adjust(avg - rightmost, size);
852 int shift = adjust(size, size) == 8 ? 3 : 2;
855 for (int x = 0; x < size; x++) {
857 arr1[x] = adjust(((bottommost - val) * (1 << shift)) + r6 * (x + 1), size);
860 for (int y = 0; y < size; y++) {
861 int val = left[y * frame->linesize[plane]];
862 arr2[y] = adjust(((rightmost - val) * (1 << shift)) + r9 * (y + 1), size);
865 block = frame->data[plane] + ay * frame->linesize[plane] + ax;
866 for (int y = 0; y < size; y++) {
867 for (int x = 0; x < size; x++) {
868 block[x] = (((top[x] + left[0] + ((arr1[x] * (y + 1) +
869 arr2[y] * (x + 1)) >> 2 * shift)) + 1) / 2) & 0xFF;
871 block += frame->linesize[plane];
872 left += frame->linesize[plane];
880 if (ax == 0 && ay == 0) {
882 } else if (ax >= 1 && ay >= 1) {
883 int left = block_sum(frame->data[plane] + ay * frame->linesize[plane] + ax - 1,
884 1, size, frame->linesize[plane]);
885 int top = block_sum(frame->data[plane] + (ay - 1) * frame->linesize[plane] + ax,
886 size, 1, frame->linesize[plane]);
888 fill = ((left + top) * 2 / (2 * size) + 1) / 2;
889 } else if (ax >= 1) {
890 fill = (block_sum(frame->data[plane] + ay * frame->linesize[plane] + ax - 1,
891 1, size, frame->linesize[plane]) * 2 / size + 1) / 2;
892 } else if (ay >= 1) {
893 fill = (block_sum(frame->data[plane] + (ay - 1) * frame->linesize[plane] + ax,
894 size, 1, frame->linesize[plane]) * 2 / size + 1) / 2;
899 block_fill_simple(frame->data[plane] + ay * frame->linesize[plane] + ax,
900 size, frame->linesize[plane], fill);
904 block_fill(frame->data[plane], size, frame->linesize[plane], w, h, ax, ay, pick_4);
907 block_fill(frame->data[plane], size, frame->linesize[plane], w, h, ax, ay, pick_5);
910 block_fill(frame->data[plane], size, frame->linesize[plane], w, h, ax, ay, pick_6);
913 block_fill(frame->data[plane], size, frame->linesize[plane], w, h, ax, ay, pick_7);
916 block_fill(frame->data[plane], size, frame->linesize[plane], w, h, ax, ay, pick_8);
921 ret = add_coefficients(avctx, frame, ax, ay, size, plane);
926 static int get_prediction(AVCodecContext *avctx, int x, int y, int size)
928 MobiClipContext *s = avctx->priv_data;
929 GetBitContext *gb = &s->gb;
930 int index = (y & 0xC) | (x / 4 % 4);
932 uint8_t val = FFMIN(s->pre[index], index % 4 == 0 ? 9 : s->pre[index + 3]);
936 if (!get_bits1(gb)) {
937 int x = get_bits(gb, 3);
938 val = x + (x >= val ? 1 : 0);
941 s->pre[index + 4] = val;
943 s->pre[index + 5] = s->pre[index + 8] = s->pre[index + 9] = val;
948 static int process_block(AVCodecContext *avctx, AVFrame *frame,
949 int x, int y, int pmode, int has_coeffs, int plane)
951 MobiClipContext *s = avctx->priv_data;
952 GetBitContext *gb = &s->gb;
957 pmode = get_prediction(avctx, x, y, 8);
958 return predict_intra(avctx, frame, x, y, pmode, 0, 8, plane);
961 tmp = get_ue_golomb_31(gb);
962 if ((unsigned)tmp > FF_ARRAY_ELEMS(block4x4_coefficients_tab))
963 return AVERROR_INVALIDDATA;
967 pmode = get_prediction(avctx, x, y, 8);
968 ret = predict_intra(avctx, frame, x, y, pmode, 1, 8, plane);
970 int flags = block4x4_coefficients_tab[tmp - 1];
972 for (int by = y; by < y + 8; by += 4) {
973 for (int bx = x; bx < x + 8; bx += 4) {
974 int new_pmode = pmode;
977 new_pmode = get_prediction(avctx, bx, by, 4);
978 ret = predict_intra(avctx, frame, bx, by, new_pmode, flags & 1, 4, plane);
989 static int decode_macroblock(AVCodecContext *avctx, AVFrame *frame,
990 int x, int y, int predict)
992 MobiClipContext *s = avctx->priv_data;
993 GetBitContext *gb = &s->gb;
994 int flags, pmode_uv, idx = get_ue_golomb(gb);
997 if (idx < 0 || idx >= FF_ARRAY_ELEMS(block8x8_coefficients_tab))
998 return AVERROR_INVALIDDATA;
1000 flags = block8x8_coefficients_tab[idx];
1003 ret = process_block(avctx, frame, x, y, -1, flags & 1, 0);
1007 ret = process_block(avctx, frame, x + 8, y, -1, flags & 1, 0);
1011 ret = process_block(avctx, frame, x, y + 8, -1, flags & 1, 0);
1015 ret = process_block(avctx, frame, x + 8, y + 8, -1, flags & 1, 0);
1020 int pmode = get_bits(gb, 3);
1023 ret = predict_intra(avctx, frame, x, y, pmode, 0, 16, 0);
1029 ret = process_block(avctx, frame, x, y, pmode, flags & 1, 0);
1033 ret = process_block(avctx, frame, x + 8, y, pmode, flags & 1, 0);
1037 ret = process_block(avctx, frame, x, y + 8, pmode, flags & 1, 0);
1041 ret = process_block(avctx, frame, x + 8, y + 8, pmode, flags & 1, 0);
1047 pmode_uv = get_bits(gb, 3);
1048 if (pmode_uv == 2) {
1049 ret = predict_intra(avctx, frame, x >> 1, y >> 1, pmode_uv, 0, 8, 1 + !s->moflex);
1052 ret = predict_intra(avctx, frame, x >> 1, y >> 1, pmode_uv, 0, 8, 2 - !s->moflex);
1058 ret = process_block(avctx, frame, x >> 1, y >> 1, pmode_uv, flags & 1, 1 + !s->moflex);
1062 ret = process_block(avctx, frame, x >> 1, y >> 1, pmode_uv, flags & 1, 2 - !s->moflex);
1069 static int get_index(int x)
1071 return x == 16 ? 0 : x == 8 ? 1 : x == 4 ? 2 : x == 2 ? 3 : 0;
1074 static int predict_motion(AVCodecContext *avctx,
1075 int width, int height, int index,
1076 int offsetm, int offsetx, int offsety)
1078 MobiClipContext *s = avctx->priv_data;
1079 MotionXY *motion = s->motion;
1080 GetBitContext *gb = &s->gb;
1081 int fheight = avctx->height;
1082 int fwidth = avctx->width;
1085 int sidx = -FFMAX(1, index) + s->current_pic;
1086 MotionXY mv = s->motion[0];
1092 mv.x = mv.x + get_se_golomb(gb);
1093 mv.y = mv.y + get_se_golomb(gb);
1095 if (mv.x >= INT_MAX || mv.y >= INT_MAX)
1096 return AVERROR_INVALIDDATA;
1098 motion[offsetm].x = mv.x;
1099 motion[offsetm].y = mv.y;
1101 for (int i = 0; i < 3; i++) {
1102 int method, src_linesize, dst_linesize;
1106 offsetx = offsetx >> 1;
1107 offsety = offsety >> 1;
1111 height = height >> 1;
1112 fwidth = fwidth >> 1;
1113 fheight = fheight >> 1;
1116 av_assert0(s->pic[sidx]);
1117 av_assert0(s->pic[s->current_pic]);
1118 av_assert0(s->pic[s->current_pic]->data[i]);
1119 if (!s->pic[sidx]->data[i])
1120 return AVERROR_INVALIDDATA;
1122 method = (mv.x & 1) | ((mv.y & 1) << 1);
1123 src_linesize = s->pic[sidx]->linesize[i];
1124 dst_linesize = s->pic[s->current_pic]->linesize[i];
1125 dst = s->pic[s->current_pic]->data[i] + offsetx + offsety * dst_linesize;
1127 if (offsetx + (mv.x >> 1) < 0 ||
1128 offsety + (mv.y >> 1) < 0 ||
1129 offsetx + width + (mv.x + 1 >> 1) > fwidth ||
1130 offsety + height + (mv.y + 1 >> 1) > fheight)
1131 return AVERROR_INVALIDDATA;
1135 src = s->pic[sidx]->data[i] + offsetx + (mv.x >> 1) +
1136 (offsety + (mv.y >> 1)) * src_linesize;
1137 for (int y = 0; y < height; y++) {
1138 for (int x = 0; x < width; x++)
1140 dst += dst_linesize;
1141 src += src_linesize;
1145 src = s->pic[sidx]->data[i] + offsetx + (mv.x >> 1) +
1146 (offsety + (mv.y >> 1)) * src_linesize;
1147 for (int y = 0; y < height; y++) {
1148 for (int x = 0; x < width; x++) {
1149 dst[x] = (uint8_t)((src[x] >> 1) + (src[x + 1] >> 1));
1152 dst += dst_linesize;
1153 src += src_linesize;
1157 src = s->pic[sidx]->data[i] + offsetx + (mv.x >> 1) +
1158 (offsety + (mv.y >> 1)) * src_linesize;
1159 for (int y = 0; y < height; y++) {
1160 for (int x = 0; x < width; x++) {
1161 dst[x] = (uint8_t)((src[x] >> 1) + (src[x + src_linesize] >> 1));
1164 dst += dst_linesize;
1165 src += src_linesize;
1169 src = s->pic[sidx]->data[i] + offsetx + (mv.x >> 1) +
1170 (offsety + (mv.y >> 1)) * src_linesize;
1171 for (int y = 0; y < height; y++) {
1172 for (int x = 0; x < width; x++) {
1173 dst[x] = (uint8_t)((((src[x] >> 1) + (src[x + 1] >> 1)) >> 1) +
1174 (((src[x + src_linesize] >> 1) + (src[x + 1 + src_linesize] >> 1)) >> 1));
1177 dst += dst_linesize;
1178 src += src_linesize;
1185 int adjx = index == 8 ? 0 : width / 2;
1186 int adjy = index == 8 ? height / 2 : 0;
1188 width = width - adjx;
1189 height = height - adjy;
1190 tidx = get_index(height) * 4 + get_index(width);
1192 for (int i = 0; i < 2; i++) {
1195 idx2 = get_vlc2(gb, mv_vlc[s->moflex][tidx].table,
1196 MOBI_MV_VLC_BITS, 1);
1198 ret = predict_motion(avctx, width, height, idx2,
1199 offsetm, offsetx + i * adjx, offsety + i * adjy);
1208 static int mobiclip_decode(AVCodecContext *avctx, void *data,
1209 int *got_frame, AVPacket *pkt)
1211 MobiClipContext *s = avctx->priv_data;
1212 GetBitContext *gb = &s->gb;
1213 AVFrame *frame = s->pic[s->current_pic];
1216 av_fast_padded_malloc(&s->bitstream, &s->bitstream_size,
1219 if ((ret = ff_reget_buffer(avctx, frame, 0)) < 0)
1222 s->bdsp.bswap16_buf((uint16_t *)s->bitstream,
1223 (uint16_t *)pkt->data,
1224 (pkt->size + 1) >> 1);
1226 ret = init_get_bits8(gb, s->bitstream, FFALIGN(pkt->size, 2));
1230 if (get_bits1(gb)) {
1231 frame->pict_type = AV_PICTURE_TYPE_I;
1232 frame->key_frame = 1;
1233 s->moflex = get_bits1(gb);
1234 s->dct_tab_idx = get_bits1(gb);
1236 ret = setup_qtables(avctx, get_bits(gb, 6));
1240 for (int y = 0; y < avctx->height; y += 16) {
1241 for (int x = 0; x < avctx->width; x += 16) {
1242 ret = decode_macroblock(avctx, frame, x, y, get_bits1(gb));
1248 MotionXY *motion = s->motion;
1250 memset(motion, 0, s->motion_size);
1252 frame->pict_type = AV_PICTURE_TYPE_P;
1253 frame->key_frame = 0;
1256 ret = setup_qtables(avctx, s->quantizer + get_se_golomb(gb));
1260 for (int y = 0; y < avctx->height; y += 16) {
1261 for (int x = 0; x < avctx->width; x += 16) {
1264 motion[0].x = mid_pred(motion[x / 16 + 1].x, motion[x / 16 + 2].x, motion[x / 16 + 3].x);
1265 motion[0].y = mid_pred(motion[x / 16 + 1].y, motion[x / 16 + 2].y, motion[x / 16 + 3].y);
1266 motion[x / 16 + 2].x = 0;
1267 motion[x / 16 + 2].y = 0;
1269 idx = get_vlc2(gb, mv_vlc[s->moflex][0].table,
1270 MOBI_MV_VLC_BITS, 1);
1272 if (idx == 6 || idx == 7) {
1273 ret = decode_macroblock(avctx, frame, x, y, idx == 7);
1278 ret = predict_motion(avctx, 16, 16, idx, x / 16 + 2, x, y);
1281 idx2 = get_ue_golomb(gb);
1282 if (idx2 >= FF_ARRAY_ELEMS(pframe_block8x8_coefficients_tab))
1283 return AVERROR_INVALIDDATA;
1284 flags = pframe_block8x8_coefficients_tab[idx2];
1286 for (int sy = y; sy < y + 16; sy += 8) {
1287 for (int sx = x; sx < x + 16; sx += 8) {
1289 add_pframe_coefficients(avctx, frame, sx, sy, 8, 0);
1295 add_pframe_coefficients(avctx, frame, x >> 1, y >> 1, 8, 1 + !s->moflex);
1298 add_pframe_coefficients(avctx, frame, x >> 1, y >> 1, 8, 2 - !s->moflex);
1305 avctx->colorspace = AVCOL_SPC_YCGCO;
1307 s->current_pic = (s->current_pic + 1) % 6;
1308 ret = av_frame_ref(data, frame);
1316 static void mobiclip_flush(AVCodecContext *avctx)
1318 MobiClipContext *s = avctx->priv_data;
1320 for (int i = 0; i < 6; i++)
1321 av_frame_unref(s->pic[i]);
1324 static av_cold int mobiclip_close(AVCodecContext *avctx)
1326 MobiClipContext *s = avctx->priv_data;
1328 av_freep(&s->bitstream);
1329 s->bitstream_size = 0;
1330 av_freep(&s->motion);
1333 for (int i = 0; i < 6; i++) {
1334 av_frame_free(&s->pic[i]);
1340 AVCodec ff_mobiclip_decoder = {
1342 .long_name = NULL_IF_CONFIG_SMALL("MobiClip Video"),
1343 .type = AVMEDIA_TYPE_VIDEO,
1344 .id = AV_CODEC_ID_MOBICLIP,
1345 .priv_data_size = sizeof(MobiClipContext),
1346 .init = mobiclip_init,
1347 .decode = mobiclip_decode,
1348 .flush = mobiclip_flush,
1349 .close = mobiclip_close,
1350 .capabilities = AV_CODEC_CAP_DR1,
1351 .caps_internal = FF_CODEC_CAP_INIT_CLEANUP,