FFmpeg coverage


Directory: ../../../ffmpeg/
File: src/libavcodec/mobiclip.c
Date: 2022-01-16 20:33:26
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 return 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 return 0;
509 } else {
510 return AVERROR_INVALIDDATA;
511 }
512 }
513
514 static int adjust(int x, int size)
515 {
516 return size == 16 ? (x + 1) >> 1 : x;
517 }
518
519 static 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
540 static uint8_t half(int a, int b)
541 {
542 return ((a + b) + 1) / 2;
543 }
544
545 static uint8_t half3(int a, int b, int c)
546 {
547 return ((a + b + b + c) * 2 / 4 + 1) / 2;
548 }
549
550 static uint8_t pick_above(BlockXY bxy)
551 {
552 bxy.y = bxy.y - 1;
553
554 return pget(bxy);
555 }
556
557 static uint8_t pick_left(BlockXY bxy)
558 {
559 bxy.x = bxy.x - 1;
560
561 return pget(bxy);
562 }
563
564 static 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
574 static 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
584 static 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
615 static 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
655 static 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
695 static 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
727 static 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
778 static 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
786 static 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
814 static 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
828 static 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
928 static 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
950 static int process_block(AVCodecContext *avctx, AVFrame *frame,
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);
964 if ((unsigned)tmp > FF_ARRAY_ELEMS(block4x4_coefficients_tab))
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 {
972 int flags = block4x4_coefficients_tab[tmp - 1];
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
991 static int decode_macroblock(AVCodecContext *avctx, AVFrame *frame,
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
1002 flags = block8x8_coefficients_tab[idx];
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
1071 static int get_index(int x)
1072 {
1073 return x == 16 ? 0 : x == 8 ? 1 : x == 4 ? 2 : x == 2 ? 3 : 0;
1074 }
1075
1076 static int predict_motion(AVCodecContext *avctx,
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].table,
1198 MOBI_MV_VLC_BITS, 1);
1199
1200 ret = predict_motion(avctx, width, height, idx2,
1201 offsetm, offsetx + i * adjx, offsety + i * adjy);
1202 if (ret < 0)
1203 return ret;
1204 }
1205 }
1206
1207 return 0;
1208 }
1209
1210 static int mobiclip_decode(AVCodecContext *avctx, void *data,
1211 int *got_frame, AVPacket *pkt)
1212 {
1213 MobiClipContext *s = avctx->priv_data;
1214 GetBitContext *gb = &s->gb;
1215 AVFrame *frame = s->pic[s->current_pic];
1216 int ret;
1217
1218 av_fast_padded_malloc(&s->bitstream, &s->bitstream_size,
1219 pkt->size);
1220
1221 if ((ret = ff_reget_buffer(avctx, frame, 0)) < 0)
1222 return ret;
1223
1224 s->bdsp.bswap16_buf((uint16_t *)s->bitstream,
1225 (uint16_t *)pkt->data,
1226 (pkt->size + 1) >> 1);
1227
1228 ret = init_get_bits8(gb, s->bitstream, FFALIGN(pkt->size, 2));
1229 if (ret < 0)
1230 return ret;
1231
1232 if (get_bits1(gb)) {
1233 frame->pict_type = AV_PICTURE_TYPE_I;
1234 frame->key_frame = 1;
1235 s->moflex = get_bits1(gb);
1236 s->dct_tab_idx = get_bits1(gb);
1237
1238 ret = setup_qtables(avctx, get_bits(gb, 6));
1239 if (ret < 0)
1240 return ret;
1241
1242 for (int y = 0; y < avctx->height; y += 16) {
1243 for (int x = 0; x < avctx->width; x += 16) {
1244 ret = decode_macroblock(avctx, frame, x, y, get_bits1(gb));
1245 if (ret < 0)
1246 return ret;
1247 }
1248 }
1249 } else {
1250 MotionXY *motion = s->motion;
1251
1252 memset(motion, 0, s->motion_size);
1253
1254 frame->pict_type = AV_PICTURE_TYPE_P;
1255 frame->key_frame = 0;
1256 s->dct_tab_idx = 0;
1257
1258 ret = setup_qtables(avctx, s->quantizer + get_se_golomb(gb));
1259 if (ret < 0)
1260 return ret;
1261
1262 for (int y = 0; y < avctx->height; y += 16) {
1263 for (int x = 0; x < avctx->width; x += 16) {
1264 int idx;
1265
1266 motion[0].x = mid_pred(motion[x / 16 + 1].x, motion[x / 16 + 2].x, motion[x / 16 + 3].x);
1267 motion[0].y = mid_pred(motion[x / 16 + 1].y, motion[x / 16 + 2].y, motion[x / 16 + 3].y);
1268 motion[x / 16 + 2].x = 0;
1269 motion[x / 16 + 2].y = 0;
1270
1271 idx = get_vlc2(gb, mv_vlc[s->moflex][0].table,
1272 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(data, 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 AVCodec ff_mobiclip_decoder = {
1343 .name = "mobiclip",
1344 .long_name = NULL_IF_CONFIG_SMALL("MobiClip Video"),
1345 .type = AVMEDIA_TYPE_VIDEO,
1346 .id = AV_CODEC_ID_MOBICLIP,
1347 .priv_data_size = sizeof(MobiClipContext),
1348 .init = mobiclip_init,
1349 .decode = mobiclip_decode,
1350 .flush = mobiclip_flush,
1351 .close = mobiclip_close,
1352 .capabilities = AV_CODEC_CAP_DR1,
1353 .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE | FF_CODEC_CAP_INIT_CLEANUP,
1354 };
1355