FFmpeg
Loading...
Searching...
No Matches
mobiclip.c
Go to the documentation of this file.
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
27#include "libavutil/avassert.h"
28#include "libavutil/mem.h"
29#include "libavutil/thread.h"
30
31#include "avcodec.h"
32#include "bswapdsp.h"
33#include "codec_internal.h"
34#include "decode.h"
35#include "get_bits.h"
36#include "golomb.h"
37#include "mathops.h"
38
39#define MOBI_RL_VLC_BITS 12
40#define MOBI_MV_VLC_BITS 6
41
42static const uint8_t zigzag4x4_tab[] =
43{
44 0x00, 0x04, 0x01, 0x02, 0x05, 0x08, 0x0C, 0x09, 0x06, 0x03, 0x07, 0x0A,
45 0x0D, 0x0E, 0x0B, 0x0F
46};
47
48static const uint8_t quant4x4_tab[][16] =
49{
50 { 10, 13, 13, 10, 16, 10, 13, 13, 13, 13, 16, 10, 16, 13, 13, 16 },
51 { 11, 14, 14, 11, 18, 11, 14, 14, 14, 14, 18, 11, 18, 14, 14, 18 },
52 { 13, 16, 16, 13, 20, 13, 16, 16, 16, 16, 20, 13, 20, 16, 16, 20 },
53 { 14, 18, 18, 14, 23, 14, 18, 18, 18, 18, 23, 14, 23, 18, 18, 23 },
54 { 16, 20, 20, 16, 25, 16, 20, 20, 20, 20, 25, 16, 25, 20, 20, 25 },
55 { 18, 23, 23, 18, 29, 18, 23, 23, 23, 23, 29, 18, 29, 23, 23, 29 },
56};
57
58static const uint8_t quant8x8_tab[][64] =
59{
60 { 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,
61 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,},
62 { 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,
63 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,},
64 { 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,
65 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,},
66 { 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,
67 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,},
68 { 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,
69 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,},
70 { 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,
71 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,},
72};
73
74static const uint8_t block4x4_coefficients_tab[] =
75{
76 15, 0, 2, 1, 4, 8, 12, 3, 11, 13, 14, 7, 10, 5, 9, 6,
77};
78
79static const uint8_t pframe_block4x4_coefficients_tab[] =
80{
81 0, 4, 1, 8, 2, 12, 3, 5, 10, 15, 7, 13, 14, 11, 9, 6,
82};
83
84static const uint8_t block8x8_coefficients_tab[] =
85{
86 0x00, 0x1F, 0x3F, 0x0F, 0x08, 0x04, 0x02, 0x01, 0x0B, 0x0E, 0x1B, 0x0D,
87 0x03, 0x07, 0x0C, 0x17, 0x1D, 0x0A, 0x1E, 0x05, 0x10, 0x2F, 0x37, 0x3B,
88 0x13, 0x3D, 0x3E, 0x09, 0x1C, 0x06, 0x15, 0x1A, 0x33, 0x11, 0x12, 0x14,
89 0x18, 0x20, 0x3C, 0x35, 0x19, 0x16, 0x3A, 0x30, 0x31, 0x32, 0x27, 0x34,
90 0x2B, 0x2D, 0x39, 0x38, 0x23, 0x36, 0x2E, 0x21, 0x25, 0x22, 0x24, 0x2C,
91 0x2A, 0x28, 0x29, 0x26,
92};
93
94static const uint8_t pframe_block8x8_coefficients_tab[] =
95{
96 0x00, 0x0F, 0x04, 0x01, 0x08, 0x02, 0x0C, 0x03, 0x05, 0x0A, 0x0D, 0x07, 0x0E, 0x0B, 0x1F, 0x09,
97 0x06, 0x10, 0x3F, 0x1E, 0x17, 0x1D, 0x1B, 0x1C, 0x13, 0x18, 0x1A, 0x12, 0x11, 0x14, 0x15, 0x20,
98 0x2F, 0x16, 0x19, 0x37, 0x3D, 0x3E, 0x3B, 0x3C, 0x33, 0x35, 0x21, 0x24, 0x22, 0x28, 0x23, 0x2C,
99 0x30, 0x27, 0x2D, 0x25, 0x3A, 0x2B, 0x2E, 0x2A, 0x31, 0x34, 0x38, 0x32, 0x29, 0x26, 0x39, 0x36
100};
101
102static const uint8_t run_residue[2][256] =
103{
104 {
105 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,
106 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,
107 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,
108 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,
109 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,
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 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,
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 },
114 {
115 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,
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 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,
118 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,
119 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,
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 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,
122 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,
123 },
124};
125
126static const uint8_t bits0[] = {
127 9, 11, 11, 11, 11, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10,
128 10, 10, 11, 11, 11, 11, 11, 11, 11, 11, 12, 12, 12, 12, 12,
129 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 7, 10, 10, 9,
130 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
131 9, 9, 9, 9, 9, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
132 8, 8, 8, 7, 7, 7, 7, 7, 7, 7, 7, 6, 6, 6, 6,
133 6, 6, 6, 6, 6, 6, 5, 5, 5, 4, 2, 3, 4, 4,
134};
135
136static const uint16_t syms0[] = {
137 0x0, 0x822, 0x803, 0xB, 0xA, 0xB81, 0xB61, 0xB41, 0xB21, 0x122,
138 0x102, 0xE2, 0xC2, 0xA2, 0x63, 0x43, 0x24, 0xC, 0x25, 0x2E1, 0x301,
139 0xBA1, 0xBC1, 0xBE1, 0xC01, 0x26, 0x44, 0x83, 0xA3, 0xC3, 0x142,
140 0x321, 0x341, 0xC21, 0xC41, 0xC61, 0xC81, 0xCA1, 0xCC1, 0xCE1, 0xD01,
141 0x0, 0x9, 0x8, 0xB01, 0xAE1, 0xAC1, 0xAA1, 0xA81, 0xA61, 0xA41, 0xA21,
142 0x802, 0x2C1, 0x2A1, 0x281, 0x261, 0x241, 0x221, 0x201, 0x1E1, 0x82,
143 0x62, 0x7, 0x6, 0xA01, 0x9E1, 0x9C1, 0x9A1, 0x981, 0x961, 0x941, 0x921,
144 0x1C1, 0x1A1, 0x42, 0x23, 0x5, 0x901, 0x8E1, 0x8C1, 0x8A1, 0x181, 0x161,
145 0x141, 0x4, 0x881, 0x861, 0x841, 0x821, 0x121, 0x101, 0xE1, 0xC1, 0x22,
146 0x3, 0xA1, 0x81, 0x61, 0x801, 0x1, 0x21, 0x41, 0x2,
147};
148
149static const uint16_t syms1[] = {
150 0x0, 0x807, 0x806, 0x16, 0x15, 0x842, 0x823, 0x805, 0x1A1, 0xA3, 0x102, 0x83,
151 0x64, 0x44, 0x27, 0x14, 0x13, 0x17, 0x18, 0x28, 0x122, 0x862, 0x882, 0x9E1, 0xA01,
152 0x19, 0x1A, 0x1B, 0x29, 0xC3, 0x2A, 0x45, 0xE3, 0x1C1, 0x808, 0x8A2, 0x8C2, 0xA21,
153 0xA41, 0xA61, 0xA81, 0x0, 0x12, 0x11, 0x9C1, 0x9A1, 0x981, 0x961, 0x941, 0x822, 0x804,
154 0x181, 0x161, 0xE2, 0xC2, 0xA2, 0x63, 0x43, 0x26, 0x25, 0x10, 0x82, 0xF, 0xE, 0xD, 0x901,
155 0x8E1, 0x8C1, 0x803, 0x141, 0x121, 0x101, 0x921, 0x62, 0x24, 0xC, 0xB, 0xA, 0x881, 0x861,
156 0xC1, 0x8A1, 0xE1, 0x42, 0x23, 0x9, 0x802, 0xA1, 0x841, 0x821, 0x81, 0x61, 0x8, 0x7, 0x22,
157 0x6, 0x41, 0x5, 0x4, 0x801, 0x1, 0x2, 0x21, 0x3,
158};
159
160static const uint8_t mv_len[16] =
161{
162 10, 8, 8, 7, 8, 8, 8, 7, 8, 8, 8, 7, 7, 7, 7, 6,
163};
164
165static const uint8_t mv_bits[2][16][10] =
166{
167 {
168 { 2, 3, 3, 5, 5, 4, 4, 5, 5, 2 },
169 { 2, 3, 4, 4, 3, 4, 4, 2 },
170 { 3, 4, 4, 2, 4, 4, 3, 2 },
171 { 1, 3, 4, 5, 5, 3, 3 },
172 { 2, 4, 4, 3, 3, 4, 4, 2 },
173 { 2, 3, 4, 4, 4, 4, 3, 2 },
174 { 2, 3, 4, 4, 4, 4, 3, 2 },
175 { 2, 2, 3, 4, 5, 5, 2 },
176 { 2, 3, 4, 4, 3, 4, 4, 2 },
177 { 2, 4, 4, 3, 4, 4, 3, 2 },
178 { 2, 3, 3, 5, 5, 4, 3, 2 },
179 { 2, 3, 4, 4, 3, 3, 2 },
180 { 1, 4, 4, 3, 3, 4, 4 },
181 { 2, 3, 4, 4, 3, 3, 2 },
182 { 2, 3, 4, 4, 3, 3, 2 },
183 { 3, 3, 2, 2, 3, 3 },
184 },
185 {
186 { 3, 4, 5, 5, 3, 5, 6, 6, 4, 1 },
187 { 2, 3, 4, 5, 5, 2, 3, 3 },
188 { 2, 4, 4, 3, 3, 4, 4, 2 },
189 { 1, 4, 4, 3, 4, 4, 3 },
190 { 3, 3, 2, 4, 5, 5, 3, 2 },
191 { 3, 4, 4, 3, 3, 3, 3, 2 },
192 { 1, 3, 3, 4, 4, 4, 5, 5 },
193 { 1, 4, 4, 3, 3, 4, 4 },
194 { 2, 4, 4, 3, 3, 4, 4, 2 },
195 { 1, 3, 3, 4, 4, 4, 5, 5 },
196 { 2, 3, 4, 4, 4, 4, 3, 2 },
197 { 2, 3, 3, 4, 4, 3, 2 },
198 { 1, 4, 4, 3, 3, 4, 4 },
199 { 1, 4, 4, 3, 3, 4, 4 },
200 { 2, 3, 3, 4, 4, 3, 2 },
201 { 2, 3, 3, 3, 3, 2 },
202 }
203};
204
205static const uint8_t mv_syms[2][16][10] =
206{
207 {
208 { 1, 8, 9, 4, 3, 2, 7, 5, 6, 0 },
209 { 0, 9, 5, 4, 2, 3, 8, 1 },
210 { 3, 9, 5, 0, 4, 8, 2, 1 },
211 { 1, 3, 4, 8, 5, 2, 0 },
212 { 0, 5, 4, 8, 2, 3, 9, 1 },
213 { 0, 3, 5, 9, 4, 8, 2, 1 },
214 { 0, 3, 9, 5, 8, 4, 2, 1 },
215 { 0, 2, 3, 4, 8, 5, 1 },
216 { 0, 3, 8, 4, 2, 5, 9, 1 },
217 { 2, 8, 9, 3, 5, 4, 0, 1 },
218 { 0, 4, 3, 8, 9, 5, 2, 1 },
219 { 0, 4, 8, 5, 3, 2, 1 },
220 { 1, 9, 4, 2, 0, 5, 3 },
221 { 2, 4, 9, 5, 3, 0, 1 },
222 { 0, 4, 9, 5, 3, 2, 1 },
223 { 5, 4, 1, 0, 3, 2 },
224 },
225 {
226 { 8, 2, 3, 6, 1, 7, 5, 4, 9, 0 },
227 { 9, 2, 3, 5, 4, 1, 8, 0 },
228 { 0, 5, 4, 2, 9, 3, 8, 1 },
229 { 1, 5, 4, 2, 8, 3, 0 },
230 { 2, 9, 8, 3, 5, 4, 0, 1 },
231 { 3, 5, 4, 2, 9, 8, 0, 1 },
232 { 1, 2, 0, 9, 8, 3, 5, 4 },
233 { 1, 8, 5, 2, 0, 4, 3 },
234 { 0, 5, 4, 2, 8, 3, 9, 1 },
235 { 1, 2, 0, 9, 8, 3, 5, 4 },
236 { 0, 3, 9, 8, 5, 4, 2, 1 },
237 { 0, 4, 3, 8, 5, 2, 1 },
238 { 1, 5, 4, 2, 0, 9, 3 },
239 { 1, 9, 5, 2, 0, 4, 3 },
240 { 0, 5, 3, 9, 4, 2, 1 },
241 { 0, 4, 5, 3, 2, 1 },
242 }
243};
244
245typedef struct BlockXY {
246 int w, h;
247 int ax, ay;
248 int x, y;
249 int size;
250 uint8_t *block;
252} BlockXY;
253
254typedef struct MotionXY {
255 int x, y;
256} MotionXY;
257
278
279static const VLCElem *rl_vlc[2];
280static const VLCElem *mv_vlc[2][16];
281
283{
284 static VLCElem vlc_buf[(2 << MOBI_RL_VLC_BITS) + (2 * 16 << MOBI_MV_VLC_BITS)];
286
287 for (int i = 0; i < 2; i++) {
288 rl_vlc[i] =
290 bits0, sizeof(*bits0),
291 i ? syms1 : syms0, sizeof(*syms0), sizeof(*syms0),
292 0, 0);
293 for (int j = 0; j < 16; j++) {
294 mv_vlc[i][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, 0);
299 }
300 }
301}
302
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
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
333static 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
358static 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
371static 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
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], MOBI_RL_VLC_BITS, 1);
414
415 *last = (n >> 11) == 1;
416 *run = (n >> 5) & 0x3F;
417 *level = n & 0x1F;
418}
419
421 int bx, int by, int size, int plane)
422{
423 MobiClipContext *s = avctx->priv_data;
424 GetBitContext *gb = &s->gb;
425 int mat[64] = { 0 };
426 const uint8_t *ztab = size == 8 ? ff_zigzag_direct : zigzag4x4_tab;
427 const int *qtab = s->qtab[size == 8];
428 uint8_t *dst = frame->data[plane] + by * frame->linesize[plane] + bx;
429
430 for (int pos = 0; get_bits_left(gb) > 0; pos++) {
431 int qval, last, run, level;
432
433 read_run_encoding(avctx, &last, &run, &level);
434
435 if (level) {
436 if (get_bits1(gb))
437 level = -level;
438 } else if (!get_bits1(gb)) {
439 read_run_encoding(avctx, &last, &run, &level);
440 level += run_residue[s->dct_tab_idx][(last ? 64 : 0) + run];
441 if (get_bits1(gb))
442 level = -level;
443 } else if (!get_bits1(gb)) {
444 read_run_encoding(avctx, &last, &run, &level);
445 run += run_residue[s->dct_tab_idx][128 + (last ? 64 : 0) + level];
446 if (get_bits1(gb))
447 level = -level;
448 } else {
449 last = get_bits1(gb);
450 run = get_bits(gb, 6);
451 level = get_sbits(gb, 12);
452 }
453
454 pos += run;
455 if (pos >= size * size)
456 return AVERROR_INVALIDDATA;
457 qval = qtab[pos];
458 mat[ztab[pos]] = qval *(unsigned)level;
459
460 if (last)
461 break;
462 }
463
464 mat[0] += 32;
465 for (int y = 0; y < size; y++)
466 idct(&mat[y * size], size);
467
468 for (int y = 0; y < size; y++) {
469 for (int x = y + 1; x < size; x++) {
470 int a = mat[x * size + y];
471 int b = mat[y * size + x];
472
473 mat[y * size + x] = a;
474 mat[x * size + y] = b;
475 }
476
477 idct(&mat[y * size], size);
478 for (int x = 0; x < size; x++)
479 dst[x] = av_clip_uint8(dst[x] + (mat[y * size + x] >> 6));
480 dst += frame->linesize[plane];
481 }
482
483 return 0;
484}
485
487 int bx, int by, int size, int plane)
488{
489 MobiClipContext *s = avctx->priv_data;
490 GetBitContext *gb = &s->gb;
491 int ret, idx = get_ue_golomb_31(gb);
492
493 if (idx == 0) {
494 return add_coefficients(avctx, frame, bx, by, size, plane);
495 } else if ((unsigned)idx < FF_ARRAY_ELEMS(pframe_block4x4_coefficients_tab)) {
497
498 for (int y = by; y < by + 8; y += 4) {
499 for (int x = bx; x < bx + 8; x += 4) {
500 if (flags & 1) {
501 ret = add_coefficients(avctx, frame, x, y, 4, plane);
502 if (ret < 0)
503 return ret;
504 }
505 flags >>= 1;
506 }
507 }
508 return 0;
509 } else {
510 return AVERROR_INVALIDDATA;
511 }
512}
513
514static int adjust(int x, int size)
515{
516 return size == 16 ? (x + 1) >> 1 : x;
517}
518
519static uint8_t pget(BlockXY b)
520{
521 BlockXY ret = b;
522 int x, y;
523
524 if (b.x == -1 && b.y >= b.size) {
525 ret.x = -1, ret.y = b.size - 1;
526 } else if (b.x >= -1 && b.y >= -1) {
527 ret.x = b.x, ret.y = b.y;
528 } else if (b.x == -1 && b.y == -2) {
529 ret.x = 0, ret.y = -1;
530 } else if (b.x == -2 && b.y == -1) {
531 ret.x = -1, ret.y = 0;
532 }
533
534 y = av_clip(ret.ay + ret.y, 0, ret.h - 1);
535 x = av_clip(ret.ax + ret.x, 0, ret.w - 1);
536
537 return ret.block[y * ret.linesize + x];
538}
539
540static uint8_t half(int a, int b)
541{
542 return ((a + b) + 1) / 2;
543}
544
545static uint8_t half3(int a, int b, int c)
546{
547 return ((a + b + b + c) * 2 / 4 + 1) / 2;
548}
549
550static uint8_t pick_above(BlockXY bxy)
551{
552 bxy.y = bxy.y - 1;
553
554 return pget(bxy);
555}
556
557static uint8_t pick_left(BlockXY bxy)
558{
559 bxy.x = bxy.x - 1;
560
561 return pget(bxy);
562}
563
564static uint8_t half_horz(BlockXY bxy)
565{
566 BlockXY a = bxy, b = bxy, c = bxy;
567
568 a.x -= 1;
569 c.x += 1;
570
571 return half3(pget(a), pget(b), pget(c));
572}
573
574static uint8_t half_vert(BlockXY bxy)
575{
576 BlockXY a = bxy, b = bxy, c = bxy;
577
578 a.y -= 1;
579 c.y += 1;
580
581 return half3(pget(a), pget(b), pget(c));
582}
583
584static uint8_t pick_4(BlockXY bxy)
585{
586 int val;
587
588 if ((bxy.x % 2) == 0) {
589 BlockXY ba, bb;
590 int a, b;
591
592 ba = bxy;
593 ba.x = -1;
594 ba.y = bxy.y + bxy.x / 2;
595 a = pget(ba);
596
597 bb = bxy;
598 bb.x = -1;
599 bb.y = bxy.y + bxy.x / 2 + 1;
600 b = pget(bb);
601
602 val = half(a, b);
603 } else {
604 BlockXY ba;
605
606 ba = bxy;
607 ba.x = -1;
608 ba.y = bxy.y + bxy.x / 2 + 1;
609 val = half_vert(ba);
610 }
611
612 return val;
613}
614
615static uint8_t pick_5(BlockXY bxy)
616{
617 int val;
618
619 if (bxy.x == 0) {
620 BlockXY a = bxy;
621 BlockXY b = bxy;
622
623 a.x = -1;
624 a.y -= 1;
625
626 b.x = -1;
627
628 val = half(pget(a), pget(b));
629 } else if (bxy.y == 0) {
630 BlockXY a = bxy;
631
632 a.x -= 2;
633 a.y -= 1;
634
635 val = half_horz(a);
636 } else if (bxy.x == 1) {
637 BlockXY a = bxy;
638
639 a.x -= 2;
640 a.y -= 1;
641
642 val = half_vert(a);
643 } else {
644 BlockXY a = bxy;
645
646 a.x -= 2;
647 a.y -= 1;
648
649 val = pget(a);
650 }
651
652 return val;
653}
654
655static uint8_t pick_6(BlockXY bxy)
656{
657 int val;
658
659 if (bxy.y == 0) {
660 BlockXY a = bxy;
661 BlockXY b = bxy;
662
663 a.x -= 1;
664 a.y = -1;
665
666 b.y = -1;
667
668 val = half(pget(a), pget(b));
669 } else if (bxy.x == 0) {
670 BlockXY a = bxy;
671
672 a.x -= 1;
673 a.y -= 2;
674
675 val = half_vert(a);
676 } else if (bxy.y == 1) {
677 BlockXY a = bxy;
678
679 a.x -= 1;
680 a.y -= 2;
681
682 val = half_horz(a);
683 } else {
684 BlockXY a = bxy;
685
686 a.x -= 1;
687 a.y -= 2;
688
689 val = pget(a);
690 }
691
692 return val;
693}
694
695static uint8_t pick_7(BlockXY bxy)
696{
697 int clr, acc1, acc2;
698 BlockXY a = bxy;
699
700 a.x -= 1;
701 a.y -= 1;
702 clr = pget(a);
703 if (bxy.x && bxy.y)
704 return clr;
705
706 if (bxy.x == 0) {
707 a.x = -1;
708 a.y = bxy.y;
709 } else {
710 a.x = bxy.x - 2;
711 a.y = -1;
712 }
713 acc1 = pget(a);
714
715 if (bxy.y == 0) {
716 a.x = bxy.x;
717 a.y = -1;
718 } else {
719 a.x = -1;
720 a.y = bxy.y - 2;
721 }
722 acc2 = pget(a);
723
724 return half3(acc1, clr, acc2);
725}
726
727static uint8_t pick_8(BlockXY bxy)
728{
729 BlockXY ba = bxy;
730 BlockXY bb = bxy;
731 int val;
732
733 if (bxy.y == 0) {
734 int a, b;
735
736 ba.y = -1;
737 a = pget(ba);
738
739 bb.x += 1;
740 bb.y = -1;
741
742 b = pget(bb);
743
744 val = half(a, b);
745 } else if (bxy.y == 1) {
746 ba.x += 1;
747 ba.y -= 2;
748
749 val = half_horz(ba);
750 } else if (bxy.x < bxy.size - 1) {
751 ba.x += 1;
752 ba.y -= 2;
753
754 val = pget(ba);
755 } else if (bxy.y % 2 == 0) {
756 int a, b;
757
758 ba.x = bxy.y / 2 + bxy.size - 1;
759 ba.y = -1;
760 a = pget(ba);
761
762 bb.x = bxy.y / 2 + bxy.size;
763 bb.y = -1;
764
765 b = pget(bb);
766
767 val = half(a, b);
768 } else {
769 ba.x = bxy.y / 2 + bxy.size;
770 ba.y = -1;
771
772 val = half_horz(ba);
773 }
774
775 return val;
776}
777
778static void block_fill_simple(uint8_t *block, int size, int linesize, int fill)
779{
780 for (int y = 0; y < size; y++) {
781 memset(block, fill, size);
782 block += linesize;
783 }
784}
785
786static void block_fill(uint8_t *block, int size, int linesize,
787 int w, int h, int ax, int ay,
788 uint8_t (*pick)(BlockXY bxy))
789{
790 BlockXY bxy;
791
792 bxy.size = size;
793 bxy.block = block;
794 bxy.linesize = linesize;
795 bxy.w = w;
796 bxy.h = h;
797 bxy.ay = ay;
798 bxy.ax = ax;
799
800 for (int y = 0; y < size; y++) {
801 bxy.y = y;
802 for (int x = 0; x < size; x++) {
803 uint8_t val;
804
805 bxy.x = x;
806
807 val = pick(bxy);
808
809 block[ax + x + (ay + y) * linesize] = val;
810 }
811 }
812}
813
814static int block_sum(const uint8_t *block, int w, int h, int linesize)
815{
816 int sum = 0;
817
818 for (int y = 0; y < h; y++) {
819 for (int x = 0; x < w; x++) {
820 sum += block[x];
821 }
822 block += linesize;
823 }
824
825 return sum;
826}
827
828static int predict_intra(AVCodecContext *avctx, AVFrame *frame, int ax, int ay,
829 int pmode, int add_coeffs, int size, int plane)
830{
831 MobiClipContext *s = avctx->priv_data;
832 GetBitContext *gb = &s->gb;
833 int w = avctx->width >> !!plane, h = avctx->height >> !!plane;
834 int ret = 0;
835
836 switch (pmode) {
837 case 0:
838 block_fill(frame->data[plane], size, frame->linesize[plane], w, h, ax, ay, pick_above);
839 break;
840 case 1:
841 block_fill(frame->data[plane], size, frame->linesize[plane], w, h, ax, ay, pick_left);
842 break;
843 case 2:
844 {
845 int arr1[16];
846 int arr2[16];
847 uint8_t *top = frame->data[plane] + FFMAX(ay - 1, 0) * frame->linesize[plane] + ax;
848 uint8_t *left = frame->data[plane] + ay * frame->linesize[plane] + FFMAX(ax - 1, 0);
849 int bottommost = frame->data[plane][(ay + size - 1) * frame->linesize[plane] + FFMAX(ax - 1, 0)];
850 int rightmost = frame->data[plane][FFMAX(ay - 1, 0) * frame->linesize[plane] + ax + size - 1];
851 int avg = (bottommost + rightmost + 1) / 2 + 2 * av_clip(get_se_golomb(gb), -(1<<16), 1<<16);
852 int r6 = adjust(avg - bottommost, size);
853 int r9 = adjust(avg - rightmost, size);
854 int shift = adjust(size, size) == 8 ? 3 : 2;
855 uint8_t *block;
856
857 for (int x = 0; x < size; x++) {
858 int val = top[x];
859 arr1[x] = adjust(((bottommost - val) * (1 << shift)) + r6 * (x + 1), size);
860 }
861
862 for (int y = 0; y < size; y++) {
863 int val = left[y * frame->linesize[plane]];
864 arr2[y] = adjust(((rightmost - val) * (1 << shift)) + r9 * (y + 1), size);
865 }
866
867 block = frame->data[plane] + ay * frame->linesize[plane] + ax;
868 for (int y = 0; y < size; y++) {
869 for (int x = 0; x < size; x++) {
870 block[x] = (((top[x] + left[0] + ((arr1[x] * (y + 1) +
871 arr2[y] * (x + 1)) >> 2 * shift)) + 1) / 2) & 0xFF;
872 }
873 block += frame->linesize[plane];
874 left += frame->linesize[plane];
875 }
876 }
877 break;
878 case 3:
879 {
880 uint8_t fill;
881
882 if (ax == 0 && ay == 0) {
883 fill = 0x80;
884 } else if (ax >= 1 && ay >= 1) {
885 int left = block_sum(frame->data[plane] + ay * frame->linesize[plane] + ax - 1,
886 1, size, frame->linesize[plane]);
887 int top = block_sum(frame->data[plane] + (ay - 1) * frame->linesize[plane] + ax,
888 size, 1, frame->linesize[plane]);
889
890 fill = ((left + top) * 2 / (2 * size) + 1) / 2;
891 } else if (ax >= 1) {
892 fill = (block_sum(frame->data[plane] + ay * frame->linesize[plane] + ax - 1,
893 1, size, frame->linesize[plane]) * 2 / size + 1) / 2;
894 } else if (ay >= 1) {
895 fill = (block_sum(frame->data[plane] + (ay - 1) * frame->linesize[plane] + ax,
896 size, 1, frame->linesize[plane]) * 2 / size + 1) / 2;
897 } else {
898 return -1;
899 }
900
901 block_fill_simple(frame->data[plane] + ay * frame->linesize[plane] + ax,
902 size, frame->linesize[plane], fill);
903 }
904 break;
905 case 4:
906 block_fill(frame->data[plane], size, frame->linesize[plane], w, h, ax, ay, pick_4);
907 break;
908 case 5:
909 block_fill(frame->data[plane], size, frame->linesize[plane], w, h, ax, ay, pick_5);
910 break;
911 case 6:
912 block_fill(frame->data[plane], size, frame->linesize[plane], w, h, ax, ay, pick_6);
913 break;
914 case 7:
915 block_fill(frame->data[plane], size, frame->linesize[plane], w, h, ax, ay, pick_7);
916 break;
917 case 8:
918 block_fill(frame->data[plane], size, frame->linesize[plane], w, h, ax, ay, pick_8);
919 break;
920 }
921
922 if (add_coeffs)
923 ret = add_coefficients(avctx, frame, ax, ay, size, plane);
924
925 return ret;
926}
927
928static int get_prediction(AVCodecContext *avctx, int x, int y, int size)
929{
930 MobiClipContext *s = avctx->priv_data;
931 GetBitContext *gb = &s->gb;
932 int index = (y & 0xC) | (x / 4 % 4);
933
934 uint8_t val = FFMIN(s->pre[index], index % 4 == 0 ? 9 : s->pre[index + 3]);
935 if (val == 9)
936 val = 3;
937
938 if (!get_bits1(gb)) {
939 int x = get_bits(gb, 3);
940 val = x + (x >= val ? 1 : 0);
941 }
942
943 s->pre[index + 4] = val;
944 if (size == 8)
945 s->pre[index + 5] = s->pre[index + 8] = s->pre[index + 9] = val;
946
947 return val;
948}
949
951 int x, int y, int pmode, int has_coeffs, int plane)
952{
953 MobiClipContext *s = avctx->priv_data;
954 GetBitContext *gb = &s->gb;
955 int tmp, ret;
956
957 if (!has_coeffs) {
958 if (pmode < 0)
959 pmode = get_prediction(avctx, x, y, 8);
960 return predict_intra(avctx, frame, x, y, pmode, 0, 8, plane);
961 }
962
963 tmp = get_ue_golomb_31(gb);
965 return AVERROR_INVALIDDATA;
966
967 if (tmp == 0) {
968 if (pmode < 0)
969 pmode = get_prediction(avctx, x, y, 8);
970 ret = predict_intra(avctx, frame, x, y, pmode, 1, 8, plane);
971 } else {
973
974 for (int by = y; by < y + 8; by += 4) {
975 for (int bx = x; bx < x + 8; bx += 4) {
976 int new_pmode = pmode;
977
978 if (new_pmode < 0)
979 new_pmode = get_prediction(avctx, bx, by, 4);
980 ret = predict_intra(avctx, frame, bx, by, new_pmode, flags & 1, 4, plane);
981 if (ret < 0)
982 return ret;
983 flags >>= 1;
984 }
985 }
986 }
987
988 return ret;
989}
990
992 int x, int y, int predict)
993{
994 MobiClipContext *s = avctx->priv_data;
995 GetBitContext *gb = &s->gb;
996 int flags, pmode_uv, idx = get_ue_golomb(gb);
997 int ret = 0;
998
999 if (idx < 0 || idx >= FF_ARRAY_ELEMS(block8x8_coefficients_tab))
1000 return AVERROR_INVALIDDATA;
1001
1003
1004 if (predict) {
1005 ret = process_block(avctx, frame, x, y, -1, flags & 1, 0);
1006 if (ret < 0)
1007 return ret;
1008 flags >>= 1;
1009 ret = process_block(avctx, frame, x + 8, y, -1, flags & 1, 0);
1010 if (ret < 0)
1011 return ret;
1012 flags >>= 1;
1013 ret = process_block(avctx, frame, x, y + 8, -1, flags & 1, 0);
1014 if (ret < 0)
1015 return ret;
1016 flags >>= 1;
1017 ret = process_block(avctx, frame, x + 8, y + 8, -1, flags & 1, 0);
1018 if (ret < 0)
1019 return ret;
1020 flags >>= 1;
1021 } else {
1022 int pmode = get_bits(gb, 3);
1023
1024 if (pmode == 2) {
1025 ret = predict_intra(avctx, frame, x, y, pmode, 0, 16, 0);
1026 if (ret < 0)
1027 return ret;
1028 pmode = 9;
1029 }
1030
1031 ret = process_block(avctx, frame, x, y, pmode, flags & 1, 0);
1032 if (ret < 0)
1033 return ret;
1034 flags >>= 1;
1035 ret = process_block(avctx, frame, x + 8, y, pmode, flags & 1, 0);
1036 if (ret < 0)
1037 return ret;
1038 flags >>= 1;
1039 ret = process_block(avctx, frame, x, y + 8, pmode, flags & 1, 0);
1040 if (ret < 0)
1041 return ret;
1042 flags >>= 1;
1043 ret = process_block(avctx, frame, x + 8, y + 8, pmode, flags & 1, 0);
1044 if (ret < 0)
1045 return ret;
1046 flags >>= 1;
1047 }
1048
1049 pmode_uv = get_bits(gb, 3);
1050 if (pmode_uv == 2) {
1051 ret = predict_intra(avctx, frame, x >> 1, y >> 1, pmode_uv, 0, 8, 1 + !s->moflex);
1052 if (ret < 0)
1053 return ret;
1054 ret = predict_intra(avctx, frame, x >> 1, y >> 1, pmode_uv, 0, 8, 2 - !s->moflex);
1055 if (ret < 0)
1056 return ret;
1057 pmode_uv = 9;
1058 }
1059
1060 ret = process_block(avctx, frame, x >> 1, y >> 1, pmode_uv, flags & 1, 1 + !s->moflex);
1061 if (ret < 0)
1062 return ret;
1063 flags >>= 1;
1064 ret = process_block(avctx, frame, x >> 1, y >> 1, pmode_uv, flags & 1, 2 - !s->moflex);
1065 if (ret < 0)
1066 return ret;
1067
1068 return 0;
1069}
1070
1071static int get_index(int x)
1072{
1073 return x == 16 ? 0 : x == 8 ? 1 : x == 4 ? 2 : x == 2 ? 3 : 0;
1074}
1075
1077 int width, int height, int index,
1078 int offsetm, int offsetx, int offsety)
1079{
1080 MobiClipContext *s = avctx->priv_data;
1081 MotionXY *motion = s->motion;
1082 GetBitContext *gb = &s->gb;
1083 int fheight = avctx->height;
1084 int fwidth = avctx->width;
1085
1086 if (index <= 5) {
1087 int sidx = -FFMAX(1, index) + s->current_pic;
1088 MotionXY mv = s->motion[0];
1089
1090 if (sidx < 0)
1091 sidx += 6;
1092
1093 if (index > 0) {
1094 mv.x = mv.x + (unsigned)get_se_golomb(gb);
1095 mv.y = mv.y + (unsigned)get_se_golomb(gb);
1096 }
1097 if (mv.x >= INT_MAX || mv.y >= INT_MAX)
1098 return AVERROR_INVALIDDATA;
1099
1100 motion[offsetm].x = mv.x;
1101 motion[offsetm].y = mv.y;
1102
1103 for (int i = 0; i < 3; i++) {
1104 int method, src_linesize, dst_linesize;
1105 uint8_t *src, *dst;
1106
1107 if (i == 1) {
1108 offsetx = offsetx >> 1;
1109 offsety = offsety >> 1;
1110 mv.x = mv.x >> 1;
1111 mv.y = mv.y >> 1;
1112 width = width >> 1;
1113 height = height >> 1;
1114 fwidth = fwidth >> 1;
1115 fheight = fheight >> 1;
1116 }
1117
1118 av_assert0(s->pic[sidx]);
1119 av_assert0(s->pic[s->current_pic]);
1120 av_assert0(s->pic[s->current_pic]->data[i]);
1121 if (!s->pic[sidx]->data[i])
1122 return AVERROR_INVALIDDATA;
1123
1124 method = (mv.x & 1) | ((mv.y & 1) << 1);
1125 src_linesize = s->pic[sidx]->linesize[i];
1126 dst_linesize = s->pic[s->current_pic]->linesize[i];
1127 dst = s->pic[s->current_pic]->data[i] + offsetx + offsety * dst_linesize;
1128
1129 if (offsetx + (mv.x >> 1) < 0 ||
1130 offsety + (mv.y >> 1) < 0 ||
1131 offsetx + width + (mv.x + 1 >> 1) > fwidth ||
1132 offsety + height + (mv.y + 1 >> 1) > fheight)
1133 return AVERROR_INVALIDDATA;
1134
1135 switch (method) {
1136 case 0:
1137 src = s->pic[sidx]->data[i] + offsetx + (mv.x >> 1) +
1138 (offsety + (mv.y >> 1)) * src_linesize;
1139 for (int y = 0; y < height; y++) {
1140 for (int x = 0; x < width; x++)
1141 dst[x] = src[x];
1142 dst += dst_linesize;
1143 src += src_linesize;
1144 }
1145 break;
1146 case 1:
1147 src = s->pic[sidx]->data[i] + offsetx + (mv.x >> 1) +
1148 (offsety + (mv.y >> 1)) * src_linesize;
1149 for (int y = 0; y < height; y++) {
1150 for (int x = 0; x < width; x++) {
1151 dst[x] = (uint8_t)((src[x] >> 1) + (src[x + 1] >> 1));
1152 }
1153
1154 dst += dst_linesize;
1155 src += src_linesize;
1156 }
1157 break;
1158 case 2:
1159 src = s->pic[sidx]->data[i] + offsetx + (mv.x >> 1) +
1160 (offsety + (mv.y >> 1)) * src_linesize;
1161 for (int y = 0; y < height; y++) {
1162 for (int x = 0; x < width; x++) {
1163 dst[x] = (uint8_t)((src[x] >> 1) + (src[x + src_linesize] >> 1));
1164 }
1165
1166 dst += dst_linesize;
1167 src += src_linesize;
1168 }
1169 break;
1170 case 3:
1171 src = s->pic[sidx]->data[i] + offsetx + (mv.x >> 1) +
1172 (offsety + (mv.y >> 1)) * src_linesize;
1173 for (int y = 0; y < height; y++) {
1174 for (int x = 0; x < width; x++) {
1175 dst[x] = (uint8_t)((((src[x] >> 1) + (src[x + 1] >> 1)) >> 1) +
1176 (((src[x + src_linesize] >> 1) + (src[x + 1 + src_linesize] >> 1)) >> 1));
1177 }
1178
1179 dst += dst_linesize;
1180 src += src_linesize;
1181 }
1182 break;
1183 }
1184 }
1185 } else {
1186 int tidx;
1187 int adjx = index == 8 ? 0 : width / 2;
1188 int adjy = index == 8 ? height / 2 : 0;
1189
1190 width = width - adjx;
1191 height = height - adjy;
1192 tidx = get_index(height) * 4 + get_index(width);
1193
1194 for (int i = 0; i < 2; i++) {
1195 int ret, idx2;
1196
1197 idx2 = get_vlc2(gb, mv_vlc[s->moflex][tidx], MOBI_MV_VLC_BITS, 1);
1198
1199 ret = predict_motion(avctx, width, height, idx2,
1200 offsetm, offsetx + i * adjx, offsety + i * adjy);
1201 if (ret < 0)
1202 return ret;
1203 }
1204 }
1205
1206 return 0;
1207}
1208
1209static int mobiclip_decode(AVCodecContext *avctx, AVFrame *rframe,
1210 int *got_frame, AVPacket *pkt)
1211{
1212 MobiClipContext *s = avctx->priv_data;
1213 GetBitContext *gb = &s->gb;
1214 AVFrame *frame = s->pic[s->current_pic];
1215 int ret;
1216
1217 if (avctx->height/16 * (avctx->width/16) * 2 > 8LL*FFALIGN(pkt->size, 2))
1218 return AVERROR_INVALIDDATA;
1219
1220 av_fast_padded_malloc(&s->bitstream, &s->bitstream_size,
1221 pkt->size);
1222
1223 if ((ret = ff_reget_buffer(avctx, frame, 0)) < 0)
1224 return ret;
1225
1226 s->bdsp.bswap16_buf((uint16_t *)s->bitstream,
1227 (uint16_t *)pkt->data,
1228 (pkt->size + 1) >> 1);
1229
1230 ret = init_get_bits8(gb, s->bitstream, FFALIGN(pkt->size, 2));
1231 if (ret < 0)
1232 return ret;
1233
1234 if (get_bits1(gb)) {
1235 frame->pict_type = AV_PICTURE_TYPE_I;
1236 frame->flags |= AV_FRAME_FLAG_KEY;
1237 s->moflex = get_bits1(gb);
1238 s->dct_tab_idx = get_bits1(gb);
1239
1240 ret = setup_qtables(avctx, get_bits(gb, 6));
1241 if (ret < 0)
1242 return ret;
1243
1244 for (int y = 0; y < avctx->height; y += 16) {
1245 for (int x = 0; x < avctx->width; x += 16) {
1246 ret = decode_macroblock(avctx, frame, x, y, get_bits1(gb));
1247 if (ret < 0)
1248 return ret;
1249 }
1250 }
1251 } else {
1252 MotionXY *motion = s->motion;
1253
1254 memset(motion, 0, s->motion_size);
1255
1256 frame->pict_type = AV_PICTURE_TYPE_P;
1257 frame->flags &= ~AV_FRAME_FLAG_KEY;
1258 s->dct_tab_idx = 0;
1259
1260 ret = setup_qtables(avctx, s->quantizer + (int64_t)get_se_golomb(gb));
1261 if (ret < 0)
1262 return ret;
1263
1264 for (int y = 0; y < avctx->height; y += 16) {
1265 for (int x = 0; x < avctx->width; x += 16) {
1266 int idx;
1267
1268 motion[0].x = mid_pred(motion[x / 16 + 1].x, motion[x / 16 + 2].x, motion[x / 16 + 3].x);
1269 motion[0].y = mid_pred(motion[x / 16 + 1].y, motion[x / 16 + 2].y, motion[x / 16 + 3].y);
1270 motion[x / 16 + 2].x = 0;
1271 motion[x / 16 + 2].y = 0;
1272
1273 idx = get_vlc2(gb, mv_vlc[s->moflex][0], 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);
1286 return AVERROR_INVALIDDATA;
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
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
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
1344 .p.name = "mobiclip",
1345 CODEC_LONG_NAME("MobiClip Video"),
1346 .p.type = AVMEDIA_TYPE_VIDEO,
1347 .p.id = AV_CODEC_ID_MOBICLIP,
1348 .priv_data_size = sizeof(MobiClipContext),
1351 .flush = mobiclip_flush,
1352 .close = mobiclip_close,
1353 .p.capabilities = AV_CODEC_CAP_DR1,
1354 .caps_internal = FF_CODEC_CAP_INIT_CLEANUP,
1355};
static av_always_inline void predict(PredictorState *ps, int *coef, int output_enable)
uint8_t ptrdiff_t const uint8_t ptrdiff_t int intptr_t intptr_t int int16_t * dst
Definition dsp.h:87
static double val(void *priv, double ch)
Definition aeval.c:77
const FFCodec ff_mobiclip_decoder
Definition mobiclip.c:1343
simple assert() macros that are a bit more flexible than ISO C assert().
#define av_assert0(cond)
assert() equivalent, that is always enabled.
Definition avassert.h:42
Libavcodec external API header.
static int BS_FUNC left(const BSCTX *bc)
Return the number of the bits left in a buffer.
#define flags(name, subs,...)
Definition cbs_h264.c:74
#define i(width, name, range_min, range_max)
Definition cbs_h264.c:63
#define f(width, name)
Definition cbs_vp8.c:236
#define s(width, name)
Definition cbs_vp9.c:198
#define FF_CODEC_DECODE_CB(func)
#define CODEC_LONG_NAME(str)
#define FF_CODEC_CAP_INIT_CLEANUP
The codec allows calling the close function for deallocation even if the init function returned a fai...
#define avg(a, b, c, d)
#define av_clip
Definition common.h:100
#define av_clip_uint8
Definition common.h:106
long long int64_t
Definition coverity.c:34
static int16_t block[64]
Definition dct.c:125
int ff_reget_buffer(AVCodecContext *avctx, AVFrame *frame, int flags)
Identical in function to ff_get_buffer(), except it reuses the existing buffer if available.
Definition decode.c:1906
static AVPacket * pkt
static AVFrame * frame
int(* init)(AVBSFContext *ctx)
Definition dts2pts.c:608
static struct @346255127015250356166251341105367306144006377143 state
#define get_index(num, offset, size)
Quantize the current LSP subvector.
Definition g723_1enc.c:336
bitstream reader API header.
static av_always_inline int get_vlc2(GetBitContext *s, const VLCElem *table, int bits, int max_depth)
Parse a vlc code.
Definition get_bits.h:645
static int get_sbits(GetBitContext *s, int n)
Definition get_bits.h:322
static int get_bits_left(GetBitContext *gb)
Definition get_bits.h:688
static unsigned int get_bits1(GetBitContext *s)
Definition get_bits.h:391
static int init_get_bits8(GetBitContext *s, const uint8_t *buffer, int byte_size)
Initialize GetBitContext.
Definition get_bits.h:544
static unsigned int get_bits(GetBitContext *s, int n)
Read 1-25 bits.
Definition get_bits.h:337
exp golomb vlc stuff
static int get_se_golomb(GetBitContext *gb)
read signed exp golomb code.
Definition golomb.h:239
static int get_ue_golomb_31(GetBitContext *gb)
read unsigned exp golomb code, constraint to a max of 31.
Definition golomb.h:120
static int get_ue_golomb(GetBitContext *gb)
Read an unsigned Exp-Golomb code in the range 0 to 8190.
Definition golomb.h:53
#define AV_CODEC_CAP_DR1
Codec uses get_buffer() or get_encode_buffer() for allocating buffers and supports custom allocators.
Definition codec.h:49
@ AV_CODEC_ID_MOBICLIP
Definition codec_id.h:299
void av_fast_padded_malloc(void *ptr, unsigned int *size, size_t min_size)
Same behaviour av_fast_malloc but the buffer has additional AV_INPUT_BUFFER_PADDING_SIZE at the end w...
Definition utils.c:53
#define AVERROR_INVALIDDATA
Invalid data found when processing input.
Definition error.h:61
#define AVERROR(e)
Definition error.h:45
#define AV_FRAME_FLAG_KEY
A flag to mark frames that are keyframes.
Definition frame.h:687
void av_frame_unref(AVFrame *frame)
Unreference all the buffers referenced by frame and reset the frame fields.
Definition frame.c:496
int av_frame_ref(AVFrame *dst, const AVFrame *src)
Set up a new reference to the data described by the source frame.
Definition frame.c:278
void av_frame_free(AVFrame **frame)
Free the frame and any dynamically allocated objects in it, e.g.
Definition frame.c:64
AVFrame * av_frame_alloc(void)
Allocate an AVFrame and set its fields to default values.
Definition frame.c:52
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition log.h:210
@ AVMEDIA_TYPE_VIDEO
Definition avutil.h:200
@ AV_PICTURE_TYPE_I
Intra.
Definition avutil.h:278
@ AV_PICTURE_TYPE_P
Predicted.
Definition avutil.h:279
int index
Definition gxfenc.c:90
int a
#define b
Definition input.c:43
static const int8_t mv[256][2]
Definition 4xm.c:81
static int shift(int a, int b)
Definition bonk.c:261
av_cold void ff_bswapdsp_init(BswapDSPContext *c)
Definition bswapdsp.c:37
Macro definitions for various function/variable attributes.
#define av_cold
Definition attributes.h:117
#define AVOnce
Definition thread.h:202
static int ff_thread_once(char *control, void(*routine)(void))
Definition thread.h:205
#define AV_ONCE_INIT
Definition thread.h:203
uint8_t w
Definition llvidencdsp.c:39
#define FFMIN(a, b)
Definition macros.h:49
#define FFMAX(a, b)
Definition macros.h:47
#define FFALIGN(x, a)
Definition macros.h:78
const uint8_t ff_zigzag_direct[64]
Definition mathtables.c:137
#define mid_pred
Definition mathops.h:115
void * av_calloc(size_t nmemb, size_t size)
Definition mem.c:264
Memory handling functions.
static int add_pframe_coefficients(AVCodecContext *avctx, AVFrame *frame, int bx, int by, int size, int plane)
Definition mobiclip.c:486
static void read_run_encoding(AVCodecContext *avctx, int *last, int *run, int *level)
Definition mobiclip.c:408
static const uint8_t pframe_block4x4_coefficients_tab[]
Definition mobiclip.c:79
static const uint8_t quant8x8_tab[][64]
Definition mobiclip.c:58
static uint8_t half3(int a, int b, int c)
Definition mobiclip.c:545
static int adjust(int x, int size)
Definition mobiclip.c:514
static const uint8_t block4x4_coefficients_tab[]
Definition mobiclip.c:74
static const uint8_t block8x8_coefficients_tab[]
Definition mobiclip.c:84
static const VLCElem * rl_vlc[2]
Definition mobiclip.c:279
static int block_sum(const uint8_t *block, int w, int h, int linesize)
Definition mobiclip.c:814
static void inverse4(unsigned *rs)
Definition mobiclip.c:358
static uint8_t pick_5(BlockXY bxy)
Definition mobiclip.c:615
static int process_block(AVCodecContext *avctx, AVFrame *frame, int x, int y, int pmode, int has_coeffs, int plane)
Definition mobiclip.c:950
static void block_fill_simple(uint8_t *block, int size, int linesize, int fill)
Definition mobiclip.c:778
static const uint8_t quant4x4_tab[][16]
Definition mobiclip.c:48
static uint8_t pick_8(BlockXY bxy)
Definition mobiclip.c:727
static uint8_t pick_left(BlockXY bxy)
Definition mobiclip.c:557
static const uint8_t run_residue[2][256]
Definition mobiclip.c:102
static int add_coefficients(AVCodecContext *avctx, AVFrame *frame, int bx, int by, int size, int plane)
Definition mobiclip.c:420
static uint8_t pick_4(BlockXY bxy)
Definition mobiclip.c:584
#define MOBI_RL_VLC_BITS
Definition mobiclip.c:39
static void idct(int *arr, int size)
Definition mobiclip.c:371
static uint8_t pick_above(BlockXY bxy)
Definition mobiclip.c:550
static void block_fill(uint8_t *block, int size, int linesize, int w, int h, int ax, int ay, uint8_t(*pick)(BlockXY bxy))
Definition mobiclip.c:786
static uint8_t half(int a, int b)
Definition mobiclip.c:540
static av_cold int mobiclip_close(AVCodecContext *avctx)
Definition mobiclip.c:1327
static av_cold void mobiclip_flush(AVCodecContext *avctx)
Definition mobiclip.c:1319
static int decode_macroblock(AVCodecContext *avctx, AVFrame *frame, int x, int y, int predict)
Definition mobiclip.c:991
static av_cold int mobiclip_init(AVCodecContext *avctx)
Definition mobiclip.c:303
static int predict_motion(AVCodecContext *avctx, int width, int height, int index, int offsetm, int offsetx, int offsety)
Definition mobiclip.c:1076
static const uint16_t syms1[]
Definition mobiclip.c:149
static uint8_t pick_7(BlockXY bxy)
Definition mobiclip.c:695
static uint8_t half_vert(BlockXY bxy)
Definition mobiclip.c:574
static const uint8_t mv_len[16]
Definition mobiclip.c:160
static const VLCElem * mv_vlc[2][16]
Definition mobiclip.c:280
static int mobiclip_decode(AVCodecContext *avctx, AVFrame *rframe, int *got_frame, AVPacket *pkt)
Definition mobiclip.c:1209
static const uint8_t pframe_block8x8_coefficients_tab[]
Definition mobiclip.c:94
static const uint8_t mv_bits[2][16][10]
Definition mobiclip.c:165
static uint8_t pick_6(BlockXY bxy)
Definition mobiclip.c:655
static int setup_qtables(AVCodecContext *avctx, int64_t quantizer)
Definition mobiclip.c:333
static const uint8_t bits0[]
Definition mobiclip.c:126
#define MOBI_MV_VLC_BITS
Definition mobiclip.c:40
static const uint8_t zigzag4x4_tab[]
Definition mobiclip.c:42
static int get_prediction(AVCodecContext *avctx, int x, int y, int size)
Definition mobiclip.c:928
static const uint16_t syms0[]
Definition mobiclip.c:136
static av_cold void mobiclip_init_static(void)
Definition mobiclip.c:282
static int predict_intra(AVCodecContext *avctx, AVFrame *frame, int ax, int ay, int pmode, int add_coeffs, int size, int plane)
Definition mobiclip.c:828
static uint8_t half_horz(BlockXY bxy)
Definition mobiclip.c:564
static uint8_t pget(BlockXY b)
Definition mobiclip.c:519
static const uint8_t mv_syms[2][16][10]
Definition mobiclip.c:205
@ AV_PIX_FMT_YUV420P
planar YUV 4:2:0, 12bpp, (1 Cr & Cb sample per 2x2 Y samples)
Definition pixfmt.h:73
@ AVCOL_SPC_YCGCO
used by Dirac / VC-2 and H.264 FRext, see ITU-T SG16
Definition pixfmt.h:715
#define FF_ARRAY_ELEMS(a)
unsigned int pos
Definition spdifenc.c:431
main external API structure.
Definition avcodec.h:443
enum AVPixelFormat pix_fmt
Pixel format, see AV_PIX_FMT_xxx.
Definition avcodec.h:643
int width
picture width / height.
Definition avcodec.h:604
enum AVColorSpace colorspace
YUV colorspace type.
Definition avcodec.h:671
void * priv_data
Definition avcodec.h:470
This structure describes decoded (raw) audio or video data.
Definition frame.h:472
This structure stores compressed data.
Definition packet.h:580
uint8_t * block
Definition mobiclip.c:250
int ax
Definition mobiclip.c:247
int ay
Definition mobiclip.c:247
int linesize
Definition mobiclip.c:251
int h
Definition mobiclip.c:246
int size
Definition mobiclip.c:249
int y
Definition mobiclip.c:248
int w
Definition mobiclip.c:246
int x
Definition mobiclip.c:248
AVFrame * pic[6]
Definition mobiclip.c:259
uint8_t * bitstream
Definition mobiclip.c:268
BswapDSPContext bdsp
Definition mobiclip.c:276
GetBitContext gb
Definition mobiclip.c:266
int qtab[2][64]
Definition mobiclip.c:271
uint8_t pre[32]
Definition mobiclip.c:272
MotionXY * motion
Definition mobiclip.c:273
Definition vlc.h:32
For static VLCs, the number of bits can often be hardcoded at each get_vlc2() callsite.
Definition vlc.h:220
uint8_t run
Definition svq3.c:207
uint8_t level
Definition svq3.c:208
#define av_freep(p)
#define av_log(a,...)
static uint8_t tmp[40]
Definition aes_ctr.c:52
#define src
Definition vp8dsp.c:248
#define height
Definition dsp.h:89
#define width
Definition dsp.h:89
int size
const char * g
Definition vf_curves.c:128
av_cold const VLCElem * ff_vlc_init_tables_from_lengths(VLCInitState *state, int nb_bits, int nb_codes, const int8_t *lens, int lens_wrap, const void *symbols, int symbols_wrap, int symbols_size, int offset, int flags)
Definition vlc.c:366
#define VLC_INIT_STATE(_table)
Definition vlc.h:225
static double c[64]