GStreamer与MPEG-TS Video4Linux ATSC / DVB录制

时间:2013-01-30 15:40:45

标签: ffmpeg gstreamer dvb

我有一个不可能的时间设置一个滤镜图来读取我从DVB video4linux设备制作的录音。任何帮助都将受到极大的赞赏。

我是如何录制的:

调整频道:

azap -c ~/channels.conf "Florida"

录制频道:

cat /dev/dvb/adapter0/dvr0 > /tmp/test

这是必须录制的方式(我不能使用任何GST DVB插件为我这样做)。

我用tstools来识别录音是TS流:

tstools/bin$ ./stream_type ~/recordings/20130129-202049
Reading from /home/dustin/recordings/20130129-202049
It appears to be Transport Stream

...但是没有PAT / PMT帧:

tstools/bin$ ./tsinfo ~/recordings/20130129-202049
Reading from /home/dustin/recordings/20130129-202049
Scanning 10000 TS packets

Found 0 PAT packets and 0 PMT packets in 10000 TS packets

我能够通过运行ts2es来生成单个ES(基本流)流:

tstools/bin$ ./ts2es -pid 97 ~/recordings/20130129-202049 ~/recordings/20130129-202049.es
Reading from /home/dustin/recordings/20130129-202049
Writing to   /home/dustin/recordings/20130129-202049.es
Extracting packets for PID 0061 (97)
!!! 4 bytes ignored at end of file - not enough to make a TS packet
Extracted 219258 of 248113 TS packets

我可以播放ES流(即使视频在第一帧被冻结):

gst-launch-0.10 filesrc location=~/recordings/20130129-202049.es ! decodebin2 ! autovideosink
gst-launch-0.10 filesrc location=~/recordings/20130129-202049.es ! decodebin2 ! xvimagesink
gst-launch-0.10 playbin2 uri=file:///home/dustin/recordings/20130129-202049.es

不管我做什么,我都无法打开原来的TS文件。但是,它在Mplayer / FFMPEG中完全打开(但不是VLC)。这是FFMPEG的输出:

ffmpeg -i 20130129-202049

ffmpeg version 0.8.5-4:0.8.5-0ubuntu0.12.04.1, Copyright (c) 2000-2012 the Libav developers
  built on Jan 24 2013 18:03:14 with gcc 4.6.3
*** THIS PROGRAM IS DEPRECATED ***
This program is only provided for compatibility and will be removed in a future release. Please use avconv instead.
[mpeg2video @ 0x9be7be0] mpeg_decode_postinit() failure
    Last message repeated 4 times
[mpegts @ 0x9be3aa0] max_analyze_duration reached
[mpegts @ 0x9be3aa0] PES packet size mismatch
Input #0, mpegts, from '20130129-202049':
  Duration: 00:03:39.99, start: 9204.168844, bitrate: 1696 kb/s
    Stream #0.0[0x61]: Video: mpeg2video (Main), yuv420p, 528x480 [PAR 40:33 DAR 4:3], 15000 kb/s, 30.57 fps, 29.97 tbr, 90k tbn, 59.94 tbc
    Stream #0.1[0x64]: Audio: ac3, 48000 Hz, stereo, s16, 192 kb/s
At least one output file must be specified

这告诉我们视频流有PID 0x61(97)。

我已经尝试了几天,所以以下只是几次尝试的例子。我将首先提供playbin2示例,因为我知道会有成千上万的人回应,坚持认为我只是使用它。它不起作用。

gst-launch-0.10 playbin2 uri=file:///home/dustin/recordings/20130129-202049

