From patchwork Thu Oct 25 12:58:58 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: =?utf-8?q?Martin_Storsj=C3=B6?= X-Patchwork-Id: 10785 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 08E0744BE3B for ; Thu, 25 Oct 2018 16:06:11 +0300 (EEST) Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id 7950468A583; Thu, 25 Oct 2018 16:05:42 +0300 (EEST) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from mail-lj1-f195.google.com (mail-lj1-f195.google.com [209.85.208.195]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id 605B468091C for ; Thu, 25 Oct 2018 16:05:36 +0300 (EEST) Received: by mail-lj1-f195.google.com with SMTP id k11-v6so8132722lja.5 for ; Thu, 25 Oct 2018 06:06:05 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=martin-st.20150623.gappssmtp.com; s=20150623; h=from:to:subject:date:message-id:in-reply-to:references; bh=lwEzfgrg+Gxs9x9qVLcKIF+5Re5oo9ChiqEcvkuM6c4=; b=ehxM4dlHdcw1TvgxfGaivyMv4Ol/B/ZaBJXe7xAv5Uh2xQJ+h7SZ9jwVyC+YN3iRq6 LNNac+9A5n2djpaVzGzDTDDDHXPZJdJrP8/rp/rdxrDCjXGRU2hCAP4dypp87Ks7XoO7 1ynKQs5t8zz9oxrn2WkT91sKQpSEhEhYrK6X+87tb/th8b/HIZbx76YyE/tNVlngtod0 H16IcVbODEvhEznPeTwSjUMi1/vqWTW5Jyn4Mx9EKEceqLGIzslBZ9XpjrN58qb+ORvi rn/xO39Idewtpj+5PGggk1vRfI8FTGQIBVA9dn2c5uk6IPD5N1xuZ9vkxhIsfC+U0tc6 iFAQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:subject:date:message-id:in-reply-to :references; bh=lwEzfgrg+Gxs9x9qVLcKIF+5Re5oo9ChiqEcvkuM6c4=; b=kGPZbrZAkDq5yW30Pdpo5pXnlpTAMt7mi4e2qY0H0grTPDqx7aaek1+a84QOkJ0QCs APc5TOkanTKUpQY/6+dT7lyTAtC84PkVWS9wXlNinvXbb6JRIj53CZ3XmEEM19o62yDY zTPuZzAY6BpnoiBuKINgHk1tROoXj4tjJdcubILtv4BYySHpyK+rYQwgz5osmkD2mSsX yacfpAfGYcMX2QGsMrN3A/A29xCk7pUNpgYlxv+m0zLRsnr1ZYtVBHdxPiMGAVO3ppkl OJ2THCIry8afDKVFcMePlwCvjRI/ZQk/PO9rKBeOvaWM6IfhsvDKNrJFeinWKso77IsK yYPQ== X-Gm-Message-State: AGRZ1gKRabONXfGtAi+wFytEj+6KQA84bvrA0ZupnDAQpasuEtnXkbLe QJrDSbzo5s4pDkae5xrtNwWKr7n+DOtXfg== X-Google-Smtp-Source: AJdET5cLoy/IX49gn+adXGjzjViYfDu+1/E/exuMbC3Z1NsomyzMBFtBih+2PVY4ce9yZoVAxb5HCw== X-Received: by 2002:a2e:94c4:: with SMTP id r4-v6mr1244663ljh.68.1540472341347; Thu, 25 Oct 2018 05:59:01 -0700 (PDT) Received: from localhost (dsl-tkubng21-58c01c-243.dhcp.inet.fi. [88.192.28.243]) by smtp.gmail.com with ESMTPSA id r63-v6sm1253536lfr.66.2018.10.25.05.59.00 for (version=TLS1 cipher=AES128-SHA bits=128/128); Thu, 25 Oct 2018 05:59:01 -0700 (PDT) From: =?UTF-8?q?Martin=20Storsj=C3=B6?= To: ffmpeg-devel@ffmpeg.org Date: Thu, 25 Oct 2018 15:58:58 +0300 Message-Id: <20181025125858.31807-2-martin@martin.st> X-Mailer: git-send-email 2.17.1 (Apple Git-112) In-Reply-To: <20181025125858.31807-1-martin@martin.st> References: <20181025125858.31807-1-martin@martin.st> Subject: [FFmpeg-devel] [PATCH 2/2] libx264: Pass the reordered_opaque field through the 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 MIME-Version: 1.0 Errors-To: ffmpeg-devel-bounces@ffmpeg.org Sender: "ffmpeg-devel" libx264 does have a field for opaque data to pass along with frames through the encoder, but it is a pointer, while the libavcodec reordered_opaque field is an int64_t. Therefore, allocate an array within the libx264 wrapper, where reordered_opaque values in flight are stored, and pass a pointer to this array to libx264. Update the public libavcodec documentation for the AVCodecContext field to explain this usage, and add a codec capability that allows detecting whether an encoder handles this field. --- libavcodec/avcodec.h | 12 +++++++++++- libavcodec/libx264.c | 33 ++++++++++++++++++++++++++++++--- libavcodec/version.h | 4 ++-- 3 files changed, 43 insertions(+), 6 deletions(-) diff --git a/libavcodec/avcodec.h b/libavcodec/avcodec.h index 705a3ce4f3..69c5a82757 100644 --- a/libavcodec/avcodec.h +++ b/libavcodec/avcodec.h @@ -1070,6 +1070,13 @@ typedef struct RcOverride{ */ #define AV_CODEC_CAP_HYBRID (1 << 19) +/** + * This codec takes the reordered_opaque field from input AVFrames + * and returns it in the corresponding field in AVCodecContext after + * encoding. + */ +#define AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE (1 << 20) + /** * Pan Scan area. * This specifies the area which should be displayed. @@ -2676,7 +2683,10 @@ typedef struct AVCodecContext { /** * opaque 64-bit number (generally a PTS) that will be reordered and * output in AVFrame.reordered_opaque - * - encoding: unused + * - encoding: Set by libavcodec to the reordered_opaque of the input + * frame corresponding to the last returned packet. Only + * supported by encoders with the + * AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE capability. * - decoding: Set by user. */ int64_t reordered_opaque; diff --git a/libavcodec/libx264.c b/libavcodec/libx264.c index d6367bf557..13c86a9451 100644 --- a/libavcodec/libx264.c +++ b/libavcodec/libx264.c @@ -92,6 +92,9 @@ typedef struct X264Context { int noise_reduction; char *x264_params; + + int nb_reordered_opaque, next_reordered_opaque; + int64_t *reordered_opaque; } X264Context; static void X264_log(void *p, int level, const char *fmt, va_list args) @@ -278,6 +281,7 @@ static int X264_frame(AVCodecContext *ctx, AVPacket *pkt, const AVFrame *frame, int nnal, i, ret; x264_picture_t pic_out = {0}; int pict_type; + int64_t *out_opaque; x264_picture_init( &x4->pic ); x4->pic.img.i_csp = x4->params.i_csp; @@ -297,6 +301,11 @@ static int X264_frame(AVCodecContext *ctx, AVPacket *pkt, const AVFrame *frame, x4->pic.i_pts = frame->pts; + x4->reordered_opaque[x4->next_reordered_opaque] = frame->reordered_opaque; + x4->pic.opaque = &x4->reordered_opaque[x4->next_reordered_opaque]; + x4->next_reordered_opaque++; + x4->next_reordered_opaque %= x4->nb_reordered_opaque; + switch (frame->pict_type) { case AV_PICTURE_TYPE_I: x4->pic.i_type = x4->forced_idr > 0 ? X264_TYPE_IDR @@ -350,6 +359,14 @@ static int X264_frame(AVCodecContext *ctx, AVPacket *pkt, const AVFrame *frame, pkt->pts = pic_out.i_pts; pkt->dts = pic_out.i_dts; + out_opaque = pic_out.opaque; + if (out_opaque >= x4->reordered_opaque && + out_opaque < &x4->reordered_opaque[x4->nb_reordered_opaque]) { + ctx->reordered_opaque = *out_opaque; + } else { + // Unexpected opaque pointer on picture output + ctx->reordered_opaque = 0; + } switch (pic_out.i_type) { case X264_TYPE_IDR: @@ -393,6 +410,7 @@ static av_cold int X264_close(AVCodecContext *avctx) av_freep(&avctx->extradata); av_freep(&x4->sei); + av_freep(&x4->reordered_opaque); if (x4->enc) { x264_encoder_close(x4->enc); @@ -846,6 +864,12 @@ FF_ENABLE_DEPRECATION_WARNINGS cpb_props->max_bitrate = x4->params.rc.i_vbv_max_bitrate * 1000; cpb_props->avg_bitrate = x4->params.rc.i_bitrate * 1000; + x4->nb_reordered_opaque = x264_encoder_maximum_delayed_frames(x4->enc) + 1; + x4->reordered_opaque = av_malloc_array(x4->nb_reordered_opaque, + sizeof(*x4->reordered_opaque)); + if (!x4->reordered_opaque) + return AVERROR(ENOMEM); + return 0; } @@ -1059,7 +1083,8 @@ AVCodec ff_libx264_encoder = { .init = X264_init, .encode2 = X264_frame, .close = X264_close, - .capabilities = AV_CODEC_CAP_DELAY | AV_CODEC_CAP_AUTO_THREADS, + .capabilities = AV_CODEC_CAP_DELAY | AV_CODEC_CAP_AUTO_THREADS | + AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE, .priv_class = &x264_class, .defaults = x264_defaults, .init_static_data = X264_init_static, @@ -1085,7 +1110,8 @@ AVCodec ff_libx264rgb_encoder = { .init = X264_init, .encode2 = X264_frame, .close = X264_close, - .capabilities = AV_CODEC_CAP_DELAY | AV_CODEC_CAP_AUTO_THREADS, + .capabilities = AV_CODEC_CAP_DELAY | AV_CODEC_CAP_AUTO_THREADS | + AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE, .priv_class = &rgbclass, .defaults = x264_defaults, .pix_fmts = pix_fmts_8bit_rgb, @@ -1110,7 +1136,8 @@ AVCodec ff_libx262_encoder = { .init = X264_init, .encode2 = X264_frame, .close = X264_close, - .capabilities = AV_CODEC_CAP_DELAY | AV_CODEC_CAP_AUTO_THREADS, + .capabilities = AV_CODEC_CAP_DELAY | AV_CODEC_CAP_AUTO_THREADS | + AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE, .priv_class = &X262_class, .defaults = x264_defaults, .pix_fmts = pix_fmts_8bit, diff --git a/libavcodec/version.h b/libavcodec/version.h index 9098882f47..91809641b4 100644 --- a/libavcodec/version.h +++ b/libavcodec/version.h @@ -28,8 +28,8 @@ #include "libavutil/version.h" #define LIBAVCODEC_VERSION_MAJOR 58 -#define LIBAVCODEC_VERSION_MINOR 33 -#define LIBAVCODEC_VERSION_MICRO 102 +#define LIBAVCODEC_VERSION_MINOR 34 +#define LIBAVCODEC_VERSION_MICRO 100 #define LIBAVCODEC_VERSION_INT AV_VERSION_INT(LIBAVCODEC_VERSION_MAJOR, \ LIBAVCODEC_VERSION_MINOR, \