Eugenio Peroni
Eugenio Peroni

Reputation: 1

Gstreamer Webrtcbin displaying only 1 frame

I’m developing a custom WebRTC system built upon Gstreamer’s webrtcbin element and gi library. The objective is to have 1 Linux machine stream a video to another Linux machine, where it is displayed. All of course inside a WebRTC framework.

The current state of the application is the following: signaling is being handled correctly, ICE candidates and SDP offer/answer are exchanged through a custom signalin server, therefore the stream is indeed routed from the first to the second machine, but here comes the issue:

The receiving pipeline only displays (autovideosink > nicesink0) a single frame, then it gets stuck. I figure that something is wrong with just the receiving pipeline, since Wireshark and logs show that the packets coming from the sender do keep on flowing into the receiving machine even after the immediate freeze.

I here provide the code of the transmitting and receiving script, as well as its logs and the still picture shown by autovideosink.

Transmitter script

import random
import ssl
import websockets
import asyncio
import json
import gi
import sys
gi.require_version('Gst', '1.0')
from gi.repository import Gst
gi.require_version('GstWebRTC', '1.0')
from gi.repository import GstWebRTC
gi.require_version('GstSdp', '1.0')
from gi.repository import GstSdp


PIPELINE_DESC = '''
webrtcbin name=sendrecv bundle-policy=max-bundle
videotestsrc is-live=true pattern=ball ! videorate ! video/x-raw, framerate=1/1 ! videoconvert ! queue ! 
x264enc tune=zerolatency bitrate=500 speed-preset=ultrafast ! rtph264pay !
queue ! application/x-rtp,media=video,encoding-name=H264,payload=97 ! sendrecv.
videotestsrc is-live=true pattern=ball ! videoconvert ! autovideosink
'''


