xpra icon
Bug tracker and wiki

This bug tracker and wiki are being discontinued
please use https://github.com/Xpra-org/xpra instead.


Ticket #1462: x264-10bit.patch

File x264-10bit.patch, 14.8 KB (added by Antoine Martin, 12 months ago)

work in progress

  • ../rpmbuild/x264-xpra.spec

     
    5151    --prefix="%{_prefix}" \
    5252    --libdir="%{_libdir}/xpra" \
    5353    --includedir="%{_includedir}/xpra" \
     54    --bit-depth=all \
    5455    --enable-shared \
    5556    --enable-static
    5657
  • ../src/xpra/client/gl/gl_window_backing_base.py

     
    122122    "YUV420P" : GL_UNSIGNED_BYTE,
    123123    "YUV422P" : GL_UNSIGNED_BYTE,
    124124    "YUV444P" : GL_UNSIGNED_BYTE,
     125    "YUV422P10" : GL_UNSIGNED_SHORT,
    125126    }
    126127CONSTANT_TO_PIXEL_FORMAT = {
    127128    GL_BGR   : "BGR",
     
    299300        if self.bit_depth>32:
    300301            self.internal_format = GL_RGBA16
    301302            self.RGB_MODES.append("r210")
     303            self.RGB_MODES.append("YUV422P10")
    302304        elif self.bit_depth==30:
    303305            self.internal_format = GL_RGB10_A2
    304306            self.RGB_MODES.append("r210")
     307            self.RGB_MODES.append("YUV422P10")
    305308        elif self.bit_depth==16:
    306309            if self._alpha_enabled:
    307310                if envbool("XPRA_GL_RGBA4", True):
     
    11191122        x, y = self.gravity_adjust(x, y, options)
    11201123        try:
    11211124            pixel_format = img.get_pixel_format()
    1122             assert pixel_format in ("YUV420P", "YUV422P", "YUV444P", "GBRP", ), \
     1125            assert pixel_format in ("YUV420P", "YUV422P", "YUV444P", "GBRP", "YUV422P10"), \
    11231126                "sorry the GL backing does not handle pixel format '%s' yet!" % (pixel_format)
    11241127
    11251128            context = self.gl_context()
     
    11841187        self.gl_marker("updating planar textures: %sx%s %s", width, height, pixel_format)
    11851188        rowstrides = img.get_rowstride()
    11861189        img_data = img.get_pixels()
    1187         BPP = 1
     1190        BPP = 2 if pixel_format.endswith("P10") else 1
    11881191        assert len(rowstrides)==3 and len(img_data)==3
    11891192        for texture, index, tex_name in (
    11901193            (GL_TEXTURE0, TEX_Y, "Y"*BPP),
  • ../src/xpra/codecs/argb/argb.pyx

     
    100100cdef r210data_to_rgba(unsigned int* r210,
    101101                      const unsigned int w, const unsigned int h,
    102102                      const unsigned int src_stride, const unsigned int dst_stride):
     103    log.info("r210data_to_rgba")
    103104    cdef MemBuf output_buf = getbuf(h*dst_stride)
    104105    cdef unsigned char* rgba = <unsigned char*> output_buf.get_mem()
    105106    cdef unsigned int y = 0
     
    135136cdef r210data_to_rgbx(unsigned int* r210,
    136137                      const unsigned int w, const unsigned int h,
    137138                      const unsigned int src_stride, const unsigned int dst_stride):
     139    log.info("r210data_to_rgbx")
    138140    cdef MemBuf output_buf = getbuf(h*dst_stride)
    139141    cdef unsigned char* rgba = <unsigned char*> output_buf.get_mem()
    140142    cdef unsigned int y = 0
     
    175177cdef r210data_to_rgb(unsigned int* r210,
    176178                     const unsigned int w, const unsigned int h,
    177179                     const unsigned int src_stride, const unsigned int dst_stride):
     180    log.info("r210data_to_rgb")
    178181    cdef MemBuf output_buf = getbuf(h*dst_stride)
    179182    cdef unsigned char* rgba = <unsigned char*> output_buf.get_mem()
    180183    cdef unsigned int y = 0
     
    192195    return memoryview(output_buf)
    193196
    194197
     198def r210_to_rgb48(buf,
     199                  const unsigned int w, const unsigned int h,
     200                  const unsigned int src_stride, const unsigned int dst_stride):
     201    assert buf, "no buffer"
     202    assert w*4<=src_stride, "invalid source stride %i for width %i" % (src_stride, w)
     203    assert w*6<=dst_stride, "invalid destination stride %i for width %i" % (dst_stride, w)
     204    assert (dst_stride%2)==0, "invalid destination stride %i (odd number)" % (dst_stride)
     205    # buf is a Python buffer object
     206    cdef unsigned int* cbuf = <unsigned int *> 0
     207    cdef Py_ssize_t cbuf_len = 0
     208    assert as_buffer(buf, <const void**> &cbuf, &cbuf_len)==0, "cannot convert %s to a readable buffer" % type(buf)
     209    assert cbuf_len>0, "invalid buffer size: %i" % cbuf_len
     210    assert cbuf_len>=h*src_stride, "source buffer is %i bytes, which is too small for %ix%i" % (cbuf_len, src_stride, h)
     211    return r210data_to_rgb48(cbuf, w, h, src_stride, dst_stride)
     212
     213#white:  3fffffff
     214#red:    3ff00000
     215#green:     ffc00
     216#blue:        3ff
     217#black:         0
     218cdef r210data_to_rgb48(unsigned int* r210,
     219                       const unsigned int w, const unsigned int h,
     220                       const unsigned int src_stride, const unsigned int dst_stride):
     221    cdef MemBuf output_buf = getbuf(h*dst_stride)
     222    cdef unsigned short* rgba = <unsigned short*> output_buf.get_mem()
     223    cdef unsigned int y = 0
     224    cdef unsigned int i = 0
     225    cdef unsigned int v
     226    for y in range(h):
     227        i = y*dst_stride//2
     228        for x in range(w):
     229            v = r210[x]
     230            rgba[i+2] = (v&0x000003ff) << 4
     231            rgba[i+1] = (v&0x000ffc00) >> 4
     232            rgba[i]   = (v&0x3ff00000) >> 14
     233            i = i + 3
     234        r210 = <unsigned int*> ((<uintptr_t> r210) + src_stride)
     235    return memoryview(output_buf)
     236
     237
    195238def argb_to_rgba(buf):
    196239    assert len(buf) % 4 == 0, "invalid buffer size: %s is not a multiple of 4" % len(buf)
    197240    # buf is a Python buffer object
     
    448491        #    image.set_pixels(r210_to_rgba(pixels))
    449492        #    image.set_pixel_format("RGBA")
    450493        #    return True
     494        log.info("argb_swap r210")
    451495        w = image.get_width()
    452496        h = image.get_height()
    453497        if "RGB" in rgb_formats:
  • ../src/xpra/codecs/codec_constants.py

     
    4343    "NV12"    : 2,
    4444    "YUV420P" : 2,
    4545    "YUV422P" : 1.5,
     46    "YUV422P10" : 1.5,
    4647    }
    4748
    4849PIXEL_SUBSAMPLING = {
     
    5152    "YUV422P"   : ((1, 1), (2, 1), (2, 1)),
    5253    "YUV444P"   : ((1, 1), (1, 1), (1, 1)),
    5354    "GBRP"      : ((1, 1), (1, 1), (1, 1)),
     55    "YUV422P10" : ((1, 1), (2, 1), (2, 1)),
    5456}
    5557def get_subsampling_divs(pixel_format):
    5658    # Return size dividers for the given pixel format
  • ../src/xpra/codecs/dec_avcodec2/decoder.pyx

     
    8989    AVPixelFormat AV_PIX_FMT_VAAPI_IDCT
    9090    AVPixelFormat AV_PIX_FMT_VAAPI_VLD
    9191    AVPixelFormat AV_PIX_FMT_VAAPI
    92     AVPixelFormat AV_PIX_FMT_VAAPI
    9392    AVPixelFormat AV_PIX_FMT_YUV420P16LE
    9493    AVPixelFormat AV_PIX_FMT_YUV420P16BE
    9594    AVPixelFormat AV_PIX_FMT_YUV422P16LE
     
    502501    AV_PIX_FMT_NB : "NB",
    503502    }
    504503
     504#given one of our format names,
     505#what ffmpeg AV_PIX_FMT we expect to find in the output:
    505506FORMAT_TO_ENUM = {
    506507            "YUV420P"   : AV_PIX_FMT_YUV420P,
    507508            "YUV422P"   : AV_PIX_FMT_YUV422P,
     
    512513            "ARGB"      : AV_PIX_FMT_ARGB,
    513514            "BGRA"      : AV_PIX_FMT_BGRA,
    514515            "GBRP"      : AV_PIX_FMT_GBRP,
     516            "r210"      : AV_PIX_FMT_YUV422P10LE,
    515517            }
    516518#for planar formats, this is the number of bytes per channel
    517519BYTES_PER_PIXEL = {
     
    524526    AV_PIX_FMT_ARGB     : 4,
    525527    AV_PIX_FMT_BGRA     : 4,
    526528    AV_PIX_FMT_GBRP     : 1,
     529    AV_PIX_FMT_YUV422P10LE : 4,
    527530    }
    528531
    529532COLORSPACES = tuple(FORMAT_TO_ENUM.keys())
     533#given an ffmpeg format,
     534#what is our format name for it:
    530535ENUM_TO_FORMAT = {}
    531536for pix_fmt, av_enum in FORMAT_TO_ENUM.items():
    532537    ENUM_TO_FORMAT[av_enum] = pix_fmt
     538#override for YUV422P10LE:
     539ENUM_TO_FORMAT[AV_PIX_FMT_YUV422P10LE] = "YUV422P10"
    533540
     541
    534542def get_version():
    535543    return (LIBAVCODEC_VERSION_MAJOR, LIBAVCODEC_VERSION_MINOR, LIBAVCODEC_VERSION_MICRO)
    536544
     
    595603def get_output_colorspace(encoding, csc):
    596604    if encoding not in CODECS:
    597605        return ""
    598     if encoding=="h264" and csc in ("RGB", "XRGB", "BGRX", "ARGB", "BGRA"):
    599         #h264 from plain RGB data is returned as "GBRP"!
    600         return "GBRP"
     606    if encoding=="h264":
     607        if csc in ("RGB", "XRGB", "BGRX", "ARGB", "BGRA"):
     608            #h264 from plain RGB data is returned as "GBRP"!
     609            return "GBRP"
     610        elif csc=="r210":
     611            return "YUV422P10LE"
    601612    elif encoding in ("vp8", "mpeg4", "mpeg1", "mpeg2"):
    602613        return "YUV420P"
    603614    #everything else as normal:
     
    950961            log("avcodec actual output pixel format is %s (%s), expected %s (%s)", self.actual_pix_fmt, self.get_actual_colorspace(), self.pix_fmt, self.colorspace)
    951962
    952963        cs = self.get_actual_colorspace()
    953         if cs.endswith("P"):
     964        log.info("actual_colorspace(%s)=%s", self.actual_pix_fmt, cs)
     965        if cs.find("P")>0:  #ie: GBRP, YUV420P, YUV422P10LE etc
    954966            divs = get_subsampling_divs(cs)
    955967            nplanes = 3
    956968            for i in range(3):
     
    967979                size = height * stride
    968980                outsize += size
    969981
     982                #for z in range(size):
     983                #    av_frame.data[i][z] = (z + 2**(z%8)) % 256
     984
    970985                out.append(memory_as_pybuffer(<void *>av_frame.data[i], size, True))
    971986                strides.append(stride)
    972987                log("decompress_image() read back yuv plane %s: %s bytes", i, size)
  • ../src/xpra/codecs/enc_x264/encoder.pyx

     
    2626LOGGING = os.environ.get("XPRA_X264_LOGGING", "WARNING")
    2727PROFILE = os.environ.get("XPRA_X264_PROFILE")
    2828SUPPORT_24BPP = envbool("XPRA_X264_SUPPORT_24BPP")
     29SUPPORT_30BPP = envbool("XPRA_X264_SUPPORT_30BPP", True)
    2930TUNE = os.environ.get("XPRA_X264_TUNE")
    3031LOG_NALS = envbool("XPRA_X264_LOG_NALS")
    3132SAVE_TO_FILE = os.environ.get("XPRA_SAVE_TO_FILE")
     
    6364    int X264_CSP_BGR
    6465    int X264_CSP_BGRA
    6566    int X264_CSP_RGB
     67    int X264_CSP_NV12
     68    int X264_CSP_V210
     69    int X264_CSP_HIGH_DEPTH
    6670
    6771    int X264_RC_CQP
    6872    int X264_RC_CRF
     
    168172        int i_width
    169173        int i_height
    170174        int i_csp               #CSP of encoded bitstream
     175        int i_bitdepth
    171176        int i_level_idc
    172177        int i_frame_total       #number of frames to encode if known, else 0
    173178
     
    344349    "YUV444P"   : (X264_CSP_I444,    PROFILE_HIGH444_PREDICTIVE,    I444_PROFILES),
    345350    "BGRA"      : (X264_CSP_BGRA,    PROFILE_HIGH444_PREDICTIVE,    RGB_PROFILES),
    346351    "BGRX"      : (X264_CSP_BGRA,    PROFILE_HIGH444_PREDICTIVE,    RGB_PROFILES),
     352    "r210"      : (X264_CSP_V210 | X264_CSP_HIGH_DEPTH,    PROFILE_HIGH444_PREDICTIVE,    RGB_PROFILES),
    347353    }
    348354if SUPPORT_24BPP:
    349355    COLORSPACE_FORMATS.update({
     
    358364    "BGRA"      : ("BGRA",),
    359365    "BGRX"      : ("BGRX",),
    360366    }
     367if SUPPORT_30BPP:
     368    COLORSPACES["r210"] = ("BGRX",)
    361369if SUPPORT_24BPP:
    362370    COLORSPACES.update({
    363371        "BGR"       : ("BGR",),
     
    610618        param.i_width = self.width
    611619        param.i_height = self.height
    612620        param.i_csp = self.colorspace
     621        if (self.colorspace & X264_CSP_HIGH_DEPTH)>0:
     622            param.i_bitdepth = 10
     623        else:
     624            param.i_bitdepth = 8
    613625        #logging hook:
    614626        param.pf_log = <void *> X264_log
    615627        param.i_log_level = LOG_LEVEL
     
    818830
    819831        x264_picture_init(&pic_in)
    820832
    821         if self.src_format.find("RGB")>=0 or self.src_format.find("BGR")>=0:
     833        if self.src_format.find("RGB")>=0 or self.src_format.find("BGR")>=0 or self.src_format=="r210":
    822834            assert len(pixels)>0
    823835            assert istrides>0
     836            if self.src_format=="r210":
     837                #CSC should be moved elsewhere!
     838                from xpra.codecs.argb.argb import r210_to_rgb48
     839                pixels = r210_to_rgb48(pixels, self.width, self.height, istrides, self.width*6)
     840                istrides = self.width*6
     841                log.error("r210_to_rgb48!")
    824842            assert object_as_buffer(pixels, <const void**> &pic_buf, &pic_buf_len)==0, "unable to convert %s to a buffer" % type(pixels)
    825843            for i in range(3):
    826844                pic_in.img.plane[i] = pic_buf
    827845                pic_in.img.i_stride[i] = istrides
    828846            self.bytes_in += pic_buf_len
     847            pic_in.img.i_plane = 1
    829848        else:
    830849            assert len(pixels)==3, "image pixels does not have 3 planes! (found %s)" % len(pixels)
    831850            assert len(istrides)==3, "image strides does not have 3 values! (found %s)" % len(istrides)
     
    833852                assert object_as_buffer(pixels[i], <const void**> &pic_buf, &pic_buf_len)==0, "unable to convert %s to a buffer (plane=%s)" % (type(pixels[i]), i)
    834853                pic_in.img.plane[i] = pic_buf
    835854                pic_in.img.i_stride[i] = istrides[i]
     855            pic_in.img.i_plane = 3
    836856
    837857        pic_in.img.i_csp = self.colorspace
    838         pic_in.img.i_plane = 3
    839858        pic_in.i_pts = image.get_timestamp()-self.first_frame_timestamp
    840859        return self.do_compress_image(&pic_in, quality, speed)
    841860
     
    9901009
    9911010
    9921011def selftest(full=False):
     1012    log("enc_x264 selftest: %s", get_info())
    9931013    global SAVE_TO_FILE
    9941014    from xpra.codecs.codec_checks import testencoder, get_encoder_max_sizes
    9951015    from xpra.codecs.enc_x264 import encoder
  • ../src/xpra/codecs/rgb_transform.py

     
    3838
    3939def rgb_reformat(image, rgb_formats, supports_transparency) -> bool:
    4040    """ convert the RGB pixel data into a format supported by the client """
     41    log.info("rgb_reformat%s", (image, rgb_formats, supports_transparency))
    4142    #need to convert to a supported format!
    4243    pixel_format = bytestostr(image.get_pixel_format())
    4344    pixels = image.get_pixels()
  • ../src/xpra/server/window/window_video_source.py

     
    21302130        if not self.common_video_encodings:
    21312131            #we have to send using a non-video encoding as that's all we have!
    21322132            return self.video_fallback(image, options)
    2133         if self.image_depth not in (24, 32):
     2133        if self.image_depth not in (24, 30, 32):
    21342134            #this image depth is not supported for video
    21352135            return self.video_fallback(image, options)
    21362136