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/attributes.h"
27 #include "libavutil/avassert.h"
28 #include "libavutil/mem.h"
29 #include "libavutil/thread.h"
30 
31 #include "avcodec.h"
32 #include "bswapdsp.h"
33 #include "codec_internal.h"
34 #include "decode.h"
35 #include "get_bits.h"
36 #include "golomb.h"
37 #include "mathops.h"
38 
39 #define MOBI_RL_VLC_BITS 12
40 #define MOBI_MV_VLC_BITS 6
41 
42 static const uint8_t zigzag4x4_tab[] =
43 {
44  0x00, 0x04, 0x01, 0x02, 0x05, 0x08, 0x0C, 0x09, 0x06, 0x03, 0x07, 0x0A,
45  0x0D, 0x0E, 0x0B, 0x0F
46 };
47 
48 static const uint8_t quant4x4_tab[][16] =
49 {
50  { 10, 13, 13, 10, 16, 10, 13, 13, 13, 13, 16, 10, 16, 13, 13, 16 },
51  { 11, 14, 14, 11, 18, 11, 14, 14, 14, 14, 18, 11, 18, 14, 14, 18 },
52  { 13, 16, 16, 13, 20, 13, 16, 16, 16, 16, 20, 13, 20, 16, 16, 20 },
53  { 14, 18, 18, 14, 23, 14, 18, 18, 18, 18, 23, 14, 23, 18, 18, 23 },
54  { 16, 20, 20, 16, 25, 16, 20, 20, 20, 20, 25, 16, 25, 20, 20, 25 },
55  { 18, 23, 23, 18, 29, 18, 23, 23, 23, 23, 29, 18, 29, 23, 23, 29 },
56 };
57 
58 static const uint8_t quant8x8_tab[][64] =
59 {
60  { 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,
61  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,},
62  { 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,
63  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,},
64  { 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,
65  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,},
66  { 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,
67  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,},
68  { 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,
69  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,},
70  { 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,
71  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,},
72 };
73 
74 static const uint8_t block4x4_coefficients_tab[] =
75 {
76  15, 0, 2, 1, 4, 8, 12, 3, 11, 13, 14, 7, 10, 5, 9, 6,
77 };
78 
79 static const uint8_t pframe_block4x4_coefficients_tab[] =
80 {
81  0, 4, 1, 8, 2, 12, 3, 5, 10, 15, 7, 13, 14, 11, 9, 6,
82 };
83 
84 static const uint8_t block8x8_coefficients_tab[] =
85 {
86  0x00, 0x1F, 0x3F, 0x0F, 0x08, 0x04, 0x02, 0x01, 0x0B, 0x0E, 0x1B, 0x0D,
87  0x03, 0x07, 0x0C, 0x17, 0x1D, 0x0A, 0x1E, 0x05, 0x10, 0x2F, 0x37, 0x3B,
88  0x13, 0x3D, 0x3E, 0x09, 0x1C, 0x06, 0x15, 0x1A, 0x33, 0x11, 0x12, 0x14,
89  0x18, 0x20, 0x3C, 0x35, 0x19, 0x16, 0x3A, 0x30, 0x31, 0x32, 0x27, 0x34,
90  0x2B, 0x2D, 0x39, 0x38, 0x23, 0x36, 0x2E, 0x21, 0x25, 0x22, 0x24, 0x2C,
91  0x2A, 0x28, 0x29, 0x26,
92 };
93 
94 static const uint8_t pframe_block8x8_coefficients_tab[] =
95 {
96  0x00, 0x0F, 0x04, 0x01, 0x08, 0x02, 0x0C, 0x03, 0x05, 0x0A, 0x0D, 0x07, 0x0E, 0x0B, 0x1F, 0x09,
97  0x06, 0x10, 0x3F, 0x1E, 0x17, 0x1D, 0x1B, 0x1C, 0x13, 0x18, 0x1A, 0x12, 0x11, 0x14, 0x15, 0x20,
98  0x2F, 0x16, 0x19, 0x37, 0x3D, 0x3E, 0x3B, 0x3C, 0x33, 0x35, 0x21, 0x24, 0x22, 0x28, 0x23, 0x2C,
99  0x30, 0x27, 0x2D, 0x25, 0x3A, 0x2B, 0x2E, 0x2A, 0x31, 0x34, 0x38, 0x32, 0x29, 0x26, 0x39, 0x36
100 };
101 
102 static const uint8_t run_residue[2][256] =
103 {
104  {
105  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,
106  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,
107  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,
108  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,
109  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,
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  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,
112  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,
113  },
114  {
115  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,
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  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,
118  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,
119  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,
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  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,
122  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,
123  },
124 };
125 
126 static const uint8_t bits0[] = {
127  9, 11, 11, 11, 11, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10,
128  10, 10, 11, 11, 11, 11, 11, 11, 11, 11, 12, 12, 12, 12, 12,
129  12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 7, 10, 10, 9,
130  9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
131  9, 9, 9, 9, 9, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
132  8, 8, 8, 7, 7, 7, 7, 7, 7, 7, 7, 6, 6, 6, 6,
133  6, 6, 6, 6, 6, 6, 5, 5, 5, 4, 2, 3, 4, 4,
134 };
135 
136 static const uint16_t syms0[] = {
137  0x0, 0x822, 0x803, 0xB, 0xA, 0xB81, 0xB61, 0xB41, 0xB21, 0x122,
138  0x102, 0xE2, 0xC2, 0xA2, 0x63, 0x43, 0x24, 0xC, 0x25, 0x2E1, 0x301,
139  0xBA1, 0xBC1, 0xBE1, 0xC01, 0x26, 0x44, 0x83, 0xA3, 0xC3, 0x142,
140  0x321, 0x341, 0xC21, 0xC41, 0xC61, 0xC81, 0xCA1, 0xCC1, 0xCE1, 0xD01,
141  0x0, 0x9, 0x8, 0xB01, 0xAE1, 0xAC1, 0xAA1, 0xA81, 0xA61, 0xA41, 0xA21,
142  0x802, 0x2C1, 0x2A1, 0x281, 0x261, 0x241, 0x221, 0x201, 0x1E1, 0x82,
143  0x62, 0x7, 0x6, 0xA01, 0x9E1, 0x9C1, 0x9A1, 0x981, 0x961, 0x941, 0x921,
144  0x1C1, 0x1A1, 0x42, 0x23, 0x5, 0x901, 0x8E1, 0x8C1, 0x8A1, 0x181, 0x161,
145  0x141, 0x4, 0x881, 0x861, 0x841, 0x821, 0x121, 0x101, 0xE1, 0xC1, 0x22,
146  0x3, 0xA1, 0x81, 0x61, 0x801, 0x1, 0x21, 0x41, 0x2,
147 };
148 
149 static const uint16_t syms1[] = {
150  0x0, 0x807, 0x806, 0x16, 0x15, 0x842, 0x823, 0x805, 0x1A1, 0xA3, 0x102, 0x83,
151  0x64, 0x44, 0x27, 0x14, 0x13, 0x17, 0x18, 0x28, 0x122, 0x862, 0x882, 0x9E1, 0xA01,
152  0x19, 0x1A, 0x1B, 0x29, 0xC3, 0x2A, 0x45, 0xE3, 0x1C1, 0x808, 0x8A2, 0x8C2, 0xA21,
153  0xA41, 0xA61, 0xA81, 0x0, 0x12, 0x11, 0x9C1, 0x9A1, 0x981, 0x961, 0x941, 0x822, 0x804,
154  0x181, 0x161, 0xE2, 0xC2, 0xA2, 0x63, 0x43, 0x26, 0x25, 0x10, 0x82, 0xF, 0xE, 0xD, 0x901,
155  0x8E1, 0x8C1, 0x803, 0x141, 0x121, 0x101, 0x921, 0x62, 0x24, 0xC, 0xB, 0xA, 0x881, 0x861,
156  0xC1, 0x8A1, 0xE1, 0x42, 0x23, 0x9, 0x802, 0xA1, 0x841, 0x821, 0x81, 0x61, 0x8, 0x7, 0x22,
157  0x6, 0x41, 0x5, 0x4, 0x801, 0x1, 0x2, 0x21, 0x3,
158 };
159 
160 static const uint8_t mv_len[16] =
161 {
162  10, 8, 8, 7, 8, 8, 8, 7, 8, 8, 8, 7, 7, 7, 7, 6,
163 };
164 
165 static const uint8_t mv_bits[2][16][10] =
166 {
167  {
168  { 2, 3, 3, 5, 5, 4, 4, 5, 5, 2 },
169  { 2, 3, 4, 4, 3, 4, 4, 2 },
170  { 3, 4, 4, 2, 4, 4, 3, 2 },
171  { 1, 3, 4, 5, 5, 3, 3 },
172  { 2, 4, 4, 3, 3, 4, 4, 2 },
173  { 2, 3, 4, 4, 4, 4, 3, 2 },
174  { 2, 3, 4, 4, 4, 4, 3, 2 },
175  { 2, 2, 3, 4, 5, 5, 2 },
176  { 2, 3, 4, 4, 3, 4, 4, 2 },
177  { 2, 4, 4, 3, 4, 4, 3, 2 },
178  { 2, 3, 3, 5, 5, 4, 3, 2 },
179  { 2, 3, 4, 4, 3, 3, 2 },
180  { 1, 4, 4, 3, 3, 4, 4 },
181  { 2, 3, 4, 4, 3, 3, 2 },
182  { 2, 3, 4, 4, 3, 3, 2 },
183  { 3, 3, 2, 2, 3, 3 },
184  },
185  {
186  { 3, 4, 5, 5, 3, 5, 6, 6, 4, 1 },
187  { 2, 3, 4, 5, 5, 2, 3, 3 },
188  { 2, 4, 4, 3, 3, 4, 4, 2 },
189  { 1, 4, 4, 3, 4, 4, 3 },
190  { 3, 3, 2, 4, 5, 5, 3, 2 },
191  { 3, 4, 4, 3, 3, 3, 3, 2 },
192  { 1, 3, 3, 4, 4, 4, 5, 5 },
193  { 1, 4, 4, 3, 3, 4, 4 },
194  { 2, 4, 4, 3, 3, 4, 4, 2 },
195  { 1, 3, 3, 4, 4, 4, 5, 5 },
196  { 2, 3, 4, 4, 4, 4, 3, 2 },
197  { 2, 3, 3, 4, 4, 3, 2 },
198  { 1, 4, 4, 3, 3, 4, 4 },
199  { 1, 4, 4, 3, 3, 4, 4 },
200  { 2, 3, 3, 4, 4, 3, 2 },
201  { 2, 3, 3, 3, 3, 2 },
202  }
203 };
204 
205 static const uint8_t mv_syms[2][16][10] =
206 {
207  {
208  { 1, 8, 9, 4, 3, 2, 7, 5, 6, 0 },
209  { 0, 9, 5, 4, 2, 3, 8, 1 },
210  { 3, 9, 5, 0, 4, 8, 2, 1 },
211  { 1, 3, 4, 8, 5, 2, 0 },
212  { 0, 5, 4, 8, 2, 3, 9, 1 },
213  { 0, 3, 5, 9, 4, 8, 2, 1 },
214  { 0, 3, 9, 5, 8, 4, 2, 1 },
215  { 0, 2, 3, 4, 8, 5, 1 },
216  { 0, 3, 8, 4, 2, 5, 9, 1 },
217  { 2, 8, 9, 3, 5, 4, 0, 1 },
218  { 0, 4, 3, 8, 9, 5, 2, 1 },
219  { 0, 4, 8, 5, 3, 2, 1 },
220  { 1, 9, 4, 2, 0, 5, 3 },
221  { 2, 4, 9, 5, 3, 0, 1 },
222  { 0, 4, 9, 5, 3, 2, 1 },
223  { 5, 4, 1, 0, 3, 2 },
224  },
225  {
226  { 8, 2, 3, 6, 1, 7, 5, 4, 9, 0 },
227  { 9, 2, 3, 5, 4, 1, 8, 0 },
228  { 0, 5, 4, 2, 9, 3, 8, 1 },
229  { 1, 5, 4, 2, 8, 3, 0 },
230  { 2, 9, 8, 3, 5, 4, 0, 1 },
231  { 3, 5, 4, 2, 9, 8, 0, 1 },
232  { 1, 2, 0, 9, 8, 3, 5, 4 },
233  { 1, 8, 5, 2, 0, 4, 3 },
234  { 0, 5, 4, 2, 8, 3, 9, 1 },
235  { 1, 2, 0, 9, 8, 3, 5, 4 },
236  { 0, 3, 9, 8, 5, 4, 2, 1 },
237  { 0, 4, 3, 8, 5, 2, 1 },
238  { 1, 5, 4, 2, 0, 9, 3 },
239  { 1, 9, 5, 2, 0, 4, 3 },
240  { 0, 5, 3, 9, 4, 2, 1 },
241  { 0, 4, 5, 3, 2, 1 },
242  }
243 };
244 
245 typedef struct BlockXY {
246  int w, h;
247  int ax, ay;
248  int x, y;
249  int size;
250  uint8_t *block;
251  int linesize;
252 } BlockXY;
253 
254 typedef struct MotionXY {
255  int x, y;
256 } MotionXY;
257 
258 typedef struct MobiClipContext {
260 
262  int moflex;
265 
267 
268  uint8_t *bitstream;
270 
271  int qtab[2][64];
272  uint8_t pre[32];
275 
278 
279 static const VLCElem *rl_vlc[2];
280 static const VLCElem *mv_vlc[2][16];
281 
282 static av_cold void mobiclip_init_static(void)
283 {
284  static VLCElem vlc_buf[(2 << MOBI_RL_VLC_BITS) + (2 * 16 << MOBI_MV_VLC_BITS)];
286 
287  for (int i = 0; i < 2; i++) {
288  rl_vlc[i] =
290  bits0, sizeof(*bits0),
291  i ? syms1 : syms0, sizeof(*syms0), sizeof(*syms0),
292  0, 0);
293  for (int j = 0; j < 16; j++) {
294  mv_vlc[i][j] =
296  mv_bits[i][j], sizeof(*mv_bits[i][j]),
297  mv_syms[i][j], sizeof(*mv_syms[i][j]), sizeof(*mv_syms[i][j]),
298  0, 0);
299  }
300  }
301 }
302 
304 {
305  static AVOnce init_static_once = AV_ONCE_INIT;
306  MobiClipContext *s = avctx->priv_data;
307 
308  if (avctx->width & 15 || avctx->height & 15) {
309  av_log(avctx, AV_LOG_ERROR, "width/height not multiple of 16\n");
310  return AVERROR_INVALIDDATA;
311  }
312 
313  ff_bswapdsp_init(&s->bdsp);
314 
315  avctx->pix_fmt = AV_PIX_FMT_YUV420P;
316 
317  s->motion = av_calloc(avctx->width / 16 + 3, sizeof(MotionXY));
318  if (!s->motion)
319  return AVERROR(ENOMEM);
320  s->motion_size = (avctx->width / 16 + 3) * sizeof(MotionXY);
321 
322  for (int i = 0; i < 6; i++) {
323  s->pic[i] = av_frame_alloc();
324  if (!s->pic[i])
325  return AVERROR(ENOMEM);
326  }
327 
328  ff_thread_once(&init_static_once, mobiclip_init_static);
329 
330  return 0;
331 }
332 
333 static int setup_qtables(AVCodecContext *avctx, int64_t quantizer)
334 {
335  MobiClipContext *s = avctx->priv_data;
336  int qx, qy;
337 
338  if (quantizer < 12 || quantizer > 161)
339  return AVERROR_INVALIDDATA;
340 
341  s->quantizer = quantizer;
342 
343  qx = quantizer % 6;
344  qy = quantizer / 6;
345 
346  for (int i = 0; i < 16; i++)
347  s->qtab[0][i] = quant4x4_tab[qx][i] << qy;
348 
349  for (int i = 0; i < 64; i++)
350  s->qtab[1][i] = quant8x8_tab[qx][i] << (qy - 2);
351 
352  for (int i = 0; i < 20; i++)
353  s->pre[i] = 9;
354 
355  return 0;
356 }
357 
358 static void inverse4(unsigned *rs)
359 {
360  unsigned a = rs[0] + rs[2];
361  unsigned b = rs[0] - rs[2];
362  unsigned c = rs[1] + ((int)rs[3] >> 1);
363  unsigned d = ((int)rs[1] >> 1) - rs[3];
364 
365  rs[0] = a + c;
366  rs[1] = b + d;
367  rs[2] = b - d;
368  rs[3] = a - c;
369 }
370 
371 static void idct(int *arr, int size)
372 {
373  int e, f, g, h;
374  unsigned x3, x2, x1, x0;
375  int tmp[4];
376 
377  if (size == 4) {
378  inverse4(arr);
379  return;
380  }
381 
382  tmp[0] = arr[0];
383  tmp[1] = arr[2];
384  tmp[2] = arr[4];
385  tmp[3] = arr[6];
386 
387  inverse4(tmp);
388 
389  e = (unsigned)arr[7] + arr[1] - arr[3] - (arr[3] >> 1);
390  f = (unsigned)arr[7] - arr[1] + arr[5] + (arr[5] >> 1);
391  g = (unsigned)arr[5] - arr[3] - arr[7] - (arr[7] >> 1);
392  h = (unsigned)arr[5] + arr[3] + arr[1] + (arr[1] >> 1);
393  x3 = (unsigned)g + (h >> 2);
394  x2 = (unsigned)e + (f >> 2);
395  x1 = (e >> 2) - (unsigned)f;
396  x0 = (unsigned)h - (g >> 2);
397 
398  arr[0] = tmp[0] + x0;
399  arr[1] = tmp[1] + x1;
400  arr[2] = tmp[2] + x2;
401  arr[3] = tmp[3] + x3;
402  arr[4] = tmp[3] - x3;
403  arr[5] = tmp[2] - x2;
404  arr[6] = tmp[1] - x1;
405  arr[7] = tmp[0] - x0;
406 }
407 
409  int *last, int *run, int *level)
410 {
411  MobiClipContext *s = avctx->priv_data;
412  GetBitContext *gb = &s->gb;
413  int n = get_vlc2(gb, rl_vlc[s->dct_tab_idx], 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], MOBI_MV_VLC_BITS, 1);
1198 
1199  ret = predict_motion(avctx, width, height, idx2,
1200  offsetm, offsetx + i * adjx, offsety + i * adjy);
1201  if (ret < 0)
1202  return ret;
1203  }
1204  }
1205 
1206  return 0;
1207 }
1208 
1209 static int mobiclip_decode(AVCodecContext *avctx, AVFrame *rframe,
1210  int *got_frame, AVPacket *pkt)
1211 {
1212  MobiClipContext *s = avctx->priv_data;
1213  GetBitContext *gb = &s->gb;
1214  AVFrame *frame = s->pic[s->current_pic];
1215  int ret;
1216 
1217  if (avctx->height/16 * (avctx->width/16) * 2 > 8LL*FFALIGN(pkt->size, 2))
1218  return AVERROR_INVALIDDATA;
1219 
1220  av_fast_padded_malloc(&s->bitstream, &s->bitstream_size,
1221  pkt->size);
1222 
1223  if ((ret = ff_reget_buffer(avctx, frame, 0)) < 0)
1224  return ret;
1225 
1226  s->bdsp.bswap16_buf((uint16_t *)s->bitstream,
1227  (uint16_t *)pkt->data,
1228  (pkt->size + 1) >> 1);
1229 
1230  ret = init_get_bits8(gb, s->bitstream, FFALIGN(pkt->size, 2));
1231  if (ret < 0)
1232  return ret;
1233 
1234  if (get_bits1(gb)) {
1235  frame->pict_type = AV_PICTURE_TYPE_I;
1236  frame->flags |= AV_FRAME_FLAG_KEY;
1237  s->moflex = get_bits1(gb);
1238  s->dct_tab_idx = get_bits1(gb);
1239 
1240  ret = setup_qtables(avctx, get_bits(gb, 6));
1241  if (ret < 0)
1242  return ret;
1243 
1244  for (int y = 0; y < avctx->height; y += 16) {
1245  for (int x = 0; x < avctx->width; x += 16) {
1246  ret = decode_macroblock(avctx, frame, x, y, get_bits1(gb));
1247  if (ret < 0)
1248  return ret;
1249  }
1250  }
1251  } else {
1252  MotionXY *motion = s->motion;
1253 
1254  memset(motion, 0, s->motion_size);
1255 
1256  frame->pict_type = AV_PICTURE_TYPE_P;
1257  frame->flags &= ~AV_FRAME_FLAG_KEY;
1258  s->dct_tab_idx = 0;
1259 
1260  ret = setup_qtables(avctx, s->quantizer + (int64_t)get_se_golomb(gb));
1261  if (ret < 0)
1262  return ret;
1263 
1264  for (int y = 0; y < avctx->height; y += 16) {
1265  for (int x = 0; x < avctx->width; x += 16) {
1266  int idx;
1267 
1268  motion[0].x = mid_pred(motion[x / 16 + 1].x, motion[x / 16 + 2].x, motion[x / 16 + 3].x);
1269  motion[0].y = mid_pred(motion[x / 16 + 1].y, motion[x / 16 + 2].y, motion[x / 16 + 3].y);
1270  motion[x / 16 + 2].x = 0;
1271  motion[x / 16 + 2].y = 0;
1272 
1273  idx = get_vlc2(gb, mv_vlc[s->moflex][0], MOBI_MV_VLC_BITS, 1);
1274 
1275  if (idx == 6 || idx == 7) {
1276  ret = decode_macroblock(avctx, frame, x, y, idx == 7);
1277  if (ret < 0)
1278  return ret;
1279  } else {
1280  int flags, idx2;
1281  ret = predict_motion(avctx, 16, 16, idx, x / 16 + 2, x, y);
1282  if (ret < 0)
1283  return ret;
1284  idx2 = get_ue_golomb(gb);
1286  return AVERROR_INVALIDDATA;
1288 
1289  for (int sy = y; sy < y + 16; sy += 8) {
1290  for (int sx = x; sx < x + 16; sx += 8) {
1291  if (flags & 1)
1292  add_pframe_coefficients(avctx, frame, sx, sy, 8, 0);
1293  flags >>= 1;
1294  }
1295  }
1296 
1297  if (flags & 1)
1298  add_pframe_coefficients(avctx, frame, x >> 1, y >> 1, 8, 1 + !s->moflex);
1299  flags >>= 1;
1300  if (flags & 1)
1301  add_pframe_coefficients(avctx, frame, x >> 1, y >> 1, 8, 2 - !s->moflex);
1302  }
1303  }
1304  }
1305  }
1306 
1307  if (!s->moflex)
1308  avctx->colorspace = AVCOL_SPC_YCGCO;
1309 
1310  s->current_pic = (s->current_pic + 1) % 6;
1311  ret = av_frame_ref(rframe, frame);
1312  if (ret < 0)
1313  return ret;
1314  *got_frame = 1;
1315 
1316  return 0;
1317 }
1318 
1320 {
1321  MobiClipContext *s = avctx->priv_data;
1322 
1323  for (int i = 0; i < 6; i++)
1324  av_frame_unref(s->pic[i]);
1325 }
1326 
1328 {
1329  MobiClipContext *s = avctx->priv_data;
1330 
1331  av_freep(&s->bitstream);
1332  s->bitstream_size = 0;
1333  av_freep(&s->motion);
1334  s->motion_size = 0;
1335 
1336  for (int i = 0; i < 6; i++) {
1337  av_frame_free(&s->pic[i]);
1338  }
1339 
1340  return 0;
1341 }
1342 
1344  .p.name = "mobiclip",
1345  CODEC_LONG_NAME("MobiClip Video"),
1346  .p.type = AVMEDIA_TYPE_VIDEO,
1347  .p.id = AV_CODEC_ID_MOBICLIP,
1348  .priv_data_size = sizeof(MobiClipContext),
1349  .init = mobiclip_init,
1351  .flush = mobiclip_flush,
1352  .close = mobiclip_close,
1353  .p.capabilities = AV_CODEC_CAP_DR1,
1354  .caps_internal = FF_CODEC_CAP_INIT_CLEANUP,
1355 };
flags
const SwsFlags flags[]
Definition: swscale.c:61
MobiClipContext::dct_tab_idx
int dct_tab_idx
Definition: mobiclip.c:263
bswapdsp.h
level
uint8_t level
Definition: svq3.c:208
av_clip
#define av_clip
Definition: common.h:100
MOBI_RL_VLC_BITS
#define MOBI_RL_VLC_BITS
Definition: mobiclip.c:39
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:689
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:40
MobiClipContext::pre
uint8_t pre[32]
Definition: mobiclip.c:272
AVCodecContext::colorspace
enum AVColorSpace colorspace
YUV colorspace type.
Definition: avcodec.h:659
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:308
pick_left
static uint8_t pick_left(BlockXY bxy)
Definition: mobiclip.c:557
int64_t
long long int64_t
Definition: coverity.c:34
mv
static const int8_t mv[256][2]
Definition: 4xm.c:81
block_sum
static int block_sum(const uint8_t *block, int w, int h, int linesize)
Definition: mobiclip.c:814
setup_qtables
static int setup_qtables(AVCodecContext *avctx, int64_t quantizer)
Definition: mobiclip.c:333
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:165
av_frame_free
void av_frame_free(AVFrame **frame)
Free the frame and any dynamically allocated objects in it, e.g.
Definition: frame.c:64
quant8x8_tab
static const uint8_t quant8x8_tab[][64]
Definition: mobiclip.c:58
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:427
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:258
MobiClipContext::quantizer
int quantizer
Definition: mobiclip.c:264
AVPacket::data
uint8_t * data
Definition: packet.h:558
pframe_block4x4_coefficients_tab
static const uint8_t pframe_block4x4_coefficients_tab[]
Definition: mobiclip.c:79
MobiClipContext::moflex
int moflex
Definition: mobiclip.c:262
b
#define b
Definition: input.c:42
half
static uint8_t half(int a, int b)
Definition: mobiclip.c:540
predict
static av_always_inline void predict(PredictorState *ps, int *coef, int output_enable)
Definition: aacdec_fixed_prediction.h:77
MobiClipContext::qtab
int qtab[2][64]
Definition: mobiclip.c:271
FFCodec
Definition: codec_internal.h:127
BlockXY::linesize
int linesize
Definition: mobiclip.c:251
FFMAX
#define FFMAX(a, b)
Definition: macros.h:47
MobiClipContext::motion
MotionXY * motion
Definition: mobiclip.c:273
golomb.h
exp golomb vlc stuff
pframe_block8x8_coefficients_tab
static const uint8_t pframe_block8x8_coefficients_tab[]
Definition: mobiclip.c:94
get_bits
static unsigned int get_bits(GetBitContext *s, int n)
Read 1-25 bits.
Definition: get_bits.h:333
FFCodec::p
AVCodec p
The public AVCodec.
Definition: codec_internal.h:131
mobiclip_flush
static av_cold void mobiclip_flush(AVCodecContext *avctx)
Definition: mobiclip.c:1319
pick_5
static uint8_t pick_5(BlockXY bxy)
Definition: mobiclip.c:615
syms1
static const uint16_t syms1[]
Definition: mobiclip.c:149
GetBitContext
Definition: get_bits.h:109
val
static double val(void *priv, double ch)
Definition: aeval.c:77
MobiClipContext::current_pic
int current_pic
Definition: mobiclip.c:261
av_frame_alloc
AVFrame * av_frame_alloc(void)
Allocate an AVFrame and set its fields to default values.
Definition: frame.c:52
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:60
AV_LOG_ERROR
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:210
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:247
init_get_bits8
static int init_get_bits8(GetBitContext *s, const uint8_t *buffer, int byte_size)
Initialize GetBitContext.
Definition: get_bits.h:539
AV_FRAME_FLAG_KEY
#define AV_FRAME_FLAG_KEY
A flag to mark frames that are keyframes.
Definition: frame.h:642
VLCInitState
For static VLCs, the number of bits can often be hardcoded at each get_vlc2() callsite.
Definition: vlc.h:220
FF_CODEC_DECODE_CB
#define FF_CODEC_DECODE_CB(func)
Definition: codec_internal.h:346
s
#define s(width, name)
Definition: cbs_vp9.c:198
quant4x4_tab
static const uint8_t quant4x4_tab[][16]
Definition: mobiclip.c:48
adjust
static int adjust(int x, int size)
Definition: mobiclip.c:514
g
const char * g
Definition: vf_curves.c:128
BlockXY::block
uint8_t * block
Definition: mobiclip.c:250
av_assert0
#define av_assert0(cond)
assert() equivalent, that is always enabled.
Definition: avassert.h:41
get_sbits
static int get_sbits(GetBitContext *s, int n)
Definition: get_bits.h:318
MotionXY
Definition: mobiclip.c:254
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
state
static struct @522 state
CODEC_LONG_NAME
#define CODEC_LONG_NAME(str)
Definition: codec_internal.h:331
tmp
static uint8_t tmp[40]
Definition: aes_ctr.c:52
rl_vlc
static const VLCElem * rl_vlc[2]
Definition: mobiclip.c:279
mobiclip_close
static av_cold int mobiclip_close(AVCodecContext *avctx)
Definition: mobiclip.c:1327
syms0
static const uint16_t syms0[]
Definition: mobiclip.c:136
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:207
AV_PICTURE_TYPE_I
@ AV_PICTURE_TYPE_I
Intra.
Definition: avutil.h:278
get_bits1
static unsigned int get_bits1(GetBitContext *s)
Definition: get_bits.h:386
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:828
AVCOL_SPC_YCGCO
@ AVCOL_SPC_YCGCO
used by Dirac / VC-2 and H.264 FRext, see ITU-T SG16
Definition: pixfmt.h:699
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:646
AVOnce
#define AVOnce
Definition: thread.h:202
index
int index
Definition: gxfenc.c:90
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:259
f
f
Definition: af_crystalizer.c:122
init
int(* init)(AVBSFContext *ctx)
Definition: dts2pts.c:368
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:160
AVPacket::size
int size
Definition: packet.h:559
height
#define height
Definition: dsp.h:89
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:278
codec_internal.h
shift
static int shift(int a, int b)
Definition: bonk.c:261
dst
uint8_t ptrdiff_t const uint8_t ptrdiff_t int intptr_t intptr_t int int16_t * dst
Definition: dsp.h:87
for
for(k=2;k<=8;++k)
Definition: h264pred_template.c:424
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:248
VLCElem
Definition: vlc.h:32
ff_mobiclip_decoder
const FFCodec ff_mobiclip_decoder
Definition: mobiclip.c:1343
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:249
BlockXY::w
int w
Definition: mobiclip.c:246
run_residue
static const uint8_t run_residue[2][256]
Definition: mobiclip.c:102
predict_motion
static int predict_motion(AVCodecContext *avctx, int width, int height, int index, int offsetm, int offsetx, int offsety)
Definition: mobiclip.c:1076
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
attributes.h
BlockXY::h
int h
Definition: mobiclip.c:246
half_horz
static uint8_t half_horz(BlockXY bxy)
Definition: mobiclip.c:564
MotionXY::x
int x
Definition: mobiclip.c:255
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:256
pick_8
static uint8_t pick_8(BlockXY bxy)
Definition: mobiclip.c:727
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:53
FFMIN
#define FFMIN(a, b)
Definition: macros.h:49
block8x8_coefficients_tab
static const uint8_t block8x8_coefficients_tab[]
Definition: mobiclip.c:84
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:496
AVCodec::name
const char * name
Name of the codec implementation.
Definition: codec.h:179
MobiClipContext::gb
GetBitContext gb
Definition: mobiclip.c:266
pick_6
static uint8_t pick_6(BlockXY bxy)
Definition: mobiclip.c:655
AVCodecContext::height
int height
Definition: avcodec.h:592
AVCodecContext::pix_fmt
enum AVPixelFormat pix_fmt
Pixel format, see AV_PIX_FMT_xxx.
Definition: avcodec.h:631
av_calloc
void * av_calloc(size_t nmemb, size_t size)
Definition: mem.c:264
mobiclip_decode
static int mobiclip_decode(AVCodecContext *avctx, AVFrame *rframe, int *got_frame, AVPacket *pkt)
Definition: mobiclip.c:1209
avcodec.h
ff_zigzag_direct
const uint8_t ff_zigzag_direct[64]
Definition: mathtables.c:137
mid_pred
#define mid_pred
Definition: mathops.h:97
BlockXY::y
int y
Definition: mobiclip.c:248
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:1840
ret
ret
Definition: filter_design.txt:187
bits0
static const uint8_t bits0[]
Definition: mobiclip.c:126
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:265
read_run_encoding
static void read_run_encoding(AVCodecContext *avctx, int *last, int *run, int *level)
Definition: mobiclip.c:408
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:414
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:276
AVCodecContext
main external API structure.
Definition: avcodec.h:431
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
mobiclip_init_static
static av_cold void mobiclip_init_static(void)
Definition: mobiclip.c:282
inverse4
static void inverse4(unsigned *rs)
Definition: mobiclip.c:358
block4x4_coefficients_tab
static const uint8_t block4x4_coefficients_tab[]
Definition: mobiclip.c:74
zigzag4x4_tab
static const uint8_t zigzag4x4_tab[]
Definition: mobiclip.c:42
mv_vlc
static const VLCElem * mv_vlc[2][16]
Definition: mobiclip.c:280
BlockXY
Definition: mobiclip.c:245
av_clip_uint8
#define av_clip_uint8
Definition: common.h:106
mobiclip_init
static av_cold int mobiclip_init(AVCodecContext *avctx)
Definition: mobiclip.c:303
pget
static uint8_t pget(BlockXY b)
Definition: mobiclip.c:519
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:279
AVMEDIA_TYPE_VIDEO
@ AVMEDIA_TYPE_VIDEO
Definition: avutil.h:200
mem.h
MotionXY::y
int y
Definition: mobiclip.c:255
pick_4
static uint8_t pick_4(BlockXY bxy)
Definition: mobiclip.c:584
FFALIGN
#define FFALIGN(x, a)
Definition: macros.h:78
VLC_INIT_STATE
#define VLC_INIT_STATE(_table)
Definition: vlc.h:225
AVPacket
This structure stores compressed data.
Definition: packet.h:535
AVCodecContext::priv_data
void * priv_data
Definition: avcodec.h:458
av_freep
#define av_freep(p)
Definition: tableprint_vlc.h:35
idct
static void idct(int *arr, int size)
Definition: mobiclip.c:371
AVCodecContext::width
int width
picture width / height.
Definition: avcodec.h:592
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:2070
width
#define width
Definition: dsp.h:89
MobiClipContext::motion_size
int motion_size
Definition: mobiclip.c:274
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:268
src
#define src
Definition: vp8dsp.c:248
MobiClipContext::bitstream_size
int bitstream_size
Definition: mobiclip.c:269
mv_syms
static const uint8_t mv_syms[2][16][10]
Definition: mobiclip.c:205
BlockXY::ax
int ax
Definition: mobiclip.c:247