xpra icon
Bug tracker and wiki

Ticket #1107: video-container-templates.patch

File video-container-templates.patch, 26.5 KB (added by Antoine Martin, 4 years ago)

stubs for 3 new video container plugins

  • xpra/codecs/enc_ffmpeg/__init__.py

     
     1# This file is part of Xpra.
     2# Copyright (C) 2016 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/enc_ffmpeg/encoder.pyx

     
     1# This file is part of Xpra.
     2# Copyright (C) 2012-2014 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 weakref
     7from xpra.log import Logger
     8log = Logger("decoder", "ffmpeg")
     9
     10from xpra.codecs.codec_constants import get_subsampling_divs
     11from xpra.codecs.image_wrapper import ImageWrapper
     12from xpra.codecs.libav_common.av_log cimport override_logger, restore_logger #@UnresolvedImport
     13from xpra.util import bytestostr
     14
     15
     16ctypedef unsigned long size_t
     17ctypedef unsigned char uint8_t
     18
     19
     20cdef extern from "../../buffers/buffers.h":
     21    object memory_as_pybuffer(void* ptr, Py_ssize_t buf_len, int readonly)
     22    int    object_as_buffer(object obj, const void ** buffer, Py_ssize_t * buffer_len)
     23    int get_buffer_api_version()
     24
     25cdef extern from "string.h":
     26    void * memcpy(void * destination, void * source, size_t num) nogil
     27    void * memset(void * ptr, int value, size_t num) nogil
     28    void free(void * ptr) nogil
     29
     30
     31cdef extern from "../../inline.h":
     32    pass
     33
     34cdef extern from "../../buffers/memalign.h":
     35    void *xmemalign(size_t size)
     36
     37
     38cdef extern from "libavutil/mem.h":
     39    void av_free(void *ptr)
     40
     41cdef extern from "libavutil/error.h":
     42    int av_strerror(int errnum, char *errbuf, size_t errbuf_size)
     43
     44cdef extern from "libavcodec/version.h":
     45    int LIBAVCODEC_VERSION_MAJOR
     46    int LIBAVCODEC_VERSION_MINOR
     47    int LIBAVCODEC_VERSION_MICRO
     48
     49#why can't we define this inside the avcodec.h section? (beats me)
     50ctypedef unsigned int AVCodecID
     51ctypedef long AVPixelFormat
     52
     53
     54cdef extern from "libavutil/pixfmt.h":
     55    AVPixelFormat AV_PIX_FMT_NONE
     56    AVPixelFormat AV_PIX_FMT_YUV420P
     57
     58cdef extern from "libavcodec/avcodec.h":
     59    int CODEC_FLAG2_FAST
     60
     61    ctypedef struct AVFrame:
     62        uint8_t **data
     63        int *linesize
     64        int format
     65        void *opaque
     66    ctypedef struct AVCodec:
     67        pass
     68    ctypedef struct AVDictionary:
     69        pass
     70    ctypedef struct AVPacket:
     71        uint8_t *data
     72        int      size
     73
     74    ctypedef struct AVCodecContext:
     75        int width
     76        int height
     77        AVPixelFormat pix_fmt
     78        int thread_safe_callbacks
     79        int thread_count
     80        int thread_type
     81        int flags
     82        int flags2
     83        int refcounted_frames
     84
     85    AVCodecID AV_CODEC_ID_H264
     86    AVCodecID AV_CODEC_ID_H265
     87    AVCodecID AV_CODEC_ID_VP8
     88    AVCodecID AV_CODEC_ID_VP9
     89    AVCodecID AV_CODEC_ID_MPEG4
     90
     91    #init and free:
     92    void avcodec_register_all()
     93    AVCodec *avcodec_find_decoder(AVCodecID id)
     94    AVCodecContext *avcodec_alloc_context3(const AVCodec *codec)
     95    int avcodec_open2(AVCodecContext *avctx, const AVCodec *codec, AVDictionary **options)
     96    AVFrame* av_frame_alloc()
     97    void av_frame_free(AVFrame **frame)
     98    int avcodec_close(AVCodecContext *avctx)
     99
     100    #actual decoding:
     101    void av_init_packet(AVPacket *pkt) nogil
     102    void avcodec_get_frame_defaults(AVFrame *frame) nogil
     103    int avcodec_decode_video2(AVCodecContext *avctx, AVFrame *picture,
     104                                int *got_picture_ptr, const AVPacket *avpkt) nogil
     105
     106    void av_frame_unref(AVFrame *frame) nogil
     107
     108
     109FORMAT_TO_ENUM = {
     110            "YUV420P"   : AV_PIX_FMT_YUV420P,
     111            "YUV422P"   : AV_PIX_FMT_YUV422P,
     112            "YUV444P"   : AV_PIX_FMT_YUV444P,
     113            "RGB"       : AV_PIX_FMT_RGB24,
     114            "XRGB"      : AV_PIX_FMT_0RGB,
     115            "BGRX"      : AV_PIX_FMT_BGR0,
     116            "ARGB"      : AV_PIX_FMT_ARGB,
     117            "BGRA"      : AV_PIX_FMT_BGRA,
     118            "GBRP"      : AV_PIX_FMT_GBRP,
     119            }
     120
     121COLORSPACES = FORMAT_TO_ENUM.keys()
     122ENUM_TO_FORMAT = {}
     123for pix_fmt, av_enum in FORMAT_TO_ENUM.items():
     124    ENUM_TO_FORMAT[av_enum] = pix_fmt
     125
     126def get_version():
     127    return (LIBAVCODEC_VERSION_MAJOR, LIBAVCODEC_VERSION_MINOR, LIBAVCODEC_VERSION_MICRO)
     128
     129avcodec_register_all()
     130CODECS = []
     131if avcodec_find_decoder(AV_CODEC_ID_H264)!=NULL:
     132    CODECS.append("h264")
     133if avcodec_find_decoder(AV_CODEC_ID_VP8)!=NULL:
     134    CODECS.append("vp8")
     135if avcodec_find_decoder(AV_CODEC_ID_VP9)!=NULL:
     136    CODECS.append("vp9")
     137if avcodec_find_decoder(AV_CODEC_ID_H265)!=NULL:
     138    CODECS.append("h265")
     139if avcodec_find_decoder(AV_CODEC_ID_MPEG4)!=NULL:
     140    CODECS.append("mpeg4")
     141log("enc_ffmpeg.init_module: CODECS=%s", CODECS)
     142
     143
     144def init_module():
     145    log("enc_ffmpeg.init_module()")
     146    override_logger()
     147
     148def cleanup_module():
     149    log("enc_ffmpeg.cleanup_module()")
     150    restore_logger()
     151
     152def get_type():
     153    return "ffmpeg"
     154
     155def get_info():
     156    f = {}
     157    for e in get_encodings():
     158        f["formats.%s" % e] = get_input_colorspaces(e)
     159    return  {"version"      : get_version(),
     160             "encodings"    : get_encodings(),
     161             "buffer_api"   : get_buffer_api_version(),
     162             "formats"      : f,
     163             }
     164
     165def get_encodings():
     166    global CODECS
     167    return CODECS
     168
     169def get_input_colorspaces(encoding):
     170    return ["YUV420P"]
     171
     172def get_output_colorspace(encoding, csc):
     173    if encoding not in CODECS:
     174        return ""
     175    return "YUV420P"
     176
     177
     178cdef void clear_frame(AVFrame *frame):
     179    assert frame!=NULL, "frame is not set!"
     180    for i in range(4):
     181        frame.data[i] = NULL
     182
     183
     184cdef class AVFrameWrapper:
     185    """
     186        Wraps an AVFrame so we can free it
     187        once both xpra and avcodec are done with it.
     188    """
     189    cdef AVCodecContext *avctx
     190    cdef AVFrame *frame
     191    cdef int xpra_freed
     192
     193    cdef set_context(self, AVCodecContext *avctx, AVFrame *frame):
     194        self.avctx = avctx
     195        self.frame = frame
     196        log("%s.set_context(%#x, %#x)", self, <unsigned long> avctx, <unsigned long> frame)
     197
     198    def __dealloc__(self):
     199        #By the time this wrapper is garbage collected,
     200        #we must have freed it!
     201        assert self.frame==NULL and self.avctx==NULL, "frame was freed by both, but not actually freed!"
     202
     203    def __str__(self):
     204        if self.frame==NULL:
     205            return "AVFrameWrapper(NULL)"
     206        return "AVFrameWrapper(%#x)" % <unsigned long> self.frame
     207
     208    def xpra_free(self):
     209        log("%s.xpra_free()", self)
     210        self.free()
     211
     212    cdef free(self):
     213        log("%s.free() context=%#x, frame=%#x", self, <unsigned long> self.avctx, <unsigned long> self.frame)
     214        if self.avctx!=NULL and self.frame!=NULL:
     215            av_frame_unref(self.frame)
     216            self.frame = NULL
     217            self.avctx = NULL
     218
     219
     220class AVImageWrapper(ImageWrapper):
     221    """
     222        Wrapper which allows us to call xpra_free on the decoder
     223        when the image is freed, or once we have made a copy of the pixels.
     224    """
     225
     226    def __repr__(self):                          #@DuplicatedSignature
     227        return ImageWrapper.__repr__(self)+"-(%s)" % self.av_frame
     228
     229    def free(self):                             #@DuplicatedSignature
     230        log("AVImageWrapper.free()")
     231        ImageWrapper.free(self)
     232        self.xpra_free_frame()
     233
     234    def clone_pixel_data(self):
     235        log("AVImageWrapper.clone_pixel_data()")
     236        ImageWrapper.clone_pixel_data(self)
     237        self.xpra_free_frame()
     238
     239    def xpra_free_frame(self):
     240        av_frame = self.av_frame
     241        log("AVImageWrapper.xpra_free_frame() av_frame=%s", av_frame)
     242        if av_frame:
     243            self.av_frame = None
     244            av_frame.xpra_free()
     245
     246
     247cdef class Encoder:
     248    """
     249        This wraps the AVCodecContext and its configuration,
     250        also tracks AVFrames.
     251        It also handles reconstructing a single ImageWrapper
     252        constructed from 3-pass decoding (see plane_sizes).
     253    """
     254    cdef AVCodec *codec
     255    cdef AVCodecContext *codec_ctx
     256    cdef AVPixelFormat pix_fmt
     257    cdef AVPixelFormat actual_pix_fmt
     258    cdef object colorspace
     259    cdef object weakref_images
     260    cdef AVFrame *av_frame
     261    #this is the actual number of images we have returned
     262    cdef unsigned long frames
     263    cdef int width
     264    cdef int height
     265    cdef object encoding
     266
     267    cdef object __weakref__
     268
     269    def init_context(self, encoding, int width, int height, colorspace):
     270        cdef int r
     271        cdef int i
     272        assert encoding in CODECS
     273        self.encoding = encoding
     274        self.width = width
     275        self.height = height
     276        assert colorspace in COLORSPACES, "invalid colorspace: %s" % colorspace
     277        self.colorspace = ""
     278        for x in COLORSPACES:
     279            if x==colorspace:
     280                self.colorspace = x
     281                break
     282        if not self.colorspace:
     283            log.error("invalid pixel format: %s", colorspace)
     284            return  False
     285        self.pix_fmt = FORMAT_TO_ENUM.get(colorspace, AV_PIX_FMT_NONE)
     286        if self.pix_fmt==AV_PIX_FMT_NONE:
     287            log.error("invalid pixel format: %s", colorspace)
     288            return  False
     289        self.actual_pix_fmt = self.pix_fmt
     290
     291        avcodec_register_all()
     292
     293        cdef AVCodecID CodecID
     294        if self.encoding=="h264":
     295            CodecID = AV_CODEC_ID_H264
     296        elif self.encoding=="h265":
     297            CodecID = AV_CODEC_ID_H265
     298        elif self.encoding=="vp8":
     299            CodecID = AV_CODEC_ID_VP8
     300        elif self.encoding=="vp9":
     301            CodecID = AV_CODEC_ID_VP9
     302        elif self.encoding=="mpeg4":
     303            CodecID = AV_CODEC_ID_MPEG4
     304        else:
     305            raise Exception("invalid codec; %s" % self.encoding)
     306        self.codec = avcodec_find_decoder(CodecID)
     307        if self.codec==NULL:
     308            log.error("codec %s not found!" % self.encoding)
     309            return  False
     310
     311        #from here on, we have to call clean_decoder():
     312        self.codec_ctx = avcodec_alloc_context3(self.codec)
     313        if self.codec_ctx==NULL:
     314            log.error("failed to allocate codec context!")
     315            self.clean_decoder()
     316            return  False
     317
     318        self.codec_ctx.refcounted_frames = 1
     319        self.codec_ctx.width = width
     320        self.codec_ctx.height = height
     321        self.codec_ctx.pix_fmt = self.pix_fmt
     322        #self.codec_ctx.get_buffer2 = avcodec_get_buffer2
     323        #self.codec_ctx.release_buffer = avcodec_release_buffer
     324        self.codec_ctx.thread_safe_callbacks = 1
     325        self.codec_ctx.thread_type = 2      #FF_THREAD_SLICE: allow more than one thread per frame
     326        self.codec_ctx.thread_count = 0     #auto
     327        self.codec_ctx.flags2 |= CODEC_FLAG2_FAST   #may cause "no deblock across slices" - which should be fine
     328        r = avcodec_open2(self.codec_ctx, self.codec, NULL)
     329        if r<0:
     330            log.error("could not open codec: %s", self.av_error_str(r))
     331            self.clean_decoder()
     332            return  False
     333        #up to 3 AVFrame objects used:
     334        self.av_frame = av_frame_alloc()
     335        if self.av_frame==NULL:
     336            log.error("could not allocate an AVFrame for decoding")
     337            self.clean_decoder()
     338            return  False
     339        self.frames = 0
     340        #to keep track of images not freed yet:
     341        #(we want a weakref.WeakSet() but this is python2.7+ only..)
     342        self.weakref_images = []
     343        #register this decoder in the global dictionary:
     344        log("dec_avcodec.Decoder.init_context(%s, %s, %s) self=%s", width, height, colorspace, self.get_info())
     345        return True
     346
     347    def clean(self):
     348        self.clean_decoder()
     349        self.codec = NULL
     350        self.pix_fmt = 0
     351        self.actual_pix_fmt = 0
     352        self.colorspace = ""
     353        self.weakref_images = []
     354        self.av_frame = NULL                        #should be redundant
     355        self.frames = 0
     356        self.width = 0
     357        self.height = 0
     358        self.encoding = ""
     359
     360
     361    def clean_decoder(self):
     362        cdef int r, i
     363        log("%s.clean_decoder()", self)
     364        #we may have images handed out, ensure we don't reference any memory
     365        #that needs to be freed using avcodec_release_buffer(..)
     366        #as this requires the context to still be valid!
     367        #copying the pixels should ensure we free the AVFrameWrapper associated with it:
     368        if self.weakref_images:
     369            images = [y for y in [x() for x in self.weakref_images] if y is not None]
     370            self.weakref_images = []
     371            log("clean_decoder() cloning pixels for images still in use: %s", images)
     372            for img in images:
     373                if not img.freed:
     374                    img.clone_pixel_data()
     375
     376        if self.av_frame!=NULL:
     377            log("clean_decoder() freeing AVFrame: %#x", <unsigned long> self.av_frame)
     378            av_frame_free(&self.av_frame)
     379            #redundant: self.frame = NULL
     380
     381        cdef unsigned long ctx_key          #@DuplicatedSignature
     382        log("clean_decoder() freeing AVCodecContext: %#x", <unsigned long> self.codec_ctx)
     383        if self.codec_ctx!=NULL:
     384            r = avcodec_close(self.codec_ctx)
     385            if r!=0:
     386                log.warn("error closing decoder context %#x: %s", <unsigned long> self.codec_ctx, self.av_error_str(r))
     387            av_free(self.codec_ctx)
     388            self.codec_ctx = NULL
     389        log("clean_decoder() done")
     390
     391    cdef av_error_str(self, errnum):
     392        cdef char[128] err_str
     393        cdef int i = 0
     394        if av_strerror(errnum, err_str, 128)==0:
     395            while i<128 and err_str[i]!=0:
     396                i += 1
     397            return bytestostr(err_str[:i])
     398        return str(errnum)
     399
     400    def __repr__(self):                      #@DuplicatedSignature
     401        if self.is_closed():
     402            return "dec_avcodec.Decoder(*closed*)"
     403        return "dec_avcodec.Decoder(%s)" % self.get_info()
     404
     405    def get_info(self):                      #@DuplicatedSignature
     406        info = {"version"   : get_version(),
     407                "encoding"  : self.encoding,
     408                "formats"   : get_input_colorspaces(self.encoding),
     409                "type"      : self.get_type(),
     410                "frames"    : self.frames,
     411                "width"     : self.width,
     412                "height"    : self.height,
     413                }
     414        if self.colorspace:
     415            info["colorspace"] = self.colorspace
     416            info["actual_colorspace"] = self.get_actual_colorspace()
     417        if not self.is_closed():
     418            info["decoder_width"] = self.codec_ctx.width
     419            info["decoder_height"] = self.codec_ctx.height
     420        else:
     421            info["closed"] = True
     422        return info
     423
     424    def is_closed(self):
     425        return self.codec_ctx==NULL
     426
     427    def __dealloc__(self):                          #@DuplicatedSignature
     428        self.clean()
     429
     430    def get_width(self):
     431        return self.width
     432
     433    def get_height(self):
     434        return self.height
     435
     436    def get_encoding(self):
     437        return self.encoding
     438
     439    def get_type(self):                             #@DuplicatedSignature
     440        return "avcodec"
     441
     442    def decompress_image(self, input, options):
     443        cdef unsigned char * padded_buf = NULL
     444        cdef const unsigned char * buf = NULL
     445        cdef Py_ssize_t buf_len = 0
     446        cdef int size
     447        cdef int len = 0
     448        cdef int nplanes
     449        cdef int got_picture
     450        cdef AVPacket avpkt
     451        cdef unsigned long frame_key                #@DuplicatedSignature
     452        cdef AVFrameWrapper framewrapper
     453        cdef AVFrame *av_frame
     454        cdef object img
     455        assert self.codec_ctx!=NULL, "no codec context! (not initialized or already closed)"
     456        assert self.codec!=NULL
     457
     458        #copy the whole input buffer into a padded C buffer:
     459        assert object_as_buffer(input, <const void**> &buf, &buf_len)==0
     460        padded_buf = <unsigned char *> xmemalign(buf_len+128)
     461        memcpy(padded_buf, buf, buf_len)
     462        memset(padded_buf+buf_len, 0, 128)
     463
     464        #note: plain RGB output, will redefine those:
     465        out = []
     466        strides = []
     467        outsize = 0
     468
     469        #ensure we can detect if the frame buffer got allocated:
     470        clear_frame(self.av_frame)
     471        #now safe to run without gil:
     472        with nogil:
     473            av_init_packet(&avpkt)
     474            avpkt.data = <uint8_t *> (padded_buf)
     475            avpkt.size = buf_len
     476            len = avcodec_decode_video2(self.codec_ctx, self.av_frame, &got_picture, &avpkt)
     477        if len<0:
     478            av_frame_unref(self.av_frame)
     479            log("%s.decompress_image(%s:%s, %s) avcodec_decode_video2 failure: %s", self, type(input), buf_len, options, self.av_error_str(len))
     480            log.error("avcodec_decode_video2 %s decoding failure:", self.encoding)
     481            log.error(" %s", self.av_error_str(len))
     482            return None
     483        if len==0:
     484            av_frame_unref(self.av_frame)
     485            log("%s.decompress_image(%s:%s, %s) avcodec_decode_video2 failed to decode the stream", self, type(input), buf_len, options)
     486            log.error("avcodec_decode_video2 %s decoding failure - no stream", self.encoding)
     487            return None
     488
     489        if self.actual_pix_fmt!=self.av_frame.format:
     490            if self.av_frame.format==-1:
     491                log.error("avcodec error decoding %i bytes of %s data", buf_len, self.encoding)
     492                log.error(" frame %i", self.frames)
     493                log.error(" options=%s", options)
     494                log.error(" decoder state:")
     495                for k,v in self.get_info().items():
     496                    log.error("  %s = %s", k, v)
     497                return None
     498            self.actual_pix_fmt = self.av_frame.format
     499            if self.actual_pix_fmt not in ENUM_TO_FORMAT:
     500                av_frame_unref(self.av_frame)
     501                log.error("unknown output pixel format: %s, expected %s (%s)", self.actual_pix_fmt, self.pix_fmt, self.colorspace)
     502                return None
     503            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)
     504
     505        cs = self.get_actual_colorspace()
     506        if cs.endswith("P"):
     507            divs = get_subsampling_divs(cs)
     508            nplanes = 3
     509            for i in range(3):
     510                _, dy = divs[i]
     511                if dy==1:
     512                    height = self.codec_ctx.height
     513                elif dy==2:
     514                    height = (self.codec_ctx.height+1)>>1
     515                else:
     516                    av_frame_unref(self.av_frame)
     517                    raise Exception("invalid height divisor %s" % dy)
     518                stride = self.av_frame.linesize[i]
     519                size = height * stride
     520                outsize += size
     521
     522                out.append(memory_as_pybuffer(<void *>self.av_frame.data[i], size, True))
     523                strides.append(stride)
     524                log("decompress_image() read back yuv plane %s: %s bytes", i, size)
     525        else:
     526            #RGB mode: "out" is a single buffer
     527            strides = self.av_frame.linesize[0]+self.av_frame.linesize[1]+self.av_frame.linesize[2]
     528            outsize = self.codec_ctx.height * strides
     529            out = memory_as_pybuffer(<void *>self.av_frame.data[0], outsize, True)
     530            nplanes = 0
     531            log("decompress_image() read back rgb buffer: %s bytes", outsize)
     532
     533        #FIXME: we could lose track of framewrappers if an error occurs before the end:
     534        framewrapper = AVFrameWrapper()
     535        framewrapper.set_context(self.codec_ctx, self.av_frame)
     536
     537        if outsize==0:
     538            av_frame_unref(self.av_frame)
     539            raise Exception("output size is zero!")
     540
     541        free(padded_buf)
     542        assert self.codec_ctx.width>=self.width, "codec width is smaller than our width: %s<%s" % (self.codec_ctx.width, self.width)
     543        assert self.codec_ctx.height>=self.height, "codec height is smaller than our height: %s<%s" % (self.codec_ctx.height, self.height)
     544        img = AVImageWrapper(0, 0, self.width, self.height, out, cs, 24, strides, nplanes, thread_safe=False)
     545        img.av_frame = framewrapper
     546        self.frames += 1
     547        #add to weakref list after cleaning it up:
     548        self.weakref_images = [x for x in self.weakref_images if x() is not None]
     549        self.weakref_images.append(weakref.ref(img))
     550        log("%s.decompress_image(%s:%s, %s)=%s", self, type(input), buf_len, options, img)
     551        return img
     552
     553
     554    def get_colorspace(self):
     555        return self.colorspace
     556
     557    def get_actual_colorspace(self):
     558        return ENUM_TO_FORMAT.get(self.actual_pix_fmt, "unknown/invalid")
     559
     560
     561def selftest(full=False):
     562    global CODECS
     563    from xpra.codecs.codec_checks import testdecoder
     564    from xpra.codecs.dec_avcodec2 import decoder
     565    global CODECS
     566    CODECS = testdecoder(decoder, full)
  • xpra/codecs/mkv/__init__.py

     
     1# This file is part of Xpra.
     2# Copyright (C) 2016 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/mkv/muxer.pyx

     
     1# This file is part of Xpra.
     2# Copyright (C) 2016 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 time
     7import os
     8
     9from xpra.log import Logger
     10log = Logger("encoder", "mkv")
     11
     12from libc.stdint cimport int64_t
     13
     14cdef extern from "string.h":
     15    void *memset(void *ptr, int value, size_t num) nogil
     16    void free(void *ptr) nogil
     17
     18cdef extern from "../../buffers/memalign.h":
     19    void *xmemalign(size_t size)
     20
     21cdef extern from "../../buffers/buffers.h":
     22    int object_as_buffer(object obj, const void ** buffer, Py_ssize_t * buffer_len)
     23    int get_buffer_api_version()
     24
     25
     26cdef extern from "libmkv.h":
     27    pass
     28
     29cdef class Muxer:
     30    cdef object __weakref__
     31
     32#init_context(w, h, src_format, encoding, quality, speed, scaling, options)
     33    def init_context(self, int width, int height, src_format, dst_formats, encoding, int quality, int speed, scaling, options):    #@DuplicatedSignature
     34        pass
  • xpra/codecs/ogg/__init__.py

     
     1# This file is part of Xpra.
     2# Copyright (C) 2016 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/ogg/muxer.pyx

     
     1# This file is part of Xpra.
     2# Copyright (C) 2016 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 time
     7import os
     8
     9from xpra.log import Logger
     10log = Logger("encoder", "mkv")
     11
     12from libc.stdint cimport int64_t
     13
     14cdef extern from "string.h":
     15    void *memset(void *ptr, int value, size_t num) nogil
     16    void free(void *ptr) nogil
     17
     18cdef extern from "../../buffers/memalign.h":
     19    void *xmemalign(size_t size)
     20
     21cdef extern from "../../buffers/buffers.h":
     22    int object_as_buffer(object obj, const void ** buffer, Py_ssize_t * buffer_len)
     23    int get_buffer_api_version()
     24
     25
     26cdef extern from "ogg/ogg.h":
     27    pass
     28
     29cdef class Muxer:
     30    cdef object __weakref__
     31
     32#init_context(w, h, src_format, encoding, quality, speed, scaling, options)
     33    def init_context(self, int width, int height, src_format, dst_formats, encoding, int quality, int speed, scaling, options):    #@DuplicatedSignature
     34        pass
  • setup.py

     
    145145pillow_ENABLED          = DEFAULT
    146146webp_ENABLED            = DEFAULT and pkg_config_ok("--atleast-version=0.4", "libwebp")
    147147vpx_ENABLED             = DEFAULT and pkg_config_ok("--atleast-version=1.3", "vpx", fallback=WIN32)
     148mkv_include = os.environ.get("PREFIX", "/usr/include") + "/libmkv.h"
     149mkv_ENABLED             = DEFAULT and os.path.exists(mkv_include)
     150ogg_ENABLED             = DEFAULT and pkg_config_ok("--exists", "ogg")
     151enc_ffmpeg_ENABLED             = DEFAULT and pkg_config_ok("--atleast-version=56", "libavcodec")
    148152webcam_ENABLED          = DEFAULT and not OSX
    149153v4l2_ENABLED            = DEFAULT and (not WIN32 and not OSX)
    150154#ffmpeg 2 onwards:
     
    195199rebuild_ENABLED         = True
    196200
    197201#allow some of these flags to be modified on the command line:
    198 SWITCHES = ["enc_x264", "enc_x265", "xvid",
     202SWITCHES = ["enc_x264", "enc_x265", "xvid", "mkv", "ogg", "enc_ffmpeg",
    199203            "nvenc4", "nvenc5", "nvenc6",
    200204            "vpx", "webp", "pillow",
    201205            "dec_avcodec2", "csc_swscale",
     
    23322336                ["xpra/codecs/vpx/decoder.pyx"]+membuffers_c,
    23332337                **vpx_pkgconfig))
    23342338
     2339toggle_packages(mkv_ENABLED, "xpra.codecs.mkv")
     2340if mkv_ENABLED:
     2341    mkv_pkgconfig = {"extra_link_args" : ["-lmkv"]}
     2342    cython_add(Extension("xpra.codecs.mkv.muxer",
     2343                ["xpra/codecs/mkv/muxer.pyx"]+membuffers_c,
     2344                **mkv_pkgconfig))
     2345
     2346toggle_packages(ogg_ENABLED, "xpra.codecs.ogg")
     2347if ogg_ENABLED:
     2348    ogg_pkgconfig = pkgconfig("ogg")
     2349    cython_add(Extension("xpra.codecs.ogg.muxer",
     2350                ["xpra/codecs/ogg/muxer.pyx"]+membuffers_c,
     2351                **ogg_pkgconfig))
     2352
     2353toggle_packages(enc_ffmpeg_ENABLED, "xpra.codecs.enc_ffmpeg")
     2354if enc_ffmpeg_ENABLED:
     2355    ffmpeg_pkgconfig = pkgconfig("libavcodec")
     2356    cython_add(Extension("xpra.codecs.enc_ffmpeg.encoder",
     2357                ["xpra/codecs/enc_ffmpeg/encoder.pyx"]+membuffers_c,
     2358                **ffmpeg_pkgconfig))
     2359
    23352360toggle_packages(v4l2_ENABLED, "xpra.codecs.v4l2")
    23362361if v4l2_ENABLED:
    23372362    cython_add(Extension("xpra.codecs.v4l2.pusher",