From patchwork Sun Aug 6 19:09:21 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Marton Balint X-Patchwork-Id: 4642 Delivered-To: ffmpegpatchwork@gmail.com Received: by 10.103.46.211 with SMTP id u202csp2008057vsu; Sun, 6 Aug 2017 12:10:19 -0700 (PDT) X-Received: by 10.28.40.66 with SMTP id o63mr406832wmo.33.1502046619750; Sun, 06 Aug 2017 12:10:19 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1502046619; cv=none; d=google.com; s=arc-20160816; b=H8gk7JEJIHASL8CacAisfqOjOiun2J/meVr6dXsGWlKed1GA3ElvF4LY2NwlPvXB5g dz6fkmddonCV5X9VeGdIJLd7mHhjSfvUIAVNWzoIs1yB9GZSh8V4K5e5lGyoaG4HpMHo EPOB9WPlI5w0eGWeRwaNRVEAi0iv71REyGi5MkfIQtVMZPzsRGEDOsweUxtaqD8fkCTP QawhF9bVGNbgmN6SYUExJkndaaK8XfIy98/qcaBDkhWkMo4oSNzBx/TBHVqa3lCxw4e1 t9ntOROq4o+viTPgwVHC/CprpIQ5ibpze2ipfh/H7f2od4nwOwHNykw6vdDXCorNOYKd uqIA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:content-transfer-encoding:mime-version:cc:reply-to :list-subscribe:list-help:list-post:list-archive:list-unsubscribe :list-id:precedence:subject:references:in-reply-to:message-id:date :to:from:delivered-to:arc-authentication-results; bh=R0ZiB4Riz7OR7eB8zFIfKe9dKGHPlTo/j+eP4oSda9Q=; b=cDt8GIZPef8T+2SJDClZfnCJ5DIFTDcFmIzejlXsAbNoV/pMH1ViNMh9EAK0LJWEGu 6BzPZyr35aWEYOoTs9pqV+txiDn1Ji6UO8ZQzkl2L6ssml4cc2Giz+RAxo0072KrmqHk NI9EtadjvcrffuksMjaM5S7QW/rz8a/iMgWKXEDbqW4C4k6M5H+YxoQG9bp6MmZqbP8m XOqnSZtLuP9KyqPai4u777agXs674UX59LNuT/Y8bM0CVADURfnYW7e6NQy4VBdXsHL6 qFDZpCr0cSaySFNo+j6wg/wfxwS1Coa3yxhigNnXtpO5i3T4jp7eYa2eslyIy6qJS7wa qBSw== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: domain of ffmpeg-devel-bounces@ffmpeg.org designates 79.124.17.100 as permitted sender) smtp.mailfrom=ffmpeg-devel-bounces@ffmpeg.org Return-Path: Received: from ffbox0-bg.mplayerhq.hu (ffbox0-bg.ffmpeg.org. [79.124.17.100]) by mx.google.com with ESMTP id l7si7135140wre.502.2017.08.06.12.10.19; Sun, 06 Aug 2017 12:10:19 -0700 (PDT) Received-SPF: pass (google.com: domain of ffmpeg-devel-bounces@ffmpeg.org designates 79.124.17.100 as permitted sender) client-ip=79.124.17.100; Authentication-Results: mx.google.com; spf=pass (google.com: domain of ffmpeg-devel-bounces@ffmpeg.org designates 79.124.17.100 as permitted sender) smtp.mailfrom=ffmpeg-devel-bounces@ffmpeg.org Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id C46666898CE; Sun, 6 Aug 2017 22:10:04 +0300 (EEST) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from iq.passwd.hu (iq.passwd.hu [217.27.212.140]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id 7A6BF689893 for ; Sun, 6 Aug 2017 22:09:58 +0300 (EEST) Received: from localhost (localhost [127.0.0.1]) by iq.passwd.hu (Postfix) with ESMTP id 9DBDC102F15; Sun, 6 Aug 2017 21:09:59 +0200 (CEST) X-Virus-Scanned: amavisd-new at passwd.hu Received: from iq.passwd.hu ([127.0.0.1]) by localhost (iq.passwd.hu [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id BsqewCTQYpFw; Sun, 6 Aug 2017 21:09:58 +0200 (CEST) Received: from bluegene.passwd.hu (localhost [127.0.0.1]) by iq.passwd.hu (Postfix) with ESMTP id 012EA103190; Sun, 6 Aug 2017 21:09:57 +0200 (CEST) From: Marton Balint To: ffmpeg-devel@ffmpeg.org Date: Sun, 6 Aug 2017 21:09:21 +0200 Message-Id: <20170806190921.10897-3-cus@passwd.hu> X-Mailer: git-send-email 2.13.1 In-Reply-To: <20170806190921.10897-1-cus@passwd.hu> References: <20170806190921.10897-1-cus@passwd.hu> Subject: [FFmpeg-devel] [PATCH 3/3] ffplay: add support for more SDL pixel formats when rendering video X-BeenThere: ffmpeg-devel@ffmpeg.org X-Mailman-Version: 2.1.20 Precedence: list List-Id: FFmpeg development discussions and patches List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Reply-To: FFmpeg development discussions and patches Cc: Marton Balint MIME-Version: 1.0 Errors-To: ffmpeg-devel-bounces@ffmpeg.org Sender: "ffmpeg-devel" Signed-off-by: Marton Balint --- ffplay.c | 114 +++++++++++++++++++++++++++++++++++++++++++++------------------ 1 file changed, 82 insertions(+), 32 deletions(-) diff --git a/ffplay.c b/ffplay.c index 8174caf4a6..7a9b76a93d 100644 --- a/ffplay.c +++ b/ffplay.c @@ -362,6 +362,32 @@ static AVPacket flush_pkt; static SDL_Window *window; static SDL_Renderer *renderer; +static const struct TextureFormatEntry { + enum AVPixelFormat format; + int texture_fmt; +} sdl_texture_format_map[] = { + { AV_PIX_FMT_RGB8, SDL_PIXELFORMAT_RGB332 }, + { AV_PIX_FMT_RGB444, SDL_PIXELFORMAT_RGB444 }, + { AV_PIX_FMT_RGB555, SDL_PIXELFORMAT_RGB555 }, + { AV_PIX_FMT_BGR555, SDL_PIXELFORMAT_BGR555 }, + { AV_PIX_FMT_RGB565, SDL_PIXELFORMAT_RGB565 }, + { AV_PIX_FMT_BGR565, SDL_PIXELFORMAT_BGR565 }, + { AV_PIX_FMT_RGB24, SDL_PIXELFORMAT_RGB24 }, + { AV_PIX_FMT_BGR24, SDL_PIXELFORMAT_BGR24 }, + { AV_PIX_FMT_0RGB32, SDL_PIXELFORMAT_RGB888 }, + { AV_PIX_FMT_0BGR32, SDL_PIXELFORMAT_BGR888 }, + { AV_PIX_FMT_NE(RGB0, 0BGR), SDL_PIXELFORMAT_RGBX8888 }, + { AV_PIX_FMT_NE(BGR0, 0RGB), SDL_PIXELFORMAT_BGRX8888 }, + { AV_PIX_FMT_RGB32, SDL_PIXELFORMAT_ARGB8888 }, + { AV_PIX_FMT_RGB32_1, SDL_PIXELFORMAT_RGBA8888 }, + { AV_PIX_FMT_BGR32, SDL_PIXELFORMAT_ABGR8888 }, + { AV_PIX_FMT_BGR32_1, SDL_PIXELFORMAT_BGRA8888 }, + { AV_PIX_FMT_YUV420P, SDL_PIXELFORMAT_IYUV }, + { AV_PIX_FMT_YUYV422, SDL_PIXELFORMAT_YUY2 }, + { AV_PIX_FMT_UYVY422, SDL_PIXELFORMAT_UYVY }, + { AV_PIX_FMT_NONE, SDL_PIXELFORMAT_UNKNOWN }, +}; + #if CONFIG_AVFILTER static int opt_add_vfilter(void *optctx, const char *opt, const char *arg) { @@ -820,6 +846,7 @@ static int realloc_texture(SDL_Texture **texture, Uint32 new_format, int new_wid memset(pixels, 0, pitch * new_height); SDL_UnlockTexture(*texture); } + av_log(NULL, AV_LOG_VERBOSE, "Created %dx%d texture with %s.\n", new_width, new_height, SDL_GetPixelFormatName(new_format)); } return 0; } @@ -855,31 +882,33 @@ static void calculate_display_rect(SDL_Rect *rect, rect->h = FFMAX(height, 1); } -static int upload_texture(SDL_Texture *tex, AVFrame *frame, struct SwsContext **img_convert_ctx) { +static void get_sdl_pix_fmt_and_blendmode(int format, Uint32 *sdl_pix_fmt, SDL_BlendMode *sdl_blendmode) +{ + int i; + *sdl_blendmode = SDL_BLENDMODE_NONE; + *sdl_pix_fmt = SDL_PIXELFORMAT_UNKNOWN; + if (format == AV_PIX_FMT_RGB32 || + format == AV_PIX_FMT_RGB32_1 || + format == AV_PIX_FMT_BGR32 || + format == AV_PIX_FMT_BGR32_1) + *sdl_blendmode = SDL_BLENDMODE_BLEND; + for (i = 0; i < FF_ARRAY_ELEMS(sdl_texture_format_map) - 1; i++) { + if (format == sdl_texture_format_map[i].format) { + *sdl_pix_fmt = sdl_texture_format_map[i].texture_fmt; + return; + } + } +} + +static int upload_texture(SDL_Texture **tex, AVFrame *frame, struct SwsContext **img_convert_ctx) { int ret = 0; - switch (frame->format) { - case AV_PIX_FMT_YUV420P: - if (frame->linesize[0] > 0 && frame->linesize[1] > 0 && frame->linesize[2] > 0) { - ret = SDL_UpdateYUVTexture(tex, NULL, frame->data[0], frame->linesize[0], - frame->data[1], frame->linesize[1], - frame->data[2], frame->linesize[2]); - } else if (frame->linesize[0] < 0 && frame->linesize[1] < 0 && frame->linesize[2] < 0) { - ret = SDL_UpdateYUVTexture(tex, NULL, frame->data[0] + frame->linesize[0] * (frame->height - 1), -frame->linesize[0], - frame->data[1] + frame->linesize[1] * (AV_CEIL_RSHIFT(frame->height, 1) - 1), -frame->linesize[1], - frame->data[2] + frame->linesize[2] * (AV_CEIL_RSHIFT(frame->height, 1) - 1), -frame->linesize[2]); - } else { - av_log(NULL, AV_LOG_ERROR, "Mixed negative and positive linesizes are not supported.\n"); - return -1; - } - break; - case AV_PIX_FMT_BGRA: - if (frame->linesize[0] < 0) { - ret = SDL_UpdateTexture(tex, NULL, frame->data[0] + frame->linesize[0] * (frame->height - 1), -frame->linesize[0]); - } else { - ret = SDL_UpdateTexture(tex, NULL, frame->data[0], frame->linesize[0]); - } - break; - default: + Uint32 sdl_pix_fmt; + SDL_BlendMode sdl_blendmode; + get_sdl_pix_fmt_and_blendmode(frame->format, &sdl_pix_fmt, &sdl_blendmode); + if (realloc_texture(tex, sdl_pix_fmt == SDL_PIXELFORMAT_UNKNOWN ? SDL_PIXELFORMAT_ARGB8888 : sdl_pix_fmt, frame->width, frame->height, sdl_blendmode, 0) < 0) + return -1; + switch (sdl_pix_fmt) { + case SDL_PIXELFORMAT_UNKNOWN: /* This should only happen if we are not using avfilter... */ *img_convert_ctx = sws_getCachedContext(*img_convert_ctx, frame->width, frame->height, frame->format, frame->width, frame->height, @@ -887,16 +916,37 @@ static int upload_texture(SDL_Texture *tex, AVFrame *frame, struct SwsContext ** if (*img_convert_ctx != NULL) { uint8_t *pixels[4]; int pitch[4]; - if (!SDL_LockTexture(tex, NULL, (void **)pixels, pitch)) { + if (!SDL_LockTexture(*tex, NULL, (void **)pixels, pitch)) { sws_scale(*img_convert_ctx, (const uint8_t * const *)frame->data, frame->linesize, 0, frame->height, pixels, pitch); - SDL_UnlockTexture(tex); + SDL_UnlockTexture(*tex); } } else { av_log(NULL, AV_LOG_FATAL, "Cannot initialize the conversion context\n"); ret = -1; } break; + case SDL_PIXELFORMAT_IYUV: + if (frame->linesize[0] > 0 && frame->linesize[1] > 0 && frame->linesize[2] > 0) { + ret = SDL_UpdateYUVTexture(*tex, NULL, frame->data[0], frame->linesize[0], + frame->data[1], frame->linesize[1], + frame->data[2], frame->linesize[2]); + } else if (frame->linesize[0] < 0 && frame->linesize[1] < 0 && frame->linesize[2] < 0) { + ret = SDL_UpdateYUVTexture(*tex, NULL, frame->data[0] + frame->linesize[0] * (frame->height - 1), -frame->linesize[0], + frame->data[1] + frame->linesize[1] * (AV_CEIL_RSHIFT(frame->height, 1) - 1), -frame->linesize[1], + frame->data[2] + frame->linesize[2] * (AV_CEIL_RSHIFT(frame->height, 1) - 1), -frame->linesize[2]); + } else { + av_log(NULL, AV_LOG_ERROR, "Mixed negative and positive linesizes are not supported.\n"); + return -1; + } + break; + default: + if (frame->linesize[0] < 0) { + ret = SDL_UpdateTexture(*tex, NULL, frame->data[0] + frame->linesize[0] * (frame->height - 1), -frame->linesize[0]); + } else { + ret = SDL_UpdateTexture(*tex, NULL, frame->data[0], frame->linesize[0]); + } + break; } return ret; } @@ -956,11 +1006,7 @@ static void video_image_display(VideoState *is) calculate_display_rect(&rect, is->xleft, is->ytop, is->width, is->height, vp->width, vp->height, vp->sar); if (!vp->uploaded) { - int sdl_pix_fmt = vp->frame->format == AV_PIX_FMT_YUV420P ? SDL_PIXELFORMAT_YV12 : SDL_PIXELFORMAT_ARGB8888; - SDL_BlendMode sdl_blendmode = vp->frame->format == AV_PIX_FMT_YUV420P ? SDL_BLENDMODE_NONE : SDL_BLENDMODE_BLEND; - if (realloc_texture(&is->vid_texture, sdl_pix_fmt, vp->frame->width, vp->frame->height, sdl_blendmode, 0) < 0) - return; - if (upload_texture(is->vid_texture, vp->frame, &is->img_convert_ctx) < 0) + if (upload_texture(&is->vid_texture, vp->frame, &is->img_convert_ctx) < 0) return; vp->uploaded = 1; vp->flip_v = vp->frame->linesize[0] < 0; @@ -1796,7 +1842,7 @@ fail: static int configure_video_filters(AVFilterGraph *graph, VideoState *is, const char *vfilters, AVFrame *frame) { - static const enum AVPixelFormat pix_fmts[] = { AV_PIX_FMT_YUV420P, AV_PIX_FMT_BGRA, AV_PIX_FMT_NONE }; + static enum AVPixelFormat pix_fmts[FF_ARRAY_ELEMS(sdl_texture_format_map)]; char sws_flags_str[512] = ""; char buffersrc_args[256]; int ret; @@ -1804,6 +1850,10 @@ static int configure_video_filters(AVFilterGraph *graph, VideoState *is, const c AVCodecParameters *codecpar = is->video_st->codecpar; AVRational fr = av_guess_frame_rate(is->ic, is->video_st, NULL); AVDictionaryEntry *e = NULL; + int i; + + for (i = 0; i < FF_ARRAY_ELEMS(pix_fmts); i++) + pix_fmts[i] = sdl_texture_format_map[i].format; while ((e = av_dict_get(sws_dict, "", e, AV_DICT_IGNORE_SUFFIX))) { if (!strcmp(e->key, "sws_flags")) {