From patchwork Mon May 12 12:41:48 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Hans Verkuil X-Patchwork-Id: 23890 X-Patchwork-Delegate: hverkuil@xs4all.nl Received: from mail.tu-berlin.de ([130.149.7.33]) by www.linuxtv.org with esmtp (Exim 4.72) (envelope-from ) id 1WjpYb-0000EL-Tq; Mon, 12 May 2014 14:42:13 +0200 X-tubIT-Incoming-IP: 209.132.180.67 Received: from vger.kernel.org ([209.132.180.67]) by mail.tu-berlin.de (exim-4.72/mailfrontend-7) with esmtp id 1WjpYZ-0002Pf-1P; Mon, 12 May 2014 14:42:13 +0200 Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1757629AbaELMmI (ORCPT + 1 other); Mon, 12 May 2014 08:42:08 -0400 Received: from smtp-vbr5.xs4all.nl ([194.109.24.25]:4749 "EHLO smtp-vbr5.xs4all.nl" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1754515AbaELMmH (ORCPT ); Mon, 12 May 2014 08:42:07 -0400 Received: from tschai.lan (173-38-208-169.cisco.com [173.38.208.169]) (authenticated bits=0) by smtp-vbr5.xs4all.nl (8.13.8/8.13.8) with ESMTP id s4CCfwJq025771; Mon, 12 May 2014 14:42:00 +0200 (CEST) (envelope-from hverkuil@xs4all.nl) Received: from [127.0.0.1] (localhost [127.0.0.1]) by tschai.lan (Postfix) with ESMTPSA id 5ED212A19A4; Mon, 12 May 2014 14:41:48 +0200 (CEST) Message-ID: <5370C18C.7040006@xs4all.nl> Date: Mon, 12 May 2014 14:41:48 +0200 From: Hans Verkuil User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:24.0) Gecko/20100101 Icedove/24.4.0 MIME-Version: 1.0 To: Linux Media Mailing List CC: Ryley Angus , "'Keith Pyle'" Subject: [PATCH] hdpvr: fix interrupted recording X-Virus-Scanned: by XS4ALL Virus Scanner Sender: linux-media-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-media@vger.kernel.org X-PMX-Version: 6.0.0.2142326, Antispam-Engine: 2.7.2.2107409, Antispam-Data: 2014.5.12.123319 X-PMX-Spam: Gauge=IIIIIIIII, Probability=9%, Report=' MULTIPLE_RCPTS 0.1, HTML_00_01 0.05, HTML_00_10 0.05, MSGID_ADDED_BY_MTA 0.05, BODY_SIZE_3000_3999 0, BODY_SIZE_5000_LESS 0, BODY_SIZE_7000_LESS 0, URI_ENDS_IN_HTML 0, __ANY_URI 0, __CP_MEDIA_BODY 0, __CP_URI_IN_BODY 0, __CT 0, __CTE 0, __CT_TEXT_PLAIN 0, __FRAUD_BADTHINGS 0, __FRAUD_BODY_WEBMAIL 0, __FRAUD_WEBMAIL 0, __HAS_FROM 0, __HAS_MSGID 0, __HAS_X_MAILING_LIST 0, __MIME_TEXT_ONLY 0, __MIME_VERSION 0, __MOZILLA_MSGID 0, __MOZILLA_USER_AGENT 0, __MULTIPLE_RCPTS_CC_X2 0, __SANE_MSGID 0, __SUBJ_ALPHA_END 0, __SUBJ_ALPHA_NEGATE 0, __TO_MALFORMED_2 0, __URI_NO_WWW 0, __URI_NS , __USER_AGENT 0' Ryley, Keith, can you test this one more time and if it works reply with a 'Tested-by' tag that I can add to the patch? Thanks! Hans This issue was reported by Ryley Angus: I record from my satellite set top box using component video and optical audio input. I basically use "cat /dev/video0 > ~/video.ts” or use dd. The box is set to output audio as AC-3 over optical, but most channels are actually output as stereo PCM. When the channel is changed between a PCM channel and (typically to a movie channel) to a channel utilising AC-3, the HD-PVR stops the recording as the set top box momentarily outputs no audio. Changing between PCM channels doesn't cause any issues. My main problem was that when this happens, cat/dd doesn't actually exit. When going through the hdpvr driver source and the dmesg output, I found the hdpvr driver wasn't actually shutting down the device properly until I manually killed cat/dd. I've seen references to this issue being a hardware issue from as far back as 2010: http://forums.gbpvr.com/showthread.php?46429-HD-PVR-drops-recording-on-channel-change-Hauppauge-says-too-bad . I tracked my issue to the file hdpvr-video.c. Specifically: "if (wait_event_interruptible(dev->wait_data, buf->status = BUFSTAT_READY)) {" (line ~450). The device seems to get stuck waiting for the buffer to become ready. But as far as I can tell, when the channel is changed between a PCM and AC-3 broadcast the buffer status will never actually become ready. Angus provided a hack to fix this, which I've rewritten. Signed-off-by: Hans Verkuil Reported-by: Ryley Angus Tested-by: Ryley Angus --- drivers/media/usb/hdpvr/hdpvr-video.c | 20 +++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/drivers/media/usb/hdpvr/hdpvr-video.c b/drivers/media/usb/hdpvr/hdpvr-video.c index 0500c417..44227da 100644 --- a/drivers/media/usb/hdpvr/hdpvr-video.c +++ b/drivers/media/usb/hdpvr/hdpvr-video.c @@ -454,6 +454,8 @@ static ssize_t hdpvr_read(struct file *file, char __user *buffer, size_t count, if (buf->status != BUFSTAT_READY && dev->status != STATUS_DISCONNECTED) { + int err; + /* return nonblocking */ if (file->f_flags & O_NONBLOCK) { if (!ret) @@ -461,11 +463,23 @@ static ssize_t hdpvr_read(struct file *file, char __user *buffer, size_t count, goto err; } - if (wait_event_interruptible(dev->wait_data, - buf->status == BUFSTAT_READY)) { - ret = -ERESTARTSYS; + err = wait_event_interruptible_timeout(dev->wait_data, + buf->status == BUFSTAT_READY, + msecs_to_jiffies(3000)); + if (err < 0) { + ret = err; goto err; } + if (!err) { + v4l2_dbg(MSG_INFO, hdpvr_debug, &dev->v4l2_dev, + "timeout: restart streaming\n"); + hdpvr_stop_streaming(dev); + err = hdpvr_start_streaming(dev); + if (err) { + ret = err; + goto err; + } + } } if (buf->status != BUFSTAT_READY)