Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 754f9969 authored by Andy Walls's avatar Andy Walls Committed by Mauro Carvalho Chehab
Browse files

[media] cx18: Only allocate a struct cx18_dvb for the DVB TS stream



The cx18_stream struct contained a struct cx18_dvb for
every stream object, most of which were for analog capture.
Now we only allocate the cx18_dvb object for the DTV TS stream.

Signed-off-by: default avatarAndy Walls <awalls@md.metrocast.net>
Signed-off-by: default avatarMauro Carvalho Chehab <mchehab@redhat.com>
parent fa98447f
Loading
Loading
Loading
Loading
+5 −4
Original line number Diff line number Diff line
@@ -325,7 +325,10 @@ struct cx18_queue {
	spinlock_t lock;
};

struct cx18_stream; /* forward reference */

struct cx18_dvb {
	struct cx18_stream *stream;
	struct dmx_frontend hw_frontend;
	struct dmx_frontend mem_frontend;
	struct dmxdev dmxdev;
@@ -365,9 +368,10 @@ struct cx18_in_work_order {
#define CX18_INVALID_TASK_HANDLE 0xffffffff

struct cx18_stream {
	/* These first four fields are always set, even if the stream
	/* These first five fields are always set, even if the stream
	   is not actually created. */
	struct video_device *video_dev;	/* NULL when stream not created */
	struct cx18_dvb *dvb;		/* DVB / Digital Transport */
	struct cx18 *cx; 		/* for ease of use */
	const char *name;		/* name of the stream */
	int type;			/* stream type */
@@ -397,9 +401,6 @@ struct cx18_stream {
	struct cx18_queue q_idle;	/* idle - not in rotation */

	struct work_struct out_work_order;

	/* DVB / Digital Transport */
	struct cx18_dvb dvb;
};

struct cx18_open_id {
+19 −13
Original line number Diff line number Diff line
@@ -137,7 +137,7 @@ static int yuan_mpc718_mt352_init(struct dvb_frontend *fe)
{
	struct cx18_dvb *dvb = container_of(fe->dvb,
					    struct cx18_dvb, dvb_adapter);
	struct cx18_stream *stream = container_of(dvb, struct cx18_stream, dvb);
	struct cx18_stream *stream = dvb->stream;
	const struct firmware *fw = NULL;
	int ret;
	int i;
@@ -266,22 +266,22 @@ static int cx18_dvb_start_feed(struct dvb_demux_feed *feed)
	if (!demux->dmx.frontend)
		return -EINVAL;

	mutex_lock(&stream->dvb.feedlock);
	if (stream->dvb.feeding++ == 0) {
	mutex_lock(&stream->dvb->feedlock);
	if (stream->dvb->feeding++ == 0) {
		CX18_DEBUG_INFO("Starting Transport DMA\n");
		mutex_lock(&cx->serialize_lock);
		set_bit(CX18_F_S_STREAMING, &stream->s_flags);
		ret = cx18_start_v4l2_encode_stream(stream);
		if (ret < 0) {
			CX18_DEBUG_INFO("Failed to start Transport DMA\n");
			stream->dvb.feeding--;
			if (stream->dvb.feeding == 0)
			stream->dvb->feeding--;
			if (stream->dvb->feeding == 0)
				clear_bit(CX18_F_S_STREAMING, &stream->s_flags);
		}
		mutex_unlock(&cx->serialize_lock);
	} else
		ret = 0;
	mutex_unlock(&stream->dvb.feedlock);
	mutex_unlock(&stream->dvb->feedlock);

	return ret;
}
@@ -299,15 +299,15 @@ static int cx18_dvb_stop_feed(struct dvb_demux_feed *feed)
		CX18_DEBUG_INFO("Stop feed: pid = 0x%x index = %d\n",
				feed->pid, feed->index);

		mutex_lock(&stream->dvb.feedlock);
		if (--stream->dvb.feeding == 0) {
		mutex_lock(&stream->dvb->feedlock);
		if (--stream->dvb->feeding == 0) {
			CX18_DEBUG_INFO("Stopping Transport DMA\n");
			mutex_lock(&cx->serialize_lock);
			ret = cx18_stop_v4l2_encode_stream(stream, 0);
			mutex_unlock(&cx->serialize_lock);
		} else
			ret = 0;
		mutex_unlock(&stream->dvb.feedlock);
		mutex_unlock(&stream->dvb->feedlock);
	}

	return ret;
@@ -316,7 +316,7 @@ static int cx18_dvb_stop_feed(struct dvb_demux_feed *feed)
int cx18_dvb_register(struct cx18_stream *stream)
{
	struct cx18 *cx = stream->cx;
	struct cx18_dvb *dvb = &stream->dvb;
	struct cx18_dvb *dvb = stream->dvb;
	struct dvb_adapter *dvb_adapter;
	struct dvb_demux *dvbdemux;
	struct dmx_demux *dmx;
@@ -325,6 +325,9 @@ int cx18_dvb_register(struct cx18_stream *stream)
	if (!dvb)
		return -EINVAL;

	dvb->enabled = 0;
	dvb->stream = stream;

	ret = dvb_register_adapter(&dvb->dvb_adapter,
			CX18_DRIVER_NAME,
			THIS_MODULE, &cx->pci_dev->dev, adapter_nr);
@@ -378,7 +381,7 @@ int cx18_dvb_register(struct cx18_stream *stream)

	CX18_INFO("DVB Frontend registered\n");
	CX18_INFO("Registered DVB adapter%d for %s (%d x %d.%02d kB)\n",
		  stream->dvb.dvb_adapter.num, stream->name,
		  stream->dvb->dvb_adapter.num, stream->name,
		  stream->buffers, stream->buf_size/1024,
		  (stream->buf_size * 100 / 1024) % 100);

@@ -405,13 +408,16 @@ int cx18_dvb_register(struct cx18_stream *stream)
void cx18_dvb_unregister(struct cx18_stream *stream)
{
	struct cx18 *cx = stream->cx;
	struct cx18_dvb *dvb = &stream->dvb;
	struct cx18_dvb *dvb = stream->dvb;
	struct dvb_adapter *dvb_adapter;
	struct dvb_demux *dvbdemux;
	struct dmx_demux *dmx;

	CX18_INFO("unregister DVB\n");

	if (dvb == NULL || !dvb->enabled)
		return;

	dvb_adapter = &dvb->dvb_adapter;
	dvbdemux = &dvb->demux;
	dmx = &dvbdemux->dmx;
@@ -432,7 +438,7 @@ void cx18_dvb_unregister(struct cx18_stream *stream)
 */
static int dvb_register(struct cx18_stream *stream)
{
	struct cx18_dvb *dvb = &stream->dvb;
	struct cx18_dvb *dvb = stream->dvb;
	struct cx18 *cx = stream->cx;
	int ret = 0;

+3 −3
Original line number Diff line number Diff line
@@ -136,7 +136,7 @@ static void cx18_mdl_send_to_dvb(struct cx18_stream *s, struct cx18_mdl *mdl)
{
	struct cx18_buffer *buf;

	if (!s->dvb.enabled || mdl->bytesused == 0)
	if (s->dvb == NULL || !s->dvb->enabled || mdl->bytesused == 0)
		return;

	/* We ignore mdl and buf readpos accounting here - it doesn't matter */
@@ -146,7 +146,7 @@ static void cx18_mdl_send_to_dvb(struct cx18_stream *s, struct cx18_mdl *mdl)
		buf = list_first_entry(&mdl->buf_list, struct cx18_buffer,
				       list);
		if (buf->bytesused)
			dvb_dmx_swfilter(&s->dvb.demux,
			dvb_dmx_swfilter(&s->dvb->demux,
					 buf->buf, buf->bytesused);
		return;
	}
@@ -154,7 +154,7 @@ static void cx18_mdl_send_to_dvb(struct cx18_stream *s, struct cx18_mdl *mdl)
	list_for_each_entry(buf, &mdl->buf_list, list) {
		if (buf->bytesused == 0)
			break;
		dvb_dmx_swfilter(&s->dvb.demux, buf->buf, buf->bytesused);
		dvb_dmx_swfilter(&s->dvb->demux, buf->buf, buf->bytesused);
	}
}

+31 −14
Original line number Diff line number Diff line
@@ -107,6 +107,7 @@ static void cx18_stream_init(struct cx18 *cx, int type)
	s->video_dev = video_dev;

	/* initialize cx18_stream fields */
	s->dvb = NULL;
	s->cx = cx;
	s->type = type;
	s->name = cx18_stream_info[type].name;
@@ -140,10 +141,15 @@ static int cx18_prep_dev(struct cx18 *cx, int type)
	int num_offset = cx18_stream_info[type].num_offset;
	int num = cx->instance + cx18_first_minor + num_offset;

	/* These four fields are always initialized. If video_dev == NULL, then
	   this stream is not in use. In that case no other fields but these
	   four can be used. */
	/*
	 * These five fields are always initialized.
	 * For analog capture related streams, if video_dev == NULL then the
	 * stream is not in use.
	 * For the TS stream, if dvb == NULL then the stream is not in use.
	 * In those cases no other fields but these four can be used.
	 */
	s->video_dev = NULL;
	s->dvb = NULL;
	s->cx = cx;
	s->type = type;
	s->name = cx18_stream_info[type].name;
@@ -167,6 +173,21 @@ static int cx18_prep_dev(struct cx18 *cx, int type)

	cx18_stream_init(cx, type);

	/* Allocate the cx18_dvb struct only for the TS on cards with DTV */
	if (type == CX18_ENC_STREAM_TYPE_TS) {
		if (cx->card->hw_all & CX18_HW_DVB) {
			s->dvb = kzalloc(sizeof(struct cx18_dvb), GFP_KERNEL);
			if (s->dvb == NULL) {
				CX18_ERR("Couldn't allocate cx18_dvb structure"
					 " for %s\n", s->name);
				return -ENOMEM;
			}
		} else {
			/* Don't need buffers for the TS, if there is no DVB */
			s->buffers = 0;
		}
	}

	if (num_offset == -1)
		return 0;

@@ -222,13 +243,7 @@ static int cx18_reg_dev(struct cx18 *cx, int type)
	const char *name;
	int num, ret;

	/* TODO: Shouldn't this be a VFL_TYPE_TRANSPORT or something?
	 * We need a VFL_TYPE_TS defined.
	 */
	if (strcmp("TS", s->name) == 0) {
		/* just return if no DVB is supported */
		if ((cx->card->hw_all & CX18_HW_DVB) == 0)
			return 0;
	if (type == CX18_ENC_STREAM_TYPE_TS && s->dvb != NULL) {
		ret = cx18_dvb_register(s);
		if (ret < 0) {
			CX18_ERR("DVB failed to register\n");
@@ -320,11 +335,13 @@ void cx18_streams_cleanup(struct cx18 *cx, int unregister)
	/* Teardown all streams */
	for (type = 0; type < CX18_MAX_STREAMS; type++) {

		/* No struct video_device, but can have buffers allocated */
		/* The TS has a cx18_dvb structure, not a video_device */
		if (type == CX18_ENC_STREAM_TYPE_TS) {
			if (cx->streams[type].dvb.enabled) {
			if (cx->streams[type].dvb != NULL) {
				if (unregister)
					cx18_dvb_unregister(&cx->streams[type]);
				cx->streams[type].dvb.enabled = false;
				kfree(cx->streams[type].dvb);
				cx->streams[type].dvb = NULL;
				cx18_stream_free(&cx->streams[type]);
			}
			continue;
+2 −1
Original line number Diff line number Diff line
@@ -33,7 +33,8 @@ void cx18_stream_rotate_idx_mdls(struct cx18 *cx);

static inline bool cx18_stream_enabled(struct cx18_stream *s)
{
	return s->video_dev || s->dvb.enabled ||
	return s->video_dev ||
	       (s->dvb && s->dvb->enabled) ||
	       (s->type == CX18_ENC_STREAM_TYPE_IDX &&
		s->cx->stream_buffers[CX18_ENC_STREAM_TYPE_IDX] != 0);
}