class WebRTCSender:
    def __init__(self, peer_id, server):
        self.peer_id = peer_id
        self.server = server or 'ws://192.168.1.154:8080'
        self.conn = None
        self.pipe = None
        self.webrtc = None

    async def connect(self):
        print("Connecting to signaling server...")
        self.conn = await websockets.connect(self.server)
        print(f"Connected to signaling server at {self.server}")
        hello_msg = f"HELLO {random.randint(10, 10000)}"
        print(f"Sending HELLO message: {hello_msg}")
        await self.conn.send(hello_msg)

    async def setup_call(self):
        session_msg = f"SESSION {self.peer_id}"
        print(f"Requesting session with peer ID: {self.peer_id}")
        await self.conn.send(session_msg)

    def send_sdp_offer(self, offer, peer_id):
        text = offer.sdp.as_text()
        print("SDP Offer created:\n", text)
        msg = json.dumps({'sdp': {'type': 'offer', 'sdp': text}, 'to': peer_id})
        print(f"Sending SDP offer message:\n{msg}")
        asyncio.run(self.conn.send(msg))

    def on_offer_created(self, promise, _, __):
        print("Creating SDP offer...")
        promise.wait()
        reply = promise.get_reply()
        offer = reply.get_value('offer')
        promise = Gst.Promise.new()
        self.webrtc.emit('set-local-description', offer, promise)
        print("SDP offer successfully set as local description.")
        self.send_sdp_offer(offer, self.peer_id)

    def on_negotiation_needed(self, element):
        print("Negotiation needed, creating SDP offer...")
        promise = Gst.Promise.new_with_change_func(self.on_offer_created, element, None)
        element.emit('create-offer', None, promise)

    def send_ice_candidate(self, _, mlineindex, candidate, peer_id):
        msg = json.dumps({'ice': {'candidate': candidate, 'sdpMLineIndex': mlineindex}, 'to': peer_id})
        print(f"Sending ICE candidate:\n{msg}")
        asyncio.run(self.conn.send(msg))
    
    def add_ice_candidate(self, candidate, mlineindex):
        print(f"Adding ICE candidate: {candidate}, mline index: {mlineindex}")
        self.webrtc.emit('add-ice-candidate', mlineindex, candidate)

    def start_pipeline(self):
        print("Starting GStreamer pipeline...")
        self.pipe = Gst.parse_launch(PIPELINE_DESC)
        self.webrtc = self.pipe.get_by_name('sendrecv')
        if not self.webrtc:
            print("Error: webrtcbin element not found!")
            return
        self.webrtc.connect('on-negotiation-needed', self.on_negotiation_needed)
        self.webrtc.connect('on-ice-candidate', lambda _, mlineindex, candidate: self.send_ice_candidate(_, mlineindex, candidate, self.peer_id))  # Fix here
        self.pipe.set_state(Gst.State.PLAYING)
        print("Pipeline started successfully.")

    def handle_sdp_answer(self, answer_sdp):
        print("Handling SDP answer...")
        res, sdpmsg = GstSdp.SDPMessage.new()
        GstSdp.sdp_message_parse_buffer(bytes(answer_sdp.encode()), sdpmsg)
        answer = GstWebRTC.WebRTCSessionDescription.new(GstWebRTC.WebRTCSDPType.ANSWER, sdpmsg)
        promise = Gst.Promise.new()
        self.webrtc.emit('set-remote-description', answer, promise)
        promise.wait()  # Wait for the operation to complete
        print("SDP answer successfully set as remote description.")

    async def handle_messages(self):
        async for message in self.conn:
            print(f"Received message from server: {message}")
            
            # Handle SESSION_OK message separately
            if message == "SESSION_OK":
                print("Session established, starting pipeline...")
                self.start_pipeline()
            
            # Handle ERROR message
            elif "ERROR" in message:
                print(f"Error received from server: {message}")
            
            # Try to parse other messages as JSON
            else:
                try:
                    msg = json.loads(message)
                    # Print out the raw message for better debugging
                    print(f"Parsed message: {msg}")
                    if msg.get("type") == "SESSION_REQUEST":
                        print(f"Session requested by {msg['from']}")
                        # Handle session request logic here
                    elif "sdp" in msg:
                        if msg["sdp"]["type"] == "offer":
                            print("SDP Offer received, processing...")
                            self.handle_sdp_offer(msg["sdp"]["sdp"])
                        elif msg["sdp"]["type"] == "answer":
                            print("SDP Answer received, processing...")
                            self.handle_sdp_answer(msg["sdp"]["sdp"])
                    elif "ice" in msg:
                        print(f"ICE candidate received: {msg['ice']['candidate']}")
                        self.add_ice_candidate(msg["ice"]["candidate"], msg["ice"]["sdpMLineIndex"])
                except json.JSONDecodeError:
                    print("Error: Received non-JSON message. Raw message:", message)


    async def run(self):
        await self.connect()
        await self.setup_call()
        await self.handle_messages()

def check_plugins():
    needed = ["opus", "vpx", "nice", "webrtc", "dtls", "srtp", "rtp",
            "rtpmanager", "videotestsrc", "audiotestsrc"]
    missing = list(filter(lambda p: Gst.Registry.get().find_plugin(p) is None, needed))
    if len(missing):
        print('Missing gstreamer plugins:', missing)
        return False
    return True

if __name__ == '__main__':
    Gst.init(None)
    if not check_plugins():
        sys.exit(1)
    peer_id = input("Enter the receiver's peer ID: ")
    server = input("Enter the signaling server URL: ")
    sender = WebRTCSender(peer_id, server)
    asyncio.run(sender.run())

Receiver script:

import ssl
import websockets
import asyncio
import json
import gi
import sys
import os
gi.require_version('Gst', '1.0')
from gi.repository import Gst
gi.require_version('GstWebRTC', '1.0')
from gi.repository import GstWebRTC
gi.require_version('GstSdp', '1.0')
from gi.repository import GstSdp

# Set the environment variable to enable dot file generation
os.environ['GST_DEBUG_DUMP_DOT_DIR'] = '/media/sf_shared_folder/webrtc'

