diff options
Diffstat (limited to 'drivers/media/video/cx18/cx18-streams.c')
| -rw-r--r-- | drivers/media/video/cx18/cx18-streams.c | 72 | 
1 files changed, 61 insertions, 11 deletions
diff --git a/drivers/media/video/cx18/cx18-streams.c b/drivers/media/video/cx18/cx18-streams.c index 987a9308d93..054450f65a6 100644 --- a/drivers/media/video/cx18/cx18-streams.c +++ b/drivers/media/video/cx18/cx18-streams.c @@ -319,11 +319,27 @@ void cx18_streams_cleanup(struct cx18 *cx, int unregister)  	/* Teardown all streams */  	for (type = 0; type < CX18_MAX_STREAMS; type++) { -		if (cx->streams[type].dvb.enabled) { -			cx18_dvb_unregister(&cx->streams[type]); -			cx->streams[type].dvb.enabled = false; + +		/* No struct video_device, but can have buffers allocated */ +		if (type == CX18_ENC_STREAM_TYPE_TS) { +			if (cx->streams[type].dvb.enabled) { +				cx18_dvb_unregister(&cx->streams[type]); +				cx->streams[type].dvb.enabled = false; +				cx18_stream_free(&cx->streams[type]); +			} +			continue; +		} + +		/* No struct video_device, but can have buffers allocated */ +		if (type == CX18_ENC_STREAM_TYPE_IDX) { +			if (cx->stream_buffers[type] != 0) { +				cx->stream_buffers[type] = 0; +				cx18_stream_free(&cx->streams[type]); +			} +			continue;  		} +		/* If struct video_device exists, can have buffers allocated */  		vdev = cx->streams[type].video_dev;  		cx->streams[type].video_dev = NULL; @@ -447,6 +463,32 @@ static void cx18_vbi_setup(struct cx18_stream *s)  	cx18_api(cx, CX18_CPU_SET_RAW_VBI_PARAM, 6, data);  } +void cx18_stream_rotate_idx_mdls(struct cx18 *cx) +{ +	struct cx18_stream *s = &cx->streams[CX18_ENC_STREAM_TYPE_IDX]; +	struct cx18_mdl *mdl; + +	if (!cx18_stream_enabled(s)) +		return; + +	/* Return if the firmware is not running low on MDLs */ +	if ((atomic_read(&s->q_free.depth) + atomic_read(&s->q_busy.depth)) >= +					    CX18_ENC_STREAM_TYPE_IDX_FW_MDL_MIN) +		return; + +	/* Return if there are no MDLs to rotate back to the firmware */ +	if (atomic_read(&s->q_full.depth) < 2) +		return; + +	/* +	 * Take the oldest IDX MDL still holding data, and discard its index +	 * entries by scheduling the MDL to go back to the firmware +	 */ +	mdl = cx18_dequeue(s, &s->q_full); +	if (mdl != NULL) +		cx18_enqueue(s, mdl, &s->q_free); +} +  static  struct cx18_queue *_cx18_stream_put_mdl_fw(struct cx18_stream *s,  					   struct cx18_mdl *mdl) @@ -546,8 +588,9 @@ int cx18_start_v4l2_encode_stream(struct cx18_stream *s)  	struct cx18 *cx = s->cx;  	int captype = 0;  	struct cx18_api_func_private priv; +	struct cx18_stream *s_idx; -	if (s->video_dev == NULL && s->dvb.enabled == 0) +	if (!cx18_stream_enabled(s))  		return -EINVAL;  	CX18_DEBUG_INFO("Start encoder stream %s\n", s->name); @@ -561,6 +604,9 @@ int cx18_start_v4l2_encode_stream(struct cx18_stream *s)  		cx->search_pack_header = 0;  		break; +	case CX18_ENC_STREAM_TYPE_IDX: +		captype = CAPTURE_CHANNEL_TYPE_INDEX; +		break;  	case CX18_ENC_STREAM_TYPE_TS:  		captype = CAPTURE_CHANNEL_TYPE_TS;  		break; @@ -635,11 +681,13 @@ int cx18_start_v4l2_encode_stream(struct cx18_stream *s)  			cx18_vbi_setup(s);  		/* -		 * assign program index info. -		 * Mask 7: select I/P/B, Num_req: 400 max -		 * FIXME - currently we have this hardcoded as disabled +		 * Select to receive I, P, and B frame index entries, if the +		 * index stream is enabled.  Otherwise disable index entry +		 * generation.  		 */ -		cx18_vapi_result(cx, data, CX18_CPU_SET_INDEXTABLE, 1, 0); +		s_idx = &cx->streams[CX18_ENC_STREAM_TYPE_IDX]; +		cx18_vapi_result(cx, data, CX18_CPU_SET_INDEXTABLE, 2, +				 s->handle, cx18_stream_enabled(s_idx) ? 7 : 0);  		/* Call out to the common CX2341x API setup for user controls */  		priv.cx = cx; @@ -697,6 +745,7 @@ int cx18_start_v4l2_encode_stream(struct cx18_stream *s)  	atomic_inc(&cx->tot_capturing);  	return 0;  } +EXPORT_SYMBOL(cx18_start_v4l2_encode_stream);  void cx18_stop_all_captures(struct cx18 *cx)  { @@ -705,7 +754,7 @@ void cx18_stop_all_captures(struct cx18 *cx)  	for (i = CX18_MAX_STREAMS - 1; i >= 0; i--) {  		struct cx18_stream *s = &cx->streams[i]; -		if (s->video_dev == NULL && s->dvb.enabled == 0) +		if (!cx18_stream_enabled(s))  			continue;  		if (test_bit(CX18_F_S_STREAMING, &s->s_flags))  			cx18_stop_v4l2_encode_stream(s, 0); @@ -717,7 +766,7 @@ int cx18_stop_v4l2_encode_stream(struct cx18_stream *s, int gop_end)  	struct cx18 *cx = s->cx;  	unsigned long then; -	if (s->video_dev == NULL && s->dvb.enabled == 0) +	if (!cx18_stream_enabled(s))  		return -EINVAL;  	/* This function assumes that you are allowed to stop the capture @@ -762,6 +811,7 @@ int cx18_stop_v4l2_encode_stream(struct cx18_stream *s, int gop_end)  	return 0;  } +EXPORT_SYMBOL(cx18_stop_v4l2_encode_stream);  u32 cx18_find_handle(struct cx18 *cx)  { @@ -789,7 +839,7 @@ struct cx18_stream *cx18_handle_to_stream(struct cx18 *cx, u32 handle)  		s = &cx->streams[i];  		if (s->handle != handle)  			continue; -		if (s->video_dev || s->dvb.enabled) +		if (cx18_stream_enabled(s))  			return s;  	}  	return NULL;  |