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_31(gb);
543 
544  if (idx == 0) {
545  ret = add_coefficients(avctx, frame, bx, by, size, plane);
546  } else if ((unsigned)idx < FF_ARRAY_ELEMS(pframe_block4x4_coefficients_tab)) {
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_31(gb);
1016  if ((unsigned)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  if (mv.x >= INT_MAX || mv.y >= INT_MAX)
1150  return AVERROR_INVALIDDATA;
1151 
1152  motion[offsetm].x = mv.x;
1153  motion[offsetm].y = mv.y;
1154 
1155  for (int i = 0; i < 3; i++) {
1156  int method, src_linesize, dst_linesize;
1157  uint8_t *src, *dst;
1158 
1159  if (i == 1) {
1160  offsetx = offsetx >> 1;
1161  offsety = offsety >> 1;
1162  mv.x = mv.x >> 1;
1163  mv.y = mv.y >> 1;
1164  width = width >> 1;
1165  height = height >> 1;
1166  fwidth = fwidth >> 1;
1167  fheight = fheight >> 1;
1168  }
1169 
1170  av_assert0(s->pic[sidx]);
1171  av_assert0(s->pic[s->current_pic]);
1172  av_assert0(s->pic[s->current_pic]->data[i]);
1173  if (!s->pic[sidx]->data[i])
1174  return AVERROR_INVALIDDATA;
1175 
1176  method = (mv.x & 1) | ((mv.y & 1) << 1);
1177  src_linesize = s->pic[sidx]->linesize[i];
1178  dst_linesize = s->pic[s->current_pic]->linesize[i];
1179  dst = s->pic[s->current_pic]->data[i] + offsetx + offsety * dst_linesize;
1180 
1181  if (offsetx + (mv.x >> 1) < 0 ||
1182  offsety + (mv.y >> 1) < 0 ||
1183  offsetx + width + (mv.x + 1 >> 1) > fwidth ||
1184  offsety + height + (mv.y + 1 >> 1) > fheight)
1185  return AVERROR_INVALIDDATA;
1186 
1187  switch (method) {
1188  case 0:
1189  src = s->pic[sidx]->data[i] + offsetx + (mv.x >> 1) +
1190  (offsety + (mv.y >> 1)) * src_linesize;
1191  for (int y = 0; y < height; y++) {
1192  for (int x = 0; x < width; x++)
1193  dst[x] = src[x];
1194  dst += dst_linesize;
1195  src += src_linesize;
1196  }
1197  break;
1198  case 1:
1199  src = s->pic[sidx]->data[i] + offsetx + (mv.x >> 1) +
1200  (offsety + (mv.y >> 1)) * src_linesize;
1201  for (int y = 0; y < height; y++) {
1202  for (int x = 0; x < width; x++) {
1203  dst[x] = (uint8_t)((src[x] >> 1) + (src[x + 1] >> 1));
1204  }
1205 
1206  dst += dst_linesize;
1207  src += src_linesize;
1208  }
1209  break;
1210  case 2:
1211  src = s->pic[sidx]->data[i] + offsetx + (mv.x >> 1) +
1212  (offsety + (mv.y >> 1)) * src_linesize;
1213  for (int y = 0; y < height; y++) {
1214  for (int x = 0; x < width; x++) {
1215  dst[x] = (uint8_t)((src[x] >> 1) + (src[x + src_linesize] >> 1));
1216  }
1217 
1218  dst += dst_linesize;
1219  src += src_linesize;
1220  }
1221  break;
1222  case 3:
1223  src = s->pic[sidx]->data[i] + offsetx + (mv.x >> 1) +
1224  (offsety + (mv.y >> 1)) * src_linesize;
1225  for (int y = 0; y < height; y++) {
1226  for (int x = 0; x < width; x++) {
1227  dst[x] = (uint8_t)((((src[x] >> 1) + (src[x + 1] >> 1)) >> 1) +
1228  (((src[x + src_linesize] >> 1) + (src[x + 1 + src_linesize] >> 1)) >> 1));
1229  }
1230 
1231  dst += dst_linesize;
1232  src += src_linesize;
1233  }
1234  break;
1235  }
1236  }
1237  } else {
1238  int tidx;
1239  int adjx = index == 8 ? 0 : width / 2;
1240  int adjy = index == 8 ? height / 2 : 0;
1241 
1242  width = width - adjx;
1243  height = height - adjy;
1244  tidx = get_index(height) * 4 + get_index(width);
1245 
1246  for (int i = 0; i < 2; i++) {
1247  int ret, idx2;
1248 
1249  idx2 = get_vlc2(gb, mv_vlc[s->moflex][tidx].table,
1250  MOBI_MV_VLC_BITS, 1);
1251 
1252  ret = predict_motion(avctx, width, height, idx2,
1253  offsetm, offsetx + i * adjx, offsety + i * adjy);
1254  if (ret < 0)
1255  return ret;
1256  }
1257  }
1258 
1259  return 0;
1260 }
1261 
1262 static int mobiclip_decode(AVCodecContext *avctx, void *data,
1263  int *got_frame, AVPacket *pkt)
1264 {
1265  MobiClipContext *s = avctx->priv_data;
1266  GetBitContext *gb = &s->gb;
1267  AVFrame *frame = s->pic[s->current_pic];
1268  int ret;
1269 
1271  pkt->size);
1272 
1273  if ((ret = ff_reget_buffer(avctx, frame, 0)) < 0)
1274  return ret;
1275 
1276  s->bdsp.bswap16_buf((uint16_t *)s->bitstream,
1277  (uint16_t *)pkt->data,
1278  (pkt->size + 1) >> 1);
1279 
1280  ret = init_get_bits8(gb, s->bitstream, FFALIGN(pkt->size, 2));
1281  if (ret < 0)
1282  return ret;
1283 
1284  if (get_bits1(gb)) {
1285  frame->pict_type = AV_PICTURE_TYPE_I;
1286  frame->key_frame = 1;
1287  s->moflex = get_bits1(gb);
1288  s->dct_tab_idx = get_bits1(gb);
1289 
1290  ret = setup_qtables(avctx, get_bits(gb, 6));
1291  if (ret < 0)
1292  return ret;
1293 
1294  for (int y = 0; y < avctx->height; y += 16) {
1295  for (int x = 0; x < avctx->width; x += 16) {
1296  ret = decode_macroblock(avctx, frame, x, y, get_bits1(gb));
1297  if (ret < 0)
1298  return ret;
1299  }
1300  }
1301  } else {
1302  MotionXY *motion = s->motion;
1303 
1304  memset(motion, 0, s->motion_size);
1305 
1306  frame->pict_type = AV_PICTURE_TYPE_P;
1307  frame->key_frame = 0;
1308  s->dct_tab_idx = 0;
1309 
1310  ret = setup_qtables(avctx, s->quantizer + get_se_golomb(gb));
1311  if (ret < 0)
1312  return ret;
1313 
1314  for (int y = 0; y < avctx->height; y += 16) {
1315  for (int x = 0; x < avctx->width; x += 16) {
1316  int idx;
1317 
1318  motion[0].x = mid_pred(motion[x / 16 + 1].x, motion[x / 16 + 2].x, motion[x / 16 + 3].x);
1319  motion[0].y = mid_pred(motion[x / 16 + 1].y, motion[x / 16 + 2].y, motion[x / 16 + 3].y);
1320  motion[x / 16 + 2].x = 0;
1321  motion[x / 16 + 2].y = 0;
1322 
1323  idx = get_vlc2(gb, mv_vlc[s->moflex][0].table,
1324  MOBI_MV_VLC_BITS, 1);
1325 
1326  if (idx == 6 || idx == 7) {
1327  ret = decode_macroblock(avctx, frame, x, y, idx == 7);
1328  if (ret < 0)
1329  return ret;
1330  } else {
1331  int flags, idx2;
1332  ret = predict_motion(avctx, 16, 16, idx, x / 16 + 2, x, y);
1333  if (ret < 0)
1334  return ret;
1335  idx2 = get_ue_golomb(gb);
1337  return AVERROR_INVALIDDATA;
1338  flags = pframe_block8x8_coefficients_tab[idx2];
1339 
1340  for (int sy = y; sy < y + 16; sy += 8) {
1341  for (int sx = x; sx < x + 16; sx += 8) {
1342  if (flags & 1)
1343  add_pframe_coefficients(avctx, frame, sx, sy, 8, 0);
1344  flags >>= 1;
1345  }
1346  }
1347 
1348  if (flags & 1)
1349  add_pframe_coefficients(avctx, frame, x >> 1, y >> 1, 8, 1 + !s->moflex);
1350  flags >>= 1;
1351  if (flags & 1)
1352  add_pframe_coefficients(avctx, frame, x >> 1, y >> 1, 8, 2 - !s->moflex);
1353  }
1354  }
1355  }
1356  }
1357 
1358  if (!s->moflex)
1359  avctx->colorspace = AVCOL_SPC_YCGCO;
1360 
1361  s->current_pic = (s->current_pic + 1) % 6;
1362  ret = av_frame_ref(data, frame);
1363  if (ret < 0)
1364  return ret;
1365  *got_frame = 1;
1366 
1367  return 0;
1368 }
1369 
1370 static void mobiclip_flush(AVCodecContext *avctx)
1371 {
1372  MobiClipContext *s = avctx->priv_data;
1373 
1374  for (int i = 0; i < 6; i++)
1375  av_frame_unref(s->pic[i]);
1376 }
1377 
1379 {
1380  MobiClipContext *s = avctx->priv_data;
1381 
1382  av_freep(&s->bitstream);
1383  s->bitstream_size = 0;
1384  av_freep(&s->motion);
1385  s->motion_size = 0;
1386 
1387  for (int i = 0; i < 6; i++) {
1388  av_frame_free(&s->pic[i]);
1389  }
1390 
1391  return 0;
1392 }
1393 
1395  .name = "mobiclip",
1396  .long_name = NULL_IF_CONFIG_SMALL("MobiClip Video"),
1397  .type = AVMEDIA_TYPE_VIDEO,
1398  .id = AV_CODEC_ID_MOBICLIP,
1399  .priv_data_size = sizeof(MobiClipContext),
1400  .init = mobiclip_init,
1402  .flush = mobiclip_flush,
1403  .close = mobiclip_close,
1404  .capabilities = AV_CODEC_CAP_DR1,
1405  .caps_internal = FF_CODEC_CAP_INIT_CLEANUP,
1406 };
#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:275
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:1378
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:443
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:1370
#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
static int get_ue_golomb_31(GetBitContext *gb)
read unsigned exp golomb code, constraint to a max of 31.
Definition: golomb.h:122
int linesize[AV_NUM_DATA_POINTERS]
For video, size in bytes of each picture line.
Definition: frame.h: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:1394
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:553
#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:1262
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