From patchwork Tue Jan 9 17:06:12 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jorge Ramirez-Ortiz X-Patchwork-Id: 7230 Delivered-To: ffmpegpatchwork@gmail.com Received: by 10.2.78.2 with SMTP id r2csp4164073jaa; Tue, 9 Jan 2018 09:13:00 -0800 (PST) X-Google-Smtp-Source: ACJfBoudDjTsnwR5gBBSywfi1u9wOinWAbA9Z78VmuaJSFguXntkV4Riep637AKVnT/1dvH118/k X-Received: by 10.223.134.125 with SMTP id 58mr14453543wrw.224.1515517980489; Tue, 09 Jan 2018 09:13:00 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1515517980; cv=none; d=google.com; s=arc-20160816; b=TsNFP0yJwtm8Oa7gYiowT++//W3RBnrczlOQiLFVvT71fYtErFByZbVRlQEil+DBKs ehR1TxyVkJdJev1jz1cMOvvcV7GghBhOS8wfrMmzQ46+Eq3vDDWrb+JdQVYvLd64i7cB L4uFARslI62TSTGoz7Ot9K6Ri/bQTzzNdVjt1JObdHVYvG6VomRWdTSRv77z1gzV9t8K YZbDjCVuHqldWL2UbiMpCDNliNXV6RrdpNjIvxBu9cTNsxMooNrwoLm6jyh1HfgxDAb2 njvdY6n2V1vXk4uAEBIFfGlbZQZlEH3dhXSeU4fBucxmR183TmxTK4I/C7dWZkE6w7Ds pm3w== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:content-transfer-encoding:mime-version:cc:reply-to :list-subscribe:list-help:list-post:list-archive:list-unsubscribe :list-id:precedence:subject:references:in-reply-to:message-id:date :to:from:dkim-signature:delivered-to:arc-authentication-results; bh=kiYGz5eI1Iikr9iPMQA4dYabounVQwT1enWmAN4GDC0=; b=wOp3X6T49FvCxdHDleUYjC5sgl0MWIDN0SJJ+71fL1r9BJjpnzFp6YPpqoPnPr8r2a bAEcYSKjOhWkszgFs/Katy2WeUY5L23mrblsRxWCuomd8M5hIdUw98hbFHVDqOTWDCDb WEq7kYW66BHlCJjhi+dc7XXwniktinCFzbASa/BRGa9mKzkFJZucPtX67l+il11BhUVg idN5TvFyAt7i/zttzUwiCB6z7UP5VHyLM76MACKXFk8/i7LfhidsbN9XVRjW2CMVRCsO 6HO/ferUyCcHZUTZIKXvwCGY4MqvJG6gvjdI2yUOSUgE2eo9/OvV0bXFxLl+ww8AmRc/ L26A== ARC-Authentication-Results: i=1; mx.google.com; dkim=neutral (body hash did not verify) header.i=@gmail.com header.s=20161025 header.b=HWpSsYPs; 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; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=gmail.com Return-Path: Received: from ffbox0-bg.mplayerhq.hu (ffbox0-bg.ffmpeg.org. [79.124.17.100]) by mx.google.com with ESMTP id y72si9641585wmc.111.2018.01.09.09.12.59; Tue, 09 Jan 2018 09:13:00 -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; dkim=neutral (body hash did not verify) header.i=@gmail.com header.s=20161025 header.b=HWpSsYPs; 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; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=gmail.com Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id 21161689F2D; Tue, 9 Jan 2018 19:12:56 +0200 (EET) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from mail-wr0-f195.google.com (mail-wr0-f195.google.com [209.85.128.195]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id 54DB5689BDC for ; Tue, 9 Jan 2018 19:12:49 +0200 (EET) Received: by mail-wr0-f195.google.com with SMTP id n9so4992954wrg.2 for ; Tue, 09 Jan 2018 09:12:50 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=maZnbWeTrTcvsZNDfSPjduAlMooal8cwogSeiuEBnCo=; b=HWpSsYPsLVWeRoarIYICwAeLgEP6rRXadGiHITf+4JGzBSnI4e53Ueo1kPycK9Wmx8 QI19pDXfH3gjIu6ScRM29MROQf9UFJwgXvlIgrmOuWR1ueGOTli8dZhQXqx3xKjXibiU 5LX3jHxTY50inxZva35X0jKJ5I4WelmYhjNyxMCSMzrpRgp6dizMpCkuXgf9og78INGD yIT+wI1BmzVEN4MJ00ywIG2lhoxckmYweykbnPaEoFgoD5EsPJ19ipYB+eOzpiH07QvV moQ+OyZeqqRAWZGzZQQwGDiWnTMChz4X7P6ukGPxnmeTI9POB38QvmKqdyjkEN96bpED lqtA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=maZnbWeTrTcvsZNDfSPjduAlMooal8cwogSeiuEBnCo=; b=AnjxyHl74wRfOqJwQiSf+XXXEMrwg2jl0XcwRFSUIkzmL5bUMICMHs8+/PUutRuvnO PDXGEw0SPBHMklwlLyr4KKk8QrR+hsXO3ZTdTzM30SraX3PDpCHqxP3LS/C1OmZ+siaN uiA7UGoyVrQTd0du9xD0fdocoHjDosH+DE6pe2Mjz5b1VKJ9BBrs0wjjBaVZ/wSjhHKb apMpK6VGneFD+2vbwKp8yvaKS4rcB+eUL6QUHj/x5TMy9aKqVdBkrsrf857++8uGhQPZ CTw6CkQC3yK0JmvWwxlFy2d6byURi/LBRXq9AdXfQsmwrghSo9Sz6iseHoT+xJhVwDDz LutQ== X-Gm-Message-State: AKGB3mLDqBXf+Y6hSXPV3gq9H3ClnEpyCw6Ege5q1xtzfsbNahbVjrVz f3uNhjvGEwIsveWNUaNXBZM= X-Received: by 10.223.187.75 with SMTP id x11mr14144186wrg.77.1515517580106; Tue, 09 Jan 2018 09:06:20 -0800 (PST) Received: from igloo.80.58.61.254 (141.pool85-51-114.dynamic.orange.es. [85.51.114.141]) by smtp.gmail.com with ESMTPSA id 11sm1703018wmd.33.2018.01.09.09.06.18 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Tue, 09 Jan 2018 09:06:19 -0800 (PST) From: Jorge Ramirez-Ortiz To: jorge.ramirez.ortiz@gmail.com, ffmpeg-devel@ffmpeg.org Date: Tue, 9 Jan 2018 18:06:12 +0100 Message-Id: <1515517573-27292-2-git-send-email-jorge.ramirez.ortiz@gmail.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1515517573-27292-1-git-send-email-jorge.ramirez.ortiz@gmail.com> References: <1515517573-27292-1-git-send-email-jorge.ramirez.ortiz@gmail.com> Subject: [FFmpeg-devel] [PATCH 2/3] avcodec: v4l2_m2m: remove unnecessary timeout. 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, sw@jkqxz.net, nfxjfg@googlemail.com MIME-Version: 1.0 Errors-To: ffmpeg-devel-bounces@ffmpeg.org Sender: "ffmpeg-devel" From: Jorge Ramirez-Ortiz Qualcomm's db410c/db820 Venus driver currently present in mainline kernel has a bug which mishandles the CMD_STOP requests causing the decoder to block while draining [1]. This patch removes the workaround that was used to prevent that situation. Encoding/Decoding tested on db820c. [1] on CMD_STOP, the driver is flushing all buffers and never raising IPIPE which ends up in blocking on poll. --- libavcodec/v4l2_buffers.c | 10 ++++++++-- libavcodec/v4l2_context.c | 48 +++++++++++++++++++++++------------------------ libavcodec/v4l2_m2m_dec.c | 14 +++++++++++--- libavcodec/v4l2_m2m_enc.c | 14 +++++++++++--- 4 files changed, 54 insertions(+), 32 deletions(-) diff --git a/libavcodec/v4l2_buffers.c b/libavcodec/v4l2_buffers.c index 4e68f90..8e4d4d1 100644 --- a/libavcodec/v4l2_buffers.c +++ b/libavcodec/v4l2_buffers.c @@ -213,8 +213,14 @@ static void v4l2_free_buffer(void *opaque, uint8_t *unused) if (s->reinit) { if (!atomic_load(&s->refcount)) sem_post(&s->refsync); - } else if (avbuf->context->streamon) - ff_v4l2_buffer_enqueue(avbuf); + } else { + if (s->draining) { + /* no need to queue more buffers to the driver */ + avbuf->status = V4L2BUF_AVAILABLE; + } + else if (avbuf->context->streamon) + ff_v4l2_buffer_enqueue(avbuf); + } av_buffer_unref(&avbuf->context_ref); } diff --git a/libavcodec/v4l2_context.c b/libavcodec/v4l2_context.c index 4c16992..fb482cf 100644 --- a/libavcodec/v4l2_context.c +++ b/libavcodec/v4l2_context.c @@ -217,6 +217,7 @@ static int v4l2_stop_decode(V4L2Context *ctx) { struct v4l2_decoder_cmd cmd = { .cmd = V4L2_DEC_CMD_STOP, + .flags = 0, }; int ret; @@ -234,6 +235,7 @@ static int v4l2_stop_encode(V4L2Context *ctx) { struct v4l2_encoder_cmd cmd = { .cmd = V4L2_ENC_CMD_STOP, + .flags = 0, }; int ret; @@ -260,6 +262,11 @@ static V4L2Buffer* v4l2_dequeue_v4l2buf(V4L2Context *ctx, int timeout) if (V4L2_TYPE_IS_OUTPUT(ctx->type)) pfd.events = POLLOUT | POLLWRNORM; + else { + /* no need to listen to requests for more input while draining */ + if (ctx_to_m2mctx(ctx)->draining) + pfd.events = POLLIN | POLLRDNORM | POLLPRI; + } for (;;) { ret = poll(&pfd, 1, timeout); @@ -267,11 +274,6 @@ static V4L2Buffer* v4l2_dequeue_v4l2buf(V4L2Context *ctx, int timeout) break; if (errno == EINTR) continue; - - /* timeout is being used to indicate last valid bufer when draining */ - if (ctx_to_m2mctx(ctx)->draining) - ctx->done = 1; - return NULL; } @@ -286,7 +288,7 @@ static V4L2Buffer* v4l2_dequeue_v4l2buf(V4L2Context *ctx, int timeout) ret = v4l2_handle_event(ctx); if (ret < 0) { /* if re-init failed, abort */ - ctx->done = EINVAL; + ctx->done = 1; return NULL; } if (ret) { @@ -325,23 +327,25 @@ dequeue: ret = ioctl(ctx_to_m2mctx(ctx)->fd, VIDIOC_DQBUF, &buf); if (ret) { if (errno != EAGAIN) { - ctx->done = errno; + ctx->done = 1; if (errno != EPIPE) av_log(logger(ctx), AV_LOG_DEBUG, "%s VIDIOC_DQBUF, errno (%s)\n", ctx->name, av_err2str(AVERROR(errno))); } - } else { - avbuf = &ctx->buffers[buf.index]; - avbuf->status = V4L2BUF_AVAILABLE; - avbuf->buf = buf; - if (V4L2_TYPE_IS_MULTIPLANAR(ctx->type)) { - memcpy(avbuf->planes, planes, sizeof(planes)); - avbuf->buf.m.planes = avbuf->planes; - } + return NULL; + } + + avbuf = &ctx->buffers[buf.index]; + avbuf->status = V4L2BUF_AVAILABLE; + avbuf->buf = buf; + if (V4L2_TYPE_IS_MULTIPLANAR(ctx->type)) { + memcpy(avbuf->planes, planes, sizeof(planes)); + avbuf->buf.m.planes = avbuf->planes; } + return avbuf; } - return avbuf; + return NULL; } static V4L2Buffer* v4l2_getfree_v4l2buf(V4L2Context *ctx) @@ -552,14 +556,12 @@ int ff_v4l2_context_dequeue_frame(V4L2Context* ctx, AVFrame* frame) { V4L2Buffer* avbuf = NULL; - /* if we are draining, we are no longer inputing data, therefore enable a - * timeout so we can dequeue and flag the last valid buffer. - * + /* * blocks until: * 1. decoded frame available * 2. an input buffer is ready to be dequeued */ - avbuf = v4l2_dequeue_v4l2buf(ctx, ctx_to_m2mctx(ctx)->draining ? 200 : -1); + avbuf = v4l2_dequeue_v4l2buf(ctx, -1); if (!avbuf) { if (ctx->done) return AVERROR_EOF; @@ -574,14 +576,12 @@ int ff_v4l2_context_dequeue_packet(V4L2Context* ctx, AVPacket* pkt) { V4L2Buffer* avbuf = NULL; - /* if we are draining, we are no longer inputing data, therefore enable a - * timeout so we can dequeue and flag the last valid buffer. - * + /* * blocks until: * 1. encoded packet available * 2. an input buffer ready to be dequeued */ - avbuf = v4l2_dequeue_v4l2buf(ctx, ctx_to_m2mctx(ctx)->draining ? 200 : -1); + avbuf = v4l2_dequeue_v4l2buf(ctx, -1); if (!avbuf) { if (ctx->done) return AVERROR_EOF; diff --git a/libavcodec/v4l2_m2m_dec.c b/libavcodec/v4l2_m2m_dec.c index bca45be..34d1f9c 100644 --- a/libavcodec/v4l2_m2m_dec.c +++ b/libavcodec/v4l2_m2m_dec.c @@ -131,14 +131,22 @@ static int v4l2_receive_frame(AVCodecContext *avctx, AVFrame *frame) V4L2Context *const capture = &s->capture; V4L2Context *const output = &s->output; AVPacket avpkt = {0}; - int ret; + int i, ret; ret = ff_decode_get_packet(avctx, &avpkt); if (ret < 0 && ret != AVERROR_EOF) return ret; - if (s->draining) - goto dequeue; + if (s->draining) { + for (i = 0; i < capture->num_buffers; i++) { + if (capture->buffers[i].status == V4L2BUF_IN_DRIVER) + goto dequeue; + } + + /* no more buffers in the driver, we are done */ + capture->done = 1; + return AVERROR_EOF; + } ret = ff_v4l2_context_enqueue_packet(output, &avpkt); if (ret < 0) { diff --git a/libavcodec/v4l2_m2m_enc.c b/libavcodec/v4l2_m2m_enc.c index 4c9ea1f..3d7c241 100644 --- a/libavcodec/v4l2_m2m_enc.c +++ b/libavcodec/v4l2_m2m_enc.c @@ -253,10 +253,18 @@ static int v4l2_receive_packet(AVCodecContext *avctx, AVPacket *avpkt) V4L2m2mContext *s = ((V4L2m2mPriv*)avctx->priv_data)->context; V4L2Context *const capture = &s->capture; V4L2Context *const output = &s->output; - int ret; + int i, ret; + + if (s->draining) { + for (i = 0; i < capture->num_buffers; i++) { + if (capture->buffers[i].status == V4L2BUF_IN_DRIVER) + goto dequeue; + } - if (s->draining) - goto dequeue; + /* no more buffers in the driver, we are done */ + capture->done = 1; + return AVERROR_EOF; + } if (!output->streamon) { ret = ff_v4l2_context_set_status(output, VIDIOC_STREAMON);