From patchwork Mon Mar 5 13:04:25 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Pierre Chatelier X-Patchwork-Id: 7815 Delivered-To: ffmpegpatchwork@gmail.com Received: by 10.2.181.170 with SMTP id m39csp2933678jaj; Mon, 5 Mar 2018 12:06:31 -0800 (PST) X-Google-Smtp-Source: AG47ELt7zSTiZcXbVJe5H1u9S40vAJC3+l2X39/UaPb67MI21nxvyVBypDaClbNYkq0iTrLZ72yr X-Received: by 10.223.199.69 with SMTP id b5mr15005366wrh.212.1520280391421; Mon, 05 Mar 2018 12:06:31 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1520280391; cv=none; d=google.com; s=arc-20160816; b=ZAG+OhidUwuBTCMyApC48Ch1Km6XASr1Fh1v4JOXyUNJsNKiEP0CZKtm+swIOhUXO2 gcj3KzgdqUS/Tv1l7mm3peBhzBABXLa+1lkb5VoqPiL+HEr/S6VgLBGZV2m6gYFFcrHl 9FPNSn8c+ABXyDCXVxzsFPteVXrehRbHfUJRvz4bJojoxC/Hp0Xmak82v00EwQuU0nPz 9ORRt/GXHJv/nPucB/7g4HvbRR90g4ZoQTXm8oRcnMtktOTUO3PitdW0YDmE5A876t68 ePu8L89HlWjpjfMbVFWHQ1uc0NMSAmzgBECMEkjWMTtJqEUQ3fnmnEExAuuyMLvDO0kK H53g== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:reply-to:list-subscribe:list-help:list-post :list-archive:list-unsubscribe:list-id:precedence:subject :content-language:mime-version:user-agent:date:message-id:from:to :delivered-to:arc-authentication-results; bh=1U0xXvpENK90Yq1LL3yc4vBjb29Lo8hz7pPDB0WLJks=; b=IQXutPANxUUAUFoAxgvNxVXTLso9acQqARAs1XQVMpdVrQchktFiDs8K6XsJJoAkrL H8+ONgFZiwk6QREJ9HoDKD0O6fOZ2Bphtq7vDoBGJPbjK4a/Q2aNwGLeC9m9lIn4jkPo 7l4IVqbMqgjk5vWiF6g4wYBQv4CdbPd1+qr+EsPh3CZij7uIbm+ZCYlikxSsqSFLPosE VmCKYW7DHYC94tKqqNUPFdCjU8VBtLUB83PFHgQbjc0afQg/76WXqSxCFpeyWxGrnfmB X3b/OKV+DGDXGxpjuoRistW9bH9INpLfOyJ9ciYBvjSyO52pGX7aXslnoK4lt3yfmfxX 4ubA== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: domain of ffmpeg-devel-bounces@ffmpeg.org designates 79.124.17.100 as permitted sender) smtp.mailfrom=ffmpeg-devel-bounces@ffmpeg.org Return-Path: Received: from ffbox0-bg.mplayerhq.hu (ffbox0-bg.ffmpeg.org. [79.124.17.100]) by mx.google.com with ESMTP id u26si1866101wrd.446.2018.03.05.12.06.30; Mon, 05 Mar 2018 12:06:31 -0800 (PST) Received-SPF: pass (google.com: domain of ffmpeg-devel-bounces@ffmpeg.org designates 79.124.17.100 as permitted sender) client-ip=79.124.17.100; Authentication-Results: mx.google.com; spf=pass (google.com: domain of ffmpeg-devel-bounces@ffmpeg.org designates 79.124.17.100 as permitted sender) smtp.mailfrom=ffmpeg-devel-bounces@ffmpeg.org Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id 9C36A68A3D5; Mon, 5 Mar 2018 22:06:21 +0200 (EET) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from 7.mo173.mail-out.ovh.net (7.mo173.mail-out.ovh.net [46.105.44.159]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id C925868A266 for ; Mon, 5 Mar 2018 15:04:26 +0200 (EET) Received: from player771.ha.ovh.net (unknown [10.109.108.118]) by mo173.mail-out.ovh.net (Postfix) with ESMTP id E0120B17E8 for ; Mon, 5 Mar 2018 14:04:32 +0100 (CET) Received: from [192.168.1.28] (LAubervilliers-656-1-32-168.w193-251.abo.wanadoo.fr [193.251.28.168]) (Authenticated sender: pierre@chachatelier.fr) by player771.ha.ovh.net (Postfix) with ESMTPA id 47848840083 for ; Mon, 5 Mar 2018 14:04:31 +0100 (CET) To: ffmpeg-devel@ffmpeg.org From: Pierre Chatelier Message-ID: Date: Mon, 5 Mar 2018 14:04:25 +0100 User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:52.0) Gecko/20100101 Thunderbird/52.6.0 MIME-Version: 1.0 Content-Language: fr X-Ovh-Tracer-Id: 4638707617910377149 X-VR-SPAMSTATE: OK X-VR-SPAMSCORE: 0 X-VR-SPAMCAUSE: gggruggvucftvghtrhhoucdtuddrgedtfedrjeejgdeglecutefuodetggdotefrodftvfcurfhrohhfihhlvgemucfqggfjpdevjffgvefmvefgnecuuegrihhlohhuthemuceftddtnecu X-Mailman-Approved-At: Mon, 05 Mar 2018 22:06:20 +0200 Subject: [FFmpeg-devel] patch for ticket #7053 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 Errors-To: ffmpeg-devel-bounces@ffmpeg.org Sender: "ffmpeg-devel" Here is a patch proposition for https://trac.ffmpeg.org/ticket/7053 Pierre Chatelier From 7cbc1bd47fb97e3498d92eda9c84144de2c06d01 Mon Sep 17 00:00:00 2001 From: Pierre Chatelier Date: Mon, 5 Mar 2018 13:57:00 +0100 Subject: [PATCH 1/1] added YUV422-12, -14, -16 bit depth, mono-8, -10, -12, -16 bit depth, rgb888 to bitpacked codec --- libavcodec/bitpacked.c | 281 ++++++++++++++++++++++++++++++++++++++++++- libavformat/rtpdec_rfc4175.c | 51 +++++++- 2 files changed, 330 insertions(+), 2 deletions(-) diff --git a/libavcodec/bitpacked.c b/libavcodec/bitpacked.c index f0b417d595..cf6275d963 100644 --- a/libavcodec/bitpacked.c +++ b/libavcodec/bitpacked.c @@ -55,6 +55,141 @@ static int bitpacked_decode_uyvy422(AVCodecContext *avctx, AVFrame *frame, return 0; } +static int bitpacked_decode_gray8(AVCodecContext *avctx, AVFrame *frame, + AVPacket *avpkt) +{ + int ret; + + /* there is no need to copy as the data already match + * a known pixel format */ + frame->buf[0] = av_buffer_ref(avpkt->buf); + ret = av_image_fill_arrays(frame->data, frame->linesize, avpkt->data, + avctx->pix_fmt, avctx->width, avctx->height, 1); + if (ret < 0) { + av_buffer_unref(&frame->buf[0]); + return ret; + } + + return 0; +} + +static int bitpacked_decode_gray10(AVCodecContext *avctx, AVFrame *frame, + AVPacket *avpkt) +{ + uint64_t frame_size = (uint64_t)avctx->width * (uint64_t)avctx->height * 10; + uint64_t packet_size = (uint64_t)avpkt->size * 8; + GetBitContext bc; + uint16_t *g; + int ret, i, j; + + ret = ff_get_buffer(avctx, frame, 0); + if (ret < 0) + return ret; + + if (frame_size > packet_size) + return AVERROR_INVALIDDATA; + + ret = init_get_bits(&bc, avpkt->data, avctx->width * avctx->height * 10); + if (ret) + return ret; + + for (i = 0; i < avctx->height; i++) { + g = (uint16_t*)(frame->data[0] + i * frame->linesize[0]); + + for (j = 0; j < avctx->width; j += 4) + { + *g++ = get_bits(&bc, 10); + *g++ = get_bits(&bc, 10); + *g++ = get_bits(&bc, 10); + *g++ = get_bits(&bc, 10); + } + } + + + return 0; +} + +static int bitpacked_decode_gray12(AVCodecContext *avctx, AVFrame *frame, + AVPacket *avpkt) +{ + uint64_t frame_size = (uint64_t)avctx->width * (uint64_t)avctx->height * 12; + uint64_t packet_size = (uint64_t)avpkt->size * 8; + GetBitContext bc; + uint16_t *g; + int ret, i, j; + + ret = ff_get_buffer(avctx, frame, 0); + if (ret < 0) + return ret; + + if (frame_size > packet_size) + return AVERROR_INVALIDDATA; + + ret = init_get_bits(&bc, avpkt->data, avctx->width * avctx->height * 12); + if (ret) + return ret; + + for (i = 0; i < avctx->height; i++) { + g = (uint16_t*)(frame->data[0] + i * frame->linesize[0]); + + for (j = 0; j < avctx->width; j += 2) + { + *g++ = get_bits(&bc, 12); + *g++ = get_bits(&bc, 12); + } + } + + return 0; +} + +static int bitpacked_decode_gray16(AVCodecContext *avctx, AVFrame *frame, + AVPacket *avpkt) +{ + uint64_t frame_size = (uint64_t)avctx->width * (uint64_t)avctx->height * 16; + uint64_t packet_size = (uint64_t)avpkt->size * 8; + GetBitContext bc; + uint16_t *g; + int ret, i, j; + + ret = ff_get_buffer(avctx, frame, 0); + if (ret < 0) + return ret; + + if (frame_size > packet_size) + return AVERROR_INVALIDDATA; + + ret = init_get_bits(&bc, avpkt->data, avctx->width * avctx->height * 16); + if (ret) + return ret; + + for (i = 0; i < avctx->height; i++) { + g = (uint16_t*)(frame->data[0] + i * frame->linesize[0]); + + for (j = 0; j < avctx->width; j++) + *g++ = get_bits(&bc, 16); + } + + return 0; +} + +static int bitpacked_decode_rgb24(AVCodecContext *avctx, AVFrame *frame, + AVPacket *avpkt) +{ + int ret; + + /* there is no need to copy as the data already match + * a known pixel format */ + frame->buf[0] = av_buffer_ref(avpkt->buf); + ret = av_image_fill_arrays(frame->data, frame->linesize, avpkt->data, + avctx->pix_fmt, avctx->width, avctx->height, 1); + if (ret < 0) { + av_buffer_unref(&frame->buf[0]); + return ret; + } + + return 0; +} + static int bitpacked_decode_yuv422p10(AVCodecContext *avctx, AVFrame *frame, AVPacket *avpkt) { @@ -94,6 +229,123 @@ static int bitpacked_decode_yuv422p10(AVCodecContext *avctx, AVFrame *frame, return 0; } +static int bitpacked_decode_yuv422p12(AVCodecContext *avctx, AVFrame *frame, + AVPacket *avpkt) +{ + uint64_t frame_size = (uint64_t)avctx->width * (uint64_t)avctx->height * 24; + uint64_t packet_size = (uint64_t)avpkt->size * 8; + GetBitContext bc; + uint16_t *y, *u, *v; + int ret, i, j; + + ret = ff_get_buffer(avctx, frame, 0); + if (ret < 0) + return ret; + + if (frame_size > packet_size) + return AVERROR_INVALIDDATA; + + if (avctx->width % 2) + return AVERROR_PATCHWELCOME; + + ret = init_get_bits(&bc, avpkt->data, avctx->width * avctx->height * 24); + if (ret) + return ret; + + for (i = 0; i < avctx->height; i++) { + y = (uint16_t*)(frame->data[0] + i * frame->linesize[0]); + u = (uint16_t*)(frame->data[1] + i * frame->linesize[1]); + v = (uint16_t*)(frame->data[2] + i * frame->linesize[2]); + + for (j = 0; j < avctx->width; j += 2) { + *u++ = get_bits(&bc, 12); + *y++ = get_bits(&bc, 12); + *v++ = get_bits(&bc, 12); + *y++ = get_bits(&bc, 12); + } + } + + return 0; +} + +static int bitpacked_decode_yuv422p14(AVCodecContext *avctx, AVFrame *frame, + AVPacket *avpkt) +{ + uint64_t frame_size = (uint64_t)avctx->width * (uint64_t)avctx->height * 28; + uint64_t packet_size = (uint64_t)avpkt->size * 8; + GetBitContext bc; + uint16_t *y, *u, *v; + int ret, i, j; + + ret = ff_get_buffer(avctx, frame, 0); + if (ret < 0) + return ret; + + if (frame_size > packet_size) + return AVERROR_INVALIDDATA; + + if (avctx->width % 2) + return AVERROR_PATCHWELCOME; + + ret = init_get_bits(&bc, avpkt->data, avctx->width * avctx->height * 28); + if (ret) + return ret; + + for (i = 0; i < avctx->height; i++) { + y = (uint16_t*)(frame->data[0] + i * frame->linesize[0]); + u = (uint16_t*)(frame->data[1] + i * frame->linesize[1]); + v = (uint16_t*)(frame->data[2] + i * frame->linesize[2]); + + for (j = 0; j < avctx->width; j += 2) { + *u++ = get_bits(&bc, 14); + *y++ = get_bits(&bc, 14); + *v++ = get_bits(&bc, 14); + *y++ = get_bits(&bc, 14); + } + } + + return 0; +} + +static int bitpacked_decode_yuv422p16(AVCodecContext *avctx, AVFrame *frame, + AVPacket *avpkt) +{ + uint64_t frame_size = (uint64_t)avctx->width * (uint64_t)avctx->height * 32; + uint64_t packet_size = (uint64_t)avpkt->size * 8; + GetBitContext bc; + uint16_t *y, *u, *v; + int ret, i, j; + + ret = ff_get_buffer(avctx, frame, 0); + if (ret < 0) + return ret; + + if (frame_size > packet_size) + return AVERROR_INVALIDDATA; + + if (avctx->width % 2) + return AVERROR_PATCHWELCOME; + + ret = init_get_bits(&bc, avpkt->data, avctx->width * avctx->height * 32); + if (ret) + return ret; + + for (i = 0; i < avctx->height; i++) { + y = (uint16_t*)(frame->data[0] + i * frame->linesize[0]); + u = (uint16_t*)(frame->data[1] + i * frame->linesize[1]); + v = (uint16_t*)(frame->data[2] + i * frame->linesize[2]); + + for (j = 0; j < avctx->width; j += 2) { + *u++ = get_bits(&bc, 16); + *y++ = get_bits(&bc, 16); + *v++ = get_bits(&bc, 16); + *y++ = get_bits(&bc, 16); + } + } + + return 0; +} + static av_cold int bitpacked_init_decoder(AVCodecContext *avctx) { struct BitpackedContext *bc = avctx->priv_data; @@ -101,13 +353,40 @@ static av_cold int bitpacked_init_decoder(AVCodecContext *avctx) if (!avctx->codec_tag || !avctx->width || !avctx->height) return AVERROR_INVALIDDATA; - if (avctx->codec_tag == MKTAG('U', 'Y', 'V', 'Y')) { + if (avctx->codec_tag == MKTAG('r', 'a', 'w', ' ')) { + if (avctx->bits_per_coded_sample == 8 && + avctx->pix_fmt == AV_PIX_FMT_GRAY8) + bc->decode = bitpacked_decode_gray8; + else if (avctx->bits_per_coded_sample == 10 && + avctx->pix_fmt == AV_PIX_FMT_GRAY10) + bc->decode = bitpacked_decode_gray10; + else if (avctx->bits_per_coded_sample == 12 && + avctx->pix_fmt == AV_PIX_FMT_GRAY12) + bc->decode = bitpacked_decode_gray12; + else if (avctx->bits_per_coded_sample == 16 && + avctx->pix_fmt == AV_PIX_FMT_GRAY16) + bc->decode = bitpacked_decode_gray16; + else if (avctx->bits_per_coded_sample == 24 && + avctx->pix_fmt == AV_PIX_FMT_RGB24) + bc->decode = bitpacked_decode_rgb24; + else + return AVERROR_INVALIDDATA; + } else if (avctx->codec_tag == MKTAG('U', 'Y', 'V', 'Y')) { if (avctx->bits_per_coded_sample == 16 && avctx->pix_fmt == AV_PIX_FMT_UYVY422) bc->decode = bitpacked_decode_uyvy422; else if (avctx->bits_per_coded_sample == 20 && avctx->pix_fmt == AV_PIX_FMT_YUV422P10) bc->decode = bitpacked_decode_yuv422p10; + else if (avctx->bits_per_coded_sample == 24 && + avctx->pix_fmt == AV_PIX_FMT_YUV422P12) + bc->decode = bitpacked_decode_yuv422p12; + else if (avctx->bits_per_coded_sample == 28 && + avctx->pix_fmt == AV_PIX_FMT_YUV422P14) + bc->decode = bitpacked_decode_yuv422p14; + else if (avctx->bits_per_coded_sample == 32 && + avctx->pix_fmt == AV_PIX_FMT_YUV422P16) + bc->decode = bitpacked_decode_yuv422p16; else return AVERROR_INVALIDDATA; } else { diff --git a/libavformat/rtpdec_rfc4175.c b/libavformat/rtpdec_rfc4175.c index 498381dfd3..fda0023b15 100644 --- a/libavformat/rtpdec_rfc4175.c +++ b/libavformat/rtpdec_rfc4175.c @@ -45,8 +45,45 @@ static int rfc4175_parse_format(AVStream *stream, PayloadContext *data) enum AVPixelFormat pixfmt = AV_PIX_FMT_NONE; int bits_per_sample = 0; int tag = 0; + + if (!strncmp(data->sampling, "Mono", 4)) { + tag = MKTAG('r', 'a', 'w', ' '); - if (!strncmp(data->sampling, "YCbCr-4:2:2", 11)) { + if (data->depth == 8) { + data->xinc = 1; + data->pgroup = 1; + bits_per_sample = 8; + pixfmt = AV_PIX_FMT_GRAY8; + }else if (data->depth == 10) { + data->xinc = 4; + data->pgroup = 5; + bits_per_sample = 10; + pixfmt = AV_PIX_FMT_GRAY10; + } else if (data->depth == 12) { + data->xinc = 2; + data->pgroup = 3; + bits_per_sample = 12; + pixfmt = AV_PIX_FMT_GRAY12; + } else if (data->depth == 16) { + data->xinc = 1; + data->pgroup = 2; + bits_per_sample = 16; + pixfmt = AV_PIX_FMT_GRAY16; + } else { + return AVERROR_INVALIDDATA; + } + } else if (!strncmp(data->sampling, "RGB", 3)) { + tag = MKTAG('r', 'a', 'w', ' '); + data->xinc = 1; + + if (data->depth == 8) { + data->pgroup = 3; + bits_per_sample = 24; + pixfmt = AV_PIX_FMT_RGB24; + } else { + return AVERROR_INVALIDDATA; + } + } else if (!strncmp(data->sampling, "YCbCr-4:2:2", 11)) { tag = MKTAG('U', 'Y', 'V', 'Y'); data->xinc = 2; @@ -58,6 +95,18 @@ static int rfc4175_parse_format(AVStream *stream, PayloadContext *data) data->pgroup = 5; bits_per_sample = 20; pixfmt = AV_PIX_FMT_YUV422P10; + } else if (data->depth == 12) { + data->pgroup = 6; + bits_per_sample = 24; + pixfmt = AV_PIX_FMT_YUV422P12; + } else if (data->depth == 14) { + data->pgroup = 7; + bits_per_sample = 28; + pixfmt = AV_PIX_FMT_YUV422P14; + } else if (data->depth == 16) { + data->pgroup = 8; + bits_per_sample = 32; + pixfmt = AV_PIX_FMT_YUV422P16; } else { return AVERROR_INVALIDDATA; }