I'm getting the following error:<br>(s11.py:12310): GStreamer-CRITICAL **: gst_segment_set_newsegment_full: assertion `segment->format == format' failed<br><br>When I try to use input-select to choose an appsrc which has it's data coming from another pipeline. I think this is a caps issue, but I can't seem to locate it. I'm pushing data directly from the appsink to the appsrc (intention is to allow the sink to dynamically die or change rather then having appsrc pull from the appsink). I do know data is moving between the two, as if I set the starting input-selector to be this src, it plays fine, it just dies with the above error is I switch between the two bins.<br>
<br>Maybe I'm just missing some caps, which I don't know I need to set as well (what others are there for video beyond what I've included?)<br><br><br>Here's the src (it's just a modified switch.py script) :<br>
<br><br>#!/usr/bin/env python<br># -*- Mode: Python -*-<br># vi:si:et:sw=4:sts=4:ts=4<br><br>import pygtk<br>pygtk.require('2.0')<br><br>import sys<br><br>import gobject<br>gobject.threads_init()<br><br>import pygst<br>
pygst.require('0.10')<br>import gst<br>import gst.interfaces<br>import gtk<br>gtk.gdk.threads_init()<br><br>class SwitchTest:<br> def __init__(self, videowidget):<br> self.buffers = []<br> self.playing = False<br>
<br> <br> caps = gst.Caps("video/x-raw-yuv,framerate=30/1,pixel-aspect-ratio=1/1,width=320,height=240,color-matrix=sdtv,chroma-site=jpeg,format=(fourcc)YUY2")<br> <br> self.pipeline2 = gst.Pipeline("pipeline2")<br>
<br> uri2 = gst.element_factory_make("videotestsrc","uri2")<br> filter2 = gst.element_factory_make("capsfilter","filter2")<br> filter2.set_property("caps",caps)<br>
sink = gst.element_factory_make("appsink","sink")<br> sink.set_property("caps",caps)<br> sink.set_property('emit-signals', True)<br> sink.set_property('sync', False)<br>
<br><br> self.pipeline2.add(uri2,filter2,sink)<br> gst.element_link_many(uri2,filter2,sink)<br><br><br> #Now set up the master pipeline<br> pipestr = ('videotestsrc name=uri ! s.sink0'<br>
' appsrc name=source caps=video/x-raw-yuv,framerate=30/1,pixel-aspect-ratio=1/1,width=320,height=240,color-matrix=sdtv,chroma-site=jpeg,format=\(fourcc\)YUY2 ! ffmpegcolorspace ! s.sink1'<br> ' videotestsrc name=blah ! s.sink2'<br>
' input-selector sync-streams=true name=s ! autovideosink name=blah2 filter-sink-caps=video/x-raw-yuv,format=\(fourcc\)YUY2 ')<br> self.pipeline = gst.parse_launch(pipestr)<br> self.videowidget = videowidget<br>
<br> source = self.pipeline.get_by_name("source")<br> #Not going to pull buffer, instead pushing them <br> #directly from the sink in pipeline2<br> #source.connect('need-data', self.source_pull_buffer)<br>
#source.connect('push-buffer', self.source_pull_buffer)<br> self.source = source<br><br> # attach some of the call backs now that both pipelines are up<br> sink.connect('new-preroll', self.sink_new_preroll, self.pipeline)<br>
sink.connect('new-buffer', self.sink_new_buffer, self.pipeline)<br> sink.connect('eos', self.eos)<br><br> bus = self.pipeline.get_bus()<br> bus.enable_sync_message_emission()<br>
bus.add_signal_watch()<br> bus.connect('sync-message::element', self.on_sync_message)<br> bus.connect('message', self.on_message)<br><br> self.pipeline2.set_state(gst.STATE_PLAYING)<br>
<br> def on_sync_message(self, bus, message):<br> if message.structure is None:<br> return<br> if message.structure.get_name() == 'prepare-xwindow-id':<br> # Sync with the X server before giving the X-id to the sink<br>
gtk.gdk.threads_enter()<br> gtk.gdk.display_get_default().sync()<br> self.videowidget.set_sink(message.src)<br> message.src.set_property('force-aspect-ratio', True)<br>
gtk.gdk.threads_leave()<br> <br> def on_message(self, bus, message):<br> t = message.type<br> if t == gst.MESSAGE_ERROR:<br> err, debug = message.parse_error()<br> print "Error: %s" % err, debug<br>
if self.on_eos:<br> self.on_eos()<br> self.playing = False<br> elif t == gst.MESSAGE_EOS:<br> if self.on_eos:<br> self.on_eos()<br> self.playing = False<br>
<br> def play(self):<br> self.playing = True<br> <a href="http://gst.info">gst.info</a>("playing player")<br> self.pipeline.set_state(gst.STATE_PLAYING)<br> <br> def stop(self):<br>
self.pipeline.set_state(gst.STATE_NULL)<br> <a href="http://gst.info">gst.info</a>("stopped player")<br> self.playing = False<br><br> def get_state(self, timeout=1):<br> return self.pipeline.get_state(timeout=timeout)<br>
<br> def is_playing(self):<br> return self.playing<br> <br> def switch(self, padname):<br> switch = self.pipeline.get_by_name('s')<br> stop_time = switch.emit('block')<br> newpad = switch.get_static_pad(padname)<br>
start_time = newpad.get_property('running-time')<br> <br> gst.warning('stop time = %d' % (stop_time,))<br> gst.warning('stop time = %s' % (gst.TIME_ARGS(stop_time),))<br><br>
gst.warning('start time = %d' % (start_time,))<br> gst.warning('start time = %s' % (gst.TIME_ARGS(start_time),))<br><br> gst.warning('switching from %r to %r'<br> % (switch.get_property('active-pad'), padname))<br>
switch.emit('switch', newpad, stop_time, start_time)<br><br> def sink_new_preroll(self, sink, pipe):<br> #print "Prerolling sink"<br> buf = sink.emit('pull-preroll')<br>
#self.buffers.append(buf)<br> #print "PREROLL BUFFERS: ", len(self.buffers)<br> mysrc = pipe.get_by_name("source")<br> mysrc.emit('push-buffer', buf)<br> return True<br>
<br> def sink_new_buffer(self, sink, pipe):<br> #print "new buffer from sink"<br> buf = sink.emit('pull-buffer')<br> #self.buffers.append(buf)<br> #print "NEW BUFFER BUFFERS: ", len(self.buffers)<br>
#test of directly emitting the buffer <br> mysrc = pipe.get_by_name("source")<br> mysrc.emit('push-buffer', buf)<br> return True<br><br> def eos(self, sink):<br> return True<br>
<br> def source_pull_buffer(self, source, length):<br> print "PULLING BUFER"<br> if self.buffers:<br> buf = self.buffers.pop(0)<br> source.emit('push-buffer', buf)<br>
return True<br><br> def pull_next_buffer(self):<br> print "PULLING NEXT BUFER"<br> self.source.emit('push-buffer', self.buffers.pop(0))<br> return True<br><br><br>class VideoWidget(gtk.DrawingArea):<br>
def __init__(self):<br> gtk.DrawingArea.__init__(self)<br> self.imagesink = None<br> self.unset_flags(gtk.DOUBLE_BUFFERED)<br><br> def do_expose_event(self, event):<br> if self.imagesink:<br>
self.imagesink.expose()<br> return False<br> else:<br> return True<br><br> def set_sink(self, sink):<br> assert self.window.xid<br> self.imagesink = sink<br> self.imagesink.set_xwindow_id(self.window.xid)<br>
<br>class SwitchWindow(gtk.Window):<br> UPDATE_INTERVAL = 500<br> def __init__(self):<br> gtk.Window.__init__(self)<br> self.set_default_size(410, 325)<br><br> self.create_ui()<br> self.player = SwitchTest(self.videowidget)<br>
self.populate_combobox()<br><br> self.update_id = -1<br> self.changed_id = -1<br> self.seek_timeout_id = -1<br><br> self.p_position = gst.CLOCK_TIME_NONE<br> self.p_duration = gst.CLOCK_TIME_NONE<br>
<br> def on_delete_event():<br> self.player.stop()<br> gtk.main_quit()<br> self.connect('delete-event', lambda *x: on_delete_event())<br><br> def load_file(self, location):<br>
self.player.set_location(location)<br> <br> def play(self):<br> self.player.play()<br> <br> def populate_combobox(self):<br> switch = self.player.pipeline.get_by_name('s')<br>
for i, pad in enumerate([p for p in switch.pads()<br> if p.get_direction() == gst.PAD_SINK]):<br> self.combobox.append_text(pad.get_name())<br> if switch.get_property('active-pad') == pad.get_name():<br>
self.combobox.set_active(i)<br> if self.combobox.get_active() == -1:<br> self.combobox.set_active(0)<br><br> def combobox_changed(self):<br> model = self.combobox.get_model()<br>
row = model[self.combobox.get_active()]<br> padname, = row<br> self.player.switch(padname)<br><br> def enter_callback(self, widget, entry):<br><br> entry_text = entry.get_text()<br> print "Entry contents: %s\n" % entry_text<br>
<br> def create_ui(self):<br> vbox = gtk.VBox()<br> self.add(vbox)<br><br> self.videowidget = VideoWidget()<br> vbox.pack_start(self.videowidget)<br> <br> hbox = gtk.HBox()<br>
vbox.pack_start(hbox, fill=False, expand=False)<br> <br> self.combobox = combobox = gtk.combo_box_new_text()<br> combobox.show()<br> hbox.pack_start(combobox)<br><br> self.combobox.connect('changed',<br>
lambda *x: self.combobox_changed())<br><br> self.videowidget.connect_after('realize',<br> lambda *x: self.play())<br> entry = gtk.Entry()<br>
entry.set_max_length(50)<br> entry.connect("activate", self.enter_callback, entry)<br> entry.set_text("hello")<br> entry.insert_text(" world", len(entry.get_text()))<br>
entry.select_region(0, len(entry.get_text()))<br> hbox.pack_start(entry)<br> entry.show()<br><br>def main(args):<br> def usage():<br> sys.stderr.write("usage: %s\n" % args[0])<br>
return 1<br><br> # Need to register our derived widget types for implicit event<br> # handlers to get called.<br> gobject.type_register(SwitchWindow)<br> gobject.type_register(VideoWidget)<br><br> if len(args) != 1:<br>
return usage()<br><br> w = SwitchWindow()<br> w.show_all()<br> gtk.main()<br> return 0<br><br>if __name__ == '__main__':<br> sys.exit(main(sys.argv))<br><br><br><br><br><br><br>