11import logging
22import sys
3- from typing import cast
43
5- from gi .repository import Gst , Gdk , Gtk
4+ from gi .repository import Gst , Gdk
65
76from voctogui .lib .args import Args
87from voctogui .lib .config import Config
1615
1716class VideoDisplay (object ):
1817 """Displays a Voctomix-Video-Stream into a GtkWidget"""
19- imagesink : Gst .Element
20- widget : Gtk .Widget
21- pipeline : Gst .Pipeline
2218
23- def __init__ (self , audio_display , port , name , width = None , height = None ,
19+ def __init__ (self , video_drawing_area , audio_display , port , name , width = None , height = None ,
2420 has_audio = True , play_audio = False ):
2521 self .log = logging .getLogger ('VideoDisplay:%s' % name )
2622 self .name = name
23+ self .video_drawing_area = video_drawing_area
2724 self .level_callback = None if audio_display is None else audio_display .callback
2825 video_decoder = None
2926
@@ -81,16 +78,28 @@ def __init__(self, audio_display, port, name, width=None, height=None,
8178 # Video Display
8279 videosystem = Config .getVideoSystem ()
8380 self .log .debug ('Configuring for Video-System %s' , videosystem )
84- if videosystem == 'gtk' :
85- pipe += """ ! gtksink
86- name=imagesink-{name} sync=false
87- """ .format (name = name )
8881
89- elif videosystem == 'gtkgl ' :
82+ if videosystem == 'gl ' :
9083 pipe += """ ! glupload
91- ! gtkglsink
92- name=imagesink-{name} sync=false
93- """ .format (name = name )
84+ ! glcolorconvert
85+ ! glimagesinkelement
86+ name=imagesink-{name}
87+ """ .format (name = name )
88+
89+ elif videosystem == 'xv' :
90+ pipe += """ ! xvimagesink
91+ name=imagesink-{name}
92+ """ .format (name = name )
93+
94+ elif videosystem == 'x' :
95+ pipe += """ ! ximagesink
96+ name=imagesink-{name}
97+ """ .format (name = name )
98+
99+ elif videosystem == 'vaapi' :
100+ pipe += """ ! vaapisink
101+ name=imagesink-{name}
102+ """ .format (name = name )
94103
95104 else :
96105 raise Exception (
@@ -125,27 +134,48 @@ def __init__(self, audio_display, port, name, width=None, height=None,
125134 self .log .info ("Creating Display-Pipeline:\n %s" , pretty (pipe ))
126135 try :
127136 # launch gstreamer pipeline
128- self .pipeline = cast ( Gst .Pipeline , Gst . parse_launch (pipe ) )
137+ self .pipeline = Gst .parse_launch (pipe )
129138 self .log .info ("pipeline launched successfuly" )
130139 except :
131140 self .log .error ("Can not launch pipeline" )
132141 sys .exit (- 1 )
133142
134- self .imagesink = cast (Gst .Element , self .pipeline .get_by_name ('imagesink-{name}' .format (name = self .name )))
135- self .widget = cast (Gtk .Widget , self .imagesink .get_property ("widget" ))
136-
137143 if Args .dot :
138144 self .log .debug ("Generating DOT image of videodisplay pipeline" )
139145 gst_generate_dot (self .pipeline , "gui.videodisplay.{}" .format (name ), Args .gst_debug_details )
140146
141- self .pipeline .set_clock (Clock )
147+ self .pipeline .use_clock (Clock )
148+
149+ self .video_drawing_area .add_events (
150+ Gdk .EventMask .KEY_PRESS_MASK | Gdk .EventMask .KEY_RELEASE_MASK )
151+ self .video_drawing_area .connect ("realize" , self .on_realize )
142152 bus = self .pipeline .get_bus ()
143153 bus .add_signal_watch ()
144154 bus .enable_sync_message_emission ()
145155
146156 bus .connect ('message::error' , self .on_error )
157+ bus .connect ('sync-message::element' , self .on_syncmsg )
158+ bus .connect ('message::state-changed' , self .on_state_changed )
147159 bus .connect ("message::element" , self .on_level )
148160
161+ def on_realize (self , win ):
162+ self .imagesink = self .pipeline .get_by_name (
163+ 'imagesink-{name}' .format (name = self .name ))
164+ self .xid = self .video_drawing_area .get_property ('window' ).get_xid ()
165+
166+ self .log .debug ('Realized Drawing-Area with xid %u' , self .xid )
167+ self .video_drawing_area .realize ()
168+
169+ self .log .info ("Launching Display-Pipeline" )
170+ self .pipeline .set_state (Gst .State .PLAYING )
171+
172+ def on_syncmsg (self , bus , msg ):
173+ if type (msg ) == Gst .Message and self .imagesink :
174+ if msg .get_structure ().get_name () == "prepare-window-handle" :
175+ self .log .info (
176+ 'Setting imagesink window-handle to 0x%x' , self .xid )
177+ self .imagesink .set_window_handle (self .xid )
178+
149179 def on_error (self , bus , message ):
150180 (error , debug ) = message .parse_error ()
151181 self .log .error (
@@ -162,5 +192,6 @@ def on_level(self, bus, msg):
162192 decay = msg .get_structure ().get_value ('decay' )
163193 self .level_callback (rms , peak , decay )
164194
165- def play (self ):
166- self .pipeline .set_state (Gst .State .PLAYING )
195+ def on_state_changed (self , bus , message ):
196+ if message .parse_state_changed ().newstate == Gst .State .PLAYING :
197+ self .video_drawing_area .show ()
0 commit comments