]> git.sesse.net Git - ffmpeg/blobdiff - libavformat/mpegtsenc.c
lavf/movenc: fix invalid free with timecode meta and tmcd data copy.
[ffmpeg] / libavformat / mpegtsenc.c
index 9e95718a61fe46ae9fa3c5de56a8f5f30eeb21aa..2ed6f031a9e789762dc9e3c1f75c44cce4758001 100644 (file)
@@ -83,6 +83,7 @@ typedef struct MpegTSWrite {
 #define MPEGTS_FLAG_REEMIT_PAT_PMT  0x01
 #define MPEGTS_FLAG_AAC_LATM        0x02
     int flags;
+    int copyts;
 } MpegTSWrite;
 
 /* a PES packet header is generated every DEFAULT_PES_HEADER_FREQ packets */
@@ -117,6 +118,8 @@ static const AVOption options[] = {
     // backward compatibility
     { "resend_headers", "Reemit PAT/PMT before writing the next packet",
       offsetof(MpegTSWrite, reemit_pat_pmt), AV_OPT_TYPE_INT, {0}, 0, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM},
+    { "mpegts_copyts", "dont offset dts/pts",
+      offsetof(MpegTSWrite, copyts), AV_OPT_TYPE_INT, {.dbl=-1}, -1, 1, AV_OPT_FLAG_ENCODING_PARAM},
     { NULL },
 };
 
@@ -636,7 +639,8 @@ static int mpegts_write_header(AVFormatContext *s)
         ts->pat_packet_period      = (ts->mux_rate * PAT_RETRANS_TIME) /
             (TS_PACKET_SIZE * 8 * 1000);
 
-        ts->first_pcr = av_rescale(s->max_delay, PCR_TIME_BASE, AV_TIME_BASE);
+        if(ts->copyts < 1)
+            ts->first_pcr = av_rescale(s->max_delay, PCR_TIME_BASE, AV_TIME_BASE);
     } else {
         /* Arbitrary values, PAT/PMT will also be written on video key frames */
         ts->sdt_packet_period = 200;
@@ -655,6 +659,8 @@ static int mpegts_write_header(AVFormatContext *s)
             service->pcr_packet_period =
                 pcr_st->codec->time_base.den/(10*pcr_st->codec->time_base.num);
         }
+        if(!service->pcr_packet_period)
+            service->pcr_packet_period = 1;
     }
 
     // output a PCR as soon as possible
@@ -794,7 +800,7 @@ static void write_pts(uint8_t *q, int fourbits, int64_t pts)
 static void set_af_flag(uint8_t *pkt, int flag)
 {
     // expect at least one flag to set
-    assert(flag);
+    av_assert0(flag);
 
     if ((pkt[3] & 0x20) == 0) {
         // no AF yet, set adaptation field flag
@@ -810,7 +816,7 @@ static void set_af_flag(uint8_t *pkt, int flag)
 static void extend_af(uint8_t *pkt, int size)
 {
     // expect already existing adaptation field
-    assert(pkt[3] & 0x20);
+    av_assert0(pkt[3] & 0x20);
     pkt[4] += size;
 }
 
@@ -915,6 +921,10 @@ static void mpegts_write_pes(AVFormatContext *s, AVStream *st,
                         st->codec->codec_id == CODEC_ID_MP3 ||
                         st->codec->codec_id == CODEC_ID_AAC)) {
                 *q++ = 0xc0;
+            } else if (st->codec->codec_type == AVMEDIA_TYPE_AUDIO &&
+                        st->codec->codec_id == CODEC_ID_AC3 &&
+                        ts->m2ts_mode) {
+                *q++ = 0xfd;
             } else {
                 *q++ = 0xbd;
                 if (st->codec->codec_type == AVMEDIA_TYPE_SUBTITLE) {
@@ -944,6 +954,17 @@ static void mpegts_write_pes(AVFormatContext *s, AVStream *st,
                 */
                 header_len += 3;
             }
+            /* for Blu-ray AC3 Audio the PES Extension flag should be as follow
+             * otherwise it will not play sound on blu-ray
+             */
+            if (ts->m2ts_mode &&
+                st->codec->codec_type == AVMEDIA_TYPE_AUDIO &&
+                st->codec->codec_id == CODEC_ID_AC3) {
+                        /* set PES_extension_flag */
+                        pes_extension = 1;
+                        flags |= 0x01;
+                        header_len += 3;
+            }
             len = payload_size + header_len + 3;
             if (private_code != 0)
                 len++;
@@ -976,6 +997,17 @@ static void mpegts_write_pes(AVFormatContext *s, AVStream *st,
                 */
                 *q++ = 0x00 | 0x60;
             }
+            /* For Blu-ray AC3 Audio Setting extended flags */
+          if (ts->m2ts_mode &&
+              pes_extension &&
+              st->codec->codec_id == CODEC_ID_AC3) {
+                      flags = 0x01; /* set PES_extension_flag_2 */
+                      *q++ = flags;
+                      *q++ = 0x80 | 0x01; /* marker bit + extension length */
+                      *q++ = 0x00 | 0x71; /* for AC3 Audio (specifically on blue-rays) */
+              }
+
+
             if (private_code != 0)
                 *q++ = private_code;
             is_start = 0;
@@ -1027,7 +1059,7 @@ static int mpegts_write_packet_internal(AVFormatContext *s, AVPacket *pkt)
     MpegTSWrite *ts = s->priv_data;
     MpegTSWriteStream *ts_st = st->priv_data;
     const int64_t delay = av_rescale(s->max_delay, 90000, AV_TIME_BASE)*2;
-    int64_t dts = AV_NOPTS_VALUE, pts = AV_NOPTS_VALUE;
+    int64_t dts = pkt->dts, pts = pkt->pts;
 
     if (ts->reemit_pat_pmt) {
         av_log(s, AV_LOG_WARNING, "resend_headers option is deprecated, use -mpegts_flags resend_headers\n");
@@ -1041,10 +1073,12 @@ static int mpegts_write_packet_internal(AVFormatContext *s, AVPacket *pkt)
         ts->flags &= ~MPEGTS_FLAG_REEMIT_PAT_PMT;
     }
 
-    if (pkt->pts != AV_NOPTS_VALUE)
-        pts = pkt->pts + delay;
-    if (pkt->dts != AV_NOPTS_VALUE)
-        dts = pkt->dts + delay;
+    if(ts->copyts < 1){
+        if (pts != AV_NOPTS_VALUE)
+            pts += delay;
+        if (dts != AV_NOPTS_VALUE)
+            dts += delay;
+    }
 
     if (ts_st->first_pts_check && pts == AV_NOPTS_VALUE) {
         av_log(s, AV_LOG_ERROR, "first pts value must set\n");
@@ -1217,7 +1251,7 @@ static int mpegts_write_end(AVFormatContext *s)
 
 AVOutputFormat ff_mpegts_muxer = {
     .name              = "mpegts",
-    .long_name         = NULL_IF_CONFIG_SMALL("MPEG-2 transport stream format"),
+    .long_name         = NULL_IF_CONFIG_SMALL("MPEG-TS (MPEG-2 Transport Stream)"),
     .mime_type         = "video/x-mpegts",
     .extensions        = "ts,m2t,m2ts,mts",
     .priv_data_size    = sizeof(MpegTSWrite),