*/
#include "libavutil/mathematics.h"
+#include "libavutil/opt.h"
#include "avformat.h"
#include "avio_internal.h"
-struct MuxChain {
+typedef struct MuxChain {
+ const AVClass *class;
AVFormatContext *mpegts_ctx;
AVFormatContext *rtp_ctx;
AVPacket *pkt;
-};
+ AVDictionary* mpegts_muxer_options;
+ AVDictionary* rtp_muxer_options;
+} MuxChain;
static int rtp_mpegts_write_close(AVFormatContext *s)
{
- struct MuxChain *chain = s->priv_data;
+ MuxChain *chain = s->priv_data;
if (chain->mpegts_ctx) {
av_write_trailer(chain->mpegts_ctx);
static int rtp_mpegts_write_header(AVFormatContext *s)
{
- struct MuxChain *chain = s->priv_data;
+ MuxChain *chain = s->priv_data;
AVFormatContext *mpegts_ctx = NULL, *rtp_ctx = NULL;
- ff_const59 AVOutputFormat *mpegts_format = av_guess_format("mpegts", NULL, NULL);
- ff_const59 AVOutputFormat *rtp_format = av_guess_format("rtp", NULL, NULL);
+ const AVOutputFormat *mpegts_format = av_guess_format("mpegts", NULL, NULL);
+ const AVOutputFormat *rtp_format = av_guess_format("rtp", NULL, NULL);
int i, ret = AVERROR(ENOMEM);
AVStream *st;
+ AVDictionary *mpegts_muxer_options = NULL;
+ AVDictionary *rtp_muxer_options = NULL;
if (!mpegts_format || !rtp_format)
return AVERROR(ENOSYS);
goto fail;
st->time_base = s->streams[i]->time_base;
st->sample_aspect_ratio = s->streams[i]->sample_aspect_ratio;
+ st->id = s->streams[i]->id;
avcodec_parameters_copy(st->codecpar, s->streams[i]->codecpar);
}
if ((ret = avio_open_dyn_buf(&mpegts_ctx->pb)) < 0)
goto fail;
- if ((ret = avformat_write_header(mpegts_ctx, NULL)) < 0)
+
+ av_dict_copy(&mpegts_muxer_options, chain->mpegts_muxer_options, 0);
+
+ ret = avformat_write_header(mpegts_ctx, &mpegts_muxer_options);
+ av_dict_free(&mpegts_muxer_options);
+ if (ret < 0)
goto fail;
+
for (i = 0; i < s->nb_streams; i++)
s->streams[i]->time_base = mpegts_ctx->streams[i]->time_base;
st->time_base.den = 90000;
st->codecpar->codec_id = AV_CODEC_ID_MPEG2TS;
rtp_ctx->pb = s->pb;
- if ((ret = avformat_write_header(rtp_ctx, NULL)) < 0)
+ av_dict_copy(&rtp_muxer_options, chain->rtp_muxer_options, 0);
+ ret = avformat_write_header(rtp_ctx, &rtp_muxer_options);
+ av_dict_free(&rtp_muxer_options);
+ if (ret < 0)
goto fail;
+
chain->rtp_ctx = rtp_ctx;
return 0;
static int rtp_mpegts_write_packet(AVFormatContext *s, AVPacket *pkt)
{
- struct MuxChain *chain = s->priv_data;
+ MuxChain *chain = s->priv_data;
int ret = 0, size;
uint8_t *buf;
AVPacket *local_pkt = chain->pkt;
return ret;
}
+#define OFFSET(x) offsetof(MuxChain, x)
+#define E AV_OPT_FLAG_ENCODING_PARAM
+static const AVOption options[] = {
+ { "mpegts_muxer_options", "set list of options for the MPEG-TS muxer", OFFSET(mpegts_muxer_options), AV_OPT_TYPE_DICT, {.str = NULL}, 0, 0, E },
+ { "rtp_muxer_options", "set list of options for the RTP muxer", OFFSET(rtp_muxer_options), AV_OPT_TYPE_DICT, {.str = NULL}, 0, 0, E },
+ { NULL },
+};
+
+static const AVClass rtp_mpegts_class = {
+ .class_name = "rtp_mpegts muxer",
+ .item_name = av_default_item_name,
+ .option = options,
+ .version = LIBAVUTIL_VERSION_INT,
+};
+
AVOutputFormat ff_rtp_mpegts_muxer = {
.name = "rtp_mpegts",
.long_name = NULL_IF_CONFIG_SMALL("RTP/mpegts output format"),
- .priv_data_size = sizeof(struct MuxChain),
+ .priv_data_size = sizeof(MuxChain),
.audio_codec = AV_CODEC_ID_AAC,
.video_codec = AV_CODEC_ID_MPEG4,
.write_header = rtp_mpegts_write_header,
.write_packet = rtp_mpegts_write_packet,
.write_trailer = rtp_mpegts_write_close,
+ .priv_class = &rtp_mpegts_class,
};