Commit e4c5f7e2 authored by hkuang's avatar hkuang
Browse files

Delay decreasing reference count in frame-parallel decoding.

The current decoding scheme will decrease the reference count
of the output frame when finish decoding. Then the application
could copy the frame from the decoder buffer to application buffer.
In frame-parallel decoding, a decoded frame will not be outputted
until several frames later which depends on thread numbers. So
the decoded frame's reference count should be decreased only
after application finish copying the frame out. But due to the
limitation of vpx_codec_get_frame, decoder could not know when
application finish decoding. So use a index last_show_frame to
release the last output frame's reference count.

Change-Id: I403ee0d01148ac1182e5a2d87cf7dcc302b51e63
parent c49fda26
...@@ -211,7 +211,10 @@ static void swap_frame_buffers(VP9Decoder *pbi) { ...@@ -211,7 +211,10 @@ static void swap_frame_buffers(VP9Decoder *pbi) {
} }
cm->frame_to_show = get_frame_new_buffer(cm); 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. // Invalidate these references until the next frame starts.
for (ref_index = 0; ref_index < 3; ref_index++) for (ref_index = 0; ref_index < 3; ref_index++)
...@@ -240,7 +243,9 @@ int vp9_receive_compressed_data(VP9Decoder *pbi, ...@@ -240,7 +243,9 @@ int vp9_receive_compressed_data(VP9Decoder *pbi,
} }
// Check if the previous frame was a frame without any references to it. // 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->release_fb_cb(cm->cb_priv,
&cm->frame_bufs[cm->new_fb_idx].raw_frame_buffer); &cm->frame_bufs[cm->new_fb_idx].raw_frame_buffer);
cm->new_fb_idx = get_free_fb(cm); cm->new_fb_idx = get_free_fb(cm);
......
...@@ -40,6 +40,7 @@ struct vpx_codec_alg_priv { ...@@ -40,6 +40,7 @@ struct vpx_codec_alg_priv {
vpx_image_t img; vpx_image_t img;
int invert_tile_order; int invert_tile_order;
int frame_parallel_decode; // frame-based threading. 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. // External frame buffer info to save for VP9 common.
void *ext_priv; // Private data associated with the external frame buffers. 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) { ...@@ -238,6 +239,7 @@ static void init_decoder(vpx_codec_alg_priv_t *ctx) {
ctx->pbi->max_threads = ctx->cfg.threads; ctx->pbi->max_threads = ctx->cfg.threads;
ctx->pbi->inv_tile_order = ctx->invert_tile_order; ctx->pbi->inv_tile_order = ctx->invert_tile_order;
ctx->pbi->frame_parallel_decode = ctx->frame_parallel_decode; ctx->pbi->frame_parallel_decode = ctx->frame_parallel_decode;
ctx->last_show_frame = -1;
// If postprocessing was enabled by the application and a // If postprocessing was enabled by the application and a
// configuration has not been provided, default it. // configuration has not been provided, default it.
...@@ -430,6 +432,15 @@ static vpx_image_t *decoder_get_frame(vpx_codec_alg_priv_t *ctx, ...@@ -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; ctx->img.fb_priv = cm->frame_bufs[cm->new_fb_idx].raw_frame_buffer.priv;
img = &ctx->img; img = &ctx->img;
*iter = 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;
} }
} }
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment