Re: [FFmpeg-devel] [PATCH 1/1] avformat/demux: Fix accurate probing of durations in mpegts/ps

2024-03-14 Thread Michael Niedermayer
On Thu, Mar 14, 2024 at 06:57:39PM +0100, Nicolas Gaullier wrote:
> Two issues affect accuracy of duration in estimate_timings_from_pts():
> - pkt->duration typically reports the duration of a single audio frame,
> whereas a pes often contain several audio frames
> - for video, compute_frame_duration() use r_frame_rate which is not
> reliable; typically, it is the duration of a single field for an
> interlaced video using two field pictures.
> 
> Packet splitting/parsing is required to get accurate durations, so this
> patch replaces ff_read_packet() calls by av_read_frame() calls.
> 
> Note that concatdec makes use of avformat_find_stream_info() to stitch
> correctly the files, so it benefits from this patch (typically, overlap
> is avoided).
> e.g. in fate/concat-demuxer-simple2-lavf-ts: the input audio stream
> duration is now longer than that of the video, which results in
> concatdec joining on audio after the patch instead of joining on video
> before that.
> 
> Signed-off-by: Nicolas Gaullier 
> ---
>  libavformat/demux.c   |  30 +---
>  tests/ref/fate/concat-demuxer-simple2-lavf-ts | 170 +-
>  tests/ref/fate/ts-opus-demux  |   4 +-
>  3 files changed, 93 insertions(+), 111 deletions(-)

for some reason this seems to loose a resolution of some subtitle stream when 
probing:

make -j32 && ./ffprobe -v 99 -analyzeduration 2G -probesize 2G -i 
tickets/2471/part.ts 2>&1 | grep dvb_teletext
  Stream #0:2[0x240](eng), 1020, 1/9: Subtitle: dvb_teletext 
(libzvbi_teletextdec) ([6][0][0][0] / 0x0006), 492x250
  Stream #0:4[0x247](eng), 1902, 1/9: Subtitle: dvb_teletext 
(libzvbi_teletextdec) ([6][0][0][0] / 0x0006), 492x250
vs.
  Stream #0:2[0x240](eng), 1020, 1/9: Subtitle: dvb_teletext 
(libzvbi_teletextdec) ([6][0][0][0] / 0x0006), 492x250
  Stream #0:4[0x247](eng), 1902, 1/9: Subtitle: dvb_teletext 
(libzvbi_teletextdec) ([6][0][0][0] / 0x0006)

ive not looked at this so i have no idea this is a bug, just wanted to report it

thx

[...]

-- 
Michael GnuPG fingerprint: 9FF2128B147EF6730BADF133611EC787040B0FAB

I have often repented speaking, but never of holding my tongue.
-- Xenocrates


signature.asc
Description: PGP signature
___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

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


[FFmpeg-devel] [PATCH 1/1] avformat/demux: Fix accurate probing of durations in mpegts/ps

2024-03-14 Thread Nicolas Gaullier
Two issues affect accuracy of duration in estimate_timings_from_pts():
- pkt->duration typically reports the duration of a single audio frame,
whereas a pes often contain several audio frames
- for video, compute_frame_duration() use r_frame_rate which is not
reliable; typically, it is the duration of a single field for an
interlaced video using two field pictures.

Packet splitting/parsing is required to get accurate durations, so this
patch replaces ff_read_packet() calls by av_read_frame() calls.

Note that concatdec makes use of avformat_find_stream_info() to stitch
correctly the files, so it benefits from this patch (typically, overlap
is avoided).
e.g. in fate/concat-demuxer-simple2-lavf-ts: the input audio stream
duration is now longer than that of the video, which results in
concatdec joining on audio after the patch instead of joining on video
before that.

Signed-off-by: Nicolas Gaullier 
---
 libavformat/demux.c   |  30 +---
 tests/ref/fate/concat-demuxer-simple2-lavf-ts | 170 +-
 tests/ref/fate/ts-opus-demux  |   4 +-
 3 files changed, 93 insertions(+), 111 deletions(-)

diff --git a/libavformat/demux.c b/libavformat/demux.c
index 4c50eb5568..7e75e7149c 100644
--- a/libavformat/demux.c
+++ b/libavformat/demux.c
@@ -1820,20 +1820,17 @@ static void 
estimate_timings_from_bit_rate(AVFormatContext *ic)
 #define DURATION_MAX_READ_SIZE 25LL
 #define DURATION_MAX_RETRY 6
 
