From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from ffbox0-bg.ffmpeg.org (ffbox0-bg.ffmpeg.org [79.124.17.100]) by master.gitmailbox.com (Postfix) with ESMTPS id 21D694C38C for ; Thu, 4 Sep 2025 14:10:22 +0000 (UTC) Authentication-Results: ffbox; dkim=fail (Bad 0 bit rsa-sha256 signature.) header.d=tflc.us header.a=rsa-sha256 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ffmpeg.org; i=@ffmpeg.org; q=dns/txt; s=mail; t=1756995001; h=to : date : message-id : mime-version : reply-to : subject : list-id : list-archive : list-archive : list-help : list-owner : list-post : list-subscribe : list-unsubscribe : from : cc : content-type : content-transfer-encoding : from; bh=/VNmlXCpu28OhYp1AnR5JSLlsTjsmV6XUBt15VhbzAI=; b=qIFxwRlefgiouV2ZN3eFQEY3I39Pq7voaW+y3/esa2NF+tzwhIeNoL9U2EHHRaJqSy1vn wgBfSb3EIQkI4usJc/gIXAF8YH3VKNOj3wNslADuMOqZ1x+42PYG17yzLYDGzeme9HDeMCn /+4sYGqqyELE3nXNvIZeX+dpQtVpZbgnAyVXp9RgXS86ClzDXzU51Q/jpacx7mcz1CC78jU /L+Ks1lnjB9YlaXIr68x8yB5eIAycTGF7XzGDjlr6amId4yz984Ic4FY2YCCk3SBF6t0rpN 6WLakGK6s1bb9CpFrG8tXcXs8YxlgrewQgUtngajYacutCsWPobTuFJvsEfg== Received: from [172.19.0.4] (unknown [172.19.0.4]) by ffbox0-bg.ffmpeg.org (Postfix) with ESMTP id 50EC368E7ED; Thu, 4 Sep 2025 17:10:01 +0300 (EEST) ARC-Seal: i=1; cv=none; a=rsa-sha256; d=ffmpeg.org; s=arc; t=1756994979; b=FXmEHsLei1QBzqaDu4FcMuWQdUjSZveoqVMx+hltjwwHCjx0q27mcBZkOtn/Rn8NfELr6 zDYc4oose2yJ+tYGgDknaTS05rBzjY/NxPaSsY+rcGAw4Ias1FZYD8uUuRMZoVpMcVwL+nO K8M49hv5gZz/FKgXgIV/vX2k3xuS+n+Hpi6gHF6TRuEuJs7q0gZ8q17v1IRAC2mmFpZmyk2 FXQCrxoA/D90Ld1go9NTy94N7Q702arsOHwWTGZNm9xFRn5c0kyJ8AJyvrmIM9L9ugHQKEE vhHwm1Yy3g0XfaQdAbD9l7xpAPj/Ik/RSd+sYsbc44pUxi7tLEbq3An7yHdQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=ffmpeg.org; s=arc; t=1756994979; h=from : sender : reply-to : subject : date : message-id : to : cc : mime-version : content-type : content-transfer-encoding : content-id : content-description : resent-date : resent-from : resent-sender : resent-to : resent-cc : resent-message-id : in-reply-to : references : list-id : list-help : list-unsubscribe : list-subscribe : list-post : list-owner : list-archive; bh=afeNLBYwUMqW2rKs2AA/qLYwkPDx0i1zkTgx6OYBntM=; b=AXSccubptG4DQ0tTnRH85PG2b5fyL9KBLdxVdMvFJnhscftSvS3sFm0N26bn0oD07t941 gLo627F9cngr3Jf71uCQTBiUxmDhCzt0VLHV1S9xI38MiMVBy62j16RakLV8/qmTJ/ivgJy ByqmZc9sB2IQiNlAmLJ8ILWcWJF9AK40TPslqZmuCKdoE1vDKbV0J5+OYH/gVoOkxWDE2GL eSPer9cC6STTDdzh9BiLR6Ov6o/mjFNQnDJjZNCV54RIukQ6iU6kAB71Mhq3qu6IV1ocntx zSIxQmNIGb5+z9X0T5LzdGrDTnAqEqGkofEFlTe0+iVPL+yl7ftfS6F0lMGw== ARC-Authentication-Results: i=1; ffmpeg.org; dkim=fail header.d=tflc.us; arc=none; dmarc=none Authentication-Results: ffmpeg.org; dkim=fail header.d=tflc.us; arc=none (Message is not ARC signed); dmarc=none Received: from outbound.st.icloud.com (p-east2-cluster4-host7-snip4-4.eps.apple.com [57.103.78.235]) by ffbox0-bg.ffmpeg.org (Postfix) with ESMTPS id D12E268E6F9 for ; Thu, 4 Sep 2025 17:09:25 +0300 (EEST) Received: from outbound.st.icloud.com (unknown [127.0.0.2]) by p00-icloudmta-asmtp-us-east-1a-60-percent-6 (Postfix) with ESMTPS id E610118019F2; Thu, 4 Sep 2025 14:09:20 +0000 (UTC) Dkim-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=tflc.us; s=sig1; bh=FqVLRZUyAhI5lFopW3q/DaR+AuOyzdIUVRBd4zsT14I=; h=From:To:Subject:Date:Message-ID:MIME-Version:x-icloud-hme; b=GrXlYnEF9qGz0Wigjg+s3WLAP7BIvXJM5Bbm6h1bkouktpRNsp2h/ws9BM+9VVVwvgXw7EzXPyOjOuIotj6/dmA0m/YtG+c2t1+YPOmf8gDFWiL407w2Gr2hJu9/FiHzdqepoZt19bUnFbZjWRqmJgoBzOdxV7ZrSHHFfasoVFzsHg6v+islW9rJN6wMbFqedPLFHlcbLWaUzDZsO3JjM/kTKHqL+DV+xw4sX9aenFNXiSIxzzXVL+lzS6aHmqz6qN+qw6SG4yrbWMCmuMRcSPZ1QSU0ob1l96WGIehe5tLblRwofNpf9wxumCpSz4sK0I0EZ+Y8X8mwO9sMKWsjyg== mail-alias-created-date: 1727727383918 Received: from tainaka (st-asmtp-me-k8s.p00.prod.me.com [17.42.251.67]) by p00-icloudmta-asmtp-us-east-1a-60-percent-6 (Postfix) with ESMTPSA id DA12518019DE; Thu, 4 Sep 2025 14:08:14 +0000 (UTC) To: ffmpeg-devel@ffmpeg.org Date: Thu, 4 Sep 2025 10:08:40 -0400 Message-ID: <20250904140840.6590-1-paper@tflc.us> X-Mailer: git-send-email 2.51.0 MIME-Version: 1.0 X-Proofpoint-ORIG-GUID: yFfgw0LD1-e9-frfdE7JjlJJhvi6g-4P X-Proofpoint-Spam-Details-Enc: AW1haW4tMjUwOTA0MDE0MCBTYWx0ZWRfX19E4s+fbAm2n MCWSkoNGCFDSyQoykyYUARsobSN7XmQok0D+Dt+Q1ZZ6ln+uQsPxw7s4FEGudTi0aieVHR/JpLk aDB3oKJHHw/z4JcQ+bP8M6kkUm0fblDulxGpzDJPLvbI0ZjUEbKVc0QnF0HgHA9HgHu4A+doGZp GQeIjO5g7JUl7XpmV0LQIo6sCPCEPDDa/H/n/tVOe/13ai+LBY566mg4q1cvcb4UsdjlmyRbfUP tXcMhmygPQhpGX0P7ekW7g199rpJvwnyHqsGHcsqUmAJXFKAuCPElk3Vw7KYwwchiIxij76lw= X-Proofpoint-GUID: yFfgw0LD1-e9-frfdE7JjlJJhvi6g-4P X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1117,Hydra:6.1.9,FMLib:17.12.80.40 definitions=2025-09-04_05,2025-09-04_01,2025-03-28_01 X-Proofpoint-Spam-Details: rule=notspam policy=default score=0 bulkscore=0 mlxlogscore=999 suspectscore=0 malwarescore=0 phishscore=0 adultscore=0 clxscore=1030 spamscore=0 mlxscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.22.0-2506270000 definitions=main-2509040140 X-JNJ: AAAAAAABgJ+TnvxGs4RF7C9Fz5INGDLKkaAgQYfOZYLx139b48cLPfOy0HBFgxfgITbGNFg7r4FCVl3NosjgZ5N2sf1mvdGnE0Tk50GhAiNnKNnhmNJcuxQoCE+/AlECYkyCg6ejfYfuTJbaB1Kcx20MFWkmt/tcINwQyMGDqLf87bH8EyZUxnHwfGLdBo2dbA442IXOqtUeHCs/Jji+5MEv5PjocTc79sW1BA+kTDBoJFeiGVelZJfZ3eIpQ/9dz/bXGk7cKR2Vif4dBVhqw69c2V0MFAHhaXm2bDRAcRqq51Z0FNf9rsJp8WjprAUs4DBG/TesCfNrPCJM/SfXhSG2zjO1573VMTL88AokjeWKdHqQkjglHHj0ihh3v1LVGNtb5gwBr3wRI2Mz7OcR+7KpwaHd3n04Clms9yUlAg4//R+1nnrC+ND5JCCC4k9EHdiRt0YhfSdskuc6YPtPE0cVhGphxrxv4iYQ6ZUlBRFlBnas0bxEEBR8VFeunhfdRxqrY9teg4Am5GUwxC3KWR09bOmGMjCwt08= Message-ID-Hash: PHEO43YLIXVEIE45U3UZS33Z3WOWQLQ7 X-Message-ID-Hash: PHEO43YLIXVEIE45U3UZS33Z3WOWQLQ7 X-MailFrom: SRS0=t9bV=3P=tflc.us=paper@ffmpeg.org X-Mailman-Rule-Misses: dmarc-mitigation; no-senders; approved; loop; banned-address; header-match-ffmpeg-devel.ffmpeg.org-0; header-match-ffmpeg-devel.ffmpeg.org-1; header-match-ffmpeg-devel.ffmpeg.org-2; header-match-ffmpeg-devel.ffmpeg.org-3; emergency; member-moderation; nonmember-moderation; administrivia; implicit-dest; max-recipients; max-size; news-moderation; no-subject; digests; suspicious-header X-Mailman-Version: 3.3.10 Precedence: list Reply-To: FFmpeg development discussions and patches Subject: [FFmpeg-devel] [PATCH] avformat/libopenmpt: implement file reading callbacks List-Id: FFmpeg development discussions and patches Archived-At: Archived-At: List-Archive: List-Archive: List-Help: List-Owner: List-Post: List-Subscribe: List-Unsubscribe: From: Paper via ffmpeg-devel Cc: Paper Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Archived-At: List-Archive: List-Post: Before, this code would unnecessarily waste quite a bit of memory reading the entire file in, and in many cases just freeing the result and throwing it out anyway. This commit changes the behavior to use libopenmpt's callback structure. This is much more memory efficient, especially for particularly large files. Both pre-0.3.0 and post-0.3.0 preprocessor branches have been tested working with a plain amiga-style 'M.K.' module in ffplay. Signed-off-by: Paper --- libavformat/libopenmpt.c | 93 +++++++++++++++++++++++++++++----------- 1 file changed, 68 insertions(+), 25 deletions(-) diff --git a/libavformat/libopenmpt.c b/libavformat/libopenmpt.c index 46af4bff22..2c8aa2659a 100644 --- a/libavformat/libopenmpt.c +++ b/libavformat/libopenmpt.c @@ -46,17 +46,24 @@ typedef struct OpenMPTContext { int sample_rate; AVChannelLayout ch_layout; int subsong; + int interp; } OpenMPTContext; #define OFFSET(x) offsetof(OpenMPTContext, x) #define A AV_OPT_FLAG_AUDIO_PARAM #define D AV_OPT_FLAG_DECODING_PARAM static const AVOption options[] = { - { "sample_rate", "set sample rate", OFFSET(sample_rate), AV_OPT_TYPE_INT, { .i64 = 48000 }, 1000, INT_MAX, A | D }, - { "layout", "set channel layout", OFFSET(ch_layout), AV_OPT_TYPE_CHLAYOUT, { .str = "stereo" }, 0, 0, A | D }, - { "subsong", "set subsong", OFFSET(subsong), AV_OPT_TYPE_INT, { .i64 = -2 }, -2, INT_MAX, A | D, .unit = "subsong"}, - { "all", "all", 0, AV_OPT_TYPE_CONST, { .i64 = -1}, 0, 0, A | D, .unit = "subsong" }, - { "auto", "auto", 0, AV_OPT_TYPE_CONST, { .i64 = -2}, 0, 0, A | D, .unit = "subsong" }, + { "sample_rate", "set sample rate", OFFSET(sample_rate), AV_OPT_TYPE_INT, { .i64 = 48000 }, 1000, INT_MAX, A | D }, + { "layout", "set channel layout", OFFSET(ch_layout), AV_OPT_TYPE_CHLAYOUT, { .str = "stereo" }, 0, 0, A | D }, + { "subsong", "set subsong", OFFSET(subsong), AV_OPT_TYPE_INT, { .i64 = -2 }, -2, INT_MAX, A | D, .unit = "subsong"}, + { "all", "all", 0, AV_OPT_TYPE_CONST, { .i64 = -1 }, 0, 0, A | D, .unit = "subsong" }, + { "auto", "auto", 0, AV_OPT_TYPE_CONST, { .i64 = -2 }, 0, 0, A | D, .unit = "subsong" }, + { "interpolation", "set interpolation method", OFFSET(interp), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, INT_MAX, A | D, .unit = "interpolation"}, + { "default", "default", 0, AV_OPT_TYPE_CONST, { .i64 = 0 }, 0, 0, A | D, .unit = "interpolation"}, + { "none", "none", 0, AV_OPT_TYPE_CONST, { .i64 = 1 }, 0, 0, A | D, .unit = "interpolation"}, + { "linear", "linear", 0, AV_OPT_TYPE_CONST, { .i64 = 2 }, 0, 0, A | D, .unit = "interpolation"}, + { "cubic", "cubic", 0, AV_OPT_TYPE_CONST, { .i64 = 4 }, 0, 0, A | D, .unit = "interpolation"}, + { "8-tap-sinc", "8-tap windowed sinc", 0, AV_OPT_TYPE_CONST, { .i64 = 8 }, 0, 0, A | D, .unit = "interpolation"}, { NULL } }; @@ -69,6 +76,51 @@ static void openmpt_logfunc(const char *message, void *userdata) av_log(userdata, level, "%s\n", message); } +static size_t av_openmpt_read(void *stream, void *dst, size_t bytes) +{ + AVIOContext *ioctx = stream; + int r; + + /* avio_read takes an int, cap the size accordingly */ + if (bytes > (size_t)INT_MAX) + bytes = (size_t)INT_MAX; + + r = avio_read(ioctx, dst, bytes); + + return (r >= 0) ? r : 0; +} + +static int av_openmpt_seek(void *stream, int64_t offset, int whence) +{ + AVIOContext *ioctx = stream; + int whence_av; + + switch (whence) { + case OPENMPT_STREAM_SEEK_SET: whence_av = SEEK_SET; break; + case OPENMPT_STREAM_SEEK_CUR: whence_av = SEEK_CUR; break; + case OPENMPT_STREAM_SEEK_END: whence_av = SEEK_END; break; + /* invalid value, punt */ + default: return -1; + } + + /* openmpt expects stdio-style seek; don't return new position */ + return (avio_seek(ioctx, offset, whence_av) < 0) ? -1 : 0; +} + +static int64_t av_openmpt_tell(void *stream) +{ + AVIOContext *ioctx = stream; + int64_t r = avio_tell(ioctx); + + return (r < 0) ? -1 : r; +} + +static const openmpt_stream_callbacks openmpt_cbs = { + av_openmpt_read, + av_openmpt_seek, + av_openmpt_tell +}; + #define add_meta(s, name, meta) \ do { \ const char *value = meta; \ @@ -81,30 +133,14 @@ static int read_header_openmpt(AVFormatContext *s) { AVStream *st; OpenMPTContext *openmpt = s->priv_data; - int64_t size; - char *buf; #if OPENMPT_API_VERSION_AT_LEAST(0,3,0) int error; #endif int ret; - size = avio_size(s->pb); - if (size <= 0) - return AVERROR_INVALIDDATA; - buf = av_malloc(size); - if (!buf) - return AVERROR(ENOMEM); - size = avio_read(s->pb, buf, size); - if (size < 0) { - av_log(s, AV_LOG_ERROR, "Reading input buffer failed.\n"); - av_freep(&buf); - return size; - } - #if OPENMPT_API_VERSION_AT_LEAST(0,3,0) error = OPENMPT_ERROR_OK; - openmpt->module = openmpt_module_create_from_memory2(buf, size, openmpt_logfunc, s, NULL, NULL, &error, NULL, NULL); - av_freep(&buf); + openmpt->module = openmpt_module_create2(openmpt_cbs, s->pb, openmpt_logfunc, s, NULL, NULL, &error, NULL, NULL); if (!openmpt->module) { if (error == OPENMPT_ERROR_OUT_OF_MEMORY) return AVERROR(ENOMEM); @@ -114,12 +150,19 @@ static int read_header_openmpt(AVFormatContext *s) return AVERROR_UNKNOWN; } #else - openmpt->module = openmpt_module_create_from_memory(buf, size, openmpt_logfunc, s, NULL); - av_freep(&buf); + openmpt->module = openmpt_module_create(openmpt_cbs, s->pb, openmpt_logfunc, s, NULL); if (!openmpt->module) - return AVERROR_INVALIDDATA; + return AVERROR_INVALIDDATA; #endif + ret = openmpt_module_set_render_param(openmpt->module, + OPENMPT_MODULE_RENDER_INTERPOLATIONFILTER_LENGTH, + openmpt->interp); + if (!ret) { + av_log(s, AV_LOG_ERROR, "Invalid interpolation setting: %d\n", openmpt->interp); + return AVERROR(EINVAL); + } + if (openmpt->subsong >= openmpt_module_get_num_subsongs(openmpt->module)) { av_log(s, AV_LOG_ERROR, "Invalid subsong index: %d\n", openmpt->subsong); return AVERROR(EINVAL); -- 2.51.0 _______________________________________________ ffmpeg-devel mailing list -- ffmpeg-devel@ffmpeg.org To unsubscribe send an email to ffmpeg-devel-leave@ffmpeg.org