@@ -568,7 +568,7 @@ static inline int parse_nal_units(AVCodecParserContext *s,
if (p->sei.common.unregistered.x264_build < 44U)
den *= 2;
av_reduce(&avctx->framerate.den, &avctx->framerate.num,
- sps->num_units_in_tick * avctx->ticks_per_frame, den, 1 << 30);
+ sps->num_units_in_tick * 2, den, 1 << 30);
}
av_freep(&rbsp.rbsp_buffer);
@@ -625,7 +625,7 @@ static int h264_parse(AVCodecParserContext *s,
parse_nal_units(s, avctx, buf, buf_size);
if (avctx->framerate.num)
- time_base = av_inv_q(av_mul_q(avctx->framerate, (AVRational){avctx->ticks_per_frame, 1}));
+ time_base = av_inv_q(av_mul_q(avctx->framerate, (AVRational){2, 1}));
if (p->sei.picture_timing.cpb_removal_delay >= 0) {
s->dts_sync_point = p->sei.buffering_period.present;
s->dts_ref_dts_delta = p->sei.picture_timing.cpb_removal_delay;
@@ -129,6 +129,7 @@ static void mpegvideo_extract_headers(AVCodecParserContext *s,
s->pict_type = (buf[1] >> 3) & 7;
if (bytes_left >= 4)
vbv_delay = ((buf[1] & 0x07) << 13) | (buf[2] << 5) | (buf[3] >> 3);
+ s->repeat_pict = 1;
}
break;
case SEQ_START_CODE:
@@ -186,7 +187,6 @@ static void mpegvideo_extract_headers(AVCodecParserContext *s,
progressive_frame = buf[4] & (1 << 7);
/* check if we must repeat the frame */
- s->repeat_pict = 1;
if (repeat_first_field) {
if (pc->progressive_sequence) {
if (top_field_first)
@@ -679,6 +679,7 @@ AVRational av_guess_sample_aspect_ratio(AVFormatContext *format, AVStream *strea
AVRational av_guess_frame_rate(AVFormatContext *format, AVStream *st, AVFrame *frame)
{
AVRational fr = st->r_frame_rate;
+ const AVCodecDescriptor *desc = cffstream(st)->codec_desc;
AVCodecContext *const avctx = ffstream(st)->avctx;
AVRational codec_fr = avctx->framerate;
AVRational avg_fr = st->avg_frame_rate;
@@ -688,7 +689,7 @@ AVRational av_guess_frame_rate(AVFormatContext *format, AVStream *st, AVFrame *f
fr = avg_fr;
}
- if (avctx->ticks_per_frame > 1) {
+ if (desc && (desc->props & AV_CODEC_PROP_FIELDS)) {
if ( codec_fr.num > 0 && codec_fr.den > 0 &&
(fr.num == 0 || av_q2d(codec_fr) < av_q2d(fr)*0.7 && fabs(1.0 - av_q2d(av_div_q(avg_fr, fr))) > 0.1))
fr = codec_fr;
@@ -701,10 +702,12 @@ int avformat_transfer_internal_stream_timing_info(const AVOutputFormat *ofmt,
AVStream *ost, const AVStream *ist,
enum AVTimebaseSource copy_tb)
{
+ const AVCodecDescriptor *desc = cffstream(ist)->codec_desc;
const AVCodecContext *const dec_ctx = cffstream(ist)->avctx;
AVCodecContext *const enc_ctx = ffstream(ost)->avctx;
- AVRational dec_ctx_tb = dec_ctx->framerate.num ? av_inv_q(av_mul_q(dec_ctx->framerate,
- (AVRational){dec_ctx->ticks_per_frame, 1}))
+
+ AVRational mul = (AVRational){ desc && (desc->props & AV_CODEC_PROP_FIELDS) ? 2 : 1, 1 };
+ AVRational dec_ctx_tb = dec_ctx->framerate.num ? av_inv_q(av_mul_q(dec_ctx->framerate, mul))
: (ist->codecpar->codec_type == AVMEDIA_TYPE_AUDIO ? (AVRational){0, 1}
: ist->time_base);
@@ -213,6 +213,8 @@ FF_ENABLE_DEPRECATION_WARNINGS
if (ret < 0)
return ret;
+ sti->codec_desc = avcodec_descriptor_get(sti->avctx->codec_id);
+
sti->need_context_update = 0;
}
return 0;
@@ -677,10 +679,11 @@ static void compute_frame_duration(AVFormatContext *s, int *pnum, int *pden,
*pnum = st->time_base.num;
*pden = st->time_base.den;
} else if (codec_framerate.den * 1000LL > codec_framerate.num) {
- av_assert0(sti->avctx->ticks_per_frame);
+ int ticks_per_frame = (sti->codec_desc &&
+ (sti->codec_desc->props & AV_CODEC_PROP_FIELDS)) ? 2 : 1;
av_reduce(pnum, pden,
codec_framerate.den,
- codec_framerate.num * (int64_t)sti->avctx->ticks_per_frame,
+ codec_framerate.num * (int64_t)ticks_per_frame,
INT_MAX);
if (pc && pc->repeat_pict) {
@@ -692,7 +695,8 @@ static void compute_frame_duration(AVFormatContext *s, int *pnum, int *pden,
/* If this codec can be interlaced or progressive then we need
* a parser to compute duration of a packet. Thus if we have
* no parser in such case leave duration undefined. */
- if (sti->avctx->ticks_per_frame > 1 && !pc)
+ if (sti->codec_desc &&
+ (sti->codec_desc->props & AV_CODEC_PROP_FIELDS) && !pc)
*pnum = *pden = 0;
}
break;
@@ -1288,6 +1292,8 @@ static int read_frame_internal(AVFormatContext *s, AVPacket *pkt)
return ret;
}
+ sti->codec_desc = avcodec_descriptor_get(sti->avctx->codec_id);
+
sti->need_context_update = 0;
}
@@ -2164,9 +2170,10 @@ static int get_std_framerate(int i)
static int tb_unreliable(AVFormatContext *ic, AVStream *st)
{
FFStream *const sti = ffstream(st);
+ const AVCodecDescriptor *desc = sti->codec_desc;
AVCodecContext *c = sti->avctx;
- AVRational time_base = c->framerate.num ? av_inv_q(av_mul_q(c->framerate,
- (AVRational){c->ticks_per_frame, 1}))
+ AVRational mul = (AVRational){ desc && (desc->props & AV_CODEC_PROP_FIELDS) ? 2 : 1, 1 };
+ AVRational time_base = c->framerate.num ? av_inv_q(av_mul_q(c->framerate, mul))
/* NOHEADER check added to not break existing behavior */
: (((ic->ctx_flags & AVFMTCTX_NOHEADER) ||
st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO) ? (AVRational){0, 1}
@@ -2718,13 +2725,14 @@ int avformat_find_stream_info(AVFormatContext *ic, AVDictionary **options)
break;
}
if (pkt->duration > 0) {
+ const int fields = sti->codec_desc && (sti->codec_desc->props & AV_CODEC_PROP_FIELDS);
if (avctx->codec_type == AVMEDIA_TYPE_SUBTITLE && pkt->pts != AV_NOPTS_VALUE && st->start_time != AV_NOPTS_VALUE && pkt->pts >= st->start_time
&& (uint64_t)pkt->pts - st->start_time < INT64_MAX
) {
sti->info->codec_info_duration = FFMIN(pkt->pts - st->start_time, sti->info->codec_info_duration + pkt->duration);
} else
sti->info->codec_info_duration += pkt->duration;
- sti->info->codec_info_duration_fields += sti->parser && sti->need_parsing && avctx->ticks_per_frame == 2
+ sti->info->codec_info_duration_fields += sti->parser && sti->need_parsing && fields
? sti->parser->repeat_pict + 1 : 2;
}
}
@@ -2864,15 +2872,12 @@ int avformat_find_stream_info(AVFormatContext *ic, AVDictionary **options)
best_fps, 12 * 1001, INT_MAX);
}
if (!st->r_frame_rate.num) {
- AVRational time_base = avctx->framerate.num ? av_inv_q(av_mul_q(avctx->framerate,
- (AVRational){avctx->ticks_per_frame, 1}))
- /* NOHEADER check added to not break existing behavior */
- : ((ic->ctx_flags & AVFMTCTX_NOHEADER) ? (AVRational){0, 1}
- : st->time_base);
- if ( time_base.den * (int64_t) st->time_base.num
- <= time_base.num * (uint64_t)avctx->ticks_per_frame * st->time_base.den) {
- av_reduce(&st->r_frame_rate.num, &st->r_frame_rate.den,
- time_base.den, (int64_t)time_base.num * avctx->ticks_per_frame, INT_MAX);
+ const AVCodecDescriptor *desc = sti->codec_desc;
+ AVRational mul = (AVRational){ desc && (desc->props & AV_CODEC_PROP_FIELDS) ? 2 : 1, 1 };
+ AVRational fr = av_mul_q(avctx->framerate, mul);
+
+ if (fr.num && fr.den && av_cmp_q(st->time_base, av_inv_q(fr)) <= 0) {
+ st->r_frame_rate = fr;
} else {
st->r_frame_rate.num = st->time_base.den;
st->r_frame_rate.den = st->time_base.num;
@@ -23,6 +23,7 @@
#include <stdint.h>
+#include "libavcodec/codec_desc.h"
#include "libavcodec/packet_internal.h"
#include "avformat.h"
@@ -408,6 +409,8 @@ typedef struct FFStream {
*/
int64_t first_dts;
int64_t cur_dts;
+
+ const AVCodecDescriptor *codec_desc;
} FFStream;
static av_always_inline FFStream *ffstream(AVStream *st)