繁体   English   中英

GStreamer:在播放过程中不会动态更新textoverlay

[英]GStreamer: textoverlay is not dynamically updated during play

我想在视频图像(源代码为/dev/video0 )上查看当前的CPU负载,并且我认为textoverlay元素非常适合此操作。 我已经构造了一个(看似)工作的管道,除了textoverlay一直显示最初设置的值。

该管道当前如下所示:

v4l2src > qtdemux > queue > ffmpegcolorspace > textoverlay > xvimagesink

代码看起来像这样(我删除了一堆gtk窗口,线程处理代码和其他一些信号处理,只留下了相关部分):

#!/usr/bin/env python

import sys, os, time, signal
import pygtk, gtk, gobject

import pygst
pygst.require("0.10")
import gst

# For cpu load stats
import psutil
from multiprocessing import Process, Value, Lock # For starting threads

class Video:
  def __init__(self):

    window = gtk.Window(gtk.WINDOW_TOPLEVEL)        
    vbox = gtk.VBox()
    window.add(vbox)
    self.movie_window = gtk.DrawingArea()
    vbox.add(self.movie_window)   
    window.show_all()

    # Set up the gstreamer pipeline
    self.pipeline = gst.Pipeline("pipeline")
    self.camera = gst.element_factory_make("v4l2src","camera")
    self.camera.set_property("device","""/dev/video0""")
    self.pipeline.add(self.camera)

    # Demuxer
    self.demuxer = gst.element_factory_make("qtdemux","demuxer")

    # Create a dynamic callback for the demuxer
    self.demuxer.connect("pad-added", self.demuxer_callback)

    self.pipeline.add(self.demuxer)  

    # Demuxer doesnt have static pads, but they are created at runtime, we will need a callback to link those
    self.videoqueue = gst.element_factory_make("queue","videoqueue")

    self.pipeline.add(self.videoqueue)

    self.videoconverter = gst.element_factory_make("ffmpegcolorspace","videoconverter")
    self.pipeline.add(self.videoconverter)

    ## Text overlay stuff
    self.textoverlay = gst.element_factory_make("textoverlay","textoverlay")

    self.overlay_text = "cpu load, initializing"
    self.textoverlay.set_property("text",self.overlay_text)
    self.textoverlay.set_property("halign", "left")
    self.textoverlay.set_property("valign", "top")
    self.textoverlay.set_property("shaded-background","true")
    self.pipeline.add(self.textoverlay)

    self.videosink = gst.element_factory_make("xvimagesink","videosink")
    self.pipeline.add(self.videosink)

    self.camera.link(self.videoqueue)
    gst.element_link_many(self.videoqueue,   self.videoconverter, self.textoverlay, self.videosink)


    bus = self.pipeline.get_bus()
    bus.add_signal_watch()
    bus.enable_sync_message_emission()

    # Start stream
    self.pipeline.set_state(gst.STATE_PLAYING)

    # CPU stats calculator thread    
    cpu_load_thread = Process(target=self.cpu_load_calculator, args=())
    cpu_load_thread.start()

  def demuxer_callback(self, dbin, pad):

    if pad.get_property("template").name_template == "video_%02d":
      print "Linking demuxer & videopad"
      qv_pad = self.videoqueue.get_pad("sink")
      pad.link(qv_pad)


  def cpu_load_calculator(self):

    cpu_num = len( psutil.cpu_percent(percpu=True))

    while True:
      load = psutil.cpu_percent(percpu=True)
      self.parsed_load = ""

      for i in range (0,cpu_num):
        self.parsed_load = self.parsed_load + "CPU%d: %s%% " % (i, load[i])

      print self.textoverlay.get_property("text") # Correctly prints previous cycle CPU load
      self.textoverlay.set_property("text",self.parsed_load)


      time.sleep(2)

c = Video()

gtk.threads_init()
gtk.main()

cpu_load_calculator一直在后台运行,在设置新值之前,我先使用get_property()函数打印出前一个值,并且设置正确。 但是在实际的视频输出窗口上,它保持为初始值。我如何使textoverlay也正确地更新到视频窗口?

问题是您正在尝试从其他Process更新textoverlay。 与线程不同的进程在单独的地址空间中运行。

您可以切换到线程:

from threading import Thread
...
# CPU stats calculator thread    
cpu_load_thread = Thread(target=self.cpu_load_calculator, args=())
cpu_load_thread.start()

或者,您可以从主线程运行cpu_load_calculator循环。 这将起作用,因为self.pipeline.set_state(gst.STATE_PLAYING)在后台启动它自己的线程。

这样就足够了:

# Start stream
self.pipeline.set_state(gst.STATE_PLAYING)

# CPU stats calculator loop
self.cpu_load_calculator()

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM