Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 181461
b: refs/heads/master
c: 79f3e96
h: refs/heads/master
i:
  181459: 48d69b5
v: v3
  • Loading branch information
Andy Walls authored and Mauro Carvalho Chehab committed Feb 26, 2010
1 parent c527173 commit d7ae5c1
Show file tree
Hide file tree
Showing 4 changed files with 126 additions and 73 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: e46c54a87e4a6364b0e86b03cb3d00d09ef2f627
refs/heads/master: 79f3e96018dc55ff7819a6a1ac3740a1d7103589
183 changes: 118 additions & 65 deletions trunk/drivers/media/video/cx18/cx18-fileops.c
Original file line number Diff line number Diff line change
Expand Up @@ -37,15 +37,21 @@

/* This function tries to claim the stream for a specific file descriptor.
If no one else is using this stream then the stream is claimed and
associated VBI streams are also automatically claimed.
associated VBI and IDX streams are also automatically claimed.
Possible error returns: -EBUSY if someone else has claimed
the stream or 0 on success. */
static int cx18_claim_stream(struct cx18_open_id *id, int type)
{
struct cx18 *cx = id->cx;
struct cx18_stream *s = &cx->streams[type];
struct cx18_stream *s_vbi;
int vbi_type;
struct cx18_stream *s_assoc;

/* Nothing should ever try to directly claim the IDX stream */
if (type == CX18_ENC_STREAM_TYPE_IDX) {
CX18_WARN("MPEG Index stream cannot be claimed "
"directly, but something tried.\n");
return -EINVAL;
}

if (test_and_set_bit(CX18_F_S_CLAIMED, &s->s_flags)) {
/* someone already claimed this stream */
Expand All @@ -67,21 +73,27 @@ static int cx18_claim_stream(struct cx18_open_id *id, int type)
}
s->id = id->open_id;

/* CX18_ENC_STREAM_TYPE_MPG needs to claim CX18_ENC_STREAM_TYPE_VBI
(provided VBI insertion is on and sliced VBI is selected), for all
other streams we're done */
if (type == CX18_ENC_STREAM_TYPE_MPG &&
cx->vbi.insert_mpeg && !cx18_raw_vbi(cx)) {
vbi_type = CX18_ENC_STREAM_TYPE_VBI;
} else {
/*
* CX18_ENC_STREAM_TYPE_MPG needs to claim:
* CX18_ENC_STREAM_TYPE_VBI, if VBI insertion is on for sliced VBI, or
* CX18_ENC_STREAM_TYPE_IDX, if VBI insertion is off for sliced VBI
* (We don't yet fix up MPEG Index entries for our inserted packets).
*
* For all other streams we're done.
*/
if (type != CX18_ENC_STREAM_TYPE_MPG)
return 0;
}
s_vbi = &cx->streams[vbi_type];

set_bit(CX18_F_S_CLAIMED, &s_vbi->s_flags);
s_assoc = &cx->streams[CX18_ENC_STREAM_TYPE_IDX];
if (cx->vbi.insert_mpeg && !cx18_raw_vbi(cx))
s_assoc = &cx->streams[CX18_ENC_STREAM_TYPE_VBI];
else if (!cx18_stream_enabled(s_assoc))
return 0;

set_bit(CX18_F_S_CLAIMED, &s_assoc->s_flags);

/* mark that it is used internally */
set_bit(CX18_F_S_INTERNAL_USE, &s_vbi->s_flags);
set_bit(CX18_F_S_INTERNAL_USE, &s_assoc->s_flags);
return 0;
}

