[FFmpeg-devel] [PATCH] libavformat/mpegtsenc: Add minimal support for ATSC PSIP tables

2019-05-15 Thread Phillip Burr
Minimal support for ATSC PSIP tables.  Does not support STT or
EIT tables and so is not compliant with terrestrial ATSC.
ATSC tables are not created by default, and will only be transmitted
if either "atsc_name" or "atsc_channel" metadata is supplied.

Signed-off-by: Phillip Burr 
---
 libavformat/mpegts.h|   8 +
 libavformat/mpegtsenc.c | 412 
 2 files changed, 343 insertions(+), 77 deletions(-)

diff --git a/libavformat/mpegts.h b/libavformat/mpegts.h
index 272e2be4f7..ca6943b1ba 100644
--- a/libavformat/mpegts.h
+++ b/libavformat/mpegts.h
@@ -35,12 +35,20 @@
 /* pids */
 #define PAT_PID 0x
 #define SDT_PID 0x0011
+#define ATSC_PID0x1ffb
 
 /* table ids */
 #define PAT_TID   0x00
 #define PMT_TID   0x02
 #define M4OD_TID  0x05
 #define SDT_TID   0x42
+#define MGT_TID   0xc7
+#define TVCT_TID  0xc8
+#define CVCT_TID  0xc9
+#define RRT_TID   0xca
+#define EIT_TID   0xcb
+#define ETT_TID   0xcc
+#define STT_TID   0xcd
 
 #define STREAM_TYPE_VIDEO_MPEG1 0x01
 #define STREAM_TYPE_VIDEO_MPEG2 0x02
