首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >支持MPEG-TS Video4Linux ATSC/DVB录制的GStreamer

支持MPEG-TS Video4Linux ATSC/DVB录制的GStreamer
EN

Stack Overflow用户
提问于 2013-01-30 23:40:45
回答 1查看 4.8K关注 0票数 0

我在设置滤镜以读取从我的数字电视video4linux设备上录制的录音时遇到了不可能的时间。任何帮助都将不胜感激。

我是如何录制的:

要调整频道,请执行以下操作:

代码语言:javascript
复制
azap -c ~/channels.conf "Florida"

录制频道的步骤:

代码语言:javascript
复制
cat /dev/dvb/adapter0/dvr0 > /tmp/test

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

我使用tstools来识别录制的是TS流:

代码语言:javascript
复制
tstools/bin$ ./stream_type ~/recordings/20130129-202049
Reading from /home/dustin/recordings/20130129-202049
It appears to be Transport Stream

没有PAT/PMT帧的...but:

代码语言:javascript
复制
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 (基本流)流:

代码语言:javascript
复制
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流(即使视频在第一帧被冻结):

代码语言:javascript
复制
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的输出:

代码语言:javascript
复制
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示例,因为我知道成千上万的人会做出响应,坚持让我使用它。它不起作用。

代码语言:javascript
复制
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- PID”属性在没有PMT信息的情况下接收PID(上面tstools说没有任何信息),但我也尝试了"program-number",以防万一。gst-inspect表示一个是十六进制的,另一个是十进制的:

代码语言:javascript
复制
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

输出:

代码语言:javascript
复制
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))时,我会得到进一步的结果:

代码语言:javascript
复制
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。

我做错了什么?

达斯汀

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2013-01-31 15:34:52

对啰。

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

代码语言:javascript
复制
mencoder 20130129-202049 -oac copy -ovc copy -o 20130129-202049.copy

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

编辑

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

代码语言:javascript
复制
$ 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数据包如预期的那样存在。您可以使用tstools包中的tsreport来确定是否存在某些类型的数据包:

OTA提要:

代码语言:javascript
复制
$ tsreport -v capture_20130621-0402.trunc | grep PMT
!!! 60 bytes ignored at end of file - not enough to make a TS packet

电缆馈送:

代码语言:javascript
复制
$ 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

希望这能节省一些人的时间。它占用了我足够多的钱。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/14607860

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档