summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThiago Santos <thiagoss@osg.samsung.com>2015-04-17 11:01:27 -0300
committerThiago Santos <thiagoss@osg.samsung.com>2015-04-17 11:04:50 -0300
commit08d22e8850fd4a16c25dd496b304ea2ad5963c66 (patch)
tree3a6f1b204490ef103054e1d6768ba6ee5675f70a
parent010dbfb077b66f8183e0a5bf9049ad1300a5fcdc (diff)
vp9dec: implement libvpx buffer allocationvpx-1.4
-rw-r--r--ext/vpx/gstvp9dec.c74
-rw-r--r--ext/vpx/gstvp9dec.h1
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;