diff mbox

[FFmpeg-devel] libavformat: forced PCR pid in mpegts muxer

Message ID rdbJj0jl8qu3P2q2BIOvV6ii74Rhv9ndEKtBKQ6KXsnrUfjXkXJwRUHAW1GOt1iPUniiKJICZk7sayA8XgJIO5GPI1nuqfICJedW6oWV3pM=@protonmail.com
State New
Headers show

Commit Message

Andreas Håkon April 23, 2019, 12:03 p.m. UTC
‐‐‐‐‐‐‐ Original Message ‐‐‐‐‐‐‐
On Tuesday, 23 de April de 2019 13:43, Moritz Barsnick <barsnick@gmx.net> wrote:

> On Tue, Apr 23, 2019 at 11:15:40 +0000, Andreas Håkon wrote:
>
> Nits:
>
> > Subject: libavformat: forced PCR pid in mpegts muxer
>
> "libavformat/mpegtsenc: allow to force the PID carrying the PCR"
> (or something along those lines)
>
> > By default FFmpeg selects the first video stream, or the first one in
> > the service if no video stream is found.
>
> This could also go into the documentation, if it doesn't already say so
> somewhere.
>
> > All then the output audio stream (with pid:202) will host the PCR marks.
>
> "All then the"?
>
> > +Override the pid for carring the PCR clock.
>
>                         ^
>
>
> Typo: carrying
>
> Thanks,
> Moritz

Thank you Moritz!
All applied.

In addition, one correction regarding the initialization.
Sorry, but first version has an error. This is clean!

Regards.
A.H.

---
From af5a92aa00bb159eb2c967ee8764a2a6ffea1abf Mon Sep 17 00:00:00 2001
From: Andreas Hakon <andreas.hakon@protonmail.com>
Date: Tue, 23 Apr 2019 12:55:04 +0100
Subject: [PATCH] libavformat/mpegtsenc: allow to force the PID carrying the PCR

This patch provides a new optional parameter for the mpegtsenc muxer.
The parameter "-force_prc_pid" can be used to override the default PCR pid.
By default FFmpeg selects the first video stream, or the first one in the
service if no video stream is found. With this new parameter any of the pids in 
the service can be used to carry the PCR clock.
This can be handy for many reasons.

Example:
  $ ffmpeg -i input.mpg -c:v libx264 -c:a mp2 \
    -f mpegts -mpegts_pmt_start_pid 200 -streamid 0:201 -streamid 1:202 \
    -force_pcr_pid 202 output.ts
Result: output audio stream (with pid:202) will host the PCR marks.

Signed-off-by: Andreas Hakon <andreas.hakon@protonmail.com>
---
 doc/muxers.texi         |    5 +++++
 libavformat/mpegtsenc.c |   11 ++++++++---
 2 files changed, 13 insertions(+), 3 deletions(-)

Comments

Moritz Barsnick April 23, 2019, 12:20 p.m. UTC | #1
On Tue, Apr 23, 2019 at 12:03:11 +0000, Andreas Håkon wrote:
> In addition, one correction regarding the initialization.
> Sorry, but first version has an error. This is clean!

I had seen that the option got initialized to 0x0000, but checked that
that is never a legally assigned pid (there's a "< 16" check
somewhere), so figured it would be okay as a default.

