diff options
author | James Almer <jamrial@gmail.com> | 2024-02-15 19:10:53 -0300 |
---|---|---|
committer | James Almer <jamrial@gmail.com> | 2024-02-20 11:24:19 -0300 |
commit | b140b8332c617b0eef4f872f3ef90c469e99920f (patch) | |
tree | 1be44afbbd5a172cf2956ac01505cfe9a954cd92 /libavformat/demux.c | |
parent | 37702e20663dc8111534229af551763c2a954e73 (diff) | |
download | ffmpeg-b140b8332c617b0eef4f872f3ef90c469e99920f.tar.gz |
avformat/demux: allow demuxers to output more than one packet per read_packet() call
Signed-off-by: James Almer <jamrial@gmail.com>
Diffstat (limited to 'libavformat/demux.c')
-rw-r--r-- | libavformat/demux.c | 89 |
1 files changed, 68 insertions, 21 deletions
diff --git a/libavformat/demux.c b/libavformat/demux.c index b70979c520..2e1d0ed66d 100644 --- a/libavformat/demux.c +++ b/libavformat/demux.c @@ -540,6 +540,73 @@ static int update_wrap_reference(AVFormatContext *s, AVStream *st, int stream_in return 1; } +static void update_timestamps(AVFormatContext *s, AVStream *st, AVPacket *pkt) +{ + FFStream *const sti = ffstream(st); + + av_assert0(pkt->stream_index < (unsigned)s->nb_streams && + "Invalid stream index.\n"); + + if (update_wrap_reference(s, st, pkt->stream_index, pkt) && sti->pts_wrap_behavior == AV_PTS_WRAP_SUB_OFFSET) { + // correct first time stamps to negative values + if (!is_relative(sti->first_dts)) + sti->first_dts = wrap_timestamp(st, sti->first_dts); + if (!is_relative(st->start_time)) + st->start_time = wrap_timestamp(st, st->start_time); + if (!is_relative(sti->cur_dts)) + sti->cur_dts = wrap_timestamp(st, sti->cur_dts); + } + + pkt->dts = wrap_timestamp(st, pkt->dts); + pkt->pts = wrap_timestamp(st, pkt->pts); + + force_codec_ids(s, st); + + /* TODO: audio: time filter; video: frame reordering (pts != dts) */ + if (s->use_wallclock_as_timestamps) + pkt->dts = pkt->pts = av_rescale_q(av_gettime(), AV_TIME_BASE_Q, st->time_base); +} + +int ff_buffer_packet(AVFormatContext *s, AVPacket *pkt) +{ + FFFormatContext *const si = ffformatcontext(s); + AVStream *st = s->streams[pkt->stream_index]; + FFStream *sti = ffstream(st); + int err; + + if (pkt->flags & AV_PKT_FLAG_CORRUPT) { + av_log(s, AV_LOG_WARNING, + "Packet corrupt (stream = %d, dts = %s)", + pkt->stream_index, av_ts2str(pkt->dts)); + if (s->flags & AVFMT_FLAG_DISCARD_CORRUPT) { + av_log(s, AV_LOG_WARNING, ", dropping it.\n"); + av_packet_unref(pkt); + return 0; + } + av_log(s, AV_LOG_WARNING, ".\n"); + } + + update_timestamps(s, st, pkt); + + err = avpriv_packet_list_put(&si->raw_packet_buffer, pkt, NULL, 0); + if (err < 0) { + av_packet_unref(pkt); + return err; + } + + pkt = &si->raw_packet_buffer.tail->pkt; + si->raw_packet_buffer_size += pkt->size; + + if (sti->request_probe <= 0) + return 0; + + err = probe_codec(s, st, pkt); + if (err < 0) + return err; + + return 0; +} + int ff_read_packet(AVFormatContext *s, AVPacket *pkt) { FFFormatContext *const si = ffformatcontext(s); @@ -613,30 +680,10 @@ FF_ENABLE_DEPRECATION_WARNINGS av_log(s, AV_LOG_WARNING, ".\n"); } - av_assert0(pkt->stream_index < (unsigned)s->nb_streams && - "Invalid stream index.\n"); - st = s->streams[pkt->stream_index]; sti = ffstream(st); - if (update_wrap_reference(s, st, pkt->stream_index, pkt) && sti->pts_wrap_behavior == AV_PTS_WRAP_SUB_OFFSET) { - // correct first time stamps to negative values - if (!is_relative(sti->first_dts)) - sti->first_dts = wrap_timestamp(st, sti->first_dts); - if (!is_relative(st->start_time)) - st->start_time = wrap_timestamp(st, st->start_time); - if (!is_relative(sti->cur_dts)) - sti->cur_dts = wrap_timestamp(st, sti->cur_dts); - } - - pkt->dts = wrap_timestamp(st, pkt->dts); - pkt->pts = wrap_timestamp(st, pkt->pts); - - force_codec_ids(s, st); - - /* TODO: audio: time filter; video: frame reordering (pts != dts) */ - if (s->use_wallclock_as_timestamps) - pkt->dts = pkt->pts = av_rescale_q(av_gettime(), AV_TIME_BASE_Q, st->time_base); + update_timestamps(s, st, pkt); if (!pktl && sti->request_probe <= 0) return 0; |