[FFmpeg-cvslog] avcodec/nvenc: fix timestamp offset ticks logic

2021-01-09 Thread Timo Rothenpieler
ffmpeg | branch: master | Timo Rothenpieler  | Sat Jan  
9 16:34:59 2021 +0100| [7a2d94cf1ade02829b36f9ebc8d6bb2e6e126343] | committer: 
Timo Rothenpieler

avcodec/nvenc: fix timestamp offset ticks logic

> http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=7a2d94cf1ade02829b36f9ebc8d6bb2e6e126343
---

 libavcodec/nvenc.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/libavcodec/nvenc.c b/libavcodec/nvenc.c
index 1c06b6af27..0830db714c 100644
--- a/libavcodec/nvenc.c
+++ b/libavcodec/nvenc.c
@@ -1921,7 +1921,7 @@ static int nvenc_set_timestamp(AVCodecContext *avctx,
 pkt->pts = params->outputTimeStamp;
 pkt->dts = timestamp_queue_dequeue(ctx->timestamp_list);
 
-pkt->dts -= FFMAX(avctx->max_b_frames, 0) * FFMIN(avctx->ticks_per_frame, 
1);
+pkt->dts -= FFMAX(avctx->max_b_frames, 0) * FFMAX(avctx->ticks_per_frame, 
1);
 
 return 0;
 }

___
ffmpeg-cvslog mailing list
ffmpeg-cvslog@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-cvslog

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

[FFmpeg-cvslog] avformat/mov: adjust skip_samples according to seek timestamp

2021-01-09 Thread Matthieu Bouron
ffmpeg | branch: master | Matthieu Bouron  | Fri Oct 
30 15:38:51 2020 +0100| [2e174354805ea220b6a57f6b8755347c7f240077] | committer: 
Marton Balint

avformat/mov: adjust skip_samples according to seek timestamp

Currently skip_samples is set to start_pad if sample_time is lesser or
equal to 0. This can cause issues if the stream starts with packets that
have negative pts. Calling avformat_seek_file() with ts set to 0 on such
streams makes the mov demuxer return the right corresponding packets
(near the 0 timestamp) but set skip_samples to start_pad which is
incorrect as the audio decoder will discard the returned samples
according to skip_samples from the first packet it receives (which has
its timestamp near 0).

For example, considering the following audio stream with start_pad=1344:

 [PKT pts=-1344] [PKT pts=-320] [PKT pts=704] [PKT pts=1728] [...]

Calling avformat_seek_file() with ts=0 makes the next call to
av_read_frame() return the packet with pts=-320 and a skip samples
side data set to 1344 (start_pad). This makes the audio decoder
incorrectly discard (1344 - 320) samples.

This commit makes the move demuxer adjust skip_samples according to the
stream start_pad, seek timestamp and first sample timestamp.

The above example will now result in av_read_frame() still returning the
packet with pts=-320 but with a skip samples side data set to 320
(src_pad - (seek_timestamp - first_timestamp)). This makes the audio
decoder only discard 320 samples (from pts=-320 to pts=0).

Signed-off-by: Marton Balint 

> http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=2e174354805ea220b6a57f6b8755347c7f240077
---

 libavformat/mov.c | 23 ---
 1 file changed, 20 insertions(+), 3 deletions(-)

diff --git a/libavformat/mov.c b/libavformat/mov.c
index c6a2d9c388..3215b53636 100644
--- a/libavformat/mov.c
+++ b/libavformat/mov.c
@@ -8122,6 +8122,22 @@ static int mov_seek_stream(AVFormatContext *s, AVStream 
*st, int64_t timestamp,
 return sample;
 }
 
