Example #1
0
    def to_string_array(cls, actual_arg):
        """ Return GValue holding instance of type GStrv created from actual_arg """
        # Fail: GStrv is not a GType, only a C typedef.
        # Fail: GObject.TYPE_BOXED, cannot initialize GValue with type 'GBoxed', this type has no GTypeValueTable implementation
        # Fail: GLib.VariantType
        # G_TYPE_STRV
        # Setter is not a GIMP method, but a method of GObject.Value
        # See GObject>Structures>Value
        # Fail: self.to_gimp_array(GObject.TYPE_STRV, GObject.Value.set_boxed )
        # Fail: gvalue = FuGenericValueArray.to_gimp_array(actual_arg, GObject.TYPE_STRV, GObject.Value.set_variant )

        cls.logger.info(f"to_string_array")
        # require a sequence
        try:
            a_list = FuGenericValueArray.sequence_for_actual_arg(actual_arg)
        except Exception as err:
            proceed(
                f"Exception in sequence_for_actual_arg: _actual_arg: {actual_arg}, {err}"
            )

        # Create GObject.Value
        '''
        gvalue = GObject.Value(GObject.TYPE_STRV, a_list)
        '''
        '''
        try:
            # create empty (i.e. no value) GValue of desired type,
            gvalue = GObject.Value (GObject.TYPE_STRV)
        except Exception as err:
            proceed(f"Fail to create GObject.Value for array, err is: {err}.")

        # GObject.GStrv is not a class?
        # Code lifted from PyGObject/tests/test_properties.property
        # GStrv inherits Python list type
        class GStrv(list):
            __gtype__ = GObject.TYPE_STRV

        # Create instance from instance of Python list type
        gstrv = GStrv(a_list)

        # put instance in the gvalue.
        gvalue.set_boxed(gstrv)
        '''
        gvalue = GObject.Value(GObject.TYPE_STRV)
        gvalue.set_boxed(a_list)

        assert GObject.type_check_value_holds(gvalue, GObject.TYPE_STRV)

        return gvalue
