使用gstreamer将视频文件从服务器传输到客户端时出错

时间:2014-01-28 14:18:55

标签: video-streaming gstreamer rtp

我正在尝试传输视频并在客户端PC上播放。 管道(服务器端):

 gst-launch videotestsrc ! ffenc_mpeg4 ! rtpmp4vpay ! udpsink host=192.168.1.16 port=5000 

工作正常。 但现在,我需要从服务器传输视频文件而不是videotestsrc。这是管道:

gst-launch filesrc location=movie.mp4 ! ffenc_mpeg4 ! rtpmp4vpay ! udpsink host=192.168.1.16 port=5000 

我收到此错误:

Setting pipeline to PAUSED ...
Pipeline is PREROLLING ...

** (gst-launch-0.10:10550): CRITICAL **: gst_ffmpegenc_chain_video: assertion `frame_size == GST_BUFFER_SIZE (inbuf)' failed
ERROR: from element /GstPipeline:pipeline0/GstFileSrc:filesrc0: Internal data flow error.
Additional debug info:
gstbasesrc.c(2625): gst_base_src_loop (): /GstPipeline:pipeline0/GstFileSrc:filesrc0:
streaming task paused, reason error (-5)
ERROR: pipeline doesn't want to preroll.
Setting pipeline to NULL ...
Freeing pipeline ... 

似乎缓冲区没有足够的空间(我认为......)。

有人知道如何修复它吗?

1 个答案:

答案 0 :(得分:3)

让我们来看看你的第二个管道:

gst-launch filesrc location=movie.mp4 ! ffenc_mpeg4 ! rtpmp4vpay ! udpsink host=192.168.1.16 port=5000 

您正在连接filesrc(在您的情况下,正在阅读已编码的.mp4文件,并在不知道其格式的情况下输出文件的原始内容。)

然后你将这些数据直接填充到ffenc_mpeg4 使用gst-inspect ffenc_mpeg4查看接收器上限,我们会收到以下信息:

…
Pad Templates:
  …
  SINK template: 'sink'
    Availability: Always
    Capabilities:
      video/x-raw-rgb
      video/x-raw-yuv
      video/x-raw-gray
…

所以ffenc_mpeg4期望原始未编码的视频位于其接收器(=输入),但它得到的是mpeg4数据(未声明为此类)。

因此我们的问题有两种可能的解决方案:

  • 不修改发送mp4文件。这样,服务器只需读取文件并将其内容写入网络套接字即可。

    gst-launch-0.10 filesrc location=movie.mp4 ! udpsink host=192.168.1.16 port=5000
    

    这样服务器就不必进行任何cpu密集型的重新编码,因此需要很少的资源 但是如果你有不同格式的源文件,客户端必须支持所有这些(并正确检测它们)。

  • 另一种方法是在重新编码之前对文件进行解码(只需在管道中添加decodebin):

    gst-launch filesrc location=movie.mp4 ! decodebin ! ffenc_mpeg4 ! rtpmp4vpay ! udpsink host=192.168.1.16 port=5000
    

    这里的优点是(无论相应地配置编码器元素),无论您获得哪种输入文件格式,只要您的服务器可以对其进行解码,您最终将获得MPEG4 UDP流,但服务器可能会浪费资源(并丢失视频质量)通过解码文件只是为了将其编码回相同的格式。