FFmpeg
mobiclip.c
Go to the documentation of this file.
1 /*
2  * MobiClip Video decoder
3  * Copyright (c) 2017 Adib Surani
4  * Copyright (c) 2020 Paul B Mahol
5  *
6  * This file is part of FFmpeg.
7  *
8  * FFmpeg is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU Lesser General Public
10  * License as published by the Free Software Foundation; either
11  * version 2.1 of the License, or (at your option) any later version.
12  *
13  * FFmpeg is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16  * Lesser General Public License for more details.
17  *
18  * You should have received a copy of the GNU Lesser General Public
19  * License along with FFmpeg; if not, write to the Free Software
20  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
21  */
22 
23 #include <inttypes.h>
24 
25 #include "libavutil/avassert.h"
26 #include "libavutil/thread.h"
27 
28 #include "avcodec.h"
29 #include "bytestream.h"
30 #include "bswapdsp.h"
31 #include "get_bits.h"
32 #include "golomb.h"
33 #include "internal.h"
34 
35 #define MOBI_RL_VLC_BITS 12
36 #define MOBI_MV_VLC_BITS 6
37 
38 static const uint8_t zigzag4x4_tab[] =
39 {
40  0x00, 0x04, 0x01, 0x02, 0x05, 0x08, 0x0C, 0x09, 0x06, 0x03, 0x07, 0x0A,
41  0x0D, 0x0E, 0x0B, 0x0F
42 };
43 
44 static const uint8_t quant4x4_tab[][16] =
45 {
46  { 10, 13, 13, 10, 16, 10, 13, 13, 13, 13, 16, 10, 16, 13, 13, 16 },
47  { 11, 14, 14, 11, 18, 11, 14, 14, 14, 14, 18, 11, 18, 14, 14, 18 },
48  { 13, 16, 16, 13, 20, 13, 16, 16, 16, 16, 20, 13, 20, 16, 16, 20 },
49  { 14, 18, 18, 14, 23, 14, 18, 18, 18, 18, 23, 14, 23, 18, 18, 23 },
50  { 16, 20, 20, 16, 25, 16, 20, 20, 20, 20, 25, 16, 25, 20, 20, 25 },
51  { 18, 23, 23, 18, 29, 18, 23, 23, 23, 23, 29, 18, 29, 23, 23, 29 },
52 };
53 
54 static const uint8_t quant8x8_tab[][64] =
55 {
56  { 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,
57  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,},
58  { 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,
59  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,},
60  { 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,
61  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,},
62  { 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,
63  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,},
64  { 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,
65  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,},
66  { 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,
67  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,},
68 };
69 
71 {
72  15, 0, 2, 1, 4, 8, 12, 3, 11, 13, 14, 7, 10, 5, 9, 6,
73 };
74 
76 {
77  0, 4, 1, 8, 2, 12, 3, 5, 10, 15, 7, 13, 14, 11, 9, 6,
78 };
79 
81 {
82  0x00, 0x1F, 0x3F, 0x0F, 0x08, 0x04, 0x02, 0x01, 0x0B, 0x0E, 0x1B, 0x0D,
83  0x03, 0x07, 0x0C, 0x17, 0x1D, 0x0A, 0x1E, 0x05, 0x10, 0x2F, 0x37, 0x3B,
84  0x13, 0x3D, 0x3E, 0x09, 0x1C, 0x06, 0x15, 0x1A, 0x33, 0x11, 0x12, 0x14,
85  0x18, 0x20, 0x3C, 0x35, 0x19, 0x16, 0x3A, 0x30, 0x31, 0x32, 0x27, 0x34,
86  0x2B, 0x2D, 0x39, 0x38, 0x23, 0x36, 0x2E, 0x21, 0x25, 0x22, 0x24, 0x2C,
87  0x2A, 0x28, 0x29, 0x26,
88 };
89 
91 {
92  0x00, 0x0F, 0x04, 0x01, 0x08, 0x02, 0x0C, 0x03, 0x05, 0x0A, 0x0D, 0x07, 0x0E, 0x0B, 0x1F, 0x09,
93  0x06, 0x10, 0x3F, 0x1E, 0x17, 0x1D, 0x1B, 0x1C, 0x13, 0x18, 0x1A, 0x12, 0x11, 0x14, 0x15, 0x20,
94  0x2F, 0x16, 0x19, 0x37, 0x3D, 0x3E, 0x3B, 0x3C, 0x33, 0x35, 0x21, 0x24, 0x22, 0x28, 0x23, 0x2C,
95  0x30, 0x27, 0x2D, 0x25, 0x3A, 0x2B, 0x2E, 0x2A, 0x31, 0x34, 0x38, 0x32, 0x29, 0x26, 0x39, 0x36
96 };
97 
98 static const uint8_t run_residue[2][256] =
99 {
100  {
101  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,
102  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,
103  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,
104  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,
105  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,
106  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,
107  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,
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  },
110  {
111  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,
112  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,
113  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,
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  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,
116  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,
117  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,
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  },
120 };
121 
122 static const uint8_t bits0[] = {
123  9, 11, 11, 11, 11, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10,
124  10, 10, 11, 11, 11, 11, 11, 11, 11, 11, 12, 12, 12, 12, 12,
125  12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 7, 10, 10, 9,
126  9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
127  9, 9, 9, 9, 9, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
128  8, 8, 8, 7, 7, 7, 7, 7, 7, 7, 7, 6, 6, 6, 6,
129  6, 6, 6, 6, 6, 6, 5, 5, 5, 4, 2, 3, 4, 4,
130 };
131 
132 static const uint16_t syms0[] = {
133  0x0, 0x822, 0x803, 0xB, 0xA, 0xB81, 0xB61, 0xB41, 0xB21, 0x122,
134  0x102, 0xE2, 0xC2, 0xA2, 0x63, 0x43, 0x24, 0xC, 0x25, 0x2E1, 0x301,
135  0xBA1, 0xBC1, 0xBE1, 0xC01, 0x26, 0x44, 0x83, 0xA3, 0xC3, 0x142,
136  0x321, 0x341, 0xC21, 0xC41, 0xC61, 0xC81, 0xCA1, 0xCC1, 0xCE1, 0xD01,
137  0x0, 0x9, 0x8, 0xB01, 0xAE1, 0xAC1, 0xAA1, 0xA81, 0xA61, 0xA41, 0xA21,
138  0x802, 0x2C1, 0x2A1, 0x281, 0x261, 0x241, 0x221, 0x201, 0x1E1, 0x82,
139  0x62, 0x7, 0x6, 0xA01, 0x9E1, 0x9C1, 0x9A1, 0x981, 0x961, 0x941, 0x921,
140  0x1C1, 0x1A1, 0x42, 0x23, 0x5, 0x901, 0x8E1, 0x8C1, 0x8A1, 0x181, 0x161,
141  0x141, 0x4, 0x881, 0x861, 0x841, 0x821, 0x121, 0x101, 0xE1, 0xC1, 0x22,
142  0x3, 0xA1, 0x81, 0x61, 0x801, 0x1, 0x21, 0x41, 0x2,
143 };
144 
145 static const uint16_t syms1[] = {
146  0x0, 0x807, 0x806, 0x16, 0x15, 0x842, 0x823, 0x805, 0x1A1, 0xA3, 0x102, 0x83,
147  0x64, 0x44, 0x27, 0x14, 0x13, 0x17, 0x18, 0x28, 0x122, 0x862, 0x882, 0x9E1, 0xA01,
148  0x19, 0x1A, 0x1B, 0x29, 0xC3, 0x2A, 0x45, 0xE3, 0x1C1, 0x808, 0x8A2, 0x8C2, 0xA21,
149  0xA41, 0xA61, 0xA81, 0x0, 0x12, 0x11, 0x9C1, 0x9A1, 0x981, 0x961, 0x941, 0x822, 0x804,
150  0x181, 0x161, 0xE2, 0xC2, 0xA2, 0x63, 0x43, 0x26, 0x25, 0x10, 0x82, 0xF, 0xE, 0xD, 0x901,
151  0x8E1, 0x8C1, 0x803, 0x141, 0x121, 0x101, 0x921, 0x62, 0x24, 0xC, 0xB, 0xA, 0x881, 0x861,
152  0xC1, 0x8A1, 0xE1, 0x42, 0x23, 0x9, 0x802, 0xA1, 0x841, 0x821, 0x81, 0x61, 0x8, 0x7, 0x22,
153  0x6, 0x41, 0x5, 0x4, 0x801, 0x1, 0x2, 0x21, 0x3,
154 };
155 
156 static const uint8_t mv_len[16] =
157 {
158  10, 8, 8, 7, 8, 8, 8, 7, 8, 8, 8, 7, 7, 7, 7, 6,
159 };
160 
161 static const uint8_t mv_bits[2][16][10] =
162 {
163  {
164  { 2, 3, 3, 5, 5, 4, 4, 5, 5, 2 },
165  { 2, 3, 4, 4, 3, 4, 4, 2 },
166  { 3, 4, 4, 2, 4, 4, 3, 2 },
167  { 1, 3, 4, 5, 5, 3, 3 },
168  { 2, 4, 4, 3, 3, 4, 4, 2 },
169  { 2, 3, 4, 4, 4, 4, 3, 2 },
170  { 2, 3, 4, 4, 4, 4, 3, 2 },
171  { 2, 2, 3, 4, 5, 5, 2 },
172  { 2, 3, 4, 4, 3, 4, 4, 2 },
173  { 2, 4, 4, 3, 4, 4, 3, 2 },
174  { 2, 3, 3, 5, 5, 4, 3, 2 },
175  { 2, 3, 4, 4, 3, 3, 2 },
176  { 1, 4, 4, 3, 3, 4, 4 },
177  { 2, 3, 4, 4, 3, 3, 2 },
178  { 2, 3, 4, 4, 3, 3, 2 },
179  { 3, 3, 2, 2, 3, 3 },
180  },
181  {
182  { 3, 4, 5, 5, 3, 5, 6, 6, 4, 1 },
183  { 2, 3, 4, 5, 5, 2, 3, 3 },
184  { 2, 4, 4, 3, 3, 4, 4, 2 },
185  { 1, 4, 4, 3, 4, 4, 3 },
186  { 3, 3, 2, 4, 5, 5, 3, 2 },
187  { 3, 4, 4, 3, 3, 3, 3, 2 },
188  { 1, 3, 3, 4, 4, 4, 5, 5 },
189  { 1, 4, 4, 3, 3, 4, 4 },
190  { 2, 4, 4, 3, 3, 4, 4, 2 },
191  { 1, 3, 3, 4, 4, 4, 5, 5 },
192  { 2, 3, 4, 4, 4, 4, 3, 2 },
193  { 2, 3, 3, 4, 4, 3, 2 },
194  { 1, 4, 4, 3, 3, 4, 4 },
195  { 1, 4, 4, 3, 3, 4, 4 },
196  { 2, 3, 3, 4, 4, 3, 2 },
197  { 2, 3, 3, 3, 3, 2 },
198  }
199 };
200 
201 static const uint8_t mv_syms[2][16][10] =
202 {
203  {
204  { 1, 8, 9, 4, 3, 2, 7, 5, 6, 0 },
205  { 0, 9, 5, 4, 2, 3, 8, 1 },
206  { 3, 9, 5, 0, 4, 8, 2, 1 },
207  { 1, 3, 4, 8, 5, 2, 0 },
208  { 0, 5, 4, 8, 2, 3, 9, 1 },
209  { 0, 3, 5, 9, 4, 8, 2, 1 },
210  { 0, 3, 9, 5, 8, 4, 2, 1 },
211  { 0, 2, 3, 4, 8, 5, 1 },
212  { 0, 3, 8, 4, 2, 5, 9, 1 },
213  { 2, 8, 9, 3, 5, 4, 0, 1 },
214  { 0, 4, 3, 8, 9, 5, 2, 1 },
215  { 0, 4, 8, 5, 3, 2, 1 },
216  { 1, 9, 4, 2, 0, 5, 3 },
217  { 2, 4, 9, 5, 3, 0, 1 },
218  { 0, 4, 9, 5, 3, 2, 1 },
219  { 5, 4, 1, 0, 3, 2 },
220  },
221  {
222  { 8, 2, 3, 6, 1, 7, 5, 4, 9, 0 },
223  { 9, 2, 3, 5, 4, 1, 8, 0 },
224  { 0, 5, 4, 2, 9, 3, 8, 1 },
225  { 1, 5, 4, 2, 8, 3, 0 },
226  { 2, 9, 8, 3, 5, 4, 0, 1 },
227  { 3, 5, 4, 2, 9, 8, 0, 1 },
228  { 1, 2, 0, 9, 8, 3, 5, 4 },
229  { 1, 8, 5, 2, 0, 4, 3 },
230  { 0, 5, 4, 2, 8, 3, 9, 1 },
231  { 1, 2, 0, 9, 8, 3, 5, 4 },
232  { 0, 3, 9, 8, 5, 4, 2, 1 },
233  { 0, 4, 3, 8, 5, 2, 1 },
234  { 1, 5, 4, 2, 0, 9, 3 },
235  { 1, 9, 5, 2, 0, 4, 3 },
236  { 0, 5, 3, 9, 4, 2, 1 },
237  { 0, 4, 5, 3, 2, 1 },
238  }
239 };
240 
241 typedef struct BlockXY {
242  int w, h;
243  int ax, ay;
244  int x, y;
245  int size;
247  int linesize;
248 } BlockXY;
249 
250 typedef struct MotionXY {
251  int x, y;
252 } MotionXY;
253 
254 typedef struct MobiClipContext {
255  AVFrame *pic[6];
256 
258  int moflex;
261 
263 
266 
267  int qtab[2][64];
268  uint8_t pre[32];
271 
274 
275 static VLC rl_vlc[2];
276 static VLC mv_vlc[2][16];
277 
278 static av_cold void mobiclip_init_static(void)
279 {
281  bits0, sizeof(*bits0),
282  syms0, sizeof(*syms0), sizeof(*syms0),
283  0, 0, 1 << MOBI_RL_VLC_BITS);
285  bits0, sizeof(*bits0),
286  syms1, sizeof(*syms1), sizeof(*syms1),
287  0, 0, 1 << MOBI_RL_VLC_BITS);
288  for (int i = 0; i < 2; i++) {
289  static VLC_TYPE vlc_buf[2 * 16 << MOBI_MV_VLC_BITS][2];
290  for (int j = 0; j < 16; j++) {
291  mv_vlc[i][j].table = &vlc_buf[(16 * i + j) << MOBI_MV_VLC_BITS];
292  mv_vlc[i][j].table_allocated = 1 << MOBI_MV_VLC_BITS;
294  mv_bits[i][j], sizeof(*mv_bits[i][j]),
295  mv_syms[i][j], sizeof(*mv_syms[i][j]), sizeof(*mv_syms[i][j]),
297  }
298  }
299 }
300 
302 {
303  static AVOnce init_static_once = AV_ONCE_INIT;
304  MobiClipContext *s = avctx->priv_data;
305 
306  if (avctx->width & 15 || avctx->height & 15) {
307  av_log(avctx, AV_LOG_ERROR, "width/height not multiple of 16\n");
308  return AVERROR_INVALIDDATA;
309  }
310 
311  ff_bswapdsp_init(&s->bdsp);
312 
313  avctx->pix_fmt = AV_PIX_FMT_YUV420P;
314 
315  s->motion = av_calloc(avctx->width / 16 + 3, sizeof(MotionXY));
316  if (!s->motion)
317  return AVERROR(ENOMEM);
318  s->motion_size = (avctx->width / 16 + 3) * sizeof(MotionXY);
319 
320  for (int i = 0; i < 6; i++) {
321  s->pic[i] = av_frame_alloc();
322  if (!s->pic[i])
323  return AVERROR(ENOMEM);
324  }
325 
326  ff_thread_once(&init_static_once, mobiclip_init_static);
327 
328  return 0;
329 }
330 
331 static int setup_qtables(AVCodecContext *avctx, int quantizer)
332 {
333  MobiClipContext *s = avctx->priv_data;
334  int qx, qy;
335 
336  if (quantizer < 12 || quantizer > 161)
337  return AVERROR_INVALIDDATA;
338 
339  s->quantizer = quantizer;
340 
341  qx = quantizer % 6;
342  qy = quantizer / 6;
343 
344  for (int i = 0; i < 16; i++)
345  s->qtab[0][i] = quant4x4_tab[qx][i] << qy;
346 
347  for (int i = 0; i < 64; i++)
348  s->qtab[1][i] = quant8x8_tab[qx][i] << (qy - 2);
349 
350  for (int i = 0; i < 20; i++)
351  s->pre[i] = 9;
352 
353  return 0;
354 }
355 
356 static void inverse4(unsigned *rs)
357 {
358  unsigned a = rs[0] + rs[2];
359  unsigned b = rs[0] - rs[2];
360  unsigned c = rs[1] + ((int)rs[3] >> 1);
361  unsigned d = ((int)rs[1] >> 1) - rs[3];
362 
363  rs[0] = a + c;
364  rs[1] = b + d;
365  rs[2] = b - d;
366  rs[3] = a - c;
367 }
368 
369 static void idct(int *arr, int size)
370 {
371  int e, f, g, h;
372  unsigned x3, x2, x1, x0;
373  int tmp[4];
374 
375  if (size == 4) {
376  inverse4(arr);
377  return;
378  }
379 
380  tmp[0] = arr[0];
381  tmp[1] = arr[2];
382  tmp[2] = arr[4];
383  tmp[3] = arr[6];
384 
385  inverse4(tmp);
386 
387  e = (unsigned)arr[7] + arr[1] - arr[3] - (arr[3] >> 1);
388  f = (unsigned)arr[7] - arr[1] + arr[5] + (arr[5] >> 1);
389  g = (unsigned)arr[5] - arr[3] - arr[7] - (arr[7] >> 1);
390  h = (unsigned)arr[5] + arr[3] + arr[1] + (arr[1] >> 1);
391  x3 = (unsigned)g + (h >> 2);
392  x2 = (unsigned)e + (f >> 2);
393  x1 = (e >> 2) - (unsigned)f;
394  x0 = (unsigned)h - (g >> 2);
395 
396  arr[0] = tmp[0] + x0;
397  arr[1] = tmp[1] + x1;
398  arr[2] = tmp[2] + x2;
399  arr[3] = tmp[3] + x3;
400  arr[4] = tmp[3] - x3;
401  arr[5] = tmp[2] - x2;
402  arr[6] = tmp[1] - x1;
403  arr[7] = tmp[0] - x0;
404 }
405 
407  int *last, int *run, int *level)
408 {
409  MobiClipContext *s = avctx->priv_data;
410  GetBitContext *gb = &s->gb;
411  int n = get_vlc2(gb, rl_vlc[s->dct_tab_idx].table,
412  MOBI_RL_VLC_BITS, 1);
413 
414  *last = (n >> 11) == 1;
415  *run = (n >> 5) & 0x3F;
416  *level = n & 0x1F;
417 }
418 
420  int bx, int by, int size, int plane)
421 {
422  MobiClipContext *s = avctx->priv_data;
423  GetBitContext *gb = &s->gb;
424  int mat[64] = { 0 };
425  const uint8_t *ztab = size == 8 ? ff_zigzag_direct : zigzag4x4_tab;
426  const int *qtab = s->qtab[size == 8];
427  uint8_t *dst = frame->data[plane] + by * frame->linesize[plane] + bx;
428 
429  for (int pos = 0; get_bits_left(gb) > 0; pos++) {
430  int qval, last, run, level;
431 
432  read_run_encoding(avctx, &last, &run, &level);
433 
434  if (level) {
435  if (get_bits1(gb))
436  level = -level;
437  } else if (!get_bits1(gb)) {
438  read_run_encoding(avctx, &last, &run, &level);
439  level += run_residue[s->dct_tab_idx][(last ? 64 : 0) + run];
440  if (get_bits1(gb))
441  level = -level;
442  } else if (!get_bits1(gb)) {
443  read_run_encoding(avctx, &last, &run, &level);
444  run += run_residue[s->dct_tab_idx][128 + (last ? 64 : 0) + level];
445  if (get_bits1(gb))
446  level = -level;
447  } else {
448  last = get_bits1(gb);
449  run = get_bits(gb, 6);
450  level = get_sbits(gb, 12);
451  }
452 
453  pos += run;
454  if (pos >= size * size)
455  return AVERROR_INVALIDDATA;
456  qval = qtab[pos];
457  mat[ztab[pos]] = qval *(unsigned)level;
458 
459  if (last)
460  break;
461  }
462 
463  mat[0] += 32;
464  for (int y = 0; y < size; y++)
465  idct(&mat[y * size], size);
466 
467  for (int y = 0; y < size; y++) {
468  for (int x = y + 1; x < size; x++) {
469  int a = mat[x * size + y];
470  int b = mat[y * size + x];
471 
472  mat[y * size + x] = a;
473  mat[x * size + y] = b;
474  }
475 
476  idct(&mat[y * size], size);
477  for (int x = 0; x < size; x++)
478  dst[x] = av_clip_uint8(dst[x] + (mat[y * size + x] >> 6));
479  dst += frame->linesize[plane];
480  }
481 
482  return 0;
483 }
484 
486  int bx, int by, int size, int plane)
487 {
488  MobiClipContext *s = avctx->priv_data;
489  GetBitContext *gb = &s->gb;
490  int ret, idx = get_ue_golomb_31(gb);
491 
492  if (idx == 0) {
493  ret = add_coefficients(avctx, frame, bx, by, size, plane);
494  } else if ((unsigned)idx < FF_ARRAY_ELEMS(pframe_block4x4_coefficients_tab)) {
496 
497  for (int y = by; y < by + 8; y += 4) {
498  for (int x = bx; x < bx + 8; x += 4) {
499  if (flags & 1) {
500  ret = add_coefficients(avctx, frame, x, y, 4, plane);
501  if (ret < 0)
502  return ret;
503  }
504  flags >>= 1;
505  }
506  }
507  } else {
508  ret = AVERROR_INVALIDDATA;
509  }
510 
511  return ret;
512 }
513 
514 static int adjust(int x, int size)
515 {
516  return size == 16 ? (x + 1) >> 1 : x;
517 }
518 
520 {
521  BlockXY ret = b;
522  int x, y;
523 
524  if (b.x == -1 && b.y >= b.size) {
525  ret.x = -1, ret.y = b.size - 1;
526  } else if (b.x >= -1 && b.y >= -1) {
527  ret.x = b.x, ret.y = b.y;
528  } else if (b.x == -1 && b.y == -2) {
529  ret.x = 0, ret.y = -1;
530  } else if (b.x == -2 && b.y == -1) {
531  ret.x = -1, ret.y = 0;
532  }
533 
534  y = av_clip(ret.ay + ret.y, 0, ret.h - 1);
535  x = av_clip(ret.ax + ret.x, 0, ret.w - 1);
536 
537  return ret.block[y * ret.linesize + x];
538 }
539 
540 static uint8_t half(int a, int b)
541 {
542  return ((a + b) + 1) / 2;
543 }
544 
545 static uint8_t half3(int a, int b, int c)
546 {
547  return ((a + b + b + c) * 2 / 4 + 1) / 2;;
548 }
549 
551 {
552  bxy.y = bxy.y - 1;
553 
554  return pget(bxy);
555 }
556 
558 {
559  bxy.x = bxy.x - 1;
560 
561  return pget(bxy);
562 }
563 
565 {
566  BlockXY a = bxy, b = bxy, c = bxy;
567 
568  a.x -= 1;
569  c.x += 1;
570 
571  return half3(pget(a), pget(b), pget(c));
572 }
573 
575 {
576  BlockXY a = bxy, b = bxy, c = bxy;
577 
578  a.y -= 1;
579  c.y += 1;
580 
581  return half3(pget(a), pget(b), pget(c));
582 }
583 
584 static uint8_t pick_4(BlockXY bxy)
585 {
586  int val;
587 
588  if ((bxy.x % 2) == 0) {
589  BlockXY ba, bb;
590  int a, b;
591 
592  ba = bxy;
593  ba.x = -1;
594  ba.y = bxy.y + bxy.x / 2;
595  a = pget(ba);
596 
597  bb = bxy;
598  bb.x = -1;
599  bb.y = bxy.y + bxy.x / 2 + 1;
600  b = pget(bb);
601 
602  val = half(a, b);
603  } else {
604  BlockXY ba;
605 
606  ba = bxy;
607  ba.x = -1;
608  ba.y = bxy.y + bxy.x / 2 + 1;
609  val = half_vert(ba);
610  }
611 
612  return val;
613 }
614 
615 static uint8_t pick_5(BlockXY bxy)
616 {
617  int val;
618 
619  if (bxy.x == 0) {
620  BlockXY a = bxy;
621  BlockXY b = bxy;
622 
623  a.x = -1;
624  a.y -= 1;
625 
626  b.x = -1;
627 
628  val = half(pget(a), pget(b));
629  } else if (bxy.y == 0) {
630  BlockXY a = bxy;
631 
632  a.x -= 2;
633  a.y -= 1;
634 
635  val = half_horz(a);
636  } else if (bxy.x == 1) {
637  BlockXY a = bxy;
638 
639  a.x -= 2;
640  a.y -= 1;
641 
642  val = half_vert(a);
643  } else {
644  BlockXY a = bxy;
645 
646  a.x -= 2;
647  a.y -= 1;
648 
649  val = pget(a);
650  }
651 
652  return val;
653 }
654 
655 static uint8_t pick_6(BlockXY bxy)
656 {
657  int val;
658 
659  if (bxy.y == 0) {
660  BlockXY a = bxy;
661  BlockXY b = bxy;
662 
663  a.x -= 1;
664  a.y = -1;
665 
666  b.y = -1;
667 
668  val = half(pget(a), pget(b));
669  } else if (bxy.x == 0) {
670  BlockXY a = bxy;
671 
672  a.x -= 1;
673  a.y -= 2;
674 
675  val = half_vert(a);
676  } else if (bxy.y == 1) {
677  BlockXY a = bxy;
678 
679  a.x -= 1;
680  a.y -= 2;
681 
682  val = half_horz(a);
683  } else {
684  BlockXY a = bxy;
685 
686  a.x -= 1;
687  a.y -= 2;
688 
689  val = pget(a);
690  }
691 
692  return val;
693 }
694 
695 static uint8_t pick_7(BlockXY bxy)
696 {
697  int clr, acc1, acc2;
698  BlockXY a = bxy;
699 
700  a.x -= 1;
701  a.y -= 1;
702  clr = pget(a);
703  if (bxy.x && bxy.y)
704  return clr;
705 
706  if (bxy.x == 0) {
707  a.x = -1;
708  a.y = bxy.y;
709  } else {
710  a.x = bxy.x - 2;
711  a.y = -1;
712  }
713  acc1 = pget(a);
714 
715  if (bxy.y == 0) {
716  a.x = bxy.x;
717  a.y = -1;
718  } else {
719  a.x = -1;
720  a.y = bxy.y - 2;
721  }
722  acc2 = pget(a);
723 
724  return half3(acc1, clr, acc2);
725 }
726 
727 static uint8_t pick_8(BlockXY bxy)
728 {
729  BlockXY ba = bxy;
730  BlockXY bb = bxy;
731  int val;
732 
733  if (bxy.y == 0) {
734  int a, b;
735 
736  ba.y = -1;
737  a = pget(ba);
738 
739  bb.x += 1;
740  bb.y = -1;
741 
742  b = pget(bb);
743 
744  val = half(a, b);
745  } else if (bxy.y == 1) {
746  ba.x += 1;
747  ba.y -= 2;
748 
749  val = half_horz(ba);
750  } else if (bxy.x < bxy.size - 1) {
751  ba.x += 1;
752  ba.y -= 2;
753 
754  val = pget(ba);
755  } else if (bxy.y % 2 == 0) {
756  int a, b;
757 
758  ba.x = bxy.y / 2 + bxy.size - 1;
759  ba.y = -1;
760  a = pget(ba);
761 
762  bb.x = bxy.y / 2 + bxy.size;
763  bb.y = -1;
764 
765  b = pget(bb);
766 
767  val = half(a, b);
768  } else {
769  ba.x = bxy.y / 2 + bxy.size;
770  ba.y = -1;
771 
772  val = half_horz(ba);
773  }
774 
775  return val;
776 }
777 
778 static void block_fill_simple(uint8_t *block, int size, int linesize, int fill)
779 {
780  for (int y = 0; y < size; y++) {
781  memset(block, fill, size);
782  block += linesize;
783  }
784 }
785 
786 static void block_fill(uint8_t *block, int size, int linesize,
787  int w, int h, int ax, int ay,
788  uint8_t (*pick)(BlockXY bxy))
789 {
790  BlockXY bxy;
791 
792  bxy.size = size;
793  bxy.block = block;
794  bxy.linesize = linesize;
795  bxy.w = w;
796  bxy.h = h;
797  bxy.ay = ay;
798  bxy.ax = ax;
799 
800  for (int y = 0; y < size; y++) {
801  bxy.y = y;
802  for (int x = 0; x < size; x++) {
803  uint8_t val;
804 
805  bxy.x = x;
806 
807  val = pick(bxy);
808 
809  block[ax + x + (ay + y) * linesize] = val;
810  }
811  }
812 }
813 
814 static int block_sum(const uint8_t *block, int w, int h, int linesize)
815 {
816  int sum = 0;
817 
818  for (int y = 0; y < h; y++) {
819  for (int x = 0; x < w; x++) {
820  sum += block[x];
821  }
822  block += linesize;
823  }
824 
825  return sum;
826 }
827 
828 static int predict_intra(AVCodecContext *avctx, AVFrame *frame, int ax, int ay,
829  int pmode, int add_coeffs, int size, int plane)
830 {
831  MobiClipContext *s = avctx->priv_data;
832  GetBitContext *gb = &s->gb;
833  int w = avctx->width >> !!plane, h = avctx->height >> !!plane;
834  int ret = 0;
835 
836  switch (pmode) {
837  case 0:
838  block_fill(frame->data[plane], size, frame->linesize[plane], w, h, ax, ay, pick_above);
839  break;
840  case 1:
841  block_fill(frame->data[plane], size, frame->linesize[plane], w, h, ax, ay, pick_left);
842  break;
843  case 2:
844  {
845  int arr1[16];
846  int arr2[16];
847  uint8_t *top = frame->data[plane] + FFMAX(ay - 1, 0) * frame->linesize[plane] + ax;
848  uint8_t *left = frame->data[plane] + ay * frame->linesize[plane] + FFMAX(ax - 1, 0);
849  int bottommost = frame->data[plane][(ay + size - 1) * frame->linesize[plane] + FFMAX(ax - 1, 0)];
850  int rightmost = frame->data[plane][FFMAX(ay - 1, 0) * frame->linesize[plane] + ax + size - 1];
851  int avg = (bottommost + rightmost + 1) / 2 + 2 * get_se_golomb(gb);
852  int r6 = adjust(avg - bottommost, size);
853  int r9 = adjust(avg - rightmost, size);
854  int shift = adjust(size, size) == 8 ? 3 : 2;
855  uint8_t *block;
856 
857  for (int x = 0; x < size; x++) {
858  int val = top[x];
859  arr1[x] = adjust(((bottommost - val) * (1 << shift)) + r6 * (x + 1), size);
860  }
861 
862  for (int y = 0; y < size; y++) {
863  int val = left[y * frame->linesize[plane]];
864  arr2[y] = adjust(((rightmost - val) * (1 << shift)) + r9 * (y + 1), size);
865  }
866 
867  block = frame->data[plane] + ay * frame->linesize[plane] + ax;
868  for (int y = 0; y < size; y++) {
869  for (int x = 0; x < size; x++) {
870  block[x] = (((top[x] + left[0] + ((arr1[x] * (y + 1) +
871  arr2[y] * (x + 1)) >> 2 * shift)) + 1) / 2) & 0xFF;
872  }
873  block += frame->linesize[plane];
874  left += frame->linesize[plane];
875  }
876  }
877  break;
878  case 3:
879  {
880  uint8_t fill;
881 
882  if (ax == 0 && ay == 0) {
883  fill = 0x80;
884  } else if (ax >= 1 && ay >= 1) {
885  int left = block_sum(frame->data[plane] + ay * frame->linesize[plane] + ax - 1,
886  1, size, frame->linesize[plane]);
887  int top = block_sum(frame->data[plane] + (ay - 1) * frame->linesize[plane] + ax,
888  size, 1, frame->linesize[plane]);
889 
890  fill = ((left + top) * 2 / (2 * size) + 1) / 2;
891  } else if (ax >= 1) {
892  fill = (block_sum(frame->data[plane] + ay * frame->linesize[plane] + ax - 1,
893  1, size, frame->linesize[plane]) * 2 / size + 1) / 2;
894  } else if (ay >= 1) {
895  fill = (block_sum(frame->data[plane] + (ay - 1) * frame->linesize[plane] + ax,
896  size, 1, frame->linesize[plane]) * 2 / size + 1) / 2;
897  } else {
898  return -1;
899  }
900 
901  block_fill_simple(frame->data[plane] + ay * frame->linesize[plane] + ax,
902  size, frame->linesize[plane], fill);
903  }
904  break;
905  case 4:
906  block_fill(frame->data[plane], size, frame->linesize[plane], w, h, ax, ay, pick_4);
907  break;
908  case 5:
909  block_fill(frame->data[plane], size, frame->linesize[plane], w, h, ax, ay, pick_5);
910  break;
911  case 6:
912  block_fill(frame->data[plane], size, frame->linesize[plane], w, h, ax, ay, pick_6);
913  break;
914  case 7:
915  block_fill(frame->data[plane], size, frame->linesize[plane], w, h, ax, ay, pick_7);
916  break;
917  case 8:
918  block_fill(frame->data[plane], size, frame->linesize[plane], w, h, ax, ay, pick_8);
919  break;
920  }
921 
922  if (add_coeffs)
923  ret = add_coefficients(avctx, frame, ax, ay, size, plane);
924 
925  return ret;
926 }
927 
928 static int get_prediction(AVCodecContext *avctx, int x, int y, int size)
929 {
930  MobiClipContext *s = avctx->priv_data;
931  GetBitContext *gb = &s->gb;
932  int index = (y & 0xC) | (x / 4 % 4);
933 
934  uint8_t val = FFMIN(s->pre[index], index % 4 == 0 ? 9 : s->pre[index + 3]);
935  if (val == 9)
936  val = 3;
937 
938  if (!get_bits1(gb)) {
939  int x = get_bits(gb, 3);
940  val = x + (x >= val ? 1 : 0);
941  }
942 
943  s->pre[index + 4] = val;
944  if (size == 8)
945  s->pre[index + 5] = s->pre[index + 8] = s->pre[index + 9] = val;
946 
947  return val;
948 }
949 
951  int x, int y, int pmode, int has_coeffs, int plane)
952 {
953  MobiClipContext *s = avctx->priv_data;
954  GetBitContext *gb = &s->gb;
955  int tmp, ret;
956 
957  if (!has_coeffs) {
958  if (pmode < 0)
959  pmode = get_prediction(avctx, x, y, 8);
960  return predict_intra(avctx, frame, x, y, pmode, 0, 8, plane);
961  }
962 
963  tmp = get_ue_golomb_31(gb);
964  if ((unsigned)tmp > FF_ARRAY_ELEMS(block4x4_coefficients_tab))
965  return AVERROR_INVALIDDATA;
966 
967  if (tmp == 0) {
968  if (pmode < 0)
969  pmode = get_prediction(avctx, x, y, 8);
970  ret = predict_intra(avctx, frame, x, y, pmode, 1, 8, plane);
971  } else {
972  int flags = block4x4_coefficients_tab[tmp - 1];
973 
974  for (int by = y; by < y + 8; by += 4) {
975  for (int bx = x; bx < x + 8; bx += 4) {
976  int new_pmode = pmode;
977 
978  if (new_pmode < 0)
979  new_pmode = get_prediction(avctx, bx, by, 4);
980  ret = predict_intra(avctx, frame, bx, by, new_pmode, flags & 1, 4, plane);
981  if (ret < 0)
982  return ret;
983  flags >>= 1;
984  }
985  }
986  }
987 
988  return ret;
989 }
990 
992  int x, int y, int predict)
993 {
994  MobiClipContext *s = avctx->priv_data;
995  GetBitContext *gb = &s->gb;
996  int flags, pmode_uv, idx = get_ue_golomb(gb);
997  int ret = 0;
998 
999  if (idx < 0 || idx >= FF_ARRAY_ELEMS(block8x8_coefficients_tab))
1000  return AVERROR_INVALIDDATA;
1001 
1002  flags = block8x8_coefficients_tab[idx];
1003 
1004  if (predict) {
1005  ret = process_block(avctx, frame, x, y, -1, flags & 1, 0);
1006  if (ret < 0)
1007  return ret;
1008  flags >>= 1;
1009  ret = process_block(avctx, frame, x + 8, y, -1, flags & 1, 0);
1010  if (ret < 0)
1011  return ret;
1012  flags >>= 1;
1013  ret = process_block(avctx, frame, x, y + 8, -1, flags & 1, 0);
1014  if (ret < 0)
1015  return ret;
1016  flags >>= 1;
1017  ret = process_block(avctx, frame, x + 8, y + 8, -1, flags & 1, 0);
1018  if (ret < 0)
1019  return ret;
1020  flags >>= 1;
1021  } else {
1022  int pmode = get_bits(gb, 3);
1023 
1024  if (pmode == 2) {
1025  ret = predict_intra(avctx, frame, x, y, pmode, 0, 16, 0);
1026  if (ret < 0)
1027  return ret;
1028  pmode = 9;
1029  }
1030 
1031  ret = process_block(avctx, frame, x, y, pmode, flags & 1, 0);
1032  if (ret < 0)
1033  return ret;
1034  flags >>= 1;
1035  ret = process_block(avctx, frame, x + 8, y, pmode, flags & 1, 0);
1036  if (ret < 0)
1037  return ret;
1038  flags >>= 1;
1039  ret = process_block(avctx, frame, x, y + 8, pmode, flags & 1, 0);
1040  if (ret < 0)
1041  return ret;
1042  flags >>= 1;
1043  ret = process_block(avctx, frame, x + 8, y + 8, pmode, flags & 1, 0);
1044  if (ret < 0)
1045  return ret;
1046  flags >>= 1;
1047  }
1048 
1049  pmode_uv = get_bits(gb, 3);
1050  if (pmode_uv == 2) {
1051  ret = predict_intra(avctx, frame, x >> 1, y >> 1, pmode_uv, 0, 8, 1 + !s->moflex);
1052  if (ret < 0)
1053  return ret;
1054  ret = predict_intra(avctx, frame, x >> 1, y >> 1, pmode_uv, 0, 8, 2 - !s->moflex);
1055  if (ret < 0)
1056  return ret;
1057  pmode_uv = 9;
1058  }
1059 
1060  ret = process_block(avctx, frame, x >> 1, y >> 1, pmode_uv, flags & 1, 1 + !s->moflex);
1061  if (ret < 0)
1062  return ret;
1063  flags >>= 1;
1064  ret = process_block(avctx, frame, x >> 1, y >> 1, pmode_uv, flags & 1, 2 - !s->moflex);
1065  if (ret < 0)
1066  return ret;
1067 
1068  return 0;
1069 }
1070 
1071 static int get_index(int x)
1072 {
1073  return x == 16 ? 0 : x == 8 ? 1 : x == 4 ? 2 : x == 2 ? 3 : 0;
1074 }
1075 
1076 static int predict_motion(AVCodecContext *avctx,
1077  int width, int height, int index,
1078  int offsetm, int offsetx, int offsety)
1079 {
1080  MobiClipContext *s = avctx->priv_data;
1081  MotionXY *motion = s->motion;
1082  GetBitContext *gb = &s->gb;
1083  int fheight = avctx->height;
1084  int fwidth = avctx->width;
1085 
1086  if (index <= 5) {
1087  int sidx = -FFMAX(1, index) + s->current_pic;
1088  MotionXY mv = s->motion[0];
1089 
1090  if (sidx < 0)
1091  sidx += 6;
1092 
1093  if (index > 0) {
1094  mv.x = mv.x + get_se_golomb(gb);
1095  mv.y = mv.y + get_se_golomb(gb);
1096  }
1097  if (mv.x >= INT_MAX || mv.y >= INT_MAX)
1098  return AVERROR_INVALIDDATA;
1099 
1100  motion[offsetm].x = mv.x;
1101  motion[offsetm].y = mv.y;
1102 
1103  for (int i = 0; i < 3; i++) {
1104  int method, src_linesize, dst_linesize;
1105  uint8_t *src, *dst;
1106 
1107  if (i == 1) {
1108  offsetx = offsetx >> 1;
1109  offsety = offsety >> 1;
1110  mv.x = mv.x >> 1;
1111  mv.y = mv.y >> 1;
1112  width = width >> 1;
1113  height = height >> 1;
1114  fwidth = fwidth >> 1;
1115  fheight = fheight >> 1;
1116  }
1117 
1118  av_assert0(s->pic[sidx]);
1119  av_assert0(s->pic[s->current_pic]);
1120  av_assert0(s->pic[s->current_pic]->data[i]);
1121  if (!s->pic[sidx]->data[i])
1122  return AVERROR_INVALIDDATA;
1123 
1124  method = (mv.x & 1) | ((mv.y & 1) << 1);
1125  src_linesize = s->pic[sidx]->linesize[i];
1126  dst_linesize = s->pic[s->current_pic]->linesize[i];
1127  dst = s->pic[s->current_pic]->data[i] + offsetx + offsety * dst_linesize;
1128 
1129  if (offsetx + (mv.x >> 1) < 0 ||
1130  offsety + (mv.y >> 1) < 0 ||
1131  offsetx + width + (mv.x + 1 >> 1) > fwidth ||
1132  offsety + height + (mv.y + 1 >> 1) > fheight)
1133  return AVERROR_INVALIDDATA;
1134 
1135  switch (method) {
1136  case 0:
1137  src = s->pic[sidx]->data[i] + offsetx + (mv.x >> 1) +
1138  (offsety + (mv.y >> 1)) * src_linesize;
1139  for (int y = 0; y < height; y++) {
1140  for (int x = 0; x < width; x++)
1141  dst[x] = src[x];
1142  dst += dst_linesize;
1143  src += src_linesize;
1144  }
1145  break;
1146  case 1:
1147  src = s->pic[sidx]->data[i] + offsetx + (mv.x >> 1) +
1148  (offsety + (mv.y >> 1)) * src_linesize;
1149  for (int y = 0; y < height; y++) {
1150  for (int x = 0; x < width; x++) {
1151  dst[x] = (uint8_t)((src[x] >> 1) + (src[x + 1] >> 1));
1152  }
1153 
1154  dst += dst_linesize;
1155  src += src_linesize;
1156  }
1157  break;
1158  case 2:
1159  src = s->pic[sidx]->data[i] + offsetx + (mv.x >> 1) +
1160  (offsety + (mv.y >> 1)) * src_linesize;
1161  for (int y = 0; y < height; y++) {
1162  for (int x = 0; x < width; x++) {
1163  dst[x] = (uint8_t)((src[x] >> 1) + (src[x + src_linesize] >> 1));
1164  }
1165 
1166  dst += dst_linesize;
1167  src += src_linesize;
1168  }
1169  break;
1170  case 3:
1171  src = s->pic[sidx]->data[i] + offsetx + (mv.x >> 1) +
1172  (offsety + (mv.y >> 1)) * src_linesize;
1173  for (int y = 0; y < height; y++) {
1174  for (int x = 0; x < width; x++) {
1175  dst[x] = (uint8_t)((((src[x] >> 1) + (src[x + 1] >> 1)) >> 1) +
1176  (((src[x + src_linesize] >> 1) + (src[x + 1 + src_linesize] >> 1)) >> 1));
1177  }
1178 
1179  dst += dst_linesize;
1180  src += src_linesize;
1181  }
1182  break;
1183  }
1184  }
1185  } else {
1186  int tidx;
1187  int adjx = index == 8 ? 0 : width / 2;
1188  int adjy = index == 8 ? height / 2 : 0;
1189 
1190  width = width - adjx;
1191  height = height - adjy;
1192  tidx = get_index(height) * 4 + get_index(width);
1193 
1194  for (int i = 0; i < 2; i++) {
1195  int ret, idx2;
1196 
1197  idx2 = get_vlc2(gb, mv_vlc[s->moflex][tidx].table,
1198  MOBI_MV_VLC_BITS, 1);
1199 
1200  ret = predict_motion(avctx, width, height, idx2,
1201  offsetm, offsetx + i * adjx, offsety + i * adjy);
1202  if (ret < 0)
1203  return ret;
1204  }
1205  }
1206 
1207  return 0;
1208 }
1209 
1210 static int mobiclip_decode(AVCodecContext *avctx, void *data,
1211  int *got_frame, AVPacket *pkt)
1212 {
1213  MobiClipContext *s = avctx->priv_data;
1214  GetBitContext *gb = &s->gb;
1215  AVFrame *frame = s->pic[s->current_pic];
1216  int ret;
1217 
1219  pkt->size);
1220 
1221  if ((ret = ff_reget_buffer(avctx, frame, 0)) < 0)
1222  return ret;
1223 
1224  s->bdsp.bswap16_buf((uint16_t *)s->bitstream,
1225  (uint16_t *)pkt->data,
1226  (pkt->size + 1) >> 1);
1227 
1228  ret = init_get_bits8(gb, s->bitstream, FFALIGN(pkt->size, 2));
1229  if (ret < 0)
1230  return ret;
1231 
1232  if (get_bits1(gb)) {
1233  frame->pict_type = AV_PICTURE_TYPE_I;
1234  frame->key_frame = 1;
1235  s->moflex = get_bits1(gb);
1236  s->dct_tab_idx = get_bits1(gb);
1237 
1238  ret = setup_qtables(avctx, get_bits(gb, 6));
1239  if (ret < 0)
1240  return ret;
1241 
1242  for (int y = 0; y < avctx->height; y += 16) {
1243  for (int x = 0; x < avctx->width; x += 16) {
1244  ret = decode_macroblock(avctx, frame, x, y, get_bits1(gb));
1245  if (ret < 0)
1246  return ret;
1247  }
1248  }
1249  } else {
1250  MotionXY *motion = s->motion;
1251 
1252  memset(motion, 0, s->motion_size);
1253 
1254  frame->pict_type = AV_PICTURE_TYPE_P;
1255  frame->key_frame = 0;
1256  s->dct_tab_idx = 0;
1257 
1258  ret = setup_qtables(avctx, s->quantizer + get_se_golomb(gb));
1259  if (ret < 0)
1260  return ret;
1261 
1262  for (int y = 0; y < avctx->height; y += 16) {
1263  for (int x = 0; x < avctx->width; x += 16) {
1264  int idx;
1265 
1266  motion[0].x = mid_pred(motion[x / 16 + 1].x, motion[x / 16 + 2].x, motion[x / 16 + 3].x);
1267  motion[0].y = mid_pred(motion[x / 16 + 1].y, motion[x / 16 + 2].y, motion[x / 16 + 3].y);
1268  motion[x / 16 + 2].x = 0;
1269  motion[x / 16 + 2].y = 0;
1270 
1271  idx = get_vlc2(gb, mv_vlc[s->moflex][0].table,
1272  MOBI_MV_VLC_BITS, 1);
1273 
1274  if (idx == 6 || idx == 7) {
1275  ret = decode_macroblock(avctx, frame, x, y, idx == 7);
1276  if (ret < 0)
1277  return ret;
1278  } else {
1279  int flags, idx2;
1280  ret = predict_motion(avctx, 16, 16, idx, x / 16 + 2, x, y);
1281  if (ret < 0)
1282  return ret;
1283  idx2 = get_ue_golomb(gb);
1285  return AVERROR_INVALIDDATA;
1286  flags = pframe_block8x8_coefficients_tab[idx2];
1287 
1288  for (int sy = y; sy < y + 16; sy += 8) {
1289  for (int sx = x; sx < x + 16; sx += 8) {
1290  if (flags & 1)
1291  add_pframe_coefficients(avctx, frame, sx, sy, 8, 0);
1292  flags >>= 1;
1293  }
1294  }
1295 
1296  if (flags & 1)
1297  add_pframe_coefficients(avctx, frame, x >> 1, y >> 1, 8, 1 + !s->moflex);
1298  flags >>= 1;
1299  if (flags & 1)
1300  add_pframe_coefficients(avctx, frame, x >> 1, y >> 1, 8, 2 - !s->moflex);
1301  }
1302  }
1303  }
1304  }
1305 
1306  if (!s->moflex)
1307  avctx->colorspace = AVCOL_SPC_YCGCO;
1308 
1309  s->current_pic = (s->current_pic + 1) % 6;
1310  ret = av_frame_ref(data, frame);
1311  if (ret < 0)
1312  return ret;
1313  *got_frame = 1;
1314 
1315  return 0;
1316 }
1317 
1318 static void mobiclip_flush(AVCodecContext *avctx)
1319 {
1320  MobiClipContext *s = avctx->priv_data;
1321 
1322  for (int i = 0; i < 6; i++)
1323  av_frame_unref(s->pic[i]);
1324 }
1325 
1327 {
1328  MobiClipContext *s = avctx->priv_data;
1329 
1330  av_freep(&s->bitstream);
1331  s->bitstream_size = 0;
1332  av_freep(&s->motion);
1333  s->motion_size = 0;
1334 
1335  for (int i = 0; i < 6; i++) {
1336  av_frame_free(&s->pic[i]);
1337  }
1338 
1339  return 0;
1340 }
1341 
1343  .name = "mobiclip",
1344  .long_name = NULL_IF_CONFIG_SMALL("MobiClip Video"),
1345  .type = AVMEDIA_TYPE_VIDEO,
1346  .id = AV_CODEC_ID_MOBICLIP,
1347  .priv_data_size = sizeof(MobiClipContext),
1348  .init = mobiclip_init,
1350  .flush = mobiclip_flush,
1351  .close = mobiclip_close,
1352  .capabilities = AV_CODEC_CAP_DR1,
1354 };
#define FF_CODEC_CAP_INIT_CLEANUP
The codec allows calling the close function for deallocation even if the init function returned a fai...
Definition: internal.h:48
static const uint16_t syms1[]
Definition: mobiclip.c:145
#define NULL
Definition: coverity.c:32
#define AVERROR_INVALIDDATA
Invalid data found when processing input.
Definition: error.h:59
static int shift(int a, int b)
Definition: sonic.c:82
This structure describes decoded (raw) audio or video data.
Definition: frame.h:314
static const uint8_t quant4x4_tab[][16]
Definition: mobiclip.c:44
void(* bswap16_buf)(uint16_t *dst, const uint16_t *src, int len)
Definition: bswapdsp.h:26
static int adjust(int x, int size)
Definition: mobiclip.c:514
ptrdiff_t const GLvoid * data
Definition: opengl_enc.c:100
static void flush(AVCodecContext *avctx)
static int predict_motion(AVCodecContext *avctx, int width, int height, int index, int offsetm, int offsetx, int offsety)
Definition: mobiclip.c:1076
static const uint8_t block4x4_coefficients_tab[]
Definition: mobiclip.c:70
static av_cold void mobiclip_init_static(void)
Definition: mobiclip.c:278
static int get_se_golomb(GetBitContext *gb)
read signed exp golomb code.
Definition: golomb.h:241
int linesize
Definition: mobiclip.c:247
static unsigned int get_bits(GetBitContext *s, int n)
Read 1-25 bits.
Definition: get_bits.h:379
AVFrame * pic[6]
Definition: mobiclip.c:255
const char * g
Definition: vf_curves.c:115
static av_cold int init(AVCodecContext *avctx)
Definition: avrndec.c:35
static void block_fill_simple(uint8_t *block, int size, int linesize, int fill)
Definition: mobiclip.c:778
static int get_prediction(AVCodecContext *avctx, int x, int y, int size)
Definition: mobiclip.c:928
int size
Definition: packet.h:364
static int block_sum(const uint8_t *block, int w, int h, int linesize)
Definition: mobiclip.c:814
int ay
Definition: mobiclip.c:243
The reader does not expect b to be semantically here and if the code is changed by maybe adding a a division or other the signedness will almost certainly be mistaken To avoid this confusion a new type was SUINT is the C unsigned type but it holds a signed int to use the same example SUINT a
Definition: undefined.txt:36
enum AVPixelFormat pix_fmt
Pixel format, see AV_PIX_FMT_xxx.
Definition: avcodec.h:741
void av_fast_padded_malloc(void *ptr, unsigned int *size, size_t min_size)
Same behaviour av_fast_malloc but the buffer has additional AV_INPUT_BUFFER_PADDING_SIZE at the end w...
Definition: utils.c:72
static av_cold int mobiclip_close(AVCodecContext *avctx)
Definition: mobiclip.c:1326
uint8_t run
Definition: svq3.c:205
static AVPacket pkt
static uint8_t pick_7(BlockXY bxy)
Definition: mobiclip.c:695
static av_always_inline void predict(PredictorState *ps, float *coef, int output_enable)
Definition: aacdec.c:179
AVCodec.
Definition: codec.h:190
static int get_sbits(GetBitContext *s, int n)
Definition: get_bits.h:359
static void decode(AVCodecContext *dec_ctx, AVPacket *pkt, AVFrame *frame, FILE *outfile)
Definition: decode_audio.c:71
static uint8_t half3(int a, int b, int c)
Definition: mobiclip.c:545
void * av_calloc(size_t nmemb, size_t size)
Non-inlined equivalent of av_mallocz_array().
Definition: mem.c:245
static int get_index(int x)
Definition: mobiclip.c:1071
#define av_assert0(cond)
assert() equivalent, that is always enabled.
Definition: avassert.h:37
static VLC rl_vlc[2]
Definition: mobiclip.c:275
#define FF_CODEC_CAP_INIT_THREADSAFE
The codec does not modify any global variables in the init function, allowing to call the init functi...
Definition: internal.h:40
static void idct(int *arr, int size)
Definition: mobiclip.c:369
uint8_t
#define av_cold
Definition: attributes.h:88
AVFrame * av_frame_alloc(void)
Allocate an AVFrame and set its fields to default values.
Definition: frame.c:190
#define MOBI_RL_VLC_BITS
Definition: mobiclip.c:35
static uint8_t pick_left(BlockXY bxy)
Definition: mobiclip.c:557
BswapDSPContext bdsp
Definition: mobiclip.c:272
#define f(width, name)
Definition: cbs_vp9.c:255
Undefined Behavior In the C some operations are like signed integer dereferencing freed accessing outside allocated Undefined Behavior must not occur in a C it is not safe even if the output of undefined operations is unused The unsafety may seem nit picking but Optimizing compilers have in fact optimized code on the assumption that no undefined Behavior occurs Optimizing code based on wrong assumptions can and has in some cases lead to effects beyond the output of computations The signed integer overflow problem in speed critical code Code which is highly optimized and works with signed integers sometimes has the problem that often the output of the computation does not c
Definition: undefined.txt:32
Used by Dirac / VC-2 and H.264 FRext, see ITU-T SG16.
Definition: pixfmt.h:521
int av_frame_ref(AVFrame *dst, const AVFrame *src)
Set up a new reference to the data described by the source frame.
Definition: frame.c:443
GetBitContext gb
Definition: mobiclip.c:262
#define height
uint8_t * data
Definition: packet.h:363
bitstream reader API header.
int ax
Definition: mobiclip.c:243
ptrdiff_t size
Definition: opengl_enc.c:100
#define AVOnce
Definition: thread.h:172
#define FFALIGN(x, a)
Definition: macros.h:48
static const uint8_t pframe_block4x4_coefficients_tab[]
Definition: mobiclip.c:75
static const uint8_t bits0[]
Definition: mobiclip.c:122
#define av_log(a,...)
static const uint8_t mv_bits[2][16][10]
Definition: mobiclip.c:161
#define src
Definition: vp8dsp.c:255
static int get_bits_left(GetBitContext *gb)
Definition: get_bits.h:849
static void mobiclip_flush(AVCodecContext *avctx)
Definition: mobiclip.c:1318
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:194
static int get_ue_golomb(GetBitContext *gb)
Read an unsigned Exp-Golomb code in the range 0 to 8190.
Definition: golomb.h:55
int y
Definition: mobiclip.c:251
void av_frame_free(AVFrame **frame)
Free the frame and any dynamically allocated objects in it, e.g.
Definition: frame.c:203
#define NULL_IF_CONFIG_SMALL(x)
Return NULL if CONFIG_SMALL is true, otherwise the argument without modification. ...
Definition: internal.h:115
int y
Definition: mobiclip.c:244
int ff_reget_buffer(AVCodecContext *avctx, AVFrame *frame, int flags)
Identical in function to ff_get_buffer(), except it reuses the existing buffer if available...
Definition: decode.c:1983
unsigned int pos
Definition: spdifenc.c:410
static int setup_qtables(AVCodecContext *avctx, int quantizer)
Definition: mobiclip.c:331
simple assert() macros that are a bit more flexible than ISO C assert().
const char * name
Name of the codec implementation.
Definition: codec.h:197
int bitstream_size
Definition: mobiclip.c:265
static void read_run_encoding(AVCodecContext *avctx, int *last, int *run, int *level)
Definition: mobiclip.c:406
#define FFMAX(a, b)
Definition: common.h:94
int h
Definition: mobiclip.c:242
static int add_coefficients(AVCodecContext *avctx, AVFrame *frame, int bx, int by, int size, int plane)
Definition: mobiclip.c:419
#define MOBI_MV_VLC_BITS
Definition: mobiclip.c:36
Definition: vlc.h:26
static const uint16_t syms0[]
Definition: mobiclip.c:132
uint8_t pre[32]
Definition: mobiclip.c:268
static uint8_t pick_6(BlockXY bxy)
Definition: mobiclip.c:655
#define b
Definition: input.c:41
enum AVPictureType pict_type
Picture type of the frame.
Definition: frame.h:397
#define FFMIN(a, b)
Definition: common.h:96
static void inverse4(unsigned *rs)
Definition: mobiclip.c:356
#define width
uint8_t * bitstream
Definition: mobiclip.c:264
int width
picture width / height.
Definition: avcodec.h:704
static uint8_t pick_5(BlockXY bxy)
Definition: mobiclip.c:615
static int add_pframe_coefficients(AVCodecContext *avctx, AVFrame *frame, int bx, int by, int size, int plane)
Definition: mobiclip.c:485
these buffered frames must be flushed immediately if a new input produces new the filter must not call request_frame to get more It must just process the frame or queue it The task of requesting more frames is left to the filter s request_frame method or the application If a filter has several the filter must be ready for frames arriving randomly on any input any filter with several inputs will most likely require some kind of queuing mechanism It is perfectly acceptable to have a limited queue and to drop frames when the inputs are too unbalanced request_frame For filters that do not use the this method is called when a frame is wanted on an output For a it should directly call filter_frame on the corresponding output For a if there are queued frames already one of these frames should be pushed If the filter should request a frame on one of its repeatedly until at least one frame has been pushed Return or at least make progress towards producing a frame
#define s(width, name)
Definition: cbs_vp9.c:257
#define INIT_VLC_STATIC_FROM_LENGTHS(vlc, bits, nb_codes, lens, len_wrap,symbols, symbols_wrap, symbols_size,offset, flags, static_size)
Definition: vlc.h:126
static av_always_inline int get_vlc2(GetBitContext *s, VLC_TYPE(*table)[2], int bits, int max_depth)
Parse a vlc code.
Definition: get_bits.h:797
static av_cold int mobiclip_init(AVCodecContext *avctx)
Definition: mobiclip.c:301
static uint8_t pget(BlockXY b)
Definition: mobiclip.c:519
static int decode_macroblock(AVCodecContext *avctx, AVFrame *frame, int x, int y, int predict)
Definition: mobiclip.c:991
static const uint8_t quant8x8_tab[][64]
Definition: mobiclip.c:54
#define FF_ARRAY_ELEMS(a)
static const uint8_t pframe_block8x8_coefficients_tab[]
Definition: mobiclip.c:90
int table_allocated
Definition: vlc.h:29
static const int8_t mv[256][2]
Definition: 4xm.c:78
static int predict_intra(AVCodecContext *avctx, AVFrame *frame, int ax, int ay, int pmode, int add_coeffs, int size, int plane)
Definition: mobiclip.c:828
static const uint8_t zigzag4x4_tab[]
Definition: mobiclip.c:38
#define AV_ONCE_INIT
Definition: thread.h:173
static const uint8_t mv_len[16]
Definition: mobiclip.c:156
Libavcodec external API header.
MotionXY * motion
Definition: mobiclip.c:269
static VLC mv_vlc[2][16]
Definition: mobiclip.c:276
static int get_ue_golomb_31(GetBitContext *gb)
read unsigned exp golomb code, constraint to a max of 31.
Definition: golomb.h:122
int linesize[AV_NUM_DATA_POINTERS]
For video, size in bytes of each picture line.
Definition: frame.h:345
static int init_get_bits8(GetBitContext *s, const uint8_t *buffer, int byte_size)
Initialize GetBitContext.
Definition: get_bits.h:677
main external API structure.
Definition: avcodec.h:531
int x
Definition: mobiclip.c:251
Tag MUST be and< 10hcoeff half pel interpolation filter coefficients, hcoeff[0] are the 2 middle coefficients[1] are the next outer ones and so on, resulting in a filter like:...eff[2], hcoeff[1], hcoeff[0], hcoeff[0], hcoeff[1], hcoeff[2]...the sign of the coefficients is not explicitly stored but alternates after each coeff and coeff[0] is positive, so...,+,-,+,-,+,+,-,+,-,+,...hcoeff[0] is not explicitly stored but found by subtracting the sum of all stored coefficients with signs from 32 hcoeff[0]=32-hcoeff[1]-hcoeff[2]-...a good choice for hcoeff and htaps is htaps=6 hcoeff={40,-10, 2}an alternative which requires more computations at both encoder and decoder side and may or may not be better is htaps=8 hcoeff={42,-14, 6,-2}ref_frames minimum of the number of available reference frames and max_ref_frames for example the first frame after a key frame always has ref_frames=1spatial_decomposition_type wavelet type 0 is a 9/7 symmetric compact integer wavelet 1 is a 5/3 symmetric compact integer wavelet others are reserved stored as delta from last, last is reset to 0 if always_reset||keyframeqlog quality(logarithmic quantizer scale) stored as delta from last, last is reset to 0 if always_reset||keyframemv_scale stored as delta from last, last is reset to 0 if always_reset||keyframe FIXME check that everything works fine if this changes between framesqbias dequantization bias stored as delta from last, last is reset to 0 if always_reset||keyframeblock_max_depth maximum depth of the block tree stored as delta from last, last is reset to 0 if always_reset||keyframequant_table quantization tableHighlevel bitstream structure:==============================--------------------------------------------|Header|--------------------------------------------|------------------------------------|||Block0||||split?||||yes no||||.........intra?||||:Block01:yes no||||:Block02:.................||||:Block03::y DC::ref index:||||:Block04::cb DC::motion x:||||.........:cr DC::motion y:||||.................|||------------------------------------||------------------------------------|||Block1|||...|--------------------------------------------|------------------------------------|||Y subbands||Cb subbands||Cr subbands||||------||------||------|||||LL0||HL0||||LL0||HL0||||LL0||HL0|||||------||------||------||||------||------||------|||||LH0||HH0||||LH0||HH0||||LH0||HH0|||||------||------||------||||------||------||------|||||HL1||LH1||||HL1||LH1||||HL1||LH1|||||------||------||------||||------||------||------|||||HH1||HL2||||HH1||HL2||||HH1||HL2|||||...||...||...|||------------------------------------|--------------------------------------------Decoding process:=================------------|||Subbands|------------||||------------|Intra DC||||LL0 subband prediction------------|\Dequantization-------------------\||Reference frames|\IDWT|--------------|Motion\|||Frame 0||Frame 1||Compensation.OBMC v-------|--------------|--------------.\------> Frame n output Frame Frame<----------------------------------/|...|-------------------Range Coder:============Binary Range Coder:-------------------The implemented range coder is an adapted version based upon"Range encoding: an algorithm for removing redundancy from a digitised message."by G.N.N.Martin.The symbols encoded by the Snow range coder are bits(0|1).The associated probabilities are not fix but change depending on the symbol mix seen so far.bit seen|new state---------+-----------------------------------------------0|256-state_transition_table[256-old_state];1|state_transition_table[old_state];state_transition_table={0, 0, 0, 0, 0, 0, 0, 0, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 190, 191, 192, 194, 194, 195, 196, 197, 198, 199, 200, 201, 202, 202, 204, 205, 206, 207, 208, 209, 209, 210, 211, 212, 213, 215, 215, 216, 217, 218, 219, 220, 220, 222, 223, 224, 225, 226, 227, 227, 229, 229, 230, 231, 232, 234, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 248, 0, 0, 0, 0, 0, 0, 0};FIXME Range Coding of integers:-------------------------FIXME Neighboring Blocks:===================left and top are set to the respective blocks unless they are outside of the image in which case they are set to the Null block top-left is set to the top left block unless it is outside of the image in which case it is set to the left block if this block has no larger parent block or it is at the left side of its parent block and the top right block is not outside of the image then the top right block is used for top-right else the top-left block is used Null block y, cb, cr are 128 level, ref, mx and my are 0 Motion Vector Prediction:=========================1.the motion vectors of all the neighboring blocks are scaled to compensate for the difference of reference frames scaled_mv=(mv *(256 *(current_reference+1)/(mv.reference+1))+128)> the median of the scaled left
Definition: snow.txt:206
static unsigned int get_bits1(GetBitContext *s)
Definition: get_bits.h:498
int qtab[2][64]
Definition: mobiclip.c:267
static const uint8_t block8x8_coefficients_tab[]
Definition: mobiclip.c:80
int index
Definition: gxfenc.c:89
enum AVColorSpace colorspace
YUV colorspace type.
Definition: avcodec.h:1159
int ff_init_vlc_from_lengths(VLC *vlc_arg, int nb_bits, int nb_codes, const int8_t *lens, int lens_wrap, const void *symbols, int symbols_wrap, int symbols_size, int offset, int flags, void *logctx)
Build VLC decoding tables suitable for use with get_vlc2()
Definition: bitstream.c:381
int size
Definition: mobiclip.c:245
const uint8_t ff_zigzag_direct[64]
Definition: mathtables.c:98
#define mid_pred
Definition: mathops.h:97
static int process_block(AVCodecContext *avctx, AVFrame *frame, int x, int y, int pmode, int has_coeffs, int plane)
Definition: mobiclip.c:950
static void block_fill(uint8_t *block, int size, int linesize, int w, int h, int ax, int ay, uint8_t(*pick)(BlockXY bxy))
Definition: mobiclip.c:786
AVCodec ff_mobiclip_decoder
Definition: mobiclip.c:1342
static uint8_t half_horz(BlockXY bxy)
Definition: mobiclip.c:564
static uint8_t pick_above(BlockXY bxy)
Definition: mobiclip.c:550
static const uint8_t mv_syms[2][16][10]
Definition: mobiclip.c:201
void av_frame_unref(AVFrame *frame)
Unreference all the buffers referenced by frame and reset the frame fields.
Definition: frame.c:553
#define flags(name, subs,...)
Definition: cbs_av1.c:561
uint8_t * data[AV_NUM_DATA_POINTERS]
pointer to the picture/channel planes.
Definition: frame.h:328
uint8_t level
Definition: svq3.c:206
uint8_t * block
Definition: mobiclip.c:246
#define avg(a, b, c, d)
int
planar YUV 4:2:0, 12bpp, (1 Cr & Cb sample per 2x2 Y samples)
Definition: pixfmt.h:66
common internal api header.
#define INIT_VLC_USE_NEW_STATIC
Definition: vlc.h:95
static uint8_t pick_8(BlockXY bxy)
Definition: mobiclip.c:727
static int mobiclip_decode(AVCodecContext *avctx, void *data, int *got_frame, AVPacket *pkt)
Definition: mobiclip.c:1210
av_cold void ff_bswapdsp_init(BswapDSPContext *c)
Definition: bswapdsp.c:49
void * priv_data
Definition: avcodec.h:558
static const uint8_t run_residue[2][256]
Definition: mobiclip.c:98
static int ff_thread_once(char *control, void(*routine)(void))
Definition: thread.h:175
VLC_TYPE(* table)[2]
code, bits
Definition: vlc.h:28
int key_frame
1 -> keyframe, 0-> not
Definition: frame.h:392
static uint8_t half(int a, int b)
Definition: mobiclip.c:540
static VLC_TYPE vlc_buf[16716][2]
Definition: clearvideo.c:86
#define av_freep(p)
#define VLC_TYPE
Definition: vlc.h:24
int x
Definition: mobiclip.c:244
int w
Definition: mobiclip.c:242
Filter the word “frame” indicates either a video frame or a group of audio as stored in an AVFrame structure Format for each input and each output the list of supported formats For video that means pixel format For audio that means channel sample they are references to shared objects When the negotiation mechanism computes the intersection of the formats supported at each end of a all references to both lists are replaced with a reference to the intersection And when a single format is eventually chosen for a link amongst the remaining all references to the list are updated That means that if a filter requires that its input and output have the same format amongst a supported all it has to do is use a reference to the same list of formats query_formats can leave some formats unset and return AVERROR(EAGAIN) to cause the negotiation mechanism toagain later.That can be used by filters with complex requirements to use the format negotiated on one link to set the formats supported on another.Frame references ownership and permissions
static uint8_t pick_4(BlockXY bxy)
Definition: mobiclip.c:584
exp golomb vlc stuff
static uint8_t half_vert(BlockXY bxy)
Definition: mobiclip.c:574
static double val(void *priv, double ch)
Definition: aeval.c:76
This structure stores compressed data.
Definition: packet.h:340
#define AV_CODEC_CAP_DR1
Codec uses get_buffer() for allocating buffers and supports custom allocators.
Definition: codec.h:50
for(j=16;j >0;--j)
int i
Definition: input.c:407
Predicted.
Definition: avutil.h:275
static uint8_t tmp[11]
Definition: aes_ctr.c:27