GNOME Bugzilla – Bug 449529
basetransform broken, not linking properly
Last modified: 2008-05-06 13:09:29 UTC
Please describe the problem: when there is no current peer, a pad template is returned with an ANY capsfilter which is not necessarily the desired action. This bug confirmed by thaytan I have included python code for two files in which I discovered this bug. My MetaDataDemuxer class will not link properly to the tee. Linking it manually fixes the problem. Steps to reproduce: I found this bug while working in python with the following 2 files: #### metadata.py ### import pygst pygst.require('0.10') import gst import gobject import time # a constant so that we do not have to keep creating new caps METADATA_CAPS = gst.caps_from_string('text/x-metadata') # an object for encapsulating our video and metadata class MetaData: def __init__(self, name="MetaData"): self.name = name self.data = {} self.fingerprints = {} def to_string(self): string = "name: %s\r\n" % str(self.name) for key, value in self.data.iteritems(): string += "%s: %s\r\n" % (str(key), str(value)) if len(self.fingerprints) > 0: for server, times in self.fingerprints.iteritems(): entry, exit = times string += "fingerprint: %s, %s, %s\r\n" % (str(server), str(entry), str(exit)) string += "\r\n" return string # the MetaDataInsertFilter element/plugin class MetaDataInsertFilter(gst.Element): __gstdetails__ = ('MetaDataInsertFilter Plugin', "metadata.py", "Create Metadata to be pushed along with Buffers", "Corey O.") _srcpadtemplate = gst.PadTemplate ("src", gst.PAD_SRC, gst.PAD_ALWAYS, gst.caps_new_any()) _sinkpadtemplate = gst.PadTemplate ("sink", gst.PAD_SINK, gst.PAD_ALWAYS, gst.caps_new_any()) __gsttemplates__ = (_srcpadtemplate, _sinkpadtemplate) def __init__(self): gst.Element.__init__(self) self.frame_count = 1 self.srcpad = gst.Pad(self._srcpadtemplate) self.sinkpad = gst.Pad(self._sinkpadtemplate) self.add_pad(self.srcpad) self.add_pad(self.sinkpad) self.sinkpad.set_chain_function(self.chainfunc) self.sinkpad.set_event_function(self.eventfunc) def chainfunc(self, pad, buffer): metadata = MetaData() name = self.get_name() # remember to make the timestamp a proper string timestamp = repr(time.time()) metadata.data['origin'] = name metadata.data['previous_node'] = name metadata.data['frame_count'] = self.frame_count self.frame_count = self.frame_count + 1 metadata.data['timestamp'] = timestamp if metadata.fingerprints.has_key(name): entry, exit = metadata.fingerprints[name] else: entry = '0.0' metadata.fingerprints[name] = [entry, timestamp] metadata_buffer = gst.Buffer(metadata.to_string()) metadata_buffer.set_caps(METADATA_CAPS) self.srcpad.push(metadata_buffer) return self.srcpad.push(buffer) def eventfunc(self, pad, event): return self.srcpad.push_event(event) # the MetaDataDemuxer element/plugin class MetaDataDemuxer(gst.Element): __gstdetails__ = ('MetaDataDemuxer Plugin', "metadata.py", "Strip Metadata from Frames", "Corey O.") _srcpadtemplate = gst.PadTemplate ("src", gst.PAD_SRC, gst.PAD_REQUEST, gst.caps_new_any()) _metadatasrcpadtemplate = gst.PadTemplate ("metadatasrc", gst.PAD_SRC, gst.PAD_REQUEST, METADATA_CAPS) _sinkpadtemplate = gst.PadTemplate ("sink", gst.PAD_SINK, gst.PAD_ALWAYS, gst.caps_new_any()) __gsttemplates__ = (_srcpadtemplate, _metadatasrcpadtemplate, _sinkpadtemplate) def __init__(self): gst.Element.__init__(self) self.srcpad = gst.Pad(self._srcpadtemplate) self.mdsrcpad = gst.Pad(self._metadatasrcpadtemplate) self.sinkpad = gst.Pad(self._sinkpadtemplate) self.add_pad(self.srcpad) self.add_pad(self.mdsrcpad) self.add_pad(self.sinkpad) self.sinkpad.set_chain_function(self.chainfunc) self.sinkpad.set_event_function(self.eventfunc) def chainfunc(self, pad, buffer): caps = buffer.get_caps() if caps == METADATA_CAPS: return self.mdsrcpad.push(buffer) else: return self.srcpad.push(buffer) def eventfunc(self, pad, event): return self.srcpad.push_event(event) gobject.type_register(MetaDataInsertFilter) gst.element_register(MetaDataInsertFilter, 'metadatainsertfilter') gobject.type_register(MetaDataDemuxer) gst.element_register(MetaDataDemuxer, 'metadatademux') ######## end file ############ ####### test.py ####### #!/usr/bin/env python import sys import signal import gobject import pygst pygst.require ("0.10") import gst import metadata import mergemuxer def main(args): pipeline = gst.parse_launch ("videotestsrc ! capsfilter caps=video/x-raw-yuv,format=(fourcc)I420,width=(int)640,height=(int)480,framerate=(fraction)2/1 ! metadatainsertfilter ! metadatademux ! tee name=t ! queue ! ffmpegcolorspace ! textoverlay text='<b>CAM1</b>' shaded-background=true ! ffmpegcolorspace ! xvimagesink") pipeline.set_state(gst.STATE_PLAYING) try: gobject.MainLoop().run() except KeyboardInterrupt: pipeline.set_state(gst.STATE_NULL) return 0 return -1 if __name__ == '__main__': gobject.threads_init() sys.exit(main(sys.argv)) ######### end file ######## Actual results: failure to link two elements properly Expected results: Does this happen every time? yes Other information:
what is the problem here? If the padtemplate says ANY, it'll return ANY. Maybe you want to implement the getcaps function to proxy the caps from the upstream/downstream element?
Closing this bug report as no further information has been provided. Please feel free to reopen this bug if you can provide the information asked for. Thanks!