By Date: <-- -->
By Thread: <-- -->

HVR-1300, cx88-blackbird and MythTV



Sebastian Buks wrote:
> I've been hanging around the IRC-channel for some time. Been talking to
> some really friendly and helpful people there. Well, now the time has
> come to post a question here. My problem is that I can't get my
> Hauppauge HVR-1300 to work very well. I know the driver is a bit
> unmature and maybe I should not expect too much at this point, but there
> seems to be cases where they actually have gotten it to work. My main
> concern is to get the analogue part working with blackbird (ie with
> mpeg2-device working) in MythTV. For now when I load the modules I do
> get a /dev/video1 but I can't record a stream from it (cat /dev/video1 >
> test.mpg). The command just says its invalid and MythTV complains it
> can't open it. Permissions is set to 777. I'm running Ubuntu 6.10 with
> 2.6.17 kernel 64bit.
> 
> Anyone heard of a working card under MythTV (Analogue)?

Before I begin, based on the information above it could very well be
that you don't have a (correct) firmware installed for the driver. Make
sure you have the same encoder firmware that the ivtv driver uses, and
make sure your file is 256KB (and make sure your hotplug setup works for
loading firmware). 'dmesg' should help a lot to see where you are on
that front.

If you can't even get any mpeg data from the mpeg device yet, trying in
mythtv is pointless, you should then first figure out what is missing in
your setup and/or in the driver support for your particular card...

Oh, and I don't know if anybody ever tested it in 64bit mode, so maybe
it helps to try in 32bit mode first... I don't have a 64bit machine for
my grabber cards.

I'm (still) using the PVR-416 myself, in mythtv, but with some patches
and still some open issues...

