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