diff options
Diffstat (limited to 'drivers/media/video/ivtv/ivtv-ioctl.c')
-rw-r--r-- | drivers/media/video/ivtv/ivtv-ioctl.c | 106 |
1 files changed, 67 insertions, 39 deletions
diff --git a/drivers/media/video/ivtv/ivtv-ioctl.c b/drivers/media/video/ivtv/ivtv-ioctl.c index b0630773e507..13020a7e5db9 100644 --- a/drivers/media/video/ivtv/ivtv-ioctl.c +++ b/drivers/media/video/ivtv/ivtv-ioctl.c @@ -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, |