+static int64_t mov_get_skip_samples(AVStream *st, int sample)
+{
+MOVStreamContext *sc = st->priv_data;
+int64_t first_ts = st->internal->index_entries[0].timestamp;
+int64_t ts = st->internal->index_entries[sample].timestamp;
+int64_t off;
+
+if (st->codecpar->codec_type != AVMEDIA_TYPE_AUDIO)
+return 0;
+
+/* compute skip samples according to stream start_pad, seek ts and first 
ts */
+off = av_rescale_q(ts - first_ts, st->time_base,
+   (AVRational){1, st->codecpar->sample_rate});
+return FFMAX(sc->start_pad - off, 0);
+}
+
 static int mov_read_seek(AVFormatContext *s, int stream_index, int64_t 
sample_time, int flags)
 {
 MOVContext *mc = s->priv_data;
@@ -8140,18 +8156,19 @@ static int mov_read_seek(AVFormatContext *s, int 
stream_index, int64_t sample_ti
 if (mc->seek_individually) {
 /* adjust seek timestamp to found sample timestamp */
 int64_t seek_timestamp = st->internal->index_entries[sample].timestamp;
+st->internal->skip_samples = mov_get_skip_samples(st, sample);
 
 for (i = 0; i < s->nb_streams; i++) {
 int64_t timestamp;
-MOVStreamContext *sc = s->streams[i]->priv_data;
 st = s->streams[i];
-st->internal->skip_samples = (sample_time <= 0) ? sc->start_pad : 
0;
 
 if (stream_index == i)
 continue;
 
 timestamp = av_rescale_q(seek_timestamp, 
s->streams[stream_index]->time_base, st->time_base);
-mov_seek_stream(s, st, timestamp, flags);
+sample = mov_seek_stream(s, st, timestamp, flags);
+if (sample >= 0)
+st->internal->skip_samples = mov_get_skip_samples(st, sample);
 }
 } else {
 for (i = 0; i < s->nb_streams; i++) {

___
ffmpeg-cvslog mailing list
ffmpeg-cvslog@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-cvslog

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

[FFmpeg-cvslog] doc/protocols: explain tcp listen option description

2021-01-09 Thread Lingjiang Fang
ffmpeg | branch: master | Lingjiang Fang  | Sat Jan  2 
19:37:34 2021 +0800| [c4407a3e00033c7dd2260a3203fd5a5f104737b9] | committer: 
Marton Balint

doc/protocols: explain tcp listen option description

Signed-off-by: Marton Balint 

> http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=c4407a3e00033c7dd2260a3203fd5a5f104737b9
---

 doc/protocols.texi | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/doc/protocols.texi b/doc/protocols.texi
index af887761e9..c0b511b7a4 100644
--- a/doc/protocols.texi
+++ b/doc/protocols.texi
@@ -1652,8 +1652,9 @@ tcp://@var{hostname}:@var{port}[?@var{options}]
 The list of supported options follows.
 
 @table @option
-@item listen=@var{1|0}
-Listen for an incoming connection. Default value is 0.
+@item listen=@var{2|1|0}
+Listen for an incoming connection. 0 disables listen, 1 enables listen in
+single client mode, 2 enables listen in multi-client mode. Default value is 0.
 
 @item timeout=@var{microseconds}
 Set raise error timeout, expressed in microseconds.

___
ffmpeg-cvslog mailing list
ffmpeg-cvslog@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-cvslog

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

[FFmpeg-cvslog] avdevice/decklink_dec: mark get_frame_timecode and get_bmd_timecode static

2021-01-09 Thread Christopher Degawa
ffmpeg | branch: master | Christopher Degawa  | Wed Jan  6 
18:09:36 2021 +| [eacad3406e3e772558642d342e87892c3338eb4e] | committer: 
Marton Balint

avdevice/decklink_dec: mark get_frame_timecode and get_bmd_timecode static

The function is not used anywhere else and is causing mingw-w64 clang
builds to fail with

ffmpeg-git/libavdevice/decklink_dec.cpp:792:5: error: no previous prototype for 
function 'get_bmd_timecode' [-Werror,-Wmissing-prototypes]
int get_bmd_timecode(AVFormatContext *avctx, AVTimecode *tc, AVRational 
frame_rate, BMDTimecodeFormat tc_format, IDeckLinkVideoInputFrame *videoFrame)

Signed-off-by: Christopher Degawa 
Signed-off-by: Marton Balint 

> http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=eacad3406e3e772558642d342e87892c3338eb4e
---

 libavdevice/decklink_dec.cpp | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/libavdevice/decklink_dec.cpp b/libavdevice/decklink_dec.cpp
index 6bd4676f5e..4f8103e614 100644
--- a/libavdevice/decklink_dec.cpp
+++ b/libavdevice/decklink_dec.cpp
@@ -789,7 +789,7 @@ static int64_t get_pkt_pts(IDeckLinkVideoInputFrame 
*videoFrame,
 return pts;
 }
 
-int get_bmd_timecode(AVFormatContext *avctx, AVTimecode *tc, AVRational 
frame_rate, BMDTimecodeFormat tc_format, IDeckLinkVideoInputFrame *videoFrame)
+static int get_bmd_timecode(AVFormatContext *avctx, AVTimecode *tc, AVRational 
frame_rate, BMDTimecodeFormat tc_format, IDeckLinkVideoInputFrame *videoFrame)
 {
 IDeckLinkTimecode *timecode;
 int ret = AVERROR(ENOENT);
@@ -811,7 +811,7 @@ int get_bmd_timecode(AVFormatContext *avctx, AVTimecode 
*tc, AVRational frame_ra
 return ret;
 }
 
-int get_frame_timecode(AVFormatContext *avctx, decklink_ctx *ctx, AVTimecode 
*tc, IDeckLinkVideoInputFrame *videoFrame)
+static int get_frame_timecode(AVFormatContext *avctx, decklink_ctx *ctx, 
AVTimecode *tc, IDeckLinkVideoInputFrame *videoFrame)
 {
 AVRational frame_rate = ctx->video_st->r_frame_rate;
 int ret;

___
ffmpeg-cvslog mailing list
ffmpeg-cvslog@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-cvslog

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

[FFmpeg-cvslog] sbc: do not set sample format in parser

2021-01-09 Thread Arnaud Vrac
ffmpeg | branch: master | Arnaud Vrac  | Tue Jan  5 13:47:43 
2021 +0100| [29993b2947a99806cf41dd58853af510b0ce152c] | committer: James Almer

sbc: do not set sample format in parser

Commit bdd31feec934 changed the SBC decoder to only set the output
sample format on init, instead of setting it explicitly on each frame,
which is correct. But the SBC parser overrides the sample format to S16,
which triggers a crash when combining the parser and the decoder.

Fix the issue by not setting the sample format anymore in the parser,
which is wrong.

Signed-off-by: James Almer 

> http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=29993b2947a99806cf41dd58853af510b0ce152c
---

 libavcodec/sbc_parser.c | 2 --
 1 file changed, 2 deletions(-)

diff --git a/libavcodec/sbc_parser.c b/libavcodec/sbc_parser.c
index f56564147a..5549b1951c 100644
--- a/libavcodec/sbc_parser.c
+++ b/libavcodec/sbc_parser.c
@@ -42,7 +42,6 @@ static int sbc_parse_header(AVCodecParserContext *s, 
AVCodecContext *avctx,
 
 if (data[0] == MSBC_SYNCWORD && data[1] == 0 && data[2] == 0) {
 avctx->channels = 1;
-avctx->sample_fmt = AV_SAMPLE_FMT_S16;
 avctx->sample_rate = 16000;
 avctx->frame_size = 120;
 s->duration = avctx->frame_size;
@@ -66,7 +65,6 @@ static int sbc_parse_header(AVCodecParserContext *s, 
AVCodecContext *avctx,
  + (joint * subbands)) + 7) / 8;
 
 avctx->channels = channels;
-avctx->sample_fmt = AV_SAMPLE_FMT_S16;
 avctx->sample_rate = sample_rates[sr];
 avctx->frame_size = subbands * blocks;
 s->duration = avctx->frame_size;

___
ffmpeg-cvslog mailing list
ffmpeg-cvslog@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-cvslog

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

[FFmpeg-cvslog] lavu/tx: clip when converting table values to fixed-point

2021-01-09 Thread Lynne
ffmpeg | branch: master | Lynne  | Sat Jan  9 20:41:25 2021 
+0100| [91e1625db15fe8853ceedca9eed14307aaa514c7] | committer: Lynne

lavu/tx: clip when converting table values to fixed-point

INT32_MAX (2147483647) isn't exactly representable by a floating point
value, with the closest being 2147483648.0. So when rescaling a value
of 1.0, this could overflow when casting the 64-bit value returned from
lrintf() into 32 bits.
Unfortunately the properties of integer overflows don't match up well
with how a Fourier Transform operates. So clip the value before
casting to a 32-bit int.

Should be noted we don't have overflows with the table values we're
currently using. However, converting a Kaiser-Bessel window function
with a length of 256 and a parameter of 5.0 to fixed point did create
overflows. So this is more of insurance to save debugging time
in case something changes in the future.
The macro is only used during init, so it being a little slower is
not a problem.

> http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=91e1625db15fe8853ceedca9eed14307aaa514c7
---

 libavutil/tx_priv.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/libavutil/tx_priv.h b/libavutil/tx_priv.h
index a3738f68bd..0ace3e90dc 100644
--- a/libavutil/tx_priv.h
+++ b/libavutil/tx_priv.h
@@ -85,7 +85,7 @@ typedef void FFTComplex;
 (dim)   = (int)(((accu) + 0x4000) >> 31);  
\
 } while (0)
 
-#define RESCALE(x) (lrintf((x) * 2147483648.0))
+#define RESCALE(x) (av_clip64(lrintf((x) * 2147483648.0), INT32_MIN, 
INT32_MAX))
 
 #define FOLD(x, y) ((int)((x) + (unsigned)(y) + 32) >> 6)
 

___
ffmpeg-cvslog mailing list
ffmpeg-cvslog@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-cvslog

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

[FFmpeg-cvslog] avformat/utils: do not overwrite already existing program with defaults in av_new_program

2021-01-09 Thread Marton Balint
ffmpeg | branch: master | Marton Balint  | Sun Dec 27 20:32:54 
2020 +0100| [9298e8eb61f6c796aaf7c6e14e59f345318d2753] | committer: Marton 
Balint

avformat/utils: do not overwrite already existing program with defaults in 
av_new_program

av_new_program returns the existing program if that already exists, in that
case it makes no sense to overwrite existing attributes.

Signed-off-by: Marton Balint 

> http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=9298e8eb61f6c796aaf7c6e14e59f345318d2753
---

 libavformat/utils.c | 12 +---
 1 file changed, 5 insertions(+), 7 deletions(-)

diff --git a/libavformat/utils.c b/libavformat/utils.c
index 3ba4ae4123..c52f39e1b7 100644
--- a/libavformat/utils.c
+++ b/libavformat/utils.c
@@ -4590,14 +4590,12 @@ AVProgram *av_new_program(AVFormatContext *ac, int id)
 dynarray_add(&ac->programs, &ac->nb_programs, program);
 program->discard = AVDISCARD_NONE;
 program->pmt_version = -1;
+program->id = id;
+program->pts_wrap_reference = AV_NOPTS_VALUE;
+program->pts_wrap_behavior = AV_PTS_WRAP_IGNORE;
+program->start_time =
+program->end_time   = AV_NOPTS_VALUE;
 }
-program->id = id;
-program->pts_wrap_reference = AV_NOPTS_VALUE;
-program->pts_wrap_behavior = AV_PTS_WRAP_IGNORE;
-
-program->start_time =
-program->end_time   = AV_NOPTS_VALUE;
-
 return program;
 }
 

___
ffmpeg-cvslog mailing list
ffmpeg-cvslog@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-cvslog

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

[FFmpeg-cvslog] avformat/mpegts: never discard PAT pid

2021-01-09 Thread Marton Balint
ffmpeg | branch: master | Marton Balint  | Sun Dec 27 17:35:36 
2020 +0100| [5ea37923a8aaa3f670c1455c783c10d3142f4a71] | committer: Marton 
Balint

avformat/mpegts: never discard PAT pid

PID 0 was removed from the pid list when then PMT was parsed, it is better
to explictly avoid it from being discarded instead of keeing it in the list of
every program.

Signed-off-by: Marton Balint 

> http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=5ea37923a8aaa3f670c1455c783c10d3142f4a71
---

 libavformat/mpegts.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/libavformat/mpegts.c b/libavformat/mpegts.c
index efff5130de..3712dad1c8 100644
--- a/libavformat/mpegts.c
+++ b/libavformat/mpegts.c
@@ -380,6 +380,9 @@ static int discard_pid(MpegTSContext *ts, unsigned int pid)
 int used = 0, discarded = 0;
 struct Program *p;
 
+if (pid == PAT_PID)
+return 0;
+
 /* If none of the programs have .discard=AVDISCARD_ALL then there's
  * no way we have to discard this packet */
 for (k = 0; k < ts->stream->nb_programs; k++)
@@ -2543,7 +2546,6 @@ static void pat_cb(MpegTSFilter *filter, const uint8_t 
*section, int section_len
 if (!ts->pids[pmt_pid])
 mpegts_open_section_filter(ts, pmt_pid, pmt_cb, ts, 1);
 add_pat_entry(ts, sid);
-add_pid_to_pmt(ts, sid, 0); // add pat pid to program
 add_pid_to_pmt(ts, sid, pmt_pid);
 }
 }

___
ffmpeg-cvslog mailing list
ffmpeg-cvslog@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-cvslog

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

[FFmpeg-cvslog] avformat/mpegts: rework clearing and adding pid to program

2021-01-09 Thread Marton Balint
ffmpeg | branch: master | Marton Balint  | Sun Dec 27 19:38:50 
2020 +0100| [10c8e532943cc1339cf42d3f84eed4eafd8b0ca8] | committer: Marton 
Balint

avformat/mpegts: rework clearing and adding pid to program

And use better function names.

Signed-off-by: Marton Balint 

> http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=10c8e532943cc1339cf42d3f84eed4eafd8b0ca8
---

 libavformat/mpegts.c | 59 ++--
 1 file changed, 25 insertions(+), 34 deletions(-)

diff --git a/libavformat/mpegts.c b/libavformat/mpegts.c
index 3712dad1c8..1b990f7a66 100644
--- a/libavformat/mpegts.c
+++ b/libavformat/mpegts.c
@@ -285,16 +285,12 @@ static void clear_avprogram(MpegTSContext *ts, unsigned 
int programid)
 prg->nb_stream_indexes = 0;
 }
 
