[FFmpeg-devel] [PATCH v3 2/3] avformat/mpegts: keep track of AVProgram.pmt_version and set AV_PROGRAM_CHANGED on version updates

Aman Gupta aman at tmm1.net
Fri May 18 04:13:34 EEST 2018


On Thu, May 17, 2018 at 3:49 PM, Aman Gupta <ffmpeg at tmm1.net> wrote:

> From: Aman Gupta <aman at tmm1.net>
>
> This can be used to detect changes to the streams in an AVProgram
>

Forgot to add: I have seen two related patches in the wild that attempt to
solve this same problem in different ways.

The first is in MythTV's ffmpeg fork, where they added a void
(*streams_changed)(void*); to AVFormatContext and call it from their mpegts
demuxer when the PMT changes.

The second was proposed by XBMC in
https://ffmpeg.org/pipermail/ffmpeg-devel/2012-December/135036.html, where
they created a new AVMEDIA_TYPE_DATA stream with id=0 and attempted to send
packets to it whenever the PMT changed.

The approach in this patch is similar to what's used by
AVFormatContext.event_flags and AVFMT_EVENT_FLAG_METADATA_UPDATED.

I re-used AVProgram.flags for this purpose (which appears not to be used
for anything else). To be more explicit, it might be better to add
AVProgram.event_flags. Note that either way, the user would need to clear
AV_PROGRAM_CHANGED after detecting it (which should be documented).

Another possibility would be to remove AV_PROGRAM_CHANGED altogether, which
means the user would need to keep a copy of program->version and compare it
to detect changes.

Aman


>
> Signed-off-by: Aman Gupta <aman at tmm1.net>
> ---
>  libavformat/mpegts.c | 20 ++++++++++++++++----
>  1 file changed, 16 insertions(+), 4 deletions(-)
>
> diff --git a/libavformat/mpegts.c b/libavformat/mpegts.c
> index fc9bb3940e..e83238d733 100644
> --- a/libavformat/mpegts.c
> +++ b/libavformat/mpegts.c
> @@ -330,12 +330,24 @@ static void set_pmt_found(MpegTSContext *ts,
> unsigned int programid)
>      p->pmt_found = 1;
>  }
>
> -static void set_pcr_pid(AVFormatContext *s, unsigned int programid,
> unsigned int pid)
> +static void update_av_program_info(AVFormatContext *s, unsigned int
> programid,
> +                                   unsigned int pid, int version)
>  {
>      int i;
>      for (i = 0; i < s->nb_programs; i++) {
> -        if (s->programs[i]->id == programid) {
> -            s->programs[i]->pcr_pid = pid;
> +        AVProgram *program = s->programs[i];
> +        if (program->id == programid) {
> +            int old_pcr_pid = program->pcr_pid,
> +                old_version = program->pmt_version;
> +            program->pcr_pid = pid;
> +            program->pmt_version = version;
> +
> +            if (old_version != -1 && old_version != version) {
> +                program->flags |= AV_PROGRAM_CHANGED;
> +                av_log(s, AV_LOG_DEBUG,
> +                       "detected PMT change on program %d (version=%d/%d,
> pcr_pid=0x%x/0x%x)\n",
> +                       programid, old_version, version, old_pcr_pid, pid);
> +            }
>              break;
>          }
>      }
> @@ -2036,7 +2048,7 @@ static void pmt_cb(MpegTSFilter *filter, const
> uint8_t *section, int section_len
>          return;
>      pcr_pid &= 0x1fff;
>      add_pid_to_pmt(ts, h->id, pcr_pid);
> -    set_pcr_pid(ts->stream, h->id, 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);
>
> --
> 2.14.2
>
>


More information about the ffmpeg-devel mailing list