~jocave/checkbox/hybrid-amd-gpu-mods

« back to all changes in this revision

Viewing changes to providers/plainbox-provider-checkbox/bin/camera_test

  • Committer: Sylvain Pineau
  • Date: 2014-07-29 16:05:54 UTC
  • mto: This revision was merged to the branch mainline in revision 3149.
  • Revision ID: sylvain.pineau@canonical.com-20140729160554-qev8887xbunn9tmi
checkbox-ng:launchers:checkbox-cli: The checkbox-cli launcher

Running the default whitelist (with the suite selection screen skipped)

Show diffs side-by-side

added added

removed removed

Lines of Context:
26
26
# along with Checkbox.  If not, see <http://www.gnu.org/licenses/>.
27
27
#
28
28
 
29
 
import argparse
30
 
import ctypes
31
 
import errno
32
 
import fcntl
33
 
import imghdr
34
 
import logging
35
29
import os
36
30
import re
37
 
import struct
38
31
import sys
39
32
import time
40
 
 
 
33
import errno
 
34
import fcntl
 
35
import ctypes
 
36
import struct
 
37
import imghdr
 
38
from tempfile import NamedTemporaryFile
 
39
from subprocess import check_call, CalledProcessError, STDOUT
 
40
import argparse
 
41
from glob import glob
41
42
from gi.repository import GObject
42
 
from glob import glob
43
 
from subprocess import check_call, CalledProcessError, STDOUT
44
 
from tempfile import NamedTemporaryFile
45
43
 
46
44
 
47
45
_IOC_NRBITS = 8
164
162
    """
165
163
    A simple class that displays a test image via GStreamer.
166
164
    """
167
 
    def __init__(self, args):
 
165
    def __init__(self, args, gst_plugin=None, gst_video_type=None):
168
166
        self.args = args
 
167
        self._mainloop = GObject.MainLoop()
169
168
        self._width = 640
170
169
        self._height = 480
 
170
        self._gst_plugin = gst_plugin
 
171
        self._gst_video_type = gst_video_type
171
172
 
172
173
    def detect(self):
173
174
        """
188
189
            print("    driver : %s" % cp.driver.decode('UTF-8'))
189
190
            print("    version: %s.%s.%s"
190
191
                  % (cp.version >> 16,
191
 
                    (cp.version >> 8) & 0xff,
192
 
                     cp.version & 0xff))
 
192
                  (cp.version >> 8) & 0xff,
 
193
                  cp.version & 0xff))
193
194
            print("    flags  : 0x%x [" % cp.capabilities,
194
195
                  ' CAPTURE' if cp.capabilities & V4L2_CAP_VIDEO_CAPTURE
195
196
                  else '',
201
202
                  else '',
202
203
                  ' ]', sep="")
203
204
 
204
 
            resolutions = self._supported_resolutions_to_string(
205
 
                self._get_supported_resolutions(device))
206
 
            resolutions = resolutions.replace(
207
 
                "Resolutions:", "    Resolutions:")
208
 
            resolutions = resolutions.replace("Format:", "    Format:")
209
 
            print(resolutions)
 
205
            resolutions = self._get_supported_resolutions(device)
 
206
            print('    ',
 
207
                  self._supported_resolutions_to_string(resolutions).replace(
 
208
                  "\n", " "),
 
209
                  sep="")
210
210
 
211
211
            if cp.capabilities & V4L2_CAP_VIDEO_CAPTURE:
212
212
                cap_status = 0
213
213
        return dev_status | cap_status
214
214
 
215
 
    def _on_destroy(self, *args):
216
 
        Clutter.main_quit()
217
 
 
218
 
    def _take_photo(self, *args):
219
 
        Cheese.Camera.take_photo(self.camera, self.filename)
220
 
 
221
215
    def led(self):
222
216
        """
223
217
        Activate camera (switch on led), but don't display any output
