GCC Code Coverage Report
Directory: ../../../ffmpeg/ Exec Total Coverage
File: src/libavcodec/mobiclip.c Lines: 0 667 0.0 %
Date: 2021-04-14 23:45:22 Branches: 0 353 0.0 %

Line Branch Exec Source
1
/*
2
 * MobiClip Video decoder
3
 * Copyright (c) 2015-2016 Florian Nouwt
4
 * Copyright (c) 2017 Adib Surani
5
 * Copyright (c) 2020 Paul B Mahol
6
 *
7
 * This file is part of FFmpeg.
8
 *
9
 * FFmpeg is free software; you can redistribute it and/or
10
 * modify it under the terms of the GNU Lesser General Public
11
 * License as published by the Free Software Foundation; either
12
 * version 2.1 of the License, or (at your option) any later version.
13
 *
14
 * FFmpeg is distributed in the hope that it will be useful,
15
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
17
 * Lesser General Public License for more details.
18
 *
19
 * You should have received a copy of the GNU Lesser General Public
20
 * License along with FFmpeg; if not, write to the Free Software
21
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
22
 */
23
24
#include <inttypes.h>
25
26
#include "libavutil/avassert.h"
27
#include "libavutil/thread.h"
28
29
#include "avcodec.h"
30
#include "bytestream.h"
31
#include "bswapdsp.h"
32
#include "get_bits.h"
33
#include "golomb.h"
34
#include "internal.h"
35
36
#define MOBI_RL_VLC_BITS 12
37
#define MOBI_MV_VLC_BITS 6
38
39
static const uint8_t zigzag4x4_tab[] =
40
{
41
    0x00, 0x04, 0x01, 0x02, 0x05, 0x08, 0x0C, 0x09, 0x06, 0x03, 0x07, 0x0A,
42
    0x0D, 0x0E, 0x0B, 0x0F
43
};
44
45
static const uint8_t quant4x4_tab[][16] =
46
{
47
    { 10, 13, 13, 10, 16, 10, 13, 13, 13, 13, 16, 10, 16, 13, 13, 16 },
48
    { 11, 14, 14, 11, 18, 11, 14, 14, 14, 14, 18, 11, 18, 14, 14, 18 },
49
    { 13, 16, 16, 13, 20, 13, 16, 16, 16, 16, 20, 13, 20, 16, 16, 20 },
50
    { 14, 18, 18, 14, 23, 14, 18, 18, 18, 18, 23, 14, 23, 18, 18, 23 },
51
    { 16, 20, 20, 16, 25, 16, 20, 20, 20, 20, 25, 16, 25, 20, 20, 25 },
52
    { 18, 23, 23, 18, 29, 18, 23, 23, 23, 23, 29, 18, 29, 23, 23, 29 },
53
};
54
55
static const uint8_t quant8x8_tab[][64] =
56
{
57
    { 20, 19, 19, 25, 18, 25, 19, 24, 24, 19, 20, 18, 32, 18, 20, 19, 19, 24, 24, 19, 19, 25, 18, 25, 18, 25, 18, 25, 19, 24, 24, 19,
58
      19, 24, 24, 19, 18, 32, 18, 20, 18, 32, 18, 24, 24, 19, 19, 24, 24, 18, 25, 18, 25, 18, 19, 24, 24, 19, 18, 32, 18, 24, 24, 18,},
59
    { 22, 21, 21, 28, 19, 28, 21, 26, 26, 21, 22, 19, 35, 19, 22, 21, 21, 26, 26, 21, 21, 28, 19, 28, 19, 28, 19, 28, 21, 26, 26, 21,
60
      21, 26, 26, 21, 19, 35, 19, 22, 19, 35, 19, 26, 26, 21, 21, 26, 26, 19, 28, 19, 28, 19, 21, 26, 26, 21, 19, 35, 19, 26, 26, 19,},
61
    { 26, 24, 24, 33, 23, 33, 24, 31, 31, 24, 26, 23, 42, 23, 26, 24, 24, 31, 31, 24, 24, 33, 23, 33, 23, 33, 23, 33, 24, 31, 31, 24,
62
      24, 31, 31, 24, 23, 42, 23, 26, 23, 42, 23, 31, 31, 24, 24, 31, 31, 23, 33, 23, 33, 23, 24, 31, 31, 24, 23, 42, 23, 31, 31, 23,},
63
    { 28, 26, 26, 35, 25, 35, 26, 33, 33, 26, 28, 25, 45, 25, 28, 26, 26, 33, 33, 26, 26, 35, 25, 35, 25, 35, 25, 35, 26, 33, 33, 26,
64
      26, 33, 33, 26, 25, 45, 25, 28, 25, 45, 25, 33, 33, 26, 26, 33, 33, 25, 35, 25, 35, 25, 26, 33, 33, 26, 25, 45, 25, 33, 33, 25,},
65
    { 32, 30, 30, 40, 28, 40, 30, 38, 38, 30, 32, 28, 51, 28, 32, 30, 30, 38, 38, 30, 30, 40, 28, 40, 28, 40, 28, 40, 30, 38, 38, 30,
66
      30, 38, 38, 30, 28, 51, 28, 32, 28, 51, 28, 38, 38, 30, 30, 38, 38, 28, 40, 28, 40, 28, 30, 38, 38, 30, 28, 51, 28, 38, 38, 28,},
67
    { 36, 34, 34, 46, 32, 46, 34, 43, 43, 34, 36, 32, 58, 32, 36, 34, 34, 43, 43, 34, 34, 46, 32, 46, 32, 46, 32, 46, 34, 43, 43, 34,
68
      34, 43, 43, 34, 32, 58, 32, 36, 32, 58, 32, 43, 43, 34, 34, 43, 43, 32, 46, 32, 46, 32, 34, 43, 43, 34, 32, 58, 32, 43, 43, 32,},
69
};
70
71
static const uint8_t block4x4_coefficients_tab[] =
72
{
73
    15, 0, 2, 1, 4, 8, 12, 3, 11, 13, 14, 7, 10, 5, 9, 6,
74
};
75
76
static const uint8_t pframe_block4x4_coefficients_tab[] =
77
{
78
    0, 4, 1, 8, 2, 12, 3, 5, 10, 15, 7, 13, 14, 11, 9, 6,
79
};
80
81
static const uint8_t block8x8_coefficients_tab[] =
82
{
83
    0x00, 0x1F, 0x3F, 0x0F, 0x08, 0x04, 0x02, 0x01, 0x0B, 0x0E, 0x1B, 0x0D,
84
    0x03, 0x07, 0x0C, 0x17, 0x1D, 0x0A, 0x1E, 0x05, 0x10, 0x2F, 0x37, 0x3B,
85
    0x13, 0x3D, 0x3E, 0x09, 0x1C, 0x06, 0x15, 0x1A, 0x33, 0x11, 0x12, 0x14,
86
    0x18, 0x20, 0x3C, 0x35, 0x19, 0x16, 0x3A, 0x30, 0x31, 0x32, 0x27, 0x34,
87
    0x2B, 0x2D, 0x39, 0x38, 0x23, 0x36, 0x2E, 0x21, 0x25, 0x22, 0x24, 0x2C,
88
    0x2A, 0x28, 0x29, 0x26,
89
};
90
91
static const uint8_t pframe_block8x8_coefficients_tab[] =
92
{
93
    0x00, 0x0F, 0x04, 0x01, 0x08, 0x02, 0x0C, 0x03, 0x05, 0x0A, 0x0D, 0x07, 0x0E, 0x0B, 0x1F, 0x09,
94
    0x06, 0x10, 0x3F, 0x1E, 0x17, 0x1D, 0x1B, 0x1C, 0x13, 0x18, 0x1A, 0x12, 0x11, 0x14, 0x15, 0x20,
95
    0x2F, 0x16, 0x19, 0x37, 0x3D, 0x3E, 0x3B, 0x3C, 0x33, 0x35, 0x21, 0x24, 0x22, 0x28, 0x23, 0x2C,
96
    0x30, 0x27, 0x2D, 0x25, 0x3A, 0x2B, 0x2E, 0x2A, 0x31, 0x34, 0x38, 0x32, 0x29, 0x26, 0x39, 0x36
97
};
98
99
static const uint8_t run_residue[2][256] =
100
{
101
    {
102
       12,  6,  4,  3,  3,  3,  3,  2,  2,  2,  2,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,
103
        0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
104
        3,  2,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,
105
        1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
106
        1, 27, 11,  7,  3,  2,  2,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,
107
        1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,
108
        1, 41,  2,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,
109
        1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,
110
    },
111
    {
112
       27, 10,  5,  4,  3,  3,  3,  3,  2,  2,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
113
        0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
114
        8,  3,  2,  2,  2,  2,  2,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
115
        0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
116
        1, 15, 10,  8,  4,  3,  2,  2,  2,  2,  2,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,
117
        1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,
118
        1, 21,  7,  2,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,
119
        1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,
120
    },
121
};
122
123
static const uint8_t bits0[] = {
124
     9, 11, 11, 11, 11, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10,
125
    10, 10, 11, 11, 11, 11, 11, 11, 11, 11, 12, 12, 12, 12, 12,
126
    12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,  7, 10, 10,  9,
127
     9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,
128
     9,  9,  9,  9,  9,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,
129
     8,  8,  8,  7,  7,  7,  7,  7,  7,  7,  7,  6,  6,  6,  6,
130
     6,  6,  6,  6,  6,  6,  5,  5,  5,  4,  2,  3,  4,  4,
131
};
132
133
static const uint16_t syms0[] = {
134
    0x0, 0x822, 0x803, 0xB, 0xA, 0xB81, 0xB61, 0xB41, 0xB21, 0x122,
135
    0x102, 0xE2, 0xC2, 0xA2, 0x63, 0x43, 0x24, 0xC, 0x25, 0x2E1, 0x301,
136
    0xBA1, 0xBC1, 0xBE1, 0xC01, 0x26, 0x44, 0x83, 0xA3, 0xC3, 0x142,
137
    0x321, 0x341, 0xC21, 0xC41, 0xC61, 0xC81, 0xCA1, 0xCC1, 0xCE1, 0xD01,
138
    0x0, 0x9, 0x8, 0xB01, 0xAE1, 0xAC1, 0xAA1, 0xA81, 0xA61, 0xA41, 0xA21,
139
    0x802, 0x2C1, 0x2A1, 0x281, 0x261, 0x241, 0x221, 0x201, 0x1E1, 0x82,
140
    0x62, 0x7, 0x6, 0xA01, 0x9E1, 0x9C1, 0x9A1, 0x981, 0x961, 0x941, 0x921,
141
    0x1C1, 0x1A1, 0x42, 0x23, 0x5, 0x901, 0x8E1, 0x8C1, 0x8A1, 0x181, 0x161,
142
    0x141, 0x4, 0x881, 0x861, 0x841, 0x821, 0x121, 0x101, 0xE1, 0xC1, 0x22,
143
    0x3, 0xA1, 0x81, 0x61, 0x801, 0x1, 0x21, 0x41, 0x2,
144
};
145
146
static const uint16_t syms1[] = {
147
    0x0, 0x807, 0x806, 0x16, 0x15, 0x842, 0x823, 0x805, 0x1A1, 0xA3, 0x102, 0x83,
148
    0x64, 0x44, 0x27, 0x14, 0x13, 0x17, 0x18, 0x28, 0x122, 0x862, 0x882, 0x9E1, 0xA01,
149
    0x19, 0x1A, 0x1B, 0x29, 0xC3, 0x2A, 0x45, 0xE3, 0x1C1, 0x808, 0x8A2, 0x8C2, 0xA21,
150
    0xA41, 0xA61, 0xA81, 0x0, 0x12, 0x11, 0x9C1, 0x9A1, 0x981, 0x961, 0x941, 0x822, 0x804,
151
    0x181, 0x161, 0xE2, 0xC2, 0xA2, 0x63, 0x43, 0x26, 0x25, 0x10, 0x82, 0xF, 0xE, 0xD, 0x901,
152
    0x8E1, 0x8C1, 0x803, 0x141, 0x121, 0x101, 0x921, 0x62, 0x24, 0xC, 0xB, 0xA, 0x881, 0x861,
153
    0xC1, 0x8A1, 0xE1, 0x42, 0x23, 0x9, 0x802, 0xA1, 0x841, 0x821, 0x81, 0x61, 0x8, 0x7, 0x22,
154
    0x6, 0x41, 0x5, 0x4, 0x801, 0x1, 0x2, 0x21, 0x3,
155
};
156
157
static const uint8_t mv_len[16] =
158
{
159
    10, 8, 8, 7, 8, 8, 8, 7, 8, 8, 8, 7, 7, 7, 7, 6,
160
};
161
162
static const uint8_t mv_bits[2][16][10] =
163
{
164
    {
165
        { 2, 3, 3, 5, 5, 4, 4, 5, 5, 2 },
166
        { 2, 3, 4, 4, 3, 4, 4, 2 },
167
        { 3, 4, 4, 2, 4, 4, 3, 2 },
168
        { 1, 3, 4, 5, 5, 3, 3 },
169
        { 2, 4, 4, 3, 3, 4, 4, 2 },
170
        { 2, 3, 4, 4, 4, 4, 3, 2 },
171
        { 2, 3, 4, 4, 4, 4, 3, 2 },
172
        { 2, 2, 3, 4, 5, 5, 2 },
173
        { 2, 3, 4, 4, 3, 4, 4, 2 },
174
        { 2, 4, 4, 3, 4, 4, 3, 2 },
175
        { 2, 3, 3, 5, 5, 4, 3, 2 },
176
        { 2, 3, 4, 4, 3, 3, 2 },
177
        { 1, 4, 4, 3, 3, 4, 4 },
178
        { 2, 3, 4, 4, 3, 3, 2 },
179
        { 2, 3, 4, 4, 3, 3, 2 },
180
        { 3, 3, 2, 2, 3, 3 },
181
    },
182
    {
183
        { 3, 4, 5, 5, 3, 5, 6, 6, 4, 1 },
184
        { 2, 3, 4, 5, 5, 2, 3, 3 },
185
        { 2, 4, 4, 3, 3, 4, 4, 2 },
186
        { 1, 4, 4, 3, 4, 4, 3 },
187
        { 3, 3, 2, 4, 5, 5, 3, 2 },
188
        { 3, 4, 4, 3, 3, 3, 3, 2 },
189
        { 1, 3, 3, 4, 4, 4, 5, 5 },
190
        { 1, 4, 4, 3, 3, 4, 4 },
191
        { 2, 4, 4, 3, 3, 4, 4, 2 },
192
        { 1, 3, 3, 4, 4, 4, 5, 5 },
193
        { 2, 3, 4, 4, 4, 4, 3, 2 },
194
        { 2, 3, 3, 4, 4, 3, 2 },
195
        { 1, 4, 4, 3, 3, 4, 4 },
196
        { 1, 4, 4, 3, 3, 4, 4 },
197
        { 2, 3, 3, 4, 4, 3, 2 },
198
        { 2, 3, 3, 3, 3, 2 },
199
    }
200
};
201
202
static const uint8_t mv_syms[2][16][10] =
203
{
204
    {
205
        { 1, 8, 9, 4, 3, 2, 7, 5, 6, 0 },
206
        { 0, 9, 5, 4, 2, 3, 8, 1 },
207
        { 3, 9, 5, 0, 4, 8, 2, 1 },
208
        { 1, 3, 4, 8, 5, 2, 0 },
209
        { 0, 5, 4, 8, 2, 3, 9, 1 },
210
        { 0, 3, 5, 9, 4, 8, 2, 1 },
211
        { 0, 3, 9, 5, 8, 4, 2, 1 },
212
        { 0, 2, 3, 4, 8, 5, 1 },
213
        { 0, 3, 8, 4, 2, 5, 9, 1 },
214
        { 2, 8, 9, 3, 5, 4, 0, 1 },
215
        { 0, 4, 3, 8, 9, 5, 2, 1 },
216
        { 0, 4, 8, 5, 3, 2, 1 },
217
        { 1, 9, 4, 2, 0, 5, 3 },
218
        { 2, 4, 9, 5, 3, 0, 1 },
219
        { 0, 4, 9, 5, 3, 2, 1 },
220
        { 5, 4, 1, 0, 3, 2 },
221
    },
222
    {
223
        { 8, 2, 3, 6, 1, 7, 5, 4, 9, 0 },
224
        { 9, 2, 3, 5, 4, 1, 8, 0 },
225
        { 0, 5, 4, 2, 9, 3, 8, 1 },
226
        { 1, 5, 4, 2, 8, 3, 0 },
227
        { 2, 9, 8, 3, 5, 4, 0, 1 },
228
        { 3, 5, 4, 2, 9, 8, 0, 1 },
229
        { 1, 2, 0, 9, 8, 3, 5, 4 },
230
        { 1, 8, 5, 2, 0, 4, 3 },
231
        { 0, 5, 4, 2, 8, 3, 9, 1 },
232
        { 1, 2, 0, 9, 8, 3, 5, 4 },
233
        { 0, 3, 9, 8, 5, 4, 2, 1 },
234
        { 0, 4, 3, 8, 5, 2, 1 },
235
        { 1, 5, 4, 2, 0, 9, 3 },
236
        { 1, 9, 5, 2, 0, 4, 3 },
237
        { 0, 5, 3, 9, 4, 2, 1 },
238
        { 0, 4, 5, 3, 2, 1 },
239
    }
240
};
241
242
typedef struct BlockXY {
243
    int w, h;
244
    int ax, ay;
245
    int x, y;
246
    int size;
247
    uint8_t *block;
248
    int linesize;
249
} BlockXY;
250
251
typedef struct MotionXY {
252
    int x, y;
253
} MotionXY;
254
255
typedef struct MobiClipContext {
256
    AVFrame *pic[6];
257
258
    int current_pic;
259
    int moflex;
260
    int dct_tab_idx;
261
    int quantizer;
262
263
    GetBitContext gb;
264
265
    uint8_t *bitstream;
266
    int bitstream_size;
267
268
    int     qtab[2][64];
269
    uint8_t pre[32];
270
    MotionXY *motion;
271
    int     motion_size;
272
273
    BswapDSPContext bdsp;
274
} MobiClipContext;
275
276
static VLC rl_vlc[2];
277
static VLC mv_vlc[2][16];
278
279
static av_cold void mobiclip_init_static(void)
280
{
281
    INIT_VLC_STATIC_FROM_LENGTHS(&rl_vlc[0], MOBI_RL_VLC_BITS, 104,
282
                                 bits0, sizeof(*bits0),
283
                                 syms0, sizeof(*syms0), sizeof(*syms0),
284
                                 0, 0, 1 << MOBI_RL_VLC_BITS);
285
    INIT_VLC_STATIC_FROM_LENGTHS(&rl_vlc[1], MOBI_RL_VLC_BITS, 104,
286
                                 bits0, sizeof(*bits0),
287
                                 syms1, sizeof(*syms1), sizeof(*syms1),
288
                                 0, 0, 1 << MOBI_RL_VLC_BITS);
289
    for (int i = 0; i < 2; i++) {
290
        static VLC_TYPE vlc_buf[2 * 16 << MOBI_MV_VLC_BITS][2];
291
        for (int j = 0; j < 16; j++) {
292
            mv_vlc[i][j].table           = &vlc_buf[(16 * i + j) << MOBI_MV_VLC_BITS];
293
            mv_vlc[i][j].table_allocated = 1 << MOBI_MV_VLC_BITS;
294
            ff_init_vlc_from_lengths(&mv_vlc[i][j], MOBI_MV_VLC_BITS, mv_len[j],
295
                                     mv_bits[i][j], sizeof(*mv_bits[i][j]),
296
                                     mv_syms[i][j], sizeof(*mv_syms[i][j]), sizeof(*mv_syms[i][j]),
297
                                     0, INIT_VLC_USE_NEW_STATIC, NULL);
298
        }
299
    }
300
}
301
302
static av_cold int mobiclip_init(AVCodecContext *avctx)
303
{
304
    static AVOnce init_static_once = AV_ONCE_INIT;
305
    MobiClipContext *s = avctx->priv_data;
306
307
    if (avctx->width & 15 || avctx->height & 15) {
308
        av_log(avctx, AV_LOG_ERROR, "width/height not multiple of 16\n");
309
        return AVERROR_INVALIDDATA;
310
    }
311
312
    ff_bswapdsp_init(&s->bdsp);
313
314
    avctx->pix_fmt = AV_PIX_FMT_YUV420P;
315
316
    s->motion = av_calloc(avctx->width / 16 + 3, sizeof(MotionXY));
317
    if (!s->motion)
318
        return AVERROR(ENOMEM);
319
    s->motion_size = (avctx->width / 16 + 3) * sizeof(MotionXY);
320
321
    for (int i = 0; i < 6; i++) {
322
        s->pic[i] = av_frame_alloc();
323
        if (!s->pic[i])
324
            return AVERROR(ENOMEM);
325
    }
326
327
    ff_thread_once(&init_static_once, mobiclip_init_static);
328
329
    return 0;
330
}
331
332
static int setup_qtables(AVCodecContext *avctx, int quantizer)
333
{
334
    MobiClipContext *s = avctx->priv_data;
335
    int qx, qy;
336
337
    if (quantizer < 12 || quantizer > 161)
338
        return AVERROR_INVALIDDATA;
339
340
    s->quantizer = quantizer;
341
342
    qx = quantizer % 6;
343
    qy = quantizer / 6;
344
345
    for (int i = 0; i < 16; i++)
346
        s->qtab[0][i] = quant4x4_tab[qx][i] << qy;
347
348
    for (int i = 0; i < 64; i++)
349
        s->qtab[1][i] = quant8x8_tab[qx][i] << (qy - 2);
350
351
    for (int i = 0; i < 20; i++)
352
        s->pre[i] = 9;
353
354
    return 0;
355
}
356
357
static void inverse4(unsigned *rs)
358
{
359
    unsigned a = rs[0] + rs[2];
360
    unsigned b = rs[0] - rs[2];
361
    unsigned c = rs[1] + ((int)rs[3] >> 1);
362
    unsigned d = ((int)rs[1] >> 1) - rs[3];
363
364
    rs[0] = a + c;
365
    rs[1] = b + d;
366
    rs[2] = b - d;
367
    rs[3] = a - c;
368
}
369
370
static void idct(int *arr, int size)
371
{
372
    int e, f, g, h;
373
    unsigned x3, x2, x1, x0;
374
    int tmp[4];
375
376
    if (size == 4) {
377
        inverse4(arr);
378
        return;
379
    }
380
381
    tmp[0] = arr[0];
382
    tmp[1] = arr[2];
383
    tmp[2] = arr[4];
384
    tmp[3] = arr[6];
385
386
    inverse4(tmp);
387
388
    e = (unsigned)arr[7] + arr[1] - arr[3] - (arr[3] >> 1);
389
    f = (unsigned)arr[7] - arr[1] + arr[5] + (arr[5] >> 1);
390
    g = (unsigned)arr[5] - arr[3] - arr[7] - (arr[7] >> 1);
391
    h = (unsigned)arr[5] + arr[3] + arr[1] + (arr[1] >> 1);
392
    x3 = (unsigned)g + (h >> 2);
393
    x2 = (unsigned)e + (f >> 2);
394
    x1 = (e >> 2) - (unsigned)f;
395
    x0 = (unsigned)h - (g >> 2);
396
397
    arr[0] = tmp[0] + x0;
398
    arr[1] = tmp[1] + x1;
399
    arr[2] = tmp[2] + x2;
400
    arr[3] = tmp[3] + x3;
401
    arr[4] = tmp[3] - x3;
402
    arr[5] = tmp[2] - x2;
403
    arr[6] = tmp[1] - x1;
404
    arr[7] = tmp[0] - x0;
405
}
406
407
static void read_run_encoding(AVCodecContext *avctx,
408
                              int *last, int *run, int *level)
