1cabdff1aSopenharmony_ci/* 2cabdff1aSopenharmony_ci * Escape 124 Video Decoder 3cabdff1aSopenharmony_ci * Copyright (C) 2008 Eli Friedman (eli.friedman@gmail.com) 4cabdff1aSopenharmony_ci * 5cabdff1aSopenharmony_ci * This file is part of FFmpeg. 6cabdff1aSopenharmony_ci * 7cabdff1aSopenharmony_ci * FFmpeg is free software; you can redistribute it and/or 8cabdff1aSopenharmony_ci * modify it under the terms of the GNU Lesser General Public 9cabdff1aSopenharmony_ci * License as published by the Free Software Foundation; either 10cabdff1aSopenharmony_ci * version 2.1 of the License, or (at your option) any later version. 11cabdff1aSopenharmony_ci * 12cabdff1aSopenharmony_ci * FFmpeg is distributed in the hope that it will be useful, 13cabdff1aSopenharmony_ci * but WITHOUT ANY WARRANTY; without even the implied warranty of 14cabdff1aSopenharmony_ci * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15cabdff1aSopenharmony_ci * Lesser General Public License for more details. 16cabdff1aSopenharmony_ci * 17cabdff1aSopenharmony_ci * You should have received a copy of the GNU Lesser General Public 18cabdff1aSopenharmony_ci * License along with FFmpeg; if not, write to the Free Software 19cabdff1aSopenharmony_ci * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 20cabdff1aSopenharmony_ci */ 21cabdff1aSopenharmony_ci 22cabdff1aSopenharmony_ci#define BITSTREAM_READER_LE 23cabdff1aSopenharmony_ci#include "avcodec.h" 24cabdff1aSopenharmony_ci#include "codec_internal.h" 25cabdff1aSopenharmony_ci#include "get_bits.h" 26cabdff1aSopenharmony_ci#include "internal.h" 27cabdff1aSopenharmony_ci 28cabdff1aSopenharmony_citypedef union MacroBlock { 29cabdff1aSopenharmony_ci uint16_t pixels[4]; 30cabdff1aSopenharmony_ci uint32_t pixels32[2]; 31cabdff1aSopenharmony_ci} MacroBlock; 32cabdff1aSopenharmony_ci 33cabdff1aSopenharmony_citypedef union SuperBlock { 34cabdff1aSopenharmony_ci uint16_t pixels[64]; 35cabdff1aSopenharmony_ci uint32_t pixels32[32]; 36cabdff1aSopenharmony_ci} SuperBlock; 37cabdff1aSopenharmony_ci 38cabdff1aSopenharmony_citypedef struct CodeBook { 39cabdff1aSopenharmony_ci unsigned depth; 40cabdff1aSopenharmony_ci unsigned size; 41cabdff1aSopenharmony_ci MacroBlock* blocks; 42cabdff1aSopenharmony_ci} CodeBook; 43cabdff1aSopenharmony_ci 44cabdff1aSopenharmony_citypedef struct Escape124Context { 45cabdff1aSopenharmony_ci AVFrame *frame; 46cabdff1aSopenharmony_ci 47cabdff1aSopenharmony_ci unsigned num_superblocks; 48cabdff1aSopenharmony_ci 49cabdff1aSopenharmony_ci CodeBook codebooks[3]; 50cabdff1aSopenharmony_ci} Escape124Context; 51cabdff1aSopenharmony_ci 52cabdff1aSopenharmony_ci/** 53cabdff1aSopenharmony_ci * Initialize the decoder 54cabdff1aSopenharmony_ci * @param avctx decoder context 55cabdff1aSopenharmony_ci * @return 0 success, negative on error 56cabdff1aSopenharmony_ci */ 57cabdff1aSopenharmony_cistatic av_cold int escape124_decode_init(AVCodecContext *avctx) 58cabdff1aSopenharmony_ci{ 59cabdff1aSopenharmony_ci Escape124Context *s = avctx->priv_data; 60cabdff1aSopenharmony_ci 61cabdff1aSopenharmony_ci avctx->pix_fmt = AV_PIX_FMT_RGB555; 62cabdff1aSopenharmony_ci 63cabdff1aSopenharmony_ci s->num_superblocks = ((unsigned)avctx->width / 8) * 64cabdff1aSopenharmony_ci ((unsigned)avctx->height / 8); 65cabdff1aSopenharmony_ci 66cabdff1aSopenharmony_ci s->frame = av_frame_alloc(); 67cabdff1aSopenharmony_ci if (!s->frame) 68cabdff1aSopenharmony_ci return AVERROR(ENOMEM); 69cabdff1aSopenharmony_ci 70cabdff1aSopenharmony_ci return 0; 71cabdff1aSopenharmony_ci} 72cabdff1aSopenharmony_ci 73cabdff1aSopenharmony_cistatic av_cold int escape124_decode_close(AVCodecContext *avctx) 74cabdff1aSopenharmony_ci{ 75cabdff1aSopenharmony_ci unsigned i; 76cabdff1aSopenharmony_ci Escape124Context *s = avctx->priv_data; 77cabdff1aSopenharmony_ci 78cabdff1aSopenharmony_ci for (i = 0; i < 3; i++) 79cabdff1aSopenharmony_ci av_freep(&s->codebooks[i].blocks); 80cabdff1aSopenharmony_ci 81cabdff1aSopenharmony_ci av_frame_free(&s->frame); 82cabdff1aSopenharmony_ci 83cabdff1aSopenharmony_ci return 0; 84cabdff1aSopenharmony_ci} 85cabdff1aSopenharmony_ci 86cabdff1aSopenharmony_cistatic CodeBook unpack_codebook(GetBitContext* gb, unsigned depth, 87cabdff1aSopenharmony_ci unsigned size) 88cabdff1aSopenharmony_ci{ 89cabdff1aSopenharmony_ci unsigned i, j; 90cabdff1aSopenharmony_ci CodeBook cb = { 0 }; 91cabdff1aSopenharmony_ci 92cabdff1aSopenharmony_ci cb.blocks = av_malloc(size ? size * sizeof(MacroBlock) : 1); 93cabdff1aSopenharmony_ci if (!cb.blocks) 94cabdff1aSopenharmony_ci return cb; 95cabdff1aSopenharmony_ci 96cabdff1aSopenharmony_ci cb.depth = depth; 97cabdff1aSopenharmony_ci cb.size = size; 98cabdff1aSopenharmony_ci for (i = 0; i < size; i++) { 99cabdff1aSopenharmony_ci unsigned mask_bits = get_bits(gb, 4); 100cabdff1aSopenharmony_ci unsigned color0 = get_bits(gb, 15); 101cabdff1aSopenharmony_ci unsigned color1 = get_bits(gb, 15); 102cabdff1aSopenharmony_ci 103cabdff1aSopenharmony_ci for (j = 0; j < 4; j++) { 104cabdff1aSopenharmony_ci if (mask_bits & (1 << j)) 105cabdff1aSopenharmony_ci cb.blocks[i].pixels[j] = color1; 106cabdff1aSopenharmony_ci else 107cabdff1aSopenharmony_ci cb.blocks[i].pixels[j] = color0; 108cabdff1aSopenharmony_ci } 109cabdff1aSopenharmony_ci } 110cabdff1aSopenharmony_ci return cb; 111cabdff1aSopenharmony_ci} 112cabdff1aSopenharmony_ci 113cabdff1aSopenharmony_cistatic unsigned decode_skip_count(GetBitContext* gb) 114cabdff1aSopenharmony_ci{ 115cabdff1aSopenharmony_ci unsigned value; 116cabdff1aSopenharmony_ci // This function reads a maximum of 23 bits, 117cabdff1aSopenharmony_ci // which is within the padding space 118cabdff1aSopenharmony_ci if (get_bits_left(gb) < 1) 119cabdff1aSopenharmony_ci return -1; 120cabdff1aSopenharmony_ci value = get_bits1(gb); 121cabdff1aSopenharmony_ci if (!value) 122cabdff1aSopenharmony_ci return value; 123cabdff1aSopenharmony_ci 124cabdff1aSopenharmony_ci value += get_bits(gb, 3); 125cabdff1aSopenharmony_ci if (value != (1 + ((1 << 3) - 1))) 126cabdff1aSopenharmony_ci return value; 127cabdff1aSopenharmony_ci 128cabdff1aSopenharmony_ci value += get_bits(gb, 7); 129cabdff1aSopenharmony_ci if (value != (1 + ((1 << 3) - 1)) + ((1 << 7) - 1)) 130cabdff1aSopenharmony_ci return value; 131cabdff1aSopenharmony_ci 132cabdff1aSopenharmony_ci return value + get_bits(gb, 12); 133cabdff1aSopenharmony_ci} 134cabdff1aSopenharmony_ci 135cabdff1aSopenharmony_cistatic MacroBlock decode_macroblock(Escape124Context* s, GetBitContext* gb, 136cabdff1aSopenharmony_ci int* codebook_index, int superblock_index) 137cabdff1aSopenharmony_ci{ 138cabdff1aSopenharmony_ci // This function reads a maximum of 22 bits; the callers 139cabdff1aSopenharmony_ci // guard this function appropriately 140cabdff1aSopenharmony_ci unsigned block_index, depth; 141cabdff1aSopenharmony_ci int value = get_bits1(gb); 142cabdff1aSopenharmony_ci if (value) { 143cabdff1aSopenharmony_ci static const int8_t transitions[3][2] = { {2, 1}, {0, 2}, {1, 0} }; 144cabdff1aSopenharmony_ci value = get_bits1(gb); 145cabdff1aSopenharmony_ci *codebook_index = transitions[*codebook_index][value]; 146cabdff1aSopenharmony_ci } 147cabdff1aSopenharmony_ci 148cabdff1aSopenharmony_ci depth = s->codebooks[*codebook_index].depth; 149cabdff1aSopenharmony_ci 150cabdff1aSopenharmony_ci // depth = 0 means that this shouldn't read any bits; 151cabdff1aSopenharmony_ci // in theory, this is the same as get_bits(gb, 0), but 152cabdff1aSopenharmony_ci // that doesn't actually work. 153cabdff1aSopenharmony_ci block_index = get_bitsz(gb, depth); 154cabdff1aSopenharmony_ci 155cabdff1aSopenharmony_ci if (*codebook_index == 1) { 156cabdff1aSopenharmony_ci block_index += superblock_index << s->codebooks[1].depth; 157cabdff1aSopenharmony_ci } 158cabdff1aSopenharmony_ci 159cabdff1aSopenharmony_ci // This condition can occur with invalid bitstreams and 160cabdff1aSopenharmony_ci // *codebook_index == 2 161cabdff1aSopenharmony_ci if (block_index >= s->codebooks[*codebook_index].size || !s->codebooks[*codebook_index].blocks) 162cabdff1aSopenharmony_ci return (MacroBlock) { { 0 } }; 163cabdff1aSopenharmony_ci 164cabdff1aSopenharmony_ci return s->codebooks[*codebook_index].blocks[block_index]; 165cabdff1aSopenharmony_ci} 166cabdff1aSopenharmony_ci 167cabdff1aSopenharmony_cistatic void insert_mb_into_sb(SuperBlock* sb, MacroBlock mb, unsigned index) { 168cabdff1aSopenharmony_ci // Formula: ((index / 4) * 16 + (index % 4) * 2) / 2 169cabdff1aSopenharmony_ci uint32_t *dst = sb->pixels32 + index + (index & -4); 170cabdff1aSopenharmony_ci 171cabdff1aSopenharmony_ci // This technically violates C99 aliasing rules, but it should be safe. 172cabdff1aSopenharmony_ci dst[0] = mb.pixels32[0]; 173cabdff1aSopenharmony_ci dst[4] = mb.pixels32[1]; 174cabdff1aSopenharmony_ci} 175cabdff1aSopenharmony_ci 176cabdff1aSopenharmony_cistatic void copy_superblock(uint16_t* dest, unsigned dest_stride, 177cabdff1aSopenharmony_ci uint16_t* src, unsigned src_stride) 178cabdff1aSopenharmony_ci{ 179cabdff1aSopenharmony_ci unsigned y; 180cabdff1aSopenharmony_ci if (src) 181cabdff1aSopenharmony_ci for (y = 0; y < 8; y++) 182cabdff1aSopenharmony_ci memcpy(dest + y * dest_stride, src + y * src_stride, 183cabdff1aSopenharmony_ci sizeof(uint16_t) * 8); 184cabdff1aSopenharmony_ci else 185cabdff1aSopenharmony_ci for (y = 0; y < 8; y++) 186cabdff1aSopenharmony_ci memset(dest + y * dest_stride, 0, sizeof(uint16_t) * 8); 187cabdff1aSopenharmony_ci} 188cabdff1aSopenharmony_ci 189cabdff1aSopenharmony_cistatic const uint16_t mask_matrix[] = {0x1, 0x2, 0x10, 0x20, 190cabdff1aSopenharmony_ci 0x4, 0x8, 0x40, 0x80, 191cabdff1aSopenharmony_ci 0x100, 0x200, 0x1000, 0x2000, 192cabdff1aSopenharmony_ci 0x400, 0x800, 0x4000, 0x8000}; 193cabdff1aSopenharmony_ci 194cabdff1aSopenharmony_cistatic int escape124_decode_frame(AVCodecContext *avctx, AVFrame *frame, 195cabdff1aSopenharmony_ci int *got_frame, AVPacket *avpkt) 196cabdff1aSopenharmony_ci{ 197cabdff1aSopenharmony_ci int buf_size = avpkt->size; 198cabdff1aSopenharmony_ci Escape124Context *s = avctx->priv_data; 199cabdff1aSopenharmony_ci 200cabdff1aSopenharmony_ci GetBitContext gb; 201cabdff1aSopenharmony_ci unsigned frame_flags, frame_size; 202cabdff1aSopenharmony_ci unsigned i; 203cabdff1aSopenharmony_ci 204cabdff1aSopenharmony_ci unsigned superblock_index, cb_index = 1, 205cabdff1aSopenharmony_ci superblock_col_index = 0, 206cabdff1aSopenharmony_ci superblocks_per_row = avctx->width / 8, skip = -1; 207cabdff1aSopenharmony_ci 208cabdff1aSopenharmony_ci uint16_t* old_frame_data, *new_frame_data; 209cabdff1aSopenharmony_ci unsigned old_stride, new_stride; 210cabdff1aSopenharmony_ci 211cabdff1aSopenharmony_ci int ret; 212cabdff1aSopenharmony_ci 213cabdff1aSopenharmony_ci if ((ret = init_get_bits8(&gb, avpkt->data, avpkt->size)) < 0) 214cabdff1aSopenharmony_ci return ret; 215cabdff1aSopenharmony_ci 216cabdff1aSopenharmony_ci // This call also guards the potential depth reads for the 217cabdff1aSopenharmony_ci // codebook unpacking. 218cabdff1aSopenharmony_ci // Check if the amount we will read minimally is available on input. 219cabdff1aSopenharmony_ci // The 64 represent the immediately next 2 frame_* elements read, the 23/4320 220cabdff1aSopenharmony_ci // represent a lower bound of the space needed for skipped superblocks. Non 221cabdff1aSopenharmony_ci // skipped SBs need more space. 222cabdff1aSopenharmony_ci if (get_bits_left(&gb) < 64 + s->num_superblocks * 23LL / 4320) 223cabdff1aSopenharmony_ci return AVERROR_INVALIDDATA; 224cabdff1aSopenharmony_ci 225cabdff1aSopenharmony_ci frame_flags = get_bits_long(&gb, 32); 226cabdff1aSopenharmony_ci frame_size = get_bits_long(&gb, 32); 227cabdff1aSopenharmony_ci 228cabdff1aSopenharmony_ci // Leave last frame unchanged 229cabdff1aSopenharmony_ci // FIXME: Is this necessary? I haven't seen it in any real samples 230cabdff1aSopenharmony_ci if (!(frame_flags & 0x114) || !(frame_flags & 0x7800000)) { 231cabdff1aSopenharmony_ci if (!s->frame->data[0]) 232cabdff1aSopenharmony_ci return AVERROR_INVALIDDATA; 233cabdff1aSopenharmony_ci 234cabdff1aSopenharmony_ci av_log(avctx, AV_LOG_DEBUG, "Skipping frame\n"); 235cabdff1aSopenharmony_ci 236cabdff1aSopenharmony_ci *got_frame = 1; 237cabdff1aSopenharmony_ci if ((ret = av_frame_ref(frame, s->frame)) < 0) 238cabdff1aSopenharmony_ci return ret; 239cabdff1aSopenharmony_ci 240cabdff1aSopenharmony_ci return 0; 241cabdff1aSopenharmony_ci } 242cabdff1aSopenharmony_ci 243cabdff1aSopenharmony_ci for (i = 0; i < 3; i++) { 244cabdff1aSopenharmony_ci if (frame_flags & (1 << (17 + i))) { 245cabdff1aSopenharmony_ci unsigned cb_depth, cb_size; 246cabdff1aSopenharmony_ci if (i == 2) { 247cabdff1aSopenharmony_ci // This codebook can be cut off at places other than 248cabdff1aSopenharmony_ci // powers of 2, leaving some of the entries undefined. 249cabdff1aSopenharmony_ci cb_size = get_bits(&gb, 20); 250cabdff1aSopenharmony_ci if (!cb_size) { 251cabdff1aSopenharmony_ci av_log(avctx, AV_LOG_ERROR, "Invalid codebook size 0.\n"); 252cabdff1aSopenharmony_ci return AVERROR_INVALIDDATA; 253cabdff1aSopenharmony_ci } 254cabdff1aSopenharmony_ci cb_depth = av_log2(cb_size - 1) + 1; 255cabdff1aSopenharmony_ci } else { 256cabdff1aSopenharmony_ci cb_depth = get_bits(&gb, 4); 257cabdff1aSopenharmony_ci if (i == 0) { 258cabdff1aSopenharmony_ci // This is the most basic codebook: pow(2,depth) entries 259cabdff1aSopenharmony_ci // for a depth-length key 260cabdff1aSopenharmony_ci cb_size = 1 << cb_depth; 261cabdff1aSopenharmony_ci } else { 262cabdff1aSopenharmony_ci // This codebook varies per superblock 263cabdff1aSopenharmony_ci // FIXME: I don't think this handles integer overflow 264cabdff1aSopenharmony_ci // properly 265cabdff1aSopenharmony_ci cb_size = s->num_superblocks << cb_depth; 266cabdff1aSopenharmony_ci } 267cabdff1aSopenharmony_ci } 268cabdff1aSopenharmony_ci if (s->num_superblocks >= INT_MAX >> cb_depth) { 269cabdff1aSopenharmony_ci av_log(avctx, AV_LOG_ERROR, "Depth or num_superblocks are too large\n"); 270cabdff1aSopenharmony_ci return AVERROR_INVALIDDATA; 271cabdff1aSopenharmony_ci } 272cabdff1aSopenharmony_ci 273cabdff1aSopenharmony_ci av_freep(&s->codebooks[i].blocks); 274cabdff1aSopenharmony_ci if (cb_size >= INT_MAX / 34 || get_bits_left(&gb) < (int)cb_size * 34) 275cabdff1aSopenharmony_ci return AVERROR_INVALIDDATA; 276cabdff1aSopenharmony_ci 277cabdff1aSopenharmony_ci if (cb_size >= INT_MAX / sizeof(MacroBlock)) 278cabdff1aSopenharmony_ci return AVERROR_INVALIDDATA; 279cabdff1aSopenharmony_ci s->codebooks[i] = unpack_codebook(&gb, cb_depth, cb_size); 280cabdff1aSopenharmony_ci if (!s->codebooks[i].blocks) 281cabdff1aSopenharmony_ci return AVERROR(ENOMEM); 282cabdff1aSopenharmony_ci } 283cabdff1aSopenharmony_ci } 284cabdff1aSopenharmony_ci 285cabdff1aSopenharmony_ci if ((ret = ff_get_buffer(avctx, frame, AV_GET_BUFFER_FLAG_REF)) < 0) 286cabdff1aSopenharmony_ci return ret; 287cabdff1aSopenharmony_ci 288cabdff1aSopenharmony_ci new_frame_data = (uint16_t*)frame->data[0]; 289cabdff1aSopenharmony_ci new_stride = frame->linesize[0] / 2; 290cabdff1aSopenharmony_ci old_frame_data = (uint16_t*)s->frame->data[0]; 291cabdff1aSopenharmony_ci old_stride = s->frame->linesize[0] / 2; 292cabdff1aSopenharmony_ci 293cabdff1aSopenharmony_ci for (superblock_index = 0; superblock_index < s->num_superblocks; 294cabdff1aSopenharmony_ci superblock_index++) { 295cabdff1aSopenharmony_ci MacroBlock mb; 296cabdff1aSopenharmony_ci SuperBlock sb; 297cabdff1aSopenharmony_ci unsigned multi_mask = 0; 298cabdff1aSopenharmony_ci 299cabdff1aSopenharmony_ci if (skip == -1) { 300cabdff1aSopenharmony_ci // Note that this call will make us skip the rest of the blocks 301cabdff1aSopenharmony_ci // if the frame prematurely ends 302cabdff1aSopenharmony_ci skip = decode_skip_count(&gb); 303cabdff1aSopenharmony_ci } 304cabdff1aSopenharmony_ci 305cabdff1aSopenharmony_ci if (skip) { 306cabdff1aSopenharmony_ci copy_superblock(new_frame_data, new_stride, 307cabdff1aSopenharmony_ci old_frame_data, old_stride); 308cabdff1aSopenharmony_ci } else { 309cabdff1aSopenharmony_ci copy_superblock(sb.pixels, 8, 310cabdff1aSopenharmony_ci old_frame_data, old_stride); 311cabdff1aSopenharmony_ci 312cabdff1aSopenharmony_ci while (get_bits_left(&gb) >= 1 && !get_bits1(&gb)) { 313cabdff1aSopenharmony_ci unsigned mask; 314cabdff1aSopenharmony_ci mb = decode_macroblock(s, &gb, &cb_index, superblock_index); 315cabdff1aSopenharmony_ci mask = get_bits(&gb, 16); 316cabdff1aSopenharmony_ci multi_mask |= mask; 317cabdff1aSopenharmony_ci for (i = 0; i < 16; i++) { 318cabdff1aSopenharmony_ci if (mask & mask_matrix[i]) { 319cabdff1aSopenharmony_ci insert_mb_into_sb(&sb, mb, i); 320cabdff1aSopenharmony_ci } 321cabdff1aSopenharmony_ci } 322cabdff1aSopenharmony_ci } 323cabdff1aSopenharmony_ci 324cabdff1aSopenharmony_ci if (!get_bits1(&gb)) { 325cabdff1aSopenharmony_ci unsigned inv_mask = get_bits(&gb, 4); 326cabdff1aSopenharmony_ci for (i = 0; i < 4; i++) { 327cabdff1aSopenharmony_ci if (inv_mask & (1 << i)) { 328cabdff1aSopenharmony_ci multi_mask ^= 0xF << i*4; 329cabdff1aSopenharmony_ci } else { 330cabdff1aSopenharmony_ci multi_mask ^= get_bits(&gb, 4) << i*4; 331cabdff1aSopenharmony_ci } 332cabdff1aSopenharmony_ci } 333cabdff1aSopenharmony_ci 334cabdff1aSopenharmony_ci for (i = 0; i < 16; i++) { 335cabdff1aSopenharmony_ci if (multi_mask & mask_matrix[i]) { 336cabdff1aSopenharmony_ci mb = decode_macroblock(s, &gb, &cb_index, 337cabdff1aSopenharmony_ci superblock_index); 338cabdff1aSopenharmony_ci insert_mb_into_sb(&sb, mb, i); 339cabdff1aSopenharmony_ci } 340cabdff1aSopenharmony_ci } 341cabdff1aSopenharmony_ci } else if (frame_flags & (1 << 16)) { 342cabdff1aSopenharmony_ci while (get_bits_left(&gb) >= 1 && !get_bits1(&gb)) { 343cabdff1aSopenharmony_ci mb = decode_macroblock(s, &gb, &cb_index, superblock_index); 344cabdff1aSopenharmony_ci insert_mb_into_sb(&sb, mb, get_bits(&gb, 4)); 345cabdff1aSopenharmony_ci } 346cabdff1aSopenharmony_ci } 347cabdff1aSopenharmony_ci 348cabdff1aSopenharmony_ci copy_superblock(new_frame_data, new_stride, sb.pixels, 8); 349cabdff1aSopenharmony_ci } 350cabdff1aSopenharmony_ci 351cabdff1aSopenharmony_ci superblock_col_index++; 352cabdff1aSopenharmony_ci new_frame_data += 8; 353cabdff1aSopenharmony_ci if (old_frame_data) 354cabdff1aSopenharmony_ci old_frame_data += 8; 355cabdff1aSopenharmony_ci if (superblock_col_index == superblocks_per_row) { 356cabdff1aSopenharmony_ci new_frame_data += new_stride * 8 - superblocks_per_row * 8; 357cabdff1aSopenharmony_ci if (old_frame_data) 358cabdff1aSopenharmony_ci old_frame_data += old_stride * 8 - superblocks_per_row * 8; 359cabdff1aSopenharmony_ci superblock_col_index = 0; 360cabdff1aSopenharmony_ci } 361cabdff1aSopenharmony_ci skip--; 362cabdff1aSopenharmony_ci } 363cabdff1aSopenharmony_ci 364cabdff1aSopenharmony_ci av_log(avctx, AV_LOG_DEBUG, 365cabdff1aSopenharmony_ci "Escape sizes: %i, %i, %i\n", 366cabdff1aSopenharmony_ci frame_size, buf_size, get_bits_count(&gb) / 8); 367cabdff1aSopenharmony_ci 368cabdff1aSopenharmony_ci av_frame_unref(s->frame); 369cabdff1aSopenharmony_ci if ((ret = av_frame_ref(s->frame, frame)) < 0) 370cabdff1aSopenharmony_ci return ret; 371cabdff1aSopenharmony_ci 372cabdff1aSopenharmony_ci *got_frame = 1; 373cabdff1aSopenharmony_ci 374cabdff1aSopenharmony_ci return 0; 375cabdff1aSopenharmony_ci} 376cabdff1aSopenharmony_ci 377cabdff1aSopenharmony_ci 378cabdff1aSopenharmony_ciconst FFCodec ff_escape124_decoder = { 379cabdff1aSopenharmony_ci .p.name = "escape124", 380cabdff1aSopenharmony_ci .p.long_name = NULL_IF_CONFIG_SMALL("Escape 124"), 381cabdff1aSopenharmony_ci .p.type = AVMEDIA_TYPE_VIDEO, 382cabdff1aSopenharmony_ci .p.id = AV_CODEC_ID_ESCAPE124, 383cabdff1aSopenharmony_ci .priv_data_size = sizeof(Escape124Context), 384cabdff1aSopenharmony_ci .init = escape124_decode_init, 385cabdff1aSopenharmony_ci .close = escape124_decode_close, 386cabdff1aSopenharmony_ci FF_CODEC_DECODE_CB(escape124_decode_frame), 387cabdff1aSopenharmony_ci .p.capabilities = AV_CODEC_CAP_DR1, 388cabdff1aSopenharmony_ci .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE, 389cabdff1aSopenharmony_ci}; 390