1cabdff1aSopenharmony_ci/* 2cabdff1aSopenharmony_ci * LOCO codec 3cabdff1aSopenharmony_ci * Copyright (c) 2005 Konstantin Shishkov 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/** 23cabdff1aSopenharmony_ci * @file 24cabdff1aSopenharmony_ci * LOCO codec. 25cabdff1aSopenharmony_ci */ 26cabdff1aSopenharmony_ci 27cabdff1aSopenharmony_ci#include "avcodec.h" 28cabdff1aSopenharmony_ci#include "codec_internal.h" 29cabdff1aSopenharmony_ci#include "get_bits.h" 30cabdff1aSopenharmony_ci#include "golomb.h" 31cabdff1aSopenharmony_ci#include "internal.h" 32cabdff1aSopenharmony_ci#include "mathops.h" 33cabdff1aSopenharmony_ci 34cabdff1aSopenharmony_cienum LOCO_MODE { 35cabdff1aSopenharmony_ci LOCO_UNKN = 0, 36cabdff1aSopenharmony_ci LOCO_CYUY2 = -1, 37cabdff1aSopenharmony_ci LOCO_CRGB = -2, 38cabdff1aSopenharmony_ci LOCO_CRGBA = -3, 39cabdff1aSopenharmony_ci LOCO_CYV12 = -4, 40cabdff1aSopenharmony_ci LOCO_YUY2 = 1, 41cabdff1aSopenharmony_ci LOCO_UYVY = 2, 42cabdff1aSopenharmony_ci LOCO_RGB = 3, 43cabdff1aSopenharmony_ci LOCO_RGBA = 4, 44cabdff1aSopenharmony_ci LOCO_YV12 = 5, 45cabdff1aSopenharmony_ci}; 46cabdff1aSopenharmony_ci 47cabdff1aSopenharmony_citypedef struct LOCOContext { 48cabdff1aSopenharmony_ci AVCodecContext *avctx; 49cabdff1aSopenharmony_ci int lossy; 50cabdff1aSopenharmony_ci enum LOCO_MODE mode; 51cabdff1aSopenharmony_ci} LOCOContext; 52cabdff1aSopenharmony_ci 53cabdff1aSopenharmony_citypedef struct RICEContext { 54cabdff1aSopenharmony_ci GetBitContext gb; 55cabdff1aSopenharmony_ci int save, run, run2; /* internal rice decoder state */ 56cabdff1aSopenharmony_ci int sum, count; /* sum and count for getting rice parameter */ 57cabdff1aSopenharmony_ci int lossy; 58cabdff1aSopenharmony_ci} RICEContext; 59cabdff1aSopenharmony_ci 60cabdff1aSopenharmony_cistatic int loco_get_rice_param(RICEContext *r) 61cabdff1aSopenharmony_ci{ 62cabdff1aSopenharmony_ci int cnt = 0; 63cabdff1aSopenharmony_ci int val = r->count; 64cabdff1aSopenharmony_ci 65cabdff1aSopenharmony_ci while (r->sum > val && cnt < 9) { 66cabdff1aSopenharmony_ci val <<= 1; 67cabdff1aSopenharmony_ci cnt++; 68cabdff1aSopenharmony_ci } 69cabdff1aSopenharmony_ci 70cabdff1aSopenharmony_ci return cnt; 71cabdff1aSopenharmony_ci} 72cabdff1aSopenharmony_ci 73cabdff1aSopenharmony_cistatic inline void loco_update_rice_param(RICEContext *r, int val) 74cabdff1aSopenharmony_ci{ 75cabdff1aSopenharmony_ci r->sum += val; 76cabdff1aSopenharmony_ci r->count++; 77cabdff1aSopenharmony_ci 78cabdff1aSopenharmony_ci if (r->count == 16) { 79cabdff1aSopenharmony_ci r->sum >>= 1; 80cabdff1aSopenharmony_ci r->count >>= 1; 81cabdff1aSopenharmony_ci } 82cabdff1aSopenharmony_ci} 83cabdff1aSopenharmony_ci 84cabdff1aSopenharmony_cistatic inline int loco_get_rice(RICEContext *r) 85cabdff1aSopenharmony_ci{ 86cabdff1aSopenharmony_ci unsigned v; 87cabdff1aSopenharmony_ci if (r->run > 0) { /* we have zero run */ 88cabdff1aSopenharmony_ci r->run--; 89cabdff1aSopenharmony_ci loco_update_rice_param(r, 0); 90cabdff1aSopenharmony_ci return 0; 91cabdff1aSopenharmony_ci } 92cabdff1aSopenharmony_ci if (get_bits_left(&r->gb) < 1) 93cabdff1aSopenharmony_ci return INT_MIN; 94cabdff1aSopenharmony_ci v = get_ur_golomb_jpegls(&r->gb, loco_get_rice_param(r), INT_MAX, 0); 95cabdff1aSopenharmony_ci loco_update_rice_param(r, (v + 1) >> 1); 96cabdff1aSopenharmony_ci if (!v) { 97cabdff1aSopenharmony_ci if (r->save >= 0) { 98cabdff1aSopenharmony_ci r->run = get_ur_golomb_jpegls(&r->gb, 2, INT_MAX, 0); 99cabdff1aSopenharmony_ci if (r->run > 1) 100cabdff1aSopenharmony_ci r->save += r->run + 1; 101cabdff1aSopenharmony_ci else 102cabdff1aSopenharmony_ci r->save -= 3; 103cabdff1aSopenharmony_ci } else 104cabdff1aSopenharmony_ci r->run2++; 105cabdff1aSopenharmony_ci } else { 106cabdff1aSopenharmony_ci v = ((v >> 1) + r->lossy) ^ -(v & 1); 107cabdff1aSopenharmony_ci if (r->run2 > 0) { 108cabdff1aSopenharmony_ci if (r->run2 > 2) 109cabdff1aSopenharmony_ci r->save += r->run2; 110cabdff1aSopenharmony_ci else 111cabdff1aSopenharmony_ci r->save -= 3; 112cabdff1aSopenharmony_ci r->run2 = 0; 113cabdff1aSopenharmony_ci } 114cabdff1aSopenharmony_ci } 115cabdff1aSopenharmony_ci 116cabdff1aSopenharmony_ci return v; 117cabdff1aSopenharmony_ci} 118cabdff1aSopenharmony_ci 119cabdff1aSopenharmony_ci/* LOCO main predictor - LOCO-I/JPEG-LS predictor */ 120cabdff1aSopenharmony_cistatic inline int loco_predict(uint8_t* data, int stride) 121cabdff1aSopenharmony_ci{ 122cabdff1aSopenharmony_ci int a, b, c; 123cabdff1aSopenharmony_ci 124cabdff1aSopenharmony_ci a = data[-stride]; 125cabdff1aSopenharmony_ci b = data[-1]; 126cabdff1aSopenharmony_ci c = data[-stride - 1]; 127cabdff1aSopenharmony_ci 128cabdff1aSopenharmony_ci return mid_pred(a, a + b - c, b); 129cabdff1aSopenharmony_ci} 130cabdff1aSopenharmony_ci 131cabdff1aSopenharmony_cistatic int loco_decode_plane(LOCOContext *l, uint8_t *data, int width, int height, 132cabdff1aSopenharmony_ci int stride, const uint8_t *buf, int buf_size) 133cabdff1aSopenharmony_ci{ 134cabdff1aSopenharmony_ci RICEContext rc; 135cabdff1aSopenharmony_ci unsigned val; 136cabdff1aSopenharmony_ci int ret; 137cabdff1aSopenharmony_ci int i, j; 138cabdff1aSopenharmony_ci 139cabdff1aSopenharmony_ci if(buf_size<=0) 140cabdff1aSopenharmony_ci return -1; 141cabdff1aSopenharmony_ci 142cabdff1aSopenharmony_ci if ((ret = init_get_bits8(&rc.gb, buf, buf_size)) < 0) 143cabdff1aSopenharmony_ci return ret; 144cabdff1aSopenharmony_ci 145cabdff1aSopenharmony_ci rc.save = 0; 146cabdff1aSopenharmony_ci rc.run = 0; 147cabdff1aSopenharmony_ci rc.run2 = 0; 148cabdff1aSopenharmony_ci rc.lossy = l->lossy; 149cabdff1aSopenharmony_ci 150cabdff1aSopenharmony_ci rc.sum = 8; 151cabdff1aSopenharmony_ci rc.count = 1; 152cabdff1aSopenharmony_ci 153cabdff1aSopenharmony_ci /* restore top left pixel */ 154cabdff1aSopenharmony_ci val = loco_get_rice(&rc); 155cabdff1aSopenharmony_ci data[0] = 128 + val; 156cabdff1aSopenharmony_ci /* restore top line */ 157cabdff1aSopenharmony_ci for (i = 1; i < width; i++) { 158cabdff1aSopenharmony_ci val = loco_get_rice(&rc); 159cabdff1aSopenharmony_ci if (val == INT_MIN) 160cabdff1aSopenharmony_ci return AVERROR_INVALIDDATA; 161cabdff1aSopenharmony_ci data[i] = data[i - 1] + val; 162cabdff1aSopenharmony_ci } 163cabdff1aSopenharmony_ci data += stride; 164cabdff1aSopenharmony_ci for (j = 1; j < height; j++) { 165cabdff1aSopenharmony_ci /* restore left column */ 166cabdff1aSopenharmony_ci val = loco_get_rice(&rc); 167cabdff1aSopenharmony_ci if (val == INT_MIN) 168cabdff1aSopenharmony_ci return AVERROR_INVALIDDATA; 169cabdff1aSopenharmony_ci data[0] = data[-stride] + val; 170cabdff1aSopenharmony_ci /* restore all other pixels */ 171cabdff1aSopenharmony_ci for (i = 1; i < width; i++) { 172cabdff1aSopenharmony_ci val = loco_get_rice(&rc); 173cabdff1aSopenharmony_ci if (val == INT_MIN) 174cabdff1aSopenharmony_ci return -1; 175cabdff1aSopenharmony_ci data[i] = loco_predict(&data[i], stride) + val; 176cabdff1aSopenharmony_ci } 177cabdff1aSopenharmony_ci data += stride; 178cabdff1aSopenharmony_ci } 179cabdff1aSopenharmony_ci 180cabdff1aSopenharmony_ci return (get_bits_count(&rc.gb) + 7) >> 3; 181cabdff1aSopenharmony_ci} 182cabdff1aSopenharmony_ci 183cabdff1aSopenharmony_cistatic void rotate_faulty_loco(uint8_t *data, int width, int height, int stride) 184cabdff1aSopenharmony_ci{ 185cabdff1aSopenharmony_ci int y; 186cabdff1aSopenharmony_ci 187cabdff1aSopenharmony_ci for (y=1; y<height; y++) { 188cabdff1aSopenharmony_ci if (width>=y) { 189cabdff1aSopenharmony_ci memmove(data + y*stride, 190cabdff1aSopenharmony_ci data + y*(stride + 1), 191cabdff1aSopenharmony_ci (width-y)); 192cabdff1aSopenharmony_ci if (y+1 < height) 193cabdff1aSopenharmony_ci memmove(data + y*stride + (width-y), 194cabdff1aSopenharmony_ci data + (y+1)*stride, y); 195cabdff1aSopenharmony_ci } 196cabdff1aSopenharmony_ci } 197cabdff1aSopenharmony_ci} 198cabdff1aSopenharmony_ci 199cabdff1aSopenharmony_cistatic int decode_frame(AVCodecContext *avctx, AVFrame *p, 200cabdff1aSopenharmony_ci int *got_frame, AVPacket *avpkt) 201cabdff1aSopenharmony_ci{ 202cabdff1aSopenharmony_ci LOCOContext * const l = avctx->priv_data; 203cabdff1aSopenharmony_ci const uint8_t *buf = avpkt->data; 204cabdff1aSopenharmony_ci int buf_size = avpkt->size; 205cabdff1aSopenharmony_ci int decoded, ret; 206cabdff1aSopenharmony_ci 207cabdff1aSopenharmony_ci if ((ret = ff_get_buffer(avctx, p, 0)) < 0) 208cabdff1aSopenharmony_ci return ret; 209cabdff1aSopenharmony_ci p->key_frame = 1; 210cabdff1aSopenharmony_ci 211cabdff1aSopenharmony_ci#define ADVANCE_BY_DECODED do { \ 212cabdff1aSopenharmony_ci if (decoded < 0 || decoded >= buf_size) goto buf_too_small; \ 213cabdff1aSopenharmony_ci buf += decoded; buf_size -= decoded; \ 214cabdff1aSopenharmony_ci} while(0) 215cabdff1aSopenharmony_ci switch(l->mode) { 216cabdff1aSopenharmony_ci case LOCO_CYUY2: case LOCO_YUY2: case LOCO_UYVY: 217cabdff1aSopenharmony_ci decoded = loco_decode_plane(l, p->data[0], avctx->width, avctx->height, 218cabdff1aSopenharmony_ci p->linesize[0], buf, buf_size); 219cabdff1aSopenharmony_ci ADVANCE_BY_DECODED; 220cabdff1aSopenharmony_ci decoded = loco_decode_plane(l, p->data[1], avctx->width / 2, avctx->height, 221cabdff1aSopenharmony_ci p->linesize[1], buf, buf_size); 222cabdff1aSopenharmony_ci ADVANCE_BY_DECODED; 223cabdff1aSopenharmony_ci decoded = loco_decode_plane(l, p->data[2], avctx->width / 2, avctx->height, 224cabdff1aSopenharmony_ci p->linesize[2], buf, buf_size); 225cabdff1aSopenharmony_ci break; 226cabdff1aSopenharmony_ci case LOCO_CYV12: case LOCO_YV12: 227cabdff1aSopenharmony_ci decoded = loco_decode_plane(l, p->data[0], avctx->width, avctx->height, 228cabdff1aSopenharmony_ci p->linesize[0], buf, buf_size); 229cabdff1aSopenharmony_ci ADVANCE_BY_DECODED; 230cabdff1aSopenharmony_ci decoded = loco_decode_plane(l, p->data[2], avctx->width / 2, avctx->height / 2, 231cabdff1aSopenharmony_ci p->linesize[2], buf, buf_size); 232cabdff1aSopenharmony_ci ADVANCE_BY_DECODED; 233cabdff1aSopenharmony_ci decoded = loco_decode_plane(l, p->data[1], avctx->width / 2, avctx->height / 2, 234cabdff1aSopenharmony_ci p->linesize[1], buf, buf_size); 235cabdff1aSopenharmony_ci break; 236cabdff1aSopenharmony_ci case LOCO_CRGB: case LOCO_RGB: 237cabdff1aSopenharmony_ci decoded = loco_decode_plane(l, p->data[1] + p->linesize[1]*(avctx->height-1), avctx->width, avctx->height, 238cabdff1aSopenharmony_ci -p->linesize[1], buf, buf_size); 239cabdff1aSopenharmony_ci ADVANCE_BY_DECODED; 240cabdff1aSopenharmony_ci decoded = loco_decode_plane(l, p->data[0] + p->linesize[0]*(avctx->height-1), avctx->width, avctx->height, 241cabdff1aSopenharmony_ci -p->linesize[0], buf, buf_size); 242cabdff1aSopenharmony_ci ADVANCE_BY_DECODED; 243cabdff1aSopenharmony_ci decoded = loco_decode_plane(l, p->data[2] + p->linesize[2]*(avctx->height-1), avctx->width, avctx->height, 244cabdff1aSopenharmony_ci -p->linesize[2], buf, buf_size); 245cabdff1aSopenharmony_ci if (avctx->width & 1) { 246cabdff1aSopenharmony_ci rotate_faulty_loco(p->data[0] + p->linesize[0]*(avctx->height-1), avctx->width, avctx->height, -p->linesize[0]); 247cabdff1aSopenharmony_ci rotate_faulty_loco(p->data[1] + p->linesize[1]*(avctx->height-1), avctx->width, avctx->height, -p->linesize[1]); 248cabdff1aSopenharmony_ci rotate_faulty_loco(p->data[2] + p->linesize[2]*(avctx->height-1), avctx->width, avctx->height, -p->linesize[2]); 249cabdff1aSopenharmony_ci } 250cabdff1aSopenharmony_ci break; 251cabdff1aSopenharmony_ci case LOCO_CRGBA: 252cabdff1aSopenharmony_ci case LOCO_RGBA: 253cabdff1aSopenharmony_ci decoded = loco_decode_plane(l, p->data[1] + p->linesize[1]*(avctx->height-1), avctx->width, avctx->height, 254cabdff1aSopenharmony_ci -p->linesize[1], buf, buf_size); 255cabdff1aSopenharmony_ci ADVANCE_BY_DECODED; 256cabdff1aSopenharmony_ci decoded = loco_decode_plane(l, p->data[0] + p->linesize[0]*(avctx->height-1), avctx->width, avctx->height, 257cabdff1aSopenharmony_ci -p->linesize[0], buf, buf_size); 258cabdff1aSopenharmony_ci ADVANCE_BY_DECODED; 259cabdff1aSopenharmony_ci decoded = loco_decode_plane(l, p->data[2] + p->linesize[2]*(avctx->height-1), avctx->width, avctx->height, 260cabdff1aSopenharmony_ci -p->linesize[2], buf, buf_size); 261cabdff1aSopenharmony_ci ADVANCE_BY_DECODED; 262cabdff1aSopenharmony_ci decoded = loco_decode_plane(l, p->data[3] + p->linesize[3]*(avctx->height-1), avctx->width, avctx->height, 263cabdff1aSopenharmony_ci -p->linesize[3], buf, buf_size); 264cabdff1aSopenharmony_ci break; 265cabdff1aSopenharmony_ci default: 266cabdff1aSopenharmony_ci av_assert0(0); 267cabdff1aSopenharmony_ci } 268cabdff1aSopenharmony_ci 269cabdff1aSopenharmony_ci if (decoded < 0 || decoded > buf_size) 270cabdff1aSopenharmony_ci goto buf_too_small; 271cabdff1aSopenharmony_ci buf_size -= decoded; 272cabdff1aSopenharmony_ci 273cabdff1aSopenharmony_ci *got_frame = 1; 274cabdff1aSopenharmony_ci 275cabdff1aSopenharmony_ci return avpkt->size - buf_size; 276cabdff1aSopenharmony_cibuf_too_small: 277cabdff1aSopenharmony_ci av_log(avctx, AV_LOG_ERROR, "Input data too small.\n"); 278cabdff1aSopenharmony_ci return AVERROR(EINVAL); 279cabdff1aSopenharmony_ci} 280cabdff1aSopenharmony_ci 281cabdff1aSopenharmony_cistatic av_cold int decode_init(AVCodecContext *avctx) 282cabdff1aSopenharmony_ci{ 283cabdff1aSopenharmony_ci LOCOContext * const l = avctx->priv_data; 284cabdff1aSopenharmony_ci int version; 285cabdff1aSopenharmony_ci 286cabdff1aSopenharmony_ci l->avctx = avctx; 287cabdff1aSopenharmony_ci if (avctx->extradata_size < 12) { 288cabdff1aSopenharmony_ci av_log(avctx, AV_LOG_ERROR, "Extradata size must be >= 12 instead of %i\n", 289cabdff1aSopenharmony_ci avctx->extradata_size); 290cabdff1aSopenharmony_ci return AVERROR_INVALIDDATA; 291cabdff1aSopenharmony_ci } 292cabdff1aSopenharmony_ci version = AV_RL32(avctx->extradata); 293cabdff1aSopenharmony_ci switch (version) { 294cabdff1aSopenharmony_ci case 1: 295cabdff1aSopenharmony_ci l->lossy = 0; 296cabdff1aSopenharmony_ci break; 297cabdff1aSopenharmony_ci case 2: 298cabdff1aSopenharmony_ci l->lossy = AV_RL32(avctx->extradata + 8); 299cabdff1aSopenharmony_ci break; 300cabdff1aSopenharmony_ci default: 301cabdff1aSopenharmony_ci l->lossy = AV_RL32(avctx->extradata + 8); 302cabdff1aSopenharmony_ci avpriv_request_sample(avctx, "LOCO codec version %i", version); 303cabdff1aSopenharmony_ci } 304cabdff1aSopenharmony_ci 305cabdff1aSopenharmony_ci if (l->lossy > 65536U) { 306cabdff1aSopenharmony_ci av_log(avctx, AV_LOG_ERROR, "lossy %i is too large\n", l->lossy); 307cabdff1aSopenharmony_ci return AVERROR_INVALIDDATA; 308cabdff1aSopenharmony_ci } 309cabdff1aSopenharmony_ci 310cabdff1aSopenharmony_ci l->mode = AV_RL32(avctx->extradata + 4); 311cabdff1aSopenharmony_ci switch (l->mode) { 312cabdff1aSopenharmony_ci case LOCO_CYUY2: 313cabdff1aSopenharmony_ci case LOCO_YUY2: 314cabdff1aSopenharmony_ci case LOCO_UYVY: 315cabdff1aSopenharmony_ci avctx->pix_fmt = AV_PIX_FMT_YUV422P; 316cabdff1aSopenharmony_ci break; 317cabdff1aSopenharmony_ci case LOCO_CRGB: 318cabdff1aSopenharmony_ci case LOCO_RGB: 319cabdff1aSopenharmony_ci avctx->pix_fmt = AV_PIX_FMT_GBRP; 320cabdff1aSopenharmony_ci break; 321cabdff1aSopenharmony_ci case LOCO_CYV12: 322cabdff1aSopenharmony_ci case LOCO_YV12: 323cabdff1aSopenharmony_ci avctx->pix_fmt = AV_PIX_FMT_YUV420P; 324cabdff1aSopenharmony_ci break; 325cabdff1aSopenharmony_ci case LOCO_CRGBA: 326cabdff1aSopenharmony_ci case LOCO_RGBA: 327cabdff1aSopenharmony_ci avctx->pix_fmt = AV_PIX_FMT_GBRAP; 328cabdff1aSopenharmony_ci break; 329cabdff1aSopenharmony_ci default: 330cabdff1aSopenharmony_ci av_log(avctx, AV_LOG_INFO, "Unknown colorspace, index = %i\n", l->mode); 331cabdff1aSopenharmony_ci return AVERROR_INVALIDDATA; 332cabdff1aSopenharmony_ci } 333cabdff1aSopenharmony_ci if (avctx->debug & FF_DEBUG_PICT_INFO) 334cabdff1aSopenharmony_ci av_log(avctx, AV_LOG_INFO, "lossy:%i, version:%i, mode: %i\n", l->lossy, version, l->mode); 335cabdff1aSopenharmony_ci 336cabdff1aSopenharmony_ci return 0; 337cabdff1aSopenharmony_ci} 338cabdff1aSopenharmony_ci 339cabdff1aSopenharmony_ciconst FFCodec ff_loco_decoder = { 340cabdff1aSopenharmony_ci .p.name = "loco", 341cabdff1aSopenharmony_ci .p.long_name = NULL_IF_CONFIG_SMALL("LOCO"), 342cabdff1aSopenharmony_ci .p.type = AVMEDIA_TYPE_VIDEO, 343cabdff1aSopenharmony_ci .p.id = AV_CODEC_ID_LOCO, 344cabdff1aSopenharmony_ci .priv_data_size = sizeof(LOCOContext), 345cabdff1aSopenharmony_ci .init = decode_init, 346cabdff1aSopenharmony_ci FF_CODEC_DECODE_CB(decode_frame), 347cabdff1aSopenharmony_ci .p.capabilities = AV_CODEC_CAP_DR1, 348cabdff1aSopenharmony_ci .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE, 349cabdff1aSopenharmony_ci}; 350