Example #1
0
    def test_AtomicInteger_threading(self):
        a = AtomicInteger()
        N = 5000

        def increase():
            for _ in range(N):
                a.increase()

        def decrease():
            for _ in range(N):
                a.decrease()

        T = 20
        from threading import Thread
        threads = []
        for i in range(T):
            if i % 2 == 0:
                target = increase
            else:
                target = decrease
            t = Thread(target=target, name=str(target))
            t.daemon = True
            threads.append(t)
        for t in threads:
            t.start()
        for t in threads:
            t.join()
Example #2
0
 def __init__(self):
     StubClientMixin.__init__(self)
     #rpc / dbus:
     self.rpc_counter = AtomicInteger()
     self.rpc_pending_requests = {}
     self.server_dbus_proxy = False
     self.server_rpc_types = []
     self.rpc_filter_timers = {}
Example #3
0
 def __init__(self, uid, gid, env_options, session_options, socket_dir,
              video_encoder_modules, csc_modules, client_conn, disp_desc,
              client_state, cipher, encryption_key, server_conn, caps,
              message_queue):
     Process.__init__(self, name=str(client_conn))
     self.uid = uid
     self.gid = gid
     self.env_options = env_options
     self.session_options = session_options
     self.socket_dir = socket_dir
     self.video_encoder_modules = video_encoder_modules
     self.csc_modules = csc_modules
     self.client_conn = client_conn
     self.disp_desc = disp_desc
     self.client_state = client_state
     self.cipher = cipher
     self.encryption_key = encryption_key
     self.server_conn = server_conn
     self.caps = caps
     log("ProxyProcess%s",
         (uid, gid, env_options, session_options, socket_dir,
          video_encoder_modules, csc_modules, client_conn, disp_desc,
          repr_ellipsized(str(client_state)), cipher, encryption_key,
          server_conn, "%s: %s.." %
          (type(caps), repr_ellipsized(str(caps))), message_queue))
     self.client_protocol = None
     self.server_protocol = None
     self.exit = False
     self.main_queue = None
     self.message_queue = message_queue
     self.encode_queue = None  #holds draw packets to encode
     self.encode_thread = None
     self.video_encoding_defs = None
     self.video_encoders = None
     self.video_encoders_last_used_time = None
     self.video_encoder_types = None
     self.video_helper = None
     self.lost_windows = None
     #for handling the local unix domain socket:
     self.control_socket_cleanup = None
     self.control_socket = None
     self.control_socket_thread = None
     self.control_socket_path = None
     self.potential_protocols = []
     self.max_connections = MAX_CONCURRENT_CONNECTIONS
     self.timer_id = AtomicInteger()
     self.timers = {}
     self.timer_lock = RLock()
Example #4
0
    return dbus_to_native(*args)


def ni(*args):
    return int(n(*args))


def nb(*args):
    return bool(n(*args))


def ns(*args):
    return str(n(*args))


sequence = AtomicInteger()


class DBUS_Source(dbus.service.Object):
    SUPPORTS_MULTIPLE_OBJECT_PATHS = True

    def __init__(self, source=None, extra=""):
        self.source = source
        session_bus = init_session_bus()
        name = BUS_NAME
        self.path = PATH + str(sequence.increase())
        if extra:
            name += extra.replace(".", "_").replace(":", "_")
        bus_name = dbus.service.BusName(name, session_bus)
        dbus.service.Object.__init__(self, bus_name, self.path)
        self.log("(%s)", source)
Example #5
0
from xpra.server.source.clientinfo_mixin import ClientInfoMixin
from xpra.server.source.dbus_mixin import DBUS_Mixin
from xpra.server.source.windows_mixin import WindowsMixin
from xpra.server.source.encodings_mixin import EncodingsMixin
from xpra.server.source.idle_mixin import IdleMixin
from xpra.server.source.input_mixin import InputMixin
from xpra.server.source.avsync_mixin import AVSyncMixin
from xpra.server.source.clientdisplay_mixin import ClientDisplayMixin
from xpra.server.source.webcam_mixin import WebcamMixin
from xpra.os_util import monotonic_time
from xpra.util import merge_dicts, flatten_dict, notypedict, envbool, envint, AtomicInteger

