From 746182d185960f988005af9e95b33569b0b20c20 Mon Sep 17 00:00:00 2001 From: Antoine Martin Date: Thu, 14 Mar 2013 09:55:10 +0000 Subject: [PATCH] window backings can now tell the video codecs if they are going to need swscale or not, and if not, we save on initialization/cleanup. (used by GL backing) git-svn-id: https://xpra.org/svn/Xpra/trunk@2964 3bb7dfac-3a0b-4e04-842a-767bc560f471 --- src/xpra/gl/gl_window_backing.py | 1 + src/xpra/vpx/codec.pyx | 9 ++++++--- src/xpra/vpx/vpxlib.c | 11 ++++++++--- src/xpra/vpx/vpxlib.h | 2 +- src/xpra/window_backing.py | 5 +++-- src/xpra/x264/codec.pyx | 8 +++++--- src/xpra/x264/x264lib.c | 17 +++++++++++------ src/xpra/x264/x264lib.h | 2 +- 8 files changed, 36 insertions(+), 19 deletions(-) diff --git a/src/xpra/gl/gl_window_backing.py b/src/xpra/gl/gl_window_backing.py index d209735e53..16324c534b 100644 --- a/src/xpra/gl/gl_window_backing.py +++ b/src/xpra/gl/gl_window_backing.py @@ -61,6 +61,7 @@ def __init__(self, wid, w, h, mmap_enabled, mmap): self.size = 0, 0 self.gl_setup = False self.paint_screen = False + self._video_use_swscale = False def init(self, w, h): #re-init gl context with new dimensions: diff --git a/src/xpra/vpx/codec.pyx b/src/xpra/vpx/codec.pyx index 6c20d7f959..b892eebceb 100644 --- a/src/xpra/vpx/codec.pyx +++ b/src/xpra/vpx/codec.pyx @@ -25,7 +25,7 @@ cdef extern from "vpxlib.h": int csc_image_yuv2rgb(vpx_codec_ctx_t *ctx, uint8_t *input[3], int stride[3], uint8_t **out, int *outsz, int *outstride) nogil int compress_image(vpx_codec_ctx_t *ctx, vpx_image_t *image, uint8_t **out, int *outsz) nogil - vpx_codec_ctx_t* init_decoder(int width, int height) + vpx_codec_ctx_t* init_decoder(int width, int height, int use_swscale) void clean_decoder(vpx_codec_ctx_t *context) int decompress_image(vpx_codec_ctx_t *context, uint8_t *input, int size, uint8_t *(*out)[3], int *outsize, int (*outstride)[3]) @@ -83,10 +83,12 @@ cdef class RGBImage: cdef class Decoder(xcoder): + cdef int use_swscale - def init_context(self, width, height, options): + def init_context(self, width, height, use_swscale, options): self.init(width, height) - self.context = init_decoder(width, height) + self.use_swscale = use_swscale + self.context = init_decoder(width, height, use_swscale) def clean(self): if self.context!=NULL: @@ -128,6 +130,7 @@ cdef class Decoder(xcoder): cdef Py_ssize_t buf_len = 0 #@DuplicatedSignature cdef int i = 0 #@DuplicatedSignature assert self.context!=NULL + assert self.use_swscale, "cannot decompress to rgb without swscale!" PyObject_AsReadBuffer(input, &buf, &buf_len) i = decompress_image(self.context, buf, buf_len, &yuvplanes, &outsize, &yuvstrides) if i!=0: diff --git a/src/xpra/vpx/vpxlib.c b/src/xpra/vpx/vpxlib.c index 48132896f8..b5bd5a4922 100644 --- a/src/xpra/vpx/vpxlib.c +++ b/src/xpra/vpx/vpxlib.c @@ -34,6 +34,7 @@ struct vpx_context { vpx_codec_ctx_t codec; + int use_swscale; struct SwsContext *rgb2yuv; struct SwsContext *yuv2rgb; int width; @@ -65,9 +66,11 @@ struct vpx_context *init_encoder(int width, int height) free(ctx); return NULL; } + ctx->use_swscale = 1; ctx->width = width; ctx->height = height; - ctx->rgb2yuv = sws_getContext(width, height, PIX_FMT_RGB24, width, height, PIX_FMT_YUV420P, SWS_FAST_BILINEAR, NULL, NULL, NULL); + if (ctx->use_swscale) + ctx->rgb2yuv = sws_getContext(width, height, PIX_FMT_RGB24, width, height, PIX_FMT_YUV420P, SWS_FAST_BILINEAR, NULL, NULL, NULL); return ctx; } @@ -77,7 +80,7 @@ void clean_encoder(struct vpx_context *ctx) free(ctx); } -struct vpx_context *init_decoder(int width, int height) +struct vpx_context *init_decoder(int width, int height, int use_swscale) { struct vpx_context *ctx = malloc(sizeof(struct vpx_context)); vpx_codec_iface_t *codec_iface = vpx_codec_vp8_dx(); @@ -89,9 +92,11 @@ struct vpx_context *init_decoder(int width, int height) free(ctx); return NULL; } + ctx->use_swscale = use_swscale; ctx->width = width; ctx->height = height; - ctx->yuv2rgb = sws_getContext(width, height, PIX_FMT_YUV420P, width, height, PIX_FMT_RGB24, SWS_FAST_BILINEAR, NULL, NULL, NULL); + if (ctx->use_swscale) + ctx->yuv2rgb = sws_getContext(width, height, PIX_FMT_YUV420P, width, height, PIX_FMT_RGB24, SWS_FAST_BILINEAR, NULL, NULL, NULL); return ctx; } diff --git a/src/xpra/vpx/vpxlib.h b/src/xpra/vpx/vpxlib.h index 71a19646a9..13a148fcbe 100644 --- a/src/xpra/vpx/vpxlib.h +++ b/src/xpra/vpx/vpxlib.h @@ -20,7 +20,7 @@ struct vpx_context; struct vpx_context *init_encoder(int width, int height); /** Create a decoding context for images of a given size. */ -struct vpx_context *init_decoder(int width, int height); +struct vpx_context *init_decoder(int width, int height, int use_swscale); /** Cleanup encoding context. Must be freed after calling this function. */ void clean_encoder(struct vpx_context *ctx); diff --git a/src/xpra/window_backing.py b/src/xpra/window_backing.py index 866dd9ae8d..2ccc421de7 100644 --- a/src/xpra/window_backing.py +++ b/src/xpra/window_backing.py @@ -74,6 +74,7 @@ def __init__(self, wid, mmap_enabled, mmap): self.mmap = mmap self._backing = None self._last_pixmap_data = None + self._video_use_swscale = True self._video_decoder = None self._video_decoder_lock = Lock() @@ -147,12 +148,12 @@ def paint_with_video_decoder(self, factory, coding, img_data, x, y, width, heigh if DRAW_DEBUG: log.info("paint_with_video_decoder: window dimensions have changed from %s to %s", (self._video_decoder.get_width(), self._video_decoder.get_height()), (width, height)) self._video_decoder.clean() - self._video_decoder.init_context(width, height, options) + self._video_decoder.init_context(width, height, self._video_use_swscale, options) if self._video_decoder is None: if DRAW_DEBUG: log.info("paint_with_video_decoder: new %s(%s,%s,%s)", factory, width, height, options) self._video_decoder = factory() - self._video_decoder.init_context(width, height, options) + self._video_decoder.init_context(width, height, self._video_use_swscale, options) if DRAW_DEBUG: log.info("paint_with_video_decoder: options=%s, decoder=%s", options, type(self._video_decoder)) self.do_video_paint(coding, img_data, x, y, width, height, options, callbacks) diff --git a/src/xpra/x264/codec.pyx b/src/xpra/x264/codec.pyx index 5612e47143..48e160208b 100644 --- a/src/xpra/x264/codec.pyx +++ b/src/xpra/x264/codec.pyx @@ -54,7 +54,7 @@ cdef extern from "x264lib.h": int get_encoder_speed(x264lib_ctx *ctx) int get_pixel_format(int csc_format) - x264lib_ctx* init_decoder(int width, int height, int csc_fmt) + x264lib_ctx* init_decoder(int width, int height, int use_swscale, int csc_fmt) void set_decoder_csc_format(x264lib_ctx *context, int csc_fmt) void clean_decoder(x264lib_ctx *context) int decompress_image(x264lib_ctx *context, uint8_t *input, int size, uint8_t *(*out)[3], int (*outstride)[3]) nogil @@ -118,10 +118,11 @@ cdef class RGBImage: cdef class Decoder(xcoder): - def init_context(self, width, height, options): + def init_context(self, width, height, use_swscale, options): self.init(width, height) + self.use_swscale = use_swscale csc_fmt = options.get("csc_pixel_format", -1) - self.context = init_decoder(width, height, csc_fmt) + self.context = init_decoder(width, height, use_swscale, csc_fmt) def clean(self): if self.context!=NULL: @@ -169,6 +170,7 @@ cdef class Decoder(xcoder): cdef Py_ssize_t buf_len = 0 #@DuplicatedSignature cdef int i = 0 assert self.context!=NULL + assert self.use_swscale, "cannot decompress to rgb without swscale!" PyObject_AsReadBuffer(input, &buf, &buf_len) padded_buf = xmemalign(buf_len+32) if padded_buf==NULL: diff --git a/src/xpra/x264/x264lib.c b/src/xpra/x264/x264lib.c index a14622d3dc..3e1670762b 100644 --- a/src/xpra/x264/x264lib.c +++ b/src/xpra/x264/x264lib.c @@ -57,6 +57,7 @@ struct x264lib_ctx { // Encoding x264_t *encoder; struct SwsContext *rgb2yuv; + int use_swscale; int speed; //percentage 0-100 int quality; //percentage 0-100 @@ -259,6 +260,7 @@ void configure_encoder(struct x264lib_ctx *ctx, int width, int height, char *i420_profile, char *i422_profile, char *i444_profile) { //printf("configure_encoder(%p, %i, %i, %i, %i, %i, %i, %s, %s, %s)\n", ctx, width, height, initial_quality, supports_csc_option, I422_quality, I444_quality, i420_profile, i422_profile, i444_profile); + ctx->use_swscale = 1; ctx->width = width; ctx->height = height; if (initial_speed >= 0) @@ -327,7 +329,8 @@ void do_init_encoder(struct x264lib_ctx *ctx) param.b_open_gop = 1; //allow open gop x264_param_apply_profile(¶m, ctx->profile); ctx->encoder = x264_encoder_open(¶m); - ctx->rgb2yuv = init_encoder_csc(ctx); + if (ctx->use_swscale) + ctx->rgb2yuv = init_encoder_csc(ctx); } struct x264lib_ctx *init_encoder(int width, int height, @@ -368,15 +371,17 @@ void do_clean_encoder(struct x264lib_ctx *ctx) } -int init_decoder_context(struct x264lib_ctx *ctx, int width, int height, int csc_fmt) +int init_decoder_context(struct x264lib_ctx *ctx, int width, int height, int use_swscale, int csc_fmt) { if (csc_fmt<0) csc_fmt = PIX_FMT_YUV420P; + ctx->use_swscale = use_swscale; ctx->width = width; ctx->height = height; ctx->csc_format = csc_fmt; ctx->csc_algo = get_csc_algo_for_quality(100); - ctx->yuv2rgb = sws_getContext(ctx->width, ctx->height, ctx->csc_format, ctx->width, ctx->height, PIX_FMT_RGB24, ctx->csc_algo, NULL, NULL, NULL); + if (use_swscale) + ctx->yuv2rgb = sws_getContext(ctx->width, ctx->height, ctx->csc_format, ctx->width, ctx->height, PIX_FMT_RGB24, ctx->csc_algo, NULL, NULL, NULL); avcodec_register_all(); @@ -404,13 +409,13 @@ int init_decoder_context(struct x264lib_ctx *ctx, int width, int height, int csc } return 0; } -struct x264lib_ctx *init_decoder(int width, int height, int csc_fmt) +struct x264lib_ctx *init_decoder(int width, int height, int use_swscale, int csc_fmt) { struct x264lib_ctx *ctx = malloc(sizeof(struct x264lib_ctx)); if (ctx==NULL) return NULL; memset(ctx, 0, sizeof(struct x264lib_ctx)); - if (init_decoder_context(ctx, width, height, csc_fmt)) { + if (init_decoder_context(ctx, width, height, use_swscale, csc_fmt)) { clean_decoder(ctx); return NULL; } @@ -518,7 +523,7 @@ void set_decoder_csc_format(struct x264lib_ctx *ctx, int csc_fmt) if (ctx->csc_format!=csc_fmt) { //we need to re-initialize with the new format: do_clean_decoder(ctx); - if (init_decoder_context(ctx, ctx->width, ctx->height, csc_fmt)) { + if (init_decoder_context(ctx, ctx->width, ctx->height, ctx->use_swscale, csc_fmt)) { fprintf(stderr, "Failed to reconfigure decoder\n"); } } diff --git a/src/xpra/x264/x264lib.h b/src/xpra/x264/x264lib.h index d67d4d3b58..13f66b81be 100644 --- a/src/xpra/x264/x264lib.h +++ b/src/xpra/x264/x264lib.h @@ -39,7 +39,7 @@ struct x264lib_ctx *init_encoder(int width, int height, char *i420_profile, char *i422_profile, char *i444_profile); /** Create a decoding context for images of a given size. */ -struct x264lib_ctx *init_decoder(int width, int height, int csc_fmt); +struct x264lib_ctx *init_decoder(int width, int height, int use_swscale, int csc_fmt); /** Call this before decoding, the decoder may need to be re-initialized with the new csc format */ void set_decoder_csc_format(struct x264lib_ctx *ctx, int csc_fmt);