static GstFlowReturn
gst_v4l2_buffer_pool_qbuf (GstV4l2BufferPool * pool, GstBuffer * buf)
{
- GstFlowReturn ret;
GstV4l2MemoryGroup *group = NULL;
gint index;
index = group->buffer.index;
- if (V4L2_TYPE_IS_OUTPUT (pool->obj->type)) {
- /* If already queued, dequeue it, so we keep the render order */
- while (pool->buffers[index]) {
- GstBuffer *tmp;
-
- ret = gst_v4l2_buffer_pool_dqbuf (pool, &tmp);
-
- if (ret != GST_FLOW_OK)
- goto already_queued;
-
- gst_buffer_unref (tmp);
- }
- } else {
- /* Should never happen, would mean a buffer got freed twice */
- g_return_val_if_fail (pool->buffers[index] == NULL, GST_FLOW_ERROR);
- }
+ if (pool->buffers[index] != NULL)
+ goto already_queued;
GST_LOG_OBJECT (pool, "queuing buffer %i", index);
already_queued:
{
- if (ret != GST_FLOW_FLUSHING)
- GST_ERROR_OBJECT (pool,
- "buffer %i was already queued and we could not dequeue it", index);
- return ret;
+ GST_ERROR_OBJECT (pool, "the buffer %i was already queued", index);
+ return GST_FLOW_ERROR;
}
queue_failed:
{
case GST_V4L2_IO_DMABUF:
case GST_V4L2_IO_MMAP:
{
- GstBuffer *to_queue;
+ GstBuffer *to_queue = NULL;
+ GstV4l2MemoryGroup *group;
+ gint index;
- if ((*buf)->pool == bpool) {
- /* nothing, we can queue directly */
- to_queue = gst_buffer_ref (*buf);
- GST_LOG_OBJECT (pool, "processing buffer from our pool");
- } else {
+ if ((*buf)->pool != bpool)
+ goto copying;
+
+ if (!gst_v4l2_is_buffer_valid (*buf, &group))
+ goto copying;
+
+ index = group->buffer.index;
+
+ GST_LOG_OBJECT (pool, "processing buffer %i from our pool", index);
+
+ index = group->buffer.index;
+ if (pool->buffers[index] != NULL) {
+ GST_LOG_OBJECT (pool, "buffer %i already queued, copying", index);
+ goto copying;
+ }
+
+ /* we can queue directly */
+ to_queue = gst_buffer_ref (*buf);
+
+ copying:
+ if (to_queue == NULL) {
GstBufferPoolAcquireParams params = { 0 };
GST_LOG_OBJECT (pool, "alloc buffer from our pool");
gst_v4l2sink_propose_allocation (GstBaseSink * bsink, GstQuery * query)
{
GstV4l2Sink *v4l2sink = GST_V4L2SINK (bsink);
- return gst_v4l2_object_propose_allocation (v4l2sink->v4l2object, query);
+ gboolean last_sample_enabled;
+
+ if (!gst_v4l2_object_propose_allocation (v4l2sink->v4l2object, query))
+ return FALSE;
+
+ g_object_get (bsink, "enable-last-sample", &last_sample_enabled, NULL);
+
+ if (last_sample_enabled) {
+ GstBufferPool *pool;
+ guint size, min, max;
+
+ gst_query_parse_nth_allocation_pool (query, 0, &pool, &size, &min, &max);
+
+ /* we need 1 more, otherwise we'll run out of buffers at preroll */
+ min++;
+ if (max < min)
+ max = min;
+
+ gst_query_set_nth_allocation_pool (query, 0, pool, size, min, max);
+ }
+
+ return TRUE;
}
/* called after A/V sync to render frame */