Message ID | 20201222003600.27621-2-ffmpeg@tmm1.net |
---|---|
State | Superseded |
Headers | show |
Series | [FFmpeg-devel,1/3] avformat/rtsp: add support for satip:// | expand |
Context | Check | Description |
---|---|---|
andriy/x86_make | success | Make finished |
andriy/x86_make_fate | success | Make fate finished |
andriy/PPC64_make | success | Make finished |
andriy/PPC64_make_fate | success | Make fate finished |
On Mon, Dec 21, 2020 at 4:36 PM Aman Karmani <ffmpeg@tmm1.net> wrote: > From: Aman Karmani <aman@tmm1.net> > > Passthrough handler which can be used to receive MP2T stream > over RTP, and repackage it into a AV_CODEC_ID_MPEG2TS data stream. > > Signed-off-by: Aman Karmani <aman@tmm1.net> > --- > libavformat/rtpdec_formats.h | 1 + > libavformat/rtpdec_mpegts.c | 55 ++++++++++++++++++++++++++++++++++++ > 2 files changed, 56 insertions(+) > > diff --git a/libavformat/rtpdec_formats.h b/libavformat/rtpdec_formats.h > index dad2b8ac1b..ce349292df 100644 > --- a/libavformat/rtpdec_formats.h > +++ b/libavformat/rtpdec_formats.h > @@ -74,6 +74,7 @@ extern const RTPDynamicProtocolHandler > ff_mpeg_audio_robust_dynamic_handler; > extern const RTPDynamicProtocolHandler ff_mpeg_video_dynamic_handler; > extern const RTPDynamicProtocolHandler ff_mpeg4_generic_dynamic_handler; > extern const RTPDynamicProtocolHandler ff_mpegts_dynamic_handler; > +extern const RTPDynamicProtocolHandler ff_mpegtsraw_dynamic_handler; > extern const RTPDynamicProtocolHandler ff_ms_rtp_asf_pfa_handler; > extern const RTPDynamicProtocolHandler ff_ms_rtp_asf_pfv_handler; > extern const RTPDynamicProtocolHandler ff_qcelp_dynamic_handler; > diff --git a/libavformat/rtpdec_mpegts.c b/libavformat/rtpdec_mpegts.c > index 405271f744..6d5a547030 100644 > --- a/libavformat/rtpdec_mpegts.c > +++ b/libavformat/rtpdec_mpegts.c > @@ -20,6 +20,7 @@ > */ > > #include "libavutil/attributes.h" > +#include "libavformat/internal.h" > #include "mpegts.h" > #include "rtpdec_formats.h" > > @@ -28,6 +29,7 @@ struct PayloadContext { > int read_buf_index; > int read_buf_size; > uint8_t buf[RTP_MAX_PACKET_LENGTH]; > + AVStream *raw; > }; > > static void mpegts_close_context(PayloadContext *data) > @@ -89,6 +91,50 @@ static int mpegts_handle_packet(AVFormatContext *ctx, > PayloadContext *data, > return 0; > } > > +static av_cold int mpegtsraw_init(AVFormatContext *ctx, int st_index, > + PayloadContext *data) > +{ > + AVStream *st; > + st = avformat_new_stream(ctx, NULL); > + if (!st) > + return AVERROR(ENOMEM); > + st->codecpar->codec_type = AVMEDIA_TYPE_DATA; > + st->codecpar->codec_id = AV_CODEC_ID_MPEG2TS; > + data->raw = st; > + return 0; > +} > + > +static int mpegtsraw_handle_packet(AVFormatContext *ctx, PayloadContext > *data, > + AVStream *st, AVPacket *pkt, uint32_t > *timestamp, > + const uint8_t *buf, int len, uint16_t > seq, > + int flags) > +{ > + int ret; > + > + // We don't want to use the RTP timestamps at all. If the mpegts > demuxer > + // doesn't set any pts/dts, the generic rtpdec code shouldn't try to > + // fill it in either, since the mpegts and RTP timestamps are in > totally > + // different ranges. > + *timestamp = RTP_NOTS_VALUE; > + > + if (!buf || len < 188) { > + return AVERROR_INVALIDDATA; > + } > + > + if ((ret = av_new_packet(pkt, len)) < 0) > + return ret; > + memcpy(pkt->data, buf, len); > + pkt->stream_index = data->raw->index; > I realized this is a lot of unnecessary boilerplate just to copy data into a packet. The same thing can be achieved directly in rtsp.c, by creating the DATA stream there. I've updated my local patchset accordingly and dropped this patch. > + return 0; > +} > + > +static void mpegtsraw_close_context(PayloadContext *data) > +{ > + if (!data) > + return; > + data->raw = NULL; > +} > + > const RTPDynamicProtocolHandler ff_mpegts_dynamic_handler = { > .codec_type = AVMEDIA_TYPE_DATA, > .priv_data_size = sizeof(PayloadContext), > @@ -97,3 +143,12 @@ const RTPDynamicProtocolHandler > ff_mpegts_dynamic_handler = { > .close = mpegts_close_context, > .static_payload_id = 33, > }; > + > +const RTPDynamicProtocolHandler ff_mpegtsraw_dynamic_handler = { > + .codec_type = AVMEDIA_TYPE_DATA, > + .priv_data_size = sizeof(PayloadContext), > + .parse_packet = mpegtsraw_handle_packet, > + .init = mpegtsraw_init, > + .close = mpegtsraw_close_context, > + .static_payload_id = 33, > +}; > -- > 2.29.2 > >
diff --git a/libavformat/rtpdec_formats.h b/libavformat/rtpdec_formats.h index dad2b8ac1b..ce349292df 100644 --- a/libavformat/rtpdec_formats.h +++ b/libavformat/rtpdec_formats.h @@ -74,6 +74,7 @@ extern const RTPDynamicProtocolHandler ff_mpeg_audio_robust_dynamic_handler; extern const RTPDynamicProtocolHandler ff_mpeg_video_dynamic_handler; extern const RTPDynamicProtocolHandler ff_mpeg4_generic_dynamic_handler; extern const RTPDynamicProtocolHandler ff_mpegts_dynamic_handler; +extern const RTPDynamicProtocolHandler ff_mpegtsraw_dynamic_handler; extern const RTPDynamicProtocolHandler ff_ms_rtp_asf_pfa_handler; extern const RTPDynamicProtocolHandler ff_ms_rtp_asf_pfv_handler; extern const RTPDynamicProtocolHandler ff_qcelp_dynamic_handler; diff --git a/libavformat/rtpdec_mpegts.c b/libavformat/rtpdec_mpegts.c index 405271f744..6d5a547030 100644 --- a/libavformat/rtpdec_mpegts.c +++ b/libavformat/rtpdec_mpegts.c @@ -20,6 +20,7 @@ */ #include "libavutil/attributes.h" +#include "libavformat/internal.h" #include "mpegts.h" #include "rtpdec_formats.h" @@ -28,6 +29,7 @@ struct PayloadContext { int read_buf_index; int read_buf_size; uint8_t buf[RTP_MAX_PACKET_LENGTH]; + AVStream *raw; }; static void mpegts_close_context(PayloadContext *data) @@ -89,6 +91,50 @@ static int mpegts_handle_packet(AVFormatContext *ctx, PayloadContext *data, return 0; } +static av_cold int mpegtsraw_init(AVFormatContext *ctx, int st_index, + PayloadContext *data) +{ + AVStream *st; + st = avformat_new_stream(ctx, NULL); + if (!st) + return AVERROR(ENOMEM); + st->codecpar->codec_type = AVMEDIA_TYPE_DATA; + st->codecpar->codec_id = AV_CODEC_ID_MPEG2TS; + data->raw = st; + return 0; +} + +static int mpegtsraw_handle_packet(AVFormatContext *ctx, PayloadContext *data, + AVStream *st, AVPacket *pkt, uint32_t *timestamp, + const uint8_t *buf, int len, uint16_t seq, + int flags) +{ + int ret; + + // We don't want to use the RTP timestamps at all. If the mpegts demuxer + // doesn't set any pts/dts, the generic rtpdec code shouldn't try to + // fill it in either, since the mpegts and RTP timestamps are in totally + // different ranges. + *timestamp = RTP_NOTS_VALUE; + + if (!buf || len < 188) { + return AVERROR_INVALIDDATA; + } + + if ((ret = av_new_packet(pkt, len)) < 0) + return ret; + memcpy(pkt->data, buf, len); + pkt->stream_index = data->raw->index; + return 0; +} + +static void mpegtsraw_close_context(PayloadContext *data) +{ + if (!data) + return; + data->raw = NULL; +} + const RTPDynamicProtocolHandler ff_mpegts_dynamic_handler = { .codec_type = AVMEDIA_TYPE_DATA, .priv_data_size = sizeof(PayloadContext), @@ -97,3 +143,12 @@ const RTPDynamicProtocolHandler ff_mpegts_dynamic_handler = { .close = mpegts_close_context, .static_payload_id = 33, }; + +const RTPDynamicProtocolHandler ff_mpegtsraw_dynamic_handler = { + .codec_type = AVMEDIA_TYPE_DATA, + .priv_data_size = sizeof(PayloadContext), + .parse_packet = mpegtsraw_handle_packet, + .init = mpegtsraw_init, + .close = mpegtsraw_close_context, + .static_payload_id = 33, +};