This is an automated email from the git hooks/post-receive script.

Git pushed a commit to branch master
in repository ffmpeg.

commit c52b287ba9e4d23bab6e9401fd860a4dd4f31f32
Author:     James Almer <[email protected]>
AuthorDate: Sat Jan 24 14:04:31 2026 -0300
Commit:     James Almer <[email protected]>
CommitDate: Thu Jan 29 21:09:02 2026 -0300

    avformat/cafdec: fix setting stream and packet durations
    
    Take into account priming frames, exported as start time, and remainder 
frames,
    substracted from the stream duration as well as exported as discard padding
    side data in the last packet.
    
    Signed-off-by: James Almer <[email protected]>
---
 libavformat/cafdec.c          | 36 ++++++++++++++++++++++++++++++++++--
 tests/ref/fate/caf-alac-remux |  6 +++---
 tests/ref/fate/caf-qdm2-remux |  6 +++---
 3 files changed, 40 insertions(+), 8 deletions(-)

diff --git a/libavformat/cafdec.c b/libavformat/cafdec.c
index 99ae041364..081fc9d06c 100644
--- a/libavformat/cafdec.c
+++ b/libavformat/cafdec.c
@@ -45,11 +45,14 @@ typedef struct CafContext {
     int frames_per_packet;          ///< frames in a packet, or 0 if variable
     int64_t num_bytes;              ///< total number of bytes in stream
 
+    int64_t num_packets;            ///< packet amount
     int64_t packet_cnt;             ///< packet counter
     int64_t frame_cnt;              ///< frame counter
 
     int64_t data_start;             ///< data start position, in bytes
     int64_t data_size;              ///< raw data size, in bytes
+
+    unsigned remainder;             ///< frames to discard from the last packet
 } CafContext;
 
 static int probe(const AVProbeData *p)
@@ -244,6 +247,7 @@ static int read_pakt_chunk(AVFormatContext *s, int64_t size)
     AVStream *st      = s->streams[0];
     CafContext *caf   = s->priv_data;
     int64_t pos = 0, ccount, num_packets;
+    unsigned priming;
     int i;
     int ret;
 
@@ -254,10 +258,19 @@ static int read_pakt_chunk(AVFormatContext *s, int64_t 
size)
         return AVERROR_INVALIDDATA;
 
     st->nb_frames  = avio_rb64(pb); /* valid frames */
-    st->nb_frames += avio_rb32(pb); /* priming frames */
-    st->nb_frames += avio_rb32(pb); /* remainder frames */
+    priming        = avio_rb32(pb); /* priming frames */
+    caf->remainder = avio_rb32(pb); /* remainder frames */
+
+    st->codecpar->initial_padding = priming;
+    st->nb_frames += priming;
+    st->nb_frames += caf->remainder;
 
     if (caf->bytes_per_packet > 0 && caf->frames_per_packet > 0) {
+        if (!num_packets) {
+            if (caf->data_size < 0)
+                return AVERROR_INVALIDDATA;
+            num_packets = caf->data_size / caf->bytes_per_packet;
+        }
         st->duration = caf->frames_per_packet * num_packets;
         pos          = caf-> bytes_per_packet * num_packets;
     } else {
@@ -272,6 +285,9 @@ static int read_pakt_chunk(AVFormatContext *s, int64_t size)
             st->duration += caf->frames_per_packet ? caf->frames_per_packet : 
ff_mp4_read_descr_len(pb);
         }
     }
+    st->duration -= caf->remainder;
+    if (st->duration < 0)
+        return AVERROR_INVALIDDATA;
 
     if (avio_tell(pb) - ccount > size || size > INT64_MAX - ccount) {
         av_log(s, AV_LOG_ERROR, "error reading packet table\n");
@@ -279,6 +295,7 @@ static int read_pakt_chunk(AVFormatContext *s, int64_t size)
     }
     avio_seek(pb, ccount + size, SEEK_SET);
 
+    caf->num_packets = num_packets;
     caf->num_bytes = pos;
     return 0;
 }
@@ -433,6 +450,7 @@ static int read_packet(AVFormatContext *s, AVPacket *pkt)
     FFStream *const sti = ffstream(st);
     CafContext *caf   = s->priv_data;
     int res, pkt_size = 0, pkt_frames = 0;
+    unsigned remainder = 0;
     int64_t left      = CAF_MAX_PKT_SIZE;
 
     if (avio_feof(pb))
@@ -461,9 +479,13 @@ static int read_packet(AVFormatContext *s, AVPacket *pkt)
         } else if (caf->packet_cnt == sti->nb_index_entries - 1) {
             pkt_size   = caf->num_bytes - 
sti->index_entries[caf->packet_cnt].pos;
             pkt_frames = st->duration   - 
sti->index_entries[caf->packet_cnt].timestamp;
+            remainder  = caf->remainder;
         } else {
             return AVERROR_INVALIDDATA;
         }
+    } else if (caf->packet_cnt + 1 == caf->num_packets) {
+        pkt_frames -= caf->remainder;
+        remainder   = caf->remainder;
     }
 
     if (pkt_size == 0 || pkt_frames == 0 || pkt_size > left)
@@ -473,6 +495,16 @@ static int read_packet(AVFormatContext *s, AVPacket *pkt)
     if (res < 0)
         return res;
 
+    if (remainder > 0) {
+        uint8_t* side_data = av_packet_new_side_data(pkt,
+                                                     AV_PKT_DATA_SKIP_SAMPLES,
+                                                     10);
+        if (!side_data)
+            return AVERROR(ENOMEM);
+        AV_WL32(side_data + 4, caf->remainder);
+    }
+
+    pkt->duration       = pkt_frames;
     pkt->size           = res;
     pkt->stream_index   = 0;
     pkt->dts = pkt->pts = caf->frame_cnt;
diff --git a/tests/ref/fate/caf-alac-remux b/tests/ref/fate/caf-alac-remux
index f33182b721..2a1d24092b 100644
--- a/tests/ref/fate/caf-alac-remux
+++ b/tests/ref/fate/caf-alac-remux
@@ -6,9 +6,9 @@
 #codec_id 0: alac
 #sample_rate 0: 44100
 #channel_layout_name 0: stereo
-0,          0,          0,        0,       32, 0xa0af0dfe
-0,       4096,       4096,        0,     6701, 0xa9ddc14e
-0,       8192,       8192,        0,     6639, 0x3ccda8d6
+0,          0,          0,     4096,       32, 0xa0af0dfe
+0,       4096,       4096,     4096,     6701, 0xa9ddc14e
+0,       8192,       8192,     4096,     6639, 0x3ccda8d6
 [FORMAT]
 TAG:track=5/13
 TAG:minor_version=0
diff --git a/tests/ref/fate/caf-qdm2-remux b/tests/ref/fate/caf-qdm2-remux
index d4f658c163..e0e96eaf5e 100644
--- a/tests/ref/fate/caf-qdm2-remux
+++ b/tests/ref/fate/caf-qdm2-remux
@@ -6,6 +6,6 @@
 #codec_id 0: qdm2
 #sample_rate 0: 44100
 #channel_layout_name 0: stereo
-0,          0,          0,        0,      370, 0x4d1897fc
-0,       4096,       4096,        0,      370, 0xea999da0
-0,       8192,       8192,        0,      370, 0xca259462
+0,          0,          0,     4096,      370, 0x4d1897fc
+0,       4096,       4096,     4096,      370, 0xea999da0
+0,       8192,       8192,     4096,      370, 0xca259462

_______________________________________________
ffmpeg-cvslog mailing list -- [email protected]
To unsubscribe send an email to [email protected]

Reply via email to