wingo - in flumotion/trunk: . data/glade flumotion/wizard flumotion/worker/checks

flumotion-commit at lists.fluendo.com flumotion-commit at lists.fluendo.com
Wed Jun 6 13:46:42 CEST 2007


Author: wingo
Date: Wed Jun  6 13:46:38 2007
New Revision: 5108

Modified:
   flumotion/trunk/ChangeLog
   flumotion/trunk/data/glade/wizard_webcam.glade
   flumotion/trunk/flumotion/wizard/steps.py
   flumotion/trunk/flumotion/worker/checks/video.py
Log:
2007-06-06  Andy Wingo  <wingo at pobox.com>

	* flumotion/worker/checks/video.py (checkWebcam): 
	* flumotion/wizard/steps.py (Webcam):
	* data/glade/wizard_webcam.glade: Update to present discrete
	choices rather than spinbuttons.



Modified: flumotion/trunk/ChangeLog
==============================================================================
--- flumotion/trunk/ChangeLog	(original)
+++ flumotion/trunk/ChangeLog	Wed Jun  6 13:46:38 2007
@@ -1,5 +1,16 @@
 2007-06-06  Andy Wingo  <wingo at pobox.com>
 
+	* flumotion/worker/checks/video.py (checkWebcam): 
+	* flumotion/wizard/steps.py (Webcam):
+	* data/glade/wizard_webcam.glade: Update to present discrete
+	choices rather than spinbuttons.
+
+	* flumotion/worker/checks/video.py
+	(checkWebcam.probeDevice.forAllStructValues): Instead of just
+	calling proc on the high value, call for the low value, doubling
+	until we get to the high value. Still not really good, but it at
+	least is more useful in the v4l1 case.
+
 	Patch by: Sebastien Merle  <sebastien at fluendo.com>
 
 	* flumotion/admin/gtk/parts.py: 

Modified: flumotion/trunk/data/glade/wizard_webcam.glade
==============================================================================
--- flumotion/trunk/data/glade/wizard_webcam.glade	(original)
+++ flumotion/trunk/data/glade/wizard_webcam.glade	Wed Jun  6 13:46:38 2007
@@ -2,7 +2,6 @@
 <!DOCTYPE glade-interface SYSTEM "http://glade.gnome.org/glade-2.0.dtd">
 
 <glade-interface>
-<requires lib="gnome"/>
 
 <widget class="GtkWindow" id="window1">
   <property name="title" translatable="yes">window1</property>
@@ -16,11 +15,13 @@
   <property name="skip_pager_hint">False</property>
   <property name="type_hint">GDK_WINDOW_TYPE_HINT_NORMAL</property>
   <property name="gravity">GDK_GRAVITY_NORTH_WEST</property>
+  <property name="focus_on_map">True</property>
+  <property name="urgency_hint">False</property>
 
   <child>
     <widget class="GtkTable" id="table1">
       <property name="visible">True</property>
-      <property name="n_rows">5</property>
+      <property name="n_rows">4</property>
       <property name="n_columns">2</property>
       <property name="homogeneous">False</property>
       <property name="row_spacing">6</property>
@@ -39,6 +40,10 @@
 	  <property name="yalign">0.5</property>
 	  <property name="xpad">0</property>
 	  <property name="ypad">0</property>
+	  <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+	  <property name="width_chars">-1</property>
+	  <property name="single_line_mode">False</property>
+	  <property name="angle">0</property>
 	</widget>
 	<packing>
 	  <property name="left_attach">0</property>
@@ -53,7 +58,9 @@
       <child>
 	<widget class="GtkComboBox" id="combobox_device">
 	  <property name="visible">True</property>
-	  <property name="items" translatable="no">/dev/video</property>
+	  <property name="items">/dev/video</property>
+	  <property name="add_tearoffs">False</property>
+	  <property name="focus_on_click">True</property>
 	  <signal name="changed" handler="on_combobox_device_changed" last_modification_time="Fri, 05 Nov 2004 10:42:45 GMT"/>
 	</widget>
 	<packing>
