Method to Cancel/Abort GStreamer tcpclientsink Timeout

痞子三分冷 提交于 2019-12-11 20:29:14

问题


I am working on an application that uses GStreamer to send a Motion JPEG video stream through a tcpclientsink element. The application works fine, except if I disrupt the network by switching the connection from wired to wireless or wireless to wired. When that happens, it looks like the tcpclientsink element waits 15 minutes before responding to messages. That becomes a problem if I try to shut down the application during this time. Here is what I've observed:

  1. Start a Motion JPEG media stream with GStreamer using tcpclientsink as the sink. The code pushing the video runs in its own thread.
  2. While the media stream is running, disrupt the connection by switching the type of network connection.
  3. Start shutting down the application. Call gst_bus_post(bus, gst_message_new_eos(NULL)). This seems to get ignored.
  4. Call pthread_join to wait for the video thread to exit. It does not respond for up to 15 minutes.

When I look at the GST_DEBUG messages, I can see that the GStreamer tcpclientsink hit an error while writing. It apparently waits 15 minutes while retrying.

Is there a way I can abort or cancel the timeout associated with tcpclientsink? Is there a different message I could send to cause the sink to terminate immediately?

I know I can use pthread_timedjoin_np and pthread_cancel to kill the video thread if GStreamer does not respond as fast as I would like, but I would prefer to have GStreamer exit as cleanly as possible.

Update

I should have mentioned I'm using GStreamer 0.10.36. Unfortunately this might just be a bug with that version. I see the handling has changed quite a bit in 1.2.x. I'm still hoping there is a workaround for the version I'm using.

I was able to recreate this problem using gst-launch-0.10. This might be more complicated than necessary, but it worked for me:

Launch three scripts:

  • The following relays the data between the consumer and the producer:

    while [ 1 ] do gst-launch-0.10 tcpserversrc host=0 port=${PORT_IN} ! jpegdec ! jpegenc ! tcpserversink port=${PORT_OUT} done

  • The following is the script for the consumer

    gst-launch-0.10 tcpclientsrc host=${IP_ADDR} port=${PORT_OUT} ! jpegdec ! ffmpegcolorspace ! ximagesink

  • The following is the script for the producer

    gst-launch-0.10 ximagesrc ! videoscale ! video/x-raw-rgb,framerate=1/1,width=640,height=320 ! ffmpegcolorspace ! jpegenc ! tcpclientsink host=${IP_ADDR} port=${PORT_IN}

I ran the first two scripts on one machine and the third script on a second machine. When I switched the network connection on the second machine from wired to wireless, it took 15+ minutes for the tcpclientsink to report an error.


回答1:


In order to fix the problem, I had to patch GStreamer. I added code to specify the send timeout in the gst_tcp_client_sink_start() function of gsttcpclientsink.c

struct timeval timeout;
timeout.tv_sec = 60;
timeout.tv_usec = 0;
...
setsockopt (this->sock_fd.fd, SOL_SOCKET, SO_SNDTIMEO, (char *)&timeout, sizeof(timeout));

Now the application is capable of shutting down within one minute (acceptable for my situation) even if the network was disrupted while streaming video.

Note: It doesn't look like this will be a problem with version 1.2.1, but I need to stay with 0.10.36.



来源:https://stackoverflow.com/questions/20548804/method-to-cancel-abort-gstreamer-tcpclientsink-timeout

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!