xpra icon
Bug tracker and wiki

Ticket #2839: csc_cython-GBRP10_to_r210.patch

File csc_cython-GBRP10_to_r210.patch, 7.0 KB (added by Antoine Martin, 2 months ago)

adds GBRP10_to_r210 to csc_cython

  • xpra/codecs/csc_cython/colorspace_converter.pyx

     
    7171               "YUV420P"    : get_CS("YUV420P", ["RGB", "BGR", "RGBX", "BGRX"]),
    7272               "GBRP"       : get_CS("GBRP",    ["RGBX", "BGRX"]),
    7373               "r210"       : get_CS("r210",    ["YUV420P", "BGR48"]),
     74               "GBRP10"     : get_CS("GBRP10",  ["r210"]),
    7475               }
    7576
    7677
     
    106107    can_scale = True
    107108    if in_colorspace=="r210" and out_colorspace=="BGR48":
    108109        can_scale = False
     110    elif in_colorspace=="GBRP10" and out_colorspace=="r210":
     111        can_scale = False
    109112    return csc_spec(in_colorspace, out_colorspace,
    110113                    ColorspaceConverter, codec_type=get_type(),
    111114                    quality=50, speed=10, setup_cost=10, min_w=2, min_h=2, max_w=16*1024, max_h=16*1024, can_scale=can_scale)
     
    193196cdef inline void r210_to_BGR48_copy(unsigned short *bgr48, const unsigned int *r210,
    194197                                    unsigned int w, unsigned int h,
    195198                                    unsigned int src_stride, unsigned int dst_stride) nogil:
     199    assert (dst_stride%2)==0
    196200    cdef unsigned int y = 0
    197201    cdef unsigned int i = 0
    198202    cdef unsigned int v
     
    203207            bgr48[i] = v&0x000003ff
    204208            bgr48[i+1] = (v&0x000ffc00) >> 10
    205209            bgr48[i+2] = (v&0x3ff00000) >> 20
    206             i = i + 3
     210            i += 3
    207211        r210 = <unsigned int*> ((<uintptr_t> r210) + src_stride)
    208212
    209213
     
    279283            self.convert_image_function = self.r210_to_BGR48
    280284            assert src_width==dst_width
    281285            assert src_height==dst_height
     286        elif src_format=="GBRP10" and dst_format=="r210":
     287            self.dst_strides[0] = roundup(self.dst_width*4, STRIDE_ROUNDUP)
     288            self.dst_sizes[0] = self.dst_strides[0] * self.dst_height
     289            self.buffer_size = self.dst_sizes[0]+self.dst_strides[0]
     290            self.convert_image_function = self.GBRP10_to_r210
     291            assert src_width==dst_width
     292            assert src_height==dst_height
    282293        elif src_format=="YUV420P" and dst_format in ("RGBX", "BGRX", "RGB", "BGR"):
    283294            #3 or 4 bytes per pixel:
    284295            self.dst_strides[0] = roundup(self.dst_width*len(dst_format), STRIDE_ROUNDUP)
     
    425436        pixels = image.get_pixels()
    426437        assert pixels, "failed to get pixels from %s" % image
    427438        input_stride = image.get_rowstride()
    428         log("do_RGB_to_YUV420P(%s, %i, %i, %i, %i) input=%s, strides=%s" % (image, Bpp, Rindex, Gindex, Bindex, len(pixels), input_stride))
     439        log("do_RGB_to_YUV420P(%s, %i, %i, %i, %i) input=%s, strides=%s", image, Bpp, Rindex, Gindex, Bindex, len(pixels), input_stride)
    429440
    430441        assert object_as_buffer(pixels, <const void**> &input_image, &pic_buf_len)==0
    431442        #allocate output buffer:
     
    542553        pixels = image.get_pixels()
    543554        assert pixels, "failed to get pixels from %s" % image
    544555        input_stride = image.get_rowstride()
    545         log("r210_to_BGR48(%s) input=%s, strides=%s" % (image, len(pixels), input_stride))
     556        log("r210_to_BGR48(%s) input=%s, strides=%s", image, len(pixels), input_stride)
    546557
    547558        cdef Py_ssize_t pic_buf_len = 0
    548559        cdef const unsigned int *r210
     
    564575
    565576        bgr48_buffer = memory_as_pybuffer(<void *> bgr48, self.dst_sizes[0], True)
    566577        cdef double elapsed = time.time()-start
    567         log("%s took %.1fms", self, 1000.0*elapsed)
     578        log("r210_to_BGR48 took %.1fms", 1000.0*elapsed)
    568579        self.time += elapsed
    569580        self.frames += 1
    570581        out_image = CythonImageWrapper(0, 0, self.dst_width, self.dst_height, bgr48_buffer, "BGR48", 48, dst_stride, ImageWrapper.PACKED)
     
    572583        return out_image
    573584
    574585
     586    def GBRP10_to_r210(self, image):
     587        cdef double start = time.time()
     588        assert image.get_planes()==ImageWrapper.PLANAR_3, "invalid input format: %s planes" % image.get_planes()
     589        assert image.get_width()>=self.src_width, "invalid image width: %s (minimum is %s)" % (image.get_width(), self.src_width)
     590        assert image.get_height()>=self.src_height, "invalid image height: %s (minimum is %s)" % (image.get_height(), self.src_height)
     591        pixels = image.get_pixels()
     592        assert pixels, "failed to get pixels from %s" % image
     593
     594        input_strides = image.get_rowstride()
     595        cdef unsigned int w = self.src_width
     596        cdef unsigned int h = self.src_height
     597        cdef unsigned int src_stride = input_strides[0]
     598        cdef unsigned int dst_stride = self.dst_strides[0]
     599        assert input_strides[1]==src_stride and input_strides[2]==src_stride, "mismatch in rowstrides: %s" % (input_strides,)
     600        assert src_stride>=w*2
     601        assert dst_stride>=w*4
     602        assert self.dst_sizes[0]>=dst_stride*h
     603        log.warn("GBRP10_to_r210(%s) input=%s, strides=%s", image, tuple(len(p) for p in pixels), src_stride)
     604
     605        cdef Py_ssize_t pic_buf_len[3]
     606        cdef const unsigned short *gbrp10[3]
     607        cdef unsigned int i
     608        for i in range(3):
     609            assert object_as_buffer(pixels[i], <const void**> &gbrp10[i], &pic_buf_len[i])==0
     610            assert pic_buf_len[i]>=src_stride*h, "input plane '%s' is too small: %i bytes" % ("GBR"[i], pic_buf_len[i])
     611
     612        #allocate output buffer:
     613        cdef unsigned int *r210 = <unsigned int*> memalign(self.dst_sizes[0])
     614
     615        #if image.is_thread_safe():
     616        #    with nogil:
     617        #        r210_to_BGR48_copy(bgr48, r210, w, h, src_stride, dst_stride)
     618        #else:
     619        #    r210_to_BGR48_copy(bgr48, r210, w, h, src_stride, dst_stride)
     620        cdef unsigned int x, y
     621        cdef unsigned short *b
     622        cdef unsigned short *g
     623        cdef unsigned short *r
     624        cdef unsigned int *dst
     625        for y in range(h):
     626            dst = <unsigned int*> ((<uintptr_t> r210) + y*dst_stride)
     627            if y>=h//2:
     628                for x in range(w):
     629                    dst[x] = 0
     630                continue
     631            b = <unsigned short*> (<uintptr_t> gbrp10[0]) + y*src_stride
     632            g = <unsigned short*> (<uintptr_t> gbrp10[1]) + y*src_stride
     633            r = <unsigned short*> (<uintptr_t> gbrp10[2]) + y*src_stride
     634            for x in range(w):
     635                dst[x] = (b[x] & 0x3ff) + ((g[x] & 0x3ff)<<10) + ((r[x] & 0x3ff)<<20)
     636        r210_buffer = memory_as_pybuffer(<void *> r210, self.dst_sizes[0], True)
     637        cdef double elapsed = time.time()-start
     638        log("GBRP10_to_r210 took %.1fms", 1000.0*elapsed)
     639        self.time += elapsed
     640        self.frames += 1
     641        out_image = CythonImageWrapper(0, 0, self.dst_width, self.dst_height, r210_buffer, "r210", 30, dst_stride, ImageWrapper.PACKED)
     642        out_image.cython_buffer = <uintptr_t> r210
     643        return out_image
     644
     645
    575646    def YUV420P_to_RGBX(self, image):
    576647        return self.do_YUV420P_to_RGB(image, 4, RGBX_R, RGBX_G, RGBX_B, RGBX_X)
    577648