glupload: Keep input frame mapped as long as needed

When performing a raw upload, we need to keep the raw data mapped as
long as needed.

https://bugzilla.gnome.org/show_bug.cgi?id=752937
This commit is contained in:
Nicolas Dufresne 2015-07-27 16:58:22 -04:00 committed by Nicolas Dufresne
parent eb4d3c352a
commit adbd9d3c05
3 changed files with 61 additions and 16 deletions

View file

@ -1508,22 +1508,26 @@ gst_gl_memory_setup_buffer (GstGLContext * context,
* @valign: a #GstVideoInfo
* @data: a list of per plane data pointers
* @textures: (transfer out): a list of #GstGLMemory
* @user_data: user data for the destroy function
* @notify: A function called each time a memory is freed
*
* Wraps per plane data pointer in @data into the corresponding entry in
* @textures based on @info and padding from @valign.
* @textures based on @info and padding from @valign. Note that the @notify
* will be called as many time as there is planes.
*
* Returns: whether the memory's were sucessfully created.
*/
gboolean
gst_gl_memory_setup_wrapped (GstGLContext * context, GstVideoInfo * info,
GstVideoAlignment * valign, gpointer data[GST_VIDEO_MAX_PLANES],
GstGLMemory * textures[GST_VIDEO_MAX_PLANES])
GstGLMemory * textures[GST_VIDEO_MAX_PLANES], gpointer user_data,
GDestroyNotify notify)
{
gint i;
for (i = 0; i < GST_VIDEO_INFO_N_PLANES (info); i++) {
textures[i] = (GstGLMemory *) gst_gl_memory_wrapped (context, info, i,
valign, data[i], NULL, NULL);
valign, data[i], user_data, notify);
}
return TRUE;

View file

@ -142,7 +142,9 @@ gboolean gst_gl_memory_setup_wrapped (GstGLContext * context,
GstVideoInfo * info,
GstVideoAlignment *valign,
gpointer data[GST_VIDEO_MAX_PLANES],
GstGLMemory *textures[GST_VIDEO_MAX_PLANES]);
GstGLMemory *textures[GST_VIDEO_MAX_PLANES],
gpointer user_data,
GDestroyNotify notify);
gint gst_gl_memory_get_texture_width (GstGLMemory * gl_mem);
gint gst_gl_memory_get_texture_height (GstGLMemory * gl_mem);

View file

@ -696,12 +696,55 @@ static const UploadMethod _upload_meta_upload = {
&_upload_meta_upload_free
};
struct RawUploadFrame
{
gint ref_count;
GstVideoFrame frame;
};
struct RawUpload
{
GstGLUpload *upload;
GstVideoFrame in_frame;
struct RawUploadFrame *in_frame;
};
static struct RawUploadFrame *
_raw_upload_frame_new (struct RawUpload *raw, GstBuffer * buffer)
{
struct RawUploadFrame *frame;
if (!buffer)
return NULL;
frame = g_slice_new (struct RawUploadFrame);
frame->ref_count = 1;
if (!gst_video_frame_map (&frame->frame, &raw->upload->priv->in_info,
buffer, GST_MAP_READ)) {
g_slice_free (struct RawUploadFrame, frame);
return NULL;
}
raw->upload->priv->in_info = frame->frame.info;
return frame;
}
static void
_raw_upload_frame_ref (struct RawUploadFrame *frame)
{
g_atomic_int_inc (&frame->ref_count);
}
static void
_raw_upload_frame_unref (struct RawUploadFrame *frame)
{
if (g_atomic_int_dec_and_test (&frame->ref_count)) {
gst_video_frame_unmap (&frame->frame);
g_slice_free (struct RawUploadFrame, frame);
}
}
static gpointer
_raw_data_upload_new (GstGLUpload * upload)
{
@ -738,15 +781,9 @@ _raw_data_upload_accept (gpointer impl, GstBuffer * buffer, GstCaps * in_caps,
if (!gst_caps_features_contains (features, GST_CAPS_FEATURE_MEMORY_GL_MEMORY))
return FALSE;
if (buffer) {
if (!gst_video_frame_map (&raw->in_frame, &raw->upload->priv->in_info,
buffer, GST_MAP_READ))
return FALSE;
raw->in_frame = _raw_upload_frame_new (raw, buffer);
raw->upload->priv->in_info = raw->in_frame.info;
}
return TRUE;
return (raw->in_frame != NULL);
}
static void
@ -772,10 +809,12 @@ _raw_data_upload_perform (gpointer impl, GstBuffer * buffer,
max_planes *= GST_VIDEO_INFO_VIEWS (in_info);
gst_gl_memory_setup_wrapped (raw->upload->context,
&raw->upload->priv->in_info, NULL, raw->in_frame.data, in_tex);
&raw->upload->priv->in_info, NULL, raw->in_frame->frame.data, in_tex,
raw->in_frame, (GDestroyNotify) _raw_upload_frame_unref);
*outbuf = gst_buffer_new ();
for (i = 0; i < max_planes; i++) {
_raw_upload_frame_ref (raw->in_frame);
gst_buffer_append_memory (*outbuf, (GstMemory *) in_tex[i]);
}
@ -786,8 +825,8 @@ static void
_raw_data_upload_release (gpointer impl, GstBuffer * buffer)
{
struct RawUpload *raw = impl;
gst_video_frame_unmap (&raw->in_frame);
_raw_upload_frame_unref (raw->in_frame);
raw->in_frame = NULL;
}
static void