xpra icon
Bug tracker and wiki

Ticket #328: yuv-codec-v2.patch

File yuv-codec-v2.patch, 9.6 KB (added by Antoine Martin, 6 years ago)

better patch - no longer using a yuvlib, all in cython

  • xpra/codecs/codec_constants.py

     
    88YUV422P = 422
    99YUV444P = 444
    1010
     11RGB24 = 24
     12#not used yet:
     13#ARGB = 320
     14#RGBA = 321
     15#ABGR = 322
     16#BGRA = 323
     17
     18
    1119def get_subsampling_divs(pixel_format):
    1220    # Return size dividers for the given pixel format
    1321    #  (Y_w, Y_h), (U_w, U_h), (V_w, V_h)
  • xpra/codecs/yuv/__init__.py

     
     1# This file is part of Xpra.
     2# Copyright (C) 2013 Antoine Martin <antoine@devloop.org.uk>
     3# Xpra is released under the terms of the GNU GPL v2, or, at your option, any
     4# later version. See the file COPYING for details.
  • xpra/codecs/yuv/decoder.pyx

     
     1# This file is part of Xpra.
     2# Copyright (C) 2012, 2013 Antoine Martin <antoine@devloop.org.uk>
     3# Xpra is released under the terms of the GNU GPL v2, or, at your option, any
     4# later version. See the file COPYING for details.
     5
     6import os
     7from libc.stdlib cimport free
     8
     9cdef extern from *:
     10    ctypedef unsigned long size_t
     11
     12cdef extern from "Python.h":
     13    ctypedef int Py_ssize_t
     14    ctypedef object PyObject
     15    ctypedef void** const_void_pp "const void**"
     16    int PyObject_AsReadBuffer(object obj, void ** buffer, Py_ssize_t * buffer_len) except -1
     17
     18ctypedef unsigned char uint8_t
     19ctypedef void yuvlib_ctx
     20cdef extern from "memalign.h":
     21    void* xmemalign(size_t size) nogil
     22    void xmemfree(void* ptr) nogil
     23
     24
     25cdef class Decoder:
     26
     27    cdef yuvlib_ctx *context
     28    cdef int width
     29    cdef int height
     30
     31    def init_context(self, width, height, options):
     32        self.width = width
     33        self.height = height
     34        csc_fmt = options.get("csc_pixel_format", -1)
     35        #self.context = init_decoder(width, height, csc_fmt)
     36
     37    def clean(self):
     38        pass
     39
     40    def is_closed(self):
     41        return self.context==NULL
     42
     43    #def get_pixel_format(self, csc_pixel_format):
     44    #    return get_pixel_format(csc_pixel_format)
     45    def yuv2rgb(self, input, options):
     46        cdef uint8_t *yuvplanes[3]
     47        cdef uint8_t *dout
     48        cdef int yuvstrides[3]
     49        cdef int outstrides[3]
     50        cdef unsigned char * padded_buf = NULL  #@DuplicatedSignature
     51        cdef unsigned char * buf = NULL         #@DuplicatedSignature
     52        cdef Py_ssize_t buf_len = 0             #@DuplicatedSignature
     53        cdef int i = 0                          #@DuplicatedSignature
     54        assert self.context!=NULL
     55        PyObject_AsReadBuffer(input, <const_void_pp> &buf, &buf_len)
     56        #i = yuv2rgb(self.context, yuvplanes, yuvstrides, &dout, outstrides)
     57        i = 0
     58        if i!=0:
     59            if dout!=NULL:
     60                xmemfree(dout)
     61            return i, "", 0
     62        xmemfree(dout)
     63        return  i
  • xpra/codecs/yuv/encoder.pyx

     
     1# This file is part of Xpra.
     2# Copyright (C) 2012, 2013 Antoine Martin <antoine@devloop.org.uk>
     3# Xpra is released under the terms of the GNU GPL v2, or, at your option, any
     4# later version. See the file COPYING for details.
     5
     6import os
     7from libc.stdlib cimport free
     8
     9cdef extern from *:
     10    ctypedef unsigned long size_t
     11
     12cdef extern from "Python.h":
     13    ctypedef int Py_ssize_t
     14    ctypedef object PyObject
     15    ctypedef void** const_void_pp "const void**"
     16    int PyObject_AsReadBuffer(object obj, void ** buffer, Py_ssize_t * buffer_len) except -1
     17
     18ctypedef unsigned char uint8_t
     19ctypedef void yuvlib_ctx
     20cdef extern from "memalign.h":
     21    void* xmemalign(size_t size) nogil
     22    void xmemfree(void* ptr) nogil
     23
     24cdef extern from "libavutil/pixfmt.h":
     25    ctypedef enum PixelFormat:
     26        PIX_FMT_YUV420P
     27        PIX_FMT_YUV422P
     28        PIX_FMT_YUV444P
     29        PIX_FMT_RGB24
     30
     31ctypedef void SwsContext
     32ctypedef void SwsFilter
     33
     34cdef extern from "libswscale/swscale.h":
     35    SwsContext *sws_getContext(int srcW, int srcH, PixelFormat srcFormat,
     36                                  int dstW, int dstH, PixelFormat dstFormat,
     37                                  int flags, SwsFilter *srcFilter,
     38                                  SwsFilter *dstFilter, const double *param)
     39
     40    void sws_freeContext(SwsContext *swsContext)
     41
     42    int sws_scale(SwsContext *c, const uint8_t *srcSlice[],
     43              const int srcStride[], int srcSliceY, int srcSliceH,
     44              uint8_t *dst[], const int dstStride[])
     45
     46
     47SWS_BICUBLIN = 4
     48SWS_ACCURATE_RND = 0x40000
     49
     50
     51from xpra.codec_constants import YUV420P, YUV422P, YUV444P, RGB24, get_subsampling_divs
     52
     53cdef class Encoder:
     54
     55    cdef SwsContext *context
     56    cdef int width
     57    cdef int height
     58    cdef int div_x
     59    cdef int dib_y
     60    cdef int frames
     61
     62    def init_context(self, int width, int height, rgb_format, yuv_format):
     63        cdef int yuv_fmt
     64        cdef int flags
     65        self.width = width
     66        self.height = height
     67        self.frames = 0
     68        flags = SWS_BICUBLIN | SWS_ACCURATE_RND
     69        assert rgb_format==RGB24, "invalid rgb format: %s" % rgb_format
     70        assert yuv_format in (YUV420P, YUV422P, YUV444P)
     71        self.div_x, self.div_y = get_subsampling_divs(yuv_format)
     72        #ugly code copy&paste because cython and enums don't mix well:
     73        if yuv_format==YUV420P:
     74            self.context = sws_getContext(width, height, PIX_FMT_RGB24, width, height, PIX_FMT_YUV420P, flags, NULL, NULL, NULL)
     75        elif yuv_format==YUV422P:
     76            self.context = sws_getContext(width, height, PIX_FMT_RGB24, width, height, PIX_FMT_YUV422P, flags, NULL, NULL, NULL)
     77        elif yuv_format==YUV444P:
     78            self.context = sws_getContext(width, height, PIX_FMT_RGB24, width, height, PIX_FMT_YUV444P, flags, NULL, NULL, NULL)
     79        else:
     80            raise Exception("invalid yuv format: %s" % yuv_format)
     81
     82    def clean(self):
     83        if self.context:
     84            sws_freeContext(self.context)
     85            self.context = NULL
     86
     87    def is_closed(self):
     88        return self.context==NULL
     89
     90    def rgb2yuv(self, input, rowstride, options):
     91        cdef uint8_t *pic_buf = NULL
     92        cdef const uint8_t *src[3]
     93        cdef int instrides[3]
     94        cdef uint8_t *dout
     95        cdef const int outstrides[3]
     96        cdef Py_ssize_t pic_buf_len = 0
     97        assert self.context!=NULL
     98        assert rowstride>self.width
     99        assert len(input)==rowstride*self.width
     100        #colourspace conversion with gil held:
     101        PyObject_AsReadBuffer(input, <const_void_pp> &pic_buf, &pic_buf_len)
     102        #r = rgb2yuv(self.context, pic_buf, rowstride, &dout, outstrides)
     103        #sws_scale(ctx->rgb2yuv, &in, &stride, 0, ctx->height, pic_in->img.plane, outstrides)
     104        src[0] = pic_buf
     105        src[1] = pic_buf
     106        src[2] = pic_buf
     107        instrides[0] = rowstride
     108        instrides[1] = rowstride
     109        instrides[2] = rowstride
     110        h = sws_scale(self.context, src, instrides, 0, 0, &dout, outstrides)
     111        #...
  • xpra/codecs/yuv/memalign.c

     
     1/* This file is part of Xpra.
     2 * Copyright (C) 2012, 2013 Antoine Martin <antoine@devloop.org.uk>
     3 * Xpra is released under the terms of the GNU GPL v2, or, at your option, any
     4 * later version. See the file COPYING for details.
     5 */
     6
     7#include <stdlib.h>
     8
     9#ifdef _WIN32
     10#define _STDINT_H
     11#endif
     12#if !defined(__APPLE__)
     13#include <malloc.h>
     14#endif
     15
     16//not honoured on MS Windows:
     17#define MEMALIGN 1
     18//not honoured on OSX:
     19#define MEMALIGN_ALIGNMENT 32
     20//comment this out to turn off csc 422 and 444 colourspace modes
     21//(ie: when not supported by the library we build against)
     22#define SUPPORT_CSC_MODES 1
     23
     24
     25void* xmemalign(size_t size)
     26{
     27#ifdef MEMALIGN
     28#ifdef _WIN32
     29        //_aligned_malloc and _aligned_free lead to a memleak
     30        //well done Microsoft, I didn't think you could screw up this badly
     31        //and thank you for wasting my time once again
     32        return malloc(size);
     33#elif defined(__APPLE__) || defined(__OSX__)
     34        //Crapple version: "all memory allocations are 16-byte aligned"
     35        //no choice, this is what you get
     36        return malloc(size);
     37#else
     38        //not WIN32 and not APPLE/OSX, assume POSIX:
     39        void* memptr=NULL;
     40        if (posix_memalign(&memptr, MEMALIGN_ALIGNMENT, size))
     41                return  NULL;
     42        return  memptr;
     43#endif
     44//MEMALIGN not set:
     45#else
     46        return  malloc(size);
     47#endif
     48}
     49
     50void xmemfree(void *ptr)
     51{
     52        free(ptr);
     53}
  • xpra/codecs/yuv/memalign.h

     
     1/* This file is part of Parti.
     2 * Copyright (C) 2012 Serviware (Arthur Huillet, <ahuillet@serviware.com>)
     3 * Copyright (C) 2012, 2013 Antoine Martin <antoine@devloop.org.uk>
     4 * Parti is released under the terms of the GNU GPL v2, or, at your option, any
     5 * later version. See the file COPYING for details.
     6 */
     7
     8/**
     9 * Define our own memalign function so we can more easily
     10 * workaround platforms that lack posix_memalign.
     11 * It does its best to provide sse compatible memory allocation.
     12 */
     13void* xmemalign(size_t size);
     14
     15/**
     16 * Frees memory allocated with xmemalign
     17 */
     18void xmemfree(void *ptr);