class WebRTCReceiver:
    def __init__(self, server):
        self.server = server or 'ws://192.168.1.154:8080'
        self.conn = None
        self.pipe = None
        self.webrtc = None
        self.sender_id = None  # Initialize sender_id
        self.ice_candidates = []  # Store receiver's ICE candidates until SDP offer is received


    async def connect(self):
        print("Connecting to signaling server...")
        self.conn = await websockets.connect(self.server)
        print(f"Connected to signaling server at {self.server}")
        self.peer_id = input("Enter a unique peer ID for this receiver (e.g., 'receiver'): ")
        hello_msg = f"HELLO {self.peer_id}"
        print(f"Sending HELLO message: {hello_msg}")
        await self.conn.send(hello_msg)

    async def send_sdp_answer(self, answer):
        if self.sender_id:
            print(f"Sender ID: {self.sender_id}")
        else:
            print("Error: No sender ID found.")

        print("SDP Answer created:\n", answer)
        msg = json.dumps({'sdp': {'type': 'answer', 'sdp': answer}, 'to': self.sender_id})
        print(f"Sending SDP answer message:\n{msg}")
        await self.conn.send(msg)

    def handle_sdp_offer(self, offer_sdp):
        print("Handling SDP offer...")
        res, sdpmsg = GstSdp.SDPMessage.new()
        GstSdp.sdp_message_parse_buffer(bytes(offer_sdp.encode()), sdpmsg)
        offer = GstWebRTC.WebRTCSessionDescription.new(GstWebRTC.WebRTCSDPType.OFFER, sdpmsg)
        promise = Gst.Promise.new()
        self.webrtc.emit('set-remote-description', offer, promise)
        promise.wait()
        print("SDP offer successfully set as remote description.")
        print("Creating SDP answer...")
        promise = Gst.Promise.new()
        self.webrtc.emit('create-answer', None, promise)
        promise.wait()
        reply = promise.get_reply()
        answer = reply.get_value('answer')
        promise = Gst.Promise.new()
        self.webrtc.emit('set-local-description', answer, promise)
        print("SDP answer successfully set as local description.")
        
        # Use await instead of asyncio.run() to avoid event loop conflicts
        asyncio.create_task(self.send_sdp_answer(answer.sdp.as_text()))

        # Now that the answer has been sent, send the locally collected ICE candidates
        for candidate in self.ice_candidates:
            self.send_ice_candidate(candidate['mlineindex'], candidate['candidate'], self.peer_id)
        self.ice_candidates.clear()  # Clear the list after sending candidates

    def send_ice_candidate(self, mlineindex, candidate):
        msg = json.dumps({'ice': {'candidate': candidate, 'sdpMLineIndex': mlineindex}, 'to': self.sender_id})
        print(f"Sending ICE candidate:\n{msg}")
        asyncio.run(self.conn.send(msg))

    def add_ice_candidate(self, candidate, mlineindex):
        print(f"Adding ICE candidate: {candidate}, mline index: {mlineindex}")
        self.webrtc.emit('add-ice-candidate', mlineindex, candidate)

    def on_ice_candidate(self, _, mlineindex, candidate):
        # Store ICE candidates until the SDP offer has been received and processed
        ret, state, pending = self.webrtc.get_state(Gst.CLOCK_TIME_NONE)
        if state != Gst.State.PLAYING:
            # Handle the case where the state is not playing
            print(f"Storing ICE candidate until SDP is processed: {candidate}")
            self.ice_candidates.append({'mlineindex': mlineindex, 'candidate': candidate})
        else:
            self.send_ice_candidate(mlineindex, candidate)

    def on_incoming_stream(self, _, pad):
        if pad.direction != Gst.PadDirection.SRC:
            return
        print("Incoming stream detected.")

        # Use a single decodebin for all incoming streams
        decodebin = self.pipe.get_by_name("decodebin")
        if not decodebin:
            decodebin = Gst.ElementFactory.make("decodebin", "decodebin")
            self.pipe.add(decodebin)
            decodebin.sync_state_with_parent()
        
        decodebin.connect("pad-added", self.on_decodebin_pad_added)
        pad.link(decodebin.get_static_pad("sink"))

    def on_decodebin_pad_added(self, _, pad):
        if not pad.has_current_caps():
            return
        name = pad.get_current_caps().to_string()
        print(f"Decodebin pad added, caps: {name}")

        if name.startswith("video"):
            # Add a queue to handle buffering
            queue = Gst.ElementFactory.make("queue", "queue")
            convert = Gst.ElementFactory.make("videoconvert", "convert")
            # Explicitly set the desired sink (autovideosink)
            sink = Gst.ElementFactory.make("autovideosink", "sink")
            sink.set_property("sync", True)

            # Add elements to the pipeline
            self.pipe.add(queue)
            self.pipe.add(convert)
            self.pipe.add(sink)

            # Link elements: pad -> queue -> convert -> sink
            queue.sync_state_with_parent()
            convert.sync_state_with_parent()
            sink.sync_state_with_parent()
            pad.link(queue.get_static_pad("sink"))
            queue.link(convert)
            convert.link(sink)

            Gst.debug_bin_to_dot_file(self.pipe, Gst.DebugGraphDetails.ALL, '/media/sf_shared_folder/webrtc/pipeline.dot')


    def start_pipeline(self):
        print("Starting GStreamer pipeline...")
        self.pipe = Gst.parse_launch("webrtcbin name=recvrecv ! autovideosink sync=true")
        self.webrtc = self.pipe.get_by_name("recvrecv")
        if not self.webrtc:
            print("Error: 'recvrecv' webrtcbin element not found!")
            return
        self.webrtc.connect('on-ice-candidate', self.on_ice_candidate)  # Collect ICE candidates
        self.webrtc.connect("pad-added", self.on_incoming_stream)
        self.pipe.set_state(Gst.State.PLAYING)
        print("Pipeline started successfully.")


    async def handle_messages(self):
        async for message in self.conn:
            print(f"Received message from server: {message}")
            try:
                msg = json.loads(message)
                # Print out the raw message for better debugging
                print(f"Parsed message: {msg}")
                if msg.get("type") == "SESSION_REQUEST":
                    print(f"Session requested by {msg['from']}")
                    self.sender_id = msg["from"]  # Store sender_id
                elif "sdp" in msg:
                    if msg["sdp"]["type"] == "offer":
                        print("SDP Offer received, processing...")
                        self.handle_sdp_offer(msg["sdp"]["sdp"])
                elif "ice" in msg:
                    print(f"ICE candidate received: {msg['ice']['candidate']}")
                    self.add_ice_candidate(msg["ice"]["candidate"], msg["ice"]["sdpMLineIndex"])
            except json.JSONDecodeError:
                print("Error: Received non-JSON message. Raw message:", message)

    async def run(self):
        await self.connect()
        self.start_pipeline()
        await self.handle_messages()

