[FFmpeg-cvslog] avcodec/nvenc: fix timestamp offset ticks logic
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
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
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
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
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
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
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
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
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
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
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
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".