Gitweb:     
http://git.kernel.org/git/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commit;h=f9e54e0c84da869ad9bc372fb4eab26d558dbfc2
Commit:     f9e54e0c84da869ad9bc372fb4eab26d558dbfc2
Parent:     4bfae52b69360a966f41ba3308e57a6df41ff8e1
Author:     Jelle Foks <[EMAIL PROTECTED]>
AuthorDate: Mon May 21 14:36:01 2007 -0300
Committer:  Mauro Carvalho Chehab <[EMAIL PROTECTED]>
CommitDate: Fri Jan 25 19:03:47 2008 -0200

    V4L/DVB (6828): cx88-blackbird: audio improvements
    
    This patch should fix the 'muted audio' and 'raspy audio' problem for
    mpeg2 streams out of cx88-blackbird devices.
    
    Especially mythtv users would find that the audio would often sound bad
    (aliased, or 'raspy'), mainly related to channel changes, many (all?)
    other users would find that there was no audio at all in the mpeg data
    from the encoder chip, unless the audio was manually unmuted.
    
    The patch includes the following modifications:
    
    Don't actually start the mpeg2 encoder until the device is read from
    by the application.
    
    Wait until the audio is stable for at least 400ms before starting the
    mpeg encoder.
    
    Mute/Unmute the audio when starting/stopping the mpeg encoder.
    
    Stop the mpeg encoder when changing parameters and when changing tuner
    frequency.
    
    Add a variable 'mpeg_active' to struct cx8802_dev to allow tracking of
    whether or not the mpeg2 encoder is active.
    
    Load the firmware on cx88-blackbird driver load.
    
    Signed-off-by: Jelle Foks <[EMAIL PROTECTED]>
    Signed-off-by: Michael Krufky <[EMAIL PROTECTED]>
    Signed-off-by: Mauro Carvalho Chehab <[EMAIL PROTECTED]>
---
 drivers/media/video/cx88/cx88-blackbird.c |   89 ++++++++++++++++++++++-------
 drivers/media/video/cx88/cx88.h           |    1 +
 2 files changed, 70 insertions(+), 20 deletions(-)

diff --git a/drivers/media/video/cx88/cx88-blackbird.c 
b/drivers/media/video/cx88/cx88-blackbird.c
index f802b56..7ce37f4 100644
--- a/drivers/media/video/cx88/cx88-blackbird.c
+++ b/drivers/media/video/cx88/cx88-blackbird.c
@@ -536,6 +536,9 @@ static int blackbird_initialize_codec(struct cx8802_dev 
*dev)
        dprintk(1,"Initialize codec\n");
        retval = blackbird_api_cmd(dev, CX2341X_ENC_PING_FW, 0, 0); /* ping */
        if (retval < 0) {
+
+               dev->mpeg_active = 0;
+
                /* ping was not successful, reset and upload firmware */
                cx_write(MO_SRST_IO, 0); /* SYS_RSTO=0 */
                msleep(1);
@@ -572,38 +575,80 @@ static int blackbird_initialize_codec(struct cx8802_dev 
*dev)
        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);
 
-       /* initialize the video input */
-       blackbird_api_cmd(dev, CX2341X_ENC_INITIALIZE_INPUT, 0, 0);
-
        msleep(1);
+       return 0;
+}
+
+static int blackbird_start_codec(struct file *file, void *priv)
+{
+       struct cx8802_dev *dev  = ((struct cx8802_fh *)priv)->dev;
+       struct cx88_core *core = dev->core;
+       /* start capturing to the host interface */
+       u32 reg;
+
+       int i;
+       int lastchange = -1;
+       int lastval = 0;
+
+       for (i=0; (i < 10) && (i < (lastchange + 4)); i++)
+       {
+               reg = cx_read(AUD_STATUS);
+
+               dprintk(1,"AUD_STATUS:%dL: 0x%x\n", i, reg);
+               if ((reg & 0x0F) != lastval)
+               {
+                       lastval = reg & 0x0F;
+                       lastchange = i;
+               }
+               msleep(100);
+       }
+
+       /* unmute audio source */
+       cx_clear(AUD_VOL_CTL, (1 << 6));
 
        blackbird_api_cmd(dev, CX2341X_ENC_MUTE_VIDEO, 1, 0, BLACKBIRD_UNMUTE);
        msleep(1);
        blackbird_api_cmd(dev, CX2341X_ENC_MUTE_AUDIO, 1, 0, BLACKBIRD_UNMUTE);
        msleep(1);
 
+       blackbird_api_cmd(dev, CX2341X_ENC_REFRESH_INPUT, 0,0);
+
+       /* initialize the video input */
+       blackbird_api_cmd(dev, CX2341X_ENC_INITIALIZE_INPUT, 0, 0);
+
        /* 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->mpeg_active = 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->mpeg_active = 0;
        return 0;
 }
 
@@ -833,6 +878,10 @@ static int vidioc_s_ext_ctrls (struct file *file, void 
*priv,
 
        if (f->ctrl_class != V4L2_CTRL_CLASS_MPEG)
                return -EINVAL;
+
+       if (dev->mpeg_active)
+               blackbird_stop_codec(dev);
+
        p = dev->params;
        err = cx2341x_ext_ctrls(&p, 0, f, VIDIOC_S_EXT_CTRLS);
        if (!err) {
@@ -864,10 +913,9 @@ static int vidioc_s_frequency (struct file *file, void 
*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);
+       if (dev->mpeg_active)
+               blackbird_stop_codec(dev);
+
        cx88_set_freq (core,f);
        blackbird_initialize_codec(dev);
        cx88_set_scale(dev->core, dev->width, dev->height,
@@ -1073,15 +1121,11 @@ static int mpeg_open(struct inode *inode, struct file 
*file)
 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
-               );
+       if (dev->mpeg_active)
+               blackbird_stop_codec(dev);
 
        cx8802_cancel_buffers(fh->dev);
        /* stop mpeg capture */
@@ -1107,6 +1151,10 @@ static ssize_t
 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->mpeg_active)
+               blackbird_start_codec(file, fh);
 
        return videobuf_read_stream(&fh->mpegq, data, count, ppos, 0,
                                    file->f_flags & O_NONBLOCK);
@@ -1282,6 +1330,7 @@ static int cx8802_blackbird_probe(struct cx8802_driver 
*drv)
               core->name);
        host_setup(dev->core);
 
+       blackbird_initialize_codec(dev);
        blackbird_register_video(dev);
 
        /* initial device configuration: needed ? */
diff --git a/drivers/media/video/cx88/cx88.h b/drivers/media/video/cx88/cx88.h
index bb1036a..f10d432 100644
--- a/drivers/media/video/cx88/cx88.h
+++ b/drivers/media/video/cx88/cx88.h
@@ -461,6 +461,7 @@ struct cx8802_dev {
        u32                        mailbox;
        int                        width;
        int                        height;
+       unsigned char              mpeg_active; /* nonzero if mpeg encoder is 
active */
 
        /* mpeg params */
        struct cx2341x_mpeg_params params;
-
To unsubscribe from this list: send the line "unsubscribe git-commits-head" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to