[media] ivtv: implement new decoder command ioctls
authorHans Verkuil <hans.verkuil@cisco.com>
Thu, 24 Nov 2011 12:58:53 +0000 (09:58 -0300)
committerMauro Carvalho Chehab <mchehab@redhat.com>
Tue, 14 Feb 2012 15:43:27 +0000 (13:43 -0200)
Signed-off-by: Hans Verkuil <hans.verkuil@cisco.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
drivers/media/video/ivtv/ivtv-driver.c
drivers/media/video/ivtv/ivtv-fileops.c
drivers/media/video/ivtv/ivtv-ioctl.c
drivers/media/video/ivtv/ivtv-streams.c

index 3949b7dc2368370ebe6d28f15b3b83bc2999babe..48d1d47ed04f157e6fbdcabadc8496fbeb3bff99 100644 (file)
@@ -1375,7 +1375,7 @@ static void ivtv_remove(struct pci_dev *pdev)
                        else
                                type = IVTV_DEC_STREAM_TYPE_MPG;
                        ivtv_stop_v4l2_decode_stream(&itv->streams[type],
-                               VIDEO_CMD_STOP_TO_BLACK | VIDEO_CMD_STOP_IMMEDIATELY, 0);
+                               V4L2_DEC_CMD_STOP_TO_BLACK | V4L2_DEC_CMD_STOP_IMMEDIATELY, 0);
                }
                ivtv_halt_firmware(itv);
        }
index 2cd6c89b7d917d618de7791bf919bb1015c899b9..c9663e885b9f9724bf4439dc613fc07bded2ed94 100644 (file)
@@ -900,7 +900,7 @@ int ivtv_v4l2_close(struct file *filp)
        if (s->type >= IVTV_DEC_STREAM_TYPE_MPG) {
                struct ivtv_stream *s_vout = &itv->streams[IVTV_DEC_STREAM_TYPE_VOUT];
 
-               ivtv_stop_decoding(id, VIDEO_CMD_STOP_TO_BLACK | VIDEO_CMD_STOP_IMMEDIATELY, 0);
+               ivtv_stop_decoding(id, V4L2_DEC_CMD_STOP_TO_BLACK | V4L2_DEC_CMD_STOP_IMMEDIATELY, 0);
 
                /* If all output streams are closed, and if the user doesn't have
                   IVTV_DEC_STREAM_TYPE_VOUT open, then disable CC on TV-out. */
index b0630773e507b8aba480ac5390e19a02c482354c..13020a7e5db92886155399b75663245f1f1694ad 100644 (file)
@@ -246,34 +246,40 @@ static int ivtv_validate_speed(int cur_speed, int new_speed)
 }
 
 static int ivtv_video_command(struct ivtv *itv, struct ivtv_open_id *id,
-               struct video_command *vc, int try)
+               struct v4l2_decoder_cmd *dc, int try)
 {
        struct ivtv_stream *s = &itv->streams[IVTV_DEC_STREAM_TYPE_MPG];
 
        if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT))
                return -EINVAL;
 
