[farsight2/master] Improve the UI to force the output to have the same size as the data

Olivier Crête olivier.crete at collabora.co.uk
Tue Dec 23 15:20:35 PST 2008


---
 tests/gui/fs2-gui.glade |  146 ++++++++++++++++++++++------------------------
 tests/gui/fs2-gui.py    |   63 ++++++++++++++++----
 2 files changed, 120 insertions(+), 89 deletions(-)

diff --git a/tests/gui/fs2-gui.glade b/tests/gui/fs2-gui.glade
index 8c8b69f..b1e5d7a 100644
--- a/tests/gui/fs2-gui.glade
+++ b/tests/gui/fs2-gui.glade
@@ -1,10 +1,11 @@
 <?xml version="1.0" encoding="UTF-8" standalone="no"?>
 <!DOCTYPE glade-interface SYSTEM "glade-2.0.dtd">
-<!--Generated with glade3 3.4.0 on Mon Dec 17 16:35:38 2007 -->
+<!--Generated with glade3 3.4.0 on Mon Dec 17 20:11:01 2007 -->
 <glade-interface>
   <widget class="GtkWindow" id="main_window">
     <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
     <property name="border_width">6</property>
+    <property name="resizable">False</property>
     <signal name="destroy" handler="shutdown"/>
     <child>
       <widget class="GtkVBox" id="vbox1">
@@ -20,6 +21,10 @@
             <property name="use_underline">True</property>
             <property name="justify">GTK_JUSTIFY_CENTER</property>
           </widget>
+          <packing>
+            <property name="expand">False</property>
+            <property name="fill">False</property>
+          </packing>
         </child>
         <child>
           <widget class="GtkHBox" id="user_hbox">
@@ -27,44 +32,26 @@
             <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
             <property name="spacing">6</property>
             <child>
-              <widget class="GtkFrame" id="user_frame2">
+              <widget class="GtkAspectFrame" id="preview_aspectframe">
                 <property name="visible">True</property>
                 <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+                <property name="border_width">6</property>
                 <property name="label_xalign">0</property>
-                <property name="shadow_type">GTK_SHADOW_IN</property>
+                <property name="ratio">1.3300000429153442</property>
                 <child>
-                  <widget class="GtkHBox" id="hbox1">
+                  <widget class="GtkDrawingArea" id="preview_drawingarea">
+                    <property name="width_request">320</property>
+                    <property name="height_request">200</property>
                     <property name="visible">True</property>
                     <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
-                    <child>
-                      <widget class="GtkTable" id="table1">
-                        <property name="visible">True</property>
-                        <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
-                        <property name="n_rows">1</property>
-                        <property name="n_columns">1</property>
-                        <child>
-                          <widget class="GtkDrawingArea" id="preview_drawingarea">
-                            <property name="width_request">320</property>
-                            <property name="height_request">200</property>
-                            <property name="visible">True</property>
-                            <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
-                            <signal name="expose_event" handler="exposed"/>
-                            <signal name="realize" handler="drawing_realize"/>
-                          </widget>
-                          <packing>
-                            <property name="x_padding">6</property>
-                            <property name="y_padding">6</property>
-                          </packing>
-                        </child>
-                      </widget>
-                    </child>
+                    <signal name="expose_event" handler="exposed"/>
                   </widget>
                 </child>
                 <child>
-                  <widget class="GtkLabel" id="frame_label2">
+                  <widget class="GtkLabel" id="frame_label">
                     <property name="visible">True</property>
                     <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
-                    <property name="label" translatable="yes">&lt;b&gt;My preview&lt;/b&gt;</property>
+                    <property name="label" translatable="yes">&lt;b&gt;User&lt;/b&gt;</property>
                     <property name="use_markup">True</property>
                   </widget>
                   <packing>
@@ -72,6 +59,10 @@
                   </packing>
                 </child>
               </widget>
+              <packing>
+                <property name="expand">False</property>
+                <property name="fill">False</property>
+              </packing>
             </child>
             <child>
               <widget class="GtkHBox" id="participants_hbox">
@@ -84,6 +75,8 @@
             </child>
           </widget>
           <packing>
