From: mkver via ffmpeg-devel <ffmpeg-devel@ffmpeg.org>
To: ffmpeg-devel@ffmpeg.org
Cc: mkver <code@ffmpeg.org>
Subject: [FFmpeg-devel] [PR] avformat/cafenc: Simplify writing pakt box (PR #21609)
Date: Fri, 30 Jan 2026 14:17:59 -0000
Message-ID: <176978268033.25.9369479870127554602@4457048688e7> (raw)
PR #21609 opened by mkver
URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/21609
Patch URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/21609.patch
>From d845f9b7475c76da897aad5dfbab5c76e2a4df48 Mon Sep 17 00:00:00 2001
From: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
Date: Fri, 30 Jan 2026 14:25:00 +0100
Subject: [PATCH 1/2] avformat/cafenc: Simplify writing pakt box
Assemble it already in caf_write_packet(). This has the advantage
of reducing the amount of buffers used; it also allows to avoid
a seek when writing the trailer and avoids function call overhead
(for the avio_w8(); it also reduces codesize).
Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
---
libavformat/cafenc.c | 98 +++++++++++++++-----------------------------
1 file changed, 34 insertions(+), 64 deletions(-)
diff --git a/libavformat/cafenc.c b/libavformat/cafenc.c
index 5f2d79e0a7..4542cc7b04 100644
--- a/libavformat/cafenc.c
+++ b/libavformat/cafenc.c
@@ -19,6 +19,8 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
+#include <stdint.h>
+
#include "avformat.h"
#include "caf.h"
#include "isom.h"
@@ -36,10 +38,9 @@ typedef struct {
int64_t packets;
uint32_t frame_size;
- uint32_t *byte_size_buffer;
- uint32_t *frame_size_buffer;
- unsigned byte_size_buffer_sz;
- unsigned frame_size_buffer_sz;
+ uint8_t *pakt_buf;
+ unsigned pakt_buf_size;
+ unsigned pakt_buf_alloc_size;
} CAFContext;
static uint32_t codec_flags(enum AVCodecID codec_id) {
@@ -235,39 +236,39 @@ static int caf_write_header(AVFormatContext *s)
return 0;
}
+static uint8_t *put_variable_length_num(uint8_t *buf, uint32_t num)
+{
+ for (int j = 4; j > 0; j--) {
+ unsigned top = num >> j * 7;
+ if (top)
+ *(buf++) = top | 128;
+ }
+ *(buf++) = num & 127;
+ return buf;
+}
+
static int caf_write_packet(AVFormatContext *s, AVPacket *pkt)
{
CAFContext *caf = s->priv_data;
AVStream *const st = s->streams[0];
if (!st->codecpar->block_align || !caf->frame_size) {
- void *pkt_sizes;
- unsigned alloc_size = caf->packets + 1;
+#if SIZE_MAX - 10 < UINT_MAX
+ if (caf->pakt_buf_size > SIZE_MAX - 10)
+ return AVERROR(ERANGE);
+#endif
+ uint8_t *pakt_buf = av_fast_realloc(caf->pakt_buf, &caf->pakt_buf_alloc_size,
+ caf->pakt_buf_size + (size_t)10);
+ if (!pakt_buf)
+ return AVERROR(ENOMEM);
+ caf->pakt_buf = pakt_buf;
+ pakt_buf += caf->pakt_buf_size;
- if (!st->codecpar->block_align) {
- if (UINT_MAX / sizeof(*caf->byte_size_buffer) < alloc_size)
- return AVERROR(ERANGE);
-
- pkt_sizes = av_fast_realloc(caf->byte_size_buffer,
- &caf->byte_size_buffer_sz,
- alloc_size * sizeof(*caf->byte_size_buffer));
- if (!pkt_sizes)
- return AVERROR(ENOMEM);
- caf->byte_size_buffer = pkt_sizes;
- caf->byte_size_buffer[caf->packets] = pkt->size;
- }
- if (!caf->frame_size) {
- if (UINT_MAX / sizeof(*caf->frame_size_buffer) < alloc_size)
- return AVERROR(ERANGE);
-
- pkt_sizes = av_fast_realloc(caf->frame_size_buffer,
- &caf->frame_size_buffer_sz,
- alloc_size * sizeof(*caf->frame_size_buffer));
- if (!pkt_sizes)
- return AVERROR(ENOMEM);
- caf->frame_size_buffer = pkt_sizes;
- caf->frame_size_buffer[caf->packets] = pkt->duration;
- }
+ if (!st->codecpar->block_align)
+ pakt_buf = put_variable_length_num(pakt_buf, pkt->size);
+ if (!caf->frame_size)
+ pakt_buf = put_variable_length_num(pakt_buf, pkt->duration);
+ caf->pakt_buf_size = pakt_buf - caf->pakt_buf;
}
caf->packets++;
caf->total_duration += pkt->duration;
@@ -294,47 +295,17 @@ static int caf_write_trailer(AVFormatContext *s)
avio_wb64(pb, file_size - caf->data - 8);
if (!par->block_align || !caf->frame_size || par->initial_padding || remainder_frames) {
- int64_t size = 24;
-
valid_frames -= par->initial_padding;
valid_frames -= remainder_frames;
avio_seek(pb, file_size, SEEK_SET);
ffio_wfourcc(pb, "pakt");
- avio_wb64(pb, 0); // size, to be replaced
+ avio_wb64(pb, 24 + caf->pakt_buf_size); // size
avio_wb64(pb, packets); ///< mNumberPackets
avio_wb64(pb, valid_frames); ///< mNumberValidFrames
avio_wb32(pb, par->initial_padding); ///< mPrimingFrames
avio_wb32(pb, remainder_frames); ///< mRemainderFrames
- for (int i = 0; i < packets; i++) {
- if (!par->block_align) {
- for (int j = 4; j > 0; j--) {
- unsigned top = caf->byte_size_buffer[i] >> j * 7;
- if (top) {
- avio_w8(pb, 128 | (uint8_t)top);
- size++;
- }
- }
- avio_w8(pb, caf->byte_size_buffer[i] & 127);
- size++;
- }
- if (!caf->frame_size) {
- for (int j = 4; j > 0; j--) {
- unsigned top = caf->frame_size_buffer[i] >> j * 7;
- if (top) {
- avio_w8(pb, 128 | (uint8_t)top);
- size++;
- }
- }
- avio_w8(pb, caf->frame_size_buffer[i] & 127);
- size++;
- }
- }
-
- int64_t end = avio_tell(pb);
- avio_seek(pb, file_size + 4, SEEK_SET);
- avio_wb64(pb, size);
- avio_seek(pb, end, SEEK_SET);
+ avio_write(pb, caf->pakt_buf, caf->pakt_buf_size);
}
}
@@ -345,8 +316,7 @@ static void caf_write_deinit(AVFormatContext *s)
{
CAFContext *caf = s->priv_data;
- av_freep(&caf->byte_size_buffer);
- av_freep(&caf->frame_size_buffer);
+ av_freep(&caf->pakt_buf);
}
const FFOutputFormat ff_caf_muxer = {
--
2.52.0
>From 2b82ab60fea0327a2fd606976fc677ae255902dc Mon Sep 17 00:00:00 2001
From: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
Date: Fri, 30 Jan 2026 15:02:33 +0100
Subject: [PATCH 2/2] avformat/cafenc: don't keep track of nb packets ourselves
Just reuse AVStream.nb_frames.
Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
---
libavformat/cafenc.c | 6 ++----
1 file changed, 2 insertions(+), 4 deletions(-)
diff --git a/libavformat/cafenc.c b/libavformat/cafenc.c
index 4542cc7b04..8879d13940 100644
--- a/libavformat/cafenc.c
+++ b/libavformat/cafenc.c
@@ -35,7 +35,6 @@
typedef struct {
int64_t data;
int64_t total_duration;
- int64_t packets;
uint32_t frame_size;
uint8_t *pakt_buf;
@@ -270,7 +269,6 @@ static int caf_write_packet(AVFormatContext *s, AVPacket *pkt)
pakt_buf = put_variable_length_num(pakt_buf, pkt->duration);
caf->pakt_buf_size = pakt_buf - caf->pakt_buf;
}
- caf->packets++;
caf->total_duration += pkt->duration;
avio_write(s->pb, pkt->data, pkt->size);
@@ -286,8 +284,8 @@ static int caf_write_trailer(AVFormatContext *s)
if (pb->seekable & AVIO_SEEKABLE_NORMAL) {
int64_t file_size = avio_tell(pb);
- int64_t packets = (!par->block_align || !caf->frame_size) ? caf->packets : 0;
- int64_t valid_frames = caf->frame_size ? caf->packets * caf->frame_size : caf->total_duration;
+ int64_t packets = (!par->block_align || !caf->frame_size) ? st->nb_frames : 0;
+ int64_t valid_frames = caf->frame_size ? st->nb_frames * caf->frame_size : caf->total_duration;
unsigned remainder_frames = valid_frames > caf->total_duration
? valid_frames - caf->total_duration : 0;
--
2.52.0
_______________________________________________
ffmpeg-devel mailing list -- ffmpeg-devel@ffmpeg.org
To unsubscribe send an email to ffmpeg-devel-leave@ffmpeg.org
reply other threads:[~2026-01-30 14:18 UTC|newest]
Thread overview: [no followups] expand[flat|nested] mbox.gz Atom feed
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=176978268033.25.9369479870127554602@4457048688e7 \
--to=ffmpeg-devel@ffmpeg.org \
--cc=code@ffmpeg.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Git Inbox Mirror of the ffmpeg-devel mailing list - see https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
This inbox may be cloned and mirrored by anyone:
git clone --mirror https://master.gitmailbox.com/ffmpegdev/0 ffmpegdev/git/0.git
# If you have public-inbox 1.1+ installed, you may
# initialize and index your mirror using the following commands:
public-inbox-init -V2 ffmpegdev ffmpegdev/ https://master.gitmailbox.com/ffmpegdev \
ffmpegdev@gitmailbox.com
public-inbox-index ffmpegdev
Example config snippet for mirrors.
AGPL code for this site: git clone https://public-inbox.org/public-inbox.git