Beispiel #1
0
    def paint_with_video_decoder(self, decoder_module, coding, img_data, x, y, width, height, options, callbacks):
        #log("paint_with_video_decoder%s", (decoder_module, coding, "%s bytes" % len(img_data), x, y, width, height, options, callbacks))
        assert decoder_module, "decoder module not found for %s" % coding
        try:
            self._decoder_lock.acquire()
            if self._backing is None:
                log("window %s is already gone!", self.wid)
                fire_paint_callbacks(callbacks, False)
                return  False
            enc_width, enc_height = options.intpair("scaled_size", (width, height))
            input_colorspace = options.strget("csc")
            if not input_colorspace:
                # Backwards compatibility with pre 0.10.x clients
                # We used to specify the colorspace as an avutil PixelFormat constant
                old_csc_fmt = options.intget("csc_pixel_format")
                input_colorspace = get_colorspace_from_avutil_enum(old_csc_fmt)
                if input_colorspace is None:
                    #completely broken and out of date servers (ie: v0.3.x):
                    log("csc was not specified and we cannot find a colorspace from csc_pixel_format=%s, assuming it is an old server and using YUV420P", old_csc_fmt)
                    input_colorspace = "YUV420P"

            #do we need a prep step for decoders that cannot handle the input_colorspace directly?
            decoder_colorspaces = decoder_module.get_input_colorspaces(coding)
            assert input_colorspace in decoder_colorspaces, "decoder does not support %s for %s" % (input_colorspace, coding)

            if self._video_decoder:
                if self._video_decoder.get_encoding()!=coding:
                    log("paint_with_video_decoder: encoding changed from %s to %s", self._video_decoder.get_encoding(), coding)
                    self.do_clean_video_decoder()
                elif self._video_decoder.get_width()!=enc_width or self._video_decoder.get_height()!=enc_height:
                    log("paint_with_video_decoder: window dimensions have changed from %s to %s", (self._video_decoder.get_width(), self._video_decoder.get_height()), (enc_width, enc_height))
                    self.do_clean_video_decoder()
                elif self._video_decoder.get_colorspace()!=input_colorspace:
                    log("paint_with_video_decoder: colorspace changed from %s to %s", self._video_decoder.get_colorspace(), input_colorspace)
                    self.do_clean_video_decoder()
                elif options.get("frame")==0:
                    log("paint_with_video_decoder: first frame of new stream")
                    self.do_clean_video_decoder()
            if self._video_decoder is None:
                log("paint_with_video_decoder: new %s(%s,%s,%s)", decoder_module.Decoder, width, height, input_colorspace)
                self._video_decoder = decoder_module.Decoder()
                self._video_decoder.init_context(coding, enc_width, enc_height, input_colorspace)
                log("paint_with_video_decoder: info=%s", self._video_decoder.get_info())

            img = self._video_decoder.decompress_image(img_data, options)
            if not img:
                fire_paint_callbacks(callbacks, False)
                log.error("paint_with_video_decoder: wid=%s, %s decompression error on %s bytes of picture data for %sx%s pixels using %s, options=%s",
                      self.wid, coding, len(img_data), width, height, self._video_decoder, options)
                return False
            self.do_video_paint(img, x, y, enc_width, enc_height, width, height, options, callbacks)
        finally:
            self._decoder_lock.release()
            if self._backing is None:
                self.close_decoder(True)
        return  False