+            <property name="expand">False</property>
+            <property name="fill">False</property>
             <property name="position">1</property>
           </packing>
         </child>
@@ -121,32 +114,19 @@
   <widget class="GtkWindow" id="window1">
     <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
     <child>
-      <widget class="GtkFrame" id="user_frame">
+      <widget class="GtkAspectFrame" id="user_frame">
         <property name="visible">True</property>
         <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+        <property name="border_width">6</property>
         <property name="label_xalign">0</property>
-        <property name="shadow_type">GTK_SHADOW_IN</property>
+        <property name="ratio">1.3300000429153442</property>
         <child>
-          <widget class="GtkTable" id="table5">
+          <widget class="GtkDrawingArea" id="user_drawingarea">
+            <property name="width_request">320</property>
+            <property name="height_request">200</property>
             <property name="visible">True</property>
             <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
-            <property name="n_rows">1</property>
-            <property name="n_columns">1</property>
-            <property name="row_spacing">1</property>
-            <child>
-              <widget class="GtkDrawingArea" id="user_drawingarea">
-                <property name="width_request">320</property>
-                <property name="height_request">200</property>
-                <property name="visible">True</property>
-                <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
-                <signal name="expose_event" handler="exposed"/>
-                <signal name="realize" handler="drawing_realize"/>
-              </widget>
-              <packing>
-                <property name="x_padding">6</property>
-                <property name="y_padding">6</property>
-              </packing>
-            </child>
+            <signal name="expose_event" handler="exposed"/>
           </widget>
         </child>
         <child>
@@ -166,6 +146,7 @@
   <widget class="GtkDialog" id="neworconnect_dialog">
     <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
     <property name="border_width">5</property>
+    <property name="resizable">False</property>
     <property name="window_position">GTK_WIN_POS_CENTER_ON_PARENT</property>
     <property name="type_hint">GDK_WINDOW_TYPE_HINT_DIALOG</property>
     <property name="has_separator">False</property>
@@ -182,46 +163,40 @@
             <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
             <property name="border_width">6</property>
             <property name="n_rows">3</property>
-            <property name="n_columns">2</property>
+            <property name="n_columns">3</property>
             <property name="column_spacing">12</property>
             <property name="row_spacing">12</property>
             <child>
-              <widget class="GtkSpinButton" id="newport_spinbutton">
+              <widget class="GtkLabel" id="label1">
                 <property name="visible">True</property>
-                <property name="can_focus">True</property>
                 <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
-                <property name="max_length">5</property>
-                <property name="width_chars">5</property>
-                <property name="adjustment">9393 1 65535 1 10 10</property>
-                <property name="snap_to_ticks">True</property>
-                <property name="numeric">True</property>
               </widget>
               <packing>
-                <property name="left_attach">1</property>
-                <property name="right_attach">2</property>
+                <property name="left_attach">2</property>
+                <property name="right_attach">3</property>
                 <property name="top_attach">2</property>
                 <property name="bottom_attach">3</property>
               </packing>
             </child>
             <child>
-              <widget class="GtkLabel" id="label11">
+              <widget class="GtkImage" id="image5">
                 <property name="visible">True</property>
                 <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
-                <property name="label" translatable="yes">Enter the IP address and the port of the server to connect to, or only the port if you want to start a new server</property>
-                <property name="wrap">True</property>
+                <property name="yalign">0</property>
+                <property name="icon_size">6</property>
+                <property name="icon_name">start-here</property>
               </widget>
-              <packing>
-                <property name="left_attach">1</property>
-                <property name="right_attach">2</property>
-              </packing>
             </child>
             <child>
-              <widget class="GtkLabel" id="label10">
+              <widget class="GtkEntry" id="newip_entry">
                 <property name="visible">True</property>
+                <property name="can_focus">True</property>
                 <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
-                <property name="label" translatable="yes">IP address: </property>
+                <property name="text" translatable="yes">127.0.0.1</property>
               </widget>
               <packing>
+                <property name="left_attach">1</property>
+                <property name="right_attach">3</property>
                 <property name="top_attach">1</property>
                 <property name="bottom_attach">2</property>
                 <property name="y_options">GTK_FILL</property>
