[gst-devel] Managing single buffers (snapshot functionality)

Olivier Aubert olivier.aubert at liris.cnrs.fr
Tue Apr 3 22:15:24 CEST 2007


On Tue, 2007-01-16 at 15:09 +0100, Olivier Aubert wrote:
> The problem I am facing is the snapshot functionality. The playbin
> plugin offers a 'frame' property which points a gstBuffer containing the
> last decoded frame, in whatever format has been negociated in the
> pipeline. Now, I need this frame in PNG.

Just replying to myself... As I did not get any answer, but in the end
figured out how to do it, I am posting the solution I use. It may be of
use to someone else. It defines a conversion pipeline, that can take a
single gst.Buffer (obtained from the 'frame' property of the playbin
element) and convert it to png. In addition, some locking is used to
obtain a synchronous behaviour (the snapshot method returns the PNG
snapshot).

#! /usr/bin/python

import gst
import time
import gtk
from threading import Condition

player=gst.element_factory_make("playbin", "player")
p_conv=gst.parse_launch('fakesrc name=src ! queue name=queue ! videoscale ! ffmpegcolorspace ! video/x-raw-rgb,width=160 ! pngenc ! fakesink name=sink signal-handoffs=true')
p_conv._lock = Condition()

src=p_conv.get_by_name('src')
queue=p_conv.get_by_name('queue')
sink=p_conv.get_by_name('sink')

# Run the p_conv pipeline
p_conv.set_state(gst.STATE_PLAYING)

def buffer_cb(element, buffer, pad):
    print "Snapshot captured", buffer.timestamp / gst.MSECOND
    p_conv._lock.acquire()
    p_conv._buffer=buffer
    p_conv._lock.notify()
    p_conv._lock.release()
    return True

sink.connect('handoff', buffer_cb)

def snapshot():
    """Synchronous snapshot method.

    Returns a gst.Buffer containing a scaled-down PNG version of the
    current frame.
    """
    # Get the current frame
    b=player.props.frame.copy()

    # Lock the snapshot object
    p_conv._lock.acquire()
    p_conv._buffer=None

    # Push it into the conversion pipeline
    queue.get_pad('src').push(b)

    # Wait for the lock to be released
    while p_conv._buffer is None:
        p_conv._lock.wait()

    b=p_conv._buffer.copy()
    p_conv._lock.release()
    return b

player.props.uri='file:///tmp/foo.avi'
player.set_state(gst.STATE_PLAYING)

gtk.main()






More information about the gstreamer-devel mailing list