mirror of
https://git.ffmpeg.org/ffmpeg.git
synced 2024-12-19 05:55:07 +00:00
lavf/mov.c: Guess video codec delay based on PTS while parsing MOV header.
Signed-off-by: Sasi Inguva <isasi@google.com> Signed-off-by: Michael Niedermayer <michael@niedermayer.cc>
This commit is contained in:
parent
05c1c79d37
commit
58a25aeb8e
@ -3241,6 +3241,60 @@ static int64_t add_ctts_entry(MOVStts** ctts_data, unsigned int* ctts_count, uns
|
||||
return *ctts_count;
|
||||
}
|
||||
|
||||
#define MAX_REORDER_DELAY 16
|
||||
static void mov_estimate_video_delay(MOVContext *c, AVStream* st) {
|
||||
MOVStreamContext *msc = st->priv_data;
|
||||
int ind;
|
||||
int ctts_ind = 0;
|
||||
int ctts_sample = 0;
|
||||
int64_t pts_buf[MAX_REORDER_DELAY + 1]; // Circular buffer to sort pts.
|
||||
int buf_start = 0;
|
||||
int buf_size = 0;
|
||||
int j, r, num_swaps;
|
||||
|
||||
if (st->codecpar->video_delay <= 0 && msc->ctts_data &&
|
||||
st->codecpar->codec_id == AV_CODEC_ID_H264) {
|
||||
st->codecpar->video_delay = 0;
|
||||
for(ind = 0; ind < st->nb_index_entries && ctts_ind < msc->ctts_count; ++ind) {
|
||||
if (buf_size == (MAX_REORDER_DELAY + 1)) {
|
||||
// If circular buffer is full, then move the first element forward.
|
||||
buf_start = (buf_start + 1) % buf_size;
|
||||
} else {
|
||||
++buf_size;
|
||||
}
|
||||
|
||||
// Point j to the last elem of the buffer and insert the current pts there.
|
||||
j = (buf_start + buf_size - 1) % buf_size;
|
||||
pts_buf[j] = st->index_entries[ind].timestamp + msc->ctts_data[ctts_ind].duration;
|
||||
|
||||
// The timestamps that are already in the sorted buffer, and are greater than the
|
||||
// current pts, are exactly the timestamps that need to be buffered to output PTS
|
||||
// in correct sorted order.
|
||||
// Hence the video delay (which is the buffer size used to sort DTS and output PTS),
|
||||
// can be computed as the maximum no. of swaps any particular timestamp needs to
|
||||
// go through, to keep this buffer in sorted order.
|
||||
num_swaps = 0;
|
||||
while (j != buf_start) {
|
||||
r = (j - 1 + buf_size) % buf_size;
|
||||
if (pts_buf[j] < pts_buf[r]) {
|
||||
FFSWAP(int64_t, pts_buf[j], pts_buf[r]);
|
||||
++num_swaps;
|
||||
}
|
||||
j = r;
|
||||
}
|
||||
st->codecpar->video_delay = FFMAX(st->codecpar->video_delay, num_swaps);
|
||||
|
||||
ctts_sample++;
|
||||
if (ctts_sample == msc->ctts_data[ctts_ind].count) {
|
||||
ctts_ind++;
|
||||
ctts_sample = 0;
|
||||
}
|
||||
}
|
||||
av_log(c->fc, AV_LOG_DEBUG, "Setting codecpar->delay to %d for stream st: %d\n",
|
||||
st->codecpar->video_delay, st->index);
|
||||
}
|
||||
}
|
||||
|
||||
static void mov_current_sample_inc(MOVStreamContext *sc)
|
||||
{
|
||||
sc->current_sample++;
|
||||
@ -3897,6 +3951,8 @@ static void mov_build_index(MOVContext *mov, AVStream *st)
|
||||
// Fix index according to edit lists.
|
||||
mov_fix_index(mov, st);
|
||||
}
|
||||
|
||||
mov_estimate_video_delay(mov, st);
|
||||
}
|
||||
|
||||
static int test_same_origin(const char *src, const char *ref) {
|
||||
|
@ -13,6 +13,9 @@ FATE_MOV = fate-mov-3elist \
|
||||
fate-mov-elst-ends-betn-b-and-i \
|
||||
fate-mov-frag-overlap \
|
||||
fate-mov-bbi-elst-starts-b \
|
||||
fate-mov-guess-delay-1 \
|
||||
fate-mov-guess-delay-2 \
|
||||
fate-mov-guess-delay-3 \
|
||||
|
||||
FATE_MOV_FFPROBE = fate-mov-aac-2048-priming \
|
||||
fate-mov-zombie \
|
||||
@ -82,3 +85,7 @@ fate-mov-spherical-mono: CMD = run ffprobe$(PROGSSUF)$(EXESUF) -show_entries str
|
||||
fate-mov-gpmf-remux: CMD = md5 -i $(TARGET_SAMPLES)/mov/fake-gp-media-with-real-gpmf.mp4 -map 0 -c copy -fflags +bitexact -f mp4
|
||||
fate-mov-gpmf-remux: CMP = oneline
|
||||
fate-mov-gpmf-remux: REF = 8f48e435ee1f6b7e173ea756141eabf3
|
||||
|
||||
fate-mov-guess-delay-1: CMD = run ffprobe$(PROGSSUF)$(EXESUF) -show_entries stream=has_b_frames -select_streams v $(TARGET_SAMPLES)/h264/h264_3bf_nopyramid_nobsrestriction.mp4
|
||||
fate-mov-guess-delay-2: CMD = run ffprobe$(PROGSSUF)$(EXESUF) -show_entries stream=has_b_frames -select_streams v $(TARGET_SAMPLES)/h264/h264_3bf_pyramid_nobsrestriction.mp4
|
||||
fate-mov-guess-delay-3: CMD = run ffprobe$(PROGSSUF)$(EXESUF) -show_entries stream=has_b_frames -select_streams v $(TARGET_SAMPLES)/h264/h264_4bf_pyramid_nobsrestriction.mp4
|
||||
|
3
tests/ref/fate/mov-guess-delay-1
Normal file
3
tests/ref/fate/mov-guess-delay-1
Normal file
@ -0,0 +1,3 @@
|
||||
[STREAM]
|
||||
has_b_frames=1
|
||||
[/STREAM]
|
3
tests/ref/fate/mov-guess-delay-2
Normal file
3
tests/ref/fate/mov-guess-delay-2
Normal file
@ -0,0 +1,3 @@
|
||||
[STREAM]
|
||||
has_b_frames=2
|
||||
[/STREAM]
|
3
tests/ref/fate/mov-guess-delay-3
Normal file
3
tests/ref/fate/mov-guess-delay-3
Normal file
@ -0,0 +1,3 @@
|
||||
[STREAM]
|
||||
has_b_frames=2
|
||||
[/STREAM]
|
Loading…
Reference in New Issue
Block a user