diff options
author | Thiago Santos <thiagoss@osg.samsung.com> | 2015-04-17 11:01:27 -0300 |
---|---|---|
committer | Thiago Santos <thiagoss@osg.samsung.com> | 2015-04-17 11:04:50 -0300 |
commit | 08d22e8850fd4a16c25dd496b304ea2ad5963c66 (patch) | |
tree | 3a6f1b204490ef103054e1d6768ba6ee5675f70a | |
parent | 010dbfb077b66f8183e0a5bf9049ad1300a5fcdc (diff) |
vp9dec: implement libvpx buffer allocationvpx-1.4
-rw-r--r-- | ext/vpx/gstvp9dec.c | 74 | ||||
-rw-r--r-- | ext/vpx/gstvp9dec.h | 1 |
2 files changed, 68 insertions, 7 deletions
diff --git a/ext/vpx/gstvp9dec.c b/ext/vpx/gstvp9dec.c index e23b0232a..749badd3a 100644 --- a/ext/vpx/gstvp9dec.c +++ b/ext/vpx/gstvp9dec.c @@ -392,8 +392,8 @@ gst_vp9_dec_image_to_buffer (GstVP9Dec * dec, const vpx_image_t * img, comp); memcpy (dest, src, srcstride * height); } else { - GST_TRACE_OBJECT (dec, "Stride mismatches, copying line by line," - " comp %d", comp); + GST_TRACE_OBJECT (dec, "Stride mismatches (%d != %d), " + "copying line by line, comp %d", srcstride, deststride, comp); for (line = 0; line < height; line++) { memcpy (dest, src, width); dest += deststride; @@ -425,14 +425,23 @@ gst_vp9_dec_get_frame_buffer_cb (void *cb_priv, size_t min_size, frame_data = g_malloc (sizeof (GstVP9DecFrameData)); - data = g_malloc0 (min_size); - frame_data->buffer = gst_buffer_new_wrapped (data, min_size); + if (dec->output_state == NULL) { + data = g_malloc0 (min_size); + frame_data->buffer = gst_buffer_new_wrapped (data, min_size); + } else { + frame_data->buffer = + gst_video_decoder_allocate_output_buffer (GST_VIDEO_DECODER_CAST (dec)); + } gst_buffer_map (frame_data->buffer, &frame_data->mapinfo, GST_MAP_WRITE); frame_data->mapped = TRUE; - fb->data = (void *) data; - fb->size = min_size; + GST_DEBUG_OBJECT (dec, "Requested: %d, got %d", (gint) min_size, + (gint) frame_data->mapinfo.size); + g_assert (frame_data->mapinfo.size >= min_size); + + fb->data = (void *) frame_data->mapinfo.data; + fb->size = frame_data->mapinfo.size; /* priv must be set in order for libvpx to recognize that this was * allocated externally */ fb->priv = frame_data; @@ -555,6 +564,16 @@ open_codec (GstVP9Dec * dec, GstVideoCodecFrame * frame) return GST_FLOW_OK; } +static void +gst_vp9_dec_update_allocation (GstVP9Dec * dec, vpx_image_t * img) +{ + gint c; + + for (c = 0; c < 3; c++) { + dec->last_stride[c] = img->stride[c]; + } +} + static GstFlowReturn gst_vp9_dec_handle_frame (GstVideoDecoder * decoder, GstVideoCodecFrame * frame) { @@ -641,6 +660,7 @@ gst_vp9_dec_handle_frame (GstVideoDecoder * decoder, GstVideoCodecFrame * frame) dec->output_state = gst_video_decoder_set_output_state (GST_VIDEO_DECODER (dec), fmt, img->d_w, img->d_h, dec->input_state); + gst_vp9_dec_update_allocation (dec, img); gst_video_decoder_negotiate (GST_VIDEO_DECODER (dec)); if (send_tags) @@ -652,6 +672,7 @@ gst_vp9_dec_handle_frame (GstVideoDecoder * decoder, GstVideoCodecFrame * frame) (double) -deadline / GST_SECOND); gst_video_decoder_drop_frame (decoder, frame); } else { +#ifdef HAVE_VPX_1_4 ret = gst_video_decoder_allocate_output_frame (decoder, frame); if (ret == GST_FLOW_OK) { @@ -660,6 +681,16 @@ gst_vp9_dec_handle_frame (GstVideoDecoder * decoder, GstVideoCodecFrame * frame) } else { gst_video_decoder_drop_frame (decoder, frame); } +#else + ret = gst_video_decoder_allocate_output_frame (decoder, frame); + + if (ret == GST_FLOW_OK) { + gst_vp9_dec_image_to_buffer (dec, img, frame->output_buffer); + ret = gst_video_decoder_finish_frame (decoder, frame); + } else { + gst_video_decoder_drop_frame (decoder, frame); + } +#endif } vpx_img_free (img); @@ -680,8 +711,10 @@ gst_vp9_dec_handle_frame (GstVideoDecoder * decoder, GstVideoCodecFrame * frame) static gboolean gst_vp9_dec_decide_allocation (GstVideoDecoder * bdec, GstQuery * query) { + GstVP9Dec *dec = GST_VP9_DEC (bdec); GstBufferPool *pool; GstStructure *config; + gboolean has_video_meta, has_alignment_meta; if (!GST_VIDEO_DECODER_CLASS (parent_class)->decide_allocation (bdec, query)) return FALSE; @@ -691,10 +724,37 @@ gst_vp9_dec_decide_allocation (GstVideoDecoder * bdec, GstQuery * query) g_assert (pool != NULL); config = gst_buffer_pool_get_config (pool); - if (gst_query_find_allocation_meta (query, GST_VIDEO_META_API_TYPE, NULL)) { + has_video_meta = + gst_query_find_allocation_meta (query, GST_VIDEO_META_API_TYPE, NULL); + if (has_video_meta) { gst_buffer_pool_config_add_option (config, GST_BUFFER_POOL_OPTION_VIDEO_META); + has_alignment_meta = + gst_buffer_pool_has_option (pool, + GST_BUFFER_POOL_OPTION_VIDEO_ALIGNMENT); } + + if (has_video_meta && has_alignment_meta) { + GstVideoAlignment align; + gint c; + + align.padding_top = 0; + align.padding_left = 0; + align.padding_right = 0; + align.padding_bottom = 0; + + memset (&align, 0, sizeof (GstVideoAlignment)); + for (c = 0; c < 3; c++) { + align.stride_align[c] = dec->last_stride[c]; + GST_DEBUG_OBJECT (dec, "Requesting stride: comp: %d: %d", c, + align.stride_align[c]); + } + + gst_buffer_pool_config_add_option (config, + GST_BUFFER_POOL_OPTION_VIDEO_ALIGNMENT); + gst_buffer_pool_config_set_video_alignment (config, &align); + } + gst_buffer_pool_set_config (pool, config); gst_object_unref (pool); diff --git a/ext/vpx/gstvp9dec.h b/ext/vpx/gstvp9dec.h index 8cd69ba0d..fbbd4b672 100644 --- a/ext/vpx/gstvp9dec.h +++ b/ext/vpx/gstvp9dec.h @@ -63,6 +63,7 @@ struct _GstVP9Dec /* < private > */ vpx_codec_ctx_t decoder; + gint last_stride[3]; /* state */ gboolean decoder_inited; |