static GstFlowReturn gst_gl_view_convert_element_submit_input_buffer (GstBaseTransform * trans, gboolean is_discont, GstBuffer * input) { GstGLContext *context = GST_GL_BASE_FILTER (trans)->context; GstGLViewConvertElement *viewconvert_filter = GST_GL_VIEW_CONVERT_ELEMENT (trans); GstFlowReturn ret; ret = GST_BASE_TRANSFORM_CLASS (parent_class)->submit_input_buffer (trans, is_discont, input); if (ret != GST_FLOW_OK || trans->queued_buf == NULL) return ret; gst_gl_view_convert_set_context (viewconvert_filter->viewconvert, context); /* Takes the ref to the input buffer */ ret = gst_gl_view_convert_submit_input_buffer (viewconvert_filter->viewconvert, is_discont, input); trans->queued_buf = NULL; return ret; }
/* called with the object lock held */ static gboolean gst_gl_stereo_mix_process_frames (GstGLStereoMix * mixer) { GstVideoAggregator *vagg = GST_VIDEO_AGGREGATOR (mixer); GstBuffer *converted_buffer, *inbuf; GstVideoInfo *out_info = &vagg->info; #ifndef G_DISABLE_ASSERT gint n; #endif gint v, views; gint valid_views = 0; GList *walk; inbuf = gst_buffer_new (); walk = GST_ELEMENT (mixer)->sinkpads; while (walk) { GstGLStereoMixPad *pad = walk->data; GstMemory *in_mem; GST_LOG_OBJECT (mixer, "Handling frame %d", valid_views); if (!pad || !pad->current_buffer) { GST_DEBUG ("skipping texture, null frame"); walk = g_list_next (walk); continue; } in_mem = gst_buffer_get_memory (pad->current_buffer, 0); GST_LOG_OBJECT (mixer, "Appending memory %" GST_PTR_FORMAT " to intermediate buffer", in_mem); /* Appending the memory to a 2nd buffer locks it * exclusive a 2nd time, which will mark it for * copy-on-write. The ref will keep the memory * alive but we add a parent_buffer_meta to also * prevent the input buffer from returning to any buffer * pool it might belong to */ gst_buffer_append_memory (inbuf, in_mem); /* Use parent buffer meta to keep input buffer alive */ gst_buffer_add_parent_buffer_meta (inbuf, pad->current_buffer); valid_views++; walk = g_list_next (walk); } if (mixer->mix_info.views != valid_views) { GST_WARNING_OBJECT (mixer, "Not enough input views to process"); return FALSE; } if (GST_VIDEO_INFO_MULTIVIEW_MODE (out_info) == GST_VIDEO_MULTIVIEW_MODE_SEPARATED) views = out_info->views; else views = 1; if (gst_gl_view_convert_submit_input_buffer (mixer->viewconvert, FALSE, inbuf) != GST_FLOW_OK) return FALSE; /* Clear any existing buffers, just in case */ gst_buffer_replace (&mixer->primary_out, NULL); gst_buffer_replace (&mixer->auxilliary_out, NULL); if (gst_gl_view_convert_get_output (mixer->viewconvert, &mixer->primary_out) != GST_FLOW_OK) return FALSE; if (GST_VIDEO_INFO_MULTIVIEW_MODE (out_info) == GST_VIDEO_MULTIVIEW_MODE_FRAME_BY_FRAME) { if (gst_gl_view_convert_get_output (mixer->viewconvert, &mixer->auxilliary_out) != GST_FLOW_OK) return FALSE; } if (mixer->primary_out == NULL) return FALSE; converted_buffer = mixer->primary_out; #ifndef G_DISABLE_ASSERT n = gst_buffer_n_memory (converted_buffer); g_assert (n == GST_VIDEO_INFO_N_PLANES (out_info) * views); #endif for (v = 0; v < views; v++) { gst_buffer_add_video_meta_full (converted_buffer, v, GST_VIDEO_INFO_FORMAT (out_info), GST_VIDEO_INFO_WIDTH (out_info), GST_VIDEO_INFO_HEIGHT (out_info), GST_VIDEO_INFO_N_PLANES (out_info), out_info->offset, out_info->stride); if (mixer->auxilliary_out) { gst_buffer_add_video_meta_full (mixer->auxilliary_out, v, GST_VIDEO_INFO_FORMAT (out_info), GST_VIDEO_INFO_WIDTH (out_info), GST_VIDEO_INFO_HEIGHT (out_info), GST_VIDEO_INFO_N_PLANES (out_info), out_info->offset, out_info->stride); } } return TRUE; }
static GstFlowReturn stereosplit_chain (GstPad * pad, GstGLStereoSplit * split, GstBuffer * buf) { GstBuffer *uploaded_buffer, *converted_buffer, *left, *right; GstBuffer *split_buffer = NULL; GstFlowReturn ret; gint i, n_planes; if (!split->upload) _init_upload (split); n_planes = GST_VIDEO_INFO_N_PLANES (&split->viewconvert->out_info); GST_LOG_OBJECT (split, "chaining buffer %" GST_PTR_FORMAT, buf); if (GST_GL_UPLOAD_DONE != gst_gl_upload_perform_with_buffer (split->upload, buf, &uploaded_buffer)) { gst_buffer_unref (buf); GST_ELEMENT_ERROR (split, RESOURCE, NOT_FOUND, ("%s", "Failed to upload buffer"), (NULL)); return GST_FLOW_ERROR; } gst_buffer_unref (buf); if (!(converted_buffer = gst_gl_color_convert_perform (split->convert, uploaded_buffer))) { GST_ELEMENT_ERROR (split, RESOURCE, NOT_FOUND, ("%s", "Failed to convert buffer"), (NULL)); gst_buffer_unref (uploaded_buffer); return GST_FLOW_ERROR; } gst_buffer_unref (uploaded_buffer); if (gst_gl_view_convert_submit_input_buffer (split->viewconvert, GST_BUFFER_IS_DISCONT (converted_buffer), converted_buffer) != GST_FLOW_OK) { GST_ELEMENT_ERROR (split, RESOURCE, NOT_FOUND, ("%s", "Failed to 3d convert buffer"), ("Could not get submit input buffer")); return GST_FLOW_ERROR; } ret = gst_gl_view_convert_get_output (split->viewconvert, &split_buffer); if (ret != GST_FLOW_OK) { GST_ELEMENT_ERROR (split, RESOURCE, NOT_FOUND, ("%s", "Failed to 3d convert buffer"), ("Could not get output buffer")); return GST_FLOW_ERROR; } if (split_buffer == NULL) return GST_FLOW_OK; /* Need another input buffer */ left = gst_buffer_new (); gst_buffer_copy_into (left, buf, GST_BUFFER_COPY_FLAGS | GST_BUFFER_COPY_TIMESTAMPS, 0, -1); GST_BUFFER_FLAG_UNSET (left, GST_VIDEO_BUFFER_FLAG_FIRST_IN_BUNDLE); gst_buffer_add_parent_buffer_meta (left, split_buffer); for (i = 0; i < n_planes; i++) { GstMemory *mem = gst_buffer_get_memory (split_buffer, i); gst_buffer_append_memory (left, mem); } ret = gst_pad_push (split->left_pad, gst_buffer_ref (left)); /* Allow unlinked on the first pad - as long as the 2nd isn't unlinked */ gst_buffer_unref (left); if (G_UNLIKELY (ret != GST_FLOW_OK && ret != GST_FLOW_NOT_LINKED)) { gst_buffer_unref (split_buffer); return ret; } right = gst_buffer_new (); gst_buffer_copy_into (right, buf, GST_BUFFER_COPY_FLAGS | GST_BUFFER_COPY_TIMESTAMPS, 0, -1); GST_BUFFER_FLAG_UNSET (left, GST_VIDEO_BUFFER_FLAG_FIRST_IN_BUNDLE); gst_buffer_add_parent_buffer_meta (right, split_buffer); for (i = n_planes; i < n_planes * 2; i++) { GstMemory *mem = gst_buffer_get_memory (split_buffer, i); gst_buffer_append_memory (right, mem); } ret = gst_pad_push (split->right_pad, gst_buffer_ref (right)); gst_buffer_unref (right); gst_buffer_unref (split_buffer); return ret; }