Performance/timing for gstreamer application using uridecodebin and ffmpegcolorspace

wng wng at appcomsci.com
Mon Mar 25 22:07:36 PDT 2013


I'm trying to optimize throughput in a gstreamer application, so I wrote a
simple program to test the performance of just loading images by iterating
through a list of uris, processing each through the pipeline and changing
the uri location when an EOS is detected. 

uridecodebin ! fakesink (using the pad-added signal) takes an average of
0.02 seconds per image. 

uridecodebin ! ffmpegcolorspace ! fakesink (also using the pad-added signal)
takes an average of 0.03 seconds per image. 

The images are PNGS and JPEG, between 6 KB to 650 KB. Is there any way to
increase the performance of either image loading and/or ffmpegcolorspace to
decrease the processing to < 0.01 seconds ? There seems to be a delay
waiting for the pads to connect that doesn't appear when I run this from
command-line using gst-launch. Would using gst-launch directly in my program
work with switching the uris on eos?

Here's the simple program for testing uridecodebin ! ffmpegcolorspace !
fakesink. I'm running CentOS 5.9, 64-bit with gstreamer-0.10 if that makes a
difference. Thanks in advance!

#!/usr/bin/python

import sys, os
import time
from datetime import datetime
import pygst
pygst.require("0.10")
import gst, gobject
import threading
import logging

# initialize threads
gobject.threads_init()
logging.basicConfig() 

_log = logging.getLogger(__name__)
_log.setLevel(logging.INFO)

class DetectObjects(object):
    
    def on_new_pad_uri(dbin, pad, islast):
        time = datetime.now()
        _log.info("Adding pad     : " + str(time))
        pipeline = pad.get_parent()
        colorspace = pipeline.get_by_name("colorspace")
        pad.link(colorspace)
        pipeline.set_state(gst.STATE_PLAYING)
        _log.info("Done adding pad: " + str(datetime.now()))
        _log.info("Pad time              = " + str(datetime.now() - time))
        
    def __init__(self):
        
        self.pipeline = gst.Pipeline("pipeline") 
            
        self.src = gst.element_factory_make("uridecodebin", "src")
        self.colorspace = gst.element_factory_make("ffmpegcolorspace",
"colorspace")
        self.sink = gst.element_factory_make("fakesink", "sink")
        
        if (self.pipeline is None or 
            self.src is None or 
            self.colorspace is None or
            self.sink is None):
            _log.error("Element(s) did not initialize")
            sys.exit()
        
        # add elements to pipeline
        self.pipeline.add(self.src,
                          self.colorspace,
                          self.sink)
        
        gst.element_link_many(self.colorspace,self.sink)  
#        # watch messages on the bus
        self.bus = self.pipeline.get_bus()
        self.bus.add_watch(self.process_signal)
        
#        # add pad signal
        self.src.connect("pad-added", self.on_new_pad_uri)  # uridecodebin !
colorspace
        self.pipeline.set_state(gst.STATE_PAUSED)
        _log.debug("Finished initialization of " + __name__)
    
    def set_location(self, uri):
        src = self.pipeline.get_by_name("src")
        self.pipeline.set_state(gst.STATE_READY)
        src.set_property("uri", uri)
        self.pipeline.set_state(gst.STATE_PAUSED)
    
    def process_signal(self, bus, msg):
        t = msg.type
        if t == gst.MESSAGE_ERROR:
            err, debug = msg.parse_error()
            # for some reason, uridecodebin will cause a resource not found
error, but it does work
            # so must ignore messages
            if debug.find("Resource not found. gsturidecodebin"):
                _log.debug("Ignore error")
            else: 
                print "Error: %s" % err, debug
                self.pipeline.set_state(gst.STATE_NULL)
                self.loop.quit()
                return False
        elif t == gst.MESSAGE_EOS:
            self.bus.set_flushing(True)
            self.pipeline.set_state(gst.STATE_NULL)
            _log.info("Reached EOS    : " + str(datetime.now()))
            self.processResourcesRec()
        return gst.BUS_PASS

        
    def processResources(self, resources):
        self.starttime = datetime.now()
        main = gobject.MainLoop ()
        self.loop = main
        self.resources = resources
        self.time = datetime.now()
        self.processResourcesRec()
        self.loop.run()
    
    # recursive helper called when the previous resource is at EOS
    def processResourcesRec(self):
        if len(self.resources) > 0:
            self.time = datetime.now()
            r = self.resources.pop() 
            uri = r[0]
            _log.info("Start processing " + uri + ":" + str(datetime.now()))
            self.set_location(uri)
        else:
            timediff = datetime.now() - self.starttime
            _log.info("Total processing time = " + str(timediff))
            self.loop.quit()



--
View this message in context: http://gstreamer-devel.966125.n4.nabble.com/Performance-timing-for-gstreamer-application-using-uridecodebin-and-ffmpegcolorspace-tp4659261.html
Sent from the GStreamer-devel mailing list archive at Nabble.com.


More information about the gstreamer-devel mailing list