Expand All @@ -90,9 +102,17 @@ static int cx18_claim_stream(struct cx18_open_id *id, int type)
static void cx18_release_stream(struct cx18_stream *s)
{
struct cx18 *cx = s->cx;
struct cx18_stream *s_vbi;
struct cx18_stream *s_assoc;

s->id = -1;
if (s->type == CX18_ENC_STREAM_TYPE_IDX) {
/*
* The IDX stream is only used internally, and can
* only be indirectly unclaimed by unclaiming the MPG stream.
*/
return;
}

if (s->type == CX18_ENC_STREAM_TYPE_VBI &&
test_bit(CX18_F_S_INTERNAL_USE, &s->s_flags)) {
/* this stream is still in use internally */
Expand All @@ -105,24 +125,34 @@ static void cx18_release_stream(struct cx18_stream *s)

cx18_flush_queues(s);

/* CX18_ENC_STREAM_TYPE_MPG needs to release CX18_ENC_STREAM_TYPE_VBI,
for all other streams we're done */
if (s->type == CX18_ENC_STREAM_TYPE_MPG)
s_vbi = &cx->streams[CX18_ENC_STREAM_TYPE_VBI];
else
/*
* CX18_ENC_STREAM_TYPE_MPG needs to release the
* CX18_ENC_STREAM_TYPE_VBI and/or CX18_ENC_STREAM_TYPE_IDX streams.
*
* For all other streams we're done.
*/
if (s->type != CX18_ENC_STREAM_TYPE_MPG)
return;

/* clear internal use flag */
if (!test_and_clear_bit(CX18_F_S_INTERNAL_USE, &s_vbi->s_flags)) {
/* was already cleared */
return;
/* Unclaim the associated MPEG Index stream */
s_assoc = &cx->streams[CX18_ENC_STREAM_TYPE_IDX];
if (test_and_clear_bit(CX18_F_S_INTERNAL_USE, &s_assoc->s_flags)) {
clear_bit(CX18_F_S_CLAIMED, &s_assoc->s_flags);
cx18_flush_queues(s_assoc);
}
if (s_vbi->id != -1) {
/* VBI stream still claimed by a file descriptor */
return;

/* Unclaim the associated VBI stream */
s_assoc = &cx->streams[CX18_ENC_STREAM_TYPE_VBI];
if (test_and_clear_bit(CX18_F_S_INTERNAL_USE, &s_assoc->s_flags)) {
if (s_assoc->id == -1) {
/*
* The VBI stream is not still claimed by a file
* descriptor, so completely unclaim it.
*/
clear_bit(CX18_F_S_CLAIMED, &s_assoc->s_flags);
cx18_flush_queues(s_assoc);
}
}
clear_bit(CX18_F_S_CLAIMED, &s_vbi->s_flags);
cx18_flush_queues(s_vbi);
}

static void cx18_dualwatch(struct cx18 *cx)
Expand Down Expand Up @@ -498,6 +528,7 @@ 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;
struct cx18_stream *s_idx;

if (s->type == CX18_ENC_STREAM_TYPE_RAD) {
/* you cannot read from these stream types. */
Expand All @@ -516,25 +547,33 @@ int cx18_start_capture(struct cx18_open_id *id)
return 0;
}

/* Start VBI capture if required */
/* Start associated VBI or IDX stream 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;
s_idx = &cx->streams[CX18_ENC_STREAM_TYPE_IDX];
if (s->type == CX18_ENC_STREAM_TYPE_MPG) {
/*
* The VBI and IDX streams should have been claimed
* automatically, if for internal use, when the MPG stream was
* claimed. We only need to start these streams capturing.
*/
if (test_bit(CX18_F_S_INTERNAL_USE, &s_idx->s_flags) &&
!test_and_set_bit(CX18_F_S_STREAMING, &s_idx->s_flags)) {
if (cx18_start_v4l2_encode_stream(s_idx)) {
CX18_DEBUG_WARN("IDX capture start failed\n");
clear_bit(CX18_F_S_STREAMING, &s_idx->s_flags);
goto start_failed;
}
CX18_DEBUG_INFO("IDX capture started\n");
}
if (test_bit(CX18_F_S_INTERNAL_USE, &s_vbi->s_flags) &&
!test_and_set_bit(CX18_F_S_STREAMING, &s_vbi->s_flags)) {
if (cx18_start_v4l2_encode_stream(s_vbi)) {
CX18_DEBUG_WARN("VBI capture start failed\n");
clear_bit(CX18_F_S_STREAMING, &s_vbi->s_flags);
goto start_failed;
}
CX18_DEBUG_INFO("VBI insertion started\n");
}
CX18_DEBUG_INFO("VBI insertion started\n");
}

/* Tell the card to start capturing */
Expand All @@ -547,19 +586,29 @@ int cx18_start_capture(struct cx18_open_id *id)
return 0;
}

/* failure, clean up */
start_failed:
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);
/*
* The associated VBI and IDX streams for internal use are released
* automatically when the MPG stream is released. We only need to stop
* the associated stream.
*/
if (s->type == CX18_ENC_STREAM_TYPE_MPG) {
/* Stop the IDX stream which is always for internal use */
if (test_bit(CX18_F_S_STREAMING, &s_idx->s_flags)) {
cx18_stop_v4l2_encode_stream(s_idx, 0);
clear_bit(CX18_F_S_STREAMING, &s_idx->s_flags);
}
/* Stop the VBI stream, if only running for internal use */
if (test_bit(CX18_F_S_STREAMING, &s_vbi->s_flags) &&
!test_bit(CX18_F_S_APPL_IO, &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);
cx18_release_stream(s); /* Also releases associated streams */
return -EIO;
}

Expand Down Expand Up @@ -618,24 +667,28 @@ 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];
struct cx18_stream *s_vbi = &cx->streams[CX18_ENC_STREAM_TYPE_VBI];
struct cx18_stream *s_idx = &cx->streams[CX18_ENC_STREAM_TYPE_IDX];

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_MPG) {
/* Stop internal use associated VBI and IDX streams */
if (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 (test_bit(CX18_F_S_STREAMING, &s_idx->s_flags)) {
CX18_DEBUG_INFO("close stopping IDX capture\n");
cx18_stop_v4l2_encode_stream(s_idx, 0);
}
}
if (id->type == CX18_ENC_STREAM_TYPE_VBI &&
test_bit(CX18_F_S_INTERNAL_USE, &s->s_flags))
Expand Down
7 changes: 0 additions & 7 deletions trunk/drivers/media/video/cx18/cx18-streams.c
Original file line number Diff line number Diff line change
Expand Up @@ -356,13 +356,6 @@ void cx18_streams_cleanup(struct cx18 *cx, int unregister)
}
}

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

static void cx18_vbi_setup(struct cx18_stream *s)
{
struct cx18 *cx = s->cx;
Expand Down
7 changes: 7 additions & 0 deletions trunk/drivers/media/video/cx18/cx18-streams.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,13 @@ int cx18_streams_setup(struct cx18 *cx);
int cx18_streams_register(struct cx18 *cx);
void cx18_streams_cleanup(struct cx18 *cx, int unregister);

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

/* Related to submission of mdls to firmware */
static inline void cx18_stream_load_fw_queue(struct cx18_stream *s)
{
Expand Down

0 comments on commit d7ae5c1

Please sign in to comment.