FFmpeg coverage


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