From: Gautam Ramakrishnan <gautamr...@gmail.com> This patch adds support to receive JPEG2000 RTP streams. --- libavformat/Makefile | 1 + libavformat/rtpdec.c | 1 + libavformat/rtpdec_formats.h | 1 + libavformat/rtpdec_jpeg2000.c | 116 ++++++++++++++++++++++++++++++++++ 4 files changed, 119 insertions(+) create mode 100644 libavformat/rtpdec_jpeg2000.c
diff --git a/libavformat/Makefile b/libavformat/Makefile index 62d8cbb54e..4495047e3a 100644 --- a/libavformat/Makefile +++ b/libavformat/Makefile @@ -46,6 +46,7 @@ OBJS-$(CONFIG_RTPDEC) += rdt.o \ rtpdec_hevc.o \ rtpdec_ilbc.o \ rtpdec_jpeg.o \ + rtpdec_jpeg2000.o \ rtpdec_latm.o \ rtpdec_mpa_robust.o \ rtpdec_mpeg12.o \ diff --git a/libavformat/rtpdec.c b/libavformat/rtpdec.c index 3d5b200099..b47dfdfebc 100644 --- a/libavformat/rtpdec.c +++ b/libavformat/rtpdec.c @@ -118,6 +118,7 @@ static const RTPDynamicProtocolHandler *rtp_dynamic_protocol_handler_list[] = { &ff_vorbis_dynamic_handler, &ff_vp8_dynamic_handler, &ff_vp9_dynamic_handler, + &ff_jpeg2000_dynamic_handler, &gsm_dynamic_handler, &l24_dynamic_handler, &opus_dynamic_handler, diff --git a/libavformat/rtpdec_formats.h b/libavformat/rtpdec_formats.h index dad2b8ac1b..78ea4fb384 100644 --- a/libavformat/rtpdec_formats.h +++ b/libavformat/rtpdec_formats.h @@ -89,5 +89,6 @@ extern const RTPDynamicProtocolHandler ff_vc2hq_dynamic_handler; extern const RTPDynamicProtocolHandler ff_vorbis_dynamic_handler; extern const RTPDynamicProtocolHandler ff_vp8_dynamic_handler; extern const RTPDynamicProtocolHandler ff_vp9_dynamic_handler; +extern const RTPDynamicProtocolHandler ff_jpeg2000_dynamic_handler; #endif /* AVFORMAT_RTPDEC_FORMATS_H */ diff --git a/libavformat/rtpdec_jpeg2000.c b/libavformat/rtpdec_jpeg2000.c new file mode 100644 index 0000000000..b5337a9cdb --- /dev/null +++ b/libavformat/rtpdec_jpeg2000.c @@ -0,0 +1,116 @@ +/* + * Code for the RTP depacketization of JPEG2000. + * Copyright (c) 2020 Gautam Ramakrishnan + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/** + * @file + * @brief JPEG2000 / RTP Code + * @author Gautam Ramakrishnan + */ + +#include "rtpdec_formats.h" +#include "avio_internal.h" +#include "internal.h" +#include "libavutil/attributes.h" +#include "libavutil/avstring.h" +#include "libavcodec/get_bits.h" + +#define PAYLOAD_HDR_SIZ 8 + +/** + * RTP/JPEG specific private data. + */ +struct PayloadContext { + AVIOContext *frame; // current frame buffer + uint32_t timestamp; // current frame timestamp +}; + +static void jpeg2000_close_context(PayloadContext *data) +{ + ffio_free_dyn_buf(&data->frame); +} + +static int jpeg2000_parse_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; + int off; + + if (len < 8) { + av_log(ctx, AV_LOG_ERROR, "Too short RTP/JPEG packet.\n"); + return AVERROR_INVALIDDATA; + } + off = (uint64_t)AV_RB64(buf) & 0xFFFFFF; + buf += 8; + len -= 8; + if (!off) { + /* Skip the current frame in case of the end packet + * has been lost somewhere. */ + ffio_free_dyn_buf(&data->frame); + + if ((ret = avio_open_dyn_buf(&data->frame)) < 0) + return ret; + data->timestamp = *timestamp; + } + if (!data->frame) { + av_log(ctx, AV_LOG_ERROR, + "Received packet without a start chunk; dropping frame.\n"); + return AVERROR(EAGAIN); + } + + if (data->timestamp != *timestamp) { + /* Skip the current frame if timestamp is incorrect. + * A start packet has been lost somewhere. */ + ffio_free_dyn_buf(&data->frame); + av_log(ctx, AV_LOG_ERROR, "RTP timestamps don't match.\n"); + return AVERROR_INVALIDDATA; + } + + if (off != avio_tell(data->frame)) { + av_log(ctx, AV_LOG_ERROR, + "Missing packets; dropping frame.\n"); + return AVERROR(EAGAIN); + } + /* Copy data to frame buffer. */ + avio_write(data->frame, buf, len); + + if (flags & RTP_FLAG_MARKER) { + /* Prepare the JPEG2000 packet. */ + if ((ret = ff_rtp_finalize_packet(pkt, &data->frame, st->index)) < 0) { + av_log(ctx, AV_LOG_ERROR, + "Error occurred when getting frame buffer.\n"); + return ret; + } + + return 0; + } + return AVERROR(EAGAIN); +} + +const RTPDynamicProtocolHandler ff_jpeg2000_dynamic_handler = { + .enc_name = "jpeg2000", + .codec_type = AVMEDIA_TYPE_VIDEO, + .codec_id = AV_CODEC_ID_JPEG2000, + .priv_data_size = sizeof(PayloadContext), + .parse_packet = jpeg2000_parse_packet, + .close = jpeg2000_close_context, +}; -- 2.17.1 _______________________________________________ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".