xref: /third_party/ffmpeg/libavcodec/svq1dec.c (revision cabdff1a)
1cabdff1aSopenharmony_ci/*
2cabdff1aSopenharmony_ci * SVQ1 decoder
3cabdff1aSopenharmony_ci * ported to MPlayer by Arpi <arpi@thot.banki.hu>
4cabdff1aSopenharmony_ci * ported to libavcodec by Nick Kurshev <nickols_k@mail.ru>
5cabdff1aSopenharmony_ci *
6cabdff1aSopenharmony_ci * Copyright (c) 2002 The Xine project
7cabdff1aSopenharmony_ci * Copyright (c) 2002 The FFmpeg project
8cabdff1aSopenharmony_ci *
9cabdff1aSopenharmony_ci * SVQ1 Encoder (c) 2004 Mike Melanson <melanson@pcisys.net>
10cabdff1aSopenharmony_ci *
11cabdff1aSopenharmony_ci * This file is part of FFmpeg.
12cabdff1aSopenharmony_ci *
13cabdff1aSopenharmony_ci * FFmpeg is free software; you can redistribute it and/or
14cabdff1aSopenharmony_ci * modify it under the terms of the GNU Lesser General Public
15cabdff1aSopenharmony_ci * License as published by the Free Software Foundation; either
16cabdff1aSopenharmony_ci * version 2.1 of the License, or (at your option) any later version.
17cabdff1aSopenharmony_ci *
18cabdff1aSopenharmony_ci * FFmpeg is distributed in the hope that it will be useful,
19cabdff1aSopenharmony_ci * but WITHOUT ANY WARRANTY; without even the implied warranty of
20cabdff1aSopenharmony_ci * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
21cabdff1aSopenharmony_ci * Lesser General Public License for more details.
22cabdff1aSopenharmony_ci *
23cabdff1aSopenharmony_ci * You should have received a copy of the GNU Lesser General Public
24cabdff1aSopenharmony_ci * License along with FFmpeg; if not, write to the Free Software
25cabdff1aSopenharmony_ci * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
26cabdff1aSopenharmony_ci */
27cabdff1aSopenharmony_ci
28cabdff1aSopenharmony_ci/**
29cabdff1aSopenharmony_ci * @file
30cabdff1aSopenharmony_ci * Sorenson Vector Quantizer #1 (SVQ1) video codec.
31cabdff1aSopenharmony_ci * For more information of the SVQ1 algorithm, visit:
32cabdff1aSopenharmony_ci *   http://www.pcisys.net/~melanson/codecs/
33cabdff1aSopenharmony_ci */
34cabdff1aSopenharmony_ci
35cabdff1aSopenharmony_ci#include "libavutil/crc.h"
36cabdff1aSopenharmony_ci#include "libavutil/thread.h"
37cabdff1aSopenharmony_ci
38cabdff1aSopenharmony_ci#include "avcodec.h"
39cabdff1aSopenharmony_ci#include "codec_internal.h"
40cabdff1aSopenharmony_ci#include "get_bits.h"
41cabdff1aSopenharmony_ci#include "h263data.h"
42cabdff1aSopenharmony_ci#include "hpeldsp.h"
43cabdff1aSopenharmony_ci#include "internal.h"
44cabdff1aSopenharmony_ci#include "mathops.h"
45cabdff1aSopenharmony_ci#include "svq1.h"
46cabdff1aSopenharmony_ci
47cabdff1aSopenharmony_ci#define SVQ1_BLOCK_TYPE_VLC_BITS 3
48cabdff1aSopenharmony_cistatic VLC svq1_block_type;
49cabdff1aSopenharmony_cistatic VLC svq1_motion_component;
50cabdff1aSopenharmony_cistatic VLC svq1_intra_multistage[6];
51cabdff1aSopenharmony_cistatic VLC svq1_inter_multistage[6];
52cabdff1aSopenharmony_cistatic VLC svq1_intra_mean;
53cabdff1aSopenharmony_cistatic VLC svq1_inter_mean;
54cabdff1aSopenharmony_ci
55cabdff1aSopenharmony_ci/* motion vector (prediction) */
56cabdff1aSopenharmony_citypedef struct svq1_pmv_s {
57cabdff1aSopenharmony_ci    int x;
58cabdff1aSopenharmony_ci    int y;
59cabdff1aSopenharmony_ci} svq1_pmv;
60cabdff1aSopenharmony_ci
61cabdff1aSopenharmony_citypedef struct SVQ1Context {
62cabdff1aSopenharmony_ci    HpelDSPContext hdsp;
63cabdff1aSopenharmony_ci    GetBitContext gb;
64cabdff1aSopenharmony_ci    AVFrame *prev;
65cabdff1aSopenharmony_ci
66cabdff1aSopenharmony_ci    uint8_t *pkt_swapped;
67cabdff1aSopenharmony_ci    int pkt_swapped_allocated;
68cabdff1aSopenharmony_ci
69cabdff1aSopenharmony_ci    svq1_pmv *pmv;
70cabdff1aSopenharmony_ci    int pmv_allocated;
71cabdff1aSopenharmony_ci
72cabdff1aSopenharmony_ci    int width;
73cabdff1aSopenharmony_ci    int height;
74cabdff1aSopenharmony_ci    int frame_code;
75cabdff1aSopenharmony_ci    int nonref;         // 1 if the current frame won't be referenced
76cabdff1aSopenharmony_ci} SVQ1Context;
77cabdff1aSopenharmony_ci
78cabdff1aSopenharmony_cistatic const uint8_t string_table[256] = {
79cabdff1aSopenharmony_ci    0x00, 0xD5, 0x7F, 0xAA, 0xFE, 0x2B, 0x81, 0x54,
80cabdff1aSopenharmony_ci    0x29, 0xFC, 0x56, 0x83, 0xD7, 0x02, 0xA8, 0x7D,
81cabdff1aSopenharmony_ci    0x52, 0x87, 0x2D, 0xF8, 0xAC, 0x79, 0xD3, 0x06,
82cabdff1aSopenharmony_ci    0x7B, 0xAE, 0x04, 0xD1, 0x85, 0x50, 0xFA, 0x2F,
83cabdff1aSopenharmony_ci    0xA4, 0x71, 0xDB, 0x0E, 0x5A, 0x8F, 0x25, 0xF0,
84cabdff1aSopenharmony_ci    0x8D, 0x58, 0xF2, 0x27, 0x73, 0xA6, 0x0C, 0xD9,
85cabdff1aSopenharmony_ci    0xF6, 0x23, 0x89, 0x5C, 0x08, 0xDD, 0x77, 0xA2,
86cabdff1aSopenharmony_ci    0xDF, 0x0A, 0xA0, 0x75, 0x21, 0xF4, 0x5E, 0x8B,
87cabdff1aSopenharmony_ci    0x9D, 0x48, 0xE2, 0x37, 0x63, 0xB6, 0x1C, 0xC9,
88cabdff1aSopenharmony_ci    0xB4, 0x61, 0xCB, 0x1E, 0x4A, 0x9F, 0x35, 0xE0,
89cabdff1aSopenharmony_ci    0xCF, 0x1A, 0xB0, 0x65, 0x31, 0xE4, 0x4E, 0x9B,
90cabdff1aSopenharmony_ci    0xE6, 0x33, 0x99, 0x4C, 0x18, 0xCD, 0x67, 0xB2,
91cabdff1aSopenharmony_ci    0x39, 0xEC, 0x46, 0x93, 0xC7, 0x12, 0xB8, 0x6D,
92cabdff1aSopenharmony_ci    0x10, 0xC5, 0x6F, 0xBA, 0xEE, 0x3B, 0x91, 0x44,
93cabdff1aSopenharmony_ci    0x6B, 0xBE, 0x14, 0xC1, 0x95, 0x40, 0xEA, 0x3F,
94cabdff1aSopenharmony_ci    0x42, 0x97, 0x3D, 0xE8, 0xBC, 0x69, 0xC3, 0x16,
95cabdff1aSopenharmony_ci    0xEF, 0x3A, 0x90, 0x45, 0x11, 0xC4, 0x6E, 0xBB,
96cabdff1aSopenharmony_ci    0xC6, 0x13, 0xB9, 0x6C, 0x38, 0xED, 0x47, 0x92,
97cabdff1aSopenharmony_ci    0xBD, 0x68, 0xC2, 0x17, 0x43, 0x96, 0x3C, 0xE9,
98cabdff1aSopenharmony_ci    0x94, 0x41, 0xEB, 0x3E, 0x6A, 0xBF, 0x15, 0xC0,
99cabdff1aSopenharmony_ci    0x4B, 0x9E, 0x34, 0xE1, 0xB5, 0x60, 0xCA, 0x1F,
100cabdff1aSopenharmony_ci    0x62, 0xB7, 0x1D, 0xC8, 0x9C, 0x49, 0xE3, 0x36,
101cabdff1aSopenharmony_ci    0x19, 0xCC, 0x66, 0xB3, 0xE7, 0x32, 0x98, 0x4D,
102cabdff1aSopenharmony_ci    0x30, 0xE5, 0x4F, 0x9A, 0xCE, 0x1B, 0xB1, 0x64,
103cabdff1aSopenharmony_ci    0x72, 0xA7, 0x0D, 0xD8, 0x8C, 0x59, 0xF3, 0x26,
104cabdff1aSopenharmony_ci    0x5B, 0x8E, 0x24, 0xF1, 0xA5, 0x70, 0xDA, 0x0F,
105cabdff1aSopenharmony_ci    0x20, 0xF5, 0x5F, 0x8A, 0xDE, 0x0B, 0xA1, 0x74,
106cabdff1aSopenharmony_ci    0x09, 0xDC, 0x76, 0xA3, 0xF7, 0x22, 0x88, 0x5D,
107cabdff1aSopenharmony_ci    0xD6, 0x03, 0xA9, 0x7C, 0x28, 0xFD, 0x57, 0x82,
108cabdff1aSopenharmony_ci    0xFF, 0x2A, 0x80, 0x55, 0x01, 0xD4, 0x7E, 0xAB,
109cabdff1aSopenharmony_ci    0x84, 0x51, 0xFB, 0x2E, 0x7A, 0xAF, 0x05, 0xD0,
110cabdff1aSopenharmony_ci    0xAD, 0x78, 0xD2, 0x07, 0x53, 0x86, 0x2C, 0xF9
111cabdff1aSopenharmony_ci};
112cabdff1aSopenharmony_ci
113cabdff1aSopenharmony_ci#define SVQ1_PROCESS_VECTOR()                                           \
114cabdff1aSopenharmony_ci    for (; level > 0; i++) {                                            \
115cabdff1aSopenharmony_ci        /* process next depth */                                        \
116cabdff1aSopenharmony_ci        if (i == m) {                                                   \
117cabdff1aSopenharmony_ci            m = n;                                                      \
118cabdff1aSopenharmony_ci            if (--level == 0)                                           \
119cabdff1aSopenharmony_ci                break;                                                  \
120cabdff1aSopenharmony_ci        }                                                               \
121cabdff1aSopenharmony_ci        /* divide block if next bit set */                              \
122cabdff1aSopenharmony_ci        if (!get_bits1(bitbuf))                                         \
123cabdff1aSopenharmony_ci            break;                                                      \
124cabdff1aSopenharmony_ci        /* add child nodes */                                           \
125cabdff1aSopenharmony_ci        list[n++] = list[i];                                            \
126cabdff1aSopenharmony_ci        list[n++] = list[i] + (((level & 1) ? pitch : 1) << ((level >> 1) + 1));\
127cabdff1aSopenharmony_ci    }
128cabdff1aSopenharmony_ci
129cabdff1aSopenharmony_ci#define SVQ1_ADD_CODEBOOK()                                             \
130cabdff1aSopenharmony_ci    /* add codebook entries to vector */                                \
131cabdff1aSopenharmony_ci    for (j = 0; j < stages; j++) {                                      \
132cabdff1aSopenharmony_ci        n3  = codebook[entries[j]] ^ 0x80808080;                        \
133cabdff1aSopenharmony_ci        n1 += (n3 & 0xFF00FF00) >> 8;                                   \
134cabdff1aSopenharmony_ci        n2 +=  n3 & 0x00FF00FF;                                         \
135cabdff1aSopenharmony_ci    }                                                                   \
136cabdff1aSopenharmony_ci                                                                        \
137cabdff1aSopenharmony_ci    /* clip to [0..255] */                                              \
138cabdff1aSopenharmony_ci    if (n1 & 0xFF00FF00) {                                              \
139cabdff1aSopenharmony_ci        n3  = (n1 >> 15  & 0x00010001 | 0x01000100) - 0x00010001;       \
140cabdff1aSopenharmony_ci        n1 += 0x7F007F00;                                               \
141cabdff1aSopenharmony_ci        n1 |= (~n1 >> 15 & 0x00010001 | 0x01000100) - 0x00010001;       \
142cabdff1aSopenharmony_ci        n1 &= n3 & 0x00FF00FF;                                          \
143cabdff1aSopenharmony_ci    }                                                                   \
144cabdff1aSopenharmony_ci                                                                        \
145cabdff1aSopenharmony_ci    if (n2 & 0xFF00FF00) {                                              \
146cabdff1aSopenharmony_ci        n3  = (n2 >> 15  & 0x00010001 | 0x01000100) - 0x00010001;       \
147cabdff1aSopenharmony_ci        n2 += 0x7F007F00;                                               \
148cabdff1aSopenharmony_ci        n2 |= (~n2 >> 15 & 0x00010001 | 0x01000100) - 0x00010001;       \
149cabdff1aSopenharmony_ci        n2 &= n3 & 0x00FF00FF;                                          \
150cabdff1aSopenharmony_ci    }
151cabdff1aSopenharmony_ci
152cabdff1aSopenharmony_ci#define SVQ1_CALC_CODEBOOK_ENTRIES(cbook)                               \
153cabdff1aSopenharmony_ci    codebook = (const uint32_t *)cbook[level];                          \
154cabdff1aSopenharmony_ci    if (stages > 0)                                                     \
155cabdff1aSopenharmony_ci        bit_cache = get_bits(bitbuf, 4 * stages);                       \
156cabdff1aSopenharmony_ci    /* calculate codebook entries for this vector */                    \
157cabdff1aSopenharmony_ci    for (j = 0; j < stages; j++) {                                      \
158cabdff1aSopenharmony_ci        entries[j] = (((bit_cache >> (4 * (stages - j - 1))) & 0xF) +   \
159cabdff1aSopenharmony_ci                      16 * j) << (level + 1);                           \
160cabdff1aSopenharmony_ci    }                                                                   \
161cabdff1aSopenharmony_ci    mean -= stages * 128;                                               \
162cabdff1aSopenharmony_ci    n4    = (mean << 16) + mean;
163cabdff1aSopenharmony_ci
164cabdff1aSopenharmony_cistatic int svq1_decode_block_intra(GetBitContext *bitbuf, uint8_t *pixels,
165cabdff1aSopenharmony_ci                                   ptrdiff_t pitch)
166cabdff1aSopenharmony_ci{
167cabdff1aSopenharmony_ci    uint32_t bit_cache;
168cabdff1aSopenharmony_ci    uint8_t *list[63];
169cabdff1aSopenharmony_ci    uint32_t *dst;
170cabdff1aSopenharmony_ci    const uint32_t *codebook;
171cabdff1aSopenharmony_ci    int entries[6];
172cabdff1aSopenharmony_ci    int i, j, m, n;
173cabdff1aSopenharmony_ci    int stages;
174cabdff1aSopenharmony_ci    unsigned mean;
175cabdff1aSopenharmony_ci    unsigned x, y, width, height, level;
176cabdff1aSopenharmony_ci    uint32_t n1, n2, n3, n4;
177cabdff1aSopenharmony_ci
178cabdff1aSopenharmony_ci    /* initialize list for breadth first processing of vectors */
179cabdff1aSopenharmony_ci    list[0] = pixels;
180cabdff1aSopenharmony_ci
181cabdff1aSopenharmony_ci    /* recursively process vector */
182cabdff1aSopenharmony_ci    for (i = 0, m = 1, n = 1, level = 5; i < n; i++) {
183cabdff1aSopenharmony_ci        SVQ1_PROCESS_VECTOR();
184cabdff1aSopenharmony_ci
185cabdff1aSopenharmony_ci        /* destination address and vector size */
186cabdff1aSopenharmony_ci        dst    = (uint32_t *)list[i];
187cabdff1aSopenharmony_ci        width  = 1 << ((4 + level) / 2);
188cabdff1aSopenharmony_ci        height = 1 << ((3 + level) / 2);
189cabdff1aSopenharmony_ci
190cabdff1aSopenharmony_ci        /* get number of stages (-1 skips vector, 0 for mean only) */
191cabdff1aSopenharmony_ci        stages = get_vlc2(bitbuf, svq1_intra_multistage[level].table, 3, 3) - 1;
192cabdff1aSopenharmony_ci
193cabdff1aSopenharmony_ci        if (stages == -1) {
194cabdff1aSopenharmony_ci            for (y = 0; y < height; y++)
195cabdff1aSopenharmony_ci                memset(&dst[y * (pitch / 4)], 0, width);
196cabdff1aSopenharmony_ci            continue;   /* skip vector */
197cabdff1aSopenharmony_ci        }
198cabdff1aSopenharmony_ci
199cabdff1aSopenharmony_ci        if ((stages > 0 && level >= 4)) {
200cabdff1aSopenharmony_ci            ff_dlog(NULL,
201cabdff1aSopenharmony_ci                    "Error (svq1_decode_block_intra): invalid vector: stages=%i level=%i\n",
202cabdff1aSopenharmony_ci                    stages, level);
203cabdff1aSopenharmony_ci            return AVERROR_INVALIDDATA;  /* invalid vector */
204cabdff1aSopenharmony_ci        }
205cabdff1aSopenharmony_ci        av_assert0(stages >= 0);
206cabdff1aSopenharmony_ci
207cabdff1aSopenharmony_ci        mean = get_vlc2(bitbuf, svq1_intra_mean.table, 8, 3);
208cabdff1aSopenharmony_ci
209cabdff1aSopenharmony_ci        if (stages == 0) {
210cabdff1aSopenharmony_ci            for (y = 0; y < height; y++)
211cabdff1aSopenharmony_ci                memset(&dst[y * (pitch / 4)], mean, width);
212cabdff1aSopenharmony_ci        } else {
213cabdff1aSopenharmony_ci            SVQ1_CALC_CODEBOOK_ENTRIES(ff_svq1_intra_codebooks);
214cabdff1aSopenharmony_ci
215cabdff1aSopenharmony_ci            for (y = 0; y < height; y++) {
216cabdff1aSopenharmony_ci                for (x = 0; x < width / 4; x++, codebook++) {
217cabdff1aSopenharmony_ci                    n1 = n4;
218cabdff1aSopenharmony_ci                    n2 = n4;
219cabdff1aSopenharmony_ci                    SVQ1_ADD_CODEBOOK()
220cabdff1aSopenharmony_ci                    /* store result */
221cabdff1aSopenharmony_ci                    dst[x] = n1 << 8 | n2;
222cabdff1aSopenharmony_ci                }
223cabdff1aSopenharmony_ci                dst += pitch / 4;
224cabdff1aSopenharmony_ci            }
225cabdff1aSopenharmony_ci        }
226cabdff1aSopenharmony_ci    }
227cabdff1aSopenharmony_ci
228cabdff1aSopenharmony_ci    return 0;
229cabdff1aSopenharmony_ci}
230cabdff1aSopenharmony_ci
231cabdff1aSopenharmony_cistatic int svq1_decode_block_non_intra(GetBitContext *bitbuf, uint8_t *pixels,
232cabdff1aSopenharmony_ci                                       ptrdiff_t pitch)
233cabdff1aSopenharmony_ci{
234cabdff1aSopenharmony_ci    uint32_t bit_cache;
235cabdff1aSopenharmony_ci    uint8_t *list[63];
236cabdff1aSopenharmony_ci    uint32_t *dst;
237cabdff1aSopenharmony_ci    const uint32_t *codebook;
238cabdff1aSopenharmony_ci    int entries[6];
239cabdff1aSopenharmony_ci    int i, j, m, n;
240cabdff1aSopenharmony_ci    int stages;
241cabdff1aSopenharmony_ci    unsigned mean;
242cabdff1aSopenharmony_ci    int x, y, width, height, level;
243cabdff1aSopenharmony_ci    uint32_t n1, n2, n3, n4;
244cabdff1aSopenharmony_ci
245cabdff1aSopenharmony_ci    /* initialize list for breadth first processing of vectors */
246cabdff1aSopenharmony_ci    list[0] = pixels;
247cabdff1aSopenharmony_ci
248cabdff1aSopenharmony_ci    /* recursively process vector */
249cabdff1aSopenharmony_ci    for (i = 0, m = 1, n = 1, level = 5; i < n; i++) {
250cabdff1aSopenharmony_ci        SVQ1_PROCESS_VECTOR();
251cabdff1aSopenharmony_ci
252cabdff1aSopenharmony_ci        /* destination address and vector size */
253cabdff1aSopenharmony_ci        dst    = (uint32_t *)list[i];
254cabdff1aSopenharmony_ci        width  = 1 << ((4 + level) / 2);
255cabdff1aSopenharmony_ci        height = 1 << ((3 + level) / 2);
256cabdff1aSopenharmony_ci
257cabdff1aSopenharmony_ci        /* get number of stages (-1 skips vector, 0 for mean only) */
258cabdff1aSopenharmony_ci        stages = get_vlc2(bitbuf, svq1_inter_multistage[level].table, 3, 2) - 1;
259cabdff1aSopenharmony_ci
260cabdff1aSopenharmony_ci        if (stages == -1)
261cabdff1aSopenharmony_ci            continue;           /* skip vector */
262cabdff1aSopenharmony_ci
263cabdff1aSopenharmony_ci        if ((stages > 0 && level >= 4)) {
264cabdff1aSopenharmony_ci            ff_dlog(NULL,
265cabdff1aSopenharmony_ci                    "Error (svq1_decode_block_non_intra): invalid vector: stages=%i level=%i\n",
266cabdff1aSopenharmony_ci                    stages, level);
267cabdff1aSopenharmony_ci            return AVERROR_INVALIDDATA;  /* invalid vector */
268cabdff1aSopenharmony_ci        }
269cabdff1aSopenharmony_ci        av_assert0(stages >= 0);
270cabdff1aSopenharmony_ci
271cabdff1aSopenharmony_ci        mean = get_vlc2(bitbuf, svq1_inter_mean.table, 9, 3) - 256;
272cabdff1aSopenharmony_ci
273cabdff1aSopenharmony_ci        SVQ1_CALC_CODEBOOK_ENTRIES(ff_svq1_inter_codebooks);
274cabdff1aSopenharmony_ci
275cabdff1aSopenharmony_ci        for (y = 0; y < height; y++) {
276cabdff1aSopenharmony_ci            for (x = 0; x < width / 4; x++, codebook++) {
277cabdff1aSopenharmony_ci                n3 = dst[x];
278cabdff1aSopenharmony_ci                /* add mean value to vector */
279cabdff1aSopenharmony_ci                n1 = n4 + ((n3 & 0xFF00FF00) >> 8);
280cabdff1aSopenharmony_ci                n2 = n4 +  (n3 & 0x00FF00FF);
281cabdff1aSopenharmony_ci                SVQ1_ADD_CODEBOOK()
282cabdff1aSopenharmony_ci                /* store result */
283cabdff1aSopenharmony_ci                dst[x] = n1 << 8 | n2;
284cabdff1aSopenharmony_ci            }
285cabdff1aSopenharmony_ci            dst += pitch / 4;
286cabdff1aSopenharmony_ci        }
287cabdff1aSopenharmony_ci    }
288cabdff1aSopenharmony_ci    return 0;
289cabdff1aSopenharmony_ci}
290cabdff1aSopenharmony_ci
291cabdff1aSopenharmony_cistatic int svq1_decode_motion_vector(GetBitContext *bitbuf, svq1_pmv *mv,
292cabdff1aSopenharmony_ci                                     svq1_pmv **pmv)
293cabdff1aSopenharmony_ci{
294cabdff1aSopenharmony_ci    int diff;
295cabdff1aSopenharmony_ci    int i;
296cabdff1aSopenharmony_ci
297cabdff1aSopenharmony_ci    for (i = 0; i < 2; i++) {
298cabdff1aSopenharmony_ci        /* get motion code */
299cabdff1aSopenharmony_ci        diff = get_vlc2(bitbuf, svq1_motion_component.table, 7, 2);
300cabdff1aSopenharmony_ci        if (diff < 0)
301cabdff1aSopenharmony_ci            return AVERROR_INVALIDDATA;
302cabdff1aSopenharmony_ci        else if (diff) {
303cabdff1aSopenharmony_ci            if (get_bits1(bitbuf))
304cabdff1aSopenharmony_ci                diff = -diff;
305cabdff1aSopenharmony_ci        }
306cabdff1aSopenharmony_ci
307cabdff1aSopenharmony_ci        /* add median of motion vector predictors and clip result */
308cabdff1aSopenharmony_ci        if (i == 1)
309cabdff1aSopenharmony_ci            mv->y = sign_extend(diff + mid_pred(pmv[0]->y, pmv[1]->y, pmv[2]->y), 6);
310cabdff1aSopenharmony_ci        else
311cabdff1aSopenharmony_ci            mv->x = sign_extend(diff + mid_pred(pmv[0]->x, pmv[1]->x, pmv[2]->x), 6);
312cabdff1aSopenharmony_ci    }
313cabdff1aSopenharmony_ci
314cabdff1aSopenharmony_ci    return 0;
315cabdff1aSopenharmony_ci}
316cabdff1aSopenharmony_ci
317cabdff1aSopenharmony_cistatic void svq1_skip_block(uint8_t *current, uint8_t *previous,
318cabdff1aSopenharmony_ci                            ptrdiff_t pitch, int x, int y)
319cabdff1aSopenharmony_ci{
320cabdff1aSopenharmony_ci    uint8_t *src;
321cabdff1aSopenharmony_ci    uint8_t *dst;
322cabdff1aSopenharmony_ci    int i;
323cabdff1aSopenharmony_ci
324cabdff1aSopenharmony_ci    src = &previous[x + y * pitch];
325cabdff1aSopenharmony_ci    dst = current;
326cabdff1aSopenharmony_ci
327cabdff1aSopenharmony_ci    for (i = 0; i < 16; i++) {
328cabdff1aSopenharmony_ci        memcpy(dst, src, 16);
329cabdff1aSopenharmony_ci        src += pitch;
330cabdff1aSopenharmony_ci        dst += pitch;
331cabdff1aSopenharmony_ci    }
332cabdff1aSopenharmony_ci}
333cabdff1aSopenharmony_ci
334cabdff1aSopenharmony_cistatic int svq1_motion_inter_block(HpelDSPContext *hdsp, GetBitContext *bitbuf,
335cabdff1aSopenharmony_ci                                   uint8_t *current, uint8_t *previous,
336cabdff1aSopenharmony_ci                                   ptrdiff_t pitch, svq1_pmv *motion, int x, int y,
337cabdff1aSopenharmony_ci                                   int width, int height)
338cabdff1aSopenharmony_ci{
339cabdff1aSopenharmony_ci    uint8_t *src;
340cabdff1aSopenharmony_ci    uint8_t *dst;
341cabdff1aSopenharmony_ci    svq1_pmv mv;
342cabdff1aSopenharmony_ci    svq1_pmv *pmv[3];
343cabdff1aSopenharmony_ci    int result;
344cabdff1aSopenharmony_ci
345cabdff1aSopenharmony_ci    /* predict and decode motion vector */
346cabdff1aSopenharmony_ci    pmv[0] = &motion[0];
347cabdff1aSopenharmony_ci    if (y == 0) {
348cabdff1aSopenharmony_ci        pmv[1] =
349cabdff1aSopenharmony_ci        pmv[2] = pmv[0];
350cabdff1aSopenharmony_ci    } else {
351cabdff1aSopenharmony_ci        pmv[1] = &motion[x / 8 + 2];
352cabdff1aSopenharmony_ci        pmv[2] = &motion[x / 8 + 4];
353cabdff1aSopenharmony_ci    }
354cabdff1aSopenharmony_ci
355cabdff1aSopenharmony_ci    result = svq1_decode_motion_vector(bitbuf, &mv, pmv);
356cabdff1aSopenharmony_ci    if (result)
357cabdff1aSopenharmony_ci        return result;
358cabdff1aSopenharmony_ci
359cabdff1aSopenharmony_ci    motion[0].x         =
360cabdff1aSopenharmony_ci    motion[x / 8 + 2].x =
361cabdff1aSopenharmony_ci    motion[x / 8 + 3].x = mv.x;
362cabdff1aSopenharmony_ci    motion[0].y         =
363cabdff1aSopenharmony_ci    motion[x / 8 + 2].y =
364cabdff1aSopenharmony_ci    motion[x / 8 + 3].y = mv.y;
365cabdff1aSopenharmony_ci
366cabdff1aSopenharmony_ci    mv.x = av_clip(mv.x, -2 * x, 2 * (width  - x - 16));
367cabdff1aSopenharmony_ci    mv.y = av_clip(mv.y, -2 * y, 2 * (height - y - 16));
368cabdff1aSopenharmony_ci
369cabdff1aSopenharmony_ci    src = &previous[(x + (mv.x >> 1)) + (y + (mv.y >> 1)) * pitch];
370cabdff1aSopenharmony_ci    dst = current;
371cabdff1aSopenharmony_ci
372cabdff1aSopenharmony_ci    hdsp->put_pixels_tab[0][(mv.y & 1) << 1 | (mv.x & 1)](dst, src, pitch, 16);
373cabdff1aSopenharmony_ci
374cabdff1aSopenharmony_ci    return 0;
375cabdff1aSopenharmony_ci}
376cabdff1aSopenharmony_ci
377cabdff1aSopenharmony_cistatic int svq1_motion_inter_4v_block(HpelDSPContext *hdsp, GetBitContext *bitbuf,
378cabdff1aSopenharmony_ci                                      uint8_t *current, uint8_t *previous,
379cabdff1aSopenharmony_ci                                      ptrdiff_t pitch, svq1_pmv *motion, int x, int y,
380cabdff1aSopenharmony_ci                                      int width, int height)
381cabdff1aSopenharmony_ci{
382cabdff1aSopenharmony_ci    uint8_t *src;
383cabdff1aSopenharmony_ci    uint8_t *dst;
384cabdff1aSopenharmony_ci    svq1_pmv mv;
385cabdff1aSopenharmony_ci    svq1_pmv *pmv[4];
386cabdff1aSopenharmony_ci    int i, result;
387cabdff1aSopenharmony_ci
388cabdff1aSopenharmony_ci    /* predict and decode motion vector (0) */
389cabdff1aSopenharmony_ci    pmv[0] = &motion[0];
390cabdff1aSopenharmony_ci    if (y == 0) {
391cabdff1aSopenharmony_ci        pmv[1] =
392cabdff1aSopenharmony_ci        pmv[2] = pmv[0];
393cabdff1aSopenharmony_ci    } else {
394cabdff1aSopenharmony_ci        pmv[1] = &motion[(x / 8) + 2];
395cabdff1aSopenharmony_ci        pmv[2] = &motion[(x / 8) + 4];
396cabdff1aSopenharmony_ci    }
397cabdff1aSopenharmony_ci
398cabdff1aSopenharmony_ci    result = svq1_decode_motion_vector(bitbuf, &mv, pmv);
399cabdff1aSopenharmony_ci    if (result)
400cabdff1aSopenharmony_ci        return result;
401cabdff1aSopenharmony_ci
402cabdff1aSopenharmony_ci    /* predict and decode motion vector (1) */
403cabdff1aSopenharmony_ci    pmv[0] = &mv;
404cabdff1aSopenharmony_ci    if (y == 0) {
405cabdff1aSopenharmony_ci        pmv[1] =
406cabdff1aSopenharmony_ci        pmv[2] = pmv[0];
407cabdff1aSopenharmony_ci    } else {
408cabdff1aSopenharmony_ci        pmv[1] = &motion[(x / 8) + 3];
409cabdff1aSopenharmony_ci    }
410cabdff1aSopenharmony_ci    result = svq1_decode_motion_vector(bitbuf, &motion[0], pmv);
411cabdff1aSopenharmony_ci    if (result)
412cabdff1aSopenharmony_ci        return result;
413cabdff1aSopenharmony_ci
414cabdff1aSopenharmony_ci    /* predict and decode motion vector (2) */
415cabdff1aSopenharmony_ci    pmv[1] = &motion[0];
416cabdff1aSopenharmony_ci    pmv[2] = &motion[(x / 8) + 1];
417cabdff1aSopenharmony_ci
418cabdff1aSopenharmony_ci    result = svq1_decode_motion_vector(bitbuf, &motion[(x / 8) + 2], pmv);
419cabdff1aSopenharmony_ci    if (result)
420cabdff1aSopenharmony_ci        return result;
421cabdff1aSopenharmony_ci
422cabdff1aSopenharmony_ci    /* predict and decode motion vector (3) */
423cabdff1aSopenharmony_ci    pmv[2] = &motion[(x / 8) + 2];
424cabdff1aSopenharmony_ci    pmv[3] = &motion[(x / 8) + 3];
425cabdff1aSopenharmony_ci
426cabdff1aSopenharmony_ci    result = svq1_decode_motion_vector(bitbuf, pmv[3], pmv);
427cabdff1aSopenharmony_ci    if (result)
428cabdff1aSopenharmony_ci        return result;
429cabdff1aSopenharmony_ci
430cabdff1aSopenharmony_ci    /* form predictions */
431cabdff1aSopenharmony_ci    for (i = 0; i < 4; i++) {
432cabdff1aSopenharmony_ci        int mvx = pmv[i]->x + (i  & 1) * 16;
433cabdff1aSopenharmony_ci        int mvy = pmv[i]->y + (i >> 1) * 16;
434cabdff1aSopenharmony_ci
435cabdff1aSopenharmony_ci        // FIXME: clipping or padding?
436cabdff1aSopenharmony_ci        mvx = av_clip(mvx, -2 * x, 2 * (width  - x - 8));
437cabdff1aSopenharmony_ci        mvy = av_clip(mvy, -2 * y, 2 * (height - y - 8));
438cabdff1aSopenharmony_ci
439cabdff1aSopenharmony_ci        src = &previous[(x + (mvx >> 1)) + (y + (mvy >> 1)) * pitch];
440cabdff1aSopenharmony_ci        dst = current;
441cabdff1aSopenharmony_ci
442cabdff1aSopenharmony_ci        hdsp->put_pixels_tab[1][((mvy & 1) << 1) | (mvx & 1)](dst, src, pitch, 8);
443cabdff1aSopenharmony_ci
444cabdff1aSopenharmony_ci        /* select next block */
445cabdff1aSopenharmony_ci        if (i & 1)
446cabdff1aSopenharmony_ci            current += 8 * (pitch - 1);
447cabdff1aSopenharmony_ci        else
448cabdff1aSopenharmony_ci            current += 8;
449cabdff1aSopenharmony_ci    }
450cabdff1aSopenharmony_ci
451cabdff1aSopenharmony_ci    return 0;
452cabdff1aSopenharmony_ci}
453cabdff1aSopenharmony_ci
454cabdff1aSopenharmony_cistatic int svq1_decode_delta_block(AVCodecContext *avctx, HpelDSPContext *hdsp,
455cabdff1aSopenharmony_ci                                   GetBitContext *bitbuf,
456cabdff1aSopenharmony_ci                                   uint8_t *current, uint8_t *previous,
457cabdff1aSopenharmony_ci                                   ptrdiff_t pitch, svq1_pmv *motion, int x, int y,
458cabdff1aSopenharmony_ci                                   int width, int height)
459cabdff1aSopenharmony_ci{
460cabdff1aSopenharmony_ci    uint32_t block_type;
461cabdff1aSopenharmony_ci    int result = 0;
462cabdff1aSopenharmony_ci
463cabdff1aSopenharmony_ci    /* get block type */
464cabdff1aSopenharmony_ci    block_type = get_vlc2(bitbuf, svq1_block_type.table,
465cabdff1aSopenharmony_ci                          SVQ1_BLOCK_TYPE_VLC_BITS, 1);
466cabdff1aSopenharmony_ci
467cabdff1aSopenharmony_ci    /* reset motion vectors */
468cabdff1aSopenharmony_ci    if (block_type == SVQ1_BLOCK_SKIP || block_type == SVQ1_BLOCK_INTRA) {
469cabdff1aSopenharmony_ci        motion[0].x         =
470cabdff1aSopenharmony_ci        motion[0].y         =
471cabdff1aSopenharmony_ci        motion[x / 8 + 2].x =
472cabdff1aSopenharmony_ci        motion[x / 8 + 2].y =
473cabdff1aSopenharmony_ci        motion[x / 8 + 3].x =
474cabdff1aSopenharmony_ci        motion[x / 8 + 3].y = 0;
475cabdff1aSopenharmony_ci    }
476cabdff1aSopenharmony_ci
477cabdff1aSopenharmony_ci    switch (block_type) {
478cabdff1aSopenharmony_ci    case SVQ1_BLOCK_SKIP:
479cabdff1aSopenharmony_ci        svq1_skip_block(current, previous, pitch, x, y);
480cabdff1aSopenharmony_ci        break;
481cabdff1aSopenharmony_ci
482cabdff1aSopenharmony_ci    case SVQ1_BLOCK_INTER:
483cabdff1aSopenharmony_ci        result = svq1_motion_inter_block(hdsp, bitbuf, current, previous,
484cabdff1aSopenharmony_ci                                         pitch, motion, x, y, width, height);
485cabdff1aSopenharmony_ci
486cabdff1aSopenharmony_ci        if (result != 0) {
487cabdff1aSopenharmony_ci            ff_dlog(avctx, "Error in svq1_motion_inter_block %i\n", result);
488cabdff1aSopenharmony_ci            break;
489cabdff1aSopenharmony_ci        }
490cabdff1aSopenharmony_ci        result = svq1_decode_block_non_intra(bitbuf, current, pitch);
491cabdff1aSopenharmony_ci        break;
492cabdff1aSopenharmony_ci
493cabdff1aSopenharmony_ci    case SVQ1_BLOCK_INTER_4V:
494cabdff1aSopenharmony_ci        result = svq1_motion_inter_4v_block(hdsp, bitbuf, current, previous,
495cabdff1aSopenharmony_ci                                            pitch, motion, x, y, width, height);
496cabdff1aSopenharmony_ci
497cabdff1aSopenharmony_ci        if (result != 0) {
498cabdff1aSopenharmony_ci            ff_dlog(avctx, "Error in svq1_motion_inter_4v_block %i\n", result);
499cabdff1aSopenharmony_ci            break;
500cabdff1aSopenharmony_ci        }
501cabdff1aSopenharmony_ci        result = svq1_decode_block_non_intra(bitbuf, current, pitch);
502cabdff1aSopenharmony_ci        break;
503cabdff1aSopenharmony_ci
504cabdff1aSopenharmony_ci    case SVQ1_BLOCK_INTRA:
505cabdff1aSopenharmony_ci        result = svq1_decode_block_intra(bitbuf, current, pitch);
506cabdff1aSopenharmony_ci        break;
507cabdff1aSopenharmony_ci    }
508cabdff1aSopenharmony_ci
509cabdff1aSopenharmony_ci    return result;
510cabdff1aSopenharmony_ci}
511cabdff1aSopenharmony_ci
512cabdff1aSopenharmony_cistatic void svq1_parse_string(GetBitContext *bitbuf, uint8_t out[257])
513cabdff1aSopenharmony_ci{
514cabdff1aSopenharmony_ci    uint8_t seed;
515cabdff1aSopenharmony_ci    int i;
516cabdff1aSopenharmony_ci
517cabdff1aSopenharmony_ci    out[0] = get_bits(bitbuf, 8);
518cabdff1aSopenharmony_ci    seed   = string_table[out[0]];
519cabdff1aSopenharmony_ci
520cabdff1aSopenharmony_ci    for (i = 1; i <= out[0]; i++) {
521cabdff1aSopenharmony_ci        out[i] = get_bits(bitbuf, 8) ^ seed;
522cabdff1aSopenharmony_ci        seed   = string_table[out[i] ^ seed];
523cabdff1aSopenharmony_ci    }
524cabdff1aSopenharmony_ci    out[i] = 0;
525cabdff1aSopenharmony_ci}
526cabdff1aSopenharmony_ci
527cabdff1aSopenharmony_cistatic int svq1_decode_frame_header(AVCodecContext *avctx, AVFrame *frame)
528cabdff1aSopenharmony_ci{
529cabdff1aSopenharmony_ci    SVQ1Context *s = avctx->priv_data;
530cabdff1aSopenharmony_ci    GetBitContext *bitbuf = &s->gb;
531cabdff1aSopenharmony_ci    int frame_size_code;
532cabdff1aSopenharmony_ci    int width  = s->width;
533cabdff1aSopenharmony_ci    int height = s->height;
534cabdff1aSopenharmony_ci
535cabdff1aSopenharmony_ci    skip_bits(bitbuf, 8); /* temporal_reference */
536cabdff1aSopenharmony_ci
537cabdff1aSopenharmony_ci    /* frame type */
538cabdff1aSopenharmony_ci    s->nonref = 0;
539cabdff1aSopenharmony_ci    switch (get_bits(bitbuf, 2)) {
540cabdff1aSopenharmony_ci    case 0:
541cabdff1aSopenharmony_ci        frame->pict_type = AV_PICTURE_TYPE_I;
542cabdff1aSopenharmony_ci        break;
543cabdff1aSopenharmony_ci    case 2:
544cabdff1aSopenharmony_ci        s->nonref = 1;
545cabdff1aSopenharmony_ci    case 1:
546cabdff1aSopenharmony_ci        frame->pict_type = AV_PICTURE_TYPE_P;
547cabdff1aSopenharmony_ci        break;
548cabdff1aSopenharmony_ci    default:
549cabdff1aSopenharmony_ci        av_log(avctx, AV_LOG_ERROR, "Invalid frame type.\n");
550cabdff1aSopenharmony_ci        return AVERROR_INVALIDDATA;
551cabdff1aSopenharmony_ci    }
552cabdff1aSopenharmony_ci
553cabdff1aSopenharmony_ci    if (frame->pict_type == AV_PICTURE_TYPE_I) {
554cabdff1aSopenharmony_ci        /* unknown fields */
555cabdff1aSopenharmony_ci        if (s->frame_code == 0x50 || s->frame_code == 0x60) {
556cabdff1aSopenharmony_ci            int csum = get_bits(bitbuf, 16);
557cabdff1aSopenharmony_ci
558cabdff1aSopenharmony_ci            csum = av_bswap16(av_crc(av_crc_get_table(AV_CRC_16_CCITT), av_bswap16(csum), bitbuf->buffer, bitbuf->size_in_bits >> 3));
559cabdff1aSopenharmony_ci
560cabdff1aSopenharmony_ci            ff_dlog(avctx, "%s checksum (%02x) for packet data\n",
561cabdff1aSopenharmony_ci                    (csum == 0) ? "correct" : "incorrect", csum);
562cabdff1aSopenharmony_ci        }
563cabdff1aSopenharmony_ci
564cabdff1aSopenharmony_ci        if ((s->frame_code ^ 0x10) >= 0x50) {
565cabdff1aSopenharmony_ci            uint8_t msg[257];
566cabdff1aSopenharmony_ci
567cabdff1aSopenharmony_ci            svq1_parse_string(bitbuf, msg);
568cabdff1aSopenharmony_ci
569cabdff1aSopenharmony_ci            av_log(avctx, AV_LOG_INFO,
570cabdff1aSopenharmony_ci                   "embedded message:\n%s\n", ((char *)msg) + 1);
571cabdff1aSopenharmony_ci        }
572cabdff1aSopenharmony_ci
573cabdff1aSopenharmony_ci        skip_bits(bitbuf, 2);
574cabdff1aSopenharmony_ci        skip_bits(bitbuf, 2);
575cabdff1aSopenharmony_ci        skip_bits1(bitbuf);
576cabdff1aSopenharmony_ci
577cabdff1aSopenharmony_ci        /* load frame size */
578cabdff1aSopenharmony_ci        frame_size_code = get_bits(bitbuf, 3);
579cabdff1aSopenharmony_ci
580cabdff1aSopenharmony_ci        if (frame_size_code == 7) {
581cabdff1aSopenharmony_ci            /* load width, height (12 bits each) */
582cabdff1aSopenharmony_ci            width  = get_bits(bitbuf, 12);
583cabdff1aSopenharmony_ci            height = get_bits(bitbuf, 12);
584cabdff1aSopenharmony_ci
585cabdff1aSopenharmony_ci            if (!width || !height)
586cabdff1aSopenharmony_ci                return AVERROR_INVALIDDATA;
587cabdff1aSopenharmony_ci        } else {
588cabdff1aSopenharmony_ci            /* get width, height from table */
589cabdff1aSopenharmony_ci            width  = ff_svq1_frame_size_table[frame_size_code][0];
590cabdff1aSopenharmony_ci            height = ff_svq1_frame_size_table[frame_size_code][1];
591cabdff1aSopenharmony_ci        }
592cabdff1aSopenharmony_ci    }
593cabdff1aSopenharmony_ci
594cabdff1aSopenharmony_ci    /* unknown fields */
595cabdff1aSopenharmony_ci    if (get_bits1(bitbuf)) {
596cabdff1aSopenharmony_ci        skip_bits1(bitbuf);    /* use packet checksum if (1) */
597cabdff1aSopenharmony_ci        skip_bits1(bitbuf);    /* component checksums after image data if (1) */
598cabdff1aSopenharmony_ci
599cabdff1aSopenharmony_ci        if (get_bits(bitbuf, 2) != 0)
600cabdff1aSopenharmony_ci            return AVERROR_INVALIDDATA;
601cabdff1aSopenharmony_ci    }
602cabdff1aSopenharmony_ci
603cabdff1aSopenharmony_ci    if (get_bits1(bitbuf)) {
604cabdff1aSopenharmony_ci        skip_bits1(bitbuf);
605cabdff1aSopenharmony_ci        skip_bits(bitbuf, 4);
606cabdff1aSopenharmony_ci        skip_bits1(bitbuf);
607cabdff1aSopenharmony_ci        skip_bits(bitbuf, 2);
608cabdff1aSopenharmony_ci
609cabdff1aSopenharmony_ci        if (skip_1stop_8data_bits(bitbuf) < 0)
610cabdff1aSopenharmony_ci            return AVERROR_INVALIDDATA;
611cabdff1aSopenharmony_ci    }
612cabdff1aSopenharmony_ci    if (get_bits_left(bitbuf) <= 0)
613cabdff1aSopenharmony_ci        return AVERROR_INVALIDDATA;
614cabdff1aSopenharmony_ci
615cabdff1aSopenharmony_ci    s->width  = width;
616cabdff1aSopenharmony_ci    s->height = height;
617cabdff1aSopenharmony_ci    return 0;
618cabdff1aSopenharmony_ci}
619cabdff1aSopenharmony_ci
620cabdff1aSopenharmony_cistatic int svq1_decode_frame(AVCodecContext *avctx, AVFrame *cur,
621cabdff1aSopenharmony_ci                             int *got_frame, AVPacket *avpkt)
622cabdff1aSopenharmony_ci{
623cabdff1aSopenharmony_ci    const uint8_t *buf = avpkt->data;
624cabdff1aSopenharmony_ci    int buf_size       = avpkt->size;
625cabdff1aSopenharmony_ci    SVQ1Context     *s = avctx->priv_data;
626cabdff1aSopenharmony_ci    uint8_t *current;
627cabdff1aSopenharmony_ci    int result, i, x, y, width, height;
628cabdff1aSopenharmony_ci    int ret;
629cabdff1aSopenharmony_ci
630cabdff1aSopenharmony_ci    /* initialize bit buffer */
631cabdff1aSopenharmony_ci    ret = init_get_bits8(&s->gb, buf, buf_size);
632cabdff1aSopenharmony_ci    if (ret < 0)
633cabdff1aSopenharmony_ci        return ret;
634cabdff1aSopenharmony_ci
635cabdff1aSopenharmony_ci    /* decode frame header */
636cabdff1aSopenharmony_ci    s->frame_code = get_bits(&s->gb, 22);
637cabdff1aSopenharmony_ci
638cabdff1aSopenharmony_ci    if ((s->frame_code & ~0x70) || !(s->frame_code & 0x60))
639cabdff1aSopenharmony_ci        return AVERROR_INVALIDDATA;
640cabdff1aSopenharmony_ci
641cabdff1aSopenharmony_ci    /* swap some header bytes (why?) */
642cabdff1aSopenharmony_ci    if (s->frame_code != 0x20) {
643cabdff1aSopenharmony_ci        uint32_t *src;
644cabdff1aSopenharmony_ci
645cabdff1aSopenharmony_ci        if (buf_size < 9 * 4) {
646cabdff1aSopenharmony_ci            av_log(avctx, AV_LOG_ERROR, "Input packet too small\n");
647cabdff1aSopenharmony_ci            return AVERROR_INVALIDDATA;
648cabdff1aSopenharmony_ci        }
649cabdff1aSopenharmony_ci
650cabdff1aSopenharmony_ci        av_fast_padded_malloc(&s->pkt_swapped,
651cabdff1aSopenharmony_ci                              &s->pkt_swapped_allocated,
652cabdff1aSopenharmony_ci                              buf_size);
653cabdff1aSopenharmony_ci        if (!s->pkt_swapped)
654cabdff1aSopenharmony_ci            return AVERROR(ENOMEM);
655cabdff1aSopenharmony_ci
656cabdff1aSopenharmony_ci        memcpy(s->pkt_swapped, buf, buf_size);
657cabdff1aSopenharmony_ci        buf = s->pkt_swapped;
658cabdff1aSopenharmony_ci        init_get_bits(&s->gb, buf, buf_size * 8);
659cabdff1aSopenharmony_ci        skip_bits(&s->gb, 22);
660cabdff1aSopenharmony_ci
661cabdff1aSopenharmony_ci        src = (uint32_t *)(s->pkt_swapped + 4);
662cabdff1aSopenharmony_ci
663cabdff1aSopenharmony_ci        for (i = 0; i < 4; i++)
664cabdff1aSopenharmony_ci            src[i] = ((src[i] << 16) | (src[i] >> 16)) ^ src[7 - i];
665cabdff1aSopenharmony_ci    }
666cabdff1aSopenharmony_ci
667cabdff1aSopenharmony_ci    result = svq1_decode_frame_header(avctx, cur);
668cabdff1aSopenharmony_ci    if (result != 0) {
669cabdff1aSopenharmony_ci        ff_dlog(avctx, "Error in svq1_decode_frame_header %i\n", result);
670cabdff1aSopenharmony_ci        return result;
671cabdff1aSopenharmony_ci    }
672cabdff1aSopenharmony_ci
673cabdff1aSopenharmony_ci    result = ff_set_dimensions(avctx, s->width, s->height);
674cabdff1aSopenharmony_ci    if (result < 0)
675cabdff1aSopenharmony_ci        return result;
676cabdff1aSopenharmony_ci
677cabdff1aSopenharmony_ci    if ((avctx->skip_frame >= AVDISCARD_NONREF && s->nonref) ||
678cabdff1aSopenharmony_ci        (avctx->skip_frame >= AVDISCARD_NONKEY &&
679cabdff1aSopenharmony_ci         cur->pict_type != AV_PICTURE_TYPE_I) ||
680cabdff1aSopenharmony_ci        avctx->skip_frame >= AVDISCARD_ALL)
681cabdff1aSopenharmony_ci        return buf_size;
682cabdff1aSopenharmony_ci
683cabdff1aSopenharmony_ci    result = ff_get_buffer(avctx, cur, s->nonref ? 0 : AV_GET_BUFFER_FLAG_REF);
684cabdff1aSopenharmony_ci    if (result < 0)
685cabdff1aSopenharmony_ci        return result;
686cabdff1aSopenharmony_ci
687cabdff1aSopenharmony_ci    av_fast_padded_malloc(&s->pmv, &s->pmv_allocated, (FFALIGN(s->width, 16) / 8 + 3) * sizeof(*s->pmv));
688cabdff1aSopenharmony_ci    if (!s->pmv)
689cabdff1aSopenharmony_ci        return AVERROR(ENOMEM);
690cabdff1aSopenharmony_ci
691cabdff1aSopenharmony_ci    /* decode y, u and v components */
692cabdff1aSopenharmony_ci    for (i = 0; i < 3; i++) {
693cabdff1aSopenharmony_ci        int linesize = cur->linesize[i];
694cabdff1aSopenharmony_ci        if (i == 0) {
695cabdff1aSopenharmony_ci            width    = FFALIGN(s->width,  16);
696cabdff1aSopenharmony_ci            height   = FFALIGN(s->height, 16);
697cabdff1aSopenharmony_ci        } else {
698cabdff1aSopenharmony_ci            if (avctx->flags & AV_CODEC_FLAG_GRAY)
699cabdff1aSopenharmony_ci                break;
700cabdff1aSopenharmony_ci            width    = FFALIGN(s->width  / 4, 16);
701cabdff1aSopenharmony_ci            height   = FFALIGN(s->height / 4, 16);
702cabdff1aSopenharmony_ci        }
703cabdff1aSopenharmony_ci
704cabdff1aSopenharmony_ci        current = cur->data[i];
705cabdff1aSopenharmony_ci
706cabdff1aSopenharmony_ci        if (cur->pict_type == AV_PICTURE_TYPE_I) {
707cabdff1aSopenharmony_ci            /* keyframe */
708cabdff1aSopenharmony_ci            for (y = 0; y < height; y += 16) {
709cabdff1aSopenharmony_ci                for (x = 0; x < width; x += 16) {
710cabdff1aSopenharmony_ci                    result = svq1_decode_block_intra(&s->gb, &current[x],
711cabdff1aSopenharmony_ci                                                     linesize);
712cabdff1aSopenharmony_ci                    if (result) {
713cabdff1aSopenharmony_ci                        av_log(avctx, AV_LOG_ERROR,
714cabdff1aSopenharmony_ci                               "Error in svq1_decode_block %i (keyframe)\n",
715cabdff1aSopenharmony_ci                               result);
716cabdff1aSopenharmony_ci                        return result;
717cabdff1aSopenharmony_ci                    }
718cabdff1aSopenharmony_ci                }
719cabdff1aSopenharmony_ci                current += 16 * linesize;
720cabdff1aSopenharmony_ci            }
721cabdff1aSopenharmony_ci        } else {
722cabdff1aSopenharmony_ci            /* delta frame */
723cabdff1aSopenharmony_ci            uint8_t *previous = s->prev->data[i];
724cabdff1aSopenharmony_ci            if (!previous ||
725cabdff1aSopenharmony_ci                s->prev->width != s->width || s->prev->height != s->height) {
726cabdff1aSopenharmony_ci                av_log(avctx, AV_LOG_ERROR, "Missing reference frame.\n");
727cabdff1aSopenharmony_ci                return AVERROR_INVALIDDATA;
728cabdff1aSopenharmony_ci            }
729cabdff1aSopenharmony_ci
730cabdff1aSopenharmony_ci            memset(s->pmv, 0, ((width / 8) + 3) * sizeof(svq1_pmv));
731cabdff1aSopenharmony_ci
732cabdff1aSopenharmony_ci            for (y = 0; y < height; y += 16) {
733cabdff1aSopenharmony_ci                for (x = 0; x < width; x += 16) {
734cabdff1aSopenharmony_ci                    result = svq1_decode_delta_block(avctx, &s->hdsp,
735cabdff1aSopenharmony_ci                                                     &s->gb, &current[x],
736cabdff1aSopenharmony_ci                                                     previous, linesize,
737cabdff1aSopenharmony_ci                                                     s->pmv, x, y, width, height);
738cabdff1aSopenharmony_ci                    if (result != 0) {
739cabdff1aSopenharmony_ci                        ff_dlog(avctx,
740cabdff1aSopenharmony_ci                                "Error in svq1_decode_delta_block %i\n",
741cabdff1aSopenharmony_ci                                result);
742cabdff1aSopenharmony_ci                        return result;
743cabdff1aSopenharmony_ci                    }
744cabdff1aSopenharmony_ci                }
745cabdff1aSopenharmony_ci
746cabdff1aSopenharmony_ci                s->pmv[0].x =
747cabdff1aSopenharmony_ci                s->pmv[0].y = 0;
748cabdff1aSopenharmony_ci
749cabdff1aSopenharmony_ci                current += 16 * linesize;
750cabdff1aSopenharmony_ci            }
751cabdff1aSopenharmony_ci        }
752cabdff1aSopenharmony_ci    }
753cabdff1aSopenharmony_ci
754cabdff1aSopenharmony_ci    if (!s->nonref) {
755cabdff1aSopenharmony_ci        av_frame_unref(s->prev);
756cabdff1aSopenharmony_ci        result = av_frame_ref(s->prev, cur);
757cabdff1aSopenharmony_ci        if (result < 0)
758cabdff1aSopenharmony_ci            return result;
759cabdff1aSopenharmony_ci    }
760cabdff1aSopenharmony_ci
761cabdff1aSopenharmony_ci    *got_frame = 1;
762cabdff1aSopenharmony_ci    result     = buf_size;
763cabdff1aSopenharmony_ci
764cabdff1aSopenharmony_ci    return result;
765cabdff1aSopenharmony_ci}
766cabdff1aSopenharmony_ci
767cabdff1aSopenharmony_cistatic av_cold void svq1_static_init(void)
768cabdff1aSopenharmony_ci{
769cabdff1aSopenharmony_ci    INIT_VLC_STATIC(&svq1_block_type, SVQ1_BLOCK_TYPE_VLC_BITS, 4,
770cabdff1aSopenharmony_ci                    &ff_svq1_block_type_vlc[0][1], 2, 1,
771cabdff1aSopenharmony_ci                    &ff_svq1_block_type_vlc[0][0], 2, 1, 8);
772cabdff1aSopenharmony_ci
773cabdff1aSopenharmony_ci    INIT_VLC_STATIC(&svq1_motion_component, 7, 33,
774cabdff1aSopenharmony_ci                    &ff_mvtab[0][1], 2, 1,
775cabdff1aSopenharmony_ci                    &ff_mvtab[0][0], 2, 1, 176);
776cabdff1aSopenharmony_ci
777cabdff1aSopenharmony_ci    for (int i = 0, offset = 0; i < 6; i++) {
778cabdff1aSopenharmony_ci        static const uint8_t sizes[2][6] = { { 14, 10, 14, 18, 16, 18 },
779cabdff1aSopenharmony_ci                                             { 10, 10, 14, 14, 14, 16 } };
780cabdff1aSopenharmony_ci        static VLCElem table[168];
781cabdff1aSopenharmony_ci        svq1_intra_multistage[i].table           = &table[offset];
782cabdff1aSopenharmony_ci        svq1_intra_multistage[i].table_allocated = sizes[0][i];
783cabdff1aSopenharmony_ci        offset                                  += sizes[0][i];
784cabdff1aSopenharmony_ci        init_vlc(&svq1_intra_multistage[i], 3, 8,
785cabdff1aSopenharmony_ci                 &ff_svq1_intra_multistage_vlc[i][0][1], 2, 1,
786cabdff1aSopenharmony_ci                 &ff_svq1_intra_multistage_vlc[i][0][0], 2, 1,
787cabdff1aSopenharmony_ci                 INIT_VLC_USE_NEW_STATIC);
788cabdff1aSopenharmony_ci        svq1_inter_multistage[i].table           = &table[offset];
789cabdff1aSopenharmony_ci        svq1_inter_multistage[i].table_allocated = sizes[1][i];
790cabdff1aSopenharmony_ci        offset                                  += sizes[1][i];
791cabdff1aSopenharmony_ci        init_vlc(&svq1_inter_multistage[i], 3, 8,
792cabdff1aSopenharmony_ci                 &ff_svq1_inter_multistage_vlc[i][0][1], 2, 1,
793cabdff1aSopenharmony_ci                 &ff_svq1_inter_multistage_vlc[i][0][0], 2, 1,
794cabdff1aSopenharmony_ci                 INIT_VLC_USE_NEW_STATIC);
795cabdff1aSopenharmony_ci    }
796cabdff1aSopenharmony_ci
797cabdff1aSopenharmony_ci    INIT_VLC_STATIC(&svq1_intra_mean, 8, 256,
798cabdff1aSopenharmony_ci                    &ff_svq1_intra_mean_vlc[0][1], 4, 2,
799cabdff1aSopenharmony_ci                    &ff_svq1_intra_mean_vlc[0][0], 4, 2, 632);
800cabdff1aSopenharmony_ci
801cabdff1aSopenharmony_ci    INIT_VLC_STATIC(&svq1_inter_mean, 9, 512,
802cabdff1aSopenharmony_ci                    &ff_svq1_inter_mean_vlc[0][1], 4, 2,
803cabdff1aSopenharmony_ci                    &ff_svq1_inter_mean_vlc[0][0], 4, 2, 1434);
804cabdff1aSopenharmony_ci}
805cabdff1aSopenharmony_ci
806cabdff1aSopenharmony_cistatic av_cold int svq1_decode_init(AVCodecContext *avctx)
807cabdff1aSopenharmony_ci{
808cabdff1aSopenharmony_ci    static AVOnce init_static_once = AV_ONCE_INIT;
809cabdff1aSopenharmony_ci    SVQ1Context *s = avctx->priv_data;
810cabdff1aSopenharmony_ci
811cabdff1aSopenharmony_ci    s->prev = av_frame_alloc();
812cabdff1aSopenharmony_ci    if (!s->prev)
813cabdff1aSopenharmony_ci        return AVERROR(ENOMEM);
814cabdff1aSopenharmony_ci
815cabdff1aSopenharmony_ci    s->width            = avctx->width  + 3 & ~3;
816cabdff1aSopenharmony_ci    s->height           = avctx->height + 3 & ~3;
817cabdff1aSopenharmony_ci    avctx->pix_fmt      = AV_PIX_FMT_YUV410P;
818cabdff1aSopenharmony_ci
819cabdff1aSopenharmony_ci    ff_hpeldsp_init(&s->hdsp, avctx->flags);
820cabdff1aSopenharmony_ci
821cabdff1aSopenharmony_ci    ff_thread_once(&init_static_once, svq1_static_init);
822cabdff1aSopenharmony_ci
823cabdff1aSopenharmony_ci    return 0;
824cabdff1aSopenharmony_ci}
825cabdff1aSopenharmony_ci
826cabdff1aSopenharmony_cistatic av_cold int svq1_decode_end(AVCodecContext *avctx)
827cabdff1aSopenharmony_ci{
828cabdff1aSopenharmony_ci    SVQ1Context *s = avctx->priv_data;
829cabdff1aSopenharmony_ci
830cabdff1aSopenharmony_ci    av_frame_free(&s->prev);
831cabdff1aSopenharmony_ci    av_freep(&s->pkt_swapped);
832cabdff1aSopenharmony_ci    s->pkt_swapped_allocated = 0;
833cabdff1aSopenharmony_ci    av_freep(&s->pmv);
834cabdff1aSopenharmony_ci    s->pmv_allocated = 0;
835cabdff1aSopenharmony_ci
836cabdff1aSopenharmony_ci    return 0;
837cabdff1aSopenharmony_ci}
838cabdff1aSopenharmony_ci
839cabdff1aSopenharmony_cistatic void svq1_flush(AVCodecContext *avctx)
840cabdff1aSopenharmony_ci{
841cabdff1aSopenharmony_ci    SVQ1Context *s = avctx->priv_data;
842cabdff1aSopenharmony_ci
843cabdff1aSopenharmony_ci    av_frame_unref(s->prev);
844cabdff1aSopenharmony_ci}
845cabdff1aSopenharmony_ci
846cabdff1aSopenharmony_ciconst FFCodec ff_svq1_decoder = {
847cabdff1aSopenharmony_ci    .p.name         = "svq1",
848cabdff1aSopenharmony_ci    .p.long_name    = NULL_IF_CONFIG_SMALL("Sorenson Vector Quantizer 1 / Sorenson Video 1 / SVQ1"),
849cabdff1aSopenharmony_ci    .p.type         = AVMEDIA_TYPE_VIDEO,
850cabdff1aSopenharmony_ci    .p.id           = AV_CODEC_ID_SVQ1,
851cabdff1aSopenharmony_ci    .priv_data_size = sizeof(SVQ1Context),
852cabdff1aSopenharmony_ci    .init           = svq1_decode_init,
853cabdff1aSopenharmony_ci    .close          = svq1_decode_end,
854cabdff1aSopenharmony_ci    FF_CODEC_DECODE_CB(svq1_decode_frame),
855cabdff1aSopenharmony_ci    .p.capabilities = AV_CODEC_CAP_DR1,
856cabdff1aSopenharmony_ci    .flush          = svq1_flush,
857cabdff1aSopenharmony_ci    .p.pix_fmts     = (const enum AVPixelFormat[]) { AV_PIX_FMT_YUV410P,
858cabdff1aSopenharmony_ci                                                     AV_PIX_FMT_NONE },
859cabdff1aSopenharmony_ci    .caps_internal  = FF_CODEC_CAP_INIT_THREADSAFE,
860cabdff1aSopenharmony_ci};
861