From patchwork Fri Sep 20 02:59:49 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: martin schitter X-Patchwork-Id: 51669 Delivered-To: ffmpegpatchwork2@gmail.com Received: by 2002:a59:d154:0:b0:48e:c0f8:d0de with SMTP id bt20csp706310vqb; Thu, 19 Sep 2024 20:10:03 -0700 (PDT) X-Forwarded-Encrypted: i=2; AJvYcCUKFMjEs5o9SF3S4ccfnCWZfvB0XaDQun8zPgDW/MlVO3YFtcvMXcr2hri0M+g6IE4m4iKnkGG6OC0LcrUTIxuW@gmail.com X-Google-Smtp-Source: AGHT+IF+fR3ctbgZMDQVxdaL4jrHkrlrM35AZChOk0Pznijmh/NSrvJLb9V23YP/2VAkPF8lxnaP X-Received: by 2002:a05:651c:b26:b0:2ef:2f9e:dd1b with SMTP id 38308e7fff4ca-2f7cb2f69f8mr8630691fa.14.1726801802986; Thu, 19 Sep 2024 20:10:02 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1726801802; cv=none; d=google.com; s=arc-20240605; b=bfbih7XYfQXFstLf/JefeKTnxl1bRSjNUgB1XQQAu8DbZtnS74EhUWl2DsI7M67V4d JBx8KqWQ/hORapkLdfluXH8a/iUMeLDTaYEUfDtp0HBEAjQBeB8YH8KKCgIZVXqCnij0 sp3M5i1G8I1k5r3ul20Z8AGxibuT55fY8W4LlGMZNFvORLkjG0wCTh3vTJBGyYaEZILQ YF4jGfOJIVVHPdgCThaZgY6lVBjDWq3NQeWnIYYWz1gpW5kkODP72T7j0Vwa6T4SM/EF GUoKmnu04P+dNZURZ4LRfVZZCFQxSXhyWf3g5mhD755MTDLyQ+GMlzjgXf53DeuY9IQB +wnQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20240605; h=sender:errors-to:content-transfer-encoding:cc:reply-to :list-subscribe:list-help:list-post:list-archive:list-unsubscribe :list-id:precedence:subject:mime-version:references:in-reply-to :message-id:date:to:from:dkim-signature:delivered-to; bh=mH0K/llgclGcKqZg+rC+pOxhOtr/wG2hJ5VjNfNWKAI=; fh=igg3JDwkSkAbPTwY6V0OsEq0RUkG4DKWC8fVJg4GhMY=; b=KK6zF7fkRd/cJLwW0rZUroaH/brenE8miZqyHufgv8Qg37BmhWKphopSXYJZZrtRWT mAV7DBgRFXImceuccORDieGskjs5qfjcBi2Fuy7PaQ2s9seT2oK3N7ptIRmTM+R66rPF dKi+S7lW4ChsyD46HB8x2NzkD/b5KB9ECriBrZ9TYvxiKNt34PLv4RFQ1HFidnsBWCP7 wEWDT9z21ssRL9XR61Bkojw2Mifg1VNPDOdVkcGy2g2Q65xcOdx38amAOKD4QKnw+Bg0 kug29r2g03LaOpBN9Nhihcc+S1pm0x7in3lukpHYbb/jt0HSJfHBJ5CAqXb8Yr1RTTF6 mVfA==; dara=google.com ARC-Authentication-Results: i=1; mx.google.com; dkim=neutral (body hash did not verify) header.i=@mur.at header.s=dkim2 header.b=FEkInR3i; 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; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=mur.at Return-Path: Received: from ffbox0-bg.mplayerhq.hu (ffbox0-bg.ffmpeg.org. [79.124.17.100]) by mx.google.com with ESMTP id 38308e7fff4ca-2f79d35e102si40760841fa.318.2024.09.19.20.10.02; Thu, 19 Sep 2024 20:10:02 -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=@mur.at header.s=dkim2 header.b=FEkInR3i; 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; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=mur.at Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id E7E0168DB14; Fri, 20 Sep 2024 06:09:28 +0300 (EEST) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from efeu.mur.at (efeu.mur.at [89.106.208.42]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id B96BD68D901 for ; Fri, 20 Sep 2024 06:09:18 +0300 (EEST) Received: from localhost.localdomain (lan1.raspi.ma39.ffgraz.net [10.12.1.243]) by efeu.mur.at (Postfix) with ESMTPSA id 49FE2461A0; Fri, 20 Sep 2024 05:09:18 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple; d=mur.at; s=dkim2; t=1726801758; bh=DFe79CV/sHQFKszwL/mb0m7JPtoeOwKEJA7grf/IbnA=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=FEkInR3i1LiAuTSDI7quXVh2ZX09+1EaCRuRTCGgqgLQ3HQLtdl2FQ4FgqNyGkKA5 8Mrd+pjOMh3tTuVMULtzG8F/FOVyDgJIlOO5aCJfU1oXqL+jTn9yW1F3EeHl3SKjao BCTKtmgLDQtlZK/1jJx5E0itmKNnjWRCnumUOmTd+dTMYJIAAHK/64UBLsfLCVNXct /f2SgkAc4MdlS7jfQZ2m7TVo/RUm57cmQvqrzHkqVOHLuW2ibDEJ6UXgEqxgtJSSHj 6mKcsPnHbigiUc8qGI1Z9jKDI0OZ05GV6ADB0ImEf4Oqy898aiP3ab8qgYekUhgSf+ n9Z9ITDkLfmK6pQEyqlOCVar9tE0K+maTdRtxIfh81N8HXVEJanvNMghMFXFUmMpPo Ib5TNii/3AReey24xv6fWvxPsfQspFPTV6/No/awdZzYW8/1Ia4WOQEB46G8IhtqUt p+qzyauVsm1GAk6tMAeQ3Yu/Fc9zJFG1v5ZTeSOeeeaxeCcPheV From: Martin Schitter To: ffmpeg-devel@ffmpeg.org Date: Fri, 20 Sep 2024 04:59:49 +0200 Message-ID: <20240920030849.1976240-4-ms+git@mur.at> X-Mailer: git-send-email 2.45.2 In-Reply-To: <20240920030849.1976240-1-ms+git@mur.at> References: <20240920030849.1976240-1-ms+git@mur.at> MIME-Version: 1.0 Subject: [FFmpeg-devel] [PATCH v8 3/6] libavcodec/dnxuc_parser: DNxUncompressed essence parser 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 Cc: Martin Schitter Errors-To: ffmpeg-devel-bounces@ffmpeg.org Sender: "ffmpeg-devel" X-TUID: DkTdrQxeAmOw --- libavcodec/Makefile | 1 + libavcodec/dnxuc_parser.c | 124 ++++++++++++++++++++++++++++++++++++++ libavcodec/parsers.c | 1 + 3 files changed, 126 insertions(+) create mode 100644 libavcodec/dnxuc_parser.c diff --git a/libavcodec/Makefile b/libavcodec/Makefile index 936fc34..76366b3 100644 --- a/libavcodec/Makefile +++ b/libavcodec/Makefile @@ -1191,6 +1191,7 @@ OBJS-$(CONFIG_DCA_PARSER) += dca_parser.o dca_exss.o dca.o \ dca_sample_rate_tab.o OBJS-$(CONFIG_DIRAC_PARSER) += dirac_parser.o OBJS-$(CONFIG_DNXHD_PARSER) += dnxhd_parser.o dnxhddata.o +OBJS-$(CONFIG_DNXUC_PARSER) += dnxuc_parser.o OBJS-$(CONFIG_DOLBY_E_PARSER) += dolby_e_parser.o dolby_e_parse.o OBJS-$(CONFIG_DPX_PARSER) += dpx_parser.o OBJS-$(CONFIG_DVAUDIO_PARSER) += dvaudio_parser.o diff --git a/libavcodec/dnxuc_parser.c b/libavcodec/dnxuc_parser.c new file mode 100644 index 0000000..55d5763 --- /dev/null +++ b/libavcodec/dnxuc_parser.c @@ -0,0 +1,124 @@ +/* + * Avid DNxUncomressed / SMPTE RDD 50 parser + * Copyright (c) 2024 Martin Schitter + * + * 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 + */ + +/* + This parser for DNxUncompressed video data is mostly based on + reverse engineering of output generated by DaVinci Resolve 19 + but was later also checked against the SMPTE RDD 50 specification. + + Limitations: Multiple image planes are not supported. +*/ + +#include "avcodec.h" +#include "libavutil/intreadwrite.h" + +typedef struct DNxUcParseContext { + uint32_t fourcc_tag; + uint32_t width; + uint32_t height; + uint32_t nr_bytes; +} DNxUcParseContext; + +/* +DNxUncompressed frame data comes wrapped in nested boxes of metadata +(box structure: len + fourcc marker + data): + +[0-4] len of outer essence unit box (typically 37 bytes of header + frame data) +[4-7] fourcc 'pack' + +[8-11] len of "signal info box" (always 21) +[12-15] fourcc 'sinf' +[16-19] frame width / line packing size +[20-23] frame hight / nr of lines +[24-27] fourcc pixel format indicator +[28] frame_layout (0: progressive, 1: interlaced) + +[29-32] len of "signal data box" (nr of frame data bytes + 8) +[33-36] fourcc 'sdat' +[37-..] frame data + +A sequence of 'signal info'+'signal data' box pairs wrapped in +'icmp'(=image component) boxes can be utilized to compose more +complex multi plane images. +This feature is only partially supported in the present implementation. +We never pick more than the first pair of info and image data enclosed +in this way. +*/ + +static int dnxuc_parse(AVCodecParserContext *s, + AVCodecContext *avctx, + const uint8_t **poutbuf, int *poutbuf_size, + const uint8_t *buf, int buf_size) +{ + char fourcc_buf[5]; + const int HEADER_SIZE = 37; + int icmp_offset = 0; + + DNxUcParseContext *pc; + pc = (DNxUcParseContext *) s->priv_data; + + if (!buf_size) { + return 0; + } + if (buf_size > 16 && MKTAG('i','c','m','p') == AV_RL32(buf+12)){ + icmp_offset += 8; + } + if ( buf_size < 37 + icmp_offset /* check metadata structure expectations */ + || MKTAG('p','a','c','k') != AV_RL32(buf+4+icmp_offset) + || MKTAG('s','i','n','f') != AV_RL32(buf+12+icmp_offset) + || MKTAG('s','d','a','t') != AV_RL32(buf+33+icmp_offset)){ + av_log(avctx, AV_LOG_ERROR, "can't read DNxUncompressed metadata.\n"); + *poutbuf_size = 0; + return buf_size; + } + + pc->fourcc_tag = AV_RL32(buf+24+icmp_offset); + pc->width = AV_RL32(buf+16+icmp_offset); + pc->height = AV_RL32(buf+20+icmp_offset); + pc->nr_bytes = AV_RL32(buf+29+icmp_offset) - 8; + + if (!avctx->codec_tag) { + av_fourcc_make_string(fourcc_buf, pc->fourcc_tag); + av_log(avctx, AV_LOG_INFO, "dnxuc_parser: '%s' %dx%d %dbpp %d\n", + fourcc_buf, + pc->width, pc->height, + (pc->nr_bytes*8)/(pc->width*pc->height), + pc->nr_bytes); + avctx->codec_tag = pc->fourcc_tag; + } + + if (pc->nr_bytes > buf_size - HEADER_SIZE + icmp_offset){ + av_log(avctx, AV_LOG_ERROR, "Insufficient size of image essence data.\n"); + *poutbuf_size = 0; + return buf_size; + } + + *poutbuf = buf + HEADER_SIZE + icmp_offset; + *poutbuf_size = pc->nr_bytes; + + return buf_size; +} + +const AVCodecParser ff_dnxuc_parser = { + .codec_ids = { AV_CODEC_ID_DNXUC }, + .priv_data_size = sizeof(DNxUcParseContext), + .parser_parse = dnxuc_parse, +}; diff --git a/libavcodec/parsers.c b/libavcodec/parsers.c index 5128009..8bfd2db 100644 --- a/libavcodec/parsers.c +++ b/libavcodec/parsers.c @@ -35,6 +35,7 @@ extern const AVCodecParser ff_cri_parser; extern const AVCodecParser ff_dca_parser; extern const AVCodecParser ff_dirac_parser; extern const AVCodecParser ff_dnxhd_parser; +extern const AVCodecParser ff_dnxuc_parser; extern const AVCodecParser ff_dolby_e_parser; extern const AVCodecParser ff_dpx_parser; extern const AVCodecParser ff_dvaudio_parser;