@@ -79,80 +86,14 @@
 	  <property name="yalign">0.5</property>
 	  <property name="xpad">0</property>
 	  <property name="ypad">0</property>
-	  <property name="mnemonic_widget">spinbutton_framerate</property>
+	  <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+	  <property name="width_chars">-1</property>
+	  <property name="single_line_mode">False</property>
+	  <property name="angle">0</property>
 	</widget>
 	<packing>
 	  <property name="left_attach">0</property>
 	  <property name="right_attach">1</property>
-	  <property name="top_attach">4</property>
-	  <property name="bottom_attach">5</property>
-	  <property name="x_options">fill</property>
-	  <property name="y_options"></property>
-	</packing>
-      </child>
-
-      <child>
-	<widget class="GtkSpinButton" id="spinbutton_framerate">
-	  <property name="visible">True</property>
-	  <property name="can_focus">True</property>
-	  <property name="climb_rate">1</property>
-	  <property name="digits">4</property>
-	  <property name="numeric">False</property>
-	  <property name="update_policy">GTK_UPDATE_ALWAYS</property>
-	  <property name="snap_to_ticks">False</property>
-	  <property name="wrap">False</property>
-	  <property name="adjustment">7.5 3.75 30 0.9375 3.75 10</property>
-	</widget>
-	<packing>
-	  <property name="left_attach">1</property>
-	  <property name="right_attach">2</property>
-	  <property name="top_attach">4</property>
-	  <property name="bottom_attach">5</property>
-	  <property name="x_options">fill</property>
-	  <property name="y_options"></property>
-	</packing>
-      </child>
-
-      <child>
-	<widget class="GtkLabel" id="label2">
-	  <property name="visible">True</property>
-	  <property name="label" translatable="yes">_Height:</property>
-	  <property name="use_underline">True</property>
-	  <property name="use_markup">False</property>
-	  <property name="justify">GTK_JUSTIFY_LEFT</property>
-	  <property name="wrap">False</property>
-	  <property name="selectable">False</property>
-	  <property name="xalign">0</property>
-	  <property name="yalign">0.5</property>
-	  <property name="xpad">0</property>
-	  <property name="ypad">0</property>
-	  <property name="mnemonic_widget">spinbutton_height</property>
-	</widget>
-	<packing>
-	  <property name="left_attach">0</property>
-	  <property name="right_attach">1</property>
-	  <property name="top_attach">3</property>
-	  <property name="bottom_attach">4</property>
-	  <property name="x_options">fill</property>
-	  <property name="y_options"></property>
-	</packing>
-      </child>
-
-      <child>
-	<widget class="GtkSpinButton" id="spinbutton_height">
-	  <property name="visible">True</property>
-	  <property name="can_focus">True</property>
-	  <property name="climb_rate">1</property>
-	  <property name="digits">0</property>
-	  <property name="numeric">False</property>
-	  <property name="update_policy">GTK_UPDATE_ALWAYS</property>
-	  <property name="snap_to_ticks">False</property>
-	  <property name="wrap">False</property>
-	  <property name="adjustment">240 16 768 1 16 10</property>
-	</widget>
-	<packing>
-	  <property name="left_attach">1</property>
-	  <property name="right_attach">2</property>
 	  <property name="top_attach">3</property>
 	  <property name="bottom_attach">4</property>
 	  <property name="x_options">fill</property>
@@ -163,7 +104,7 @@
       <child>
 	<widget class="GtkLabel" id="label1">
 	  <property name="visible">True</property>
-	  <property name="label" translatable="yes">_Width:</property>
+	  <property name="label" translatable="yes">_Size:</property>
 	  <property name="use_underline">True</property>
 	  <property name="use_markup">False</property>
 	  <property name="justify">GTK_JUSTIFY_LEFT</property>
@@ -173,7 +114,10 @@
 	  <property name="yalign">0.5</property>
 	  <property name="xpad">0</property>
 	  <property name="ypad">0</property>
