diff --git a/vp9/decoder/vp9_decoder.c b/vp9/decoder/vp9_decoder.c index 13d79ff44b4e5a7e1f41c818a8725f73885cf261..5859859fae68b07a7f6bcf55d60580624637f8c6 100644 --- a/vp9/decoder/vp9_decoder.c +++ b/vp9/decoder/vp9_decoder.c @@ -211,7 +211,10 @@ static void swap_frame_buffers(VP9Decoder *pbi) { } cm->frame_to_show = get_frame_new_buffer(cm); - cm->frame_bufs[cm->new_fb_idx].ref_count--; + + if (!pbi->frame_parallel_decode || !cm->show_frame) { + --cm->frame_bufs[cm->new_fb_idx].ref_count; + } // Invalidate these references until the next frame starts. for (ref_index = 0; ref_index < 3; ref_index++) @@ -240,7 +243,9 @@ int vp9_receive_compressed_data(VP9Decoder *pbi, } // Check if the previous frame was a frame without any references to it. - if (cm->new_fb_idx >= 0 && cm->frame_bufs[cm->new_fb_idx].ref_count == 0) + // Release frame buffer if not decoding in frame parallel mode. + if (!pbi->frame_parallel_decode && cm->new_fb_idx >= 0 && + cm->frame_bufs[cm->new_fb_idx].ref_count == 0) cm->release_fb_cb(cm->cb_priv, &cm->frame_bufs[cm->new_fb_idx].raw_frame_buffer); cm->new_fb_idx = get_free_fb(cm); diff --git a/vp9/vp9_dx_iface.c b/vp9/vp9_dx_iface.c index 98faa7f65762a43c6b314bde185e447880273c7e..07389713a9af1219b6013f6cb56b90a4a3946242 100644 --- a/vp9/vp9_dx_iface.c +++ b/vp9/vp9_dx_iface.c @@ -40,6 +40,7 @@ struct vpx_codec_alg_priv { vpx_image_t img; int invert_tile_order; int frame_parallel_decode; // frame-based threading. + int last_show_frame; // Index of last output frame. // External frame buffer info to save for VP9 common. void *ext_priv; // Private data associated with the external frame buffers. @@ -238,6 +239,7 @@ static void init_decoder(vpx_codec_alg_priv_t *ctx) { ctx->pbi->max_threads = ctx->cfg.threads; ctx->pbi->inv_tile_order = ctx->invert_tile_order; ctx->pbi->frame_parallel_decode = ctx->frame_parallel_decode; + ctx->last_show_frame = -1; // If postprocessing was enabled by the application and a // configuration has not been provided, default it. @@ -430,6 +432,15 @@ static vpx_image_t *decoder_get_frame(vpx_codec_alg_priv_t *ctx, ctx->img.fb_priv = cm->frame_bufs[cm->new_fb_idx].raw_frame_buffer.priv; img = &ctx->img; *iter = img; + // Decrease reference count of last output frame in frame parallel mode. + if (ctx->frame_parallel_decode && ctx->last_show_frame >= 0) { + --cm->frame_bufs[ctx->last_show_frame].ref_count; + if (cm->frame_bufs[ctx->last_show_frame].ref_count == 0) { + cm->release_fb_cb(cm->cb_priv, + &cm->frame_bufs[ctx->last_show_frame].raw_frame_buffer); + } + } + ctx->last_show_frame = ctx->pbi->common.new_fb_idx; } }