GCC Code Coverage Report
Directory: ../../../ffmpeg/ Exec Total Coverage
File: src/libavcodec/mobiclip.c Lines: 0 710 0.0 %
Date: 2020-09-25 14:59:26 Branches: 0 395 0.0 %

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