>          ts_st->discontinuity   = ts->flags & MPEGTS_FLAG_DISCONT;
> -        /* update PCR pid by using the first video stream */
> -        if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO &&
> -            service->pcr_pid == 0x1fff) {
> +        /* update PCR pid by: forced pid or using the first video stream */
> +        if ((ts->pcr_forced_pid != 0x0010 && ts_st->pid == ts->pcr_forced_pid) ||
> +            (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO && service->pcr_pid == 0x1fff)) {
>              service->pcr_pid = ts_st->pid;

Okay if pid 0x0010 shall actually never carry the PCR. (Probably
0x0010-0x001F if I guess by Wikipedia's list of PIDs properly, but
then, the article isn't very well written for my understanding, and I
have no idea about PIDs.)

Cheers,
Moritz
Andreas Håkon April 23, 2019, 12:34 p.m. UTC | #2
‐‐‐‐‐‐‐ Original Message ‐‐‐‐‐‐‐
On Tuesday, 23 de April de 2019 14:20, Moritz Barsnick <barsnick@gmx.net> wrote:

> On Tue, Apr 23, 2019 at 12:03:11 +0000, Andreas Håkon wrote:
>
> > In addition, one correction regarding the initialization.
> > Sorry, but first version has an error. This is clean!
>
> I had seen that the option got initialized to 0x0000, but checked that
> that is never a legally assigned pid (there's a "< 16" check
> somewhere), so figured it would be okay as a default.
>
> >          ts_st->discontinuity   = ts->flags & MPEGTS_FLAG_DISCONT;
> >
> >
> > -          /* update PCR pid by using the first video stream */
> >
> >
> > -          if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO &&
> >
> >
> > -              service->pcr_pid == 0x1fff) {
> >
> >
> >
> > -          /* update PCR pid by: forced pid or using the first video stream */
> >
> >
> > -          if ((ts->pcr_forced_pid != 0x0010 && ts_st->pid == ts->pcr_forced_pid) ||
> >
> >
> > -              (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO && service->pcr_pid == 0x1fff)) {
> >                service->pcr_pid = ts_st->pid;
> >
> >
>
> Okay if pid 0x0010 shall actually never carry the PCR. (Probably
> 0x0010-0x001F if I guess by Wikipedia's list of PIDs properly, but
> then, the article isn't very well written for my understanding, and I
> have no idea about PIDs.)

Hi Moritz,

Pids 0x00-0x10 (0-16 in decimal values) are reserved. So pid 0x10 can't carry PCR marks.
Then I use this value as the "empty" (aka NOT_SET) value for the parameter. In this case the
default behaviour is used: that's auto-select first video, or first stream if no video.

Regards.
A.H.
Andreas Håkon April 29, 2019, 7:09 a.m. UTC | #3
‐‐‐‐‐‐‐ Original Message ‐‐‐‐‐‐‐
On Tuesday, 23 de April de 2019 14:03, Andreas Håkon <andreas.hakon@protonmail.com> wrote:

>
> Thank you Moritz!
> All applied.
>
> In addition, one correction regarding the initialization.
> Sorry, but first version has an error. This is clean!
>
> Regards.
> A.H.
>


Hi Michael Niedermayer,

All issues resolved now.
Please review this patch about this new handy functionality.


Regards.
A.H.


---
diff mbox

Patch

diff --git a/doc/muxers.texi b/doc/muxers.texi
index 83ae017..e5d81ad 100644
--- a/doc/muxers.texi
+++ b/doc/muxers.texi
@@ -1590,6 +1590,11 @@  is @code{-1}, which results in shifting timestamps so that they start from 0.
 @item omit_video_pes_length @var{boolean}
 Omit the PES packet length for video packets. Default is @code{1} (true).
 
+@item force_pcr_pid @var{integer}
+Override the pid for carrying the PCR clock.
+By default FFmpeg selects the first video stream, or the first one in
+the service if no video stream is found.
+
 @item pcr_period @var{integer}
 Override the default PCR retransmission time in milliseconds. Ignored if
 variable muxrate is selected. Default is @code{20}.
diff --git a/libavformat/mpegtsenc.c b/libavformat/mpegtsenc.c
index fc0ea22..b741b48 100644
--- a/libavformat/mpegtsenc.c
+++ b/libavformat/mpegtsenc.c
@@ -96,6 +96,7 @@  typedef struct MpegTSWrite {
 
     int pmt_start_pid;
     int start_pid;
+    int pcr_forced_pid;
     int m2ts_mode;
 
     int reemit_pat_pmt; // backward compatibility
@@ -913,9 +914,9 @@  static int mpegts_init(AVFormatContext *s)
         ts_st->first_pts_check = 1;
         ts_st->cc              = 15;
         ts_st->discontinuity   = ts->flags & MPEGTS_FLAG_DISCONT;
-        /* update PCR pid by using the first video stream */
-        if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO &&
-            service->pcr_pid == 0x1fff) {
+        /* update PCR pid by: forced pid or using the first video stream */
+        if ((ts->pcr_forced_pid != 0x0010 && ts_st->pid == ts->pcr_forced_pid) ||
+            (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO && service->pcr_pid == 0x1fff)) {
             service->pcr_pid = ts_st->pid;
             pcr_st           = st;
         }
@@ -960,6 +961,7 @@  static int mpegts_init(AVFormatContext *s)
         service->pcr_pid = ts_st->pid;
     } else
         ts_st = pcr_st->priv_data;
+    av_log(s, AV_LOG_VERBOSE, "PCR in pid %d (%d) \n", service->pcr_pid, st->index);
 
     if (ts->mux_rate > 1) {
         service->pcr_packet_period = (int64_t)ts->mux_rate * ts->pcr_period /
@@ -1917,6 +1919,9 @@  static const AVOption options[] = {
     { "mpegts_start_pid", "Set the first pid.",
       offsetof(MpegTSWrite, start_pid), AV_OPT_TYPE_INT,
       { .i64 = 0x0100 }, 0x0010, 0x0f00, AV_OPT_FLAG_ENCODING_PARAM },
+    { "force_pcr_pid", "Force the pid carring PCR.",
+      offsetof(MpegTSWrite, pcr_forced_pid), AV_OPT_TYPE_INT,
+      { .i64 = 0x0010 }, 0x0010, 0x1ffe, AV_OPT_FLAG_ENCODING_PARAM },
     { "mpegts_m2ts_mode", "Enable m2ts mode.",
       offsetof(MpegTSWrite, m2ts_mode), AV_OPT_TYPE_BOOL,
       { .i64 = -1 }, -1, 1, AV_OPT_FLAG_ENCODING_PARAM },