Exemple #1
0
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);
    }
}
Exemple #2
0
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;
}
Exemple #3
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;
}
Exemple #4
0
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;
}