From patchwork Wed Sep 2 15:42:13 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Paul B Mahol X-Patchwork-Id: 22064 Return-Path: X-Original-To: patchwork@ffaux-bg.ffmpeg.org Delivered-To: patchwork@ffaux-bg.ffmpeg.org Received: from ffbox0-bg.mplayerhq.hu (ffbox0-bg.ffmpeg.org [79.124.17.100]) by ffaux.localdomain (Postfix) with ESMTP id 8D9FB4495C0 for ; Wed, 2 Sep 2020 18:50:54 +0300 (EEST) Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id 6AE6F68029E; Wed, 2 Sep 2020 18:50:54 +0300 (EEST) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from mail-lj1-f196.google.com (mail-lj1-f196.google.com [209.85.208.196]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id 9333B68028B for ; Wed, 2 Sep 2020 18:50:48 +0300 (EEST) Received: by mail-lj1-f196.google.com with SMTP id v12so6513425ljc.10 for ; Wed, 02 Sep 2020 08:50:48 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:subject:date:message-id; bh=ghQkMnZ5DcMoiZ58vhQCuiweXNHjNCt3tfXmyP5WW8s=; b=scF//S3hugv3CHaOWwscxS9SRYDsVoAAkVrW3Jh2lFwPRVYhVPSDXT4DfxAU7SuOd2 cCj/vdGrql4L3pB+Fs4lwyg7VnRLsK1qMXCOtXSLOEOREnx/vgOXGfnu4xTQWqRHX6nM 5kKlvkDBHzVd8FInq6vHwlezFiROS+7OSGc+YlfR1BNcycfVlmI4zKWPBZGgOWEKz3wC AVOStkmXjuzHu+ZS6wBwtaMjbrEzcM3w1cO6XkIOZoRBvBvjbWmf4NL7mJGnP4ZjWg/s xejxy0fKGWtGw6CR/sc8i4BDyBkTjskwH/PC8VR/9tYDqz3zCk0AftQF1J9RADnQJZXj K4Kw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:subject:date:message-id; bh=ghQkMnZ5DcMoiZ58vhQCuiweXNHjNCt3tfXmyP5WW8s=; b=priOpzl9bknqJIO1643HYYnN0MiJ9MK/1IxGI0oU7FEoRDtBC6WrBqDm1SuDGH0ufe u6QUivfc8pMdG2+Aic1d6zcuDf9qnwo2nfCJZiQjXYSV1JC04i6Bla5D7JG3GCLvDmgW 5CpGBoYwpiHRf9skAUKhXBWsOF8Wx7q369h8gYkP8mvZtAqL2ZYWwoqqyUXimBVLoUPJ +6COKqkBP56oFVUoAX62bpOvYR+GRQmrwYO2L62cbcSrbilQFDhH+Svcd6MBxRr2vLfu 7OQwYHoNq5ZEP06Bld/RwCBSTGLzopIa7wWyt+hG4LoAVvISla7z2CgaRoHV0emkk6s/ o92A== X-Gm-Message-State: AOAM531tPdnGlgXDKU5ZZDBoZ02CItl3QYHl0M+ML0V+L+tzrqarTh8Z I40j/5YSOC/M+AQ0XhzRX6mX/o/ujUawpw== X-Google-Smtp-Source: ABdhPJyto/5UcSFbrUzu9NU1Tr0zyS1BkaYnUDDgN+foDt5DqmxEBoKA3NsuhR1/HNUzvWSKilb00A== X-Received: by 2002:a50:8c66:: with SMTP id p93mr707412edp.156.1599061418649; Wed, 02 Sep 2020 08:43:38 -0700 (PDT) Received: from localhost.localdomain ([31.45.254.223]) by smtp.gmail.com with ESMTPSA id c2sm1972909edu.3.2020.09.02.08.43.37 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 02 Sep 2020 08:43:38 -0700 (PDT) From: Paul B Mahol To: ffmpeg-devel@ffmpeg.org Date: Wed, 2 Sep 2020 17:42:13 +0200 Message-Id: <20200902154213.5761-1-onemda@gmail.com> X-Mailer: git-send-email 2.17.1 Subject: [FFmpeg-devel] [PATCH] avcodec/dxtory: add support for vertically flipped frames 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 MIME-Version: 1.0 Errors-To: ffmpeg-devel-bounces@ffmpeg.org Sender: "ffmpeg-devel" Signed-off-by: Paul B Mahol --- libavcodec/dxtory.c | 144 ++++++++++++++++++++++++++++++++++---------- 1 file changed, 113 insertions(+), 31 deletions(-) diff --git a/libavcodec/dxtory.c b/libavcodec/dxtory.c index 4dd675316b..bc19f27951 100644 --- a/libavcodec/dxtory.c +++ b/libavcodec/dxtory.c @@ -32,9 +32,44 @@ #include "internal.h" #include "unary.h" +static void do_vflip(AVCodecContext *avctx, AVFrame *pic, int vflip) +{ + if (!vflip) + return; + + switch (pic->format) { + case AV_PIX_FMT_YUV444P: + pic->data[1] += (avctx->height - 1) * pic->linesize[1]; + pic->linesize[1] = -pic->linesize[1]; + pic->data[2] += (avctx->height - 1) * pic->linesize[2]; + pic->linesize[2] = -pic->linesize[2]; + case AV_PIX_FMT_BGR24: + case AV_PIX_FMT_RGB24: + pic->data[0] += (avctx->height - 1) * pic->linesize[0]; + pic->linesize[0] = -pic->linesize[0]; + break; + case AV_PIX_FMT_YUV410P: + pic->data[0] += (avctx->height - 1) * pic->linesize[0]; + pic->linesize[0] = -pic->linesize[0]; + pic->data[1] += ((avctx->height >> 2) - 1) * pic->linesize[1]; + pic->linesize[1] = -pic->linesize[1]; + pic->data[2] += ((avctx->height >> 2) - 1) * pic->linesize[2]; + pic->linesize[2] = -pic->linesize[2]; + break; + case AV_PIX_FMT_YUV420P: + pic->data[0] += (avctx->height - 1) * pic->linesize[0]; + pic->linesize[0] = -pic->linesize[0]; + pic->data[1] += ((avctx->height >> 1) - 1) * pic->linesize[1]; + pic->linesize[1] = -pic->linesize[1]; + pic->data[2] += ((avctx->height >> 1) - 1) * pic->linesize[2]; + pic->linesize[2] = -pic->linesize[2]; + break; + } +} + static int dxtory_decode_v1_rgb(AVCodecContext *avctx, AVFrame *pic, const uint8_t *src, int src_size, - int id, int bpp) + int id, int bpp, uint32_t vflipped) { int h; uint8_t *dst; @@ -49,6 +84,8 @@ static int dxtory_decode_v1_rgb(AVCodecContext *avctx, AVFrame *pic, if ((ret = ff_get_buffer(avctx, pic, 0)) < 0) return ret; + do_vflip(avctx, pic, vflipped); + dst = pic->data[0]; for (h = 0; h < avctx->height; h++) { memcpy(dst, src, avctx->width * bpp); @@ -56,11 +93,14 @@ static int dxtory_decode_v1_rgb(AVCodecContext *avctx, AVFrame *pic, dst += pic->linesize[0]; } + do_vflip(avctx, pic, vflipped); + return 0; } static int dxtory_decode_v1_410(AVCodecContext *avctx, AVFrame *pic, - const uint8_t *src, int src_size) + const uint8_t *src, int src_size, + uint32_t vflipped) { int h, w; uint8_t *Y1, *Y2, *Y3, *Y4, *U, *V; @@ -75,6 +115,8 @@ static int dxtory_decode_v1_410(AVCodecContext *avctx, AVFrame *pic, if ((ret = ff_get_buffer(avctx, pic, 0)) < 0) return ret; + do_vflip(avctx, pic, vflipped); + Y1 = pic->data[0]; Y2 = pic->data[0] + pic->linesize[0]; Y3 = pic->data[0] + pic->linesize[0] * 2; @@ -99,11 +141,14 @@ static int dxtory_decode_v1_410(AVCodecContext *avctx, AVFrame *pic, V += pic->linesize[2]; } + do_vflip(avctx, pic, vflipped); + return 0; } static int dxtory_decode_v1_420(AVCodecContext *avctx, AVFrame *pic, - const uint8_t *src, int src_size) + const uint8_t *src, int src_size, + uint32_t vflipped) { int h, w; uint8_t *Y1, *Y2, *U, *V; @@ -118,6 +163,8 @@ static int dxtory_decode_v1_420(AVCodecContext *avctx, AVFrame *pic, if ((ret = ff_get_buffer(avctx, pic, 0)) < 0) return ret; + do_vflip(avctx, pic, vflipped); + Y1 = pic->data[0]; Y2 = pic->data[0] + pic->linesize[0]; U = pic->data[1]; @@ -136,11 +183,14 @@ static int dxtory_decode_v1_420(AVCodecContext *avctx, AVFrame *pic, V += pic->linesize[2]; } + do_vflip(avctx, pic, vflipped); + return 0; } static int dxtory_decode_v1_444(AVCodecContext *avctx, AVFrame *pic, - const uint8_t *src, int src_size) + const uint8_t *src, int src_size, + uint32_t vflipped) { int h, w; uint8_t *Y, *U, *V; @@ -155,6 +205,8 @@ static int dxtory_decode_v1_444(AVCodecContext *avctx, AVFrame *pic, if ((ret = ff_get_buffer(avctx, pic, 0)) < 0) return ret; + do_vflip(avctx, pic, vflipped); + Y = pic->data[0]; U = pic->data[1]; V = pic->data[2]; @@ -169,6 +221,8 @@ static int dxtory_decode_v1_444(AVCodecContext *avctx, AVFrame *pic, V += pic->linesize[2]; } + do_vflip(avctx, pic, vflipped); + return 0; } @@ -270,7 +324,8 @@ static int dxtory_decode_v2(AVCodecContext *avctx, AVFrame *pic, const uint8_t *src, int src_size, decode_slice_func decode_slice, setup_lru_func setup_lru, - enum AVPixelFormat fmt) + enum AVPixelFormat fmt, + uint32_t vflipped) { GetByteContext gb, gb_check; GetBitContext gb2; @@ -301,6 +356,8 @@ static int dxtory_decode_v2(AVCodecContext *avctx, AVFrame *pic, if ((ret = ff_get_buffer(avctx, pic, 0)) < 0) return ret; + do_vflip(avctx, pic, vflipped); + for (slice = 0; slice < nslices; slice++) { slice_size = bytestream2_get_le32(&gb); @@ -322,6 +379,8 @@ static int dxtory_decode_v2(AVCodecContext *avctx, AVFrame *pic, avpriv_request_sample(avctx, "Not enough slice data available"); } + do_vflip(avctx, pic, vflipped); + return 0; } @@ -379,19 +438,20 @@ static int dx2_decode_slice_565(GetBitContext *gb, AVFrame *frame, } static int dxtory_decode_v2_565(AVCodecContext *avctx, AVFrame *pic, - const uint8_t *src, int src_size, int is_565) + const uint8_t *src, int src_size, int is_565, + uint32_t vflipped) { enum AVPixelFormat fmt = AV_PIX_FMT_RGB24; if (is_565) return dxtory_decode_v2(avctx, pic, src, src_size, dx2_decode_slice_565, setup_lru_565, - fmt); + fmt, vflipped); else return dxtory_decode_v2(avctx, pic, src, src_size, dx2_decode_slice_555, setup_lru_555, - fmt); + fmt, vflipped); } static int dx2_decode_slice_rgb(GetBitContext *gb, AVFrame *frame, @@ -424,12 +484,13 @@ static void default_setup_lru(uint8_t lru[3][8]) } static int dxtory_decode_v2_rgb(AVCodecContext *avctx, AVFrame *pic, - const uint8_t *src, int src_size) + const uint8_t *src, int src_size, + uint32_t vflipped) { return dxtory_decode_v2(avctx, pic, src, src_size, dx2_decode_slice_rgb, default_setup_lru, - AV_PIX_FMT_BGR24); + AV_PIX_FMT_BGR24, vflipped); } static int dx2_decode_slice_410(GetBitContext *gb, AVFrame *frame, @@ -466,12 +527,13 @@ static int dx2_decode_slice_410(GetBitContext *gb, AVFrame *frame, static int dxtory_decode_v2_410(AVCodecContext *avctx, AVFrame *pic, - const uint8_t *src, int src_size) + const uint8_t *src, int src_size, + uint32_t vflipped) { return dxtory_decode_v2(avctx, pic, src, src_size, dx2_decode_slice_410, default_setup_lru, - AV_PIX_FMT_YUV410P); + AV_PIX_FMT_YUV410P, vflipped); } static int dx2_decode_slice_420(GetBitContext *gb, AVFrame *frame, @@ -510,12 +572,13 @@ static int dx2_decode_slice_420(GetBitContext *gb, AVFrame *frame, } static int dxtory_decode_v2_420(AVCodecContext *avctx, AVFrame *pic, - const uint8_t *src, int src_size) + const uint8_t *src, int src_size, + uint32_t vflipped) { return dxtory_decode_v2(avctx, pic, src, src_size, dx2_decode_slice_420, default_setup_lru, - AV_PIX_FMT_YUV420P); + AV_PIX_FMT_YUV420P, vflipped); } static int dx2_decode_slice_444(GetBitContext *gb, AVFrame *frame, @@ -550,12 +613,13 @@ static int dx2_decode_slice_444(GetBitContext *gb, AVFrame *frame, } static int dxtory_decode_v2_444(AVCodecContext *avctx, AVFrame *pic, - const uint8_t *src, int src_size) + const uint8_t *src, int src_size, + uint32_t vflipped) { return dxtory_decode_v2(avctx, pic, src, src_size, dx2_decode_slice_444, default_setup_lru, - AV_PIX_FMT_YUV444P); + AV_PIX_FMT_YUV444P, vflipped); } static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame, @@ -563,57 +627,75 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame, { AVFrame *pic = data; const uint8_t *src = avpkt->data; - int ret; + uint32_t type; + int vflipped, ret; if (avpkt->size < 16) { av_log(avctx, AV_LOG_ERROR, "packet too small\n"); return AVERROR_INVALIDDATA; } - switch (AV_RB32(src)) { + type = AV_RB32(src); + vflipped = !!(type & 0x20); + + switch (type) { + case 0x01000021: case 0x01000001: ret = dxtory_decode_v1_rgb(avctx, pic, src + 16, avpkt->size - 16, - AV_PIX_FMT_BGR24, 3); + AV_PIX_FMT_BGR24, 3, vflipped); break; + case 0x01000029: case 0x01000009: - ret = dxtory_decode_v2_rgb(avctx, pic, src + 16, avpkt->size - 16); + ret = dxtory_decode_v2_rgb(avctx, pic, src + 16, avpkt->size - 16, vflipped); break; + case 0x02000021: case 0x02000001: - ret = dxtory_decode_v1_420(avctx, pic, src + 16, avpkt->size - 16); + ret = dxtory_decode_v1_420(avctx, pic, src + 16, avpkt->size - 16, vflipped); break; + case 0x02000029: case 0x02000009: - ret = dxtory_decode_v2_420(avctx, pic, src + 16, avpkt->size - 16); + ret = dxtory_decode_v2_420(avctx, pic, src + 16, avpkt->size - 16, vflipped); break; + case 0x03000021: case 0x03000001: - ret = dxtory_decode_v1_410(avctx, pic, src + 16, avpkt->size - 16); + ret = dxtory_decode_v1_410(avctx, pic, src + 16, avpkt->size - 16, vflipped); break; + case 0x03000029: case 0x03000009: - ret = dxtory_decode_v2_410(avctx, pic, src + 16, avpkt->size - 16); + ret = dxtory_decode_v2_410(avctx, pic, src + 16, avpkt->size - 16, vflipped); break; + case 0x04000021: case 0x04000001: - ret = dxtory_decode_v1_444(avctx, pic, src + 16, avpkt->size - 16); + ret = dxtory_decode_v1_444(avctx, pic, src + 16, avpkt->size - 16, vflipped); break; + case 0x04000029: case 0x04000009: - ret = dxtory_decode_v2_444(avctx, pic, src + 16, avpkt->size - 16); + ret = dxtory_decode_v2_444(avctx, pic, src + 16, avpkt->size - 16, vflipped); break; + case 0x17000021: case 0x17000001: ret = dxtory_decode_v1_rgb(avctx, pic, src + 16, avpkt->size - 16, - AV_PIX_FMT_RGB565LE, 2); + AV_PIX_FMT_RGB565LE, 2, vflipped); break; + case 0x17000029: case 0x17000009: - ret = dxtory_decode_v2_565(avctx, pic, src + 16, avpkt->size - 16, 1); + ret = dxtory_decode_v2_565(avctx, pic, src + 16, avpkt->size - 16, 1, vflipped); break; + case 0x18000021: + case 0x19000021: case 0x18000001: case 0x19000001: ret = dxtory_decode_v1_rgb(avctx, pic, src + 16, avpkt->size - 16, - AV_PIX_FMT_RGB555LE, 2); + AV_PIX_FMT_RGB555LE, 2, vflipped); break; + case 0x18000029: + case 0x19000029: case 0x18000009: case 0x19000009: - ret = dxtory_decode_v2_565(avctx, pic, src + 16, avpkt->size - 16, 0); + ret = dxtory_decode_v2_565(avctx, pic, src + 16, avpkt->size - 16, 0, vflipped); break; default: - avpriv_request_sample(avctx, "Frame header %"PRIX32, AV_RB32(src)); + avpriv_request_sample(avctx, "Frame header %"PRIX32, type); return AVERROR_PATCHWELCOME; }