409
{
410
    MobiClipContext *s = avctx->priv_data;
411
    GetBitContext *gb = &s->gb;
412
    int n = get_vlc2(gb, rl_vlc[s->dct_tab_idx].table,
413
                     MOBI_RL_VLC_BITS, 1);
414
415
    *last = (n >> 11) == 1;
416
    *run  = (n >> 5) & 0x3F;
417
    *level = n & 0x1F;
418
}
419
420
static int add_coefficients(AVCodecContext *avctx, AVFrame *frame,
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
486
static int add_pframe_coefficients(AVCodecContext *avctx, AVFrame *frame,
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
        ret = add_coefficients(avctx, frame, bx, by, size, plane);
495
    } else if ((unsigned)idx < FF_ARRAY_ELEMS(pframe_block4x4_coefficients_tab)) {
496
        int flags = pframe_block4x4_coefficients_tab[idx];
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
    } else {
509
        ret = AVERROR_INVALIDDATA;
510
    }
511
512
    return ret;
513
}
514
515
static int adjust(int x, int size)
516
{
517
    return size == 16 ? (x + 1) >> 1 : x;
518
}
519
520
static uint8_t pget(BlockXY b)
521
{
522
    BlockXY ret = b;
523
    int x, y;
524
525
    if (b.x == -1 && b.y >= b.size) {
526
        ret.x = -1, ret.y = b.size - 1;
527
    } else if (b.x >= -1 && b.y >= -1) {
528
        ret.x = b.x, ret.y = b.y;
529
    } else if (b.x == -1 && b.y == -2) {
530
        ret.x = 0, ret.y = -1;
531
    } else if (b.x == -2 && b.y == -1) {
532
        ret.x = -1, ret.y = 0;
533
    }
534
535
    y = av_clip(ret.ay + ret.y, 0, ret.h - 1);
536
    x = av_clip(ret.ax + ret.x, 0, ret.w - 1);
537
538
    return ret.block[y * ret.linesize + x];
539
}
540
541
static uint8_t half(int a, int b)
542
{
543
    return ((a + b) + 1) / 2;
544
}
545
546
static uint8_t half3(int a, int b, int c)
547
{
548
    return ((a + b + b + c) * 2 / 4 + 1) / 2;
549
}
550
551
static uint8_t pick_above(BlockXY bxy)
552
{
553
    bxy.y = bxy.y - 1;
554
555
    return pget(bxy);
556
}
557
558
static uint8_t pick_left(BlockXY bxy)
559
{
560
    bxy.x = bxy.x - 1;
561
562
    return pget(bxy);
563
}
564
565
static uint8_t half_horz(BlockXY bxy)
566
{
567
    BlockXY a = bxy, b = bxy, c = bxy;
568
569
    a.x -= 1;
570
    c.x += 1;
571
572
    return half3(pget(a), pget(b), pget(c));
573
}
574
575
static uint8_t half_vert(BlockXY bxy)
576
{
577
    BlockXY a = bxy, b = bxy, c = bxy;
578
579
    a.y -= 1;
580
    c.y += 1;
581
582
    return half3(pget(a), pget(b), pget(c));
583
}
584
585
static uint8_t pick_4(BlockXY bxy)
586
{
587
    int val;
588
589
    if ((bxy.x % 2) == 0) {
590
        BlockXY ba, bb;
591
        int a, b;
592
593
        ba = bxy;
594
        ba.x = -1;
595
        ba.y = bxy.y + bxy.x / 2;
596
        a = pget(ba);
597
598
        bb = bxy;
599
        bb.x = -1;
600
        bb.y = bxy.y + bxy.x / 2 + 1;
601
        b = pget(bb);
602
603
        val = half(a, b);
604
    } else {
605
        BlockXY ba;
606
607
        ba = bxy;
608
        ba.x = -1;
609
        ba.y = bxy.y + bxy.x / 2 + 1;
610
        val = half_vert(ba);
611
    }
612
613
    return val;
614
}
615
616
static uint8_t pick_5(BlockXY bxy)
617
{
618
    int val;
619
620
    if (bxy.x == 0) {
621
        BlockXY a = bxy;
622
        BlockXY b = bxy;
623
624
        a.x = -1;
625
        a.y -= 1;
626
627
        b.x = -1;
628
629
        val = half(pget(a), pget(b));
630
    } else if (bxy.y == 0) {
631
        BlockXY a = bxy;
632
633
        a.x -= 2;
634
        a.y -= 1;
635
636
        val = half_horz(a);
637
    } else if (bxy.x == 1) {
638
        BlockXY a = bxy;
639
640
        a.x -= 2;
641
        a.y -= 1;
642
643
        val = half_vert(a);
644
    } else {
645
        BlockXY a = bxy;
646
647
        a.x -= 2;
648
        a.y -= 1;
649
650
        val = pget(a);
651
    }
652
653
    return val;
654
}
655
656
static uint8_t pick_6(BlockXY bxy)
657
{
658
    int val;
659
660
    if (bxy.y == 0) {
661
        BlockXY a = bxy;
662
        BlockXY b = bxy;
663
664
        a.x -= 1;
665
        a.y = -1;
666
667
        b.y = -1;
668
669
        val = half(pget(a), pget(b));
670
    } else if (bxy.x == 0) {
671
        BlockXY a = bxy;
672
673
        a.x -= 1;
674
        a.y -= 2;
675
676
        val = half_vert(a);
677
    } else if (bxy.y == 1) {
678
        BlockXY a = bxy;
679
680
        a.x -= 1;
681
        a.y -= 2;
682
683
        val = half_horz(a);
684
    } else {
685
        BlockXY a = bxy;
686
687
        a.x -= 1;
688
        a.y -= 2;
689
690
        val = pget(a);
691
    }
692
693
    return val;
694
}
695
696
static uint8_t pick_7(BlockXY bxy)
697
{
698
    int clr, acc1, acc2;
699
    BlockXY a = bxy;
700
701
    a.x -= 1;
702
    a.y -= 1;
703
    clr = pget(a);
704
    if (bxy.x && bxy.y)
705
        return clr;
706
707
    if (bxy.x == 0) {
708
        a.x = -1;
709
        a.y = bxy.y;
710
    } else {
711
        a.x = bxy.x - 2;
712
        a.y = -1;
713
    }
714
    acc1 = pget(a);
715
716
    if (bxy.y == 0) {
717
        a.x = bxy.x;
718
        a.y = -1;
719
    } else {
720
        a.x = -1;
721
        a.y = bxy.y - 2;
722
    }
723
    acc2 = pget(a);
724
725
    return half3(acc1, clr, acc2);
726
}
727
728
static uint8_t pick_8(BlockXY bxy)
729
{
730
    BlockXY ba = bxy;
731
    BlockXY bb = bxy;
732
    int val;
733
734
    if (bxy.y == 0) {
735
        int a, b;
736
737
        ba.y = -1;
738
        a = pget(ba);
739
740
        bb.x += 1;
741
        bb.y = -1;
742
743
        b = pget(bb);
744
745
        val = half(a, b);
746
    } else if (bxy.y == 1) {
747
        ba.x += 1;
748
        ba.y -= 2;
749
750
        val = half_horz(ba);
751
    } else if (bxy.x < bxy.size - 1) {
752
        ba.x += 1;
753
        ba.y -= 2;
754
755
        val = pget(ba);
756
    } else if (bxy.y % 2 == 0) {
757
        int a, b;
758
759
        ba.x = bxy.y / 2 + bxy.size - 1;
760
        ba.y = -1;
761
        a = pget(ba);
762
763
        bb.x = bxy.y / 2 + bxy.size;
764
        bb.y = -1;
765
766
        b = pget(bb);
767
768
        val = half(a, b);
769
    } else {
770
        ba.x = bxy.y / 2 + bxy.size;
771
        ba.y = -1;
772
773
        val = half_horz(ba);
774
    }
775
776
    return val;
777
}
778
779
static void block_fill_simple(uint8_t *block, int size, int linesize, int fill)
780
{
781
    for (int y = 0; y < size; y++) {
782
        memset(block, fill, size);
783
        block += linesize;
784
    }
785
}
786
787
static void block_fill(uint8_t *block, int size, int linesize,
788
                       int w, int h, int ax, int ay,
789
                       uint8_t (*pick)(BlockXY bxy))
