~nico-inattendu/luciole/bug_727175

« back to all changes in this revision

Viewing changes to luciole/media/lgst/image_save_bin.py

  • Committer: NicoInattendu
  • Date: 2011-02-28 18:27:56 UTC
  • mfrom: (123.1.54 luciole-with-sound)
  • Revision ID: nico@inattendu.org-20110228182756-weonszu8zpzermrl
initial merge with luciole-with-sound branch

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
#!/usr/bin/env python
 
2
# -*- coding: utf-8 -*-
 
3
# -*- Mode: Python -*-
 
4
# vim:si:ai:et:sw=4:sts=4:ts=4
 
5
#
 
6
#       :webcam_bin.py
 
7
#
 
8
# Copyright (c) 2011, Nicolas Bertrand <nico@inattendu.org>
 
9
#
 
10
# This program is free software; you can redistribute it and/or
 
11
# modify it under the terms of the GNU Lesser General Public
 
12
# License as published by the Free Software Foundation; either
 
13
# version 2.1 of the License, or (at your option) any later version.
 
14
#
 
15
# This program is distributed in the hope that it will be useful,
 
16
# but WITHOUT ANY WARRANTY; without even the implied warranty of
 
17
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 
18
# Lesser General Public License for more details.
 
19
#
 
20
# You should have received a copy of the GNU Lesser General Public
 
21
# License along with this program; if not, write to the
 
22
# Free Software Foundation, Inc., 59 Temple Place - Suite 330,
 
23
# Boston, MA 02111-1307, USA.
 
24
"""
 
25
    Webcam input bin
 
26
"""
 
27
# standard library imports
 
28
import copy
 
29
# related third party imports
 
30
import pygst
 
31
pygst.require('0.10')
 
32
 
 
33
import gst
 
34
import gobject
 
35
 
 
36
import gtk.gdk
 
37
 
 
38
# local application/library specific imports
 
39
import luciole.media.lgst.common as LG_COMMON
 
40
 
 
41
 
 
42
 
 
43
 
 
44
 
 
45
 
 
46
class ImageSinkBin(LG_COMMON.BaseBin) :
 
47
    """ gst.Bin for Web cam input"""
 
48
    __gsignals__ = {
 
49
        "capture-done" : (gobject.SIGNAL_RUN_LAST,
 
50
                       gobject.TYPE_NONE,
 
51
                      (gobject.TYPE_PYOBJECT,)),
 
52
        }
 
53
  
 
54
    RATE_FILTER = {    
 
55
            'name' : 'Ratefilter',
 
56
            'element': 'capsfilter',
 
57
            'media_type' : 'video/x-raw-rgb',
 
58
            'properties' : {
 
59
                'framerate': '(fraction)1/1',
 
60
                "bpp" : 24,
 
61
                "depth": 24,
 
62
                
 
63
                },
 
64
            }
 
65
    
 
66
    IMG_SINK = {
 
67
                'name' : 'Imgsink',
 
68
                'element': 'fakesink',
 
69
                'properties' : {
 
70
                    'signal-handoffs': 'true',
 
71
                },
 
72
            }
 
73
    """
 
74
    IMG_SINK = {
 
75
                'name' : 'Imgsink',
 
76
                'element': 'filesink',
 
77
                'properties' : {
 
78
                    'location': './test.jpeg',
 
79
                },
 
80
            }
 
81
    """
 
82
 
 
83
    # TODO : input should be x-raw-yuv
 
84
    DEFAULT_PROPS = {
 
85
        'rate' : {
 
86
                'name' : 'ImageRate',
 
87
                'element': 'videorate',
 
88
            },
 
89
        'imgcsp' :{
 
90
                'name' : 'ImageCsp',
 
91
                'element': 'ffmpegcolorspace',
 
92
            },
 
93
 
 
94
        'rate_filter' : RATE_FILTER,
 
95
        
 
96
        'imgenc' : {
 
97
                'name' : 'ImgEncoder',
 
98
                'element': 'jpegenc',
 
99
                },
 
100
        'imgsink' : IMG_SINK,
 
101
            }
 
102
 
 
103
 
 
104
    
 
105
    def __init__(self, filename, params = {} ) :
 
106
        LG_COMMON.BaseBin.__init__(self, 'ImageSinkBin', params)
 
107
        self.filename = filename            
 
108
        self.capture_handler_id = 0
 
109
    
 
110
    
 
111
    def _makeBin(self) :
 
112
        self.rate = \
 
113
                LG_COMMON.make_element(self.params['rate'])
 
114
        
 
115
        self.imgcsp = \
 
116
                LG_COMMON.make_element(self.params['imgcsp'])
 
117
 
 
118
        self.rate_filter = \
 
119
                LG_COMMON.make_element(self.params['rate_filter'])
 
120
 
 
121
        #self.imgenc = \
 
122
        #        LG_COMMON.make_element(self.params['imgenc'])
 
123
        
 
124
        self.imgsink = \
 
125
                LG_COMMON.make_element(self.params['imgsink'])
 
126
 
 
127
 
 
128
        self.add(
 
129
            self.rate,
 
130
            self.rate_filter,
 
131
            self.imgcsp,
 
132
            #self.imgenc,
 
133
            self.imgsink, 
 
134
            )
 
135
 
 
136
        # make static  links
 
137
        # rate ! rate_filter  ! imgsink   
 
138
        gst.element_link_many(
 
139
            self.rate,
 
140
            self.imgcsp,
 
141
            self.rate_filter,
 
142
            #self.imgenc,
 
143
            self.imgsink, 
 
144
            )
 
