xpra icon
Bug tracker and wiki

Ticket #2828: 10-bit-render.patch

File 10-bit-render.patch, 8.6 KB (added by Antoine Martin, 3 months ago)

almost works

  • xpra/client/gl/gl_window_backing_base.py

     
    5555    POSIX,
    5656    DummyContextManager,
    5757    )
    58 from xpra.util import envint, envbool, repr_ellipsized
     58from xpra.util import envint, envbool, repr_ellipsized, first_time
    5959from xpra.client.paint_colors import get_paint_box_color
    6060from xpra.codecs.codec_constants import get_subsampling_divs
    6161from xpra.client.window_backing_base import (
     
    122122    "YUV420P" : GL_UNSIGNED_BYTE,
    123123    "YUV422P" : GL_UNSIGNED_BYTE,
    124124    "YUV444P" : GL_UNSIGNED_BYTE,
     125    "GBRP"  : GL_UNSIGNED_BYTE,
     126    "GBRP10" : GL_UNSIGNED_SHORT,
    125127    }
    126128CONSTANT_TO_PIXEL_FORMAT = {
    127129    GL_BGR   : "BGR",
     
    298300        self.RGB_MODES = list(GLWindowBackingBase.RGB_MODES)
    299301        if self.bit_depth>32:
    300302            self.internal_format = GL_RGBA16
    301             self.RGB_MODES.append("r210")
     303            self.RGB_MODES.append("BGR48")
     304            self.RGB_MODES.append("GBRP10")
    302305        elif self.bit_depth==30:
    303306            self.internal_format = GL_RGB10_A2
    304             self.RGB_MODES.append("r210")
    305         elif self.bit_depth==16:
     307            self.RGB_MODES.append("BGR48")
     308            self.RGB_MODES.append("GBRP10")
     309        elif 0<self.bit_depth<=16:
    306310            if self._alpha_enabled:
    307311                if envbool("XPRA_GL_RGBA4", True):
    308312                    self.internal_format = GL_RGBA4
     
    315319                self.RGB_MODES.append("BGR565")
    316320                self.RGB_MODES.append("RGB565")
    317321        else:
     322            if self.bit_depth not in (0, 24, 32) and first_time("bit-depth-%i" % self.bit_depth):
     323                log.warn("Warning: invalid bit depth %i, using 24", self.bit_depth)
    318324            #assume 24:
    319325            if self._alpha_enabled:
    320326                self.internal_format = GL_RGBA8
     
    325331            self.texture_pixel_format = GL_RGBA
    326332        else:
    327333            self.texture_pixel_format = GL_RGB
    328         log("init_formats() texture pixel format=%s, internal format=%s, rgb modes=%s",
     334        log.error("init_formats() texture pixel format=%s, internal format=%s, rgb modes=%s",
    329335            CONSTANT_TO_PIXEL_FORMAT.get(self.texture_pixel_format),
    330336            INTERNAL_FORMAT_TO_STR.get(self.internal_format),
    331337            self.RGB_MODES)
     
    11041110            #copy so the data will be usable (usually a str)
    11051111            img.clone_pixel_data()
    11061112        pixel_format = img.get_pixel_format()
    1107         if pixel_format=="GBRP":
     1113        if pixel_format.startswith("GBRP"):
    11081114            shader = RGBP2RGB_SHADER
    11091115        else:
    11101116            shader = YUV2RGB_SHADER
     
    11191125        x, y = self.gravity_adjust(x, y, options)
    11201126        try:
    11211127            pixel_format = img.get_pixel_format()
    1122             assert pixel_format in ("YUV420P", "YUV422P", "YUV444P", "GBRP", ), \
     1128            assert pixel_format in ("YUV420P", "YUV422P", "YUV444P", "GBRP", "GBRP10"), \
    11231129                "sorry the GL backing does not handle pixel format '%s' yet!" % (pixel_format)
    11241130
    11251131            context = self.gl_context()
     
    11841190        self.gl_marker("updating planar textures: %sx%s %s", width, height, pixel_format)
    11851191        rowstrides = img.get_rowstride()
    11861192        img_data = img.get_pixels()
    1187         BPP = 1
     1193        BPP = 2 if pixel_format.endswith("P10") else 1
    11881194        assert len(rowstrides)==3 and len(img_data)==3
    11891195        for texture, index, tex_name in (
    11901196            (GL_TEXTURE0, TEX_Y, "Y"*BPP),
     
    12181224    def render_planar_update(self, rx : int, ry : int, rw : int, rh : int, x_scale=1, y_scale=1, shader=YUV2RGB_SHADER):
    12191225        log("%s.render_planar_update%s pixel_format=%s",
    12201226            self, (rx, ry, rw, rh, x_scale, y_scale, shader), self.pixel_format)
    1221         if self.pixel_format not in ("YUV420P", "YUV422P", "YUV444P", "GBRP"):
     1227        if self.pixel_format not in ("YUV420P", "YUV422P", "YUV444P", "GBRP", "GBRP10"):
    12221228            #not ready to render yet
    12231229            return
    12241230        self.gl_marker("painting planar update, format %s", self.pixel_format)
  • xpra/codecs/dec_avcodec2/decoder.pyx

     
    1010from xpra.log import Logger
    1111log = Logger("decoder", "avcodec")
    1212
    13 from xpra.os_util import bytestostr, WIN32
     13from xpra.os_util import bytestostr, WIN32, hexstr
    1414from xpra.util import csv
    1515from xpra.codecs.codec_constants import get_subsampling_divs
    1616from xpra.codecs.image_wrapper import ImageWrapper
     
    503503    #AV_PIX_FMT_NB : "NB",
    504504    }
    505505
     506#given one of our format names,
     507#describing the pixel data fed to the encoder,
     508#what ffmpeg AV_PIX_FMT we expect to find in the output:
    506509FORMAT_TO_ENUM = {
    507510            "YUV420P"   : AV_PIX_FMT_YUV420P,
    508511            "YUV422P"   : AV_PIX_FMT_YUV422P,
     
    513516            "ARGB"      : AV_PIX_FMT_ARGB,
    514517            "BGRA"      : AV_PIX_FMT_BGRA,
    515518            "GBRP"      : AV_PIX_FMT_GBRP,
     519            "BGR48"     : AV_PIX_FMT_GBRP10LE,
    516520            }
    517521#for planar formats, this is the number of bytes per channel
    518522BYTES_PER_PIXEL = {
     
    525529    AV_PIX_FMT_ARGB     : 4,
    526530    AV_PIX_FMT_BGRA     : 4,
    527531    AV_PIX_FMT_GBRP     : 1,
     532    AV_PIX_FMT_GBRP10LE : 6,
    528533    }
    529534
     535#given an ffmpeg pixel format,
     536#what is our format name for it:
    530537COLORSPACES = tuple(FORMAT_TO_ENUM.keys())
    531538ENUM_TO_FORMAT = {}
    532539for pix_fmt, av_enum in FORMAT_TO_ENUM.items():
    533540    ENUM_TO_FORMAT[av_enum] = pix_fmt
     541#ENUM_TO_FORMAT[AV_PIX_FMT_YUV422P10LE] = "YUV422P10"
     542ENUM_TO_FORMAT[AV_PIX_FMT_GBRP10LE] = "GBRP10"
    534543
     544
    535545def get_version():
    536546    return (LIBAVCODEC_VERSION_MAJOR, LIBAVCODEC_VERSION_MINOR, LIBAVCODEC_VERSION_MICRO)
    537547
     
    596606def get_output_colorspace(encoding, csc):
    597607    if encoding not in CODECS:
    598608        return ""
    599     if encoding=="h264" and csc in ("RGB", "XRGB", "BGRX", "ARGB", "BGRA"):
    600         #h264 from plain RGB data is returned as "GBRP"!
    601         return "GBRP"
     609    if encoding=="h264":
     610        if csc in ("RGB", "XRGB", "BGRX", "ARGB", "BGRA"):
     611            #h264 from plain RGB data is returned as "GBRP"!
     612            return "GBRP"
     613        if csc=="BGR48":
     614            return "GBRP10"
    602615    elif encoding in ("vp8", "mpeg4", "mpeg1", "mpeg2"):
    603616        return "YUV420P"
    604617    #everything else as normal:
     
    951964            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)
    952965
    953966        cs = self.get_actual_colorspace()
    954         if cs.endswith("P"):
     967        log("actual_colorspace(%s)=%s", self.actual_pix_fmt, cs)
     968        if cs.find("P")>0:  #ie: GBRP, YUV420P, YUV422P10LE etc
    955969            divs = get_subsampling_divs(cs)
    956970            nplanes = 3
    957971            for i in range(3):
     
    968982                size = height * stride
    969983                outsize += size
    970984
     985                #if cs=="GBRP10":
     986                    #for z in range(size//2):
     987                        #av_frame.data[i][z] = (z + 2**(z%8)) % 256
     988                        #av_frame.data[i][z*2] = min(255, av_frame.data[i][z]<<4)
     989                        #av_frame.data[i][z*2+1] = 0xff   #min(255, av_frame.data[i][z]<<4)
     990
    971991                out.append(memory_as_pybuffer(<void *>av_frame.data[i], size, True))
     992                if cs=="GBRP10":
     993                    log("plane %s: %s", cs[i:i+1], hexstr(out[-1][:1024]))
     994                    #for z in range(size//2):
     995                        #av_frame.data[i][z] = (z + 2**(z%8)) % 256
     996                        #av_frame.data[i][z*2] = min(255, av_frame.data[i][z]<<4)
     997                        #av_frame.data[i][z*2+1] = 0xff   #min(255, av_frame.data[i][z]<<4)
     998
    972999                strides.append(stride)
    973                 log("decompress_image() read back yuv plane %s: %s bytes", i, size)
     1000                log("decompress_image() read back '%s' plane: %s bytes", cs[i:i+1], size)
    9741001        else:
    9751002            #RGB mode: "out" is a single buffer
    9761003            strides = av_frame.linesize[0]+av_frame.linesize[1]+av_frame.linesize[2]
     
    9771004            outsize = self.codec_ctx.height * strides
    9781005            out = memory_as_pybuffer(<void *>av_frame.data[0], outsize, True)
    9791006            nplanes = 0
    980             log("decompress_image() read back rgb buffer: %s bytes", outsize)
     1007            log("decompress_image() read back '%s' buffer: %s bytes", cs, outsize)
    9811008
    9821009        if outsize==0:
    9831010            av_frame_unref(av_frame)