790
{
791
    BlockXY bxy;
792
793
    bxy.size = size;
794
    bxy.block = block;
795
    bxy.linesize = linesize;
796
    bxy.w = w;
797
    bxy.h = h;
798
    bxy.ay = ay;
799
    bxy.ax = ax;
800
801
    for (int y = 0; y < size; y++) {
802
        bxy.y = y;
803
        for (int x = 0; x < size; x++) {
804
            uint8_t val;
805
806
            bxy.x = x;
807
808
            val = pick(bxy);
809
810
            block[ax + x + (ay + y) * linesize] = val;
811
        }
812
    }
813
}
814
815
static int block_sum(const uint8_t *block, int w, int h, int linesize)
816
{
817
    int sum = 0;
818
819
    for (int y = 0; y < h; y++) {
820
        for (int x = 0; x < w; x++) {
821
            sum += block[x];
822
        }
823
        block += linesize;
824
    }
825
826
    return sum;
827
}
828
829
static int predict_intra(AVCodecContext *avctx, AVFrame *frame, int ax, int ay,
830
                          int pmode, int add_coeffs, int size, int plane)
831
{
832
    MobiClipContext *s = avctx->priv_data;
833
    GetBitContext *gb = &s->gb;
834
    int w = avctx->width >> !!plane, h = avctx->height >> !!plane;
835
    int ret = 0;
836
837
    switch (pmode) {
838
    case 0:
839
        block_fill(frame->data[plane], size, frame->linesize[plane], w, h, ax, ay, pick_above);
840
        break;
841
    case 1:
842
        block_fill(frame->data[plane], size, frame->linesize[plane], w, h, ax, ay, pick_left);
843
        break;
844
    case 2:
845
        {
846
            int arr1[16];
847
            int arr2[16];
848
            uint8_t *top = frame->data[plane] + FFMAX(ay - 1, 0) * frame->linesize[plane] + ax;
849
            uint8_t *left = frame->data[plane] + ay * frame->linesize[plane] + FFMAX(ax - 1, 0);
850
            int bottommost = frame->data[plane][(ay + size - 1) * frame->linesize[plane] + FFMAX(ax - 1, 0)];
851
            int rightmost = frame->data[plane][FFMAX(ay - 1, 0) * frame->linesize[plane] + ax + size - 1];
852
            int avg = (bottommost + rightmost + 1) / 2 + 2 * av_clip(get_se_golomb(gb), -(1<<16), 1<<16);
853
            int r6 = adjust(avg - bottommost, size);
854
            int r9 = adjust(avg - rightmost, size);
855
            int shift = adjust(size, size) == 8 ? 3 : 2;
856
            uint8_t *block;
857
858
            for (int x = 0; x < size; x++) {
859
                int val = top[x];
860
                arr1[x] = adjust(((bottommost - val) * (1 << shift)) + r6 * (x + 1), size);
861
            }
862
863
            for (int y = 0; y < size; y++) {
864
                int val = left[y * frame->linesize[plane]];
865
                arr2[y] = adjust(((rightmost - val) * (1 << shift)) + r9 * (y + 1), size);
866
            }
867
868
            block = frame->data[plane] + ay * frame->linesize[plane] + ax;
869
            for (int y = 0; y < size; y++) {
870
                for (int x = 0; x < size; x++) {
871
                    block[x] = (((top[x] + left[0] + ((arr1[x] * (y + 1) +
872
                                                       arr2[y] * (x + 1)) >> 2 * shift)) + 1) / 2) & 0xFF;
873
                }
874
                block += frame->linesize[plane];
875
                left  += frame->linesize[plane];
876
            }
877
        }
878
        break;
879
    case 3:
880
        {
881
            uint8_t fill;
882
883
            if (ax == 0 && ay == 0) {
884
                fill = 0x80;
885
            } else if (ax >= 1 && ay >= 1) {
886
                int left = block_sum(frame->data[plane] + ay * frame->linesize[plane] + ax - 1,
887
                                     1, size, frame->linesize[plane]);
888
                int top  = block_sum(frame->data[plane] + (ay - 1) * frame->linesize[plane] + ax,
889
                                     size, 1, frame->linesize[plane]);
890
891
                fill = ((left + top) * 2 / (2 * size) + 1) / 2;
892
            } else if (ax >= 1) {
893
                fill = (block_sum(frame->data[plane] + ay * frame->linesize[plane] + ax - 1,
894
                                  1, size, frame->linesize[plane]) * 2 / size + 1) / 2;
895
            } else if (ay >= 1) {
896
                fill = (block_sum(frame->data[plane] + (ay - 1) * frame->linesize[plane] + ax,
897
                                  size, 1, frame->linesize[plane]) * 2 / size + 1) / 2;
898
            } else {
899
                return -1;
900
            }
901
902
            block_fill_simple(frame->data[plane] + ay * frame->linesize[plane] + ax,
903
                              size, frame->linesize[plane], fill);
904
        }
905
        break;
906
    case 4:
907
        block_fill(frame->data[plane], size, frame->linesize[plane], w, h, ax, ay, pick_4);
908
        break;
909
    case 5:
910
        block_fill(frame->data[plane], size, frame->linesize[plane], w, h, ax, ay, pick_5);
911
        break;
912
    case 6:
913
        block_fill(frame->data[plane], size, frame->linesize[plane], w, h, ax, ay, pick_6);
914
        break;
915
    case 7:
916
        block_fill(frame->data[plane], size, frame->linesize[plane], w, h, ax, ay, pick_7);
917
        break;
918
    case 8:
919
        block_fill(frame->data[plane], size, frame->linesize[plane], w, h, ax, ay, pick_8);
920
        break;
921
    }
922
923
    if (add_coeffs)
924
        ret = add_coefficients(avctx, frame, ax, ay, size, plane);
925
926
    return ret;
927
}
928
929
static int get_prediction(AVCodecContext *avctx, int x, int y, int size)
930
{
931
    MobiClipContext *s = avctx->priv_data;
932
    GetBitContext *gb = &s->gb;
933
    int index = (y & 0xC) | (x / 4 % 4);
934
935
    uint8_t val = FFMIN(s->pre[index], index % 4 == 0 ? 9 : s->pre[index + 3]);
936
    if (val == 9)
937
        val = 3;
938
939
    if (!get_bits1(gb)) {
940
        int x = get_bits(gb, 3);
941
        val = x + (x >= val ? 1 : 0);
942
    }
943
944
    s->pre[index + 4] = val;
945
    if (size == 8)
946
        s->pre[index + 5] = s->pre[index + 8] = s->pre[index + 9] = val;
947
948
    return val;
949
}
950
951
static int process_block(AVCodecContext *avctx, AVFrame *frame,
952
                         int x, int y, int pmode, int has_coeffs, int plane)
