From patchwork Tue Sep 3 01:02:12 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Aman Karmani X-Patchwork-Id: 14872 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 BF40B449E21 for ; Tue, 3 Sep 2019 04:09:00 +0300 (EEST) Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id A66F7687FF5; Tue, 3 Sep 2019 04:09:00 +0300 (EEST) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from mail-ot1-f65.google.com (mail-ot1-f65.google.com [209.85.210.65]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id 0080C687FB7 for ; Tue, 3 Sep 2019 04:08:53 +0300 (EEST) Received: by mail-ot1-f65.google.com with SMTP id 90so11186552otg.10 for ; Mon, 02 Sep 2019 18:08:53 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=tmm1-net.20150623.gappssmtp.com; s=20150623; h=sender:from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=ZqxAT+IFU+9L1cjIWVJNgQnlDkAAbhUtVN7rrz7tG+k=; b=AXkZb6RDgbELp03tkdOfJ8kpaC54VOSM814M2xjJY78CXui2tlGiSksZSpbw2131/l LnA+W2NDuW5IWAOE6troudoaXF04BI4oYv8X9RBnWiZEBFk7ORW8hEtC+R7pATl5B4Iy a3ouez7WezMOk2//7vGQEbr0tPENoWRRonI7w8gvKiqVA1vhgtchR5Kmt6np0dFB2P4T mIy7U37wQ7VqmTXWTwAsAzCzDjNkpLCItSLQNB2G2FBCceFW5/OiDFlnLh9hQty+9uYi V07BCzYxCjO7yaMrRer/AlVoMhEiLZ0fbAErwj4FB6WhrzvaOV9DjbxFJeHecx94lcuS wxrg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:sender:from:to:cc:subject:date:message-id :in-reply-to:references:mime-version:content-transfer-encoding; bh=ZqxAT+IFU+9L1cjIWVJNgQnlDkAAbhUtVN7rrz7tG+k=; b=Wj9bRMvC53cSP7VMJpaqr/+Lcmjc5FTD+kvMbZ/NEIs6k0XUzCd56W1Fw2+nA48uZb xz+H3Zao/He68NM2K+ROvYk9ypIUKguRlO72/rALW1o24c1yhMoSjCIqR5RgIXoLaaXG SNwjUh4s0AP+6SGLqJqEc7vrm3ot5dwmJC2OapqrLR4V8m3wPwtk7v2gu5EG/UUJUfhV X+wPstcoCyjbwHl4fT3YICWbGiT+Xrv+YzkkGQqSg0f3H4tVGhRd0iDRsA3RnSjMxnjc BxAl39S7VTMmec5utRmGkqf5JU/yqmbJHGkcsnP4VW0hzIxA03+34xY2iy2u4gtgIB9M jJvA== X-Gm-Message-State: APjAAAUDm7jbe4cQwt8wnqEqGjLz+SlbLRZG2ikTkZJMjvelFoROm2FS WOxHjIYihV0hvfzabS6WmdsHpPz/IpY= X-Google-Smtp-Source: APXvYqxOtpdukXV36Ca/cPsz4QgGGmBqRMZKRQufapRs/QTlNXItTVH7et0KzvvGQku75Mg4YNmjtQ== X-Received: by 2002:a05:6830:15cc:: with SMTP id j12mr24886175otr.64.1567472579969; Mon, 02 Sep 2019 18:02:59 -0700 (PDT) Received: from tmm1-imac.lan (ip184-189-221-177.sb.sd.cox.net. [184.189.221.177]) by smtp.gmail.com with ESMTPSA id a21sm4299633oie.9.2019.09.02.18.02.58 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Mon, 02 Sep 2019 18:02:59 -0700 (PDT) From: Aman Gupta To: ffmpeg-devel@ffmpeg.org Date: Mon, 2 Sep 2019 18:02:12 -0700 Message-Id: <20190903010230.96236-8-ffmpeg@tmm1.net> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20190903010230.96236-1-ffmpeg@tmm1.net> References: <20190903010230.96236-1-ffmpeg@tmm1.net> MIME-Version: 1.0 Subject: [FFmpeg-devel] [PATCH 07/25] avcodec/v4l2_m2m: decouple v4l2_m2m helpers from AVCodecContext 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: lorusak@gmail.com, Aman Gupta , jorge.ramirez.ortiz@gmail.com, Aman Gupta Errors-To: ffmpeg-devel-bounces@ffmpeg.org Sender: "ffmpeg-devel" From: Aman Gupta This will allow re-use of the m2m backend with AVFilterContext Signed-off-by: Aman Gupta --- libavcodec/v4l2_context.c | 9 +++---- libavcodec/v4l2_m2m.c | 50 +++++++++++++++++++-------------------- libavcodec/v4l2_m2m.h | 18 +++++++------- libavcodec/v4l2_m2m_dec.c | 14 +++++++---- libavcodec/v4l2_m2m_enc.c | 13 +++++++--- 5 files changed, 60 insertions(+), 44 deletions(-) diff --git a/libavcodec/v4l2_context.c b/libavcodec/v4l2_context.c index 90356bb740..b02142a5d6 100644 --- a/libavcodec/v4l2_context.c +++ b/libavcodec/v4l2_context.c @@ -48,9 +48,9 @@ static inline V4L2m2mContext *ctx_to_m2mctx(V4L2Context *ctx) container_of(ctx, V4L2m2mContext, capture); } -static inline AVCodecContext *logger(V4L2Context *ctx) +static inline AVClass *logger(V4L2Context *ctx) { - return ctx_to_m2mctx(ctx)->avctx; + return ctx_to_m2mctx(ctx)->priv; } static inline unsigned int v4l2_get_width(struct v4l2_format *fmt) @@ -96,7 +96,7 @@ static inline int v4l2_get_framesize_compressed(V4L2Context* ctx, int width, int const int SZ_4K = 0x1000; int size; - if (av_codec_is_decoder(s->avctx->codec)) + if (s->avctx && av_codec_is_decoder(s->avctx->codec)) return ((width * height * 3 / 2) / 2) + 128; /* encoder */ @@ -193,7 +193,8 @@ static int v4l2_handle_event(V4L2Context *ctx) } if (reinit) { - ret = ff_set_dimensions(s->avctx, s->capture.width, s->capture.height); + if (s->avctx) + ret = ff_set_dimensions(s->avctx, s->capture.width, s->capture.height); if (ret < 0) av_log(logger(ctx), AV_LOG_WARNING, "update avcodec height and width\n"); diff --git a/libavcodec/v4l2_m2m.c b/libavcodec/v4l2_m2m.c index 827662b9a5..358f587797 100644 --- a/libavcodec/v4l2_m2m.c +++ b/libavcodec/v4l2_m2m.c @@ -63,6 +63,7 @@ static inline int v4l2_mplane_video(struct v4l2_capability *cap) static int v4l2_prepare_contexts(V4L2m2mContext* s, int probe) { struct v4l2_capability cap; + void *log_ctx = s->priv; int ret; s->capture.done = s->output.done = 0; @@ -76,7 +77,7 @@ static int v4l2_prepare_contexts(V4L2m2mContext* s, int probe) if (ret < 0) return ret; - av_log(s->avctx, probe ? AV_LOG_DEBUG : AV_LOG_INFO, + av_log(log_ctx, probe ? AV_LOG_DEBUG : AV_LOG_INFO, "driver '%s' on card '%s' in %s mode\n", cap.driver, cap.card, v4l2_mplane_video(&cap) ? "mplane" : v4l2_splane_video(&cap) ? "splane" : "unknown"); @@ -98,6 +99,7 @@ static int v4l2_prepare_contexts(V4L2m2mContext* s, int probe) static int v4l2_probe_driver(V4L2m2mContext* s) { + void *log_ctx = s->priv; int ret; s->fd = open(s->devname, O_RDWR | O_NONBLOCK, 0); @@ -110,20 +112,20 @@ static int v4l2_probe_driver(V4L2m2mContext* s) ret = ff_v4l2_context_get_format(&s->output, 1); if (ret) { - av_log(s->avctx, AV_LOG_DEBUG, "v4l2 output format not supported\n"); + av_log(log_ctx, AV_LOG_DEBUG, "v4l2 output format not supported\n"); goto done; } ret = ff_v4l2_context_get_format(&s->capture, 1); if (ret) { - av_log(s->avctx, AV_LOG_DEBUG, "v4l2 capture format not supported\n"); + av_log(log_ctx, AV_LOG_DEBUG, "v4l2 capture format not supported\n"); goto done; } done: if (close(s->fd) < 0) { ret = AVERROR(errno); - av_log(s->avctx, AV_LOG_ERROR, "failure closing %s (%s)\n", s->devname, av_err2str(AVERROR(errno))); + av_log(log_ctx, AV_LOG_ERROR, "failure closing %s (%s)\n", s->devname, av_err2str(AVERROR(errno))); } s->fd = -1; @@ -133,7 +135,7 @@ done: static int v4l2_configure_contexts(V4L2m2mContext* s) { - void *log_ctx = s->avctx; + void *log_ctx = s->priv; int ret; struct v4l2_format ofmt, cfmt; @@ -174,7 +176,7 @@ static int v4l2_configure_contexts(V4L2m2mContext* s) } /* decoder's buffers need to be updated at a later stage */ - if (!av_codec_is_decoder(s->avctx->codec)) { + if (!s->avctx || !av_codec_is_decoder(s->avctx->codec)) { ret = ff_v4l2_context_init(&s->capture); if (ret) { av_log(log_ctx, AV_LOG_ERROR, "no v4l2 capture context's buffers\n"); @@ -202,20 +204,21 @@ error: ******************************************************************************/ int ff_v4l2_m2m_codec_reinit(V4L2m2mContext* s) { + void *log_ctx = s->priv; int ret; - av_log(s->avctx, AV_LOG_DEBUG, "reinit context\n"); + av_log(log_ctx, AV_LOG_DEBUG, "reinit context\n"); /* 1. streamoff */ ret = ff_v4l2_context_set_status(&s->capture, VIDIOC_STREAMOFF); if (ret) - av_log(s->avctx, AV_LOG_ERROR, "capture VIDIOC_STREAMOFF\n"); + av_log(log_ctx, AV_LOG_ERROR, "capture VIDIOC_STREAMOFF\n"); /* 2. unmap the capture buffers (v4l2 and ffmpeg): * we must wait for all references to be released before being allowed * to queue new buffers. */ - av_log(s->avctx, AV_LOG_DEBUG, "waiting for user to release AVBufferRefs\n"); + av_log(log_ctx, AV_LOG_DEBUG, "waiting for user to release AVBufferRefs\n"); if (atomic_load(&s->refcount)) while(sem_wait(&s->refsync) == -1 && errno == EINTR); @@ -224,14 +227,14 @@ int ff_v4l2_m2m_codec_reinit(V4L2m2mContext* s) /* 3. get the new capture format */ ret = ff_v4l2_context_get_format(&s->capture, 0); if (ret) { - av_log(s->avctx, AV_LOG_ERROR, "query the new capture format\n"); + av_log(log_ctx, AV_LOG_ERROR, "query the new capture format\n"); return ret; } /* 4. set the capture format */ ret = ff_v4l2_context_set_format(&s->capture); if (ret) { - av_log(s->avctx, AV_LOG_ERROR, "setting capture format\n"); + av_log(log_ctx, AV_LOG_ERROR, "setting capture format\n"); return ret; } @@ -304,7 +307,7 @@ int ff_v4l2_m2m_codec_full_reinit(V4L2m2mContext *s) } /* decoder's buffers need to be updated at a later stage */ - if (!av_codec_is_decoder(s->avctx->codec)) { + if (!s->avctx || !av_codec_is_decoder(s->avctx->codec)) { ret = ff_v4l2_context_init(&s->capture); if (ret) { av_log(log_ctx, AV_LOG_ERROR, "no v4l2 capture context's buffers\n"); @@ -330,19 +333,18 @@ static void v4l2_m2m_destroy_context(void *opaque, uint8_t *context) av_free(s); } -int ff_v4l2_m2m_codec_end(AVCodecContext *avctx) +int ff_v4l2_m2m_codec_end(V4L2m2mPriv *priv) { - V4L2m2mPriv *priv = avctx->priv_data; V4L2m2mContext* s = priv->context; int ret; ret = ff_v4l2_context_set_status(&s->output, VIDIOC_STREAMOFF); if (ret) - av_log(avctx, AV_LOG_ERROR, "VIDIOC_STREAMOFF %s\n", s->output.name); + av_log(priv, AV_LOG_ERROR, "VIDIOC_STREAMOFF %s\n", s->output.name); ret = ff_v4l2_context_set_status(&s->capture, VIDIOC_STREAMOFF); if (ret) - av_log(avctx, AV_LOG_ERROR, "VIDIOC_STREAMOFF %s\n", s->capture.name); + av_log(priv, AV_LOG_ERROR, "VIDIOC_STREAMOFF %s\n", s->capture.name); ff_v4l2_context_release(&s->output); @@ -352,15 +354,14 @@ int ff_v4l2_m2m_codec_end(AVCodecContext *avctx) return 0; } -int ff_v4l2_m2m_codec_init(AVCodecContext *avctx) +int ff_v4l2_m2m_codec_init(V4L2m2mPriv *priv) { int ret = AVERROR(EINVAL); struct dirent *entry; char node[PATH_MAX]; DIR *dirp; - V4L2m2mContext *s = ((V4L2m2mPriv*)avctx->priv_data)->context; - s->avctx = avctx; + V4L2m2mContext *s = priv->context; dirp = opendir("/dev"); if (!dirp) @@ -372,7 +373,7 @@ int ff_v4l2_m2m_codec_init(AVCodecContext *avctx) continue; snprintf(node, sizeof(node), "/dev/%s", entry->d_name); - av_log(s->avctx, AV_LOG_DEBUG, "probing device %s\n", node); + av_log(priv, AV_LOG_DEBUG, "probing device %s\n", node); strncpy(s->devname, node, strlen(node) + 1); ret = v4l2_probe_driver(s); if (!ret) @@ -382,21 +383,19 @@ int ff_v4l2_m2m_codec_init(AVCodecContext *avctx) closedir(dirp); if (ret) { - av_log(s->avctx, AV_LOG_ERROR, "Could not find a valid device\n"); + av_log(priv, AV_LOG_ERROR, "Could not find a valid device\n"); memset(s->devname, 0, sizeof(s->devname)); return ret; } - av_log(s->avctx, AV_LOG_INFO, "Using device %s\n", node); + av_log(priv, AV_LOG_INFO, "Using device %s\n", node); return v4l2_configure_contexts(s); } -int ff_v4l2_m2m_create_context(AVCodecContext *avctx, V4L2m2mContext **s) +int ff_v4l2_m2m_create_context(V4L2m2mPriv *priv, V4L2m2mContext **s) { - V4L2m2mPriv *priv = avctx->priv_data; - *s = av_mallocz(sizeof(V4L2m2mContext)); if (!*s) return AVERROR(ENOMEM); @@ -410,6 +409,7 @@ int ff_v4l2_m2m_create_context(AVCodecContext *avctx, V4L2m2mContext **s) /* assign the context */ priv->context = *s; + (*s)->priv = priv; /* populate it */ priv->context->capture.num_buffers = priv->num_capture_buffers; diff --git a/libavcodec/v4l2_m2m.h b/libavcodec/v4l2_m2m.h index 0d4671beb1..c860e96ef5 100644 --- a/libavcodec/v4l2_m2m.h +++ b/libavcodec/v4l2_m2m.h @@ -59,10 +59,12 @@ typedef struct V4L2m2mContext { /* Reference to self; only valid while codec is active. */ AVBufferRef *self_ref; + + /* reference back to V4L2m2mPriv */ + void *priv; } V4L2m2mContext; -typedef struct V4L2m2mPriv -{ +typedef struct V4L2m2mPriv { AVClass *class; V4L2m2mContext *context; @@ -75,33 +77,33 @@ typedef struct V4L2m2mPriv /** * Allocate a new context and references for a V4L2 M2M instance. * - * @param[in] ctx The AVCodecContext instantiated by the encoder/decoder. + * @param[in] ctx The V4L2m2mPriv instantiated by the encoder/decoder. * @param[out] ctx The V4L2m2mContext. * * @returns 0 in success, a negative error code otherwise. */ -int ff_v4l2_m2m_create_context(AVCodecContext *avctx, V4L2m2mContext **s); +int ff_v4l2_m2m_create_context(V4L2m2mPriv *priv, V4L2m2mContext **s); /** * Probes the video nodes looking for the required codec capabilities. * - * @param[in] ctx The AVCodecContext instantiated by the encoder/decoder. + * @param[in] ctx The V4L2m2mPriv instantiated by the encoder/decoder. * * @returns 0 if a driver is found, a negative number otherwise. */ -int ff_v4l2_m2m_codec_init(AVCodecContext *avctx); +int ff_v4l2_m2m_codec_init(V4L2m2mPriv *priv); /** * Releases all the codec resources if all AVBufferRefs have been returned to the * ctx. Otherwise keep the driver open. * - * @param[in] The AVCodecContext instantiated by the encoder/decoder. + * @param[in] The V4L2m2mPriv instantiated by the encoder/decoder. * * @returns 0 * */ -int ff_v4l2_m2m_codec_end(AVCodecContext *avctx); +int ff_v4l2_m2m_codec_end(V4L2m2mPriv *priv); /** * Reinitializes the V4L2m2mContext when the driver cannot continue processing diff --git a/libavcodec/v4l2_m2m_dec.c b/libavcodec/v4l2_m2m_dec.c index 5fb8ddd542..596e435463 100644 --- a/libavcodec/v4l2_m2m_dec.c +++ b/libavcodec/v4l2_m2m_dec.c @@ -169,9 +169,10 @@ static av_cold int v4l2_decode_init(AVCodecContext *avctx) { V4L2Context *capture, *output; V4L2m2mContext *s; + V4L2m2mPriv *priv = avctx->priv_data; int ret; - ret = ff_v4l2_m2m_create_context(avctx, &s); + ret = ff_v4l2_m2m_create_context(priv, &s); if (ret < 0) return ret; @@ -191,19 +192,24 @@ static av_cold int v4l2_decode_init(AVCodecContext *avctx) capture->av_codec_id = AV_CODEC_ID_RAWVIDEO; capture->av_pix_fmt = avctx->pix_fmt; - ret = ff_v4l2_m2m_codec_init(avctx); + ret = ff_v4l2_m2m_codec_init(priv); if (ret) { - V4L2m2mPriv *priv = avctx->priv_data; av_log(avctx, AV_LOG_ERROR, "can't configure decoder\n"); s->self_ref = NULL; av_buffer_unref(&priv->context_ref); return ret; } + s->avctx = avctx; return v4l2_prepare_decoder(s); } +static av_cold int v4l2_decode_close(AVCodecContext *avctx) +{ + return ff_v4l2_m2m_codec_end(avctx->priv_data); +} + #define OFFSET(x) offsetof(V4L2m2mPriv, x) #define FLAGS AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_DECODING_PARAM @@ -231,7 +237,7 @@ AVCodec ff_ ## NAME ## _v4l2m2m_decoder = { \ .priv_class = &v4l2_m2m_ ## NAME ## _dec_class,\ .init = v4l2_decode_init,\ .receive_frame = v4l2_receive_frame,\ - .close = ff_v4l2_m2m_codec_end,\ + .close = v4l2_decode_close,\ .bsfs = bsf_name, \ .capabilities = AV_CODEC_CAP_HARDWARE | AV_CODEC_CAP_DELAY | \ AV_CODEC_CAP_AVOID_PROBING, \ diff --git a/libavcodec/v4l2_m2m_enc.c b/libavcodec/v4l2_m2m_enc.c index a0d5bcf760..8014e442a8 100644 --- a/libavcodec/v4l2_m2m_enc.c +++ b/libavcodec/v4l2_m2m_enc.c @@ -285,9 +285,10 @@ static av_cold int v4l2_encode_init(AVCodecContext *avctx) { V4L2Context *capture, *output; V4L2m2mContext *s; + V4L2m2mPriv *priv = avctx->priv_data; int ret; - ret = ff_v4l2_m2m_create_context(avctx, &s); + ret = ff_v4l2_m2m_create_context(priv, &s); if (ret < 0) return ret; @@ -306,15 +307,21 @@ static av_cold int v4l2_encode_init(AVCodecContext *avctx) capture->av_codec_id = avctx->codec_id; capture->av_pix_fmt = AV_PIX_FMT_NONE; - ret = ff_v4l2_m2m_codec_init(avctx); + ret = ff_v4l2_m2m_codec_init(priv); if (ret) { av_log(avctx, AV_LOG_ERROR, "can't configure encoder\n"); return ret; } + s->avctx = avctx; return v4l2_prepare_encoder(s); } +static av_cold int v4l2_encode_close(AVCodecContext *avctx) +{ + return ff_v4l2_m2m_codec_end(avctx->priv_data); +} + #define OFFSET(x) offsetof(V4L2m2mPriv, x) #define FLAGS AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_ENCODING_PARAM @@ -343,7 +350,7 @@ AVCodec ff_ ## NAME ## _v4l2m2m_encoder = { \ .init = v4l2_encode_init,\ .send_frame = v4l2_send_frame,\ .receive_packet = v4l2_receive_packet,\ - .close = ff_v4l2_m2m_codec_end,\ + .close = v4l2_encode_close,\ .capabilities = AV_CODEC_CAP_HARDWARE | AV_CODEC_CAP_DELAY, \ .wrapper_name = "v4l2m2m", \ };