On Fri, Mar 20, 2020 at 02:31:05PM +0100, Paul B Mahol wrote: > Signed-off-by: Paul B Mahol <one...@gmail.com> > --- > configure | 1 + > libavcodec/Makefile | 1 + > libavcodec/allcodecs.c | 1 + > libavcodec/avcodec.h | 1 + > libavcodec/bink2.c | 869 ++++++++++++++++++++++++++++ > libavcodec/bink2f.c | 1125 ++++++++++++++++++++++++++++++++++++ > libavcodec/bink2g.c | 1197 +++++++++++++++++++++++++++++++++++++++ > libavcodec/codec_desc.c | 7 + > libavformat/bink.c | 3 +- > 9 files changed, 3203 insertions(+), 2 deletions(-) > create mode 100644 libavcodec/bink2.c > create mode 100644 libavcodec/bink2f.c > create mode 100644 libavcodec/bink2g.c
> +++ b/libavcodec/bink2.c > @@ -0,0 +1,869 @@ > +/* > + * Bink video 2 decoder > + * Copyright (c) 2014 Konstantin Shishkov > + * Copyright (c) 2019 Paul B Mahol > + * > + * This file is part of FFmpeg. > + * > +static void bink2f_predict_dc(Bink2Context *c, > + int is_luma, float mindc, float maxdc, > + int flags, float tdc[16]) > +{ > + float *LTdc = c->prev_dc[FFMAX(c->mb_pos - 1, 0)].dc[c->comp]; comp is only used for dc coeff predicition suggestion: pass comp value via stack > + float *Tdc = c->prev_dc[c->mb_pos].dc[c->comp]; > + float *Ldc = c->current_dc[FFMAX(c->mb_pos - 1, 0)].dc[c->comp]; > + float *dc = c->current_dc[c->mb_pos].dc[c->comp]; > + > + if (is_luma && (flags & 0x20) && (flags & 0x80)) { > + dc[0] = av_clipf((mindc < 0 ? 0 : 1024.f) + tdc[0], mindc, maxdc); > + dc[1] = av_clipf(dc[0] + tdc[1], mindc, maxdc); > + dc[2] = av_clipf(DC_MPRED2(dc[0], dc[1]) + tdc[2], mindc, maxdc); > + dc[3] = av_clipf(DC_MPRED(dc[0], dc[2], dc[1]) + tdc[3], mindc, > maxdc); > + dc[4] = av_clipf(DC_MPRED2(dc[1], dc[3]) + tdc[4], mindc, maxdc); > + dc[5] = av_clipf(dc[4] + tdc[5], mindc, maxdc); > + dc[6] = av_clipf(DC_MPRED(dc[1], dc[3], dc[4]) + tdc[6], mindc, > maxdc); > + dc[7] = av_clipf(DC_MPRED(dc[4], dc[6], dc[5]) + tdc[7], mindc, > maxdc); > + dc[8] = av_clipf(DC_MPRED2(dc[2], dc[3]) + tdc[8], mindc, maxdc); > + dc[9] = av_clipf(DC_MPRED(dc[2], dc[8], dc[3]) + tdc[9], mindc, > maxdc); > + dc[10] = av_clipf(DC_MPRED2(dc[8], dc[9]) + tdc[10], mindc, maxdc); > + dc[11] = av_clipf(DC_MPRED(dc[8], dc[10], dc[9]) + tdc[11], mindc, > maxdc); > + dc[12] = av_clipf(DC_MPRED(dc[3], dc[9], dc[6]) + tdc[12], mindc, > maxdc); > + dc[13] = av_clipf(DC_MPRED(dc[6], dc[12], dc[7]) + tdc[13], mindc, > maxdc); > + dc[14] = av_clipf(DC_MPRED(dc[9], dc[11], dc[12]) + tdc[14], mindc, > maxdc); > + dc[15] = av_clipf(DC_MPRED(dc[12], dc[14], dc[13]) + tdc[15], mindc, > maxdc); > + } else if (is_luma && (flags & 0x80)) { imho too many compound if expressions against is_luma and flags (i prefered the way you do this in bink2f_predict_mv) > +static int bink2f_decode_slice(Bink2Context *c, > + uint8_t *dst[4], int stride[4], > + uint8_t *src[4], int sstride[4], > + int is_kf, int start, int end) > +{ > + GetBitContext *gb = &c->gb; > + int w = c->avctx->width; > + int h = c->avctx->height; > + int flags, ret = 0; > + > + memset(c->prev_mv, 0, ((c->avctx->width + 31) / 32) * > sizeof(*c->prev_mv)); > + > + for (int y = start; y < end; y += 32) { > + unsigned y_cbp_intra = 0, u_cbp_intra = 0, v_cbp_intra = 0, > a_cbp_intra = 0; > + unsigned y_cbp_inter = 0, u_cbp_inter = 0, v_cbp_inter = 0, > a_cbp_inter = 0; > + int y_intra_q = 8, u_intra_q = 8, v_intra_q = 8, a_intra_q = 8; > + int y_inter_q = 8, u_inter_q = 8, v_inter_q = 8, a_inter_q = 8; > + > + memset(c->current_mv, 0, ((c->avctx->width + 31) / 32) * > sizeof(*c->current_mv)); > + > + for (int x = 0; x < c->avctx->width; x += 32) { > + MVectors mv = { 0 }; > + int type = is_kf ? INTRA_BLOCK : get_bits(gb, 2); > + > + c->mb_pos = x / 32; > + c->current_dc[c->mb_pos].block_type = type; > + flags = 0; > + if (y == start) > + flags |= 0x80; > + if (!x) > + flags |= 0x20; > + if (x == 32) > + flags |= 0x200; > + if (x + 32 >= c->avctx->width) > + flags |= 0x40; > + > + switch (type) { > + case INTRA_BLOCK: > + if (!(flags & 0xA0) && c->prev_dc[c->mb_pos - 1].block_type > != INTRA_BLOCK) { > + bink2f_average_luma (c, x -32, -32, dst[0], stride[0], > c->prev_dc[c->mb_pos - 1].dc[0]); > + case MOTION_BLOCK: > + bink2f_decode_mv(c, gb, x, y, flags, &mv); > + bink2f_predict_mv(c, x, y, flags, mv); > + c->comp = 0; > + ret = bink2f_mcompensate_luma(c, x, y, > + dst[0], stride[0], > + src[0], sstride[0], > + w, h); > + if (ret < 0) > + goto fail; > + c->comp = 1; > + ret = bink2f_mcompensate_chroma(c, x/2, y/2, > + dst[2], stride[2], > + src[2], sstride[2], > + w/2, h/2); > + if (ret < 0) > + goto fail; > + c->comp = 2; > + ret = bink2f_mcompensate_chroma(c, x/2, y/2, > + dst[1], stride[1], > + src[1], sstride[1], > + w/2, h/2); c->comp required for MOTION_BLOCK? > + default: > + return AVERROR_INVALIDDATA; use goto fail. decoder may have already invoked simd functions. > + } > + } > + > + dst[0] += stride[0] * 32; > + dst[1] += stride[1] * 16; > + dst[2] += stride[2] * 16; > + dst[3] += stride[3] * 32; > + > + FFSWAP(MVPredict *, c->current_mv, c->prev_mv); > + FFSWAP(DCPredict *, c->current_dc, c->prev_dc); > + } > +fail: > + emms_c(); > + > + return ret; > +} > --- /dev/null > +++ b/libavcodec/bink2g.c > @@ -0,0 +1,1197 @@ > +/* > +static void bink2g_predict_dc(Bink2Context *c, > + int is_luma, int mindc, int maxdc, > + int flags, int tdc[16]) > +{ see bink2f_predict_dc comments > +static void bink2g_decode_dc(Bink2Context *c, GetBitContext *gb, int *dc, > + int is_luma, int q, int mindc, int maxdc, > + int flags) > +{ > + const int num_dc = is_luma ? 16 : 4; > + int tdc[16]; > + int pat; > + > + q = FFMAX(q, 8); > + pat = bink2g_dc_pat[q]; > + > + memset(tdc, 0, sizeof(tdc)); tdc[16] = { 0 } like you did elsewhere > + if (get_bits1(gb)) { > + for (int i = 0; i < num_dc; i++) { > + int cnt = get_unary(gb, 0, 12); > + > + if (cnt > 3) > + cnt = (1 << (cnt - 3)) + get_bits(gb, cnt - 3) + 2; > + if (cnt && get_bits1(gb)) > + cnt = -cnt; > + tdc[i] = (cnt * pat + 0x200) >> 10; > + } > + } > + > + bink2g_predict_dc(c, is_luma, mindc, maxdc, flags, tdc); > +} > + > +static int bink2g_decode_ac(GetBitContext *gb, const uint8_t scan[64], > + int16_t block[4][64], unsigned cbp, > + int q, const uint16_t qmat[4][64]) > +{ > + int idx, next, val, skip; > + VLC *skip_vlc; > + > + for (int i = 0; i < 4; i++) > + memset(block[i], 0, sizeof(int16_t) * 64); sizeof(**block) > + if ((cbp & 0xf) == 0) > + return 0; > + can fold memset into loop below > + skip_vlc = &bink2g_ac_skip0_vlc; > + if (cbp & 0xffff0000) > + skip_vlc = &bink2g_ac_skip1_vlc; > + > + for (int i = 0; i < 4; i++, cbp >>= 1) { > + if (!(cbp & 1)) > + continue; > + > +static int bink2g_decode_slice(Bink2Context *c, > + uint8_t *dst[4], int stride[4], > + uint8_t *src[4], int sstride[4], > + int is_kf, int start, int end) > +{ > + GetBitContext *gb = &c->gb; > + int w = c->avctx->width; > + int h = c->avctx->height; > + int ret = 0, dq, flags; > + > + memset(c->prev_q, 0, ((c->avctx->width + 31) / 32) * sizeof(*c->prev_q)); > + memset(c->prev_mv, 0, ((c->avctx->width + 31) / 32) * > sizeof(*c->prev_mv)); > + > + for (int y = start; y < end; y += 32) { > + int types_lru[4] = { MOTION_BLOCK, RESIDUE_BLOCK, SKIP_BLOCK, > INTRA_BLOCK }; > + unsigned y_cbp_intra = 0, u_cbp_intra = 0, v_cbp_intra = 0, > a_cbp_intra = 0; > + unsigned y_cbp_inter = 0, u_cbp_inter = 0, v_cbp_inter = 0, > a_cbp_inter = 0; > + > + memset(c->current_q, 0, ((c->avctx->width + 31) / 32) * > sizeof(*c->current_q)); > + memset(c->current_mv, 0, ((c->avctx->width + 31) / 32) * > sizeof(*c->current_mv)); > + > + for (int x = 0; x < c->avctx->width; x += 32) { > + int type = is_kf ? INTRA_BLOCK : bink2g_get_type(gb, types_lru); > + int8_t *intra_q = &c->current_q[x / 32].intra_q; > + int8_t *inter_q = &c->current_q[x / 32].inter_q; > + MVectors mv = { 0 }; > + > + c->mb_pos = x / 32; > + c->current_idc[c->mb_pos].block_type = type; > + flags = 0; > + if (y == start) > + flags |= 0x80; > + if (!x) > + flags |= 0x20; > + if (x == 32) > + flags |= 0x200; > + if (x + 32 >= c->avctx->width) > + flags |= 0x40; > + switch (type) { > + case INTRA_BLOCK: > + if (!(flags & 0xA0) && c->prev_idc[c->mb_pos - 1].block_type > != INTRA_BLOCK) { > + bink2g_average_luma (c, x -32, -32, dst[0], stride[0], > c->prev_idc[c->mb_pos - 1].dc[0]); > + bink2g_average_chroma(c, x/2-16, -16, dst[2], stride[2], > c->prev_idc[c->mb_pos - 1].dc[1]); > + default: > + return AVERROR_INVALIDDATA; goto fail > + } > + } > + > + dst[0] += stride[0] * 32; > + dst[1] += stride[1] * 16; > + dst[2] += stride[2] * 16; > + dst[3] += stride[3] * 32; > + > + FFSWAP(MVPredict *, c->current_mv, c->prev_mv); > + FFSWAP(QuantPredict *, c->current_q, c->prev_q); > + FFSWAP(DCIPredict *, c->current_idc, c->prev_idc); > + } > +fail: > + emms_c(); > + > + return ret; > +} -- Peter (A907 E02F A6E5 0CD2 34CD 20D2 6760 79C5 AC40 DD6B)
signature.asc
Description: PGP signature
_______________________________________________ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".