953
{
954
    MobiClipContext *s = avctx->priv_data;
955
    GetBitContext *gb = &s->gb;
956
    int tmp, ret;
957
958
    if (!has_coeffs) {
959
        if (pmode < 0)
960
            pmode = get_prediction(avctx, x, y, 8);
961
        return predict_intra(avctx, frame, x, y, pmode, 0, 8, plane);
962
    }
963
964
    tmp = get_ue_golomb_31(gb);
965
    if ((unsigned)tmp > FF_ARRAY_ELEMS(block4x4_coefficients_tab))
966
        return AVERROR_INVALIDDATA;
967
968
    if (tmp == 0) {
969
        if (pmode < 0)
970
            pmode = get_prediction(avctx, x, y, 8);
971
        ret = predict_intra(avctx, frame, x, y, pmode, 1, 8, plane);
972
    } else {
973
        int flags = block4x4_coefficients_tab[tmp - 1];
974
975
        for (int by = y; by < y + 8; by += 4) {
976
            for (int bx = x; bx < x + 8; bx += 4) {
977
                int new_pmode = pmode;
978
979
                if (new_pmode < 0)
980
                    new_pmode = get_prediction(avctx, bx, by, 4);
981
                ret = predict_intra(avctx, frame, bx, by, new_pmode, flags & 1, 4, plane);
982
                if (ret < 0)
983
                    return ret;
984
                flags >>= 1;
985
            }
986
        }
987
    }
988
989
    return ret;
990
}
991
992
static int decode_macroblock(AVCodecContext *avctx, AVFrame *frame,
993
                             int x, int y, int predict)