-	  <property name="mnemonic_widget">spinbutton_width</property>
+	  <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+	  <property name="width_chars">-1</property>
+	  <property name="single_line_mode">False</property>
+	  <property name="angle">0</property>
 	</widget>
 	<packing>
 	  <property name="left_attach">0</property>
@@ -186,28 +130,6 @@
       </child>
 
       <child>
-	<widget class="GtkSpinButton" id="spinbutton_width">
-	  <property name="visible">True</property>
-	  <property name="can_focus">True</property>
-	  <property name="climb_rate">1</property>
-	  <property name="digits">0</property>
-	  <property name="numeric">False</property>
-	  <property name="update_policy">GTK_UPDATE_ALWAYS</property>
-	  <property name="snap_to_ticks">False</property>
-	  <property name="wrap">False</property>
-	  <property name="adjustment">320 16 1024 1 16 10</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">fill</property>
-	  <property name="y_options"></property>
-	</packing>
-      </child>
-
-      <child>
 	<widget class="GtkLabel" id="label5">
 	  <property name="visible">True</property>
 	  <property name="label" translatable="yes">Name:</property>
@@ -220,6 +142,10 @@
 	  <property name="yalign">0.5</property>
 	  <property name="xpad">0</property>
 	  <property name="ypad">0</property>
+	  <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+	  <property name="width_chars">-1</property>
+	  <property name="single_line_mode">False</property>
+	  <property name="angle">0</property>
 	</widget>
 	<packing>
 	  <property name="left_attach">0</property>
@@ -244,6 +170,10 @@
 	  <property name="yalign">0.5</property>
 	  <property name="xpad">0</property>
 	  <property name="ypad">0</property>
+	  <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+	  <property name="width_chars">-1</property>
+	  <property name="single_line_mode">False</property>
+	  <property name="angle">0</property>
 	</widget>
 	<packing>
 	  <property name="left_attach">1</property>
@@ -254,6 +184,39 @@
 	  <property name="y_options"></property>
 	</packing>
       </child>
+
+      <child>
+	<widget class="GtkComboBox" id="combobox_size">
+	  <property name="visible">True</property>
+	  <property name="add_tearoffs">False</property>
+	  <property name="focus_on_click">True</property>
+	  <signal name="changed" handler="on_combobox_size_changed" last_modification_time="Wed, 30 May 2007 17:15:11 GMT"/>
+	</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">fill</property>
+	  <property name="y_options">fill</property>
+	</packing>
+      </child>
+
+      <child>
+	<widget class="GtkComboBox" id="combobox_framerate">
+	  <property name="visible">True</property>
+	  <property name="add_tearoffs">False</property>
+	  <property name="focus_on_click">True</property>
+	</widget>
+	<packing>
+	  <property name="left_attach">1</property>
+	  <property name="right_attach">2</property>
+	  <property name="top_attach">3</property>
+	  <property name="bottom_attach">4</property>
+	  <property name="x_options">fill</property>
+	  <property name="y_options">fill</property>
+	</packing>
+      </child>
     </widget>
   </child>
 </widget>

Modified: flumotion/trunk/flumotion/wizard/steps.py
==============================================================================
--- flumotion/trunk/flumotion/wizard/steps.py	(original)
+++ flumotion/trunk/flumotion/wizard/steps.py	Wed Jun  6 13:46:38 2007
@@ -516,9 +516,8 @@
     
     in_setup = False
 
-    # these are probed, not set from the UI
-    _mime = None
-    _format = None
+    # _sizes is probed, not set from the UI
+    _sizes = None
     
     def setup(self):
         self.in_setup = True
@@ -526,19 +525,38 @@
                                        '/dev/video1',
                                        '/dev/video2',
                                        '/dev/video3'))
+        cell = gtk.CellRendererText()
+        self.combobox_size.pack_start(cell, True)
+        self.combobox_size.add_attribute(cell, 'text', 0)
+        cell = gtk.CellRendererText()
+        self.combobox_framerate.pack_start(cell, True)
+        self.combobox_framerate.add_attribute(cell, 'text', 0)
         self.in_setup = False
 
     def on_combobox_device_changed(self, combo):
         self.run_checks()
 
