def get_available_video_source_configs(): ''' Returns ------- (pandas.DataFrame) : Available video source configuration with highest width and framerate. .. versionchanged:: 0.3.5 Skip devices with no allowed capabilities. ''' with nostderr(): from .video_source import (get_video_source_names, expand_allowed_capabilities, get_allowed_capabilities) device_names = get_video_source_names() frames = [] for device_name_i in device_names: df_allowed_caps = get_allowed_capabilities(device_name_i) if df_allowed_caps.shape[0] < 1: continue df_source_caps = expand_allowed_capabilities(df_allowed_caps) df_source_caps.insert(0, 'device_name', device_name_i) frames.append(df_source_caps) return pd.concat(frames)
def pipeline_command_from_json(json_source, colorspace='bgr'): ''' Args ---- json_source (dict) : A dictionary containing at least the keys `device_name`, `width`, `height`, `framerate_num`, and `framerate_denom`. colorspace (str) : Supported values are `bgr` or `rgb`. Returns ------- (str) : A pipeline command string compatible with `gst-launch` terminated with an `appsink` element. ''' # Import here, since importing `gst` before calling `parse_args` causes # command-line help to be overridden by GStreamer help. with nostderr(): from .video_source import VIDEO_SOURCE_PLUGIN, DEVICE_KEY caps_str = (u'video/x-raw-rgb,width={width:d},height={height:d},' u'framerate={framerate_num:d}/{framerate_denom:d}' .format(**json_source)) # Set `(red|green|blue)_mask` to ensure RGB channel order for both YUY2 and # I420 video sources. If this is not done, red and blue channels might be # swapped. # # See [here][1] for default mask values. # # [1]: https://www.freedesktop.org/software/gstreamer-sdk/data/docs/latest/gst-plugins-bad-plugins-0.10/gst-plugins-bad-plugins-videoparse.html#GstVideoParse--blue-mask if colorspace == 'bgr': caps_str += (u',red_mask=(int)255,green_mask=(int)65280,' u'blue_mask=(int)16711680') device_str = u'{} {}="{}"'.format(VIDEO_SOURCE_PLUGIN, DEVICE_KEY, json_source['device_name']) logger.debug('[View] video config device string: %s', device_str) logger.debug('[View] video config caps string: %s', caps_str) video_command = ''.join([device_str, ' ! ffmpegcolorspace ! ', caps_str, ' ! appsink name=app-video emit-signals=true']) return video_command
def on_video_config_menu__activate(self, widget): with nostderr(): from pygst_utils.video_view.mode import video_mode_dialog from pygst_utils.video_source import get_source_capabilities gtk.gdk.threads_init() df_video_configs = (get_source_capabilities() .sort_values(['device_name', 'width', 'framerate'], ascending=[True, True, True])) df_video_configs = df_video_configs.loc[df_video_configs.width >= 320] try: config = video_mode_dialog(df_video_configs=df_video_configs, title='Select barcode scanner video ' 'config') except RuntimeError: # User cancelled dialog. Do nothing. pass else: self.set_video_config(config)
def default_video_source(): ''' Returns ------- (pandas.Series) : Available video source configuration with highest width and framerate. ''' with nostderr(): from .video_source import (get_video_source_names, expand_allowed_capabilities, get_allowed_capabilities) device_names = get_video_source_names() device_name = device_names[0] df_allowed_caps = get_allowed_capabilities(device_name) df_source_caps = expand_allowed_capabilities(df_allowed_caps) df_source_caps.sort_values(['width', 'framerate'], ascending=False, inplace=True) df_source_caps.insert(0, 'device_name', device_name) return df_source_caps.iloc[0]
def schema_dialog(schema, data=None, device_name=None, max_width=None, max_fps=None, **kwargs): ''' Parameters ---------- schema : dict jsonschema definition. Each property *must* have a default value. device_name : False or None or str or list_like, optional GStreamer video source device name(s). If `None` (default), first available video device is used. If `False`, video is disabled. max_width : int Maximum video frame width. max_fps : float Maximum video frame rate (frames/second). Returns ------- dict json-encodable dictionary containing validated values for properties included in the specified schema. Raises ------ KeyError If no video configuration is found that matches the specified parameters. ValueError If values to not validate. ''' # TODO Remove pygst code (or at least gracefully handle case where it is # not available). if not device_name and device_name is not None: dialog = SchemaDialog(schema, **kwargs) else: with nostderr(): import pygst_utils as pu gtk.threads_init() df_modes = pu.get_available_video_source_configs() query = (df_modes.width == df_modes.width) if device_name is not None: if isinstance(device_name, types.StringTypes): query &= (df_modes.device_name == device_name) else: query &= (df_modes.device_name.isin(device_name)) if max_width is not None: query &= (df_modes.width <= max_width) if max_fps is not None: query &= (df_modes.framerate <= max_fps) df_modes = df_modes.loc[query] if not df_modes.shape[0]: raise KeyError('No compatible video mode found.') config = df_modes.sort_values(['width', 'framerate'], ascending=False).iloc[0] pipeline_command = pu.pipeline_command_from_json(config, colorspace='rgb') dialog = MetaDataDialog(schema, pipeline_command, **kwargs) with nostderr(): valid, results = dialog.run(values=data) if not valid: raise ValueError('Invalid values.') return results
from pygtkhelpers.utils import gsignal from pygtkhelpers.delegates import SlaveView import gtk import pandas as pd from redirect_io import nostderr with nostderr(): from ..video_source import get_source_capabilities, DeviceNotFound class VideoModeSelector(SlaveView): gsignal('video-config-selected', object) def __init__(self, configs=None): if configs is None: try: self.configs = get_source_capabilities() except DeviceNotFound: self.configs = pd.DataFrame(None) else: self.configs = configs super(VideoModeSelector, self).__init__() def create_ui(self): self.config_store = gtk.ListStore(int, object, str) self.set_configs(self.configs) self.config_combo = gtk.ComboBox(model=self.config_store) renderer_text = gtk.CellRendererText() self.config_combo.pack_start(renderer_text, True) self.config_combo.add_attribute(renderer_text, "text", 2)