1cabdff1aSopenharmony_ci/* 2cabdff1aSopenharmony_ci * Copyright (c) 2010-2011 Maxim Poliakovski 3cabdff1aSopenharmony_ci * Copyright (c) 2010-2011 Elvis Presley 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 * Known FOURCCs: 'apch' (HQ), 'apcn' (SD), 'apcs' (LT), 'apco' (Proxy), 'ap4h' (4444), 'ap4x' (4444 XQ) 25cabdff1aSopenharmony_ci */ 26cabdff1aSopenharmony_ci 27cabdff1aSopenharmony_ci//#define DEBUG 28cabdff1aSopenharmony_ci 29cabdff1aSopenharmony_ci#define LONG_BITSTREAM_READER 30cabdff1aSopenharmony_ci 31cabdff1aSopenharmony_ci#include "config_components.h" 32cabdff1aSopenharmony_ci 33cabdff1aSopenharmony_ci#include "libavutil/internal.h" 34cabdff1aSopenharmony_ci#include "libavutil/mem_internal.h" 35cabdff1aSopenharmony_ci 36cabdff1aSopenharmony_ci#include "avcodec.h" 37cabdff1aSopenharmony_ci#include "codec_internal.h" 38cabdff1aSopenharmony_ci#include "get_bits.h" 39cabdff1aSopenharmony_ci#include "hwconfig.h" 40cabdff1aSopenharmony_ci#include "idctdsp.h" 41cabdff1aSopenharmony_ci#include "internal.h" 42cabdff1aSopenharmony_ci#include "profiles.h" 43cabdff1aSopenharmony_ci#include "simple_idct.h" 44cabdff1aSopenharmony_ci#include "proresdec.h" 45cabdff1aSopenharmony_ci#include "proresdata.h" 46cabdff1aSopenharmony_ci#include "thread.h" 47cabdff1aSopenharmony_ci 48cabdff1aSopenharmony_cistatic void permute(uint8_t *dst, const uint8_t *src, const uint8_t permutation[64]) 49cabdff1aSopenharmony_ci{ 50cabdff1aSopenharmony_ci int i; 51cabdff1aSopenharmony_ci for (i = 0; i < 64; i++) 52cabdff1aSopenharmony_ci dst[i] = permutation[src[i]]; 53cabdff1aSopenharmony_ci} 54cabdff1aSopenharmony_ci 55cabdff1aSopenharmony_ci#define ALPHA_SHIFT_16_TO_10(alpha_val) (alpha_val >> 6) 56cabdff1aSopenharmony_ci#define ALPHA_SHIFT_8_TO_10(alpha_val) ((alpha_val << 2) | (alpha_val >> 6)) 57cabdff1aSopenharmony_ci#define ALPHA_SHIFT_16_TO_12(alpha_val) (alpha_val >> 4) 58cabdff1aSopenharmony_ci#define ALPHA_SHIFT_8_TO_12(alpha_val) ((alpha_val << 4) | (alpha_val >> 4)) 59cabdff1aSopenharmony_ci 60cabdff1aSopenharmony_cistatic void inline unpack_alpha(GetBitContext *gb, uint16_t *dst, int num_coeffs, 61cabdff1aSopenharmony_ci const int num_bits, const int decode_precision) { 62cabdff1aSopenharmony_ci const int mask = (1 << num_bits) - 1; 63cabdff1aSopenharmony_ci int i, idx, val, alpha_val; 64cabdff1aSopenharmony_ci 65cabdff1aSopenharmony_ci idx = 0; 66cabdff1aSopenharmony_ci alpha_val = mask; 67cabdff1aSopenharmony_ci do { 68cabdff1aSopenharmony_ci do { 69cabdff1aSopenharmony_ci if (get_bits1(gb)) { 70cabdff1aSopenharmony_ci val = get_bits(gb, num_bits); 71cabdff1aSopenharmony_ci } else { 72cabdff1aSopenharmony_ci int sign; 73cabdff1aSopenharmony_ci val = get_bits(gb, num_bits == 16 ? 7 : 4); 74cabdff1aSopenharmony_ci sign = val & 1; 75cabdff1aSopenharmony_ci val = (val + 2) >> 1; 76cabdff1aSopenharmony_ci if (sign) 77cabdff1aSopenharmony_ci val = -val; 78cabdff1aSopenharmony_ci } 79cabdff1aSopenharmony_ci alpha_val = (alpha_val + val) & mask; 80cabdff1aSopenharmony_ci if (num_bits == 16) { 81cabdff1aSopenharmony_ci if (decode_precision == 10) { 82cabdff1aSopenharmony_ci dst[idx++] = ALPHA_SHIFT_16_TO_10(alpha_val); 83cabdff1aSopenharmony_ci } else { /* 12b */ 84cabdff1aSopenharmony_ci dst[idx++] = ALPHA_SHIFT_16_TO_12(alpha_val); 85cabdff1aSopenharmony_ci } 86cabdff1aSopenharmony_ci } else { 87cabdff1aSopenharmony_ci if (decode_precision == 10) { 88cabdff1aSopenharmony_ci dst[idx++] = ALPHA_SHIFT_8_TO_10(alpha_val); 89cabdff1aSopenharmony_ci } else { /* 12b */ 90cabdff1aSopenharmony_ci dst[idx++] = ALPHA_SHIFT_8_TO_12(alpha_val); 91cabdff1aSopenharmony_ci } 92cabdff1aSopenharmony_ci } 93cabdff1aSopenharmony_ci if (idx >= num_coeffs) 94cabdff1aSopenharmony_ci break; 95cabdff1aSopenharmony_ci } while (get_bits_left(gb)>0 && get_bits1(gb)); 96cabdff1aSopenharmony_ci val = get_bits(gb, 4); 97cabdff1aSopenharmony_ci if (!val) 98cabdff1aSopenharmony_ci val = get_bits(gb, 11); 99cabdff1aSopenharmony_ci if (idx + val > num_coeffs) 100cabdff1aSopenharmony_ci val = num_coeffs - idx; 101cabdff1aSopenharmony_ci if (num_bits == 16) { 102cabdff1aSopenharmony_ci for (i = 0; i < val; i++) { 103cabdff1aSopenharmony_ci if (decode_precision == 10) { 104cabdff1aSopenharmony_ci dst[idx++] = ALPHA_SHIFT_16_TO_10(alpha_val); 105cabdff1aSopenharmony_ci } else { /* 12b */ 106cabdff1aSopenharmony_ci dst[idx++] = ALPHA_SHIFT_16_TO_12(alpha_val); 107cabdff1aSopenharmony_ci } 108cabdff1aSopenharmony_ci } 109cabdff1aSopenharmony_ci } else { 110cabdff1aSopenharmony_ci for (i = 0; i < val; i++) { 111cabdff1aSopenharmony_ci if (decode_precision == 10) { 112cabdff1aSopenharmony_ci dst[idx++] = ALPHA_SHIFT_8_TO_10(alpha_val); 113cabdff1aSopenharmony_ci } else { /* 12b */ 114cabdff1aSopenharmony_ci dst[idx++] = ALPHA_SHIFT_8_TO_12(alpha_val); 115cabdff1aSopenharmony_ci } 116cabdff1aSopenharmony_ci } 117cabdff1aSopenharmony_ci } 118cabdff1aSopenharmony_ci } while (idx < num_coeffs); 119cabdff1aSopenharmony_ci} 120cabdff1aSopenharmony_ci 121cabdff1aSopenharmony_cistatic void unpack_alpha_10(GetBitContext *gb, uint16_t *dst, int num_coeffs, 122cabdff1aSopenharmony_ci const int num_bits) 123cabdff1aSopenharmony_ci{ 124cabdff1aSopenharmony_ci if (num_bits == 16) { 125cabdff1aSopenharmony_ci unpack_alpha(gb, dst, num_coeffs, 16, 10); 126cabdff1aSopenharmony_ci } else { /* 8 bits alpha */ 127cabdff1aSopenharmony_ci unpack_alpha(gb, dst, num_coeffs, 8, 10); 128cabdff1aSopenharmony_ci } 129cabdff1aSopenharmony_ci} 130cabdff1aSopenharmony_ci 131cabdff1aSopenharmony_cistatic void unpack_alpha_12(GetBitContext *gb, uint16_t *dst, int num_coeffs, 132cabdff1aSopenharmony_ci const int num_bits) 133cabdff1aSopenharmony_ci{ 134cabdff1aSopenharmony_ci if (num_bits == 16) { 135cabdff1aSopenharmony_ci unpack_alpha(gb, dst, num_coeffs, 16, 12); 136cabdff1aSopenharmony_ci } else { /* 8 bits alpha */ 137cabdff1aSopenharmony_ci unpack_alpha(gb, dst, num_coeffs, 8, 12); 138cabdff1aSopenharmony_ci } 139cabdff1aSopenharmony_ci} 140cabdff1aSopenharmony_ci 141cabdff1aSopenharmony_cistatic av_cold int decode_init(AVCodecContext *avctx) 142cabdff1aSopenharmony_ci{ 143cabdff1aSopenharmony_ci int ret = 0; 144cabdff1aSopenharmony_ci ProresContext *ctx = avctx->priv_data; 145cabdff1aSopenharmony_ci uint8_t idct_permutation[64]; 146cabdff1aSopenharmony_ci 147cabdff1aSopenharmony_ci avctx->bits_per_raw_sample = 10; 148cabdff1aSopenharmony_ci 149cabdff1aSopenharmony_ci switch (avctx->codec_tag) { 150cabdff1aSopenharmony_ci case MKTAG('a','p','c','o'): 151cabdff1aSopenharmony_ci avctx->profile = FF_PROFILE_PRORES_PROXY; 152cabdff1aSopenharmony_ci break; 153cabdff1aSopenharmony_ci case MKTAG('a','p','c','s'): 154cabdff1aSopenharmony_ci avctx->profile = FF_PROFILE_PRORES_LT; 155cabdff1aSopenharmony_ci break; 156cabdff1aSopenharmony_ci case MKTAG('a','p','c','n'): 157cabdff1aSopenharmony_ci avctx->profile = FF_PROFILE_PRORES_STANDARD; 158cabdff1aSopenharmony_ci break; 159cabdff1aSopenharmony_ci case MKTAG('a','p','c','h'): 160cabdff1aSopenharmony_ci avctx->profile = FF_PROFILE_PRORES_HQ; 161cabdff1aSopenharmony_ci break; 162cabdff1aSopenharmony_ci case MKTAG('a','p','4','h'): 163cabdff1aSopenharmony_ci avctx->profile = FF_PROFILE_PRORES_4444; 164cabdff1aSopenharmony_ci avctx->bits_per_raw_sample = 12; 165cabdff1aSopenharmony_ci break; 166cabdff1aSopenharmony_ci case MKTAG('a','p','4','x'): 167cabdff1aSopenharmony_ci avctx->profile = FF_PROFILE_PRORES_XQ; 168cabdff1aSopenharmony_ci avctx->bits_per_raw_sample = 12; 169cabdff1aSopenharmony_ci break; 170cabdff1aSopenharmony_ci default: 171cabdff1aSopenharmony_ci avctx->profile = FF_PROFILE_UNKNOWN; 172cabdff1aSopenharmony_ci av_log(avctx, AV_LOG_WARNING, "Unknown prores profile %d\n", avctx->codec_tag); 173cabdff1aSopenharmony_ci } 174cabdff1aSopenharmony_ci 175cabdff1aSopenharmony_ci if (avctx->bits_per_raw_sample == 10) { 176cabdff1aSopenharmony_ci av_log(avctx, AV_LOG_DEBUG, "Auto bitdepth precision. Use 10b decoding based on codec tag.\n"); 177cabdff1aSopenharmony_ci } else { /* 12b */ 178cabdff1aSopenharmony_ci av_log(avctx, AV_LOG_DEBUG, "Auto bitdepth precision. Use 12b decoding based on codec tag.\n"); 179cabdff1aSopenharmony_ci } 180cabdff1aSopenharmony_ci 181cabdff1aSopenharmony_ci ff_blockdsp_init(&ctx->bdsp, avctx); 182cabdff1aSopenharmony_ci ret = ff_proresdsp_init(&ctx->prodsp, avctx); 183cabdff1aSopenharmony_ci if (ret < 0) { 184cabdff1aSopenharmony_ci av_log(avctx, AV_LOG_ERROR, "Fail to init proresdsp for bits per raw sample %d\n", avctx->bits_per_raw_sample); 185cabdff1aSopenharmony_ci return ret; 186cabdff1aSopenharmony_ci } 187cabdff1aSopenharmony_ci 188cabdff1aSopenharmony_ci ff_init_scantable_permutation(idct_permutation, 189cabdff1aSopenharmony_ci ctx->prodsp.idct_permutation_type); 190cabdff1aSopenharmony_ci 191cabdff1aSopenharmony_ci permute(ctx->progressive_scan, ff_prores_progressive_scan, idct_permutation); 192cabdff1aSopenharmony_ci permute(ctx->interlaced_scan, ff_prores_interlaced_scan, idct_permutation); 193cabdff1aSopenharmony_ci 194cabdff1aSopenharmony_ci ctx->pix_fmt = AV_PIX_FMT_NONE; 195cabdff1aSopenharmony_ci 196cabdff1aSopenharmony_ci if (avctx->bits_per_raw_sample == 10){ 197cabdff1aSopenharmony_ci ctx->unpack_alpha = unpack_alpha_10; 198cabdff1aSopenharmony_ci } else if (avctx->bits_per_raw_sample == 12){ 199cabdff1aSopenharmony_ci ctx->unpack_alpha = unpack_alpha_12; 200cabdff1aSopenharmony_ci } else { 201cabdff1aSopenharmony_ci av_log(avctx, AV_LOG_ERROR, "Fail to set unpack_alpha for bits per raw sample %d\n", avctx->bits_per_raw_sample); 202cabdff1aSopenharmony_ci return AVERROR_BUG; 203cabdff1aSopenharmony_ci } 204cabdff1aSopenharmony_ci return ret; 205cabdff1aSopenharmony_ci} 206cabdff1aSopenharmony_ci 207cabdff1aSopenharmony_cistatic int decode_frame_header(ProresContext *ctx, const uint8_t *buf, 208cabdff1aSopenharmony_ci const int data_size, AVCodecContext *avctx) 209cabdff1aSopenharmony_ci{ 210cabdff1aSopenharmony_ci int hdr_size, width, height, flags; 211cabdff1aSopenharmony_ci int version; 212cabdff1aSopenharmony_ci const uint8_t *ptr; 213cabdff1aSopenharmony_ci enum AVPixelFormat pix_fmt; 214cabdff1aSopenharmony_ci 215cabdff1aSopenharmony_ci hdr_size = AV_RB16(buf); 216cabdff1aSopenharmony_ci ff_dlog(avctx, "header size %d\n", hdr_size); 217cabdff1aSopenharmony_ci if (hdr_size > data_size) { 218cabdff1aSopenharmony_ci av_log(avctx, AV_LOG_ERROR, "error, wrong header size\n"); 219cabdff1aSopenharmony_ci return AVERROR_INVALIDDATA; 220cabdff1aSopenharmony_ci } 221cabdff1aSopenharmony_ci 222cabdff1aSopenharmony_ci version = AV_RB16(buf + 2); 223cabdff1aSopenharmony_ci ff_dlog(avctx, "%.4s version %d\n", buf+4, version); 224cabdff1aSopenharmony_ci if (version > 1) { 225cabdff1aSopenharmony_ci av_log(avctx, AV_LOG_ERROR, "unsupported version: %d\n", version); 226cabdff1aSopenharmony_ci return AVERROR_PATCHWELCOME; 227cabdff1aSopenharmony_ci } 228cabdff1aSopenharmony_ci 229cabdff1aSopenharmony_ci width = AV_RB16(buf + 8); 230cabdff1aSopenharmony_ci height = AV_RB16(buf + 10); 231cabdff1aSopenharmony_ci 232cabdff1aSopenharmony_ci if (width != avctx->width || height != avctx->height) { 233cabdff1aSopenharmony_ci int ret; 234cabdff1aSopenharmony_ci 235cabdff1aSopenharmony_ci av_log(avctx, AV_LOG_WARNING, "picture resolution change: %dx%d -> %dx%d\n", 236cabdff1aSopenharmony_ci avctx->width, avctx->height, width, height); 237cabdff1aSopenharmony_ci if ((ret = ff_set_dimensions(avctx, width, height)) < 0) 238cabdff1aSopenharmony_ci return ret; 239cabdff1aSopenharmony_ci } 240cabdff1aSopenharmony_ci 241cabdff1aSopenharmony_ci ctx->frame_type = (buf[12] >> 2) & 3; 242cabdff1aSopenharmony_ci ctx->alpha_info = buf[17] & 0xf; 243cabdff1aSopenharmony_ci 244cabdff1aSopenharmony_ci if (ctx->alpha_info > 2) { 245cabdff1aSopenharmony_ci av_log(avctx, AV_LOG_ERROR, "Invalid alpha mode %d\n", ctx->alpha_info); 246cabdff1aSopenharmony_ci return AVERROR_INVALIDDATA; 247cabdff1aSopenharmony_ci } 248cabdff1aSopenharmony_ci if (avctx->skip_alpha) ctx->alpha_info = 0; 249cabdff1aSopenharmony_ci 250cabdff1aSopenharmony_ci ff_dlog(avctx, "frame type %d\n", ctx->frame_type); 251cabdff1aSopenharmony_ci 252cabdff1aSopenharmony_ci if (ctx->frame_type == 0) { 253cabdff1aSopenharmony_ci ctx->scan = ctx->progressive_scan; // permuted 254cabdff1aSopenharmony_ci } else { 255cabdff1aSopenharmony_ci ctx->scan = ctx->interlaced_scan; // permuted 256cabdff1aSopenharmony_ci ctx->frame->interlaced_frame = 1; 257cabdff1aSopenharmony_ci ctx->frame->top_field_first = ctx->frame_type == 1; 258cabdff1aSopenharmony_ci } 259cabdff1aSopenharmony_ci 260cabdff1aSopenharmony_ci if (ctx->alpha_info) { 261cabdff1aSopenharmony_ci if (avctx->bits_per_raw_sample == 10) { 262cabdff1aSopenharmony_ci pix_fmt = (buf[12] & 0xC0) == 0xC0 ? AV_PIX_FMT_YUVA444P10 : AV_PIX_FMT_YUVA422P10; 263cabdff1aSopenharmony_ci } else { /* 12b */ 264cabdff1aSopenharmony_ci pix_fmt = (buf[12] & 0xC0) == 0xC0 ? AV_PIX_FMT_YUVA444P12 : AV_PIX_FMT_YUVA422P12; 265cabdff1aSopenharmony_ci } 266cabdff1aSopenharmony_ci } else { 267cabdff1aSopenharmony_ci if (avctx->bits_per_raw_sample == 10) { 268cabdff1aSopenharmony_ci pix_fmt = (buf[12] & 0xC0) == 0xC0 ? AV_PIX_FMT_YUV444P10 : AV_PIX_FMT_YUV422P10; 269cabdff1aSopenharmony_ci } else { /* 12b */ 270cabdff1aSopenharmony_ci pix_fmt = (buf[12] & 0xC0) == 0xC0 ? AV_PIX_FMT_YUV444P12 : AV_PIX_FMT_YUV422P12; 271cabdff1aSopenharmony_ci } 272cabdff1aSopenharmony_ci } 273cabdff1aSopenharmony_ci 274cabdff1aSopenharmony_ci if (pix_fmt != ctx->pix_fmt) { 275cabdff1aSopenharmony_ci#define HWACCEL_MAX (CONFIG_PRORES_VIDEOTOOLBOX_HWACCEL) 276cabdff1aSopenharmony_ci enum AVPixelFormat pix_fmts[HWACCEL_MAX + 2], *fmtp = pix_fmts; 277cabdff1aSopenharmony_ci int ret; 278cabdff1aSopenharmony_ci 279cabdff1aSopenharmony_ci ctx->pix_fmt = pix_fmt; 280cabdff1aSopenharmony_ci 281cabdff1aSopenharmony_ci#if CONFIG_PRORES_VIDEOTOOLBOX_HWACCEL 282cabdff1aSopenharmony_ci *fmtp++ = AV_PIX_FMT_VIDEOTOOLBOX; 283cabdff1aSopenharmony_ci#endif 284cabdff1aSopenharmony_ci *fmtp++ = ctx->pix_fmt; 285cabdff1aSopenharmony_ci *fmtp = AV_PIX_FMT_NONE; 286cabdff1aSopenharmony_ci 287cabdff1aSopenharmony_ci if ((ret = ff_thread_get_format(avctx, pix_fmts)) < 0) 288cabdff1aSopenharmony_ci return ret; 289cabdff1aSopenharmony_ci 290cabdff1aSopenharmony_ci avctx->pix_fmt = ret; 291cabdff1aSopenharmony_ci } 292cabdff1aSopenharmony_ci 293cabdff1aSopenharmony_ci avctx->color_primaries = buf[14]; 294cabdff1aSopenharmony_ci avctx->color_trc = buf[15]; 295cabdff1aSopenharmony_ci avctx->colorspace = buf[16]; 296cabdff1aSopenharmony_ci avctx->color_range = AVCOL_RANGE_MPEG; 297cabdff1aSopenharmony_ci 298cabdff1aSopenharmony_ci ptr = buf + 20; 299cabdff1aSopenharmony_ci flags = buf[19]; 300cabdff1aSopenharmony_ci ff_dlog(avctx, "flags %x\n", flags); 301cabdff1aSopenharmony_ci 302cabdff1aSopenharmony_ci if (flags & 2) { 303cabdff1aSopenharmony_ci if(buf + data_size - ptr < 64) { 304cabdff1aSopenharmony_ci av_log(avctx, AV_LOG_ERROR, "Header truncated\n"); 305cabdff1aSopenharmony_ci return AVERROR_INVALIDDATA; 306cabdff1aSopenharmony_ci } 307cabdff1aSopenharmony_ci permute(ctx->qmat_luma, ctx->prodsp.idct_permutation, ptr); 308cabdff1aSopenharmony_ci ptr += 64; 309cabdff1aSopenharmony_ci } else { 310cabdff1aSopenharmony_ci memset(ctx->qmat_luma, 4, 64); 311cabdff1aSopenharmony_ci } 312cabdff1aSopenharmony_ci 313cabdff1aSopenharmony_ci if (flags & 1) { 314cabdff1aSopenharmony_ci if(buf + data_size - ptr < 64) { 315cabdff1aSopenharmony_ci av_log(avctx, AV_LOG_ERROR, "Header truncated\n"); 316cabdff1aSopenharmony_ci return AVERROR_INVALIDDATA; 317cabdff1aSopenharmony_ci } 318cabdff1aSopenharmony_ci permute(ctx->qmat_chroma, ctx->prodsp.idct_permutation, ptr); 319cabdff1aSopenharmony_ci } else { 320cabdff1aSopenharmony_ci memcpy(ctx->qmat_chroma, ctx->qmat_luma, 64); 321cabdff1aSopenharmony_ci } 322cabdff1aSopenharmony_ci 323cabdff1aSopenharmony_ci return hdr_size; 324cabdff1aSopenharmony_ci} 325cabdff1aSopenharmony_ci 326cabdff1aSopenharmony_cistatic int decode_picture_header(AVCodecContext *avctx, const uint8_t *buf, const int buf_size) 327cabdff1aSopenharmony_ci{ 328cabdff1aSopenharmony_ci ProresContext *ctx = avctx->priv_data; 329cabdff1aSopenharmony_ci int i, hdr_size, slice_count; 330cabdff1aSopenharmony_ci unsigned pic_data_size; 331cabdff1aSopenharmony_ci int log2_slice_mb_width, log2_slice_mb_height; 332cabdff1aSopenharmony_ci int slice_mb_count, mb_x, mb_y; 333cabdff1aSopenharmony_ci const uint8_t *data_ptr, *index_ptr; 334cabdff1aSopenharmony_ci 335cabdff1aSopenharmony_ci hdr_size = buf[0] >> 3; 336cabdff1aSopenharmony_ci if (hdr_size < 8 || hdr_size > buf_size) { 337cabdff1aSopenharmony_ci av_log(avctx, AV_LOG_ERROR, "error, wrong picture header size\n"); 338cabdff1aSopenharmony_ci return AVERROR_INVALIDDATA; 339cabdff1aSopenharmony_ci } 340cabdff1aSopenharmony_ci 341cabdff1aSopenharmony_ci pic_data_size = AV_RB32(buf + 1); 342cabdff1aSopenharmony_ci if (pic_data_size > buf_size) { 343cabdff1aSopenharmony_ci av_log(avctx, AV_LOG_ERROR, "error, wrong picture data size\n"); 344cabdff1aSopenharmony_ci return AVERROR_INVALIDDATA; 345cabdff1aSopenharmony_ci } 346cabdff1aSopenharmony_ci 347cabdff1aSopenharmony_ci log2_slice_mb_width = buf[7] >> 4; 348cabdff1aSopenharmony_ci log2_slice_mb_height = buf[7] & 0xF; 349cabdff1aSopenharmony_ci if (log2_slice_mb_width > 3 || log2_slice_mb_height) { 350cabdff1aSopenharmony_ci av_log(avctx, AV_LOG_ERROR, "unsupported slice resolution: %dx%d\n", 351cabdff1aSopenharmony_ci 1 << log2_slice_mb_width, 1 << log2_slice_mb_height); 352cabdff1aSopenharmony_ci return AVERROR_INVALIDDATA; 353cabdff1aSopenharmony_ci } 354cabdff1aSopenharmony_ci 355cabdff1aSopenharmony_ci ctx->mb_width = (avctx->width + 15) >> 4; 356cabdff1aSopenharmony_ci if (ctx->frame_type) 357cabdff1aSopenharmony_ci ctx->mb_height = (avctx->height + 31) >> 5; 358cabdff1aSopenharmony_ci else 359cabdff1aSopenharmony_ci ctx->mb_height = (avctx->height + 15) >> 4; 360cabdff1aSopenharmony_ci 361cabdff1aSopenharmony_ci // QT ignores the written value 362cabdff1aSopenharmony_ci // slice_count = AV_RB16(buf + 5); 363cabdff1aSopenharmony_ci slice_count = ctx->mb_height * ((ctx->mb_width >> log2_slice_mb_width) + 364cabdff1aSopenharmony_ci av_popcount(ctx->mb_width & (1 << log2_slice_mb_width) - 1)); 365cabdff1aSopenharmony_ci 366cabdff1aSopenharmony_ci if (ctx->slice_count != slice_count || !ctx->slices) { 367cabdff1aSopenharmony_ci av_freep(&ctx->slices); 368cabdff1aSopenharmony_ci ctx->slice_count = 0; 369cabdff1aSopenharmony_ci ctx->slices = av_calloc(slice_count, sizeof(*ctx->slices)); 370cabdff1aSopenharmony_ci if (!ctx->slices) 371cabdff1aSopenharmony_ci return AVERROR(ENOMEM); 372cabdff1aSopenharmony_ci ctx->slice_count = slice_count; 373cabdff1aSopenharmony_ci } 374cabdff1aSopenharmony_ci 375cabdff1aSopenharmony_ci if (!slice_count) 376cabdff1aSopenharmony_ci return AVERROR(EINVAL); 377cabdff1aSopenharmony_ci 378cabdff1aSopenharmony_ci if (hdr_size + slice_count*2 > buf_size) { 379cabdff1aSopenharmony_ci av_log(avctx, AV_LOG_ERROR, "error, wrong slice count\n"); 380cabdff1aSopenharmony_ci return AVERROR_INVALIDDATA; 381cabdff1aSopenharmony_ci } 382cabdff1aSopenharmony_ci 383cabdff1aSopenharmony_ci // parse slice information 384cabdff1aSopenharmony_ci index_ptr = buf + hdr_size; 385cabdff1aSopenharmony_ci data_ptr = index_ptr + slice_count*2; 386cabdff1aSopenharmony_ci 387cabdff1aSopenharmony_ci slice_mb_count = 1 << log2_slice_mb_width; 388cabdff1aSopenharmony_ci mb_x = 0; 389cabdff1aSopenharmony_ci mb_y = 0; 390cabdff1aSopenharmony_ci 391cabdff1aSopenharmony_ci for (i = 0; i < slice_count; i++) { 392cabdff1aSopenharmony_ci SliceContext *slice = &ctx->slices[i]; 393cabdff1aSopenharmony_ci 394cabdff1aSopenharmony_ci slice->data = data_ptr; 395cabdff1aSopenharmony_ci data_ptr += AV_RB16(index_ptr + i*2); 396cabdff1aSopenharmony_ci 397cabdff1aSopenharmony_ci while (ctx->mb_width - mb_x < slice_mb_count) 398cabdff1aSopenharmony_ci slice_mb_count >>= 1; 399cabdff1aSopenharmony_ci 400cabdff1aSopenharmony_ci slice->mb_x = mb_x; 401cabdff1aSopenharmony_ci slice->mb_y = mb_y; 402cabdff1aSopenharmony_ci slice->mb_count = slice_mb_count; 403cabdff1aSopenharmony_ci slice->data_size = data_ptr - slice->data; 404cabdff1aSopenharmony_ci 405cabdff1aSopenharmony_ci if (slice->data_size < 6) { 406cabdff1aSopenharmony_ci av_log(avctx, AV_LOG_ERROR, "error, wrong slice data size\n"); 407cabdff1aSopenharmony_ci return AVERROR_INVALIDDATA; 408cabdff1aSopenharmony_ci } 409cabdff1aSopenharmony_ci 410cabdff1aSopenharmony_ci mb_x += slice_mb_count; 411cabdff1aSopenharmony_ci if (mb_x == ctx->mb_width) { 412cabdff1aSopenharmony_ci slice_mb_count = 1 << log2_slice_mb_width; 413cabdff1aSopenharmony_ci mb_x = 0; 414cabdff1aSopenharmony_ci mb_y++; 415cabdff1aSopenharmony_ci } 416cabdff1aSopenharmony_ci if (data_ptr > buf + buf_size) { 417cabdff1aSopenharmony_ci av_log(avctx, AV_LOG_ERROR, "error, slice out of bounds\n"); 418cabdff1aSopenharmony_ci return AVERROR_INVALIDDATA; 419cabdff1aSopenharmony_ci } 420cabdff1aSopenharmony_ci } 421cabdff1aSopenharmony_ci 422cabdff1aSopenharmony_ci if (mb_x || mb_y != ctx->mb_height) { 423cabdff1aSopenharmony_ci av_log(avctx, AV_LOG_ERROR, "error wrong mb count y %d h %d\n", 424cabdff1aSopenharmony_ci mb_y, ctx->mb_height); 425cabdff1aSopenharmony_ci return AVERROR_INVALIDDATA; 426cabdff1aSopenharmony_ci } 427cabdff1aSopenharmony_ci 428cabdff1aSopenharmony_ci return pic_data_size; 429cabdff1aSopenharmony_ci} 430cabdff1aSopenharmony_ci 431cabdff1aSopenharmony_ci#define DECODE_CODEWORD(val, codebook, SKIP) \ 432cabdff1aSopenharmony_ci do { \ 433cabdff1aSopenharmony_ci unsigned int rice_order, exp_order, switch_bits; \ 434cabdff1aSopenharmony_ci unsigned int q, buf, bits; \ 435cabdff1aSopenharmony_ci \ 436cabdff1aSopenharmony_ci UPDATE_CACHE(re, gb); \ 437cabdff1aSopenharmony_ci buf = GET_CACHE(re, gb); \ 438cabdff1aSopenharmony_ci \ 439cabdff1aSopenharmony_ci /* number of bits to switch between rice and exp golomb */ \ 440cabdff1aSopenharmony_ci switch_bits = codebook & 3; \ 441cabdff1aSopenharmony_ci rice_order = codebook >> 5; \ 442cabdff1aSopenharmony_ci exp_order = (codebook >> 2) & 7; \ 443cabdff1aSopenharmony_ci \ 444cabdff1aSopenharmony_ci q = 31 - av_log2(buf); \ 445cabdff1aSopenharmony_ci \ 446cabdff1aSopenharmony_ci if (q > switch_bits) { /* exp golomb */ \ 447cabdff1aSopenharmony_ci bits = exp_order - switch_bits + (q<<1); \ 448cabdff1aSopenharmony_ci if (bits > FFMIN(MIN_CACHE_BITS, 31)) \ 449cabdff1aSopenharmony_ci return AVERROR_INVALIDDATA; \ 450cabdff1aSopenharmony_ci val = SHOW_UBITS(re, gb, bits) - (1 << exp_order) + \ 451cabdff1aSopenharmony_ci ((switch_bits + 1) << rice_order); \ 452cabdff1aSopenharmony_ci SKIP(re, gb, bits); \ 453cabdff1aSopenharmony_ci } else if (rice_order) { \ 454cabdff1aSopenharmony_ci SKIP_BITS(re, gb, q+1); \ 455cabdff1aSopenharmony_ci val = (q << rice_order) + SHOW_UBITS(re, gb, rice_order); \ 456cabdff1aSopenharmony_ci SKIP(re, gb, rice_order); \ 457cabdff1aSopenharmony_ci } else { \ 458cabdff1aSopenharmony_ci val = q; \ 459cabdff1aSopenharmony_ci SKIP(re, gb, q+1); \ 460cabdff1aSopenharmony_ci } \ 461cabdff1aSopenharmony_ci } while (0) 462cabdff1aSopenharmony_ci 463cabdff1aSopenharmony_ci#define TOSIGNED(x) (((x) >> 1) ^ (-((x) & 1))) 464cabdff1aSopenharmony_ci 465cabdff1aSopenharmony_ci#define FIRST_DC_CB 0xB8 466cabdff1aSopenharmony_ci 467cabdff1aSopenharmony_cistatic const uint8_t dc_codebook[7] = { 0x04, 0x28, 0x28, 0x4D, 0x4D, 0x70, 0x70}; 468cabdff1aSopenharmony_ci 469cabdff1aSopenharmony_cistatic av_always_inline int decode_dc_coeffs(GetBitContext *gb, int16_t *out, 470cabdff1aSopenharmony_ci int blocks_per_slice) 471cabdff1aSopenharmony_ci{ 472cabdff1aSopenharmony_ci int16_t prev_dc; 473cabdff1aSopenharmony_ci int code, i, sign; 474cabdff1aSopenharmony_ci 475cabdff1aSopenharmony_ci OPEN_READER(re, gb); 476cabdff1aSopenharmony_ci 477cabdff1aSopenharmony_ci DECODE_CODEWORD(code, FIRST_DC_CB, LAST_SKIP_BITS); 478cabdff1aSopenharmony_ci prev_dc = TOSIGNED(code); 479cabdff1aSopenharmony_ci out[0] = prev_dc; 480cabdff1aSopenharmony_ci 481cabdff1aSopenharmony_ci out += 64; // dc coeff for the next block 482cabdff1aSopenharmony_ci 483cabdff1aSopenharmony_ci code = 5; 484cabdff1aSopenharmony_ci sign = 0; 485cabdff1aSopenharmony_ci for (i = 1; i < blocks_per_slice; i++, out += 64) { 486cabdff1aSopenharmony_ci DECODE_CODEWORD(code, dc_codebook[FFMIN(code, 6U)], LAST_SKIP_BITS); 487cabdff1aSopenharmony_ci if(code) sign ^= -(code & 1); 488cabdff1aSopenharmony_ci else sign = 0; 489cabdff1aSopenharmony_ci prev_dc += (((code + 1) >> 1) ^ sign) - sign; 490cabdff1aSopenharmony_ci out[0] = prev_dc; 491cabdff1aSopenharmony_ci } 492cabdff1aSopenharmony_ci CLOSE_READER(re, gb); 493cabdff1aSopenharmony_ci return 0; 494cabdff1aSopenharmony_ci} 495cabdff1aSopenharmony_ci 496cabdff1aSopenharmony_ci// adaptive codebook switching lut according to previous run/level values 497cabdff1aSopenharmony_cistatic const uint8_t run_to_cb[16] = { 0x06, 0x06, 0x05, 0x05, 0x04, 0x29, 0x29, 0x29, 0x29, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x4C }; 498cabdff1aSopenharmony_cistatic const uint8_t lev_to_cb[10] = { 0x04, 0x0A, 0x05, 0x06, 0x04, 0x28, 0x28, 0x28, 0x28, 0x4C }; 499cabdff1aSopenharmony_ci 500cabdff1aSopenharmony_cistatic av_always_inline int decode_ac_coeffs(AVCodecContext *avctx, GetBitContext *gb, 501cabdff1aSopenharmony_ci int16_t *out, int blocks_per_slice) 502cabdff1aSopenharmony_ci{ 503cabdff1aSopenharmony_ci ProresContext *ctx = avctx->priv_data; 504cabdff1aSopenharmony_ci int block_mask, sign; 505cabdff1aSopenharmony_ci unsigned pos, run, level; 506cabdff1aSopenharmony_ci int max_coeffs, i, bits_left; 507cabdff1aSopenharmony_ci int log2_block_count = av_log2(blocks_per_slice); 508cabdff1aSopenharmony_ci 509cabdff1aSopenharmony_ci OPEN_READER(re, gb); 510cabdff1aSopenharmony_ci UPDATE_CACHE(re, gb); \ 511cabdff1aSopenharmony_ci run = 4; 512cabdff1aSopenharmony_ci level = 2; 513cabdff1aSopenharmony_ci 514cabdff1aSopenharmony_ci max_coeffs = 64 << log2_block_count; 515cabdff1aSopenharmony_ci block_mask = blocks_per_slice - 1; 516cabdff1aSopenharmony_ci 517cabdff1aSopenharmony_ci for (pos = block_mask;;) { 518cabdff1aSopenharmony_ci bits_left = gb->size_in_bits - re_index; 519cabdff1aSopenharmony_ci if (!bits_left || (bits_left < 32 && !SHOW_UBITS(re, gb, bits_left))) 520cabdff1aSopenharmony_ci break; 521cabdff1aSopenharmony_ci 522cabdff1aSopenharmony_ci DECODE_CODEWORD(run, run_to_cb[FFMIN(run, 15)], LAST_SKIP_BITS); 523cabdff1aSopenharmony_ci pos += run + 1; 524cabdff1aSopenharmony_ci if (pos >= max_coeffs) { 525cabdff1aSopenharmony_ci av_log(avctx, AV_LOG_ERROR, "ac tex damaged %d, %d\n", pos, max_coeffs); 526cabdff1aSopenharmony_ci return AVERROR_INVALIDDATA; 527cabdff1aSopenharmony_ci } 528cabdff1aSopenharmony_ci 529cabdff1aSopenharmony_ci DECODE_CODEWORD(level, lev_to_cb[FFMIN(level, 9)], SKIP_BITS); 530cabdff1aSopenharmony_ci level += 1; 531cabdff1aSopenharmony_ci 532cabdff1aSopenharmony_ci i = pos >> log2_block_count; 533cabdff1aSopenharmony_ci 534cabdff1aSopenharmony_ci sign = SHOW_SBITS(re, gb, 1); 535cabdff1aSopenharmony_ci SKIP_BITS(re, gb, 1); 536cabdff1aSopenharmony_ci out[((pos & block_mask) << 6) + ctx->scan[i]] = ((level ^ sign) - sign); 537cabdff1aSopenharmony_ci } 538cabdff1aSopenharmony_ci 539cabdff1aSopenharmony_ci CLOSE_READER(re, gb); 540cabdff1aSopenharmony_ci return 0; 541cabdff1aSopenharmony_ci} 542cabdff1aSopenharmony_ci 543cabdff1aSopenharmony_cistatic int decode_slice_luma(AVCodecContext *avctx, SliceContext *slice, 544cabdff1aSopenharmony_ci uint16_t *dst, int dst_stride, 545cabdff1aSopenharmony_ci const uint8_t *buf, unsigned buf_size, 546cabdff1aSopenharmony_ci const int16_t *qmat) 547cabdff1aSopenharmony_ci{ 548cabdff1aSopenharmony_ci ProresContext *ctx = avctx->priv_data; 549cabdff1aSopenharmony_ci LOCAL_ALIGNED_32(int16_t, blocks, [8*4*64]); 550cabdff1aSopenharmony_ci int16_t *block; 551cabdff1aSopenharmony_ci GetBitContext gb; 552cabdff1aSopenharmony_ci int i, blocks_per_slice = slice->mb_count<<2; 553cabdff1aSopenharmony_ci int ret; 554cabdff1aSopenharmony_ci 555cabdff1aSopenharmony_ci for (i = 0; i < blocks_per_slice; i++) 556cabdff1aSopenharmony_ci ctx->bdsp.clear_block(blocks+(i<<6)); 557cabdff1aSopenharmony_ci 558cabdff1aSopenharmony_ci init_get_bits(&gb, buf, buf_size << 3); 559cabdff1aSopenharmony_ci 560cabdff1aSopenharmony_ci if ((ret = decode_dc_coeffs(&gb, blocks, blocks_per_slice)) < 0) 561cabdff1aSopenharmony_ci return ret; 562cabdff1aSopenharmony_ci if ((ret = decode_ac_coeffs(avctx, &gb, blocks, blocks_per_slice)) < 0) 563cabdff1aSopenharmony_ci return ret; 564cabdff1aSopenharmony_ci 565cabdff1aSopenharmony_ci block = blocks; 566cabdff1aSopenharmony_ci for (i = 0; i < slice->mb_count; i++) { 567cabdff1aSopenharmony_ci ctx->prodsp.idct_put(dst, dst_stride, block+(0<<6), qmat); 568cabdff1aSopenharmony_ci ctx->prodsp.idct_put(dst +8, dst_stride, block+(1<<6), qmat); 569cabdff1aSopenharmony_ci ctx->prodsp.idct_put(dst+4*dst_stride , dst_stride, block+(2<<6), qmat); 570cabdff1aSopenharmony_ci ctx->prodsp.idct_put(dst+4*dst_stride+8, dst_stride, block+(3<<6), qmat); 571cabdff1aSopenharmony_ci block += 4*64; 572cabdff1aSopenharmony_ci dst += 16; 573cabdff1aSopenharmony_ci } 574cabdff1aSopenharmony_ci return 0; 575cabdff1aSopenharmony_ci} 576cabdff1aSopenharmony_ci 577cabdff1aSopenharmony_cistatic int decode_slice_chroma(AVCodecContext *avctx, SliceContext *slice, 578cabdff1aSopenharmony_ci uint16_t *dst, int dst_stride, 579cabdff1aSopenharmony_ci const uint8_t *buf, unsigned buf_size, 580cabdff1aSopenharmony_ci const int16_t *qmat, int log2_blocks_per_mb) 581cabdff1aSopenharmony_ci{ 582cabdff1aSopenharmony_ci ProresContext *ctx = avctx->priv_data; 583cabdff1aSopenharmony_ci LOCAL_ALIGNED_32(int16_t, blocks, [8*4*64]); 584cabdff1aSopenharmony_ci int16_t *block; 585cabdff1aSopenharmony_ci GetBitContext gb; 586cabdff1aSopenharmony_ci int i, j, blocks_per_slice = slice->mb_count << log2_blocks_per_mb; 587cabdff1aSopenharmony_ci int ret; 588cabdff1aSopenharmony_ci 589cabdff1aSopenharmony_ci for (i = 0; i < blocks_per_slice; i++) 590cabdff1aSopenharmony_ci ctx->bdsp.clear_block(blocks+(i<<6)); 591cabdff1aSopenharmony_ci 592cabdff1aSopenharmony_ci init_get_bits(&gb, buf, buf_size << 3); 593cabdff1aSopenharmony_ci 594cabdff1aSopenharmony_ci if ((ret = decode_dc_coeffs(&gb, blocks, blocks_per_slice)) < 0) 595cabdff1aSopenharmony_ci return ret; 596cabdff1aSopenharmony_ci if ((ret = decode_ac_coeffs(avctx, &gb, blocks, blocks_per_slice)) < 0) 597cabdff1aSopenharmony_ci return ret; 598cabdff1aSopenharmony_ci 599cabdff1aSopenharmony_ci block = blocks; 600cabdff1aSopenharmony_ci for (i = 0; i < slice->mb_count; i++) { 601cabdff1aSopenharmony_ci for (j = 0; j < log2_blocks_per_mb; j++) { 602cabdff1aSopenharmony_ci ctx->prodsp.idct_put(dst, dst_stride, block+(0<<6), qmat); 603cabdff1aSopenharmony_ci ctx->prodsp.idct_put(dst+4*dst_stride, dst_stride, block+(1<<6), qmat); 604cabdff1aSopenharmony_ci block += 2*64; 605cabdff1aSopenharmony_ci dst += 8; 606cabdff1aSopenharmony_ci } 607cabdff1aSopenharmony_ci } 608cabdff1aSopenharmony_ci return 0; 609cabdff1aSopenharmony_ci} 610cabdff1aSopenharmony_ci 611cabdff1aSopenharmony_ci/** 612cabdff1aSopenharmony_ci * Decode alpha slice plane. 613cabdff1aSopenharmony_ci */ 614cabdff1aSopenharmony_cistatic void decode_slice_alpha(ProresContext *ctx, 615cabdff1aSopenharmony_ci uint16_t *dst, int dst_stride, 616cabdff1aSopenharmony_ci const uint8_t *buf, int buf_size, 617cabdff1aSopenharmony_ci int blocks_per_slice) 618cabdff1aSopenharmony_ci{ 619cabdff1aSopenharmony_ci GetBitContext gb; 620cabdff1aSopenharmony_ci int i; 621cabdff1aSopenharmony_ci LOCAL_ALIGNED_32(int16_t, blocks, [8*4*64]); 622cabdff1aSopenharmony_ci int16_t *block; 623cabdff1aSopenharmony_ci 624cabdff1aSopenharmony_ci for (i = 0; i < blocks_per_slice<<2; i++) 625cabdff1aSopenharmony_ci ctx->bdsp.clear_block(blocks+(i<<6)); 626cabdff1aSopenharmony_ci 627cabdff1aSopenharmony_ci init_get_bits(&gb, buf, buf_size << 3); 628cabdff1aSopenharmony_ci 629cabdff1aSopenharmony_ci if (ctx->alpha_info == 2) { 630cabdff1aSopenharmony_ci ctx->unpack_alpha(&gb, blocks, blocks_per_slice * 4 * 64, 16); 631cabdff1aSopenharmony_ci } else { 632cabdff1aSopenharmony_ci ctx->unpack_alpha(&gb, blocks, blocks_per_slice * 4 * 64, 8); 633cabdff1aSopenharmony_ci } 634cabdff1aSopenharmony_ci 635cabdff1aSopenharmony_ci block = blocks; 636cabdff1aSopenharmony_ci 637cabdff1aSopenharmony_ci for (i = 0; i < 16; i++) { 638cabdff1aSopenharmony_ci memcpy(dst, block, 16 * blocks_per_slice * sizeof(*dst)); 639cabdff1aSopenharmony_ci dst += dst_stride >> 1; 640cabdff1aSopenharmony_ci block += 16 * blocks_per_slice; 641cabdff1aSopenharmony_ci } 642cabdff1aSopenharmony_ci} 643cabdff1aSopenharmony_ci 644cabdff1aSopenharmony_cistatic int decode_slice_thread(AVCodecContext *avctx, void *arg, int jobnr, int threadnr) 645cabdff1aSopenharmony_ci{ 646cabdff1aSopenharmony_ci ProresContext *ctx = avctx->priv_data; 647cabdff1aSopenharmony_ci SliceContext *slice = &ctx->slices[jobnr]; 648cabdff1aSopenharmony_ci const uint8_t *buf = slice->data; 649cabdff1aSopenharmony_ci AVFrame *pic = ctx->frame; 650cabdff1aSopenharmony_ci int i, hdr_size, qscale, log2_chroma_blocks_per_mb; 651cabdff1aSopenharmony_ci int luma_stride, chroma_stride; 652cabdff1aSopenharmony_ci int y_data_size, u_data_size, v_data_size, a_data_size, offset; 653cabdff1aSopenharmony_ci uint8_t *dest_y, *dest_u, *dest_v; 654cabdff1aSopenharmony_ci LOCAL_ALIGNED_16(int16_t, qmat_luma_scaled, [64]); 655cabdff1aSopenharmony_ci LOCAL_ALIGNED_16(int16_t, qmat_chroma_scaled,[64]); 656cabdff1aSopenharmony_ci int mb_x_shift; 657cabdff1aSopenharmony_ci int ret; 658cabdff1aSopenharmony_ci uint16_t val_no_chroma; 659cabdff1aSopenharmony_ci 660cabdff1aSopenharmony_ci slice->ret = -1; 661cabdff1aSopenharmony_ci //av_log(avctx, AV_LOG_INFO, "slice %d mb width %d mb x %d y %d\n", 662cabdff1aSopenharmony_ci // jobnr, slice->mb_count, slice->mb_x, slice->mb_y); 663cabdff1aSopenharmony_ci 664cabdff1aSopenharmony_ci // slice header 665cabdff1aSopenharmony_ci hdr_size = buf[0] >> 3; 666cabdff1aSopenharmony_ci qscale = av_clip(buf[1], 1, 224); 667cabdff1aSopenharmony_ci qscale = qscale > 128 ? qscale - 96 << 2: qscale; 668cabdff1aSopenharmony_ci y_data_size = AV_RB16(buf + 2); 669cabdff1aSopenharmony_ci u_data_size = AV_RB16(buf + 4); 670cabdff1aSopenharmony_ci v_data_size = slice->data_size - y_data_size - u_data_size - hdr_size; 671cabdff1aSopenharmony_ci if (hdr_size > 7) v_data_size = AV_RB16(buf + 6); 672cabdff1aSopenharmony_ci a_data_size = slice->data_size - y_data_size - u_data_size - 673cabdff1aSopenharmony_ci v_data_size - hdr_size; 674cabdff1aSopenharmony_ci 675cabdff1aSopenharmony_ci if (y_data_size < 0 || u_data_size < 0 || v_data_size < 0 676cabdff1aSopenharmony_ci || hdr_size+y_data_size+u_data_size+v_data_size > slice->data_size){ 677cabdff1aSopenharmony_ci av_log(avctx, AV_LOG_ERROR, "invalid plane data size\n"); 678cabdff1aSopenharmony_ci return AVERROR_INVALIDDATA; 679cabdff1aSopenharmony_ci } 680cabdff1aSopenharmony_ci 681cabdff1aSopenharmony_ci buf += hdr_size; 682cabdff1aSopenharmony_ci 683cabdff1aSopenharmony_ci for (i = 0; i < 64; i++) { 684cabdff1aSopenharmony_ci qmat_luma_scaled [i] = ctx->qmat_luma [i] * qscale; 685cabdff1aSopenharmony_ci qmat_chroma_scaled[i] = ctx->qmat_chroma[i] * qscale; 686cabdff1aSopenharmony_ci } 687cabdff1aSopenharmony_ci 688cabdff1aSopenharmony_ci if (ctx->frame_type == 0) { 689cabdff1aSopenharmony_ci luma_stride = pic->linesize[0]; 690cabdff1aSopenharmony_ci chroma_stride = pic->linesize[1]; 691cabdff1aSopenharmony_ci } else { 692cabdff1aSopenharmony_ci luma_stride = pic->linesize[0] << 1; 693cabdff1aSopenharmony_ci chroma_stride = pic->linesize[1] << 1; 694cabdff1aSopenharmony_ci } 695cabdff1aSopenharmony_ci 696cabdff1aSopenharmony_ci if (avctx->pix_fmt == AV_PIX_FMT_YUV444P10 || avctx->pix_fmt == AV_PIX_FMT_YUVA444P10 || 697cabdff1aSopenharmony_ci avctx->pix_fmt == AV_PIX_FMT_YUV444P12 || avctx->pix_fmt == AV_PIX_FMT_YUVA444P12) { 698cabdff1aSopenharmony_ci mb_x_shift = 5; 699cabdff1aSopenharmony_ci log2_chroma_blocks_per_mb = 2; 700cabdff1aSopenharmony_ci } else { 701cabdff1aSopenharmony_ci mb_x_shift = 4; 702cabdff1aSopenharmony_ci log2_chroma_blocks_per_mb = 1; 703cabdff1aSopenharmony_ci } 704cabdff1aSopenharmony_ci 705cabdff1aSopenharmony_ci offset = (slice->mb_y << 4) * luma_stride + (slice->mb_x << 5); 706cabdff1aSopenharmony_ci dest_y = pic->data[0] + offset; 707cabdff1aSopenharmony_ci dest_u = pic->data[1] + (slice->mb_y << 4) * chroma_stride + (slice->mb_x << mb_x_shift); 708cabdff1aSopenharmony_ci dest_v = pic->data[2] + (slice->mb_y << 4) * chroma_stride + (slice->mb_x << mb_x_shift); 709cabdff1aSopenharmony_ci 710cabdff1aSopenharmony_ci if (ctx->frame_type && ctx->first_field ^ ctx->frame->top_field_first) { 711cabdff1aSopenharmony_ci dest_y += pic->linesize[0]; 712cabdff1aSopenharmony_ci dest_u += pic->linesize[1]; 713cabdff1aSopenharmony_ci dest_v += pic->linesize[2]; 714cabdff1aSopenharmony_ci offset += pic->linesize[3]; 715cabdff1aSopenharmony_ci } 716cabdff1aSopenharmony_ci 717cabdff1aSopenharmony_ci ret = decode_slice_luma(avctx, slice, (uint16_t*)dest_y, luma_stride, 718cabdff1aSopenharmony_ci buf, y_data_size, qmat_luma_scaled); 719cabdff1aSopenharmony_ci if (ret < 0) 720cabdff1aSopenharmony_ci return ret; 721cabdff1aSopenharmony_ci 722cabdff1aSopenharmony_ci if (!(avctx->flags & AV_CODEC_FLAG_GRAY) && (u_data_size + v_data_size) > 0) { 723cabdff1aSopenharmony_ci ret = decode_slice_chroma(avctx, slice, (uint16_t*)dest_u, chroma_stride, 724cabdff1aSopenharmony_ci buf + y_data_size, u_data_size, 725cabdff1aSopenharmony_ci qmat_chroma_scaled, log2_chroma_blocks_per_mb); 726cabdff1aSopenharmony_ci if (ret < 0) 727cabdff1aSopenharmony_ci return ret; 728cabdff1aSopenharmony_ci 729cabdff1aSopenharmony_ci ret = decode_slice_chroma(avctx, slice, (uint16_t*)dest_v, chroma_stride, 730cabdff1aSopenharmony_ci buf + y_data_size + u_data_size, v_data_size, 731cabdff1aSopenharmony_ci qmat_chroma_scaled, log2_chroma_blocks_per_mb); 732cabdff1aSopenharmony_ci if (ret < 0) 733cabdff1aSopenharmony_ci return ret; 734cabdff1aSopenharmony_ci } 735cabdff1aSopenharmony_ci else { 736cabdff1aSopenharmony_ci size_t mb_max_x = slice->mb_count << (mb_x_shift - 1); 737cabdff1aSopenharmony_ci size_t i, j; 738cabdff1aSopenharmony_ci if (avctx->bits_per_raw_sample == 10) { 739cabdff1aSopenharmony_ci val_no_chroma = 511; 740cabdff1aSopenharmony_ci } else { /* 12b */ 741cabdff1aSopenharmony_ci val_no_chroma = 511 * 4; 742cabdff1aSopenharmony_ci } 743cabdff1aSopenharmony_ci for (i = 0; i < 16; ++i) 744cabdff1aSopenharmony_ci for (j = 0; j < mb_max_x; ++j) { 745cabdff1aSopenharmony_ci *(uint16_t*)(dest_u + (i * chroma_stride) + (j << 1)) = val_no_chroma; 746cabdff1aSopenharmony_ci *(uint16_t*)(dest_v + (i * chroma_stride) + (j << 1)) = val_no_chroma; 747cabdff1aSopenharmony_ci } 748cabdff1aSopenharmony_ci } 749cabdff1aSopenharmony_ci 750cabdff1aSopenharmony_ci /* decode alpha plane if available */ 751cabdff1aSopenharmony_ci if (ctx->alpha_info && pic->data[3] && a_data_size) { 752cabdff1aSopenharmony_ci uint8_t *dest_a = pic->data[3] + offset; 753cabdff1aSopenharmony_ci decode_slice_alpha(ctx, (uint16_t*)dest_a, luma_stride, 754cabdff1aSopenharmony_ci buf + y_data_size + u_data_size + v_data_size, 755cabdff1aSopenharmony_ci a_data_size, slice->mb_count); 756cabdff1aSopenharmony_ci } 757cabdff1aSopenharmony_ci 758cabdff1aSopenharmony_ci slice->ret = 0; 759cabdff1aSopenharmony_ci return 0; 760cabdff1aSopenharmony_ci} 761cabdff1aSopenharmony_ci 762cabdff1aSopenharmony_cistatic int decode_picture(AVCodecContext *avctx) 763cabdff1aSopenharmony_ci{ 764cabdff1aSopenharmony_ci ProresContext *ctx = avctx->priv_data; 765cabdff1aSopenharmony_ci int i; 766cabdff1aSopenharmony_ci int error = 0; 767cabdff1aSopenharmony_ci 768cabdff1aSopenharmony_ci avctx->execute2(avctx, decode_slice_thread, NULL, NULL, ctx->slice_count); 769cabdff1aSopenharmony_ci 770cabdff1aSopenharmony_ci for (i = 0; i < ctx->slice_count; i++) 771cabdff1aSopenharmony_ci error += ctx->slices[i].ret < 0; 772cabdff1aSopenharmony_ci 773cabdff1aSopenharmony_ci if (error) 774cabdff1aSopenharmony_ci ctx->frame->decode_error_flags = FF_DECODE_ERROR_INVALID_BITSTREAM; 775cabdff1aSopenharmony_ci if (error < ctx->slice_count) 776cabdff1aSopenharmony_ci return 0; 777cabdff1aSopenharmony_ci 778cabdff1aSopenharmony_ci return ctx->slices[0].ret; 779cabdff1aSopenharmony_ci} 780cabdff1aSopenharmony_ci 781cabdff1aSopenharmony_cistatic int decode_frame(AVCodecContext *avctx, AVFrame *frame, 782cabdff1aSopenharmony_ci int *got_frame, AVPacket *avpkt) 783cabdff1aSopenharmony_ci{ 784cabdff1aSopenharmony_ci ProresContext *ctx = avctx->priv_data; 785cabdff1aSopenharmony_ci const uint8_t *buf = avpkt->data; 786cabdff1aSopenharmony_ci int buf_size = avpkt->size; 787cabdff1aSopenharmony_ci int frame_hdr_size, pic_size, ret; 788cabdff1aSopenharmony_ci 789cabdff1aSopenharmony_ci if (buf_size < 28 || AV_RL32(buf + 4) != AV_RL32("icpf")) { 790cabdff1aSopenharmony_ci av_log(avctx, AV_LOG_ERROR, "invalid frame header\n"); 791cabdff1aSopenharmony_ci return AVERROR_INVALIDDATA; 792cabdff1aSopenharmony_ci } 793cabdff1aSopenharmony_ci 794cabdff1aSopenharmony_ci ctx->frame = frame; 795cabdff1aSopenharmony_ci ctx->frame->pict_type = AV_PICTURE_TYPE_I; 796cabdff1aSopenharmony_ci ctx->frame->key_frame = 1; 797cabdff1aSopenharmony_ci ctx->first_field = 1; 798cabdff1aSopenharmony_ci 799cabdff1aSopenharmony_ci buf += 8; 800cabdff1aSopenharmony_ci buf_size -= 8; 801cabdff1aSopenharmony_ci 802cabdff1aSopenharmony_ci frame_hdr_size = decode_frame_header(ctx, buf, buf_size, avctx); 803cabdff1aSopenharmony_ci if (frame_hdr_size < 0) 804cabdff1aSopenharmony_ci return frame_hdr_size; 805cabdff1aSopenharmony_ci 806cabdff1aSopenharmony_ci buf += frame_hdr_size; 807cabdff1aSopenharmony_ci buf_size -= frame_hdr_size; 808cabdff1aSopenharmony_ci 809cabdff1aSopenharmony_ci if ((ret = ff_thread_get_buffer(avctx, frame, 0)) < 0) 810cabdff1aSopenharmony_ci return ret; 811cabdff1aSopenharmony_ci ff_thread_finish_setup(avctx); 812cabdff1aSopenharmony_ci 813cabdff1aSopenharmony_ci if (avctx->hwaccel) { 814cabdff1aSopenharmony_ci ret = avctx->hwaccel->start_frame(avctx, NULL, 0); 815cabdff1aSopenharmony_ci if (ret < 0) 816cabdff1aSopenharmony_ci return ret; 817cabdff1aSopenharmony_ci ret = avctx->hwaccel->decode_slice(avctx, avpkt->data, avpkt->size); 818cabdff1aSopenharmony_ci if (ret < 0) 819cabdff1aSopenharmony_ci return ret; 820cabdff1aSopenharmony_ci ret = avctx->hwaccel->end_frame(avctx); 821cabdff1aSopenharmony_ci if (ret < 0) 822cabdff1aSopenharmony_ci return ret; 823cabdff1aSopenharmony_ci goto finish; 824cabdff1aSopenharmony_ci } 825cabdff1aSopenharmony_ci 826cabdff1aSopenharmony_ci decode_picture: 827cabdff1aSopenharmony_ci pic_size = decode_picture_header(avctx, buf, buf_size); 828cabdff1aSopenharmony_ci if (pic_size < 0) { 829cabdff1aSopenharmony_ci av_log(avctx, AV_LOG_ERROR, "error decoding picture header\n"); 830cabdff1aSopenharmony_ci return pic_size; 831cabdff1aSopenharmony_ci } 832cabdff1aSopenharmony_ci 833cabdff1aSopenharmony_ci if ((ret = decode_picture(avctx)) < 0) { 834cabdff1aSopenharmony_ci av_log(avctx, AV_LOG_ERROR, "error decoding picture\n"); 835cabdff1aSopenharmony_ci return ret; 836cabdff1aSopenharmony_ci } 837cabdff1aSopenharmony_ci 838cabdff1aSopenharmony_ci buf += pic_size; 839cabdff1aSopenharmony_ci buf_size -= pic_size; 840cabdff1aSopenharmony_ci 841cabdff1aSopenharmony_ci if (ctx->frame_type && buf_size > 0 && ctx->first_field) { 842cabdff1aSopenharmony_ci ctx->first_field = 0; 843cabdff1aSopenharmony_ci goto decode_picture; 844cabdff1aSopenharmony_ci } 845cabdff1aSopenharmony_ci 846cabdff1aSopenharmony_cifinish: 847cabdff1aSopenharmony_ci *got_frame = 1; 848cabdff1aSopenharmony_ci 849cabdff1aSopenharmony_ci return avpkt->size; 850cabdff1aSopenharmony_ci} 851cabdff1aSopenharmony_ci 852cabdff1aSopenharmony_cistatic av_cold int decode_close(AVCodecContext *avctx) 853cabdff1aSopenharmony_ci{ 854cabdff1aSopenharmony_ci ProresContext *ctx = avctx->priv_data; 855cabdff1aSopenharmony_ci 856cabdff1aSopenharmony_ci av_freep(&ctx->slices); 857cabdff1aSopenharmony_ci 858cabdff1aSopenharmony_ci return 0; 859cabdff1aSopenharmony_ci} 860cabdff1aSopenharmony_ci 861cabdff1aSopenharmony_ci#if HAVE_THREADS 862cabdff1aSopenharmony_cistatic int update_thread_context(AVCodecContext *dst, const AVCodecContext *src) 863cabdff1aSopenharmony_ci{ 864cabdff1aSopenharmony_ci ProresContext *csrc = src->priv_data; 865cabdff1aSopenharmony_ci ProresContext *cdst = dst->priv_data; 866cabdff1aSopenharmony_ci 867cabdff1aSopenharmony_ci cdst->pix_fmt = csrc->pix_fmt; 868cabdff1aSopenharmony_ci 869cabdff1aSopenharmony_ci return 0; 870cabdff1aSopenharmony_ci} 871cabdff1aSopenharmony_ci#endif 872cabdff1aSopenharmony_ci 873cabdff1aSopenharmony_ciconst FFCodec ff_prores_decoder = { 874cabdff1aSopenharmony_ci .p.name = "prores", 875cabdff1aSopenharmony_ci .p.long_name = NULL_IF_CONFIG_SMALL("Apple ProRes (iCodec Pro)"), 876cabdff1aSopenharmony_ci .p.type = AVMEDIA_TYPE_VIDEO, 877cabdff1aSopenharmony_ci .p.id = AV_CODEC_ID_PRORES, 878cabdff1aSopenharmony_ci .priv_data_size = sizeof(ProresContext), 879cabdff1aSopenharmony_ci .init = decode_init, 880cabdff1aSopenharmony_ci .close = decode_close, 881cabdff1aSopenharmony_ci FF_CODEC_DECODE_CB(decode_frame), 882cabdff1aSopenharmony_ci .update_thread_context = ONLY_IF_THREADS_ENABLED(update_thread_context), 883cabdff1aSopenharmony_ci .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_SLICE_THREADS | AV_CODEC_CAP_FRAME_THREADS, 884cabdff1aSopenharmony_ci .p.profiles = NULL_IF_CONFIG_SMALL(ff_prores_profiles), 885cabdff1aSopenharmony_ci .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE, 886cabdff1aSopenharmony_ci .hw_configs = (const AVCodecHWConfigInternal *const []) { 887cabdff1aSopenharmony_ci#if CONFIG_PRORES_VIDEOTOOLBOX_HWACCEL 888cabdff1aSopenharmony_ci HWACCEL_VIDEOTOOLBOX(prores), 889cabdff1aSopenharmony_ci#endif 890cabdff1aSopenharmony_ci NULL 891cabdff1aSopenharmony_ci }, 892cabdff1aSopenharmony_ci}; 893