Setting pipeline to PAUSED ...
Pipeline is PREROLLING ...
ERROR: from element /GstPlayBin2:playbin20/GstURIDecodeBin:uridecodebin0/GstDecodeBin2:decodebin20/GstMpegTSDemux:mpegtsdemux0: Could not determine type of stream.
Additional debug info:
gstmpegtsdemux.c(2931): gst_mpegts_demux_sink_event (): /GstPlayBin2:playbin20/GstURIDecodeBin:uridecodebin0/GstDecodeBin2:decodebin20/GstMpegTSDemux:mpegtsdemux0:
No valid streams found at EOS
ERROR: pipeline doesn't want to preroll.
Setting pipeline to NULL ...
Freeing pipeline ...

它[可能]失败,因为没有指定用于查找视频的PID(我认为“EOS”错误)。

当然,我尝试以下方法开始拆分TS格式。我相信这是“es-pids”属性,在没有PMT信息的情况下接收PID(tstools说上面没有任何信息),但我也试过“程序号”,以防万一。 gst-inspect表示一个是十六进制而另一个是十进制:

gst-launch-0.10 -v filesrc location=20130129-202049 ! mpegtsdemux es-pids=0x61 ! fakesink
gst-launch-0.10 -v filesrc location=20130129-202049 ! mpegtsdemux program-number=97 ! fakesink

输出:

gst-launch-0.10 filesrc location=20130129-202049 ! mpegtsdemux es-pids=0x61 ! fakesink
Setting pipeline to PAUSED ...
Pipeline is PREROLLING ...
ERROR: from element /GstPipeline:pipeline0/GstMpegTSDemux:mpegtsdemux0: Could not determine type of stream.
Additional debug info:
gstmpegtsdemux.c(2931): gst_mpegts_demux_sink_event (): /GstPipeline:pipeline0/GstMpegTSDemux:mpegtsdemux0:
No valid streams found at EOS
ERROR: pipeline doesn't want to preroll.
Setting pipeline to NULL ...
Freeing pipeline ...
dustin@dustinmicro:~/recordings$ gst-launch-0.10 -v filesrc location=20130129-202049 ! mpegtsdemux es-pids=0x61 ! fakesink
Setting pipeline to PAUSED ...
Pipeline is PREROLLING ...
ERROR: from element /GstPipeline:pipeline0/GstMpegTSDemux:mpegtsdemux0: Could not determine type of stream.
Additional debug info:
gstmpegtsdemux.c(2931): gst_mpegts_demux_sink_event (): /GstPipeline:pipeline0/GstMpegTSDemux:mpegtsdemux0:
No valid streams found at EOS
ERROR: pipeline doesn't want to preroll.
Setting pipeline to NULL ...
Freeing pipeline ...
dustin@dustinmicro:~/recordings$ gst-launch-0.10 -v filesrc location=20130129-202049 ! mpegtsdemux es-pids=0x61 ! fakesink
Setting pipeline to PAUSED ...
Pipeline is PREROLLING ...
ERROR: from element /GstPipeline:pipeline0/GstMpegTSDemux:mpegtsdemux0: Could not determine type of stream.
Additional debug info:
gstmpegtsdemux.c(2931): gst_mpegts_demux_sink_event (): /GstPipeline:pipeline0/GstMpegTSDemux:mpegtsdemux0:
No valid streams found at EOS
ERROR: pipeline doesn't want to preroll.
Setting pipeline to NULL ...
Freeing pipeline ...

然而,当我尝试使用mpegpsdemux(用于节目流(PS),而不是传输流(TS))时,我得到了更多:

gst-launch-0.10 filesrc location=20130129-202049 ! mpegpsdemux ! fakesink

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

(gst-launch-0.10:14805): GStreamer-CRITICAL **: gst_event_new_new_segment_full: assertion `position != -1' failed

(gst-launch-0.10:14805): GStreamer-CRITICAL **: gst_mini_object_ref: assertion `mini_object != NULL' failed

(gst-launch-0.10:14805): GStreamer-CRITICAL **: gst_pad_push_event: assertion `event != NULL' failed
Pipeline is PREROLLED ...
Setting pipeline to PLAYING ...
New clock: GstSystemClock

(gst-launch-0.10:14805): GStreamer-CRITICAL **: gst_event_new_new_segment_full: assertion `position != -1' failed

