我正在尝试编写一个概念验证 python 程序来在 pyGTK DrawingArea 对象中显示视频(使用 gstreamer),最终目标是类似屏幕保护程序的行为,在循环中运行视频并退出鼠标活动.
但是,当我成功地将 gstreamer 输出连接到 pygtk 创建的 X 窗口时,我遇到了段错误。但是在 GDB 中运行它通常可以按预期工作(不是全屏,但我想这是一个单独的问题)并且如果我在 gdb 中运行它会使事情变得更有趣,我在 gdb 之外的下一次运行也会成功,但是然后此后失败。
这是我正在使用的代码:(python 2.7)
#!/usr/bin/env python
import pygst
pygst.require("0.10")
import gst
import time
import pygtk
pygtk.require('2.0')
import gtk
class VideoPlayer:
def on_new_decoded_pad(self, dbin, pad):
self.demux.link(self.h264)
#self.pipeline.set_state(gst.STATE_PLAYING)
print "linked!"
def varea_realized(self, varea):
print "varea realized"
self.varea.window.fullscreen()
self.sink.set_xwindow_id(self.varea.window.xid)
self.pipeline.set_state(gst.STATE_PLAYING)
def __init__(self):
self.win = gtk.Window(gtk.WINDOW_TOPLEVEL)
self.varea = gtk.DrawingArea()
self.win.fullscreen()
self.win.add(self.varea)
self.varea.connect('realize', self.varea_realized)
self.pipeline = gst.Pipeline("mypipe")
self.src = gst.element_factory_make("filesrc", "src")
self.src.set_property('location', '/home/myuser/TestMpeg4.mp4')
self.demux = gst.element_factory_make("qtdemux", "demux")
self.h264 = gst.element_factory_make("ffdec_h264", "h264")
self.crop = gst.element_factory_make("videocrop", "crop")
self.crop.set_property('left', 125)
self.crop.set_property('right', 125)
self.scale = gst.element_factory_make("videoscale", "scale")
self.cap = gst.Caps("video/x-raw-yuv,width=1024,height=1280")
self.capFilter = gst.element_factory_make("capsfilter")
self.capFilter.props.caps = self.cap
self.sink = gst.element_factory_make("xvimagesink", "sink")
self.pipeline.add_many(self.src, self.demux, self.h264, self.sink, self.scale, self.capFilter, self.crop)
gst.element_link_many(self.src, self.demux)
gst.element_link_many(self.h264, self.crop, self.scale, self.capFilter, self.sink)
self.demux.connect("pad-added", self.on_new_decoded_pad)
self.pipeline.set_state(gst.STATE_PAUSED)
#win.realize()
self.win.show_all()
#sink.set_xwindow_id(win.window.xid)
#demux.link(h264)
#h264.link(sink)
self.pipeline.set_state(gst.STATE_PLAYING)
if __name__ == "__main__":
VideoPlayer()
gtk.main()
当我通过命令行运行它时:
user@kiosk:~$ ./vidtest.py
varea realized
Segmentation fault (core dumped)
而在 gdb 中:
user@kiosk:~$ gdb python
GNU gdb (Ubuntu/Linaro 7.4-2012.04-0ubuntu2.1) 7.4-2012.04
Copyright (C) 2012 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law. Type "show copying"
and "show warranty" for details.
This GDB was configured as "x86_64-linux-gnu".
For bug reporting instructions, please see:
<http://bugs.launchpad.net/gdb-linaro/>...
Reading symbols from /usr/bin/python...Reading symbols from /usr/lib/debug/usr/bin/python2.7...done.
done.
(gdb) run vidtest.py
Starting program: /usr/bin/python vidtest.py
warning: no loadable sections found in added symbol-file system-supplied DSO at 0x7ffff7ffa000
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
[New Thread 0x7fffe6dc9700 (LWP 740)]
[New Thread 0x7fffe65c8700 (LWP 741)]
varea realized
Traceback (most recent call last):
File "vidtest.py", line 13, in on_new_decoded_pad
self.demux.link(self.h264)
gst.LinkError: failed to link demux with h264
linked!
[New Thread 0x7fffe4aba700 (LWP 742)]
[Thread 0x7fffe4aba700 (LWP 742) exited]
^C
Program received signal SIGINT, Interrupt.
0x00007ffff6990d83 in poll () from /lib/x86_64-linux-gnu/libc.so.6
(gdb)
我不担心失败的链接(这是我不需要的音轨,尽管我最终必须处理它)但程序运行正常,然后用 Ctrl-C 终止
我确实成功地运行了 strace,发现段错误就在这里发生:
user@kiosk:~$ strace ./vidtest.py
<Omitted for brevity...>
open("/home/user/TestMpeg4.mp4", O_RDONLY) = 6
fstat(6, {st_mode=S_IFREG|0664, st_size=10947268, ...}) = 0
lseek(6, 0, SEEK_END) = 10947268
lseek(6, 0, SEEK_SET) = 0
fstat(6, {st_mode=S_IFREG|0664, st_size=10947268, ...}) = 0
write(5, "\1\0\0\0\0\0\0\0", 8) = 8
mmap(NULL, 8392704, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS|MAP_STACK, -1, 0) = 0x7f4afe20e000
mprotect(0x7f4afe20e000, 4096, PROT_NONE) = 0
clone(child_stack=0x7f4afea0dff0, flags=CLONE_VM|CLONE_FS|CLONE_FILES|CLONE_SIGHAND|CLONE_THREAD|CLONE_SYSVSEM|CLONE_SETTLS|CLONE_PARENT_SETTID|CLONE_CHILD_CLEARTID, parent_tidptr=0x7f4afea0e9d0, tls=0x7f4afea0e700, child_tidptr=0x7f4afea0e9d0) = 863
futex(0x184a9b0, FUTEX_WAKE_PRIVATE, 1) = 1
futex(0x118fed0, FUTEX_WAKE_PRIVATE, 1) = 1
futex(0x1851900, FUTEX_WAKE_PRIVATE, 1) = 1
futex(0x1758500, FUTEX_WAKE_PRIVATE, 1) = 1
write(5, "\1\0\0\0\0\0\0\0", 8) = 8
write(5, "\1\0\0\0\0\0\0\0", 8) = 8
uname({sys="Linux", node="kiosk", ...}) = 0
fstat(1, <unfinished ...>
+++ killed by SIGSEGV (core dumped) +++
Segmentation fault (core dumped)
user@kiosk:~$
关于可能发生的事情的任何线索(鉴于这是一个段错误,我假设 pygst 或 pygtk 中存在某种内存问题,但我不确定我做了什么导致它)或尝试更多调试步骤将不胜感激.