Beispiel #2
0
    def paint_with_video_decoder(self, decoder_module, coding, img_data, x, y, width, height, options, callbacks):
        #log("paint_with_video_decoder%s", (decoder_module, coding, "%s bytes" % len(img_data), x, y, width, height, options, callbacks))
        assert decoder_module, "decoder module not found for %s" % coding
        try:
            self._decoder_lock.acquire()
            if self._backing is None:
                log("window %s is already gone!", self.wid)
                fire_paint_callbacks(callbacks, False)
                return  False
            enc_width, enc_height = options.intpair("scaled_size", (width, height))
            input_colorspace = options.strget("csc")
            if not input_colorspace:
                # Backwards compatibility with pre 0.10.x clients
                # We used to specify the colorspace as an avutil PixelFormat constant
                old_csc_fmt = options.intget("csc_pixel_format")
                input_colorspace = get_colorspace_from_avutil_enum(old_csc_fmt)
                if input_colorspace is None:
                    #completely broken and out of date servers (ie: v0.3.x):
                    log("csc was not specified and we cannot find a colorspace from csc_pixel_format=%s, assuming it is an old server and using YUV420P", old_csc_fmt)
                    input_colorspace = "YUV420P"

            #do we need a prep step for decoders that cannot handle the input_colorspace directly?
            decoder_colorspaces = decoder_module.get_input_colorspaces(coding)
            assert input_colorspace in decoder_colorspaces, "decoder does not support %s for %s" % (input_colorspace, coding)

            if self._video_decoder:
                if self._video_decoder.get_encoding()!=coding:
                    log("paint_with_video_decoder: encoding changed from %s to %s", self._video_decoder.get_encoding(), coding)
                    self.do_clean_video_decoder()
                elif self._video_decoder.get_width()!=enc_width or self._video_decoder.get_height()!=enc_height:
                    log("paint_with_video_decoder: window dimensions have changed from %s to %s", (self._video_decoder.get_width(), self._video_decoder.get_height()), (enc_width, enc_height))
                    self.do_clean_video_decoder()
                elif self._video_decoder.get_colorspace()!=input_colorspace:
                    log("paint_with_video_decoder: colorspace changed from %s to %s", self._video_decoder.get_colorspace(), input_colorspace)
                    self.do_clean_video_decoder()
                elif options.get("frame")==0:
                    log("paint_with_video_decoder: first frame of new stream")
                    self.do_clean_video_decoder()
            if self._video_decoder is None:
                log("paint_with_video_decoder: new %s(%s,%s,%s)", decoder_module.Decoder, width, height, input_colorspace)
                self._video_decoder = decoder_module.Decoder()
                self._video_decoder.init_context(coding, enc_width, enc_height, input_colorspace)
                log("paint_with_video_decoder: info=%s", self._video_decoder.get_info())

            img = self._video_decoder.decompress_image(img_data, options)
            if not img:
                raise Exception("paint_with_video_decoder: wid=%s, %s decompression error on %s bytes of picture data for %sx%s pixels using %s, options=%s" % (
                      self.wid, coding, len(img_data), width, height, self._video_decoder, options))
            self.do_video_paint(img, x, y, enc_width, enc_height, width, height, options, callbacks)
        finally:
            self._decoder_lock.release()
            if self._backing is None:
                self.close_decoder(True)
        return  False
    def paint_with_video_decoder(self, decoder_module, coding, img_data, x, y,
                                 width, height, options, callbacks):
        assert x == 0 and y == 0
        assert hasattr(
            decoder_module, "Decoder"
        ), "decoder module %s does not have 'Decoder' factory function!" % decoder_module
        assert hasattr(
            decoder_module, "get_colorspaces"
        ), "decoder module %s does not have 'get_colorspaces' function!" % decoder_module
        factory = getattr(decoder_module, "Decoder")
        get_colorspaces = getattr(decoder_module, "get_colorspaces")
        try:
            self._decoder_lock.acquire()
            if self._backing is None:
                log("window %s is already gone!", self.wid)
                fire_paint_callbacks(callbacks, False)
                return False
            enc_width, enc_height = options.get("scaled_size", (width, height))
            input_colorspace = options.get("csc")
            if not input_colorspace:
                # Backwards compatibility with pre 0.10.x clients
                # We used to specify the colorspace as an avutil PixelFormat constant
                old_csc_fmt = options.get("csc_pixel_format")
                input_colorspace = get_colorspace_from_avutil_enum(old_csc_fmt)
                assert input_colorspace is not None, "csc was not specified and we cannot find a colorspace from csc_pixel_format=%s" % old_csc_fmt

            #do we need a prep step for decoders that cannot handle the input_colorspace directly?
            decoder_colorspaces = get_colorspaces()
            decoder_colorspace = input_colorspace
            #if input_colorspace not in decoder_colorspaces:
            if input_colorspace not in decoder_colorspaces:
                log("colorspace not supported by %s directly", decoder_module)
                assert input_colorspace in (
                    "BGRA", "BGRX"
                ), "colorspace %s cannot be handled directly or via a csc preparation step!" % input_colorspace
                decoder_colorspace = "YUV444P"
                if self._csc_prep:
                    if self._csc_prep.get_src_format() != input_colorspace:
                        #this should not happen!
                        log.warn("input colorspace has changed from %s to %s",
                                 self._csc_prep.get_src_format(),
                                 input_colorspace)
                        self.do_clean_csc_prep()
                    elif self._csc_prep.get_dst_format(
                    ) not in decoder_colorspaces:
                        #this should not happen!
                        log.warn("csc prep colorspace %s is now invalid!?",
                                 self._csc_prep.get_dst_format())
                        self.do_clean_csc_prep()
                    elif self._csc_prep.get_src_width(
                    ) != enc_width or self._csc_prep.get_src_height(
                    ) != enc_height:
                        log("csc prep dimensions have changed from %s to %s",
                            (self._csc_prep.get_src_width(),
                             self._csc_prep.get_src_height()),
                            (enc_width, enc_height))
                        self.do_clean_csc_prep()
                if self._csc_prep is None:
                    from xpra.codecs.csc_swscale.colorspace_converter import ColorspaceConverter  #@UnresolvedImport
                    self._csc_prep = ColorspaceConverter()
                    csc_speed = 0  #always best quality
                    self._csc_prep.init_context(enc_width, enc_height,
                                                input_colorspace, width,
                                                height, decoder_colorspace,
                                                csc_speed)
                    log("csc preparation step: %s", self._csc_prep)
            elif self._csc_prep:
                #no longer needed?
                self.do_clean_csc_prep()

            if self._video_decoder:
                if self._video_decoder.get_type() != coding:
                    if DRAW_DEBUG:
                        log.info(
                            "paint_with_video_decoder: encoding changed from %s to %s",
                            self._video_decoder.get_type(), coding)
                    self.do_clean_video_decoder()
                elif self._video_decoder.get_width(
                ) != enc_width or self._video_decoder.get_height(
                ) != enc_height:
                    if DRAW_DEBUG:
                        log.info(
                            "paint_with_video_decoder: window dimensions have changed from %s to %s",
                            (self._video_decoder.get_width(),
                             self._video_decoder.get_height()),
                            (enc_width, enc_height))
                    self.do_clean_video_decoder()
                elif self._video_decoder.get_colorspace(
                ) != decoder_colorspace:
                    if DRAW_DEBUG:
                        log.info(
                            "paint_with_video_decoder: colorspace changed from %s to %s",
                            self._video_decoder.get_colorspace(),
                            decoder_colorspace)
                    self.do_clean_video_decoder()
                elif options.get("frame") == 0:
                    if DRAW_DEBUG:
                        log.info(
                            "paint_with_video_decoder: first frame of new stream"
                        )
                    self.do_clean_video_decoder()
            if self._video_decoder is None:
                if DRAW_DEBUG:
                    log.info("paint_with_video_decoder: new %s(%s,%s,%s)",
                             factory, width, height, decoder_colorspace)
                self._video_decoder = factory()
                self._video_decoder.init_context(enc_width, enc_height,
                                                 decoder_colorspace)
                if DRAW_DEBUG:
                    log.info("paint_with_video_decoder: info=%s",
                             self._video_decoder.get_info())

            img = self._video_decoder.decompress_image(img_data, options)
            if not img:
                raise Exception(
                    "paint_with_video_decoder: wid=%s, %s decompression error on %s bytes of picture data for %sx%s pixels, options=%s"
                    %
                    (self.wid, coding, len(img_data), width, height, options))
            self.do_video_paint(img, x, y, enc_width, enc_height, width,
                                height, options, callbacks)
        finally:
            self._decoder_lock.release()
            if self._backing is None:
                self.close_decoder(True)
        return False
