From patchwork Thu Feb 1 12:43:00 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Jerome Martinez X-Patchwork-Id: 7470 Delivered-To: ffmpegpatchwork@gmail.com Received: by 10.2.156.27 with SMTP id q27csp3016005jak; Thu, 1 Feb 2018 04:43:10 -0800 (PST) X-Google-Smtp-Source: AH8x224kl3Vo69NR6HI9Vrf9/klula6HfudkyHKaWPmpbu4CBuVt2KKO1Nu311NVULsRCpHc8NYJ X-Received: by 10.28.106.26 with SMTP id f26mr25321752wmc.36.1517488990435; Thu, 01 Feb 2018 04:43:10 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1517488990; cv=none; d=google.com; s=arc-20160816; b=pmmHJZ37sV/8RwFhSDFLefcXSHMQXv9EdIUCP81Diwq09UAFXfseuWYCTwQG7nJnGl 9iyP5YtE5tFnod025ju1Z27dPKEOHjUGF1fLx1O2sUSBEGx1/9CjfKcxHZrtQVv9Zu5R NJai1ivNVQINogZhijYUu/UjRubgRJ9RuTpXcgqwP3lhlZCSEwVInfkly8JNN3x36E5z paD4UBN3AEZ2J2OBW7kpjPZE9775f8OjxnQj6stCSvjkHZYiWdbPgEU1PlKWMBZfKooy D4n2ji6GXtgsjsHvBWliqxWt/kgdBvC6pSgqw7LyUIY1s4OtXjD97M4XzbFdA++GWdKL nqyg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:reply-to:list-subscribe:list-help:list-post :list-archive:list-unsubscribe:list-id:precedence:subject :content-language:mime-version:user-agent:date:message-id:to:from :delivered-to:arc-authentication-results; bh=f9bzb5FJapEykzStk73C4bNyAdpeUGyVZ2uI/m3upb0=; b=n7/5W6KVZTTgB9wCtsYzXoclo6nIRw5DNCpzSbmnVtY/L8SWZrm2JM/k2b8tyUhBRD Kc019xEjMTP1B+bVrK3FO8dG9Y2B/fAc4LSAIrFpBRLycxjPjzlBBX34mDLDGgyADygr +ZG28dIDDUi5+BJs+TfJpyBXgaEpoDKZwLiUNeGoqZ/AVY0umB1UseWaDFxmZ3y5PEoe pdQ0ieqHSPs3A8op1L1Hyqwf+PjJPHHs6juY3F9JrwZKHlOvRI6zzj6ALS4LzPGf63Rq MlNZ3ZaAYk2Z4OT3K5KHzU/35Ryz1URqz7gvIwbzJKZt2u2vCvwf1ad41JC2YCIzh9QG SZ1Q== 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 19si1550800wmv.97.2018.02.01.04.43.07; Thu, 01 Feb 2018 04:43:10 -0800 (PST) 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 7D72A689B35; Thu, 1 Feb 2018 14:43:00 +0200 (EET) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from 16.mo5.mail-out.ovh.net (16.mo5.mail-out.ovh.net [87.98.174.144]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id 17D04689252 for ; Thu, 1 Feb 2018 14:42:54 +0200 (EET) Received: from player786.ha.ovh.net (b7.ovh.net [213.186.33.57]) by mo5.mail-out.ovh.net (Postfix) with ESMTP id 6CC931867D7 for ; Thu, 1 Feb 2018 13:42:59 +0100 (CET) Received: from [192.168.2.120] (p5DDB56EF.dip0.t-ipconnect.de [93.219.86.239]) (Authenticated sender: zen-lists@mediaarea.net) by player786.ha.ovh.net (Postfix) with ESMTPSA id 33F61800A3 for ; Thu, 1 Feb 2018 13:42:59 +0100 (CET) From: Jerome Martinez To: FFmpeg development discussions and patches Message-ID: <63dcf4c8-53bf-ef81-140a-025d6181818c@mediaarea.net> Date: Thu, 1 Feb 2018 13:43:00 +0100 User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64; rv:52.0) Gecko/20100101 Thunderbird/52.5.2 MIME-Version: 1.0 Content-Language: en-GB X-Ovh-Tracer-Id: 815995960332587197 X-VR-SPAMSTATE: OK X-VR-SPAMSCORE: -100 X-VR-SPAMCAUSE: gggruggvucftvghtrhhoucdtuddrgedtfedrtdeggdegjecutefuodetggdotefrodftvfcurfhrohhfihhlvgemucfqggfjpdevjffgvefmvefgnecuuegrihhlohhuthemuceftddtnecusecvtfgvtghiphhivghnthhsucdlqddutddtmd Subject: [FFmpeg-devel] [PATCH] avcodec/ffv1: Support for RGBA64 and GBRAP16 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 Errors-To: ffmpeg-devel-bounces@ffmpeg.org Sender: "ffmpeg-devel" Add support for 16-bit/component RGB with Alpha encoding and decoding in FFV1, both RGBA64 and GBRAP16 for encoding, GBRAP16 for decoding. Resulting bitstream was tested about lossless encoding/decoding by the compression from DPX to FFV1 then decompression from FFV1 to DPX, see commands below (resulting framemd5 hashes are all same). Resulting bitstream is decodable by another decoder (with same resulting framemd5 hash). Resulting bitstream passed through a conformance checker compared to current FFV1 specification IETF draft. About the patch: - some modified lines are not used (the ones not used when f->use32bit is 1), but it makes the code more coherent (especially because decode_rgb_frame signature is same for both 16-bit and 32-bit version) and prepares the support of RGBA with 10/12/14 bits/component. - GBRAP16 was chosen for decoding because GBRP16 is already used when no alpha, and the code is more prepared for planar pix_fmt when bit depth is >8. - "s->transparency = desc->nb_components == 4 || desc->nb_components == 2;" is a copy of a line a bit above about the detection of transparency, I preferred to reuse it as is even if "YA" 16-bit/component is not (yet) supported. FFmpeg commands used for tests: ./ffmpeg -i in.dpx -c:v ffv1 out.mkv ./ffmpeg -i in.dpx -pix_fmt gbrap16 -strict -2 -c:v ffv1 out2.mkv ./ffmpeg -i out.mkv out.dpx ./ffmpeg -i in.dpx -f framemd5 in.dpx.framemd5 ./ffmpeg -i out.mkv -pix_fmt rgba64be -f framemd5 out.mkv.framemd5 ./ffmpeg -i out2.mkv -pix_fmt rgba64be -f framemd5 out2.mkv.framemd5 ./ffmpeg -i out.dpx -f framemd5 out.dpx.framemd5 Test file used (renamed to in.dpx): https://mediaarea.net/temp/uncropped_DPX_4K_16bit_Overscan15pros.dpx Jérôme From 0e149afd7eadb1ec05cc79fff78337b2c543ad8e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=B4me=20Martinez?= Date: Thu, 1 Feb 2018 13:11:53 +0100 Subject: [PATCH] avcodec/ffv1: Support for RGBA64 and GBRAP16 --- libavcodec/ffv1dec.c | 14 ++++++++++---- libavcodec/ffv1dec_template.c | 6 +++++- libavcodec/ffv1enc.c | 16 ++++++++++++++-- libavcodec/ffv1enc_template.c | 10 +++++++--- 4 files changed, 36 insertions(+), 10 deletions(-) diff --git a/libavcodec/ffv1dec.c b/libavcodec/ffv1dec.c index 5eadb6b158..923b79f3ab 100644 --- a/libavcodec/ffv1dec.c +++ b/libavcodec/ffv1dec.c @@ -336,14 +336,16 @@ static int decode_slice(AVCodecContext *c, void *arg) decode_plane(fs, p->data[0] + ps*x + y*p->linesize[0] , width, height, p->linesize[0], 0, 2); decode_plane(fs, p->data[0] + ps*x + y*p->linesize[0] + 1, width, height, p->linesize[0], 1, 2); } else if (f->use32bit) { - uint8_t *planes[3] = { p->data[0] + ps * x + y * p->linesize[0], + uint8_t *planes[4] = { p->data[0] + ps * x + y * p->linesize[0], p->data[1] + ps * x + y * p->linesize[1], - p->data[2] + ps * x + y * p->linesize[2] }; + p->data[2] + ps * x + y * p->linesize[2], + p->data[3] + ps * x + y * p->linesize[3] }; decode_rgb_frame32(fs, planes, width, height, p->linesize); } else { - uint8_t *planes[3] = { p->data[0] + ps * x + y * p->linesize[0], + uint8_t *planes[4] = { p->data[0] + ps * x + y * p->linesize[0], p->data[1] + ps * x + y * p->linesize[1], - p->data[2] + ps * x + y * p->linesize[2] }; + p->data[2] + ps * x + y * p->linesize[2], + p->data[3] + ps * x + y * p->linesize[3] }; decode_rgb_frame(fs, planes, width, height, p->linesize); } if (fs->ac != AC_GOLOMB_RICE && f->version > 2) { @@ -694,6 +696,10 @@ static int read_header(FFV1Context *f) f->avctx->pix_fmt = AV_PIX_FMT_GBRP16; f->use32bit = 1; } + else if (f->avctx->bits_per_raw_sample == 16 && f->transparency) { + f->avctx->pix_fmt = AV_PIX_FMT_GBRAP16; + f->use32bit = 1; + } } else { av_log(f->avctx, AV_LOG_ERROR, "colorspace not supported\n"); return AVERROR(ENOSYS); diff --git a/libavcodec/ffv1dec_template.c b/libavcodec/ffv1dec_template.c index 37df766773..2904a44112 100644 --- a/libavcodec/ffv1dec_template.c +++ b/libavcodec/ffv1dec_template.c @@ -107,7 +107,7 @@ static av_always_inline int RENAME(decode_line)(FFV1Context *s, int w, return 0; } -static void RENAME(decode_rgb_frame)(FFV1Context *s, uint8_t *src[3], int w, int h, int stride[3]) +static void RENAME(decode_rgb_frame)(FFV1Context *s, uint8_t *src[4], int w, int h, int stride[4]) { int x, y, p; TYPE *sample[4][2]; @@ -158,10 +158,14 @@ static void RENAME(decode_rgb_frame)(FFV1Context *s, uint8_t *src[3], int w, int *((uint16_t*)(src[0] + x*2 + stride[0]*y)) = g; *((uint16_t*)(src[1] + x*2 + stride[1]*y)) = b; *((uint16_t*)(src[2] + x*2 + stride[2]*y)) = r; + if (s->transparency) + *((uint16_t*)(src[3] + x*2 + stride[3]*y)) = a; } else { *((uint16_t*)(src[0] + x*2 + stride[0]*y)) = b; *((uint16_t*)(src[1] + x*2 + stride[1]*y)) = g; *((uint16_t*)(src[2] + x*2 + stride[2]*y)) = r; + if (s->transparency) + *((uint16_t*)(src[3] + x*2 + stride[3]*y)) = a; } } } diff --git a/libavcodec/ffv1enc.c b/libavcodec/ffv1enc.c index c0c1558ffe..9ba5c6fcfd 100644 --- a/libavcodec/ffv1enc.c +++ b/libavcodec/ffv1enc.c @@ -624,6 +624,14 @@ FF_ENABLE_DEPRECATION_WARNINGS s->chroma_planes = 1; s->bits_per_raw_sample = 8; break; + case AV_PIX_FMT_RGBA64: + s->colorspace = 1; + s->transparency = 1; + s->chroma_planes = 1; + s->bits_per_raw_sample = 16; + s->use32bit = 1; + s->version = FFMAX(s->version, 1); + break; case AV_PIX_FMT_RGB48: s->colorspace = 1; s->chroma_planes = 1; @@ -649,10 +657,12 @@ FF_ENABLE_DEPRECATION_WARNINGS if (!avctx->bits_per_raw_sample && !s->bits_per_raw_sample) s->bits_per_raw_sample = 14; case AV_PIX_FMT_GBRP16: + case AV_PIX_FMT_GBRAP16: if (!avctx->bits_per_raw_sample && !s->bits_per_raw_sample) s->bits_per_raw_sample = 16; else if (!s->bits_per_raw_sample) s->bits_per_raw_sample = avctx->bits_per_raw_sample; + s->transparency = desc->nb_components == 4 || desc->nb_components == 2; s->colorspace = 1; s->chroma_planes = 1; if (s->bits_per_raw_sample >= 16) { @@ -1028,9 +1038,10 @@ static int encode_slice(AVCodecContext *c, void *arg) const int ps = av_pix_fmt_desc_get(c->pix_fmt)->comp[0].step; int ret; RangeCoder c_bak = fs->c; - const uint8_t *planes[3] = {p->data[0] + ps*x + y*p->linesize[0], + const uint8_t *planes[4] = {p->data[0] + ps*x + y*p->linesize[0], p->data[1] ? p->data[1] + ps*x + y*p->linesize[1] : NULL, - p->data[2] ? p->data[2] + ps*x + y*p->linesize[2] : NULL}; + p->data[2] ? p->data[2] + ps*x + y*p->linesize[2] : NULL, + p->data[3] ? p->data[3] + ps*x + y*p->linesize[3] : NULL}; fs->slice_coding_mode = 0; if (f->version > 3) { @@ -1322,6 +1333,7 @@ AVCodec ff_ffv1_encoder = { AV_PIX_FMT_YA8, AV_PIX_FMT_GRAY10, AV_PIX_FMT_GRAY12, AV_PIX_FMT_GBRP16, AV_PIX_FMT_RGB48, + AV_PIX_FMT_GBRAP16, AV_PIX_FMT_RGBA64, AV_PIX_FMT_NONE }, diff --git a/libavcodec/ffv1enc_template.c b/libavcodec/ffv1enc_template.c index b7eea0dd70..2763082540 100644 --- a/libavcodec/ffv1enc_template.c +++ b/libavcodec/ffv1enc_template.c @@ -122,8 +122,8 @@ static av_always_inline int RENAME(encode_line)(FFV1Context *s, int w, return 0; } -static int RENAME(encode_rgb_frame)(FFV1Context *s, const uint8_t *src[3], - int w, int h, const int stride[3]) +static int RENAME(encode_rgb_frame)(FFV1Context *s, const uint8_t *src[4], + int w, int h, const int stride[4]) { int x, y, p, i; const int ring_size = s->context_model ? 3 : 2; @@ -152,14 +152,18 @@ static int RENAME(encode_rgb_frame)(FFV1Context *s, const uint8_t *src[3], r = (v >> 16) & 0xFF; a = v >> 24; } else if (packed) { - const uint16_t *p = ((const uint16_t*)(src[0] + x*6 + stride[0]*y)); + const uint16_t *p = ((const uint16_t*)(src[0] + x*(3 + s->transparency)*2 + stride[0]*y)); r = p[0]; g = p[1]; b = p[2]; + if (s->transparency) + a = p[3]; } else if (sizeof(TYPE) == 4) { g = *((const uint16_t *)(src[0] + x*2 + stride[0]*y)); b = *((const uint16_t *)(src[1] + x*2 + stride[1]*y)); r = *((const uint16_t *)(src[2] + x*2 + stride[2]*y)); + if (s->transparency) + a = *((const uint16_t *)(src[3] + x*2 + stride[2]*y)); } else { b = *((const uint16_t *)(src[0] + x*2 + stride[0]*y)); g = *((const uint16_t *)(src[1] + x*2 + stride[1]*y));