Grabbing an image frame from a running pipeline on demand

Charlie Turner charlie at dune.rocks
Thu Jun 9 11:52:45 UTC 2016


Thanks Tim! That got me unblocked. May I ask hopefully one final question?
:)

I am now trying to add the "appsrc name=thumbnailer ! jpegenc ! filesink
location=thumb.jpg " pipeline to my now working pipeline with the fakesink.

The following launch line works fine,

$ gst-launch-1.0 -e v4l2src device=/dev/video1 ! tee name=t t. ! queue !
videoconvert ! videorate ! x264enc ! mpegtsmux ! filesink
location=test_stream.ts t. ! queue max-size-bytes=0 max-size-time=0
max-size-buffers=0 ! fakesink name=snapshotter   appsrc name=thumbnailer !
jpegenc ! filesink location=thumb.jpg
Setting pipeline to PAUSED ...
Pipeline is live and does not need PREROLL ...
Setting pipeline to PLAYING ...
New clock: GstSystemClock
Redistribute latency...
  C-c C-chandling interrupt.
Interrupt: Stopping pipeline ...
EOS on shutdown enabled -- Forcing EOS on the pipeline
Waiting for EOS...
Got EOS from element "pipeline0".
EOS received - stopping pipeline...
Execution ended after 0:00:03.865664400
Setting pipeline to PAUSED ...
Setting pipeline to READY ...
Setting pipeline to NULL ...
Freeing pipeline ...

But actually I'm trying to replicate this in a C program, and despite
launching the exact same pipeline, it hangs indefinitely before getting
into the PLAYING state (sometimes I get a libjpeg EOS error). I'll attach
the whole program just in case this snippet doesn't describe enough
context, but here's what I'm doing,

int main(...) {
  ...
  descr =
    g_strdup_printf ("v4l2src device=/dev/video1 ! tee name=t "
    "t. ! queue ! videoconvert ! videorate ! x264enc ! mpegtsmux ! filesink
location=test_stream.ts "
    "t. ! queue max-size-bytes=0 max-size-time=0 max-size-buffers=0 !
fakesink name=snapshotter  "
    " appsrc name=thumbnailer ! jpegenc ! filesink location=thumb.jpg ");

  printf("launch line: %s\n", descr);
  pipeline = gst_parse_launch (descr, &error);

  gst_element_set_state (pipeline, GST_STATE_PLAYING);

  /* wait until it's up and running or failed    << THIS CALL HANGS
SOMETIMES >> */
  if (gst_element_get_state (pipeline, NULL, NULL, -1) ==
GST_STATE_CHANGE_FAILURE) {
    g_error ("Failed to go into PLAYING state");
  }

  g_print ("Running ...\n");
  g_main_loop_run (loop);
  ...
}

$ gcc fakesink_test.c $(pkg-config --cflags gtk+-3.0 gstreamer-1.0) -o
fake_sink_test $(pkg-config --libs gstreamer-1.0 gtk+-3.0)
charlie:[gstreamer]$ ./fake_sink_test
launch line: v4l2src device=/dev/video1 ! tee name=t t. ! queue !
videoconvert ! videorate ! x264enc ! mpegtsmux ! filesink
location=test_stream.ts t. ! queue max-size-bytes=0 max-size-time=0
max-size-buffers=0 ! fakesink name=snapshotter   appsrc name=thumbnailer !
jpegenc ! filesink location=thumb.jpg
// tumbleweed
  C-c C-c


I can copy n' paste my printf output labelled "launch line" above and I
don't see a stall. There must be something wrong with my state management,
but I can't think what else I should do.

Thanks very much for your help,


On 9 June 2016 at 11:48, Tim Müller <tim at centricular.com> wrote:

> On Thu, 2016-06-09 at 11:23 +0100, Charlie Turner wrote:
>
> Hi Charlie,
>
>
> If I run a time "tee'd" pipeline like this,
>
>  gst-launch-1.0 -e v4l2src  device=/dev/video0 ! tee name=t    \
>      t. ! queue ! x264enc ! filesink location=fakesink_test.raw     \
>      t. ! queue ! fakesink
>
> I see the following output in my terminal,
>  (snip)
> And when I look at the "fakesink_test.raw" file, I see that it's zero
> bytes. Something appears to be getting blocked in the above minimal example.
>
> If I remove the x264enc element, the pipeline works as I expect it to,
> producing a suitably large file,
>
>
> The problem is that x264enc with default settings consumes about 3 seconds
> of video before outputting anything, but queue's default size is only ~1
> second. Which means the fakesink branch queue will run full and block, and
> the x264enc branch will never receive enough data for x264enc to output a
> buffer (and make the pipeline as a whole preroll).
>
> You can work around this by making the queue before fakesink unlimited in
> size:
>
>   ! queue max-size-bytes=0 max-size-time=0 max-size-buffers=0 ! fakesink
>
> or by configuring x264enc differently, e.g.
>
>   x264enc tune=zerocopy
>
> (other parameters will also help, this is just the easiest, but it will
> affect quality)
>
> Cheers
>  -Tim
>
> --
>
> Tim Müller, Centricular Ltd - http://www.centricular.com
>
>
> _______________________________________________
> gstreamer-devel mailing list
> gstreamer-devel at lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/gstreamer-devel
>
>


-- 
Kind regards,
Charlie Turner
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.freedesktop.org/archives/gstreamer-devel/attachments/20160609/9100c429/attachment.html>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: fakesink_test.c
Type: text/x-csrc
Size: 1689 bytes
Desc: not available
URL: <https://lists.freedesktop.org/archives/gstreamer-devel/attachments/20160609/9100c429/attachment.c>


More information about the gstreamer-devel mailing list