• 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 "codec_internal.h"
33 #include "get_bits.h"
34 #include "golomb.h"
35 #include "internal.h"
36 
37 #define MOBI_RL_VLC_BITS 12
38 #define MOBI_MV_VLC_BITS 6
39 
40 static const uint8_t zigzag4x4_tab[] =
41 {
42     0x00, 0x04, 0x01, 0x02, 0x05, 0x08, 0x0C, 0x09, 0x06, 0x03, 0x07, 0x0A,
43     0x0D, 0x0E, 0x0B, 0x0F
44 };
45 
46 static const uint8_t quant4x4_tab[][16] =
47 {
48     { 10, 13, 13, 10, 16, 10, 13, 13, 13, 13, 16, 10, 16, 13, 13, 16 },
49     { 11, 14, 14, 11, 18, 11, 14, 14, 14, 14, 18, 11, 18, 14, 14, 18 },
50     { 13, 16, 16, 13, 20, 13, 16, 16, 16, 16, 20, 13, 20, 16, 16, 20 },
51     { 14, 18, 18, 14, 23, 14, 18, 18, 18, 18, 23, 14, 23, 18, 18, 23 },
52     { 16, 20, 20, 16, 25, 16, 20, 20, 20, 20, 25, 16, 25, 20, 20, 25 },
53     { 18, 23, 23, 18, 29, 18, 23, 23, 23, 23, 29, 18, 29, 23, 23, 29 },
54 };
55 
56 static const uint8_t quant8x8_tab[][64] =
57 {
58     { 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,
59       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,},
60     { 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,
61       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,},
62     { 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,
63       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,},
64     { 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,
65       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,},
66     { 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,
67       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,},
68     { 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,
69       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,},
70 };
71 
72 static const uint8_t block4x4_coefficients_tab[] =
73 {
74     15, 0, 2, 1, 4, 8, 12, 3, 11, 13, 14, 7, 10, 5, 9, 6,
75 };
76 
77 static const uint8_t pframe_block4x4_coefficients_tab[] =
78 {
79     0, 4, 1, 8, 2, 12, 3, 5, 10, 15, 7, 13, 14, 11, 9, 6,
80 };
81 
82 static const uint8_t block8x8_coefficients_tab[] =
83 {
84     0x00, 0x1F, 0x3F, 0x0F, 0x08, 0x04, 0x02, 0x01, 0x0B, 0x0E, 0x1B, 0x0D,
85     0x03, 0x07, 0x0C, 0x17, 0x1D, 0x0A, 0x1E, 0x05, 0x10, 0x2F, 0x37, 0x3B,
86     0x13, 0x3D, 0x3E, 0x09, 0x1C, 0x06, 0x15, 0x1A, 0x33, 0x11, 0x12, 0x14,
87     0x18, 0x20, 0x3C, 0x35, 0x19, 0x16, 0x3A, 0x30, 0x31, 0x32, 0x27, 0x34,
88     0x2B, 0x2D, 0x39, 0x38, 0x23, 0x36, 0x2E, 0x21, 0x25, 0x22, 0x24, 0x2C,
89     0x2A, 0x28, 0x29, 0x26,
90 };
91 
92 static const uint8_t pframe_block8x8_coefficients_tab[] =
93 {
94     0x00, 0x0F, 0x04, 0x01, 0x08, 0x02, 0x0C, 0x03, 0x05, 0x0A, 0x0D, 0x07, 0x0E, 0x0B, 0x1F, 0x09,
95     0x06, 0x10, 0x3F, 0x1E, 0x17, 0x1D, 0x1B, 0x1C, 0x13, 0x18, 0x1A, 0x12, 0x11, 0x14, 0x15, 0x20,
96     0x2F, 0x16, 0x19, 0x37, 0x3D, 0x3E, 0x3B, 0x3C, 0x33, 0x35, 0x21, 0x24, 0x22, 0x28, 0x23, 0x2C,
97     0x30, 0x27, 0x2D, 0x25, 0x3A, 0x2B, 0x2E, 0x2A, 0x31, 0x34, 0x38, 0x32, 0x29, 0x26, 0x39, 0x36
98 };
99 
100 static const uint8_t run_residue[2][256] =
101 {
102     {
103        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,
104         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,
105         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,
106         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,
107         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,
108         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,
109         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,
110         1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,
111     },
112     {
113        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,
114         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,
115         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,
116         0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
117         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,
118         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,
119         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,
120         1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,
121     },
122 };
123 
124 static const uint8_t bits0[] = {
125      9, 11, 11, 11, 11, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10,
126     10, 10, 11, 11, 11, 11, 11, 11, 11, 11, 12, 12, 12, 12, 12,
127     12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,  7, 10, 10,  9,
128      9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,
129      9,  9,  9,  9,  9,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,
130      8,  8,  8,  7,  7,  7,  7,  7,  7,  7,  7,  6,  6,  6,  6,
131      6,  6,  6,  6,  6,  6,  5,  5,  5,  4,  2,  3,  4,  4,
132 };
133 
134 static const uint16_t syms0[] = {
135     0x0, 0x822, 0x803, 0xB, 0xA, 0xB81, 0xB61, 0xB41, 0xB21, 0x122,
136     0x102, 0xE2, 0xC2, 0xA2, 0x63, 0x43, 0x24, 0xC, 0x25, 0x2E1, 0x301,
137     0xBA1, 0xBC1, 0xBE1, 0xC01, 0x26, 0x44, 0x83, 0xA3, 0xC3, 0x142,
138     0x321, 0x341, 0xC21, 0xC41, 0xC61, 0xC81, 0xCA1, 0xCC1, 0xCE1, 0xD01,
139     0x0, 0x9, 0x8, 0xB01, 0xAE1, 0xAC1, 0xAA1, 0xA81, 0xA61, 0xA41, 0xA21,
140     0x802, 0x2C1, 0x2A1, 0x281, 0x261, 0x241, 0x221, 0x201, 0x1E1, 0x82,
141     0x62, 0x7, 0x6, 0xA01, 0x9E1, 0x9C1, 0x9A1, 0x981, 0x961, 0x941, 0x921,
142     0x1C1, 0x1A1, 0x42, 0x23, 0x5, 0x901, 0x8E1, 0x8C1, 0x8A1, 0x181, 0x161,
143     0x141, 0x4, 0x881, 0x861, 0x841, 0x821, 0x121, 0x101, 0xE1, 0xC1, 0x22,
144     0x3, 0xA1, 0x81, 0x61, 0x801, 0x1, 0x21, 0x41, 0x2,
145 };
146 
147 static const uint16_t syms1[] = {
148     0x0, 0x807, 0x806, 0x16, 0x15, 0x842, 0x823, 0x805, 0x1A1, 0xA3, 0x102, 0x83,
149     0x64, 0x44, 0x27, 0x14, 0x13, 0x17, 0x18, 0x28, 0x122, 0x862, 0x882, 0x9E1, 0xA01,
150     0x19, 0x1A, 0x1B, 0x29, 0xC3, 0x2A, 0x45, 0xE3, 0x1C1, 0x808, 0x8A2, 0x8C2, 0xA21,
151     0xA41, 0xA61, 0xA81, 0x0, 0x12, 0x11, 0x9C1, 0x9A1, 0x981, 0x961, 0x941, 0x822, 0x804,
152     0x181, 0x161, 0xE2, 0xC2, 0xA2, 0x63, 0x43, 0x26, 0x25, 0x10, 0x82, 0xF, 0xE, 0xD, 0x901,
153     0x8E1, 0x8C1, 0x803, 0x141, 0x121, 0x101, 0x921, 0x62, 0x24, 0xC, 0xB, 0xA, 0x881, 0x861,
154     0xC1, 0x8A1, 0xE1, 0x42, 0x23, 0x9, 0x802, 0xA1, 0x841, 0x821, 0x81, 0x61, 0x8, 0x7, 0x22,
155     0x6, 0x41, 0x5, 0x4, 0x801, 0x1, 0x2, 0x21, 0x3,
156 };
157 
158 static const uint8_t mv_len[16] =
159 {
160     10, 8, 8, 7, 8, 8, 8, 7, 8, 8, 8, 7, 7, 7, 7, 6,
161 };
162 
163 static const uint8_t mv_bits[2][16][10] =
164 {
165     {
166         { 2, 3, 3, 5, 5, 4, 4, 5, 5, 2 },
167         { 2, 3, 4, 4, 3, 4, 4, 2 },
168         { 3, 4, 4, 2, 4, 4, 3, 2 },
169         { 1, 3, 4, 5, 5, 3, 3 },
170         { 2, 4, 4, 3, 3, 4, 4, 2 },
171         { 2, 3, 4, 4, 4, 4, 3, 2 },
172         { 2, 3, 4, 4, 4, 4, 3, 2 },
173         { 2, 2, 3, 4, 5, 5, 2 },
174         { 2, 3, 4, 4, 3, 4, 4, 2 },
175         { 2, 4, 4, 3, 4, 4, 3, 2 },
176         { 2, 3, 3, 5, 5, 4, 3, 2 },
177         { 2, 3, 4, 4, 3, 3, 2 },
178         { 1, 4, 4, 3, 3, 4, 4 },
179         { 2, 3, 4, 4, 3, 3, 2 },
180         { 2, 3, 4, 4, 3, 3, 2 },
181         { 3, 3, 2, 2, 3, 3 },
182     },
183     {
184         { 3, 4, 5, 5, 3, 5, 6, 6, 4, 1 },
185         { 2, 3, 4, 5, 5, 2, 3, 3 },
186         { 2, 4, 4, 3, 3, 4, 4, 2 },
187         { 1, 4, 4, 3, 4, 4, 3 },
188         { 3, 3, 2, 4, 5, 5, 3, 2 },
189         { 3, 4, 4, 3, 3, 3, 3, 2 },
190         { 1, 3, 3, 4, 4, 4, 5, 5 },
191         { 1, 4, 4, 3, 3, 4, 4 },
192         { 2, 4, 4, 3, 3, 4, 4, 2 },
193         { 1, 3, 3, 4, 4, 4, 5, 5 },
194         { 2, 3, 4, 4, 4, 4, 3, 2 },
195         { 2, 3, 3, 4, 4, 3, 2 },
196         { 1, 4, 4, 3, 3, 4, 4 },
197         { 1, 4, 4, 3, 3, 4, 4 },
198         { 2, 3, 3, 4, 4, 3, 2 },
199         { 2, 3, 3, 3, 3, 2 },
200     }
201 };
202 
203 static const uint8_t mv_syms[2][16][10] =
204 {
205     {
206         { 1, 8, 9, 4, 3, 2, 7, 5, 6, 0 },
207         { 0, 9, 5, 4, 2, 3, 8, 1 },
208         { 3, 9, 5, 0, 4, 8, 2, 1 },
209         { 1, 3, 4, 8, 5, 2, 0 },
210         { 0, 5, 4, 8, 2, 3, 9, 1 },
211         { 0, 3, 5, 9, 4, 8, 2, 1 },
212         { 0, 3, 9, 5, 8, 4, 2, 1 },
213         { 0, 2, 3, 4, 8, 5, 1 },
214         { 0, 3, 8, 4, 2, 5, 9, 1 },
215         { 2, 8, 9, 3, 5, 4, 0, 1 },
216         { 0, 4, 3, 8, 9, 5, 2, 1 },
217         { 0, 4, 8, 5, 3, 2, 1 },
218         { 1, 9, 4, 2, 0, 5, 3 },
219         { 2, 4, 9, 5, 3, 0, 1 },
220         { 0, 4, 9, 5, 3, 2, 1 },
221         { 5, 4, 1, 0, 3, 2 },
222     },
223     {
224         { 8, 2, 3, 6, 1, 7, 5, 4, 9, 0 },
225         { 9, 2, 3, 5, 4, 1, 8, 0 },
226         { 0, 5, 4, 2, 9, 3, 8, 1 },
227         { 1, 5, 4, 2, 8, 3, 0 },
228         { 2, 9, 8, 3, 5, 4, 0, 1 },
229         { 3, 5, 4, 2, 9, 8, 0, 1 },
230         { 1, 2, 0, 9, 8, 3, 5, 4 },
231         { 1, 8, 5, 2, 0, 4, 3 },
232         { 0, 5, 4, 2, 8, 3, 9, 1 },
233         { 1, 2, 0, 9, 8, 3, 5, 4 },
234         { 0, 3, 9, 8, 5, 4, 2, 1 },
235         { 0, 4, 3, 8, 5, 2, 1 },
236         { 1, 5, 4, 2, 0, 9, 3 },
237         { 1, 9, 5, 2, 0, 4, 3 },
238         { 0, 5, 3, 9, 4, 2, 1 },
239         { 0, 4, 5, 3, 2, 1 },
240     }
241 };
242 
243 typedef struct BlockXY {
244     int w, h;
245     int ax, ay;
246     int x, y;
247     int size;
248     uint8_t *block;
249     int linesize;
250 } BlockXY;
251 
252 typedef struct MotionXY {
253     int x, y;
254 } MotionXY;
255 
256 typedef struct MobiClipContext {
257     AVFrame *pic[6];
258 
259     int current_pic;
260     int moflex;
261     int dct_tab_idx;
262     int quantizer;
263 
264     GetBitContext gb;
265 
266     uint8_t *bitstream;
267     int bitstream_size;
268 
269     int     qtab[2][64];
270     uint8_t pre[32];
271     MotionXY *motion;
272     int     motion_size;
273 
274     BswapDSPContext bdsp;
275 } MobiClipContext;
276 
277 static VLC rl_vlc[2];
278 static VLC mv_vlc[2][16];
279 
mobiclip_init_static(void)280 static av_cold void mobiclip_init_static(void)
281 {
282     INIT_VLC_STATIC_FROM_LENGTHS(&rl_vlc[0], MOBI_RL_VLC_BITS, 104,
283                                  bits0, sizeof(*bits0),
284                                  syms0, sizeof(*syms0), sizeof(*syms0),
285                                  0, 0, 1 << MOBI_RL_VLC_BITS);
286     INIT_VLC_STATIC_FROM_LENGTHS(&rl_vlc[1], MOBI_RL_VLC_BITS, 104,
287                                  bits0, sizeof(*bits0),
288                                  syms1, sizeof(*syms1), sizeof(*syms1),
289                                  0, 0, 1 << MOBI_RL_VLC_BITS);
290     for (int i = 0; i < 2; i++) {
291         static VLCElem vlc_buf[2 * 16 << MOBI_MV_VLC_BITS];
292         for (int j = 0; j < 16; j++) {
293             mv_vlc[i][j].table           = &vlc_buf[(16 * i + j) << MOBI_MV_VLC_BITS];
294             mv_vlc[i][j].table_allocated = 1 << MOBI_MV_VLC_BITS;
295             ff_init_vlc_from_lengths(&mv_vlc[i][j], MOBI_MV_VLC_BITS, mv_len[j],
296                                      mv_bits[i][j], sizeof(*mv_bits[i][j]),
297                                      mv_syms[i][j], sizeof(*mv_syms[i][j]), sizeof(*mv_syms[i][j]),
298                                      0, INIT_VLC_USE_NEW_STATIC, NULL);
299         }
300     }
301 }
302 
mobiclip_init(AVCodecContext * avctx)303 static av_cold int mobiclip_init(AVCodecContext *avctx)
304 {
305     static AVOnce init_static_once = AV_ONCE_INIT;
306     MobiClipContext *s = avctx->priv_data;
307 
308     if (avctx->width & 15 || avctx->height & 15) {
309         av_log(avctx, AV_LOG_ERROR, "width/height not multiple of 16\n");
310         return AVERROR_INVALIDDATA;
311     }
312 
313     ff_bswapdsp_init(&s->bdsp);
314 
315     avctx->pix_fmt = AV_PIX_FMT_YUV420P;
316 
317     s->motion = av_calloc(avctx->width / 16 + 3, sizeof(MotionXY));
318     if (!s->motion)
319         return AVERROR(ENOMEM);
320     s->motion_size = (avctx->width / 16 + 3) * sizeof(MotionXY);
321 
322     for (int i = 0; i < 6; i++) {
323         s->pic[i] = av_frame_alloc();
324         if (!s->pic[i])
325             return AVERROR(ENOMEM);
326     }
327 
328     ff_thread_once(&init_static_once, mobiclip_init_static);
329 
330     return 0;
331 }
332 
setup_qtables(AVCodecContext * avctx,int64_t quantizer)333 static int setup_qtables(AVCodecContext *avctx, int64_t quantizer)
334 {
335     MobiClipContext *s = avctx->priv_data;
336     int qx, qy;
337 
338     if (quantizer < 12 || quantizer > 161)
339         return AVERROR_INVALIDDATA;
340 
341     s->quantizer = quantizer;
342 
343     qx = quantizer % 6;
344     qy = quantizer / 6;
345 
346     for (int i = 0; i < 16; i++)
347         s->qtab[0][i] = quant4x4_tab[qx][i] << qy;
348 
349     for (int i = 0; i < 64; i++)
350         s->qtab[1][i] = quant8x8_tab[qx][i] << (qy - 2);
351 
352     for (int i = 0; i < 20; i++)
353         s->pre[i] = 9;
354 
355     return 0;
356 }
357 
inverse4(unsigned * rs)358 static void inverse4(unsigned *rs)
359 {
360     unsigned a = rs[0] + rs[2];
361     unsigned b = rs[0] - rs[2];
362     unsigned c = rs[1] + ((int)rs[3] >> 1);
363     unsigned d = ((int)rs[1] >> 1) - rs[3];
364 
365     rs[0] = a + c;
366     rs[1] = b + d;
367     rs[2] = b - d;
368     rs[3] = a - c;
369 }
370 
idct(int * arr,int size)371 static void idct(int *arr, int size)
372 {
373     int e, f, g, h;
374     unsigned x3, x2, x1, x0;
375     int tmp[4];
376 
377     if (size == 4) {
378         inverse4(arr);
379         return;
380     }
381 
382     tmp[0] = arr[0];
383     tmp[1] = arr[2];
384     tmp[2] = arr[4];
385     tmp[3] = arr[6];
386 
387     inverse4(tmp);
388 
389     e = (unsigned)arr[7] + arr[1] - arr[3] - (arr[3] >> 1);
390     f = (unsigned)arr[7] - arr[1] + arr[5] + (arr[5] >> 1);
391     g = (unsigned)arr[5] - arr[3] - arr[7] - (arr[7] >> 1);
392     h = (unsigned)arr[5] + arr[3] + arr[1] + (arr[1] >> 1);
393     x3 = (unsigned)g + (h >> 2);
394     x2 = (unsigned)e + (f >> 2);
395     x1 = (e >> 2) - (unsigned)f;
396     x0 = (unsigned)h - (g >> 2);
397 
398     arr[0] = tmp[0] + x0;
399     arr[1] = tmp[1] + x1;
400     arr[2] = tmp[2] + x2;
401     arr[3] = tmp[3] + x3;
402     arr[4] = tmp[3] - x3;
403     arr[5] = tmp[2] - x2;
404     arr[6] = tmp[1] - x1;
405     arr[7] = tmp[0] - x0;
406 }
407 
read_run_encoding(AVCodecContext * avctx,int * last,int * run,int * level)408 static void read_run_encoding(AVCodecContext *avctx,
409                               int *last, int *run, int *level)
410 {
411     MobiClipContext *s = avctx->priv_data;
412     GetBitContext *gb = &s->gb;
413     int n = get_vlc2(gb, rl_vlc[s->dct_tab_idx].table,
414                      MOBI_RL_VLC_BITS, 1);
415 
416     *last = (n >> 11) == 1;
417     *run  = (n >> 5) & 0x3F;
418     *level = n & 0x1F;
419 }
420 
add_coefficients(AVCodecContext * avctx,AVFrame * frame,int bx,int by,int size,int plane)421 static int add_coefficients(AVCodecContext *avctx, AVFrame *frame,
422                             int bx, int by, int size, int plane)
423 {
424     MobiClipContext *s = avctx->priv_data;
425     GetBitContext *gb = &s->gb;
426     int mat[64] = { 0 };
427     const uint8_t *ztab = size == 8 ? ff_zigzag_direct : zigzag4x4_tab;
428     const int *qtab = s->qtab[size == 8];
429     uint8_t *dst = frame->data[plane] + by * frame->linesize[plane] + bx;
430 
431     for (int pos = 0; get_bits_left(gb) > 0; pos++) {
432         int qval, last, run, level;
433 
434         read_run_encoding(avctx, &last, &run, &level);
435 
436         if (level) {
437             if (get_bits1(gb))
438                 level = -level;
439         } else if (!get_bits1(gb)) {
440             read_run_encoding(avctx, &last, &run, &level);
441             level += run_residue[s->dct_tab_idx][(last ? 64 : 0) + run];
442             if (get_bits1(gb))
443                 level = -level;
444         } else if (!get_bits1(gb)) {
445             read_run_encoding(avctx, &last, &run, &level);
446             run += run_residue[s->dct_tab_idx][128 + (last ? 64 : 0) + level];
447             if (get_bits1(gb))
448                 level = -level;
449         } else {
450             last  = get_bits1(gb);
451             run   = get_bits(gb, 6);
452             level = get_sbits(gb, 12);
453         }
454 
455         pos += run;
456         if (pos >= size * size)
457             return AVERROR_INVALIDDATA;
458         qval = qtab[pos];
459         mat[ztab[pos]] = qval *(unsigned)level;
460 
461         if (last)
462             break;
463     }
464 
465     mat[0] += 32;
466     for (int y = 0; y < size; y++)
467         idct(&mat[y * size], size);
468 
469     for (int y = 0; y < size; y++) {
470         for (int x = y + 1; x < size; x++) {
471             int a = mat[x * size + y];
472             int b = mat[y * size + x];
473 
474             mat[y * size + x] = a;
475             mat[x * size + y] = b;
476         }
477 
478         idct(&mat[y * size], size);
479         for (int x = 0; x < size; x++)
480             dst[x] = av_clip_uint8(dst[x] + (mat[y * size + x] >> 6));
481         dst += frame->linesize[plane];
482     }
483 
484     return 0;
485 }
486 
add_pframe_coefficients(AVCodecContext * avctx,AVFrame * frame,int bx,int by,int size,int plane)487 static int add_pframe_coefficients(AVCodecContext *avctx, AVFrame *frame,
488                                    int bx, int by, int size, int plane)
489 {
490     MobiClipContext *s = avctx->priv_data;
491     GetBitContext *gb = &s->gb;
492     int ret, idx = get_ue_golomb_31(gb);
493 
494     if (idx == 0) {
495         return add_coefficients(avctx, frame, bx, by, size, plane);
496     } else if ((unsigned)idx < FF_ARRAY_ELEMS(pframe_block4x4_coefficients_tab)) {
497         int flags = pframe_block4x4_coefficients_tab[idx];
498 
499         for (int y = by; y < by + 8; y += 4) {
500             for (int x = bx; x < bx + 8; x += 4) {
501                 if (flags & 1) {
502                     ret = add_coefficients(avctx, frame, x, y, 4, plane);
503                     if (ret < 0)
504                         return ret;
505                 }
506                 flags >>= 1;
507             }
508         }
509         return 0;
510     } else {
511         return AVERROR_INVALIDDATA;
512     }
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,AVFrame * rframe,int * got_frame,AVPacket * pkt)1211 static int mobiclip_decode(AVCodecContext *avctx, AVFrame *rframe,
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 + (int64_t)get_se_golomb(gb));
1260         if (ret < 0)
1261             return ret;
1262 
1263         for (int y = 0; y < avctx->height; y += 16) {
1264             for (int x = 0; x < avctx->width; x += 16) {
1265                 int idx;
1266 
1267                 motion[0].x = mid_pred(motion[x / 16 + 1].x, motion[x / 16 + 2].x, motion[x / 16 + 3].x);
1268                 motion[0].y = mid_pred(motion[x / 16 + 1].y, motion[x / 16 + 2].y, motion[x / 16 + 3].y);
1269                 motion[x / 16 + 2].x = 0;
1270                 motion[x / 16 + 2].y = 0;
1271 
1272                 idx = get_vlc2(gb, mv_vlc[s->moflex][0].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(rframe, 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 const FFCodec ff_mobiclip_decoder = {
1344     .p.name         = "mobiclip",
1345     .p.long_name    = NULL_IF_CONFIG_SMALL("MobiClip Video"),
1346     .p.type         = AVMEDIA_TYPE_VIDEO,
1347     .p.id           = AV_CODEC_ID_MOBICLIP,
1348     .priv_data_size = sizeof(MobiClipContext),
1349     .init           = mobiclip_init,
1350     FF_CODEC_DECODE_CB(mobiclip_decode),
1351     .flush          = mobiclip_flush,
1352     .close          = mobiclip_close,
1353     .p.capabilities = AV_CODEC_CAP_DR1,
1354     .caps_internal  = FF_CODEC_CAP_INIT_THREADSAFE | FF_CODEC_CAP_INIT_CLEANUP,
1355 };
1356