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, ¤t[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, ¤t[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