[FFmpeg-cvslog] avformat/mxfdec: compute sample_count after seek from index for audio streams

Marton Balint git at videolan.org
Thu Mar 1 23:31:51 EET 2018


ffmpeg | branch: master | Marton Balint <cus at passwd.hu> | Tue Feb 13 23:44:05 2018 +0100| [e8e1c22f21eecca9269f6bb18c615acaf29d974f] | committer: Marton Balint

avformat/mxfdec: compute sample_count after seek from index for audio streams

This fixes audio timestamps if the audio streams are not frame wrapped with the
video.

Signed-off-by: Marton Balint <cus at passwd.hu>

> http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=e8e1c22f21eecca9269f6bb18c615acaf29d974f
---

 libavformat/mxfdec.c | 54 ++++++++++++++++++++++++++++++++++++++++++++++------
 1 file changed, 48 insertions(+), 6 deletions(-)

diff --git a/libavformat/mxfdec.c b/libavformat/mxfdec.c
index 497a97d3ef..21fd2a876b 100644
--- a/libavformat/mxfdec.c
+++ b/libavformat/mxfdec.c
@@ -3055,6 +3055,42 @@ fail:
     return ret;
 }
 
+static MXFIndexTable *mxf_find_index_table(MXFContext *mxf, int index_sid)
+{
+    int i;
+    for (i = 0; i < mxf->nb_index_tables; i++)
+        if (mxf->index_tables[i].index_sid == index_sid)
+            return &mxf->index_tables[i];
+    return NULL;
+}
+
+/* Get the edit unit of the next packet from current_offset in a track. The returned edit unit can be original_duration as well! */
+static int mxf_get_next_track_edit_unit(MXFContext *mxf, MXFTrack *track, int64_t current_offset, int64_t *edit_unit_out)
+{
+    int64_t a, b, m, offset;
+    MXFIndexTable *t = mxf_find_index_table(mxf, track->index_sid);
+
+    if (!t || track->original_duration <= 0)
+        return -1;
+
+    a = -1;
+    b = track->original_duration;
+
+    while (b - a > 1) {
+        m = (a + b) >> 1;
+        if (mxf_edit_unit_absolute_offset(mxf, t, m, NULL, &offset, 0) < 0)
+            return -1;
+        if (offset < current_offset)
+            a = m;
+        else
+            b = m;
+    }
+
+    *edit_unit_out = b;
+
+    return 0;
+}
+
 /**
  * Sets mxf->current_edit_unit based on what offset we're currently at.
  * @return next_ofs if OK, <0 on error
@@ -3454,13 +3490,19 @@ static int mxf_read_seek(AVFormatContext *s, int stream_index, int64_t sample_ti
     for (i = 0; i < s->nb_streams; i++) {
         AVStream *cur_st = s->streams[i];
         MXFTrack *cur_track = cur_st->priv_data;
-        uint64_t current_sample_count = 0;
         if (cur_st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO) {
-            ret = mxf_compute_sample_count(mxf, i, &current_sample_count);
-            if (ret < 0)
-                return ret;
-
-            cur_track->sample_count = current_sample_count;
+            int64_t track_edit_unit;
+            if (st != cur_st && mxf_get_next_track_edit_unit(mxf, cur_track, seekpos, &track_edit_unit) >= 0) {
+                cur_track->sample_count = av_rescale_q(track_edit_unit,
+                                                       av_inv_q(cur_track->edit_rate),
+                                                       cur_st->time_base);
+            } else {
+                uint64_t current_sample_count = 0;
+                ret = mxf_compute_sample_count(mxf, i, &current_sample_count);
+                if (ret < 0)
+                    return ret;
+                cur_track->sample_count = current_sample_count;
+            }
         }
     }
     return 0;



More information about the ffmpeg-cvslog mailing list