FFmpeg
mobiclip.c
Go to the documentation of this file.
1 /*
2  * MobiClip Video decoder
3  * Copyright (c) 2015-2016 Florian Nouwt
4  * Copyright (c) 2017 Adib Surani
5  * Copyright (c) 2020 Paul B Mahol
6  *
7  * This file is part of FFmpeg.
8  *
9  * FFmpeg is free software; you can redistribute it and/or
10  * modify it under the terms of the GNU Lesser General Public
11  * License as published by the Free Software Foundation; either
12  * version 2.1 of the License, or (at your option) any later version.
13  *
14  * FFmpeg is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17  * Lesser General Public License for more details.
18  *
19  * You should have received a copy of the GNU Lesser General Public
20  * License along with FFmpeg; if not, write to the Free Software
21  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
22  */
23 
24 #include <inttypes.h>
25 
26 #include "libavutil/avassert.h"
27 #include "libavutil/thread.h"
28 
29 #include "avcodec.h"
30 #include "bytestream.h"
31 #include "bswapdsp.h"
32 #include "get_bits.h"
33 #include "golomb.h"
34 #include "internal.h"
35 
36 #define MOBI_RL_VLC_BITS 12
37 #define MOBI_MV_VLC_BITS 6
38 
39 static const uint8_t zigzag4x4_tab[] =
40 {
41  0x00, 0x04, 0x01, 0x02, 0x05, 0x08, 0x0C, 0x09, 0x06, 0x03, 0x07, 0x0A,
42  0x0D, 0x0E, 0x0B, 0x0F
43 };
44 
45 static const uint8_t quant4x4_tab[][16] =
46 {
47  { 10, 13, 13, 10, 16, 10, 13, 13, 13, 13, 16, 10, 16, 13, 13, 16 },
48  { 11, 14, 14, 11, 18, 11, 14, 14, 14, 14, 18, 11, 18, 14, 14, 18 },
49  { 13, 16, 16, 13, 20, 13, 16, 16, 16, 16, 20, 13, 20, 16, 16, 20 },
50  { 14, 18, 18, 14, 23, 14, 18, 18, 18, 18, 23, 14, 23, 18, 18, 23 },
51  { 16, 20, 20, 16, 25, 16, 20, 20, 20, 20, 25, 16, 25, 20, 20, 25 },
52  { 18, 23, 23, 18, 29, 18, 23, 23, 23, 23, 29, 18, 29, 23, 23, 29 },
53 };
54 
55 static const uint8_t quant8x8_tab[][64] =
56 {
57  { 20, 19, 19, 25, 18, 25, 19, 24, 24, 19, 20, 18, 32, 18, 20, 19, 19, 24, 24, 19, 19, 25, 18, 25, 18, 25, 18, 25, 19, 24, 24, 19,
58  19, 24, 24, 19, 18, 32, 18, 20, 18, 32, 18, 24, 24, 19, 19, 24, 24, 18, 25, 18, 25, 18, 19, 24, 24, 19, 18, 32, 18, 24, 24, 18,},
59  { 22, 21, 21, 28, 19, 28, 21, 26, 26, 21, 22, 19, 35, 19, 22, 21, 21, 26, 26, 21, 21, 28, 19, 28, 19, 28, 19, 28, 21, 26, 26, 21,
60  21, 26, 26, 21, 19, 35, 19, 22, 19, 35, 19, 26, 26, 21, 21, 26, 26, 19, 28, 19, 28, 19, 21, 26, 26, 21, 19, 35, 19, 26, 26, 19,},
61  { 26, 24, 24, 33, 23, 33, 24, 31, 31, 24, 26, 23, 42, 23, 26, 24, 24, 31, 31, 24, 24, 33, 23, 33, 23, 33, 23, 33, 24, 31, 31, 24,
62  24, 31, 31, 24, 23, 42, 23, 26, 23, 42, 23, 31, 31, 24, 24, 31, 31, 23, 33, 23, 33, 23, 24, 31, 31, 24, 23, 42, 23, 31, 31, 23,},
63  { 28, 26, 26, 35, 25, 35, 26, 33, 33, 26, 28, 25, 45, 25, 28, 26, 26, 33, 33, 26, 26, 35, 25, 35, 25, 35, 25, 35, 26, 33, 33, 26,
64  26, 33, 33, 26, 25, 45, 25, 28, 25, 45, 25, 33, 33, 26, 26, 33, 33, 25, 35, 25, 35, 25, 26, 33, 33, 26, 25, 45, 25, 33, 33, 25,},
65  { 32, 30, 30, 40, 28, 40, 30, 38, 38, 30, 32, 28, 51, 28, 32, 30, 30, 38, 38, 30, 30, 40, 28, 40, 28, 40, 28, 40, 30, 38, 38, 30,
66  30, 38, 38, 30, 28, 51, 28, 32, 28, 51, 28, 38, 38, 30, 30, 38, 38, 28, 40, 28, 40, 28, 30, 38, 38, 30, 28, 51, 28, 38, 38, 28,},
67  { 36, 34, 34, 46, 32, 46, 34, 43, 43, 34, 36, 32, 58, 32, 36, 34, 34, 43, 43, 34, 34, 46, 32, 46, 32, 46, 32, 46, 34, 43, 43, 34,
68  34, 43, 43, 34, 32, 58, 32, 36, 32, 58, 32, 43, 43, 34, 34, 43, 43, 32, 46, 32, 46, 32, 34, 43, 43, 34, 32, 58, 32, 43, 43, 32,},
69 };
70 
72 {
73  15, 0, 2, 1, 4, 8, 12, 3, 11, 13, 14, 7, 10, 5, 9, 6,
74 };
75 
77 {
78  0, 4, 1, 8, 2, 12, 3, 5, 10, 15, 7, 13, 14, 11, 9, 6,
79 };
80 
82 {
83  0x00, 0x1F, 0x3F, 0x0F, 0x08, 0x04, 0x02, 0x01, 0x0B, 0x0E, 0x1B, 0x0D,
84  0x03, 0x07, 0x0C, 0x17, 0x1D, 0x0A, 0x1E, 0x05, 0x10, 0x2F, 0x37, 0x3B,
85  0x13, 0x3D, 0x3E, 0x09, 0x1C, 0x06, 0x15, 0x1A, 0x33, 0x11, 0x12, 0x14,
86  0x18, 0x20, 0x3C, 0x35, 0x19, 0x16, 0x3A, 0x30, 0x31, 0x32, 0x27, 0x34,
87  0x2B, 0x2D, 0x39, 0x38, 0x23, 0x36, 0x2E, 0x21, 0x25, 0x22, 0x24, 0x2C,
88  0x2A, 0x28, 0x29, 0x26,
89 };
90 
92 {
93  0x00, 0x0F, 0x04, 0x01, 0x08, 0x02, 0x0C, 0x03, 0x05, 0x0A, 0x0D, 0x07, 0x0E, 0x0B, 0x1F, 0x09,
94  0x06, 0x10, 0x3F, 0x1E, 0x17, 0x1D, 0x1B, 0x1C, 0x13, 0x18, 0x1A, 0x12, 0x11, 0x14, 0x15, 0x20,
95  0x2F, 0x16, 0x19, 0x37, 0x3D, 0x3E, 0x3B, 0x3C, 0x33, 0x35, 0x21, 0x24, 0x22, 0x28, 0x23, 0x2C,
96  0x30, 0x27, 0x2D, 0x25, 0x3A, 0x2B, 0x2E, 0x2A, 0x31, 0x34, 0x38, 0x32, 0x29, 0x26, 0x39, 0x36
97 };
98 
99 static const uint8_t run_residue[2][256] =
100 {
101  {
102  12, 6, 4, 3, 3, 3, 3, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0,
103  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
104  3, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
105  1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
106  1, 27, 11, 7, 3, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
107  1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
108  1, 41, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
109  1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
110  },
111  {
112  27, 10, 5, 4, 3, 3, 3, 3, 2, 2, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
113  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
114  8, 3, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
115  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
116  1, 15, 10, 8, 4, 3, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
117  1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
118  1, 21, 7, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
119  1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
120  },
121 };
122 
123 static const uint8_t bits0[] = {
124  9, 11, 11, 11, 11, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10,
125  10, 10, 11, 11, 11, 11, 11, 11, 11, 11, 12, 12, 12, 12, 12,
126  12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 7, 10, 10, 9,
127  9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
128  9, 9, 9, 9, 9, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
129  8, 8, 8, 7, 7, 7, 7, 7, 7, 7, 7, 6, 6, 6, 6,
130  6, 6, 6, 6, 6, 6, 5, 5, 5, 4, 2, 3, 4, 4,
131 };
132 
133 static const uint16_t syms0[] = {
134  0x0, 0x822, 0x803, 0xB, 0xA, 0xB81, 0xB61, 0xB41, 0xB21, 0x122,
135  0x102, 0xE2, 0xC2, 0xA2, 0x63, 0x43, 0x24, 0xC, 0x25, 0x2E1, 0x301,
136  0xBA1, 0xBC1, 0xBE1, 0xC01, 0x26, 0x44, 0x83, 0xA3, 0xC3, 0x142,
137  0x321, 0x341, 0xC21, 0xC41, 0xC61, 0xC81, 0xCA1, 0xCC1, 0xCE1, 0xD01,
138  0x0, 0x9, 0x8, 0xB01, 0xAE1, 0xAC1, 0xAA1, 0xA81, 0xA61, 0xA41, 0xA21,
139  0x802, 0x2C1, 0x2A1, 0x281, 0x261, 0x241, 0x221, 0x201, 0x1E1, 0x82,
140  0x62, 0x7, 0x6, 0xA01, 0x9E1, 0x9C1, 0x9A1, 0x981, 0x961, 0x941, 0x921,
141  0x1C1, 0x1A1, 0x42, 0x23, 0x5, 0x901, 0x8E1, 0x8C1, 0x8A1, 0x181, 0x161,
142  0x141, 0x4, 0x881, 0x861, 0x841, 0x821, 0x121, 0x101, 0xE1, 0xC1, 0x22,
143  0x3, 0xA1, 0x81, 0x61, 0x801, 0x1, 0x21, 0x41, 0x2,
144 };
145 
146 static const uint16_t syms1[] = {
147  0x0, 0x807, 0x806, 0x16, 0x15, 0x842, 0x823, 0x805, 0x1A1, 0xA3, 0x102, 0x83,
148  0x64, 0x44, 0x27, 0x14, 0x13, 0x17, 0x18, 0x28, 0x122, 0x862, 0x882, 0x9E1, 0xA01,
149  0x19, 0x1A, 0x1B, 0x29, 0xC3, 0x2A, 0x45, 0xE3, 0x1C1, 0x808, 0x8A2, 0x8C2, 0xA21,
150  0xA41, 0xA61, 0xA81, 0x0, 0x12, 0x11, 0x9C1, 0x9A1, 0x981, 0x961, 0x941, 0x822, 0x804,
151  0x181, 0x161, 0xE2, 0xC2, 0xA2, 0x63, 0x43, 0x26, 0x25, 0x10, 0x82, 0xF, 0xE, 0xD, 0x901,
152  0x8E1, 0x8C1, 0x803, 0x141, 0x121, 0x101, 0x921, 0x62, 0x24, 0xC, 0xB, 0xA, 0x881, 0x861,
153  0xC1, 0x8A1, 0xE1, 0x42, 0x23, 0x9, 0x802, 0xA1, 0x841, 0x821, 0x81, 0x61, 0x8, 0x7, 0x22,
154  0x6, 0x41, 0x5, 0x4, 0x801, 0x1, 0x2, 0x21, 0x3,
155 };
156 
157 static const uint8_t mv_len[16] =
158 {
159  10, 8, 8, 7, 8, 8, 8, 7, 8, 8, 8, 7, 7, 7, 7, 6,
160 };
161 
162 static const uint8_t mv_bits[2][16][10] =
163 {
164  {
165  { 2, 3, 3, 5, 5, 4, 4, 5, 5, 2 },
166  { 2, 3, 4, 4, 3, 4, 4, 2 },
167  { 3, 4, 4, 2, 4, 4, 3, 2 },
168  { 1, 3, 4, 5, 5, 3, 3 },
169  { 2, 4, 4, 3, 3, 4, 4, 2 },
170  { 2, 3, 4, 4, 4, 4, 3, 2 },
171  { 2, 3, 4, 4, 4, 4, 3, 2 },
172  { 2, 2, 3, 4, 5, 5, 2 },
173  { 2, 3, 4, 4, 3, 4, 4, 2 },
174  { 2, 4, 4, 3, 4, 4, 3, 2 },
175  { 2, 3, 3, 5, 5, 4, 3, 2 },
176  { 2, 3, 4, 4, 3, 3, 2 },
177  { 1, 4, 4, 3, 3, 4, 4 },
178  { 2, 3, 4, 4, 3, 3, 2 },
179  { 2, 3, 4, 4, 3, 3, 2 },
180  { 3, 3, 2, 2, 3, 3 },
181  },
182  {
183  { 3, 4, 5, 5, 3, 5, 6, 6, 4, 1 },
184  { 2, 3, 4, 5, 5, 2, 3, 3 },
185  { 2, 4, 4, 3, 3, 4, 4, 2 },
186  { 1, 4, 4, 3, 4, 4, 3 },
187  { 3, 3, 2, 4, 5, 5, 3, 2 },
188  { 3, 4, 4, 3, 3, 3, 3, 2 },
189  { 1, 3, 3, 4, 4, 4, 5, 5 },
190  { 1, 4, 4, 3, 3, 4, 4 },
191  { 2, 4, 4, 3, 3, 4, 4, 2 },
192  { 1, 3, 3, 4, 4, 4, 5, 5 },
193  { 2, 3, 4, 4, 4, 4, 3, 2 },
194  { 2, 3, 3, 4, 4, 3, 2 },
195  { 1, 4, 4, 3, 3, 4, 4 },
196  { 1, 4, 4, 3, 3, 4, 4 },
197  { 2, 3, 3, 4, 4, 3, 2 },
198  { 2, 3, 3, 3, 3, 2 },
199  }
200 };
201 
202 static const uint8_t mv_syms[2][16][10] =
203 {
204  {
205  { 1, 8, 9, 4, 3, 2, 7, 5, 6, 0 },
206  { 0, 9, 5, 4, 2, 3, 8, 1 },
207  { 3, 9, 5, 0, 4, 8, 2, 1 },
208  { 1, 3, 4, 8, 5, 2, 0 },
209  { 0, 5, 4, 8, 2, 3, 9, 1 },
210  { 0, 3, 5, 9, 4, 8, 2, 1 },
211  { 0, 3, 9, 5, 8, 4, 2, 1 },
212  { 0, 2, 3, 4, 8, 5, 1 },
213  { 0, 3, 8, 4, 2, 5, 9, 1 },
214  { 2, 8, 9, 3, 5, 4, 0, 1 },
215  { 0, 4, 3, 8, 9, 5, 2, 1 },
216  { 0, 4, 8, 5, 3, 2, 1 },
217  { 1, 9, 4, 2, 0, 5, 3 },
218  { 2, 4, 9, 5, 3, 0, 1 },
219  { 0, 4, 9, 5, 3, 2, 1 },
220  { 5, 4, 1, 0, 3, 2 },
221  },
222  {
223  { 8, 2, 3, 6, 1, 7, 5, 4, 9, 0 },
224  { 9, 2, 3, 5, 4, 1, 8, 0 },
225  { 0, 5, 4, 2, 9, 3, 8, 1 },
226  { 1, 5, 4, 2, 8, 3, 0 },
227  { 2, 9, 8, 3, 5, 4, 0, 1 },
228  { 3, 5, 4, 2, 9, 8, 0, 1 },
229  { 1, 2, 0, 9, 8, 3, 5, 4 },
230  { 1, 8, 5, 2, 0, 4, 3 },
231  { 0, 5, 4, 2, 8, 3, 9, 1 },
232  { 1, 2, 0, 9, 8, 3, 5, 4 },
233  { 0, 3, 9, 8, 5, 4, 2, 1 },
234  { 0, 4, 3, 8, 5, 2, 1 },
235  { 1, 5, 4, 2, 0, 9, 3 },
236  { 1, 9, 5, 2, 0, 4, 3 },
237  { 0, 5, 3, 9, 4, 2, 1 },
238  { 0, 4, 5, 3, 2, 1 },
239  }
240 };
241 
242 typedef struct BlockXY {
243  int w, h;
244  int ax, ay;
245  int x, y;
246  int size;
248  int linesize;
249 } BlockXY;
250 
251 typedef struct MotionXY {
252  int x, y;
253 } MotionXY;
254 
255 typedef struct MobiClipContext {
257 
259  int moflex;
262 
264 
267 
268  int qtab[2][64];
272 
275 
276 static VLC rl_vlc[2];
277 static VLC mv_vlc[2][16];
278 
279 static av_cold void mobiclip_init_static(void)
280 {
282  bits0, sizeof(*bits0),
283  syms0, sizeof(*syms0), sizeof(*syms0),
284  0, 0, 1 << MOBI_RL_VLC_BITS);
286  bits0, sizeof(*bits0),
287  syms1, sizeof(*syms1), sizeof(*syms1),
288  0, 0, 1 << MOBI_RL_VLC_BITS);
289  for (int i = 0; i < 2; i++) {
290  static VLC_TYPE vlc_buf[2 * 16 << MOBI_MV_VLC_BITS][2];
291  for (int j = 0; j < 16; j++) {
292  mv_vlc[i][j].table = &vlc_buf[(16 * i + j) << MOBI_MV_VLC_BITS];
295  mv_bits[i][j], sizeof(*mv_bits[i][j]),
296  mv_syms[i][j], sizeof(*mv_syms[i][j]), sizeof(*mv_syms[i][j]),
298  }
299  }
300 }
301 
303 {
304  static AVOnce init_static_once = AV_ONCE_INIT;
305  MobiClipContext *s = avctx->priv_data;
306 
307  if (avctx->width & 15 || avctx->height & 15) {
308  av_log(avctx, AV_LOG_ERROR, "width/height not multiple of 16\n");
309  return AVERROR_INVALIDDATA;
310  }
311 
312  ff_bswapdsp_init(&s->bdsp);
313 
314  avctx->pix_fmt = AV_PIX_FMT_YUV420P;
315 
316  s->motion = av_calloc(avctx->width / 16 + 3, sizeof(MotionXY));
317  if (!s->motion)
318  return AVERROR(ENOMEM);
319  s->motion_size = (avctx->width / 16 + 3) * sizeof(MotionXY);
320 
321  for (int i = 0; i < 6; i++) {
322  s->pic[i] = av_frame_alloc();
323  if (!s->pic[i])
324  return AVERROR(ENOMEM);
325  }
326 
327  ff_thread_once(&init_static_once, mobiclip_init_static);
328 
329  return 0;
330 }
331 
332 static int setup_qtables(AVCodecContext *avctx, int quantizer)
333 {
334  MobiClipContext *s = avctx->priv_data;
335  int qx, qy;
336 
337  if (quantizer < 12 || quantizer > 161)
338  return AVERROR_INVALIDDATA;
339 
340  s->quantizer = quantizer;
341 
342  qx = quantizer % 6;
343  qy = quantizer / 6;
344 
345  for (int i = 0; i < 16; i++)
346  s->qtab[0][i] = quant4x4_tab[qx][i] << qy;
347 
348  for (int i = 0; i < 64; i++)
349  s->qtab[1][i] = quant8x8_tab[qx][i] << (qy - 2);
350 
351  for (int i = 0; i < 20; i++)
352  s->pre[i] = 9;
353 
354  return 0;
355 }
356 
357 static void inverse4(unsigned *rs)
358 {
359  unsigned a = rs[0] + rs[2];
360  unsigned b = rs[0] - rs[2];
361  unsigned c = rs[1] + ((int)rs[3] >> 1);
362  unsigned d = ((int)rs[1] >> 1) - rs[3];
363 
364  rs[0] = a + c;
365  rs[1] = b + d;
366  rs[2] = b - d;
367  rs[3] = a - c;
368 }
369 
370 static void idct(int *arr, int size)
371 {
372  int e, f, g, h;
373  unsigned x3, x2, x1, x0;
374  int tmp[4];
375 
376  if (size == 4) {
377  inverse4(arr);
378  return;
379  }
380 
381  tmp[0] = arr[0];
382  tmp[1] = arr[2];
383  tmp[2] = arr[4];
384  tmp[3] = arr[6];
385 
386  inverse4(tmp);
387 
388  e = (unsigned)arr[7] + arr[1] - arr[3] - (arr[3] >> 1);
389  f = (unsigned)arr[7] - arr[1] + arr[5] + (arr[5] >> 1);
390  g = (unsigned)arr[5] - arr[3] - arr[7] - (arr[7] >> 1);
391  h = (unsigned)arr[5] + arr[3] + arr[1] + (arr[1] >> 1);
392  x3 = (unsigned)g + (h >> 2);
393  x2 = (unsigned)e + (f >> 2);
394  x1 = (e >> 2) - (unsigned)f;
395  x0 = (unsigned)h - (g >> 2);
396 
397  arr[0] = tmp[0] + x0;
398  arr[1] = tmp[1] + x1;
399  arr[2] = tmp[2] + x2;
400  arr[3] = tmp[3] + x3;
401  arr[4] = tmp[3] - x3;
402  arr[5] = tmp[2] - x2;
403  arr[6] = tmp[1] - x1;
404  arr[7] = tmp[0] - x0;
405 }
406 
408  int *last, int *run, int *level)
409 {
410  MobiClipContext *s = avctx->priv_data;
411  GetBitContext *gb = &s->gb;
412  int n = get_vlc2(gb, rl_vlc[s->dct_tab_idx].table,
413  MOBI_RL_VLC_BITS, 1);
414 
415  *last = (n >> 11) == 1;
416  *run = (n >> 5) & 0x3F;
417  *level = n & 0x1F;
418 }
419 
421  int bx, int by, int size, int plane)
422 {
423  MobiClipContext *s = avctx->priv_data;
424  GetBitContext *gb = &s->gb;
425  int mat[64] = { 0 };
426  const uint8_t *ztab = size == 8 ? ff_zigzag_direct : zigzag4x4_tab;
427  const int *qtab = s->qtab[size == 8];
428  uint8_t *dst = frame->data[plane] + by * frame->linesize[plane] + bx;
429 
430  for (int pos = 0; get_bits_left(gb) > 0; pos++) {
431  int qval, last, run, level;
432 
433  read_run_encoding(avctx, &last, &run, &level);
434 
435  if (level) {
436  if (get_bits1(gb))
437  level = -level;
438  } else if (!get_bits1(gb)) {
439  read_run_encoding(avctx, &last, &run, &level);
440  level += run_residue[s->dct_tab_idx][(last ? 64 : 0) + run];
441  if (get_bits1(gb))
442  level = -level;
443  } else if (!get_bits1(gb)) {
444  read_run_encoding(avctx, &last, &run, &level);
445  run += run_residue[s->dct_tab_idx][128 + (last ? 64 : 0) + level];
446  if (get_bits1(gb))
447  level = -level;
448  } else {
449  last = get_bits1(gb);
450  run = get_bits(gb, 6);
451  level = get_sbits(gb, 12);
452  }
453 
454  pos += run;
455  if (pos >= size * size)
456  return AVERROR_INVALIDDATA;
457  qval = qtab[pos];
458  mat[ztab[pos]] = qval *(unsigned)level;
459 
460  if (last)
461  break;
462  }
463 
464  mat[0] += 32;
465  for (int y = 0; y < size; y++)
466  idct(&mat[y * size], size);
467 
468  for (int y = 0; y < size; y++) {
469  for (int x = y + 1; x < size; x++) {
470  int a = mat[x * size + y];
471  int b = mat[y * size + x];
472 
473  mat[y * size + x] = a;
474  mat[x * size + y] = b;
475  }
476 
477  idct(&mat[y * size], size);
478  for (int x = 0; x < size; x++)
479  dst[x] = av_clip_uint8(dst[x] + (mat[y * size + x] >> 6));
480  dst += frame->linesize[plane];
481  }
482 
483  return 0;
484 }
485 
487  int bx, int by, int size, int plane)
488 {
489  MobiClipContext *s = avctx->priv_data;
490  GetBitContext *gb = &s->gb;
491  int ret, idx = get_ue_golomb_31(gb);
492 
493  if (idx == 0) {
494  ret = add_coefficients(avctx, frame, bx, by, size, plane);
495  } else if ((unsigned)idx < FF_ARRAY_ELEMS(pframe_block4x4_coefficients_tab)) {
497 
498  for (int y = by; y < by + 8; y += 4) {
499  for (int x = bx; x < bx + 8; x += 4) {
500  if (flags & 1) {
501  ret = add_coefficients(avctx, frame, x, y, 4, plane);
502  if (ret < 0)
503  return ret;
504  }
505  flags >>= 1;
506  }
507  }
508  } else {
510  }
511 
512  return ret;
513 }
514 
515 static int adjust(int x, int size)
516 {
517  return size == 16 ? (x + 1) >> 1 : x;
518 }
519 
521 {
522  BlockXY ret = b;
523  int x, y;
524 
525  if (b.x == -1 && b.y >= b.size) {
526  ret.x = -1, ret.y = b.size - 1;
527  } else if (b.x >= -1 && b.y >= -1) {
528  ret.x = b.x, ret.y = b.y;
529  } else if (b.x == -1 && b.y == -2) {
530  ret.x = 0, ret.y = -1;
531  } else if (b.x == -2 && b.y == -1) {
532  ret.x = -1, ret.y = 0;
533  }
534 
535  y = av_clip(ret.ay + ret.y, 0, ret.h - 1);
536  x = av_clip(ret.ax + ret.x, 0, ret.w - 1);
537 
538  return ret.block[y * ret.linesize + x];
539 }
540 
541 static uint8_t half(int a, int b)
542 {
543  return ((a + b) + 1) / 2;
544 }
545 
546 static uint8_t half3(int a, int b, int c)
547 {
548  return ((a + b + b + c) * 2 / 4 + 1) / 2;
549 }
550 
552 {
553  bxy.y = bxy.y - 1;
554 
555  return pget(bxy);
556 }
557 
559 {
560  bxy.x = bxy.x - 1;
561 
562  return pget(bxy);
563 }
564 
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 
576 {
577  BlockXY a = bxy, b = bxy, c = bxy;
578 
579  a.y -= 1;
580  c.y += 1;
581 
582  return half3(pget(a), pget(b), pget(c));
583 }
584 
585 static uint8_t pick_4(BlockXY bxy)
586 {
587  int val;
588 
589  if ((bxy.x % 2) == 0) {
590  BlockXY ba, bb;
591  int a, b;
592 
593  ba = bxy;
594  ba.x = -1;
595  ba.y = bxy.y + bxy.x / 2;
596  a = pget(ba);
597 
598  bb = bxy;
599  bb.x = -1;
600  bb.y = bxy.y + bxy.x / 2 + 1;
601  b = pget(bb);
602 
603  val = half(a, b);
604  } else {
605  BlockXY ba;
606 
607  ba = bxy;
608  ba.x = -1;
609  ba.y = bxy.y + bxy.x / 2 + 1;
610  val = half_vert(ba);
611  }
612 
613  return val;
614 }
615 
616 static uint8_t pick_5(BlockXY bxy)
617 {
618  int val;
619 
620  if (bxy.x == 0) {
621  BlockXY a = bxy;
622  BlockXY b = bxy;
623 
624  a.x = -1;
625  a.y -= 1;
626 
627  b.x = -1;
628 
629  val = half(pget(a), pget(b));
630  } else if (bxy.y == 0) {
631  BlockXY a = bxy;
632 
633  a.x -= 2;
634  a.y -= 1;
635 
636  val = half_horz(a);
637  } else if (bxy.x == 1) {
638  BlockXY a = bxy;
639 
640  a.x -= 2;
641  a.y -= 1;
642 
643  val = half_vert(a);
644  } else {
645  BlockXY a = bxy;
646 
647  a.x -= 2;
648  a.y -= 1;
649 
650  val = pget(a);
651  }
652 
653  return val;
654 }
655 
656 static uint8_t pick_6(BlockXY bxy)
657 {
658  int val;
659 
660  if (bxy.y == 0) {
661  BlockXY a = bxy;
662  BlockXY b = bxy;
663 
664  a.x -= 1;
665  a.y = -1;
666 
667  b.y = -1;
668 
669  val = half(pget(a), pget(b));
670  } else if (bxy.x == 0) {
671  BlockXY a = bxy;
672 
673  a.x -= 1;
674  a.y -= 2;
675 
676  val = half_vert(a);
677  } else if (bxy.y == 1) {
678  BlockXY a = bxy;
679 
680  a.x -= 1;
681  a.y -= 2;
682 
683  val = half_horz(a);
684  } else {
685  BlockXY a = bxy;
686 
687  a.x -= 1;
688  a.y -= 2;
689 
690  val = pget(a);
691  }
692 
693  return val;
694 }
695 
696 static uint8_t pick_7(BlockXY bxy)
697 {
698  int clr, acc1, acc2;
699  BlockXY a = bxy;
700 
701  a.x -= 1;
702  a.y -= 1;
703  clr = pget(a);
704  if (bxy.x && bxy.y)
705  return clr;
706 
707  if (bxy.x == 0) {
708  a.x = -1;
709  a.y = bxy.y;
710  } else {
711  a.x = bxy.x - 2;
712  a.y = -1;
713  }
714  acc1 = pget(a);
715 
716  if (bxy.y == 0) {
717  a.x = bxy.x;
718  a.y = -1;
719  } else {
720  a.x = -1;
721  a.y = bxy.y - 2;
722  }
723  acc2 = pget(a);
724 
725  return half3(acc1, clr, acc2);
726 }
727 
728 static uint8_t pick_8(BlockXY bxy)
729 {
730  BlockXY ba = bxy;
731  BlockXY bb = bxy;
732  int val;
733 
734  if (bxy.y == 0) {
735  int a, b;
736 
737  ba.y = -1;
738  a = pget(ba);
739 
740  bb.x += 1;
741  bb.y = -1;
742 
743  b = pget(bb);
744 
745  val = half(a, b);
746  } else if (bxy.y == 1) {
747  ba.x += 1;
748  ba.y -= 2;
749 
750  val = half_horz(ba);
751  } else if (bxy.x < bxy.size - 1) {
752  ba.x += 1;
753  ba.y -= 2;
754 
755  val = pget(ba);
756  } else if (bxy.y % 2 == 0) {
757  int a, b;
758 
759  ba.x = bxy.y / 2 + bxy.size - 1;
760  ba.y = -1;
761  a = pget(ba);
762 
763  bb.x = bxy.y / 2 + bxy.size;
764  bb.y = -1;
765 
766  b = pget(bb);
767 
768  val = half(a, b);
769  } else {
770  ba.x = bxy.y / 2 + bxy.size;
771  ba.y = -1;
772 
773  val = half_horz(ba);
774  }
775 
776  return val;
777 }
778 
779 static void block_fill_simple(uint8_t *block, int size, int linesize, int fill)
780 {
781  for (int y = 0; y < size; y++) {
782  memset(block, fill, size);
783  block += linesize;
784  }
785 }
786 
787 static void block_fill(uint8_t *block, int size, int linesize,
788  int w, int h, int ax, int ay,
789  uint8_t (*pick)(BlockXY bxy))
790 {
791  BlockXY bxy;
792 
793  bxy.size = size;
794  bxy.block = block;
795  bxy.linesize = linesize;
796  bxy.w = w;
797  bxy.h = h;
798  bxy.ay = ay;
799  bxy.ax = ax;
800 
801  for (int y = 0; y < size; y++) {
802  bxy.y = y;
803  for (int x = 0; x < size; x++) {
804  uint8_t val;
805 
806  bxy.x = x;
807 
808  val = pick(bxy);
809 
810  block[ax + x + (ay + y) * linesize] = val;
811  }
812  }
813 }
814 
815 static int block_sum(const uint8_t *block, int w, int h, int linesize)
816 {
817  int sum = 0;
818 
819  for (int y = 0; y < h; y++) {
820  for (int x = 0; x < w; x++) {
821  sum += block[x];
822  }
823  block += linesize;
824  }
825 
826  return sum;
827 }
828 
829 static int predict_intra(AVCodecContext *avctx, AVFrame *frame, int ax, int ay,
830  int pmode, int add_coeffs, int size, int plane)
831 {
832  MobiClipContext *s = avctx->priv_data;
833  GetBitContext *gb = &s->gb;
834  int w = avctx->width >> !!plane, h = avctx->height >> !!plane;
835  int ret = 0;
836 
837  switch (pmode) {
838  case 0:
839  block_fill(frame->data[plane], size, frame->linesize[plane], w, h, ax, ay, pick_above);
840  break;
841  case 1:
842  block_fill(frame->data[plane], size, frame->linesize[plane], w, h, ax, ay, pick_left);
843  break;
844  case 2:
845  {
846  int arr1[16];
847  int arr2[16];
848  uint8_t *top = frame->data[plane] + FFMAX(ay - 1, 0) * frame->linesize[plane] + ax;
849  uint8_t *left = frame->data[plane] + ay * frame->linesize[plane] + FFMAX(ax - 1, 0);
850  int bottommost = frame->data[plane][(ay + size - 1) * frame->linesize[plane] + FFMAX(ax - 1, 0)];
851  int rightmost = frame->data[plane][FFMAX(ay - 1, 0) * frame->linesize[plane] + ax + size - 1];
852  int avg = (bottommost + rightmost + 1) / 2 + 2 * av_clip(get_se_golomb(gb), -(1<<16), 1<<16);
853  int r6 = adjust(avg - bottommost, size);
854  int r9 = adjust(avg - rightmost, size);
855  int shift = adjust(size, size) == 8 ? 3 : 2;
856  uint8_t *block;
857 
858  for (int x = 0; x < size; x++) {
859  int val = top[x];
860  arr1[x] = adjust(((bottommost - val) * (1 << shift)) + r6 * (x + 1), size);
861  }
862 
863  for (int y = 0; y < size; y++) {
864  int val = left[y * frame->linesize[plane]];
865  arr2[y] = adjust(((rightmost - val) * (1 << shift)) + r9 * (y + 1), size);
866  }
867 
868  block = frame->data[plane] + ay * frame->linesize[plane] + ax;
869  for (int y = 0; y < size; y++) {
870  for (int x = 0; x < size; x++) {
871  block[x] = (((top[x] + left[0] + ((arr1[x] * (y + 1) +
872  arr2[y] * (x + 1)) >> 2 * shift)) + 1) / 2) & 0xFF;
873  }
874  block += frame->linesize[plane];
875  left += frame->linesize[plane];
876  }
877  }
878  break;
879  case 3:
880  {
881  uint8_t fill;
882 
883  if (ax == 0 && ay == 0) {
884  fill = 0x80;
885  } else if (ax >= 1 && ay >= 1) {
886  int left = block_sum(frame->data[plane] + ay * frame->linesize[plane] + ax - 1,
887  1, size, frame->linesize[plane]);
888  int top = block_sum(frame->data[plane] + (ay - 1) * frame->linesize[plane] + ax,
889  size, 1, frame->linesize[plane]);
890 
891  fill = ((left + top) * 2 / (2 * size) + 1) / 2;
892  } else if (ax >= 1) {
893  fill = (block_sum(frame->data[plane] + ay * frame->linesize[plane] + ax - 1,
894  1, size, frame->linesize[plane]) * 2 / size + 1) / 2;
895  } else if (ay >= 1) {
896  fill = (block_sum(frame->data[plane] + (ay - 1) * frame->linesize[plane] + ax,
897  size, 1, frame->linesize[plane]) * 2 / size + 1) / 2;
898  } else {
899  return -1;
900  }
901 
902  block_fill_simple(frame->data[plane] + ay * frame->linesize[plane] + ax,
903  size, frame->linesize[plane], fill);
904  }
905  break;
906  case 4:
907  block_fill(frame->data[plane], size, frame->linesize[plane], w, h, ax, ay, pick_4);
908  break;
909  case 5:
910  block_fill(frame->data[plane], size, frame->linesize[plane], w, h, ax, ay, pick_5);
911  break;
912  case 6:
913  block_fill(frame->data[plane], size, frame->linesize[plane], w, h, ax, ay, pick_6);
914  break;
915  case 7:
916  block_fill(frame->data[plane], size, frame->linesize[plane], w, h, ax, ay, pick_7);
917  break;
918  case 8:
919  block_fill(frame->data[plane], size, frame->linesize[plane], w, h, ax, ay, pick_8);
920  break;
921  }
922 
923  if (add_coeffs)
924  ret = add_coefficients(avctx, frame, ax, ay, size, plane);
925 
926  return ret;
927 }
928 
929 static int get_prediction(AVCodecContext *avctx, int x, int y, int size)
930 {
931  MobiClipContext *s = avctx->priv_data;
932  GetBitContext *gb = &s->gb;
933  int index = (y & 0xC) | (x / 4 % 4);
934 
935  uint8_t val = FFMIN(s->pre[index], index % 4 == 0 ? 9 : s->pre[index + 3]);
936  if (val == 9)
937  val = 3;
938 
939  if (!get_bits1(gb)) {
940  int x = get_bits(gb, 3);
941  val = x + (x >= val ? 1 : 0);
942  }
943 
944  s->pre[index + 4] = val;
945  if (size == 8)
946  s->pre[index + 5] = s->pre[index + 8] = s->pre[index + 9] = val;
947 
948  return val;
949 }
950 
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);
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 {
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 
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 
1004 
1005  if (predict) {
1006  ret = process_block(avctx, frame, x, y, -1, flags & 1, 0);
1007  if (ret < 0)
1008  return ret;
1009  flags >>= 1;
1010  ret = process_block(avctx, frame, x + 8, y, -1, flags & 1, 0);
1011  if (ret < 0)
1012  return ret;
1013  flags >>= 1;
1014  ret = process_block(avctx, frame, x, y + 8, -1, flags & 1, 0);
1015  if (ret < 0)
1016  return ret;
1017  flags >>= 1;
1018  ret = process_block(avctx, frame, x + 8, y + 8, -1, flags & 1, 0);
1019  if (ret < 0)
1020  return ret;
1021  flags >>= 1;
1022  } else {
1023  int pmode = get_bits(gb, 3);
1024 
1025  if (pmode == 2) {
1026  ret = predict_intra(avctx, frame, x, y, pmode, 0, 16, 0);
1027  if (ret < 0)
1028  return ret;
1029  pmode = 9;
1030  }
1031 
1032  ret = process_block(avctx, frame, x, y, pmode, flags & 1, 0);
1033  if (ret < 0)
1034  return ret;
1035  flags >>= 1;
1036  ret = process_block(avctx, frame, x + 8, y, pmode, flags & 1, 0);
1037  if (ret < 0)
1038  return ret;
1039  flags >>= 1;
1040  ret = process_block(avctx, frame, x, y + 8, pmode, flags & 1, 0);
1041  if (ret < 0)
1042  return ret;
1043  flags >>= 1;
1044  ret = process_block(avctx, frame, x + 8, y + 8, pmode, flags & 1, 0);
1045  if (ret < 0)
1046  return ret;
1047  flags >>= 1;
1048  }
1049 
1050  pmode_uv = get_bits(gb, 3);
1051  if (pmode_uv == 2) {
1052  ret = predict_intra(avctx, frame, x >> 1, y >> 1, pmode_uv, 0, 8, 1 + !s->moflex);
1053  if (ret < 0)
1054  return ret;
1055  ret = predict_intra(avctx, frame, x >> 1, y >> 1, pmode_uv, 0, 8, 2 - !s->moflex);
1056  if (ret < 0)
1057  return ret;
1058  pmode_uv = 9;
1059  }
1060 
1061  ret = process_block(avctx, frame, x >> 1, y >> 1, pmode_uv, flags & 1, 1 + !s->moflex);
1062  if (ret < 0)
1063  return ret;
1064  flags >>= 1;
1065  ret = process_block(avctx, frame, x >> 1, y >> 1, pmode_uv, flags & 1, 2 - !s->moflex);
1066  if (ret < 0)
1067  return ret;
1068 
1069  return 0;
1070 }
1071 
1072 static int get_index(int x)
1073 {
1074  return x == 16 ? 0 : x == 8 ? 1 : x == 4 ? 2 : x == 2 ? 3 : 0;
1075 }
1076 
1077 static int predict_motion(AVCodecContext *avctx,
1078  int width, int height, int index,
1079  int offsetm, int offsetx, int offsety)
1080 {
1081  MobiClipContext *s = avctx->priv_data;
1082  MotionXY *motion = s->motion;
1083  GetBitContext *gb = &s->gb;
1084  int fheight = avctx->height;
1085  int fwidth = avctx->width;
1086 
1087  if (index <= 5) {
1088  int sidx = -FFMAX(1, index) + s->current_pic;
1089  MotionXY mv = s->motion[0];
1090 
1091  if (sidx < 0)
1092  sidx += 6;
1093 
1094  if (index > 0) {
1095  mv.x = mv.x + (unsigned)get_se_golomb(gb);
1096  mv.y = mv.y + (unsigned)get_se_golomb(gb);
1097  }
1098  if (mv.x >= INT_MAX || mv.y >= INT_MAX)
1099  return AVERROR_INVALIDDATA;
1100 
1101  motion[offsetm].x = mv.x;
1102  motion[offsetm].y = mv.y;
1103 
1104  for (int i = 0; i < 3; i++) {
1105  int method, src_linesize, dst_linesize;
1106  uint8_t *src, *dst;
1107 
1108  if (i == 1) {
1109  offsetx = offsetx >> 1;
1110  offsety = offsety >> 1;
1111  mv.x = mv.x >> 1;
1112  mv.y = mv.y >> 1;
1113  width = width >> 1;
1114  height = height >> 1;
1115  fwidth = fwidth >> 1;
1116  fheight = fheight >> 1;
1117  }
1118 
1119  av_assert0(s->pic[sidx]);
1120  av_assert0(s->pic[s->current_pic]);
1121  av_assert0(s->pic[s->current_pic]->data[i]);
1122  if (!s->pic[sidx]->data[i])
1123  return AVERROR_INVALIDDATA;
1124 
1125  method = (mv.x & 1) | ((mv.y & 1) << 1);
1126  src_linesize = s->pic[sidx]->linesize[i];
1127  dst_linesize = s->pic[s->current_pic]->linesize[i];
1128  dst = s->pic[s->current_pic]->data[i] + offsetx + offsety * dst_linesize;
1129 
1130  if (offsetx + (mv.x >> 1) < 0 ||
1131  offsety + (mv.y >> 1) < 0 ||
1132  offsetx + width + (mv.x + 1 >> 1) > fwidth ||
1133  offsety + height + (mv.y + 1 >> 1) > fheight)
1134  return AVERROR_INVALIDDATA;
1135 
1136  switch (method) {
1137  case 0:
1138  src = s->pic[sidx]->data[i] + offsetx + (mv.x >> 1) +
1139  (offsety + (mv.y >> 1)) * src_linesize;
1140  for (int y = 0; y < height; y++) {
1141  for (int x = 0; x < width; x++)
1142  dst[x] = src[x];
1143  dst += dst_linesize;
1144  src += src_linesize;
1145  }
1146  break;
1147  case 1:
1148  src = s->pic[sidx]->data[i] + offsetx + (mv.x >> 1) +
1149  (offsety + (mv.y >> 1)) * src_linesize;
1150  for (int y = 0; y < height; y++) {
1151  for (int x = 0; x < width; x++) {
1152  dst[x] = (uint8_t)((src[x] >> 1) + (src[x + 1] >> 1));
1153  }
1154 
1155  dst += dst_linesize;
1156  src += src_linesize;
1157  }
1158  break;
1159  case 2:
1160  src = s->pic[sidx]->data[i] + offsetx + (mv.x >> 1) +
1161  (offsety + (mv.y >> 1)) * src_linesize;
1162  for (int y = 0; y < height; y++) {
1163  for (int x = 0; x < width; x++) {
1164  dst[x] = (uint8_t)((src[x] >> 1) + (src[x + src_linesize] >> 1));
1165  }
1166 
1167  dst += dst_linesize;
1168  src += src_linesize;
1169  }
1170  break;
1171  case 3:
1172  src = s->pic[sidx]->data[i] + offsetx + (mv.x >> 1) +
1173  (offsety + (mv.y >> 1)) * src_linesize;
1174  for (int y = 0; y < height; y++) {
1175  for (int x = 0; x < width; x++) {
1176  dst[x] = (uint8_t)((((src[x] >> 1) + (src[x + 1] >> 1)) >> 1) +
1177  (((src[x + src_linesize] >> 1) + (src[x + 1 + src_linesize] >> 1)) >> 1));
1178  }
1179 
1180  dst += dst_linesize;
1181  src += src_linesize;
1182  }
1183  break;
1184  }
1185  }
1186  } else {
1187  int tidx;
1188  int adjx = index == 8 ? 0 : width / 2;
1189  int adjy = index == 8 ? height / 2 : 0;
1190 
1191  width = width - adjx;
1192  height = height - adjy;
1193  tidx = get_index(height) * 4 + get_index(width);
1194 
1195  for (int i = 0; i < 2; i++) {
1196  int ret, idx2;
1197 
1198  idx2 = get_vlc2(gb, mv_vlc[s->moflex][tidx].table,
1199  MOBI_MV_VLC_BITS, 1);
1200 
1201  ret = predict_motion(avctx, width, height, idx2,
1202  offsetm, offsetx + i * adjx, offsety + i * adjy);
1203  if (ret < 0)
1204  return ret;
1205  }
1206  }
1207 
1208  return 0;
1209 }
1210 
1211 static int mobiclip_decode(AVCodecContext *avctx, void *data,
1212  int *got_frame, AVPacket *pkt)
1213 {
1214  MobiClipContext *s = avctx->priv_data;
1215  GetBitContext *gb = &s->gb;
1216  AVFrame *frame = s->pic[s->current_pic];
1217  int ret;
1218 
1219  av_fast_padded_malloc(&s->bitstream, &s->bitstream_size,
1220  pkt->size);
1221 
1222  if ((ret = ff_reget_buffer(avctx, frame, 0)) < 0)
1223  return ret;
1224 
1225  s->bdsp.bswap16_buf((uint16_t *)s->bitstream,
1226  (uint16_t *)pkt->data,
1227  (pkt->size + 1) >> 1);
1228 
1229  ret = init_get_bits8(gb, s->bitstream, FFALIGN(pkt->size, 2));
1230  if (ret < 0)
1231  return ret;
1232 
1233  if (get_bits1(gb)) {
1234  frame->pict_type = AV_PICTURE_TYPE_I;
1235  frame->key_frame = 1;
1236  s->moflex = get_bits1(gb);
1237  s->dct_tab_idx = get_bits1(gb);
1238 
1239  ret = setup_qtables(avctx, get_bits(gb, 6));
1240  if (ret < 0)
1241  return ret;
1242 
1243  for (int y = 0; y < avctx->height; y += 16) {
1244  for (int x = 0; x < avctx->width; x += 16) {
1245  ret = decode_macroblock(avctx, frame, x, y, get_bits1(gb));
1246  if (ret < 0)
1247  return ret;
1248  }
1249  }
1250  } else {
1251  MotionXY *motion = s->motion;
1252 
1253  memset(motion, 0, s->motion_size);
1254 
1255  frame->pict_type = AV_PICTURE_TYPE_P;
1256  frame->key_frame = 0;
1257  s->dct_tab_idx = 0;
1258 
1259  ret = setup_qtables(avctx, s->quantizer + get_se_golomb(gb));
1260  if (ret < 0)
1261  return ret;
1262 
1263  for (int y = 0; y < avctx->height; y += 16) {
1264  for (int x = 0; x < avctx->width; x += 16) {
1265  int idx;
1266 
1267  motion[0].x = mid_pred(motion[x / 16 + 1].x, motion[x / 16 + 2].x, motion[x / 16 + 3].x);
1268  motion[0].y = mid_pred(motion[x / 16 + 1].y, motion[x / 16 + 2].y, motion[x / 16 + 3].y);
1269  motion[x / 16 + 2].x = 0;
1270  motion[x / 16 + 2].y = 0;
1271 
1272  idx = get_vlc2(gb, mv_vlc[s->moflex][0].table,
1273  MOBI_MV_VLC_BITS, 1);
1274 
1275  if (idx == 6 || idx == 7) {
1276  ret = decode_macroblock(avctx, frame, x, y, idx == 7);
1277  if (ret < 0)
1278  return ret;
1279  } else {
1280  int flags, idx2;
1281  ret = predict_motion(avctx, 16, 16, idx, x / 16 + 2, x, y);
1282  if (ret < 0)
1283  return ret;
1284  idx2 = get_ue_golomb(gb);
1286  return AVERROR_INVALIDDATA;
1288 
1289  for (int sy = y; sy < y + 16; sy += 8) {
1290  for (int sx = x; sx < x + 16; sx += 8) {
1291  if (flags & 1)
1292  add_pframe_coefficients(avctx, frame, sx, sy, 8, 0);
1293  flags >>= 1;
1294  }
1295  }
1296 
1297  if (flags & 1)
1298  add_pframe_coefficients(avctx, frame, x >> 1, y >> 1, 8, 1 + !s->moflex);
1299  flags >>= 1;
1300  if (flags & 1)
1301  add_pframe_coefficients(avctx, frame, x >> 1, y >> 1, 8, 2 - !s->moflex);
1302  }
1303  }
1304  }
1305  }
1306 
1307  if (!s->moflex)
1308  avctx->colorspace = AVCOL_SPC_YCGCO;
1309 
1310  s->current_pic = (s->current_pic + 1) % 6;
1311  ret = av_frame_ref(data, frame);
1312  if (ret < 0)
1313  return ret;
1314  *got_frame = 1;
1315 
1316  return 0;
1317 }
1318 
1319 static void mobiclip_flush(AVCodecContext *avctx)
1320 {
1321  MobiClipContext *s = avctx->priv_data;
1322 
1323  for (int i = 0; i < 6; i++)
1324  av_frame_unref(s->pic[i]);
1325 }
1326 
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 
1344  .name = "mobiclip",
1345  .long_name = NULL_IF_CONFIG_SMALL("MobiClip Video"),
1346  .type = AVMEDIA_TYPE_VIDEO,
1347  .id = AV_CODEC_ID_MOBICLIP,
1348  .priv_data_size = sizeof(MobiClipContext),
1349  .init = mobiclip_init,
1351  .flush = mobiclip_flush,
1352  .close = mobiclip_close,
1353  .capabilities = AV_CODEC_CAP_DR1,
1355 };
MobiClipContext::dct_tab_idx
int dct_tab_idx
Definition: mobiclip.c:260
mobiclip_flush
static void mobiclip_flush(AVCodecContext *avctx)
Definition: mobiclip.c:1319
mv_vlc
static VLC mv_vlc[2][16]
Definition: mobiclip.c:277
AVCodec
AVCodec.
Definition: codec.h:197
bswapdsp.h
FF_CODEC_CAP_INIT_THREADSAFE
#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:41
level
uint8_t level
Definition: svq3.c:206
av_clip
#define av_clip
Definition: common.h:122
MOBI_RL_VLC_BITS
#define MOBI_RL_VLC_BITS
Definition: mobiclip.c:36
init
static av_cold int init(AVCodecContext *avctx)
Definition: avrndec.c:31
get_bits_left
static int get_bits_left(GetBitContext *gb)
Definition: get_bits.h:849
AVERROR
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
pick_7
static uint8_t pick_7(BlockXY bxy)
Definition: mobiclip.c:696
MOBI_MV_VLC_BITS
#define MOBI_MV_VLC_BITS
Definition: mobiclip.c:37
MobiClipContext::pre
uint8_t pre[32]
Definition: mobiclip.c:269
AVCodecContext::colorspace
enum AVColorSpace colorspace
YUV colorspace type.
Definition: avcodec.h:1164
thread.h
block_fill_simple
static void block_fill_simple(uint8_t *block, int size, int linesize, int fill)
Definition: mobiclip.c:779
AV_CODEC_ID_MOBICLIP
@ AV_CODEC_ID_MOBICLIP
Definition: codec_id.h:303
pick_left
static uint8_t pick_left(BlockXY bxy)
Definition: mobiclip.c:558
mv
static const int8_t mv[256][2]
Definition: 4xm.c:78
block_sum
static int block_sum(const uint8_t *block, int w, int h, int linesize)
Definition: mobiclip.c:815
block_fill
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:787
mv_bits
static const uint8_t mv_bits[2][16][10]
Definition: mobiclip.c:162
av_frame_free
void av_frame_free(AVFrame **frame)
Free the frame and any dynamically allocated objects in it, e.g.
Definition: frame.c:203
quant8x8_tab
static const uint8_t quant8x8_tab[][64]
Definition: mobiclip.c:55
half3
static uint8_t half3(int a, int b, int c)
Definition: mobiclip.c:546
AVFrame
This structure describes decoded (raw) audio or video data.
Definition: frame.h:318
tmp
static uint8_t tmp[11]
Definition: aes_ctr.c:27
w
uint8_t w
Definition: llviddspenc.c:39
get_ue_golomb
static int get_ue_golomb(GetBitContext *gb)
Read an unsigned Exp-Golomb code in the range 0 to 8190.
Definition: golomb.h:55
MobiClipContext
Definition: mobiclip.c:255
internal.h
MobiClipContext::quantizer
int quantizer
Definition: mobiclip.c:261
AVPacket::data
uint8_t * data
Definition: packet.h:369
pframe_block4x4_coefficients_tab
static const uint8_t pframe_block4x4_coefficients_tab[]
Definition: mobiclip.c:76
MobiClipContext::moflex
int moflex
Definition: mobiclip.c:259
b
#define b
Definition: input.c:41
data
const char data[16]
Definition: mxf.c:142
half
static uint8_t half(int a, int b)
Definition: mobiclip.c:541
MobiClipContext::qtab
int qtab[2][64]
Definition: mobiclip.c:268
get_vlc2
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
BlockXY::linesize
int linesize
Definition: mobiclip.c:248
MobiClipContext::motion
MotionXY * motion
Definition: mobiclip.c:270
golomb.h
exp golomb vlc stuff
pframe_block8x8_coefficients_tab
static const uint8_t pframe_block8x8_coefficients_tab[]
Definition: mobiclip.c:91
get_bits
static unsigned int get_bits(GetBitContext *s, int n)
Read 1-25 bits.
Definition: get_bits.h:379
VLC_TYPE
#define VLC_TYPE
Definition: vlc.h:24
pick_5
static uint8_t pick_5(BlockXY bxy)
Definition: mobiclip.c:616
syms1
static const uint16_t syms1[]
Definition: mobiclip.c:146
GetBitContext
Definition: get_bits.h:61
val
static double val(void *priv, double ch)
Definition: aeval.c:76
MobiClipContext::current_pic
int current_pic
Definition: mobiclip.c:258
ff_init_vlc_from_lengths
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
av_frame_alloc
AVFrame * av_frame_alloc(void)
Allocate an AVFrame and set its fields to default values.
Definition: frame.c:190
avassert.h
ff_thread_once
static int ff_thread_once(char *control, void(*routine)(void))
Definition: thread.h:175
pkt
AVPacket * pkt
Definition: movenc.c:59
AV_LOG_ERROR
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:194
FF_ARRAY_ELEMS
#define FF_ARRAY_ELEMS(a)
Definition: sinewin_tablegen.c:29
av_cold
#define av_cold
Definition: attributes.h:90
BlockXY::ay
int ay
Definition: mobiclip.c:244
init_get_bits8
static int init_get_bits8(GetBitContext *s, const uint8_t *buffer, int byte_size)
Initialize GetBitContext.
Definition: get_bits.h:677
decode
static void decode(AVCodecContext *dec_ctx, AVPacket *pkt, AVFrame *frame, FILE *outfile)
Definition: decode_audio.c:71
width
#define width
s
#define s(width, name)
Definition: cbs_vp9.c:257
quant4x4_tab
static const uint8_t quant4x4_tab[][16]
Definition: mobiclip.c:45
adjust
static int adjust(int x, int size)
Definition: mobiclip.c:515
g
const char * g
Definition: vf_curves.c:117
BlockXY::block
uint8_t * block
Definition: mobiclip.c:247
av_assert0
#define av_assert0(cond)
assert() equivalent, that is always enabled.
Definition: avassert.h:37
get_sbits
static int get_sbits(GetBitContext *s, int n)
Definition: get_bits.h:359
MotionXY
Definition: mobiclip.c:251
get_bits.h
AV_PIX_FMT_YUV420P
@ AV_PIX_FMT_YUV420P
planar YUV 4:2:0, 12bpp, (1 Cr & Cb sample per 2x2 Y samples)
Definition: pixfmt.h:66
f
#define f(width, name)
Definition: cbs_vp9.c:255
get_se_golomb
static int get_se_golomb(GetBitContext *gb)
read signed exp golomb code.
Definition: golomb.h:241
mobiclip_close
static av_cold int mobiclip_close(AVCodecContext *avctx)
Definition: mobiclip.c:1327
syms0
static const uint16_t syms0[]
Definition: mobiclip.c:133
AV_ONCE_INIT
#define AV_ONCE_INIT
Definition: thread.h:173
ff_bswapdsp_init
av_cold void ff_bswapdsp_init(BswapDSPContext *c)
Definition: bswapdsp.c:49
flush
static void flush(AVCodecContext *avctx)
Definition: aacdec_template.c:592
NULL
#define NULL
Definition: coverity.c:32
run
uint8_t run
Definition: svq3.c:205
INIT_VLC_STATIC_FROM_LENGTHS
#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
AV_PICTURE_TYPE_I
@ AV_PICTURE_TYPE_I
Intra.
Definition: avutil.h:274
get_bits1
static unsigned int get_bits1(GetBitContext *s)
Definition: get_bits.h:498
src
#define src
Definition: vp8dsp.c:255
INIT_VLC_USE_NEW_STATIC
#define INIT_VLC_USE_NEW_STATIC
Definition: vlc.h:95
predict_intra
static int predict_intra(AVCodecContext *avctx, AVFrame *frame, int ax, int ay, int pmode, int add_coeffs, int size, int plane)
Definition: mobiclip.c:829
AVCOL_SPC_YCGCO
@ AVCOL_SPC_YCGCO
Used by Dirac / VC-2 and H.264 FRext, see ITU-T SG16.
Definition: pixfmt.h:521
mobiclip_decode
static int mobiclip_decode(AVCodecContext *avctx, void *data, int *got_frame, AVPacket *pkt)
Definition: mobiclip.c:1211
AVOnce
#define AVOnce
Definition: thread.h:172
index
int index
Definition: gxfenc.c:89
c
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
for
for(j=16;j >0;--j)
Definition: h264pred_template.c:469
MobiClipContext::pic
AVFrame * pic[6]
Definition: mobiclip.c:256
VLC::table_allocated
int table_allocated
Definition: vlc.h:29
AV_CODEC_CAP_DR1
#define AV_CODEC_CAP_DR1
Codec uses get_buffer() or get_encode_buffer() for allocating buffers and supports custom allocators.
Definition: codec.h:52
mv_len
static const uint8_t mv_len[16]
Definition: mobiclip.c:157
AVPacket::size
int size
Definition: packet.h:370
NULL_IF_CONFIG_SMALL
#define NULL_IF_CONFIG_SMALL(x)
Return NULL if CONFIG_SMALL is true, otherwise the argument without modification.
Definition: internal.h:117
av_frame_ref
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
get_index
static int get_index(int x)
Definition: mobiclip.c:1072
FFMAX
#define FFMAX(a, b)
Definition: common.h:103
size
int size
Definition: twinvq_data.h:10344
BlockXY::x
int x
Definition: mobiclip.c:245
avg
#define avg(a, b, c, d)
Definition: colorspacedsp_template.c:28
decode_macroblock
static int decode_macroblock(AVCodecContext *avctx, AVFrame *frame, int x, int y, int predict)
Definition: mobiclip.c:992
BlockXY::size
int size
Definition: mobiclip.c:246
BlockXY::w
int w
Definition: mobiclip.c:243
run_residue
static const uint8_t run_residue[2][256]
Definition: mobiclip.c:99
predict_motion
static int predict_motion(AVCodecContext *avctx, int width, int height, int index, int offsetm, int offsetx, int offsety)
Definition: mobiclip.c:1077
height
#define height
FFMIN
#define FFMIN(a, b)
Definition: common.h:105
a
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:41
BlockXY::h
int h
Definition: mobiclip.c:243
half_horz
static uint8_t half_horz(BlockXY bxy)
Definition: mobiclip.c:565
MotionXY::x
int x
Definition: mobiclip.c:252
i
int i
Definition: input.c:407
get_prediction
static int get_prediction(AVCodecContext *avctx, int x, int y, int size)
Definition: mobiclip.c:929
FF_CODEC_CAP_INIT_CLEANUP
#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:49
pick_8
static uint8_t pick_8(BlockXY bxy)
Definition: mobiclip.c:728
predict
static av_always_inline void predict(PredictorState *ps, float *coef, int output_enable)
Definition: aacdec.c:179
av_fast_padded_malloc
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:50
block8x8_coefficients_tab
static const uint8_t block8x8_coefficients_tab[]
Definition: mobiclip.c:81
pick_above
static uint8_t pick_above(BlockXY bxy)
Definition: mobiclip.c:551
uint8_t
uint8_t
Definition: audio_convert.c:194
av_frame_unref
void av_frame_unref(AVFrame *frame)
Unreference all the buffers referenced by frame and reset the frame fields.
Definition: frame.c:553
AVCodec::name
const char * name
Name of the codec implementation.
Definition: codec.h:204
MobiClipContext::gb
GetBitContext gb
Definition: mobiclip.c:263
pick_6
static uint8_t pick_6(BlockXY bxy)
Definition: mobiclip.c:656
AVCodecContext::height
int height
Definition: avcodec.h:709
AVCodecContext::pix_fmt
enum AVPixelFormat pix_fmt
Pixel format, see AV_PIX_FMT_xxx.
Definition: avcodec.h:746
avcodec.h
ff_zigzag_direct
const uint8_t ff_zigzag_direct[64]
Definition: mathtables.c:98
mid_pred
#define mid_pred
Definition: mathops.h:97
BlockXY::y
int y
Definition: mobiclip.c:245
ff_reget_buffer
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:2007
ret
ret
Definition: filter_design.txt:187
bits0
static const uint8_t bits0[]
Definition: mobiclip.c:123
frame
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
Definition: filter_design.txt:264
read_run_encoding
static void read_run_encoding(AVCodecContext *avctx, int *last, int *run, int *level)
Definition: mobiclip.c:407
add_pframe_coefficients
static int add_pframe_coefficients(AVCodecContext *avctx, AVFrame *frame, int bx, int by, int size, int plane)
Definition: mobiclip.c:486
pos
unsigned int pos
Definition: spdifenc.c:412
left
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:386
half_vert
static uint8_t half_vert(BlockXY bxy)
Definition: mobiclip.c:575
MobiClipContext::bdsp
BswapDSPContext bdsp
Definition: mobiclip.c:273
vlc_buf
static VLC_TYPE vlc_buf[16716][2]
Definition: clearvideo.c:86
AVCodecContext
main external API structure.
Definition: avcodec.h:536
get_ue_golomb_31
static int get_ue_golomb_31(GetBitContext *gb)
read unsigned exp golomb code, constraint to a max of 31.
Definition: golomb.h:122
process_block
static int process_block(AVCodecContext *avctx, AVFrame *frame, int x, int y, int pmode, int has_coeffs, int plane)
Definition: mobiclip.c:951
av_calloc
void * av_calloc(size_t nmemb, size_t size)
Non-inlined equivalent of av_mallocz_array().
Definition: mem.c:245
VLC
Definition: vlc.h:26
mobiclip_init_static
static av_cold void mobiclip_init_static(void)
Definition: mobiclip.c:279
setup_qtables
static int setup_qtables(AVCodecContext *avctx, int quantizer)
Definition: mobiclip.c:332
inverse4
static void inverse4(unsigned *rs)
Definition: mobiclip.c:357
block4x4_coefficients_tab
static const uint8_t block4x4_coefficients_tab[]
Definition: mobiclip.c:71
zigzag4x4_tab
static const uint8_t zigzag4x4_tab[]
Definition: mobiclip.c:39
BlockXY
Definition: mobiclip.c:242
av_clip_uint8
#define av_clip_uint8
Definition: common.h:128
mobiclip_init
static av_cold int mobiclip_init(AVCodecContext *avctx)
Definition: mobiclip.c:302
pget
static uint8_t pget(BlockXY b)
Definition: mobiclip.c:520
shift
static int shift(int a, int b)
Definition: sonic.c:82
AV_PICTURE_TYPE_P
@ AV_PICTURE_TYPE_P
Predicted.
Definition: avutil.h:275
AVMEDIA_TYPE_VIDEO
@ AVMEDIA_TYPE_VIDEO
Definition: avutil.h:201
MotionXY::y
int y
Definition: mobiclip.c:252
pick_4
static uint8_t pick_4(BlockXY bxy)
Definition: mobiclip.c:585
FFALIGN
#define FFALIGN(x, a)
Definition: macros.h:48
AVPacket
This structure stores compressed data.
Definition: packet.h:346
AVCodecContext::priv_data
void * priv_data
Definition: avcodec.h:563
av_freep
#define av_freep(p)
Definition: tableprint_vlc.h:35
idct
static void idct(int *arr, int size)
Definition: mobiclip.c:370
AVCodecContext::width
int width
picture width / height.
Definition: avcodec.h:709
bytestream.h
flags
#define flags(name, subs,...)
Definition: cbs_av1.c:561
block
The exact code depends on how similar the blocks are and how related they are to the block
Definition: filter_design.txt:207
av_log
#define av_log(a,...)
Definition: tableprint_vlc.h:28
AVERROR_INVALIDDATA
#define AVERROR_INVALIDDATA
Invalid data found when processing input.
Definition: error.h:59
BswapDSPContext
Definition: bswapdsp.h:24
h
h
Definition: vp9dsp_template.c:2038
ff_mobiclip_decoder
AVCodec ff_mobiclip_decoder
Definition: mobiclip.c:1343
MobiClipContext::motion_size
int motion_size
Definition: mobiclip.c:271
int
int
Definition: ffmpeg_filter.c:170
VLC::table
VLC_TYPE(* table)[2]
code, bits
Definition: vlc.h:28
add_coefficients
static int add_coefficients(AVCodecContext *avctx, AVFrame *frame, int bx, int by, int size, int plane)
Definition: mobiclip.c:420
MobiClipContext::bitstream
uint8_t * bitstream
Definition: mobiclip.c:265
MobiClipContext::bitstream_size
int bitstream_size
Definition: mobiclip.c:266
mv_syms
static const uint8_t mv_syms[2][16][10]
Definition: mobiclip.c:202
BlockXY::ax
int ax
Definition: mobiclip.c:244
rl_vlc
static VLC rl_vlc[2]
Definition: mobiclip.c:276