我正在尝试编写一个概念验证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中假设某种内存问题,但我不确定我做了什么导致它)或更多调试步骤尝试将非常感谢。