@ -21,6 +21,7 @@
# include "libavutil/bswap.h"
# include "libavutil/crc.h"
# include "libavutil/opt.h"
# include "libavcodec/mpegvideo.h"
# include "avformat.h"
# include "internal.h"
@ -64,8 +65,36 @@ typedef struct MpegTSWrite {
int tsid ;
int64_t first_pcr ;
int mux_rate ; ///< set to 1 when VBR
int transport_stream_id ;
int original_network_id ;
int service_id ;
int pmt_start_pid ;
int start_pid ;
} MpegTSWrite ;
static const AVOption options [ ] = {
{ " mpegts_transport_stream_id " , " Set transport_stream_id field. " ,
offsetof ( MpegTSWrite , transport_stream_id ) , FF_OPT_TYPE_INT , 0x0001 , 0x0001 , 0xffff , AV_OPT_FLAG_ENCODING_PARAM } ,
{ " mpegts_original_network_id " , " Set original_network_id field. " ,
offsetof ( MpegTSWrite , original_network_id ) , FF_OPT_TYPE_INT , 0x0001 , 0x0001 , 0xffff , AV_OPT_FLAG_ENCODING_PARAM } ,
{ " mpegts_service_id " , " Set service_id field. " ,
offsetof ( MpegTSWrite , service_id ) , FF_OPT_TYPE_INT , 0x0001 , 0x0001 , 0xffff , AV_OPT_FLAG_ENCODING_PARAM } ,
{ " mpegts_pmt_start_pid " , " Set the first pid of the PMT. " ,
offsetof ( MpegTSWrite , pmt_start_pid ) , FF_OPT_TYPE_INT , 0x1000 , 0x1000 , 0x1f00 , AV_OPT_FLAG_ENCODING_PARAM } ,
{ " mpegts_start_pid " , " Set the first pid. " ,
offsetof ( MpegTSWrite , start_pid ) , FF_OPT_TYPE_INT , 0x0100 , 0x0100 , 0x0f00 , AV_OPT_FLAG_ENCODING_PARAM } ,
{ NULL } ,
} ;
static const AVClass mpegts_muxer_class = {
" MPEGTS muxer " ,
av_default_item_name ,
options ,
LIBAVUTIL_VERSION_INT ,
} ;
/* NOTE: 4 bytes must be left at the end for the crc32 */
static void mpegts_write_section ( MpegTSSection * s , uint8_t * buf , int len )
{
@ -152,16 +181,9 @@ static int mpegts_write_section1(MpegTSSection *s, int tid, int id,
/*********************************************/
/* mpegts writer */
# define DEFAULT_PMT_START_PID 0x1000
# define DEFAULT_START_PID 0x0100
# define DEFAULT_PROVIDER_NAME "FFmpeg"
# define DEFAULT_SERVICE_NAME "Service01"
/* default network id, transport stream and service identifiers */
# define DEFAULT_ONID 0x0001
# define DEFAULT_TSID 0x0001
# define DEFAULT_SID 0x0001
/* a PES packet header is generated every DEFAULT_PES_HEADER_FREQ packets */
# define DEFAULT_PES_HEADER_FREQ 16
# define DEFAULT_PES_PAYLOAD_SIZE ((DEFAULT_PES_HEADER_FREQ - 1) * 184 + 170)
@ -374,7 +396,7 @@ static MpegTSService *mpegts_add_service(MpegTSWrite *ts,
service = av_mallocz ( sizeof ( MpegTSService ) ) ;
if ( ! service )
return NULL ;
service - > pmt . pid = DEFAULT_PMT_START_PID + ts - > nb_services - 1 ;
service - > pmt . pid = ts - > pmt_start_pid + ts - > nb_services ;
service - > sid = sid ;
service - > provider_name = av_strdup ( provider_name ) ;
service - > name = av_strdup ( name ) ;
@ -401,8 +423,8 @@ static int mpegts_write_header(AVFormatContext *s)
const char * provider_name ;
int * pids ;
ts - > tsid = DEFAULT_TSID ;
ts - > onid = DEFAULT_ONID ;
ts - > tsid = ts - > transport_stream_id ;
ts - > onid = ts - > original_network_id ;
/* allocate a single DVB service */
title = av_metadata_get ( s - > metadata , " service_name " , NULL , 0 ) ;
if ( ! title )
@ -410,7 +432,7 @@ static int mpegts_write_header(AVFormatContext *s)
service_name = title ? title - > value : DEFAULT_SERVICE_NAME ;
provider = av_metadata_get ( s - > metadata , " service_provider " , NULL , 0 ) ;
provider_name = provider ? provider - > value : DEFAULT_PROVIDER_NAME ;
service = mpegts_add_service ( ts , DEFAULT_SID , provider_name , service_name ) ;
service = mpegts_add_service ( ts , ts - > service_id , provider_name , service_name ) ;
service - > pmt . write_packet = section_write_packet ;
service - > pmt . opaque = s ;
service - > pmt . cc = 15 ;
@ -440,7 +462,7 @@ static int mpegts_write_header(AVFormatContext *s)
/* MPEG pid values < 16 are reserved. Applications which set st->id in
* this range are assigned a calculated pid . */
if ( st - > id < 16 ) {
ts_st - > pid = DEFAULT_START_PID + i ;
ts_st - > pid = ts - > start_pid + i ;
} else if ( st - > id < 0x1FFF ) {
ts_st - > pid = st - > id ;
} else {
@ -964,4 +986,5 @@ AVOutputFormat ff_mpegts_muxer = {
mpegts_write_header ,
mpegts_write_packet ,
mpegts_write_end ,
. priv_class = & mpegts_muxer_class ,
} ;