@@ -240,28 +215,47 @@
               </packing>
             </child>
             <child>
-              <widget class="GtkEntry" id="newip_entry">
+              <widget class="GtkLabel" id="label10">
                 <property name="visible">True</property>
-                <property name="can_focus">True</property>
                 <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
-                <property name="text" translatable="yes">127.0.0.1</property>
+                <property name="label" translatable="yes">IP address: </property>
               </widget>
               <packing>
-                <property name="left_attach">1</property>
-                <property name="right_attach">2</property>
                 <property name="top_attach">1</property>
                 <property name="bottom_attach">2</property>
                 <property name="y_options">GTK_FILL</property>
               </packing>
             </child>
             <child>
-              <widget class="GtkImage" id="image5">
+              <widget class="GtkLabel" id="label11">
                 <property name="visible">True</property>
                 <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
-                <property name="yalign">0</property>
-                <property name="icon_size">6</property>
-                <property name="icon_name">start-here</property>
+                <property name="label" translatable="yes">Enter the IP address and the port of the server to connect to, or only the port if you want to start a new server</property>
+                <property name="wrap">True</property>
               </widget>
+              <packing>
+                <property name="left_attach">1</property>
+                <property name="right_attach">3</property>
+              </packing>
+            </child>
+            <child>
+              <widget class="GtkSpinButton" id="newport_spinbutton">
+                <property name="visible">True</property>
+                <property name="can_focus">True</property>
+                <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+                <property name="max_length">5</property>
+                <property name="width_chars">5</property>
+                <property name="adjustment">9392 1 65535 1 10 10</property>
+                <property name="snap_to_ticks">True</property>
+                <property name="numeric">True</property>
+              </widget>
+              <packing>
+                <property name="left_attach">1</property>
+                <property name="right_attach">2</property>
+                <property name="top_attach">2</property>
+                <property name="bottom_attach">3</property>
+                <property name="x_options">GTK_SHRINK</property>
+              </packing>
             </child>
           </widget>
           <packing>
diff --git a/tests/gui/fs2-gui.py b/tests/gui/fs2-gui.py
index 182a9fc..528543b 100644
--- a/tests/gui/fs2-gui.py
+++ b/tests/gui/fs2-gui.py
@@ -53,7 +53,7 @@ def make_video_sink(pipeline, xid):
 #    sink.connect("element-added",
 #                 lambda bin, element: element.set_property("async", False))
     sink = gst.element_factory_make("ximagesink", "realsink")
-#    sink.set_property("async", False)
+    sink.set_property("async", False)
     bin.add(sink)
     colorspace = gst.element_factory_make("ffmpegcolorspace")
     bin.add(colorspace)
@@ -118,14 +118,25 @@ class FsUIPipeline:
         
         return True
 
-    def make_video_preview(self, xid):
+    def make_video_preview(self, xid, newsize_callback):
         self.previewsink = make_video_sink(self.pipeline, xid)
         self.pipeline.add(self.previewsink)
+        self.havesize = self.previewsink.get_pad("sink").add_buffer_probe(self.have_size,
+                                                          newsize_callback)
+                                                          
         self.previewsink.set_state(gst.STATE_PLAYING)
         self.videosource.tee.link(self.previewsink)
         self.pipeline.set_state(gst.STATE_PLAYING)
         return self.previewsink
 
+    def have_size(self, pad, buffer, callback):
+        x = buffer.caps[0]["width"]
+        y = buffer.caps[0]["height"]
+        callback(x,y)
+        self.previewsink.get_pad("sink").remove_buffer_probe(self.havesize)
+        return True
+                 
+
     def add_user(self, ip, port):
         self.intro(FsUIConnectClient (ip, port))
 
@@ -164,10 +175,18 @@ class FsUISource:
         raise NotImplementedError()
 
     def get_src_pad(self, name="src%d"):
-        return self.tee.get_request_pad(name)
+        queue = gst.element_factory_make("queue")
+        requestpad = self.tee.get_request_pad(name)
+        self.pipeline.add(queue)
+        requestpad.link(queue.get_static_pad("sink"))
+        pad = queue.get_static_pad("src")
+        pad.set_data("requestpad", requestpad)
+        pad.set_data("queue", queue)
+        return pad
 
     def put_src_pad(self, pad):
