From patchwork Tue Jul 21 16:38:49 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Gautam Ramakrishnan X-Patchwork-Id: 21215 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 7F29344B5ED for ; Tue, 21 Jul 2020 20:09:43 +0300 (EEST) Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id 62B8C68B5CC; Tue, 21 Jul 2020 20:09:43 +0300 (EEST) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from mail-pg1-f193.google.com (mail-pg1-f193.google.com [209.85.215.193]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id 67EC468B4AC for ; Tue, 21 Jul 2020 20:09:36 +0300 (EEST) Received: by mail-pg1-f193.google.com with SMTP id k27so12239535pgm.2 for ; Tue, 21 Jul 2020 10:09:36 -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=OgUg85SCGqxo2yphaSYMd0o+3ijH5dvIFQCoCr2pP/qCeIu1F88Ct0KKWbe6Y2fVmv +qTzCm0Oi/laITKUq0uU45+twIJAb9sT4fVzAlVqQNWsM6loTa91GdV+Dx7GxvGfnSAB KGvLVTUAGBhxkcAO0zOqDvT0XOlhcOYMIVPbnU5pn2W8GzFkexm5oPAdKL/ZIsMhW7QA /hEJgouL+Ao5kUdZ/NFECVxjkaONCPbvbmowYJQSwXfunZRkkdL9VSwB4CTrZKropU2f r7vyYi9/f+xoAQQt0i5NQh7g6KbFK/idvTGuoEbsEafGHmrjv70S1cMEuzCxwjqxCYs6 AJ7Q== 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=nNhDDjanCC9j3xJAEF0rELczRZ6czzcQmWPx5UtbQsc/gzMWjseaWf5thRZ4KAnXbE vSM7Ic6cjbkopcPFqCX1vUK/tTGQY2+sI5sOz7m3V0WPcj33eWjF5SLtq5bNW7KtOkYE znwJjXoV1DNBfvb96vTRRm88f9wcOBPZ4wtt8INDErrJMoq0ZXH0XUN/iYpFrZPB6zto K9flYAzssz9wFJoyXl8Wdye2SL6tSC51Zi1wu+ARQrZLQSFbbml5PmAwhm0BJt9AYApJ +w/+7dhHPT36+RFYwZjw/oMI0qoWK8Er/fASZ07TDuVAqOeha7anMXKlwNv6tv220zPP Vo+w== X-Gm-Message-State: AOAM532AWsW0V1amp49fC6AZOVusL4uRekut0YYaqcFp1kDkt10mCa57 Ot1Uh9vyuxeh7VATf0XYqInZ4PV1Ru4WnQ== X-Google-Smtp-Source: ABdhPJwS1na7I8e1TQfQWLgzcr/XO2sG8ch1F6vYp/gxvdWlioP45E9KS79xTDwK1GNVAEuVgnLKpQ== X-Received: by 2002:a62:fc4c:: with SMTP id e73mr25308388pfh.308.1595349537165; Tue, 21 Jul 2020 09:38:57 -0700 (PDT) Received: from localhost.localdomain ([122.172.60.196]) by smtp.gmail.com with ESMTPSA id r204sm21454092pfc.134.2020.07.21.09.38.55 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 21 Jul 2020 09:38:56 -0700 (PDT) From: gautamramk@gmail.com To: ffmpeg-devel@ffmpeg.org Date: Tue, 21 Jul 2020 22:08:49 +0530 Message-Id: <20200721163849.2887-1-gautamramk@gmail.com> X-Mailer: git-send-email 2.17.1 Subject: [FFmpeg-devel] [RFC PATCH] 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, +};