-/* only usable for MPEG-PS streams */
+/* only usable for MPEG-PS/TS streams */
 static void estimate_timings_from_pts(AVFormatContext *ic, int64_t old_offset)
 {
 FFFormatContext *const si = ffformatcontext(ic);
 AVPacket *const pkt = si->pkt;
-int num, den, read_size, ret;
+int read_size, ret;
 int found_duration = 0;
 int is_end;
 int64_t filesize, offset, duration;
 int retry = 0;
 
-/* flush packet queue */
-ff_flush_packet_queue(ic);
-
 for (unsigned i = 0; i < ic->nb_streams; i++) {
 AVStream *const st  = ic->streams[i];
 FFStream *const sti = ffstream(st);
@@ -1843,11 +1840,6 @@ static void estimate_timings_from_pts(AVFormatContext 
*ic, int64_t old_offset)
 st->codecpar->codec_type != AVMEDIA_TYPE_UNKNOWN)
 av_log(ic, AV_LOG_WARNING,
"start time for stream %d is not set in 
estimate_timings_from_pts\n", i);
-
-if (sti->parser) {
-av_parser_close(sti->parser);
-sti->parser = NULL;
-}
 }
 
 if (ic->skip_estimate_duration_from_pts) {
@@ -1865,6 +1857,7 @@ static void estimate_timings_from_pts(AVFormatContext 
*ic, int64_t old_offset)
 if (offset < 0)
 offset = 0;
 
+ff_read_frame_flush(ic);
 avio_seek(ic->pb, offset, SEEK_SET);
 read_size = 0;
 for (;;) {
@@ -1874,7 +1867,7 @@ static void estimate_timings_from_pts(AVFormatContext 
*ic, int64_t old_offset)
 break;
 
 do {
-ret = ff_read_packet(ic, pkt);
+ret = av_read_frame(ic, pkt);
 } while (ret == AVERROR(EAGAIN));
 if (ret != 0)
 break;
@@ -1884,15 +1877,6 @@ static void estimate_timings_from_pts(AVFormatContext 
*ic, int64_t old_offset)
 if (pkt->pts != AV_NOPTS_VALUE &&
 (st->start_time != AV_NOPTS_VALUE ||
  sti->first_dts != AV_NOPTS_VALUE)) {
-if (pkt->duration == 0) {
-compute_frame_duration(ic, &num, &den, st, sti->parser, 
pkt);
-if (den && num) {
-pkt->duration = av_rescale_rnd(1,
-   num * (int64_t) st->time_base.den,
-   den * (int64_t) st->time_base.num,
-   AV_ROUND_DOWN);
-}
-}
 duration = pkt->pts + pkt->duration;
 found_duration = 1;
 if (st->start_time != AV_NOPTS_VALUE)
@@ -1948,15 +1932,13 @@ skip_duration_calc:
 fill_all_stream_timings(ic);
 
 avio_seek(ic->pb, old_offset, SEEK_SET);
+
+ff_read_frame_flush(ic);
 for (unsigned i = 0; i < ic->nb_streams; i++) {
 AVStream *const st  = ic->streams[i];
 FFStream *const sti = ffstream(st);
 
 sti->cur_dts = sti->first_dts;
-sti->last_IP_pts = AV_NOPTS_VALUE;
-sti->last_dts_for_order_check = AV_NOPTS_VALUE;
-for (int j = 0; j < MAX_REORDER_DELAY + 1; j++)
-sti->pts_buffer[j] = AV_NOPTS_VALUE;
 }
 }
 
diff --git a/tests/ref/fate/concat-demuxer-simple2-lavf-ts 
b/tests/ref/fate/concat-demuxer-simple2-lavf-ts
index 548cab01c6..86e5e6670f 100644
--- a/tests/ref/fate/concat-demuxer-simple2-lavf-ts
+++ b/tests/ref/fate/concat-demuxer-simple2-lavf-ts
@@ -62,90 +62,90 @@ 
audio|0|86988|0.966533|86988|0.966533|2351|0.026122|209|N/A|K__
 audio|0|89339|0.99265