-       switch (vc->cmd) {
-       case VIDEO_CMD_PLAY: {
-               vc->flags = 0;
-               vc->play.speed = ivtv_validate_speed(itv->speed, vc->play.speed);
-               if (vc->play.speed < 0)
-                       vc->play.format = VIDEO_PLAY_FMT_GOP;
+       switch (dc->cmd) {
+       case V4L2_DEC_CMD_START: {
+               dc->flags &= V4L2_DEC_CMD_START_MUTE_AUDIO;
+               dc->start.speed = ivtv_validate_speed(itv->speed, dc->start.speed);
+               if (dc->start.speed < 0)
+                       dc->start.format = V4L2_DEC_START_FMT_GOP;
+               else
+                       dc->start.format = V4L2_DEC_START_FMT_NONE;
+               if (dc->start.speed != 500 && dc->start.speed != 1500)
+                       dc->flags = dc->start.speed == 1000 ? 0 :
+                                       V4L2_DEC_CMD_START_MUTE_AUDIO;
                if (try) break;
 
+               itv->speed_mute_audio = dc->flags & V4L2_DEC_CMD_START_MUTE_AUDIO;
                if (ivtv_set_output_mode(itv, OUT_MPG) != OUT_MPG)
                        return -EBUSY;
                if (test_and_clear_bit(IVTV_F_I_DEC_PAUSED, &itv->i_flags)) {
                        /* forces ivtv_set_speed to be called */
                        itv->speed = 0;
                }
-               return ivtv_start_decoding(id, vc->play.speed);
+               return ivtv_start_decoding(id, dc->start.speed);
        }
 
-       case VIDEO_CMD_STOP:
-               vc->flags &= VIDEO_CMD_STOP_IMMEDIATELY|VIDEO_CMD_STOP_TO_BLACK;
-               if (vc->flags & VIDEO_CMD_STOP_IMMEDIATELY)
-                       vc->stop.pts = 0;
+       case V4L2_DEC_CMD_STOP:
+               dc->flags &= V4L2_DEC_CMD_STOP_IMMEDIATELY | V4L2_DEC_CMD_STOP_TO_BLACK;
+               if (dc->flags & V4L2_DEC_CMD_STOP_IMMEDIATELY)
+                       dc->stop.pts = 0;
                if (try) break;
                if (atomic_read(&itv->decoding) == 0)
                        return 0;
@@ -281,22 +287,22 @@ static int ivtv_video_command(struct ivtv *itv, struct ivtv_open_id *id,
                        return -EBUSY;
 
                itv->output_mode = OUT_NONE;
-               return ivtv_stop_v4l2_decode_stream(s, vc->flags, vc->stop.pts);
+               return ivtv_stop_v4l2_decode_stream(s, dc->flags, dc->stop.pts);
 
-       case VIDEO_CMD_FREEZE:
-               vc->flags &= VIDEO_CMD_FREEZE_TO_BLACK;
+       case V4L2_DEC_CMD_PAUSE:
+               dc->flags &= V4L2_DEC_CMD_PAUSE_TO_BLACK;
                if (try) break;
                if (itv->output_mode != OUT_MPG)
                        return -EBUSY;
                if (atomic_read(&itv->decoding) > 0) {
                        ivtv_vapi(itv, CX2341X_DEC_PAUSE_PLAYBACK, 1,
-                               (vc->flags & VIDEO_CMD_FREEZE_TO_BLACK) ? 1 : 0);
+                               (dc->flags & V4L2_DEC_CMD_PAUSE_TO_BLACK) ? 1 : 0);
                        set_bit(IVTV_F_I_DEC_PAUSED, &itv->i_flags);
                }
                break;
 
-       case VIDEO_CMD_CONTINUE:
-               vc->flags = 0;
+       case V4L2_DEC_CMD_RESUME:
+               dc->flags = 0;
                if (try) break;
                if (itv->output_mode != OUT_MPG)
                        return -EBUSY;
@@ -1575,6 +1581,24 @@ static int ivtv_log_status(struct file *file, void *fh)
        return 0;
 }
 
+static int ivtv_decoder_cmd(struct file *file, void *fh, struct v4l2_decoder_cmd *dec)
+{
+       struct ivtv_open_id *id = fh2id(file->private_data);
+       struct ivtv *itv = id->itv;
+
+       IVTV_DEBUG_IOCTL("VIDIOC_DECODER_CMD %d\n", dec->cmd);
+       return ivtv_video_command(itv, id, dec, false);
+}
+
+static int ivtv_try_decoder_cmd(struct file *file, void *fh, struct v4l2_decoder_cmd *dec)
+{
+       struct ivtv_open_id *id = fh2id(file->private_data);
+       struct ivtv *itv = id->itv;
+
+       IVTV_DEBUG_IOCTL("VIDIOC_TRY_DECODER_CMD %d\n", dec->cmd);
+       return ivtv_video_command(itv, id, dec, true);
+}
+
 static int ivtv_decoder_ioctls(struct file *filp, unsigned int cmd, void *arg)
 {
        struct ivtv_open_id *id = fh2id(filp->private_data);
@@ -1669,52 +1693,54 @@ static int ivtv_decoder_ioctls(struct file *filp, unsigned int cmd, void *arg)
        }
 
        case VIDEO_PLAY: {
-               struct video_command vc;
+               struct v4l2_decoder_cmd dc;
 
                IVTV_DEBUG_IOCTL("VIDEO_PLAY\n");
-               memset(&vc, 0, sizeof(vc));
-               vc.cmd = VIDEO_CMD_PLAY;
-               return ivtv_video_command(itv, id, &vc, 0);
+               memset(&dc, 0, sizeof(dc));
+               dc.cmd = V4L2_DEC_CMD_START;
+               return ivtv_video_command(itv, id, &dc, 0);
        }
 
        case VIDEO_STOP: {
-               struct video_command vc;
+               struct v4l2_decoder_cmd dc;
 
                IVTV_DEBUG_IOCTL("VIDEO_STOP\n");
-               memset(&vc, 0, sizeof(vc));
-               vc.cmd = VIDEO_CMD_STOP;
-               vc.flags = VIDEO_CMD_STOP_TO_BLACK | VIDEO_CMD_STOP_IMMEDIATELY;
-               return ivtv_video_command(itv, id, &vc, 0);
+               memset(&dc, 0, sizeof(dc));
+               dc.cmd = V4L2_DEC_CMD_STOP;
+               dc.flags = V4L2_DEC_CMD_STOP_TO_BLACK | V4L2_DEC_CMD_STOP_IMMEDIATELY;
+               return ivtv_video_command(itv, id, &dc, 0);
        }
 
        case VIDEO_FREEZE: {
-               struct video_command vc;
+               struct v4l2_decoder_cmd dc;
 
                IVTV_DEBUG_IOCTL("VIDEO_FREEZE\n");
-               memset(&vc, 0, sizeof(vc));
-               vc.cmd = VIDEO_CMD_FREEZE;
-               return ivtv_video_command(itv, id, &vc, 0);
+               memset(&dc, 0, sizeof(dc));
+               dc.cmd = V4L2_DEC_CMD_PAUSE;
+               return ivtv_video_command(itv, id, &dc, 0);
        }
 
        case VIDEO_CONTINUE: {
-               struct video_command vc;
+               struct v4l2_decoder_cmd dc;
 
                IVTV_DEBUG_IOCTL("VIDEO_CONTINUE\n");
-               memset(&vc, 0, sizeof(vc));
-               vc.cmd = VIDEO_CMD_CONTINUE;
-               return ivtv_video_command(itv, id, &vc, 0);
+               memset(&dc, 0, sizeof(dc));
+               dc.cmd = V4L2_DEC_CMD_RESUME;
+               return ivtv_video_command(itv, id, &dc, 0);
        }
 
        case VIDEO_COMMAND:
        case VIDEO_TRY_COMMAND: {
-               struct video_command *vc = arg;
+               /* Note: struct v4l2_decoder_cmd has the same layout as
+                  struct video_command */
+               struct v4l2_decoder_cmd *dc = arg;
                int try = (cmd == VIDEO_TRY_COMMAND);
 
                if (try)
-                       IVTV_DEBUG_IOCTL("VIDEO_TRY_COMMAND %d\n", vc->cmd);
+                       IVTV_DEBUG_IOCTL("VIDEO_TRY_COMMAND %d\n", dc->cmd);
                else
-                       IVTV_DEBUG_IOCTL("VIDEO_COMMAND %d\n", vc->cmd);
-               return ivtv_video_command(itv, id, vc, try);
+                       IVTV_DEBUG_IOCTL("VIDEO_COMMAND %d\n", dc->cmd);
+               return ivtv_video_command(itv, id, dc, try);
        }
 
        case VIDEO_GET_EVENT: {
@@ -1892,6 +1918,8 @@ static const struct v4l2_ioctl_ops ivtv_ioctl_ops = {
        .vidioc_enum_fmt_vid_cap            = ivtv_enum_fmt_vid_cap,
        .vidioc_encoder_cmd                 = ivtv_encoder_cmd,
        .vidioc_try_encoder_cmd             = ivtv_try_encoder_cmd,
+       .vidioc_decoder_cmd                 = ivtv_decoder_cmd,
+       .vidioc_try_decoder_cmd             = ivtv_try_decoder_cmd,
        .vidioc_enum_fmt_vid_out            = ivtv_enum_fmt_vid_out,
        .vidioc_g_fmt_vid_cap               = ivtv_g_fmt_vid_cap,
        .vidioc_g_fmt_vbi_cap               = ivtv_g_fmt_vbi_cap,
index e5039f4f7f0752afcc1f14045574f153a4fb80cf..034c0112431fb108fe0dd20108dcb6c23be60775 100644 (file)
@@ -905,7 +905,7 @@ int ivtv_stop_v4l2_decode_stream(struct ivtv_stream *s, int flags, u64 pts)
        IVTV_DEBUG_INFO("Stop Decode at %llu, flags: %x\n", (unsigned long long)pts, flags);
 
        /* Stop Decoder */
-       if (!(flags & VIDEO_CMD_STOP_IMMEDIATELY) || pts) {
+       if (!(flags & V4L2_DEC_CMD_STOP_IMMEDIATELY) || pts) {
                u32 tmp = 0;
 
                /* Wait until the decoder is no longer running */
@@ -925,7 +925,7 @@ int ivtv_stop_v4l2_decode_stream(struct ivtv_stream *s, int flags, u64 pts)
                                break;
                }
        }
-       ivtv_vapi(itv, CX2341X_DEC_STOP_PLAYBACK, 3, flags & VIDEO_CMD_STOP_TO_BLACK, 0, 0);
+       ivtv_vapi(itv, CX2341X_DEC_STOP_PLAYBACK, 3, flags & V4L2_DEC_CMD_STOP_TO_BLACK, 0, 0);
 
        /* turn off notification of dual/stereo mode change */
        ivtv_vapi(itv, CX2341X_DEC_SET_EVENT_NOTIFICATION, 4, 0, 0, IVTV_IRQ_DEC_AUD_MODE_CHG, -1);