From patchwork Mon Jun 7 10:09:19 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dennis Fleurbaaij X-Patchwork-Id: 28125 Delivered-To: ffmpegpatchwork2@gmail.com Received: by 2002:a6b:b214:0:0:0:0:0 with SMTP id b20csp3347167iof; Mon, 7 Jun 2021 03:09:43 -0700 (PDT) X-Google-Smtp-Source: ABdhPJzoCWIrVEEGCaZVSL0jHKqfiahB7djBYkHa3vW8RmXxVpC95erCs1WucL73YXlIPs4Iv6uX X-Received: by 2002:a17:906:5a9a:: with SMTP id l26mr17155339ejq.490.1623060583299; Mon, 07 Jun 2021 03:09:43 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1623060583; cv=none; d=google.com; s=arc-20160816; b=0NsFfeveTI6smjvgKdZUYgXEumKQ+yg81dNBmM1QhLGeMuTYpIX+8kjMKGOu56/rep 9OOCHSzCm99WaxIC+QVIdVCgUUNvBxQWYctT2SxJYW09nWVHnwTVVUd23yhggT0b6oBx x7vzzTdJRxhBrpRTVK30EgDdmPV0I/VuqiwxsmmYfufSP1cB4/vXztnxDlZk3817Atvh wJQJWD9471qMxLOwq/IHifuYvuNMtHiL3GDpKStMs+0iDk5yqhAKYqtZY594nS6Hal3I mbKkao0pSXxtWA0tlqh5iCwOnFNGYm4fOfW9jw2ay7ILxgL6z2Rw8vWSJCQGTfWk3K5U IigQ== 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:to :message-id:date:from:mime-version:dkim-signature:delivered-to; bh=DGppg8EdUfzIb4PNWSg3HvJE4quBQbIRUbDt6IEgMbY=; b=hY9s6LeOzUY8Es+ekvhHQ7575O+D3IhG4I45rgRn+x/cBCLWFly6NVsP+4SY8FW1zF /ykwRABKjXGQfB3SpMDoPXKnM1N9ccX49fBuZ5UtWsbO0pCa4bGhVFDCrtDV/ol7TVVB w83ZVe5efT6vfbzdgiAJnGFnpLlGZF5I2OOkxkGGxR3SYZZaPAu+mGZIEnMgk4F1rI1C XJi1chmGxry8YmfAI3G8A63YljRgSFdjTicO4PlcHYP54ewaGZ5S9xDwNgGkG4KEfWFY v1yBUphAZRWe2ivDZALWOXNolMawR1cvLVA4DnRRks5/z2uazSleGNR8JBWkiYquyskR BMZA== ARC-Authentication-Results: i=1; mx.google.com; dkim=neutral (body hash did not verify) header.i=@dennisfleurbaaij-com.20150623.gappssmtp.com header.s=20150623 header.b=jY6fnSAn; 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 g15si11666678ejt.569.2021.06.07.03.09.42; Mon, 07 Jun 2021 03:09:43 -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; dkim=neutral (body hash did not verify) header.i=@dennisfleurbaaij-com.20150623.gappssmtp.com header.s=20150623 header.b=jY6fnSAn; 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 7E39F68052C; Mon, 7 Jun 2021 13:09:38 +0300 (EEST) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from mail-ot1-f42.google.com (mail-ot1-f42.google.com [209.85.210.42]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id 7B5C16801E6 for ; Mon, 7 Jun 2021 13:09:31 +0300 (EEST) Received: by mail-ot1-f42.google.com with SMTP id v27-20020a056830091bb02903cd67d40070so13084762ott.1 for ; Mon, 07 Jun 2021 03:09:31 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=dennisfleurbaaij-com.20150623.gappssmtp.com; s=20150623; h=mime-version:from:date:message-id:subject:to; bh=howviwZe2NSwSVwj3XX3Algd6lR6cva5ivnAxzxeSig=; b=jY6fnSAnkXFaWdlBUFR5VoktMbyc0p1lhkS4fTpKmn0VRKKu2TMyUdXTEi7QlWG7Mx /+gKk79HImR4CWQQtK7Ypp6vbHQvVTWhSo7y51jU8fVeSoHnVjNmv+zCqzEFC1sGliVE ENtgF6UHI8t+pWfQ6SFewxUNqPUQOcnryHdzm1rRcl/hTFPUbAKnipSe10ixDl2f4A9q Yf6tZ0QURzV5T1FFUWiSdg/aSudsKKAZ3xWFXbwackeG0WRxOifyskzDo3aOemiC+5Mc 3T4GYUiNeAEf1NedxgEuVAGvkbFTaeaxPUs7k4jHF0OTiOARahLoJh5ECqEHv24hVrhj HgNg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:mime-version:from:date:message-id:subject:to; bh=howviwZe2NSwSVwj3XX3Algd6lR6cva5ivnAxzxeSig=; b=GDzZ5WNx2MpVYLaCvgQYfj001HoLWoOWhRp75+oBd+dq1n33cRncUip60YoVNIjJWz fAnWCl99aY7YSMNdhboAYN30j8nrgJhdUzPT82LZLVpFDLKd3PxkA6kIj6VDg6BYeZIP RJ0bnoTj0iTbVrc/X4DGzOHdZQLBKRmKDF9LDnXqYo7opYQMs44YAo5fOGNpuAiOE9+K 5dxjxkvCmRSpCS2wUAF3ADskWmNtPaCNfz31xqCSx/3kztfpIU8qgpH8taDF4LflH/wr rnKQwn+yzNKf5A92SmCsp0FwT9rynlblrqhYx9LsSlLfVLZ8oaEEXwnfmK6fFQbuCI4A e+Pw== X-Gm-Message-State: AOAM533dum6qqPor2DBTQ6k5NUyrZw/7nKBSgcFlgDSBmPDyQ4k7sJga fjz+H01V0WeELXhtLZFxfNSVpBMLHpGhReyjehYxjPcw4nLkQw== X-Received: by 2002:a05:6830:2011:: with SMTP id e17mr12996152otp.295.1623060569592; Mon, 07 Jun 2021 03:09:29 -0700 (PDT) MIME-Version: 1.0 From: Dennis Fleurbaaij Date: Mon, 7 Jun 2021 12:09:19 +0200 Message-ID: To: FFmpeg development discussions and patches X-Content-Filtered-By: Mailman/MimeDel 2.1.29 Subject: [FFmpeg-devel] libavcodec: r12b decoder X-BeenThere: ffmpeg-devel@ffmpeg.org X-Mailman-Version: 2.1.29 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" X-TUID: xTO2sAVgdhTY Pulled master and re-applied to resolve version update conflict Kind regards, Dennis Fleurbaaij From b5fff34f545a107e07c9390a983e3a9aadb71a1c Mon Sep 17 00:00:00 2001 From: Dennis Fleurbaaij Date: Mon, 7 Jun 2021 12:06:51 +0200 Subject: [PATCH] libavcodec: r12b decoder added R12B is a format used by BlackMagic DeckLink cards, it is a big-endian 12bpp RGB format which packs 8 pixels into 36 bytes. Signed-off-by: Dennis Fleurbaaij Signed-off-by: Dennis Fleurbaaij --- Changelog | 1 + libavcodec/Makefile | 1 + libavcodec/allcodecs.c | 1 + libavcodec/codec_desc.c | 7 ++ libavcodec/codec_id.h | 1 + libavcodec/r12bdec.c | 139 ++++++++++++++++++++++++++++++++++++++++ libavcodec/version.h | 4 +- libavformat/riff.c | 1 + 8 files changed, 153 insertions(+), 2 deletions(-) create mode 100644 libavcodec/r12bdec.c diff --git a/Changelog b/Changelog index b9d5188cf6..d0717072eb 100644 --- a/Changelog +++ b/Changelog @@ -7,6 +7,7 @@ version : - ADPCM IMA Acorn Replay decoder - Argonaut Games CVG demuxer - Argonaut Games CVG muxer +- r12b decoder version 4.4: diff --git a/libavcodec/Makefile b/libavcodec/Makefile index 4fa8d7ab10..cfef9d57ff 100644 --- a/libavcodec/Makefile +++ b/libavcodec/Makefile @@ -575,6 +575,7 @@ OBJS-$(CONFIG_QTRLE_ENCODER) += qtrleenc.o OBJS-$(CONFIG_R10K_DECODER) += r210dec.o OBJS-$(CONFIG_R10K_ENCODER) += r210enc.o OBJS-$(CONFIG_R210_DECODER) += r210dec.o +OBJS-$(CONFIG_R12B_DECODER) += r12bdec.o OBJS-$(CONFIG_R210_ENCODER) += r210enc.o OBJS-$(CONFIG_RA_144_DECODER) += ra144dec.o ra144.o celp_filters.o OBJS-$(CONFIG_RA_144_ENCODER) += ra144enc.o ra144.o celp_filters.o diff --git a/libavcodec/allcodecs.c b/libavcodec/allcodecs.c index 623db2a9fa..8db7e730a6 100644 --- a/libavcodec/allcodecs.c +++ b/libavcodec/allcodecs.c @@ -266,6 +266,7 @@ extern const AVCodec ff_qtrle_encoder; extern const AVCodec ff_qtrle_decoder; extern const AVCodec ff_r10k_encoder; extern const AVCodec ff_r10k_decoder; +extern const AVCodec ff_r12b_decoder; extern const AVCodec ff_r210_encoder; extern const AVCodec ff_r210_decoder; extern const AVCodec ff_rasc_decoder; diff --git a/libavcodec/codec_desc.c b/libavcodec/codec_desc.c index 35527dcc37..ef58d73576 100644 --- a/libavcodec/codec_desc.c +++ b/libavcodec/codec_desc.c @@ -1856,6 +1856,13 @@ static const AVCodecDescriptor codec_descriptors[] = { .long_name = NULL_IF_CONFIG_SMALL("Digital Pictures SGA Video"), .props = AV_CODEC_PROP_LOSSY, }, + { + .id = AV_CODEC_ID_R12B, + .type = AVMEDIA_TYPE_VIDEO, + .name = "r12b", + .long_name = NULL_IF_CONFIG_SMALL("Uncompressed RGB 12-bit 8px in 36B"), + .props = AV_CODEC_PROP_INTRA_ONLY | AV_CODEC_PROP_LOSSLESS, + }, /* various PCM "codecs" */ { diff --git a/libavcodec/codec_id.h b/libavcodec/codec_id.h index 83e1dbb4b3..ecfdbc46c0 100644 --- a/libavcodec/codec_id.h +++ b/libavcodec/codec_id.h @@ -306,6 +306,7 @@ enum AVCodecID { AV_CODEC_ID_CRI, AV_CODEC_ID_SIMBIOSIS_IMX, AV_CODEC_ID_SGA_VIDEO, + AV_CODEC_ID_R12B, /* various PCM "codecs" */ AV_CODEC_ID_FIRST_AUDIO = 0x10000, ///< A dummy id pointing at the start of audio codecs diff --git a/libavcodec/r12bdec.c b/libavcodec/r12bdec.c new file mode 100644 index 0000000000..7d415a8fd6 --- /dev/null +++ b/libavcodec/r12bdec.c @@ -0,0 +1,139 @@ +/* + * r12b decoder + * + * Copyright (c) 2021 Dennis Fleurbaaij + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "avcodec.h" +#include "internal.h" +#include "libavutil/bswap.h" +#include "libavutil/common.h" + +#define WORDS_PER_BLOCK 9 +#define PIXELS_PER_BLOCK 8 +#define BYTES_PER_BLOCK 36 + +static av_cold int decode_init(AVCodecContext *avctx) +{ + avctx->pix_fmt = AV_PIX_FMT_GBRP12LE; + avctx->bits_per_raw_sample = 12; + + return 0; +} + +static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame, + AVPacket *avpkt) +{ + if (avctx->width % PIXELS_PER_BLOCK != 0) { + av_log(avctx, AV_LOG_ERROR, "image width not modulo 8\n"); + return AVERROR_INVALIDDATA; + } + + AVFrame *pic = data; + pic->pict_type = AV_PICTURE_TYPE_I; + pic->key_frame = 1; + + const uint8_t* src = (const uint8_t *)avpkt->data; + + const int blocks_per_line = avctx->width / PIXELS_PER_BLOCK; + + int ret; + if ((ret = ff_get_buffer(avctx, pic, 0)) < 0) + return ret; + + uint8_t* g_line = pic->data[0]; + uint8_t* b_line = pic->data[1]; + uint8_t* r_line = pic->data[2]; + + for (int h = 0; h < avctx->height; h++) { + uint16_t *g_dst = (uint16_t *)g_line; + uint16_t *b_dst = (uint16_t *)b_line; + uint16_t *r_dst = (uint16_t *)r_line; + + for (int w = 0; w < blocks_per_line; w++) { + + // This is an encoding from the table on page 213 of the BlackMagic + // Decklink SDK pdf, version 12.0. Few helper defines to directly link + // the naming in the doc to the code. + + #define GET_FF(word, byte) (*(src + ((word * 4) + byte))) + #define GET_0F(word, byte) (GET_FF(word, byte) & 0x0F) + #define GET_F0(word, byte) ((GET_FF(word, byte) & 0xF0) >> 4) + #define PUT(dst, pixel) (*(dst + pixel)) + + PUT(b_dst, 0) = GET_FF(0, 0) | GET_0F(1, 3) << 8; + PUT(g_dst, 0) = GET_F0(0, 2) | GET_FF(0, 1) << 4; + PUT(r_dst, 0) = GET_FF(0, 3) | GET_0F(0, 2) << 8; + + PUT(b_dst, 1) = GET_F0(1, 0) | GET_FF(2, 3) << 4; + PUT(g_dst, 1) = GET_FF(1, 1) | GET_0F(1, 0) << 8; + PUT(r_dst, 1) = GET_F0(1, 3) | GET_FF(1, 2) << 4; + + PUT(b_dst, 2) = GET_FF(3, 3) | GET_0F(3, 2) << 8; + PUT(g_dst, 2) = GET_F0(2, 1) | GET_FF(2, 0) << 4; + PUT(r_dst, 2) = GET_FF(2, 2) | GET_0F(2, 1) << 8; + + PUT(b_dst, 3) = GET_F0(4, 3) | GET_FF(4, 2) << 4; + PUT(g_dst, 3) = GET_FF(3, 0) | GET_0F(4, 3) << 8; + PUT(r_dst, 3) = GET_F0(3, 2) | GET_FF(3, 1) << 4; + + PUT(b_dst, 4) = GET_FF(5, 2) | GET_0F(5, 1) << 8; + PUT(g_dst, 4) = GET_F0(4, 0) | GET_FF(5, 3) << 4; + PUT(r_dst, 4) = GET_FF(4, 1) | GET_0F(4, 0) << 8; + + PUT(b_dst, 5) = GET_F0(6, 2) | GET_FF(6, 1) << 4; + PUT(g_dst, 5) = GET_FF(6, 3) | GET_0F(6, 2) << 8; + PUT(r_dst, 5) = GET_F0(5, 1) | GET_FF(5, 0) << 4; + + PUT(b_dst, 6) = GET_FF(7, 1) | GET_0F(7, 0) << 8; + PUT(g_dst, 6) = GET_F0(7, 3) | GET_FF(7, 2) << 4; + PUT(r_dst, 6) = GET_FF(6, 0) | GET_0F(7, 3) << 8; + + PUT(b_dst, 7) = GET_F0(8, 1) | GET_FF(8, 0) << 4; + PUT(g_dst, 7) = GET_FF(8, 2) | GET_0F(8, 1) << 8; + PUT(r_dst, 7) = GET_F0(7, 0) | GET_FF(8, 3) << 4; + + src += BYTES_PER_BLOCK; + b_dst += PIXELS_PER_BLOCK; + g_dst += PIXELS_PER_BLOCK; + r_dst += PIXELS_PER_BLOCK; + } + + g_line += pic->linesize[0]; + b_line += pic->linesize[1]; + r_line += pic->linesize[2]; + } + + *got_frame = 1; + + return avpkt->size; +} + +#if CONFIG_R12B_DECODER +const AVCodec ff_r12b_decoder = { + .name = "r12b", + .long_name = NULL_IF_CONFIG_SMALL("Uncompressed RGB 12-bit 8px in 36B"), + .type = AVMEDIA_TYPE_VIDEO, + .id = AV_CODEC_ID_R12B, + .init = decode_init, + .decode = decode_frame, + .capabilities = AV_CODEC_CAP_DR1, + .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE, +}; +#endif diff --git a/libavcodec/version.h b/libavcodec/version.h index 5b1e9e77f3..1288cecebe 100644 --- a/libavcodec/version.h +++ b/libavcodec/version.h @@ -28,8 +28,8 @@ #include "libavutil/version.h" #define LIBAVCODEC_VERSION_MAJOR 59 -#define LIBAVCODEC_VERSION_MINOR 1 -#define LIBAVCODEC_VERSION_MICRO 101 +#define LIBAVCODEC_VERSION_MINOR 2 +#define LIBAVCODEC_VERSION_MICRO 100 #define LIBAVCODEC_VERSION_INT AV_VERSION_INT(LIBAVCODEC_VERSION_MAJOR, \ LIBAVCODEC_VERSION_MINOR, \ diff --git a/libavformat/riff.c b/libavformat/riff.c index 270ff7c024..6e303f59ff 100644 --- a/libavformat/riff.c +++ b/libavformat/riff.c @@ -295,6 +295,7 @@ const AVCodecTag ff_codec_bmp_tags[] = { { AV_CODEC_ID_FRWU, MKTAG('F', 'R', 'W', 'U') }, { AV_CODEC_ID_R10K, MKTAG('R', '1', '0', 'k') }, { AV_CODEC_ID_R210, MKTAG('r', '2', '1', '0') }, + { AV_CODEC_ID_R12B, MKTAG('r', '1', '2', 'b') }, { AV_CODEC_ID_V210, MKTAG('v', '2', '1', '0') }, { AV_CODEC_ID_V210, MKTAG('C', '2', '1', '0') }, { AV_CODEC_ID_V308, MKTAG('v', '3', '0', '8') },