224
218
        """
225
 
        Clutter.threads_add_timeout(0, 3000, self._on_destroy, None, None)
226
 
        video_texture = Clutter.Actor()
227
 
        try:
228
 
            camera = Cheese.Camera.new(
229
 
                video_texture, self.args.device, self._width, self._height)
230
 
        except TypeError: # libcheese < 3.18 still use Clutter.Texture
231
 
            video_texture = Clutter.Texture()
232
 
            camera = Cheese.Camera.new(
233
 
                video_texture, self.args.device, self._width, self._height)
234
 
        Cheese.Camera.setup(camera, None)
235
 
        Cheese.Camera.play(camera)
236
 
        Clutter.main()
 
219
        pipespec = ("v4l2src device=%(device)s "
 
220
                    "! %(type)s "
 
221
                    "! %(plugin)s "
 
222
                    "! testsink"
 
223
                    % {'device': self.args.device,
 
224
                       'type': self._gst_video_type,
 
225
                       'plugin': self._gst_plugin})
 
226
        self._pipeline = Gst.parse_launch(pipespec)
 
227
        self._pipeline.set_state(Gst.State.PLAYING)
 
228
        time.sleep(10)
 
229
        self._pipeline.set_state(Gst.State.NULL)
237
230
 
238
231
    def display(self):
239
232
        """
240
233
        Displays the preview window
241
234
        """
242
 
        stage = Clutter.Stage()
243
 
        stage.set_title('Camera test')
244
 
        stage.set_size(self._width, self._height)
245
 
        stage.connect('destroy', self._on_destroy)
246
 
        Clutter.threads_add_timeout(0, 10000, self._on_destroy, None, None)
247
 
        video_texture = Clutter.Actor()
248
 
        try:
249
 
            camera = Cheese.Camera.new(
250
 
                video_texture, self.args.device, self._width, self._height)
251
 
        except TypeError: # libcheese < 3.18 still use Clutter.Texture
252
 
            video_texture = Clutter.Texture()
253
 
            camera = Cheese.Camera.new(
254
 
                video_texture, self.args.device, self._width, self._height)
255
 
        stage.add_actor(video_texture)
256
 
        Cheese.Camera.setup(camera, None)
257
 
        Cheese.Camera.play(camera)
258
 
        stage.show()
259
 
        Clutter.main()
 
235
        pipespec = ("v4l2src device=%(device)s "
 
236
                    "! %(type)s,width=%(width)d,height=%(height)d "
 
237
                    "! %(plugin)s "
 
238
                    "! autovideosink"
 
239
                    % {'device': self.args.device,
 
240
                       'type': self._gst_video_type,
 
241
                       'width': self._width,
 
242
                       'height': self._height,
 
243
                       'plugin': self._gst_plugin})
 
244
        self._pipeline = Gst.parse_launch(pipespec)
 
245
        self._pipeline.set_state(Gst.State.PLAYING)
 
246
        time.sleep(10)
 
247
        self._pipeline.set_state(Gst.State.NULL)
260
248
 
261
249
    def still(self):
262
250
        """
280
268
                   "-d", self.args.device,
281
269
                   "-r", "%dx%d"
282
270
                   % (width, height), filename]
283
 
        use_cheese = False
 
271
        use_gstreamer = False
284
272
        if pixelformat:
285
 
            if 'MJPG' == pixelformat:  # special tweak for fswebcam
286
 
                pixelformat = 'MJPEG'
287
273
            command.extend(["-p", pixelformat])
288
274
 
289
275
        try:
290
276
            check_call(command, stdout=open(os.devnull, 'w'), stderr=STDOUT)
291
277
        except (CalledProcessError, OSError):
292
 
            use_cheese = True
 
278
            use_gstreamer = True
293
279
 
294
 
        if use_cheese:
295
 
            stage = Clutter.Stage()
296
 
            stage.connect('destroy', self._on_destroy)
297
 
            video_texture = Clutter.Actor()
298
 
            try:
299
 
                self.camera = Cheese.Camera.new(
300
 
                    video_texture, self.args.device, self._width, self._height)
301
 
            except TypeError: # libcheese < 3.18 still use Clutter.Texture
302
 
                video_texture = Clutter.Texture()
303
 
                self.camera = Cheese.Camera.new(
304
 
                    video_texture, self.args.device, self._width, self._height)
305
 
            Cheese.Camera.setup(self.camera, None)
306
 
            Cheese.Camera.play(self.camera)
307
 
            self.filename = filename
308
 
            Clutter.threads_add_timeout(0, 3000, self._take_photo , None, None)
309
 
            Clutter.threads_add_timeout(0, 4000, self._on_destroy, None, None)
310
 
            Clutter.main()
311
 
            Cheese.Camera.stop(self.camera)
 
280
        if use_gstreamer:
 