diff --git a/libavformat/mpegtsenc.c b/libavformat/mpegtsenc.c
index fc0ea225c6..9846b50367 100644
--- a/libavformat/mpegtsenc.c
+++ b/libavformat/mpegtsenc.c
@@ -56,6 +56,11 @@ typedef struct MpegTSService {
 int sid;   /* service ID */
 uint8_t name[256];
 uint8_t provider_name[256];
+
+uint16_t atsc_name[7]; /* ATSC VCT fields */
+int atsc_mj_channel;
+int atsc_mn_channel;
+
 int pcr_pid;
 int pcr_packet_count;
 int pcr_packet_period;
@@ -77,11 +82,16 @@ typedef struct MpegTSWrite {
 const AVClass *av_class;
 MpegTSSection pat; /* MPEG-2 PAT table */
 MpegTSSection sdt; /* MPEG-2 SDT table context */
+MpegTSSection atsc; /* ATSC tables */
 MpegTSService **services;
 int sdt_packet_count;
 int sdt_packet_period;
 int pat_packet_count;
 int pat_packet_period;
+int mgt_packet_count;
+int mgt_packet_period;
+int tvct_packet_count;
+int tvct_packet_period;
 int nb_services;
 int onid;
 int tsid;
@@ -113,6 +123,9 @@ typedef struct MpegTSWrite {
 double sdt_period;
 int64_t last_pat_ts;
 int64_t last_sdt_ts;
+int64_t last_mgt_ts;
+int64_t last_tvct_ts;
+int xmit_atsc;
 
 int omit_video_pes_length;
 } MpegTSWrite;
@@ -189,14 +202,24 @@ static inline void put16(uint8_t **q_ptr, int val)
 *q_ptr = q;
 }
 
+static inline void put32(uint8_t **q_ptr, int val)
+{
+uint8_t *q;
+q  = *q_ptr;
+*q++   = val >> 24;
+*q++   = val >> 16;
+*q++   = val >> 8;
+*q++   = val;
+*q_ptr = q;
+}
+
 static int mpegts_write_section1(MpegTSSection *s, int tid, int id,
  int version, int sec_num, int last_sec_num,
- uint8_t *buf, int len)
+ int private, uint8_t *buf, int len)
 {
 uint8_t section[1024], *q;
 unsigned int tot_len;
-/* reserved_future_use field must be set to 1 for SDT */
-unsigned int flags = tid == SDT_TID ? 0xf000 : 0xb000;
+unsigned int flags = private ? 0xf000 : 0xb000;
 
 tot_len = 3 + 5 + len + 4;
 /* check if not too big */
@@ -226,6 +249,12 @@ static int mpegts_write_section1(MpegTSSection *s, int 
tid, int id,
 #define SDT_RETRANS_TIME 500
 #define PAT_RETRANS_TIME 100
 #define PCR_RETRANS_TIME 20
+#define MGT_RETRANS_TIME 150
+#define TVCT_RETRANS_TIME 400
+#define EIT0_RETRANS_TIME 500
+#define EIT1_RETRANS_TIME 3000
+#define EIT23_RETRANS_TIME 6
+#define STT_RETRANS_TIME 1000
 
 typedef struct MpegTSWriteStream {
 struct MpegTSService *service;
@@ -260,7 +289,7 @@ static void mpegts_write_pat(AVFormatContext *s)
 put16(&q, service->sid);
 put16(&q, 0xe000 | service->pmt.pid);
 }
-mpegts_write_section1(&ts->pat, PAT_TID, ts->tsid, ts->tables_version, 0, 
0,
+mpegts_write_section1(&ts->pat, PAT_TID, ts->tsid, ts->tables_version, 0, 
0, 0,
   data, q - data);
 }
 
@@ -282,6 +311,79 @@ static void put_registration_descriptor(uint8_t **q_ptr, 
uint32_t tag)
 *q_ptr = q;
 }
 
+static int extract_stream_type(AVStream *st, MpegTSWrite *ts)
+{
+int stream_type;
+
+switch (st->codecpar->codec_id) {
+case AV_CODEC_ID_MPEG1VIDEO:
+case AV_CODEC_ID_MPEG2VIDEO:
+stream_type = STREAM_TYPE_VIDEO_MPEG2;
+break;
+case AV_CODEC_ID_MPEG4:
+stream_type = STREAM_TYPE_VIDEO_MPEG4;
+break;
+case AV_CODEC_ID_H264:
+stream_type = STREAM_TYPE_VIDEO_H264;
+break;
+case AV_CODEC_ID_HEVC:
+stream_type = STREAM_TYPE_VIDEO_HEVC;
+break;
+case AV_CODEC_ID_CAVS:
+stream_type = STREAM_TYPE_VIDEO_CAVS;
+break;
+case AV_CODEC_ID_DIRAC:
+stream_type = STREAM_TYPE_VIDEO_DIRAC;
+break;
+  

[FFmpeg-devel] [PATCH v2] libavformat/mpegtsenc: Add minimal support for ATSC PSIP tables

2019-05-16 Thread Phillip Burr
Minimal support for ATSC PSIP tables.  Does not support STT or
EIT tables and so is not compliant with terrestrial ATSC.
ATSC tables are not created by default, and will only be transmitted
if either "atsc_name" or "atsc_channel" metadata is supplied.

Signed-off-by: Phillip Burr 
---
 libavformat/mpegts.h|   8 +
 libavformat/mpegtsenc.c | 414 
 2 files changed, 345 insertions(+), 77 deletions(-)

diff --git a/libavformat/mpegts.h b/libavformat/mpegts.h
index 272e2be4f7..ca6943b1ba 100644
--- a/libavformat/mpegts.h
+++ b/libavformat/mpegts.h
@@ -35,12 +35,20 @@
 /* pids */
 #define PAT_PID 0x
 #define SDT_PID 0x0011
+#define ATSC_PID0x1ffb
 
 /* table ids */
 #define PAT_TID   0x00
 #define PMT_TID   0x02
 #define M4OD_TID  0x05
 #define SDT_TID   0x42
+#define MGT_TID   0xc7
+#define TVCT_TID  0xc8
+#define CVCT_TID  0xc9
+#define RRT_TID   0xca
+#define EIT_TID   0xcb
+#define ETT_TID   0xcc
+#define STT_TID   0xcd
 
 #define STREAM_TYPE_VIDEO_MPEG1 0x01
 #define STREAM_TYPE_VIDEO_MPEG2 0x02
diff --git a/libavformat/mpegtsenc.c b/libavformat/mpegtsenc.c
index fc0ea225c6..6707efb913 100644
--- a/libavformat/mpegtsenc.c
+++ b/libavformat/mpegtsenc.c
@@ -56,6 +56,11 @@ typedef struct MpegTSService {
 int sid;   /* service ID */
 uint8_t name[256];
 uint8_t provider_name[256];
+
+uint16_t atsc_name[7]; /* ATSC VCT fields */
+int atsc_mj_channel;
+int atsc_mn_channel;
+
 int pcr_pid;
 int pcr_packet_count;
 int pcr_packet_period;
@@ -77,11 +82,16 @@ typedef struct MpegTSWrite {
 const AVClass *av_class;
 MpegTSSection pat; /* MPEG-2 PAT table */
 MpegTSSection sdt; /* MPEG-2 SDT table context */
+MpegTSSection atsc; /* ATSC tables */
 MpegTSService **services;
 int sdt_packet_count;
 int sdt_packet_period;
 int pat_packet_count;
 int pat_packet_period;
+int mgt_packet_count;
+int mgt_packet_period;
+int tvct_packet_count;
+int tvct_packet_period;
 int nb_services;
 int onid;
 int tsid;
@@ -113,6 +123,9 @@ typedef struct MpegTSWrite {
 double sdt_period;
 int64_t last_pat_ts;
 int64_t last_sdt_ts;
+int64_t last_mgt_ts;
+int64_t last_tvct_ts;
+int xmit_atsc;
 
 int omit_video_pes_length;
 } MpegTSWrite;
@@ -189,14 +202,24 @@ static inline void put16(uint8_t **q_ptr, int val)
 *q_ptr = q;
 }
 
+static inline void put32(uint8_t **q_ptr, int val)
+{
+uint8_t *q;
+q  = *q_ptr;
+*q++   = val >> 24;
+*q++   = val >> 16;
+*q++   = val >> 8;
+*q++   = val;
+*q_ptr = q;
+}
+
 static int mpegts_write_section1(MpegTSSection *s, int tid, int id,
  int version, int sec_num, int last_sec_num,
- uint8_t *buf, int len)
+ int private, uint8_t *buf, int len)
 {
 uint8_t section[1024], *q;
 unsigned int tot_len;
-/* reserved_future_use field must be set to 1 for SDT */
-unsigned int flags = tid == SDT_TID ? 0xf000 : 0xb000;
+unsigned int flags = private ? 0xf000 : 0xb000;
 
 tot_len = 3 + 5 + len + 4;
 /* check if not too big */
@@ -226,6 +249,12 @@ static int mpegts_write_section1(MpegTSSection *s, int 
tid, int id,
 #define SDT_RETRANS_TIME 500
 #define PAT_RETRANS_TIME 100
 #define PCR_RETRANS_TIME 20
+#define MGT_RETRANS_TIME 150
+#define TVCT_RETRANS_TIME 400
+#define EIT0_RETRANS_TIME 500
+#define EIT1_RETRANS_TIME 3000
+#define EIT23_RETRANS_TIME 6
+#define STT_RETRANS_TIME 1000
 
 typedef struct MpegTSWriteStream {
 struct MpegTSService *service;
@@ -260,7 +289,7 @@ static void mpegts_write_pat(AVFormatContext *s)
 put16(&q, service->sid);
 put16(&q, 0xe000 | service->pmt.pid);
 }
-mpegts_write_section1(&ts->pat, PAT_TID, ts->tsid, ts->tables_version, 0, 
0,
+mpegts_write_section1(&ts->pat, PAT_TID, ts->tsid, ts->tables_version, 0, 
0, 0,
   data, q - data);
 }
 
@@ -282,6 +311,79 @@ static void put_registration_descriptor(uint8_t **q_ptr, 
uint32_t tag)
 *q_ptr = q;
 }
 
+static int extract_stream_type(AVStream *st, MpegTSWrite *ts)
+{
+int stream_type;
+
+switch (st->codecpar->codec_id) {
+case AV_CODEC_ID_MPEG1VIDEO:
+case AV_CODEC_ID_MPEG2VIDEO:
+stream_type = STREAM_TYPE_VIDEO_MPEG2;
+break;
+case AV_CODEC_ID_MPEG4:
+stream_type = STREAM_TYPE_VIDEO_MPEG4;
+break;
+case AV_CODEC_ID_H264:
+stream_type = STREAM_TYPE_VIDEO_H264;
+break;
+case AV_CODEC_ID_HEVC:
+stream_type = STREAM_TYPE_VIDEO_HEVC;
+break;
+case AV_CODEC_ID_CAVS:
+stream_type = STREAM_TYPE_VIDEO_CAVS;
+break;
+case AV_CODEC_ID_DIRAC:
+stream_type = STREAM_TYPE_VIDEO_DIRAC;
+break;
+  

[FFmpeg-devel] [PATCH v3] libavformat/mpegtsenc: Add minimal support for ATSC PSIP tables

2019-05-20 Thread Phillip Burr
Minimal support for ATSC PSIP tables.  Does not support STT or
EIT tables and so is not compliant with terrestrial ATSC.
ATSC tables are not created by default, and will only be transmitted
if either "atsc_name" or "atsc_channel" metadata is supplied.

Signed-off-by: Phillip Burr 
---
 doc/muxers.texi |  33 +++-
 libavformat/mpegts.h|   8 +
 libavformat/mpegtsenc.c | 412 
 3 files changed, 372 insertions(+), 81 deletions(-)

diff --git a/doc/muxers.texi b/doc/muxers.texi
index 83ae017d6c..dd68eec362 100644
--- a/doc/muxers.texi
+++ b/doc/muxers.texi
@@ -1500,10 +1500,35 @@ MPEG transport stream muxer.
 
 This muxer implements ISO 13818-1 and part of ETSI EN 300 468.
 
-The recognized metadata settings in mpegts muxer are @code{service_provider}
-and @code{service_name}. If they are not set the default for
-@code{service_provider} is @samp{FFmpeg} and the default for
-@code{service_name} is @samp{Service01}.
+@subsection Metadata
+
+The recognized metadata settings in this muxer are:
+
+@table @option
+@item service_name @var{string}
+Set the @code{service_provider}.  Default is @samp{FFmpeg}.
+
+@item service_name @var{string}
+Set the @code{service_name}. Default is @samp{Service01}.
+
+@item atsc_name @var{string}
+Set the @code{atsc_name} for the stream.  This is the ATSC short
+channel name for the stream.
+
+@item atsc_channel @var{string}
+Set the @code{atsc_channel} virtual channel for the stream.  This
+is parsed as @samp{Channel[.SubChannel]} format where the subchannel
+is optional and defaults to @code{1}.
+
+@end table
+
+ATSC tables will @emph{not} be generated unless either @code{atsc_name}
+or @code{atsc_channel} are provided @emph{and} @code{muxrate} is provided.
+In the event that either @code{atsc_name} or @code{atsc_channel} is provided
+but not both, the default for @code{atsc_name} is @samp{FFmpeg}
+and the default for @code{atsc_channel} is @samp{1.1}.
+ATSC tables generated include @code{MGT} and @code{TVCT} tables but are 
lacking the mandatory
+@code{STT}, @code{EIT0}, @code{EIT1}, @code{EIT2} and @code{EIT3} tables 
needed for terrestrial ATC compliance.
 
 @subsection Options
 
diff --git a/libavformat/mpegts.h b/libavformat/mpegts.h
index 272e2be4f7..ca6943b1ba 100644
--- a/libavformat/mpegts.h
+++ b/libavformat/mpegts.h
@@ -35,12 +35,20 @@
 /* pids */
 #define PAT_PID 0x
 #define SDT_PID 0x0011
+#define ATSC_PID0x1ffb
 
 /* table ids */
 #define PAT_TID   0x00
 #define PMT_TID   0x02
 #define M4OD_TID  0x05
 #define SDT_TID   0x42
+#define MGT_TID   0xc7
+#define TVCT_TID  0xc8
+#define CVCT_TID  0xc9
+#define RRT_TID   0xca
+#define EIT_TID   0xcb
+#define ETT_TID   0xcc
+#define STT_TID   0xcd
 
 #define STREAM_TYPE_VIDEO_MPEG1 0x01
 #define STREAM_TYPE_VIDEO_MPEG2 0x02
diff --git a/libavformat/mpegtsenc.c b/libavformat/mpegtsenc.c
index fc0ea225c6..cd3460e5f3 100644
--- a/libavformat/mpegtsenc.c
+++ b/libavformat/mpegtsenc.c
@@ -56,6 +56,11 @@ typedef struct MpegTSService {
 int sid;   /* service ID */
 uint8_t name[256];
 uint8_t provider_name[256];
+
+uint16_t atsc_name[7]; /* ATSC VCT fields */
+int atsc_mj_channel;
+int atsc_mn_channel;
+
 int pcr_pid;
 int pcr_packet_count;
 int pcr_packet_period;
@@ -77,11 +82,16 @@ typedef struct MpegTSWrite {
 const AVClass *av_class;
 MpegTSSection pat; /* MPEG-2 PAT table */
 MpegTSSection sdt; /* MPEG-2 SDT table context */
+MpegTSSection atsc; /* ATSC tables */
 MpegTSService **services;
 int sdt_packet_count;
 int sdt_packet_period;
 int pat_packet_count;
 int pat_packet_period;
+int mgt_packet_count;
+int mgt_packet_period;
+int tvct_packet_count;
+int tvct_packet_period;
 int nb_services;
 int onid;
 int tsid;
@@ -113,6 +123,9 @@ typedef struct MpegTSWrite {
 double sdt_period;
 int64_t last_pat_ts;
 int64_t last_sdt_ts;
+int64_t last_mgt_ts;
+int64_t last_tvct_ts;
+int xmit_atsc;
 
 int omit_video_pes_length;
 } MpegTSWrite;
@@ -189,14 +202,24 @@ static inline void put16(uint8_t **q_ptr, int val)
 *q_ptr = q;
 }
 
+static inline void put32(uint8_t **q_ptr, int val)
+{
+uint8_t *q;
+q  = *q_ptr;
+*q++   = val >> 24;
+*q++   = val >> 16;
+*q++   = val >> 8;
+*q++   = val;
+*q_ptr = q;
+}
+
 static int mpegts_write_section1(MpegTSSection *s, int tid, int id,
  int version, int sec_num, int last_sec_num,
- uint8_t *buf, int len)
+ int private, uint8_t *buf, int len)
 {
 uint8_t section[1024], *q;
 unsigned int tot_len;
-/* reserved_future_use field must be set to 1 for SDT */
-unsigned int flags = tid == SDT_TID ? 0xf000 : 0xb000;
+unsigned int flags = private ? 0xf000 : 0xb000;
 
 tot_len = 3 +

[FFmpeg-devel] [PATCH v4] libavformat/mpegtsenc: Add minimal support for ATSC PSIP tables

2019-05-21 Thread Phillip Burr
Minimal support for ATSC PSIP tables.  Does not support STT or
EIT tables and so is not compliant with terrestrial ATSC.
ATSC tables are not created by default, and will only be transmitted
if either "atsc_name" or "atsc_channel" metadata is supplied.

Signed-off-by: Phillip Burr 
---
 doc/muxers.texi |  33 ++-
 libavformat/mpegts.h|   8 +
 libavformat/mpegtsenc.c | 468 
 3 files changed, 415 insertions(+), 94 deletions(-)

diff --git a/doc/muxers.texi b/doc/muxers.texi
index 83ae017d6c..dd68eec362 100644
--- a/doc/muxers.texi
+++ b/doc/muxers.texi
@@ -1500,10 +1500,35 @@ MPEG transport stream muxer.
 
 This muxer implements ISO 13818-1 and part of ETSI EN 300 468.
 
-The recognized metadata settings in mpegts muxer are @code{service_provider}
-and @code{service_name}. If they are not set the default for
-@code{service_provider} is @samp{FFmpeg} and the default for
-@code{service_name} is @samp{Service01}.
+@subsection Metadata
+
+The recognized metadata settings in this muxer are:
+
+@table @option
+@item service_name @var{string}
+Set the @code{service_provider}.  Default is @samp{FFmpeg}.
+
+@item service_name @var{string}
+Set the @code{service_name}. Default is @samp{Service01}.
+
+@item atsc_name @var{string}
+Set the @code{atsc_name} for the stream.  This is the ATSC short
+channel name for the stream.
+
+@item atsc_channel @var{string}
+Set the @code{atsc_channel} virtual channel for the stream.  This
+is parsed as @samp{Channel[.SubChannel]} format where the subchannel
+is optional and defaults to @code{1}.
+
+@end table
+
+ATSC tables will @emph{not} be generated unless either @code{atsc_name}
+or @code{atsc_channel} are provided @emph{and} @code{muxrate} is provided.
+In the event that either @code{atsc_name} or @code{atsc_channel} is provided
+but not both, the default for @code{atsc_name} is @samp{FFmpeg}
+and the default for @code{atsc_channel} is @samp{1.1}.
+ATSC tables generated include @code{MGT} and @code{TVCT} tables but are 
lacking the mandatory
+@code{STT}, @code{EIT0}, @code{EIT1}, @code{EIT2} and @code{EIT3} tables 
needed for terrestrial ATC compliance.
 
 @subsection Options
 
diff --git a/libavformat/mpegts.h b/libavformat/mpegts.h
index 272e2be4f7..ca6943b1ba 100644
--- a/libavformat/mpegts.h
+++ b/libavformat/mpegts.h
@@ -35,12 +35,20 @@
 /* pids */
 #define PAT_PID 0x
 #define SDT_PID 0x0011
+#define ATSC_PID0x1ffb
 
 /* table ids */
 #define PAT_TID   0x00
 #define PMT_TID   0x02
 #define M4OD_TID  0x05
 #define SDT_TID   0x42
+#define MGT_TID   0xc7
+#define TVCT_TID  0xc8
+#define CVCT_TID  0xc9
+#define RRT_TID   0xca
+#define EIT_TID   0xcb
+#define ETT_TID   0xcc
+#define STT_TID   0xcd
 
 #define STREAM_TYPE_VIDEO_MPEG1 0x01
 #define STREAM_TYPE_VIDEO_MPEG2 0x02
diff --git a/libavformat/mpegtsenc.c b/libavformat/mpegtsenc.c
index fc0ea225c6..335ff254d8 100644
--- a/libavformat/mpegtsenc.c
+++ b/libavformat/mpegtsenc.c
@@ -56,12 +56,40 @@ typedef struct MpegTSService {
 int sid;   /* service ID */
 uint8_t name[256];
 uint8_t provider_name[256];
+
+uint16_t atsc_name[7]; /* ATSC VCT fields */
+int atsc_mj_channel;
+int atsc_mn_channel;
+
 int pcr_pid;
 int pcr_packet_count;
 int pcr_packet_period;
 AVProgram *program;
 } MpegTSService;
 
+/* The section length is 12 bits. The first 2 are set to 0, the remaining
+ * 10 bits should not exceed 1021. */
+#define SECTION_LENGTH 1020
+
+typedef struct MpegTSAtsc {
+int enabled;
+int regenerate;
+
+MpegTSSection section; /* ATSC tables */
+
+int mgt_packet_count;
+int mgt_packet_period;
+int tvct_packet_count;
+int tvct_packet_period;
+int64_t last_mgt_ts;
+int64_t last_tvct_ts;
+
+uint32_t tvct_length;
+uint32_t mgt_length;
+uint8_t tvct_data[SECTION_LENGTH];
+uint8_t mgt_data[SECTION_LENGTH];
+} MpegTSAtsc;
+
 // service_type values as defined in ETSI 300 468
 enum {
 MPEGTS_SERVICE_TYPE_DIGITAL_TV   = 0x01,
@@ -78,6 +106,7 @@ typedef struct MpegTSWrite {
 MpegTSSection pat; /* MPEG-2 PAT table */
 MpegTSSection sdt; /* MPEG-2 SDT table context */
 MpegTSService **services;
+MpegTSAtsc atsc;
 int sdt_packet_count;
 int sdt_packet_period;
 int pat_packet_count;
@@ -121,10 +150,6 @@ typedef struct MpegTSWrite {
 #define DEFAULT_PES_HEADER_FREQ  16
 #define DEFAULT_PES_PAYLOAD_SIZE ((DEFAULT_PES_HEADER_FREQ - 1) * 184 + 170)
 
-/* The section length is 12 bits. The first 2 are set to 0, the remaining
- * 10 bits should not exceed 1021. */
-#define SECTION_LENGTH 1020
-
 /* NOTE: 4 bytes must be left at the end for the crc32 */
 static void mpegts_write_section(MpegTSSection *s, uint8_t *buf, int len)
 {
@@ -189,14 +214,24 @@ static inline void put16(uint8_t **q_ptr, int val)
 *q_ptr = q;
 }
 
+static inline void put32(uint8_t **q_ptr, int val

[FFmpeg-devel] [PATCH] libavcodec/vaapi_encode_mpeg2: enable constant QP setting

2019-05-31 Thread Phillip Burr
---
 libavcodec/vaapi_encode_mpeg2.c | 6 ++
 1 file changed, 6 insertions(+)

diff --git a/libavcodec/vaapi_encode_mpeg2.c b/libavcodec/vaapi_encode_mpeg2.c
index fb1ef71fdc..bd754001d5 100644
--- a/libavcodec/vaapi_encode_mpeg2.c
+++ b/libavcodec/vaapi_encode_mpeg2.c
@@ -31,6 +31,7 @@ typedef struct VAAPIEncodeMPEG2Context {
 VAAPIEncodeContext common;
 
 // User options.
+int qp;
 int profile;
 int level;
 
@@ -624,6 +625,9 @@ static av_cold int vaapi_encode_mpeg2_init(AVCodecContext 
*avctx)
 ctx->surface_width  = FFALIGN(avctx->width,  16);
 ctx->surface_height = FFALIGN(avctx->height, 16);
 
+if (priv->qp > 0)
+ctx->explicit_qp = priv->qp;
+
 return ff_vaapi_encode_init(avctx);
 }
 
@@ -643,6 +647,8 @@ static const AVOption vaapi_encode_mpeg2_options[] = {
 VAAPI_ENCODE_COMMON_OPTIONS,
 VAAPI_ENCODE_RC_OPTIONS,
 
+{ "qp", "Constant QP (for P-frames; scaled by qfactor/qoffset for I/B)",
+  OFFSET(qp), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 52, FLAGS },
 { "profile", "Set profile (in profile_and_level_indication)",
   OFFSET(profile), AV_OPT_TYPE_INT,
   { .i64 = FF_PROFILE_UNKNOWN }, FF_PROFILE_UNKNOWN, 7, FLAGS, "profile" },
-- 
2.20.1

___
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".