def check_plugins():
    needed = ["opus", "vpx", "nice", "webrtc", "dtls", "srtp", "rtp",
            "rtpmanager", "videotestsrc", "audiotestsrc"]
    missing = list(filter(lambda p: Gst.Registry.get().find_plugin(p) is None, needed))
    if len(missing):
        print('Missing gstreamer plugins:', missing)
        return False
    return True

if __name__ == '__main__':
    Gst.init(None)
    if not check_plugins():
        sys.exit(1)
    server = input("Enter the signaling server URL: ")
    receiver = WebRTCReceiver(server)
    asyncio.run(receiver.run())

Here what I see. On the left the sender showing the video that should be also displayed at rx. On the right, the receiver showing only a still image. enter image description here

Here the logs of the receiver starting from the instant in which the still image pops up:

0:00:21.325265430  5912 0x7f6a44009ea0 DEBUG               basesink gstbasesink.c:3523:gst_base_sink_chain_unlocked:<sink-actual-sink-ximage> got times start: 0:00:06.572815005, end: 0:00:07.572815005
0:00:21.325315400  5912 0x7f6a44009ea0 DEBUG               basesink gstbasesink.c:2110:gst_base_sink_get_sync_times:<sink-actual-sink-ximage> got times start: 0:00:06.572815005, stop: 0:00:07.572815005, do_sync 1
0:00:21.325320188  5912 0x7f6a44009ea0 DEBUG               basesink gstbasesink.c:2415:gst_base_sink_do_preroll:<sink-actual-sink-ximage> prerolling object 0x7f6a6c020a20
0:00:21.325322932  5912 0x7f6a44009ea0 DEBUG               basesink gstbasesink.c:1014:gst_base_sink_set_last_buffer_unlocked:<sink-actual-sink-ximage> setting last buffer to 0x7f6a6c020a20
0:00:21.325326169  5912 0x7f6a44009ea0 DEBUG               basesink gstbasesink.c:2437:gst_base_sink_do_preroll:<sink-actual-sink-ximage> preroll buffer 0:00:06.572815005
0:00:21.325739691  5912 0x7f6a44009ea0 DEBUG               basesink gstbasesink.c:1657:gst_base_sink_commit_state:<sink-actual-sink-ximage> committing state to PAUSED
0:00:21.325746742  5912 0x7f6a44009ea0 DEBUG               basesink gstbasesink.c:1682:gst_base_sink_commit_state:<sink-actual-sink-ximage> posting PAUSED state change message
0:00:21.325751879  5912 0x7f6a44009ea0 DEBUG               basesink gstbasesink.c:1688:gst_base_sink_commit_state:<sink-actual-sink-ximage> posting async-done message
0:00:21.325758565  5912 0x7f6a44009ea0 DEBUG               basesink gstbasesink.c:2368:gst_base_sink_wait_preroll:<sink-actual-sink-ximage> waiting in preroll for flush or PLAYING
0:00:22.040558093  5912 0x7f6a74002180 DEBUG             capsfilter gstcapsfilter.c:427:gst_capsfilter_prepare_buf:<capsfilter0> Have fixed output caps application/x-rtp to apply to srcpad
0:00:22.307256810  5912 0x7f6a74002180 DEBUG             capsfilter gstcapsfilter.c:427:gst_capsfilter_prepare_buf:<capsfilter0> Have fixed output caps application/x-rtp to apply to srcpad
0:00:22.307332351  5912 0x7f6a74002180 DEBUG             capsfilter gstcapsfilter.c:427:gst_capsfilter_prepare_buf:<capsfilter0> Have fixed output caps application/x-rtp to apply to srcpad
0:00:22.307344613  5912 0x7f6a74002180 DEBUG             capsfilter gstcapsfilter.c:427:gst_capsfilter_prepare_buf:<capsfilter0> Have fixed output caps application/x-rtp to apply to srcpad
0:00:22.307374661  5912 0x7f6a74002180 DEBUG             capsfilter gstcapsfilter.c:427:gst_capsfilter_prepare_buf:<capsfilter0> Have fixed output caps application/x-rtp to apply to srcpad
0:00:23.309308592  5912 0x7f6a74002180 DEBUG             capsfilter gstcapsfilter.c:427:gst_capsfilter_prepare_buf:<capsfilter0> Have fixed output caps application/x-rtp to apply to srcpad
0:00:23.309376294  5912 0x7f6a74002180 DEBUG             capsfilter gstcapsfilter.c:427:gst_capsfilter_prepare_buf:<capsfilter0> Have fixed output caps application/x-rtp to apply to srcpad
0:00:23.309388225  5912 0x7f6a74002180 DEBUG             capsfilter gstcapsfilter.c:427:gst_capsfilter_prepare_buf:<capsfilter0> Have fixed output caps application/x-rtp to apply to srcpad
0:00:23.309399203  5912 0x7f6a74002180 DEBUG             capsfilter gstcapsfilter.c:427:gst_capsfilter_prepare_buf:<capsfilter0> Have fixed output caps application/x-rtp to apply to srcpad
0:00:24.309958944  5912 0x7f6a74002180 DEBUG             capsfilter gstcapsfilter.c:427:gst_capsfilter_prepare_buf:<capsfilter0> Have fixed output caps application/x-rtp to apply to srcpad
0:00:24.310026477  5912 0x7f6a74002180 DEBUG             capsfilter gstcapsfilter.c:427:gst_capsfilter_prepare_buf:<capsfilter0> Have fixed output caps application/x-rtp to apply to srcpad
0:00:24.310038381  5912 0x7f6a74002180 DEBUG             capsfilter gstcapsfilter.c:427:gst_capsfilter_prepare_buf:<capsfilter0> Have fixed output caps application/x-rtp to apply to srcpad
0:00:24.310049091  5912 0x7f6a74002180 DEBUG             capsfilter gstcapsfilter.c:427:gst_capsfilter_prepare_buf:<capsfilter0> Have fixed output caps application/x-rtp to apply to srcpad
0:00:24.763041524  5912 0x7f6a74002000 DEBUG               basesink gstbasesink.c:3523:gst_base_sink_chain_unlocked:<nicesink0> got times start: 99:99:99.999999999, end: 99:99:99.999999999
0:00:24.763116673  5912 0x7f6a74002000 DEBUG               basesink gstbasesink.c:2110:gst_base_sink_get_sync_times:<nicesink0> got times start: 99:99:99.999999999, stop: 99:99:99.999999999, do_sync 0
0:00:24.763123733  5912 0x7f6a74002000 DEBUG               basesink gstbasesink.c:3641:gst_base_sink_chain_unlocked:<nicesink0> rendering object 0x7f6a78006120
0:00:24.763351744  5912 0x7f6a74002000 DEBUG               basesink gstbasesink.c:3680:gst_base_sink_chain_unlocked:<nicesink0> object unref after render 0x7f6a78006120
0:00:25.311213315  5912 0x7f6a74002180 DEBUG             capsfilter gstcapsfilter.c:427:gst_capsfilter_prepare_buf:<capsfilter0> Have fixed output caps application/x-rtp to apply to srcpad
0:00:25.311651168  5912 0x7f6a74002180 DEBUG             capsfilter gstcapsfilter.c:427:gst_capsfilter_prepare_buf:<capsfilter0> Have fixed output caps application/x-rtp to apply to srcpad
0:00:25.311715941  5912 0x7f6a74002180 DEBUG             capsfilter gstcapsfilter.c:427:gst_capsfilter_prepare_buf:<capsfilter0> Have fixed output caps application/x-rtp to apply to srcpad
0:00:25.311729609  5912 0x7f6a74002180 DEBUG             capsfilter gstcapsfilter.c:427:gst_capsfilter_prepare_buf:<capsfilter0> Have fixed output caps application/x-rtp to apply to srcpad
0:00:26.309745812  5912 0x7f6a74002180 DEBUG             capsfilter gstcapsfilter.c:427:gst_capsfilter_prepare_buf:<capsfilter0> Have fixed output caps application/x-rtp to apply to srcpad
0:00:26.309854876  5912 0x7f6a74002180 DEBUG             capsfilter gstcapsfilter.c:427:gst_capsfilter_prepare_buf:<capsfilter0> Have fixed output caps application/x-rtp to apply to srcpad
0:00:26.309867885  5912 0x7f6a74002180 DEBUG             capsfilter gstcapsfilter.c:427:gst_capsfilter_prepare_buf:<capsfilter0> Have fixed output caps application/x-rtp to apply to srcpad
0:00:26.309878099  5912 0x7f6a74002180 DEBUG             capsfilter gstcapsfilter.c:427:gst_capsfilter_prepare_buf:<capsfilter0> Have fixed output caps application/x-rtp to apply to srcpad
0:00:27.319067619  5912 0x7f6a74002180 DEBUG             capsfilter gstcapsfilter.c:427:gst_capsfilter_prepare_buf:<capsfilter0> Have fixed output caps application/x-rtp to apply to srcpad
0:00:27.319180781  5912 0x7f6a74002180 DEBUG             capsfilter gstcapsfilter.c:427:gst_capsfilter_prepare_buf:<capsfilter0> Have fixed output caps application/x-rtp to apply to srcpad
0:00:27.319266276  5912 0x7f6a74002180 DEBUG             capsfilter gstcapsfilter.c:427:gst_capsfilter_prepare_buf:<capsfilter0> Have fixed output caps application/x-rtp to apply to srcpad
0:00:27.319341624  5912 0x7f6a74002180 DEBUG             capsfilter gstcapsfilter.c:427:gst_capsfilter_prepare_buf:<capsfilter0> Have fixed output caps application/x-rtp to apply to srcpad
0:00:28.312261874  5912 0x7f6a74002180 DEBUG             capsfilter gstcapsfilter.c:427:gst_capsfilter_prepare_buf:<capsfilter0> Have fixed output caps application/x-rtp to apply to srcpad
0:00:28.312372555  5912 0x7f6a74002180 DEBUG             capsfilter gstcapsfilter.c:427:gst_capsfilter_prepare_buf:<capsfilter0> Have fixed output caps application/x-rtp to apply to srcpad
0:00:28.312386451  5912 0x7f6a74002180 DEBUG             capsfilter gstcapsfilter.c:427:gst_capsfilter_prepare_buf:<capsfilter0> Have fixed output caps application/x-rtp to apply to srcpad
0:00:28.312397203  5912 0x7f6a74002180 DEBUG             capsfilter gstcapsfilter.c:427:gst_capsfilter_prepare_buf:<capsfilter0> Have fixed output caps application/x-rtp to apply to srcpad
0:00:29.211383556  5912 0x7f6a74002180 DEBUG             capsfilter gstcapsfilter.c:427:gst_capsfilter_prepare_buf:<capsfilter0> Have fixed output caps application/x-rtp to apply to srcpad
0:00:29.310223599  5912 0x7f6a74002180 DEBUG             capsfilter gstcapsfilter.c:427:gst_capsfilter_prepare_buf:<capsfilter0> Have fixed output caps application/x-rtp to apply to srcpad
0:00:29.310336482  5912 0x7f6a74002180 DEBUG             capsfilter gstcapsfilter.c:427:gst_capsfilter_prepare_buf:<capsfilter0> Have fixed output caps application/x-rtp to apply to srcpad
0:00:29.310351762  5912 0x7f6a74002180 DEBUG             capsfilter gstcapsfilter.c:427:gst_capsfilter_prepare_buf:<capsfilter0> Have fixed output caps application/x-rtp to apply to srcpad
0:00:29.310362276  5912 0x7f6a74002180 DEBUG             capsfilter gstcapsfilter.c:427:gst_capsfilter_prepare_buf:<capsfilter0> Have fixed output caps application/x-rtp to apply to srcpad
0:00:30.308692784  5912 0x7f6a74002180 DEBUG             capsfilter gstcapsfilter.c:427:gst_capsfilter_prepare_buf:<capsfilter0> Have fixed output caps application/x-rtp to apply to srcpad
0:00:30.308796218  5912 0x7f6a74002180 DEBUG             capsfilter gstcapsfilter.c:427:gst_capsfilter_prepare_buf:<capsfilter0> Have fixed output caps application/x-rtp to apply to srcpad
0:00:30.308809108  5912 0x7f6a74002180 DEBUG             capsfilter gstcapsfilter.c:427:gst_capsfilter_prepare_buf:<capsfilter0> Have fixed output caps application/x-rtp to apply to srcpad
0:00:30.308818906  5912 0x7f6a74002180 DEBUG             capsfilter gstcapsfilter.c:427:gst_capsfilter_prepare_buf:<capsfilter0> Have fixed output caps application/x-rtp to apply to srcpad
0:00:30.309033875  5912 0x7f6a74002180 DEBUG             capsfilter gstcapsfilter.c:427:gst_capsfilter_prepare_buf:<capsfilter0> Have fixed output caps application/x-rtp to apply to srcpad
0:00:30.309236375  5912 0x7f6a74002180 DEBUG             capsfilter gstcapsfilter.c:427:gst_capsfilter_prepare_buf:<capsfilter0> Have fixed output caps application/x-rtp to apply to srcpad
0:00:31.308726155  5912 0x7f6a74002180 DEBUG             capsfilter gstcapsfilter.c:427:gst_capsfilter_prepare_buf:<capsfilter0> Have fixed output caps application/x-rtp to apply to srcpad
0:00:31.308797639  5912 0x7f6a74002180 DEBUG             capsfilter gstcapsfilter.c:427:gst_capsfilter_prepare_buf:<capsfilter0> Have fixed output caps application/x-rtp to apply to srcpad
0:00:31.308811091  5912 0x7f6a74002180 DEBUG             capsfilter gstcapsfilter.c:427:gst_capsfilter_prepare_buf:<capsfilter0> Have fixed output caps application/x-rtp to apply to srcpad
0:00:31.308821368  5912 0x7f6a74002180 DEBUG             capsfilter gstcapsfilter.c:427:gst_capsfilter_prepare_buf:<capsfilter0> Have fixed output caps application/x-rtp to apply to srcpad
0:00:31.668928944  5912 0x7f6a74002000 DEBUG               basesink gstbasesink.c:3523:gst_base_sink_chain_unlocked:<nicesink0> got times start: 99:99:99.999999999, end: 99:99:99.999999999
0:00:31.669214260  5912 0x7f6a74002000 DEBUG               basesink gstbasesink.c:2110:gst_base_sink_get_sync_times:<nicesink0> got times start: 99:99:99.999999999, stop: 99:99:99.999999999, do_sync 0
0:00:31.669223397  5912 0x7f6a74002000 DEBUG               basesink gstbasesink.c:3641:gst_base_sink_chain_unlocked:<nicesink0> rendering object 0x7f6a78006240
0:00:31.669550916  5912 0x7f6a74002000 DEBUG               basesink gstbasesink.c:3680:gst_base_sink_chain_unlocked:<nicesink0> object unref after render 0x7f6a78006240
0:00:32.307815552  5912 0x7f6a74002180 DEBUG             capsfilter gstcapsfilter.c:427:gst_capsfilter_prepare_buf:<capsfilter0> Have fixed output caps application/x-rtp to apply to srcpad
0:00:32.307914052  5912 0x7f6a74002180 DEBUG             capsfilter gstcapsfilter.c:427:gst_capsfilter_prepare_buf:<capsfilter0> Have fixed output caps application/x-rtp to apply to srcpad
0:00:32.307927162  5912 0x7f6a74002180 DEBUG             capsfilter gstcapsfilter.c:427:gst_capsfilter_prepare_buf:<capsfilter0> Have fixed output caps application/x-rtp to apply to srcpad
0:00:32.307937257  5912 0x7f6a74002180 DEBUG             capsfilter gstcapsfilter.c:427:gst_capsfilter_prepare_buf:<capsfilter0> Have fixed output caps application/x-rtp to apply to srcpad

Does anyone have any tips on the matter? Thanks!!

What I should display is of course the original video flow. I tried modifying the sink to another kind (ximagesink, for istance) but then the pipeline simply doesn't start.

Upvotes: 0

Views: 30

Answers (0)

Related Questions