]> err.no Git - linux-2.6/blobdiff - drivers/media/dvb/ttpci/av7110_av.c
Merge commit 'v2.6.26' into bkl-removal
[linux-2.6] / drivers / media / dvb / ttpci / av7110_av.c
index d75e7e48addcc821b0869a4b524bfb3265797c08..ec55a968f204cf1195dbb219883055a149b46267 100644 (file)
@@ -329,7 +329,7 @@ int av7110_set_volume(struct av7110 *av7110, int volleft, int volright)
        return 0;
 }
 
-int av7110_set_vidmode(struct av7110 *av7110, int mode)
+int av7110_set_vidmode(struct av7110 *av7110, enum av7110_video_mode mode)
 {
        int ret;
        dprintk(2, "av7110:%p, \n", av7110);
@@ -348,11 +348,15 @@ int av7110_set_vidmode(struct av7110 *av7110, int mode)
 }
 
 
-static int sw2mode[16] = {
-       VIDEO_MODE_PAL, VIDEO_MODE_NTSC, VIDEO_MODE_NTSC, VIDEO_MODE_PAL,
-       VIDEO_MODE_NTSC, VIDEO_MODE_NTSC, VIDEO_MODE_PAL, VIDEO_MODE_NTSC,
-       VIDEO_MODE_PAL, VIDEO_MODE_PAL, VIDEO_MODE_PAL, VIDEO_MODE_PAL,
-       VIDEO_MODE_PAL, VIDEO_MODE_PAL, VIDEO_MODE_PAL, VIDEO_MODE_PAL,
+static enum av7110_video_mode sw2mode[16] = {
+       AV7110_VIDEO_MODE_PAL, AV7110_VIDEO_MODE_NTSC,
+       AV7110_VIDEO_MODE_NTSC, AV7110_VIDEO_MODE_PAL,
+       AV7110_VIDEO_MODE_NTSC, AV7110_VIDEO_MODE_NTSC,
+       AV7110_VIDEO_MODE_PAL, AV7110_VIDEO_MODE_NTSC,
+       AV7110_VIDEO_MODE_PAL, AV7110_VIDEO_MODE_PAL,
+       AV7110_VIDEO_MODE_PAL, AV7110_VIDEO_MODE_PAL,
+       AV7110_VIDEO_MODE_PAL, AV7110_VIDEO_MODE_PAL,
+       AV7110_VIDEO_MODE_PAL, AV7110_VIDEO_MODE_PAL,
 };
 
 static int get_video_format(struct av7110 *av7110, u8 *buf, int count)
@@ -961,7 +965,9 @@ static u8 iframe_header[] = { 0x00, 0x00, 0x01, 0xe0, 0x00, 0x00, 0x80, 0x00, 0x
 
 static int play_iframe(struct av7110 *av7110, char __user *buf, unsigned int len, int nonblock)
 {
-       int i, n;
+       unsigned i, n;
+       int progressive = 0;
+       int match = 0;
 
        dprintk(2, "av7110:%p, \n", av7110);
 
@@ -970,6 +976,33 @@ static int play_iframe(struct av7110 *av7110, char __user *buf, unsigned int len
                        return -EBUSY;
        }
 
+       /* search in buf for instances of 00 00 01 b5 1? */
+       for (i = 0; i < len; i++) {
+               unsigned char c;
+               if (get_user(c, buf + i))
+                       return -EFAULT;
+               if (match == 5) {
+                       progressive = c & 0x08;
+                       match = 0;
+               }
+               if (c == 0x00) {
+                       match = (match == 1 || match == 2) ? 2 : 1;
+                       continue;
+               }
+               switch (match++) {
+               case 2: if (c == 0x01)
+                               continue;
+                       break;
+               case 3: if (c == 0xb5)
+                               continue;
+                       break;
+               case 4: if ((c & 0xf0) == 0x10)
+                               continue;
+                       break;
+               }
+               match = 0;
+       }
+
        /* setting n always > 1, fixes problems when playing stillframes
           consisting of I- and P-Frames */
        n = MIN_IFRAME / len + 1;
@@ -981,7 +1014,11 @@ static int play_iframe(struct av7110 *av7110, char __user *buf, unsigned int len
                dvb_play(av7110, buf, len, 0, 1);
 
        av7110_ipack_flush(&av7110->ipack[1]);
-       return 0;
+
+       if (progressive)
+               return vidcom(av7110, AV_VIDEO_CMD_FREEZE, 1);
+       else
+               return 0;
 }