diff mbox series

[FFmpeg-devel] mov.c fix the duration for the last audio frame.

Message ID 20240530193836.2602182-1-wangcao@google.com
State New
Headers show
Series [FFmpeg-devel] mov.c fix the duration for the last audio frame. | expand

Checks

Context Check Description
yinshiyou/commit_msg_loongarch64 warning The first line of the commit message must start with a context terminated by a colon and a space, for example "lavu/opt: " or "doc: ".
andriy/commit_msg_x86 warning The first line of the commit message must start with a context terminated by a colon and a space, for example "lavu/opt: " or "doc: ".
andriy/make_x86 success Make finished
andriy/make_fate_x86 success Make fate finished

Commit Message

Wang Cao May 30, 2024, 7:38 p.m. UTC
It is possible that the actual audio data only occupy part of the last audio frame. This can be signaled by duration in the "trun" atom. We should respect the metadata of file and set the duration correctly.
---
 libavformat/mov.c | 12 ++++++++++--
 1 file changed, 10 insertions(+), 2 deletions(-)

Comments

Michael Niedermayer May 30, 2024, 11:49 p.m. UTC | #1
On Thu, May 30, 2024 at 07:38:36PM +0000, Wang Cao via ffmpeg-devel wrote:
> It is possible that the actual audio data only occupy part of the last audio frame. This can be signaled by duration in the "trun" atom. We should respect the metadata of file and set the duration correctly.
> ---
>  libavformat/mov.c | 12 ++++++++++--
>  1 file changed, 10 insertions(+), 2 deletions(-)

please add a fate test

thx

[...]
diff mbox series

Patch

diff --git a/libavformat/mov.c b/libavformat/mov.c
index 45eca74d1d..caea36b495 100644
--- a/libavformat/mov.c
+++ b/libavformat/mov.c
@@ -5700,11 +5700,16 @@  static int mov_read_trun(MOVContext *c, AVIOContext *pb, MOVAtom atom)
 
         sc->ctts_data[index_entry_pos].count = 1;
         sc->ctts_data[index_entry_pos].duration = ctts_duration;
+        if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO) {
+            sc->ctts_data[index_entry_pos].duration = sample_duration;
+        } else {
+            sc->ctts_data[index_entry_pos].duration = ctts_duration;
+        }
         index_entry_pos++;
 
         av_log(c->fc, AV_LOG_TRACE, "AVIndex stream %d, sample %d, offset %"PRIx64", dts %"PRId64", "
-                "size %u, distance %d, keyframe %d\n", st->index,
-                index_entry_pos, offset, dts, sample_size, distance, keyframe);
+                "size %u, distance %d, keyframe %d duration %d\n", st->index,
+                index_entry_pos, offset, dts, sample_size, distance, keyframe, sc->ctts_data[index_entry_pos-1].duration);
         distance++;
         if (av_sat_add64(dts, sample_duration) != dts + (uint64_t)sample_duration)
             return AVERROR_INVALIDDATA;
@@ -9894,6 +9899,9 @@  static int mov_finalize_packet(AVFormatContext *s, AVStream *st, AVIndexEntry *s
     }
     if (sc->ctts_data && sc->ctts_index < sc->ctts_count) {
         pkt->pts = av_sat_add64(pkt->dts, av_sat_add64(sc->dts_shift, sc->ctts_data[sc->ctts_index].duration));
+        if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO) {
+            pkt->duration = sc->ctts_data[sc->ctts_index].duration;
+        }
         /* update ctts context */
         sc->ctts_sample++;
         if (sc->ctts_index < sc->ctts_count &&