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