BANDWIDTH_DETECTION = envbool("XPRA_BANDWIDTH_DETECTION", True)
MIN_BANDWIDTH = envint("XPRA_MIN_BANDWIDTH", 5 * 1024 * 1024)

counter = AtomicInteger()
"""
This class mediates between the server class (which only knows about actual window objects and display server events)
and the client specific WindowSource instances (which only know about window ids
and manage window pixel compression).
It sends messages to the client via its 'protocol' instance (the network connection),
directly for a number of cases (cursor, sound, notifications, etc)
or on behalf of the window sources for pixel data.

Strategy: if we have 'ordinary_packets' to send, send those.
When we don't, then send packets from the 'packet_queue'. (compressed pixels or clipboard data)
See 'next_packet'.

The UI thread calls damage(), which goes into WindowSource and eventually (batching may be involved)
adds the damage pixels ready for processing to the encode_work_queue,
items are picked off by the separate 'encode' thread (see 'encode_loop')
Example #6
0
def test_gl_client_window(gl_client_window_class,
                          max_window_size=(1024, 1024),
                          pixel_depth=24,
                          show=False):
    #try to render using a temporary window:
    draw_result = {}
    window = None
    try:
        x, y = -100, -100
        if show:
            x, y = 100, 100
        w, h = 250, 250
        from xpra.codecs.loader import load_codec
        load_codec("dec_pillow")
        from xpra.client.window_border import WindowBorder
        border = WindowBorder()
        default_cursor_data = None
        noclient = FakeClient()
        #test with alpha, but not on win32
        #because we can't do alpha on win32 with opengl
        metadata = typedict({b"has-alpha": not WIN32})

        class NoHeaderGLClientWindow(gl_client_window_class):
            def add_header_bar(self):
                pass

            def schedule_recheck_focus(self):
                pass

        window = NoHeaderGLClientWindow(noclient, None, None, 2**32 - 1, x, y,
                                        w, h, w, h, metadata, False,
                                        typedict({}), border, max_window_size,
                                        default_cursor_data, pixel_depth)
        window_backing = window._backing
        window_backing.idle_add = no_idle_add
        window_backing.timeout_add = no_timeout_add
        window_backing.source_remove = no_source_remove
        window.realize()
        window_backing.paint_screen = True
        pixel_format = "BGRX"
        bpp = len(pixel_format)
        options = typedict({"pixel_format": pixel_format})
        stride = bpp * w
        coding = "rgb32"
        widget = window_backing._backing
        widget.realize()

        def paint_callback(success, message=""):
            log("paint_callback(%s, %s)", success, message)
            draw_result["success"] = success
            if message:
                draw_result["message"] = message.replace("\n", " ")

        log("OpenGL: testing draw on %s widget %s with %s : %s", window,
            widget, coding, pixel_format)
        pix = AtomicInteger(0x7f)
        REPAINT_DELAY = envint("XPRA_REPAINT_DELAY", int(show) * 16)
        gl_icon = get_icon_filename("opengl", ext="png")
        icon_data = None
        if os.path.exists(gl_icon):
            from PIL import Image
            img = Image.open(gl_icon)
            img.load()
            icon_w, icon_h = img.size
            icon_stride = icon_w * 4
            noalpha = Image.new("RGB", img.size, (255, 255, 255))
            noalpha.paste(img, mask=img.split()[3])  # 3 is the alpha channel
            buf = BytesIO()
            noalpha.save(buf, format="JPEG")
            icon_data = buf.getvalue()
            buf.close()
            icon_format = "jpeg"
        if not icon_data:
            icon_w = 32
            icon_h = 32
            icon_stride = icon_w * 4
            icon_data = bytes([0]) * icon_stride * icon_h
            icon_format = "rgb32"

        def draw():
            v = pix.increase()
            img_data = bytes([v % 256] * stride * h)
            options["flush"] = 1
            window.draw_region(0, 0, w, h, coding, img_data, stride, v,
                               options, [paint_callback])
            options["flush"] = 0
            mx = w // 2 - icon_w // 2
            my = h // 2 - icon_h // 2
            x = iround(mx * (1 + sin(v / 100)))
            y = iround(my * (1 + cos(v / 100)))
            window.draw_region(x, y, icon_w, icon_h, icon_format, icon_data,
                               icon_stride, v, options, [paint_callback])
            return REPAINT_DELAY > 0

        #the paint code is actually synchronous here,
        #so we can check the present_fbo() result:
        if show:
            widget.show()
            window.show()
            from gi.repository import Gtk, GLib

            def window_close_event(*_args):
                Gtk.main_quit()

            noclient.window_close_event = window_close_event
            GLib.timeout_add(REPAINT_DELAY, draw)
            Gtk.main()
        else:
            draw()
        if window_backing.last_present_fbo_error:
            return {
                "success":
                False,
                "message":
                "failed to present FBO on screen: %s" %
                window_backing.last_present_fbo_error
            }
    finally:
        if window:
            window.destroy()
    log("test_gl_client_window(..) draw_result=%s", draw_result)
    return draw_result
Example #7
0
 def __init__(self):
     self.main_queue = Queue()
     self.exit = False
     self.timer_id = AtomicInteger()
     self.timers = {}
     self.timer_lock = RLock()
Example #8
0
def test_gl_client_window(gl_client_window_class, max_window_size=(1024, 1024), pixel_depth=24, show=False):
    #try to render using a temporary window:
    draw_result = {}
    window = None
    try:
        x, y = -100, -100
        if show:
            x, y = 100, 100
        w, h = 250, 250
        from xpra.client.window_border import WindowBorder
        border = WindowBorder()
        default_cursor_data = None
        noclient = FakeClient()
        #test with alpha, but not on win32
        #because we can't do alpha on win32 with opengl
        metadata = typedict({b"has-alpha" : not WIN32})
        window = gl_client_window_class(noclient, None, None, 2**32-1, x, y, w, h, w, h,
                                        metadata, False, typedict({}),
                                        border, max_window_size, default_cursor_data, pixel_depth)
        window_backing = window._backing
        window_backing.idle_add = no_idle_add
        window_backing.timeout_add = no_timeout_add
        window_backing.source_remove = no_source_remove
        window.realize()
        window_backing.paint_screen = True
        pixel_format = "BGRX"
        bpp = len(pixel_format)
        options = typedict({"pixel_format" : pixel_format})
        stride = bpp*w
        coding = "rgb32"
        widget = window_backing._backing
        widget.realize()
        def paint_callback(success, message):
            log("paint_callback(%s, %s)", success, message)
            draw_result.update({
                "success"   : success,
                "message"   : message,
                })
        log("OpenGL: testing draw on %s widget %s with %s : %s", window, widget, coding, pixel_format)
        pix = AtomicInteger(0x7f)
        REPAINT_DELAY = envint("XPRA_REPAINT_DELAY", 0)
        def draw():
            if PYTHON3:
                img_data = bytes([pix.increase() % 256]*stride*h)
            else:
                img_data = chr(pix.increase() % 256)*stride*h
            window.draw_region(0, 0, w, h, coding, img_data, stride, 1, options, [paint_callback])
            return REPAINT_DELAY>0
        #the paint code is actually synchronous here,
        #so we can check the present_fbo() result:
        if show:
            widget.show()
            window.show()
            from xpra.gtk_common.gobject_compat import import_gtk, import_glib
            gtk = import_gtk()
            glib = import_glib()
            def window_close_event(*_args):
                gtk.main_quit()
            noclient.window_close_event = window_close_event
            glib.timeout_add(REPAINT_DELAY, draw)
            gtk.main()
        else:
            draw()
        if window_backing.last_present_fbo_error:
            return {
                "success" : False,
                "message" : "failed to present FBO on screen: %s" % window_backing.last_present_fbo_error
                }
    finally:
        if window:
            window.destroy()
    log("test_gl_client_window(..) draw_result=%s", draw_result)
    return draw_result
Example #9
0
class SoundPipeline(GObject.GObject):

    generation = AtomicInteger()

    __generic_signals__ = {
        "state-changed": one_arg_signal,
        "error": one_arg_signal,
        "new-stream": one_arg_signal,
        "info": one_arg_signal,
    }

    def __init__(self, codec):
        GObject.GObject.__init__(self)
        self.stream_compressor = None
        self.codec = codec
        self.codec_description = ""
        self.codec_mode = ""
        self.container_format = ""
        self.container_description = ""
        self.bus = None
        self.bus_message_handler_id = None
        self.bitrate = -1
        self.pipeline = None
        self.pipeline_str = ""
        self.start_time = 0
        self.state = "stopped"
        self.buffer_count = 0
        self.byte_count = 0
        self.emit_info_timer = None
        self.info = {
            "codec": self.codec,
            "state": self.state,
        }
        self.idle_add = GLib.idle_add
        self.timeout_add = GLib.timeout_add
        self.source_remove = GLib.source_remove
        self.file = None

    def init_file(self, codec):
        gen = self.generation.increase()
        log("init_file(%s) generation=%s, SAVE_AUDIO=%s", codec, gen,
            SAVE_AUDIO)
        if SAVE_AUDIO is not None:
            parts = codec.split("+")
            if len(parts) > 1:
                filename = SAVE_AUDIO + str(
                    gen) + "-" + parts[0] + ".%s" % parts[1]
            else:
                filename = SAVE_AUDIO + str(gen) + ".%s" % codec
            self.file = open(filename, 'wb')
            log.info("saving %s stream to %s", codec, filename)

    def save_to_file(self, *buffers):
        f = self.file
        if f and buffers:
            for x in buffers:
                self.file.write(x)
            self.file.flush()

    def idle_emit(self, sig, *args):
        self.idle_add(self.emit, sig, *args)

    def emit_info(self):
        if self.emit_info_timer:
            return

        def do_emit_info():
            self.emit_info_timer = None
            if self.pipeline:
                info = self.get_info()
                #reset info:
                self.info = {}
                self.emit("info", info)

        self.emit_info_timer = self.timeout_add(200, do_emit_info)

    def cancel_emit_info_timer(self):
        eit = self.emit_info_timer
        if eit:
            self.emit_info_timer = None
            self.source_remove(eit)

    def get_info(self) -> dict:
        info = self.info.copy()
        if inject_fault():
            info["INJECTING_NONE_FAULT"] = None
            log.warn("injecting None fault: get_info()=%s", info)
        return info

    def setup_pipeline_and_bus(self, elements):
        gstlog("pipeline elements=%s", elements)
        self.pipeline_str = " ! ".join([x for x in elements if x is not None])
        gstlog("pipeline=%s", self.pipeline_str)
        self.start_time = monotonic_time()
        try:
            self.pipeline = gst.parse_launch(self.pipeline_str)
        except Exception as e:
            self.pipeline = None
            gstlog.error("Error setting up the sound pipeline:")
            gstlog.error(" %s", e)
            gstlog.error(" GStreamer pipeline for %s:", self.codec)
            for i, x in enumerate(elements):
                gstlog.error("  %s%s", x,
                             ["", " ! \\"][int(i < (len(elements) - 1))])
            self.cleanup()
            return False
        self.bus = self.pipeline.get_bus()
        self.bus_message_handler_id = self.bus.connect("message",
                                                       self.on_message)
        self.bus.add_signal_watch()
        self.info["pipeline"] = self.pipeline_str
        return True

    def do_get_state(self, state):
        if not self.pipeline:
            return "stopped"
        return {
            gst.State.PLAYING: "active",
            gst.State.PAUSED: "paused",
            gst.State.NULL: "stopped",
            gst.State.READY: "ready"
        }.get(state, "unknown")

    def get_state(self):
        return self.state

    def update_bitrate(self, new_bitrate):
        if new_bitrate == self.bitrate:
            return
        self.bitrate = new_bitrate
        log("new bitrate: %s", self.bitrate)
        self.info["bitrate"] = new_bitrate

    def update_state(self, state):
        log("update_state(%s)", state)
        self.state = state
        self.info["state"] = state

    def inc_buffer_count(self, inc=1):
        self.buffer_count += inc
        self.info["buffer_count"] = self.buffer_count

    def inc_byte_count(self, count):
        self.byte_count += count
        self.info["bytes"] = self.byte_count

    def set_volume(self, volume=100):
        if self.volume:
            self.volume.set_property("volume", volume / 100.0)
            self.info["volume"] = volume

    def get_volume(self):
        if self.volume:
            return int(self.volume.get_property("volume") * 100)
        return GST_FLOW_OK

    def start(self):
        if not self.pipeline:
            log.error("cannot start")
            return
        register_SIGUSR_signals(self.idle_add)
        log("SoundPipeline.start() codec=%s", self.codec)
        self.idle_emit("new-stream", self.codec)
        self.update_state("active")
        self.pipeline.set_state(gst.State.PLAYING)
        if self.stream_compressor:
            self.info["stream-compressor"] = self.stream_compressor
        self.emit_info()
        #we may never get the stream start, synthesize codec event so we get logging:
        parts = self.codec.split("+")
        self.timeout_add(1000, self.new_codec_description, parts[0])
        if len(parts) > 1 and parts[1] != self.stream_compressor:
            self.timeout_add(1000, self.new_container_description, parts[1])
        elif self.container_format:
            self.timeout_add(1000, self.new_container_description,
                             self.container_format)
        if self.stream_compressor:

            def logsc():
                self.gstloginfo("using stream compression %s",
                                self.stream_compressor)

            self.timeout_add(1000, logsc)
        log("SoundPipeline.start() done")

    def stop(self):
        p = self.pipeline
        self.pipeline = None
        if not p:
            return
        log("SoundPipeline.stop() state=%s", self.state)
        #uncomment this to see why we end up calling stop()
        #import traceback
        #for x in traceback.format_stack():
        #    for s in x.split("\n"):
        #        v = s.replace("\r", "").replace("\n", "")
        #        if v:
        #            log(v)
        if self.state not in ("starting", "stopped", "ready", None):
            log.info("stopping")
        self.update_state("stopped")
        p.set_state(gst.State.NULL)
        log("SoundPipeline.stop() done")

    def cleanup(self):
        log("SoundPipeline.cleanup()")
        self.cancel_emit_info_timer()
        self.stop()
        b = self.bus
        self.bus = None
        log("SoundPipeline.cleanup() bus=%s", b)
        if not b:
            return
        b.remove_signal_watch()
        bmhid = self.bus_message_handler_id
        log("SoundPipeline.cleanup() bus_message_handler_id=%s", bmhid)
        if bmhid:
            self.bus_message_handler_id = None
            b.disconnect(bmhid)
        self.pipeline = None
        self.codec = None
        self.bitrate = -1
        self.state = None
        self.volume = None
        self.info = {}
        f = self.file
        if f:
            self.file = None
            noerr(f.close)
        log("SoundPipeline.cleanup() done")

    def gstloginfo(self, msg, *args):
        if self.state != "stopped":
            gstlog.info(msg, *args)
        else:
            gstlog(msg, *args)

    def gstlogwarn(self, msg, *args):
        if self.state != "stopped":
            gstlog.warn(msg, *args)
        else:
            gstlog(msg, *args)

    def new_codec_description(self, desc):
        log("new_codec_description(%s) current codec description=%s", desc,
            self.codec_description)
        if not desc:
            return
        dl = desc.lower()
        if dl == "wav" and self.codec_description:
            return
        cdl = self.codec_description.lower()
        if not cdl or (cdl != dl and dl.find(cdl) < 0 and cdl.find(dl) < 0):
            self.gstloginfo("using '%s' audio codec", dl)
        self.codec_description = dl
        self.info["codec_description"] = dl

    def new_container_description(self, desc):
        log("new_container_description(%s) current container description=%s",
            desc, self.container_description)
        if not desc:
            return
        cdl = self.container_description.lower()
        dl = {
            "mka": "matroska",
            "mpeg4": "iso fmp4",
        }.get(desc.lower(), desc.lower())
        if not cdl or (cdl != dl and dl.find(cdl) < 0 and cdl.find(dl) < 0):
            self.gstloginfo("using '%s' container format", dl)
        self.container_description = dl
        self.info["container_description"] = dl

    def on_message(self, _bus, message):
        #log("on_message(%s, %s)", bus, message)
        gstlog("on_message: %s", message)
        t = message.type
        if t == gst.MessageType.EOS:
            self.pipeline.set_state(gst.State.NULL)
            self.gstloginfo("EOS")
            self.update_state("stopped")
            self.idle_emit("state-changed", self.state)
        elif t == gst.MessageType.ERROR:
            self.pipeline.set_state(gst.State.NULL)
            err, details = message.parse_error()
            gstlog.error("Gstreamer pipeline error: %s", err.message)
            for l in err.args:
                if l != err.message:
                    gstlog(" %s", l)
            try:
                #prettify (especially on win32):
                p = details.find("\\Source\\")
                if p > 0:
                    details = details[p + len("\\Source\\"):]
                for d in details.split(": "):
                    for dl in d.splitlines():
                        if dl.strip():
                            gstlog.error(" %s", dl.strip())
            except Exception:
                gstlog.error(" %s", details)
            self.update_state("error")
            self.idle_emit("error", str(err))
            #exit
            self.cleanup()
        elif t == gst.MessageType.TAG:
            try:
                self.parse_message(message)
            except Exception as e:
                self.gstlogwarn("Warning: failed to parse gstreamer message:")
                self.gstlogwarn(" %s: %s", type(e), e)
        elif t == gst.MessageType.ELEMENT:
            try:
                self.parse_element_message(message)
            except Exception as e:
                self.gstlogwarn(
                    "Warning: failed to parse gstreamer element message:")
                self.gstlogwarn(" %s: %s", type(e), e)
        elif t == gst.MessageType.STREAM_STATUS:
            gstlog("stream status: %s", message)
        elif t == gst.MessageType.STREAM_START:
            log("stream start: %s", message)
            #with gstreamer 1.x, we don't always get the "audio-codec" message..
            #so print the codec from here instead (and assume gstreamer is using what we told it to)
            #after a delay, just in case we do get the real "audio-codec" message!
            self.timeout_add(500, self.new_codec_description,
                             self.codec.split("+")[0])
        elif t in (gst.MessageType.ASYNC_DONE, gst.MessageType.NEW_CLOCK):
            gstlog("%s", message)
        elif t == gst.MessageType.STATE_CHANGED:
            _, new_state, _ = message.parse_state_changed()
            gstlog("state-changed on %s: %s", message.src,
                   gst.Element.state_get_name(new_state))
            state = self.do_get_state(new_state)
            if isinstance(message.src, gst.Pipeline):
                self.update_state(state)
                self.idle_emit("state-changed", state)
        elif t == gst.MessageType.DURATION_CHANGED:
            gstlog("duration changed: %s", message)
        elif t == gst.MessageType.LATENCY:
            gstlog("latency message from %s: %s", message.src, message)
        elif t == gst.MessageType.INFO:
            self.gstloginfo("pipeline message: %s", message)
        elif t == gst.MessageType.WARNING:
            w = message.parse_warning()
            self.gstlogwarn("pipeline warning: %s", w[0].message)
            for x in w[1:]:
                for l in x.split(":"):
                    if l:
                        if l.startswith("\n"):
                            l = l.strip("\n") + " "
                            for lp in l.split(". "):
                                lp = lp.strip()
                                if lp:
                                    self.gstlogwarn(" %s", lp)
                        else:
                            self.gstlogwarn("                  %s",
                                            l.strip("\n\r"))
        else:
            self.gstlogwarn("unhandled bus message type %s: %s", t, message)
        self.emit_info()
        return GST_FLOW_OK

    def parse_element_message(self, message):
        structure = message.get_structure()
        props = {
            "seqnum": int(message.seqnum),
        }
        for i in range(structure.n_fields()):
            name = structure.nth_field_name(i)
            props[name] = structure.get_value(name)
        self.do_parse_element_message(message, message.src.get_name(), props)

    def do_parse_element_message(self, message, name, props=None):
        gstlog("do_parse_element_message%s", (message, name, props))

    def parse_message(self, message):
        #message parsing code for GStreamer 1.x
        taglist = message.parse_tag()
        tags = [taglist.nth_tag_name(x) for x in range(taglist.n_tags())]
        gstlog("bus message with tags=%s", tags)
        if not tags:
            #ignore it
            return
        if "bitrate" in tags:
            new_bitrate = taglist.get_uint("bitrate")
            if new_bitrate[0] is True:
                self.update_bitrate(new_bitrate[1])
                gstlog("bitrate: %s", new_bitrate[1])
        if "codec" in tags:
            desc = taglist.get_string("codec")
            if desc[0] is True:
                self.new_codec_description(desc[1])
        if "audio-codec" in tags:
            desc = taglist.get_string("audio-codec")
            if desc[0] is True:
                self.new_codec_description(desc[1])
                gstlog("audio-codec: %s", desc[1])
        if "mode" in tags:
            mode = taglist.get_string("mode")
            if mode[0] is True and self.codec_mode != mode[1]:
                gstlog("mode: %s", mode[1])
                self.codec_mode = mode[1]
                self.info["codec_mode"] = self.codec_mode
        if "container-format" in tags:
            cf = taglist.get_string("container-format")
            if cf[0] is True:
                self.new_container_description(cf[1])
        for x in ("encoder", "description", "language-code"):
            if x in tags:
                desc = taglist.get_string(x)
                gstlog("%s: %s", x, desc[1])
        if not set(tags).intersection(KNOWN_TAGS):
            structure = message.get_structure()
            self.gstloginfo("unknown sound pipeline tag message: %s, tags=%s",
                            structure.to_string(), tags)
Example #10
0
log = Logger("sound")
gstlog = Logger("gstreamer")

APPSINK = os.environ.get(
    "XPRA_SOURCE_APPSINK",
    "appsink name=sink emit-signals=true max-buffers=10 drop=true sync=false async=false qos=false"
)
JITTER = envint("XPRA_SOUND_SOURCE_JITTER", 0)
SOURCE_QUEUE_TIME = get_queue_time(50, "SOURCE_")

BUFFER_TIME = envint("XPRA_SOUND_SOURCE_BUFFER_TIME", 0)  #ie: 64
LATENCY_TIME = envint("XPRA_SOUND_SOURCE_LATENCY_TIME", 0)  #ie: 32
BUNDLE_METADATA = envbool("XPRA_SOUND_BUNDLE_METADATA", True)
SAVE_TO_FILE = os.environ.get("XPRA_SAVE_TO_FILE")

generation = AtomicInteger()


class SoundSource(SoundPipeline):

    __gsignals__ = SoundPipeline.__generic_signals__.copy()
    __gsignals__.update({
        "new-buffer": n_arg_signal(3),
    })

    def __init__(self,
                 src_type=None,
                 src_options={},
                 codecs=get_encoders(),
                 codec_options={},
                 volume=1.0):