-static void clear_program(MpegTSContext *ts, unsigned int programid)
+static void clear_program(struct Program *p)
 {
-int i;
-
-clear_avprogram(ts, programid);
-for (i = 0; i < ts->nb_prg; i++)
-if (ts->prg[i].id == programid) {
-ts->prg[i].nb_pids = 0;
-ts->prg[i].pmt_found = 0;
-}
+if (!p)
+return;
+p->nb_pids = 0;
+p->pmt_found = 0;
 }
 
 static void clear_programs(MpegTSContext *ts)
@@ -303,24 +299,22 @@ static void clear_programs(MpegTSContext *ts)
 ts->nb_prg = 0;
 }
 
-static void add_pat_entry(MpegTSContext *ts, unsigned int programid)
+static struct Program * add_program(MpegTSContext *ts, unsigned int programid)
 {
 struct Program *p;
 if (av_reallocp_array(&ts->prg, ts->nb_prg + 1, sizeof(*ts->prg)) < 0) {
 ts->nb_prg = 0;
-return;
+return NULL;
 }
 p = &ts->prg[ts->nb_prg];
 p->id = programid;
-p->nb_pids = 0;
-p->pmt_found = 0;
+clear_program(p);
 ts->nb_prg++;
+return p;
 }
 
-static void add_pid_to_pmt(MpegTSContext *ts, unsigned int programid,
-   unsigned int pid)
+static void add_pid_to_program(struct Program *p, unsigned int pid)
 {
-struct Program *p = get_program(ts, programid);
 int i;
 if (!p)
 return;
@@ -335,15 +329,6 @@ static void add_pid_to_pmt(MpegTSContext *ts, unsigned int 
programid,
 p->pids[p->nb_pids++] = pid;
 }
 
-static void set_pmt_found(MpegTSContext *ts, unsigned int programid)
-{
-struct Program *p = get_program(ts, programid);
-if (!p)
-return;
-
-p->pmt_found = 1;
-}
-
 static void update_av_program_info(AVFormatContext *s, unsigned int programid,
unsigned int pid, int version)
 {
@@ -2290,6 +2275,7 @@ static void pmt_cb(MpegTSFilter *filter, const uint8_t 
*section, int section_len
 int desc_list_len;
 uint32_t prog_reg_desc = 0; /* registration descriptor */
 int stream_identifier = -1;
+struct Program *prg;
 
 int mp4_descr_count = 0;
 Mp4Descr mp4_descr[MAX_MP4_DESCR_COUNT] = { { 0 } };
@@ -2313,16 +2299,20 @@ static void pmt_cb(MpegTSFilter *filter, const uint8_t 
*section, int section_len
 if (!ts->scan_all_pmts && ts->skip_changes)
 return;
 
-if (ts->skip_unknown_pmt && !get_program(ts, h->id))
+prg = get_program(ts, h->id);
+
+if (ts->skip_unknown_pmt && !prg)
 return;
-if (!ts->skip_clear)
-clear_program(ts, h->id);
+if (!ts->skip_clear) {
+clear_avprogram(ts, h->id);
+clear_program(prg);
+}
 
 pcr_pid = get16(&p, p_end);
 if (pcr_pid < 0)
 return;
 pcr_pid &= 0x1fff;
-add_pid_to_pmt(ts, h->id, pcr_pid);
+add_pid_to_program(prg, pcr_pid);
 update_av_program_info(ts->stream, h->id, pcr_pid, h->version);
 
 av_log(ts->stream, AV_LOG_TRACE, "pcr_pid=0x%x\n", pcr_pid);
@@ -2362,8 +2352,8 @@ static void pmt_cb(MpegTSFilter *filter, const uint8_t 
*section, int section_len
 if (!ts->pkt)
 ts->stop_parse = 2;
 
-set_pmt_found(ts, h->id);
-
+if (prg)
+prg->pmt_found = 1;
 
 for (i = 0; ; i++) {
 st = 0;
@@ -2453,7 +2443,7 @@ static void pmt_cb(MpegTSFilter *filter, const uint8_t 
*section, int section_len
 if (pes && !pes->stream_type)
 mpegts_set_stream_info(st, pes, stream_type, prog_reg_desc);
 
-add_pid_to_pmt(ts, h->id, pid);
+add_pid_to_program(prg, pid);
 
 av_program_add_stream_index(ts->stream, h->id, st->index);
 
@@ -2532,6 +2522,7 @@ static void pat_cb(MpegTSFilter *filter, const uint8_t 
*section, int section_len
 /* NIT info */
 } else {
 MpegTSFilter *fil = ts->pids[pmt_pid];
+struct Program *prg;
 program = av_new_program(ts->stream, sid);
 if (program) {
 program->program_num = sid;
@@ -2545,8 +2536,8 @@ static void pat_cb(MpegTSFilter *filter, const uint8_t 
*section, int section_len
 
 if (!ts->pids[pmt_pid])
 mpegts_open_section_filter(ts, pmt_pid, pmt_cb, ts, 1);
-add_pat_entry(ts, sid);
-

[FFmpeg-cvslog] avformat/mpegts: only clear programs which no longer exist or have a new PMT

2021-01-09 Thread Marton Balint
ffmpeg | branch: master | Marton Balint  | Sun Dec 27 23:05:16 
2020 +0100| [f143a6c1515cb0c4db4dbead46d0e7c53fafc5db] | committer: Marton 
Balint

avformat/mpegts: only clear programs which no longer exist or have a new PMT

Otherwise there can be a small period when the programs only contain the PMT
pid.

Also make sure skip_clear only affects AVProgram clear, and that pmt_pid is
always kept as the first entry of the PID list of the programs. Also reject
PMTs for programs on the wrong PID.

Signed-off-by: Marton Balint 

> http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=f143a6c1515cb0c4db4dbead46d0e7c53fafc5db
---

 libavformat/mpegts.c | 27 +--
 1 file changed, 21 insertions(+), 6 deletions(-)

diff --git a/libavformat/mpegts.c b/libavformat/mpegts.c
index 1b990f7a66..ee69e2ca29 100644
--- a/libavformat/mpegts.c
+++ b/libavformat/mpegts.c
@@ -20,6 +20,7 @@
  */
 
 #include "libavutil/buffer.h"
+#include "libavutil/common.h"
 #include "libavutil/crc.h"
 #include "libavutil/internal.h"
 #include "libavutil/intreadwrite.h"
@@ -301,7 +302,9 @@ static void clear_programs(MpegTSContext *ts)
 
 static struct Program * add_program(MpegTSContext *ts, unsigned int programid)
 {
-struct Program *p;
+struct Program *p = get_program(ts, programid);
+if (p)
+return p;
 if (av_reallocp_array(&ts->prg, ts->nb_prg + 1, sizeof(*ts->prg)) < 0) {
 ts->nb_prg = 0;
 return NULL;
@@ -2303,10 +2306,12 @@ static void pmt_cb(MpegTSFilter *filter, const uint8_t 
*section, int section_len
 
 if (ts->skip_unknown_pmt && !prg)
 return;
-if (!ts->skip_clear) {
+if (prg && prg->nb_pids && prg->pids[0] != ts->current_pid)
+return;
+if (!ts->skip_clear)
 clear_avprogram(ts, h->id);
-clear_program(prg);
-}
+clear_program(prg);
+add_pid_to_program(prg, ts->current_pid);
 
 pcr_pid = get16(&p, p_end);
 if (pcr_pid < 0)
@@ -2485,6 +2490,7 @@ static void pat_cb(MpegTSFilter *filter, const uint8_t 
*section, int section_len
 SectionHeader h1, *h = &h1;
 const uint8_t *p, *p_end;
 int sid, pmt_pid;
+int nb_prg = 0;
 AVProgram *program;
 
 av_log(ts->stream, AV_LOG_TRACE, "PAT:\n");
@@ -2503,7 +2509,6 @@ static void pat_cb(MpegTSFilter *filter, const uint8_t 
*section, int section_len
 return;
 ts->stream->ts_id = h->id;
 
-clear_programs(ts);
 for (;;) {
 sid = get16(&p, p_end);
 if (sid < 0)
@@ -2537,9 +2542,19 @@ static void pat_cb(MpegTSFilter *filter, const uint8_t 
*section, int section_len
 if (!ts->pids[pmt_pid])
 mpegts_open_section_filter(ts, pmt_pid, pmt_cb, ts, 1);
 prg = add_program(ts, sid);
-add_pid_to_program(prg, pmt_pid);
+if (prg) {
+unsigned prg_idx = prg - ts->prg;
+if (prg->nb_pids && prg->pids[0] != pmt_pid)
+clear_program(prg);
+add_pid_to_program(prg, pmt_pid);
+if (prg_idx > nb_prg)
+FFSWAP(struct Program, ts->prg[nb_prg], ts->prg[prg_idx]);
+if (prg_idx >= nb_prg)
+nb_prg++;
+}
 }
 }
+ts->nb_prg = nb_prg;
 
 if (sid < 0) {
 int i,j;

___
ffmpeg-cvslog mailing list
ffmpeg-cvslog@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-cvslog

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

[FFmpeg-cvslog] avformat/mpegts: use stream index based lookup with merge_pmt_versions if stream identifier matches multiple streams

2021-01-09 Thread Marton Balint
ffmpeg | branch: master | Marton Balint  | Sun Dec 27 23:49:06 
2020 +0100| [e57879ec18edab5827268a498577cece82d56811] | committer: Marton 
Balint

avformat/mpegts: use stream index based lookup with merge_pmt_versions if 
stream identifier matches multiple streams

Also make sure we are checking the old state of the streams because otherwise
some streams might already have the newly parsed stream identifiers which
corrupts matching.

Fixes streams having the same identifier mixed up on pmt version change.

Fixes ticket #9006.

Signed-off-by: Marton Balint 

> http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=e57879ec18edab5827268a498577cece82d56811
---

 libavformat/mpegts.c | 53 
 1 file changed, 33 insertions(+), 20 deletions(-)

diff --git a/libavformat/mpegts.c b/libavformat/mpegts.c
index ee69e2ca29..bde0eeec35 100644
--- a/libavformat/mpegts.c
+++ b/libavformat/mpegts.c
@@ -107,11 +107,19 @@ struct MpegTSFilter {
 } u;
 };
 
-#define MAX_PIDS_PER_PROGRAM 64
+struct Stream {
+int idx;
+int stream_identifier;
+};
+
+#define MAX_STREAMS_PER_PROGRAM 128
+#define MAX_PIDS_PER_PROGRAM (MAX_STREAMS_PER_PROGRAM + 2)
 struct Program {
 unsigned int id; // program id/service id
 unsigned int nb_pids;
 unsigned int pids[MAX_PIDS_PER_PROGRAM];
+unsigned int nb_streams;
+struct Stream streams[MAX_STREAMS_PER_PROGRAM];
 
 /** have we found pmt for this program */
 int pmt_found;
@@ -291,6 +299,7 @@ static void clear_program(struct Program *p)
 if (!p)
 return;
 p->nb_pids = 0;
+p->nb_streams = 0;
 p->pmt_found = 0;
 }
 
@@ -2193,25 +2202,20 @@ int ff_parse_mpeg2_descriptor(AVFormatContext *fc, 
AVStream *st, int stream_type
 }
 
 static AVStream *find_matching_stream(MpegTSContext *ts, int pid, unsigned int 
programid,
-  int stream_identifier, int 
pmt_stream_idx)
+  int stream_identifier, int 
pmt_stream_idx, struct Program *p)
 {
 AVFormatContext *s = ts->stream;
 int i;
 AVStream *found = NULL;
 
-for (i = 0; i < s->nb_streams; i++) {
-AVStream *st = s->streams[i];
-if (st->program_num != programid)
-continue;
-if (stream_identifier != -1) { /* match based on "stream identifier 
descriptor" if present */
-if (st->stream_identifier == stream_identifier+1) {
-found = st;
-break;
-}
-} else if (st->pmt_stream_idx == pmt_stream_idx) { /* match based on 
position within the PMT */
-found = st;
-break;
+if (stream_identifier) { /* match based on "stream identifier descriptor" 
if present */
+for (i = 0; i < p->nb_streams; i++) {
+if (p->streams[i].stream_identifier == stream_identifier)
+if (!found || pmt_stream_idx == i) /* fallback to idx based 
guess if multiple streams have the same identifier */
+found = s->streams[p->streams[i].idx];
 }
+} else if (pmt_stream_idx < p->nb_streams) { /* match based on position 
within the PMT */
+found = s->streams[p->streams[pmt_stream_idx].idx];
 }
 
 if (found) {
@@ -2270,6 +2274,7 @@ static void pmt_cb(MpegTSFilter *filter, const uint8_t 
*section, int section_len
 {
 MpegTSContext *ts = filter->u.section_filter.opaque;
 MpegTSSectionFilter *tssf = &filter->u.section_filter;
+struct Program old_program;
 SectionHeader h1, *h = &h1;
 PESContext *pes;
 AVStream *st;
@@ -2303,6 +2308,10 @@ static void pmt_cb(MpegTSFilter *filter, const uint8_t 
*section, int section_len
 return;
 
 prg = get_program(ts, h->id);
+if (prg)
+old_program = *prg;
+else
+clear_program(&old_program);
 
 if (ts->skip_unknown_pmt && !prg)
 return;
@@ -2360,7 +2369,7 @@ static void pmt_cb(MpegTSFilter *filter, const uint8_t 
*section, int section_len
 if (prg)
 prg->pmt_found = 1;
 
-for (i = 0; ; i++) {
+for (i = 0; i < MAX_STREAMS_PER_PROGRAM; i++) {
 st = 0;
 pes = NULL;
 stream_type = get8(&p, p_end);
@@ -2373,14 +2382,13 @@ static void pmt_cb(MpegTSFilter *filter, const uint8_t 
*section, int section_len
 if (pid == ts->current_pid)
 goto out;
 
-if (ts->merge_pmt_versions)
-stream_identifier = parse_stream_identifier_desc(p, p_end);
+stream_identifier = parse_stream_identifier_desc(p, p_end) + 1;
 
 /* now create stream */
 if (ts->pids[pid] && ts->pids[pid]->type == MPEGTS_PES) {
 pes = ts->pids[pid]->u.pes_filter.opaque;
 if (ts->merge_pmt_versions && !pes->st) {
-st = find_matching_stream(ts, pid, h->id, stream_identifier, 
i);
+st = find_matching_stream(ts, pid, h->id, stream_identifier, 
i, &old_program);
 if (st) {
 

[FFmpeg-cvslog] avformat: remove some mpegts details from AVStream

2021-01-09 Thread Marton Balint
ffmpeg | branch: master | Marton Balint  | Mon Dec 28 01:21:20 
2020 +0100| [2e2891383e596314a9888ba9b99d6987c82d7c9b] | committer: Marton 
Balint

avformat: remove some mpegts details from AVStream

These fields were added to support -merge_pmt_versions, but the mpegts demuxer
is also keeping track its programs internally, so that should be a better place
to handle it.

Also it is not a very good idea to keep fields like program_num or
pmt_stream_idx in an AVStream, because a single stream can be part of multiple
programs, multiple PMTs, so the stream attributes can refer to any program the
stream is part of.

Since they are not part of public API, lets simply remove them, or rather
replace them with placeholders for ABI compatibility with libavdevice.

Signed-off-by: Marton Balint 

> http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=2e2891383e596314a9888ba9b99d6987c82d7c9b
---

 libavformat/avformat.h | 12 ++--
 libavformat/mpegts.c   |  9 -
 2 files changed, 6 insertions(+), 15 deletions(-)

diff --git a/libavformat/avformat.h b/libavformat/avformat.h
index 4865c56cc3..523cf34d55 100644
--- a/libavformat/avformat.h
+++ b/libavformat/avformat.h
@@ -1096,12 +1096,12 @@ typedef struct AVStream {
  */
 int stream_identifier;
 
-/**
- * Details of the MPEG-TS program which created this stream.
- */
-int program_num;
-int pmt_version;
-int pmt_stream_idx;
+#if LIBAVFORMAT_VERSION_MAJOR < 59
+// kept for ABI compatibility only, do not access in any way
+int unused8;
+int unused9;
+int unused10;
+#endif
 
 /**
  * An opaque field for libavformat internal usage.
diff --git a/libavformat/mpegts.c b/libavformat/mpegts.c
index bde0eeec35..e283ec09d7 100644
--- a/libavformat/mpegts.c
+++ b/libavformat/mpegts.c
@@ -2400,9 +2400,6 @@ static void pmt_cb(MpegTSFilter *filter, const uint8_t 
*section, int section_len
 if (!pes->st)
 goto out;
 pes->st->id = pes->pid;
-pes->st->program_num = h->id;
-pes->st->pmt_version = h->version;
-pes->st->pmt_stream_idx = i;
 }
 st = pes->st;
 } else if (is_pes_stream(stream_type, prog_reg_desc)) {
@@ -2422,9 +2419,6 @@ static void pmt_cb(MpegTSFilter *filter, const uint8_t 
*section, int section_len
 if (!st)
 goto out;
 st->id = pes->pid;
-st->program_num = h->id;
-st->pmt_version = h->version;
-st->pmt_stream_idx = i;
 }
 } else {
 int idx = ff_find_stream_index(ts->stream, pid);
@@ -2439,9 +2433,6 @@ static void pmt_cb(MpegTSFilter *filter, const uint8_t 
*section, int section_len
 if (!st)
 goto out;
 st->id = pid;
-st->program_num = h->id;
-st->pmt_version = h->version;
-st->pmt_stream_idx = i;
 st->codecpar->codec_type = AVMEDIA_TYPE_DATA;
 if (stream_type == 0x86 && prog_reg_desc == AV_RL32("CUEI")) {
 mpegts_find_stream_type(st, stream_type, SCTE_types);

___
ffmpeg-cvslog mailing list
ffmpeg-cvslog@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-cvslog

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