+    def on_combobox_size_changed(self, combo):
+        # check for custom
+        i = self.combobox_size.get_active_iter()
+        if i:
+            w, h = self.combobox_size.get_model().get(i, 1, 2)
+            store = gtk.ListStore(str, object)
+            for d in self._sizes[(w,h)]:
+                num, denom = d['framerate']
+                store.set(store.append(), 0, '%.2f fps' % (1.0*num/denom),
+                          1, d)
+            # add custom
+            self.combobox_framerate.set_model(store)
+            self.combobox_framerate.set_active(0)
+
     def worker_changed(self):
         self.clear()
         self.run_checks()
         
     def clear(self):
-        self.spinbutton_width.set_sensitive(False)
-        self.spinbutton_height.set_sensitive(False)
-        self.spinbutton_framerate.set_sensitive(False)
+        self.combobox_size.set_sensitive(False)
+        self.combobox_framerate.set_sensitive(False)
         self.label_name.set_label("")
         self.wizard.block_next(True)
         
@@ -563,19 +581,19 @@
                 self.debug('no device %s' % device)
                 yield None
 
-            deviceName, caps = result
+            deviceName, sizes = result
+            self._sizes = sizes
             self.clear_msg('webcam-check')
             self.label_name.set_label(deviceName)
             self.wizard.block_next(False)
-            self.spinbutton_width.set_value(caps['width'])
-            self.spinbutton_width.set_sensitive(True)
-            self.spinbutton_height.set_value(caps['height'])
-            self.spinbutton_height.set_sensitive(True)
-            fps = caps['framerate']
-            self.spinbutton_framerate.set_value(float(fps[0]) / fps[1])
-            self.spinbutton_framerate.set_sensitive(True)
-            self._mime = caps['mime']
-            self._format = caps.get('format', None)
+            self.combobox_size.set_sensitive(True)
+            self.combobox_framerate.set_sensitive(True)
+            store = gtk.ListStore(str, int, int)
+            for w, h in sizes:
+                store.set(store.append(), 0, '%d x %d' % (w,h),
+                          1, w, 2, h)
+            self.combobox_size.set_model(store)
+            self.combobox_size.set_active(0)
         except errors.RemoteRunFailure, e:
             self.debug('a RemoteRunFailure happened')
             self.clear()
@@ -583,14 +601,31 @@
 
     def get_state(self):
         options = {}
+        i = self.combobox_size.get_active_iter()
+        if i:
+            w, h = self.combobox_size.get_model().get(i, 1, 2)
+        else:
+            self.warning('something bad happened: no height/width selected?')
+            w, h = 320, 240
+        i = self.combobox_framerate.get_active_iter()
+        if i:
+            d = self.combobox_framerate.get_model().get_value(i, 1)
+            num, denom = d['framerate']
+            mime = d['mime']
+            format = d.get('format', None)
+        else:
+            self.warning('something bad happened: no framerate selected?')
+            num, denom = 15, 2
+            mime = 'video/x-raw-yuv'
+            format = None
+
         options['device'] = self.combobox_device.get_string()
-        options['width'] = int(self.spinbutton_width.get_value())
-        options['height'] = int(self.spinbutton_height.get_value())
-        options['framerate'] = \
-            _fraction_from_float(self.spinbutton_framerate.get_value(), 16)
-        options['mime'] = self._mime
-        if self._format:
-            options['format'] = self._format
+        options['width'] = w
+        options['height'] = h
+        options['framerate'] = '%d/%d' % (num, denom)
+        options['mime'] = mime
+        if format:
+            options['format'] = format
         return options
 
 class TestVideoSource(VideoSource):

Modified: flumotion/trunk/flumotion/worker/checks/video.py
==============================================================================
--- flumotion/trunk/flumotion/worker/checks/video.py	(original)
+++ flumotion/trunk/flumotion/worker/checks/video.py	Wed Jun  6 13:46:38 2007
@@ -19,6 +19,7 @@
 
 # Headers in this file shall remain intact.
 
