From patchwork Tue Aug 22 23:59:13 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ilia X-Patchwork-Id: 4800 Delivered-To: ffmpegpatchwork@gmail.com Received: by 10.2.137.29 with SMTP id o29csp1371312jaj; Tue, 22 Aug 2017 17:05:25 -0700 (PDT) X-Received: by 10.28.101.139 with SMTP id z133mr667181wmb.160.1503446725864; Tue, 22 Aug 2017 17:05:25 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1503446725; cv=none; d=google.com; s=arc-20160816; b=hHbJrMZoS64/EkzynhRW1vpWJXsG2XPTS09HY8VbsVVYmdYPKqIAX2c2qUSZx85uWC nNiC+/3zx2n9GTFXpFMjtSHkwjkf4GncSgXc32m6u/GWDRffyNQJ6+budxRP1Yhoyfta U2k8oKN1toZVymUCG+KTKptUzwKaZCwPQR4R/GDUVNPPHR+PvGiv5zCydALgN2hVBnEd msbW+l4irdszKwlNDLgQlVxrh8ZrhgSA+B6/dmHR+bkwfYZenDFvugNUo0buBJyTtz46 DdCYBJor/kEUFSZcRtxJGbR5IIOyXQcHRImJxywPg4/1gl18sDnYUkYnQ2bCdR2otHPN QAQA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:content-transfer-encoding:mime-version:cc:reply-to :list-subscribe:list-help:list-post:list-archive:list-unsubscribe :list-id:precedence:subject:message-id:date:to:from:dkim-signature :delivered-to:arc-authentication-results; bh=s9t46N3Iig2Byg6uJ6Komi/ppPO1zrdZykJzRGbX+gk=; b=BLjjTuyCYtn+ifWTeST966yuAYrO1W+FcY+9ODYgq2ggODQSoS2qA206fPOuzyn4yU 6VJW45XMEFXck+us6trTf1poKpqllZAzgLjIk6Qi1XhEcD1U5LNWHQdULKyUXjLTURA4 D2HkFJUtBTICfIfhsT3hKaE/rs+SVm7lYLOkT/5EFtWEI+wsbx+JJX+DrCmBJqwmqdIZ CLCTti5ibQvY5Lpsf3tnUZwFtzrsIceXdUqB0ADGFmuRP/2BOhLf0vf85sAjfO8kSZZq BkvjUN8xhb6+mVTKvXx5YzsjRe0aWklzsNbFfuT47frgQshQI3ojzn/Vg+sm7gHgMFXC S2WQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=neutral (body hash did not verify) header.i=@gmail.com header.s=20161025 header.b=o8aLk+0d; spf=pass (google.com: domain of ffmpeg-devel-bounces@ffmpeg.org designates 79.124.17.100 as permitted sender) smtp.mailfrom=ffmpeg-devel-bounces@ffmpeg.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=gmail.com Return-Path: Received: from ffbox0-bg.mplayerhq.hu (ffbox0-bg.ffmpeg.org. [79.124.17.100]) by mx.google.com with ESMTP id f17si317088wmh.89.2017.08.22.17.05.24; Tue, 22 Aug 2017 17:05:25 -0700 (PDT) Received-SPF: pass (google.com: domain of ffmpeg-devel-bounces@ffmpeg.org designates 79.124.17.100 as permitted sender) client-ip=79.124.17.100; Authentication-Results: mx.google.com; dkim=neutral (body hash did not verify) header.i=@gmail.com header.s=20161025 header.b=o8aLk+0d; spf=pass (google.com: domain of ffmpeg-devel-bounces@ffmpeg.org designates 79.124.17.100 as permitted sender) smtp.mailfrom=ffmpeg-devel-bounces@ffmpeg.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=gmail.com Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id B77A0689C90; Wed, 23 Aug 2017 03:05:15 +0300 (EEST) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from mail-lf0-f67.google.com (mail-lf0-f67.google.com [209.85.215.67]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id BDE3C688324 for ; Wed, 23 Aug 2017 03:05:08 +0300 (EEST) Received: by mail-lf0-f67.google.com with SMTP id c189so135455lfe.3 for ; Tue, 22 Aug 2017 17:05:16 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id; bh=ZV9V0I3gTpWArUzasKgnKQ54fjXYQWEthKNrWqUQXzQ=; b=o8aLk+0dLWEx9RUtn3OmDeICWnpmXOjfp5kaK71zBjQOSqud/22hDORjlBOwQ6gz98 mqRRy+P9pNXCwllv4NAtSVteEGh4PFIoskmqaeC3uV10jCH28pouXkbzo4RFpIserKep QdwVobqOeZcPRcu5JU5FYGiqw/R/NUfLpg2rrByOXHNZWitXZ//qHL0Z1hpeZFmVaSRF FGqx6Fqlupunq37yTbmWfTQpApQQvfWKgzSL7gPXPYv3djDZyK66mvgjOBOzOZpjdPGv Fbp4fcgcZI6WTuTPU7anglkQs+/Dr8qdaYPzQjw62Uo0pYI/dW0Ik6lJ4UMUO0Kmm6mZ Q54w== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id; bh=ZV9V0I3gTpWArUzasKgnKQ54fjXYQWEthKNrWqUQXzQ=; b=IU+rWIR0PGXmNEsz5HPhI/r71/2Bw26LB3KN2iDVKmpm8zlysnU2v2RDcBR/x8HYd9 t/y9+Q1vC/aPRwrEHK01EtOmQIE9uPwM9tSSNQMHZkJdxUC5ocVWh/2t73AsJRgbmyw1 b1Bzl8juCbXhvRkmhwIg1UKiInPkCnDPAP6q74cEPSy+5GvmqxfAhvWkRks0po/SETYA YG8LvWiMRkkFaF2jAZezU7PwObQJM97xHu+3ttOHdDHDo8b4nC41G3U9CCIa/ZUgB1n3 iNTTs9FgQasjaUu8nqhQppc+t4AsZrTu2OY0Z2psW6qORa6EoFFLSCfvRiCTWRYc+O4D di2A== X-Gm-Message-State: AHYfb5i0Kh1bwtc+91CuN2b6PQaJH+LYGmdfEFn5hqAK0XMTpKVV5XTb laSC4rBqw/yRuaWZ X-Received: by 10.46.76.26 with SMTP id z26mr341769lja.81.1503446372559; Tue, 22 Aug 2017 16:59:32 -0700 (PDT) Received: from localhost.localdomain ([176.51.136.198]) by smtp.gmail.com with ESMTPSA id 2sm30592ljh.2.2017.08.22.16.59.28 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Tue, 22 Aug 2017 16:59:31 -0700 (PDT) From: Ilia Valiakhmetov To: ffmpeg-devel@ffmpeg.org Date: Wed, 23 Aug 2017 06:59:13 +0700 Message-Id: <20170822235913.5028-1-zakne0ne@gmail.com> X-Mailer: git-send-email 2.8.3 Subject: [FFmpeg-devel] [PATCH] avcodec/vp9: Add tile threading support X-BeenThere: ffmpeg-devel@ffmpeg.org X-Mailman-Version: 2.1.20 Precedence: list List-Id: FFmpeg development discussions and patches List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Reply-To: FFmpeg development discussions and patches Cc: Ilia Valiakhmetov MIME-Version: 1.0 Errors-To: ffmpeg-devel-bounces@ffmpeg.org Sender: "ffmpeg-devel" Tile threading is ~35% faster at 2 threads vs 1. Frame threading is ~41% faster at 2 threads vs 1. Signed-off-by: Ilia Valiakhmetov --- libavcodec/avcodec.h | 3 +- libavcodec/options.c | 1 + libavcodec/pthread_slice.c | 39 +++- libavcodec/thread.h | 1 + libavcodec/utils.c | 13 ++ libavcodec/vp9.c | 535 ++++++++++++++++++++++++++++--------------- libavcodec/vp9_mc_template.c | 202 ++++++++-------- libavcodec/vp9block.c | 506 ++++++++++++++++++++-------------------- libavcodec/vp9dec.h | 94 ++++---- libavcodec/vp9mvs.c | 97 ++++---- libavcodec/vp9prob.c | 64 +++--- libavcodec/vp9recon.c | 153 +++++++------ 12 files changed, 969 insertions(+), 739 deletions(-) diff --git a/libavcodec/avcodec.h b/libavcodec/avcodec.h index c594993..a22d473 100644 --- a/libavcodec/avcodec.h +++ b/libavcodec/avcodec.h @@ -3233,7 +3233,7 @@ typedef struct AVCodecContext { * - decoding: Set by libavcodec, user can override. */ int (*execute2)(struct AVCodecContext *c, int (*func)(struct AVCodecContext *c2, void *arg, int jobnr, int threadnr), void *arg2, int *ret, int count); - + int (*execute3)(struct AVCodecContext *c, int (*func)(struct AVCodecContext *c2, void *arg, int jobnr, int threadnr), int (*m_func)(struct AVCodecContext *c3), void *arg2, int *ret, int count); /** * noise vs. sse weight for the nsse comparison function * - encoding: Set by user. @@ -5782,6 +5782,7 @@ const char *avcodec_profile_name(enum AVCodecID codec_id, int profile); int avcodec_default_execute(AVCodecContext *c, int (*func)(AVCodecContext *c2, void *arg2),void *arg, int *ret, int count, int size); int avcodec_default_execute2(AVCodecContext *c, int (*func)(AVCodecContext *c2, void *arg2, int, int),void *arg, int *ret, int count); +int avcodec_default_execute3(AVCodecContext *c, int (*func)(AVCodecContext *c2, void *arg2, int jobnr, int threadnr), int (*m_func)(struct AVCodecContext *c3), void *arg, int *ret, int count); //FIXME func typedef /** diff --git a/libavcodec/options.c b/libavcodec/options.c index 82e1217..6d63bdb 100644 --- a/libavcodec/options.c +++ b/libavcodec/options.c @@ -117,6 +117,7 @@ static int init_context_defaults(AVCodecContext *s, const AVCodec *codec) s->get_format = avcodec_default_get_format; s->execute = avcodec_default_execute; s->execute2 = avcodec_default_execute2; + s->execute3 = avcodec_default_execute3; s->sample_aspect_ratio = (AVRational){0,1}; s->pix_fmt = AV_PIX_FMT_NONE; s->sw_pix_fmt = AV_PIX_FMT_NONE; diff --git a/libavcodec/pthread_slice.c b/libavcodec/pthread_slice.c index c781d35..3b0cd9b 100644 --- a/libavcodec/pthread_slice.c +++ b/libavcodec/pthread_slice.c @@ -38,11 +38,13 @@ typedef int (action_func)(AVCodecContext *c, void *arg); typedef int (action_func2)(AVCodecContext *c, void *arg, int jobnr, int threadnr); +typedef int (main_func)(AVCodecContext *c); typedef struct SliceThreadContext { AVSliceThread *thread; action_func *func; action_func2 *func2; + main_func *m_func; void *args; int *rets; int job_size; @@ -54,6 +56,12 @@ typedef struct SliceThreadContext { pthread_mutex_t *progress_mutex; } SliceThreadContext; +static void main_function(void *priv) { + AVCodecContext *avctx = priv; + SliceThreadContext *c = avctx->internal->thread_ctx; + c->m_func(avctx); +} + static void worker_func(void *priv, int jobnr, int threadnr, int nb_jobs, int nb_threads) { AVCodecContext *avctx = priv; @@ -99,7 +107,11 @@ static int thread_execute(AVCodecContext *avctx, action_func* func, void *arg, i c->func = func; c->rets = ret; - avpriv_slicethread_execute(c->thread, job_count, 0); + if (c->m_func) + avpriv_slicethread_execute(c->thread, job_count, 1); + else + avpriv_slicethread_execute(c->thread, job_count, 0); + return 0; } @@ -110,6 +122,15 @@ static int thread_execute2(AVCodecContext *avctx, action_func2* func2, void *arg return thread_execute(avctx, NULL, arg, ret, job_count, 0); } +static int thread_execute3(AVCodecContext *avctx, action_func2* func2, main_func* m_func, void *arg, int *ret, int job_count) +{ + SliceThreadContext *c = avctx->internal->thread_ctx; + c->func2 = func2; + c->m_func = m_func; + return thread_execute(avctx, NULL, arg, ret, job_count, 0); +} + + int ff_slice_thread_init(AVCodecContext *avctx) { SliceThreadContext *c; @@ -142,7 +163,7 @@ int ff_slice_thread_init(AVCodecContext *avctx) } avctx->internal->thread_ctx = c = av_mallocz(sizeof(*c)); - if (!c || (thread_count = avpriv_slicethread_create(&c->thread, avctx, worker_func, NULL, thread_count)) <= 1) { + if (!c || (thread_count = avpriv_slicethread_create(&c->thread, avctx, worker_func, main_function, thread_count)) <= 1) { if (c) avpriv_slicethread_free(&c->thread); av_freep(&avctx->internal->thread_ctx); @@ -150,10 +171,12 @@ int ff_slice_thread_init(AVCodecContext *avctx) avctx->active_thread_type = 0; return 0; } + c->m_func = NULL; avctx->thread_count = thread_count; avctx->execute = thread_execute; avctx->execute2 = thread_execute2; + avctx->execute3 = thread_execute3; return 0; } @@ -184,6 +207,18 @@ void ff_thread_await_progress2(AVCodecContext *avctx, int field, int thread, int pthread_mutex_unlock(&p->progress_mutex[thread]); } +void ff_thread_await_progress3(AVCodecContext *avctx, int field, int thread, int shift) +{ + SliceThreadContext *p = avctx->internal->thread_ctx; + int *entries = p->entries; + + pthread_mutex_lock(&p->progress_mutex[thread]); + while ((entries[field]) != shift){ + pthread_cond_wait(&p->progress_cond[thread], &p->progress_mutex[thread]); + } + pthread_mutex_unlock(&p->progress_mutex[thread]); +} + int ff_alloc_entries(AVCodecContext *avctx, int count) { int i; diff --git a/libavcodec/thread.h b/libavcodec/thread.h index 90864b5..67c809c 100644 --- a/libavcodec/thread.h +++ b/libavcodec/thread.h @@ -139,5 +139,6 @@ int ff_alloc_entries(AVCodecContext *avctx, int count); void ff_reset_entries(AVCodecContext *avctx); void ff_thread_report_progress2(AVCodecContext *avctx, int field, int thread, int n); void ff_thread_await_progress2(AVCodecContext *avctx, int field, int thread, int shift); +void ff_thread_await_progress3(AVCodecContext *avctx, int field, int thread, int shift); #endif /* AVCODEC_THREAD_H */ diff --git a/libavcodec/utils.c b/libavcodec/utils.c index 1336e92..c3cc3d0 100644 --- a/libavcodec/utils.c +++ b/libavcodec/utils.c @@ -558,6 +558,19 @@ int avcodec_default_execute2(AVCodecContext *c, int (*func)(AVCodecContext *c2, return 0; } +int avcodec_default_execute3(AVCodecContext *c, int (*func)(AVCodecContext *c2, void *arg2, int jobnr, int threadnr), int (*m_func)(struct AVCodecContext *c3), void *arg, int *ret, int count) +{ + int i; + m_func(c); + for (i = 0; i < count; i++) { + int r = func(c, arg, i, 0); + if (ret) + ret[i] = r; + } + emms_c(); + return 0; +} + enum AVPixelFormat avpriv_find_pix_fmt(const PixelFormatTag *tags, unsigned int fourcc) { diff --git a/libavcodec/vp9.c b/libavcodec/vp9.c index 94430db..2bcc492 100644 --- a/libavcodec/vp9.c +++ b/libavcodec/vp9.c @@ -118,6 +118,7 @@ static int update_size(AVCodecContext *avctx, int w, int h) VP9Context *s = avctx->priv_data; uint8_t *p; int bytesperpixel = s->bytesperpixel, ret, cols, rows; + int lflvl_len; av_assert0(w > 0 && h > 0); @@ -170,13 +171,14 @@ static int update_size(AVCodecContext *avctx, int w, int h) s->sb_rows = (h + 63) >> 6; s->cols = (w + 7) >> 3; s->rows = (h + 7) >> 3; + lflvl_len = avctx->active_thread_type == FF_THREAD_SLICE ? s->sb_rows : 1; #define assign(var, type, n) var = (type) p; p += s->sb_cols * (n) * sizeof(*var) av_freep(&s->intra_pred_data[0]); // FIXME we slightly over-allocate here for subsampled chroma, but a little // bit of padding shouldn't affect performance... p = av_malloc(s->sb_cols * (128 + 192 * bytesperpixel + - sizeof(*s->lflvl) + 16 * sizeof(*s->above_mv_ctx))); + lflvl_len*sizeof(*s->lflvl) + 16 * sizeof(*s->above_mv_ctx))); if (!p) return AVERROR(ENOMEM); assign(s->intra_pred_data[0], uint8_t *, 64 * bytesperpixel); @@ -195,13 +197,9 @@ static int update_size(AVCodecContext *avctx, int w, int h) assign(s->above_comp_ctx, uint8_t *, 8); assign(s->above_ref_ctx, uint8_t *, 8); assign(s->above_filter_ctx, uint8_t *, 8); - assign(s->lflvl, VP9Filter *, 1); + assign(s->lflvl, VP9Filter *, lflvl_len); #undef assign - // these will be re-allocated a little later - av_freep(&s->b_base); - av_freep(&s->block_base); - if (s->s.h.bpp != s->last_bpp) { ff_vp9dsp_init(&s->dsp, s->s.h.bpp, avctx->flags & AV_CODEC_FLAG_BITEXACT); ff_videodsp_init(&s->vdsp, s->s.h.bpp); @@ -213,40 +211,50 @@ static int update_size(AVCodecContext *avctx, int w, int h) static int update_block_buffers(AVCodecContext *avctx) { + int i; VP9Context *s = avctx->priv_data; int chroma_blocks, chroma_eobs, bytesperpixel = s->bytesperpixel; + VP9TileData *td = &s->td[0]; - if (s->b_base && s->block_base && s->block_alloc_using_2pass == s->s.frames[CUR_FRAME].uses_2pass) + if (td->b_base && td->block_base && s->block_alloc_using_2pass == s->s.frames[CUR_FRAME].uses_2pass) return 0; - av_free(s->b_base); - av_free(s->block_base); + av_free(td->b_base); + av_free(td->block_base); chroma_blocks = 64 * 64 >> (s->ss_h + s->ss_v); chroma_eobs = 16 * 16 >> (s->ss_h + s->ss_v); if (s->s.frames[CUR_FRAME].uses_2pass) { int sbs = s->sb_cols * s->sb_rows; - s->b_base = av_malloc_array(s->cols * s->rows, sizeof(VP9Block)); - s->block_base = av_mallocz(((64 * 64 + 2 * chroma_blocks) * bytesperpixel * sizeof(int16_t) + + td->b_base = av_malloc_array(s->cols * s->rows, sizeof(VP9Block)); + td->block_base = av_mallocz(((64 * 64 + 2 * chroma_blocks) * bytesperpixel * sizeof(int16_t) + 16 * 16 + 2 * chroma_eobs) * sbs); - if (!s->b_base || !s->block_base) + if (!td->b_base || !td->block_base) return AVERROR(ENOMEM); - s->uvblock_base[0] = s->block_base + sbs * 64 * 64 * bytesperpixel; - s->uvblock_base[1] = s->uvblock_base[0] + sbs * chroma_blocks * bytesperpixel; - s->eob_base = (uint8_t *) (s->uvblock_base[1] + sbs * chroma_blocks * bytesperpixel); - s->uveob_base[0] = s->eob_base + 16 * 16 * sbs; - s->uveob_base[1] = s->uveob_base[0] + chroma_eobs * sbs; + td->uvblock_base[0] = td->block_base + sbs * 64 * 64 * bytesperpixel; + td->uvblock_base[1] = td->uvblock_base[0] + sbs * chroma_blocks * bytesperpixel; + td->eob_base = (uint8_t *) (td->uvblock_base[1] + sbs * chroma_blocks * bytesperpixel); + td->uveob_base[0] = td->eob_base + 16 * 16 * sbs; + td->uveob_base[1] = td->uveob_base[0] + chroma_eobs * sbs; } else { - s->b_base = av_malloc(sizeof(VP9Block)); - s->block_base = av_mallocz((64 * 64 + 2 * chroma_blocks) * bytesperpixel * sizeof(int16_t) + - 16 * 16 + 2 * chroma_eobs); - if (!s->b_base || !s->block_base) - return AVERROR(ENOMEM); - s->uvblock_base[0] = s->block_base + 64 * 64 * bytesperpixel; - s->uvblock_base[1] = s->uvblock_base[0] + chroma_blocks * bytesperpixel; - s->eob_base = (uint8_t *) (s->uvblock_base[1] + chroma_blocks * bytesperpixel); - s->uveob_base[0] = s->eob_base + 16 * 16; - s->uveob_base[1] = s->uveob_base[0] + chroma_eobs; + for (i = 1; i < s->s.h.tiling.tile_cols; i++) { + if (s->td[i].b_base && s->td[i].block_base) { + av_free(s->td[i].b_base); + av_free(s->td[i].block_base); + } + } + for (i = 0; i < s->s.h.tiling.tile_cols; i++) { + s->td[i].b_base = av_malloc(sizeof(VP9Block)); + s->td[i].block_base = av_mallocz((64 * 64 + 2 * chroma_blocks) * bytesperpixel * sizeof(int16_t) + + 16 * 16 + 2 * chroma_eobs); + if (!s->td[i].b_base || !s->td[i].block_base) + return AVERROR(ENOMEM); + s->td[i].uvblock_base[0] = s->td[i].block_base + 64 * 64 * bytesperpixel; + s->td[i].uvblock_base[1] = s->td[i].uvblock_base[0] + chroma_blocks * bytesperpixel; + s->td[i].eob_base = (uint8_t *) (s->td[i].uvblock_base[1] + chroma_blocks * bytesperpixel); + s->td[i].uveob_base[0] = s->td[i].eob_base + 16 * 16; + s->td[i].uveob_base[1] = s->td[i].uveob_base[0] + chroma_eobs; + } } s->block_alloc_using_2pass = s->s.frames[CUR_FRAME].uses_2pass; @@ -543,8 +551,23 @@ static int decode_frame_header(AVCodecContext *avctx, sharp = get_bits(&s->gb, 3); // if sharpness changed, reinit lim/mblim LUTs. if it didn't change, keep // the old cache values since they are still valid - if (s->s.h.filter.sharpness != sharp) - memset(s->filter_lut.lim_lut, 0, sizeof(s->filter_lut.lim_lut)); + if (s->s.h.filter.sharpness != sharp) { + for (i = 1; i <= 63; i++) { + if (!s->filter_lut.lim_lut[i]) { + int sharp = s->s.h.filter.sharpness; + int limit = i; + + if (sharp > 0) { + limit >>= (sharp + 3) >> 2; + limit = FFMIN(limit, 9 - sharp); + } + limit = FFMAX(limit, 1); + + s->filter_lut.lim_lut[i] = limit; + s->filter_lut.mblim_lut[i] = 2 * (i + 2) + limit; + } + } + } s->s.h.filter.sharpness = sharp; if ((s->s.h.lf_delta.enabled = get_bits1(&s->gb))) { if ((s->s.h.lf_delta.updated = get_bits1(&s->gb))) { @@ -663,12 +686,16 @@ static int decode_frame_header(AVCodecContext *avctx, s->s.h.tiling.tile_rows = 1 << s->s.h.tiling.log2_tile_rows; if (s->s.h.tiling.tile_cols != (1 << s->s.h.tiling.log2_tile_cols)) { s->s.h.tiling.tile_cols = 1 << s->s.h.tiling.log2_tile_cols; - s->c_b = av_fast_realloc(s->c_b, &s->c_b_size, - sizeof(VP56RangeCoder) * s->s.h.tiling.tile_cols); - if (!s->c_b) { - av_log(avctx, AV_LOG_ERROR, "Ran out of memory during range coder init\n"); + + if (s->td) + av_free(s->td); + + s->td = av_mallocz_array(s->s.h.tiling.tile_cols, sizeof(VP9TileData)); + if (!s->td) return AVERROR(ENOMEM); - } + + for (i = 0; i < s->s.h.tiling.tile_cols; i++) + s->td[i].s = s; } /* check reference frames */ @@ -735,12 +762,15 @@ static int decode_frame_header(AVCodecContext *avctx, return AVERROR_INVALIDDATA; } - if (s->s.h.keyframe || s->s.h.intraonly) { - memset(s->counts.coef, 0, sizeof(s->counts.coef)); - memset(s->counts.eob, 0, sizeof(s->counts.eob)); - } else { - memset(&s->counts, 0, sizeof(s->counts)); + for (i = 0; i < s->s.h.tiling.tile_cols; i++) { + if (s->s.h.keyframe || s->s.h.intraonly) { + memset(s->td[i].counts.coef, 0, sizeof(s->td[0].counts.coef)); + memset(s->td[i].counts.eob, 0, sizeof(s->td[0].counts.eob)); + } else { + memset(&s->td[i].counts, 0, sizeof(s->td[0].counts)); + } } + /* FIXME is it faster to not copy here, but do it down in the fw updates * as explicit copies if the fw update is missing (and skip the copy upon * fw update)? */ @@ -929,12 +959,12 @@ static int decode_frame_header(AVCodecContext *avctx, return (data2 - data) + size2; } -static void decode_sb(AVCodecContext *avctx, int row, int col, VP9Filter *lflvl, +static void decode_sb(VP9TileData *td, int row, int col, VP9Filter *lflvl, ptrdiff_t yoff, ptrdiff_t uvoff, enum BlockLevel bl) { - VP9Context *s = avctx->priv_data; + VP9Context *s = td->s; int c = ((s->above_partition_ctx[col] >> (3 - bl)) & 1) | - (((s->left_partition_ctx[row & 0x7] >> (3 - bl)) & 1) << 1); + (((td->left_partition_ctx[row & 0x7] >> (3 - bl)) & 1) << 1); const uint8_t *p = s->s.h.keyframe || s->s.h.intraonly ? ff_vp9_default_kf_partition_probs[bl][c] : s->prob.p.partition[bl][c]; enum BlockPartition bp; @@ -944,75 +974,75 @@ static void decode_sb(AVCodecContext *avctx, int row, int col, VP9Filter *lflvl, int bytesperpixel = s->bytesperpixel; if (bl == BL_8X8) { - bp = vp8_rac_get_tree(&s->c, ff_vp9_partition_tree, p); - ff_vp9_decode_block(avctx, row, col, lflvl, yoff, uvoff, bl, bp); + bp = vp8_rac_get_tree(&td->c, ff_vp9_partition_tree, p); + ff_vp9_decode_block(td, row, col, lflvl, yoff, uvoff, bl, bp); } else if (col + hbs < s->cols) { // FIXME why not <=? if (row + hbs < s->rows) { // FIXME why not <=? - bp = vp8_rac_get_tree(&s->c, ff_vp9_partition_tree, p); + bp = vp8_rac_get_tree(&td->c, ff_vp9_partition_tree, p); switch (bp) { case PARTITION_NONE: - ff_vp9_decode_block(avctx, row, col, lflvl, yoff, uvoff, bl, bp); + ff_vp9_decode_block(td, row, col, lflvl, yoff, uvoff, bl, bp); break; case PARTITION_H: - ff_vp9_decode_block(avctx, row, col, lflvl, yoff, uvoff, bl, bp); + ff_vp9_decode_block(td, row, col, lflvl, yoff, uvoff, bl, bp); yoff += hbs * 8 * y_stride; uvoff += hbs * 8 * uv_stride >> s->ss_v; - ff_vp9_decode_block(avctx, row + hbs, col, lflvl, yoff, uvoff, bl, bp); + ff_vp9_decode_block(td, row + hbs, col, lflvl, yoff, uvoff, bl, bp); break; case PARTITION_V: - ff_vp9_decode_block(avctx, row, col, lflvl, yoff, uvoff, bl, bp); + ff_vp9_decode_block(td, row, col, lflvl, yoff, uvoff, bl, bp); yoff += hbs * 8 * bytesperpixel; uvoff += hbs * 8 * bytesperpixel >> s->ss_h; - ff_vp9_decode_block(avctx, row, col + hbs, lflvl, yoff, uvoff, bl, bp); + ff_vp9_decode_block(td, row, col + hbs, lflvl, yoff, uvoff, bl, bp); break; case PARTITION_SPLIT: - decode_sb(avctx, row, col, lflvl, yoff, uvoff, bl + 1); - decode_sb(avctx, row, col + hbs, lflvl, + decode_sb(td, row, col, lflvl, yoff, uvoff, bl + 1); + decode_sb(td, row, col + hbs, lflvl, yoff + 8 * hbs * bytesperpixel, uvoff + (8 * hbs * bytesperpixel >> s->ss_h), bl + 1); yoff += hbs * 8 * y_stride; uvoff += hbs * 8 * uv_stride >> s->ss_v; - decode_sb(avctx, row + hbs, col, lflvl, yoff, uvoff, bl + 1); - decode_sb(avctx, row + hbs, col + hbs, lflvl, + decode_sb(td, row + hbs, col, lflvl, yoff, uvoff, bl + 1); + decode_sb(td, row + hbs, col + hbs, lflvl, yoff + 8 * hbs * bytesperpixel, uvoff + (8 * hbs * bytesperpixel >> s->ss_h), bl + 1); break; default: av_assert0(0); } - } else if (vp56_rac_get_prob_branchy(&s->c, p[1])) { + } else if (vp56_rac_get_prob_branchy(&td->c, p[1])) { bp = PARTITION_SPLIT; - decode_sb(avctx, row, col, lflvl, yoff, uvoff, bl + 1); - decode_sb(avctx, row, col + hbs, lflvl, + decode_sb(td, row, col, lflvl, yoff, uvoff, bl + 1); + decode_sb(td, row, col + hbs, lflvl, yoff + 8 * hbs * bytesperpixel, uvoff + (8 * hbs * bytesperpixel >> s->ss_h), bl + 1); } else { bp = PARTITION_H; - ff_vp9_decode_block(avctx, row, col, lflvl, yoff, uvoff, bl, bp); + ff_vp9_decode_block(td, row, col, lflvl, yoff, uvoff, bl, bp); } } else if (row + hbs < s->rows) { // FIXME why not <=? - if (vp56_rac_get_prob_branchy(&s->c, p[2])) { + if (vp56_rac_get_prob_branchy(&td->c, p[2])) { bp = PARTITION_SPLIT; - decode_sb(avctx, row, col, lflvl, yoff, uvoff, bl + 1); + decode_sb(td, row, col, lflvl, yoff, uvoff, bl + 1); yoff += hbs * 8 * y_stride; uvoff += hbs * 8 * uv_stride >> s->ss_v; - decode_sb(avctx, row + hbs, col, lflvl, yoff, uvoff, bl + 1); + decode_sb(td, row + hbs, col, lflvl, yoff, uvoff, bl + 1); } else { bp = PARTITION_V; - ff_vp9_decode_block(avctx, row, col, lflvl, yoff, uvoff, bl, bp); + ff_vp9_decode_block(td, row, col, lflvl, yoff, uvoff, bl, bp); } } else { bp = PARTITION_SPLIT; - decode_sb(avctx, row, col, lflvl, yoff, uvoff, bl + 1); + decode_sb(td, row, col, lflvl, yoff, uvoff, bl + 1); } - s->counts.partition[bl][c][bp]++; + td->counts.partition[bl][c][bp]++; } -static void decode_sb_mem(AVCodecContext *avctx, int row, int col, VP9Filter *lflvl, +static void decode_sb_mem(VP9TileData *td, int row, int col, VP9Filter *lflvl, ptrdiff_t yoff, ptrdiff_t uvoff, enum BlockLevel bl) { - VP9Context *s = avctx->priv_data; - VP9Block *b = s->b; + VP9Context *s = td->s; + VP9Block *b = td->b; ptrdiff_t hbs = 4 >> bl; AVFrame *f = s->s.frames[CUR_FRAME].tf.f; ptrdiff_t y_stride = f->linesize[0], uv_stride = f->linesize[1]; @@ -1020,39 +1050,39 @@ static void decode_sb_mem(AVCodecContext *avctx, int row, int col, VP9Filter *lf if (bl == BL_8X8) { av_assert2(b->bl == BL_8X8); - ff_vp9_decode_block(avctx, row, col, lflvl, yoff, uvoff, b->bl, b->bp); - } else if (s->b->bl == bl) { - ff_vp9_decode_block(avctx, row, col, lflvl, yoff, uvoff, b->bl, b->bp); + ff_vp9_decode_block(td, row, col, lflvl, yoff, uvoff, b->bl, b->bp); + } else if (td->b->bl == bl) { + ff_vp9_decode_block(td, row, col, lflvl, yoff, uvoff, b->bl, b->bp); if (b->bp == PARTITION_H && row + hbs < s->rows) { yoff += hbs * 8 * y_stride; uvoff += hbs * 8 * uv_stride >> s->ss_v; - ff_vp9_decode_block(avctx, row + hbs, col, lflvl, yoff, uvoff, b->bl, b->bp); + ff_vp9_decode_block(td, row + hbs, col, lflvl, yoff, uvoff, b->bl, b->bp); } else if (b->bp == PARTITION_V && col + hbs < s->cols) { yoff += hbs * 8 * bytesperpixel; uvoff += hbs * 8 * bytesperpixel >> s->ss_h; - ff_vp9_decode_block(avctx, row, col + hbs, lflvl, yoff, uvoff, b->bl, b->bp); + ff_vp9_decode_block(td, row, col + hbs, lflvl, yoff, uvoff, b->bl, b->bp); } } else { - decode_sb_mem(avctx, row, col, lflvl, yoff, uvoff, bl + 1); + decode_sb_mem(td, row, col, lflvl, yoff, uvoff, bl + 1); if (col + hbs < s->cols) { // FIXME why not <=? if (row + hbs < s->rows) { - decode_sb_mem(avctx, row, col + hbs, lflvl, yoff + 8 * hbs * bytesperpixel, + decode_sb_mem(td, row, col + hbs, lflvl, yoff + 8 * hbs * bytesperpixel, uvoff + (8 * hbs * bytesperpixel >> s->ss_h), bl + 1); yoff += hbs * 8 * y_stride; uvoff += hbs * 8 * uv_stride >> s->ss_v; - decode_sb_mem(avctx, row + hbs, col, lflvl, yoff, uvoff, bl + 1); - decode_sb_mem(avctx, row + hbs, col + hbs, lflvl, + decode_sb_mem(td, row + hbs, col, lflvl, yoff, uvoff, bl + 1); + decode_sb_mem(td, row + hbs, col + hbs, lflvl, yoff + 8 * hbs * bytesperpixel, uvoff + (8 * hbs * bytesperpixel >> s->ss_h), bl + 1); } else { yoff += hbs * 8 * bytesperpixel; uvoff += hbs * 8 * bytesperpixel >> s->ss_h; - decode_sb_mem(avctx, row, col + hbs, lflvl, yoff, uvoff, bl + 1); + decode_sb_mem(td, row, col + hbs, lflvl, yoff, uvoff, bl + 1); } } else if (row + hbs < s->rows) { yoff += hbs * 8 * y_stride; uvoff += hbs * 8 * uv_stride >> s->ss_v; - decode_sb_mem(avctx, row + hbs, col, lflvl, yoff, uvoff, bl + 1); + decode_sb_mem(td, row + hbs, col, lflvl, yoff, uvoff, bl + 1); } } } @@ -1067,9 +1097,13 @@ static void set_tile_offset(int *start, int *end, int idx, int log2_n, int n) static void free_buffers(VP9Context *s) { + int i; + av_freep(&s->intra_pred_data[0]); - av_freep(&s->b_base); - av_freep(&s->block_base); + for (i = 0; i < s->s.h.tiling.tile_cols; i++) { + av_freep(&s->td[i].b_base); + av_freep(&s->td[i].block_base); + } } static av_cold int vp9_decode_free(AVCodecContext *avctx) @@ -1090,10 +1124,223 @@ static av_cold int vp9_decode_free(AVCodecContext *avctx) ff_thread_release_buffer(avctx, &s->next_refs[i]); av_frame_free(&s->next_refs[i].f); } + free_buffers(s); - av_freep(&s->c_b); - s->c_b_size = 0; + av_freep(&s->td); + return 0; +} +static int decode_tiles(AVCodecContext *avctx) +{ + VP9Context *s = avctx->priv_data; + VP9TileData *td = &s->td[0]; + int row, col, tile_row, tile_col; + int bytesperpixel; + int tile_row_start, tile_row_end, tile_col_start, tile_col_end; + AVFrame *f; + ptrdiff_t yoff, uvoff, ls_y, ls_uv; + + f = s->s.frames[CUR_FRAME].tf.f; + ls_y = f->linesize[0]; + ls_uv =f->linesize[1]; + bytesperpixel = s->bytesperpixel; + + yoff = uvoff = 0; + for (tile_row = 0; tile_row < s->s.h.tiling.tile_rows; tile_row++) { + set_tile_offset(&tile_row_start, &tile_row_end, + tile_row, s->s.h.tiling.log2_tile_rows, s->sb_rows); + + for (row = tile_row_start; row < tile_row_end; + row += 8, yoff += ls_y * 64, uvoff += ls_uv * 64 >> s->ss_v) { + VP9Filter *lflvl_ptr = s->lflvl; + ptrdiff_t yoff2 = yoff, uvoff2 = uvoff; + + for (tile_col = 0; tile_col < s->s.h.tiling.tile_cols; tile_col++) { + set_tile_offset(&tile_col_start, &tile_col_end, + tile_col, s->s.h.tiling.log2_tile_cols, s->sb_cols); + td->tile_col_start = tile_col_start; + if (s->pass != 2) { + memset(td->left_partition_ctx, 0, 8); + memset(td->left_skip_ctx, 0, 8); + if (s->s.h.keyframe || s->s.h.intraonly) { + memset(td->left_mode_ctx, DC_PRED, 16); + } else { + memset(td->left_mode_ctx, NEARESTMV, 8); + } + memset(td->left_y_nnz_ctx, 0, 16); + memset(td->left_uv_nnz_ctx, 0, 32); + memset(td->left_segpred_ctx, 0, 8); + + memcpy(&td->c, &s->td[tile_col].c_b[tile_row], sizeof(td->c)); + } + + for (col = tile_col_start; + col < tile_col_end; + col += 8, yoff2 += 64 * bytesperpixel, + uvoff2 += 64 * bytesperpixel >> s->ss_h, lflvl_ptr++) { + // FIXME integrate with lf code (i.e. zero after each + // use, similar to invtxfm coefficients, or similar) + if (s->pass != 1) { + memset(lflvl_ptr->mask, 0, sizeof(lflvl_ptr->mask)); + } + + if (s->pass == 2) { + decode_sb_mem(td, row, col, lflvl_ptr, + yoff2, uvoff2, BL_64X64); + } else { + decode_sb(td, row, col, lflvl_ptr, + yoff2, uvoff2, BL_64X64); + } + } + if (s->pass != 2) + memcpy(&s->td[tile_col].c_b[tile_row], &td->c, sizeof(td->c)); + } + + if (s->pass == 1) + continue; + + // backup pre-loopfilter reconstruction data for intra + // prediction of next row of sb64s + if (row + 8 < s->rows) { + memcpy(s->intra_pred_data[0], + f->data[0] + yoff + 63 * ls_y, + 8 * s->cols * bytesperpixel); + memcpy(s->intra_pred_data[1], + f->data[1] + uvoff + ((64 >> s->ss_v) - 1) * ls_uv, + 8 * s->cols * bytesperpixel >> s->ss_h); + memcpy(s->intra_pred_data[2], + f->data[2] + uvoff + ((64 >> s->ss_v) - 1) * ls_uv, + 8 * s->cols * bytesperpixel >> s->ss_h); + } + + // loopfilter one row + if (s->s.h.filter.level) { + yoff2 = yoff; + uvoff2 = uvoff; + lflvl_ptr = s->lflvl; + for (col = 0; col < s->cols; + col += 8, yoff2 += 64 * bytesperpixel, + uvoff2 += 64 * bytesperpixel >> s->ss_h, lflvl_ptr++) { + ff_vp9_loopfilter_sb(avctx, lflvl_ptr, row, col, + yoff2, uvoff2); + } + } + + // FIXME maybe we can make this more finegrained by running the + // loopfilter per-block instead of after each sbrow + // In fact that would also make intra pred left preparation easier? + ff_thread_report_progress(&s->s.frames[CUR_FRAME].tf, row >> 3, 0); + } + } + return 0; +} + + +static av_always_inline +int decode_tiles_mt(AVCodecContext *avctx, void *tdata, int jobnr, + int threadnr) +{ + VP9Context *s = avctx->priv_data; + VP9TileData *td = &s->td[jobnr]; + ptrdiff_t uvoff, yoff, ls_y, ls_uv; + int bytesperpixel = s->bytesperpixel, row, col, tile_row; + unsigned tile_cols_len; + int tile_row_start, tile_row_end, tile_col_start, tile_col_end; + VP9Filter *lflvl_ptr_base; + AVFrame *f; + + f = s->s.frames[CUR_FRAME].tf.f; + ls_y = f->linesize[0]; + ls_uv =f->linesize[1]; + + set_tile_offset(&tile_col_start, &tile_col_end, + jobnr, s->s.h.tiling.log2_tile_cols, s->sb_cols); + td->tile_col_start = tile_col_start; + uvoff = (64 * bytesperpixel >> s->ss_h)*(tile_col_start >> 3); + yoff = (64 * bytesperpixel)*(tile_col_start >> 3); + lflvl_ptr_base = s->lflvl+(tile_col_start >> 3); + + for (tile_row = 0; tile_row < s->s.h.tiling.tile_rows; tile_row++) { + set_tile_offset(&tile_row_start, &tile_row_end, + tile_row, s->s.h.tiling.log2_tile_rows, s->sb_rows); + + memcpy(&td->c, &td->c_b[tile_row], sizeof(td->c)); + for (row = tile_row_start; row < tile_row_end; + row += 8, yoff += ls_y * 64, uvoff += ls_uv * 64 >> s->ss_v) { + ptrdiff_t yoff2 = yoff, uvoff2 = uvoff; + VP9Filter *lflvl_ptr = lflvl_ptr_base+s->sb_cols*(row >> 3); + + memset(td->left_partition_ctx, 0, 8); + memset(td->left_skip_ctx, 0, 8); + if (s->s.h.keyframe || s->s.h.intraonly) { + memset(td->left_mode_ctx, DC_PRED, 16); + } else { + memset(td->left_mode_ctx, NEARESTMV, 8); + } + memset(td->left_y_nnz_ctx, 0, 16); + memset(td->left_uv_nnz_ctx, 0, 32); + memset(td->left_segpred_ctx, 0, 8); + + for (col = tile_col_start; + col < tile_col_end; + col += 8, yoff2 += 64 * bytesperpixel, + uvoff2 += 64 * bytesperpixel >> s->ss_h, lflvl_ptr++) { + // FIXME integrate with lf code (i.e. zero after each + // use, similar to invtxfm coefficients, or similar) + memset(lflvl_ptr->mask, 0, sizeof(lflvl_ptr->mask)); + decode_sb(td, row, col, lflvl_ptr, + yoff2, uvoff2, BL_64X64); + } + + // backup pre-loopfilter reconstruction data for intra + // prediction of next row of sb64s + tile_cols_len = tile_col_end - tile_col_start; + if (row + 8 < s->rows) { + memcpy(s->intra_pred_data[0] + (tile_col_start * 8 * bytesperpixel), + f->data[0] + yoff + 63 * ls_y, + 8 * tile_cols_len * bytesperpixel); + memcpy(s->intra_pred_data[1] + (tile_col_start * 8 * bytesperpixel >> s->ss_h), + f->data[1] + uvoff + ((64 >> s->ss_v) - 1) * ls_uv, + 8 * tile_cols_len * bytesperpixel >> s->ss_h); + memcpy(s->intra_pred_data[2] + (tile_col_start * 8 * bytesperpixel >> s->ss_h), + f->data[2] + uvoff + ((64 >> s->ss_v) - 1) * ls_uv, + 8 * tile_cols_len * bytesperpixel >> s->ss_h); + } + + ff_thread_report_progress2(avctx, row >> 3, 0, 1); + } + } + return 0; +} + +static av_always_inline +int loopfilter_proc(AVCodecContext *avctx) +{ + VP9Context *s = avctx->priv_data; + ptrdiff_t uvoff, yoff, ls_y, ls_uv; + VP9Filter *lflvl_ptr; + int bytesperpixel = s->bytesperpixel, col, i; + AVFrame *f; + + f = s->s.frames[CUR_FRAME].tf.f; + ls_y = f->linesize[0]; + ls_uv =f->linesize[1]; + + for (i = 0; i < s->sb_rows; i++) { + ff_thread_await_progress3(avctx, i, 0, s->s.h.tiling.tile_cols); + + if (s->s.h.filter.level) { + yoff = (ls_y * 64)*i; + uvoff = (ls_uv * 64 >> s->ss_v)*i; + lflvl_ptr = s->lflvl+s->sb_cols*i; + for (col = 0; col < s->cols; + col += 8, yoff += 64 * bytesperpixel, + uvoff += 64 * bytesperpixel >> s->ss_h, lflvl_ptr++) { + ff_vp9_loopfilter_sb(avctx, lflvl_ptr, i << 3, col, + yoff, uvoff); + } + } + } return 0; } @@ -1104,12 +1351,10 @@ static int vp9_decode_frame(AVCodecContext *avctx, void *frame, const uint8_t *data = pkt->data; int size = pkt->size; VP9Context *s = avctx->priv_data; - int ret, tile_row, tile_col, i, ref, row, col; + int ret, tile_row, tile_col, i, j, ref; int retain_segmap_ref = s->s.frames[REF_FRAME_SEGMAP].segmentation_map && (!s->s.h.segmentation.enabled || !s->s.h.segmentation.update_map); - ptrdiff_t yoff, uvoff, ls_y, ls_uv; AVFrame *f; - int bytesperpixel; if ((ret = decode_frame_header(avctx, data, size, &ref)) < 0) { return ret; @@ -1159,8 +1404,6 @@ FF_ENABLE_DEPRECATION_WARNINGS f = s->s.frames[CUR_FRAME].tf.f; f->key_frame = s->s.h.keyframe; f->pict_type = (s->s.h.keyframe || s->s.h.intraonly) ? AV_PICTURE_TYPE_I : AV_PICTURE_TYPE_P; - ls_y = f->linesize[0]; - ls_uv =f->linesize[1]; if (s->s.frames[REF_FRAME_SEGMAP].tf.f->buf[0] && (s->s.frames[REF_FRAME_MVPAIR].tf.f->width != s->s.frames[CUR_FRAME].tf.f->width || @@ -1195,7 +1438,6 @@ FF_ENABLE_DEPRECATION_WARNINGS } // main tile decode loop - bytesperpixel = s->bytesperpixel; memset(s->above_partition_ctx, 0, s->cols); memset(s->above_skip_ctx, 0, s->cols); if (s->s.h.keyframe || s->s.h.intraonly) { @@ -1233,19 +1475,20 @@ FF_ENABLE_DEPRECATION_WARNINGS ff_thread_finish_setup(avctx); } + ff_alloc_entries(avctx, s->sb_rows); + do { - yoff = uvoff = 0; - s->b = s->b_base; - s->block = s->block_base; - s->uvblock[0] = s->uvblock_base[0]; - s->uvblock[1] = s->uvblock_base[1]; - s->eob = s->eob_base; - s->uveob[0] = s->uveob_base[0]; - s->uveob[1] = s->uveob_base[1]; + for (i = 0; i < s->s.h.tiling.tile_cols; i++) { + s->td[i].b = s->td[i].b_base; + s->td[i].block = s->td[i].block_base; + s->td[i].uvblock[0] = s->td[i].uvblock_base[0]; + s->td[i].uvblock[1] = s->td[i].uvblock_base[1]; + s->td[i].eob = s->td[i].eob_base; + s->td[i].uveob[0] = s->td[i].uveob_base[0]; + s->td[i].uveob[1] = s->td[i].uveob_base[1]; + } for (tile_row = 0; tile_row < s->s.h.tiling.tile_rows; tile_row++) { - set_tile_offset(&s->tile_row_start, &s->tile_row_end, - tile_row, s->s.h.tiling.log2_tile_rows, s->sb_rows); if (s->pass != 2) { for (tile_col = 0; tile_col < s->s.h.tiling.tile_cols; tile_col++) { int64_t tile_size; @@ -1262,10 +1505,10 @@ FF_ENABLE_DEPRECATION_WARNINGS ff_thread_report_progress(&s->s.frames[CUR_FRAME].tf, INT_MAX, 0); return AVERROR_INVALIDDATA; } - ret = ff_vp56_init_range_decoder(&s->c_b[tile_col], data, tile_size); + ret = ff_vp56_init_range_decoder(&s->td[tile_col].c_b[tile_row], data, tile_size); if (ret < 0) return ret; - if (vp56_rac_get_prob_branchy(&s->c_b[tile_col], 128)) { // marker bit + if (vp56_rac_get_prob_branchy(&s->td[tile_col].c_b[tile_row], 128)) { // marker bit ff_thread_report_progress(&s->s.frames[CUR_FRAME].tf, INT_MAX, 0); return AVERROR_INVALIDDATA; } @@ -1273,89 +1516,17 @@ FF_ENABLE_DEPRECATION_WARNINGS size -= tile_size; } } + } - for (row = s->tile_row_start; row < s->tile_row_end; - row += 8, yoff += ls_y * 64, uvoff += ls_uv * 64 >> s->ss_v) { - VP9Filter *lflvl_ptr = s->lflvl; - ptrdiff_t yoff2 = yoff, uvoff2 = uvoff; - - for (tile_col = 0; tile_col < s->s.h.tiling.tile_cols; tile_col++) { - set_tile_offset(&s->tile_col_start, &s->tile_col_end, - tile_col, s->s.h.tiling.log2_tile_cols, s->sb_cols); - - if (s->pass != 2) { - memset(s->left_partition_ctx, 0, 8); - memset(s->left_skip_ctx, 0, 8); - if (s->s.h.keyframe || s->s.h.intraonly) { - memset(s->left_mode_ctx, DC_PRED, 16); - } else { - memset(s->left_mode_ctx, NEARESTMV, 8); - } - memset(s->left_y_nnz_ctx, 0, 16); - memset(s->left_uv_nnz_ctx, 0, 32); - memset(s->left_segpred_ctx, 0, 8); - - memcpy(&s->c, &s->c_b[tile_col], sizeof(s->c)); - } - - for (col = s->tile_col_start; - col < s->tile_col_end; - col += 8, yoff2 += 64 * bytesperpixel, - uvoff2 += 64 * bytesperpixel >> s->ss_h, lflvl_ptr++) { - // FIXME integrate with lf code (i.e. zero after each - // use, similar to invtxfm coefficients, or similar) - if (s->pass != 1) { - memset(lflvl_ptr->mask, 0, sizeof(lflvl_ptr->mask)); - } - - if (s->pass == 2) { - decode_sb_mem(avctx, row, col, lflvl_ptr, - yoff2, uvoff2, BL_64X64); - } else { - decode_sb(avctx, row, col, lflvl_ptr, - yoff2, uvoff2, BL_64X64); - } - } - if (s->pass != 2) - memcpy(&s->c_b[tile_col], &s->c, sizeof(s->c)); - } - - if (s->pass == 1) - continue; - - // backup pre-loopfilter reconstruction data for intra - // prediction of next row of sb64s - if (row + 8 < s->rows) { - memcpy(s->intra_pred_data[0], - f->data[0] + yoff + 63 * ls_y, - 8 * s->cols * bytesperpixel); - memcpy(s->intra_pred_data[1], - f->data[1] + uvoff + ((64 >> s->ss_v) - 1) * ls_uv, - 8 * s->cols * bytesperpixel >> s->ss_h); - memcpy(s->intra_pred_data[2], - f->data[2] + uvoff + ((64 >> s->ss_v) - 1) * ls_uv, - 8 * s->cols * bytesperpixel >> s->ss_h); - } - - // loopfilter one row - if (s->s.h.filter.level) { - yoff2 = yoff; - uvoff2 = uvoff; - lflvl_ptr = s->lflvl; - for (col = 0; col < s->cols; - col += 8, yoff2 += 64 * bytesperpixel, - uvoff2 += 64 * bytesperpixel >> s->ss_h, lflvl_ptr++) { - ff_vp9_loopfilter_sb(avctx, lflvl_ptr, row, col, - yoff2, uvoff2); - } - } + if (avctx->active_thread_type == FF_THREAD_SLICE) + avctx->execute3(avctx, decode_tiles_mt, loopfilter_proc, s->td, NULL, s->s.h.tiling.tile_cols); + else + decode_tiles(avctx); - // FIXME maybe we can make this more finegrained by running the - // loopfilter per-block instead of after each sbrow - // In fact that would also make intra pred left preparation easier? - ff_thread_report_progress(&s->s.frames[CUR_FRAME].tf, row >> 3, 0); - } - } + if (avctx->active_thread_type == FF_THREAD_SLICE) + for (i = 1; i < s->s.h.tiling.tile_cols; i++) + for (j = 0; j < sizeof(s->td[i].counts) / sizeof(unsigned); j++) + ((unsigned *)&s->td[0].counts)[j] += ((unsigned *)&s->td[i].counts)[j]; if (s->pass < 2 && s->s.h.refreshctx && !s->s.h.parallelmode) { ff_vp9_adapt_probs(s); @@ -1492,7 +1663,7 @@ AVCodec ff_vp9_decoder = { .init = vp9_decode_init, .close = vp9_decode_free, .decode = vp9_decode_frame, - .capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_FRAME_THREADS, + .capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_FRAME_THREADS | AV_CODEC_CAP_SLICE_THREADS, .flush = vp9_decode_flush, .init_thread_copy = ONLY_IF_THREADS_ENABLED(vp9_decode_init_thread_copy), .update_thread_context = ONLY_IF_THREADS_ENABLED(vp9_decode_update_thread_context), diff --git a/libavcodec/vp9_mc_template.c b/libavcodec/vp9_mc_template.c index 8ff654b..31e692f 100644 --- a/libavcodec/vp9_mc_template.c +++ b/libavcodec/vp9_mc_template.c @@ -27,19 +27,19 @@ (VP56mv) { .x = ROUNDED_DIV(a.x + b.x + c.x + d.x, 4), \ .y = ROUNDED_DIV(a.y + b.y + c.y + d.y, 4) } -static void FN(inter_pred)(AVCodecContext *avctx) +static void FN(inter_pred)(VP9TileData *td) { static const uint8_t bwlog_tab[2][N_BS_SIZES] = { { 0, 0, 1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4 }, { 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4, 4, 4 }, }; - VP9Context *s = avctx->priv_data; - VP9Block *b = s->b; - int row = s->row, col = s->col; + VP9Context *s = td->s; + VP9Block *b = td->b; + int row = td->row, col = td->col; ThreadFrame *tref1 = &s->s.refs[s->s.h.refidx[b->ref[0]]], *tref2; AVFrame *ref1 = tref1->f, *ref2; int w1 = ref1->width, h1 = ref1->height, w2, h2; - ptrdiff_t ls_y = s->y_stride, ls_uv = s->uv_stride; + ptrdiff_t ls_y = td->y_stride, ls_uv = td->uv_stride; int bytesperpixel = BYTES_PER_PIXEL; if (b->comp) { @@ -55,26 +55,26 @@ static void FN(inter_pred)(AVCodecContext *avctx) #if SCALED == 0 if (b->bs == BS_8x4) { - mc_luma_dir(s, mc[3][b->filter][0], s->dst[0], ls_y, + mc_luma_dir(td, mc[3][b->filter][0], td->dst[0], ls_y, ref1->data[0], ref1->linesize[0], tref1, row << 3, col << 3, &b->mv[0][0],,,,, 8, 4, w1, h1, 0); - mc_luma_dir(s, mc[3][b->filter][0], - s->dst[0] + 4 * ls_y, ls_y, + mc_luma_dir(td, mc[3][b->filter][0], + td->dst[0] + 4 * ls_y, ls_y, ref1->data[0], ref1->linesize[0], tref1, (row << 3) + 4, col << 3, &b->mv[2][0],,,,, 8, 4, w1, h1, 0); w1 = (w1 + s->ss_h) >> s->ss_h; if (s->ss_v) { h1 = (h1 + 1) >> 1; uvmv = ROUNDED_DIV_MVx2(b->mv[0][0], b->mv[2][0]); - mc_chroma_dir(s, mc[3 + s->ss_h][b->filter][0], - s->dst[1], s->dst[2], ls_uv, + mc_chroma_dir(td, mc[3 + s->ss_h][b->filter][0], + td->dst[1], td->dst[2], ls_uv, ref1->data[1], ref1->linesize[1], ref1->data[2], ref1->linesize[2], tref1, row << 2, col << (3 - s->ss_h), &uvmv,,,,, 8 >> s->ss_h, 4, w1, h1, 0); } else { - mc_chroma_dir(s, mc[3 + s->ss_h][b->filter][0], - s->dst[1], s->dst[2], ls_uv, + mc_chroma_dir(td, mc[3 + s->ss_h][b->filter][0], + td->dst[1], td->dst[2], ls_uv, ref1->data[1], ref1->linesize[1], ref1->data[2], ref1->linesize[2], tref1, row << 3, col << (3 - s->ss_h), @@ -87,8 +87,8 @@ static void FN(inter_pred)(AVCodecContext *avctx) } else { uvmv = ROUNDED_DIV_MVx2(b->mv[0][0], b->mv[2][0]); } - mc_chroma_dir(s, mc[3 + s->ss_h][b->filter][0], - s->dst[1] + 4 * ls_uv, s->dst[2] + 4 * ls_uv, ls_uv, + mc_chroma_dir(td, mc[3 + s->ss_h][b->filter][0], + td->dst[1] + 4 * ls_uv, td->dst[2] + 4 * ls_uv, ls_uv, ref1->data[1], ref1->linesize[1], ref1->data[2], ref1->linesize[2], tref1, (row << 3) + 4, col << (3 - s->ss_h), @@ -96,26 +96,26 @@ static void FN(inter_pred)(AVCodecContext *avctx) } if (b->comp) { - mc_luma_dir(s, mc[3][b->filter][1], s->dst[0], ls_y, + mc_luma_dir(td, mc[3][b->filter][1], td->dst[0], ls_y, ref2->data[0], ref2->linesize[0], tref2, row << 3, col << 3, &b->mv[0][1],,,,, 8, 4, w2, h2, 1); - mc_luma_dir(s, mc[3][b->filter][1], - s->dst[0] + 4 * ls_y, ls_y, + mc_luma_dir(td, mc[3][b->filter][1], + td->dst[0] + 4 * ls_y, ls_y, ref2->data[0], ref2->linesize[0], tref2, (row << 3) + 4, col << 3, &b->mv[2][1],,,,, 8, 4, w2, h2, 1); w2 = (w2 + s->ss_h) >> s->ss_h; if (s->ss_v) { h2 = (h2 + 1) >> 1; uvmv = ROUNDED_DIV_MVx2(b->mv[0][1], b->mv[2][1]); - mc_chroma_dir(s, mc[3 + s->ss_h][b->filter][1], - s->dst[1], s->dst[2], ls_uv, + mc_chroma_dir(td, mc[3 + s->ss_h][b->filter][1], + td->dst[1], td->dst[2], ls_uv, ref2->data[1], ref2->linesize[1], ref2->data[2], ref2->linesize[2], tref2, row << 2, col << (3 - s->ss_h), &uvmv,,,,, 8 >> s->ss_h, 4, w2, h2, 1); } else { - mc_chroma_dir(s, mc[3 + s->ss_h][b->filter][1], - s->dst[1], s->dst[2], ls_uv, + mc_chroma_dir(td, mc[3 + s->ss_h][b->filter][1], + td->dst[1], td->dst[2], ls_uv, ref2->data[1], ref2->linesize[1], ref2->data[2], ref2->linesize[2], tref2, row << 3, col << (3 - s->ss_h), @@ -128,8 +128,8 @@ static void FN(inter_pred)(AVCodecContext *avctx) } else { uvmv = ROUNDED_DIV_MVx2(b->mv[0][1], b->mv[2][1]); } - mc_chroma_dir(s, mc[3 + s->ss_h][b->filter][1], - s->dst[1] + 4 * ls_uv, s->dst[2] + 4 * ls_uv, ls_uv, + mc_chroma_dir(td, mc[3 + s->ss_h][b->filter][1], + td->dst[1] + 4 * ls_uv, td->dst[2] + 4 * ls_uv, ls_uv, ref2->data[1], ref2->linesize[1], ref2->data[2], ref2->linesize[2], tref2, (row << 3) + 4, col << (3 - s->ss_h), @@ -137,32 +137,32 @@ static void FN(inter_pred)(AVCodecContext *avctx) } } } else if (b->bs == BS_4x8) { - mc_luma_dir(s, mc[4][b->filter][0], s->dst[0], ls_y, + mc_luma_dir(td, mc[4][b->filter][0], td->dst[0], ls_y, ref1->data[0], ref1->linesize[0], tref1, row << 3, col << 3, &b->mv[0][0],,,,, 4, 8, w1, h1, 0); - mc_luma_dir(s, mc[4][b->filter][0], s->dst[0] + 4 * bytesperpixel, ls_y, + mc_luma_dir(td, mc[4][b->filter][0], td->dst[0] + 4 * bytesperpixel, ls_y, ref1->data[0], ref1->linesize[0], tref1, row << 3, (col << 3) + 4, &b->mv[1][0],,,,, 4, 8, w1, h1, 0); h1 = (h1 + s->ss_v) >> s->ss_v; if (s->ss_h) { w1 = (w1 + 1) >> 1; uvmv = ROUNDED_DIV_MVx2(b->mv[0][0], b->mv[1][0]); - mc_chroma_dir(s, mc[4][b->filter][0], - s->dst[1], s->dst[2], ls_uv, + mc_chroma_dir(td, mc[4][b->filter][0], + td->dst[1], td->dst[2], ls_uv, ref1->data[1], ref1->linesize[1], ref1->data[2], ref1->linesize[2], tref1, row << (3 - s->ss_v), col << 2, &uvmv,,,,, 4, 8 >> s->ss_v, w1, h1, 0); } else { - mc_chroma_dir(s, mc[4][b->filter][0], - s->dst[1], s->dst[2], ls_uv, + mc_chroma_dir(td, mc[4][b->filter][0], + td->dst[1], td->dst[2], ls_uv, ref1->data[1], ref1->linesize[1], ref1->data[2], ref1->linesize[2], tref1, row << (3 - s->ss_v), col << 3, &b->mv[0][0],,,,, 4, 8 >> s->ss_v, w1, h1, 0); - mc_chroma_dir(s, mc[4][b->filter][0], - s->dst[1] + 4 * bytesperpixel, - s->dst[2] + 4 * bytesperpixel, ls_uv, + mc_chroma_dir(td, mc[4][b->filter][0], + td->dst[1] + 4 * bytesperpixel, + td->dst[2] + 4 * bytesperpixel, ls_uv, ref1->data[1], ref1->linesize[1], ref1->data[2], ref1->linesize[2], tref1, row << (3 - s->ss_v), (col << 3) + 4, @@ -170,32 +170,32 @@ static void FN(inter_pred)(AVCodecContext *avctx) } if (b->comp) { - mc_luma_dir(s, mc[4][b->filter][1], s->dst[0], ls_y, + mc_luma_dir(td, mc[4][b->filter][1], td->dst[0], ls_y, ref2->data[0], ref2->linesize[0], tref2, row << 3, col << 3, &b->mv[0][1],,,,, 4, 8, w2, h2, 1); - mc_luma_dir(s, mc[4][b->filter][1], s->dst[0] + 4 * bytesperpixel, ls_y, + mc_luma_dir(td, mc[4][b->filter][1], td->dst[0] + 4 * bytesperpixel, ls_y, ref2->data[0], ref2->linesize[0], tref2, row << 3, (col << 3) + 4, &b->mv[1][1],,,,, 4, 8, w2, h2, 1); h2 = (h2 + s->ss_v) >> s->ss_v; if (s->ss_h) { w2 = (w2 + 1) >> 1; uvmv = ROUNDED_DIV_MVx2(b->mv[0][1], b->mv[1][1]); - mc_chroma_dir(s, mc[4][b->filter][1], - s->dst[1], s->dst[2], ls_uv, + mc_chroma_dir(td, mc[4][b->filter][1], + td->dst[1], td->dst[2], ls_uv, ref2->data[1], ref2->linesize[1], ref2->data[2], ref2->linesize[2], tref2, row << (3 - s->ss_v), col << 2, &uvmv,,,,, 4, 8 >> s->ss_v, w2, h2, 1); } else { - mc_chroma_dir(s, mc[4][b->filter][1], - s->dst[1], s->dst[2], ls_uv, + mc_chroma_dir(td, mc[4][b->filter][1], + td->dst[1], td->dst[2], ls_uv, ref2->data[1], ref2->linesize[1], ref2->data[2], ref2->linesize[2], tref2, row << (3 - s->ss_v), col << 3, &b->mv[0][1],,,,, 4, 8 >> s->ss_v, w2, h2, 1); - mc_chroma_dir(s, mc[4][b->filter][1], - s->dst[1] + 4 * bytesperpixel, - s->dst[2] + 4 * bytesperpixel, ls_uv, + mc_chroma_dir(td, mc[4][b->filter][1], + td->dst[1] + 4 * bytesperpixel, + td->dst[2] + 4 * bytesperpixel, ls_uv, ref2->data[1], ref2->linesize[1], ref2->data[2], ref2->linesize[2], tref2, row << (3 - s->ss_v), (col << 3) + 4, @@ -211,21 +211,21 @@ static void FN(inter_pred)(AVCodecContext *avctx) // FIXME if two horizontally adjacent blocks have the same MV, // do a w8 instead of a w4 call - mc_luma_dir(s, mc[4][b->filter][0], s->dst[0], ls_y, + mc_luma_dir(td, mc[4][b->filter][0], td->dst[0], ls_y, ref1->data[0], ref1->linesize[0], tref1, row << 3, col << 3, &b->mv[0][0], 0, 0, 8, 8, 4, 4, w1, h1, 0); - mc_luma_dir(s, mc[4][b->filter][0], s->dst[0] + 4 * bytesperpixel, ls_y, + mc_luma_dir(td, mc[4][b->filter][0], td->dst[0] + 4 * bytesperpixel, ls_y, ref1->data[0], ref1->linesize[0], tref1, row << 3, (col << 3) + 4, &b->mv[1][0], 4, 0, 8, 8, 4, 4, w1, h1, 0); - mc_luma_dir(s, mc[4][b->filter][0], - s->dst[0] + 4 * ls_y, ls_y, + mc_luma_dir(td, mc[4][b->filter][0], + td->dst[0] + 4 * ls_y, ls_y, ref1->data[0], ref1->linesize[0], tref1, (row << 3) + 4, col << 3, &b->mv[2][0], 0, 4, 8, 8, 4, 4, w1, h1, 0); - mc_luma_dir(s, mc[4][b->filter][0], - s->dst[0] + 4 * ls_y + 4 * bytesperpixel, ls_y, + mc_luma_dir(td, mc[4][b->filter][0], + td->dst[0] + 4 * ls_y + 4 * bytesperpixel, ls_y, ref1->data[0], ref1->linesize[0], tref1, (row << 3) + 4, (col << 3) + 4, &b->mv[3][0], 4, 4, 8, 8, 4, 4, w1, h1, 0); @@ -235,24 +235,24 @@ static void FN(inter_pred)(AVCodecContext *avctx) w1 = (w1 + 1) >> 1; uvmv = ROUNDED_DIV_MVx4(b->mv[0][0], b->mv[1][0], b->mv[2][0], b->mv[3][0]); - mc_chroma_dir(s, mc[4][b->filter][0], - s->dst[1], s->dst[2], ls_uv, + mc_chroma_dir(td, mc[4][b->filter][0], + td->dst[1], td->dst[2], ls_uv, ref1->data[1], ref1->linesize[1], ref1->data[2], ref1->linesize[2], tref1, row << 2, col << 2, &uvmv, 0, 0, 4, 4, 4, 4, w1, h1, 0); } else { uvmv = ROUNDED_DIV_MVx2(b->mv[0][0], b->mv[2][0]); - mc_chroma_dir(s, mc[4][b->filter][0], - s->dst[1], s->dst[2], ls_uv, + mc_chroma_dir(td, mc[4][b->filter][0], + td->dst[1], td->dst[2], ls_uv, ref1->data[1], ref1->linesize[1], ref1->data[2], ref1->linesize[2], tref1, row << 2, col << 3, &uvmv, 0, 0, 8, 4, 4, 4, w1, h1, 0); uvmv = ROUNDED_DIV_MVx2(b->mv[1][0], b->mv[3][0]); - mc_chroma_dir(s, mc[4][b->filter][0], - s->dst[1] + 4 * bytesperpixel, - s->dst[2] + 4 * bytesperpixel, ls_uv, + mc_chroma_dir(td, mc[4][b->filter][0], + td->dst[1] + 4 * bytesperpixel, + td->dst[2] + 4 * bytesperpixel, ls_uv, ref1->data[1], ref1->linesize[1], ref1->data[2], ref1->linesize[2], tref1, row << 2, (col << 3) + 4, @@ -262,8 +262,8 @@ static void FN(inter_pred)(AVCodecContext *avctx) if (s->ss_h) { w1 = (w1 + 1) >> 1; uvmv = ROUNDED_DIV_MVx2(b->mv[0][0], b->mv[1][0]); - mc_chroma_dir(s, mc[4][b->filter][0], - s->dst[1], s->dst[2], ls_uv, + mc_chroma_dir(td, mc[4][b->filter][0], + td->dst[1], td->dst[2], ls_uv, ref1->data[1], ref1->linesize[1], ref1->data[2], ref1->linesize[2], tref1, row << 3, col << 2, @@ -272,35 +272,35 @@ static void FN(inter_pred)(AVCodecContext *avctx) // bottom block // https://code.google.com/p/webm/issues/detail?id=993 uvmv = ROUNDED_DIV_MVx2(b->mv[1][0], b->mv[2][0]); - mc_chroma_dir(s, mc[4][b->filter][0], - s->dst[1] + 4 * ls_uv, s->dst[2] + 4 * ls_uv, ls_uv, + mc_chroma_dir(td, mc[4][b->filter][0], + td->dst[1] + 4 * ls_uv, td->dst[2] + 4 * ls_uv, ls_uv, ref1->data[1], ref1->linesize[1], ref1->data[2], ref1->linesize[2], tref1, (row << 3) + 4, col << 2, &uvmv, 0, 4, 4, 8, 4, 4, w1, h1, 0); } else { - mc_chroma_dir(s, mc[4][b->filter][0], - s->dst[1], s->dst[2], ls_uv, + mc_chroma_dir(td, mc[4][b->filter][0], + td->dst[1], td->dst[2], ls_uv, ref1->data[1], ref1->linesize[1], ref1->data[2], ref1->linesize[2], tref1, row << 3, col << 3, &b->mv[0][0], 0, 0, 8, 8, 4, 4, w1, h1, 0); - mc_chroma_dir(s, mc[4][b->filter][0], - s->dst[1] + 4 * bytesperpixel, - s->dst[2] + 4 * bytesperpixel, ls_uv, + mc_chroma_dir(td, mc[4][b->filter][0], + td->dst[1] + 4 * bytesperpixel, + td->dst[2] + 4 * bytesperpixel, ls_uv, ref1->data[1], ref1->linesize[1], ref1->data[2], ref1->linesize[2], tref1, row << 3, (col << 3) + 4, &b->mv[1][0], 4, 0, 8, 8, 4, 4, w1, h1, 0); - mc_chroma_dir(s, mc[4][b->filter][0], - s->dst[1] + 4 * ls_uv, s->dst[2] + 4 * ls_uv, ls_uv, + mc_chroma_dir(td, mc[4][b->filter][0], + td->dst[1] + 4 * ls_uv, td->dst[2] + 4 * ls_uv, ls_uv, ref1->data[1], ref1->linesize[1], ref1->data[2], ref1->linesize[2], tref1, (row << 3) + 4, col << 3, &b->mv[2][0], 0, 4, 8, 8, 4, 4, w1, h1, 0); - mc_chroma_dir(s, mc[4][b->filter][0], - s->dst[1] + 4 * ls_uv + 4 * bytesperpixel, - s->dst[2] + 4 * ls_uv + 4 * bytesperpixel, ls_uv, + mc_chroma_dir(td, mc[4][b->filter][0], + td->dst[1] + 4 * ls_uv + 4 * bytesperpixel, + td->dst[2] + 4 * ls_uv + 4 * bytesperpixel, ls_uv, ref1->data[1], ref1->linesize[1], ref1->data[2], ref1->linesize[2], tref1, (row << 3) + 4, (col << 3) + 4, @@ -309,18 +309,18 @@ static void FN(inter_pred)(AVCodecContext *avctx) } if (b->comp) { - mc_luma_dir(s, mc[4][b->filter][1], s->dst[0], ls_y, + mc_luma_dir(td, mc[4][b->filter][1], td->dst[0], ls_y, ref2->data[0], ref2->linesize[0], tref2, row << 3, col << 3, &b->mv[0][1], 0, 0, 8, 8, 4, 4, w2, h2, 1); - mc_luma_dir(s, mc[4][b->filter][1], s->dst[0] + 4 * bytesperpixel, ls_y, + mc_luma_dir(td, mc[4][b->filter][1], td->dst[0] + 4 * bytesperpixel, ls_y, ref2->data[0], ref2->linesize[0], tref2, row << 3, (col << 3) + 4, &b->mv[1][1], 4, 0, 8, 8, 4, 4, w2, h2, 1); - mc_luma_dir(s, mc[4][b->filter][1], - s->dst[0] + 4 * ls_y, ls_y, + mc_luma_dir(td, mc[4][b->filter][1], + td->dst[0] + 4 * ls_y, ls_y, ref2->data[0], ref2->linesize[0], tref2, (row << 3) + 4, col << 3, &b->mv[2][1], 0, 4, 8, 8, 4, 4, w2, h2, 1); - mc_luma_dir(s, mc[4][b->filter][1], - s->dst[0] + 4 * ls_y + 4 * bytesperpixel, ls_y, + mc_luma_dir(td, mc[4][b->filter][1], + td->dst[0] + 4 * ls_y + 4 * bytesperpixel, ls_y, ref2->data[0], ref2->linesize[0], tref2, (row << 3) + 4, (col << 3) + 4, &b->mv[3][1], 4, 4, 8, 8, 4, 4, w2, h2, 1); if (s->ss_v) { @@ -329,24 +329,24 @@ static void FN(inter_pred)(AVCodecContext *avctx) w2 = (w2 + 1) >> 1; uvmv = ROUNDED_DIV_MVx4(b->mv[0][1], b->mv[1][1], b->mv[2][1], b->mv[3][1]); - mc_chroma_dir(s, mc[4][b->filter][1], - s->dst[1], s->dst[2], ls_uv, + mc_chroma_dir(td, mc[4][b->filter][1], + td->dst[1], td->dst[2], ls_uv, ref2->data[1], ref2->linesize[1], ref2->data[2], ref2->linesize[2], tref2, row << 2, col << 2, &uvmv, 0, 0, 4, 4, 4, 4, w2, h2, 1); } else { uvmv = ROUNDED_DIV_MVx2(b->mv[0][1], b->mv[2][1]); - mc_chroma_dir(s, mc[4][b->filter][1], - s->dst[1], s->dst[2], ls_uv, + mc_chroma_dir(td, mc[4][b->filter][1], + td->dst[1], td->dst[2], ls_uv, ref2->data[1], ref2->linesize[1], ref2->data[2], ref2->linesize[2], tref2, row << 2, col << 3, &uvmv, 0, 0, 8, 4, 4, 4, w2, h2, 1); uvmv = ROUNDED_DIV_MVx2(b->mv[1][1], b->mv[3][1]); - mc_chroma_dir(s, mc[4][b->filter][1], - s->dst[1] + 4 * bytesperpixel, - s->dst[2] + 4 * bytesperpixel, ls_uv, + mc_chroma_dir(td, mc[4][b->filter][1], + td->dst[1] + 4 * bytesperpixel, + td->dst[2] + 4 * bytesperpixel, ls_uv, ref2->data[1], ref2->linesize[1], ref2->data[2], ref2->linesize[2], tref2, row << 2, (col << 3) + 4, @@ -356,8 +356,8 @@ static void FN(inter_pred)(AVCodecContext *avctx) if (s->ss_h) { w2 = (w2 + 1) >> 1; uvmv = ROUNDED_DIV_MVx2(b->mv[0][1], b->mv[1][1]); - mc_chroma_dir(s, mc[4][b->filter][1], - s->dst[1], s->dst[2], ls_uv, + mc_chroma_dir(td, mc[4][b->filter][1], + td->dst[1], td->dst[2], ls_uv, ref2->data[1], ref2->linesize[1], ref2->data[2], ref2->linesize[2], tref2, row << 3, col << 2, @@ -366,35 +366,35 @@ static void FN(inter_pred)(AVCodecContext *avctx) // bottom block // https://code.google.com/p/webm/issues/detail?id=993 uvmv = ROUNDED_DIV_MVx2(b->mv[1][1], b->mv[2][1]); - mc_chroma_dir(s, mc[4][b->filter][1], - s->dst[1] + 4 * ls_uv, s->dst[2] + 4 * ls_uv, ls_uv, + mc_chroma_dir(td, mc[4][b->filter][1], + td->dst[1] + 4 * ls_uv, td->dst[2] + 4 * ls_uv, ls_uv, ref2->data[1], ref2->linesize[1], ref2->data[2], ref2->linesize[2], tref2, (row << 3) + 4, col << 2, &uvmv, 0, 4, 4, 8, 4, 4, w2, h2, 1); } else { - mc_chroma_dir(s, mc[4][b->filter][1], - s->dst[1], s->dst[2], ls_uv, + mc_chroma_dir(td, mc[4][b->filter][1], + td->dst[1], td->dst[2], ls_uv, ref2->data[1], ref2->linesize[1], ref2->data[2], ref2->linesize[2], tref2, row << 3, col << 3, &b->mv[0][1], 0, 0, 8, 8, 4, 4, w2, h2, 1); - mc_chroma_dir(s, mc[4][b->filter][1], - s->dst[1] + 4 * bytesperpixel, - s->dst[2] + 4 * bytesperpixel, ls_uv, + mc_chroma_dir(td, mc[4][b->filter][1], + td->dst[1] + 4 * bytesperpixel, + td->dst[2] + 4 * bytesperpixel, ls_uv, ref2->data[1], ref2->linesize[1], ref2->data[2], ref2->linesize[2], tref2, row << 3, (col << 3) + 4, &b->mv[1][1], 4, 0, 8, 8, 4, 4, w2, h2, 1); - mc_chroma_dir(s, mc[4][b->filter][1], - s->dst[1] + 4 * ls_uv, s->dst[2] + 4 * ls_uv, ls_uv, + mc_chroma_dir(td, mc[4][b->filter][1], + td->dst[1] + 4 * ls_uv, td->dst[2] + 4 * ls_uv, ls_uv, ref2->data[1], ref2->linesize[1], ref2->data[2], ref2->linesize[2], tref2, (row << 3) + 4, col << 3, &b->mv[2][1], 0, 4, 8, 8, 4, 4, w2, h2, 1); - mc_chroma_dir(s, mc[4][b->filter][1], - s->dst[1] + 4 * ls_uv + 4 * bytesperpixel, - s->dst[2] + 4 * ls_uv + 4 * bytesperpixel, ls_uv, + mc_chroma_dir(td, mc[4][b->filter][1], + td->dst[1] + 4 * ls_uv + 4 * bytesperpixel, + td->dst[2] + 4 * ls_uv + 4 * bytesperpixel, ls_uv, ref2->data[1], ref2->linesize[1], ref2->data[2], ref2->linesize[2], tref2, (row << 3) + 4, (col << 3) + 4, @@ -410,26 +410,26 @@ static void FN(inter_pred)(AVCodecContext *avctx) int uvbw = ff_vp9_bwh_tab[s->ss_h][b->bs][0] * 4; int uvbh = ff_vp9_bwh_tab[s->ss_v][b->bs][1] * 4; - mc_luma_dir(s, mc[bwl][b->filter][0], s->dst[0], ls_y, + mc_luma_dir(td, mc[bwl][b->filter][0], td->dst[0], ls_y, ref1->data[0], ref1->linesize[0], tref1, row << 3, col << 3, &b->mv[0][0], 0, 0, bw, bh, bw, bh, w1, h1, 0); w1 = (w1 + s->ss_h) >> s->ss_h; h1 = (h1 + s->ss_v) >> s->ss_v; - mc_chroma_dir(s, mc[bwl + s->ss_h][b->filter][0], - s->dst[1], s->dst[2], ls_uv, + mc_chroma_dir(td, mc[bwl + s->ss_h][b->filter][0], + td->dst[1], td->dst[2], ls_uv, ref1->data[1], ref1->linesize[1], ref1->data[2], ref1->linesize[2], tref1, row << (3 - s->ss_v), col << (3 - s->ss_h), &b->mv[0][0], 0, 0, uvbw, uvbh, uvbw, uvbh, w1, h1, 0); if (b->comp) { - mc_luma_dir(s, mc[bwl][b->filter][1], s->dst[0], ls_y, + mc_luma_dir(td, mc[bwl][b->filter][1], td->dst[0], ls_y, ref2->data[0], ref2->linesize[0], tref2, row << 3, col << 3, &b->mv[0][1], 0, 0, bw, bh, bw, bh, w2, h2, 1); w2 = (w2 + s->ss_h) >> s->ss_h; h2 = (h2 + s->ss_v) >> s->ss_v; - mc_chroma_dir(s, mc[bwl + s->ss_h][b->filter][1], - s->dst[1], s->dst[2], ls_uv, + mc_chroma_dir(td, mc[bwl + s->ss_h][b->filter][1], + td->dst[1], td->dst[2], ls_uv, ref2->data[1], ref2->linesize[1], ref2->data[2], ref2->linesize[2], tref2, row << (3 - s->ss_v), col << (3 - s->ss_h), diff --git a/libavcodec/vp9block.c b/libavcodec/vp9block.c index a16ccdc..96c28b9 100644 --- a/libavcodec/vp9block.c +++ b/libavcodec/vp9block.c @@ -77,7 +77,7 @@ static av_always_inline void setctx_2d(uint8_t *ptr, int w, int h, } } -static void decode_mode(AVCodecContext *avctx) +static void decode_mode(VP9TileData *td) { static const uint8_t left_ctx[N_BS_SIZES] = { 0x0, 0x8, 0x0, 0x8, 0xc, 0x8, 0xc, 0xe, 0xc, 0xe, 0xf, 0xe, 0xf @@ -89,25 +89,25 @@ static void decode_mode(AVCodecContext *avctx) TX_32X32, TX_32X32, TX_32X32, TX_32X32, TX_16X16, TX_16X16, TX_16X16, TX_8X8, TX_8X8, TX_8X8, TX_4X4, TX_4X4, TX_4X4 }; - VP9Context *s = avctx->priv_data; - VP9Block *b = s->b; - int row = s->row, col = s->col, row7 = s->row7; + VP9Context *s = td->s; + VP9Block *b = td->b; + int row = td->row, col = td->col, row7 = td->row7; enum TxfmMode max_tx = max_tx_for_bl_bp[b->bs]; int bw4 = ff_vp9_bwh_tab[1][b->bs][0], w4 = FFMIN(s->cols - col, bw4); int bh4 = ff_vp9_bwh_tab[1][b->bs][1], h4 = FFMIN(s->rows - row, bh4), y; - int have_a = row > 0, have_l = col > s->tile_col_start; + int have_a = row > 0, have_l = col > td->tile_col_start; int vref, filter_id; if (!s->s.h.segmentation.enabled) { b->seg_id = 0; } else if (s->s.h.keyframe || s->s.h.intraonly) { b->seg_id = !s->s.h.segmentation.update_map ? 0 : - vp8_rac_get_tree(&s->c, ff_vp9_segmentation_tree, s->s.h.segmentation.prob); + vp8_rac_get_tree(&td->c, ff_vp9_segmentation_tree, s->s.h.segmentation.prob); } else if (!s->s.h.segmentation.update_map || (s->s.h.segmentation.temporal && - vp56_rac_get_prob_branchy(&s->c, + vp56_rac_get_prob_branchy(&td->c, s->s.h.segmentation.pred_prob[s->above_segpred_ctx[col] + - s->left_segpred_ctx[row7]]))) { + td->left_segpred_ctx[row7]]))) { if (!s->s.h.errorres && s->s.frames[REF_FRAME_SEGMAP].segmentation_map) { int pred = 8, x; uint8_t *refsegmap = s->s.frames[REF_FRAME_SEGMAP].segmentation_map; @@ -126,13 +126,13 @@ static void decode_mode(AVCodecContext *avctx) } memset(&s->above_segpred_ctx[col], 1, w4); - memset(&s->left_segpred_ctx[row7], 1, h4); + memset(&td->left_segpred_ctx[row7], 1, h4); } else { - b->seg_id = vp8_rac_get_tree(&s->c, ff_vp9_segmentation_tree, + b->seg_id = vp8_rac_get_tree(&td->c, ff_vp9_segmentation_tree, s->s.h.segmentation.prob); memset(&s->above_segpred_ctx[col], 0, w4); - memset(&s->left_segpred_ctx[row7], 0, h4); + memset(&td->left_segpred_ctx[row7], 0, h4); } if (s->s.h.segmentation.enabled && (s->s.h.segmentation.update_map || s->s.h.keyframe || s->s.h.intraonly)) { @@ -143,9 +143,9 @@ static void decode_mode(AVCodecContext *avctx) b->skip = s->s.h.segmentation.enabled && s->s.h.segmentation.feat[b->seg_id].skip_enabled; if (!b->skip) { - int c = s->left_skip_ctx[row7] + s->above_skip_ctx[col]; - b->skip = vp56_rac_get_prob(&s->c, s->prob.p.skip[c]); - s->counts.skip[c][b->skip]++; + int c = td->left_skip_ctx[row7] + s->above_skip_ctx[col]; + b->skip = vp56_rac_get_prob(&td->c, s->prob.p.skip[c]); + td->counts.skip[c][b->skip]++; } if (s->s.h.keyframe || s->s.h.intraonly) { @@ -156,14 +156,14 @@ static void decode_mode(AVCodecContext *avctx) int c, bit; if (have_a && have_l) { - c = s->above_intra_ctx[col] + s->left_intra_ctx[row7]; + c = s->above_intra_ctx[col] + td->left_intra_ctx[row7]; c += (c == 2); } else { c = have_a ? 2 * s->above_intra_ctx[col] : - have_l ? 2 * s->left_intra_ctx[row7] : 0; + have_l ? 2 * td->left_intra_ctx[row7] : 0; } - bit = vp56_rac_get_prob(&s->c, s->prob.p.intra[c]); - s->counts.intra[c][bit]++; + bit = vp56_rac_get_prob(&td->c, s->prob.p.intra[c]); + td->counts.intra[c][bit]++; b->intra = !bit; } @@ -173,37 +173,37 @@ static void decode_mode(AVCodecContext *avctx) if (have_l) { c = (s->above_skip_ctx[col] ? max_tx : s->above_txfm_ctx[col]) + - (s->left_skip_ctx[row7] ? max_tx : - s->left_txfm_ctx[row7]) > max_tx; + (td->left_skip_ctx[row7] ? max_tx : + td->left_txfm_ctx[row7]) > max_tx; } else { c = s->above_skip_ctx[col] ? 1 : (s->above_txfm_ctx[col] * 2 > max_tx); } } else if (have_l) { - c = s->left_skip_ctx[row7] ? 1 : - (s->left_txfm_ctx[row7] * 2 > max_tx); + c = td->left_skip_ctx[row7] ? 1 : + (td->left_txfm_ctx[row7] * 2 > max_tx); } else { c = 1; } switch (max_tx) { case TX_32X32: - b->tx = vp56_rac_get_prob(&s->c, s->prob.p.tx32p[c][0]); + b->tx = vp56_rac_get_prob(&td->c, s->prob.p.tx32p[c][0]); if (b->tx) { - b->tx += vp56_rac_get_prob(&s->c, s->prob.p.tx32p[c][1]); + b->tx += vp56_rac_get_prob(&td->c, s->prob.p.tx32p[c][1]); if (b->tx == 2) - b->tx += vp56_rac_get_prob(&s->c, s->prob.p.tx32p[c][2]); + b->tx += vp56_rac_get_prob(&td->c, s->prob.p.tx32p[c][2]); } - s->counts.tx32p[c][b->tx]++; + td->counts.tx32p[c][b->tx]++; break; case TX_16X16: - b->tx = vp56_rac_get_prob(&s->c, s->prob.p.tx16p[c][0]); + b->tx = vp56_rac_get_prob(&td->c, s->prob.p.tx16p[c][0]); if (b->tx) - b->tx += vp56_rac_get_prob(&s->c, s->prob.p.tx16p[c][1]); - s->counts.tx16p[c][b->tx]++; + b->tx += vp56_rac_get_prob(&td->c, s->prob.p.tx16p[c][1]); + td->counts.tx16p[c][b->tx]++; break; case TX_8X8: - b->tx = vp56_rac_get_prob(&s->c, s->prob.p.tx8p[c]); - s->counts.tx8p[c][b->tx]++; + b->tx = vp56_rac_get_prob(&td->c, s->prob.p.tx8p[c]); + td->counts.tx8p[c][b->tx]++; break; case TX_4X4: b->tx = TX_4X4; @@ -215,7 +215,7 @@ static void decode_mode(AVCodecContext *avctx) if (s->s.h.keyframe || s->s.h.intraonly) { uint8_t *a = &s->above_mode_ctx[col * 2]; - uint8_t *l = &s->left_mode_ctx[(row7) << 1]; + uint8_t *l = &td->left_mode_ctx[(row7) << 1]; b->comp = 0; if (b->bs > BS_8x8) { @@ -223,10 +223,10 @@ static void decode_mode(AVCodecContext *avctx) // necessary, they're just there to make the code slightly // simpler for now b->mode[0] = - a[0] = vp8_rac_get_tree(&s->c, ff_vp9_intramode_tree, + a[0] = vp8_rac_get_tree(&td->c, ff_vp9_intramode_tree, ff_vp9_default_kf_ymode_probs[a[0]][l[0]]); if (b->bs != BS_8x4) { - b->mode[1] = vp8_rac_get_tree(&s->c, ff_vp9_intramode_tree, + b->mode[1] = vp8_rac_get_tree(&td->c, ff_vp9_intramode_tree, ff_vp9_default_kf_ymode_probs[a[1]][b->mode[0]]); l[0] = a[1] = b->mode[1]; @@ -237,10 +237,10 @@ static void decode_mode(AVCodecContext *avctx) } if (b->bs != BS_4x8) { b->mode[2] = - a[0] = vp8_rac_get_tree(&s->c, ff_vp9_intramode_tree, + a[0] = vp8_rac_get_tree(&td->c, ff_vp9_intramode_tree, ff_vp9_default_kf_ymode_probs[a[0]][l[1]]); if (b->bs != BS_8x4) { - b->mode[3] = vp8_rac_get_tree(&s->c, ff_vp9_intramode_tree, + b->mode[3] = vp8_rac_get_tree(&td->c, ff_vp9_intramode_tree, ff_vp9_default_kf_ymode_probs[a[1]][b->mode[2]]); l[1] = a[1] = b->mode[3]; @@ -256,7 +256,7 @@ static void decode_mode(AVCodecContext *avctx) b->mode[3] = b->mode[1]; } } else { - b->mode[0] = vp8_rac_get_tree(&s->c, ff_vp9_intramode_tree, + b->mode[0] = vp8_rac_get_tree(&td->c, ff_vp9_intramode_tree, ff_vp9_default_kf_ymode_probs[*a][*l]); b->mode[3] = b->mode[2] = @@ -265,29 +265,29 @@ static void decode_mode(AVCodecContext *avctx) memset(a, b->mode[0], ff_vp9_bwh_tab[0][b->bs][0]); memset(l, b->mode[0], ff_vp9_bwh_tab[0][b->bs][1]); } - b->uvmode = vp8_rac_get_tree(&s->c, ff_vp9_intramode_tree, + b->uvmode = vp8_rac_get_tree(&td->c, ff_vp9_intramode_tree, ff_vp9_default_kf_uvmode_probs[b->mode[3]]); } else if (b->intra) { b->comp = 0; if (b->bs > BS_8x8) { - b->mode[0] = vp8_rac_get_tree(&s->c, ff_vp9_intramode_tree, + b->mode[0] = vp8_rac_get_tree(&td->c, ff_vp9_intramode_tree, s->prob.p.y_mode[0]); - s->counts.y_mode[0][b->mode[0]]++; + td->counts.y_mode[0][b->mode[0]]++; if (b->bs != BS_8x4) { - b->mode[1] = vp8_rac_get_tree(&s->c, ff_vp9_intramode_tree, + b->mode[1] = vp8_rac_get_tree(&td->c, ff_vp9_intramode_tree, s->prob.p.y_mode[0]); - s->counts.y_mode[0][b->mode[1]]++; + td->counts.y_mode[0][b->mode[1]]++; } else { b->mode[1] = b->mode[0]; } if (b->bs != BS_4x8) { - b->mode[2] = vp8_rac_get_tree(&s->c, ff_vp9_intramode_tree, + b->mode[2] = vp8_rac_get_tree(&td->c, ff_vp9_intramode_tree, s->prob.p.y_mode[0]); - s->counts.y_mode[0][b->mode[2]]++; + td->counts.y_mode[0][b->mode[2]]++; if (b->bs != BS_8x4) { - b->mode[3] = vp8_rac_get_tree(&s->c, ff_vp9_intramode_tree, + b->mode[3] = vp8_rac_get_tree(&td->c, ff_vp9_intramode_tree, s->prob.p.y_mode[0]); - s->counts.y_mode[0][b->mode[3]]++; + td->counts.y_mode[0][b->mode[3]]++; } else { b->mode[3] = b->mode[2]; } @@ -301,16 +301,16 @@ static void decode_mode(AVCodecContext *avctx) }; int sz = size_group[b->bs]; - b->mode[0] = vp8_rac_get_tree(&s->c, ff_vp9_intramode_tree, + b->mode[0] = vp8_rac_get_tree(&td->c, ff_vp9_intramode_tree, s->prob.p.y_mode[sz]); b->mode[1] = b->mode[2] = b->mode[3] = b->mode[0]; - s->counts.y_mode[sz][b->mode[3]]++; + td->counts.y_mode[sz][b->mode[3]]++; } - b->uvmode = vp8_rac_get_tree(&s->c, ff_vp9_intramode_tree, + b->uvmode = vp8_rac_get_tree(&td->c, ff_vp9_intramode_tree, s->prob.p.uv_mode[b->mode[3]]); - s->counts.uv_mode[b->mode[3]][b->uvmode]++; + td->counts.uv_mode[b->mode[3]][b->uvmode]++; } else { static const uint8_t inter_mode_ctx_lut[14][14] = { { 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 5, 5, 5, 5 }, @@ -343,32 +343,32 @@ static void decode_mode(AVCodecContext *avctx) // FIXME add intra as ref=0xff (or -1) to make these easier? if (have_a) { if (have_l) { - if (s->above_comp_ctx[col] && s->left_comp_ctx[row7]) { + if (s->above_comp_ctx[col] && td->left_comp_ctx[row7]) { c = 4; } else if (s->above_comp_ctx[col]) { - c = 2 + (s->left_intra_ctx[row7] || - s->left_ref_ctx[row7] == s->s.h.fixcompref); - } else if (s->left_comp_ctx[row7]) { + c = 2 + (td->left_intra_ctx[row7] || + td->left_ref_ctx[row7] == s->s.h.fixcompref); + } else if (td->left_comp_ctx[row7]) { c = 2 + (s->above_intra_ctx[col] || s->above_ref_ctx[col] == s->s.h.fixcompref); } else { c = (!s->above_intra_ctx[col] && s->above_ref_ctx[col] == s->s.h.fixcompref) ^ - (!s->left_intra_ctx[row7] && - s->left_ref_ctx[row & 7] == s->s.h.fixcompref); + (!td->left_intra_ctx[row7] && + td->left_ref_ctx[row & 7] == s->s.h.fixcompref); } } else { c = s->above_comp_ctx[col] ? 3 : (!s->above_intra_ctx[col] && s->above_ref_ctx[col] == s->s.h.fixcompref); } } else if (have_l) { - c = s->left_comp_ctx[row7] ? 3 : - (!s->left_intra_ctx[row7] && s->left_ref_ctx[row7] == s->s.h.fixcompref); + c = td->left_comp_ctx[row7] ? 3 : + (!td->left_intra_ctx[row7] && td->left_ref_ctx[row7] == s->s.h.fixcompref); } else { c = 1; } - b->comp = vp56_rac_get_prob(&s->c, s->prob.p.comp[c]); - s->counts.comp[c][b->comp]++; + b->comp = vp56_rac_get_prob(&td->c, s->prob.p.comp[c]); + td->counts.comp[c][b->comp]++; } // read actual references @@ -382,26 +382,26 @@ static void decode_mode(AVCodecContext *avctx) if (have_a) { if (have_l) { if (s->above_intra_ctx[col]) { - if (s->left_intra_ctx[row7]) { + if (td->left_intra_ctx[row7]) { c = 2; } else { - c = 1 + 2 * (s->left_ref_ctx[row7] != s->s.h.varcompref[1]); + c = 1 + 2 * (td->left_ref_ctx[row7] != s->s.h.varcompref[1]); } - } else if (s->left_intra_ctx[row7]) { + } else if (td->left_intra_ctx[row7]) { c = 1 + 2 * (s->above_ref_ctx[col] != s->s.h.varcompref[1]); } else { - int refl = s->left_ref_ctx[row7], refa = s->above_ref_ctx[col]; + int refl = td->left_ref_ctx[row7], refa = s->above_ref_ctx[col]; if (refl == refa && refa == s->s.h.varcompref[1]) { c = 0; - } else if (!s->left_comp_ctx[row7] && !s->above_comp_ctx[col]) { + } else if (!td->left_comp_ctx[row7] && !s->above_comp_ctx[col]) { if ((refa == s->s.h.fixcompref && refl == s->s.h.varcompref[0]) || (refl == s->s.h.fixcompref && refa == s->s.h.varcompref[0])) { c = 4; } else { c = (refa == refl) ? 3 : 1; } - } else if (!s->left_comp_ctx[row7]) { + } else if (!td->left_comp_ctx[row7]) { if (refa == s->s.h.varcompref[1] && refl != s->s.h.varcompref[1]) { c = 1; } else { @@ -429,37 +429,37 @@ static void decode_mode(AVCodecContext *avctx) } } } else if (have_l) { - if (s->left_intra_ctx[row7]) { + if (td->left_intra_ctx[row7]) { c = 2; - } else if (s->left_comp_ctx[row7]) { - c = 4 * (s->left_ref_ctx[row7] != s->s.h.varcompref[1]); + } else if (td->left_comp_ctx[row7]) { + c = 4 * (td->left_ref_ctx[row7] != s->s.h.varcompref[1]); } else { - c = 3 * (s->left_ref_ctx[row7] != s->s.h.varcompref[1]); + c = 3 * (td->left_ref_ctx[row7] != s->s.h.varcompref[1]); } } else { c = 2; } - bit = vp56_rac_get_prob(&s->c, s->prob.p.comp_ref[c]); + bit = vp56_rac_get_prob(&td->c, s->prob.p.comp_ref[c]); b->ref[var_idx] = s->s.h.varcompref[bit]; - s->counts.comp_ref[c][bit]++; + td->counts.comp_ref[c][bit]++; } else /* single reference */ { int bit, c; if (have_a && !s->above_intra_ctx[col]) { - if (have_l && !s->left_intra_ctx[row7]) { - if (s->left_comp_ctx[row7]) { + if (have_l && !td->left_intra_ctx[row7]) { + if (td->left_comp_ctx[row7]) { if (s->above_comp_ctx[col]) { - c = 1 + (!s->s.h.fixcompref || !s->left_ref_ctx[row7] || + c = 1 + (!s->s.h.fixcompref || !td->left_ref_ctx[row7] || !s->above_ref_ctx[col]); } else { c = (3 * !s->above_ref_ctx[col]) + - (!s->s.h.fixcompref || !s->left_ref_ctx[row7]); + (!s->s.h.fixcompref || !td->left_ref_ctx[row7]); } } else if (s->above_comp_ctx[col]) { - c = (3 * !s->left_ref_ctx[row7]) + + c = (3 * !td->left_ref_ctx[row7]) + (!s->s.h.fixcompref || !s->above_ref_ctx[col]); } else { - c = 2 * !s->left_ref_ctx[row7] + 2 * !s->above_ref_ctx[col]; + c = 2 * !td->left_ref_ctx[row7] + 2 * !s->above_ref_ctx[col]; } } else if (s->above_intra_ctx[col]) { c = 2; @@ -468,26 +468,26 @@ static void decode_mode(AVCodecContext *avctx) } else { c = 4 * (!s->above_ref_ctx[col]); } - } else if (have_l && !s->left_intra_ctx[row7]) { - if (s->left_intra_ctx[row7]) { + } else if (have_l && !td->left_intra_ctx[row7]) { + if (td->left_intra_ctx[row7]) { c = 2; - } else if (s->left_comp_ctx[row7]) { - c = 1 + (!s->s.h.fixcompref || !s->left_ref_ctx[row7]); + } else if (td->left_comp_ctx[row7]) { + c = 1 + (!s->s.h.fixcompref || !td->left_ref_ctx[row7]); } else { - c = 4 * (!s->left_ref_ctx[row7]); + c = 4 * (!td->left_ref_ctx[row7]); } } else { c = 2; } - bit = vp56_rac_get_prob(&s->c, s->prob.p.single_ref[c][0]); - s->counts.single_ref[c][0][bit]++; + bit = vp56_rac_get_prob(&td->c, s->prob.p.single_ref[c][0]); + td->counts.single_ref[c][0][bit]++; if (!bit) { b->ref[0] = 0; } else { // FIXME can this codeblob be replaced by some sort of LUT? if (have_a) { if (have_l) { - if (s->left_intra_ctx[row7]) { + if (td->left_intra_ctx[row7]) { if (s->above_intra_ctx[col]) { c = 2; } else if (s->above_comp_ctx[col]) { @@ -499,49 +499,49 @@ static void decode_mode(AVCodecContext *avctx) c = 4 * (s->above_ref_ctx[col] == 1); } } else if (s->above_intra_ctx[col]) { - if (s->left_intra_ctx[row7]) { + if (td->left_intra_ctx[row7]) { c = 2; - } else if (s->left_comp_ctx[row7]) { + } else if (td->left_comp_ctx[row7]) { c = 1 + 2 * (s->s.h.fixcompref == 1 || - s->left_ref_ctx[row7] == 1); - } else if (!s->left_ref_ctx[row7]) { + td->left_ref_ctx[row7] == 1); + } else if (!td->left_ref_ctx[row7]) { c = 3; } else { - c = 4 * (s->left_ref_ctx[row7] == 1); + c = 4 * (td->left_ref_ctx[row7] == 1); } } else if (s->above_comp_ctx[col]) { - if (s->left_comp_ctx[row7]) { - if (s->left_ref_ctx[row7] == s->above_ref_ctx[col]) { + if (td->left_comp_ctx[row7]) { + if (td->left_ref_ctx[row7] == s->above_ref_ctx[col]) { c = 3 * (s->s.h.fixcompref == 1 || - s->left_ref_ctx[row7] == 1); + td->left_ref_ctx[row7] == 1); } else { c = 2; } - } else if (!s->left_ref_ctx[row7]) { + } else if (!td->left_ref_ctx[row7]) { c = 1 + 2 * (s->s.h.fixcompref == 1 || s->above_ref_ctx[col] == 1); } else { - c = 3 * (s->left_ref_ctx[row7] == 1) + + c = 3 * (td->left_ref_ctx[row7] == 1) + (s->s.h.fixcompref == 1 || s->above_ref_ctx[col] == 1); } - } else if (s->left_comp_ctx[row7]) { + } else if (td->left_comp_ctx[row7]) { if (!s->above_ref_ctx[col]) { c = 1 + 2 * (s->s.h.fixcompref == 1 || - s->left_ref_ctx[row7] == 1); + td->left_ref_ctx[row7] == 1); } else { c = 3 * (s->above_ref_ctx[col] == 1) + - (s->s.h.fixcompref == 1 || s->left_ref_ctx[row7] == 1); + (s->s.h.fixcompref == 1 || td->left_ref_ctx[row7] == 1); } } else if (!s->above_ref_ctx[col]) { - if (!s->left_ref_ctx[row7]) { + if (!td->left_ref_ctx[row7]) { c = 3; } else { - c = 4 * (s->left_ref_ctx[row7] == 1); + c = 4 * (td->left_ref_ctx[row7] == 1); } - } else if (!s->left_ref_ctx[row7]) { + } else if (!td->left_ref_ctx[row7]) { c = 4 * (s->above_ref_ctx[col] == 1); } else { - c = 2 * (s->left_ref_ctx[row7] == 1) + + c = 2 * (td->left_ref_ctx[row7] == 1) + 2 * (s->above_ref_ctx[col] == 1); } } else { @@ -555,19 +555,19 @@ static void decode_mode(AVCodecContext *avctx) } } } else if (have_l) { - if (s->left_intra_ctx[row7] || - (!s->left_comp_ctx[row7] && !s->left_ref_ctx[row7])) { + if (td->left_intra_ctx[row7] || + (!td->left_comp_ctx[row7] && !td->left_ref_ctx[row7])) { c = 2; - } else if (s->left_comp_ctx[row7]) { - c = 3 * (s->s.h.fixcompref == 1 || s->left_ref_ctx[row7] == 1); + } else if (td->left_comp_ctx[row7]) { + c = 3 * (s->s.h.fixcompref == 1 || td->left_ref_ctx[row7] == 1); } else { - c = 4 * (s->left_ref_ctx[row7] == 1); + c = 4 * (td->left_ref_ctx[row7] == 1); } } else { c = 2; } - bit = vp56_rac_get_prob(&s->c, s->prob.p.single_ref[c][1]); - s->counts.single_ref[c][1][bit]++; + bit = vp56_rac_get_prob(&td->c, s->prob.p.single_ref[c][1]); + td->counts.single_ref[c][1][bit]++; b->ref[0] = 1 + bit; } } @@ -587,14 +587,14 @@ static void decode_mode(AVCodecContext *avctx) // FIXME this needs to use the LUT tables from find_ref_mvs // because not all are -1,0/0,-1 int c = inter_mode_ctx_lut[s->above_mode_ctx[col + off[b->bs]]] - [s->left_mode_ctx[row7 + off[b->bs]]]; + [td->left_mode_ctx[row7 + off[b->bs]]]; - b->mode[0] = vp8_rac_get_tree(&s->c, ff_vp9_inter_mode_tree, + b->mode[0] = vp8_rac_get_tree(&td->c, ff_vp9_inter_mode_tree, s->prob.p.mv_mode[c]); b->mode[1] = b->mode[2] = b->mode[3] = b->mode[0]; - s->counts.mv_mode[c][b->mode[0] - 10]++; + td->counts.mv_mode[c][b->mode[0] - 10]++; } } @@ -602,39 +602,39 @@ static void decode_mode(AVCodecContext *avctx) int c; if (have_a && s->above_mode_ctx[col] >= NEARESTMV) { - if (have_l && s->left_mode_ctx[row7] >= NEARESTMV) { - c = s->above_filter_ctx[col] == s->left_filter_ctx[row7] ? - s->left_filter_ctx[row7] : 3; + if (have_l && td->left_mode_ctx[row7] >= NEARESTMV) { + c = s->above_filter_ctx[col] == td->left_filter_ctx[row7] ? + td->left_filter_ctx[row7] : 3; } else { c = s->above_filter_ctx[col]; } - } else if (have_l && s->left_mode_ctx[row7] >= NEARESTMV) { - c = s->left_filter_ctx[row7]; + } else if (have_l && td->left_mode_ctx[row7] >= NEARESTMV) { + c = td->left_filter_ctx[row7]; } else { c = 3; } - filter_id = vp8_rac_get_tree(&s->c, ff_vp9_filter_tree, + filter_id = vp8_rac_get_tree(&td->c, ff_vp9_filter_tree, s->prob.p.filter[c]); - s->counts.filter[c][filter_id]++; + td->counts.filter[c][filter_id]++; b->filter = ff_vp9_filter_lut[filter_id]; } else { b->filter = s->s.h.filtermode; } if (b->bs > BS_8x8) { - int c = inter_mode_ctx_lut[s->above_mode_ctx[col]][s->left_mode_ctx[row7]]; + int c = inter_mode_ctx_lut[s->above_mode_ctx[col]][td->left_mode_ctx[row7]]; - b->mode[0] = vp8_rac_get_tree(&s->c, ff_vp9_inter_mode_tree, + b->mode[0] = vp8_rac_get_tree(&td->c, ff_vp9_inter_mode_tree, s->prob.p.mv_mode[c]); - s->counts.mv_mode[c][b->mode[0] - 10]++; - ff_vp9_fill_mv(s, b->mv[0], b->mode[0], 0); + td->counts.mv_mode[c][b->mode[0] - 10]++; + ff_vp9_fill_mv(td, b->mv[0], b->mode[0], 0); if (b->bs != BS_8x4) { - b->mode[1] = vp8_rac_get_tree(&s->c, ff_vp9_inter_mode_tree, + b->mode[1] = vp8_rac_get_tree(&td->c, ff_vp9_inter_mode_tree, s->prob.p.mv_mode[c]); - s->counts.mv_mode[c][b->mode[1] - 10]++; - ff_vp9_fill_mv(s, b->mv[1], b->mode[1], 1); + td->counts.mv_mode[c][b->mode[1] - 10]++; + ff_vp9_fill_mv(td, b->mv[1], b->mode[1], 1); } else { b->mode[1] = b->mode[0]; AV_COPY32(&b->mv[1][0], &b->mv[0][0]); @@ -642,16 +642,16 @@ static void decode_mode(AVCodecContext *avctx) } if (b->bs != BS_4x8) { - b->mode[2] = vp8_rac_get_tree(&s->c, ff_vp9_inter_mode_tree, + b->mode[2] = vp8_rac_get_tree(&td->c, ff_vp9_inter_mode_tree, s->prob.p.mv_mode[c]); - s->counts.mv_mode[c][b->mode[2] - 10]++; - ff_vp9_fill_mv(s, b->mv[2], b->mode[2], 2); + td->counts.mv_mode[c][b->mode[2] - 10]++; + ff_vp9_fill_mv(td, b->mv[2], b->mode[2], 2); if (b->bs != BS_8x4) { - b->mode[3] = vp8_rac_get_tree(&s->c, ff_vp9_inter_mode_tree, + b->mode[3] = vp8_rac_get_tree(&td->c, ff_vp9_inter_mode_tree, s->prob.p.mv_mode[c]); - s->counts.mv_mode[c][b->mode[3] - 10]++; - ff_vp9_fill_mv(s, b->mv[3], b->mode[3], 3); + td->counts.mv_mode[c][b->mode[3] - 10]++; + ff_vp9_fill_mv(td, b->mv[3], b->mode[3], 3); } else { b->mode[3] = b->mode[2]; AV_COPY32(&b->mv[3][0], &b->mv[2][0]); @@ -666,7 +666,7 @@ static void decode_mode(AVCodecContext *avctx) AV_COPY32(&b->mv[3][1], &b->mv[1][1]); } } else { - ff_vp9_fill_mv(s, b->mv[0], b->mode[0], -1); + ff_vp9_fill_mv(td, b->mv[0], b->mode[0], -1); AV_COPY32(&b->mv[1][0], &b->mv[0][0]); AV_COPY32(&b->mv[2][0], &b->mv[0][0]); AV_COPY32(&b->mv[3][0], &b->mv[0][0]); @@ -716,33 +716,33 @@ static void decode_mode(AVCodecContext *avctx) #endif switch (ff_vp9_bwh_tab[1][b->bs][0]) { -#define SET_CTXS(dir, off, n) \ +#define SET_CTXS(perf, dir, off, n) \ do { \ - SPLAT_CTX(s->dir##_skip_ctx[off], b->skip, n); \ - SPLAT_CTX(s->dir##_txfm_ctx[off], b->tx, n); \ - SPLAT_CTX(s->dir##_partition_ctx[off], dir##_ctx[b->bs], n); \ + SPLAT_CTX(perf->dir##_skip_ctx[off], b->skip, n); \ + SPLAT_CTX(perf->dir##_txfm_ctx[off], b->tx, n); \ + SPLAT_CTX(perf->dir##_partition_ctx[off], dir##_ctx[b->bs], n); \ if (!s->s.h.keyframe && !s->s.h.intraonly) { \ - SPLAT_CTX(s->dir##_intra_ctx[off], b->intra, n); \ - SPLAT_CTX(s->dir##_comp_ctx[off], b->comp, n); \ - SPLAT_CTX(s->dir##_mode_ctx[off], b->mode[3], n); \ + SPLAT_CTX(perf->dir##_intra_ctx[off], b->intra, n); \ + SPLAT_CTX(perf->dir##_comp_ctx[off], b->comp, n); \ + SPLAT_CTX(perf->dir##_mode_ctx[off], b->mode[3], n); \ if (!b->intra) { \ - SPLAT_CTX(s->dir##_ref_ctx[off], vref, n); \ + SPLAT_CTX(perf->dir##_ref_ctx[off], vref, n); \ if (s->s.h.filtermode == FILTER_SWITCHABLE) { \ - SPLAT_CTX(s->dir##_filter_ctx[off], filter_id, n); \ + SPLAT_CTX(perf->dir##_filter_ctx[off], filter_id, n); \ } \ } \ } \ } while (0) - case 1: SET_CTXS(above, col, 1); break; - case 2: SET_CTXS(above, col, 2); break; - case 4: SET_CTXS(above, col, 4); break; - case 8: SET_CTXS(above, col, 8); break; + case 1: SET_CTXS(s, above, col, 1); break; + case 2: SET_CTXS(s, above, col, 2); break; + case 4: SET_CTXS(s, above, col, 4); break; + case 8: SET_CTXS(s, above, col, 8); break; } switch (ff_vp9_bwh_tab[1][b->bs][1]) { - case 1: SET_CTXS(left, row7, 1); break; - case 2: SET_CTXS(left, row7, 2); break; - case 4: SET_CTXS(left, row7, 4); break; - case 8: SET_CTXS(left, row7, 8); break; + case 1: SET_CTXS(td, left, row7, 1); break; + case 2: SET_CTXS(td, left, row7, 2); break; + case 4: SET_CTXS(td, left, row7, 4); break; + case 8: SET_CTXS(td, left, row7, 8); break; } #undef SPLAT_CTX #undef SET_CTXS @@ -751,10 +751,10 @@ static void decode_mode(AVCodecContext *avctx) if (b->bs > BS_8x8) { int mv0 = AV_RN32A(&b->mv[3][0]), mv1 = AV_RN32A(&b->mv[3][1]); - AV_COPY32(&s->left_mv_ctx[row7 * 2 + 0][0], &b->mv[1][0]); - AV_COPY32(&s->left_mv_ctx[row7 * 2 + 0][1], &b->mv[1][1]); - AV_WN32A(&s->left_mv_ctx[row7 * 2 + 1][0], mv0); - AV_WN32A(&s->left_mv_ctx[row7 * 2 + 1][1], mv1); + AV_COPY32(&td->left_mv_ctx[row7 * 2 + 0][0], &b->mv[1][0]); + AV_COPY32(&td->left_mv_ctx[row7 * 2 + 0][1], &b->mv[1][1]); + AV_WN32A(&td->left_mv_ctx[row7 * 2 + 1][0], mv0); + AV_WN32A(&td->left_mv_ctx[row7 * 2 + 1][1], mv1); AV_COPY32(&s->above_mv_ctx[col * 2 + 0][0], &b->mv[2][0]); AV_COPY32(&s->above_mv_ctx[col * 2 + 0][1], &b->mv[2][1]); AV_WN32A(&s->above_mv_ctx[col * 2 + 1][0], mv0); @@ -767,8 +767,8 @@ static void decode_mode(AVCodecContext *avctx) AV_WN32A(&s->above_mv_ctx[col * 2 + n][1], mv1); } for (n = 0; n < h4 * 2; n++) { - AV_WN32A(&s->left_mv_ctx[row7 * 2 + n][0], mv0); - AV_WN32A(&s->left_mv_ctx[row7 * 2 + n][1], mv1); + AV_WN32A(&td->left_mv_ctx[row7 * 2 + n][0], mv0); + AV_WN32A(&td->left_mv_ctx[row7 * 2 + n][1], mv1); } } } @@ -925,54 +925,54 @@ skip_eob: return i; } -static int decode_coeffs_b_8bpp(VP9Context *s, int16_t *coef, int n_coeffs, +static int decode_coeffs_b_8bpp(VP9TileData *td, int16_t *coef, int n_coeffs, unsigned (*cnt)[6][3], unsigned (*eob)[6][2], uint8_t (*p)[6][11], int nnz, const int16_t *scan, const int16_t (*nb)[2], const int16_t *band_counts, const int16_t *qmul) { - return decode_coeffs_b_generic(&s->c, coef, n_coeffs, 0, 1, 8, cnt, eob, p, + return decode_coeffs_b_generic(&td->c, coef, n_coeffs, 0, 1, 8, cnt, eob, p, nnz, scan, nb, band_counts, qmul); } -static int decode_coeffs_b32_8bpp(VP9Context *s, int16_t *coef, int n_coeffs, +static int decode_coeffs_b32_8bpp(VP9TileData *td, int16_t *coef, int n_coeffs, unsigned (*cnt)[6][3], unsigned (*eob)[6][2], uint8_t (*p)[6][11], int nnz, const int16_t *scan, const int16_t (*nb)[2], const int16_t *band_counts, const int16_t *qmul) { - return decode_coeffs_b_generic(&s->c, coef, n_coeffs, 1, 1, 8, cnt, eob, p, + return decode_coeffs_b_generic(&td->c, coef, n_coeffs, 1, 1, 8, cnt, eob, p, nnz, scan, nb, band_counts, qmul); } -static int decode_coeffs_b_16bpp(VP9Context *s, int16_t *coef, int n_coeffs, +static int decode_coeffs_b_16bpp(VP9TileData *td, int16_t *coef, int n_coeffs, unsigned (*cnt)[6][3], unsigned (*eob)[6][2], uint8_t (*p)[6][11], int nnz, const int16_t *scan, const int16_t (*nb)[2], const int16_t *band_counts, const int16_t *qmul) { - return decode_coeffs_b_generic(&s->c, coef, n_coeffs, 0, 0, s->s.h.bpp, cnt, eob, p, + return decode_coeffs_b_generic(&td->c, coef, n_coeffs, 0, 0, td->s->s.h.bpp, cnt, eob, p, nnz, scan, nb, band_counts, qmul); } -static int decode_coeffs_b32_16bpp(VP9Context *s, int16_t *coef, int n_coeffs, +static int decode_coeffs_b32_16bpp(VP9TileData *td, int16_t *coef, int n_coeffs, unsigned (*cnt)[6][3], unsigned (*eob)[6][2], uint8_t (*p)[6][11], int nnz, const int16_t *scan, const int16_t (*nb)[2], const int16_t *band_counts, const int16_t *qmul) { - return decode_coeffs_b_generic(&s->c, coef, n_coeffs, 1, 0, s->s.h.bpp, cnt, eob, p, + return decode_coeffs_b_generic(&td->c, coef, n_coeffs, 1, 0, td->s->s.h.bpp, cnt, eob, p, nnz, scan, nb, band_counts, qmul); } -static av_always_inline int decode_coeffs(AVCodecContext *avctx, int is8bitsperpixel) +static av_always_inline int decode_coeffs(VP9TileData *td, int is8bitsperpixel) { - VP9Context *s = avctx->priv_data; - VP9Block *b = s->b; - int row = s->row, col = s->col; + VP9Context *s = td->s; + VP9Block *b = td->b; + int row = td->row, col = td->col; uint8_t (*p)[6][11] = s->prob.coef[b->tx][0 /* y */][!b->intra]; - unsigned (*c)[6][3] = s->counts.coef[b->tx][0 /* y */][!b->intra]; - unsigned (*e)[6][2] = s->counts.eob[b->tx][0 /* y */][!b->intra]; + unsigned (*c)[6][3] = td->counts.coef[b->tx][0 /* y */][!b->intra]; + unsigned (*e)[6][2] = td->counts.eob[b->tx][0 /* y */][!b->intra]; int w4 = ff_vp9_bwh_tab[1][b->bs][0] << 1, h4 = ff_vp9_bwh_tab[1][b->bs][1] << 1; int end_x = FFMIN(2 * (s->cols - col), w4); int end_y = FFMIN(2 * (s->rows - row), h4); @@ -984,7 +984,7 @@ static av_always_inline int decode_coeffs(AVCodecContext *avctx, int is8bitsperp const int16_t *uvscan = ff_vp9_scans[b->uvtx][DCT_DCT]; const int16_t (*uvnb)[2] = ff_vp9_scans_nb[b->uvtx][DCT_DCT]; uint8_t *a = &s->above_y_nnz_ctx[col * 2]; - uint8_t *l = &s->left_y_nnz_ctx[(row & 7) << 1]; + uint8_t *l = &td->left_y_nnz_ctx[(row & 7) << 1]; static const int16_t band_counts[4][8] = { { 1, 2, 3, 4, 3, 16 - 13 }, { 1, 2, 3, 4, 11, 64 - 21 }, @@ -1010,15 +1010,15 @@ static av_always_inline int decode_coeffs(AVCodecContext *avctx, int is8bitsperp for (x = 0; x < end_x; x += step, n += step * step) { \ enum TxfmType txtp = ff_vp9_intra_txfm_type[b->mode[mode_index]]; \ ret = (is8bitsperpixel ? decode_coeffs_b##v##_8bpp : decode_coeffs_b##v##_16bpp) \ - (s, s->block + 16 * n * bytesperpixel, 16 * step * step, \ + (td, td->block + 16 * n * bytesperpixel, 16 * step * step, \ c, e, p, a[x] + l[y], yscans[txtp], \ ynbs[txtp], y_band_counts, qmul[0]); \ a[x] = l[y] = !!ret; \ total_coeff |= !!ret; \ if (step >= 4) { \ - AV_WN16A(&s->eob[n], ret); \ + AV_WN16A(&td->eob[n], ret); \ } else { \ - s->eob[n] = ret; \ + td->eob[n] = ret; \ } \ } \ } @@ -1084,29 +1084,29 @@ static av_always_inline int decode_coeffs(AVCodecContext *avctx, int is8bitsperp for (n = 0, y = 0; y < end_y; y += step) { \ for (x = 0; x < end_x; x += step, n += step * step) { \ ret = (is8bitsperpixel ? decode_coeffs_b##v##_8bpp : decode_coeffs_b##v##_16bpp) \ - (s, s->uvblock[pl] + 16 * n * bytesperpixel, \ + (td, td->uvblock[pl] + 16 * n * bytesperpixel, \ 16 * step * step, c, e, p, a[x] + l[y], \ uvscan, uvnb, uv_band_counts, qmul[1]); \ a[x] = l[y] = !!ret; \ total_coeff |= !!ret; \ if (step >= 4) { \ - AV_WN16A(&s->uveob[pl][n], ret); \ + AV_WN16A(&td->uveob[pl][n], ret); \ } else { \ - s->uveob[pl][n] = ret; \ + td->uveob[pl][n] = ret; \ } \ } \ } p = s->prob.coef[b->uvtx][1 /* uv */][!b->intra]; - c = s->counts.coef[b->uvtx][1 /* uv */][!b->intra]; - e = s->counts.eob[b->uvtx][1 /* uv */][!b->intra]; + c = td->counts.coef[b->uvtx][1 /* uv */][!b->intra]; + e = td->counts.eob[b->uvtx][1 /* uv */][!b->intra]; w4 >>= s->ss_h; end_x >>= s->ss_h; h4 >>= s->ss_v; end_y >>= s->ss_v; for (pl = 0; pl < 2; pl++) { a = &s->above_uv_nnz_ctx[pl][col << !s->ss_h]; - l = &s->left_uv_nnz_ctx[pl][(row & 7) << !s->ss_v]; + l = &td->left_uv_nnz_ctx[pl][(row & 7) << !s->ss_v]; switch (b->uvtx) { case TX_4X4: DECODE_UV_COEF_LOOP(1,); @@ -1132,14 +1132,14 @@ static av_always_inline int decode_coeffs(AVCodecContext *avctx, int is8bitsperp return total_coeff; } -static int decode_coeffs_8bpp(AVCodecContext *avctx) +static int decode_coeffs_8bpp(VP9TileData *td) { - return decode_coeffs(avctx, 1); + return decode_coeffs(td, 1); } -static int decode_coeffs_16bpp(AVCodecContext *avctx) +static int decode_coeffs_16bpp(VP9TileData *td) { - return decode_coeffs(avctx, 0); + return decode_coeffs(td, 0); } static av_always_inline void mask_edges(uint8_t (*mask)[8][4], int ss_h, int ss_v, @@ -1264,33 +1264,33 @@ static av_always_inline void mask_edges(uint8_t (*mask)[8][4], int ss_h, int ss_ } } -void ff_vp9_decode_block(AVCodecContext *avctx, int row, int col, +void ff_vp9_decode_block(VP9TileData *td, int row, int col, VP9Filter *lflvl, ptrdiff_t yoff, ptrdiff_t uvoff, enum BlockLevel bl, enum BlockPartition bp) { - VP9Context *s = avctx->priv_data; - VP9Block *b = s->b; + VP9Context *s = td->s; + VP9Block *b = td->b; enum BlockSize bs = bl * 3 + bp; int bytesperpixel = s->bytesperpixel; int w4 = ff_vp9_bwh_tab[1][bs][0], h4 = ff_vp9_bwh_tab[1][bs][1], lvl; int emu[2]; AVFrame *f = s->s.frames[CUR_FRAME].tf.f; - s->row = row; - s->row7 = row & 7; - s->col = col; - s->col7 = col & 7; + td->row = row; + td->row7 = row & 7; + td->col = col; + td->col7 = col & 7; - s->min_mv.x = -(128 + col * 64); - s->min_mv.y = -(128 + row * 64); - s->max_mv.x = 128 + (s->cols - col - w4) * 64; - s->max_mv.y = 128 + (s->rows - row - h4) * 64; + td->min_mv.x = -(128 + col * 64); + td->min_mv.y = -(128 + row * 64); + td->max_mv.x = 128 + (s->cols - col - w4) * 64; + td->max_mv.y = 128 + (s->rows - row - h4) * 64; if (s->pass < 2) { b->bs = bs; b->bl = bl; b->bp = bp; - decode_mode(avctx); + decode_mode(td); b->uvtx = b->tx - ((s->ss_h && w4 * 2 == (1 << b->tx)) || (s->ss_v && h4 * 2 == (1 << b->tx))); @@ -1298,17 +1298,17 @@ void ff_vp9_decode_block(AVCodecContext *avctx, int row, int col, int has_coeffs; if (bytesperpixel == 1) { - has_coeffs = decode_coeffs_8bpp(avctx); + has_coeffs = decode_coeffs_8bpp(td); } else { - has_coeffs = decode_coeffs_16bpp(avctx); + has_coeffs = decode_coeffs_16bpp(td); } if (!has_coeffs && b->bs <= BS_8x8 && !b->intra) { b->skip = 1; memset(&s->above_skip_ctx[col], 1, w4); - memset(&s->left_skip_ctx[s->row7], 1, h4); + memset(&td->left_skip_ctx[td->row7], 1, h4); } } else { - int row7 = s->row7; + int row7 = td->row7; #define SPLAT_ZERO_CTX(v, n) \ switch (n) { \ @@ -1320,38 +1320,38 @@ void ff_vp9_decode_block(AVCodecContext *avctx, int row, int col, } #define SPLAT_ZERO_YUV(dir, var, off, n, dir2) \ do { \ - SPLAT_ZERO_CTX(s->dir##_y_##var[off * 2], n * 2); \ + SPLAT_ZERO_CTX(dir##_y_##var[off * 2], n * 2); \ if (s->ss_##dir2) { \ - SPLAT_ZERO_CTX(s->dir##_uv_##var[0][off], n); \ - SPLAT_ZERO_CTX(s->dir##_uv_##var[1][off], n); \ + SPLAT_ZERO_CTX(dir##_uv_##var[0][off], n); \ + SPLAT_ZERO_CTX(dir##_uv_##var[1][off], n); \ } else { \ - SPLAT_ZERO_CTX(s->dir##_uv_##var[0][off * 2], n * 2); \ - SPLAT_ZERO_CTX(s->dir##_uv_##var[1][off * 2], n * 2); \ + SPLAT_ZERO_CTX(dir##_uv_##var[0][off * 2], n * 2); \ + SPLAT_ZERO_CTX(dir##_uv_##var[1][off * 2], n * 2); \ } \ } while (0) switch (w4) { - case 1: SPLAT_ZERO_YUV(above, nnz_ctx, col, 1, h); break; - case 2: SPLAT_ZERO_YUV(above, nnz_ctx, col, 2, h); break; - case 4: SPLAT_ZERO_YUV(above, nnz_ctx, col, 4, h); break; - case 8: SPLAT_ZERO_YUV(above, nnz_ctx, col, 8, h); break; + case 1: SPLAT_ZERO_YUV(s->above, nnz_ctx, col, 1, h); break; + case 2: SPLAT_ZERO_YUV(s->above, nnz_ctx, col, 2, h); break; + case 4: SPLAT_ZERO_YUV(s->above, nnz_ctx, col, 4, h); break; + case 8: SPLAT_ZERO_YUV(s->above, nnz_ctx, col, 8, h); break; } switch (h4) { - case 1: SPLAT_ZERO_YUV(left, nnz_ctx, row7, 1, v); break; - case 2: SPLAT_ZERO_YUV(left, nnz_ctx, row7, 2, v); break; - case 4: SPLAT_ZERO_YUV(left, nnz_ctx, row7, 4, v); break; - case 8: SPLAT_ZERO_YUV(left, nnz_ctx, row7, 8, v); break; + case 1: SPLAT_ZERO_YUV(td->left, nnz_ctx, row7, 1, v); break; + case 2: SPLAT_ZERO_YUV(td->left, nnz_ctx, row7, 2, v); break; + case 4: SPLAT_ZERO_YUV(td->left, nnz_ctx, row7, 4, v); break; + case 8: SPLAT_ZERO_YUV(td->left, nnz_ctx, row7, 8, v); break; } } if (s->pass == 1) { - s->b++; - s->block += w4 * h4 * 64 * bytesperpixel; - s->uvblock[0] += w4 * h4 * 64 * bytesperpixel >> (s->ss_h + s->ss_v); - s->uvblock[1] += w4 * h4 * 64 * bytesperpixel >> (s->ss_h + s->ss_v); - s->eob += 4 * w4 * h4; - s->uveob[0] += 4 * w4 * h4 >> (s->ss_h + s->ss_v); - s->uveob[1] += 4 * w4 * h4 >> (s->ss_h + s->ss_v); + s->td[0].b++; + s->td[0].block += w4 * h4 * 64 * bytesperpixel; + s->td[0].uvblock[0] += w4 * h4 * 64 * bytesperpixel >> (s->ss_h + s->ss_v); + s->td[0].uvblock[1] += w4 * h4 * 64 * bytesperpixel >> (s->ss_h + s->ss_v); + s->td[0].eob += 4 * w4 * h4; + s->td[0].uveob[0] += 4 * w4 * h4 >> (s->ss_h + s->ss_v); + s->td[0].uveob[1] += 4 * w4 * h4 >> (s->ss_h + s->ss_v); return; } @@ -1365,32 +1365,32 @@ void ff_vp9_decode_block(AVCodecContext *avctx, int row, int col, emu[1] = ((col + w4) * 8 >> s->ss_h) * bytesperpixel > f->linesize[1] || (row + h4) > s->rows; if (emu[0]) { - s->dst[0] = s->tmp_y; - s->y_stride = 128; + td->dst[0] = td->tmp_y; + td->y_stride = 128; } else { - s->dst[0] = f->data[0] + yoff; - s->y_stride = f->linesize[0]; + td->dst[0] = f->data[0] + yoff; + td->y_stride = f->linesize[0]; } if (emu[1]) { - s->dst[1] = s->tmp_uv[0]; - s->dst[2] = s->tmp_uv[1]; - s->uv_stride = 128; + td->dst[1] = td->tmp_uv[0]; + td->dst[2] = td->tmp_uv[1]; + td->uv_stride = 128; } else { - s->dst[1] = f->data[1] + uvoff; - s->dst[2] = f->data[2] + uvoff; - s->uv_stride = f->linesize[1]; + td->dst[1] = f->data[1] + uvoff; + td->dst[2] = f->data[2] + uvoff; + td->uv_stride = f->linesize[1]; } if (b->intra) { if (s->s.h.bpp > 8) { - ff_vp9_intra_recon_16bpp(avctx, yoff, uvoff); + ff_vp9_intra_recon_16bpp(td, yoff, uvoff); } else { - ff_vp9_intra_recon_8bpp(avctx, yoff, uvoff); + ff_vp9_intra_recon_8bpp(td, yoff, uvoff); } } else { if (s->s.h.bpp > 8) { - ff_vp9_inter_recon_16bpp(avctx); + ff_vp9_inter_recon_16bpp(td); } else { - ff_vp9_inter_recon_8bpp(avctx); + ff_vp9_inter_recon_8bpp(td); } } if (emu[0]) { @@ -1402,7 +1402,7 @@ void ff_vp9_decode_block(AVCodecContext *avctx, int row, int col, av_assert2(n <= 4); if (w & bw) { s->dsp.mc[n][0][0][0][0](f->data[0] + yoff + o * bytesperpixel, f->linesize[0], - s->tmp_y + o * bytesperpixel, 128, h, 0, 0); + td->tmp_y + o * bytesperpixel, 128, h, 0, 0); o += bw; } } @@ -1417,9 +1417,9 @@ void ff_vp9_decode_block(AVCodecContext *avctx, int row, int col, av_assert2(n <= 4); if (w & bw) { s->dsp.mc[n][0][0][0][0](f->data[1] + uvoff + o * bytesperpixel, f->linesize[1], - s->tmp_uv[0] + o * bytesperpixel, 128, h, 0, 0); + td->tmp_uv[0] + o * bytesperpixel, 128, h, 0, 0); s->dsp.mc[n][0][0][0][0](f->data[2] + uvoff + o * bytesperpixel, f->linesize[2], - s->tmp_uv[1] + o * bytesperpixel, 128, h, 0, 0); + td->tmp_uv[1] + o * bytesperpixel, 128, h, 0, 0); o += bw; } } @@ -1430,7 +1430,7 @@ void ff_vp9_decode_block(AVCodecContext *avctx, int row, int col, (lvl = s->s.h.segmentation.feat[b->seg_id].lflvl[b->intra ? 0 : b->ref[0] + 1] [b->mode[3] != ZEROMV]) > 0) { int x_end = FFMIN(s->cols - col, w4), y_end = FFMIN(s->rows - row, h4); - int skip_inter = !b->intra && b->skip, col7 = s->col7, row7 = s->row7; + int skip_inter = !b->intra && b->skip, col7 = td->col7, row7 = td->row7; setctx_2d(&lflvl->level[row7 * 8 + col7], w4, h4, 8, lvl); mask_edges(lflvl->mask[0], 0, 0, row7, col7, x_end, y_end, 0, 0, b->tx, skip_inter); @@ -1439,29 +1439,15 @@ void ff_vp9_decode_block(AVCodecContext *avctx, int row, int col, s->cols & 1 && col + w4 >= s->cols ? s->cols & 7 : 0, s->rows & 1 && row + h4 >= s->rows ? s->rows & 7 : 0, b->uvtx, skip_inter); - - if (!s->filter_lut.lim_lut[lvl]) { - int sharp = s->s.h.filter.sharpness; - int limit = lvl; - - if (sharp > 0) { - limit >>= (sharp + 3) >> 2; - limit = FFMIN(limit, 9 - sharp); - } - limit = FFMAX(limit, 1); - - s->filter_lut.lim_lut[lvl] = limit; - s->filter_lut.mblim_lut[lvl] = 2 * (lvl + 2) + limit; - } } if (s->pass == 2) { - s->b++; - s->block += w4 * h4 * 64 * bytesperpixel; - s->uvblock[0] += w4 * h4 * 64 * bytesperpixel >> (s->ss_v + s->ss_h); - s->uvblock[1] += w4 * h4 * 64 * bytesperpixel >> (s->ss_v + s->ss_h); - s->eob += 4 * w4 * h4; - s->uveob[0] += 4 * w4 * h4 >> (s->ss_v + s->ss_h); - s->uveob[1] += 4 * w4 * h4 >> (s->ss_v + s->ss_h); + s->td[0].b++; + s->td[0].block += w4 * h4 * 64 * bytesperpixel; + s->td[0].uvblock[0] += w4 * h4 * 64 * bytesperpixel >> (s->ss_v + s->ss_h); + s->td[0].uvblock[1] += w4 * h4 * 64 * bytesperpixel >> (s->ss_v + s->ss_h); + s->td[0].eob += 4 * w4 * h4; + s->td[0].uveob[0] += 4 * w4 * h4 >> (s->ss_v + s->ss_h); + s->td[0].uveob[1] += 4 * w4 * h4 >> (s->ss_v + s->ss_h); } } diff --git a/libavcodec/vp9dec.h b/libavcodec/vp9dec.h index 4002b3a..1fc2499 100644 --- a/libavcodec/vp9dec.h +++ b/libavcodec/vp9dec.h @@ -28,6 +28,7 @@ #include #include "libavutil/buffer.h" +#include "libavutil/thread.h" #include "libavutil/internal.h" #include "vp9.h" @@ -84,20 +85,17 @@ typedef struct VP9Block { enum BlockPartition bp; } VP9Block; +typedef struct VP9TileData VP9TileData; + typedef struct VP9Context { + VP9TileData *td; VP9SharedContext s; VP9DSPContext dsp; VideoDSPContext vdsp; GetBitContext gb; VP56RangeCoder c; - VP56RangeCoder *c_b; - unsigned c_b_size; - VP9Block *b_base, *b; int pass; - int row, row7, col, col7; - uint8_t *dst[3]; - ptrdiff_t y_stride, uv_stride; uint8_t ss_h, ss_v; uint8_t last_bpp, bpp_index, bytesperpixel; @@ -115,7 +113,6 @@ typedef struct VP9Context { uint8_t lim_lut[64]; uint8_t mblim_lut[64]; } filter_lut; - unsigned tile_row_start, tile_row_end, tile_col_start, tile_col_end; struct { ProbContext p; uint8_t coef[4][2][2][6][6][3]; @@ -124,6 +121,42 @@ typedef struct VP9Context { ProbContext p; uint8_t coef[4][2][2][6][6][11]; } prob; + + // contextual (above) cache + uint8_t *above_partition_ctx; + uint8_t *above_mode_ctx; + // FIXME maybe merge some of the below in a flags field? + uint8_t *above_y_nnz_ctx; + uint8_t *above_uv_nnz_ctx[2]; + uint8_t *above_skip_ctx; // 1bit + uint8_t *above_txfm_ctx; // 2bit + uint8_t *above_segpred_ctx; // 1bit + uint8_t *above_intra_ctx; // 1bit + uint8_t *above_comp_ctx; // 1bit + uint8_t *above_ref_ctx; // 2bit + uint8_t *above_filter_ctx; + VP56mv (*above_mv_ctx)[2]; + + // whole-frame cache + uint8_t *intra_pred_data[3]; + VP9Filter *lflvl; + + // block reconstruction intermediates + int block_alloc_using_2pass; + uint16_t mvscale[3][2]; + uint8_t mvstep[3][2]; +} VP9Context; + +typedef struct VP9TileData { + VP9Context *s; + VP56RangeCoder c_b[4]; + VP56RangeCoder c; + int row, row7, col, col7; + uint8_t *dst[3]; + ptrdiff_t y_stride, uv_stride; + VP9Block *b_base, *b; + unsigned tile_col_start; + struct { unsigned y_mode[4][10]; unsigned uv_mode[10][10]; @@ -153,7 +186,10 @@ typedef struct VP9Context { unsigned eob[4][2][2][6][6][2]; } counts; - // contextual (left/above) cache + // whole-frame cache + DECLARE_ALIGNED(32, uint8_t, edge_emu_buffer)[135 * 144 * 2]; + + // contextual (left) cache DECLARE_ALIGNED(16, uint8_t, left_y_nnz_ctx)[16]; DECLARE_ALIGNED(16, uint8_t, left_mode_ctx)[16]; DECLARE_ALIGNED(16, VP56mv, left_mv_ctx)[16][2]; @@ -166,52 +202,30 @@ typedef struct VP9Context { DECLARE_ALIGNED(8, uint8_t, left_comp_ctx)[8]; DECLARE_ALIGNED(8, uint8_t, left_ref_ctx)[8]; DECLARE_ALIGNED(8, uint8_t, left_filter_ctx)[8]; - uint8_t *above_partition_ctx; - uint8_t *above_mode_ctx; - // FIXME maybe merge some of the below in a flags field? - uint8_t *above_y_nnz_ctx; - uint8_t *above_uv_nnz_ctx[2]; - uint8_t *above_skip_ctx; // 1bit - uint8_t *above_txfm_ctx; // 2bit - uint8_t *above_segpred_ctx; // 1bit - uint8_t *above_intra_ctx; // 1bit - uint8_t *above_comp_ctx; // 1bit - uint8_t *above_ref_ctx; // 2bit - uint8_t *above_filter_ctx; - VP56mv (*above_mv_ctx)[2]; - - // whole-frame cache - uint8_t *intra_pred_data[3]; - VP9Filter *lflvl; - DECLARE_ALIGNED(32, uint8_t, edge_emu_buffer)[135 * 144 * 2]; - // block reconstruction intermediates - int block_alloc_using_2pass; - int16_t *block_base, *block, *uvblock_base[2], *uvblock[2]; - uint8_t *eob_base, *uveob_base[2], *eob, *uveob[2]; - struct { int x, y; } min_mv, max_mv; DECLARE_ALIGNED(32, uint8_t, tmp_y)[64 * 64 * 2]; DECLARE_ALIGNED(32, uint8_t, tmp_uv)[2][64 * 64 * 2]; - uint16_t mvscale[3][2]; - uint8_t mvstep[3][2]; -} VP9Context; + struct { int x, y; } min_mv, max_mv; + int16_t *block_base, *block, *uvblock_base[2], *uvblock[2]; + uint8_t *eob_base, *uveob_base[2], *eob, *uveob[2]; +} VP9TileData; -void ff_vp9_fill_mv(VP9Context *s, VP56mv *mv, int mode, int sb); +void ff_vp9_fill_mv(VP9TileData *td, VP56mv *mv, int mode, int sb); void ff_vp9_adapt_probs(VP9Context *s); -void ff_vp9_decode_block(AVCodecContext *ctx, int row, int col, +void ff_vp9_decode_block(VP9TileData *td, int row, int col, VP9Filter *lflvl, ptrdiff_t yoff, ptrdiff_t uvoff, enum BlockLevel bl, enum BlockPartition bp); void ff_vp9_loopfilter_sb(AVCodecContext *avctx, VP9Filter *lflvl, int row, int col, ptrdiff_t yoff, ptrdiff_t uvoff); -void ff_vp9_intra_recon_8bpp(AVCodecContext *avctx, +void ff_vp9_intra_recon_8bpp(VP9TileData *td, ptrdiff_t y_off, ptrdiff_t uv_off); -void ff_vp9_intra_recon_16bpp(AVCodecContext *avctx, +void ff_vp9_intra_recon_16bpp(VP9TileData *td, ptrdiff_t y_off, ptrdiff_t uv_off); -void ff_vp9_inter_recon_8bpp(AVCodecContext *avctx); -void ff_vp9_inter_recon_16bpp(AVCodecContext *avctx); +void ff_vp9_inter_recon_8bpp(VP9TileData *td); +void ff_vp9_inter_recon_16bpp(VP9TileData *td); #endif /* AVCODEC_VP9DEC_H */ diff --git a/libavcodec/vp9mvs.c b/libavcodec/vp9mvs.c index e323bac..9ace373 100644 --- a/libavcodec/vp9mvs.c +++ b/libavcodec/vp9mvs.c @@ -28,13 +28,13 @@ #include "vp9dec.h" static av_always_inline void clamp_mv(VP56mv *dst, const VP56mv *src, - VP9Context *s) + VP9TileData *td) { - dst->x = av_clip(src->x, s->min_mv.x, s->max_mv.x); - dst->y = av_clip(src->y, s->min_mv.y, s->max_mv.y); + dst->x = av_clip(src->x, td->min_mv.x, td->max_mv.x); + dst->y = av_clip(src->y, td->min_mv.y, td->max_mv.y); } -static void find_ref_mvs(VP9Context *s, +static void find_ref_mvs(VP9TileData *td, VP56mv *pmv, int ref, int z, int idx, int sb) { static const int8_t mv_ref_blk_off[N_BS_SIZES][8][2] = { @@ -65,8 +65,9 @@ static void find_ref_mvs(VP9Context *s, [BS_4x4] = { { 0, -1 }, { -1, 0 }, { -1, -1 }, { 0, -2 }, { -2, 0 }, { -1, -2 }, { -2, -1 }, { -2, -2 } }, }; - VP9Block *b = s->b; - int row = s->row, col = s->col, row7 = s->row7; + VP9Context *s = td->s; + VP9Block *b = td->b; + int row = td->row, col = td->col, row7 = td->row7; const int8_t (*p)[2] = mv_ref_blk_off[b->bs]; #define INVALID_MV 0x80008000U uint32_t mem = INVALID_MV, mem_sub8x8 = INVALID_MV; @@ -103,7 +104,7 @@ static void find_ref_mvs(VP9Context *s, av_assert2(idx == 1); \ av_assert2(mem != INVALID_MV); \ if (mem_sub8x8 == INVALID_MV) { \ - clamp_mv(&tmp, &mv, s); \ + clamp_mv(&tmp, &mv, td); \ m = AV_RN32A(&tmp); \ if (m != mem) { \ AV_WN32A(pmv, m); \ @@ -111,7 +112,7 @@ static void find_ref_mvs(VP9Context *s, } \ mem_sub8x8 = AV_RN32A(&mv); \ } else if (mem_sub8x8 != AV_RN32A(&mv)) { \ - clamp_mv(&tmp, &mv, s); \ + clamp_mv(&tmp, &mv, td); \ m = AV_RN32A(&tmp); \ if (m != mem) { \ AV_WN32A(pmv, m); \ @@ -124,12 +125,12 @@ static void find_ref_mvs(VP9Context *s, } else { \ uint32_t m = AV_RN32A(&mv); \ if (!idx) { \ - clamp_mv(pmv, &mv, s); \ + clamp_mv(pmv, &mv, td); \ return; \ } else if (mem == INVALID_MV) { \ mem = m; \ } else if (m != mem) { \ - clamp_mv(pmv, &mv, s); \ + clamp_mv(pmv, &mv, td); \ return; \ } \ } \ @@ -142,12 +143,12 @@ static void find_ref_mvs(VP9Context *s, else if (mv->ref[1] == ref) RETURN_MV(s->above_mv_ctx[2 * col + (sb & 1)][1]); } - if (col > s->tile_col_start) { + if (col > td->tile_col_start) { VP9mvrefPair *mv = &s->s.frames[CUR_FRAME].mv[row * s->sb_cols * 8 + col - 1]; if (mv->ref[0] == ref) - RETURN_MV(s->left_mv_ctx[2 * row7 + (sb >> 1)][0]); + RETURN_MV(td->left_mv_ctx[2 * row7 + (sb >> 1)][0]); else if (mv->ref[1] == ref) - RETURN_MV(s->left_mv_ctx[2 * row7 + (sb >> 1)][1]); + RETURN_MV(td->left_mv_ctx[2 * row7 + (sb >> 1)][1]); } i = 2; } else { @@ -158,7 +159,7 @@ static void find_ref_mvs(VP9Context *s, for (; i < 8; i++) { int c = p[i][0] + col, r = p[i][1] + row; - if (c >= s->tile_col_start && c < s->cols && + if (c >= td->tile_col_start && c < s->cols && r >= 0 && r < s->rows) { VP9mvrefPair *mv = &s->s.frames[CUR_FRAME].mv[r * s->sb_cols * 8 + c]; @@ -195,7 +196,7 @@ static void find_ref_mvs(VP9Context *s, for (i = 0; i < 8; i++) { int c = p[i][0] + col, r = p[i][1] + row; - if (c >= s->tile_col_start && c < s->cols && r >= 0 && r < s->rows) { + if (c >= td->tile_col_start && c < s->cols && r >= 0 && r < s->rows) { VP9mvrefPair *mv = &s->s.frames[CUR_FRAME].mv[r * s->sb_cols * 8 + c]; if (mv->ref[0] != ref && mv->ref[0] >= 0) @@ -226,69 +227,71 @@ static void find_ref_mvs(VP9Context *s, } AV_ZERO32(pmv); - clamp_mv(pmv, pmv, s); + clamp_mv(pmv, pmv, td); #undef INVALID_MV #undef RETURN_MV #undef RETURN_SCALE_MV } -static av_always_inline int read_mv_component(VP9Context *s, int idx, int hp) +static av_always_inline int read_mv_component(VP9TileData *td, int idx, int hp) { - int bit, sign = vp56_rac_get_prob(&s->c, s->prob.p.mv_comp[idx].sign); - int n, c = vp8_rac_get_tree(&s->c, ff_vp9_mv_class_tree, + VP9Context *s = td->s; + int bit, sign = vp56_rac_get_prob(&td->c, s->prob.p.mv_comp[idx].sign); + int n, c = vp8_rac_get_tree(&td->c, ff_vp9_mv_class_tree, s->prob.p.mv_comp[idx].classes); - s->counts.mv_comp[idx].sign[sign]++; - s->counts.mv_comp[idx].classes[c]++; + td->counts.mv_comp[idx].sign[sign]++; + td->counts.mv_comp[idx].classes[c]++; if (c) { int m; for (n = 0, m = 0; m < c; m++) { - bit = vp56_rac_get_prob(&s->c, s->prob.p.mv_comp[idx].bits[m]); + bit = vp56_rac_get_prob(&td->c, s->prob.p.mv_comp[idx].bits[m]); n |= bit << m; - s->counts.mv_comp[idx].bits[m][bit]++; + td->counts.mv_comp[idx].bits[m][bit]++; } n <<= 3; - bit = vp8_rac_get_tree(&s->c, ff_vp9_mv_fp_tree, + bit = vp8_rac_get_tree(&td->c, ff_vp9_mv_fp_tree, s->prob.p.mv_comp[idx].fp); n |= bit << 1; - s->counts.mv_comp[idx].fp[bit]++; + td->counts.mv_comp[idx].fp[bit]++; if (hp) { - bit = vp56_rac_get_prob(&s->c, s->prob.p.mv_comp[idx].hp); - s->counts.mv_comp[idx].hp[bit]++; + bit = vp56_rac_get_prob(&td->c, s->prob.p.mv_comp[idx].hp); + td->counts.mv_comp[idx].hp[bit]++; n |= bit; } else { n |= 1; // bug in libvpx - we count for bw entropy purposes even if the // bit wasn't coded - s->counts.mv_comp[idx].hp[1]++; + td->counts.mv_comp[idx].hp[1]++; } n += 8 << c; } else { - n = vp56_rac_get_prob(&s->c, s->prob.p.mv_comp[idx].class0); - s->counts.mv_comp[idx].class0[n]++; - bit = vp8_rac_get_tree(&s->c, ff_vp9_mv_fp_tree, + n = vp56_rac_get_prob(&td->c, s->prob.p.mv_comp[idx].class0); + td->counts.mv_comp[idx].class0[n]++; + bit = vp8_rac_get_tree(&td->c, ff_vp9_mv_fp_tree, s->prob.p.mv_comp[idx].class0_fp[n]); - s->counts.mv_comp[idx].class0_fp[n][bit]++; + td->counts.mv_comp[idx].class0_fp[n][bit]++; n = (n << 3) | (bit << 1); if (hp) { - bit = vp56_rac_get_prob(&s->c, s->prob.p.mv_comp[idx].class0_hp); - s->counts.mv_comp[idx].class0_hp[bit]++; + bit = vp56_rac_get_prob(&td->c, s->prob.p.mv_comp[idx].class0_hp); + td->counts.mv_comp[idx].class0_hp[bit]++; n |= bit; } else { n |= 1; // bug in libvpx - we count for bw entropy purposes even if the // bit wasn't coded - s->counts.mv_comp[idx].class0_hp[1]++; + td->counts.mv_comp[idx].class0_hp[1]++; } } return sign ? -(n + 1) : (n + 1); } -void ff_vp9_fill_mv(VP9Context *s, VP56mv *mv, int mode, int sb) +void ff_vp9_fill_mv(VP9TileData *td, VP56mv *mv, int mode, int sb) { - VP9Block *b = s->b; + VP9Context *s = td->s; + VP9Block *b = td->b; if (mode == ZEROMV) { AV_ZERO64(mv); @@ -296,7 +299,7 @@ void ff_vp9_fill_mv(VP9Context *s, VP56mv *mv, int mode, int sb) int hp; // FIXME cache this value and reuse for other subblocks - find_ref_mvs(s, &mv[0], b->ref[0], 0, mode == NEARMV, + find_ref_mvs(td, &mv[0], b->ref[0], 0, mode == NEARMV, mode == NEWMV ? -1 : sb); // FIXME maybe move this code into find_ref_mvs() if ((mode == NEWMV || sb == -1) && @@ -316,19 +319,19 @@ void ff_vp9_fill_mv(VP9Context *s, VP56mv *mv, int mode, int sb) } } if (mode == NEWMV) { - enum MVJoint j = vp8_rac_get_tree(&s->c, ff_vp9_mv_joint_tree, + enum MVJoint j = vp8_rac_get_tree(&td->c, ff_vp9_mv_joint_tree, s->prob.p.mv_joint); - s->counts.mv_joint[j]++; + td->counts.mv_joint[j]++; if (j >= MV_JOINT_V) - mv[0].y += read_mv_component(s, 0, hp); + mv[0].y += read_mv_component(td, 0, hp); if (j & 1) - mv[0].x += read_mv_component(s, 1, hp); + mv[0].x += read_mv_component(td, 1, hp); } if (b->comp) { // FIXME cache this value and reuse for other subblocks - find_ref_mvs(s, &mv[1], b->ref[1], 1, mode == NEARMV, + find_ref_mvs(td, &mv[1], b->ref[1], 1, mode == NEARMV, mode == NEWMV ? -1 : sb); if ((mode == NEWMV || sb == -1) && !(hp = s->s.h.highprecisionmvs && @@ -347,14 +350,14 @@ void ff_vp9_fill_mv(VP9Context *s, VP56mv *mv, int mode, int sb) } } if (mode == NEWMV) { - enum MVJoint j = vp8_rac_get_tree(&s->c, ff_vp9_mv_joint_tree, + enum MVJoint j = vp8_rac_get_tree(&td->c, ff_vp9_mv_joint_tree, s->prob.p.mv_joint); - s->counts.mv_joint[j]++; + td->counts.mv_joint[j]++; if (j >= MV_JOINT_V) - mv[1].y += read_mv_component(s, 0, hp); + mv[1].y += read_mv_component(td, 0, hp); if (j & 1) - mv[1].x += read_mv_component(s, 1, hp); + mv[1].x += read_mv_component(td, 1, hp); } } } diff --git a/libavcodec/vp9prob.c b/libavcodec/vp9prob.c index cde909c..fb295b4 100644 --- a/libavcodec/vp9prob.c +++ b/libavcodec/vp9prob.c @@ -56,8 +56,8 @@ void ff_vp9_adapt_probs(VP9Context *s) for (l = 0; l < 6; l++) for (m = 0; m < 6; m++) { uint8_t *pp = s->prob_ctx[s->s.h.framectxid].coef[i][j][k][l][m]; - unsigned *e = s->counts.eob[i][j][k][l][m]; - unsigned *c = s->counts.coef[i][j][k][l][m]; + unsigned *e = s->td[0].counts.eob[i][j][k][l][m]; + unsigned *c = s->td[0].counts.coef[i][j][k][l][m]; if (l == 0 && m >= 3) // dc only has 3 pt break; @@ -77,32 +77,32 @@ void ff_vp9_adapt_probs(VP9Context *s) // skip flag for (i = 0; i < 3; i++) - adapt_prob(&p->skip[i], s->counts.skip[i][0], - s->counts.skip[i][1], 20, 128); + adapt_prob(&p->skip[i], s->td[0].counts.skip[i][0], + s->td[0].counts.skip[i][1], 20, 128); // intra/inter flag for (i = 0; i < 4; i++) - adapt_prob(&p->intra[i], s->counts.intra[i][0], - s->counts.intra[i][1], 20, 128); + adapt_prob(&p->intra[i], s->td[0].counts.intra[i][0], + s->td[0].counts.intra[i][1], 20, 128); // comppred flag if (s->s.h.comppredmode == PRED_SWITCHABLE) { for (i = 0; i < 5; i++) - adapt_prob(&p->comp[i], s->counts.comp[i][0], - s->counts.comp[i][1], 20, 128); + adapt_prob(&p->comp[i], s->td[0].counts.comp[i][0], + s->td[0].counts.comp[i][1], 20, 128); } // reference frames if (s->s.h.comppredmode != PRED_SINGLEREF) { for (i = 0; i < 5; i++) - adapt_prob(&p->comp_ref[i], s->counts.comp_ref[i][0], - s->counts.comp_ref[i][1], 20, 128); + adapt_prob(&p->comp_ref[i], s->td[0].counts.comp_ref[i][0], + s->td[0].counts.comp_ref[i][1], 20, 128); } if (s->s.h.comppredmode != PRED_COMPREF) { for (i = 0; i < 5; i++) { uint8_t *pp = p->single_ref[i]; - unsigned (*c)[2] = s->counts.single_ref[i]; + unsigned (*c)[2] = s->td[0].counts.single_ref[i]; adapt_prob(&pp[0], c[0][0], c[0][1], 20, 128); adapt_prob(&pp[1], c[1][0], c[1][1], 20, 128); @@ -113,7 +113,7 @@ void ff_vp9_adapt_probs(VP9Context *s) for (i = 0; i < 4; i++) for (j = 0; j < 4; j++) { uint8_t *pp = p->partition[i][j]; - unsigned *c = s->counts.partition[i][j]; + unsigned *c = s->td[0].counts.partition[i][j]; adapt_prob(&pp[0], c[0], c[1] + c[2] + c[3], 20, 128); adapt_prob(&pp[1], c[1], c[2] + c[3], 20, 128); @@ -123,10 +123,10 @@ void ff_vp9_adapt_probs(VP9Context *s) // tx size if (s->s.h.txfmmode == TX_SWITCHABLE) { for (i = 0; i < 2; i++) { - unsigned *c16 = s->counts.tx16p[i], *c32 = s->counts.tx32p[i]; + unsigned *c16 = s->td[0].counts.tx16p[i], *c32 = s->td[0].counts.tx32p[i]; - adapt_prob(&p->tx8p[i], s->counts.tx8p[i][0], - s->counts.tx8p[i][1], 20, 128); + adapt_prob(&p->tx8p[i], s->td[0].counts.tx8p[i][0], + s->td[0].counts.tx8p[i][1], 20, 128); adapt_prob(&p->tx16p[i][0], c16[0], c16[1] + c16[2], 20, 128); adapt_prob(&p->tx16p[i][1], c16[1], c16[2], 20, 128); adapt_prob(&p->tx32p[i][0], c32[0], c32[1] + c32[2] + c32[3], 20, 128); @@ -139,7 +139,7 @@ void ff_vp9_adapt_probs(VP9Context *s) if (s->s.h.filtermode == FILTER_SWITCHABLE) { for (i = 0; i < 4; i++) { uint8_t *pp = p->filter[i]; - unsigned *c = s->counts.filter[i]; + unsigned *c = s->td[0].counts.filter[i]; adapt_prob(&pp[0], c[0], c[1] + c[2], 20, 128); adapt_prob(&pp[1], c[1], c[2], 20, 128); @@ -149,7 +149,7 @@ void ff_vp9_adapt_probs(VP9Context *s) // inter modes for (i = 0; i < 7; i++) { uint8_t *pp = p->mv_mode[i]; - unsigned *c = s->counts.mv_mode[i]; + unsigned *c = s->td[0].counts.mv_mode[i]; adapt_prob(&pp[0], c[2], c[1] + c[0] + c[3], 20, 128); adapt_prob(&pp[1], c[0], c[1] + c[3], 20, 128); @@ -159,7 +159,7 @@ void ff_vp9_adapt_probs(VP9Context *s) // mv joints { uint8_t *pp = p->mv_joint; - unsigned *c = s->counts.mv_joint; + unsigned *c = s->td[0].counts.mv_joint; adapt_prob(&pp[0], c[0], c[1] + c[2] + c[3], 20, 128); adapt_prob(&pp[1], c[1], c[2] + c[3], 20, 128); @@ -171,11 +171,11 @@ void ff_vp9_adapt_probs(VP9Context *s) uint8_t *pp; unsigned *c, (*c2)[2], sum; - adapt_prob(&p->mv_comp[i].sign, s->counts.mv_comp[i].sign[0], - s->counts.mv_comp[i].sign[1], 20, 128); + adapt_prob(&p->mv_comp[i].sign, s->td[0].counts.mv_comp[i].sign[0], + s->td[0].counts.mv_comp[i].sign[1], 20, 128); pp = p->mv_comp[i].classes; - c = s->counts.mv_comp[i].classes; + c = s->td[0].counts.mv_comp[i].classes; sum = c[1] + c[2] + c[3] + c[4] + c[5] + c[6] + c[7] + c[8] + c[9] + c[10]; adapt_prob(&pp[0], c[0], sum, 20, 128); @@ -193,39 +193,39 @@ void ff_vp9_adapt_probs(VP9Context *s) adapt_prob(&pp[8], c[7], c[8], 20, 128); adapt_prob(&pp[9], c[9], c[10], 20, 128); - adapt_prob(&p->mv_comp[i].class0, s->counts.mv_comp[i].class0[0], - s->counts.mv_comp[i].class0[1], 20, 128); + adapt_prob(&p->mv_comp[i].class0, s->td[0].counts.mv_comp[i].class0[0], + s->td[0].counts.mv_comp[i].class0[1], 20, 128); pp = p->mv_comp[i].bits; - c2 = s->counts.mv_comp[i].bits; + c2 = s->td[0].counts.mv_comp[i].bits; for (j = 0; j < 10; j++) adapt_prob(&pp[j], c2[j][0], c2[j][1], 20, 128); for (j = 0; j < 2; j++) { pp = p->mv_comp[i].class0_fp[j]; - c = s->counts.mv_comp[i].class0_fp[j]; + c = s->td[0].counts.mv_comp[i].class0_fp[j]; adapt_prob(&pp[0], c[0], c[1] + c[2] + c[3], 20, 128); adapt_prob(&pp[1], c[1], c[2] + c[3], 20, 128); adapt_prob(&pp[2], c[2], c[3], 20, 128); } pp = p->mv_comp[i].fp; - c = s->counts.mv_comp[i].fp; + c = s->td[0].counts.mv_comp[i].fp; adapt_prob(&pp[0], c[0], c[1] + c[2] + c[3], 20, 128); adapt_prob(&pp[1], c[1], c[2] + c[3], 20, 128); adapt_prob(&pp[2], c[2], c[3], 20, 128); if (s->s.h.highprecisionmvs) { adapt_prob(&p->mv_comp[i].class0_hp, - s->counts.mv_comp[i].class0_hp[0], - s->counts.mv_comp[i].class0_hp[1], 20, 128); - adapt_prob(&p->mv_comp[i].hp, s->counts.mv_comp[i].hp[0], - s->counts.mv_comp[i].hp[1], 20, 128); + s->td[0].counts.mv_comp[i].class0_hp[0], + s->td[0].counts.mv_comp[i].class0_hp[1], 20, 128); + adapt_prob(&p->mv_comp[i].hp, s->td[0].counts.mv_comp[i].hp[0], + s->td[0].counts.mv_comp[i].hp[1], 20, 128); } } // y intra modes for (i = 0; i < 4; i++) { uint8_t *pp = p->y_mode[i]; - unsigned *c = s->counts.y_mode[i], sum, s2; + unsigned *c = s->td[0].counts.y_mode[i], sum, s2; sum = c[0] + c[1] + c[3] + c[4] + c[5] + c[6] + c[7] + c[8] + c[9]; adapt_prob(&pp[0], c[DC_PRED], sum, 20, 128); @@ -250,7 +250,7 @@ void ff_vp9_adapt_probs(VP9Context *s) // uv intra modes for (i = 0; i < 10; i++) { uint8_t *pp = p->uv_mode[i]; - unsigned *c = s->counts.uv_mode[i], sum, s2; + unsigned *c = s->td[0].counts.uv_mode[i], sum, s2; sum = c[0] + c[1] + c[3] + c[4] + c[5] + c[6] + c[7] + c[8] + c[9]; adapt_prob(&pp[0], c[DC_PRED], sum, 20, 128); diff --git a/libavcodec/vp9recon.c b/libavcodec/vp9recon.c index afdb513..49bb04e 100644 --- a/libavcodec/vp9recon.c +++ b/libavcodec/vp9recon.c @@ -29,15 +29,16 @@ #include "vp9data.h" #include "vp9dec.h" -static av_always_inline int check_intra_mode(VP9Context *s, int mode, uint8_t **a, +static av_always_inline int check_intra_mode(VP9TileData *td, int mode, uint8_t **a, uint8_t *dst_edge, ptrdiff_t stride_edge, uint8_t *dst_inner, ptrdiff_t stride_inner, uint8_t *l, int col, int x, int w, int row, int y, enum TxfmMode tx, int p, int ss_h, int ss_v, int bytesperpixel) { + VP9Context *s = td->s; int have_top = row > 0 || y > 0; - int have_left = col > s->tile_col_start || x > 0; + int have_left = col > td->tile_col_start || x > 0; int have_right = x < w - 1; int bpp = s->s.h.bpp; static const uint8_t mode_conv[10][2 /* have_left */][2 /* have_top */] = { @@ -214,19 +215,19 @@ static av_always_inline int check_intra_mode(VP9Context *s, int mode, uint8_t ** return mode; } -static av_always_inline void intra_recon(AVCodecContext *avctx, ptrdiff_t y_off, +static av_always_inline void intra_recon(VP9TileData *td, ptrdiff_t y_off, ptrdiff_t uv_off, int bytesperpixel) { - VP9Context *s = avctx->priv_data; - VP9Block *b = s->b; - int row = s->row, col = s->col; + VP9Context *s = td->s; + VP9Block *b = td->b; + int row = td->row, col = td->col; int w4 = ff_vp9_bwh_tab[1][b->bs][0] << 1, step1d = 1 << b->tx, n; int h4 = ff_vp9_bwh_tab[1][b->bs][1] << 1, x, y, step = 1 << (b->tx * 2); int end_x = FFMIN(2 * (s->cols - col), w4); int end_y = FFMIN(2 * (s->rows - row), h4); int tx = 4 * s->s.h.lossless + b->tx, uvtx = b->uvtx + 4 * s->s.h.lossless; int uvstep1d = 1 << b->uvtx, p; - uint8_t *dst = s->dst[0], *dst_r = s->s.frames[CUR_FRAME].tf.f->data[0] + y_off; + uint8_t *dst = td->dst[0], *dst_r = s->s.frames[CUR_FRAME].tf.f->data[0] + y_off; LOCAL_ALIGNED_32(uint8_t, a_buf, [96]); LOCAL_ALIGNED_32(uint8_t, l, [64]); @@ -238,19 +239,19 @@ static av_always_inline void intra_recon(AVCodecContext *avctx, ptrdiff_t y_off, y * 2 + x : 0]; uint8_t *a = &a_buf[32]; enum TxfmType txtp = ff_vp9_intra_txfm_type[mode]; - int eob = b->skip ? 0 : b->tx > TX_8X8 ? AV_RN16A(&s->eob[n]) : s->eob[n]; + int eob = b->skip ? 0 : b->tx > TX_8X8 ? AV_RN16A(&td->eob[n]) : td->eob[n]; - mode = check_intra_mode(s, mode, &a, ptr_r, + mode = check_intra_mode(td, mode, &a, ptr_r, s->s.frames[CUR_FRAME].tf.f->linesize[0], - ptr, s->y_stride, l, + ptr, td->y_stride, l, col, x, w4, row, y, b->tx, 0, 0, 0, bytesperpixel); - s->dsp.intra_pred[b->tx][mode](ptr, s->y_stride, l, a); + s->dsp.intra_pred[b->tx][mode](ptr, td->y_stride, l, a); if (eob) - s->dsp.itxfm_add[tx][txtp](ptr, s->y_stride, - s->block + 16 * n * bytesperpixel, eob); + s->dsp.itxfm_add[tx][txtp](ptr, td->y_stride, + td->block + 16 * n * bytesperpixel, eob); } dst_r += 4 * step1d * s->s.frames[CUR_FRAME].tf.f->linesize[0]; - dst += 4 * step1d * s->y_stride; + dst += 4 * step1d * td->y_stride; } // U/V @@ -259,7 +260,7 @@ static av_always_inline void intra_recon(AVCodecContext *avctx, ptrdiff_t y_off, end_y >>= s->ss_v; step = 1 << (b->uvtx * 2); for (p = 0; p < 2; p++) { - dst = s->dst[1 + p]; + dst = td->dst[1 + p]; dst_r = s->s.frames[CUR_FRAME].tf.f->data[1 + p] + uv_off; for (n = 0, y = 0; y < end_y; y += uvstep1d) { uint8_t *ptr = dst, *ptr_r = dst_r; @@ -267,40 +268,41 @@ static av_always_inline void intra_recon(AVCodecContext *avctx, ptrdiff_t y_off, ptr_r += 4 * uvstep1d * bytesperpixel, n += step) { int mode = b->uvmode; uint8_t *a = &a_buf[32]; - int eob = b->skip ? 0 : b->uvtx > TX_8X8 ? AV_RN16A(&s->uveob[p][n]) : s->uveob[p][n]; + int eob = b->skip ? 0 : b->uvtx > TX_8X8 ? AV_RN16A(&td->uveob[p][n]) : td->uveob[p][n]; - mode = check_intra_mode(s, mode, &a, ptr_r, + mode = check_intra_mode(td, mode, &a, ptr_r, s->s.frames[CUR_FRAME].tf.f->linesize[1], - ptr, s->uv_stride, l, col, x, w4, row, y, + ptr, td->uv_stride, l, col, x, w4, row, y, b->uvtx, p + 1, s->ss_h, s->ss_v, bytesperpixel); - s->dsp.intra_pred[b->uvtx][mode](ptr, s->uv_stride, l, a); + s->dsp.intra_pred[b->uvtx][mode](ptr, td->uv_stride, l, a); if (eob) - s->dsp.itxfm_add[uvtx][DCT_DCT](ptr, s->uv_stride, - s->uvblock[p] + 16 * n * bytesperpixel, eob); + s->dsp.itxfm_add[uvtx][DCT_DCT](ptr, td->uv_stride, + td->uvblock[p] + 16 * n * bytesperpixel, eob); } dst_r += 4 * uvstep1d * s->s.frames[CUR_FRAME].tf.f->linesize[1]; - dst += 4 * uvstep1d * s->uv_stride; + dst += 4 * uvstep1d * td->uv_stride; } } } -void ff_vp9_intra_recon_8bpp(AVCodecContext *avctx, ptrdiff_t y_off, ptrdiff_t uv_off) +void ff_vp9_intra_recon_8bpp(VP9TileData *td, ptrdiff_t y_off, ptrdiff_t uv_off) { - intra_recon(avctx, y_off, uv_off, 1); + intra_recon(td, y_off, uv_off, 1); } -void ff_vp9_intra_recon_16bpp(AVCodecContext *avctx, ptrdiff_t y_off, ptrdiff_t uv_off) +void ff_vp9_intra_recon_16bpp(VP9TileData *td, ptrdiff_t y_off, ptrdiff_t uv_off) { - intra_recon(avctx, y_off, uv_off, 2); + intra_recon(td, y_off, uv_off, 2); } -static av_always_inline void mc_luma_unscaled(VP9Context *s, vp9_mc_func (*mc)[2], +static av_always_inline void mc_luma_unscaled(VP9TileData *td, vp9_mc_func (*mc)[2], uint8_t *dst, ptrdiff_t dst_stride, const uint8_t *ref, ptrdiff_t ref_stride, ThreadFrame *ref_frame, ptrdiff_t y, ptrdiff_t x, const VP56mv *mv, int bw, int bh, int w, int h, int bytesperpixel) { + VP9Context *s = td->s; int mx = mv->x, my = mv->y, th; y += my >> 3; @@ -318,18 +320,18 @@ static av_always_inline void mc_luma_unscaled(VP9Context *s, vp9_mc_func (*mc)[2 // (!!my * 5) than horizontally (!!mx * 4). if (x < !!mx * 3 || y < !!my * 3 || x + !!mx * 4 > w - bw || y + !!my * 5 > h - bh) { - s->vdsp.emulated_edge_mc(s->edge_emu_buffer, + s->vdsp.emulated_edge_mc(td->edge_emu_buffer, ref - !!my * 3 * ref_stride - !!mx * 3 * bytesperpixel, 160, ref_stride, bw + !!mx * 7, bh + !!my * 7, x - !!mx * 3, y - !!my * 3, w, h); - ref = s->edge_emu_buffer + !!my * 3 * 160 + !!mx * 3 * bytesperpixel; + ref = td->edge_emu_buffer + !!my * 3 * 160 + !!mx * 3 * bytesperpixel; ref_stride = 160; } mc[!!mx][!!my](dst, dst_stride, ref, ref_stride, bh, mx << 1, my << 1); } -static av_always_inline void mc_chroma_unscaled(VP9Context *s, vp9_mc_func (*mc)[2], +static av_always_inline void mc_chroma_unscaled(VP9TileData *td, vp9_mc_func (*mc)[2], uint8_t *dst_u, uint8_t *dst_v, ptrdiff_t dst_stride, const uint8_t *ref_u, ptrdiff_t src_stride_u, @@ -338,6 +340,7 @@ static av_always_inline void mc_chroma_unscaled(VP9Context *s, vp9_mc_func (*mc) ptrdiff_t y, ptrdiff_t x, const VP56mv *mv, int bw, int bh, int w, int h, int bytesperpixel) { + VP9Context *s = td->s; int mx = mv->x * (1 << !s->ss_h), my = mv->y * (1 << !s->ss_v), th; y += my >> 4; @@ -356,20 +359,20 @@ static av_always_inline void mc_chroma_unscaled(VP9Context *s, vp9_mc_func (*mc) // (!!my * 5) than horizontally (!!mx * 4). if (x < !!mx * 3 || y < !!my * 3 || x + !!mx * 4 > w - bw || y + !!my * 5 > h - bh) { - s->vdsp.emulated_edge_mc(s->edge_emu_buffer, + s->vdsp.emulated_edge_mc(td->edge_emu_buffer, ref_u - !!my * 3 * src_stride_u - !!mx * 3 * bytesperpixel, 160, src_stride_u, bw + !!mx * 7, bh + !!my * 7, x - !!mx * 3, y - !!my * 3, w, h); - ref_u = s->edge_emu_buffer + !!my * 3 * 160 + !!mx * 3 * bytesperpixel; + ref_u = td->edge_emu_buffer + !!my * 3 * 160 + !!mx * 3 * bytesperpixel; mc[!!mx][!!my](dst_u, dst_stride, ref_u, 160, bh, mx, my); - s->vdsp.emulated_edge_mc(s->edge_emu_buffer, + s->vdsp.emulated_edge_mc(td->edge_emu_buffer, ref_v - !!my * 3 * src_stride_v - !!mx * 3 * bytesperpixel, 160, src_stride_v, bw + !!mx * 7, bh + !!my * 7, x - !!mx * 3, y - !!my * 3, w, h); - ref_v = s->edge_emu_buffer + !!my * 3 * 160 + !!mx * 3 * bytesperpixel; + ref_v = td->edge_emu_buffer + !!my * 3 * 160 + !!mx * 3 * bytesperpixel; mc[!!mx][!!my](dst_v, dst_stride, ref_v, 160, bh, mx, my); } else { mc[!!mx][!!my](dst_u, dst_stride, ref_u, src_stride_u, bh, mx, my); @@ -377,13 +380,13 @@ static av_always_inline void mc_chroma_unscaled(VP9Context *s, vp9_mc_func (*mc) } } -#define mc_luma_dir(s, mc, dst, dst_ls, src, src_ls, tref, row, col, mv, \ +#define mc_luma_dir(td, mc, dst, dst_ls, src, src_ls, tref, row, col, mv, \ px, py, pw, ph, bw, bh, w, h, i) \ - mc_luma_unscaled(s, s->dsp.mc, dst, dst_ls, src, src_ls, tref, row, col, \ + mc_luma_unscaled(td, s->dsp.mc, dst, dst_ls, src, src_ls, tref, row, col, \ mv, bw, bh, w, h, bytesperpixel) -#define mc_chroma_dir(s, mc, dstu, dstv, dst_ls, srcu, srcu_ls, srcv, srcv_ls, tref, \ +#define mc_chroma_dir(td, mc, dstu, dstv, dst_ls, srcu, srcu_ls, srcv, srcv_ls, tref, \ row, col, mv, px, py, pw, ph, bw, bh, w, h, i) \ - mc_chroma_unscaled(s, s->dsp.mc, dstu, dstv, dst_ls, srcu, srcu_ls, srcv, srcv_ls, tref, \ + mc_chroma_unscaled(td, s->dsp.mc, dstu, dstv, dst_ls, srcu, srcu_ls, srcv, srcv_ls, tref, \ row, col, mv, bw, bh, w, h, bytesperpixel) #define SCALED 0 #define FN(x) x##_8bpp @@ -400,7 +403,7 @@ static av_always_inline void mc_chroma_unscaled(VP9Context *s, vp9_mc_func (*mc) #undef BYTES_PER_PIXEL #undef SCALED -static av_always_inline void mc_luma_scaled(VP9Context *s, vp9_scaled_mc_func smc, +static av_always_inline void mc_luma_scaled(VP9TileData *td, vp9_scaled_mc_func smc, vp9_mc_func (*mc)[2], uint8_t *dst, ptrdiff_t dst_stride, const uint8_t *ref, ptrdiff_t ref_stride, @@ -410,9 +413,10 @@ static av_always_inline void mc_luma_scaled(VP9Context *s, vp9_scaled_mc_func sm int bw, int bh, int w, int h, int bytesperpixel, const uint16_t *scale, const uint8_t *step) { + VP9Context *s = td->s; if (s->s.frames[CUR_FRAME].tf.f->width == ref_frame->f->width && s->s.frames[CUR_FRAME].tf.f->height == ref_frame->f->height) { - mc_luma_unscaled(s, mc, dst, dst_stride, ref, ref_stride, ref_frame, + mc_luma_unscaled(td, mc, dst, dst_stride, ref, ref_stride, ref_frame, y, x, in_mv, bw, bh, w, h, bytesperpixel); } else { #define scale_mv(n, dim) (((int64_t)(n) * scale[dim]) >> 14) @@ -445,19 +449,19 @@ static av_always_inline void mc_luma_scaled(VP9Context *s, vp9_scaled_mc_func sm // needed, so switch to emulated edge one pixel sooner vertically // (y + 5 >= h - refbh_m1) than horizontally (x + 4 >= w - refbw_m1). if (x < 3 || y < 3 || x + 4 >= w - refbw_m1 || y + 5 >= h - refbh_m1) { - s->vdsp.emulated_edge_mc(s->edge_emu_buffer, + s->vdsp.emulated_edge_mc(td->edge_emu_buffer, ref - 3 * ref_stride - 3 * bytesperpixel, 288, ref_stride, refbw_m1 + 8, refbh_m1 + 8, x - 3, y - 3, w, h); - ref = s->edge_emu_buffer + 3 * 288 + 3 * bytesperpixel; + ref = td->edge_emu_buffer + 3 * 288 + 3 * bytesperpixel; ref_stride = 288; } smc(dst, dst_stride, ref, ref_stride, bh, mx, my, step[0], step[1]); } } -static av_always_inline void mc_chroma_scaled(VP9Context *s, vp9_scaled_mc_func smc, +static av_always_inline void mc_chroma_scaled(VP9TileData *td, vp9_scaled_mc_func smc, vp9_mc_func (*mc)[2], uint8_t *dst_u, uint8_t *dst_v, ptrdiff_t dst_stride, @@ -469,9 +473,10 @@ static av_always_inline void mc_chroma_scaled(VP9Context *s, vp9_scaled_mc_func int bw, int bh, int w, int h, int bytesperpixel, const uint16_t *scale, const uint8_t *step) { + VP9Context *s = td->s; if (s->s.frames[CUR_FRAME].tf.f->width == ref_frame->f->width && s->s.frames[CUR_FRAME].tf.f->height == ref_frame->f->height) { - mc_chroma_unscaled(s, mc, dst_u, dst_v, dst_stride, ref_u, src_stride_u, + mc_chroma_unscaled(td, mc, dst_u, dst_v, dst_stride, ref_u, src_stride_u, ref_v, src_stride_v, ref_frame, y, x, in_mv, bw, bh, w, h, bytesperpixel); } else { @@ -514,20 +519,20 @@ static av_always_inline void mc_chroma_scaled(VP9Context *s, vp9_scaled_mc_func // needed, so switch to emulated edge one pixel sooner vertically // (y + 5 >= h - refbh_m1) than horizontally (x + 4 >= w - refbw_m1). if (x < 3 || y < 3 || x + 4 >= w - refbw_m1 || y + 5 >= h - refbh_m1) { - s->vdsp.emulated_edge_mc(s->edge_emu_buffer, + s->vdsp.emulated_edge_mc(td->edge_emu_buffer, ref_u - 3 * src_stride_u - 3 * bytesperpixel, 288, src_stride_u, refbw_m1 + 8, refbh_m1 + 8, x - 3, y - 3, w, h); - ref_u = s->edge_emu_buffer + 3 * 288 + 3 * bytesperpixel; + ref_u = td->edge_emu_buffer + 3 * 288 + 3 * bytesperpixel; smc(dst_u, dst_stride, ref_u, 288, bh, mx, my, step[0], step[1]); - s->vdsp.emulated_edge_mc(s->edge_emu_buffer, + s->vdsp.emulated_edge_mc(td->edge_emu_buffer, ref_v - 3 * src_stride_v - 3 * bytesperpixel, 288, src_stride_v, refbw_m1 + 8, refbh_m1 + 8, x - 3, y - 3, w, h); - ref_v = s->edge_emu_buffer + 3 * 288 + 3 * bytesperpixel; + ref_v = td->edge_emu_buffer + 3 * 288 + 3 * bytesperpixel; smc(dst_v, dst_stride, ref_v, 288, bh, mx, my, step[0], step[1]); } else { smc(dst_u, dst_stride, ref_u, src_stride_u, bh, mx, my, step[0], step[1]); @@ -536,14 +541,14 @@ static av_always_inline void mc_chroma_scaled(VP9Context *s, vp9_scaled_mc_func } } -#define mc_luma_dir(s, mc, dst, dst_ls, src, src_ls, tref, row, col, mv, \ +#define mc_luma_dir(td, mc, dst, dst_ls, src, src_ls, tref, row, col, mv, \ px, py, pw, ph, bw, bh, w, h, i) \ - mc_luma_scaled(s, s->dsp.s##mc, s->dsp.mc, dst, dst_ls, src, src_ls, tref, row, col, \ + mc_luma_scaled(td, s->dsp.s##mc, s->dsp.mc, dst, dst_ls, src, src_ls, tref, row, col, \ mv, px, py, pw, ph, bw, bh, w, h, bytesperpixel, \ s->mvscale[b->ref[i]], s->mvstep[b->ref[i]]) -#define mc_chroma_dir(s, mc, dstu, dstv, dst_ls, srcu, srcu_ls, srcv, srcv_ls, tref, \ +#define mc_chroma_dir(td, mc, dstu, dstv, dst_ls, srcu, srcu_ls, srcv, srcv_ls, tref, \ row, col, mv, px, py, pw, ph, bw, bh, w, h, i) \ - mc_chroma_scaled(s, s->dsp.s##mc, s->dsp.mc, dstu, dstv, dst_ls, srcu, srcu_ls, srcv, srcv_ls, tref, \ + mc_chroma_scaled(td, s->dsp.s##mc, s->dsp.mc, dstu, dstv, dst_ls, srcu, srcu_ls, srcv, srcv_ls, tref, \ row, col, mv, px, py, pw, ph, bw, bh, w, h, bytesperpixel, \ s->mvscale[b->ref[i]], s->mvstep[b->ref[i]]) #define SCALED 1 @@ -561,23 +566,23 @@ static av_always_inline void mc_chroma_scaled(VP9Context *s, vp9_scaled_mc_func #undef BYTES_PER_PIXEL #undef SCALED -static av_always_inline void inter_recon(AVCodecContext *avctx, int bytesperpixel) +static av_always_inline void inter_recon(VP9TileData *td, int bytesperpixel) { - VP9Context *s = avctx->priv_data; - VP9Block *b = s->b; - int row = s->row, col = s->col; + VP9Context *s = td->s; + VP9Block *b = td->b; + int row = td->row, col = td->col; if (s->mvscale[b->ref[0]][0] || (b->comp && s->mvscale[b->ref[1]][0])) { if (bytesperpixel == 1) { - inter_pred_scaled_8bpp(avctx); + inter_pred_scaled_8bpp(td); } else { - inter_pred_scaled_16bpp(avctx); + inter_pred_scaled_16bpp(td); } } else { if (bytesperpixel == 1) { - inter_pred_8bpp(avctx); + inter_pred_8bpp(td); } else { - inter_pred_16bpp(avctx); + inter_pred_16bpp(td); } } @@ -590,20 +595,20 @@ static av_always_inline void inter_recon(AVCodecContext *avctx, int bytesperpixe int end_y = FFMIN(2 * (s->rows - row), h4); int tx = 4 * s->s.h.lossless + b->tx, uvtx = b->uvtx + 4 * s->s.h.lossless; int uvstep1d = 1 << b->uvtx, p; - uint8_t *dst = s->dst[0]; + uint8_t *dst = td->dst[0]; // y itxfm add for (n = 0, y = 0; y < end_y; y += step1d) { uint8_t *ptr = dst; for (x = 0; x < end_x; x += step1d, ptr += 4 * step1d * bytesperpixel, n += step) { - int eob = b->tx > TX_8X8 ? AV_RN16A(&s->eob[n]) : s->eob[n]; + int eob = b->tx > TX_8X8 ? AV_RN16A(&td->eob[n]) : td->eob[n]; if (eob) - s->dsp.itxfm_add[tx][DCT_DCT](ptr, s->y_stride, - s->block + 16 * n * bytesperpixel, eob); + s->dsp.itxfm_add[tx][DCT_DCT](ptr, td->y_stride, + td->block + 16 * n * bytesperpixel, eob); } - dst += 4 * s->y_stride * step1d; + dst += 4 * td->y_stride * step1d; } // uv itxfm add @@ -611,29 +616,29 @@ static av_always_inline void inter_recon(AVCodecContext *avctx, int bytesperpixe end_y >>= s->ss_v; step = 1 << (b->uvtx * 2); for (p = 0; p < 2; p++) { - dst = s->dst[p + 1]; + dst = td->dst[p + 1]; for (n = 0, y = 0; y < end_y; y += uvstep1d) { uint8_t *ptr = dst; for (x = 0; x < end_x; x += uvstep1d, ptr += 4 * uvstep1d * bytesperpixel, n += step) { - int eob = b->uvtx > TX_8X8 ? AV_RN16A(&s->uveob[p][n]) : s->uveob[p][n]; + int eob = b->uvtx > TX_8X8 ? AV_RN16A(&td->uveob[p][n]) : td->uveob[p][n]; if (eob) - s->dsp.itxfm_add[uvtx][DCT_DCT](ptr, s->uv_stride, - s->uvblock[p] + 16 * n * bytesperpixel, eob); + s->dsp.itxfm_add[uvtx][DCT_DCT](ptr, td->uv_stride, + td->uvblock[p] + 16 * n * bytesperpixel, eob); } - dst += 4 * uvstep1d * s->uv_stride; + dst += 4 * uvstep1d * td->uv_stride; } } } } -void ff_vp9_inter_recon_8bpp(AVCodecContext *avctx) +void ff_vp9_inter_recon_8bpp(VP9TileData *td) { - inter_recon(avctx, 1); + inter_recon(td, 1); } -void ff_vp9_inter_recon_16bpp(AVCodecContext *avctx) +void ff_vp9_inter_recon_16bpp(VP9TileData *td) { - inter_recon(avctx, 2); + inter_recon(td, 2); }