From patchwork Mon Sep 30 13:27:20 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Kah Goh X-Patchwork-Id: 15412 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 F07774480AB for ; Mon, 30 Sep 2019 16:28:09 +0300 (EEST) Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id D07C56881D9; Mon, 30 Sep 2019 16:28:09 +0300 (EEST) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from sonic303-24.consmr.mail.gq1.yahoo.com (sonic303-24.consmr.mail.gq1.yahoo.com [98.137.64.205]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id E12EB6880DF for ; Mon, 30 Sep 2019 16:28:01 +0300 (EEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yahoo.com.au; s=s2048; t=1569850079; bh=Su2JuwHPxbiVqt/yqOYNcqz3QYCdFRavuxgEsTTYef0=; h=From:To:Cc:Subject:Date:From:Subject; b=mHYVxICOlatGZaPB/12PMz5ZvX/hEQ6yy9g6EUlb3D7vbxROvN9Fhh3UHMNtKBKHzY4Pg9Y456lANGvfAXJ58pT1V9gLviyOJbZVGuL5EE6FpC/wK8BQeH3ztFSTR3iPgkf1yqw3X2Hb5z44UtT7628JOk1YJkB1EGtdLXQLQ+mtbMENbqGnRLpclZhj7rCniHCtbEMH7naeOus1/zwrTL9EiywjIMBaU5k36jiLsLLY5hhfxpQzVq0hNA8aPruzLyJggc8JsOHy/W2BPlXyxLHJZIEO8cLw9yPaWftNjOQgeDNzaIP+/mok/YIInBplcPBNyOpCbjEOFxBQKPn+dg== X-YMail-OSG: gDS4lUcVM1l8hEtm2ujdK2Zrla.FW4fPhzve5l9UEDBAhhKaEgsT0H7NrQO7h2r VqZTF1osU1tltNjf3nAnjwpdoNQqUiNwjx5UTswGod2uGqGkDy_pjdemOMojbIDpCSwaPuZfp1Sy Q3g238TUaDkjd.TUIgTxXtz4ZPpXCvqy9Bi0_KHHWcibGOI5FFWFXpiERUghBMnX14wIA.ULVJLU OQ2kUQ3847hwdY6YvFhsn9huFljRYy8Dj0LN9dIOa5bEbWLKLbUDukGOz7o9sAF1muv1o7l7Y8vh 3bli4kfFoH4a2Qk9fIBcFfMlx869sAwg0vdsmm1daNh_wP0UXngaZJ8r.mOpqmtWY12nbvGg5LAe 9jXptnngssU9z2NXXy01Y.tfMhTO5jmBrhd2Si4lgDNklbXOJFoc6QO9D881cKyANPsErMXaQk.k btY68se0NXIW5PhkTx7URTe3Zrpjy1khNnB3GNH8oDJBFNDFBBPHc1hgk2x.vT.JHdCZYMQaEulh 55yR4pRMNbPQM_WVUQgW3S6ie.lcgR8DxH06UUmTj6B3w_tT8VVzSh6za1ocSIvsO1JjyKIQesz3 GzYTBgcCo6XpcUL7xgo5AeYee2U735AIyM6wNNdoPEc3J.EL_bjwF77YYUe93CYcPWCtz70DGv8x sd055bD98PBq0BBH00U55hpmUoFMGh8FC_KTtBLexqYmUBDKkb6ZFYN7HqLct5JabnKluJS8CdrV YZy_TAfxHlS0fWJHC1XsHtXnLvQggKfOwCVySDMnJguP8kC1klrR4bINIl9plTSX1FGIAwAUXcJv 2dlGZGUutGJVE_i5RXBZWxvaItZQ0UGRLDFqTh41kDTR.0Z927HgozKMAxr0YD.L0.vRqG1uQqr_ 6uzDUiwHWh6cGYNtOTtUKr.z5hyjn4IXGJ3i5UKno0l1z2AByDJDRkEKwb8zwflNIu07CALJJfNV FzcLV4oyDRR0_JetBv4EsG85p056mqeKxNBFg597OkL.5PjJvqmoXRMig5FjasZQPoGUevbBwcgJ aOk4NUqE9jdTfPWHyVDjpahCJDBmDTpJhTYmRdUhw68e.F87M2zz4Jv7JLEz4dP_viwPJ32.yeZl MzmrYLsHgNLDf6XQkHgrhTPNIQrFa.mlipeoST686apqMhq97hNKyCQN.eYQ0yQCZw_TWjD921qB 5OFPVYYopu5Qqd7lXIo_CmiE39P1X3GetGTLltznXpawkU90vS_AUyT9kqI32RdHdOzrdw_DsnRJ zyL66PfEegvgZmVULIHgMM1hnRFApqUcnCteQrdpWNLpeobhP.MIS.VYcjLQxBNL6 Received: from sonic.gate.mail.ne1.yahoo.com by sonic303.consmr.mail.gq1.yahoo.com with HTTP; Mon, 30 Sep 2019 13:27:59 +0000 Received: by smtp417.mail.gq1.yahoo.com (Oath Hermes SMTP Server) with ESMTPA ID 4d6289e7d51be8c4155f8cb95f9d2e74; Mon, 30 Sep 2019 13:27:55 +0000 (UTC) From: Kah Goh To: ffmpeg-devel@ffmpeg.org Date: Mon, 30 Sep 2019 21:27:20 +0800 Message-Id: <20190930132720.172212-1-villastar@yahoo.com.au> X-Mailer: git-send-email 2.23.0 MIME-Version: 1.0 Subject: [FFmpeg-devel] [PATCH v3] avformat/rtpdec_rfc4175: support non-zero based line numbers 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: Kah Goh , Jacob Siddall Errors-To: ffmpeg-devel-bounces@ffmpeg.org Sender: "ffmpeg-devel" There are differing standards that define different starting line numbers. For example, VSF TR-03 says the line numbers starts at 1, whereas SMPTE 2110-20 says it should start at 0. This change adds support for non-zero based line numbers and addresses the following issues when it starts at 1: - The first scan line was being incorrectly interpreted as the second scan line. This means the first line in the frame was never being populated. - The last packet for the video frame would be treated as invalid because it would have been copied outside of the frame. Consequently, the packet would never be "finalized" and the next packet triggers a missed RTP marker ("Missed previous RTP marker" would keep being logged). VSF TR-03: http://www.videoservicesforum.org/download/technical_recommendations/VSF_TR-03_2015-11-12.pdf Co-Authored-By: Jacob Siddall Co-Authored-By: Kah Goh Signed-off-by: Kah Goh --- libavformat/rtpdec_rfc4175.c | 49 +++++++++++++++++++++++++++++++++--- 1 file changed, 45 insertions(+), 4 deletions(-) diff --git a/libavformat/rtpdec_rfc4175.c b/libavformat/rtpdec_rfc4175.c index e9c62c1389..47d5d23dd6 100644 --- a/libavformat/rtpdec_rfc4175.c +++ b/libavformat/rtpdec_rfc4175.c @@ -25,6 +25,7 @@ #include "rtpdec_formats.h" #include "libavutil/avstring.h" #include "libavutil/pixdesc.h" +#include struct PayloadContext { char *sampling; @@ -37,6 +38,12 @@ struct PayloadContext { unsigned int pgroup; /* size of the pixel group in bytes */ unsigned int xinc; + /* The line number of the first line in the frame (usually either 0 or 1). */ + int first_line_number; + + /* This is set to true once the first line number is confirmed. */ + bool first_line_number_known; + uint32_t timestamp; }; @@ -136,6 +143,13 @@ static int rfc4175_finalize_packet(PayloadContext *data, AVPacket *pkt, return ret; } +static int rfc4175_initialize(AVFormatContext *s, int st_index, PayloadContext *data) +{ + data->first_line_number = 0; + data->first_line_number_known = false; + return 0; +} + static int rfc4175_handle_packet(AVFormatContext *ctx, PayloadContext *data, AVStream *st, AVPacket *pkt, uint32_t *timestamp, const uint8_t * buf, int len, @@ -188,7 +202,7 @@ static int rfc4175_handle_packet(AVFormatContext *ctx, PayloadContext *data, /* and now iterate over every scan lines */ do { - int copy_offset; + int copy_offset, copy_to_line; if (payload_len < data->pgroup) return AVERROR_INVALIDDATA; @@ -199,17 +213,34 @@ static int rfc4175_handle_packet(AVFormatContext *ctx, PayloadContext *data, cont = headers[4] & 0x80; headers += 6; + if (line == 0) { + data->first_line_number = 0; + data->first_line_number_known = true; + } + if (length % data->pgroup) return AVERROR_INVALIDDATA; if (length > payload_len) length = payload_len; - /* prevent ill-formed packets to write after buffer's end */ - copy_offset = (line * data->width + offset) * data->pgroup / data->xinc; - if (copy_offset + length > data->frame_size) + copy_to_line = line - data->first_line_number; + if (copy_to_line < 0) + /* This means the first line number we have calculated is too large, which indicates that we + may have received some bad data. */ return AVERROR_INVALIDDATA; + /* prevent ill-formed packets to write after buffer's end */ + copy_offset = (copy_to_line * data->width + offset) * data->pgroup / data->xinc; + if (copy_offset + length > data->frame_size) { + if (data->first_line_number_known) + return AVERROR_INVALIDDATA; + + // This would happen if the line numbering is 1 based. We still need to check for the RTP flag + // marker (as per after the while loop). + break; + } + dest = data->frame + copy_offset; memcpy(dest, payload, length); @@ -218,6 +249,15 @@ static int rfc4175_handle_packet(AVFormatContext *ctx, PayloadContext *data, } while (cont); if ((flags & RTP_FLAG_MARKER)) { + if (!data->first_line_number_known) { + data->first_line_number = line - data->height + 1; + if (data->first_line_number < 0) { + // This could happen if the frame does not fill up the entire height. + data->first_line_number = 0; + av_log(ctx, AV_LOG_WARNING, "Video frame does not fill entire height"); + } + data->first_line_number_known = true; + } return rfc4175_finalize_packet(data, pkt, st->index); } else if (missed_last_packet) { return 0; @@ -232,5 +272,6 @@ const RTPDynamicProtocolHandler ff_rfc4175_rtp_handler = { .codec_id = AV_CODEC_ID_BITPACKED, .priv_data_size = sizeof(PayloadContext), .parse_sdp_a_line = rfc4175_parse_sdp_line, + .init = rfc4175_initialize, .parse_packet = rfc4175_handle_packet, };