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