summaryrefslogtreecommitdiff
path: root/libavformat/mux.c
diff options
context:
space:
mode:
authorAnton Khirnov <anton@khirnov.net>2020-11-29 17:40:14 +0100
committerAnton Khirnov <anton@khirnov.net>2020-12-10 09:50:18 +0100
commit1c0885334dda9ee8652e60c586fa2e3674056586 (patch)
treee02c4721496cf6a5b4d82e2e95bf7116d4f17cb4 /libavformat/mux.c
parentfe7f0d366fdea04af1bb4c7c188750b99b3593c4 (diff)
lavf/mux: rewrite guessing the packet duration
Factor out the code into a separate muxing-specific function. Stop accessing the deprecated AVStream-embedded codec context, use the average framerate (if specified) instead.
Diffstat (limited to 'libavformat/mux.c')
-rw-r--r--libavformat/mux.c49
1 files changed, 34 insertions, 15 deletions
diff --git a/libavformat/mux.c b/libavformat/mux.c
index d2a56d216b..84c56ac6ba 100644
--- a/libavformat/mux.c
+++ b/libavformat/mux.c
@@ -546,7 +546,7 @@ FF_DISABLE_DEPRECATION_WARNINGS
static int compute_muxer_pkt_fields(AVFormatContext *s, AVStream *st, AVPacket *pkt)
{
int delay = FFMAX(st->codecpar->video_delay, st->internal->avctx->max_b_frames > 0);
- int num, den, i;
+ int i;
int frame_size;
if (!s->internal->missing_ts_warning &&
@@ -564,20 +564,6 @@ static int compute_muxer_pkt_fields(AVFormatContext *s, AVStream *st, AVPacket *
av_log(s, AV_LOG_DEBUG, "compute_muxer_pkt_fields: pts:%s dts:%s cur_dts:%s b:%d size:%d st:%d\n",
av_ts2str(pkt->pts), av_ts2str(pkt->dts), av_ts2str(st->cur_dts), delay, pkt->size, pkt->stream_index);
- if (pkt->duration < 0 && st->codecpar->codec_type != AVMEDIA_TYPE_SUBTITLE) {
- av_log(s, AV_LOG_WARNING, "Packet with invalid duration %"PRId64" in stream %d\n",
- pkt->duration, pkt->stream_index);
- pkt->duration = 0;
- }
-
- /* duration field */
- if (pkt->duration == 0) {
- ff_compute_frame_duration(s, &num, &den, st, NULL, pkt);
- if (den && num) {
- pkt->duration = av_rescale(1, num * (int64_t)st->time_base.den * st->codec->ticks_per_frame, den * (int64_t)st->time_base.num);
- }
- }
-
if (pkt->pts == AV_NOPTS_VALUE && pkt->dts != AV_NOPTS_VALUE && delay == 0)
pkt->pts = pkt->dts;
@@ -652,6 +638,37 @@ static int compute_muxer_pkt_fields(AVFormatContext *s, AVStream *st, AVPacket *
FF_ENABLE_DEPRECATION_WARNINGS
#endif
+static void guess_pkt_duration(AVFormatContext *s, AVStream *st, AVPacket *pkt)
+{
+ if (pkt->duration < 0 && st->codecpar->codec_type != AVMEDIA_TYPE_SUBTITLE) {
+ av_log(s, AV_LOG_WARNING, "Packet with invalid duration %"PRId64" in stream %d\n",
+ pkt->duration, pkt->stream_index);
+ pkt->duration = 0;
+ }
+
+ if (pkt->duration)
+ return;
+
+ switch (st->codecpar->codec_type) {
+ case AVMEDIA_TYPE_VIDEO:
+ if (st->avg_frame_rate.num > 0 && st->avg_frame_rate.den > 0) {
+ pkt->duration = av_rescale_q(1, av_inv_q(st->avg_frame_rate),
+ st->time_base);
+ } else if (st->time_base.num * 1000LL > st->time_base.den)
+ pkt->duration = 1;
+ break;
+ case AVMEDIA_TYPE_AUDIO: {
+ int frame_size = av_get_audio_frame_duration2(st->codecpar, pkt->size);
+ if (frame_size && st->codecpar->sample_rate) {
+ pkt->duration = av_rescale_q(frame_size,
+ (AVRational){1, st->codecpar->sample_rate},
+ st->time_base);
+ }
+ break;
+ }
+ }
+}
+
/**
* Shift timestamps and call muxer; the original pts/dts are not kept.
*
@@ -1118,6 +1135,8 @@ static int write_packet_common(AVFormatContext *s, AVStream *st, AVPacket *pkt,
av_log(s, AV_LOG_DEBUG, "%s size:%d dts:%s pts:%s\n", __FUNCTION__,
pkt->size, av_ts2str(pkt->dts), av_ts2str(pkt->pts));
+ guess_pkt_duration(s, st, pkt);
+
#if FF_API_COMPUTE_PKT_FIELDS2 && FF_API_LAVF_AVCTX
if ((ret = compute_muxer_pkt_fields(s, st, pkt)) < 0 && !(s->oformat->flags & AVFMT_NOTIMESTAMPS))
return ret;