FFmpeg coverage


Directory: ../../../ffmpeg/
File: src/libavcodec/mobiclip.c
Date: 2024-04-19 07:31:02
Exec Total Coverage
Lines: 0 675 0.0%
Functions: 0 33 0.0%
Branches: 0 357 0.0%

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