带有 GStreamer 的 HDHomeRun 电视调谐器

带有 GStreamer 的 HDHomeRun 电视调谐器

我一直试图从我的 HDHR 调谐器读取 RTP 源,但没有成功。有人有这方面的经验吗?

GStreamer:

gst-launch --gst-debug=udpsrc:5 udpsrc port=5000 caps="application/x-rtp,media=(string)video,format=(fourcc)I420, width=(int)720, height=(int)480,encoding-name=(string)RAW,sampling=(string)YUV,pixel-aspect-ratio=(fraction)8/9, framerate=(fraction)30000/1001, interlaced=(boolean)true" ! gstrtpbin ! rtpvrawdepay ! filesink location=/tmp/output
  • 在某个时候,我通过某种方式通过自动检测获得了这些功能。

高清图:

hdhomerun_config 1310DA25 set /tuner2/target udp://192.168.5.102:5000

当我尝试通过 RTP 发送(rtp://192.168.5.102:5000,而不是如上所述使用 UDP)时,无论使用什么功能,只要它沉入 gstrtpbin,每次都会收到 UDP 错误:

ERROR: from element /GstPipeline:pipeline0/GstUDPSrc:udpsrc0: Internal data flow error.

我认为这意味着链接的焊盘之间的功能不匹配。

当我使用 UDP 方案(最初,上面)时,我没有收到任何错误,但没有数据通过管道移动。

--gst-debug 在各个层次的各个元素上都没有给我任何有用的东西。

VLC 运行完美,无论我是发送到 rtp://xxx.xxx.xxx.xxx:nnnn 并在 rtp://:nnnn 上接收,还是发送到 udp://xxx.xxx.xxx.xxx:nnnn 并在 udp://:nnnn 上接收。

有什么想法吗?

另外,GST 是否无法自动识别 RTP 流的功能?我不知道我是怎么遇到这个问题的(为了获得上述功能),但它似乎不太直观。似乎如果 VLC(超级多功能)可以做到这一点,那么 GStreamer(同样超级多功能)也可以做到这一点。

谢谢。

达斯汀

顺便说一下,我是通过使用 playbin2 获得这个的:

dustin@dustinlenovo:/tmp$ gst-launch --gst-debug=playbin2:5 playbin2 uri=udp://192.168.5.102:5000
0:00:00.021952272 32470  0x9683400 LOG                 playbin2 gstplaybin2.c:1318:gst_playbin_uri_is_valid:<playbin20> checking uri 'udp://192.168.5.102:5000'
0:00:00.022006314 32470  0x9683400 DEBUG               playbin2 gstplaybin2.c:1372:gst_play_bin_set_uri: set new uri to udp://192.168.5.102:5000
Setting pipeline to PAUSED ...
0:00:00.022144060 32470  0x9683400 LOG                 playbin2 gstplaybin2.c:3895:gst_play_bin_change_state:<playbin20> clearing shutdown flag
0:00:00.022164495 32470  0x9683400 DEBUG               playbin2 gstplaybin2.c:3790:setup_next_source:<playbin20> setup sources
0:00:00.022194614 32470  0x9683400 DEBUG               playbin2 gstplaybin2.c:3477:activate_group:<playbin20> activating group 0x9711318
0:00:00.022208169 32470  0x9683400 DEBUG               playbin2 gstplaybin2.c:3498:activate_group:<playbin20> making new uridecodebin
0:00:00.022597792 32470  0x9683400 DEBUG               playbin2 gstplaybin2.c:3456:group_set_locked_state_unlocked:<playbin20> locked_state 0 on group 0x9711318
0:00:00.023812556 32470  0x9683400 DEBUG               playbin2 gstplaybin2.c:2317:gst_play_bin_handle_message:<playbin20> Ignoring async state change of uridecodebin: uridecodebin0
Pipeline is live and does not need PREROLL ...
Setting pipeline to PLAYING ...
New clock: GstSystemClock





0:00:14.542698212 32470  0x95e5720 DEBUG               playbin2 gstplaybin2.c:3214:autoplug_continue_cb:<playbin20> continue autoplugging group 0x9711318 for '':decodepad0, video/mpegts, systemstream=(boolean)true, packetsize=(int)188: 1
0:00:14.542910589 32470  0x95e5720 DEBUG               playbin2 gstplaybin2.c:3049:autoplug_factories_cb:<playbin20> factories group 0x9711318 for '':decodepad0, video/mpegts, systemstream=(boolean)true, packetsize=(int)188
0:00:14.550811109 32470  0x95e5720 DEBUG               playbin2 gstplaybin2.c:3059:autoplug_factories_cb:<playbin20> found factories 0xb64189b0
0:00:14.551117538 32470  0x95e5720 DEBUG               playbin2 gstplaybin2.c:3268:autoplug_select_cb:<playbin20> select group 0x9711318 for '':decodepad0, video/mpegts, systemstream=(boolean)true, packetsize=(int)188
0:00:14.551202471 32470  0x95e5720 DEBUG               playbin2 gstplaybin2.c:3271:autoplug_select_cb:<playbin20> checking factory mpegtsdemux
0:00:14.713355113 32470  0x95e5720 DEBUG               playbin2 gstplaybin2.c:3214:autoplug_continue_cb:<playbin20> continue autoplugging group 0x9711318 for '':decodepad1, audio/x-ac3: 1
0:00:14.713401299 32470  0x95e5720 DEBUG               playbin2 gstplaybin2.c:3049:autoplug_factories_cb:<playbin20> factories group 0x9711318 for '':decodepad1, audio/x-ac3
0:00:14.713622715 32470  0x95e5720 DEBUG               playbin2 gstplaybin2.c:3059:autoplug_factories_cb:<playbin20> found factories 0xb6418b80
0:00:14.714048757 32470  0x95e5720 DEBUG               playbin2 gstplaybin2.c:3268:autoplug_select_cb:<playbin20> select group 0x9711318 for '':decodepad1, audio/x-ac3
0:00:14.714097628 32470  0x95e5720 DEBUG               playbin2 gstplaybin2.c:3271:autoplug_select_cb:<playbin20> checking factory pulsesink
0:00:14.714125521 32470  0x95e5720 DEBUG               playbin2 gstplaybin2.c:3344:autoplug_select_cb:<playbin20> we found a sink
0:00:14.714151129 32470  0x95e5720 DEBUG               playbin2 gstplaybin2.c:3350:autoplug_select_cb:<playbin20> we found an audio sink
0:00:14.714177845 32470  0x95e5720 DEBUG               playbin2 gstplaybin2.c:3393:autoplug_select_cb:<playbin20> we have no pending sink, try to create one
0:00:14.724957778 32470  0x95e5720 DEBUG               playbin2 gstplaybin2.c:3268:autoplug_select_cb:<playbin20> select group 0x9711318 for '':decodepad1, audio/x-ac3
0:00:14.725003694 32470  0x95e5720 DEBUG               playbin2 gstplaybin2.c:3271:autoplug_select_cb:<playbin20> checking factory ac3parse
0:00:14.725687536 32470  0x95e5720 DEBUG               playbin2 gstplaybin2.c:3049:autoplug_factories_cb:<playbin20> factories group 0x9711318 for '':decodepad2, audio/x-ac3, framed=(boolean)true, channels=(int)[ 1, 6 ], rate=(int)[ 8000, 48000 ], alignment=(string){ iec61937, frame }; audio/x-eac3, framed=(boolean)true, channels=(int)[ 1, 6 ], rate=(int)[ 8000, 48000 ], alignment=(string){ iec61937, frame }
0:00:14.725996661 32470  0x95e5720 DEBUG               playbin2 gstplaybin2.c:3059:autoplug_factories_cb:<playbin20> found factories 0xb6458eb0
0:00:14.728966979 32470  0x95e5720 DEBUG               playbin2 gstplaybin2.c:3214:autoplug_continue_cb:<playbin20> continue autoplugging group 0x9711318 for '':decodepad3, video/mpeg, mpegversion=(int)2, systemstream=(boolean)false: 1
0:00:14.729094763 32470  0x95e5720 DEBUG               playbin2 gstplaybin2.c:3049:autoplug_factories_cb:<playbin20> factories group 0x9711318 for '':decodepad3, video/mpeg, mpegversion=(int)2, systemstream=(boolean)false
0:00:14.730460890 32470  0x95e5720 DEBUG               playbin2 gstplaybin2.c:3059:autoplug_factories_cb:<playbin20> found factories 0xb6418620
0:00:14.731074426 32470  0x95e5720 DEBUG               playbin2 gstplaybin2.c:3268:autoplug_select_cb:<playbin20> select group 0x9711318 for '':decodepad3, video/mpeg, mpegversion=(int)2, systemstream=(boolean)false
0:00:14.731165683 32470  0x95e5720 DEBUG               playbin2 gstplaybin2.c:3271:autoplug_select_cb:<playbin20> checking factory mpegvideoparse
0:00:14.744258860 32470 0xb643be90 DEBUG               playbin2 gstplaybin2.c:3214:autoplug_continue_cb:<playbin20> continue autoplugging group 0x9711318 for '':decodepad5, video/mpeg, mpegversion=(int)2, systemstream=(boolean)false, parsed=(boolean)true: 1
0:00:14.744409010 32470 0xb643be90 DEBUG               playbin2 gstplaybin2.c:3049:autoplug_factories_cb:<playbin20> factories group 0x9711318 for '':decodepad5, video/mpeg, mpegversion=(int)2, systemstream=(boolean)false, parsed=(boolean)true
0:00:14.744667670 32470 0xb643be90 DEBUG               playbin2 gstplaybin2.c:3059:autoplug_factories_cb:<playbin20> found factories 0xb4c00950
0:00:14.744743720 32470 0xb643be90 DEBUG               playbin2 gstplaybin2.c:3268:autoplug_select_cb:<playbin20> select group 0x9711318 for '':decodepad5, video/mpeg, mpegversion=(int)2, systemstream=(boolean)false, parsed=(boolean)true
0:00:14.744758143 32470 0xb643be90 DEBUG               playbin2 gstplaybin2.c:3271:autoplug_select_cb:<playbin20> checking factory mpeg2dec
0:00:14.854031750 32470  0x95e5720 DEBUG               playbin2 gstplaybin2.c:3214:autoplug_continue_cb:<playbin20> continue autoplugging group 0x9711318 for '':decodepad7, audio/x-ac3: 1
0:00:14.854191602 32470  0x95e5720 DEBUG               playbin2 gstplaybin2.c:3049:autoplug_factories_cb:<playbin20> factories group 0x9711318 for '':decodepad7, audio/x-ac3
0:00:14.854649600 32470  0x95e5720 DEBUG               playbin2 gstplaybin2.c:3059:autoplug_factories_cb:<playbin20> found factories 0xb6471880
0:00:14.855619479 32470  0x95e5720 DEBUG               playbin2 gstplaybin2.c:3268:autoplug_select_cb:<playbin20> select group 0x9711318 for '':decodepad7, audio/x-ac3
0:00:14.855700091 32470  0x95e5720 DEBUG               playbin2 gstplaybin2.c:3271:autoplug_select_cb:<playbin20> checking factory pulsesink
0:00:14.855776440 32470  0x95e5720 DEBUG               playbin2 gstplaybin2.c:3344:autoplug_select_cb:<playbin20> we found a sink
0:00:14.855877980 32470  0x95e5720 DEBUG               playbin2 gstplaybin2.c:3350:autoplug_select_cb:<playbin20> we found an audio sink
0:00:14.855955069 32470  0x95e5720 DEBUG               playbin2 gstplaybin2.c:3393:autoplug_select_cb:<playbin20> we have no pending sink, try to create one
0:00:14.861079720 32470  0x95e5720 DEBUG               playbin2 gstplaybin2.c:3268:autoplug_select_cb:<playbin20> select group 0x9711318 for '':decodepad7, audio/x-ac3
0:00:14.861206558 32470  0x95e5720 DEBUG               playbin2 gstplaybin2.c:3271:autoplug_select_cb:<playbin20> checking factory ac3parse
0:00:14.861928499 32470  0x95e5720 DEBUG               playbin2 gstplaybin2.c:3049:autoplug_factories_cb:<playbin20> factories group 0x9711318 for '':decodepad8, audio/x-ac3, framed=(boolean)true, channels=(int)[ 1, 6 ], rate=(int)[ 8000, 48000 ], alignment=(string){ iec61937, frame }; audio/x-eac3, framed=(boolean)true, channels=(int)[ 1, 6 ], rate=(int)[ 8000, 48000 ], alignment=(string){ iec61937, frame }
0:00:14.862580662 32470  0x95e5720 DEBUG               playbin2 gstplaybin2.c:3059:autoplug_factories_cb:<playbin20> found factories 0xb646de20
0:00:14.864351517 32470 0xb643bf50 DEBUG               playbin2 gstplaybin2.c:3214:autoplug_continue_cb:<playbin20> continue autoplugging group 0x9711318 for '':decodepad9, audio/x-ac3, framed=(boolean)true, rate=(int)48000, channels=(int)2, alignment=(string)frame: 1
0:00:14.864560656 32470 0xb643bf50 DEBUG               playbin2 gstplaybin2.c:3049:autoplug_factories_cb:<playbin20> factories group 0x9711318 for '':decodepad9, audio/x-ac3, framed=(boolean)true, rate=(int)48000, channels=(int)2, alignment=(string)frame
0:00:14.865104298 32470 0xb643bf50 DEBUG               playbin2 gstplaybin2.c:3059:autoplug_factories_cb:<playbin20> found factories 0xb4101e40
0:00:14.865443547 32470 0xb643bf50 DEBUG               playbin2 gstplaybin2.c:3268:autoplug_select_cb:<playbin20> select group 0x9711318 for '':decodepad9, audio/x-ac3, framed=(boolean)true, rate=(int)48000, channels=(int)2, alignment=(string)frame
0:00:14.865580106 32470 0xb643bf50 DEBUG               playbin2 gstplaybin2.c:3271:autoplug_select_cb:<playbin20> checking factory pulsesink
0:00:14.865655838 32470 0xb643bf50 DEBUG               playbin2 gstplaybin2.c:3344:autoplug_select_cb:<playbin20> we found a sink
0:00:14.865725210 32470 0xb643bf50 DEBUG               playbin2 gstplaybin2.c:3350:autoplug_select_cb:<playbin20> we found an audio sink
0:00:14.865796342 32470 0xb643bf50 DEBUG               playbin2 gstplaybin2.c:3393:autoplug_select_cb:<playbin20> we have no pending sink, try to create one
0:00:14.871464068 32470 0xb643bf50 DEBUG               playbin2 gstplaybin2.c:3268:autoplug_select_cb:<playbin20> select group 0x9711318 for '':decodepad9, audio/x-ac3, framed=(boolean)true, rate=(int)48000, channels=(int)2, alignment=(string)frame
0:00:14.871598227 32470 0xb643bf50 DEBUG               playbin2 gstplaybin2.c:3271:autoplug_select_cb:<playbin20> checking factory a52dec

达斯汀

答案1

您可以使用 GStreamer,但从 MPEGTS 数据到准备好渲染解码视频似乎一直存在困难。我相信标准 MPEGTS 插件会因格式错误的帧而卡住,VLC 也是如此。

因此,如果您只想将原始 MPEGTS 数据从 RTP 推送到 mplayer,它可以正常工作(mplayer 在解码包含错误的 MPEGTS 流方面非常出色):

gst-launch udpsrc port=5011 caps="application/x-rtp, media=video, payload=33, clock-rate=90000" ! fdsink | mplayer -

“有效负载”功能的值来自 RFC 3551 中 MPEGTS 包装的 MPEG2 流的“RTP 音频/视频配置文件”。VLC 可能尝试在其中一些代码下进行解码,以便轻松接收一些 RTP 流,例如来自 HDHomeRun 的 RTP 流,从而避免需要烦人的 SDP 文件。

另一方面,如果您不介意使用 HDHomeRun 工具来获取 MPEGTS 数据,那么 GStreamer 将可以完美地查看它。

简易版:

hdhomerun_config FFFFFFFF save /tuner0/ - | gst-launch-1.0 fdsrc ! decodebin ! autovideosink

具体版本(使用上限过滤来明确移动的数据):

hdhomerun_config FFFFFFFF save /tuner0/ - | gst-launch-1.0 fdsrc ! video/mpegts ! tsdemux ! video/mpeg ! queue ! mpegvideoparse ! mpeg2dec ! xvimagesink

显然,这些示例与音频流无关(至少对我来说,视频始终具有更高的优先级,并且是最大错误/风险的来源)。

Fluendo 的人告诉我,他们的 GStreamer 插件应该可以解决错误问题。我还没有测试过。他们的插件也只能在 GStreamer .10 内部使用。

编辑

这是“观看” HDHomeRun 源的命令行。请注意,无论你观看什么,都需要设置端口号和程序号,并且必须安装“A52” AC3 库以及相应的“a52dec” “bad”插件:

gst-launch-0.10 udpsrc port=5011 caps="application/x-rtp, media=video, encoding-name=H264, clock-rate=90000" ! \
    gstrtpbin ! rtpmp2tdepay ! tsdemux program-number=12 name=demux \
        demux. ! queue ! ac3parse ! a52dec ! queue ! audioconvert ! audioresample ! volume ! autoaudiosink \
        demux. ! queue ! mpegvideoparse ! mpeg2dec ! xvimagesink

请注意,您可以通过结合使用 GST_DEBUG_DUMP_DOT_DIR 环境变量和 playbin 来获得真正信息丰富的流程图(如果您拥有所有必需的插件)。

答案2

经过几天的折腾,我终于能够在 Jetson TK1 Linux 板上使用它了。您无需使用 hdhomerun_config 或打开 rtp / udp 流。从 HDHR 中,您只需通过 http 即可获取流(如果您使用的是 HDHR PRIME)。

下面是我需要将频道转储到 POC 文件中的内容。最重要的部分是“video/x-raw,format=I420”,否则您将收到错误。omxh264enc 对帧大小非常挑剔,而使用 I420 您可以使用任何大小。

# 10.10.10.100 is the IP of the HDHR
# v588 is the example virtual channel to grab on the HDHR
# Audio is encoded to aac @ 192k

sudo gst-launch-1.0 souphttpsrc location="http://10.10.10.100:5004/auto/v588" is-live=true ! decodebin name=demux demux. ! queue ! audioresample ! audioconvert dithering=0 ! "audio/x-raw,channels=2" ! voaacenc bitrate=192000 ! mux. matroskamux name=mux streamable=true ! filesink location=output.mkv demux. ! queue ! videoconvert ! video/x-raw,format=I420 ! omxh264enc ! video/x-h264,stream-format=byte-stream,profile=high ! h264parse ! mux.

现在我想使用 flvmux + rtmpsink,但我不确定如何构建管道。

相关内容