From patchwork Fri Sep 7 23:51:12 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sam John X-Patchwork-Id: 10272 Delivered-To: ffmpegpatchwork@gmail.com Received: by 2002:a02:12c4:0:0:0:0:0 with SMTP id 65-v6csp59837jap; Fri, 7 Sep 2018 16:51:28 -0700 (PDT) X-Google-Smtp-Source: ANB0VdY1QFUJYgEiZIQ5+2xuPGZ1JRNyx3Q9wHyasREhLPy74L2AgsXCK+gp/IB1Q8My5B9EA+Rd X-Received: by 2002:a5d:6984:: with SMTP id g4-v6mr7740662wru.232.1536364288515; Fri, 07 Sep 2018 16:51:28 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1536364288; cv=none; d=google.com; s=arc-20160816; b=WQjEbWU/t0Opz8g5OXDPQXnjnVXhE1BCqCpfl2QoJLnmmTZfGMZdR5zpPmW6Z2NZoT E18H7C/QBa++yA0/eNL1dbChv1I7rCBYqxwJebzaVmwK17jS8vX0o780uSRI4KppVDe5 glEhWlJpVmnpjNn27QE5b6XyeIzlVwD3EpPaqzT5wiTUPpRgkmaOr9z1fGreREogrui9 eTu/XPo+uG+8eH+BNU72Sb9HdqcVxiXz8aDKHQS0n2dB9I9caLs967sFU/7qv4FfhVP4 5d+TreftpBm9/aUilhHbW9zmzadQ4UZfOwCFrvwn6eyDgunWqpfEPFSmx6iPtsbd6bNt imew== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:content-transfer-encoding:cc:reply-to :list-subscribe:list-help:list-post:list-archive:list-unsubscribe :list-id:precedence:subject:to:from:mime-version:message-id:date :dkim-signature:delivered-to; bh=STMrUfSD2XrCrqXIrvf8Wg0taqP4+CHlFz23hqN7+MQ=; b=FSGW2XrDEMD9poVUJF2xq8ZnqWX8/6WEoF/t828X+k5t7g5AmogXJQPFazt7Qpissf dKdT/6NctiBbcSSZiYWD81Ffc9CU1dPJQFlYl0eWWyd5+mA4Huw9ESaMoxC3WdN4bKlt +nMDh60xNHWJIP4BtEcIZtN1qKnsndnZgTDshYJrwXB0Lb08b/tnH68h7sX8zcjOeLWI hZS3kX+Tkof3KeEagLYOH5FjpJa0q8+0IeruMwWXKfaCEA2aAvy+4H0FZ5pwcFult8By i3l8oFOMFeB2PKkDwcvAupI4yjV7oTK8tVPss/g3DrT0nnhaoCqaTr69F43ArHTAbIQw 9Cng== ARC-Authentication-Results: i=1; mx.google.com; dkim=neutral (body hash did not verify) header.i=@google.com header.s=20161025 header.b="Z46SYb/a"; 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 x11-v6si7425260wmg.118.2018.09.07.16.51.27; Fri, 07 Sep 2018 16:51:28 -0700 (PDT) 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; dkim=neutral (body hash did not verify) header.i=@google.com header.s=20161025 header.b="Z46SYb/a"; 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 A4582689EF9; Sat, 8 Sep 2018 02:51:17 +0300 (EEST) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from mail-yw1-f74.google.com (mail-yw1-f74.google.com [209.85.161.74]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id B779B689E81 for ; Sat, 8 Sep 2018 02:51:10 +0300 (EEST) Received: by mail-yw1-f74.google.com with SMTP id d23-v6so9762363ywb.2 for ; Fri, 07 Sep 2018 16:51:19 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20161025; h=date:message-id:mime-version:subject:from:to:cc; bh=Q3nthAPFIHUuZwDMWHZGpsf1vileRX5ZrQj2ASrWc7o=; b=Z46SYb/a3mjRSgt8oTe96A6RsYry9GehPqwwFUk5cJXIhlLFbxQ/HpvRJqZ94MvCHH KsS4F/1aDI/36fdpKBNWdmXIdnZKr1ntdPdZm21QFzLqo8AQqtuQHpWHrixAEY2HdIRD cnNY7tyQtTutJmeMeuZORVAu7/QWxKdrzYUXjVoTTGx9kMFGYoKFjg1iWohv9In27FAW 8yUTAGw9WkSnCws+PLy3C45Q6+GTrgHnfpqbovPeqFNWBZcYXFXFRG8IoT7AJ+2qE3Zv TDlN1RB8A1NNzTleuaBq6K6+eDOLWnZbjbudzJBq6MsPGzCDp2CPCwioeEQTEXiYmJ2g W/OA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:date:message-id:mime-version:subject:from:to:cc; bh=Q3nthAPFIHUuZwDMWHZGpsf1vileRX5ZrQj2ASrWc7o=; b=t9DDFIRyQHJnhcVs3K3yKLNsaBR8G+TgpVdhyYVWRmXnYDy6JJizq1OAhqf7IP4XlH 3yxbLhlJEyfNA+MCzG/TTcaQnK+bw7Fl51YglAvA63xbNb7+V2+homt/zdNekT0KJCBz ujmroQguzxsV+r4WQbQUOk+fRRXstFIecxkcI3NbMFGgoF2b7qTyD28iGO5961oQooxy j57L+01NoSnfAm5AedML5w1kSfNK1ZLzQc85ctbJM4FklqhssRa7q6k/x6iN6HUbVU0u 36vRI6yvRxrbBnwa5esR0RkjjbpfADzofv/0KY47+VuOGFMbqTpBGqOY/m5GMU0RQRN4 xVrw== X-Gm-Message-State: APzg51DSMB5jsOPndAnNfLkJLIGDo5t7ajkVVD87HKxKZUimQ0cxlaY8 /FJudcrJwWzdPyWj0XVJszitYjecbmB4bL0hC67G7fN7JwD7DR3TZ1vWn8rf367I+iYyAvjPBCC /zpR2ci2TBptc1v3+Rn0oz1mqzQiyHorGe+gkbtRPf/LcoYHGK/9SwDpJ/diPJWSGfw== X-Received: by 2002:a5b:f4a:: with SMTP id y10-v6mr1026026ybr.72.1536364277823; Fri, 07 Sep 2018 16:51:17 -0700 (PDT) Date: Fri, 7 Sep 2018 16:51:12 -0700 Message-Id: <20180907235112.195643-1-samjohn@google.com> Mime-Version: 1.0 X-Mailer: git-send-email 2.19.0.rc2.392.g5ba43deb5a-goog From: Sam John To: ffmpeg-devel@ffmpeg.org Subject: [FFmpeg-devel] [PATCH] libavcodec/libaomenc.c: Added code for computing PSNR/SSIM for libaom encoder. 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: Sam John Errors-To: ffmpeg-devel-bounces@ffmpeg.org Sender: "ffmpeg-devel" --- libavcodec/libaomenc.c | 117 +++++++++++++++++++++++++++++++++-------- 1 file changed, 96 insertions(+), 21 deletions(-) diff --git a/libavcodec/libaomenc.c b/libavcodec/libaomenc.c index 9431179886..e62057177d 100644 --- a/libavcodec/libaomenc.c +++ b/libavcodec/libaomenc.c @@ -50,6 +50,9 @@ struct FrameListData { unsigned long duration; /**< duration to show frame (in timebase units) */ uint32_t flags; /**< flags for this frame */ + uint64_t sse[4]; + int have_sse; /**< true if we have pending sse[] */ + uint64_t frame_number; struct FrameListData *next; }; @@ -68,6 +71,9 @@ typedef struct AOMEncoderContext { int static_thresh; int drop_threshold; int noise_sensitivity; + uint64_t sse[4]; + int have_sse; /**< true if we have pending sse[] */ + uint64_t frame_number; } AOMContext; static const char *const ctlidstr[] = { @@ -289,7 +295,8 @@ static av_cold int aom_init(AVCodecContext *avctx, { AOMContext *ctx = avctx->priv_data; struct aom_codec_enc_cfg enccfg = { 0 }; - aom_codec_flags_t flags = 0; + aom_codec_flags_t flags = + (avctx->flags & AV_CODEC_FLAG_PSNR) ? AOM_CODEC_USE_PSNR : 0; AVCPBProperties *cpb_props; int res; aom_img_fmt_t img_fmt; @@ -499,13 +506,30 @@ static av_cold int aom_init(AVCodecContext *avctx, } static inline void cx_pktcpy(struct FrameListData *dst, - const struct aom_codec_cx_pkt *src) + const struct aom_codec_cx_pkt *src, + AOMContext *ctx) { dst->pts = src->data.frame.pts; dst->duration = src->data.frame.duration; dst->flags = src->data.frame.flags; dst->sz = src->data.frame.sz; dst->buf = src->data.frame.buf; + dst->have_sse = 0; + /* For alt-ref frame, don't store PSNR or increment frame_number */ + if (!(dst->flags & AOM_FRAME_IS_INVISIBLE)) { + dst->frame_number = ++ctx->frame_number; + dst->have_sse = ctx->have_sse; + if (ctx->have_sse) { + /* associate last-seen SSE to the frame. */ + /* Transfers ownership from ctx to dst. */ + /* WARNING! This makes the assumption that PSNR_PKT comes + just before the frame it refers to! */ + memcpy(dst->sse, ctx->sse, sizeof(dst->sse)); + ctx->have_sse = 0; + } + } else { + dst->frame_number = -1; /* sanity marker */ + } } /** @@ -524,26 +548,68 @@ static int storeframe(AVCodecContext *avctx, struct FrameListData *cx_frame, av_log(avctx, AV_LOG_ERROR, "Error getting output packet of size %"SIZE_SPECIFIER".\n", cx_frame->sz); return ret; - } - memcpy(pkt->data, cx_frame->buf, pkt->size); - pkt->pts = pkt->dts = cx_frame->pts; + } else { + int pict_type; + memcpy(pkt->data, cx_frame->buf, pkt->size); + pkt->pts = pkt->dts = cx_frame->pts; +#if FF_API_CODED_FRAME +FF_DISABLE_DEPRECATION_WARNINGS + avctx->coded_frame->pts = cx_frame->pts; + avctx->coded_frame->key_frame = !!(cx_frame->flags & AOM_FRAME_IS_KEY); +FF_ENABLE_DEPRECATION_WARNINGS +#endif + + if (!!(cx_frame->flags & AOM_FRAME_IS_KEY)) { + pict_type = AV_PICTURE_TYPE_I; +#if FF_API_CODED_FRAME +FF_DISABLE_DEPRECATION_WARNINGS + avctx->coded_frame->pict_type = pict_type; +FF_ENABLE_DEPRECATION_WARNINGS +#endif + pkt->flags |= AV_PKT_FLAG_KEY; + } else { + pict_type = AV_PICTURE_TYPE_P; +#if FF_API_CODED_FRAME +FF_DISABLE_DEPRECATION_WARNINGS + avctx->coded_frame->pict_type = pict_type; +FF_ENABLE_DEPRECATION_WARNINGS +#endif + } - if (!!(cx_frame->flags & AOM_FRAME_IS_KEY)) - pkt->flags |= AV_PKT_FLAG_KEY; + if (avctx->flags & AV_CODEC_FLAG_GLOBAL_HEADER) { + ret = av_bsf_send_packet(ctx->bsf, pkt); + if (ret < 0) { + av_log(avctx, AV_LOG_ERROR, "extract_extradata filter " + "failed to send input packet\n"); + return ret; + } + ret = av_bsf_receive_packet(ctx->bsf, pkt); - if (avctx->flags & AV_CODEC_FLAG_GLOBAL_HEADER) { - ret = av_bsf_send_packet(ctx->bsf, pkt); - if (ret < 0) { - av_log(avctx, AV_LOG_ERROR, "extract_extradata filter " - "failed to send input packet\n"); - return ret; + if (ret < 0) { + av_log(avctx, AV_LOG_ERROR, "extract_extradata filter " + "failed to receive output packet\n"); + return ret; + } } - ret = av_bsf_receive_packet(ctx->bsf, pkt); - if (ret < 0) { - av_log(avctx, AV_LOG_ERROR, "extract_extradata filter " - "failed to receive output packet\n"); - return ret; + ff_side_data_set_encoder_stats(pkt, 0, cx_frame->sse + 1, + cx_frame->have_sse ? 3 : 0, pict_type); + + if (cx_frame->have_sse) { + int i; + /* Beware of the Y/U/V/all order! */ +#if FF_API_CODED_FRAME +FF_DISABLE_DEPRECATION_WARNINGS + avctx->coded_frame->error[0] = cx_frame->sse[1]; + avctx->coded_frame->error[1] = cx_frame->sse[2]; + avctx->coded_frame->error[2] = cx_frame->sse[3]; + avctx->coded_frame->error[3] = 0; // alpha +FF_ENABLE_DEPRECATION_WARNINGS +#endif + for (i = 0; i < 3; ++i) { + avctx->error[i] += cx_frame->sse[i + 1]; + } + cx_frame->have_sse = 0; } } return pkt->size; @@ -585,7 +651,7 @@ static int queue_frames(AVCodecContext *avctx, AVPacket *pkt_out) /* avoid storing the frame when the list is empty and we haven't yet * provided a frame for output */ av_assert0(!ctx->coded_frame_list); - cx_pktcpy(&cx_frame, pkt); + cx_pktcpy(&cx_frame, pkt, ctx); size = storeframe(avctx, &cx_frame, pkt_out); if (size < 0) return size; @@ -598,7 +664,7 @@ static int queue_frames(AVCodecContext *avctx, AVPacket *pkt_out) "Frame queue element alloc failed\n"); return AVERROR(ENOMEM); } - cx_pktcpy(cx_frame, pkt); + cx_pktcpy(cx_frame, pkt, ctx); cx_frame->buf = av_malloc(cx_frame->sz); if (!cx_frame->buf) { @@ -628,7 +694,16 @@ static int queue_frames(AVCodecContext *avctx, AVPacket *pkt_out) stats->sz += pkt->data.twopass_stats.sz; break; } - case AOM_CODEC_PSNR_PKT: // FIXME add support for AV_CODEC_FLAG_PSNR + case AOM_CODEC_PSNR_PKT: + { + av_assert0(!ctx->have_sse); + ctx->sse[0] = pkt->data.psnr.sse[0]; + ctx->sse[1] = pkt->data.psnr.sse[1]; + ctx->sse[2] = pkt->data.psnr.sse[2]; + ctx->sse[3] = pkt->data.psnr.sse[3]; + ctx->have_sse = 1; + break; + } case AOM_CODEC_CUSTOM_PKT: // ignore unsupported/unrecognized packet types break;