994
{
995
    MobiClipContext *s = avctx->priv_data;
996
    GetBitContext *gb = &s->gb;
997
    int flags, pmode_uv, idx = get_ue_golomb(gb);
998
    int ret = 0;
999
1000
    if (idx < 0 || idx >= FF_ARRAY_ELEMS(block8x8_coefficients_tab))
1001
        return AVERROR_INVALIDDATA;
1002
1003
    flags = block8x8_coefficients_tab[idx];
1004
1005
    if (predict) {
1006
        ret = process_block(avctx, frame, x, y, -1, flags & 1, 0);
1007
        if (ret < 0)
1008
            return ret;
1009
        flags >>= 1;
1010
        ret = process_block(avctx, frame, x + 8, y, -1, flags & 1, 0);
1011
        if (ret < 0)
1012
            return ret;
1013
        flags >>= 1;
1014
        ret = process_block(avctx, frame, x, y + 8, -1, flags & 1, 0);
1015
        if (ret < 0)
1016
            return ret;
1017
        flags >>= 1;
1018
        ret = process_block(avctx, frame, x + 8, y + 8, -1, flags & 1, 0);
1019
        if (ret < 0)
1020
            return ret;
1021
        flags >>= 1;
1022
    } else {
1023
        int pmode = get_bits(gb, 3);
1024
1025
        if (pmode == 2) {
1026
            ret = predict_intra(avctx, frame, x, y, pmode, 0, 16, 0);
1027
            if (ret < 0)
1028
                return ret;
1029
            pmode = 9;
1030
        }
1031
1032
        ret = process_block(avctx, frame, x, y, pmode, flags & 1, 0);
1033
        if (ret < 0)
1034
            return ret;
1035
        flags >>= 1;
1036
        ret = process_block(avctx, frame, x + 8, y, pmode, flags & 1, 0);
1037
        if (ret < 0)
1038
            return ret;
1039
        flags >>= 1;
1040
        ret = process_block(avctx, frame, x, y + 8, pmode, flags & 1, 0);
1041
        if (ret < 0)
1042
            return ret;
1043
        flags >>= 1;
1044
        ret = process_block(avctx, frame, x + 8, y + 8, pmode, flags & 1, 0);
1045
        if (ret < 0)
1046
            return ret;
1047
        flags >>= 1;
1048
    }
1049
1050
    pmode_uv = get_bits(gb, 3);
1051
    if (pmode_uv == 2) {
1052
        ret = predict_intra(avctx, frame, x >> 1, y >> 1, pmode_uv, 0, 8, 1 + !s->moflex);
1053
        if (ret < 0)
1054
            return ret;
1055
        ret = predict_intra(avctx, frame, x >> 1, y >> 1, pmode_uv, 0, 8, 2 - !s->moflex);
1056
        if (ret < 0)
1057
            return ret;
1058
        pmode_uv = 9;
1059
    }
1060
1061
    ret = process_block(avctx, frame, x >> 1, y >> 1, pmode_uv, flags & 1, 1 + !s->moflex);
1062
    if (ret < 0)
1063
        return ret;
1064
    flags >>= 1;
1065
    ret = process_block(avctx, frame, x >> 1, y >> 1, pmode_uv, flags & 1, 2 - !s->moflex);
1066
    if (ret < 0)
1067
        return ret;
1068
1069
    return 0;
1070
}
1071
1072
static int get_index(int x)
1073
{
1074
    return x == 16 ? 0 : x == 8 ? 1 : x == 4 ? 2 : x == 2 ? 3 : 0;
1075
}
1076
1077
static int predict_motion(AVCodecContext *avctx,
1078
                          int width, int height, int index,
1079
                          int offsetm, int offsetx, int offsety)
