Grabbing an image frame from a running pipeline on demand

Charlie Turner charlie at dune.rocks
Wed Jun 8 16:02:57 UTC 2016


Hi all,

My high-level problem is that I'm generating a stream, and at certain
points in time, I would like to take a screenshot from the camera,
ensuring I don't drop any frames in my stream while this happens. More
details follow.

I currently have a pipeline that generates MPEG-TS streams, for
completeness it looks like this,

mpegtsmux name=mux ! multifilesink next-file=5 max-file-duration=5
location=%05d.ts \
  v4l2src device=/dev/video0 ! video/x-raw,width=1280,height=720 !
videoconvert ! \
      x264enc tune=zerolatency cabac=false speed-preset=ultrafast
name=x264enc ! queue ! mux. \
  autoaudiosrc ! audioconvert ! audioresample ! lamemp3enc cbr=true
target=bitrate ! \
      mpegaudioparse ! mux.

This pipeline is always running in my app. This point will be
important in a moment.

What I need to do is at an application-determined point in time, save
one frame from v4l2src device as a JPEG.

What I'd love to be able to do is just launch a separate pipeline
thusly,

v4l2src device=/dev/video0 num-buffers=1 ! jpegenc ! filesink
location="thumbnail.jpg"

Unfortunately, my hardware drivers only allow me to open the video
device once (don't ask :))

So what options do I have,

   1) I first considered a data probe attached the src of my
     camera. What it does it try to map a buffer from the received
     pad, and if that is successful, saves a JPEG image using the raw
     map.data. This feels really nasty, and I doubt I'm making good
     use of Gstreamer here. The other problem with this approach is
     that I need a user-defined hook to capture a frame. I don't want
     to save every frame, so to support this case, it seems like I
     need to have a global somewhere that my app can set, such that
     when the variable is true it enables capturing a frame, and when
     false, the probe just passes the data along.
   2) Another possibility is using the dynamic pipeline support. But no
     matter how I looked at that, I couldn't convince myself I would
     not drop any frames.
   3) I considered using a combination of the 'tee' and 'valve'
      elements. Similar to option 1), it seems like there would have to
      be some global state somewhere that the user code could set to
      turn the valve on. The problem here is I just want a frame, I
      would have to figure out some way of knowing that just one frame
      got encoded, and then turn the valve off. This seems like a bad
      approach.

Could anyone give me a pointer on what a sensible approach to this
issue might be in the Gstreamer framework? I've had a good rummage
through the excellent docs, but I feel like I'm missing something.

Thanks for your time,


-- 
Kind regards,
Charlie Turner
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.freedesktop.org/archives/gstreamer-devel/attachments/20160608/545add12/attachment.html>


More information about the gstreamer-devel mailing list