videotestsrc: use ALLOCATION query

Use the allocation query to get the buffer parameters and potentially a
bufferpool from downstream. Use the bufferpool to create buffers.
This commit is contained in:
Wim Taymans 2011-04-29 12:10:14 +02:00
parent c952567bb6
commit 4dab93ed51
2 changed files with 82 additions and 42 deletions

View file

@ -106,6 +106,7 @@ static void gst_video_test_src_get_times (GstBaseSrc * basesrc,
static GstFlowReturn gst_video_test_src_create (GstPushSrc * psrc, static GstFlowReturn gst_video_test_src_create (GstPushSrc * psrc,
GstBuffer ** buffer); GstBuffer ** buffer);
static gboolean gst_video_test_src_start (GstBaseSrc * basesrc); static gboolean gst_video_test_src_start (GstBaseSrc * basesrc);
static gboolean gst_video_test_src_stop (GstBaseSrc * basesrc);
#define GST_TYPE_VIDEO_TEST_SRC_PATTERN (gst_video_test_src_pattern_get_type ()) #define GST_TYPE_VIDEO_TEST_SRC_PATTERN (gst_video_test_src_pattern_get_type ())
static GType static GType
@ -305,6 +306,7 @@ gst_video_test_src_class_init (GstVideoTestSrcClass * klass)
gstbasesrc_class->query = gst_video_test_src_query; gstbasesrc_class->query = gst_video_test_src_query;
gstbasesrc_class->get_times = gst_video_test_src_get_times; gstbasesrc_class->get_times = gst_video_test_src_get_times;
gstbasesrc_class->start = gst_video_test_src_start; gstbasesrc_class->start = gst_video_test_src_start;
gstbasesrc_class->stop = gst_video_test_src_stop;
gstpushsrc_class->create = gst_video_test_src_create; gstpushsrc_class->create = gst_video_test_src_create;
} }
@ -664,12 +666,17 @@ gst_video_test_src_setcaps (GstBaseSrc * bsrc, GstCaps * caps)
struct fourcc_list_struct *fourcc; struct fourcc_list_struct *fourcc;
GstVideoTestSrc *videotestsrc; GstVideoTestSrc *videotestsrc;
GstVideoTestSrcColorSpec color_spec; GstVideoTestSrcColorSpec color_spec;
GstQuery *query;
GstBufferPool *pool = NULL;
guint alignment, prefix, size;
videotestsrc = GST_VIDEO_TEST_SRC (bsrc); videotestsrc = GST_VIDEO_TEST_SRC (bsrc);
res = gst_video_test_src_parse_caps (caps, &width, &height, res = gst_video_test_src_parse_caps (caps, &width, &height,
&rate_numerator, &rate_denominator, &fourcc, &color_spec); &rate_numerator, &rate_denominator, &fourcc, &color_spec);
if (res) { if (!res)
goto parse_failed;
/* looks ok here */ /* looks ok here */
videotestsrc->fourcc = fourcc; videotestsrc->fourcc = fourcc;
videotestsrc->width = width; videotestsrc->width = width;
@ -682,8 +689,45 @@ gst_video_test_src_setcaps (GstBaseSrc * bsrc, GstCaps * caps)
GST_DEBUG_OBJECT (videotestsrc, "size %dx%d, %d/%d fps", GST_DEBUG_OBJECT (videotestsrc, "size %dx%d, %d/%d fps",
videotestsrc->width, videotestsrc->height, videotestsrc->width, videotestsrc->height,
videotestsrc->rate_numerator, videotestsrc->rate_denominator); videotestsrc->rate_numerator, videotestsrc->rate_denominator);
/* find a pool for the negotiated caps now */
query = gst_query_new_allocation (caps, TRUE);
if (gst_pad_peer_query (bsrc->srcpad, query)) {
/* we got configuration from our peer, parse them */
gst_query_parse_allocation_params (query, &alignment, &prefix, &size,
&pool);
} else {
alignment = 0;
prefix = 0;
size = gst_video_test_src_get_size (videotestsrc, width, height);
} }
if (pool == NULL) {
GstStructure *config;
/* we did not get a pool, make one ourselves then */
pool = gst_buffer_pool_new ();
config = gst_buffer_pool_get_config (pool);
gst_buffer_pool_config_set (config, caps, size, 0, 0, prefix, 0, alignment);
gst_buffer_pool_set_config (pool, config);
}
if (videotestsrc->pool)
gst_object_unref (videotestsrc->pool);
videotestsrc->pool = pool;
/* and activate */
gst_buffer_pool_set_active (pool, TRUE);
return res; return res;
/* ERRORS */
parse_failed:
{
GST_DEBUG_OBJECT (bsrc, "failed to parse caps");
return FALSE;
}
} }
static gboolean static gboolean
@ -823,7 +867,7 @@ static GstFlowReturn
gst_video_test_src_create (GstPushSrc * psrc, GstBuffer ** buffer) gst_video_test_src_create (GstPushSrc * psrc, GstBuffer ** buffer)
{ {
GstVideoTestSrc *src; GstVideoTestSrc *src;
gsize newsize, size; gsize size;
GstBuffer *outbuf = NULL; GstBuffer *outbuf = NULL;
GstFlowReturn res; GstFlowReturn res;
GstClockTime next_time; GstClockTime next_time;
@ -831,44 +875,21 @@ gst_video_test_src_create (GstPushSrc * psrc, GstBuffer ** buffer)
src = GST_VIDEO_TEST_SRC (psrc); src = GST_VIDEO_TEST_SRC (psrc);
if (G_UNLIKELY (src->fourcc == NULL)) if (G_UNLIKELY (src->pool == NULL))
goto not_negotiated; goto not_negotiated;
/* 0 framerate and we are at the second frame, eos */ /* 0 framerate and we are at the second frame, eos */
if (G_UNLIKELY (src->rate_numerator == 0 && src->n_frames == 1)) if (G_UNLIKELY (src->rate_numerator == 0 && src->n_frames == 1))
goto eos; goto eos;
newsize = gst_video_test_src_get_size (src, src->width, src->height);
g_return_val_if_fail (newsize > 0, GST_FLOW_ERROR);
GST_LOG_OBJECT (src, GST_LOG_OBJECT (src,
"creating buffer of %lu bytes with %dx%d image for frame %d", newsize, "creating buffer from pool for frame %d", (gint) src->n_frames);
src->width, src->height, (gint) src->n_frames);
if (src->peer_alloc) { res = gst_buffer_pool_acquire_buffer (src->pool, &outbuf, NULL);
res =
gst_pad_alloc_buffer_and_set_caps (GST_BASE_SRC_PAD (psrc),
GST_BUFFER_OFFSET_NONE, newsize, GST_PAD_CAPS (GST_BASE_SRC_PAD (psrc)),
&outbuf);
if (res != GST_FLOW_OK) if (res != GST_FLOW_OK)
goto no_buffer; goto no_buffer;
/* the buffer could have renegotiated, we need to discard any buffers of the
* wrong size. */
size = gst_buffer_get_size (outbuf);
newsize = gst_video_test_src_get_size (src, src->width, src->height);
if (size != newsize) {
gst_buffer_unref (outbuf);
outbuf = NULL;
}
}
if (outbuf == NULL) {
outbuf = gst_buffer_new_and_alloc (newsize);
gst_buffer_set_caps (outbuf, GST_PAD_CAPS (GST_BASE_SRC_PAD (psrc))); gst_buffer_set_caps (outbuf, GST_PAD_CAPS (GST_BASE_SRC_PAD (psrc)));
}
data = gst_buffer_map (outbuf, &size, NULL, GST_MAP_WRITE); data = gst_buffer_map (outbuf, &size, NULL, GST_MAP_WRITE);
memset (data, 0, size); memset (data, 0, size);
@ -933,6 +954,22 @@ gst_video_test_src_start (GstBaseSrc * basesrc)
return TRUE; return TRUE;
} }
static gboolean
gst_video_test_src_stop (GstBaseSrc * basesrc)
{
GstVideoTestSrc *src = GST_VIDEO_TEST_SRC (basesrc);
/* deactivate */
if (src->pool) {
gst_buffer_pool_set_active (src->pool, FALSE);
gst_object_unref (src->pool);
}
src->pool = NULL;
return TRUE;
}
static gboolean static gboolean
plugin_init (GstPlugin * plugin) plugin_init (GstPlugin * plugin)
{ {

View file

@ -143,6 +143,9 @@ struct _GstVideoTestSrc {
gint rate_numerator; gint rate_numerator;
gint rate_denominator; gint rate_denominator;
/* the bufferpool */
GstBufferPool *pool;
/* private */ /* private */
gint64 timestamp_offset; /* base offset */ gint64 timestamp_offset; /* base offset */
GstClockTime running_time; /* total running time */ GstClockTime running_time; /* total running time */