José Vicente R
José Vicente R

Reputation: 23

Sending EOS pipeline gstreamer

I have an example gstreamer pipeline: gst-launch-1.0 v4l2src device=/dev/video2 ! image/jpeg,width=1280, height=800, framerate=30/1 ! v4l2jpegdec ! queue ! v4l2h264enc extra-controls="controls, h264_profile=4, video_bitrate=620000" ! 'video/x-h264, profile=high, level=(string)4' ! h264parse ! matroskamux ! filesink location=output2.mkv

That I run it from the command line. Instead of doing ctrl+c to kill the process, I want to send an EOS event to the process.

Is this possible? And if so, has anyone done it or what is the solution?

Upvotes: 0

Views: 2663

Answers (3)

user20643999
user20643999

Reputation: 11

-e works for me on a single pipe but if I tee the video into two streams it doesn't generate the EOS or create the output file when I terminate with Ctrl-C I added watchdog timeout=1000 to the pipe and disconnected the video input, then the watchdog terminates the stream and generates the EOS but I'd like to be able to do it another way. BTW I'm using windows.

C:\gstreamer\1.0\x86_64\bin\gst-launch-1.0.exe rtspsrc location=rtsp://192.168.189.3:8554/bandwidth_h264 latency=0 ! decodebin ! watchdog timeout=1000 ! tee name=split split.! queue leaky=1 ! autovideosink sync=false split.! queue leaky=1 ! videoconvert ! x264enc ! mp4mux ! filesink location=c:/demo/test.mp4 -e

Upvotes: 1

Daniel Chaves
Daniel Chaves

Reputation: 412

You can do an application that takes care of EOS events.

You could try this example written in Python.

Deps.

sudo apt install python3-gst-1.0

Python3 example:

import threading
import time

import gi
gi.require_version('Gst', '1.0')
gi.require_version('GLib', '2.0')
from gi.repository import Gst
from gi.repository import GLib


class Something(RuntimeError):
    pass


class GStreamer():
    def __init__(self):
        Gst.init(None)

        self.desc = "videotestsrc is-live=true ! appsink"
        self.pipe_obj = None

        self.sleep = 20

    def create_pipeline(self):
        try:
            self.pipe_obj = Gst.parse_launch(self.desc)
        except:
            raise Something("Unable to create pipe object")
    def play_pipeline(self):
        ret = self.pipe_obj.set_state(Gst.State.PLAYING)
        if ret == Gst.StateChangeReturn.FAILURE:
            raise Something("Unable to play pipeline")

    def signal_handler(self):
        appsink = self.pipe_obj.get_by_name("appsink0")
        appsink.connect("eos", self.signal_handler_callback, appsink)

    def signal_handler_callback(self):
        threading.Thread(target=self._counter_thread).start()
        time.sleep(self.sleep)

    def _counter_thread(self):
        for i in range(1, self.sleep + 1):
            time.sleep(1)
            print (i)

gstreamer_instance = GStreamer()
gstreamer_instance.create_pipeline()
gstreamer_instance.play_pipeline()

print ("Started signal handler with timed out EOS to ", gstreamer_instance.sleep)
gstreamer_instance.signal_handler()
gstreamer_instance.signal_handler_callback()

Gst.init(None)

Where, appsink has support for EOS Signal events, you can check that out with gst-inspect-1.0 appsink. You can update the pipeline description to fit yours and have some manipulation to write to the output file, probably using AppSrc element in a new pipeline instance so that it retrieves and saves the buffers.

# Your first instance would be:
gst-launch-1.0 v4l2src device=/dev/video2 ! image/jpeg,width=1280, height=800, framerate=30/1 ! v4l2jpegdec ! queue ! v4l2h264enc extra-controls="controls, h264_profile=4, video_bitrate=620000" ! 'video/x-h264, profile=high, level=(string)4' ! h264parse ! matroskamux ! appsink emit-signals=true

# Your receiver instance would be something similar to:
appsrc ! filesink location=output2.mkv

Hope you get the idea of how to have control of the events into the GSt pipeline process taking advantage of the Element Signals and this example.


EDIT

For a terminal only approach.

Using only the console could possible by sending the correct Signal to process.

You have your pipeline process here, per example:

gst-launch-1.0 -e  videotestsrc ! fakesink

Then from another terminal, you will want to send an Interrupt from Keyboard Standard Signal, i.e.: SIGINT (equivalent to your current Ctrl+C), for your gst-launch-1.0 process.

kill -s SIGINT $(pidof gst-launch-1.0)

That would do the job. Give it a try!

Upvotes: 1

Florian Zwoch
Florian Zwoch

Reputation: 7403

From the --help output of gst-launch-1.0:

  -e, --eos-on-shutdown             Force EOS on sources before shutting the pipeline down

Upvotes: 1

Related Questions