Beispiel #4
0
    def paint_with_video_decoder(self, decoder_name, coding, img_data, x, y, width, height, options, callbacks):
        assert x==0 and y==0
        decoder_module = get_codec(decoder_name)
        assert decoder_module, "decoder module not found for %s" % decoder_name
        assert hasattr(decoder_module, "Decoder"), "decoder module %s does not have 'Decoder' factory function!" % decoder_module
        assert hasattr(decoder_module, "get_colorspaces"), "decoder module %s does not have 'get_colorspaces' function!" % decoder_module
        factory = getattr(decoder_module, "Decoder")
        get_colorspaces = getattr(decoder_module, "get_colorspaces")
        try:
            self._decoder_lock.acquire()
            if self._backing is None:
                log("window %s is already gone!", self.wid)
                fire_paint_callbacks(callbacks, False)
                return  False
            enc_width, enc_height = options.get("scaled_size", (width, height))
            input_colorspace = options.get("csc")
            if not input_colorspace:
                # Backwards compatibility with pre 0.10.x clients
                # We used to specify the colorspace as an avutil PixelFormat constant
                old_csc_fmt = options.get("csc_pixel_format")
                input_colorspace = get_colorspace_from_avutil_enum(old_csc_fmt)
                if input_colorspace is None:
                    #completely broken and out of date clients (ie: v0.3.x):
                    log.debug("csc was not specified and we cannot find a colorspace from csc_pixel_format=%s, assuming it is an old client and using YUV420P", old_csc_fmt)
                    input_colorspace = "YUV420P"

            #do we need a prep step for decoders that cannot handle the input_colorspace directly?
            decoder_colorspaces = get_colorspaces()
            decoder_colorspace = input_colorspace
            if input_colorspace not in decoder_colorspaces:
                log("colorspace not supported by %s directly", decoder_module)
                assert input_colorspace in ("BGRA", "BGRX"), "colorspace %s cannot be handled directly or via a csc preparation step!" % input_colorspace
                decoder_colorspace = "YUV444P"
                if self._csc_prep:
                    if self._csc_prep.get_src_format()!=input_colorspace:
                        #this should not happen!
                        log.warn("input colorspace has changed from %s to %s", self._csc_prep.get_src_format(), input_colorspace)
                        self.do_clean_csc_prep()
                    elif self._csc_prep.get_dst_format() not in decoder_colorspaces:
                        #this should not happen!
                        log.warn("csc prep colorspace %s is now invalid!?", self._csc_prep.get_dst_format())
                        self.do_clean_csc_prep()
                    elif self._csc_prep.get_src_width()!=enc_width or self._csc_prep.get_src_height()!=enc_height:
                        log("csc prep dimensions have changed from %s to %s", (self._csc_prep.get_src_width(), self._csc_prep.get_src_height()), (enc_width, enc_height))
                        self.do_clean_csc_prep()
                if self._csc_prep is None:
                    csc_speed = 0   #always best quality
                    self._csc_prep = self.make_csc(enc_width, enc_height, input_colorspace,
                                           width, height, [decoder_colorspace], csc_speed)
                    log("csc preparation step: %s", self._csc_prep)
            elif self._csc_prep:
                #no longer needed?
                self.do_clean_csc_prep()

            if self._video_decoder:
                if self._video_decoder.get_encoding()!=coding:
                    if DRAW_DEBUG:
                        log.info("paint_with_video_decoder: encoding changed from %s to %s", self._video_decoder.get_encoding(), coding)
                    self.do_clean_video_decoder()
                elif self._video_decoder.get_width()!=enc_width or self._video_decoder.get_height()!=enc_height:
                    if DRAW_DEBUG:
                        log.info("paint_with_video_decoder: window dimensions have changed from %s to %s", (self._video_decoder.get_width(), self._video_decoder.get_height()), (enc_width, enc_height))
                    self.do_clean_video_decoder()
                elif self._video_decoder.get_colorspace()!=decoder_colorspace:
                    if DRAW_DEBUG:
                        log.info("paint_with_video_decoder: colorspace changed from %s to %s", self._video_decoder.get_colorspace(), decoder_colorspace)
                    self.do_clean_video_decoder()
                elif options.get("frame")==0:
                    if DRAW_DEBUG:
                        log.info("paint_with_video_decoder: first frame of new stream")
                    self.do_clean_video_decoder()
            if self._video_decoder is None:
                if DRAW_DEBUG:
                    log.info("paint_with_video_decoder: new %s(%s,%s,%s)", factory, width, height, decoder_colorspace)
                self._video_decoder = factory()
                self._video_decoder.init_context(coding, enc_width, enc_height, decoder_colorspace)
                if DRAW_DEBUG:
                    log.info("paint_with_video_decoder: info=%s", self._video_decoder.get_info())

            img = self._video_decoder.decompress_image(img_data, options)
            if not img:
                raise Exception("paint_with_video_decoder: wid=%s, %s decompression error on %s bytes of picture data for %sx%s pixels using %s, options=%s" % (
                      self.wid, coding, len(img_data), width, height, self._video_decoder, options))
            self.do_video_paint(img, x, y, enc_width, enc_height, width, height, options, callbacks)
        finally:
            self._decoder_lock.release()
            if self._backing is None:
                self.close_decoder(True)
        return  False