Git Inbox Mirror of the ffmpeg-devel mailing list - see https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
 help / color / mirror / Atom feed
From: Anton Khirnov <anton@khirnov.net>
To: ffmpeg-devel@ffmpeg.org
Subject: [FFmpeg-devel] [PATCH 04/13] lavf: use AV_CODEC_PROP_FIELDS where appropriate
Date: Sun,  7 May 2023 15:32:46 +0200
Message-ID: <20230507133255.20881-4-anton@khirnov.net> (raw)
In-Reply-To: <20230507133255.20881-1-anton@khirnov.net>

H.264 and mpeg12 parsers need to be adjusted at the same time to stop
using the value of AVCodecContext.ticks_per_frame, because it is not set
correctly unless the codec has been opened. Previously this would result
in both the parser and lavf seeing the same incorrect value, which would
cancel out.
Updating lavf and not the parsers would result in correct value in lavf,
but the wrong one in parsers, which would break some tests.
---
 libavcodec/h264_parser.c      |  4 ++--
 libavcodec/mpegvideo_parser.c |  2 +-
 libavformat/avformat.c        |  9 ++++++---
 libavformat/demux.c           | 29 +++++++++++++++++++----------
 libavformat/internal.h        |  3 +++
 5 files changed, 31 insertions(+), 16 deletions(-)

diff --git a/libavcodec/h264_parser.c b/libavcodec/h264_parser.c
index 46134a1c48..43abc45f9c 100644
--- a/libavcodec/h264_parser.c
+++ b/libavcodec/h264_parser.c
@@ -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;
diff --git a/libavcodec/mpegvideo_parser.c b/libavcodec/mpegvideo_parser.c
index 8e7e88ff25..08e5316960 100644
--- a/libavcodec/mpegvideo_parser.c
+++ b/libavcodec/mpegvideo_parser.c
@@ -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)
diff --git a/libavformat/avformat.c b/libavformat/avformat.c
index 708d90b38c..fea905693d 100644
--- a/libavformat/avformat.c
+++ b/libavformat/avformat.c
@@ -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);
 
diff --git a/libavformat/demux.c b/libavformat/demux.c
index 45e5f5c4c2..1e47cd2bba 100644
--- a/libavformat/demux.c
+++ b/libavformat/demux.c
@@ -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,16 @@ 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}))
+                const AVCodecDescriptor *desc = sti->codec_desc;
+                AVRational mul = (AVRational){ desc && (desc->props & AV_CODEC_PROP_FIELDS) ? 2 : 1, 1 };
+                AVRational time_base = avctx->framerate.num ? av_inv_q(av_mul_q(avctx->framerate, mul))
                                                             /* 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) {
+                    <= time_base.num * (uint64_t)mul.num * 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);
+                              time_base.den, (int64_t)time_base.num * mul.num, INT_MAX);
                 } else {
                     st->r_frame_rate.num = st->time_base.den;
                     st->r_frame_rate.den = st->time_base.num;
diff --git a/libavformat/internal.h b/libavformat/internal.h
index f575064e8f..40c46311c8 100644
--- a/libavformat/internal.h
+++ b/libavformat/internal.h
@@ -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)
-- 
2.39.2

_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".

  parent reply	other threads:[~2023-05-07 13:34 UTC|newest]

Thread overview: 35+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-05-07 13:32 [FFmpeg-devel] [PATCH 01/13] lavu/frame: extend AVFrame.repeat_pict documentation Anton Khirnov
2023-05-07 13:32 ` [FFmpeg-devel] [PATCH 02/13] fftools/ffmpeg: fix computing video frame duration from repeat_pict Anton Khirnov
2023-05-07 13:32 ` [FFmpeg-devel] [PATCH 03/13] lavc/codec_desc: add a property for codecs that support field coding Anton Khirnov
2023-05-07 13:32 ` Anton Khirnov [this message]
2023-05-08 14:12   ` [FFmpeg-devel] [PATCH 04/13] lavf: use AV_CODEC_PROP_FIELDS where appropriate Michael Niedermayer
2023-05-09  8:37     ` [FFmpeg-devel] [PATCH v2 " Anton Khirnov
2023-05-08 14:15   ` [FFmpeg-devel] [PATCH " Michael Niedermayer
2023-05-09  8:44     ` Anton Khirnov
2023-05-15 18:59       ` Michael Niedermayer
2023-05-15 20:44         ` Anton Khirnov
2023-05-16 17:41           ` Michael Niedermayer
2023-05-07 13:32 ` [FFmpeg-devel] [PATCH 05/13] lavc/av1*: fix exporting framerate Anton Khirnov
2023-05-10 11:52   ` James Almer
2023-05-14 19:39     ` [FFmpeg-devel] [PATCH] " Anton Khirnov
2023-05-14 19:50       ` James Almer
2023-05-15  8:22         ` Anton Khirnov
2023-05-15 11:41           ` James Almer
2023-05-07 13:32 ` [FFmpeg-devel] [PATCH 06/13] lavc/libdav1d: " Anton Khirnov
2023-05-15  8:22   ` [FFmpeg-devel] [PATCH] " Anton Khirnov
2023-05-15 11:47     ` James Almer
2023-05-15 12:22       ` Anton Khirnov
2023-05-15 12:41         ` James Almer
2023-05-07 13:32 ` [FFmpeg-devel] [PATCH 07/13] lavc/ratecontrol: use AVCodecContext.framerate when available Anton Khirnov
2023-05-07 13:32 ` [FFmpeg-devel] [PATCH 08/13] lavc/msmpeg4enc: " Anton Khirnov
2023-05-07 13:32 ` [FFmpeg-devel] [PATCH 09/13] libaomenc: " Anton Khirnov
2023-05-07 13:32 ` [FFmpeg-devel] [PATCH 10/13] lavc/libkvazaar, libopenh264enc: drop redundant checks Anton Khirnov
2023-05-07 13:32 ` [FFmpeg-devel] [PATCH 11/13] lavc/libvpxenc: send frame durations to the encoder Anton Khirnov
2023-05-09  1:18   ` James Zern
2023-05-09  9:09     ` [FFmpeg-devel] [PATCH v2 " Anton Khirnov
2023-05-09 18:17       ` James Zern
2023-05-10  6:34         ` Anton Khirnov
2023-05-07 13:32 ` [FFmpeg-devel] [PATCH 12/13] lavc: deprecate AVCodecContext.ticks_per_frame Anton Khirnov
2023-05-07 13:32 ` [FFmpeg-devel] [PATCH 13/13] fftools/ffmpeg: stop using deprecated ticks_per_frame Anton Khirnov
2023-05-07 16:59 ` [FFmpeg-devel] [PATCH 01/13] lavu/frame: extend AVFrame.repeat_pict documentation Kieran Kunhya
2023-05-07 18:01   ` Anton Khirnov

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20230507133255.20881-4-anton@khirnov.net \
    --to=anton@khirnov.net \
    --cc=ffmpeg-devel@ffmpeg.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link

Git Inbox Mirror of the ffmpeg-devel mailing list - see https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

This inbox may be cloned and mirrored by anyone:

	git clone --mirror https://master.gitmailbox.com/ffmpegdev/0 ffmpegdev/git/0.git

	# If you have public-inbox 1.1+ installed, you may
	# initialize and index your mirror using the following commands:
	public-inbox-init -V2 ffmpegdev ffmpegdev/ https://master.gitmailbox.com/ffmpegdev \
		ffmpegdev@gitmailbox.com
	public-inbox-index ffmpegdev

Example config snippet for mirrors.


AGPL code for this site: git clone https://public-inbox.org/public-inbox.git