void cx18_stop_capture(struct cx18_open_id *id, int gop_end) { struct cx18 *cx = id->cx; struct cx18_stream *s = &cx->streams[id->type]; CX18_DEBUG_IOCTL("close() of %s\n", s->name); /* 'Unclaim' this stream */ /* Stop capturing */ if (test_bit(CX18_F_S_STREAMING, &s->s_flags)) { struct cx18_stream *s_vbi = &cx->streams[CX18_ENC_STREAM_TYPE_VBI]; CX18_DEBUG_INFO("close stopping capture\n"); /* Special case: a running VBI capture for VBI insertion in the mpeg stream. Need to stop that too. */ if (id->type == CX18_ENC_STREAM_TYPE_MPG && test_bit(CX18_F_S_STREAMING, &s_vbi->s_flags) && !test_bit(CX18_F_S_APPL_IO, &s_vbi->s_flags)) { CX18_DEBUG_INFO("close stopping embedded VBI capture\n"); cx18_stop_v4l2_encode_stream(s_vbi, 0); } if (id->type == CX18_ENC_STREAM_TYPE_VBI && test_bit(CX18_F_S_INTERNAL_USE, &s->s_flags)) /* Also used internally, don't stop capturing */ s->id = -1; else cx18_stop_v4l2_encode_stream(s, gop_end); } if (!gop_end) { clear_bit(CX18_F_S_APPL_IO, &s->s_flags); clear_bit(CX18_F_S_STREAMOFF, &s->s_flags); cx18_release_stream(s); } }
static int snd_cx18_pcm_capture_close(struct snd_pcm_substream *substream) { struct snd_cx18_card *cxsc = snd_pcm_substream_chip(substream); struct v4l2_device *v4l2_dev = cxsc->v4l2_dev; struct cx18 *cx = to_cx18(v4l2_dev); struct cx18_stream *s; /* Instruct the cx18 to stop sending packets */ snd_cx18_lock(cxsc); s = &cx->streams[CX18_ENC_STREAM_TYPE_PCM]; cx18_stop_v4l2_encode_stream(s, 0); clear_bit(CX18_F_S_STREAMING, &s->s_flags); cx18_release_stream(s); cx->pcm_announce_callback = NULL; snd_cx18_unlock(cxsc); return 0; }
/* Kernel DVB framework calls this when the feed needs to stop. */ static int cx18_dvb_stop_feed(struct dvb_demux_feed *feed) { struct dvb_demux *demux = feed->demux; struct cx18_stream *stream = (struct cx18_stream *)demux->priv; struct cx18 *cx = stream->cx; int ret = -EINVAL; CX18_DEBUG_INFO("Stop feed: pid = 0x%x index = %d\n", feed->pid, feed->index); if (stream) { mutex_lock(&stream->dvb.feedlock); if (--stream->dvb.feeding == 0) { CX18_DEBUG_INFO("Stopping Transport DMA\n"); ret = cx18_stop_v4l2_encode_stream(stream, 0); } else ret = 0; mutex_unlock(&stream->dvb.feedlock); } return ret; }
int cx18_start_capture(struct cx18_open_id *id) { struct cx18 *cx = id->cx; struct cx18_stream *s = &cx->streams[id->type]; struct cx18_stream *s_vbi; if (s->type == CX18_ENC_STREAM_TYPE_RAD) { /* you cannot read from these stream types. */ return -EPERM; } /* Try to claim this stream. */ if (cx18_claim_stream(id, s->type)) return -EBUSY; /* If capture is already in progress, then we also have to do nothing extra. */ if (test_bit(CX18_F_S_STREAMOFF, &s->s_flags) || test_and_set_bit(CX18_F_S_STREAMING, &s->s_flags)) { set_bit(CX18_F_S_APPL_IO, &s->s_flags); return 0; } /* Start VBI capture if required */ s_vbi = &cx->streams[CX18_ENC_STREAM_TYPE_VBI]; if (s->type == CX18_ENC_STREAM_TYPE_MPG && test_bit(CX18_F_S_INTERNAL_USE, &s_vbi->s_flags) && !test_and_set_bit(CX18_F_S_STREAMING, &s_vbi->s_flags)) { /* Note: the CX18_ENC_STREAM_TYPE_VBI is claimed automatically when the MPG stream is claimed. We only need to start the VBI capturing. */ if (cx18_start_v4l2_encode_stream(s_vbi)) { CX18_DEBUG_WARN("VBI capture start failed\n"); /* Failure, clean up and return an error */ clear_bit(CX18_F_S_STREAMING, &s_vbi->s_flags); clear_bit(CX18_F_S_STREAMING, &s->s_flags); /* also releases the associated VBI stream */ cx18_release_stream(s); return -EIO; } CX18_DEBUG_INFO("VBI insertion started\n"); } /* Tell the card to start capturing */ if (!cx18_start_v4l2_encode_stream(s)) { /* We're done */ set_bit(CX18_F_S_APPL_IO, &s->s_flags); /* Resume a possibly paused encoder */ if (test_and_clear_bit(CX18_F_I_ENC_PAUSED, &cx->i_flags)) cx18_vapi(cx, CX18_CPU_CAPTURE_PAUSE, 1, s->handle); return 0; } /* failure, clean up */ CX18_DEBUG_WARN("Failed to start capturing for stream %s\n", s->name); /* Note: the CX18_ENC_STREAM_TYPE_VBI is released automatically when the MPG stream is released. We only need to stop the VBI capturing. */ if (s->type == CX18_ENC_STREAM_TYPE_MPG && test_bit(CX18_F_S_STREAMING, &s_vbi->s_flags)) { cx18_stop_v4l2_encode_stream(s_vbi, 0); clear_bit(CX18_F_S_STREAMING, &s_vbi->s_flags); } clear_bit(CX18_F_S_STREAMING, &s->s_flags); cx18_release_stream(s); return -EIO; }