• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
mobiclip_init_static(void)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 
mobiclip_init(AVCodecContext * avctx)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 
setup_qtables(AVCodecContext * avctx,int quantizer)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 
inverse4(unsigned * rs)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 
idct(int * arr,int size)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 
read_run_encoding(AVCodecContext * avctx,int * last,int * run,int * level)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 
add_coefficients(AVCodecContext * avctx,AVFrame * frame,int bx,int by,int size,int plane)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 
add_pframe_coefficients(AVCodecContext * avctx,AVFrame * frame,int bx,int by,int size,int plane)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 
adjust(int x,int size)515 static int adjust(int x, int size)
516 {
517     return size == 16 ? (x + 1) >> 1 : x;
518 }
519 
pget(BlockXY b)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 
half(int a,int b)541 static uint8_t half(int a, int b)
542 {
543     return ((a + b) + 1) / 2;
544 }
545 
half3(int a,int b,int c)546 static uint8_t half3(int a, int b, int c)
547 {
548     return ((a + b + b + c) * 2 / 4 + 1) / 2;
549 }
550 
pick_above(BlockXY bxy)551 static uint8_t pick_above(BlockXY bxy)
552 {
553     bxy.y = bxy.y - 1;
554 
555     return pget(bxy);
556 }
557 
pick_left(BlockXY bxy)558 static uint8_t pick_left(BlockXY bxy)
559 {
560     bxy.x = bxy.x - 1;
561 
562     return pget(bxy);
563 }
564 
half_horz(BlockXY bxy)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 
half_vert(BlockXY bxy)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 
pick_4(BlockXY bxy)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 
pick_5(BlockXY bxy)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 
pick_6(BlockXY bxy)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 
pick_7(BlockXY bxy)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 
pick_8(BlockXY bxy)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 
block_fill_simple(uint8_t * block,int size,int linesize,int fill)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 
block_fill(uint8_t * block,int size,int linesize,int w,int h,int ax,int ay,uint8_t (* pick)(BlockXY bxy))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 
block_sum(const uint8_t * block,int w,int h,int linesize)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 
predict_intra(AVCodecContext * avctx,AVFrame * frame,int ax,int ay,int pmode,int add_coeffs,int size,int plane)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 
get_prediction(AVCodecContext * avctx,int x,int y,int size)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 
process_block(AVCodecContext * avctx,AVFrame * frame,int x,int y,int pmode,int has_coeffs,int plane)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 
decode_macroblock(AVCodecContext * avctx,AVFrame * frame,int x,int y,int predict)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 
get_index(int x)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 
predict_motion(AVCodecContext * avctx,int width,int height,int index,int offsetm,int offsetx,int offsety)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 
mobiclip_decode(AVCodecContext * avctx,void * data,int * got_frame,AVPacket * pkt)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 
mobiclip_flush(AVCodecContext * avctx)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 
mobiclip_close(AVCodecContext * avctx)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 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