[FFmpeg-cvslog] vp9: expose reference frames in VP9SharedContext
Hendrik Leppkes
git at videolan.org
Thu Oct 15 13:07:44 CEST 2015
ffmpeg | branch: master | Hendrik Leppkes <h.leppkes at gmail.com> | Wed Oct 14 10:03:20 2015 +0200| [6e719dc6bb64d37c0b47f8c3387aa572e0a4780a] | committer: Hendrik Leppkes
vp9: expose reference frames in VP9SharedContext
> http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=6e719dc6bb64d37c0b47f8c3387aa572e0a4780a
---
libavcodec/vp9.c | 209 +++++++++++++++++++-----------------------
libavcodec/vp9.h | 22 +++++
libavcodec/vp9_mc_template.c | 4 +-
3 files changed, 120 insertions(+), 115 deletions(-)
diff --git a/libavcodec/vp9.c b/libavcodec/vp9.c
index ef64c18..27fb956 100644
--- a/libavcodec/vp9.c
+++ b/libavcodec/vp9.c
@@ -35,19 +35,6 @@
#define VP9_SYNCCODE 0x498342
-struct VP9mvrefPair {
- VP56mv mv[2];
- int8_t ref[2];
-};
-
-typedef struct VP9Frame {
- ThreadFrame tf;
- AVBufferRef *extradata;
- uint8_t *segmentation_map;
- struct VP9mvrefPair *mv;
- int uses_2pass;
-} VP9Frame;
-
struct VP9Filter {
uint8_t level[8 * 8];
uint8_t /* bit=col */ mask[2 /* 0=y, 1=uv */][2 /* 0=col, 1=row */]
@@ -82,11 +69,7 @@ typedef struct VP9Context {
uint8_t ss_h, ss_v;
uint8_t last_bpp, bpp, bpp_index, bytesperpixel;
uint8_t last_keyframe;
- ThreadFrame refs[8], next_refs[8];
-#define CUR_FRAME 0
-#define REF_FRAME_MVPAIR 1
-#define REF_FRAME_SEGMAP 2
- VP9Frame frames[3];
+ ThreadFrame next_refs[8];
struct {
uint8_t lim_lut[64];
@@ -292,14 +275,14 @@ static int update_block_buffers(AVCodecContext *ctx)
VP9Context *s = ctx->priv_data;
int chroma_blocks, chroma_eobs, bytesperpixel = s->bytesperpixel;
- if (s->b_base && s->block_base && s->block_alloc_using_2pass == s->frames[CUR_FRAME].uses_2pass)
+ if (s->b_base && s->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);
chroma_blocks = 64 * 64 >> (s->ss_h + s->ss_v);
chroma_eobs = 16 * 16 >> (s->ss_h + s->ss_v);
- if (s->frames[CUR_FRAME].uses_2pass) {
+ 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));
@@ -324,7 +307,7 @@ static int update_block_buffers(AVCodecContext *ctx)
s->uveob_base[0] = s->eob_base + 16 * 16;
s->uveob_base[1] = s->uveob_base[0] + chroma_eobs;
}
- s->block_alloc_using_2pass = s->frames[CUR_FRAME].uses_2pass;
+ s->block_alloc_using_2pass = s->s.frames[CUR_FRAME].uses_2pass;
return 0;
}
@@ -544,21 +527,21 @@ static int decode_frame_header(AVCodecContext *ctx,
s->s.h.signbias[1] = get_bits1(&s->gb) && !s->s.h.errorres;
s->s.h.refidx[2] = get_bits(&s->gb, 3);
s->s.h.signbias[2] = get_bits1(&s->gb) && !s->s.h.errorres;
- if (!s->refs[s->s.h.refidx[0]].f->data[0] ||
- !s->refs[s->s.h.refidx[1]].f->data[0] ||
- !s->refs[s->s.h.refidx[2]].f->data[0]) {
+ if (!s->s.refs[s->s.h.refidx[0]].f->data[0] ||
+ !s->s.refs[s->s.h.refidx[1]].f->data[0] ||
+ !s->s.refs[s->s.h.refidx[2]].f->data[0]) {
av_log(ctx, AV_LOG_ERROR, "Not all references are available\n");
return AVERROR_INVALIDDATA;
}
if (get_bits1(&s->gb)) {
- w = s->refs[s->s.h.refidx[0]].f->width;
- h = s->refs[s->s.h.refidx[0]].f->height;
+ w = s->s.refs[s->s.h.refidx[0]].f->width;
+ h = s->s.refs[s->s.h.refidx[0]].f->height;
} else if (get_bits1(&s->gb)) {
- w = s->refs[s->s.h.refidx[1]].f->width;
- h = s->refs[s->s.h.refidx[1]].f->height;
+ w = s->s.refs[s->s.h.refidx[1]].f->width;
+ h = s->s.refs[s->s.h.refidx[1]].f->height;
} else if (get_bits1(&s->gb)) {
- w = s->refs[s->s.h.refidx[2]].f->width;
- h = s->refs[s->s.h.refidx[2]].f->height;
+ w = s->s.refs[s->s.h.refidx[2]].f->width;
+ h = s->s.refs[s->s.h.refidx[2]].f->height;
} else {
w = get_bits(&s->gb, 16) + 1;
h = get_bits(&s->gb, 16) + 1;
@@ -566,8 +549,8 @@ static int decode_frame_header(AVCodecContext *ctx,
// Note that in this code, "CUR_FRAME" is actually before we
// have formally allocated a frame, and thus actually represents
// the _last_ frame
- s->s.h.use_last_frame_mvs &= s->frames[CUR_FRAME].tf.f->width == w &&
- s->frames[CUR_FRAME].tf.f->height == h;
+ s->s.h.use_last_frame_mvs &= s->s.frames[CUR_FRAME].tf.f->width == w &&
+ s->s.frames[CUR_FRAME].tf.f->height == h;
if (get_bits1(&s->gb)) // display size
skip_bits(&s->gb, 32);
s->s.h.highprecisionmvs = get_bits1(&s->gb);
@@ -592,7 +575,7 @@ static int decode_frame_header(AVCodecContext *ctx,
}
for (i = 0; i < 3; i++) {
- AVFrame *ref = s->refs[s->s.h.refidx[i]].f;
+ AVFrame *ref = s->s.refs[s->s.h.refidx[i]].f;
int refw = ref->width, refh = ref->height;
if (ref->format != fmt) {
@@ -1098,7 +1081,7 @@ static void find_ref_mvs(VP9Context *s,
} while (0)
if (row > 0) {
- struct VP9mvrefPair *mv = &s->frames[CUR_FRAME].mv[(row - 1) * s->sb_cols * 8 + col];
+ struct VP9mvrefPair *mv = &s->s.frames[CUR_FRAME].mv[(row - 1) * s->sb_cols * 8 + col];
if (mv->ref[0] == ref) {
RETURN_MV(s->above_mv_ctx[2 * col + (sb & 1)][0]);
} else if (mv->ref[1] == ref) {
@@ -1106,7 +1089,7 @@ static void find_ref_mvs(VP9Context *s,
}
}
if (col > s->tile_col_start) {
- struct VP9mvrefPair *mv = &s->frames[CUR_FRAME].mv[row * s->sb_cols * 8 + col - 1];
+ struct 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]);
} else if (mv->ref[1] == ref) {
@@ -1123,7 +1106,7 @@ static void find_ref_mvs(VP9Context *s,
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) {
- struct VP9mvrefPair *mv = &s->frames[CUR_FRAME].mv[r * s->sb_cols * 8 + c];
+ struct VP9mvrefPair *mv = &s->s.frames[CUR_FRAME].mv[r * s->sb_cols * 8 + c];
if (mv->ref[0] == ref) {
RETURN_MV(mv->mv[0]);
@@ -1135,10 +1118,10 @@ static void find_ref_mvs(VP9Context *s,
// MV at this position in previous frame, using same reference frame
if (s->s.h.use_last_frame_mvs) {
- struct VP9mvrefPair *mv = &s->frames[REF_FRAME_MVPAIR].mv[row * s->sb_cols * 8 + col];
+ struct VP9mvrefPair *mv = &s->s.frames[REF_FRAME_MVPAIR].mv[row * s->sb_cols * 8 + col];
- if (!s->frames[REF_FRAME_MVPAIR].uses_2pass)
- ff_thread_await_progress(&s->frames[REF_FRAME_MVPAIR].tf, row >> 3, 0);
+ if (!s->s.frames[REF_FRAME_MVPAIR].uses_2pass)
+ ff_thread_await_progress(&s->s.frames[REF_FRAME_MVPAIR].tf, row >> 3, 0);
if (mv->ref[0] == ref) {
RETURN_MV(mv->mv[0]);
} else if (mv->ref[1] == ref) {
@@ -1161,7 +1144,7 @@ static void find_ref_mvs(VP9Context *s,
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) {
- struct VP9mvrefPair *mv = &s->frames[CUR_FRAME].mv[r * s->sb_cols * 8 + c];
+ struct VP9mvrefPair *mv = &s->s.frames[CUR_FRAME].mv[r * s->sb_cols * 8 + c];
if (mv->ref[0] != ref && mv->ref[0] >= 0) {
RETURN_SCALE_MV(mv->mv[0], s->s.h.signbias[mv->ref[0]] != s->s.h.signbias[ref]);
@@ -1177,7 +1160,7 @@ static void find_ref_mvs(VP9Context *s,
// MV at this position in previous frame, using different reference frame
if (s->s.h.use_last_frame_mvs) {
- struct VP9mvrefPair *mv = &s->frames[REF_FRAME_MVPAIR].mv[row * s->sb_cols * 8 + col];
+ struct VP9mvrefPair *mv = &s->s.frames[REF_FRAME_MVPAIR].mv[row * s->sb_cols * 8 + col];
// no need to await_progress, because we already did that above
if (mv->ref[0] != ref && mv->ref[0] >= 0) {
@@ -1401,12 +1384,12 @@ static void decode_mode(AVCodecContext *ctx)
vp56_rac_get_prob_branchy(&s->c,
s->s.h.segmentation.pred_prob[s->above_segpred_ctx[col] +
s->left_segpred_ctx[row7]]))) {
- if (!s->s.h.errorres && s->frames[REF_FRAME_SEGMAP].segmentation_map) {
+ if (!s->s.h.errorres && s->s.frames[REF_FRAME_SEGMAP].segmentation_map) {
int pred = 8, x;
- uint8_t *refsegmap = s->frames[REF_FRAME_SEGMAP].segmentation_map;
+ uint8_t *refsegmap = s->s.frames[REF_FRAME_SEGMAP].segmentation_map;
- if (!s->frames[REF_FRAME_SEGMAP].uses_2pass)
- ff_thread_await_progress(&s->frames[REF_FRAME_SEGMAP].tf, row >> 3, 0);
+ if (!s->s.frames[REF_FRAME_SEGMAP].uses_2pass)
+ ff_thread_await_progress(&s->s.frames[REF_FRAME_SEGMAP].tf, row >> 3, 0);
for (y = 0; y < h4; y++) {
int idx_base = (y + row) * 8 * s->sb_cols + col;
for (x = 0; x < w4; x++)
@@ -1429,7 +1412,7 @@ static void decode_mode(AVCodecContext *ctx)
}
if (s->s.h.segmentation.enabled &&
(s->s.h.segmentation.update_map || s->s.h.keyframe || s->s.h.intraonly)) {
- setctx_2d(&s->frames[CUR_FRAME].segmentation_map[row * 8 * s->sb_cols + col],
+ setctx_2d(&s->s.frames[CUR_FRAME].segmentation_map[row * 8 * s->sb_cols + col],
bw4, bh4, 8 * s->sb_cols, b->seg_id);
}
@@ -2050,7 +2033,7 @@ static void decode_mode(AVCodecContext *ctx)
// FIXME kinda ugly
for (y = 0; y < h4; y++) {
int x, o = (row + y) * s->sb_cols * 8 + col;
- struct VP9mvrefPair *mv = &s->frames[CUR_FRAME].mv[o];
+ struct VP9mvrefPair *mv = &s->s.frames[CUR_FRAME].mv[o];
if (b->intra) {
for (x = 0; x < w4; x++) {
@@ -2609,7 +2592,7 @@ static av_always_inline void intra_recon(AVCodecContext *ctx, ptrdiff_t y_off,
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->frames[CUR_FRAME].tf.f->data[0] + y_off;
+ uint8_t *dst = s->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]);
@@ -2624,7 +2607,7 @@ static av_always_inline void intra_recon(AVCodecContext *ctx, ptrdiff_t y_off,
int eob = b->skip ? 0 : b->tx > TX_8X8 ? AV_RN16A(&s->eob[n]) : s->eob[n];
mode = check_intra_mode(s, mode, &a, ptr_r,
- s->frames[CUR_FRAME].tf.f->linesize[0],
+ s->s.frames[CUR_FRAME].tf.f->linesize[0],
ptr, s->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);
@@ -2632,7 +2615,7 @@ static av_always_inline void intra_recon(AVCodecContext *ctx, ptrdiff_t y_off,
s->dsp.itxfm_add[tx][txtp](ptr, s->y_stride,
s->block + 16 * n * bytesperpixel, eob);
}
- dst_r += 4 * step1d * s->frames[CUR_FRAME].tf.f->linesize[0];
+ dst_r += 4 * step1d * s->s.frames[CUR_FRAME].tf.f->linesize[0];
dst += 4 * step1d * s->y_stride;
}
@@ -2643,7 +2626,7 @@ static av_always_inline void intra_recon(AVCodecContext *ctx, ptrdiff_t y_off,
step = 1 << (b->uvtx * 2);
for (p = 0; p < 2; p++) {
dst = s->dst[1 + p];
- dst_r = s->frames[CUR_FRAME].tf.f->data[1 + p] + uv_off;
+ 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;
for (x = 0; x < end_x; x += uvstep1d, ptr += 4 * uvstep1d * bytesperpixel,
@@ -2653,7 +2636,7 @@ static av_always_inline void intra_recon(AVCodecContext *ctx, ptrdiff_t y_off,
int eob = b->skip ? 0 : b->uvtx > TX_8X8 ? AV_RN16A(&s->uveob[p][n]) : s->uveob[p][n];
mode = check_intra_mode(s, mode, &a, ptr_r,
- s->frames[CUR_FRAME].tf.f->linesize[1],
+ s->s.frames[CUR_FRAME].tf.f->linesize[1],
ptr, s->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);
@@ -2661,7 +2644,7 @@ static av_always_inline void intra_recon(AVCodecContext *ctx, ptrdiff_t y_off,
s->dsp.itxfm_add[uvtx][DCT_DCT](ptr, s->uv_stride,
s->uvblock[p] + 16 * n * bytesperpixel, eob);
}
- dst_r += 4 * uvstep1d * s->frames[CUR_FRAME].tf.f->linesize[1];
+ dst_r += 4 * uvstep1d * s->s.frames[CUR_FRAME].tf.f->linesize[1];
dst += 4 * uvstep1d * s->uv_stride;
}
}
@@ -2787,8 +2770,8 @@ 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)
{
- if (s->frames[CUR_FRAME].tf.f->width == ref_frame->f->width &&
- s->frames[CUR_FRAME].tf.f->height == ref_frame->f->height) {
+ 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,
y, x, in_mv, bw, bh, w, h, bytesperpixel);
} else {
@@ -2843,8 +2826,8 @@ 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)
{
- if (s->frames[CUR_FRAME].tf.f->width == ref_frame->f->width &&
- s->frames[CUR_FRAME].tf.f->height == ref_frame->f->height) {
+ 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,
ref_v, src_stride_v, ref_frame,
y, x, in_mv, bw, bh, w, h, bytesperpixel);
@@ -3140,7 +3123,7 @@ static void decode_b(AVCodecContext *ctx, int row, int col,
int bytesperpixel = s->bytesperpixel;
int w4 = bwh_tab[1][bs][0], h4 = bwh_tab[1][bs][1], lvl;
int emu[2];
- AVFrame *f = s->frames[CUR_FRAME].tf.f;
+ AVFrame *f = s->s.frames[CUR_FRAME].tf.f;
s->row = row;
s->row7 = row & 7;
@@ -3340,7 +3323,7 @@ static void decode_sb(AVCodecContext *ctx, int row, int col, struct VP9Filter *l
s->prob.p.partition[bl][c];
enum BlockPartition bp;
ptrdiff_t hbs = 4 >> bl;
- AVFrame *f = s->frames[CUR_FRAME].tf.f;
+ AVFrame *f = s->s.frames[CUR_FRAME].tf.f;
ptrdiff_t y_stride = f->linesize[0], uv_stride = f->linesize[1];
int bytesperpixel = s->bytesperpixel;
@@ -3415,7 +3398,7 @@ static void decode_sb_mem(AVCodecContext *ctx, int row, int col, struct VP9Filte
VP9Context *s = ctx->priv_data;
VP9Block *b = s->b;
ptrdiff_t hbs = 4 >> bl;
- AVFrame *f = s->frames[CUR_FRAME].tf.f;
+ AVFrame *f = s->s.frames[CUR_FRAME].tf.f;
ptrdiff_t y_stride = f->linesize[0], uv_stride = f->linesize[1];
int bytesperpixel = s->bytesperpixel;
@@ -3614,7 +3597,7 @@ static void loopfilter_sb(AVCodecContext *ctx, struct VP9Filter *lflvl,
int row, int col, ptrdiff_t yoff, ptrdiff_t uvoff)
{
VP9Context *s = ctx->priv_data;
- AVFrame *f = s->frames[CUR_FRAME].tf.f;
+ AVFrame *f = s->s.frames[CUR_FRAME].tf.f;
uint8_t *dst = f->data[0] + yoff;
ptrdiff_t ls_y = f->linesize[0], ls_uv = f->linesize[1];
uint8_t (*uv_masks)[8][4] = lflvl->mask[s->ss_h | s->ss_v];
@@ -3897,14 +3880,14 @@ static av_cold int vp9_decode_free(AVCodecContext *ctx)
int i;
for (i = 0; i < 3; i++) {
- if (s->frames[i].tf.f->data[0])
- vp9_unref_frame(ctx, &s->frames[i]);
- av_frame_free(&s->frames[i].tf.f);
+ if (s->s.frames[i].tf.f->data[0])
+ vp9_unref_frame(ctx, &s->s.frames[i]);
+ av_frame_free(&s->s.frames[i].tf.f);
}
for (i = 0; i < 8; i++) {
- if (s->refs[i].f->data[0])
- ff_thread_release_buffer(ctx, &s->refs[i]);
- av_frame_free(&s->refs[i].f);
+ if (s->s.refs[i].f->data[0])
+ ff_thread_release_buffer(ctx, &s->s.refs[i]);
+ av_frame_free(&s->s.refs[i].f);
if (s->next_refs[i].f->data[0])
ff_thread_release_buffer(ctx, &s->next_refs[i]);
av_frame_free(&s->next_refs[i].f);
@@ -3924,7 +3907,7 @@ static int vp9_decode_frame(AVCodecContext *ctx, void *frame,
int size = pkt->size;
VP9Context *s = ctx->priv_data;
int res, tile_row, tile_col, i, ref, row, col;
- int retain_segmap_ref = s->frames[REF_FRAME_SEGMAP].segmentation_map &&
+ 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;
@@ -3933,19 +3916,19 @@ static int vp9_decode_frame(AVCodecContext *ctx, void *frame,
if ((res = decode_frame_header(ctx, data, size, &ref)) < 0) {
return res;
} else if (res == 0) {
- if (!s->refs[ref].f->data[0]) {
+ if (!s->s.refs[ref].f->data[0]) {
av_log(ctx, AV_LOG_ERROR, "Requested reference %d not available\n", ref);
return AVERROR_INVALIDDATA;
}
- if ((res = av_frame_ref(frame, s->refs[ref].f)) < 0)
+ if ((res = av_frame_ref(frame, s->s.refs[ref].f)) < 0)
return res;
((AVFrame *)frame)->pkt_pts = pkt->pts;
((AVFrame *)frame)->pkt_dts = pkt->dts;
for (i = 0; i < 8; i++) {
if (s->next_refs[i].f->data[0])
ff_thread_release_buffer(ctx, &s->next_refs[i]);
- if (s->refs[i].f->data[0] &&
- (res = ff_thread_ref_frame(&s->next_refs[i], &s->refs[i])) < 0)
+ if (s->s.refs[i].f->data[0] &&
+ (res = ff_thread_ref_frame(&s->next_refs[i], &s->s.refs[i])) < 0)
return res;
}
*got_frame = 1;
@@ -3955,31 +3938,31 @@ static int vp9_decode_frame(AVCodecContext *ctx, void *frame,
size -= res;
if (!retain_segmap_ref || s->s.h.keyframe || s->s.h.intraonly) {
- if (s->frames[REF_FRAME_SEGMAP].tf.f->data[0])
- vp9_unref_frame(ctx, &s->frames[REF_FRAME_SEGMAP]);
- if (!s->s.h.keyframe && !s->s.h.intraonly && !s->s.h.errorres && s->frames[CUR_FRAME].tf.f->data[0] &&
- (res = vp9_ref_frame(ctx, &s->frames[REF_FRAME_SEGMAP], &s->frames[CUR_FRAME])) < 0)
+ if (s->s.frames[REF_FRAME_SEGMAP].tf.f->data[0])
+ vp9_unref_frame(ctx, &s->s.frames[REF_FRAME_SEGMAP]);
+ if (!s->s.h.keyframe && !s->s.h.intraonly && !s->s.h.errorres && s->s.frames[CUR_FRAME].tf.f->data[0] &&
+ (res = vp9_ref_frame(ctx, &s->s.frames[REF_FRAME_SEGMAP], &s->s.frames[CUR_FRAME])) < 0)
return res;
}
- if (s->frames[REF_FRAME_MVPAIR].tf.f->data[0])
- vp9_unref_frame(ctx, &s->frames[REF_FRAME_MVPAIR]);
- if (!s->s.h.intraonly && !s->s.h.keyframe && !s->s.h.errorres && s->frames[CUR_FRAME].tf.f->data[0] &&
- (res = vp9_ref_frame(ctx, &s->frames[REF_FRAME_MVPAIR], &s->frames[CUR_FRAME])) < 0)
+ if (s->s.frames[REF_FRAME_MVPAIR].tf.f->data[0])
+ vp9_unref_frame(ctx, &s->s.frames[REF_FRAME_MVPAIR]);
+ if (!s->s.h.intraonly && !s->s.h.keyframe && !s->s.h.errorres && s->s.frames[CUR_FRAME].tf.f->data[0] &&
+ (res = vp9_ref_frame(ctx, &s->s.frames[REF_FRAME_MVPAIR], &s->s.frames[CUR_FRAME])) < 0)
return res;
- if (s->frames[CUR_FRAME].tf.f->data[0])
- vp9_unref_frame(ctx, &s->frames[CUR_FRAME]);
- if ((res = vp9_alloc_frame(ctx, &s->frames[CUR_FRAME])) < 0)
+ if (s->s.frames[CUR_FRAME].tf.f->data[0])
+ vp9_unref_frame(ctx, &s->s.frames[CUR_FRAME]);
+ if ((res = vp9_alloc_frame(ctx, &s->s.frames[CUR_FRAME])) < 0)
return res;
- f = s->frames[CUR_FRAME].tf.f;
+ 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->frames[REF_FRAME_SEGMAP].tf.f->data[0] &&
- (s->frames[REF_FRAME_MVPAIR].tf.f->width != s->frames[CUR_FRAME].tf.f->width ||
- s->frames[REF_FRAME_MVPAIR].tf.f->height != s->frames[CUR_FRAME].tf.f->height)) {
- vp9_unref_frame(ctx, &s->frames[REF_FRAME_SEGMAP]);
+ if (s->s.frames[REF_FRAME_SEGMAP].tf.f->data[0] &&
+ (s->s.frames[REF_FRAME_MVPAIR].tf.f->width != s->s.frames[CUR_FRAME].tf.f->width ||
+ s->s.frames[REF_FRAME_MVPAIR].tf.f->height != s->s.frames[CUR_FRAME].tf.f->height)) {
+ vp9_unref_frame(ctx, &s->s.frames[REF_FRAME_SEGMAP]);
}
// ref frame setup
@@ -3987,9 +3970,9 @@ static int vp9_decode_frame(AVCodecContext *ctx, void *frame,
if (s->next_refs[i].f->data[0])
ff_thread_release_buffer(ctx, &s->next_refs[i]);
if (s->s.h.refreshrefmask & (1 << i)) {
- res = ff_thread_ref_frame(&s->next_refs[i], &s->frames[CUR_FRAME].tf);
- } else if (s->refs[i].f->data[0]) {
- res = ff_thread_ref_frame(&s->next_refs[i], &s->refs[i]);
+ res = ff_thread_ref_frame(&s->next_refs[i], &s->s.frames[CUR_FRAME].tf);
+ } else if (s->s.refs[i].f->data[0]) {
+ res = ff_thread_ref_frame(&s->next_refs[i], &s->s.refs[i]);
}
if (res < 0)
return res;
@@ -4008,7 +3991,7 @@ static int vp9_decode_frame(AVCodecContext *ctx, void *frame,
memset(s->above_uv_nnz_ctx[0], 0, s->sb_cols * 16 >> s->ss_h);
memset(s->above_uv_nnz_ctx[1], 0, s->sb_cols * 16 >> s->ss_h);
memset(s->above_segpred_ctx, 0, s->cols);
- s->pass = s->frames[CUR_FRAME].uses_2pass =
+ s->pass = s->s.frames[CUR_FRAME].uses_2pass =
ctx->active_thread_type == FF_THREAD_FRAME && s->s.h.refreshctx && !s->s.h.parallelmode;
if ((res = update_block_buffers(ctx)) < 0) {
av_log(ctx, AV_LOG_ERROR,
@@ -4060,12 +4043,12 @@ static int vp9_decode_frame(AVCodecContext *ctx, void *frame,
size -= 4;
}
if (tile_size > size) {
- ff_thread_report_progress(&s->frames[CUR_FRAME].tf, INT_MAX, 0);
+ ff_thread_report_progress(&s->s.frames[CUR_FRAME].tf, INT_MAX, 0);
return AVERROR_INVALIDDATA;
}
ff_vp56_init_range_decoder(&s->c_b[tile_col], data, tile_size);
if (vp56_rac_get_prob_branchy(&s->c_b[tile_col], 128)) { // marker bit
- ff_thread_report_progress(&s->frames[CUR_FRAME].tf, INT_MAX, 0);
+ ff_thread_report_progress(&s->s.frames[CUR_FRAME].tf, INT_MAX, 0);
return AVERROR_INVALIDDATA;
}
data += tile_size;
@@ -4153,7 +4136,7 @@ static int vp9_decode_frame(AVCodecContext *ctx, void *frame,
// 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->frames[CUR_FRAME].tf, row >> 3, 0);
+ ff_thread_report_progress(&s->s.frames[CUR_FRAME].tf, row >> 3, 0);
}
}
@@ -4162,19 +4145,19 @@ static int vp9_decode_frame(AVCodecContext *ctx, void *frame,
ff_thread_finish_setup(ctx);
}
} while (s->pass++ == 1);
- ff_thread_report_progress(&s->frames[CUR_FRAME].tf, INT_MAX, 0);
+ ff_thread_report_progress(&s->s.frames[CUR_FRAME].tf, INT_MAX, 0);
// ref frame setup
for (i = 0; i < 8; i++) {
- if (s->refs[i].f->data[0])
- ff_thread_release_buffer(ctx, &s->refs[i]);
+ if (s->s.refs[i].f->data[0])
+ ff_thread_release_buffer(ctx, &s->s.refs[i]);
if (s->next_refs[i].f->data[0] &&
- (res = ff_thread_ref_frame(&s->refs[i], &s->next_refs[i])) < 0)
+ (res = ff_thread_ref_frame(&s->s.refs[i], &s->next_refs[i])) < 0)
return res;
}
if (!s->s.h.invisible) {
- if ((res = av_frame_ref(frame, s->frames[CUR_FRAME].tf.f)) < 0)
+ if ((res = av_frame_ref(frame, s->s.frames[CUR_FRAME].tf.f)) < 0)
return res;
*got_frame = 1;
}
@@ -4188,9 +4171,9 @@ static void vp9_decode_flush(AVCodecContext *ctx)
int i;
for (i = 0; i < 3; i++)
- vp9_unref_frame(ctx, &s->frames[i]);
+ vp9_unref_frame(ctx, &s->s.frames[i]);
for (i = 0; i < 8; i++)
- ff_thread_release_buffer(ctx, &s->refs[i]);
+ ff_thread_release_buffer(ctx, &s->s.refs[i]);
}
static int init_frames(AVCodecContext *ctx)
@@ -4199,17 +4182,17 @@ static int init_frames(AVCodecContext *ctx)
int i;
for (i = 0; i < 3; i++) {
- s->frames[i].tf.f = av_frame_alloc();
- if (!s->frames[i].tf.f) {
+ s->s.frames[i].tf.f = av_frame_alloc();
+ if (!s->s.frames[i].tf.f) {
vp9_decode_free(ctx);
av_log(ctx, AV_LOG_ERROR, "Failed to allocate frame buffer %d\n", i);
return AVERROR(ENOMEM);
}
}
for (i = 0; i < 8; i++) {
- s->refs[i].f = av_frame_alloc();
+ s->s.refs[i].f = av_frame_alloc();
s->next_refs[i].f = av_frame_alloc();
- if (!s->refs[i].f || !s->next_refs[i].f) {
+ if (!s->s.refs[i].f || !s->next_refs[i].f) {
vp9_decode_free(ctx);
av_log(ctx, AV_LOG_ERROR, "Failed to allocate frame buffer %d\n", i);
return AVERROR(ENOMEM);
@@ -4249,18 +4232,18 @@ static int vp9_decode_update_thread_context(AVCodecContext *dst, const AVCodecCo
}
for (i = 0; i < 3; i++) {
- if (s->frames[i].tf.f->data[0])
- vp9_unref_frame(dst, &s->frames[i]);
- if (ssrc->frames[i].tf.f->data[0]) {
- if ((res = vp9_ref_frame(dst, &s->frames[i], &ssrc->frames[i])) < 0)
+ if (s->s.frames[i].tf.f->data[0])
+ vp9_unref_frame(dst, &s->s.frames[i]);
+ if (ssrc->s.frames[i].tf.f->data[0]) {
+ if ((res = vp9_ref_frame(dst, &s->s.frames[i], &ssrc->s.frames[i])) < 0)
return res;
}
}
for (i = 0; i < 8; i++) {
- if (s->refs[i].f->data[0])
- ff_thread_release_buffer(dst, &s->refs[i]);
+ if (s->s.refs[i].f->data[0])
+ ff_thread_release_buffer(dst, &s->s.refs[i]);
if (ssrc->next_refs[i].f->data[0]) {
- if ((res = ff_thread_ref_frame(&s->refs[i], &ssrc->next_refs[i])) < 0)
+ if ((res = ff_thread_ref_frame(&s->s.refs[i], &ssrc->next_refs[i])) < 0)
return res;
}
}
diff --git a/libavcodec/vp9.h b/libavcodec/vp9.h
index cac15f4..27cdfc6 100644
--- a/libavcodec/vp9.h
+++ b/libavcodec/vp9.h
@@ -26,6 +26,9 @@
#include <stdint.h>
+#include "thread.h"
+#include "vp56.h"
+
enum BlockLevel {
BL_64X64,
BL_32X32,
@@ -115,6 +118,19 @@ enum CompPredMode {
PRED_SWITCHABLE,
};
+struct VP9mvrefPair {
+ VP56mv mv[2];
+ int8_t ref[2];
+};
+
+typedef struct VP9Frame {
+ ThreadFrame tf;
+ AVBufferRef *extradata;
+ uint8_t *segmentation_map;
+ struct VP9mvrefPair *mv;
+ int uses_2pass;
+} VP9Frame;
+
typedef struct VP9BitstreamHeader {
// bitstream header
uint8_t profile;
@@ -181,6 +197,12 @@ typedef struct VP9BitstreamHeader {
typedef struct VP9SharedContext {
VP9BitstreamHeader h;
+
+ ThreadFrame refs[8];
+#define CUR_FRAME 0
+#define REF_FRAME_MVPAIR 1
+#define REF_FRAME_SEGMAP 2
+ VP9Frame frames[3];
} VP9SharedContext;
#endif /* AVCODEC_VP9_H */
diff --git a/libavcodec/vp9_mc_template.c b/libavcodec/vp9_mc_template.c
index aa848ea..38d9a6d 100644
--- a/libavcodec/vp9_mc_template.c
+++ b/libavcodec/vp9_mc_template.c
@@ -36,14 +36,14 @@ static void FN(inter_pred)(AVCodecContext *ctx)
VP9Context *s = ctx->priv_data;
VP9Block *b = s->b;
int row = s->row, col = s->col;
- ThreadFrame *tref1 = &s->refs[s->s.h.refidx[b->ref[0]]], *tref2;
+ 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;
int bytesperpixel = BYTES_PER_PIXEL;
if (b->comp) {
- tref2 = &s->refs[s->s.h.refidx[b->ref[1]]];
+ tref2 = &s->s.refs[s->s.h.refidx[b->ref[1]]];
ref2 = tref2->f;
w2 = ref2->width;
h2 = ref2->height;
More information about the ffmpeg-cvslog
mailing list