[Bug 738102] New: v4l2bufferpool: cleanly handle streamon failure for output device

GStreamer (bugzilla.gnome.org) bugzilla at gnome.org
Tue Oct 7 09:27:04 PDT 2014


https://bugzilla.gnome.org/show_bug.cgi?id=738102
  GStreamer | gst-plugins-good | git

           Summary: v4l2bufferpool: cleanly handle streamon failure for
                    output device
    Classification: Platform
           Product: GStreamer
           Version: git
        OS/Version: Linux
            Status: UNCONFIRMED
          Severity: normal
          Priority: Normal
         Component: gst-plugins-good
        AssignedTo: gstreamer-bugs at lists.freedesktop.org
        ReportedBy: aurelien.zanelli at parrot.com
         QAContact: gstreamer-bugs at lists.freedesktop.org
     GNOME version: ---


Created an attachment (id=287976)
 --> (https://bugzilla.gnome.org/attachment.cgi?id=287976)
GStreamer v4l2 log on streamon failure

Currently, for an output device, if streamon returns in errors, we end up with
a bad assert:
GLib (gthread-posix.c): Unexpected error from C library during
'pthread_mutex_lock': Invalid argument.  Aborting.
Aborted

This error is caused by a try to lock a v4l2allocator which has been finalized.
I attached a v4l2*:6,bufferpool:6 trace with some additional message.

Basically, v4l2 bufferpool is active and we finalize it. In the finalize
method, we unref the allocator so it's finalize and then we call parent
finalize method, ie gst_buffer_pool_finalize(). This method try to deactivate
pool so it call v4l2_buffer_pool_stop() whoch try to lock v4l2_allocator which
did not exist anymore.
This can be improved by setting allocator to NULL after unref it.

However, this issue is caused by the fact that v4l2 bufferpool can't be
stopped.
Here is my analysis on that issue:

We are in v4l2_buffer_pool_process() in
V4L2_BUF_TYPE_VIDEO_OUTPUT/GST_V4L2_IO_MMAP case. We successfully queue the
first buffer into the driver so pool->buffers[index] == buf, and buf refcount
== 2
Then, since we are not streaming, we call STREAMON which returns in error so we
unref the current buffer and returns in error. (buf refcount == 1)
Then the chain function unref the buffer, so buf is released to the pool using
the gst_v4l2_buffer_pool_release_buffer(). But this function won't chain up to
the parent release_buffer, ie default_release_buffer, because
pool->buffers[index] == NULL condition is false.
So, later in gst_v4l2_buffer_pool_stop, the baseclass bufferpool stop call will
always return FALSE because the previous buffer has not been release from the
baseclass point of view.


So I wrote a patch that on streamon failure set pool->buffers[index] to NULL in
order to have the buffer really released. Removing the buffer unref on failure
will solve crash but we will leak v4l2 bufferpool and allocator because
bufferpool has one outstanding buffer which will never be released.

Another solution could be to allow the gst_v4l2_buffer_pool_release_buffer to
release buffer if pool->buffers[index] is NULL and if we are not streaming.

-- 
Configure bugmail: https://bugzilla.gnome.org/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
You are the QA contact for the bug.
You are the assignee for the bug.


More information about the gstreamer-bugs mailing list