From patchwork Mon Feb 28 21:25:00 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Paul B Mahol X-Patchwork-Id: 34552 Delivered-To: ffmpegpatchwork2@gmail.com Received: by 2002:a05:6838:d078:0:0:0:0 with SMTP id x24csp3087500nkx; Mon, 28 Feb 2022 13:23:46 -0800 (PST) X-Google-Smtp-Source: ABdhPJzFhXqsgNqch3WtIuVObJkJw0QIAwLgRvEb0YcbeIzJajvaSNMCRSot36ZE7kJ8O1FPRGBU X-Received: by 2002:a17:906:2646:b0:6d5:d889:c92b with SMTP id i6-20020a170906264600b006d5d889c92bmr17170416ejc.696.1646083426529; Mon, 28 Feb 2022 13:23:46 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1646083426; cv=none; d=google.com; s=arc-20160816; b=gPX5WaRiI/jLasPuBNlDacmQ29Uvs4xvkcV3PAhM6QioQpwnJh6fVPYty4BEgqc8TB HWIfKtxXL7rMhtafag2gUCdGGThq5iykA9bKEG9I1dkVDeJ6M+2IjlCCLs0+1jN+IM6W fycKzznWNglPH+PEEQ0F/vJ21P6F9XDyFSsBRr+Q1TmrCJP1wY1G1/1ewPjS0iBklPMa je32MuAa64YHIjR02F7NMUk3vo7ewd0ysiNE+ss5Lw8pISx3rhm38Kja7JSQEOuNpUrK Q5GOJNfwd5h5GXMNzAPTGrJewmoeSsziHQy2r63eDP1bne4ocmdm6Y9NDCk+iavSMkwL eokQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:content-transfer-encoding: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=+UR65qHIeXkxFcfpCKGCF6uYsDxgptjWhOpgULhoeu4=; b=dL3J1GVCEpYhiEOtO+ncr1xUBX6/sWompqTMPFdMgTafdJ9SE+6D9HU615tjYNyncV Q9PHg6MILxl6iFBmJM5iOMcLM3QlAxAU+yTKmtdoBXSjJ3ee5CR89naEROq9sxEqFYv5 gB/Nluq6qVVhmsG1wZ6poa3YylQ3Xypw0KjFTlx6gy5Yc+8b1wCvWEHbfcLyBZXThmtk qE9vVh11J1xeG7+chqSeysswTlYvfrRi95sfjGOLr6Y7OTdlgt4A8B24W1Zx9bP2dG+9 qU/N7+Ki0mqAqalDwOpqHsAVhWsE//L/TMm7Vm8HLfjWGREBQlBhLKxuAUqCFKV7Mufo Aalg== ARC-Authentication-Results: i=1; mx.google.com; dkim=neutral (body hash did not verify) header.i=@gmail.com header.s=20210112 header.b=SR8bmcH3; 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=QUARANTINE dis=NONE) header.from=gmail.com Return-Path: Received: from ffbox0-bg.mplayerhq.hu (ffbox0-bg.ffmpeg.org. [79.124.17.100]) by mx.google.com with ESMTP id bs12-20020a170906d1cc00b006b3c5400071si6551411ejb.802.2022.02.28.13.23.45; Mon, 28 Feb 2022 13:23:46 -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; dkim=neutral (body hash did not verify) header.i=@gmail.com header.s=20210112 header.b=SR8bmcH3; 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=QUARANTINE dis=NONE) header.from=gmail.com Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id 6F11868B000; Mon, 28 Feb 2022 23:23:35 +0200 (EET) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from mail-ej1-f44.google.com (mail-ej1-f44.google.com [209.85.218.44]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id 4654D68B055 for ; Mon, 28 Feb 2022 23:23:28 +0200 (EET) Received: by mail-ej1-f44.google.com with SMTP id a23so27477305eju.3 for ; Mon, 28 Feb 2022 13:23:28 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=from:to:subject:date:message-id:in-reply-to:references:mime-version :content-transfer-encoding; bh=/0DAlkc6c/m6vXMLkW+pCF6cMxR1XOFSMmfLqhwYX8Y=; b=SR8bmcH33Ymf82sQfTsm63tmLNu1E4goMKpqU5lq9gyB+YwidM8kXLcA5BKa8jmVnI lZWyyhEEPziSv/GCsuldxvlifA0BqB4c4T2wTXDjcqsqibPkgasmVsSQj2Hl+74wZ0ML f65D/EVBenomT1iD01xSGGjpPIZ36xlN/aUeYK5AOVGw/RbaYcXMWKGZOn7jsj4n0ZNs /ufg4Qx5bwThCqaIjWhH+VHoIxGi8fAyBoKpyvWjIyyJ7uvQib0EFtZ6u8iBE4PhXjDG 21Iyc/fJZU4QgvG1FEpmyMT3FXWRoNwJGup0zGCbkbtVSLNRCVR9NApDsMoaLAEQix8l WFew== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=/0DAlkc6c/m6vXMLkW+pCF6cMxR1XOFSMmfLqhwYX8Y=; b=qTrOs2Mmf2FZ6y3Y01YdeNickDImoWwy/K8fYhVHYF0WSM4iheBkb9ya1jg15pMS3u Z72cUCJKX3Xhdf14d62fLaCX6OUEmBuRpKG60c2Yyiiq0Sv3/RAQmNV5HudBUlHNtwHL k2uv4OqIWLRyzi+25ZjZwn8q8SAQFuT3fmlzPnFqYnxBtS0LRg1I20YamD8/ZBdEklug aacmeRGWjO9drm2ylesfxK+p8g0S7NO2gcJWhfByUHSTF1FdmluJaHbzv8lWv8nP8V/N kedt0pXBcjIBSP/bW1/809GkelKXgOtZecaajSNc13jzboy52MZcjC4FkyPQMchslGYh ivsg== X-Gm-Message-State: AOAM532dBOnGDqkoMDoxwo9CroRVnQWotJT/07oh872jz1bkT2UCpQRG gpwHDWF22D33iDvAtfbEsh7l6JDNKbQ= X-Received: by 2002:a17:907:7f2a:b0:6d6:df12:7f57 with SMTP id qf42-20020a1709077f2a00b006d6df127f57mr1646932ejc.122.1646083407719; Mon, 28 Feb 2022 13:23:27 -0800 (PST) Received: from localhost.localdomain ([212.15.177.18]) by smtp.gmail.com with ESMTPSA id qx13-20020a170906fccd00b006bdeb94f50csm4666065ejb.203.2022.02.28.13.23.26 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 28 Feb 2022 13:23:27 -0800 (PST) From: Paul B Mahol To: ffmpeg-devel@ffmpeg.org Date: Mon, 28 Feb 2022 22:25:00 +0100 Message-Id: <20220228212500.7909-2-onemda@gmail.com> X-Mailer: git-send-email 2.33.0 In-Reply-To: <20220228212500.7909-1-onemda@gmail.com> References: <20220228212500.7909-1-onemda@gmail.com> MIME-Version: 1.0 Subject: [FFmpeg-devel] [PATCH 2/2] avcodec: add pcm-bluray encoder 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: kws1ojMBZ8G7 Signed-off-by: Paul B Mahol --- libavcodec/Makefile | 1 + libavcodec/allcodecs.c | 1 + libavcodec/pcm-blurayenc.c | 291 +++++++++++++++++++++++++++++++++++++ 3 files changed, 293 insertions(+) create mode 100644 libavcodec/pcm-blurayenc.c diff --git a/libavcodec/Makefile b/libavcodec/Makefile index 6076b4ad80..e34a9ae862 100644 --- a/libavcodec/Makefile +++ b/libavcodec/Makefile @@ -800,6 +800,7 @@ OBJS-$(CONFIG_ZMBV_ENCODER) += zmbvenc.o # (AD)PCM decoders/encoders OBJS-$(CONFIG_PCM_ALAW_DECODER) += pcm.o OBJS-$(CONFIG_PCM_ALAW_ENCODER) += pcm.o +OBJS-$(CONFIG_PCM_BLURAY_ENCODER) += pcm-blurayenc.o OBJS-$(CONFIG_PCM_BLURAY_DECODER) += pcm-bluray.o OBJS-$(CONFIG_PCM_DVD_DECODER) += pcm-dvd.o OBJS-$(CONFIG_PCM_DVD_ENCODER) += pcm-dvdenc.o diff --git a/libavcodec/allcodecs.c b/libavcodec/allcodecs.c index d1e10197de..1be67e3ec3 100644 --- a/libavcodec/allcodecs.c +++ b/libavcodec/allcodecs.c @@ -531,6 +531,7 @@ extern const AVCodec ff_xma2_decoder; /* PCM codecs */ extern const AVCodec ff_pcm_alaw_encoder; extern const AVCodec ff_pcm_alaw_decoder; +extern const AVCodec ff_pcm_bluray_encoder; extern const AVCodec ff_pcm_bluray_decoder; extern const AVCodec ff_pcm_dvd_encoder; extern const AVCodec ff_pcm_dvd_decoder; diff --git a/libavcodec/pcm-blurayenc.c b/libavcodec/pcm-blurayenc.c new file mode 100644 index 0000000000..c7b6981454 --- /dev/null +++ b/libavcodec/pcm-blurayenc.c @@ -0,0 +1,291 @@ +/* + * LPCM codecs for PCM formats found in Blu-ray m2ts streams + * + * 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 "libavutil/channel_layout.h" +#include "avcodec.h" +#include "bytestream.h" +#include "encode.h" +#include "internal.h" + +typedef struct BlurayPCMEncContext { + uint16_t header; // Header added to every frame +} BlurayPCMEncContext; + +static av_cold int pcm_bluray_encode_init(AVCodecContext *avctx) +{ + BlurayPCMEncContext *s = avctx->priv_data; + uint8_t ch_layout; + int quant, freq; + + switch (avctx->sample_rate) { + case 48000: + freq = 1; + break; + case 96000: + freq = 4; + break; + case 192000: + freq = 5; + break; + } + + switch (avctx->sample_fmt) { + case AV_SAMPLE_FMT_S16: + avctx->bits_per_coded_sample = 16; + quant = 1; + break; + case AV_SAMPLE_FMT_S32: + avctx->bits_per_coded_sample = 24; + quant = 3; + break; + } + + switch (avctx->channel_layout) { + case AV_CH_LAYOUT_MONO: + ch_layout = 1; + break; + case AV_CH_LAYOUT_STEREO: + ch_layout = 3; + break; + case AV_CH_LAYOUT_SURROUND: + ch_layout = 4; + break; + case AV_CH_LAYOUT_2_1: + ch_layout = 5; + break; + case AV_CH_LAYOUT_4POINT0: + ch_layout = 6; + break; + case AV_CH_LAYOUT_2_2: + ch_layout = 7; + break; + case AV_CH_LAYOUT_5POINT0: + ch_layout = 8; + break; + case AV_CH_LAYOUT_5POINT1: + ch_layout = 9; + break; + case AV_CH_LAYOUT_7POINT0: + ch_layout = 10; + break; + case AV_CH_LAYOUT_7POINT1: + ch_layout = 11; + break; + default: + return AVERROR_BUG; + } + + s->header = (((ch_layout << 4) | freq) << 8) | (quant << 6); + + return 0; +} + +static int pcm_bluray_encode_frame(AVCodecContext *avctx, AVPacket *avpkt, + const AVFrame *frame, int *got_packet_ptr) +{ + BlurayPCMEncContext *s = avctx->priv_data; + int sample_size, samples, channel, num_dest_channels; + const int16_t *src16; + const int32_t *src32; + unsigned pkt_size; + PutByteContext pb; + int ret; + + num_dest_channels = FFALIGN(avctx->channels, 2); + sample_size = (num_dest_channels * + (avctx->sample_fmt == AV_SAMPLE_FMT_S16 ? 16 : 24)) >> 3; + samples = frame->nb_samples; + + pkt_size = sample_size * samples + 4; + + if ((ret = ff_get_encode_buffer(avctx, avpkt, pkt_size, 0)) < 0) + return ret; + + AV_WB16(avpkt->data, pkt_size - 4); + AV_WB16(avpkt->data + 2, s->header); + + src16 = (const int16_t *)frame->data[0]; + src32 = (const int32_t *)frame->data[0]; + + bytestream2_init_writer(&pb, avpkt->data + 4, avpkt->size - 4); + + switch (avctx->channel_layout) { + /* cases with same number of source and coded channels */ + case AV_CH_LAYOUT_STEREO: + case AV_CH_LAYOUT_4POINT0: + case AV_CH_LAYOUT_2_2: + samples *= num_dest_channels; + if (AV_SAMPLE_FMT_S16 == avctx->sample_fmt) { +#if HAVE_BIGENDIAN + bytestream2_put_bufferu(&pb, frame->data[0], samples * 2); +#else + do { + bytestream2_put_be16u(&pb, *src16++); + } while (--samples); +#endif + } else { + do { + bytestream2_put_be24u(&pb, (*src32++) >> 8); + } while (--samples); + } + break; + /* cases where number of source channels = coded channels + 1 */ + case AV_CH_LAYOUT_MONO: + case AV_CH_LAYOUT_SURROUND: + case AV_CH_LAYOUT_2_1: + case AV_CH_LAYOUT_5POINT0: + if (AV_SAMPLE_FMT_S16 == avctx->sample_fmt) { + do { +#if HAVE_BIGENDIAN + bytestream2_put_bufferu(&pb, (const uint8_t *)src16, avctx->channels * 2); + src16 += avctx->channels; +#else + channel = avctx->channels; + do { + bytestream2_put_be16u(&pb, *src16++); + } while (--channel); +#endif + bytestream2_put_ne16(&pb, 0); + } while (--samples); + } else { + do { + channel = avctx->channels; + do { + bytestream2_put_be24u(&pb, (*src32++) >> 8); + } while (--channel); + bytestream2_put_ne24(&pb, 0); + } while (--samples); + } + break; + /* remapping: L, R, C, LBack, RBack, LF */ + case AV_CH_LAYOUT_5POINT1: + if (AV_SAMPLE_FMT_S16 == avctx->sample_fmt) { + do { + bytestream2_put_be16u(&pb, src16[0]); + bytestream2_put_be16u(&pb, src16[1]); + bytestream2_put_be16u(&pb, src16[2]); + bytestream2_put_be16u(&pb, src16[4]); + bytestream2_put_be16u(&pb, src16[5]); + bytestream2_put_be16u(&pb, src16[3]); + src16 += 6; + } while (--samples); + } else { + do { + bytestream2_put_be24u(&pb, src32[0] >> 8); + bytestream2_put_be24u(&pb, src32[1] >> 8); + bytestream2_put_be24u(&pb, src32[2] >> 8); + bytestream2_put_be24u(&pb, src32[4] >> 8); + bytestream2_put_be24u(&pb, src32[5] >> 8); + bytestream2_put_be24u(&pb, src32[3] >> 8); + src32 += 6; + } while (--samples); + } + break; + /* remapping: L, R, C, LSide, LBack, RBack, RSide, */ + case AV_CH_LAYOUT_7POINT0: + if (AV_SAMPLE_FMT_S16 == avctx->sample_fmt) { + do { + bytestream2_put_be16u(&pb, src16[0]); + bytestream2_put_be16u(&pb, src16[1]); + bytestream2_put_be16u(&pb, src16[2]); + bytestream2_put_be16u(&pb, src16[5]); + bytestream2_put_be16u(&pb, src16[3]); + bytestream2_put_be16u(&pb, src16[4]); + bytestream2_put_be16u(&pb, src16[6]); + src16 += 7; + bytestream2_put_ne16(&pb, 0); + } while (--samples); + } else { + do { + bytestream2_put_be24u(&pb, src32[0] >> 8); + bytestream2_put_be24u(&pb, src32[1] >> 8); + bytestream2_put_be24u(&pb, src32[2] >> 8); + bytestream2_put_be24u(&pb, src32[5] >> 8); + bytestream2_put_be24u(&pb, src32[3] >> 8); + bytestream2_put_be24u(&pb, src32[4] >> 8); + bytestream2_put_be24u(&pb, src32[6] >> 8); + src32 += 7; + bytestream2_put_ne24(&pb, 0); + } while (--samples); + } + break; + /* remapping: L, R, C, LSide, LBack, RBack, RSide, LF */ + case AV_CH_LAYOUT_7POINT1: + if (AV_SAMPLE_FMT_S16 == avctx->sample_fmt) { + do { + bytestream2_put_be16u(&pb, src16[0]); + bytestream2_put_be16u(&pb, src16[1]); + bytestream2_put_be16u(&pb, src16[2]); + bytestream2_put_be16u(&pb, src16[6]); + bytestream2_put_be16u(&pb, src16[4]); + bytestream2_put_be16u(&pb, src16[5]); + bytestream2_put_be16u(&pb, src16[7]); + bytestream2_put_be16u(&pb, src16[3]); + src16 += 8; + } while (--samples); + } else { + do { + bytestream2_put_be24u(&pb, src32[0]); + bytestream2_put_be24u(&pb, src32[1]); + bytestream2_put_be24u(&pb, src32[2]); + bytestream2_put_be24u(&pb, src32[6]); + bytestream2_put_be24u(&pb, src32[4]); + bytestream2_put_be24u(&pb, src32[5]); + bytestream2_put_be24u(&pb, src32[7]); + bytestream2_put_be24u(&pb, src32[3]); + src32 += 8; + } while (--samples); + } + break; + } + + avpkt->pts = frame->pts; + avpkt->duration = ff_samples_to_time_base(avctx, frame->nb_samples); + *got_packet_ptr = 1; + + return 0; +} + +const AVCodec ff_pcm_bluray_encoder = { + .name = "pcm_bluray", + .long_name = NULL_IF_CONFIG_SMALL("PCM signed 16|20|24-bit big-endian for Blu-ray media"), + .type = AVMEDIA_TYPE_AUDIO, + .id = AV_CODEC_ID_PCM_BLURAY, + .priv_data_size = sizeof(BlurayPCMEncContext), + .init = pcm_bluray_encode_init, + .encode2 = pcm_bluray_encode_frame, + .supported_samplerates = (const int[]) { 48000, 96000, 192000, 0 }, + .channel_layouts = (const uint64_t[]) { + AV_CH_LAYOUT_MONO, + AV_CH_LAYOUT_STEREO, + AV_CH_LAYOUT_SURROUND, + AV_CH_LAYOUT_2_1, + AV_CH_LAYOUT_4POINT0, + AV_CH_LAYOUT_2_2, + AV_CH_LAYOUT_5POINT0, + AV_CH_LAYOUT_5POINT1, + AV_CH_LAYOUT_7POINT0, + AV_CH_LAYOUT_7POINT1, + 0 }, + .sample_fmts = (const enum AVSampleFormat[]) { + AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_S32, AV_SAMPLE_FMT_NONE }, + .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE, + .capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_VARIABLE_FRAME_SIZE, +};