(gst-launch-0.10:14805): GStreamer-CRITICAL **: gst_mini_object_ref: assertion `mini_object != NULL' failed

(gst-launch-0.10:14805): GStreamer-CRITICAL **: gst_pad_push_event: assertion `event != NULL' failed

(gst-launch-0.10:14805): GStreamer-CRITICAL **: gst_event_new_new_segment_full: assertion `position != -1' failed

(gst-launch-0.10:14805): GStreamer-CRITICAL **: gst_mini_object_ref: assertion `mini_object != NULL' failed

(gst-launch-0.10:14805): GStreamer-CRITICAL **: gst_pad_push_event: assertion `event != NULL' failed

(gst-launch-0.10:14805): GStreamer-CRITICAL **: gst_event_new_new_segment_full: assertion `position != -1' failed

(gst-launch-0.10:14805): GStreamer-CRITICAL **: gst_mini_object_ref: assertion `mini_object != NULL' failed

(gst-launch-0.10:14805): GStreamer-CRITICAL **: gst_pad_push_event: assertion `event != NULL' failed


...


Got EOS from element "pipeline0".
Execution ended after 1654760008 ns.
Setting pipeline to PAUSED ...
Setting pipeline to READY ...
Setting pipeline to NULL ...
Freeing pipeline ...

每当我使用mpegtsdemux时,我仍然会遇到同样的问题,即使它跟在上面的mpegpsdemux之后。

我不明白这一点,因为我还没有选择PID。

我做错了什么?

达斯汀

1 个答案:

答案 0 :(得分:0)

宾果

事实证明,这个问题主要是由MPEG-TS广播流的典型无效帧引起的。通过首先通过mencoder运行TS文件来重建它(没有重新编码),playbin2突然工作了:

mencoder 20130129-202049 -oac copy -ovc copy -o 20130129-202049.copy

正如mpegtsdemux的作者告诉我的那样,flutsdemux更新,应该比旧的mpegtsdemux更受欢迎。 flutsdemux也可以更好地处理这些格式错误的框架。

修改

不幸的是,这是不正确的。 mencoder虽然被指示为-copy-流,但将其重新打包为AVI,而不是将其保留为MPEGTS:

$ gst-discoverer-1.0 ~/capture_0051_WXEL.dvb.distill
Analyzing file:///home/dustin/capture_0051_WXEL.dvb.distill
Done discovering file:///home/dustin/capture_0051_WXEL.dvb.distill

Topology:
  container: Audio Video Interleave (AVI)
    audio: AC-3 (ATSC A/52)
    video: MPEG-2 Video

Properties:
  Duration: 0:00:12.696016666
  Seekable: yes
  Tags: 
      encoder: MEncoder svn r34540 (Ubuntu), built with gcc-4.7
      container format: AVI
      audio codec: AC-3 audio
      bitrate: 384000
      video codec: MPEG 2 Video

话虽如此,当我从空中录制时,看起来PMT数据包不存在。 mplayer / mencoder似乎应对此问题,而GStreamer和VLC对数据进行了扼杀。当我使用相同的设备记录ATSC / NTSC电缆馈送时,PMT数据包按预期存在。您可以使用" tsreport"确定某些数据包类型的存在。来自" tstools"包:

OTA Feed:

$ tsreport -v capture_20130621-0402.trunc | grep PMT
!!! 60 bytes ignored at end of file - not enough to make a TS packet

电缆馈线:

$ tsreport -v capture_20130621-1118.ntsc.qam256.Florida.dvb | grep PMT
   31960: TS Packet 171 PID 0230 [pusi] PMT
   73508: TS Packet 392 PID 0230 [pusi] PMT
  101520: TS Packet 541 PID 0230 [pusi] PMT
  164688: TS Packet 877 PID 0230 [pusi] PMT

希望这能节省一些时间。我花了很多钱。