1080
{
1081
    MobiClipContext *s = avctx->priv_data;
1082
    MotionXY *motion = s->motion;
1083
    GetBitContext *gb = &s->gb;
1084
    int fheight = avctx->height;
1085
    int fwidth = avctx->width;
1086
1087
    if (index <= 5) {
1088
        int sidx = -FFMAX(1, index) + s->current_pic;
1089
        MotionXY mv = s->motion[0];
1090
1091
        if (sidx < 0)
1092
            sidx += 6;
1093
1094
        if (index > 0) {
1095
            mv.x = mv.x + (unsigned)get_se_golomb(gb);
1096
            mv.y = mv.y + (unsigned)get_se_golomb(gb);
1097
        }
1098
        if (mv.x >= INT_MAX || mv.y >= INT_MAX)
1099
            return AVERROR_INVALIDDATA;
1100
1101
        motion[offsetm].x = mv.x;
1102
        motion[offsetm].y = mv.y;
1103
1104
        for (int i = 0; i < 3; i++) {
1105
            int method, src_linesize, dst_linesize;
1106
            uint8_t *src, *dst;
1107
1108
            if (i == 1) {
1109
                offsetx = offsetx >> 1;
1110
                offsety = offsety >> 1;
1111
                mv.x = mv.x >> 1;
1112
                mv.y = mv.y >> 1;
1113
                width = width >> 1;
1114
                height = height >> 1;
1115
                fwidth = fwidth >> 1;
1116
                fheight = fheight >> 1;
1117
            }
1118
1119
            av_assert0(s->pic[sidx]);
1120
            av_assert0(s->pic[s->current_pic]);
1121
            av_assert0(s->pic[s->current_pic]->data[i]);
1122
            if (!s->pic[sidx]->data[i])
1123
                return AVERROR_INVALIDDATA;
1124
1125
            method = (mv.x & 1) | ((mv.y & 1) << 1);
1126
            src_linesize = s->pic[sidx]->linesize[i];
1127
            dst_linesize = s->pic[s->current_pic]->linesize[i];
1128
            dst = s->pic[s->current_pic]->data[i] + offsetx + offsety * dst_linesize;
1129
1130
            if (offsetx + (mv.x >> 1) < 0 ||
1131
                offsety + (mv.y >> 1) < 0 ||
1132
                offsetx + width  + (mv.x + 1 >> 1) > fwidth ||
1133
                offsety + height + (mv.y + 1 >> 1) > fheight)
1134
                return AVERROR_INVALIDDATA;
1135
1136
            switch (method) {
1137
            case 0:
1138
                src = s->pic[sidx]->data[i] + offsetx + (mv.x >> 1) +
1139
                               (offsety + (mv.y >> 1)) * src_linesize;
1140
                for (int y = 0; y < height; y++) {
1141
                    for (int x = 0; x < width; x++)
1142
                        dst[x] = src[x];
1143
                    dst += dst_linesize;
1144
                    src += src_linesize;
1145
                }
1146
                break;
1147
            case 1:
1148
                src = s->pic[sidx]->data[i] + offsetx + (mv.x >> 1) +
1149
                               (offsety + (mv.y >> 1)) * src_linesize;
1150
                for (int y = 0; y < height; y++) {
1151
                    for (int x = 0; x < width; x++) {
1152
                        dst[x] = (uint8_t)((src[x] >> 1) + (src[x + 1] >> 1));
1153
                    }
1154
1155
                    dst += dst_linesize;
1156
                    src += src_linesize;
1157
                }
1158
                break;
1159
            case 2:
1160
                src = s->pic[sidx]->data[i] + offsetx + (mv.x >> 1) +
1161
                               (offsety + (mv.y >> 1)) * src_linesize;
1162
                for (int y = 0; y < height; y++) {
1163
                    for (int x = 0; x < width; x++) {
1164
                        dst[x] = (uint8_t)((src[x] >> 1) + (src[x + src_linesize] >> 1));
1165
                    }
1166
1167
                    dst += dst_linesize;
1168
                    src += src_linesize;
1169
                }
1170
                break;
1171
            case 3:
1172
                src = s->pic[sidx]->data[i] + offsetx + (mv.x >> 1) +
1173
                               (offsety + (mv.y >> 1)) * src_linesize;
1174
                for (int y = 0; y < height; y++) {
1175
                    for (int x = 0; x < width; x++) {
1176
                        dst[x] = (uint8_t)((((src[x] >> 1) + (src[x + 1] >> 1)) >> 1) +
1177
                                           (((src[x + src_linesize] >> 1) + (src[x + 1 + src_linesize] >> 1)) >> 1));
1178
                    }
1179
1180
                    dst += dst_linesize;
1181
                    src += src_linesize;
1182
                }
1183
                break;
1184
            }
1185
        }
1186
    } else {
1187
        int tidx;
1188
        int adjx = index == 8 ? 0 :  width / 2;
1189
        int adjy = index == 8 ? height / 2 : 0;
1190
1191
        width  = width  - adjx;
1192
        height = height - adjy;
1193
        tidx = get_index(height) * 4 + get_index(width);
1194
1195
        for (int i = 0; i < 2; i++) {
1196
            int ret, idx2;
1197
1198
            idx2 = get_vlc2(gb, mv_vlc[s->moflex][tidx].table,
1199
                            MOBI_MV_VLC_BITS, 1);
1200
1201
            ret = predict_motion(avctx, width, height, idx2,
1202
                                 offsetm, offsetx + i * adjx, offsety + i * adjy);
1203
            if (ret < 0)
1204
                return ret;
1205
        }
1206
    }
1207
1208
    return 0;
1209
}
1210
1211
static int mobiclip_decode(AVCodecContext *avctx, void *data,
1212
                            int *got_frame, AVPacket *pkt)
