]> git.sesse.net Git - ffmpeg/blob - libavcodec/mobiclip.c
avformat/hlsenc: reindent the code
[ffmpeg] / libavcodec / mobiclip.c
1 /*
2  * MobiClip Video decoder
3  * Copyright (c) 2017 Adib Surani
4  * Copyright (c) 2020 Paul B Mahol
5  *
6  * This file is part of FFmpeg.
7  *
8  * FFmpeg is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU Lesser General Public
10  * License as published by the Free Software Foundation; either
11  * version 2.1 of the License, or (at your option) any later version.
12  *
13  * FFmpeg is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16  * Lesser General Public License for more details.
17  *
18  * You should have received a copy of the GNU Lesser General Public
19  * License along with FFmpeg; if not, write to the Free Software
20  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
21  */
22
23 #include <inttypes.h>
24
25 #include "libavutil/avassert.h"
26 #include "libavutil/thread.h"
27
28 #include "avcodec.h"
29 #include "bytestream.h"
30 #include "bswapdsp.h"
31 #include "get_bits.h"
32 #include "golomb.h"
33 #include "internal.h"
34
35 #define MOBI_RL_VLC_BITS 12
36 #define MOBI_MV_VLC_BITS 6
37
38 static const uint8_t zigzag4x4_tab[] =
39 {
40     0x00, 0x04, 0x01, 0x02, 0x05, 0x08, 0x0C, 0x09, 0x06, 0x03, 0x07, 0x0A,
41     0x0D, 0x0E, 0x0B, 0x0F
42 };
43
44 static const uint8_t quant4x4_tab[][16] =
45 {
46     { 10, 13, 13, 10, 16, 10, 13, 13, 13, 13, 16, 10, 16, 13, 13, 16 },
47     { 11, 14, 14, 11, 18, 11, 14, 14, 14, 14, 18, 11, 18, 14, 14, 18 },
48     { 13, 16, 16, 13, 20, 13, 16, 16, 16, 16, 20, 13, 20, 16, 16, 20 },
49     { 14, 18, 18, 14, 23, 14, 18, 18, 18, 18, 23, 14, 23, 18, 18, 23 },
50     { 16, 20, 20, 16, 25, 16, 20, 20, 20, 20, 25, 16, 25, 20, 20, 25 },
51     { 18, 23, 23, 18, 29, 18, 23, 23, 23, 23, 29, 18, 29, 23, 23, 29 },
52 };
53
54 static const uint8_t quant8x8_tab[][64] =
55 {
56     { 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,
57       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,},
58     { 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,
59       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,},
60     { 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,
61       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,},
62     { 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,
63       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,},
64     { 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,
65       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,},
66     { 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,
67       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,},
68 };
69
70 static const uint8_t block4x4_coefficients_tab[] =
71 {
72     15, 0, 2, 1, 4, 8, 12, 3, 11, 13, 14, 7, 10, 5, 9, 6,
73 };
74
75 static const uint8_t pframe_block4x4_coefficients_tab[] =
76 {
77     0, 4, 1, 8, 2, 12, 3, 5, 10, 15, 7, 13, 14, 11, 9, 6,
78 };
79
80 static const uint8_t block8x8_coefficients_tab[] =
81 {
82     0x00, 0x1F, 0x3F, 0x0F, 0x08, 0x04, 0x02, 0x01, 0x0B, 0x0E, 0x1B, 0x0D,
83     0x03, 0x07, 0x0C, 0x17, 0x1D, 0x0A, 0x1E, 0x05, 0x10, 0x2F, 0x37, 0x3B,
84     0x13, 0x3D, 0x3E, 0x09, 0x1C, 0x06, 0x15, 0x1A, 0x33, 0x11, 0x12, 0x14,
85     0x18, 0x20, 0x3C, 0x35, 0x19, 0x16, 0x3A, 0x30, 0x31, 0x32, 0x27, 0x34,
86     0x2B, 0x2D, 0x39, 0x38, 0x23, 0x36, 0x2E, 0x21, 0x25, 0x22, 0x24, 0x2C,
87     0x2A, 0x28, 0x29, 0x26,
88 };
89
90 static const uint8_t pframe_block8x8_coefficients_tab[] =
91 {
92     0x00, 0x0F, 0x04, 0x01, 0x08, 0x02, 0x0C, 0x03, 0x05, 0x0A, 0x0D, 0x07, 0x0E, 0x0B, 0x1F, 0x09,
93     0x06, 0x10, 0x3F, 0x1E, 0x17, 0x1D, 0x1B, 0x1C, 0x13, 0x18, 0x1A, 0x12, 0x11, 0x14, 0x15, 0x20,
94     0x2F, 0x16, 0x19, 0x37, 0x3D, 0x3E, 0x3B, 0x3C, 0x33, 0x35, 0x21, 0x24, 0x22, 0x28, 0x23, 0x2C,
95     0x30, 0x27, 0x2D, 0x25, 0x3A, 0x2B, 0x2E, 0x2A, 0x31, 0x34, 0x38, 0x32, 0x29, 0x26, 0x39, 0x36
96 };
97
98 static const uint8_t run_residue[2][256] =
99 {
100     {
101        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,
102         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,
103         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,
104         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,
105         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,
106         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,
107         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,
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     },
110     {
111        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,
112         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,
113         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,
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         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,
116         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,
117         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,
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     },
120 };
121
122 static const uint8_t bits0[] = {
123      9, 11, 11, 11, 11, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10,
124     10, 10, 11, 11, 11, 11, 11, 11, 11, 11, 12, 12, 12, 12, 12,
125     12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,  7, 10, 10,  9,
126      9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,
127      9,  9,  9,  9,  9,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,
128      8,  8,  8,  7,  7,  7,  7,  7,  7,  7,  7,  6,  6,  6,  6,
129      6,  6,  6,  6,  6,  6,  5,  5,  5,  4,  2,  3,  4,  4,
130 };
131
132 static const uint16_t syms0[] = {
133     0x0, 0x822, 0x803, 0xB, 0xA, 0xB81, 0xB61, 0xB41, 0xB21, 0x122,
134     0x102, 0xE2, 0xC2, 0xA2, 0x63, 0x43, 0x24, 0xC, 0x25, 0x2E1, 0x301,
135     0xBA1, 0xBC1, 0xBE1, 0xC01, 0x26, 0x44, 0x83, 0xA3, 0xC3, 0x142,
136     0x321, 0x341, 0xC21, 0xC41, 0xC61, 0xC81, 0xCA1, 0xCC1, 0xCE1, 0xD01,
137     0x0, 0x9, 0x8, 0xB01, 0xAE1, 0xAC1, 0xAA1, 0xA81, 0xA61, 0xA41, 0xA21,
138     0x802, 0x2C1, 0x2A1, 0x281, 0x261, 0x241, 0x221, 0x201, 0x1E1, 0x82,
139     0x62, 0x7, 0x6, 0xA01, 0x9E1, 0x9C1, 0x9A1, 0x981, 0x961, 0x941, 0x921,
140     0x1C1, 0x1A1, 0x42, 0x23, 0x5, 0x901, 0x8E1, 0x8C1, 0x8A1, 0x181, 0x161,
141     0x141, 0x4, 0x881, 0x861, 0x841, 0x821, 0x121, 0x101, 0xE1, 0xC1, 0x22,
142     0x3, 0xA1, 0x81, 0x61, 0x801, 0x1, 0x21, 0x41, 0x2,
143 };
144
145 static const uint16_t syms1[] = {
146     0x0, 0x807, 0x806, 0x16, 0x15, 0x842, 0x823, 0x805, 0x1A1, 0xA3, 0x102, 0x83,
147     0x64, 0x44, 0x27, 0x14, 0x13, 0x17, 0x18, 0x28, 0x122, 0x862, 0x882, 0x9E1, 0xA01,
148     0x19, 0x1A, 0x1B, 0x29, 0xC3, 0x2A, 0x45, 0xE3, 0x1C1, 0x808, 0x8A2, 0x8C2, 0xA21,
149     0xA41, 0xA61, 0xA81, 0x0, 0x12, 0x11, 0x9C1, 0x9A1, 0x981, 0x961, 0x941, 0x822, 0x804,
150     0x181, 0x161, 0xE2, 0xC2, 0xA2, 0x63, 0x43, 0x26, 0x25, 0x10, 0x82, 0xF, 0xE, 0xD, 0x901,
151     0x8E1, 0x8C1, 0x803, 0x141, 0x121, 0x101, 0x921, 0x62, 0x24, 0xC, 0xB, 0xA, 0x881, 0x861,
152     0xC1, 0x8A1, 0xE1, 0x42, 0x23, 0x9, 0x802, 0xA1, 0x841, 0x821, 0x81, 0x61, 0x8, 0x7, 0x22,
153     0x6, 0x41, 0x5, 0x4, 0x801, 0x1, 0x2, 0x21, 0x3,
154 };
155
156 static const uint8_t mv_len[16] =
157 {
158     10, 8, 8, 7, 8, 8, 8, 7, 8, 8, 8, 7, 7, 7, 7, 6,
159 };
160
161 static const uint8_t mv_bits[2][16][10] =
162 {
163     {
164         { 2, 3, 3, 5, 5, 4, 4, 5, 5, 2 },
165         { 2, 3, 4, 4, 3, 4, 4, 2 },
166         { 3, 4, 4, 2, 4, 4, 3, 2 },
167         { 1, 3, 4, 5, 5, 3, 3 },
168         { 2, 4, 4, 3, 3, 4, 4, 2 },
169         { 2, 3, 4, 4, 4, 4, 3, 2 },
170         { 2, 3, 4, 4, 4, 4, 3, 2 },
171         { 2, 2, 3, 4, 5, 5, 2 },
172         { 2, 3, 4, 4, 3, 4, 4, 2 },
173         { 2, 4, 4, 3, 4, 4, 3, 2 },
174         { 2, 3, 3, 5, 5, 4, 3, 2 },
175         { 2, 3, 4, 4, 3, 3, 2 },
176         { 1, 4, 4, 3, 3, 4, 4 },
177         { 2, 3, 4, 4, 3, 3, 2 },
178         { 2, 3, 4, 4, 3, 3, 2 },
179         { 3, 3, 2, 2, 3, 3 },
180     },
181     {
182         { 3, 4, 5, 5, 3, 5, 6, 6, 4, 1 },
183         { 2, 3, 4, 5, 5, 2, 3, 3 },
184         { 2, 4, 4, 3, 3, 4, 4, 2 },
185         { 1, 4, 4, 3, 4, 4, 3 },
186         { 3, 3, 2, 4, 5, 5, 3, 2 },
187         { 3, 4, 4, 3, 3, 3, 3, 2 },
188         { 1, 3, 3, 4, 4, 4, 5, 5 },
189         { 1, 4, 4, 3, 3, 4, 4 },
190         { 2, 4, 4, 3, 3, 4, 4, 2 },
191         { 1, 3, 3, 4, 4, 4, 5, 5 },
192         { 2, 3, 4, 4, 4, 4, 3, 2 },
193         { 2, 3, 3, 4, 4, 3, 2 },
194         { 1, 4, 4, 3, 3, 4, 4 },
195         { 1, 4, 4, 3, 3, 4, 4 },
196         { 2, 3, 3, 4, 4, 3, 2 },
197         { 2, 3, 3, 3, 3, 2 },
198     }
199 };
200
201 static const uint8_t mv_syms[2][16][10] =
202 {
203     {
204         { 1, 8, 9, 4, 3, 2, 7, 5, 6, 0 },
205         { 0, 9, 5, 4, 2, 3, 8, 1 },
206         { 3, 9, 5, 0, 4, 8, 2, 1 },
207         { 1, 3, 4, 8, 5, 2, 0 },
208         { 0, 5, 4, 8, 2, 3, 9, 1 },
209         { 0, 3, 5, 9, 4, 8, 2, 1 },
210         { 0, 3, 9, 5, 8, 4, 2, 1 },
211         { 0, 2, 3, 4, 8, 5, 1 },
212         { 0, 3, 8, 4, 2, 5, 9, 1 },
213         { 2, 8, 9, 3, 5, 4, 0, 1 },
214         { 0, 4, 3, 8, 9, 5, 2, 1 },
215         { 0, 4, 8, 5, 3, 2, 1 },
216         { 1, 9, 4, 2, 0, 5, 3 },
217         { 2, 4, 9, 5, 3, 0, 1 },
218         { 0, 4, 9, 5, 3, 2, 1 },
219         { 5, 4, 1, 0, 3, 2 },
220     },
221     {
222         { 8, 2, 3, 6, 1, 7, 5, 4, 9, 0 },
223         { 9, 2, 3, 5, 4, 1, 8, 0 },
224         { 0, 5, 4, 2, 9, 3, 8, 1 },
225         { 1, 5, 4, 2, 8, 3, 0 },
226         { 2, 9, 8, 3, 5, 4, 0, 1 },
227         { 3, 5, 4, 2, 9, 8, 0, 1 },
228         { 1, 2, 0, 9, 8, 3, 5, 4 },
229         { 1, 8, 5, 2, 0, 4, 3 },
230         { 0, 5, 4, 2, 8, 3, 9, 1 },
231         { 1, 2, 0, 9, 8, 3, 5, 4 },
232         { 0, 3, 9, 8, 5, 4, 2, 1 },
233         { 0, 4, 3, 8, 5, 2, 1 },
234         { 1, 5, 4, 2, 0, 9, 3 },
235         { 1, 9, 5, 2, 0, 4, 3 },
236         { 0, 5, 3, 9, 4, 2, 1 },
237         { 0, 4, 5, 3, 2, 1 },
238     }
239 };
240
241 typedef struct BlockXY {
242     int w, h;
243     int ax, ay;
244     int x, y;
245     int size;
246     uint8_t *block;
247     int linesize;
248 } BlockXY;
249
250 typedef struct MotionXY {
251     int x, y;
252 } MotionXY;
253
254 typedef struct MobiClipContext {
255     AVFrame *pic[6];
256
257     int current_pic;
258     int moflex;
259     int dct_tab_idx;
260     int quantizer;
261
262     GetBitContext gb;
263
264     uint8_t *bitstream;
265     int bitstream_size;
266
267     int     qtab[2][64];
268     uint8_t pre[32];
269     MotionXY *motion;
270     int     motion_size;
271
272     BswapDSPContext bdsp;
273 } MobiClipContext;
274
275 static VLC rl_vlc[2];
276 static VLC mv_vlc[2][16];
277
278 static av_cold void mobiclip_init_static(void)
279 {
280     INIT_VLC_STATIC_FROM_LENGTHS(&rl_vlc[0], MOBI_RL_VLC_BITS, 104,
281                                  bits0, sizeof(*bits0),
282                                  syms0, sizeof(*syms0), sizeof(*syms0),
283                                  0, 0, 1 << MOBI_RL_VLC_BITS);
284     INIT_VLC_STATIC_FROM_LENGTHS(&rl_vlc[1], MOBI_RL_VLC_BITS, 104,
285                                  bits0, sizeof(*bits0),
286                                  syms1, sizeof(*syms1), sizeof(*syms1),
287                                  0, 0, 1 << MOBI_RL_VLC_BITS);
288     for (int i = 0; i < 2; i++) {
289         static VLC_TYPE vlc_buf[2 * 16 << MOBI_MV_VLC_BITS][2];
290         for (int j = 0; j < 16; j++) {
291             mv_vlc[i][j].table           = &vlc_buf[(16 * i + j) << MOBI_MV_VLC_BITS];
292             mv_vlc[i][j].table_allocated = 1 << MOBI_MV_VLC_BITS;
293             ff_init_vlc_from_lengths(&mv_vlc[i][j], MOBI_MV_VLC_BITS, mv_len[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, INIT_VLC_USE_NEW_STATIC, NULL);
297         }
298     }
299 }
300
301 static av_cold int mobiclip_init(AVCodecContext *avctx)
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, int 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
406 static void read_run_encoding(AVCodecContext *avctx,
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].table,
412                      MOBI_RL_VLC_BITS, 1);
413
414     *last = (n >> 11) == 1;
415     *run  = (n >> 5) & 0x3F;
416     *level = n & 0x1F;
417 }
418
419 static int add_coefficients(AVCodecContext *avctx, AVFrame *frame,
420                             int bx, int by, int size, int plane)
421 {
422     MobiClipContext *s = avctx->priv_data;
423     GetBitContext *gb = &s->gb;
424     int mat[64] = { 0 };
425     const uint8_t *ztab = size == 8 ? ff_zigzag_direct : zigzag4x4_tab;
426     const int *qtab = s->qtab[size == 8];
427     uint8_t *dst = frame->data[plane] + by * frame->linesize[plane] + bx;
428
429     for (int pos = 0; get_bits_left(gb) > 0; pos++) {
430         int qval, last, run, level;
431
432         read_run_encoding(avctx, &last, &run, &level);
433
434         if (level) {
435             if (get_bits1(gb))
436                 level = -level;
437         } else if (!get_bits1(gb)) {
438             read_run_encoding(avctx, &last, &run, &level);
439             level += run_residue[s->dct_tab_idx][(last ? 64 : 0) + run];
440             if (get_bits1(gb))
441                 level = -level;
442         } else if (!get_bits1(gb)) {
443             read_run_encoding(avctx, &last, &run, &level);
444             run += run_residue[s->dct_tab_idx][128 + (last ? 64 : 0) + level];
445             if (get_bits1(gb))
446                 level = -level;
447         } else {
448             last  = get_bits1(gb);
449             run   = get_bits(gb, 6);
450             level = get_sbits(gb, 12);
451         }
452
453         pos += run;
454         if (pos >= size * size)
455             return AVERROR_INVALIDDATA;
456         qval = qtab[pos];
457         mat[ztab[pos]] = qval *(unsigned)level;
458
459         if (last)
460             break;
461     }
462
463     mat[0] += 32;
464     for (int y = 0; y < size; y++)
465         idct(&mat[y * size], size);
466
467     for (int y = 0; y < size; y++) {
468         for (int x = y + 1; x < size; x++) {
469             int a = mat[x * size + y];
470             int b = mat[y * size + x];
471
472             mat[y * size + x] = a;
473             mat[x * size + y] = b;
474         }
475
476         idct(&mat[y * size], size);
477         for (int x = 0; x < size; x++)
478             dst[x] = av_clip_uint8(dst[x] + (mat[y * size + x] >> 6));
479         dst += frame->linesize[plane];
480     }
481
482     return 0;
483 }
484
485 static int add_pframe_coefficients(AVCodecContext *avctx, AVFrame *frame,
486                                    int bx, int by, int size, int plane)
487 {
488     MobiClipContext *s = avctx->priv_data;
489     GetBitContext *gb = &s->gb;
490     int ret, idx = get_ue_golomb_31(gb);
491
492     if (idx == 0) {
493         ret = add_coefficients(avctx, frame, bx, by, size, plane);
494     } else if ((unsigned)idx < FF_ARRAY_ELEMS(pframe_block4x4_coefficients_tab)) {
495         int flags = pframe_block4x4_coefficients_tab[idx];
496
497         for (int y = by; y < by + 8; y += 4) {
498             for (int x = bx; x < bx + 8; x += 4) {
499                 if (flags & 1) {
500                     ret = add_coefficients(avctx, frame, x, y, 4, plane);
501                     if (ret < 0)
502                         return ret;
503                 }
504                 flags >>= 1;
505             }
506         }
507     } else {
508         ret = AVERROR_INVALIDDATA;
509     }
510
511     return ret;
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 * get_se_golomb(gb);
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
950 static int process_block(AVCodecContext *avctx, AVFrame *frame,
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);
964     if ((unsigned)tmp > FF_ARRAY_ELEMS(block4x4_coefficients_tab))
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 {
972         int flags = block4x4_coefficients_tab[tmp - 1];
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
991 static int decode_macroblock(AVCodecContext *avctx, AVFrame *frame,
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
1002     flags = block8x8_coefficients_tab[idx];
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 + get_se_golomb(gb);
1095             mv.y = mv.y + get_se_golomb(gb);
1096         }
1097         if (mv.x >= INT_MAX || mv.y >= INT_MAX)
1098             return AVERROR_INVALIDDATA;
1099
1100         motion[offsetm].x = mv.x;
1101         motion[offsetm].y = mv.y;
1102
1103         for (int i = 0; i < 3; i++) {
1104             int method, src_linesize, dst_linesize;
1105             uint8_t *src, *dst;
1106
1107             if (i == 1) {
1108                 offsetx = offsetx >> 1;
1109                 offsety = offsety >> 1;
1110                 mv.x = mv.x >> 1;
1111                 mv.y = mv.y >> 1;
1112                 width = width >> 1;
1113                 height = height >> 1;
1114                 fwidth = fwidth >> 1;
1115                 fheight = fheight >> 1;
1116             }
1117
1118             av_assert0(s->pic[sidx]);
1119             av_assert0(s->pic[s->current_pic]);
1120             av_assert0(s->pic[s->current_pic]->data[i]);
1121             if (!s->pic[sidx]->data[i])
1122                 return AVERROR_INVALIDDATA;
1123
1124             method = (mv.x & 1) | ((mv.y & 1) << 1);
1125             src_linesize = s->pic[sidx]->linesize[i];
1126             dst_linesize = s->pic[s->current_pic]->linesize[i];
1127             dst = s->pic[s->current_pic]->data[i] + offsetx + offsety * dst_linesize;
1128
1129             if (offsetx + (mv.x >> 1) < 0 ||
1130                 offsety + (mv.y >> 1) < 0 ||
1131                 offsetx + width  + (mv.x + 1 >> 1) > fwidth ||
1132                 offsety + height + (mv.y + 1 >> 1) > fheight)
1133                 return AVERROR_INVALIDDATA;
1134
1135             switch (method) {
1136             case 0:
1137                 src = s->pic[sidx]->data[i] + offsetx + (mv.x >> 1) +
1138                                (offsety + (mv.y >> 1)) * src_linesize;
1139                 for (int y = 0; y < height; y++) {
1140                     for (int x = 0; x < width; x++)
1141                         dst[x] = src[x];
1142                     dst += dst_linesize;
1143                     src += src_linesize;
1144                 }
1145                 break;
1146             case 1:
1147                 src = s->pic[sidx]->data[i] + offsetx + (mv.x >> 1) +
1148                                (offsety + (mv.y >> 1)) * src_linesize;
1149                 for (int y = 0; y < height; y++) {
1150                     for (int x = 0; x < width; x++) {
1151                         dst[x] = (uint8_t)((src[x] >> 1) + (src[x + 1] >> 1));
1152                     }
1153
1154                     dst += dst_linesize;
1155                     src += src_linesize;
1156                 }
1157                 break;
1158             case 2:
1159                 src = s->pic[sidx]->data[i] + offsetx + (mv.x >> 1) +
1160                                (offsety + (mv.y >> 1)) * src_linesize;
1161                 for (int y = 0; y < height; y++) {
1162                     for (int x = 0; x < width; x++) {
1163                         dst[x] = (uint8_t)((src[x] >> 1) + (src[x + src_linesize] >> 1));
1164                     }
1165
1166                     dst += dst_linesize;
1167                     src += src_linesize;
1168                 }
1169                 break;
1170             case 3:
1171                 src = s->pic[sidx]->data[i] + offsetx + (mv.x >> 1) +
1172                                (offsety + (mv.y >> 1)) * src_linesize;
1173                 for (int y = 0; y < height; y++) {
1174                     for (int x = 0; x < width; x++) {
1175                         dst[x] = (uint8_t)((((src[x] >> 1) + (src[x + 1] >> 1)) >> 1) +
1176                                            (((src[x + src_linesize] >> 1) + (src[x + 1 + src_linesize] >> 1)) >> 1));
1177                     }
1178
1179                     dst += dst_linesize;
1180                     src += src_linesize;
1181                 }
1182                 break;
1183             }
1184         }
1185     } else {
1186         int tidx;
1187         int adjx = index == 8 ? 0 :  width / 2;
1188         int adjy = index == 8 ? height / 2 : 0;
1189
1190         width  = width  - adjx;
1191         height = height - adjy;
1192         tidx = get_index(height) * 4 + get_index(width);
1193
1194         for (int i = 0; i < 2; i++) {
1195             int ret, idx2;
1196
1197             idx2 = get_vlc2(gb, mv_vlc[s->moflex][tidx].table,
1198                             MOBI_MV_VLC_BITS, 1);
1199
1200             ret = predict_motion(avctx, width, height, idx2,
1201                                  offsetm, offsetx + i * adjx, offsety + i * adjy);
1202             if (ret < 0)
1203                 return ret;
1204         }
1205     }
1206
1207     return 0;
1208 }
1209
1210 static int mobiclip_decode(AVCodecContext *avctx, void *data,
1211                             int *got_frame, AVPacket *pkt)
1212 {
1213     MobiClipContext *s = avctx->priv_data;
1214     GetBitContext *gb = &s->gb;
1215     AVFrame *frame = s->pic[s->current_pic];
1216     int ret;
1217
1218     av_fast_padded_malloc(&s->bitstream, &s->bitstream_size,
1219                           pkt->size);
1220
1221     if ((ret = ff_reget_buffer(avctx, frame, 0)) < 0)
1222         return ret;
1223
1224     s->bdsp.bswap16_buf((uint16_t *)s->bitstream,
1225                         (uint16_t *)pkt->data,
1226                         (pkt->size + 1) >> 1);
1227
1228     ret = init_get_bits8(gb, s->bitstream, FFALIGN(pkt->size, 2));
1229     if (ret < 0)
1230         return ret;
1231
1232     if (get_bits1(gb)) {
1233         frame->pict_type = AV_PICTURE_TYPE_I;
1234         frame->key_frame = 1;
1235         s->moflex = get_bits1(gb);
1236         s->dct_tab_idx = get_bits1(gb);
1237
1238         ret = setup_qtables(avctx, get_bits(gb, 6));
1239         if (ret < 0)
1240             return ret;
1241
1242         for (int y = 0; y < avctx->height; y += 16) {
1243             for (int x = 0; x < avctx->width; x += 16) {
1244                 ret = decode_macroblock(avctx, frame, x, y, get_bits1(gb));
1245                 if (ret < 0)
1246                     return ret;
1247             }
1248         }
1249     } else {
1250         MotionXY *motion = s->motion;
1251
1252         memset(motion, 0, s->motion_size);
1253
1254         frame->pict_type = AV_PICTURE_TYPE_P;
1255         frame->key_frame = 0;
1256         s->dct_tab_idx = 0;
1257
1258         ret = setup_qtables(avctx, s->quantizer + get_se_golomb(gb));
1259         if (ret < 0)
1260             return ret;
1261
1262         for (int y = 0; y < avctx->height; y += 16) {
1263             for (int x = 0; x < avctx->width; x += 16) {
1264                 int idx;
1265
1266                 motion[0].x = mid_pred(motion[x / 16 + 1].x, motion[x / 16 + 2].x, motion[x / 16 + 3].x);
1267                 motion[0].y = mid_pred(motion[x / 16 + 1].y, motion[x / 16 + 2].y, motion[x / 16 + 3].y);
1268                 motion[x / 16 + 2].x = 0;
1269                 motion[x / 16 + 2].y = 0;
1270
1271                 idx = get_vlc2(gb, mv_vlc[s->moflex][0].table,
1272                                    MOBI_MV_VLC_BITS, 1);
1273
1274                 if (idx == 6 || idx == 7) {
1275                     ret = decode_macroblock(avctx, frame, x, y, idx == 7);
1276                     if (ret < 0)
1277                         return ret;
1278                 } else {
1279                     int flags, idx2;
1280                     ret = predict_motion(avctx, 16, 16, idx, x / 16 + 2, x, y);
1281                     if (ret < 0)
1282                         return ret;
1283                     idx2 = get_ue_golomb(gb);
1284                     if (idx2 >= FF_ARRAY_ELEMS(pframe_block8x8_coefficients_tab))
1285                         return AVERROR_INVALIDDATA;
1286                     flags = pframe_block8x8_coefficients_tab[idx2];
1287
1288                     for (int sy = y; sy < y + 16; sy += 8) {
1289                         for (int sx = x; sx < x + 16; sx += 8) {
1290                             if (flags & 1)
1291                                 add_pframe_coefficients(avctx, frame, sx, sy, 8, 0);
1292                             flags >>= 1;
1293                         }
1294                     }
1295
1296                     if (flags & 1)
1297                         add_pframe_coefficients(avctx, frame, x >> 1, y >> 1, 8, 1 + !s->moflex);
1298                     flags >>= 1;
1299                     if (flags & 1)
1300                         add_pframe_coefficients(avctx, frame, x >> 1, y >> 1, 8, 2 - !s->moflex);
1301                 }
1302             }
1303         }
1304     }
1305
1306     if (!s->moflex)
1307         avctx->colorspace = AVCOL_SPC_YCGCO;
1308
1309     s->current_pic = (s->current_pic + 1) % 6;
1310     ret = av_frame_ref(data, frame);
1311     if (ret < 0)
1312         return ret;
1313     *got_frame = 1;
1314
1315     return 0;
1316 }
1317
1318 static void mobiclip_flush(AVCodecContext *avctx)
1319 {
1320     MobiClipContext *s = avctx->priv_data;
1321
1322     for (int i = 0; i < 6; i++)
1323         av_frame_unref(s->pic[i]);
1324 }
1325
1326 static av_cold int mobiclip_close(AVCodecContext *avctx)
1327 {
1328     MobiClipContext *s = avctx->priv_data;
1329
1330     av_freep(&s->bitstream);
1331     s->bitstream_size = 0;
1332     av_freep(&s->motion);
1333     s->motion_size = 0;
1334
1335     for (int i = 0; i < 6; i++) {
1336         av_frame_free(&s->pic[i]);
1337     }
1338
1339     return 0;
1340 }
1341
1342 AVCodec ff_mobiclip_decoder = {
1343     .name           = "mobiclip",
1344     .long_name      = NULL_IF_CONFIG_SMALL("MobiClip Video"),
1345     .type           = AVMEDIA_TYPE_VIDEO,
1346     .id             = AV_CODEC_ID_MOBICLIP,
1347     .priv_data_size = sizeof(MobiClipContext),
1348     .init           = mobiclip_init,
1349     .decode         = mobiclip_decode,
1350     .flush          = mobiclip_flush,
1351     .close          = mobiclip_close,
1352     .capabilities   = AV_CODEC_CAP_DR1,
1353     .caps_internal  = FF_CODEC_CAP_INIT_THREADSAFE | FF_CODEC_CAP_INIT_CLEANUP,
1354 };