unsigned int cx18_v4l2_enc_poll(struct file *filp, poll_table *wait) { struct cx18_open_id *id = filp->private_data; struct cx18 *cx = id->cx; struct cx18_stream *s = &cx->streams[id->type]; int eof = test_bit(CX18_F_S_STREAMOFF, &s->s_flags); /* Start a capture if there is none */ if (!eof && !test_bit(CX18_F_S_STREAMING, &s->s_flags)) { int rc; mutex_lock(&cx->serialize_lock); rc = cx18_start_capture(id); mutex_unlock(&cx->serialize_lock); if (rc) { CX18_DEBUG_INFO("Could not start capture for %s (%d)\n", s->name, rc); return POLLERR; } CX18_DEBUG_FILE("Encoder poll started capture\n"); } /* add stream's waitq to the poll list */ CX18_DEBUG_HI_FILE("Encoder poll\n"); poll_wait(filp, &s->waitq, wait); if (atomic_read(&s->q_full.buffers) || atomic_read(&s->q_io.buffers)) return POLLIN | POLLRDNORM; if (eof) return POLLHUP; return 0; }
static int cx18_encoder_cmd(struct file *file, void *fh, struct v4l2_encoder_cmd *enc) { struct cx18_open_id *id = fh; struct cx18 *cx = id->cx; u32 h; switch (enc->cmd) { case V4L2_ENC_CMD_START: CX18_DEBUG_IOCTL("V4L2_ENC_CMD_START\n"); enc->flags = 0; return cx18_start_capture(id); case V4L2_ENC_CMD_STOP: CX18_DEBUG_IOCTL("V4L2_ENC_CMD_STOP\n"); enc->flags &= V4L2_ENC_CMD_STOP_AT_GOP_END; cx18_stop_capture(id, enc->flags & V4L2_ENC_CMD_STOP_AT_GOP_END); break; case V4L2_ENC_CMD_PAUSE: CX18_DEBUG_IOCTL("V4L2_ENC_CMD_PAUSE\n"); enc->flags = 0; if (!atomic_read(&cx->ana_capturing)) return -EPERM; if (test_and_set_bit(CX18_F_I_ENC_PAUSED, &cx->i_flags)) return 0; h = cx18_find_handle(cx); if (h == CX18_INVALID_TASK_HANDLE) { CX18_ERR("Can't find valid task handle for " "V4L2_ENC_CMD_PAUSE\n"); return -EBADFD; } cx18_mute(cx); cx18_vapi(cx, CX18_CPU_CAPTURE_PAUSE, 1, h); break; case V4L2_ENC_CMD_RESUME: CX18_DEBUG_IOCTL("V4L2_ENC_CMD_RESUME\n"); enc->flags = 0; if (!atomic_read(&cx->ana_capturing)) return -EPERM; if (!test_and_clear_bit(CX18_F_I_ENC_PAUSED, &cx->i_flags)) return 0; h = cx18_find_handle(cx); if (h == CX18_INVALID_TASK_HANDLE) { CX18_ERR("Can't find valid task handle for " "V4L2_ENC_CMD_RESUME\n"); return -EBADFD; } cx18_vapi(cx, CX18_CPU_CAPTURE_RESUME, 1, h); cx18_unmute(cx); break; default: CX18_DEBUG_IOCTL("Unknown cmd %d\n", enc->cmd); return -EINVAL; } return 0; }
ssize_t cx18_v4l2_read(struct file *filp, char __user *buf, size_t count, loff_t *pos) { struct cx18_open_id *id = filp->private_data; struct cx18 *cx = id->cx; struct cx18_stream *s = &cx->streams[id->type]; int rc; CX18_DEBUG_HI_FILE("read %zd bytes from %s\n", count, s->name); mutex_lock(&cx->serialize_lock); rc = cx18_start_capture(id); mutex_unlock(&cx->serialize_lock); if (rc) return rc; return cx18_read_pos(s, buf, count, pos, filp->f_flags & O_NONBLOCK); }