+from twisted.internet import defer
 from flumotion.worker.checks import check
 
 import gst
@@ -63,44 +64,67 @@
     
     @rtype: L{flumotion.common.messages.Result}
     """
-    result = messages.Result()
-
     # FIXME: add code that checks permissions and ownership on errors,
     # so that we can offer helpful hints on what to do.
-    def get_device_name(element):
+    def probeDevice(element):
         name = element.get_property('device-name')
-        caps = element.get_pad("src").get_negotiated_caps()
-        log.debug('check', 'negotiated caps: %s' % caps.to_string())
-        s = caps[0]
-        num = s['framerate'].num
-        denom = s['framerate'].denom
-
-        d = {
-            'mime': s.get_name(),
-            'width': s['width'],
-            'height': s['height'],
-            'framerate': (num, denom),
-        }
-        # FIXME: do something about rgb
-        if s.get_name() == 'video/x-raw-yuv':
-            d['format'] = s['format'].fourcc
-        return (name, d)
+        caps = element.get_pad("src").get_caps()
+        log.debug('check', 'caps: %s' % caps.to_string())
+
+        sizes = {} # (width, height) => [{'framerate': (framerate_num,
+                   #                                    framerate_denom),
+                   #                      'mime': str,
+                   #                      'fourcc': fourcc}]
+        
+        def forAllStructValues(struct, key, proc):
+            vals = struct[key]
+            if isinstance(vals, list):
+                for val in vals:
+                    proc(struct, val)
+            elif isinstance(vals, gst.IntRange):
+                val = vals.low
+                while val < vals.high:
+                    proc(struct, val)
+                    val *= 2
+                proc(struct, vals.high)
+            elif isinstance(vals, gst.DoubleRange):
+                # hack :)
+                proc(struct, vals.high)
+            elif isinstance(vals, gst.FractionRange):
+                # hack :)
+                proc(struct, vals.high)
+            else:
+                # scalar
+                proc(struct, vals)
+        def addRatesForWidth(struct, width):
+            def addRatesForHeight(struct, height):
+                def addRate(struct, rate):
+                    if (width, height) not in sizes:
+                        sizes[(width, height)] = []
+                    d = {'framerate': (rate.num, rate.denom),
+                         'mime': struct.get_name()}
+                    if 'yuv' in d['mime']:
+                        d['format'] = struct['format'].fourcc
+                    sizes[(width, height)].append(d)
+                forAllStructValues(struct, 'framerate', addRate)
+            forAllStructValues(struct, 'height', addRatesForHeight)
+        for struct in caps:
+            if 'yuv' not in struct.get_name():
+                continue
+            forAllStructValues(struct, 'width', addRatesForWidth)
+
+        return (name, sizes)
                 
-    # FIXME: taken from the 0.8 check
-    # autoprobe = "autoprobe=false"
-    # added in gst-plugins 0.8.6
-    # if gstreamer.element_factory_has_property('v4lsrc', 'autoprobe-fps'):
-    #    autoprobe += " autoprobe-fps=false"
-
-    autoprobe = "autoprobe-fps=false"
-    # FIXME: with autoprobe-fps turned off, pwc's don't work anymore
-    autoprobe = ""
-
-    pipeline = 'v4lsrc name=source device=%s %s ! fakesink' % (device,
-        autoprobe)
-    d = do_element_check(pipeline, 'source', get_device_name, 
-        state=gst.STATE_PAUSED, set_state_deferred=True)
+    def tryV4L1(_):
+        log.debug('webcam', 'trying v4l1')
+        pipeline = 'v4lsrc name=source device=%s ! fakesink' % (device,)
+        d = do_element_check(pipeline, 'source', probeDevice, 
+                             state=gst.STATE_PAUSED, set_state_deferred=True)
+        return d
+
+    result = messages.Result()
 
+    d = tryV4L1()
     d.addCallback(check.callbackResult, result)
     d.addErrback(check.errbackNotFoundResult, result, id, device)
     d.addErrback(check.errbackResult, result, id, device)


More information about the flumotion-commit mailing list