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