aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMarton Balint <cus@passwd.hu>2018-02-13 23:44:05 +0100
committerMarton Balint <cus@passwd.hu>2018-03-01 22:03:53 +0100
commite8e1c22f21eecca9269f6bb18c615acaf29d974f (patch)
tree7841aaa7026119b0b55681184318b70fd2b204fe
parent0827c78e98da808b750966af8ff3cbe0361cfcee (diff)
downloadffmpeg-e8e1c22f21eecca9269f6bb18c615acaf29d974f.tar.gz
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@passwd.hu>
-rw-r--r--libavformat/mxfdec.c54
1 files 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;