Add support for BDAV/m2ts-mode muxing
Signed-off-by: Fredrik Axelsson <fraxbe@gmail.com> Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
This commit is contained in:
		
							parent
							
								
									b118255e91
								
							
						
					
					
						commit
						09a858da7d
					
				@ -75,6 +75,7 @@ typedef struct MpegTSWrite {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    int pmt_start_pid;
 | 
					    int pmt_start_pid;
 | 
				
			||||||
    int start_pid;
 | 
					    int start_pid;
 | 
				
			||||||
 | 
					    int m2ts_mode;
 | 
				
			||||||
} MpegTSWrite;
 | 
					} MpegTSWrite;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static const AVOption options[] = {
 | 
					static const AVOption options[] = {
 | 
				
			||||||
@ -88,6 +89,9 @@ static const AVOption options[] = {
 | 
				
			|||||||
      offsetof(MpegTSWrite, pmt_start_pid), FF_OPT_TYPE_INT, {.dbl = 0x1000 }, 0x1000, 0x1f00, AV_OPT_FLAG_ENCODING_PARAM},
 | 
					      offsetof(MpegTSWrite, pmt_start_pid), FF_OPT_TYPE_INT, {.dbl = 0x1000 }, 0x1000, 0x1f00, AV_OPT_FLAG_ENCODING_PARAM},
 | 
				
			||||||
    { "mpegts_start_pid", "Set the first pid.",
 | 
					    { "mpegts_start_pid", "Set the first pid.",
 | 
				
			||||||
      offsetof(MpegTSWrite, start_pid), FF_OPT_TYPE_INT, {.dbl = 0x0100 }, 0x0100, 0x0f00, AV_OPT_FLAG_ENCODING_PARAM},
 | 
					      offsetof(MpegTSWrite, start_pid), FF_OPT_TYPE_INT, {.dbl = 0x0100 }, 0x0100, 0x0f00, AV_OPT_FLAG_ENCODING_PARAM},
 | 
				
			||||||
 | 
					    {"mpegts_m2ts_mode", "Enable m2ts mode.",
 | 
				
			||||||
 | 
					        offsetof(MpegTSWrite, m2ts_mode), FF_OPT_TYPE_INT, {.dbl = -1 },
 | 
				
			||||||
 | 
					        -1,1, AV_OPT_FLAG_ENCODING_PARAM},
 | 
				
			||||||
    { NULL },
 | 
					    { NULL },
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -434,9 +438,28 @@ static MpegTSService *mpegts_add_service(MpegTSWrite *ts,
 | 
				
			|||||||
    return service;
 | 
					    return service;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static int64_t get_pcr(const MpegTSWrite *ts, AVIOContext *pb)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    return av_rescale(avio_tell(pb) + 11, 8 * PCR_TIME_BASE, ts->mux_rate) +
 | 
				
			||||||
 | 
					           ts->first_pcr;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void mpegts_prefix_m2ts_header(AVFormatContext *s)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    MpegTSWrite *ts = s->priv_data;
 | 
				
			||||||
 | 
					    if (ts->m2ts_mode) {
 | 
				
			||||||
 | 
					        int64_t pcr = get_pcr(s->priv_data, s->pb);
 | 
				
			||||||
 | 
					        uint32_t tp_extra_header = pcr % 0x3fffffff;
 | 
				
			||||||
 | 
					        tp_extra_header = AV_RB32(&tp_extra_header);
 | 
				
			||||||
 | 
					        avio_write(s->pb, (unsigned char *) &tp_extra_header,
 | 
				
			||||||
 | 
					                sizeof(tp_extra_header));
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void section_write_packet(MpegTSSection *s, const uint8_t *packet)
 | 
					static void section_write_packet(MpegTSSection *s, const uint8_t *packet)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    AVFormatContext *ctx = s->opaque;
 | 
					    AVFormatContext *ctx = s->opaque;
 | 
				
			||||||
 | 
					    mpegts_prefix_m2ts_header(ctx);
 | 
				
			||||||
    avio_write(ctx->pb, packet, TS_PACKET_SIZE);
 | 
					    avio_write(ctx->pb, packet, TS_PACKET_SIZE);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -584,6 +607,14 @@ static int mpegts_write_header(AVFormatContext *s)
 | 
				
			|||||||
           service->pcr_packet_period,
 | 
					           service->pcr_packet_period,
 | 
				
			||||||
           ts->sdt_packet_period, ts->pat_packet_period);
 | 
					           ts->sdt_packet_period, ts->pat_packet_period);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (ts->m2ts_mode == -1) {
 | 
				
			||||||
 | 
					        if (av_match_ext(s->filename, "m2ts")) {
 | 
				
			||||||
 | 
					            ts->m2ts_mode = 1;
 | 
				
			||||||
 | 
					        } else {
 | 
				
			||||||
 | 
					            ts->m2ts_mode = 0;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    avio_flush(s->pb);
 | 
					    avio_flush(s->pb);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    return 0;
 | 
					    return 0;
 | 
				
			||||||
@ -616,12 +647,6 @@ static void retransmit_si_info(AVFormatContext *s)
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int64_t get_pcr(const MpegTSWrite *ts, AVIOContext *pb)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    return av_rescale(avio_tell(pb) + 11, 8 * PCR_TIME_BASE, ts->mux_rate) +
 | 
					 | 
				
			||||||
           ts->first_pcr;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static int write_pcr_bits(uint8_t *buf, int64_t pcr)
 | 
					static int write_pcr_bits(uint8_t *buf, int64_t pcr)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    int64_t pcr_low = pcr % 300, pcr_high = pcr / 300;
 | 
					    int64_t pcr_low = pcr % 300, pcr_high = pcr / 300;
 | 
				
			||||||
@ -648,6 +673,7 @@ static void mpegts_insert_null_packet(AVFormatContext *s)
 | 
				
			|||||||
    *q++ = 0xff;
 | 
					    *q++ = 0xff;
 | 
				
			||||||
    *q++ = 0x10;
 | 
					    *q++ = 0x10;
 | 
				
			||||||
    memset(q, 0x0FF, TS_PACKET_SIZE - (q - buf));
 | 
					    memset(q, 0x0FF, TS_PACKET_SIZE - (q - buf));
 | 
				
			||||||
 | 
					    mpegts_prefix_m2ts_header(s);
 | 
				
			||||||
    avio_write(s->pb, buf, TS_PACKET_SIZE);
 | 
					    avio_write(s->pb, buf, TS_PACKET_SIZE);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -673,6 +699,7 @@ static void mpegts_insert_pcr_only(AVFormatContext *s, AVStream *st)
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    /* stuffing bytes */
 | 
					    /* stuffing bytes */
 | 
				
			||||||
    memset(q, 0xFF, TS_PACKET_SIZE - (q - buf));
 | 
					    memset(q, 0xFF, TS_PACKET_SIZE - (q - buf));
 | 
				
			||||||
 | 
					    mpegts_prefix_m2ts_header(s);
 | 
				
			||||||
    avio_write(s->pb, buf, TS_PACKET_SIZE);
 | 
					    avio_write(s->pb, buf, TS_PACKET_SIZE);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -909,6 +936,7 @@ static void mpegts_write_pes(AVFormatContext *s, AVStream *st,
 | 
				
			|||||||
        memcpy(buf + TS_PACKET_SIZE - len, payload, len);
 | 
					        memcpy(buf + TS_PACKET_SIZE - len, payload, len);
 | 
				
			||||||
        payload += len;
 | 
					        payload += len;
 | 
				
			||||||
        payload_size -= len;
 | 
					        payload_size -= len;
 | 
				
			||||||
 | 
					        mpegts_prefix_m2ts_header(s);
 | 
				
			||||||
        avio_write(s->pb, buf, TS_PACKET_SIZE);
 | 
					        avio_write(s->pb, buf, TS_PACKET_SIZE);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    avio_flush(s->pb);
 | 
					    avio_flush(s->pb);
 | 
				
			||||||
@ -1054,7 +1082,7 @@ AVOutputFormat ff_mpegts_muxer = {
 | 
				
			|||||||
    .name              = "mpegts",
 | 
					    .name              = "mpegts",
 | 
				
			||||||
    .long_name         = NULL_IF_CONFIG_SMALL("MPEG-2 transport stream format"),
 | 
					    .long_name         = NULL_IF_CONFIG_SMALL("MPEG-2 transport stream format"),
 | 
				
			||||||
    .mime_type         = "video/x-mpegts",
 | 
					    .mime_type         = "video/x-mpegts",
 | 
				
			||||||
    .extensions        = "ts,m2t",
 | 
					    .extensions        = "ts,m2t,m2ts",
 | 
				
			||||||
    .priv_data_size    = sizeof(MpegTSWrite),
 | 
					    .priv_data_size    = sizeof(MpegTSWrite),
 | 
				
			||||||
    .audio_codec       = CODEC_ID_MP2,
 | 
					    .audio_codec       = CODEC_ID_MP2,
 | 
				
			||||||
    .video_codec       = CODEC_ID_MPEG2VIDEO,
 | 
					    .video_codec       = CODEC_ID_MPEG2VIDEO,
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user