|
|
@ -20,6 +20,7 @@ |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
|
|
|
|
|
|
|
|
#include "libavutil/mathematics.h" |
|
|
|
#include "libavutil/mathematics.h" |
|
|
|
|
|
|
|
#include "libavutil/opt.h" |
|
|
|
#include "avformat.h" |
|
|
|
#include "avformat.h" |
|
|
|
#include "avio_internal.h" |
|
|
|
#include "avio_internal.h" |
|
|
|
|
|
|
|
|
|
|
@ -27,6 +28,7 @@ typedef struct MuxChain { |
|
|
|
AVFormatContext *mpegts_ctx; |
|
|
|
AVFormatContext *mpegts_ctx; |
|
|
|
AVFormatContext *rtp_ctx; |
|
|
|
AVFormatContext *rtp_ctx; |
|
|
|
AVPacket *pkt; |
|
|
|
AVPacket *pkt; |
|
|
|
|
|
|
|
AVDictionary* mpegts_muxer_options; |
|
|
|
} MuxChain; |
|
|
|
} MuxChain; |
|
|
|
|
|
|
|
|
|
|
|
static int rtp_mpegts_write_close(AVFormatContext *s) |
|
|
|
static int rtp_mpegts_write_close(AVFormatContext *s) |
|
|
@ -56,6 +58,7 @@ static int rtp_mpegts_write_header(AVFormatContext *s) |
|
|
|
ff_const59 AVOutputFormat *rtp_format = av_guess_format("rtp", NULL, NULL); |
|
|
|
ff_const59 AVOutputFormat *rtp_format = av_guess_format("rtp", NULL, NULL); |
|
|
|
int i, ret = AVERROR(ENOMEM); |
|
|
|
int i, ret = AVERROR(ENOMEM); |
|
|
|
AVStream *st; |
|
|
|
AVStream *st; |
|
|
|
|
|
|
|
AVDictionary *mpegts_muxer_options = NULL; |
|
|
|
|
|
|
|
|
|
|
|
if (!mpegts_format || !rtp_format) |
|
|
|
if (!mpegts_format || !rtp_format) |
|
|
|
return AVERROR(ENOSYS); |
|
|
|
return AVERROR(ENOSYS); |
|
|
@ -78,7 +81,10 @@ static int rtp_mpegts_write_header(AVFormatContext *s) |
|
|
|
} |
|
|
|
} |
|
|
|
if ((ret = avio_open_dyn_buf(&mpegts_ctx->pb)) < 0) |
|
|
|
if ((ret = avio_open_dyn_buf(&mpegts_ctx->pb)) < 0) |
|
|
|
goto fail; |
|
|
|
goto fail; |
|
|
|
if ((ret = avformat_write_header(mpegts_ctx, NULL)) < 0) |
|
|
|
|
|
|
|
|
|
|
|
av_dict_copy(&mpegts_muxer_options, chain->mpegts_muxer_options, 0); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if ((ret = avformat_write_header(mpegts_ctx, &mpegts_muxer_options)) < 0) |
|
|
|
goto fail; |
|
|
|
goto fail; |
|
|
|
for (i = 0; i < s->nb_streams; i++) |
|
|
|
for (i = 0; i < s->nb_streams; i++) |
|
|
|
s->streams[i]->time_base = mpegts_ctx->streams[i]->time_base; |
|
|
|
s->streams[i]->time_base = mpegts_ctx->streams[i]->time_base; |
|
|
@ -111,6 +117,7 @@ fail: |
|
|
|
if (mpegts_ctx) { |
|
|
|
if (mpegts_ctx) { |
|
|
|
ffio_free_dyn_buf(&mpegts_ctx->pb); |
|
|
|
ffio_free_dyn_buf(&mpegts_ctx->pb); |
|
|
|
av_dict_free(&mpegts_ctx->metadata); |
|
|
|
av_dict_free(&mpegts_ctx->metadata); |
|
|
|
|
|
|
|
av_dict_free(&mpegts_muxer_options); |
|
|
|
avformat_free_context(mpegts_ctx); |
|
|
|
avformat_free_context(mpegts_ctx); |
|
|
|
} |
|
|
|
} |
|
|
|
avformat_free_context(rtp_ctx); |
|
|
|
avformat_free_context(rtp_ctx); |
|
|
@ -155,6 +162,20 @@ static int rtp_mpegts_write_packet(AVFormatContext *s, AVPacket *pkt) |
|
|
|
return ret; |
|
|
|
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 }, |
|
|
|
|
|
|
|
{ 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 = { |
|
|
|
AVOutputFormat ff_rtp_mpegts_muxer = { |
|
|
|
.name = "rtp_mpegts", |
|
|
|
.name = "rtp_mpegts", |
|
|
|
.long_name = NULL_IF_CONFIG_SMALL("RTP/mpegts output format"), |
|
|
|
.long_name = NULL_IF_CONFIG_SMALL("RTP/mpegts output format"), |
|
|
@ -164,4 +185,5 @@ AVOutputFormat ff_rtp_mpegts_muxer = { |
|
|
|
.write_header = rtp_mpegts_write_header, |
|
|
|
.write_header = rtp_mpegts_write_header, |
|
|
|
.write_packet = rtp_mpegts_write_packet, |
|
|
|
.write_packet = rtp_mpegts_write_packet, |
|
|
|
.write_trailer = rtp_mpegts_write_close, |
|
|
|
.write_trailer = rtp_mpegts_write_close, |
|
|
|
|
|
|
|
.priv_class = &rtp_mpegts_class, |
|
|
|
}; |
|
|
|
}; |
|
|
|