summaryrefslogtreecommitdiff
path: root/drivers/media/video/ivtv/ivtv-ioctl.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/media/video/ivtv/ivtv-ioctl.c')
-rw-r--r--drivers/media/video/ivtv/ivtv-ioctl.c35
1 files changed, 25 insertions, 10 deletions
diff --git a/drivers/media/video/ivtv/ivtv-ioctl.c b/drivers/media/video/ivtv/ivtv-ioctl.c
index 57af1762de1f..dfe0aedc60fd 100644
--- a/drivers/media/video/ivtv/ivtv-ioctl.c
+++ b/drivers/media/video/ivtv/ivtv-ioctl.c
@@ -285,6 +285,10 @@ static int ivtv_video_command(struct ivtv *itv, struct ivtv_open_id *id,
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);
}
@@ -309,6 +313,7 @@ static int ivtv_video_command(struct ivtv *itv, struct ivtv_open_id *id,
if (atomic_read(&itv->decoding) > 0) {
ivtv_vapi(itv, CX2341X_DEC_PAUSE_PLAYBACK, 1,
(vc->flags & VIDEO_CMD_FREEZE_TO_BLACK) ? 1 : 0);
+ set_bit(IVTV_F_I_DEC_PAUSED, &itv->i_flags);
}
break;
@@ -317,8 +322,10 @@ static int ivtv_video_command(struct ivtv *itv, struct ivtv_open_id *id,
if (try) break;
if (itv->output_mode != OUT_MPG)
return -EBUSY;
- if (atomic_read(&itv->decoding) > 0) {
- ivtv_vapi(itv, CX2341X_DEC_START_PLAYBACK, 2, 0, 0);
+ if (test_and_clear_bit(IVTV_F_I_DEC_PAUSED, &itv->i_flags)) {
+ int speed = itv->speed;
+ itv->speed = 0;
+ return ivtv_start_decoding(id, speed);
}
break;
@@ -1092,14 +1099,21 @@ int ivtv_v4l2_ioctls(struct ivtv *itv, struct file *filp, unsigned int cmd, void
case VIDIOC_G_ENC_INDEX: {
struct v4l2_enc_idx *idx = arg;
+ struct v4l2_enc_idx_entry *e = idx->entry;
+ int entries;
int i;
- idx->entries = (itv->pgm_info_write_idx + IVTV_MAX_PGM_INDEX - itv->pgm_info_read_idx) %
+ entries = (itv->pgm_info_write_idx + IVTV_MAX_PGM_INDEX - itv->pgm_info_read_idx) %
IVTV_MAX_PGM_INDEX;
- if (idx->entries > V4L2_ENC_IDX_ENTRIES)
- idx->entries = V4L2_ENC_IDX_ENTRIES;
- for (i = 0; i < idx->entries; i++) {
- idx->entry[i] = itv->pgm_info[(itv->pgm_info_read_idx + i) % IVTV_MAX_PGM_INDEX];
+ if (entries > V4L2_ENC_IDX_ENTRIES)
+ entries = V4L2_ENC_IDX_ENTRIES;
+ idx->entries = 0;
+ for (i = 0; i < entries; i++) {
+ *e = itv->pgm_info[(itv->pgm_info_read_idx + i) % IVTV_MAX_PGM_INDEX];
+ if ((e->flags & V4L2_ENC_IDX_FRAME_MASK) <= V4L2_ENC_IDX_FRAME_B) {
+ idx->entries++;
+ e++;
+ }
}
itv->pgm_info_read_idx = (itv->pgm_info_read_idx + idx->entries) % IVTV_MAX_PGM_INDEX;
break;
@@ -1159,7 +1173,7 @@ int ivtv_v4l2_ioctls(struct ivtv *itv, struct file *filp, unsigned int cmd, void
memset(fb, 0, sizeof(*fb));
if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT_OVERLAY))
- break;
+ return -EINVAL;
fb->capability = V4L2_FBUF_CAP_EXTERNOVERLAY | V4L2_FBUF_CAP_CHROMAKEY |
V4L2_FBUF_CAP_LOCAL_ALPHA | V4L2_FBUF_CAP_GLOBAL_ALPHA;
fb->fmt.pixelformat = itv->osd_pixelformat;
@@ -1179,10 +1193,11 @@ int ivtv_v4l2_ioctls(struct ivtv *itv, struct file *filp, unsigned int cmd, void
struct v4l2_framebuffer *fb = arg;
if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT_OVERLAY))
- break;
+ return -EINVAL;
itv->osd_global_alpha_state = (fb->flags & V4L2_FBUF_FLAG_GLOBAL_ALPHA) != 0;
itv->osd_local_alpha_state = (fb->flags & V4L2_FBUF_FLAG_LOCAL_ALPHA) != 0;
itv->osd_color_key_state = (fb->flags & V4L2_FBUF_FLAG_CHROMAKEY) != 0;
+ ivtv_set_osd_alpha(itv);
break;
}
@@ -1227,7 +1242,7 @@ int ivtv_v4l2_ioctls(struct ivtv *itv, struct file *filp, unsigned int cmd, void
IVTV_INFO("Tuner: %s\n",
test_bit(IVTV_F_I_RADIO_USER, &itv->i_flags) ? "Radio" : "TV");
cx2341x_log_status(&itv->params, itv->name);
- IVTV_INFO("Status flags: 0x%08lx\n", itv->i_flags);
+ IVTV_INFO("Version: %s Status flags: 0x%08lx\n", IVTV_VERSION, itv->i_flags);
for (i = 0; i < IVTV_MAX_STREAMS; i++) {
struct ivtv_stream *s = &itv->streams[i];