281
            pipespec = ("v4l2src device=%(device)s "
 
282
                        "! %(type)s,width=%(width)d,height=%(height)d "
 
283
                        "! %(plugin)s "
 
284
                        "! jpegenc "
 
285
                        "! filesink location=%(filename)s"
 
286
                        % {'device': self.args.device,
 
287
                           'type': self._gst_video_type,
 
288
                           'width': width,
 
289
                           'height': height,
 
290
                           'plugin': self._gst_plugin,
 
291
                           'filename': filename})
 
292
            self._pipeline = Gst.parse_launch(pipespec)
 
293
            self._pipeline.set_state(Gst.State.PLAYING)
 
294
            time.sleep(3)
 
295
            self._pipeline.set_state(Gst.State.NULL)
312
296
 
313
297
        if not quiet:
314
 
            stage = Clutter.Stage()
315
 
            stage.set_title('Camera still picture test')
316
 
            stage.set_size(width, height)
317
 
            stage.connect('destroy', self._on_destroy)
318
 
            Clutter.threads_add_timeout(0, 10000, self._on_destroy, None, None)
319
 
            still_texture = Clutter.Texture.new_from_file(filename)
320
 
            stage.add_actor(still_texture)
321
 
            stage.show()
322
 
            Clutter.main()
 
298
            try:
 
299
                check_call(["timeout", "-k", "11", "10", "eog", filename])
 
300
            except CalledProcessError:
 
301
                pass
323
302
 
324
303
    def _supported_resolutions_to_string(self, supported_resolutions):
325
304
        """
446
425
                        # for continuous and stepwise, let's just use min and
447
426
                        # max they use the same structure and only return
448
427
                        # one result
449
 
                        elif (framesize.type in (V4L2_FRMSIZE_TYPE_CONTINUOUS,
450
 
                              V4L2_FRMSIZE_TYPE_STEPWISE)):
 
428
                        elif framesize.type == V4L2_FRMSIZE_TYPE_CONTINUOUS or\
 
429
                            framesize.type == V4L2_FRMSIZE_TYPE_STEPWISE:
451
430
                            resolutions.append([framesize.stepwise.min_width,
452
431
                                                framesize.stepwise.min_height]
453
432
                                               )
515
494
                                       title='test',
516
495
                                       description='Available camera tests')
517
496
 
518
 
    parser.add_argument('--debug', dest='log_level',
519
 
                        action="store_const", const=logging.DEBUG,
520
 
                        default=logging.INFO, help="Show debugging messages")
521
 
 
522
497
    def add_device_parameter(parser):
523
498
        group = parser.add_mutually_exclusive_group()
524
499
        group.add_argument("-d", "--device", default="/dev/video0",
529
504
        group.add_argument("--lowest-device", action="store_true",
530
505
                           help=("Use the /dev/videoN "
531
506
                                 "where N is the lowest value available"))
 
507
 
532
508
    subparsers.add_parser('detect')
533
509
    led_parser = subparsers.add_parser('led')
534
510
    add_device_parameter(led_parser)
564
540
    if not args.test:
565
541
        args.test = 'detect'
566
542
 
567
 
    logging.basicConfig(level=args.log_level)
568
 
 
569
543
    # Import Gst only for the test cases that will need it
570
544
    if args.test in ['display', 'still', 'led', 'resolutions']:
571
 
        import contextlib
572
 
        # Workaround to avoid "cluttervideosink missing"
573
 
        # See https://bugzilla.gnome.org/show_bug.cgi?id=721277
574
 
        with contextlib.suppress(FileNotFoundError):
575
 
            gst_registry = '~/.cache/gstreamer-1.0/registry.x86_64.bin'
576
 
            os.remove(os.path.expanduser(gst_registry))
577
 
        import gi
578
 
        gi.require_version('Gst', '1.0')
579
545
        from gi.repository import Gst
580
 
        gi.require_version('Cheese', '3.0')
581
 
        from gi.repository import Cheese
582
 
        gi.require_version('Clutter', '1.0')
583
 
        from gi.repository import Clutter
 
546
        if Gst.version()[0] > 0:
 
547
            gst_plugin = 'videoconvert'
 
548
            gst_video_type = 'video/x-raw'
 
549
        else:
 
550
            gst_plugin = 'ffmpegcolorspace'
 
551
            gst_video_type = 'video/x-raw-yuv'
584
552
        Gst.init(None)
585
 
        Clutter.init()
586
 
    camera = CameraTest(args)
 
553
        camera = CameraTest(args, gst_plugin, gst_video_type)
 
554
    else:
 
555
        camera = CameraTest(args)
 
556
 
587
557
    sys.exit(getattr(camera, args.test)())