1cabdff1aSopenharmony_ci/* 2cabdff1aSopenharmony_ci * Copyright (c) 2003 The FFmpeg Project 3cabdff1aSopenharmony_ci * 4cabdff1aSopenharmony_ci * This file is part of FFmpeg. 5cabdff1aSopenharmony_ci * 6cabdff1aSopenharmony_ci * FFmpeg is free software; you can redistribute it and/or 7cabdff1aSopenharmony_ci * modify it under the terms of the GNU Lesser General Public 8cabdff1aSopenharmony_ci * License as published by the Free Software Foundation; either 9cabdff1aSopenharmony_ci * version 2.1 of the License, or (at your option) any later version. 10cabdff1aSopenharmony_ci * 11cabdff1aSopenharmony_ci * FFmpeg is distributed in the hope that it will be useful, 12cabdff1aSopenharmony_ci * but WITHOUT ANY WARRANTY; without even the implied warranty of 13cabdff1aSopenharmony_ci * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14cabdff1aSopenharmony_ci * Lesser General Public License for more details. 15cabdff1aSopenharmony_ci * 16cabdff1aSopenharmony_ci * You should have received a copy of the GNU Lesser General Public 17cabdff1aSopenharmony_ci * License along with FFmpeg; if not, write to the Free Software 18cabdff1aSopenharmony_ci * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 19cabdff1aSopenharmony_ci */ 20cabdff1aSopenharmony_ci 21cabdff1aSopenharmony_ci/* 22cabdff1aSopenharmony_ci * How to use this decoder: 23cabdff1aSopenharmony_ci * SVQ3 data is transported within Apple Quicktime files. Quicktime files 24cabdff1aSopenharmony_ci * have stsd atoms to describe media trak properties. A stsd atom for a 25cabdff1aSopenharmony_ci * video trak contains 1 or more ImageDescription atoms. These atoms begin 26cabdff1aSopenharmony_ci * with the 4-byte length of the atom followed by the codec fourcc. Some 27cabdff1aSopenharmony_ci * decoders need information in this atom to operate correctly. Such 28cabdff1aSopenharmony_ci * is the case with SVQ3. In order to get the best use out of this decoder, 29cabdff1aSopenharmony_ci * the calling app must make the SVQ3 ImageDescription atom available 30cabdff1aSopenharmony_ci * via the AVCodecContext's extradata[_size] field: 31cabdff1aSopenharmony_ci * 32cabdff1aSopenharmony_ci * AVCodecContext.extradata = pointer to ImageDescription, first characters 33cabdff1aSopenharmony_ci * are expected to be 'S', 'V', 'Q', and '3', NOT the 4-byte atom length 34cabdff1aSopenharmony_ci * AVCodecContext.extradata_size = size of ImageDescription atom memory 35cabdff1aSopenharmony_ci * buffer (which will be the same as the ImageDescription atom size field 36cabdff1aSopenharmony_ci * from the QT file, minus 4 bytes since the length is missing) 37cabdff1aSopenharmony_ci * 38cabdff1aSopenharmony_ci * You will know you have these parameters passed correctly when the decoder 39cabdff1aSopenharmony_ci * correctly decodes this file: 40cabdff1aSopenharmony_ci * http://samples.mplayerhq.hu/V-codecs/SVQ3/Vertical400kbit.sorenson3.mov 41cabdff1aSopenharmony_ci */ 42cabdff1aSopenharmony_ci 43cabdff1aSopenharmony_ci#include <inttypes.h> 44cabdff1aSopenharmony_ci 45cabdff1aSopenharmony_ci#include "libavutil/attributes.h" 46cabdff1aSopenharmony_ci#include "libavutil/crc.h" 47cabdff1aSopenharmony_ci#include "libavutil/mem_internal.h" 48cabdff1aSopenharmony_ci 49cabdff1aSopenharmony_ci#include "codec_internal.h" 50cabdff1aSopenharmony_ci#include "internal.h" 51cabdff1aSopenharmony_ci#include "avcodec.h" 52cabdff1aSopenharmony_ci#include "mpegutils.h" 53cabdff1aSopenharmony_ci#include "h264data.h" 54cabdff1aSopenharmony_ci#include "h264dsp.h" 55cabdff1aSopenharmony_ci#include "h264pred.h" 56cabdff1aSopenharmony_ci#include "h264_parse.h" 57cabdff1aSopenharmony_ci#include "golomb.h" 58cabdff1aSopenharmony_ci#include "hpeldsp.h" 59cabdff1aSopenharmony_ci#include "mathops.h" 60cabdff1aSopenharmony_ci#include "rectangle.h" 61cabdff1aSopenharmony_ci#include "tpeldsp.h" 62cabdff1aSopenharmony_ci#include "videodsp.h" 63cabdff1aSopenharmony_ci 64cabdff1aSopenharmony_ci#if CONFIG_ZLIB 65cabdff1aSopenharmony_ci#include <zlib.h> 66cabdff1aSopenharmony_ci#endif 67cabdff1aSopenharmony_ci 68cabdff1aSopenharmony_ci#include "svq1.h" 69cabdff1aSopenharmony_ci 70cabdff1aSopenharmony_ci/** 71cabdff1aSopenharmony_ci * @file 72cabdff1aSopenharmony_ci * svq3 decoder. 73cabdff1aSopenharmony_ci */ 74cabdff1aSopenharmony_ci 75cabdff1aSopenharmony_citypedef struct SVQ3Frame { 76cabdff1aSopenharmony_ci AVFrame *f; 77cabdff1aSopenharmony_ci 78cabdff1aSopenharmony_ci int16_t (*motion_val_buf[2])[2]; 79cabdff1aSopenharmony_ci int16_t (*motion_val[2])[2]; 80cabdff1aSopenharmony_ci 81cabdff1aSopenharmony_ci uint32_t *mb_type_buf, *mb_type; 82cabdff1aSopenharmony_ci} SVQ3Frame; 83cabdff1aSopenharmony_ci 84cabdff1aSopenharmony_citypedef struct SVQ3Context { 85cabdff1aSopenharmony_ci AVCodecContext *avctx; 86cabdff1aSopenharmony_ci 87cabdff1aSopenharmony_ci H264DSPContext h264dsp; 88cabdff1aSopenharmony_ci H264PredContext hpc; 89cabdff1aSopenharmony_ci HpelDSPContext hdsp; 90cabdff1aSopenharmony_ci TpelDSPContext tdsp; 91cabdff1aSopenharmony_ci VideoDSPContext vdsp; 92cabdff1aSopenharmony_ci 93cabdff1aSopenharmony_ci SVQ3Frame *cur_pic; 94cabdff1aSopenharmony_ci SVQ3Frame *next_pic; 95cabdff1aSopenharmony_ci SVQ3Frame *last_pic; 96cabdff1aSopenharmony_ci GetBitContext gb; 97cabdff1aSopenharmony_ci GetBitContext gb_slice; 98cabdff1aSopenharmony_ci uint8_t *slice_buf; 99cabdff1aSopenharmony_ci unsigned slice_buf_size; 100cabdff1aSopenharmony_ci int halfpel_flag; 101cabdff1aSopenharmony_ci int thirdpel_flag; 102cabdff1aSopenharmony_ci int has_watermark; 103cabdff1aSopenharmony_ci uint32_t watermark_key; 104cabdff1aSopenharmony_ci int adaptive_quant; 105cabdff1aSopenharmony_ci int h_edge_pos; 106cabdff1aSopenharmony_ci int v_edge_pos; 107cabdff1aSopenharmony_ci int last_frame_output; 108cabdff1aSopenharmony_ci int slice_num; 109cabdff1aSopenharmony_ci int qscale; 110cabdff1aSopenharmony_ci int cbp; 111cabdff1aSopenharmony_ci int frame_num; 112cabdff1aSopenharmony_ci int frame_num_offset; 113cabdff1aSopenharmony_ci int prev_frame_num_offset; 114cabdff1aSopenharmony_ci int prev_frame_num; 115cabdff1aSopenharmony_ci 116cabdff1aSopenharmony_ci enum AVPictureType pict_type; 117cabdff1aSopenharmony_ci enum AVPictureType slice_type; 118cabdff1aSopenharmony_ci int low_delay; 119cabdff1aSopenharmony_ci 120cabdff1aSopenharmony_ci int mb_x, mb_y; 121cabdff1aSopenharmony_ci int mb_xy; 122cabdff1aSopenharmony_ci int mb_width, mb_height; 123cabdff1aSopenharmony_ci int mb_stride, mb_num; 124cabdff1aSopenharmony_ci int b_stride; 125cabdff1aSopenharmony_ci 126cabdff1aSopenharmony_ci uint32_t *mb2br_xy; 127cabdff1aSopenharmony_ci 128cabdff1aSopenharmony_ci int chroma_pred_mode; 129cabdff1aSopenharmony_ci int intra16x16_pred_mode; 130cabdff1aSopenharmony_ci 131cabdff1aSopenharmony_ci int8_t intra4x4_pred_mode_cache[5 * 8]; 132cabdff1aSopenharmony_ci int8_t (*intra4x4_pred_mode); 133cabdff1aSopenharmony_ci 134cabdff1aSopenharmony_ci unsigned int top_samples_available; 135cabdff1aSopenharmony_ci unsigned int left_samples_available; 136cabdff1aSopenharmony_ci 137cabdff1aSopenharmony_ci uint8_t *edge_emu_buffer; 138cabdff1aSopenharmony_ci 139cabdff1aSopenharmony_ci DECLARE_ALIGNED(16, int16_t, mv_cache)[2][5 * 8][2]; 140cabdff1aSopenharmony_ci DECLARE_ALIGNED(8, int8_t, ref_cache)[2][5 * 8]; 141cabdff1aSopenharmony_ci DECLARE_ALIGNED(16, int16_t, mb)[16 * 48 * 2]; 142cabdff1aSopenharmony_ci DECLARE_ALIGNED(16, int16_t, mb_luma_dc)[3][16 * 2]; 143cabdff1aSopenharmony_ci DECLARE_ALIGNED(8, uint8_t, non_zero_count_cache)[15 * 8]; 144cabdff1aSopenharmony_ci uint32_t dequant4_coeff[QP_MAX_NUM + 1][16]; 145cabdff1aSopenharmony_ci int block_offset[2 * (16 * 3)]; 146cabdff1aSopenharmony_ci SVQ3Frame frames[3]; 147cabdff1aSopenharmony_ci} SVQ3Context; 148cabdff1aSopenharmony_ci 149cabdff1aSopenharmony_ci#define FULLPEL_MODE 1 150cabdff1aSopenharmony_ci#define HALFPEL_MODE 2 151cabdff1aSopenharmony_ci#define THIRDPEL_MODE 3 152cabdff1aSopenharmony_ci#define PREDICT_MODE 4 153cabdff1aSopenharmony_ci 154cabdff1aSopenharmony_ci/* dual scan (from some older H.264 draft) 155cabdff1aSopenharmony_ci * o-->o-->o o 156cabdff1aSopenharmony_ci * | /| 157cabdff1aSopenharmony_ci * o o o / o 158cabdff1aSopenharmony_ci * | / | |/ | 159cabdff1aSopenharmony_ci * o o o o 160cabdff1aSopenharmony_ci * / 161cabdff1aSopenharmony_ci * o-->o-->o-->o 162cabdff1aSopenharmony_ci */ 163cabdff1aSopenharmony_cistatic const uint8_t svq3_scan[16] = { 164cabdff1aSopenharmony_ci 0 + 0 * 4, 1 + 0 * 4, 2 + 0 * 4, 2 + 1 * 4, 165cabdff1aSopenharmony_ci 2 + 2 * 4, 3 + 0 * 4, 3 + 1 * 4, 3 + 2 * 4, 166cabdff1aSopenharmony_ci 0 + 1 * 4, 0 + 2 * 4, 1 + 1 * 4, 1 + 2 * 4, 167cabdff1aSopenharmony_ci 0 + 3 * 4, 1 + 3 * 4, 2 + 3 * 4, 3 + 3 * 4, 168cabdff1aSopenharmony_ci}; 169cabdff1aSopenharmony_ci 170cabdff1aSopenharmony_cistatic const uint8_t luma_dc_zigzag_scan[16] = { 171cabdff1aSopenharmony_ci 0 * 16 + 0 * 64, 1 * 16 + 0 * 64, 2 * 16 + 0 * 64, 0 * 16 + 2 * 64, 172cabdff1aSopenharmony_ci 3 * 16 + 0 * 64, 0 * 16 + 1 * 64, 1 * 16 + 1 * 64, 2 * 16 + 1 * 64, 173cabdff1aSopenharmony_ci 1 * 16 + 2 * 64, 2 * 16 + 2 * 64, 3 * 16 + 2 * 64, 0 * 16 + 3 * 64, 174cabdff1aSopenharmony_ci 3 * 16 + 1 * 64, 1 * 16 + 3 * 64, 2 * 16 + 3 * 64, 3 * 16 + 3 * 64, 175cabdff1aSopenharmony_ci}; 176cabdff1aSopenharmony_ci 177cabdff1aSopenharmony_cistatic const uint8_t svq3_pred_0[25][2] = { 178cabdff1aSopenharmony_ci { 0, 0 }, 179cabdff1aSopenharmony_ci { 1, 0 }, { 0, 1 }, 180cabdff1aSopenharmony_ci { 0, 2 }, { 1, 1 }, { 2, 0 }, 181cabdff1aSopenharmony_ci { 3, 0 }, { 2, 1 }, { 1, 2 }, { 0, 3 }, 182cabdff1aSopenharmony_ci { 0, 4 }, { 1, 3 }, { 2, 2 }, { 3, 1 }, { 4, 0 }, 183cabdff1aSopenharmony_ci { 4, 1 }, { 3, 2 }, { 2, 3 }, { 1, 4 }, 184cabdff1aSopenharmony_ci { 2, 4 }, { 3, 3 }, { 4, 2 }, 185cabdff1aSopenharmony_ci { 4, 3 }, { 3, 4 }, 186cabdff1aSopenharmony_ci { 4, 4 } 187cabdff1aSopenharmony_ci}; 188cabdff1aSopenharmony_ci 189cabdff1aSopenharmony_cistatic const int8_t svq3_pred_1[6][6][5] = { 190cabdff1aSopenharmony_ci { { 2, -1, -1, -1, -1 }, { 2, 1, -1, -1, -1 }, { 1, 2, -1, -1, -1 }, 191cabdff1aSopenharmony_ci { 2, 1, -1, -1, -1 }, { 1, 2, -1, -1, -1 }, { 1, 2, -1, -1, -1 } }, 192cabdff1aSopenharmony_ci { { 0, 2, -1, -1, -1 }, { 0, 2, 1, 4, 3 }, { 0, 1, 2, 4, 3 }, 193cabdff1aSopenharmony_ci { 0, 2, 1, 4, 3 }, { 2, 0, 1, 3, 4 }, { 0, 4, 2, 1, 3 } }, 194cabdff1aSopenharmony_ci { { 2, 0, -1, -1, -1 }, { 2, 1, 0, 4, 3 }, { 1, 2, 4, 0, 3 }, 195cabdff1aSopenharmony_ci { 2, 1, 0, 4, 3 }, { 2, 1, 4, 3, 0 }, { 1, 2, 4, 0, 3 } }, 196cabdff1aSopenharmony_ci { { 2, 0, -1, -1, -1 }, { 2, 0, 1, 4, 3 }, { 1, 2, 0, 4, 3 }, 197cabdff1aSopenharmony_ci { 2, 1, 0, 4, 3 }, { 2, 1, 3, 4, 0 }, { 2, 4, 1, 0, 3 } }, 198cabdff1aSopenharmony_ci { { 0, 2, -1, -1, -1 }, { 0, 2, 1, 3, 4 }, { 1, 2, 3, 0, 4 }, 199cabdff1aSopenharmony_ci { 2, 0, 1, 3, 4 }, { 2, 1, 3, 0, 4 }, { 2, 0, 4, 3, 1 } }, 200cabdff1aSopenharmony_ci { { 0, 2, -1, -1, -1 }, { 0, 2, 4, 1, 3 }, { 1, 4, 2, 0, 3 }, 201cabdff1aSopenharmony_ci { 4, 2, 0, 1, 3 }, { 2, 0, 1, 4, 3 }, { 4, 2, 1, 0, 3 } }, 202cabdff1aSopenharmony_ci}; 203cabdff1aSopenharmony_ci 204cabdff1aSopenharmony_cistatic const struct { 205cabdff1aSopenharmony_ci uint8_t run; 206cabdff1aSopenharmony_ci uint8_t level; 207cabdff1aSopenharmony_ci} svq3_dct_tables[2][16] = { 208cabdff1aSopenharmony_ci { { 0, 0 }, { 0, 1 }, { 1, 1 }, { 2, 1 }, { 0, 2 }, { 3, 1 }, { 4, 1 }, { 5, 1 }, 209cabdff1aSopenharmony_ci { 0, 3 }, { 1, 2 }, { 2, 2 }, { 6, 1 }, { 7, 1 }, { 8, 1 }, { 9, 1 }, { 0, 4 } }, 210cabdff1aSopenharmony_ci { { 0, 0 }, { 0, 1 }, { 1, 1 }, { 0, 2 }, { 2, 1 }, { 0, 3 }, { 0, 4 }, { 0, 5 }, 211cabdff1aSopenharmony_ci { 3, 1 }, { 4, 1 }, { 1, 2 }, { 1, 3 }, { 0, 6 }, { 0, 7 }, { 0, 8 }, { 0, 9 } } 212cabdff1aSopenharmony_ci}; 213cabdff1aSopenharmony_ci 214cabdff1aSopenharmony_cistatic const uint32_t svq3_dequant_coeff[32] = { 215cabdff1aSopenharmony_ci 3881, 4351, 4890, 5481, 6154, 6914, 7761, 8718, 216cabdff1aSopenharmony_ci 9781, 10987, 12339, 13828, 15523, 17435, 19561, 21873, 217cabdff1aSopenharmony_ci 24552, 27656, 30847, 34870, 38807, 43747, 49103, 54683, 218cabdff1aSopenharmony_ci 61694, 68745, 77615, 89113, 100253, 109366, 126635, 141533 219cabdff1aSopenharmony_ci}; 220cabdff1aSopenharmony_ci 221cabdff1aSopenharmony_cistatic void svq3_luma_dc_dequant_idct_c(int16_t *output, int16_t *input, int qp) 222cabdff1aSopenharmony_ci{ 223cabdff1aSopenharmony_ci const unsigned qmul = svq3_dequant_coeff[qp]; 224cabdff1aSopenharmony_ci#define stride 16 225cabdff1aSopenharmony_ci int i; 226cabdff1aSopenharmony_ci int temp[16]; 227cabdff1aSopenharmony_ci static const uint8_t x_offset[4] = { 0, 1 * stride, 4 * stride, 5 * stride }; 228cabdff1aSopenharmony_ci 229cabdff1aSopenharmony_ci for (i = 0; i < 4; i++) { 230cabdff1aSopenharmony_ci const int z0 = 13 * (input[4 * i + 0] + input[4 * i + 2]); 231cabdff1aSopenharmony_ci const int z1 = 13 * (input[4 * i + 0] - input[4 * i + 2]); 232cabdff1aSopenharmony_ci const int z2 = 7 * input[4 * i + 1] - 17 * input[4 * i + 3]; 233cabdff1aSopenharmony_ci const int z3 = 17 * input[4 * i + 1] + 7 * input[4 * i + 3]; 234cabdff1aSopenharmony_ci 235cabdff1aSopenharmony_ci temp[4 * i + 0] = z0 + z3; 236cabdff1aSopenharmony_ci temp[4 * i + 1] = z1 + z2; 237cabdff1aSopenharmony_ci temp[4 * i + 2] = z1 - z2; 238cabdff1aSopenharmony_ci temp[4 * i + 3] = z0 - z3; 239cabdff1aSopenharmony_ci } 240cabdff1aSopenharmony_ci 241cabdff1aSopenharmony_ci for (i = 0; i < 4; i++) { 242cabdff1aSopenharmony_ci const int offset = x_offset[i]; 243cabdff1aSopenharmony_ci const int z0 = 13 * (temp[4 * 0 + i] + temp[4 * 2 + i]); 244cabdff1aSopenharmony_ci const int z1 = 13 * (temp[4 * 0 + i] - temp[4 * 2 + i]); 245cabdff1aSopenharmony_ci const int z2 = 7 * temp[4 * 1 + i] - 17 * temp[4 * 3 + i]; 246cabdff1aSopenharmony_ci const int z3 = 17 * temp[4 * 1 + i] + 7 * temp[4 * 3 + i]; 247cabdff1aSopenharmony_ci 248cabdff1aSopenharmony_ci output[stride * 0 + offset] = (int)((z0 + z3) * qmul + 0x80000) >> 20; 249cabdff1aSopenharmony_ci output[stride * 2 + offset] = (int)((z1 + z2) * qmul + 0x80000) >> 20; 250cabdff1aSopenharmony_ci output[stride * 8 + offset] = (int)((z1 - z2) * qmul + 0x80000) >> 20; 251cabdff1aSopenharmony_ci output[stride * 10 + offset] = (int)((z0 - z3) * qmul + 0x80000) >> 20; 252cabdff1aSopenharmony_ci } 253cabdff1aSopenharmony_ci} 254cabdff1aSopenharmony_ci#undef stride 255cabdff1aSopenharmony_ci 256cabdff1aSopenharmony_cistatic void svq3_add_idct_c(uint8_t *dst, int16_t *block, 257cabdff1aSopenharmony_ci int stride, int qp, int dc) 258cabdff1aSopenharmony_ci{ 259cabdff1aSopenharmony_ci const int qmul = svq3_dequant_coeff[qp]; 260cabdff1aSopenharmony_ci int i; 261cabdff1aSopenharmony_ci 262cabdff1aSopenharmony_ci if (dc) { 263cabdff1aSopenharmony_ci dc = 13 * 13 * (dc == 1 ? 1538U* block[0] 264cabdff1aSopenharmony_ci : qmul * (block[0] >> 3) / 2); 265cabdff1aSopenharmony_ci block[0] = 0; 266cabdff1aSopenharmony_ci } 267cabdff1aSopenharmony_ci 268cabdff1aSopenharmony_ci for (i = 0; i < 4; i++) { 269cabdff1aSopenharmony_ci const int z0 = 13 * (block[0 + 4 * i] + block[2 + 4 * i]); 270cabdff1aSopenharmony_ci const int z1 = 13 * (block[0 + 4 * i] - block[2 + 4 * i]); 271cabdff1aSopenharmony_ci const int z2 = 7 * block[1 + 4 * i] - 17 * block[3 + 4 * i]; 272cabdff1aSopenharmony_ci const int z3 = 17 * block[1 + 4 * i] + 7 * block[3 + 4 * i]; 273cabdff1aSopenharmony_ci 274cabdff1aSopenharmony_ci block[0 + 4 * i] = z0 + z3; 275cabdff1aSopenharmony_ci block[1 + 4 * i] = z1 + z2; 276cabdff1aSopenharmony_ci block[2 + 4 * i] = z1 - z2; 277cabdff1aSopenharmony_ci block[3 + 4 * i] = z0 - z3; 278cabdff1aSopenharmony_ci } 279cabdff1aSopenharmony_ci 280cabdff1aSopenharmony_ci for (i = 0; i < 4; i++) { 281cabdff1aSopenharmony_ci const unsigned z0 = 13 * (block[i + 4 * 0] + block[i + 4 * 2]); 282cabdff1aSopenharmony_ci const unsigned z1 = 13 * (block[i + 4 * 0] - block[i + 4 * 2]); 283cabdff1aSopenharmony_ci const unsigned z2 = 7 * block[i + 4 * 1] - 17 * block[i + 4 * 3]; 284cabdff1aSopenharmony_ci const unsigned z3 = 17 * block[i + 4 * 1] + 7 * block[i + 4 * 3]; 285cabdff1aSopenharmony_ci const int rr = (dc + 0x80000u); 286cabdff1aSopenharmony_ci 287cabdff1aSopenharmony_ci dst[i + stride * 0] = av_clip_uint8(dst[i + stride * 0] + ((int)((z0 + z3) * qmul + rr) >> 20)); 288cabdff1aSopenharmony_ci dst[i + stride * 1] = av_clip_uint8(dst[i + stride * 1] + ((int)((z1 + z2) * qmul + rr) >> 20)); 289cabdff1aSopenharmony_ci dst[i + stride * 2] = av_clip_uint8(dst[i + stride * 2] + ((int)((z1 - z2) * qmul + rr) >> 20)); 290cabdff1aSopenharmony_ci dst[i + stride * 3] = av_clip_uint8(dst[i + stride * 3] + ((int)((z0 - z3) * qmul + rr) >> 20)); 291cabdff1aSopenharmony_ci } 292cabdff1aSopenharmony_ci 293cabdff1aSopenharmony_ci memset(block, 0, 16 * sizeof(int16_t)); 294cabdff1aSopenharmony_ci} 295cabdff1aSopenharmony_ci 296cabdff1aSopenharmony_cistatic inline int svq3_decode_block(GetBitContext *gb, int16_t *block, 297cabdff1aSopenharmony_ci int index, const int type) 298cabdff1aSopenharmony_ci{ 299cabdff1aSopenharmony_ci static const uint8_t *const scan_patterns[4] = { 300cabdff1aSopenharmony_ci luma_dc_zigzag_scan, ff_zigzag_scan, svq3_scan, ff_h264_chroma_dc_scan 301cabdff1aSopenharmony_ci }; 302cabdff1aSopenharmony_ci 303cabdff1aSopenharmony_ci int run, level, sign, limit; 304cabdff1aSopenharmony_ci unsigned vlc; 305cabdff1aSopenharmony_ci const int intra = 3 * type >> 2; 306cabdff1aSopenharmony_ci const uint8_t *const scan = scan_patterns[type]; 307cabdff1aSopenharmony_ci 308cabdff1aSopenharmony_ci for (limit = (16 >> intra); index < 16; index = limit, limit += 8) { 309cabdff1aSopenharmony_ci for (; (vlc = get_interleaved_ue_golomb(gb)) != 0; index++) { 310cabdff1aSopenharmony_ci if ((int32_t)vlc < 0) 311cabdff1aSopenharmony_ci return -1; 312cabdff1aSopenharmony_ci 313cabdff1aSopenharmony_ci sign = (vlc & 1) ? 0 : -1; 314cabdff1aSopenharmony_ci vlc = vlc + 1 >> 1; 315cabdff1aSopenharmony_ci 316cabdff1aSopenharmony_ci if (type == 3) { 317cabdff1aSopenharmony_ci if (vlc < 3) { 318cabdff1aSopenharmony_ci run = 0; 319cabdff1aSopenharmony_ci level = vlc; 320cabdff1aSopenharmony_ci } else if (vlc < 4) { 321cabdff1aSopenharmony_ci run = 1; 322cabdff1aSopenharmony_ci level = 1; 323cabdff1aSopenharmony_ci } else { 324cabdff1aSopenharmony_ci run = vlc & 0x3; 325cabdff1aSopenharmony_ci level = (vlc + 9 >> 2) - run; 326cabdff1aSopenharmony_ci } 327cabdff1aSopenharmony_ci } else { 328cabdff1aSopenharmony_ci if (vlc < 16U) { 329cabdff1aSopenharmony_ci run = svq3_dct_tables[intra][vlc].run; 330cabdff1aSopenharmony_ci level = svq3_dct_tables[intra][vlc].level; 331cabdff1aSopenharmony_ci } else if (intra) { 332cabdff1aSopenharmony_ci run = vlc & 0x7; 333cabdff1aSopenharmony_ci level = (vlc >> 3) + ((run == 0) ? 8 : ((run < 2) ? 2 : ((run < 5) ? 0 : -1))); 334cabdff1aSopenharmony_ci } else { 335cabdff1aSopenharmony_ci run = vlc & 0xF; 336cabdff1aSopenharmony_ci level = (vlc >> 4) + ((run == 0) ? 4 : ((run < 3) ? 2 : ((run < 10) ? 1 : 0))); 337cabdff1aSopenharmony_ci } 338cabdff1aSopenharmony_ci } 339cabdff1aSopenharmony_ci 340cabdff1aSopenharmony_ci 341cabdff1aSopenharmony_ci if ((index += run) >= limit) 342cabdff1aSopenharmony_ci return -1; 343cabdff1aSopenharmony_ci 344cabdff1aSopenharmony_ci block[scan[index]] = (level ^ sign) - sign; 345cabdff1aSopenharmony_ci } 346cabdff1aSopenharmony_ci 347cabdff1aSopenharmony_ci if (type != 2) { 348cabdff1aSopenharmony_ci break; 349cabdff1aSopenharmony_ci } 350cabdff1aSopenharmony_ci } 351cabdff1aSopenharmony_ci 352cabdff1aSopenharmony_ci return 0; 353cabdff1aSopenharmony_ci} 354cabdff1aSopenharmony_ci 355cabdff1aSopenharmony_cistatic av_always_inline int 356cabdff1aSopenharmony_cisvq3_fetch_diagonal_mv(const SVQ3Context *s, const int16_t **C, 357cabdff1aSopenharmony_ci int i, int list, int part_width) 358cabdff1aSopenharmony_ci{ 359cabdff1aSopenharmony_ci const int topright_ref = s->ref_cache[list][i - 8 + part_width]; 360cabdff1aSopenharmony_ci 361cabdff1aSopenharmony_ci if (topright_ref != PART_NOT_AVAILABLE) { 362cabdff1aSopenharmony_ci *C = s->mv_cache[list][i - 8 + part_width]; 363cabdff1aSopenharmony_ci return topright_ref; 364cabdff1aSopenharmony_ci } else { 365cabdff1aSopenharmony_ci *C = s->mv_cache[list][i - 8 - 1]; 366cabdff1aSopenharmony_ci return s->ref_cache[list][i - 8 - 1]; 367cabdff1aSopenharmony_ci } 368cabdff1aSopenharmony_ci} 369cabdff1aSopenharmony_ci 370cabdff1aSopenharmony_ci/** 371cabdff1aSopenharmony_ci * Get the predicted MV. 372cabdff1aSopenharmony_ci * @param n the block index 373cabdff1aSopenharmony_ci * @param part_width the width of the partition (4, 8,16) -> (1, 2, 4) 374cabdff1aSopenharmony_ci * @param mx the x component of the predicted motion vector 375cabdff1aSopenharmony_ci * @param my the y component of the predicted motion vector 376cabdff1aSopenharmony_ci */ 377cabdff1aSopenharmony_cistatic av_always_inline void svq3_pred_motion(const SVQ3Context *s, int n, 378cabdff1aSopenharmony_ci int part_width, int list, 379cabdff1aSopenharmony_ci int ref, int *const mx, int *const my) 380cabdff1aSopenharmony_ci{ 381cabdff1aSopenharmony_ci const int index8 = scan8[n]; 382cabdff1aSopenharmony_ci const int top_ref = s->ref_cache[list][index8 - 8]; 383cabdff1aSopenharmony_ci const int left_ref = s->ref_cache[list][index8 - 1]; 384cabdff1aSopenharmony_ci const int16_t *const A = s->mv_cache[list][index8 - 1]; 385cabdff1aSopenharmony_ci const int16_t *const B = s->mv_cache[list][index8 - 8]; 386cabdff1aSopenharmony_ci const int16_t *C; 387cabdff1aSopenharmony_ci int diagonal_ref, match_count; 388cabdff1aSopenharmony_ci 389cabdff1aSopenharmony_ci/* mv_cache 390cabdff1aSopenharmony_ci * B . . A T T T T 391cabdff1aSopenharmony_ci * U . . L . . , . 392cabdff1aSopenharmony_ci * U . . L . . . . 393cabdff1aSopenharmony_ci * U . . L . . , . 394cabdff1aSopenharmony_ci * . . . L . . . . 395cabdff1aSopenharmony_ci */ 396cabdff1aSopenharmony_ci 397cabdff1aSopenharmony_ci diagonal_ref = svq3_fetch_diagonal_mv(s, &C, index8, list, part_width); 398cabdff1aSopenharmony_ci match_count = (diagonal_ref == ref) + (top_ref == ref) + (left_ref == ref); 399cabdff1aSopenharmony_ci if (match_count > 1) { //most common 400cabdff1aSopenharmony_ci *mx = mid_pred(A[0], B[0], C[0]); 401cabdff1aSopenharmony_ci *my = mid_pred(A[1], B[1], C[1]); 402cabdff1aSopenharmony_ci } else if (match_count == 1) { 403cabdff1aSopenharmony_ci if (left_ref == ref) { 404cabdff1aSopenharmony_ci *mx = A[0]; 405cabdff1aSopenharmony_ci *my = A[1]; 406cabdff1aSopenharmony_ci } else if (top_ref == ref) { 407cabdff1aSopenharmony_ci *mx = B[0]; 408cabdff1aSopenharmony_ci *my = B[1]; 409cabdff1aSopenharmony_ci } else { 410cabdff1aSopenharmony_ci *mx = C[0]; 411cabdff1aSopenharmony_ci *my = C[1]; 412cabdff1aSopenharmony_ci } 413cabdff1aSopenharmony_ci } else { 414cabdff1aSopenharmony_ci if (top_ref == PART_NOT_AVAILABLE && 415cabdff1aSopenharmony_ci diagonal_ref == PART_NOT_AVAILABLE && 416cabdff1aSopenharmony_ci left_ref != PART_NOT_AVAILABLE) { 417cabdff1aSopenharmony_ci *mx = A[0]; 418cabdff1aSopenharmony_ci *my = A[1]; 419cabdff1aSopenharmony_ci } else { 420cabdff1aSopenharmony_ci *mx = mid_pred(A[0], B[0], C[0]); 421cabdff1aSopenharmony_ci *my = mid_pred(A[1], B[1], C[1]); 422cabdff1aSopenharmony_ci } 423cabdff1aSopenharmony_ci } 424cabdff1aSopenharmony_ci} 425cabdff1aSopenharmony_ci 426cabdff1aSopenharmony_cistatic inline void svq3_mc_dir_part(SVQ3Context *s, 427cabdff1aSopenharmony_ci int x, int y, int width, int height, 428cabdff1aSopenharmony_ci int mx, int my, int dxy, 429cabdff1aSopenharmony_ci int thirdpel, int dir, int avg) 430cabdff1aSopenharmony_ci{ 431cabdff1aSopenharmony_ci const SVQ3Frame *pic = (dir == 0) ? s->last_pic : s->next_pic; 432cabdff1aSopenharmony_ci uint8_t *src, *dest; 433cabdff1aSopenharmony_ci int i, emu = 0; 434cabdff1aSopenharmony_ci int blocksize = 2 - (width >> 3); // 16->0, 8->1, 4->2 435cabdff1aSopenharmony_ci int linesize = s->cur_pic->f->linesize[0]; 436cabdff1aSopenharmony_ci int uvlinesize = s->cur_pic->f->linesize[1]; 437cabdff1aSopenharmony_ci 438cabdff1aSopenharmony_ci mx += x; 439cabdff1aSopenharmony_ci my += y; 440cabdff1aSopenharmony_ci 441cabdff1aSopenharmony_ci if (mx < 0 || mx >= s->h_edge_pos - width - 1 || 442cabdff1aSopenharmony_ci my < 0 || my >= s->v_edge_pos - height - 1) { 443cabdff1aSopenharmony_ci emu = 1; 444cabdff1aSopenharmony_ci mx = av_clip(mx, -16, s->h_edge_pos - width + 15); 445cabdff1aSopenharmony_ci my = av_clip(my, -16, s->v_edge_pos - height + 15); 446cabdff1aSopenharmony_ci } 447cabdff1aSopenharmony_ci 448cabdff1aSopenharmony_ci /* form component predictions */ 449cabdff1aSopenharmony_ci dest = s->cur_pic->f->data[0] + x + y * linesize; 450cabdff1aSopenharmony_ci src = pic->f->data[0] + mx + my * linesize; 451cabdff1aSopenharmony_ci 452cabdff1aSopenharmony_ci if (emu) { 453cabdff1aSopenharmony_ci s->vdsp.emulated_edge_mc(s->edge_emu_buffer, src, 454cabdff1aSopenharmony_ci linesize, linesize, 455cabdff1aSopenharmony_ci width + 1, height + 1, 456cabdff1aSopenharmony_ci mx, my, s->h_edge_pos, s->v_edge_pos); 457cabdff1aSopenharmony_ci src = s->edge_emu_buffer; 458cabdff1aSopenharmony_ci } 459cabdff1aSopenharmony_ci if (thirdpel) 460cabdff1aSopenharmony_ci (avg ? s->tdsp.avg_tpel_pixels_tab 461cabdff1aSopenharmony_ci : s->tdsp.put_tpel_pixels_tab)[dxy](dest, src, linesize, 462cabdff1aSopenharmony_ci width, height); 463cabdff1aSopenharmony_ci else 464cabdff1aSopenharmony_ci (avg ? s->hdsp.avg_pixels_tab 465cabdff1aSopenharmony_ci : s->hdsp.put_pixels_tab)[blocksize][dxy](dest, src, linesize, 466cabdff1aSopenharmony_ci height); 467cabdff1aSopenharmony_ci 468cabdff1aSopenharmony_ci if (!(s->avctx->flags & AV_CODEC_FLAG_GRAY)) { 469cabdff1aSopenharmony_ci mx = mx + (mx < (int) x) >> 1; 470cabdff1aSopenharmony_ci my = my + (my < (int) y) >> 1; 471cabdff1aSopenharmony_ci width = width >> 1; 472cabdff1aSopenharmony_ci height = height >> 1; 473cabdff1aSopenharmony_ci blocksize++; 474cabdff1aSopenharmony_ci 475cabdff1aSopenharmony_ci for (i = 1; i < 3; i++) { 476cabdff1aSopenharmony_ci dest = s->cur_pic->f->data[i] + (x >> 1) + (y >> 1) * uvlinesize; 477cabdff1aSopenharmony_ci src = pic->f->data[i] + mx + my * uvlinesize; 478cabdff1aSopenharmony_ci 479cabdff1aSopenharmony_ci if (emu) { 480cabdff1aSopenharmony_ci s->vdsp.emulated_edge_mc(s->edge_emu_buffer, src, 481cabdff1aSopenharmony_ci uvlinesize, uvlinesize, 482cabdff1aSopenharmony_ci width + 1, height + 1, 483cabdff1aSopenharmony_ci mx, my, (s->h_edge_pos >> 1), 484cabdff1aSopenharmony_ci s->v_edge_pos >> 1); 485cabdff1aSopenharmony_ci src = s->edge_emu_buffer; 486cabdff1aSopenharmony_ci } 487cabdff1aSopenharmony_ci if (thirdpel) 488cabdff1aSopenharmony_ci (avg ? s->tdsp.avg_tpel_pixels_tab 489cabdff1aSopenharmony_ci : s->tdsp.put_tpel_pixels_tab)[dxy](dest, src, 490cabdff1aSopenharmony_ci uvlinesize, 491cabdff1aSopenharmony_ci width, height); 492cabdff1aSopenharmony_ci else 493cabdff1aSopenharmony_ci (avg ? s->hdsp.avg_pixels_tab 494cabdff1aSopenharmony_ci : s->hdsp.put_pixels_tab)[blocksize][dxy](dest, src, 495cabdff1aSopenharmony_ci uvlinesize, 496cabdff1aSopenharmony_ci height); 497cabdff1aSopenharmony_ci } 498cabdff1aSopenharmony_ci } 499cabdff1aSopenharmony_ci} 500cabdff1aSopenharmony_ci 501cabdff1aSopenharmony_cistatic inline int svq3_mc_dir(SVQ3Context *s, int size, int mode, 502cabdff1aSopenharmony_ci int dir, int avg) 503cabdff1aSopenharmony_ci{ 504cabdff1aSopenharmony_ci int i, j, k, mx, my, dx, dy, x, y; 505cabdff1aSopenharmony_ci const int part_width = ((size & 5) == 4) ? 4 : 16 >> (size & 1); 506cabdff1aSopenharmony_ci const int part_height = 16 >> ((unsigned)(size + 1) / 3); 507cabdff1aSopenharmony_ci const int extra_width = (mode == PREDICT_MODE) ? -16 * 6 : 0; 508cabdff1aSopenharmony_ci const int h_edge_pos = 6 * (s->h_edge_pos - part_width) - extra_width; 509cabdff1aSopenharmony_ci const int v_edge_pos = 6 * (s->v_edge_pos - part_height) - extra_width; 510cabdff1aSopenharmony_ci 511cabdff1aSopenharmony_ci for (i = 0; i < 16; i += part_height) 512cabdff1aSopenharmony_ci for (j = 0; j < 16; j += part_width) { 513cabdff1aSopenharmony_ci const int b_xy = (4 * s->mb_x + (j >> 2)) + 514cabdff1aSopenharmony_ci (4 * s->mb_y + (i >> 2)) * s->b_stride; 515cabdff1aSopenharmony_ci int dxy; 516cabdff1aSopenharmony_ci x = 16 * s->mb_x + j; 517cabdff1aSopenharmony_ci y = 16 * s->mb_y + i; 518cabdff1aSopenharmony_ci k = (j >> 2 & 1) + (i >> 1 & 2) + 519cabdff1aSopenharmony_ci (j >> 1 & 4) + (i & 8); 520cabdff1aSopenharmony_ci 521cabdff1aSopenharmony_ci if (mode != PREDICT_MODE) { 522cabdff1aSopenharmony_ci svq3_pred_motion(s, k, part_width >> 2, dir, 1, &mx, &my); 523cabdff1aSopenharmony_ci } else { 524cabdff1aSopenharmony_ci mx = s->next_pic->motion_val[0][b_xy][0] * 2; 525cabdff1aSopenharmony_ci my = s->next_pic->motion_val[0][b_xy][1] * 2; 526cabdff1aSopenharmony_ci 527cabdff1aSopenharmony_ci if (dir == 0) { 528cabdff1aSopenharmony_ci mx = mx * s->frame_num_offset / 529cabdff1aSopenharmony_ci s->prev_frame_num_offset + 1 >> 1; 530cabdff1aSopenharmony_ci my = my * s->frame_num_offset / 531cabdff1aSopenharmony_ci s->prev_frame_num_offset + 1 >> 1; 532cabdff1aSopenharmony_ci } else { 533cabdff1aSopenharmony_ci mx = mx * (s->frame_num_offset - s->prev_frame_num_offset) / 534cabdff1aSopenharmony_ci s->prev_frame_num_offset + 1 >> 1; 535cabdff1aSopenharmony_ci my = my * (s->frame_num_offset - s->prev_frame_num_offset) / 536cabdff1aSopenharmony_ci s->prev_frame_num_offset + 1 >> 1; 537cabdff1aSopenharmony_ci } 538cabdff1aSopenharmony_ci } 539cabdff1aSopenharmony_ci 540cabdff1aSopenharmony_ci /* clip motion vector prediction to frame border */ 541cabdff1aSopenharmony_ci mx = av_clip(mx, extra_width - 6 * x, h_edge_pos - 6 * x); 542cabdff1aSopenharmony_ci my = av_clip(my, extra_width - 6 * y, v_edge_pos - 6 * y); 543cabdff1aSopenharmony_ci 544cabdff1aSopenharmony_ci /* get (optional) motion vector differential */ 545cabdff1aSopenharmony_ci if (mode == PREDICT_MODE) { 546cabdff1aSopenharmony_ci dx = dy = 0; 547cabdff1aSopenharmony_ci } else { 548cabdff1aSopenharmony_ci dy = get_interleaved_se_golomb(&s->gb_slice); 549cabdff1aSopenharmony_ci dx = get_interleaved_se_golomb(&s->gb_slice); 550cabdff1aSopenharmony_ci 551cabdff1aSopenharmony_ci if (dx != (int16_t)dx || dy != (int16_t)dy) { 552cabdff1aSopenharmony_ci av_log(s->avctx, AV_LOG_ERROR, "invalid MV vlc\n"); 553cabdff1aSopenharmony_ci return -1; 554cabdff1aSopenharmony_ci } 555cabdff1aSopenharmony_ci } 556cabdff1aSopenharmony_ci 557cabdff1aSopenharmony_ci /* compute motion vector */ 558cabdff1aSopenharmony_ci if (mode == THIRDPEL_MODE) { 559cabdff1aSopenharmony_ci int fx, fy; 560cabdff1aSopenharmony_ci mx = (mx + 1 >> 1) + dx; 561cabdff1aSopenharmony_ci my = (my + 1 >> 1) + dy; 562cabdff1aSopenharmony_ci fx = (unsigned)(mx + 0x30000) / 3 - 0x10000; 563cabdff1aSopenharmony_ci fy = (unsigned)(my + 0x30000) / 3 - 0x10000; 564cabdff1aSopenharmony_ci dxy = (mx - 3 * fx) + 4 * (my - 3 * fy); 565cabdff1aSopenharmony_ci 566cabdff1aSopenharmony_ci svq3_mc_dir_part(s, x, y, part_width, part_height, 567cabdff1aSopenharmony_ci fx, fy, dxy, 1, dir, avg); 568cabdff1aSopenharmony_ci mx += mx; 569cabdff1aSopenharmony_ci my += my; 570cabdff1aSopenharmony_ci } else if (mode == HALFPEL_MODE || mode == PREDICT_MODE) { 571cabdff1aSopenharmony_ci mx = (unsigned)(mx + 1 + 0x30000) / 3 + dx - 0x10000; 572cabdff1aSopenharmony_ci my = (unsigned)(my + 1 + 0x30000) / 3 + dy - 0x10000; 573cabdff1aSopenharmony_ci dxy = (mx & 1) + 2 * (my & 1); 574cabdff1aSopenharmony_ci 575cabdff1aSopenharmony_ci svq3_mc_dir_part(s, x, y, part_width, part_height, 576cabdff1aSopenharmony_ci mx >> 1, my >> 1, dxy, 0, dir, avg); 577cabdff1aSopenharmony_ci mx *= 3; 578cabdff1aSopenharmony_ci my *= 3; 579cabdff1aSopenharmony_ci } else { 580cabdff1aSopenharmony_ci mx = (unsigned)(mx + 3 + 0x60000) / 6 + dx - 0x10000; 581cabdff1aSopenharmony_ci my = (unsigned)(my + 3 + 0x60000) / 6 + dy - 0x10000; 582cabdff1aSopenharmony_ci 583cabdff1aSopenharmony_ci svq3_mc_dir_part(s, x, y, part_width, part_height, 584cabdff1aSopenharmony_ci mx, my, 0, 0, dir, avg); 585cabdff1aSopenharmony_ci mx *= 6; 586cabdff1aSopenharmony_ci my *= 6; 587cabdff1aSopenharmony_ci } 588cabdff1aSopenharmony_ci 589cabdff1aSopenharmony_ci /* update mv_cache */ 590cabdff1aSopenharmony_ci if (mode != PREDICT_MODE) { 591cabdff1aSopenharmony_ci int32_t mv = pack16to32(mx, my); 592cabdff1aSopenharmony_ci 593cabdff1aSopenharmony_ci if (part_height == 8 && i < 8) { 594cabdff1aSopenharmony_ci AV_WN32A(s->mv_cache[dir][scan8[k] + 1 * 8], mv); 595cabdff1aSopenharmony_ci 596cabdff1aSopenharmony_ci if (part_width == 8 && j < 8) 597cabdff1aSopenharmony_ci AV_WN32A(s->mv_cache[dir][scan8[k] + 1 + 1 * 8], mv); 598cabdff1aSopenharmony_ci } 599cabdff1aSopenharmony_ci if (part_width == 8 && j < 8) 600cabdff1aSopenharmony_ci AV_WN32A(s->mv_cache[dir][scan8[k] + 1], mv); 601cabdff1aSopenharmony_ci if (part_width == 4 || part_height == 4) 602cabdff1aSopenharmony_ci AV_WN32A(s->mv_cache[dir][scan8[k]], mv); 603cabdff1aSopenharmony_ci } 604cabdff1aSopenharmony_ci 605cabdff1aSopenharmony_ci /* write back motion vectors */ 606cabdff1aSopenharmony_ci fill_rectangle(s->cur_pic->motion_val[dir][b_xy], 607cabdff1aSopenharmony_ci part_width >> 2, part_height >> 2, s->b_stride, 608cabdff1aSopenharmony_ci pack16to32(mx, my), 4); 609cabdff1aSopenharmony_ci } 610cabdff1aSopenharmony_ci 611cabdff1aSopenharmony_ci return 0; 612cabdff1aSopenharmony_ci} 613cabdff1aSopenharmony_ci 614cabdff1aSopenharmony_cistatic av_always_inline void hl_decode_mb_idct_luma(SVQ3Context *s, 615cabdff1aSopenharmony_ci int mb_type, const int *block_offset, 616cabdff1aSopenharmony_ci int linesize, uint8_t *dest_y) 617cabdff1aSopenharmony_ci{ 618cabdff1aSopenharmony_ci int i; 619cabdff1aSopenharmony_ci if (!IS_INTRA4x4(mb_type)) { 620cabdff1aSopenharmony_ci for (i = 0; i < 16; i++) 621cabdff1aSopenharmony_ci if (s->non_zero_count_cache[scan8[i]] || s->mb[i * 16]) { 622cabdff1aSopenharmony_ci uint8_t *const ptr = dest_y + block_offset[i]; 623cabdff1aSopenharmony_ci svq3_add_idct_c(ptr, s->mb + i * 16, linesize, 624cabdff1aSopenharmony_ci s->qscale, IS_INTRA(mb_type) ? 1 : 0); 625cabdff1aSopenharmony_ci } 626cabdff1aSopenharmony_ci } 627cabdff1aSopenharmony_ci} 628cabdff1aSopenharmony_ci 629cabdff1aSopenharmony_cistatic av_always_inline void hl_decode_mb_predict_luma(SVQ3Context *s, 630cabdff1aSopenharmony_ci int mb_type, 631cabdff1aSopenharmony_ci const int *block_offset, 632cabdff1aSopenharmony_ci int linesize, 633cabdff1aSopenharmony_ci uint8_t *dest_y) 634cabdff1aSopenharmony_ci{ 635cabdff1aSopenharmony_ci int i; 636cabdff1aSopenharmony_ci int qscale = s->qscale; 637cabdff1aSopenharmony_ci 638cabdff1aSopenharmony_ci if (IS_INTRA4x4(mb_type)) { 639cabdff1aSopenharmony_ci for (i = 0; i < 16; i++) { 640cabdff1aSopenharmony_ci uint8_t *const ptr = dest_y + block_offset[i]; 641cabdff1aSopenharmony_ci const int dir = s->intra4x4_pred_mode_cache[scan8[i]]; 642cabdff1aSopenharmony_ci 643cabdff1aSopenharmony_ci uint8_t *topright; 644cabdff1aSopenharmony_ci int nnz; 645cabdff1aSopenharmony_ci if (dir == DIAG_DOWN_LEFT_PRED || dir == VERT_LEFT_PRED) { 646cabdff1aSopenharmony_ci av_assert2(s->mb_y || linesize <= block_offset[i]); 647cabdff1aSopenharmony_ci topright = ptr + 4 - linesize; 648cabdff1aSopenharmony_ci } else 649cabdff1aSopenharmony_ci topright = NULL; 650cabdff1aSopenharmony_ci 651cabdff1aSopenharmony_ci s->hpc.pred4x4[dir](ptr, topright, linesize); 652cabdff1aSopenharmony_ci nnz = s->non_zero_count_cache[scan8[i]]; 653cabdff1aSopenharmony_ci if (nnz) { 654cabdff1aSopenharmony_ci svq3_add_idct_c(ptr, s->mb + i * 16, linesize, qscale, 0); 655cabdff1aSopenharmony_ci } 656cabdff1aSopenharmony_ci } 657cabdff1aSopenharmony_ci } else { 658cabdff1aSopenharmony_ci s->hpc.pred16x16[s->intra16x16_pred_mode](dest_y, linesize); 659cabdff1aSopenharmony_ci svq3_luma_dc_dequant_idct_c(s->mb, s->mb_luma_dc[0], qscale); 660cabdff1aSopenharmony_ci } 661cabdff1aSopenharmony_ci} 662cabdff1aSopenharmony_ci 663cabdff1aSopenharmony_cistatic void hl_decode_mb(SVQ3Context *s) 664cabdff1aSopenharmony_ci{ 665cabdff1aSopenharmony_ci const int mb_x = s->mb_x; 666cabdff1aSopenharmony_ci const int mb_y = s->mb_y; 667cabdff1aSopenharmony_ci const int mb_xy = s->mb_xy; 668cabdff1aSopenharmony_ci const int mb_type = s->cur_pic->mb_type[mb_xy]; 669cabdff1aSopenharmony_ci uint8_t *dest_y, *dest_cb, *dest_cr; 670cabdff1aSopenharmony_ci int linesize, uvlinesize; 671cabdff1aSopenharmony_ci int i, j; 672cabdff1aSopenharmony_ci const int *block_offset = &s->block_offset[0]; 673cabdff1aSopenharmony_ci const int block_h = 16 >> 1; 674cabdff1aSopenharmony_ci 675cabdff1aSopenharmony_ci linesize = s->cur_pic->f->linesize[0]; 676cabdff1aSopenharmony_ci uvlinesize = s->cur_pic->f->linesize[1]; 677cabdff1aSopenharmony_ci 678cabdff1aSopenharmony_ci dest_y = s->cur_pic->f->data[0] + (mb_x + mb_y * linesize) * 16; 679cabdff1aSopenharmony_ci dest_cb = s->cur_pic->f->data[1] + mb_x * 8 + mb_y * uvlinesize * block_h; 680cabdff1aSopenharmony_ci dest_cr = s->cur_pic->f->data[2] + mb_x * 8 + mb_y * uvlinesize * block_h; 681cabdff1aSopenharmony_ci 682cabdff1aSopenharmony_ci s->vdsp.prefetch(dest_y + (s->mb_x & 3) * 4 * linesize + 64, linesize, 4); 683cabdff1aSopenharmony_ci s->vdsp.prefetch(dest_cb + (s->mb_x & 7) * uvlinesize + 64, dest_cr - dest_cb, 2); 684cabdff1aSopenharmony_ci 685cabdff1aSopenharmony_ci if (IS_INTRA(mb_type)) { 686cabdff1aSopenharmony_ci s->hpc.pred8x8[s->chroma_pred_mode](dest_cb, uvlinesize); 687cabdff1aSopenharmony_ci s->hpc.pred8x8[s->chroma_pred_mode](dest_cr, uvlinesize); 688cabdff1aSopenharmony_ci 689cabdff1aSopenharmony_ci hl_decode_mb_predict_luma(s, mb_type, block_offset, linesize, dest_y); 690cabdff1aSopenharmony_ci } 691cabdff1aSopenharmony_ci 692cabdff1aSopenharmony_ci hl_decode_mb_idct_luma(s, mb_type, block_offset, linesize, dest_y); 693cabdff1aSopenharmony_ci 694cabdff1aSopenharmony_ci if (s->cbp & 0x30) { 695cabdff1aSopenharmony_ci uint8_t *dest[2] = { dest_cb, dest_cr }; 696cabdff1aSopenharmony_ci s->h264dsp.h264_chroma_dc_dequant_idct(s->mb + 16 * 16 * 1, 697cabdff1aSopenharmony_ci s->dequant4_coeff[4][0]); 698cabdff1aSopenharmony_ci s->h264dsp.h264_chroma_dc_dequant_idct(s->mb + 16 * 16 * 2, 699cabdff1aSopenharmony_ci s->dequant4_coeff[4][0]); 700cabdff1aSopenharmony_ci for (j = 1; j < 3; j++) { 701cabdff1aSopenharmony_ci for (i = j * 16; i < j * 16 + 4; i++) 702cabdff1aSopenharmony_ci if (s->non_zero_count_cache[scan8[i]] || s->mb[i * 16]) { 703cabdff1aSopenharmony_ci uint8_t *const ptr = dest[j - 1] + block_offset[i]; 704cabdff1aSopenharmony_ci svq3_add_idct_c(ptr, s->mb + i * 16, 705cabdff1aSopenharmony_ci uvlinesize, ff_h264_chroma_qp[0][s->qscale + 12] - 12, 2); 706cabdff1aSopenharmony_ci } 707cabdff1aSopenharmony_ci } 708cabdff1aSopenharmony_ci } 709cabdff1aSopenharmony_ci} 710cabdff1aSopenharmony_ci 711cabdff1aSopenharmony_cistatic int svq3_decode_mb(SVQ3Context *s, unsigned int mb_type) 712cabdff1aSopenharmony_ci{ 713cabdff1aSopenharmony_ci int i, j, k, m, dir, mode; 714cabdff1aSopenharmony_ci int cbp = 0; 715cabdff1aSopenharmony_ci uint32_t vlc; 716cabdff1aSopenharmony_ci int8_t *top, *left; 717cabdff1aSopenharmony_ci const int mb_xy = s->mb_xy; 718cabdff1aSopenharmony_ci const int b_xy = 4 * s->mb_x + 4 * s->mb_y * s->b_stride; 719cabdff1aSopenharmony_ci 720cabdff1aSopenharmony_ci s->top_samples_available = (s->mb_y == 0) ? 0x33FF : 0xFFFF; 721cabdff1aSopenharmony_ci s->left_samples_available = (s->mb_x == 0) ? 0x5F5F : 0xFFFF; 722cabdff1aSopenharmony_ci 723cabdff1aSopenharmony_ci if (mb_type == 0) { /* SKIP */ 724cabdff1aSopenharmony_ci if (s->pict_type == AV_PICTURE_TYPE_P || 725cabdff1aSopenharmony_ci s->next_pic->mb_type[mb_xy] == -1) { 726cabdff1aSopenharmony_ci svq3_mc_dir_part(s, 16 * s->mb_x, 16 * s->mb_y, 16, 16, 727cabdff1aSopenharmony_ci 0, 0, 0, 0, 0, 0); 728cabdff1aSopenharmony_ci 729cabdff1aSopenharmony_ci if (s->pict_type == AV_PICTURE_TYPE_B) 730cabdff1aSopenharmony_ci svq3_mc_dir_part(s, 16 * s->mb_x, 16 * s->mb_y, 16, 16, 731cabdff1aSopenharmony_ci 0, 0, 0, 0, 1, 1); 732cabdff1aSopenharmony_ci 733cabdff1aSopenharmony_ci mb_type = MB_TYPE_SKIP; 734cabdff1aSopenharmony_ci } else { 735cabdff1aSopenharmony_ci mb_type = FFMIN(s->next_pic->mb_type[mb_xy], 6); 736cabdff1aSopenharmony_ci if (svq3_mc_dir(s, mb_type, PREDICT_MODE, 0, 0) < 0) 737cabdff1aSopenharmony_ci return -1; 738cabdff1aSopenharmony_ci if (svq3_mc_dir(s, mb_type, PREDICT_MODE, 1, 1) < 0) 739cabdff1aSopenharmony_ci return -1; 740cabdff1aSopenharmony_ci 741cabdff1aSopenharmony_ci mb_type = MB_TYPE_16x16; 742cabdff1aSopenharmony_ci } 743cabdff1aSopenharmony_ci } else if (mb_type < 8) { /* INTER */ 744cabdff1aSopenharmony_ci if (s->thirdpel_flag && s->halfpel_flag == !get_bits1(&s->gb_slice)) 745cabdff1aSopenharmony_ci mode = THIRDPEL_MODE; 746cabdff1aSopenharmony_ci else if (s->halfpel_flag && 747cabdff1aSopenharmony_ci s->thirdpel_flag == !get_bits1(&s->gb_slice)) 748cabdff1aSopenharmony_ci mode = HALFPEL_MODE; 749cabdff1aSopenharmony_ci else 750cabdff1aSopenharmony_ci mode = FULLPEL_MODE; 751cabdff1aSopenharmony_ci 752cabdff1aSopenharmony_ci /* fill caches */ 753cabdff1aSopenharmony_ci /* note ref_cache should contain here: 754cabdff1aSopenharmony_ci * ???????? 755cabdff1aSopenharmony_ci * ???11111 756cabdff1aSopenharmony_ci * N??11111 757cabdff1aSopenharmony_ci * N??11111 758cabdff1aSopenharmony_ci * N??11111 759cabdff1aSopenharmony_ci */ 760cabdff1aSopenharmony_ci 761cabdff1aSopenharmony_ci for (m = 0; m < 2; m++) { 762cabdff1aSopenharmony_ci if (s->mb_x > 0 && s->intra4x4_pred_mode[s->mb2br_xy[mb_xy - 1] + 6] != -1) { 763cabdff1aSopenharmony_ci for (i = 0; i < 4; i++) 764cabdff1aSopenharmony_ci AV_COPY32(s->mv_cache[m][scan8[0] - 1 + i * 8], 765cabdff1aSopenharmony_ci s->cur_pic->motion_val[m][b_xy - 1 + i * s->b_stride]); 766cabdff1aSopenharmony_ci } else { 767cabdff1aSopenharmony_ci for (i = 0; i < 4; i++) 768cabdff1aSopenharmony_ci AV_ZERO32(s->mv_cache[m][scan8[0] - 1 + i * 8]); 769cabdff1aSopenharmony_ci } 770cabdff1aSopenharmony_ci if (s->mb_y > 0) { 771cabdff1aSopenharmony_ci memcpy(s->mv_cache[m][scan8[0] - 1 * 8], 772cabdff1aSopenharmony_ci s->cur_pic->motion_val[m][b_xy - s->b_stride], 773cabdff1aSopenharmony_ci 4 * 2 * sizeof(int16_t)); 774cabdff1aSopenharmony_ci memset(&s->ref_cache[m][scan8[0] - 1 * 8], 775cabdff1aSopenharmony_ci (s->intra4x4_pred_mode[s->mb2br_xy[mb_xy - s->mb_stride]] == -1) ? PART_NOT_AVAILABLE : 1, 4); 776cabdff1aSopenharmony_ci 777cabdff1aSopenharmony_ci if (s->mb_x < s->mb_width - 1) { 778cabdff1aSopenharmony_ci AV_COPY32(s->mv_cache[m][scan8[0] + 4 - 1 * 8], 779cabdff1aSopenharmony_ci s->cur_pic->motion_val[m][b_xy - s->b_stride + 4]); 780cabdff1aSopenharmony_ci s->ref_cache[m][scan8[0] + 4 - 1 * 8] = 781cabdff1aSopenharmony_ci (s->intra4x4_pred_mode[s->mb2br_xy[mb_xy - s->mb_stride + 1] + 6] == -1 || 782cabdff1aSopenharmony_ci s->intra4x4_pred_mode[s->mb2br_xy[mb_xy - s->mb_stride]] == -1) ? PART_NOT_AVAILABLE : 1; 783cabdff1aSopenharmony_ci } else 784cabdff1aSopenharmony_ci s->ref_cache[m][scan8[0] + 4 - 1 * 8] = PART_NOT_AVAILABLE; 785cabdff1aSopenharmony_ci if (s->mb_x > 0) { 786cabdff1aSopenharmony_ci AV_COPY32(s->mv_cache[m][scan8[0] - 1 - 1 * 8], 787cabdff1aSopenharmony_ci s->cur_pic->motion_val[m][b_xy - s->b_stride - 1]); 788cabdff1aSopenharmony_ci s->ref_cache[m][scan8[0] - 1 - 1 * 8] = 789cabdff1aSopenharmony_ci (s->intra4x4_pred_mode[s->mb2br_xy[mb_xy - s->mb_stride - 1] + 3] == -1) ? PART_NOT_AVAILABLE : 1; 790cabdff1aSopenharmony_ci } else 791cabdff1aSopenharmony_ci s->ref_cache[m][scan8[0] - 1 - 1 * 8] = PART_NOT_AVAILABLE; 792cabdff1aSopenharmony_ci } else 793cabdff1aSopenharmony_ci memset(&s->ref_cache[m][scan8[0] - 1 * 8 - 1], 794cabdff1aSopenharmony_ci PART_NOT_AVAILABLE, 8); 795cabdff1aSopenharmony_ci 796cabdff1aSopenharmony_ci if (s->pict_type != AV_PICTURE_TYPE_B) 797cabdff1aSopenharmony_ci break; 798cabdff1aSopenharmony_ci } 799cabdff1aSopenharmony_ci 800cabdff1aSopenharmony_ci /* decode motion vector(s) and form prediction(s) */ 801cabdff1aSopenharmony_ci if (s->pict_type == AV_PICTURE_TYPE_P) { 802cabdff1aSopenharmony_ci if (svq3_mc_dir(s, mb_type - 1, mode, 0, 0) < 0) 803cabdff1aSopenharmony_ci return -1; 804cabdff1aSopenharmony_ci } else { /* AV_PICTURE_TYPE_B */ 805cabdff1aSopenharmony_ci if (mb_type != 2) { 806cabdff1aSopenharmony_ci if (svq3_mc_dir(s, 0, mode, 0, 0) < 0) 807cabdff1aSopenharmony_ci return -1; 808cabdff1aSopenharmony_ci } else { 809cabdff1aSopenharmony_ci for (i = 0; i < 4; i++) 810cabdff1aSopenharmony_ci memset(s->cur_pic->motion_val[0][b_xy + i * s->b_stride], 811cabdff1aSopenharmony_ci 0, 4 * 2 * sizeof(int16_t)); 812cabdff1aSopenharmony_ci } 813cabdff1aSopenharmony_ci if (mb_type != 1) { 814cabdff1aSopenharmony_ci if (svq3_mc_dir(s, 0, mode, 1, mb_type == 3) < 0) 815cabdff1aSopenharmony_ci return -1; 816cabdff1aSopenharmony_ci } else { 817cabdff1aSopenharmony_ci for (i = 0; i < 4; i++) 818cabdff1aSopenharmony_ci memset(s->cur_pic->motion_val[1][b_xy + i * s->b_stride], 819cabdff1aSopenharmony_ci 0, 4 * 2 * sizeof(int16_t)); 820cabdff1aSopenharmony_ci } 821cabdff1aSopenharmony_ci } 822cabdff1aSopenharmony_ci 823cabdff1aSopenharmony_ci mb_type = MB_TYPE_16x16; 824cabdff1aSopenharmony_ci } else if (mb_type == 8 || mb_type == 33) { /* INTRA4x4 */ 825cabdff1aSopenharmony_ci int8_t *i4x4 = s->intra4x4_pred_mode + s->mb2br_xy[s->mb_xy]; 826cabdff1aSopenharmony_ci int8_t *i4x4_cache = s->intra4x4_pred_mode_cache; 827cabdff1aSopenharmony_ci 828cabdff1aSopenharmony_ci memset(s->intra4x4_pred_mode_cache, -1, 8 * 5 * sizeof(int8_t)); 829cabdff1aSopenharmony_ci 830cabdff1aSopenharmony_ci if (mb_type == 8) { 831cabdff1aSopenharmony_ci if (s->mb_x > 0) { 832cabdff1aSopenharmony_ci for (i = 0; i < 4; i++) 833cabdff1aSopenharmony_ci s->intra4x4_pred_mode_cache[scan8[0] - 1 + i * 8] = s->intra4x4_pred_mode[s->mb2br_xy[mb_xy - 1] + 6 - i]; 834cabdff1aSopenharmony_ci if (s->intra4x4_pred_mode_cache[scan8[0] - 1] == -1) 835cabdff1aSopenharmony_ci s->left_samples_available = 0x5F5F; 836cabdff1aSopenharmony_ci } 837cabdff1aSopenharmony_ci if (s->mb_y > 0) { 838cabdff1aSopenharmony_ci s->intra4x4_pred_mode_cache[4 + 8 * 0] = s->intra4x4_pred_mode[s->mb2br_xy[mb_xy - s->mb_stride] + 0]; 839cabdff1aSopenharmony_ci s->intra4x4_pred_mode_cache[5 + 8 * 0] = s->intra4x4_pred_mode[s->mb2br_xy[mb_xy - s->mb_stride] + 1]; 840cabdff1aSopenharmony_ci s->intra4x4_pred_mode_cache[6 + 8 * 0] = s->intra4x4_pred_mode[s->mb2br_xy[mb_xy - s->mb_stride] + 2]; 841cabdff1aSopenharmony_ci s->intra4x4_pred_mode_cache[7 + 8 * 0] = s->intra4x4_pred_mode[s->mb2br_xy[mb_xy - s->mb_stride] + 3]; 842cabdff1aSopenharmony_ci 843cabdff1aSopenharmony_ci if (s->intra4x4_pred_mode_cache[4 + 8 * 0] == -1) 844cabdff1aSopenharmony_ci s->top_samples_available = 0x33FF; 845cabdff1aSopenharmony_ci } 846cabdff1aSopenharmony_ci 847cabdff1aSopenharmony_ci /* decode prediction codes for luma blocks */ 848cabdff1aSopenharmony_ci for (i = 0; i < 16; i += 2) { 849cabdff1aSopenharmony_ci vlc = get_interleaved_ue_golomb(&s->gb_slice); 850cabdff1aSopenharmony_ci 851cabdff1aSopenharmony_ci if (vlc >= 25U) { 852cabdff1aSopenharmony_ci av_log(s->avctx, AV_LOG_ERROR, 853cabdff1aSopenharmony_ci "luma prediction:%"PRIu32"\n", vlc); 854cabdff1aSopenharmony_ci return -1; 855cabdff1aSopenharmony_ci } 856cabdff1aSopenharmony_ci 857cabdff1aSopenharmony_ci left = &s->intra4x4_pred_mode_cache[scan8[i] - 1]; 858cabdff1aSopenharmony_ci top = &s->intra4x4_pred_mode_cache[scan8[i] - 8]; 859cabdff1aSopenharmony_ci 860cabdff1aSopenharmony_ci left[1] = svq3_pred_1[top[0] + 1][left[0] + 1][svq3_pred_0[vlc][0]]; 861cabdff1aSopenharmony_ci left[2] = svq3_pred_1[top[1] + 1][left[1] + 1][svq3_pred_0[vlc][1]]; 862cabdff1aSopenharmony_ci 863cabdff1aSopenharmony_ci if (left[1] == -1 || left[2] == -1) { 864cabdff1aSopenharmony_ci av_log(s->avctx, AV_LOG_ERROR, "weird prediction\n"); 865cabdff1aSopenharmony_ci return -1; 866cabdff1aSopenharmony_ci } 867cabdff1aSopenharmony_ci } 868cabdff1aSopenharmony_ci } else { /* mb_type == 33, DC_128_PRED block type */ 869cabdff1aSopenharmony_ci for (i = 0; i < 4; i++) 870cabdff1aSopenharmony_ci memset(&s->intra4x4_pred_mode_cache[scan8[0] + 8 * i], DC_PRED, 4); 871cabdff1aSopenharmony_ci } 872cabdff1aSopenharmony_ci 873cabdff1aSopenharmony_ci AV_COPY32(i4x4, i4x4_cache + 4 + 8 * 4); 874cabdff1aSopenharmony_ci i4x4[4] = i4x4_cache[7 + 8 * 3]; 875cabdff1aSopenharmony_ci i4x4[5] = i4x4_cache[7 + 8 * 2]; 876cabdff1aSopenharmony_ci i4x4[6] = i4x4_cache[7 + 8 * 1]; 877cabdff1aSopenharmony_ci 878cabdff1aSopenharmony_ci if (mb_type == 8) { 879cabdff1aSopenharmony_ci ff_h264_check_intra4x4_pred_mode(s->intra4x4_pred_mode_cache, 880cabdff1aSopenharmony_ci s->avctx, s->top_samples_available, 881cabdff1aSopenharmony_ci s->left_samples_available); 882cabdff1aSopenharmony_ci 883cabdff1aSopenharmony_ci s->top_samples_available = (s->mb_y == 0) ? 0x33FF : 0xFFFF; 884cabdff1aSopenharmony_ci s->left_samples_available = (s->mb_x == 0) ? 0x5F5F : 0xFFFF; 885cabdff1aSopenharmony_ci } else { 886cabdff1aSopenharmony_ci for (i = 0; i < 4; i++) 887cabdff1aSopenharmony_ci memset(&s->intra4x4_pred_mode_cache[scan8[0] + 8 * i], DC_128_PRED, 4); 888cabdff1aSopenharmony_ci 889cabdff1aSopenharmony_ci s->top_samples_available = 0x33FF; 890cabdff1aSopenharmony_ci s->left_samples_available = 0x5F5F; 891cabdff1aSopenharmony_ci } 892cabdff1aSopenharmony_ci 893cabdff1aSopenharmony_ci mb_type = MB_TYPE_INTRA4x4; 894cabdff1aSopenharmony_ci } else { /* INTRA16x16 */ 895cabdff1aSopenharmony_ci dir = ff_h264_i_mb_type_info[mb_type - 8].pred_mode; 896cabdff1aSopenharmony_ci dir = (dir >> 1) ^ 3 * (dir & 1) ^ 1; 897cabdff1aSopenharmony_ci 898cabdff1aSopenharmony_ci if ((s->intra16x16_pred_mode = ff_h264_check_intra_pred_mode(s->avctx, s->top_samples_available, 899cabdff1aSopenharmony_ci s->left_samples_available, dir, 0)) < 0) { 900cabdff1aSopenharmony_ci av_log(s->avctx, AV_LOG_ERROR, "ff_h264_check_intra_pred_mode < 0\n"); 901cabdff1aSopenharmony_ci return s->intra16x16_pred_mode; 902cabdff1aSopenharmony_ci } 903cabdff1aSopenharmony_ci 904cabdff1aSopenharmony_ci cbp = ff_h264_i_mb_type_info[mb_type - 8].cbp; 905cabdff1aSopenharmony_ci mb_type = MB_TYPE_INTRA16x16; 906cabdff1aSopenharmony_ci } 907cabdff1aSopenharmony_ci 908cabdff1aSopenharmony_ci if (!IS_INTER(mb_type) && s->pict_type != AV_PICTURE_TYPE_I) { 909cabdff1aSopenharmony_ci for (i = 0; i < 4; i++) 910cabdff1aSopenharmony_ci memset(s->cur_pic->motion_val[0][b_xy + i * s->b_stride], 911cabdff1aSopenharmony_ci 0, 4 * 2 * sizeof(int16_t)); 912cabdff1aSopenharmony_ci if (s->pict_type == AV_PICTURE_TYPE_B) { 913cabdff1aSopenharmony_ci for (i = 0; i < 4; i++) 914cabdff1aSopenharmony_ci memset(s->cur_pic->motion_val[1][b_xy + i * s->b_stride], 915cabdff1aSopenharmony_ci 0, 4 * 2 * sizeof(int16_t)); 916cabdff1aSopenharmony_ci } 917cabdff1aSopenharmony_ci } 918cabdff1aSopenharmony_ci if (!IS_INTRA4x4(mb_type)) { 919cabdff1aSopenharmony_ci memset(s->intra4x4_pred_mode + s->mb2br_xy[mb_xy], DC_PRED, 8); 920cabdff1aSopenharmony_ci } 921cabdff1aSopenharmony_ci if (!IS_SKIP(mb_type) || s->pict_type == AV_PICTURE_TYPE_B) { 922cabdff1aSopenharmony_ci memset(s->non_zero_count_cache + 8, 0, 14 * 8 * sizeof(uint8_t)); 923cabdff1aSopenharmony_ci } 924cabdff1aSopenharmony_ci 925cabdff1aSopenharmony_ci if (!IS_INTRA16x16(mb_type) && 926cabdff1aSopenharmony_ci (!IS_SKIP(mb_type) || s->pict_type == AV_PICTURE_TYPE_B)) { 927cabdff1aSopenharmony_ci if ((vlc = get_interleaved_ue_golomb(&s->gb_slice)) >= 48U){ 928cabdff1aSopenharmony_ci av_log(s->avctx, AV_LOG_ERROR, "cbp_vlc=%"PRIu32"\n", vlc); 929cabdff1aSopenharmony_ci return -1; 930cabdff1aSopenharmony_ci } 931cabdff1aSopenharmony_ci 932cabdff1aSopenharmony_ci cbp = IS_INTRA(mb_type) ? ff_h264_golomb_to_intra4x4_cbp[vlc] 933cabdff1aSopenharmony_ci : ff_h264_golomb_to_inter_cbp[vlc]; 934cabdff1aSopenharmony_ci } 935cabdff1aSopenharmony_ci if (IS_INTRA16x16(mb_type) || 936cabdff1aSopenharmony_ci (s->pict_type != AV_PICTURE_TYPE_I && s->adaptive_quant && cbp)) { 937cabdff1aSopenharmony_ci s->qscale += get_interleaved_se_golomb(&s->gb_slice); 938cabdff1aSopenharmony_ci 939cabdff1aSopenharmony_ci if (s->qscale > 31u) { 940cabdff1aSopenharmony_ci av_log(s->avctx, AV_LOG_ERROR, "qscale:%d\n", s->qscale); 941cabdff1aSopenharmony_ci return -1; 942cabdff1aSopenharmony_ci } 943cabdff1aSopenharmony_ci } 944cabdff1aSopenharmony_ci if (IS_INTRA16x16(mb_type)) { 945cabdff1aSopenharmony_ci AV_ZERO128(s->mb_luma_dc[0] + 0); 946cabdff1aSopenharmony_ci AV_ZERO128(s->mb_luma_dc[0] + 8); 947cabdff1aSopenharmony_ci if (svq3_decode_block(&s->gb_slice, s->mb_luma_dc[0], 0, 1)) { 948cabdff1aSopenharmony_ci av_log(s->avctx, AV_LOG_ERROR, 949cabdff1aSopenharmony_ci "error while decoding intra luma dc\n"); 950cabdff1aSopenharmony_ci return -1; 951cabdff1aSopenharmony_ci } 952cabdff1aSopenharmony_ci } 953cabdff1aSopenharmony_ci 954cabdff1aSopenharmony_ci if (cbp) { 955cabdff1aSopenharmony_ci const int index = IS_INTRA16x16(mb_type) ? 1 : 0; 956cabdff1aSopenharmony_ci const int type = ((s->qscale < 24 && IS_INTRA4x4(mb_type)) ? 2 : 1); 957cabdff1aSopenharmony_ci 958cabdff1aSopenharmony_ci for (i = 0; i < 4; i++) 959cabdff1aSopenharmony_ci if ((cbp & (1 << i))) { 960cabdff1aSopenharmony_ci for (j = 0; j < 4; j++) { 961cabdff1aSopenharmony_ci k = index ? (1 * (j & 1) + 2 * (i & 1) + 962cabdff1aSopenharmony_ci 2 * (j & 2) + 4 * (i & 2)) 963cabdff1aSopenharmony_ci : (4 * i + j); 964cabdff1aSopenharmony_ci s->non_zero_count_cache[scan8[k]] = 1; 965cabdff1aSopenharmony_ci 966cabdff1aSopenharmony_ci if (svq3_decode_block(&s->gb_slice, &s->mb[16 * k], index, type)) { 967cabdff1aSopenharmony_ci av_log(s->avctx, AV_LOG_ERROR, 968cabdff1aSopenharmony_ci "error while decoding block\n"); 969cabdff1aSopenharmony_ci return -1; 970cabdff1aSopenharmony_ci } 971cabdff1aSopenharmony_ci } 972cabdff1aSopenharmony_ci } 973cabdff1aSopenharmony_ci 974cabdff1aSopenharmony_ci if ((cbp & 0x30)) { 975cabdff1aSopenharmony_ci for (i = 1; i < 3; ++i) 976cabdff1aSopenharmony_ci if (svq3_decode_block(&s->gb_slice, &s->mb[16 * 16 * i], 0, 3)) { 977cabdff1aSopenharmony_ci av_log(s->avctx, AV_LOG_ERROR, 978cabdff1aSopenharmony_ci "error while decoding chroma dc block\n"); 979cabdff1aSopenharmony_ci return -1; 980cabdff1aSopenharmony_ci } 981cabdff1aSopenharmony_ci 982cabdff1aSopenharmony_ci if ((cbp & 0x20)) { 983cabdff1aSopenharmony_ci for (i = 1; i < 3; i++) { 984cabdff1aSopenharmony_ci for (j = 0; j < 4; j++) { 985cabdff1aSopenharmony_ci k = 16 * i + j; 986cabdff1aSopenharmony_ci s->non_zero_count_cache[scan8[k]] = 1; 987cabdff1aSopenharmony_ci 988cabdff1aSopenharmony_ci if (svq3_decode_block(&s->gb_slice, &s->mb[16 * k], 1, 1)) { 989cabdff1aSopenharmony_ci av_log(s->avctx, AV_LOG_ERROR, 990cabdff1aSopenharmony_ci "error while decoding chroma ac block\n"); 991cabdff1aSopenharmony_ci return -1; 992cabdff1aSopenharmony_ci } 993cabdff1aSopenharmony_ci } 994cabdff1aSopenharmony_ci } 995cabdff1aSopenharmony_ci } 996cabdff1aSopenharmony_ci } 997cabdff1aSopenharmony_ci } 998cabdff1aSopenharmony_ci 999cabdff1aSopenharmony_ci s->cbp = cbp; 1000cabdff1aSopenharmony_ci s->cur_pic->mb_type[mb_xy] = mb_type; 1001cabdff1aSopenharmony_ci 1002cabdff1aSopenharmony_ci if (IS_INTRA(mb_type)) 1003cabdff1aSopenharmony_ci s->chroma_pred_mode = ff_h264_check_intra_pred_mode(s->avctx, s->top_samples_available, 1004cabdff1aSopenharmony_ci s->left_samples_available, DC_PRED8x8, 1); 1005cabdff1aSopenharmony_ci 1006cabdff1aSopenharmony_ci return 0; 1007cabdff1aSopenharmony_ci} 1008cabdff1aSopenharmony_ci 1009cabdff1aSopenharmony_cistatic int svq3_decode_slice_header(AVCodecContext *avctx) 1010cabdff1aSopenharmony_ci{ 1011cabdff1aSopenharmony_ci SVQ3Context *s = avctx->priv_data; 1012cabdff1aSopenharmony_ci const int mb_xy = s->mb_xy; 1013cabdff1aSopenharmony_ci int i, header; 1014cabdff1aSopenharmony_ci unsigned slice_id; 1015cabdff1aSopenharmony_ci 1016cabdff1aSopenharmony_ci header = get_bits(&s->gb, 8); 1017cabdff1aSopenharmony_ci 1018cabdff1aSopenharmony_ci if (((header & 0x9F) != 1 && (header & 0x9F) != 2) || (header & 0x60) == 0) { 1019cabdff1aSopenharmony_ci /* TODO: what? */ 1020cabdff1aSopenharmony_ci av_log(avctx, AV_LOG_ERROR, "unsupported slice header (%02X)\n", header); 1021cabdff1aSopenharmony_ci return -1; 1022cabdff1aSopenharmony_ci } else { 1023cabdff1aSopenharmony_ci int slice_bits, slice_bytes, slice_length; 1024cabdff1aSopenharmony_ci int length = header >> 5 & 3; 1025cabdff1aSopenharmony_ci 1026cabdff1aSopenharmony_ci slice_length = show_bits(&s->gb, 8 * length); 1027cabdff1aSopenharmony_ci slice_bits = slice_length * 8; 1028cabdff1aSopenharmony_ci slice_bytes = slice_length + length - 1; 1029cabdff1aSopenharmony_ci 1030cabdff1aSopenharmony_ci skip_bits(&s->gb, 8); 1031cabdff1aSopenharmony_ci 1032cabdff1aSopenharmony_ci av_fast_padded_malloc(&s->slice_buf, &s->slice_buf_size, slice_bytes); 1033cabdff1aSopenharmony_ci if (!s->slice_buf) 1034cabdff1aSopenharmony_ci return AVERROR(ENOMEM); 1035cabdff1aSopenharmony_ci 1036cabdff1aSopenharmony_ci if (slice_bytes * 8LL > get_bits_left(&s->gb)) { 1037cabdff1aSopenharmony_ci av_log(avctx, AV_LOG_ERROR, "slice after bitstream end\n"); 1038cabdff1aSopenharmony_ci return AVERROR_INVALIDDATA; 1039cabdff1aSopenharmony_ci } 1040cabdff1aSopenharmony_ci memcpy(s->slice_buf, s->gb.buffer + s->gb.index / 8, slice_bytes); 1041cabdff1aSopenharmony_ci 1042cabdff1aSopenharmony_ci if (s->watermark_key) { 1043cabdff1aSopenharmony_ci uint32_t header = AV_RL32(&s->slice_buf[1]); 1044cabdff1aSopenharmony_ci AV_WL32(&s->slice_buf[1], header ^ s->watermark_key); 1045cabdff1aSopenharmony_ci } 1046cabdff1aSopenharmony_ci init_get_bits(&s->gb_slice, s->slice_buf, slice_bits); 1047cabdff1aSopenharmony_ci 1048cabdff1aSopenharmony_ci if (length > 0) { 1049cabdff1aSopenharmony_ci memmove(s->slice_buf, &s->slice_buf[slice_length], length - 1); 1050cabdff1aSopenharmony_ci } 1051cabdff1aSopenharmony_ci skip_bits_long(&s->gb, slice_bytes * 8); 1052cabdff1aSopenharmony_ci } 1053cabdff1aSopenharmony_ci 1054cabdff1aSopenharmony_ci if ((slice_id = get_interleaved_ue_golomb(&s->gb_slice)) >= 3) { 1055cabdff1aSopenharmony_ci av_log(s->avctx, AV_LOG_ERROR, "illegal slice type %u \n", slice_id); 1056cabdff1aSopenharmony_ci return -1; 1057cabdff1aSopenharmony_ci } 1058cabdff1aSopenharmony_ci 1059cabdff1aSopenharmony_ci s->slice_type = ff_h264_golomb_to_pict_type[slice_id]; 1060cabdff1aSopenharmony_ci 1061cabdff1aSopenharmony_ci if ((header & 0x9F) == 2) { 1062cabdff1aSopenharmony_ci i = (s->mb_num < 64) ? 6 : (1 + av_log2(s->mb_num - 1)); 1063cabdff1aSopenharmony_ci get_bits(&s->gb_slice, i); 1064cabdff1aSopenharmony_ci } else if (get_bits1(&s->gb_slice)) { 1065cabdff1aSopenharmony_ci avpriv_report_missing_feature(s->avctx, "Media key encryption"); 1066cabdff1aSopenharmony_ci return AVERROR_PATCHWELCOME; 1067cabdff1aSopenharmony_ci } 1068cabdff1aSopenharmony_ci 1069cabdff1aSopenharmony_ci s->slice_num = get_bits(&s->gb_slice, 8); 1070cabdff1aSopenharmony_ci s->qscale = get_bits(&s->gb_slice, 5); 1071cabdff1aSopenharmony_ci s->adaptive_quant = get_bits1(&s->gb_slice); 1072cabdff1aSopenharmony_ci 1073cabdff1aSopenharmony_ci /* unknown fields */ 1074cabdff1aSopenharmony_ci skip_bits1(&s->gb_slice); 1075cabdff1aSopenharmony_ci 1076cabdff1aSopenharmony_ci if (s->has_watermark) 1077cabdff1aSopenharmony_ci skip_bits1(&s->gb_slice); 1078cabdff1aSopenharmony_ci 1079cabdff1aSopenharmony_ci skip_bits1(&s->gb_slice); 1080cabdff1aSopenharmony_ci skip_bits(&s->gb_slice, 2); 1081cabdff1aSopenharmony_ci 1082cabdff1aSopenharmony_ci if (skip_1stop_8data_bits(&s->gb_slice) < 0) 1083cabdff1aSopenharmony_ci return AVERROR_INVALIDDATA; 1084cabdff1aSopenharmony_ci 1085cabdff1aSopenharmony_ci /* reset intra predictors and invalidate motion vector references */ 1086cabdff1aSopenharmony_ci if (s->mb_x > 0) { 1087cabdff1aSopenharmony_ci memset(s->intra4x4_pred_mode + s->mb2br_xy[mb_xy - 1] + 3, 1088cabdff1aSopenharmony_ci -1, 4 * sizeof(int8_t)); 1089cabdff1aSopenharmony_ci memset(s->intra4x4_pred_mode + s->mb2br_xy[mb_xy - s->mb_x], 1090cabdff1aSopenharmony_ci -1, 8 * sizeof(int8_t) * s->mb_x); 1091cabdff1aSopenharmony_ci } 1092cabdff1aSopenharmony_ci if (s->mb_y > 0) { 1093cabdff1aSopenharmony_ci memset(s->intra4x4_pred_mode + s->mb2br_xy[mb_xy - s->mb_stride], 1094cabdff1aSopenharmony_ci -1, 8 * sizeof(int8_t) * (s->mb_width - s->mb_x)); 1095cabdff1aSopenharmony_ci 1096cabdff1aSopenharmony_ci if (s->mb_x > 0) 1097cabdff1aSopenharmony_ci s->intra4x4_pred_mode[s->mb2br_xy[mb_xy - s->mb_stride - 1] + 3] = -1; 1098cabdff1aSopenharmony_ci } 1099cabdff1aSopenharmony_ci 1100cabdff1aSopenharmony_ci return 0; 1101cabdff1aSopenharmony_ci} 1102cabdff1aSopenharmony_ci 1103cabdff1aSopenharmony_cistatic void init_dequant4_coeff_table(SVQ3Context *s) 1104cabdff1aSopenharmony_ci{ 1105cabdff1aSopenharmony_ci int q, x; 1106cabdff1aSopenharmony_ci const int max_qp = 51; 1107cabdff1aSopenharmony_ci 1108cabdff1aSopenharmony_ci for (q = 0; q < max_qp + 1; q++) { 1109cabdff1aSopenharmony_ci int shift = ff_h264_quant_div6[q] + 2; 1110cabdff1aSopenharmony_ci int idx = ff_h264_quant_rem6[q]; 1111cabdff1aSopenharmony_ci for (x = 0; x < 16; x++) 1112cabdff1aSopenharmony_ci s->dequant4_coeff[q][(x >> 2) | ((x << 2) & 0xF)] = 1113cabdff1aSopenharmony_ci ((uint32_t)ff_h264_dequant4_coeff_init[idx][(x & 1) + ((x >> 2) & 1)] * 16) << shift; 1114cabdff1aSopenharmony_ci } 1115cabdff1aSopenharmony_ci} 1116cabdff1aSopenharmony_ci 1117cabdff1aSopenharmony_cistatic av_cold int svq3_decode_init(AVCodecContext *avctx) 1118cabdff1aSopenharmony_ci{ 1119cabdff1aSopenharmony_ci SVQ3Context *s = avctx->priv_data; 1120cabdff1aSopenharmony_ci int m, x, y; 1121cabdff1aSopenharmony_ci unsigned char *extradata; 1122cabdff1aSopenharmony_ci unsigned char *extradata_end; 1123cabdff1aSopenharmony_ci unsigned int size; 1124cabdff1aSopenharmony_ci int marker_found = 0; 1125cabdff1aSopenharmony_ci int ret; 1126cabdff1aSopenharmony_ci 1127cabdff1aSopenharmony_ci s->cur_pic = &s->frames[0]; 1128cabdff1aSopenharmony_ci s->last_pic = &s->frames[1]; 1129cabdff1aSopenharmony_ci s->next_pic = &s->frames[2]; 1130cabdff1aSopenharmony_ci 1131cabdff1aSopenharmony_ci s->cur_pic->f = av_frame_alloc(); 1132cabdff1aSopenharmony_ci s->last_pic->f = av_frame_alloc(); 1133cabdff1aSopenharmony_ci s->next_pic->f = av_frame_alloc(); 1134cabdff1aSopenharmony_ci if (!s->cur_pic->f || !s->last_pic->f || !s->next_pic->f) 1135cabdff1aSopenharmony_ci return AVERROR(ENOMEM); 1136cabdff1aSopenharmony_ci 1137cabdff1aSopenharmony_ci ff_h264dsp_init(&s->h264dsp, 8, 1); 1138cabdff1aSopenharmony_ci ff_h264_pred_init(&s->hpc, AV_CODEC_ID_SVQ3, 8, 1); 1139cabdff1aSopenharmony_ci ff_videodsp_init(&s->vdsp, 8); 1140cabdff1aSopenharmony_ci 1141cabdff1aSopenharmony_ci 1142cabdff1aSopenharmony_ci avctx->bits_per_raw_sample = 8; 1143cabdff1aSopenharmony_ci 1144cabdff1aSopenharmony_ci ff_hpeldsp_init(&s->hdsp, avctx->flags); 1145cabdff1aSopenharmony_ci ff_tpeldsp_init(&s->tdsp); 1146cabdff1aSopenharmony_ci 1147cabdff1aSopenharmony_ci avctx->pix_fmt = AV_PIX_FMT_YUVJ420P; 1148cabdff1aSopenharmony_ci avctx->color_range = AVCOL_RANGE_JPEG; 1149cabdff1aSopenharmony_ci 1150cabdff1aSopenharmony_ci s->avctx = avctx; 1151cabdff1aSopenharmony_ci s->halfpel_flag = 1; 1152cabdff1aSopenharmony_ci s->thirdpel_flag = 1; 1153cabdff1aSopenharmony_ci s->has_watermark = 0; 1154cabdff1aSopenharmony_ci 1155cabdff1aSopenharmony_ci /* prowl for the "SEQH" marker in the extradata */ 1156cabdff1aSopenharmony_ci extradata = (unsigned char *)avctx->extradata; 1157cabdff1aSopenharmony_ci extradata_end = avctx->extradata + avctx->extradata_size; 1158cabdff1aSopenharmony_ci if (extradata) { 1159cabdff1aSopenharmony_ci for (m = 0; m + 8 < avctx->extradata_size; m++) { 1160cabdff1aSopenharmony_ci if (!memcmp(extradata, "SEQH", 4)) { 1161cabdff1aSopenharmony_ci marker_found = 1; 1162cabdff1aSopenharmony_ci break; 1163cabdff1aSopenharmony_ci } 1164cabdff1aSopenharmony_ci extradata++; 1165cabdff1aSopenharmony_ci } 1166cabdff1aSopenharmony_ci } 1167cabdff1aSopenharmony_ci 1168cabdff1aSopenharmony_ci /* if a match was found, parse the extra data */ 1169cabdff1aSopenharmony_ci if (marker_found) { 1170cabdff1aSopenharmony_ci GetBitContext gb; 1171cabdff1aSopenharmony_ci int frame_size_code; 1172cabdff1aSopenharmony_ci int unk0, unk1, unk2, unk3, unk4; 1173cabdff1aSopenharmony_ci int w,h; 1174cabdff1aSopenharmony_ci 1175cabdff1aSopenharmony_ci size = AV_RB32(&extradata[4]); 1176cabdff1aSopenharmony_ci if (size > extradata_end - extradata - 8) 1177cabdff1aSopenharmony_ci return AVERROR_INVALIDDATA; 1178cabdff1aSopenharmony_ci init_get_bits(&gb, extradata + 8, size * 8); 1179cabdff1aSopenharmony_ci 1180cabdff1aSopenharmony_ci /* 'frame size code' and optional 'width, height' */ 1181cabdff1aSopenharmony_ci frame_size_code = get_bits(&gb, 3); 1182cabdff1aSopenharmony_ci switch (frame_size_code) { 1183cabdff1aSopenharmony_ci case 0: 1184cabdff1aSopenharmony_ci w = 160; 1185cabdff1aSopenharmony_ci h = 120; 1186cabdff1aSopenharmony_ci break; 1187cabdff1aSopenharmony_ci case 1: 1188cabdff1aSopenharmony_ci w = 128; 1189cabdff1aSopenharmony_ci h = 96; 1190cabdff1aSopenharmony_ci break; 1191cabdff1aSopenharmony_ci case 2: 1192cabdff1aSopenharmony_ci w = 176; 1193cabdff1aSopenharmony_ci h = 144; 1194cabdff1aSopenharmony_ci break; 1195cabdff1aSopenharmony_ci case 3: 1196cabdff1aSopenharmony_ci w = 352; 1197cabdff1aSopenharmony_ci h = 288; 1198cabdff1aSopenharmony_ci break; 1199cabdff1aSopenharmony_ci case 4: 1200cabdff1aSopenharmony_ci w = 704; 1201cabdff1aSopenharmony_ci h = 576; 1202cabdff1aSopenharmony_ci break; 1203cabdff1aSopenharmony_ci case 5: 1204cabdff1aSopenharmony_ci w = 240; 1205cabdff1aSopenharmony_ci h = 180; 1206cabdff1aSopenharmony_ci break; 1207cabdff1aSopenharmony_ci case 6: 1208cabdff1aSopenharmony_ci w = 320; 1209cabdff1aSopenharmony_ci h = 240; 1210cabdff1aSopenharmony_ci break; 1211cabdff1aSopenharmony_ci case 7: 1212cabdff1aSopenharmony_ci w = get_bits(&gb, 12); 1213cabdff1aSopenharmony_ci h = get_bits(&gb, 12); 1214cabdff1aSopenharmony_ci break; 1215cabdff1aSopenharmony_ci } 1216cabdff1aSopenharmony_ci ret = ff_set_dimensions(avctx, w, h); 1217cabdff1aSopenharmony_ci if (ret < 0) 1218cabdff1aSopenharmony_ci return ret; 1219cabdff1aSopenharmony_ci 1220cabdff1aSopenharmony_ci s->halfpel_flag = get_bits1(&gb); 1221cabdff1aSopenharmony_ci s->thirdpel_flag = get_bits1(&gb); 1222cabdff1aSopenharmony_ci 1223cabdff1aSopenharmony_ci /* unknown fields */ 1224cabdff1aSopenharmony_ci unk0 = get_bits1(&gb); 1225cabdff1aSopenharmony_ci unk1 = get_bits1(&gb); 1226cabdff1aSopenharmony_ci unk2 = get_bits1(&gb); 1227cabdff1aSopenharmony_ci unk3 = get_bits1(&gb); 1228cabdff1aSopenharmony_ci 1229cabdff1aSopenharmony_ci s->low_delay = get_bits1(&gb); 1230cabdff1aSopenharmony_ci 1231cabdff1aSopenharmony_ci /* unknown field */ 1232cabdff1aSopenharmony_ci unk4 = get_bits1(&gb); 1233cabdff1aSopenharmony_ci 1234cabdff1aSopenharmony_ci av_log(avctx, AV_LOG_DEBUG, "Unknown fields %d %d %d %d %d\n", 1235cabdff1aSopenharmony_ci unk0, unk1, unk2, unk3, unk4); 1236cabdff1aSopenharmony_ci 1237cabdff1aSopenharmony_ci if (skip_1stop_8data_bits(&gb) < 0) 1238cabdff1aSopenharmony_ci return AVERROR_INVALIDDATA; 1239cabdff1aSopenharmony_ci 1240cabdff1aSopenharmony_ci s->has_watermark = get_bits1(&gb); 1241cabdff1aSopenharmony_ci avctx->has_b_frames = !s->low_delay; 1242cabdff1aSopenharmony_ci if (s->has_watermark) { 1243cabdff1aSopenharmony_ci#if CONFIG_ZLIB 1244cabdff1aSopenharmony_ci unsigned watermark_width = get_interleaved_ue_golomb(&gb); 1245cabdff1aSopenharmony_ci unsigned watermark_height = get_interleaved_ue_golomb(&gb); 1246cabdff1aSopenharmony_ci int u1 = get_interleaved_ue_golomb(&gb); 1247cabdff1aSopenharmony_ci int u2 = get_bits(&gb, 8); 1248cabdff1aSopenharmony_ci int u3 = get_bits(&gb, 2); 1249cabdff1aSopenharmony_ci int u4 = get_interleaved_ue_golomb(&gb); 1250cabdff1aSopenharmony_ci unsigned long buf_len = watermark_width * 1251cabdff1aSopenharmony_ci watermark_height * 4; 1252cabdff1aSopenharmony_ci int offset = get_bits_count(&gb) + 7 >> 3; 1253cabdff1aSopenharmony_ci uint8_t *buf; 1254cabdff1aSopenharmony_ci 1255cabdff1aSopenharmony_ci if (watermark_height <= 0 || 1256cabdff1aSopenharmony_ci (uint64_t)watermark_width * 4 > UINT_MAX / watermark_height) 1257cabdff1aSopenharmony_ci return AVERROR_INVALIDDATA; 1258cabdff1aSopenharmony_ci 1259cabdff1aSopenharmony_ci buf = av_malloc(buf_len); 1260cabdff1aSopenharmony_ci if (!buf) 1261cabdff1aSopenharmony_ci return AVERROR(ENOMEM); 1262cabdff1aSopenharmony_ci 1263cabdff1aSopenharmony_ci av_log(avctx, AV_LOG_DEBUG, "watermark size: %ux%u\n", 1264cabdff1aSopenharmony_ci watermark_width, watermark_height); 1265cabdff1aSopenharmony_ci av_log(avctx, AV_LOG_DEBUG, 1266cabdff1aSopenharmony_ci "u1: %x u2: %x u3: %x compressed data size: %d offset: %d\n", 1267cabdff1aSopenharmony_ci u1, u2, u3, u4, offset); 1268cabdff1aSopenharmony_ci if (uncompress(buf, &buf_len, extradata + 8 + offset, 1269cabdff1aSopenharmony_ci size - offset) != Z_OK) { 1270cabdff1aSopenharmony_ci av_log(avctx, AV_LOG_ERROR, 1271cabdff1aSopenharmony_ci "could not uncompress watermark logo\n"); 1272cabdff1aSopenharmony_ci av_free(buf); 1273cabdff1aSopenharmony_ci return -1; 1274cabdff1aSopenharmony_ci } 1275cabdff1aSopenharmony_ci s->watermark_key = av_bswap16(av_crc(av_crc_get_table(AV_CRC_16_CCITT), 0, buf, buf_len)); 1276cabdff1aSopenharmony_ci 1277cabdff1aSopenharmony_ci s->watermark_key = s->watermark_key << 16 | s->watermark_key; 1278cabdff1aSopenharmony_ci av_log(avctx, AV_LOG_DEBUG, 1279cabdff1aSopenharmony_ci "watermark key %#"PRIx32"\n", s->watermark_key); 1280cabdff1aSopenharmony_ci av_free(buf); 1281cabdff1aSopenharmony_ci#else 1282cabdff1aSopenharmony_ci av_log(avctx, AV_LOG_ERROR, 1283cabdff1aSopenharmony_ci "this svq3 file contains watermark which need zlib support compiled in\n"); 1284cabdff1aSopenharmony_ci return AVERROR(ENOSYS); 1285cabdff1aSopenharmony_ci#endif 1286cabdff1aSopenharmony_ci } 1287cabdff1aSopenharmony_ci } 1288cabdff1aSopenharmony_ci 1289cabdff1aSopenharmony_ci s->mb_width = (avctx->width + 15) / 16; 1290cabdff1aSopenharmony_ci s->mb_height = (avctx->height + 15) / 16; 1291cabdff1aSopenharmony_ci s->mb_stride = s->mb_width + 1; 1292cabdff1aSopenharmony_ci s->mb_num = s->mb_width * s->mb_height; 1293cabdff1aSopenharmony_ci s->b_stride = 4 * s->mb_width; 1294cabdff1aSopenharmony_ci s->h_edge_pos = s->mb_width * 16; 1295cabdff1aSopenharmony_ci s->v_edge_pos = s->mb_height * 16; 1296cabdff1aSopenharmony_ci 1297cabdff1aSopenharmony_ci s->intra4x4_pred_mode = av_mallocz(s->mb_stride * 2 * 8); 1298cabdff1aSopenharmony_ci if (!s->intra4x4_pred_mode) 1299cabdff1aSopenharmony_ci return AVERROR(ENOMEM); 1300cabdff1aSopenharmony_ci 1301cabdff1aSopenharmony_ci s->mb2br_xy = av_mallocz(s->mb_stride * (s->mb_height + 1) * 1302cabdff1aSopenharmony_ci sizeof(*s->mb2br_xy)); 1303cabdff1aSopenharmony_ci if (!s->mb2br_xy) 1304cabdff1aSopenharmony_ci return AVERROR(ENOMEM); 1305cabdff1aSopenharmony_ci 1306cabdff1aSopenharmony_ci for (y = 0; y < s->mb_height; y++) 1307cabdff1aSopenharmony_ci for (x = 0; x < s->mb_width; x++) { 1308cabdff1aSopenharmony_ci const int mb_xy = x + y * s->mb_stride; 1309cabdff1aSopenharmony_ci 1310cabdff1aSopenharmony_ci s->mb2br_xy[mb_xy] = 8 * (mb_xy % (2 * s->mb_stride)); 1311cabdff1aSopenharmony_ci } 1312cabdff1aSopenharmony_ci 1313cabdff1aSopenharmony_ci init_dequant4_coeff_table(s); 1314cabdff1aSopenharmony_ci 1315cabdff1aSopenharmony_ci return 0; 1316cabdff1aSopenharmony_ci} 1317cabdff1aSopenharmony_ci 1318cabdff1aSopenharmony_cistatic void free_picture(SVQ3Frame *pic) 1319cabdff1aSopenharmony_ci{ 1320cabdff1aSopenharmony_ci int i; 1321cabdff1aSopenharmony_ci for (i = 0; i < 2; i++) { 1322cabdff1aSopenharmony_ci av_freep(&pic->motion_val_buf[i]); 1323cabdff1aSopenharmony_ci } 1324cabdff1aSopenharmony_ci av_freep(&pic->mb_type_buf); 1325cabdff1aSopenharmony_ci 1326cabdff1aSopenharmony_ci av_frame_unref(pic->f); 1327cabdff1aSopenharmony_ci} 1328cabdff1aSopenharmony_ci 1329cabdff1aSopenharmony_cistatic int get_buffer(AVCodecContext *avctx, SVQ3Frame *pic) 1330cabdff1aSopenharmony_ci{ 1331cabdff1aSopenharmony_ci SVQ3Context *s = avctx->priv_data; 1332cabdff1aSopenharmony_ci const int big_mb_num = s->mb_stride * (s->mb_height + 1) + 1; 1333cabdff1aSopenharmony_ci const int b4_stride = s->mb_width * 4 + 1; 1334cabdff1aSopenharmony_ci const int b4_array_size = b4_stride * s->mb_height * 4; 1335cabdff1aSopenharmony_ci int ret; 1336cabdff1aSopenharmony_ci 1337cabdff1aSopenharmony_ci if (!pic->motion_val_buf[0]) { 1338cabdff1aSopenharmony_ci int i; 1339cabdff1aSopenharmony_ci 1340cabdff1aSopenharmony_ci pic->mb_type_buf = av_calloc(big_mb_num + s->mb_stride, sizeof(uint32_t)); 1341cabdff1aSopenharmony_ci if (!pic->mb_type_buf) 1342cabdff1aSopenharmony_ci return AVERROR(ENOMEM); 1343cabdff1aSopenharmony_ci pic->mb_type = pic->mb_type_buf + 2 * s->mb_stride + 1; 1344cabdff1aSopenharmony_ci 1345cabdff1aSopenharmony_ci for (i = 0; i < 2; i++) { 1346cabdff1aSopenharmony_ci pic->motion_val_buf[i] = av_calloc(b4_array_size + 4, 2 * sizeof(int16_t)); 1347cabdff1aSopenharmony_ci if (!pic->motion_val_buf[i]) { 1348cabdff1aSopenharmony_ci ret = AVERROR(ENOMEM); 1349cabdff1aSopenharmony_ci goto fail; 1350cabdff1aSopenharmony_ci } 1351cabdff1aSopenharmony_ci 1352cabdff1aSopenharmony_ci pic->motion_val[i] = pic->motion_val_buf[i] + 4; 1353cabdff1aSopenharmony_ci } 1354cabdff1aSopenharmony_ci } 1355cabdff1aSopenharmony_ci 1356cabdff1aSopenharmony_ci ret = ff_get_buffer(avctx, pic->f, 1357cabdff1aSopenharmony_ci (s->pict_type != AV_PICTURE_TYPE_B) ? 1358cabdff1aSopenharmony_ci AV_GET_BUFFER_FLAG_REF : 0); 1359cabdff1aSopenharmony_ci if (ret < 0) 1360cabdff1aSopenharmony_ci goto fail; 1361cabdff1aSopenharmony_ci 1362cabdff1aSopenharmony_ci if (!s->edge_emu_buffer) { 1363cabdff1aSopenharmony_ci s->edge_emu_buffer = av_calloc(pic->f->linesize[0], 17); 1364cabdff1aSopenharmony_ci if (!s->edge_emu_buffer) 1365cabdff1aSopenharmony_ci return AVERROR(ENOMEM); 1366cabdff1aSopenharmony_ci } 1367cabdff1aSopenharmony_ci 1368cabdff1aSopenharmony_ci return 0; 1369cabdff1aSopenharmony_cifail: 1370cabdff1aSopenharmony_ci free_picture(pic); 1371cabdff1aSopenharmony_ci return ret; 1372cabdff1aSopenharmony_ci} 1373cabdff1aSopenharmony_ci 1374cabdff1aSopenharmony_cistatic int svq3_decode_frame(AVCodecContext *avctx, AVFrame *rframe, 1375cabdff1aSopenharmony_ci int *got_frame, AVPacket *avpkt) 1376cabdff1aSopenharmony_ci{ 1377cabdff1aSopenharmony_ci SVQ3Context *s = avctx->priv_data; 1378cabdff1aSopenharmony_ci int buf_size = avpkt->size; 1379cabdff1aSopenharmony_ci int left; 1380cabdff1aSopenharmony_ci int ret, m, i; 1381cabdff1aSopenharmony_ci 1382cabdff1aSopenharmony_ci /* special case for last picture */ 1383cabdff1aSopenharmony_ci if (buf_size == 0) { 1384cabdff1aSopenharmony_ci if (s->next_pic->f->data[0] && !s->low_delay && !s->last_frame_output) { 1385cabdff1aSopenharmony_ci ret = av_frame_ref(rframe, s->next_pic->f); 1386cabdff1aSopenharmony_ci if (ret < 0) 1387cabdff1aSopenharmony_ci return ret; 1388cabdff1aSopenharmony_ci s->last_frame_output = 1; 1389cabdff1aSopenharmony_ci *got_frame = 1; 1390cabdff1aSopenharmony_ci } 1391cabdff1aSopenharmony_ci return 0; 1392cabdff1aSopenharmony_ci } 1393cabdff1aSopenharmony_ci 1394cabdff1aSopenharmony_ci s->mb_x = s->mb_y = s->mb_xy = 0; 1395cabdff1aSopenharmony_ci 1396cabdff1aSopenharmony_ci ret = init_get_bits8(&s->gb, avpkt->data, avpkt->size); 1397cabdff1aSopenharmony_ci if (ret < 0) 1398cabdff1aSopenharmony_ci return ret; 1399cabdff1aSopenharmony_ci 1400cabdff1aSopenharmony_ci if (svq3_decode_slice_header(avctx)) 1401cabdff1aSopenharmony_ci return -1; 1402cabdff1aSopenharmony_ci 1403cabdff1aSopenharmony_ci s->pict_type = s->slice_type; 1404cabdff1aSopenharmony_ci 1405cabdff1aSopenharmony_ci if (s->pict_type != AV_PICTURE_TYPE_B) 1406cabdff1aSopenharmony_ci FFSWAP(SVQ3Frame*, s->next_pic, s->last_pic); 1407cabdff1aSopenharmony_ci 1408cabdff1aSopenharmony_ci av_frame_unref(s->cur_pic->f); 1409cabdff1aSopenharmony_ci 1410cabdff1aSopenharmony_ci /* for skipping the frame */ 1411cabdff1aSopenharmony_ci s->cur_pic->f->pict_type = s->pict_type; 1412cabdff1aSopenharmony_ci s->cur_pic->f->key_frame = (s->pict_type == AV_PICTURE_TYPE_I); 1413cabdff1aSopenharmony_ci 1414cabdff1aSopenharmony_ci ret = get_buffer(avctx, s->cur_pic); 1415cabdff1aSopenharmony_ci if (ret < 0) 1416cabdff1aSopenharmony_ci return ret; 1417cabdff1aSopenharmony_ci 1418cabdff1aSopenharmony_ci for (i = 0; i < 16; i++) { 1419cabdff1aSopenharmony_ci s->block_offset[i] = (4 * ((scan8[i] - scan8[0]) & 7)) + 4 * s->cur_pic->f->linesize[0] * ((scan8[i] - scan8[0]) >> 3); 1420cabdff1aSopenharmony_ci s->block_offset[48 + i] = (4 * ((scan8[i] - scan8[0]) & 7)) + 8 * s->cur_pic->f->linesize[0] * ((scan8[i] - scan8[0]) >> 3); 1421cabdff1aSopenharmony_ci } 1422cabdff1aSopenharmony_ci for (i = 0; i < 16; i++) { 1423cabdff1aSopenharmony_ci s->block_offset[16 + i] = 1424cabdff1aSopenharmony_ci s->block_offset[32 + i] = (4 * ((scan8[i] - scan8[0]) & 7)) + 4 * s->cur_pic->f->linesize[1] * ((scan8[i] - scan8[0]) >> 3); 1425cabdff1aSopenharmony_ci s->block_offset[48 + 16 + i] = 1426cabdff1aSopenharmony_ci s->block_offset[48 + 32 + i] = (4 * ((scan8[i] - scan8[0]) & 7)) + 8 * s->cur_pic->f->linesize[1] * ((scan8[i] - scan8[0]) >> 3); 1427cabdff1aSopenharmony_ci } 1428cabdff1aSopenharmony_ci 1429cabdff1aSopenharmony_ci if (s->pict_type != AV_PICTURE_TYPE_I) { 1430cabdff1aSopenharmony_ci if (!s->last_pic->f->data[0]) { 1431cabdff1aSopenharmony_ci av_log(avctx, AV_LOG_ERROR, "Missing reference frame.\n"); 1432cabdff1aSopenharmony_ci av_frame_unref(s->last_pic->f); 1433cabdff1aSopenharmony_ci ret = get_buffer(avctx, s->last_pic); 1434cabdff1aSopenharmony_ci if (ret < 0) 1435cabdff1aSopenharmony_ci return ret; 1436cabdff1aSopenharmony_ci memset(s->last_pic->f->data[0], 0, avctx->height * s->last_pic->f->linesize[0]); 1437cabdff1aSopenharmony_ci memset(s->last_pic->f->data[1], 0x80, (avctx->height / 2) * 1438cabdff1aSopenharmony_ci s->last_pic->f->linesize[1]); 1439cabdff1aSopenharmony_ci memset(s->last_pic->f->data[2], 0x80, (avctx->height / 2) * 1440cabdff1aSopenharmony_ci s->last_pic->f->linesize[2]); 1441cabdff1aSopenharmony_ci } 1442cabdff1aSopenharmony_ci 1443cabdff1aSopenharmony_ci if (s->pict_type == AV_PICTURE_TYPE_B && !s->next_pic->f->data[0]) { 1444cabdff1aSopenharmony_ci av_log(avctx, AV_LOG_ERROR, "Missing reference frame.\n"); 1445cabdff1aSopenharmony_ci av_frame_unref(s->next_pic->f); 1446cabdff1aSopenharmony_ci ret = get_buffer(avctx, s->next_pic); 1447cabdff1aSopenharmony_ci if (ret < 0) 1448cabdff1aSopenharmony_ci return ret; 1449cabdff1aSopenharmony_ci memset(s->next_pic->f->data[0], 0, avctx->height * s->next_pic->f->linesize[0]); 1450cabdff1aSopenharmony_ci memset(s->next_pic->f->data[1], 0x80, (avctx->height / 2) * 1451cabdff1aSopenharmony_ci s->next_pic->f->linesize[1]); 1452cabdff1aSopenharmony_ci memset(s->next_pic->f->data[2], 0x80, (avctx->height / 2) * 1453cabdff1aSopenharmony_ci s->next_pic->f->linesize[2]); 1454cabdff1aSopenharmony_ci } 1455cabdff1aSopenharmony_ci } 1456cabdff1aSopenharmony_ci 1457cabdff1aSopenharmony_ci if (avctx->debug & FF_DEBUG_PICT_INFO) 1458cabdff1aSopenharmony_ci av_log(s->avctx, AV_LOG_DEBUG, 1459cabdff1aSopenharmony_ci "%c hpel:%d, tpel:%d aqp:%d qp:%d, slice_num:%02X\n", 1460cabdff1aSopenharmony_ci av_get_picture_type_char(s->pict_type), 1461cabdff1aSopenharmony_ci s->halfpel_flag, s->thirdpel_flag, 1462cabdff1aSopenharmony_ci s->adaptive_quant, s->qscale, s->slice_num); 1463cabdff1aSopenharmony_ci 1464cabdff1aSopenharmony_ci if (avctx->skip_frame >= AVDISCARD_NONREF && s->pict_type == AV_PICTURE_TYPE_B || 1465cabdff1aSopenharmony_ci avctx->skip_frame >= AVDISCARD_NONKEY && s->pict_type != AV_PICTURE_TYPE_I || 1466cabdff1aSopenharmony_ci avctx->skip_frame >= AVDISCARD_ALL) 1467cabdff1aSopenharmony_ci return 0; 1468cabdff1aSopenharmony_ci 1469cabdff1aSopenharmony_ci if (s->pict_type == AV_PICTURE_TYPE_B) { 1470cabdff1aSopenharmony_ci s->frame_num_offset = s->slice_num - s->prev_frame_num; 1471cabdff1aSopenharmony_ci 1472cabdff1aSopenharmony_ci if (s->frame_num_offset < 0) 1473cabdff1aSopenharmony_ci s->frame_num_offset += 256; 1474cabdff1aSopenharmony_ci if (s->frame_num_offset == 0 || 1475cabdff1aSopenharmony_ci s->frame_num_offset >= s->prev_frame_num_offset) { 1476cabdff1aSopenharmony_ci av_log(s->avctx, AV_LOG_ERROR, "error in B-frame picture id\n"); 1477cabdff1aSopenharmony_ci return -1; 1478cabdff1aSopenharmony_ci } 1479cabdff1aSopenharmony_ci } else { 1480cabdff1aSopenharmony_ci s->prev_frame_num = s->frame_num; 1481cabdff1aSopenharmony_ci s->frame_num = s->slice_num; 1482cabdff1aSopenharmony_ci s->prev_frame_num_offset = s->frame_num - s->prev_frame_num; 1483cabdff1aSopenharmony_ci 1484cabdff1aSopenharmony_ci if (s->prev_frame_num_offset < 0) 1485cabdff1aSopenharmony_ci s->prev_frame_num_offset += 256; 1486cabdff1aSopenharmony_ci } 1487cabdff1aSopenharmony_ci 1488cabdff1aSopenharmony_ci for (m = 0; m < 2; m++) { 1489cabdff1aSopenharmony_ci int i; 1490cabdff1aSopenharmony_ci for (i = 0; i < 4; i++) { 1491cabdff1aSopenharmony_ci int j; 1492cabdff1aSopenharmony_ci for (j = -1; j < 4; j++) 1493cabdff1aSopenharmony_ci s->ref_cache[m][scan8[0] + 8 * i + j] = 1; 1494cabdff1aSopenharmony_ci if (i < 3) 1495cabdff1aSopenharmony_ci s->ref_cache[m][scan8[0] + 8 * i + j] = PART_NOT_AVAILABLE; 1496cabdff1aSopenharmony_ci } 1497cabdff1aSopenharmony_ci } 1498cabdff1aSopenharmony_ci 1499cabdff1aSopenharmony_ci for (s->mb_y = 0; s->mb_y < s->mb_height; s->mb_y++) { 1500cabdff1aSopenharmony_ci for (s->mb_x = 0; s->mb_x < s->mb_width; s->mb_x++) { 1501cabdff1aSopenharmony_ci unsigned mb_type; 1502cabdff1aSopenharmony_ci s->mb_xy = s->mb_x + s->mb_y * s->mb_stride; 1503cabdff1aSopenharmony_ci 1504cabdff1aSopenharmony_ci if ((get_bits_left(&s->gb_slice)) <= 7) { 1505cabdff1aSopenharmony_ci if (((get_bits_count(&s->gb_slice) & 7) == 0 || 1506cabdff1aSopenharmony_ci show_bits(&s->gb_slice, get_bits_left(&s->gb_slice) & 7) == 0)) { 1507cabdff1aSopenharmony_ci 1508cabdff1aSopenharmony_ci if (svq3_decode_slice_header(avctx)) 1509cabdff1aSopenharmony_ci return -1; 1510cabdff1aSopenharmony_ci } 1511cabdff1aSopenharmony_ci if (s->slice_type != s->pict_type) { 1512cabdff1aSopenharmony_ci avpriv_request_sample(avctx, "non constant slice type"); 1513cabdff1aSopenharmony_ci } 1514cabdff1aSopenharmony_ci /* TODO: support s->mb_skip_run */ 1515cabdff1aSopenharmony_ci } 1516cabdff1aSopenharmony_ci 1517cabdff1aSopenharmony_ci mb_type = get_interleaved_ue_golomb(&s->gb_slice); 1518cabdff1aSopenharmony_ci 1519cabdff1aSopenharmony_ci if (s->pict_type == AV_PICTURE_TYPE_I) 1520cabdff1aSopenharmony_ci mb_type += 8; 1521cabdff1aSopenharmony_ci else if (s->pict_type == AV_PICTURE_TYPE_B && mb_type >= 4) 1522cabdff1aSopenharmony_ci mb_type += 4; 1523cabdff1aSopenharmony_ci if (mb_type > 33 || svq3_decode_mb(s, mb_type)) { 1524cabdff1aSopenharmony_ci av_log(s->avctx, AV_LOG_ERROR, 1525cabdff1aSopenharmony_ci "error while decoding MB %d %d\n", s->mb_x, s->mb_y); 1526cabdff1aSopenharmony_ci return -1; 1527cabdff1aSopenharmony_ci } 1528cabdff1aSopenharmony_ci 1529cabdff1aSopenharmony_ci if (mb_type != 0 || s->cbp) 1530cabdff1aSopenharmony_ci hl_decode_mb(s); 1531cabdff1aSopenharmony_ci 1532cabdff1aSopenharmony_ci if (s->pict_type != AV_PICTURE_TYPE_B && !s->low_delay) 1533cabdff1aSopenharmony_ci s->cur_pic->mb_type[s->mb_x + s->mb_y * s->mb_stride] = 1534cabdff1aSopenharmony_ci (s->pict_type == AV_PICTURE_TYPE_P && mb_type < 8) ? (mb_type - 1) : -1; 1535cabdff1aSopenharmony_ci } 1536cabdff1aSopenharmony_ci 1537cabdff1aSopenharmony_ci ff_draw_horiz_band(avctx, s->cur_pic->f, 1538cabdff1aSopenharmony_ci s->last_pic->f->data[0] ? s->last_pic->f : NULL, 1539cabdff1aSopenharmony_ci 16 * s->mb_y, 16, PICT_FRAME, 0, 1540cabdff1aSopenharmony_ci s->low_delay); 1541cabdff1aSopenharmony_ci } 1542cabdff1aSopenharmony_ci 1543cabdff1aSopenharmony_ci left = buf_size*8 - get_bits_count(&s->gb_slice); 1544cabdff1aSopenharmony_ci 1545cabdff1aSopenharmony_ci if (s->mb_y != s->mb_height || s->mb_x != s->mb_width) { 1546cabdff1aSopenharmony_ci av_log(avctx, AV_LOG_INFO, "frame num %d incomplete pic x %d y %d left %d\n", avctx->frame_number, s->mb_y, s->mb_x, left); 1547cabdff1aSopenharmony_ci //av_hex_dump(stderr, buf+buf_size-8, 8); 1548cabdff1aSopenharmony_ci } 1549cabdff1aSopenharmony_ci 1550cabdff1aSopenharmony_ci if (left < 0) { 1551cabdff1aSopenharmony_ci av_log(avctx, AV_LOG_ERROR, "frame num %d left %d\n", avctx->frame_number, left); 1552cabdff1aSopenharmony_ci return -1; 1553cabdff1aSopenharmony_ci } 1554cabdff1aSopenharmony_ci 1555cabdff1aSopenharmony_ci if (s->pict_type == AV_PICTURE_TYPE_B || s->low_delay) 1556cabdff1aSopenharmony_ci ret = av_frame_ref(rframe, s->cur_pic->f); 1557cabdff1aSopenharmony_ci else if (s->last_pic->f->data[0]) 1558cabdff1aSopenharmony_ci ret = av_frame_ref(rframe, s->last_pic->f); 1559cabdff1aSopenharmony_ci if (ret < 0) 1560cabdff1aSopenharmony_ci return ret; 1561cabdff1aSopenharmony_ci 1562cabdff1aSopenharmony_ci /* Do not output the last pic after seeking. */ 1563cabdff1aSopenharmony_ci if (s->last_pic->f->data[0] || s->low_delay) 1564cabdff1aSopenharmony_ci *got_frame = 1; 1565cabdff1aSopenharmony_ci 1566cabdff1aSopenharmony_ci if (s->pict_type != AV_PICTURE_TYPE_B) { 1567cabdff1aSopenharmony_ci FFSWAP(SVQ3Frame*, s->cur_pic, s->next_pic); 1568cabdff1aSopenharmony_ci } else { 1569cabdff1aSopenharmony_ci av_frame_unref(s->cur_pic->f); 1570cabdff1aSopenharmony_ci } 1571cabdff1aSopenharmony_ci 1572cabdff1aSopenharmony_ci return buf_size; 1573cabdff1aSopenharmony_ci} 1574cabdff1aSopenharmony_ci 1575cabdff1aSopenharmony_cistatic av_cold int svq3_decode_end(AVCodecContext *avctx) 1576cabdff1aSopenharmony_ci{ 1577cabdff1aSopenharmony_ci SVQ3Context *s = avctx->priv_data; 1578cabdff1aSopenharmony_ci 1579cabdff1aSopenharmony_ci for (int i = 0; i < FF_ARRAY_ELEMS(s->frames); i++) { 1580cabdff1aSopenharmony_ci free_picture(&s->frames[i]); 1581cabdff1aSopenharmony_ci av_frame_free(&s->frames[i].f); 1582cabdff1aSopenharmony_ci } 1583cabdff1aSopenharmony_ci av_freep(&s->slice_buf); 1584cabdff1aSopenharmony_ci av_freep(&s->intra4x4_pred_mode); 1585cabdff1aSopenharmony_ci av_freep(&s->edge_emu_buffer); 1586cabdff1aSopenharmony_ci av_freep(&s->mb2br_xy); 1587cabdff1aSopenharmony_ci 1588cabdff1aSopenharmony_ci return 0; 1589cabdff1aSopenharmony_ci} 1590cabdff1aSopenharmony_ci 1591cabdff1aSopenharmony_ciconst FFCodec ff_svq3_decoder = { 1592cabdff1aSopenharmony_ci .p.name = "svq3", 1593cabdff1aSopenharmony_ci .p.long_name = NULL_IF_CONFIG_SMALL("Sorenson Vector Quantizer 3 / Sorenson Video 3 / SVQ3"), 1594cabdff1aSopenharmony_ci .p.type = AVMEDIA_TYPE_VIDEO, 1595cabdff1aSopenharmony_ci .p.id = AV_CODEC_ID_SVQ3, 1596cabdff1aSopenharmony_ci .priv_data_size = sizeof(SVQ3Context), 1597cabdff1aSopenharmony_ci .init = svq3_decode_init, 1598cabdff1aSopenharmony_ci .close = svq3_decode_end, 1599cabdff1aSopenharmony_ci FF_CODEC_DECODE_CB(svq3_decode_frame), 1600cabdff1aSopenharmony_ci .p.capabilities = AV_CODEC_CAP_DRAW_HORIZ_BAND | 1601cabdff1aSopenharmony_ci AV_CODEC_CAP_DR1 | 1602cabdff1aSopenharmony_ci AV_CODEC_CAP_DELAY, 1603cabdff1aSopenharmony_ci .p.pix_fmts = (const enum AVPixelFormat[]) { AV_PIX_FMT_YUVJ420P, 1604cabdff1aSopenharmony_ci AV_PIX_FMT_NONE}, 1605cabdff1aSopenharmony_ci .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE | FF_CODEC_CAP_INIT_CLEANUP, 1606cabdff1aSopenharmony_ci}; 1607