From patchwork Fri Mar 8 11:19:14 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: asivery X-Patchwork-Id: 46901 Delivered-To: ffmpegpatchwork2@gmail.com Received: by 2002:a05:6a20:c995:b0:1a1:738b:6bc0 with SMTP id gy21csp870318pzb; Fri, 8 Mar 2024 03:19:42 -0800 (PST) X-Forwarded-Encrypted: i=2; AJvYcCWNSHTIX7JtqYKYWEu+Nk6HItzn1q2yqkdoP1VdsxmC7M5Xy6d0jXbWymXVP2X5lMYM6VzGVwMcUj2l/fCUbQlo3FgSmcFpw5th7w== X-Google-Smtp-Source: AGHT+IFBDoH6wb4baiY/VD03qO6gvtK7AxhnQobWY+N4Dvu6OSF0kutw+rvnqBNO9EZLj9kehxx7 X-Received: by 2002:a17:906:b0cb:b0:a45:7f4:666d with SMTP id bk11-20020a170906b0cb00b00a4507f4666dmr2816540ejb.38.1709896781991; Fri, 08 Mar 2024 03:19:41 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1709896781; cv=none; d=google.com; s=arc-20160816; b=txjitLcGL0NqWA7JkJsRyEm5rdtRQ2eZerJCy+OtJ5jivmjjBbb0ubfH6jvi+eMAZJ GOzfYaeTNpaa1f5MnLMACLolGus2QfZaEctOhPGRRFCPPzr24Yp9g9rIDyU2/fuGGnU4 BTBSWrciJK5unqt033fCK/kFJUPHXBlQ7ToIMO6HW1y41aJ9Ptv1u+k5jknLc53IrU6c zEV7d4ZiqeftxL0MtL9sKhaXFC2t5jYKiH/H4uYB+kR/muySmtq/vNGcZUZFWgYIYT+/ O8YCf4zw4zj6xeROd9BTpegmLT0R44zBTCWQa9zkb2fmpgcsb0s9pJ+3+acjBJDZ3qzi S+6w== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:cc:reply-to:from:list-subscribe:list-help :list-post:list-archive:list-unsubscribe:list-id:precedence:subject :mime-version:feedback-id:message-id:to:date:delivered-to; bh=w1bcJuhIMpXdAPsI7lvjA+PZgeEVqNhSAJQUIye5v+I=; fh=/vzrfkErvM5rUIE6V2K9h2lYRz6Ux36UUVz1g6mlCfw=; b=m8eWop6yuM1jNuPom5SmWrVeoAryZvGYI54WtePWMbUSNxcsp72w4F37cuXhk7MrCi elpF+OP+FFyL38FYhpQpx6Boti0yl2nn6TOI77h2OnaruHMurOdlxV3N8SPYlRMOAXD5 C34HdfegtMbL3fTErE2RBxeCca+G5LGTVvgR+tk601iVwg6R+9cbi1HDkZzavpxXWXwZ GrhK3iXsHWPc4zntIHaVKKtUfDwmawHsVgZ1unS5DsM+xebGm6NUEVz/4cvR2f9JHI9n KeuqNjebvK8K7IjEcK3V26on2J8TOn3naHGU/Xp/2XNQ8Cqtf67ynNwjPnbQveSjhjXn lsaQ==; dara=google.com 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 x1-20020a170906b08100b00a45e14d0ec0si931751ejy.871.2024.03.08.03.19.41; Fri, 08 Mar 2024 03:19:41 -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 84D4368CF01; Fri, 8 Mar 2024 13:19:39 +0200 (EET) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from mail-4324.protonmail.ch (mail-4324.protonmail.ch [185.70.43.24]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id EA80468CB1D for ; Fri, 8 Mar 2024 13:19:32 +0200 (EET) Date: Fri, 08 Mar 2024 11:19:14 +0000 To: ffmpeg-devel@ffmpeg.org Message-ID: Feedback-ID: 33509725:user:proton MIME-Version: 1.0 X-Content-Filtered-By: Mailman/MimeDel 2.1.29 Subject: [FFmpeg-devel] [PATCH] avformat/aea: Add aea muxer 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: , X-Patchwork-Original-From: asivery via ffmpeg-devel From: asivery Reply-To: FFmpeg development discussions and patches Cc: asivery Errors-To: ffmpeg-devel-bounces@ffmpeg.org Sender: "ffmpeg-devel" X-TUID: XtyNbA4av/0H Empty Message From 955fc035abbb5cfc1a52b1a5ea6900e4a21cef12 Mon Sep 17 00:00:00 2001 From: asivery Date: Fri, 8 Mar 2024 11:17:51 +0100 Subject: [PATCH] avformat/aea: Add aea muxer Signed-off-by: asivery --- libavformat/Makefile | 3 +- libavformat/{aea.c => aeadec.c} | 0 libavformat/aeaenc.c | 134 ++++++++++++++++++++++++++++++++ libavformat/allformats.c | 1 + 4 files changed, 137 insertions(+), 1 deletion(-) rename libavformat/{aea.c => aeadec.c} (100%) create mode 100644 libavformat/aeaenc.c diff --git a/libavformat/Makefile b/libavformat/Makefile index 4a380668bd..9855dcc707 100644 --- a/libavformat/Makefile +++ b/libavformat/Makefile @@ -91,7 +91,8 @@ OBJS-$(CONFIG_ADTS_MUXER) += adtsenc.o apetag.o img2.o \ id3v2enc.o OBJS-$(CONFIG_ADX_DEMUXER) += adxdec.o OBJS-$(CONFIG_ADX_MUXER) += rawenc.o -OBJS-$(CONFIG_AEA_DEMUXER) += aea.o pcm.o +OBJS-$(CONFIG_AEA_DEMUXER) += aeadec.o pcm.o +OBJS-$(CONFIG_AEA_MUXER) += aeaenc.o OBJS-$(CONFIG_AFC_DEMUXER) += afc.o OBJS-$(CONFIG_AIFF_DEMUXER) += aiffdec.o aiff.o pcm.o \ mov_chan.o replaygain.o diff --git a/libavformat/aea.c b/libavformat/aeadec.c similarity index 100% rename from libavformat/aea.c rename to libavformat/aeadec.c diff --git a/libavformat/aeaenc.c b/libavformat/aeaenc.c new file mode 100644 index 0000000000..3ce4cec1ee --- /dev/null +++ b/libavformat/aeaenc.c @@ -0,0 +1,134 @@ +/* + * MD STUDIO audio muxer + * + * Copyright (c) 2024 asivery + * + * 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 "libavutil/intreadwrite.h" +#include "libavutil/avstring.h" +#include "avformat.h" +#include "mux.h" + +typedef struct { + int block_count; +} AeaMuxerContext; + +static int aea_init(AVFormatContext *s) +{ + AeaMuxerContext *c = s->priv_data; + c->block_count = 0; + + return 0; +} + +static int aea_write_header(AVFormatContext *s) +{ + AVDictionaryEntry *title_entry; + int title_length = 0, i; + char* title_contents; + AVStream *st; + + + if (s->nb_streams > 1) { + av_log(s, AV_LOG_WARNING, "Got more than one stream to encode, they will be ignored.\n"); + } + + st = s->streams[0]; + if (st->codecpar->ch_layout.nb_channels != 1 && st->codecpar->ch_layout.nb_channels != 2) { + av_log(s, AV_LOG_ERROR, "Invalid amount of channels to mux (%d).\n", st->codecpar->ch_layout.nb_channels); + return AVERROR(EINVAL); + } + + if (st->codecpar->sample_rate != 44100) { + av_log(s, AV_LOG_ERROR, "Invalid sample rate (%d) AEA only supports 44.1kHz.\n", st->codecpar->sample_rate); + return AVERROR(EINVAL); + } + + /* Write magic */ + avio_wl32(s->pb, 2048); + + /* Write AEA title */ + title_entry = av_dict_get(st->metadata, "title", NULL, 0); + if (title_entry) { + title_contents = title_entry->value; + title_length = FFMIN(256, strlen(title_contents)); + } + + if (title_length) { + avio_write(s->pb, title_contents, title_length); + } + + for (i = 0; i<(256 - title_length); i++) { + avio_w8(s->pb, 0); + } + + /* Write number of frames (zero at header-writing time, will seek later), number of channels */ + avio_wl32(s->pb, 0); + avio_w8(s->pb, st->codecpar->ch_layout.nb_channels); + avio_w8(s->pb, 0); + + /* Write flags (meaning unknown) */ + for(i = 0; i<11; i++) { + avio_wl32(s->pb, 0); + } + + /* Pad the header to 2048 bytes */ + for(i = 0; i<1738; i++) avio_w8(s->pb, 0); + + return 0; +} + +static int aea_write_packet(struct AVFormatContext *s, AVPacket *pkt) +{ + AeaMuxerContext *c = s->priv_data; + c->block_count++; + + avio_write(s->pb, pkt->data, pkt->size); + return 0; +} + +static int aea_write_trailer(struct AVFormatContext *s) +{ + AVIOContext *pb = s->pb; + AeaMuxerContext *c = s->priv_data; + if (pb->seekable & AVIO_SEEKABLE_NORMAL) { + /* Seek to rewrite the block count. */ + avio_seek(pb, 260, SEEK_SET); + avio_wl32(pb, c->block_count * s->streams[0]->codecpar->ch_layout.nb_channels); + } else { + av_log(s, AV_LOG_WARNING, "unable to rewrite AEA header.\n"); + } + + return 0; +} + +const FFOutputFormat ff_aea_muxer = { + .p.name = "aea", + .p.long_name = NULL_IF_CONFIG_SMALL("MD STUDIO audio"), + .priv_data_size = sizeof(AeaMuxerContext), + .p.extensions = "aea", + .p.audio_codec = AV_CODEC_ID_ATRAC1, + .init = aea_init, + + .write_header = aea_write_header, + .write_packet = aea_write_packet, + .write_trailer = aea_write_trailer, + .p.flags = AVFMT_GENERIC_INDEX, +}; diff --git a/libavformat/allformats.c b/libavformat/allformats.c index b04b43cab3..1a50181447 100644 --- a/libavformat/allformats.c +++ b/libavformat/allformats.c @@ -46,6 +46,7 @@ extern const FFOutputFormat ff_adts_muxer; extern const AVInputFormat ff_adx_demuxer; extern const FFOutputFormat ff_adx_muxer; extern const AVInputFormat ff_aea_demuxer; +extern const FFOutputFormat ff_aea_muxer; extern const AVInputFormat ff_afc_demuxer; extern const AVInputFormat ff_aiff_demuxer; extern const FFOutputFormat ff_aiff_muxer; -- 2.34.1