1213
{
1214
    MobiClipContext *s = avctx->priv_data;
1215
    GetBitContext *gb = &s->gb;
1216
    AVFrame *frame = s->pic[s->current_pic];
1217
    int ret;
1218
1219
    av_fast_padded_malloc(&s->bitstream, &s->bitstream_size,
1220
                          pkt->size);
1221
1222
    if ((ret = ff_reget_buffer(avctx, frame, 0)) < 0)
1223
        return ret;
1224
1225
    s->bdsp.bswap16_buf((uint16_t *)s->bitstream,
1226
                        (uint16_t *)pkt->data,
1227
                        (pkt->size + 1) >> 1);
1228
1229
    ret = init_get_bits8(gb, s->bitstream, FFALIGN(pkt->size, 2));
1230
    if (ret < 0)
1231
        return ret;
1232
1233
    if (get_bits1(gb)) {
1234
        frame->pict_type = AV_PICTURE_TYPE_I;
1235
        frame->key_frame = 1;
1236
        s->moflex = get_bits1(gb);
1237
        s->dct_tab_idx = get_bits1(gb);
1238
1239
        ret = setup_qtables(avctx, get_bits(gb, 6));
1240
        if (ret < 0)
1241
            return ret;
1242
1243
        for (int y = 0; y < avctx->height; y += 16) {
1244
            for (int x = 0; x < avctx->width; x += 16) {
1245
                ret = decode_macroblock(avctx, frame, x, y, get_bits1(gb));
1246
                if (ret < 0)
1247
                    return ret;
1248
            }
1249
        }
1250
    } else {
1251
        MotionXY *motion = s->motion;
1252
1253
        memset(motion, 0, s->motion_size);
1254
1255
        frame->pict_type = AV_PICTURE_TYPE_P;
1256
        frame->key_frame = 0;
1257
        s->dct_tab_idx = 0;
1258
1259
        ret = setup_qtables(avctx, s->quantizer + get_se_golomb(gb));
1260
        if (ret < 0)
1261
            return ret;
1262
1263
        for (int y = 0; y < avctx->height; y += 16) {
1264
            for (int x = 0; x < avctx->width; x += 16) {
1265
                int idx;
1266
1267
                motion[0].x = mid_pred(motion[x / 16 + 1].x, motion[x / 16 + 2].x, motion[x / 16 + 3].x);
1268
                motion[0].y = mid_pred(motion[x / 16 + 1].y, motion[x / 16 + 2].y, motion[x / 16 + 3].y);
1269
                motion[x / 16 + 2].x = 0;
1270
                motion[x / 16 + 2].y = 0;
1271
1272
                idx = get_vlc2(gb, mv_vlc[s->moflex][0].table,
1273
                                   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);
1285
                    if (idx2 >= FF_ARRAY_ELEMS(pframe_block8x8_coefficients_tab))
1286
                        return AVERROR_INVALIDDATA;
1287
                    flags = pframe_block8x8_coefficients_tab[idx2];
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(data, frame);
1312
    if (ret < 0)
1313
        return ret;
1314
    *got_frame = 1;
1315
1316
    return 0;
1317
}
1318
1319
static void mobiclip_flush(AVCodecContext *avctx)
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
1327
static av_cold int mobiclip_close(AVCodecContext *avctx)
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
1343
AVCodec ff_mobiclip_decoder = {
1344
    .name           = "mobiclip",
1345
    .long_name      = NULL_IF_CONFIG_SMALL("MobiClip Video"),
1346
    .type           = AVMEDIA_TYPE_VIDEO,
1347
    .id             = AV_CODEC_ID_MOBICLIP,
1348
    .priv_data_size = sizeof(MobiClipContext),
1349
    .init           = mobiclip_init,
1350
    .decode         = mobiclip_decode,
1351
    .flush          = mobiclip_flush,
1352
    .close          = mobiclip_close,
1353
    .capabilities   = AV_CODEC_CAP_DR1,
1354
    .caps_internal  = FF_CODEC_CAP_INIT_THREADSAFE | FF_CODEC_CAP_INIT_CLEANUP,
1355
};