Example #2
0
    def _eventLoop(self,
                   block=True,
                   doProgress=False,
                   targetState=Gst.State.PLAYING):
        '''
		This is the main loop that processes information on the bus and decides
		how the pipeline should react. Sometimes this entails spitting out
		messages, others it involves changing state or some other manipulation.
		'''
        buffering = False
        inProgress = False
        prerolled = targetState != Gst.State.PAUSED

        pName = self._pipeline.get_name()
        bus = self._pipeline.get_bus()

        while not self._stopper.isSet():
            # TODO: if we actually want to stop the pipeline asyncronously we
            # need to post a message on the bus that tells it to stop. Otherwise
            # it will wait here forever (or will be terminated as a daemon
            # thread by its parent)
            msg = bus.timed_pop(1e18 if block else 0)

            if not msg:
                return

            msgSrc = msg.src
            msgSrcName = msgSrc.get_name()

            msgType = msg.type
            msgTypeName = Gst.MessageType.get_name(msgType)

            # messages that involve manipulating the pipeline
            if msgType == Gst.MessageType.REQUEST_STATE:
                state = msg.parse_request_state()

                logger.info('Setting state to %s as requested by %s',
                            state.value_name, msgSrcName)

                self._pipeline.set_state(state)

            elif msgType == Gst.MessageType.CLOCK_LOST:
                logger.debug('Clock lost. Getting new one.')
                self._pipeline.set_state(Gst.State.PAUSED)
                self._pipeline.set_state(Gst.State.PLAYING)

            elif msgType == Gst.MessageType.LATENCY:
                _gstPrintMsg(pName, 'Redistributing latency', sName=msgSrcName)
                self._pipeline.recalculate_latency()

            # messages that do not require pipeline manipulation
            elif msgType == Gst.MessageType.BUFFERING:
                _gstPrintMsg(pName,
                             'Buffering: {}',
                             msg.parse_buffering(),
                             sName=msgSrcName)

            elif msgType == Gst.MessageType.NEW_CLOCK:
                clock = msg.parse_new_clock()
                clock = clock.get_name() if clock else 'NULL'
                _gstPrintMsg(pName, 'New clock: {}', clock)

            elif msgType == Gst.MessageType.INFO:
                error, debug = msg.parse_info()

                if debug:
                    _gstPrintMsg(pName,
                                 debug,
                                 level=logging.INFO,
                                 sName=msgSrcName)

            elif msgType == Gst.MessageType.WARNING:
                error, debug = msg.parse_warning()

                if debug:
                    _gstPrintMsg(pName,
                                 '{} - Additional debug info: {}',
                                 error.message,
                                 debug,
                                 level=logging.WARNING,
                                 sName=msgSrcName)
                else:
                    _gstPrintMsg(pName,
                                 error.message,
                                 level=logging.WARNING,
                                 sName=msgSrcName)

            elif msgType == Gst.MessageType.ERROR:
                _processErrorMessage(pName, msgSrcName, msg)

            elif msgType == Gst.MessageType.STATE_CHANGED:
                # we only care about pipeline level state changes
                if msgSrc == self._pipeline:
                    old, new, pending = msg.parse_state_changed()

                    # we only care if we reach the final target state
                    if targetState == Gst.State.PAUSED and new == Gst.State.PAUSED:
                        prerolled = True

                        if buffering:
                            _gstPrintMsg(
                                pName,
                                'Prerolled, waiting for buffering to finish',
                                level=logging.INFO)
                            continue

                        if inProgress:
                            _gstPrintMsg(
                                pName,
                                'Prerolled, waiting for progress to finish',
                                level=logging.INFO)
                            continue

                        return

            elif msgType == Gst.MessageType.PROGRESS:
                progressType, code, text = msg.parse_progress()

                if (progressType == Gst.ProgressType.START
                        or progressType == Gst.ProgressType.CONTINUE):
                    if doProgress:
                        inProgress = True
                        block = True
                elif (progressType == Gst.ProgressType.COMPLETE
                      or progressType == Gst.ProgressType.CANCELLED
                      or progressType == Gst.ProgressType.ERROR):
                    inProgress = False

                _gstPrintMsg(pName,
                             'Progress: ({}) {}',
                             code,
                             text,
                             sName=msgSrcName)

                if doProgress and not inProgress and not buffering and prerolled:
                    return

            elif msgType == Gst.MessageType.HAVE_CONTEXT:
                context = msg.parse_have_context()
                _gstPrintMsg(pName,
                             'Got context: {}={}',
                             context.get_context_type(),
                             context.get_structure().to_string(),
                             sName=msgSrcName)

            elif msgType == Gst.MessageType.PROPERTY_NOTIFY:
                obj, propName, val = msg.parse_property_notify()

                valStr = '(no value)'

                if val:
                    if GObject.type_check_value_holds(val,
                                                      GObject.TYPE_STRING):
                        valStr = val.dup_string()

                    elif val.g_type.is_a(Gst.Caps.__gtype__):
                        valStr = val.get_boxed().to_string()

                    else:
                        valStr = Gst.value_serialize(val)

                _gstPrintMsg(pName,
                             '{}: {} = {}',
                             obj.get_name(),
                             propName,
                             valStr,
                             sName=msgSrcName)

            # these are things I might not need...
            elif msgType == Gst.MessageType.STREAM_START:
                if msgSrc == self._pipeline:
                    _gstPrintMsg(pName, 'Started stream', level=logging.INFO)

            elif msgType == Gst.MessageType.QOS:
                frmt, processed, dropped = msg.parse_qos_stats()
                jitter, proportion, quality = msg.parse_qos_values()

                _gstPrintMsg(pName,
                             'QOS stats: jitter={} dropped={}',
                             jitter,
                             '-' if frmt == Gst.Format.UNDEFINED else dropped,
                             sName=msgSrcName)

            elif msgType == Gst.MessageType.ELEMENT:
                _gstPrintMsg(pName,
                             'Unknown message ELEMENT',
                             sName=msgSrcName)

            elif msgType == Gst.MessageType.UNKNOWN:
                _gstPrintMsg(pName, 'Unknown message', sName=msgSrcName)