(I'm not sure if/how the stuff below applies to other blackbird cards)...

First, I'm using the attached mute.diff that unmutes the audio when the
stream is started. Not all cards do their audio the same way, so I'm not
sure if this patch hurts any of them (if it doesn't, then I guess I
should submit it for the official v4l tree).

Second, I'm using the attached startread.diff that starts the mpeg
encoder when the reading starts (in the regular driver, the mpeg encoder
is started when the device is opened). I had to increase the timeout
from 0.5s to 2s for this patch (because it takes quite a while between
starting the mpeg encoder and receiving of the first data from it). I'm
not really sure this patch is needed, but because I made it while trying
to find out more about the issue below, and it does seem more correct
(smaller chance of missing mpeg packets from the beginning of the
stream). The patch is not completely 'clean', as in in contains changes
that I've been trying for the issue below, but may not be necessary (and
don't fix the issue below either...).

Third, there still seems to be something going wrong right after a
channel change: Sometimes the audio is very bad but not always,
sometimes it's perfectly fine. When it's wrong it sounds like it has a
tremendous amount of aliasing, so maybe it's a sampling rate mismatch
somewhere (but since Conexant never gave us any datasheets/data on
blackbird, it's all guesswork and a lot of trial and error to find out
what is going on...) So for now I use the attached libmythtv.diff patch
to the mpegrecorder.cpp (mythtv trunk/0.20) that sleeps 3 seconds after
a recording starts, and with that patch the audio in recordings is
always good. It's ugly but reliable and usable until we learn more...

Fourth: I haven't been able to get sound working on the s-video input at
all. I just get a very loud (white?) noise, that sounds like an FM-tuner
with no antenna... (I read somewhere that running 'radio' or sth like
that first could help, but I haven't tried it yet). Video from the
svideo works, but the audio is just loud white noise. I tried some
things but ran out of ideas for the moment...

I guess it could help if people report if/how these patches help (or
not), and/or maybe improve on them...

Jelle.


diff -r 4a2a265bd791 linux/drivers/media/video/cx88/cx88-blackbird.c
--- a/linux/drivers/media/video/cx88/cx88-blackbird.c	Wed Nov 22 13:52:36 2006 -0200
+++ b/linux/drivers/media/video/cx88/cx88-blackbird.c	Fri Nov 24 19:21:16 2006 -0500
 (at)  (at)  -871,12 +871,24  (at)  (at)  static int vidioc_streamon(struct file *
 static int vidioc_streamon(struct file *file, void *priv, enum v4l2_buf_type i)
 {
 	struct cx8802_fh  *fh   = priv;
+	struct cx8802_dev *dev  = fh->dev;
+	struct cx88_core *core = dev->core;
+
+	/* unmute audio source */
+	cx_clear(AUD_VOL_CTL, (1 << 6));
+
 	return videobuf_streamon(&fh->mpegq);
 }
 
 static int vidioc_streamoff(struct file *file, void *priv, enum v4l2_buf_type i)
 {
 	struct cx8802_fh  *fh   = priv;
+	struct cx8802_dev *dev  = fh->dev;
+	struct cx88_core *core = dev->core;
+
+	/* mute audio source */
+	cx_set(AUD_VOL_CTL, (1 << 6));
+
 	return videobuf_streamoff(&fh->mpegq);
 }
 
diff -r 4a2a265bd791 linux/drivers/media/video/cx88/cx88-blackbird.c
--- a/linux/drivers/media/video/cx88/cx88-blackbird.c	Wed Nov 22 13:52:36 2006 -0200
+++ b/linux/drivers/media/video/cx88/cx88-blackbird.c	Sat Dec 02 14:23:27 2006 -0500
 (at)  (at)  -577,16 +577,19  (at)  (at)  static struct v4l2_mpeg_compression defa
 	.pulldown          = 0
 };
 
-static int blackbird_initialize_codec(struct cx8802_dev *dev)
-{
-	struct cx88_core *core = dev->core;
+static int blackbird_initialize_codec(struct cx8802_dev *dev, int force)
+{
+	struct cx88_core  *core = dev->core;
 	int version;
 	int retval;
 
-	dprintk(1,"Initialize codec\n");
-	retval = blackbird_api_cmd(dev, CX2341X_ENC_PING_FW, 0, 0); /* ping */
+	retval = force ? force : blackbird_api_cmd(dev, CX2341X_ENC_PING_FW, 0, 0); /* ping */
 	if (retval < 0) {
+		dprintk(1,"Initialize codec\n");
 		/* ping was not successful, reset and upload firmware */
+
+		dev->capturing = 0;
+
 		cx_write(MO_SRST_IO, 0); /* SYS_RSTO=0 */
 		msleep(1);
 		cx_write(MO_SRST_IO, 1); /* SYS_RSTO=1 */
 (at)  (at)  -611,49 +614,78  (at)  (at)  static int blackbird_initialize_codec(st
 			return -1;
 		}
 		dprintk(0, "Firmware version is 0x%08x\n", version);
-	}
-	msleep(1);
-
+		msleep(1);
+
+	}
+	
+	/* if I put this inside the if(), the picture doesn't look right (scaling?) */
 	cx_write(MO_PINMUX_IO, 0x88); /* 656-8bit IO and enable MPEG parallel IO */
 	cx_clear(MO_INPUT_FORMAT, 0x100); /* chroma subcarrier lock to normal? */
 	cx_write(MO_VBOS_CONTROL, 0x84A00); /* no 656 mode, 8-bit pixels, disable VBI */
 	cx_clear(MO_OUTPUT_FORMAT, 0x0008); /* Normal Y-limits to let the mpeg encoder sync */
+	
+	return retval;
+}
+
+static int blackbird_start_codec(struct cx8802_dev *dev)
+{
+	struct cx88_core *core = dev->core;
+
+	/* unmute audio source */
+	cx_clear(AUD_VOL_CTL, (1 << 6));
+
+	dprintk(1,"Start codec\n");
 
 	blackbird_codec_settings(dev);
 	msleep(1);
-
-	/* blackbird_api_cmd(dev, IVTV_API_ASSIGN_NUM_VSYNC_LINES, 4, 0, 0xef, 0xef);
-	   blackbird_api_cmd(dev, IVTV_API_ASSIGN_NUM_VSYNC_LINES, 4, 0, 0xf0, 0xf0);
-	   blackbird_api_cmd(dev, IVTV_API_ASSIGN_NUM_VSYNC_LINES, 4, 0, 0x180, 0x180); */
+	
 	blackbird_api_cmd(dev, CX2341X_ENC_SET_NUM_VSYNC_LINES, 2, 0,
 			BLACKBIRD_FIELD1_SAA7115,
 			BLACKBIRD_FIELD2_SAA7115
-		);
-
-	/* blackbird_api_cmd(dev, IVTV_API_ASSIGN_PLACEHOLDER, 12, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0); */
+			);
+
 	blackbird_api_cmd(dev, CX2341X_ENC_SET_PLACEHOLDER, 12, 0,
 			BLACKBIRD_CUSTOM_EXTENSION_USR_DATA,
 			0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
 
+	blackbird_api_cmd(dev, CX2341X_ENC_MUTE_VIDEO, 1, 0, BLACKBIRD_UNMUTE);
+	msleep(10);
+
 	/* initialize the video input */
 	blackbird_api_cmd(dev, CX2341X_ENC_INITIALIZE_INPUT, 0, 0);
-
 	msleep(1);
 
-	blackbird_api_cmd(dev, CX2341X_ENC_MUTE_VIDEO, 1, 0, BLACKBIRD_UNMUTE);
-	msleep(1);
+	msleep(10);
 	blackbird_api_cmd(dev, CX2341X_ENC_MUTE_AUDIO, 1, 0, BLACKBIRD_UNMUTE);
-	msleep(1);
-
+	blackbird_api_cmd(dev, CX2341X_ENC_MISC, 1, 0, 12); /* Reset audio interface */
+	blackbird_api_cmd(dev, CX2341X_ENC_REFRESH_INPUT, 0,0);
+	msleep(10);
+	
 	/* start capturing to the host interface */
 	/* blackbird_api_cmd(dev, CX2341X_ENC_START_CAPTURE, 2, 0, 0, 0x13); */
 	blackbird_api_cmd(dev, CX2341X_ENC_START_CAPTURE, 2, 0,
 			BLACKBIRD_MPEG_CAPTURE,
 			BLACKBIRD_RAW_BITS_NONE
 		);
-	msleep(10);
-
-	blackbird_api_cmd(dev, CX2341X_ENC_REFRESH_INPUT, 0,0);
+
+
+	dev->capturing = 1; 
+	return 0;
+}
+
+static int blackbird_stop_codec(struct cx8802_dev *dev)
+{
+	struct cx88_core *core = dev->core;
+
+	blackbird_api_cmd(dev, CX2341X_ENC_STOP_CAPTURE, 3, 0,
+			BLACKBIRD_END_NOW,
+			BLACKBIRD_MPEG_CAPTURE,
+			BLACKBIRD_RAW_BITS_NONE
+		);
+	/* mute audio source */
+	cx_set(AUD_VOL_CTL, (1 << 6));
+
+	dev->capturing = 0;
 	return 0;
 }
 
 (at)  (at)  -946,13 +978,12  (at)  (at)  static int vidioc_s_frequency (struct fi
 	struct cx8802_fh  *fh   = priv;
 	struct cx8802_dev *dev  = fh->dev;
 	struct cx88_core  *core = dev->core;
-
 	blackbird_api_cmd(fh->dev, CX2341X_ENC_STOP_CAPTURE, 3, 0,
 				BLACKBIRD_END_NOW,
 				BLACKBIRD_MPEG_CAPTURE,
 				BLACKBIRD_RAW_BITS_NONE);
 	cx88_set_freq (core,f);
-	blackbird_initialize_codec(dev);
+	blackbird_initialize_codec(dev,0);
 	cx88_set_scale(dev->core, dev->width, dev->height,
 			fh->mpegq.field);
 	return 0;
 (at)  (at)  -1038,6 +1069,8  (at)  (at)  static int vidioc_s_input (struct file *
 static int vidioc_s_input (struct file *file, void *priv, unsigned int i)
 {
 	struct cx88_core  *core = ((struct cx8802_fh *)priv)->dev->core;
+	struct cx8802_fh  *fh   = priv;
+	struct cx8802_dev *dev  = fh->dev;
 
 	if (i >= 4)
 		return -EINVAL;
 (at)  (at)  -1103,7 +1136,7  (at)  (at)  static int mpeg_open(struct inode *inode
 	struct cx8802_driver *drv = NULL;
 	int err;
 
-       dev = cx8802_get_device(inode);
+	dev = cx8802_get_device(inode);
 
 	dprintk( 1, "%s\n", __FUNCTION__);
 
 (at)  (at)  -1120,11 +1153,12  (at)  (at)  static int mpeg_open(struct inode *inode
 		}
 	}
 
-	if (blackbird_initialize_codec(dev) < 0) {
+	if (blackbird_initialize_codec(dev,0) < 0) {
 		if (drv)
 			drv->request_release(drv);
 		return -EINVAL;
 	}
+	
 	dprintk(1,"open minor=%d\n",minor);
 
 	/* allocate + initialize per filehandle data */
 (at)  (at)  -1154,17 +1188,13  (at)  (at)  static int mpeg_release(struct inode *in
 static int mpeg_release(struct inode *inode, struct file *file)
 {
 	struct cx8802_fh  *fh  = file->private_data;
-	struct cx8802_dev *dev = NULL;
+	struct cx8802_dev *dev = fh->dev;
 	struct cx8802_driver *drv = NULL;
 
-	/* blackbird_api_cmd(fh->dev, CX2341X_ENC_STOP_CAPTURE, 3, 0, BLACKBIRD_END_NOW, 0, 0x13); */
-	blackbird_api_cmd(fh->dev, CX2341X_ENC_STOP_CAPTURE, 3, 0,
-			BLACKBIRD_END_NOW,
-			BLACKBIRD_MPEG_CAPTURE,
-			BLACKBIRD_RAW_BITS_NONE
-		);
-
-	cx8802_cancel_buffers(fh->dev);
+	if (dev->capturing)
+		blackbird_stop_codec(dev);
+
+	cx8802_cancel_buffers(dev);
 	/* stop mpeg capture */
 	if (fh->mpegq.streaming)
 		videobuf_streamoff(&fh->mpegq);
 (at)  (at)  -1176,10 +1206,6  (at)  (at)  static int mpeg_release(struct inode *in
 	kfree(fh);
 
 	/* Make sure we release the hardware */
-	dev = cx8802_get_device(inode);
-	if (dev == NULL)
-		return -ENODEV;
-
 	drv = cx8802_get_driver(dev, CX88_MPEG_BLACKBIRD);
 	if (drv)
 		drv->request_release(drv);
 (at)  (at)  -1191,6 +1217,10  (at)  (at)  mpeg_read(struct file *file, char __user
 mpeg_read(struct file *file, char __user *data, size_t count, loff_t *ppos)
 {
 	struct cx8802_fh *fh = file->private_data;
+	struct cx8802_dev *dev = fh->dev;
+
+	if (!dev->capturing)
+		blackbird_start_codec(dev);
 
 	return videobuf_read_stream(&fh->mpegq, data, count, ppos, 0,
 				    file->f_flags & O_NONBLOCK);
 (at)  (at)  -1200,6 +1230,10  (at)  (at)  mpeg_poll(struct file *file, struct poll
 mpeg_poll(struct file *file, struct poll_table_struct *wait)
 {
 	struct cx8802_fh *fh = file->private_data;
+	struct cx8802_dev *dev = fh->dev;
+
+	if (!dev->capturing)
+		blackbird_start_codec(dev);
 
 	return videobuf_poll_stream(file, &fh->mpegq, wait);
 }
 (at)  (at)  -1370,6 +1404,7  (at)  (at)  static int cx8802_blackbird_probe(struct
 	printk("%s/2: cx23416 based mpeg encoder (blackbird reference design)\n",
 	       core->name);
 	host_setup(dev->core);
+        blackbird_initialize_codec(dev, -1);
 
 	blackbird_register_video(dev);
 
diff -r 4a2a265bd791 linux/drivers/media/video/cx88/cx88.h
--- a/linux/drivers/media/video/cx88/cx88.h	Wed Nov 22 13:52:36 2006 -0200
+++ b/linux/drivers/media/video/cx88/cx88.h	Sat Dec 02 14:23:27 2006 -0500
 (at)  (at)  -261,7 +261,7  (at)  (at)  struct cx88_subid {
 #define RESOURCE_VIDEO         2
 #define RESOURCE_VBI           4
 
-#define BUFFER_TIMEOUT     (HZ/2)  /* 0.5 seconds */
+#define BUFFER_TIMEOUT     (HZ*2)  /* 0.5 seconds */
 #if 0
 #define BUFFER_TIMEOUT     (HZ*2)
 #endif
 (at)  (at)  -496,6 +496,7  (at)  (at)  struct cx8802_dev {
 	u32                        mailbox;
 	int                        width;
 	int                        height;
+	int                        capturing; /* nonzero if mpeg encoder is capturing */
 
 #ifdef HAVE_VIDEO_BUF_DVB
 	/* for dvb only */
Index: mpegrecorder.cpp
===================================================================
--- mpegrecorder.cpp	(revision 12735)
+++ mpegrecorder.cpp	(working copy)
 (at)  (at)  -377,7 +377,10  (at)  (at) 
     if (!SetV4L2DeviceOptions(chanfd) && !SetIVTVDeviceOptions(chanfd))
         return false;
 
+    close(chanfd);
+    sleep(3);
     readfd = open(videodevice.ascii(), O_RDWR | O_NONBLOCK);
+    chanfd = readfd;
     if (readfd < 0)
     {
         VERBOSE(VB_IMPORTANT, LOC_ERR + "Can't open video device." + ENO);
--
video4linux-list mailing list
Unsubscribe mailto:video4linux-list-request (at) redhat.com?subject=unsubscribe
https://www.redhat.com/mailman/listinfo/video4linux-list