-        self.tee.release_request_pad(pad)
+        self.pipeline.remove(pad.get_data("queue"))
+        self.tee.release_request_pad(pad.get_data("requestpad"))
     
 
 class FsUIVideoSource(FsUISource):
@@ -223,7 +242,7 @@ class FsUISession:
         if source.get_type() == farsight.MEDIA_TYPE_VIDEO:
             self.session.set_property("local-codecs-config",
                                       [farsight.Codec(farsight.CODEC_ID_ANY,
-                                                      "H263",
+                                                      "H263-1998",
                                                       farsight.MEDIA_TYPE_VIDEO,
                                                       0),
                                        farsight.Codec(farsight.CODEC_ID_DISABLE,
@@ -333,12 +352,14 @@ class FsUIParticipant:
         for id in self.streams:
             self.streams[id].send_local_codecs()
     def make_widget(self):
+        gtk.gdk.threads_enter()
         self.glade = gtk.glade.XML("fs2-gui.glade", "user_frame")
         self.userframe = self.glade.get_widget("user_frame")
         self.glade.get_widget("frame_label").set_text(self.cname)
         self.glade.signal_autoconnect(self)
         self.mainui.hbox_add(self.userframe)
-        
+        gtk.gdk.threads_leave()
+
     def exposed(self, widget, *args):
         try:
             self.videosink.get_by_name("realsink").expose()
@@ -351,6 +372,8 @@ class FsUIParticipant:
                 self.funnel = gst.element_factory_make("fsfunnel")
                 self.pipeline.pipeline.add(self.funnel)
                 self.funnel.link(self.videosink)
+                self.havesize = self.videosink.get_pad("sink").add_buffer_probe(self.have_size)
+
                 self.videosink.set_state(gst.STATE_PLAYING)
                 self.funnel.set_state(gst.STATE_PLAYING)
                 self.outcv.notifyAll()
@@ -358,13 +381,24 @@ class FsUIParticipant:
                 self.outcv.release()
             
 
+    def have_size(self, pad, buffer):
+        x = buffer.caps[0]["width"]
+        y = buffer.caps[0]["height"]
+        gtk.gdk.threads_enter()
+        self.glade.get_widget("user_drawingarea").set_size_request(x,y)
+        gtk.gdk.threads_leave()
+        self.videosink.get_pad("sink").remove_buffer_probe(self.havesize)
+        print "HAVE Size ",x,"x",y
+        return True
+                 
+
 
     def link_sink(self, pad):
         try:
             self.outcv.acquire()
             while self.funnel is None:
                 self.outcv.wait()
-            topad.link(self.funnel.get_pad("sink%d"))
+            pad.link(self.funnel.get_pad("sink%d"))
         finally:
             self.outcv.release()
 
@@ -397,11 +431,14 @@ class FsMainUI:
         try:
             self.preview.get_by_name("realsink").expose()
         except AttributeError:
-            print "errored"
-            self.preview = self.pipeline.make_video_preview(widget.window.xid)
+            self.preview = self.pipeline.make_video_preview(widget.window.xid,
+                                                            self.newsize)
 
+    def newsize (self, x, y):
+        self.glade.get_widget("preview_drawingarea").set_size_request(x,y)
+        
     def shutdown(self, widget=None):
-        mainloop.quit()
+        gtk.main_quit()
         
     def hbox_add(self, widget):
         self.glade.get_widget("user_hbox").pack_start(widget, True, True, 0)
@@ -446,7 +483,7 @@ class FsUIStartup:
 
     def quit(self, widget):
         if not self.acted:
-            mainloop.quit()
+            gtk.main_quit()
 
 
 
@@ -457,7 +494,7 @@ if __name__ == "__main__":
     else:
         CAMERA = None
     
-    mainloop = gobject.MainLoop()
     gobject.threads_init()
+    gtk.threads_init()
     startup = FsUIStartup()
-    mainloop.run()
+    gtk.main()
-- 
1.5.6.5




More information about the farsight-commits mailing list