From patchwork Sat Jun 5 14:51:39 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dennis Fleurbaaij X-Patchwork-Id: 28096 Delivered-To: ffmpegpatchwork2@gmail.com Received: by 2002:a6b:b214:0:0:0:0:0 with SMTP id b20csp2041591iof; Sat, 5 Jun 2021 08:19:08 -0700 (PDT) X-Google-Smtp-Source: ABdhPJxZ6DJBAF35PrGMQrXp6ZlpznIMZsK5anVXIyEGiM+BbFOUztqosKJnse7vegnI2TcOUoeh X-Received: by 2002:a05:6402:40c:: with SMTP id q12mr10677032edv.0.1622906348379; Sat, 05 Jun 2021 08:19:08 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1622906348; cv=none; d=google.com; s=arc-20160816; b=kHQf3CvEQQMHc/L5ddRcVLzAlwg1+SOie7GX3zgUIJ0UDvicpb7tXeMRSJRi4J2pvN O8xDF5QcAgqcjwfJtXHYmipav6cnh5nqItDzxvceVO1iK2bDEtWS78EZcj24+h8Asn+c JRkT1JfDrgFmaQemokRcqYYrX+ET2oB8lbe6lrE3i+/NHcit+zobVnaL3R6pIBCRrfN/ paADn8JuLvLaR+k8euLMT9b4PjPiVZxdCd2VoKxfcptY0NALepAVOwcEBd/IvCM3Nhr6 ExiawE3sbaGvQpfWNw1S0YRhYcvoznBfTMmPR9mmADpzzpihZa02pXgCuMeQT//TN5DE /Ipw== 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=Zc2iL/gWB0sN0C9UIsPQEOJL290YtgU7CklR9OhzzFQ=; b=R8IzA3dGyTOuOxfYvQb1oIIl0bhebhBFTv+Fi3F3O/RITWvBnwkTbcH0XR3eJHBGr3 kNk8S18pPQ29vWiQmiHBHLOI95XvnsrvxVct+hnJFAJJ37X1ymVN+THKTbe8camXyzD5 LBuWpnTw7y/xCURRx/V+Dtcx3ne3zwMqrxfiVs3KZFFkOqqI5hmiWJqTA50EYF6qRNC1 QcpYoX9x3Mve/HKWlW6BhIdNEqaz9VI5SbrVwnIOXa+xg9BUsGUhA2bCXNPZkAsJOdQC tFxcQ+PqU8Tv15D5GH3AOTf9ONUY7Pex+350i6Ci6nKKLxZ/qyDiLXNr+TLapK4ebQRl DqsA== 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=nXURidYA; 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 w12si7344367edv.297.2021.06.05.08.19.07; Sat, 05 Jun 2021 08:19:08 -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=nXURidYA; 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 12F066805A4; Sat, 5 Jun 2021 18:19:04 +0300 (EEST) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from mail-yb1-f169.google.com (mail-yb1-f169.google.com [209.85.219.169]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id 4CCD768A3C3 for ; Sat, 5 Jun 2021 18:18:57 +0300 (EEST) Received: by mail-yb1-f169.google.com with SMTP id f84so18145437ybg.0 for ; Sat, 05 Jun 2021 08:18:57 -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=FsmUlI/cUZyCXTtTsa8X71RmARZIybMUt7QGZWuwFdA=; b=nXURidYAX+p2HK//gVKIDZLgiN955EyfLzLCfhiG/rhk0/1Wmkaaq1LptPikpvKLYD uFw2EF3Vlyaye97ceZswiHVHqsjlvTIaPq6qnazD6D2xO7WC3UnOQ/0jnPIpsZaiU9x1 JLwfdAL1podmrLtLr5jE3mblbThQ1vkKwxfZFwxn3J3Bo2YY4vlUtpR9bNvsdRIiKef5 xZjGnLfmPhT0P+1PhkQ0FXSQY2AGkrYvQQy5l9z+7siu9UpljAI2JR0wWcncCyHn1pSL lYpIvAY1sUXrhJpRer5EqaMEqrfBr4a58VY1Fwr68nWmELN8oqTHoCWuvSP5Tf6Z4Sat jUBw== 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=FsmUlI/cUZyCXTtTsa8X71RmARZIybMUt7QGZWuwFdA=; b=dhRDO9ViIdZwVenWNMnPPCN6RD5DxJuqMrgXcbMPpKiBVRMqaCEWiq+RDd7faYM5t+ OPyZj073FeePqfbMWORacHb0XXLYRb/lJbRMcZqeuJ6HUn54lrHwEbAYYBmW/wmxpQ/U qRInWMwHMzrUNkDsIHTjuo4mdMo9Pbd707148NO8tk2HVyNyqM9SdiWfZuWT582dXNsL uCa1j0GZ3g+Oq0glyGNHnU9nDWZYmqT8d0obs9i9alJiWUxxYVE9jHKJ1E/jD+WsxwMX LvCIK0LETiCu73qoUP3H6WCYSIGZUMVmdptxlD89ABOWhpRLC+ql6Sn1MM4dtQcVPTYY dchw== X-Gm-Message-State: AOAM530U1j2t6GqpMAFIqR7novvzajBLR+W0TGoh5nvigmFHPF8idgg4 OS7afDaL6OdnznnE//bRUcbrCfQscVGlkHUeuFmIM3QW/GxZag== X-Received: by 2002:a9d:74c2:: with SMTP id a2mr6248289otl.324.1622904710349; Sat, 05 Jun 2021 07:51:50 -0700 (PDT) MIME-Version: 1.0 From: Dennis Fleurbaaij Date: Sat, 5 Jun 2021 16:51:39 +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: zsicZfwqHmpB Attempt nr three to get patchwork to see this patch; sorry for the spam. From ed84960978fe87772c304402e204c5e37742d235 Mon Sep 17 00:00:00 2001 From: Dennis Fleurbaaij Date: Sat, 5 Jun 2021 13:44:21 +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 --- 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 | 2 +- libavformat/riff.c | 1 + 8 files changed, 152 insertions(+), 1 deletion(-) 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 48165b9ac4..1288cecebe 100644 --- a/libavcodec/version.h +++ b/libavcodec/version.h @@ -28,7 +28,7 @@ #include "libavutil/version.h" #define LIBAVCODEC_VERSION_MAJOR 59 -#define LIBAVCODEC_VERSION_MINOR 1 +#define LIBAVCODEC_VERSION_MINOR 2 #define LIBAVCODEC_VERSION_MICRO 100 #define LIBAVCODEC_VERSION_INT AV_VERSION_INT(LIBAVCODEC_VERSION_MAJOR, \ 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') },