145
 
 
146
        """       
 
147
        _str_link = ('%s ! %s ! %s' %\
 
148
                (self.rate.bin_repr,
 
149
                self.rate_filter.bin_repr,
 
150
                self.imgsink.bin_repr,
 
151
                ))
 
152
 
 
153
        self.debug('%s : %s'%(self.get_name(), _str_link))
 
154
        
 
155
        self.bin_repr = _str_link 
 
156
        """
 
157
        
 
158
        self.make_ghostpads(sink = self.rate, src = None)
 
159
        
 
160
        #_pad.set_blocked_async(True, self._have_data_cb)
 
161
            
 
162
    
 
163
    def _have_data_cb(self, element, data) :
 
164
        pass
 
165
 
 
166
    def capture(self, filename =None ) :
 
167
        if self.capture_handler_id != 0 :
 
168
            self.warning('Skipping capture request. Capture on progress')
 
169
            return
 
170
        
 
171
        #self.capture_handler_id = \
 
172
        #        self.imgenc.connect('frame-encoded', self.process_data_jpeg_cb, filename )
 
173
        
 
174
       
 
175
        
 
176
        self.capture_handler_id = \
 
177
                self.imgsink.connect('handoff', self.process_data_cb, filename )
 
178
        return
 
179
 
 
180
    def process_data_jpeg_cb(self, element, toto ) :
 
181
        pass
 
182
 
 
183
 
 
184
    def process_data_cb(self, gbin ,data_buffer, pad, filename ) :
 
185
        _bits_per_pixel = 8
 
186
        
 
187
        
 
188
        _caps = data_buffer.get_caps()
 
189
        _structure = _caps[0]
 
190
        _width = _structure["width"]
 
191
        _height = _structure["height"]
 
192
        # generate pixbuf
 
193
        self.imgsink.disconnect(self.capture_handler_id)
 
194
        self.capture_handler_id = 0
 
195
        
 
196
 
 
197
        # save to file 
 
198
        _file = open(self.filename,'w')
 
199
        _file.write(data_buffer)
 
200
        _file.close()
 
201
 
 
202
        
 
203
        
 
204
       
 
205
 
 
206
        
 
207
        _pixbuf = gtk.gdk.pixbuf_new_from_data(
 
208
            data_buffer.copy_on_write(),
 
209
            gtk.gdk.COLORSPACE_RGB,
 
210
            False,
 
211
            _bits_per_pixel,
 
212
            _width,
 
213
            _height,
 
214
            data_buffer.size / _height)
 
215
        
 
216
              
 
217
        # save pixbuf to file
 
218
        if filename != None :
 
219
            _filename =  filename
 
220
        else :
 
221
            _filename =  self.filename
 
222
        _pixbuf.save(self.filename, "jpeg", {"quality":"100"})
 
223
        
 
224
        self.debug('Write Jpeg on %s'%(_filename))         
 
225
        self.emit('capture-done', _filename)
 
226
 
 
227
        
 
228
 
 
229
gobject.type_register(ImageSinkBin)
 
230
gst.element_register(ImageSinkBin, 'image-sink')
 
231
    
 
232
 
 
233
if __name__ == '__main__':
 
234
    from luciole.media.lgst.videotest_src import VideoTestSrc
 
235
    from luciole.media.lgst.webcam_bin import WebcamBin
 
236
    
 
237
    def _timeout_cb(gbin) :
 
238
        gbin.capture()
 
239
        return True
 
240
 
 
241
    def _capture_done_cb(gbin, param1) :
 
242
        pass
 
243
 
 
244
        
 
245
    def make_sink_bin(filename) :
 
246
        _bin = gst.Bin()
 
247
        _rate = gst.element_factory_make('videorate')
 
248
        
 
249
        _filter = gst.element_factory_make('capsfilter')
 
250
        _caps = gst.Caps("video/x-raw-yuv, framerate=(fraction)1/1" )
 
251
        _filter.set_property("caps", _caps)
 
252
 
 
253
        _sink = gst.element_factory_make('fakesink')
 
254
        #_sink.set_property('location', filename)
 
255
        
 
256
        _bin.add(
 
257
            _rate,
 
258
            _filter,
 
259
            _sink,
 
260
            )
 
261
        
 
262
        gst.element_link_many(
 
263
            _rate,
 
264
            _filter,
 
265
            _sink
 
266
            )
 
267
 
 
268
        _sink_pad_bin = _rate
 
269
 
 
270
        # sink pak 
 
271
        _bin.add_pad(
 
272
                gst.GhostPad(
 
273
                    'sink', _sink_pad_bin.get_pad('sink')
 
274
                    )
 
275
                ) 
 
276
        return _bin
 
277
 
 
278
    
 
279
 
 
280
    pipeline = gst.Pipeline()
 
281
    
 
282
    #_src = VideoTestSrc()
 
283
    _src = WebcamBin()
 
284
    _totest = ImageSinkBin('./file.jpeg')
 
285
    #_totest = make_sink_bin('./file.jpeg')
 
286
    _totest.connect('capture-done', _capture_done_cb)
 
287
    
 
288
    
 
289
 
 
290
    pipeline.add(_src, _totest)
 
291
    _src.link(_totest)
 
292
    
 
293
    pipeline.set_state(gst.STATE_PLAYING)
 
294
    gobject.timeout_add_seconds(2, _timeout_cb, _totest) 
 
295
    gobject.MainLoop().run()