Merge lp:~nico-inattendu/luciole/bug_excessive_cpu into lp:luciole/0.8
- bug_excessive_cpu
- Merge into 0.8
Proposed by
NicoInattendu
Status: | Merged |
---|---|
Approved by: | NicoInattendu |
Approved revision: | not available |
Merge reported by: | NicoInattendu |
Merged at revision: | not available |
Proposed branch: | lp:~nico-inattendu/luciole/bug_excessive_cpu |
Merge into: | lp:luciole/0.8 |
Diff against target: |
804 lines (+364/-74) 8 files modified
lucioLib/gui/dialog_project_properties.py (+166/-24) lucioLib/lcl_gst/lcl_gst_acq.py (+41/-11) lucioLib/lcl_gst/lcl_gst_base.py (+10/-6) lucioLib/lcl_gst/lcl_gst_play.py (+0/-1) lucioLib/lucioWebCamDetect/luciole_webcam_detection.py (+70/-16) lucioLib/luciole_controller.py (+11/-6) lucioLib/luciole_project.py (+64/-10) luciole.py (+2/-0) |
To merge this branch: | bzr merge lp:~nico-inattendu/luciole/bug_excessive_cpu |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
NicoInattendu | Approve | ||
Review via email: mp+18246@code.launchpad.net |
Commit message
Merge with corrections fo excessive CPU bug #500649
Description of the change
To post a comment you must log in.
Revision history for this message
NicoInattendu (nico-inattendu) wrote : | # |
Revision history for this message
NicoInattendu (nico-inattendu) : | # |
review:
Approve
Preview Diff
[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1 | === modified file 'lucioLib/gui/dialog_project_properties.py' |
2 | --- lucioLib/gui/dialog_project_properties.py 2009-04-28 13:36:55 +0000 |
3 | +++ lucioLib/gui/dialog_project_properties.py 2010-01-29 07:10:30 +0000 |
4 | @@ -1,9 +1,9 @@ |
5 | #!/usr/bin/env python |
6 | # -*- coding: utf-8 -*- |
7 | # -*- Mode: Python -*- |
8 | -# vi:si:ai:et:sw=4:sts=4:ts=4 |
9 | +# vim:si:ai:et:sw=4:sts=4:ts=4 |
10 | # |
11 | -# Copyright Nicolas Bertrand (nico@inattendu.org), 2009 |
12 | +# Copyright Nicolas Bertrand (nico@inattendu.org), 2009, 2010 |
13 | # |
14 | # This file is part of Luciole. |
15 | # |
16 | @@ -22,16 +22,22 @@ |
17 | # |
18 | # |
19 | """ |
20 | - dialog_project_properties.py : Dialog who display the project properties |
21 | + dialog_project_properties.py : Dialog who display the luciole project properties |
22 | """ |
23 | +#i18n |
24 | from gettext import gettext as _ |
25 | + |
26 | import gtk |
27 | import pango |
28 | |
29 | from .. import luciole_constants as LCONST |
30 | import webcam_detection_widget as LWDW |
31 | |
32 | -(LABEL,ENTRY)=range(2) |
33 | + |
34 | +#type of widgets for displaying webcam data |
35 | +(LABEL,ENTRY,SCALE)=range(3) |
36 | + |
37 | + |
38 | |
39 | class Project_properties(object): |
40 | |
41 | @@ -83,14 +89,19 @@ |
42 | 'desc' : _('Video height :'), |
43 | 'type' : LABEL |
44 | }, |
45 | + 'framerate_list': { |
46 | + 'desc' : _('Webcam framerate \n (number of images per second)'), |
47 | + 'type' : SCALE |
48 | + }, |
49 | + |
50 | + |
51 | } |
52 | |
53 | |
54 | _title = _('Project properties') |
55 | |
56 | def __init__(self,main_window, project, cb_project_change) : |
57 | - """ create a Dialog with project properties and disqpay it""" |
58 | - |
59 | + """ create a Dialog with project properties and display it""" |
60 | self._dialog = gtk.Dialog ( _(self._title), |
61 | main_window, |
62 | gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT, |
63 | @@ -101,6 +112,9 @@ |
64 | self._project = project |
65 | self._cb_project_change = cb_project_change |
66 | |
67 | + # keep framerate list and framerate selected those value can change |
68 | + self._framerate_selected = self._project['webcam_data']['framerate_selected'] |
69 | + self._framerate_list = self._project['webcam_data']['framerate_list'] |
70 | # connect destroy signal |
71 | #self._dialog.connect("destroy", self._cb_on_exit) |
72 | self._dialog.connect("delete-event", self._cb_on_exit) |
73 | @@ -131,10 +145,19 @@ |
74 | # assumption only enry on webcam data |
75 | webcam_dict = self._project['webcam_data'] |
76 | for (key_entry, widget_entry) in self.webcam_widgets.iteritems() : |
77 | - if widget_entry.get_text() != webcam_dict[key_entry] : |
78 | - # entry value changed |
79 | - # emit callback to inidcate project change |
80 | - self._cb_project_change('webcam_data', key_entry, widget_entry.get_text()) |
81 | + # specific treatment when the wigdet is associated to framerate_list |
82 | + # store framerate_list and framerate_selected |
83 | + if key_entry == 'framerate_list' : |
84 | + # callback for updated framerate |
85 | + self._cb_project_change('webcam_data', 'framerate_selected',self._framerate_selected) |
86 | + # check if framerate list has changed if yes callback for framerate list |
87 | + if webcam_dict[key_entry] != self._framerate_list : |
88 | + self._cb_project_change('webcam_data', 'framerate_list',self._framerate_list) |
89 | + else : |
90 | + if widget_entry.get_text() != webcam_dict[key_entry] : |
91 | + # entry value changed |
92 | + # emit callback to inidcate project change |
93 | + self._cb_project_change('webcam_data', key_entry, widget_entry.get_text()) |
94 | |
95 | def _cb_on_exit(self,widget,event) : |
96 | self._dialog.destroy() |
97 | @@ -196,15 +219,19 @@ |
98 | widget = None |
99 | if self._WEBCAM_PREFS[key]['type'] == ENTRY : |
100 | widget = gtk.Entry() |
101 | - widget.set_alignment(xalign=0.0) # left justification of label |
102 | - else: |
103 | + widget.set_alignment(xalign = 0.0) # left justification |
104 | + widget.set_text("%s"%self._project['webcam_data'][key]) |
105 | + elif self._WEBCAM_PREFS[key]['type'] == LABEL : |
106 | widget = gtk.Label() |
107 | - widget.set_alignment(xalign=0.0,yalign=0.5) # left justification of label |
108 | - |
109 | + widget.set_alignment(xalign = 0.0, yalign = 0.5) # left justification |
110 | + widget.set_text("%s"%self._project['webcam_data'][key]) |
111 | + elif self._WEBCAM_PREFS[key]['type'] == SCALE : |
112 | + widget = Framerate_scale(self._project['webcam_data'][key], |
113 | + self._project['webcam_data']['framerate_selected'], |
114 | + self._cb_framerate_selected) |
115 | + |
116 | self.webcam_widgets[key] = widget # save the widget |
117 | |
118 | - widget.set_text("%s"%self._project['webcam_data'][key]) |
119 | - |
120 | widget.show() |
121 | table.attach(widget, 1, 2, row, row+1,xpadding = 10 ) |
122 | |
123 | @@ -235,7 +262,9 @@ |
124 | self.make_table_webcam_row(table,2,'height') |
125 | self.make_table_webcam_row(table,3,'source_input') |
126 | self.make_table_webcam_row(table,4,'device') |
127 | - |
128 | + self.make_table_webcam_row(table,5,'framerate_list') |
129 | + # No lines for framerate_selected tag : handled framerate_list tag |
130 | + |
131 | Hbox.pack_start( child = table, |
132 | expand = True, |
133 | fill = True, |
134 | @@ -294,15 +323,25 @@ |
135 | |
136 | |
137 | def _cb_webcam_detection(self,project_data) : |
138 | - """ calback when webcam detection is done update webcam data """ |
139 | + """ callback when webcam detection is done update webcam data """ |
140 | if project_data.has_key('webcam_data') and project_data['webcam_data'] != {} : |
141 | for (w_key, w_widget) in self.webcam_widgets.iteritems() : |
142 | - if project_data['webcam_data'].has_key(w_key) : |
143 | - w_text ="%s"%project_data['webcam_data'][w_key] |
144 | - w_widget.set_text(w_text) |
145 | + # Sepcific operation for framerate_list widget |
146 | + if w_key == 'framerate_list' : |
147 | + w_widget.refresh(project_data['webcam_data']['framerate_list'], |
148 | + project_data['webcam_data']['framerate_selected'] ) |
149 | + self._framerate_list = project_data['webcam_data']['framerate_list'] |
150 | + # for other webcam widgets : only text to update |
151 | else : |
152 | - w_widget.set_text('') |
153 | - |
154 | + if project_data['webcam_data'].has_key(w_key) : |
155 | + w_text ="%s"%project_data['webcam_data'][w_key] |
156 | + w_widget.set_text(w_text) |
157 | + else : |
158 | + w_widget.set_text('') |
159 | + |
160 | + def _cb_framerate_selected(self,framerate) : |
161 | + """ callback to update selected framerate used by Framerate_scale widget """ |
162 | + self._framerate_selected = framerate |
163 | |
164 | class Webcam_detection_dialog(gtk.MessageDialog) : |
165 | """ Opens Dialog for webcam Detection """ |
166 | @@ -352,4 +391,107 @@ |
167 | return True |
168 | |
169 | |
170 | - |
171 | +class Framerate_scale(gtk.HScale) : |
172 | + """ |
173 | + Widget use to display an horizontal scale : |
174 | + represenation of webcam framerates in number of images per seconds |
175 | + """ |
176 | + |
177 | + def __init__(self,framerate_range,initial_range,cb_framerate_changed) : |
178 | + """ |
179 | + Constructor |
180 | + params : |
181 | + - framerate_range : The framerate range - a list of framerate tuple |
182 | + - initial_range : The initial range to dipslay - a tuple |
183 | + - cb_framerate_changed : the callback function to indicate framerate change |
184 | + """ |
185 | + |
186 | + # |
187 | + # store params |
188 | + # |
189 | + self._framerate_range = framerate_range |
190 | + self._initial_range = initial_range |
191 | + self._cb_framerate_changed = cb_framerate_changed |
192 | + |
193 | + |
194 | + # |
195 | + # configure widget |
196 | + # |
197 | + |
198 | + # compute the initial position on Scale bar |
199 | + initial_f_value = float(self._framerate_range.index(self._initial_range)) |
200 | + |
201 | + # |
202 | + # compute an adjustment in range [0 .. nb_framerate], icrement is 1 |
203 | + # Use floats as ints actually |
204 | + # Display framerates instead of float values |
205 | + # |
206 | + adj = gtk.Adjustment(value =initial_f_value, |
207 | + lower = 0.0, |
208 | + upper = float(len( self._framerate_range)), |
209 | + step_incr = 1.0, |
210 | + page_incr = 1.0) |
211 | + |
212 | + |
213 | + super(Framerate_scale,self).__init__(adjustment = adj) |
214 | + |
215 | + # configure signals |
216 | + self.connect("format-value", self.on_format_value) |
217 | + self.connect("value-changed", self.on_value_changed) |
218 | + |
219 | + # configure widget display properties |
220 | + self.set_update_policy(gtk.UPDATE_DISCONTINUOUS) |
221 | + self.set_value_pos(gtk.POS_BOTTOM) |
222 | + self.show_all() |
223 | + |
224 | + def on_format_value(self,widget,value) : |
225 | + """ |
226 | + Signal 'format-value' : Used to display value in scale in image/seconds format. |
227 | + Computed according the adjustment value, the intger round of value is the index |
228 | + of framerate_range |
229 | + """ |
230 | + int_val = int(value) |
231 | + if int_val >= len(self._framerate_range) : |
232 | + int_val = len(self._framerate_range) -1 |
233 | + val_to_display = self._framerate_range[int_val] |
234 | + # compute and return the number of images per second |
235 | + return int(val_to_display[0]/val_to_display[1]) |
236 | + |
237 | + def on_value_changed(self,widget) : |
238 | + """ |
239 | + Emited when a value is changed and selected by user |
240 | + the signal function get the float value, round it, |
241 | + get the equivalent framerate. |
242 | + """ |
243 | + # TODO : how to update webcam date |
244 | + |
245 | + # get rounded value |
246 | + int_val = int(widget.get_value()) |
247 | + if int_val >= len(self._framerate_range) : |
248 | + int_val = len(self._framerate_range) -1 |
249 | + # update project data : do callback call |
250 | + self._cb_framerate_changed( self._framerate_range[int_val]) |
251 | + |
252 | + |
253 | + def refresh(self, framerate_list, framerate_selected) : |
254 | + """ |
255 | + Update Scale bar and ajustment according new framerate range |
256 | + """ |
257 | + |
258 | + self._framerate_range = framerate_list |
259 | + self._initial_range = framerate_selected |
260 | + |
261 | + # |
262 | + # recompute adjustment |
263 | + # |
264 | + initial_f_value = float(self._framerate_range.index(self._initial_range)) |
265 | + |
266 | + adj = gtk.Adjustment(value =initial_f_value, |
267 | + lower = 0.0, |
268 | + upper = float(len( self._framerate_range)), |
269 | + step_incr = 1.0, |
270 | + page_incr = 1.0) |
271 | + |
272 | + self.set_adjustment(adj) |
273 | + |
274 | + |
275 | |
276 | === modified file 'lucioLib/lcl_gst/lcl_gst_acq.py' |
277 | --- lucioLib/lcl_gst/lcl_gst_acq.py 2009-12-14 06:15:44 +0000 |
278 | +++ lucioLib/lcl_gst/lcl_gst_acq.py 2010-01-29 07:10:30 +0000 |
279 | @@ -40,12 +40,28 @@ |
280 | |
281 | class PhotoSaveBin(LG.Bin) : |
282 | """ Bin Pad to save in jpeg format image from stream. Stream alyays encoded but the result will be saved to file only when a capture is done """ |
283 | + |
284 | + # Do jpeg encoding with a framerate of 5 images per second used to reduce cpu |
285 | + JPEG_CAPS_FILTER = " video/x-raw-yuv, framerate=5/1 " |
286 | + |
287 | def __init__(self) : |
288 | """ Pilpeline desc : jpegenc + fakseink """ |
289 | |
290 | + super(PhotoSaveBin,self).__init__() |
291 | self.__gobject_init__() |
292 | ImageBinElems=[] |
293 | |
294 | + Myvideorate = LG.element_factory_make('videorate') # rate transformation |
295 | + ImageBinElems.append(Myvideorate) |
296 | + |
297 | + MyJpegFilter = LG.element_factory_make("capsfilter", "JpegFilter") |
298 | + # create caps string according, width, height and framerate |
299 | + caps = LG.Caps(self.JPEG_CAPS_FILTER) |
300 | + |
301 | + self.logger.info(" Webcam cap : %s"%caps.to_string()) |
302 | + MyJpegFilter.set_property("caps", caps) |
303 | + ImageBinElems.append(MyJpegFilter) |
304 | + |
305 | MyJpegenc = LG.element_factory_make("jpegenc","MyJpegenc") # jpeg encoding |
306 | ImageBinElems.append(MyJpegenc) |
307 | |
308 | @@ -54,9 +70,9 @@ |
309 | |
310 | for elem in ImageBinElems : self.add(elem) |
311 | |
312 | - LG.element_link_many(MyJpegenc,photosink) |
313 | + LG.element_link_many(Myvideorate,MyJpegFilter,MyJpegenc,photosink) |
314 | |
315 | - self.add_pad(LG.GhostPad('sink', MyJpegenc.get_pad('sink'))) |
316 | + self.add_pad(LG.GhostPad('sink', Myvideorate.get_pad('sink'))) |
317 | |
318 | |
319 | class InputImageBin(LG.Bin): |
320 | @@ -79,7 +95,7 @@ |
321 | self.MyAlpha.set_property("alpha",self.__alphaValueImage) |
322 | alphaValueImage = property(get_alphaValueImage, set_alphaValueImage, None, " Framerate for displaying input image ") |
323 | |
324 | - def __init__(self,image,alphaValue,framerate=25) : |
325 | + def __init__(self,image,alphaValue,framerate=1) : |
326 | self.__gobject_init__() |
327 | self.__image2Mix = image |
328 | self.__framerate = framerate |
329 | @@ -90,11 +106,12 @@ |
330 | self.InputImage= LG.element_factory_make('multifilesrc') |
331 | self.InputImage.set_property('location',self.__image2Mix) |
332 | ImageBinElems.append(self.InputImage) |
333 | - |
334 | + |
335 | + |
336 | # filter to set frame rate |
337 | self.ImageFilter = LG.element_factory_make("capsfilter") |
338 | self._filter_caps_string = "image/jpeg, framerate=(fraction)%s/1 ,width=%s,height=%s " |
339 | - |
340 | + |
341 | caps_string = self._filter_caps_string%(self.__framerate,MCONST.VIDEO_PAL_RES[0],MCONST.VIDEO_PAL_RES[1]) |
342 | caps = LG.Caps(caps_string) |
343 | self.ImageFilter.set_property("caps", caps) |
344 | @@ -282,16 +299,22 @@ |
345 | |
346 | class WebcamInputBin(LG.Bin) : |
347 | """ LG.Bin for Web cam input""" |
348 | - def __init__(self,width=640,height=480,source_input='v4l2src',device='/dev/video0') : |
349 | - """build Dv cam input bin |
350 | + def __init__(self,width=640, height=480, framerate=(2,25), source_input='v4l2src', device='/dev/video0') : |
351 | + """build web cam input bin |
352 | Description of pipeline : |
353 | __________________________________________________________ |
354 | | | |
355 | -->-- | v4lsrc --> capsfilter --> ffmpegcolorspace --> ScaleBin | ghostPad -->-- |
356 | |__________________________________________________________|_ |
357 | - |
358 | + params : |
359 | + width : The webcam width. Integer value |
360 | + height : The webcam width. Integer value |
361 | + framerate : The webcam framerate. A tuple for fraction representation (denom,num) |
362 | + source_input : The type of driver input. A string |
363 | + device : Path to webcam device. A string |
364 | + |
365 | """ |
366 | - |
367 | + super(WebcamInputBin,self).__init__() |
368 | self.__gobject_init__() |
369 | ImageBinElems=[] |
370 | |
371 | @@ -300,8 +323,9 @@ |
372 | ImageBinElems.append(MyVideoSrc) |
373 | |
374 | MyVideoSrcFilter = LG.element_factory_make("capsfilter", "MyVideoSrc") |
375 | - |
376 | - caps = LG.Caps("video/x-raw-yuv, width=%s,height=%s"%(width,height) ) |
377 | + # create caps string according, width, height and framerate |
378 | + caps = LG.Caps("video/x-raw-yuv, width=%s,height=%s , framerate=%s/%s "%(width,height,framerate[0],framerate[1]) ) |
379 | + self.logger.info(" Webcam cap : %s"%caps.to_string()) |
380 | MyVideoSrcFilter.set_property("caps", caps) |
381 | ImageBinElems.append(MyVideoSrcFilter) |
382 | |
383 | @@ -492,6 +516,8 @@ |
384 | self.__webcam_data['height'] = 480 |
385 | self.__webcam_data['device'] = "/dev/video0" |
386 | self.__webcam_data['source_input'] = "v4l2src" |
387 | + self.__webcam_data['framerate_list'] = [ (25,2) ] |
388 | + self.__webcam_data['framerate_selected'] = (25,2) |
389 | |
390 | def reset_pipe(self): |
391 | """ Gstreamer pipe configuration : |
392 | @@ -500,10 +526,14 @@ |
393 | """ |
394 | ElementList = [] |
395 | self.pipe = LG.Pipeline(self.pipe_name) |
396 | + print self.__webcam_data |
397 | + print " type framerate list :" , type(self.__webcam_data['framerate_list']) |
398 | + |
399 | if (self.__inputType == MCONST.WEBCAM) : |
400 | InputBin = WebcamInputBin( |
401 | width = self.__webcam_data['width'], |
402 | height = self.__webcam_data['height'], |
403 | + framerate = self.__webcam_data['framerate_selected'], |
404 | source_input = self.__webcam_data['source_input'], |
405 | device = self.__webcam_data['device'] |
406 | ) |
407 | |
408 | === modified file 'lucioLib/lcl_gst/lcl_gst_base.py' |
409 | --- lucioLib/lcl_gst/lcl_gst_base.py 2009-12-14 06:15:44 +0000 |
410 | +++ lucioLib/lcl_gst/lcl_gst_base.py 2010-01-29 07:10:30 +0000 |
411 | @@ -60,11 +60,19 @@ |
412 | # |
413 | |
414 | class Pipeline(gst.Pipeline) : |
415 | - """ Interaface class for pipeline """ |
416 | + """ Interface class for gst pipeline """ |
417 | |
418 | def __init__(self, *args,**kwargs) : |
419 | super(Pipeline, self).__init__(*args,**kwargs) |
420 | |
421 | +class Bin(gst.Bin) : |
422 | + """ Interface class for gst Bin """ |
423 | + |
424 | + def __init__(self, *args,**kwargs) : |
425 | + super(Bin, self).__init__(*args,**kwargs) |
426 | + self.logger = logging.getLogger('luciole') |
427 | + |
428 | + |
429 | class VideoWidget(object): |
430 | """ class usage to be understood """ |
431 | def __init__(self,DrawingArea): |
432 | @@ -91,11 +99,7 @@ |
433 | |
434 | def __init__(self,video_widget = None, pipe_name=None, cb_on_error = None, cb_on_eos = None ): |
435 | # init logger |
436 | - |
437 | self.logger = logging.getLogger('luciole') |
438 | - if self.logger.level == logging.DEBUG : |
439 | - gst.debug_set_active(True) |
440 | - gst.debug_set_default_threshold(gst.LEVEL_DEBUG) |
441 | |
442 | # |
443 | # link display window widget with gstreamer |
444 | @@ -109,7 +113,7 @@ |
445 | self._cb_on_eos = cb_on_eos |
446 | |
447 | self.pipe = Pipeline(pipe_name) |
448 | - print self.pipe |
449 | + self.logger.info(self.pipe) |
450 | |
451 | def connect_bus(self) : |
452 | """ Connect to bus """ |
453 | |
454 | === modified file 'lucioLib/lcl_gst/lcl_gst_play.py' |
455 | --- lucioLib/lcl_gst/lcl_gst_play.py 2009-12-14 06:15:44 +0000 |
456 | +++ lucioLib/lcl_gst/lcl_gst_play.py 2010-01-29 07:10:30 +0000 |
457 | @@ -83,7 +83,6 @@ |
458 | # filter |
459 | self.ImageFilter = LG.element_factory_make("capsfilter") |
460 | caps_string = self._filter_caps_string % self._framerate |
461 | - print caps_string |
462 | caps = LG.gst.Caps(caps_string) |
463 | self.ImageFilter.set_property("caps", caps) |
464 | ElementList.append(self.ImageFilter) |
465 | |
466 | === modified file 'lucioLib/lucioWebCamDetect/luciole_webcam_detection.py' |
467 | --- lucioLib/lucioWebCamDetect/luciole_webcam_detection.py 2009-05-09 16:11:31 +0000 |
468 | +++ lucioLib/lucioWebCamDetect/luciole_webcam_detection.py 2010-01-29 07:10:30 +0000 |
469 | @@ -35,6 +35,12 @@ |
470 | |
471 | import gobject |
472 | |
473 | +import logging |
474 | +module_logger = logging.getLogger('luciole') |
475 | + |
476 | + |
477 | +from .. import luciole_exceptions as LEXCEP |
478 | + |
479 | |
480 | # Availables video sources for gstreamer |
481 | GSTREAMER_VIDEO_SOURCES = [ |
482 | @@ -51,6 +57,9 @@ |
483 | |
484 | def __init__(self) : |
485 | """ class init""" |
486 | + # init logger |
487 | + self.logger = logging.getLogger('luciole') |
488 | + |
489 | self._webcam_devices = list() |
490 | |
491 | ############################################################ |
492 | @@ -86,13 +95,15 @@ |
493 | video_formats = self._webcam_devices[webcam_device_index]['webcam_data']['video_formats'] |
494 | mimetypes = ('video/x-raw-yuv','video/x-raw-rgb','image/jpeg') |
495 | (width,height)=(None,None) |
496 | - |
497 | for mimetype in mimetypes : |
498 | + |
499 | if video_formats.has_key(mimetype) : |
500 | # the resolution format are sorted by resolution |
501 | # the higher resolution is first in list |
502 | width = video_formats[mimetype][0]['width'] |
503 | height = video_formats[mimetype][0]['height'] |
504 | + framerate = video_formats[mimetype][0]['framerate'] |
505 | + |
506 | |
507 | # leave loop when mimetype is found |
508 | break |
509 | @@ -101,9 +112,11 @@ |
510 | # a format was detected : prepare pipeline info |
511 | webcam_bin_data['width'] = width |
512 | webcam_bin_data['height'] = height |
513 | + webcam_bin_data['framerate_list'] = framerate |
514 | + webcam_bin_data['framerate_selected'] = framerate[len(framerate)/2] |
515 | webcam_bin_data['source_input'] = self._webcam_devices[webcam_device_index]['v4l_driver'] |
516 | webcam_bin_data['device'] = self._webcam_devices[webcam_device_index]['device'] |
517 | - webcam_bin_data['name'] = self._webcam_devices[webcam_device_index]['name'] |
518 | + webcam_bin_data['name'] = self._webcam_devices[webcam_device_index]['name'] |
519 | |
520 | return webcam_bin_data |
521 | |
522 | @@ -262,7 +275,6 @@ |
523 | for i in range(num_structures) : |
524 | # loop on each strutcures |
525 | structure = caps[i] |
526 | - |
527 | if ( structure.has_name("video/x-raw-yuv") |
528 | or structure.has_name("video/x-raw-rgb") |
529 | or structure.has_name("image/jpeg") |
530 | @@ -271,12 +283,12 @@ |
531 | if not webcam_device["video_formats"].has_key(structure.get_name()): |
532 | webcam_device["video_formats"][structure.get_name()] = list() |
533 | resolution_list = webcam_device["video_formats"][structure.get_name()] |
534 | - #print " resolution_list at the begin : %s"%webcam_device["video_formats"] |
535 | + #print " resolution_list at the begin : \n %s"%webcam_device["video_formats"] |
536 | |
537 | # take in acount only structure wih fields width and height |
538 | if (structure.has_field("width") and structure.has_field("height")) : |
539 | #print " %s : %s x %s"%(structure.get_name(),structure["width"],structure["height"] ) |
540 | - |
541 | + resolution=dict() |
542 | # check if result is in GST_TYPE_INT_RANGE format |
543 | if (isinstance(structure["width"], gst.IntRange)): |
544 | # when type is range --> some resolution points are created in the range |
545 | @@ -286,21 +298,31 @@ |
546 | while ( ( width_cur <= structure["width"].high ) and |
547 | ( height_cur <= structure["height"].high ) |
548 | ): |
549 | - resolution=dict() |
550 | + |
551 | ( resolution["width"] , resolution["height"] ) = (width_cur,height_cur) |
552 | + #store framerate |
553 | + resolution["framerate"] = None |
554 | + if structure.has_field("framerate") : |
555 | + resolution["framerate"] = structure["framerate"] |
556 | + # Append resolution dict to list |
557 | if not resolution in resolution_list : |
558 | resolution_list.append(resolution) |
559 | (width_cur,height_cur) = (width_cur*2,height_cur*2) |
560 | |
561 | # check if result is in G_TYPE_INT format |
562 | elif structure.has_field_typed("width",gobject.TYPE_INT) : |
563 | - resolution=dict() |
564 | (resolution["width"] , resolution["height"] ) = (structure["width"],structure["height"]) |
565 | + resolution["framerate"] = None |
566 | + if structure.has_field("framerate") : |
567 | + resolution["framerate"] = luciole_webcam_detection.gst_get_framerate(structure["framerate"]) |
568 | if not resolution in resolution_list : |
569 | resolution_list.append(resolution) |
570 | |
571 | else : |
572 | - print " type %s"% structure.get_field_type("width") |
573 | + # raise error |
574 | + excep_message = "unkown video type %s"% structure.get_field_type("width") |
575 | + raise LEXCEP.LucioException,excep_message |
576 | + |
577 | for mimetype,res_list in webcam_device["video_formats"].iteritems(): |
578 | # loop on video on formats to stort it |
579 | # data are sorted by width , in reverse order; i.e max res is the first in the list |
580 | @@ -314,7 +336,36 @@ |
581 | # print "----- %s : %s"%(mimetype,res_list) |
582 | gst_get_supported_video_formats = staticmethod(__gst_get_supported_video_formats) |
583 | |
584 | - |
585 | + def __gst_get_framerate(framerate_obj): |
586 | + """ create a list of gst.Fraction framerates """ |
587 | + framerate = list() |
588 | + if type(framerate_obj) == list : |
589 | + framerate = framerate_obj |
590 | + elif isinstance(framerate_obj, gst.FractionRange) : |
591 | + # convert also to list of framerate |
592 | + NB_FRAMERATE = 4 |
593 | + MAX_FRAMERATE = gst.Fraction(25,1) |
594 | + |
595 | + # limit max framerate |
596 | + if framerate_obj.high < MAX_FRAMERATE : |
597 | + framerate_obj.high = MAX_FRAMERATE |
598 | + |
599 | + new_framerate = framerate_obj.high |
600 | + for i in range(NB_FRAMERATE) : |
601 | + framerate.append(new_framerate) |
602 | + new_framerate = new_framerate/2 |
603 | + # at end of loop append the lowest framerate if not 0 |
604 | + if framerate_obj.low != gst.Fraction(0,1) : |
605 | + framerate.append(framerate_obj.low) |
606 | + else : |
607 | + # raise error |
608 | + excep_message = " unable to detect framerate : unknown type : %s for "%(type(framerate_obj),framerate_obj) |
609 | + raise LEXCEP.LucioException,excep_message |
610 | + # transform framerate in not gst format |
611 | + if framerate != None : |
612 | + framerate_trans = [ (fraction.num,fraction.denom) for fraction in framerate] |
613 | + return framerate_trans |
614 | + gst_get_framerate = staticmethod(__gst_get_framerate) |
615 | |
616 | if __name__ == '__main__' : |
617 | # TEST PURPOSE : for webcam detection |
618 | @@ -322,11 +373,14 @@ |
619 | val = CamObj.detect_webcam() |
620 | print " found %s webCam device "%val |
621 | |
622 | - if val >0 : |
623 | - for device in CamObj.webcam_devices : |
624 | - for k,j in device.iteritems() : print "%s : %s"%(k,j) |
625 | - print "----------------------------------------------------------------" |
626 | - |
627 | - |
628 | - |
629 | + #if val >0 : |
630 | + # for device in CamObj.webcam_devices : |
631 | + # for k,j in device.iteritems() : print "%s : %s"%(k,j) |
632 | + # print "----------------------------------------------------------------" |
633 | + for i in range(val) : |
634 | + #for enumerate(index,device) in CamObj.webcam_devices : |
635 | + best = CamObj.get_gst_best_input(i) |
636 | + print "Best webcam resolution found " |
637 | + print best |
638 | + print "\n \n" |
639 | |
640 | |
641 | === modified file 'lucioLib/luciole_controller.py' |
642 | --- lucioLib/luciole_controller.py 2009-12-14 06:15:44 +0000 |
643 | +++ lucioLib/luciole_controller.py 2010-01-29 07:10:30 +0000 |
644 | @@ -123,10 +123,6 @@ |
645 | project_dico_data = LP.project_dico() |
646 | for k,v in project_data.iteritems() : |
647 | project_dico_data[k] = project_data[k] |
648 | - #convert webcam_data as str values to be coherent with load of webcam data from a file |
649 | - if k == 'webcam_data' : |
650 | - for w_k in project_dico_data[k].keys() : |
651 | - project_dico_data[k][w_k] = "%s"%project_dico_data[k][w_k] |
652 | self.project = project_dico_data |
653 | |
654 | # 2. create project ( folder structure ,etc ...) |
655 | @@ -146,8 +142,17 @@ |
656 | # if a project is loaded close it |
657 | print """ DEBUG : Close project Before """ |
658 | self.close() |
659 | - |
660 | - self.project = self.project_ctrller.open(project_path) |
661 | + try : |
662 | + (is_valid,self.project) = self.project_ctrller.open(project_path) |
663 | + except L_EXCEP.LucioException,err : |
664 | + print err |
665 | + |
666 | + # webcam data are not valid |
667 | + if is_valid == False : |
668 | + msg = _(" Webcam data not valid in project. Please restart webcam detection") |
669 | + LTK.Dialog.ErrorMessage(self.gui.window, msg) |
670 | + |
671 | + |
672 | |
673 | # 3. load project in application |
674 | self.__load_project_in_app() |
675 | |
676 | === modified file 'lucioLib/luciole_project.py' |
677 | --- lucioLib/luciole_project.py 2009-04-24 13:42:04 +0000 |
678 | +++ lucioLib/luciole_project.py 2010-01-29 07:10:30 +0000 |
679 | @@ -4,7 +4,7 @@ |
680 | # vi:si:ai:et:sw=4:sts=4:ts=4 |
681 | # |
682 | # |
683 | -# Copyright Nicolas Bertrand (nico@inattendu.org), 2009 |
684 | +# Copyright Nicolas Bertrand (nico@inattendu.org), 2009,2010 |
685 | # |
686 | # This file is part of Luciole. |
687 | # |
688 | @@ -30,18 +30,49 @@ |
689 | import xml.etree.ElementTree as ET #python 2.5 |
690 | from xml.parsers.expat import ParserCreate, ExpatError |
691 | |
692 | + |
693 | import luciole_constants as LCONST |
694 | import luciole_tools as LT |
695 | import luciole_exceptions as L_EXCEP |
696 | |
697 | class project_dico(dict): |
698 | + """ |
699 | + Luciole project dicitionary : contains all porject data as dictionary |
700 | + """ |
701 | + |
702 | + # |
703 | + # CONSTANTS |
704 | + # |
705 | + |
706 | + # mandatory tags for webcam description |
707 | + WEBCAM_DATA_TAGS = [ 'name', |
708 | + 'device', |
709 | + 'source_input', |
710 | + 'height', |
711 | + 'width', |
712 | + 'framerate_list', |
713 | + 'framerate_selected', |
714 | + ] |
715 | + |
716 | + # default values for webcam |
717 | + WEBCAM_TAGS_DEFAULT_VALUES = { |
718 | + 'framerate_list' : [(5,1) ], |
719 | + 'framerate_selected' : (5,1) , |
720 | + } |
721 | + |
722 | + |
723 | def __init__(self): |
724 | + """ constructor : init a dict """ |
725 | super(project_dico,self).__init__() |
726 | |
727 | class project_controller(object) : |
728 | + """ |
729 | + Class for handling luciole projects : creation, open, save |
730 | + """ |
731 | + |
732 | |
733 | def __init__(self): |
734 | - pass |
735 | + """ Constructor""" |
736 | # by default no project loaded |
737 | self.__project_loaded = False |
738 | |
739 | @@ -170,21 +201,44 @@ |
740 | # loop on webcam data and save on data dictionary |
741 | webcam_data={} |
742 | for my_item in et_webcam_data.getchildren() : |
743 | - webcam_data[my_item.tag] = my_item.attrib.get("key") |
744 | - # create acquisition object |
745 | - p_project['webcam_data'] =webcam_data |
746 | + # for framerate_selected and framerate_list tage : evaluate to convert in tuple and list |
747 | + # for others keep it as str |
748 | + if my_item.tag == 'framerate_selected' or my_item.tag == 'framerate_list' : |
749 | + webcam_data[my_item.tag] = eval(my_item.attrib.get("key")) |
750 | + else : |
751 | + webcam_data[my_item.tag] = my_item.attrib.get("key") |
752 | + |
753 | + # check webcam data validity |
754 | + is_valid = True |
755 | + missing_tags = [] |
756 | + for data in p_project.WEBCAM_DATA_TAGS : |
757 | + if not webcam_data.has_key(data) : |
758 | + is_valid = False |
759 | + missing_tags.append(data) |
760 | + |
761 | + if is_valid == False : |
762 | + # not a valid project |
763 | + for missing_tag in missing_tags : |
764 | + if p_project.WEBCAM_TAGS_DEFAULT_VALUES.has_key(missing_tag) : |
765 | + webcam_data[missing_tag] = p_project.WEBCAM_TAGS_DEFAULT_VALUES[missing_tag] |
766 | + print missing_tag |
767 | + else : |
768 | + err = 'Invalid Project webcam data , tag %s is missing '%missing_tag |
769 | + raise L_EXCEP.LucioException, err |
770 | + |
771 | + p_project['webcam_data'] = webcam_data |
772 | else : |
773 | - # nbd@grape : raise Error |
774 | - print " Invalide webcam data found " |
775 | - return None |
776 | - |
777 | + # raise Error |
778 | + err = "Invalid webcam data found " |
779 | + raise L_EXCEP.LucioException, err |
780 | + |
781 | p_project['rush_images'] = self.__scanImages("rushData") |
782 | p_project['capture_images'] = self.__scanImages("captureData") |
783 | p_project['chrono_images'] = self.__scanImages("chronoData") |
784 | |
785 | p_project = self.__check_rush_images(p_project) |
786 | |
787 | - return p_project |
788 | + return (is_valid,p_project) |
789 | |
790 | |
791 | def __scanImages(self,p_type) : |
792 | |
793 | === modified file 'luciole.py' |
794 | --- luciole.py 2009-12-10 05:12:06 +0000 |
795 | +++ luciole.py 2010-01-29 07:10:30 +0000 |
796 | @@ -47,6 +47,8 @@ |
797 | logger = logging.getLogger("luciole") |
798 | if is_verbose == True : |
799 | logger.setLevel(logging.DEBUG) |
800 | + else : |
801 | + logger.setLevel(logging.INFO) |
802 | |
803 | # create console handler with a higher log level |
804 | ch = logging.StreamHandler() |
Merge with 0.8
Translation update needed after