From patchwork Wed Jul 22 19:25:52 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Gautam Ramakrishnan X-Patchwork-Id: 21231 Return-Path: X-Original-To: patchwork@ffaux-bg.ffmpeg.org Delivered-To: patchwork@ffaux-bg.ffmpeg.org Received: from ffbox0-bg.mplayerhq.hu (ffbox0-bg.ffmpeg.org [79.124.17.100]) by ffaux.localdomain (Postfix) with ESMTP id 1B70E44ADB0 for ; Wed, 22 Jul 2020 22:26:11 +0300 (EEST) Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id E7EAD68B7A5; Wed, 22 Jul 2020 22:26:10 +0300 (EEST) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from mail-pl1-f195.google.com (mail-pl1-f195.google.com [209.85.214.195]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id B6DDE68B683 for ; Wed, 22 Jul 2020 22:26:03 +0300 (EEST) Received: by mail-pl1-f195.google.com with SMTP id m16so1479565pls.5 for ; Wed, 22 Jul 2020 12:26:03 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id; bh=FT1YYcpQ95bcwpcAapm8sYd1N3vXJHvSW1FyFv1x7f0=; b=C9IVdB1bNJrxtmUhpcmygZGp1Zdg4ellaT1vqvTSPiqJukno3HjcwvI8L6YWNKajsu GhFBv/laE1qKN6SImZqkzG5CIcXtd9gbq3aXcrqrExXMRi8s0Ae7dPcuV32ANo73R6i9 fXujuCI3nntJsBizvq8HqdLIcq+THkP2Mf7Bke04C2K9/hES6Ziyd4x54TtZ7tkpu2if 4zcy+Y6paIJSfBavgcA6W/ntIAblL3Ep2NWkyoDdAiB53iBzpgx12F0tLK1TzIcnQA8b 2aAxURPmWadGNHmUW2pLHgRFAfJrSMlQSYoQz+Vi7p4sNTvwUdk1EYywKlB0/H5OK9Wk C51g== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id; bh=FT1YYcpQ95bcwpcAapm8sYd1N3vXJHvSW1FyFv1x7f0=; b=OmemLSzLUXb2bEte8kGt1Kcz7CHqeRJ/6iznTbasf6pQh0PpSbcpft/2+nd+fi0Kwf Voh3TNZQtKzLMYOA3CSekHoUj5UdsE+oWItnEMp1bwR8B1dGbK2cNZirLoZCPRmhgP3G LD5XP9Cy6MVX8ZDqyYnfwhtWfMTeT+PeqA+l0+oDmuGuf2h42NazuJumupUw5kkSjW0r KFbgnNbP/ZaZBweXemgq8VDWnSZpg54plsb/XipOhj4nqNmSbMApGokZmUGF4uBp4JLE K8Nvqv5ErSkinlGCPnpbyYXT+ceEDsMKYgnpBAx0amLlg+K8y36gLgw8+RVAXFB56fG5 0Z4w== X-Gm-Message-State: AOAM531icgwAjBrIsYPgYDDqbv5QPAHwHdoc4oMCpRvzLWx42A4myV+5 PaGcpuc9MAV8LNCdbKHisKN95nQN6Zk= X-Google-Smtp-Source: ABdhPJzEcg0+yyZThvJw0uvblndyh7Ab7gjOMAby0ywi5NLQwgcl8jZJz7QykUjrq+4zmEXueMvt9Q== X-Received: by 2002:a17:902:7484:: with SMTP id h4mr779099pll.243.1595445961421; Wed, 22 Jul 2020 12:26:01 -0700 (PDT) Received: from localhost.localdomain ([122.167.212.213]) by smtp.gmail.com with ESMTPSA id l134sm405963pga.50.2020.07.22.12.25.58 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 22 Jul 2020 12:26:00 -0700 (PDT) From: gautamramk@gmail.com To: ffmpeg-devel@ffmpeg.org Date: Thu, 23 Jul 2020 00:55:52 +0530 Message-Id: <20200722192553.9688-1-gautamramk@gmail.com> X-Mailer: git-send-email 2.17.1 Subject: [FFmpeg-devel] [RFC Patch 1/2] libavformat/rtpdec_jpeg2000: RTP Demuxing for JPEG2000 X-BeenThere: ffmpeg-devel@ffmpeg.org X-Mailman-Version: 2.1.20 Precedence: list List-Id: FFmpeg development discussions and patches List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Reply-To: FFmpeg development discussions and patches Cc: Gautam Ramakrishnan MIME-Version: 1.0 Errors-To: ffmpeg-devel-bounces@ffmpeg.org Sender: "ffmpeg-devel" From: Gautam Ramakrishnan 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, +};