diff options
author | Steven Toth <stoth@kernellabs.com> | 2011-04-06 07:32:56 -0400 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@redhat.com> | 2011-05-20 08:28:43 -0400 |
commit | b7101de3fff596b35e45cd9fb7007caa07e97c9a (patch) | |
tree | 1c11baca827c290a1e312180204e8dc0472eabb9 /drivers/media/video/cx18/cx18-mailbox.c | |
parent | 5ed9bd02444a00bb1e8ecc1baa8ecdb633afc126 (diff) |
[media] cx18: mmap() support for raw YUV video capture
Add support for mmap method streaming of raw YUV video on cx18-based
hardware, in addition to the existing support for read() streaming of
raw YUV and MPEG-2 encoded video.
[simon.farnsworth@onelan.co.uk: I forward-ported this from Steven's original work,
done under contract to ONELAN. The original code is at
http://www.kernellabs.com/hg/~stoth/cx18-videobuf]
Signed-off-by: Steven Toth <stoth@kernellabs.com>
Signed-off-by: Simon Farnsworth <simon.farnsworth@onelan.co.uk>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers/media/video/cx18/cx18-mailbox.c')
-rw-r--r-- | drivers/media/video/cx18/cx18-mailbox.c | 70 |
1 files changed, 70 insertions, 0 deletions
diff --git a/drivers/media/video/cx18/cx18-mailbox.c b/drivers/media/video/cx18/cx18-mailbox.c index 9605d54bd083..d4d88738d893 100644 --- a/drivers/media/video/cx18/cx18-mailbox.c +++ b/drivers/media/video/cx18/cx18-mailbox.c | |||
@@ -81,6 +81,7 @@ static const struct cx18_api_info api_info[] = { | |||
81 | API_ENTRY(CPU, CX18_CPU_SET_SLICED_VBI_PARAM, 0), | 81 | API_ENTRY(CPU, CX18_CPU_SET_SLICED_VBI_PARAM, 0), |
82 | API_ENTRY(CPU, CX18_CPU_SET_USERDATA_PLACE_HOLDER, 0), | 82 | API_ENTRY(CPU, CX18_CPU_SET_USERDATA_PLACE_HOLDER, 0), |
83 | API_ENTRY(CPU, CX18_CPU_GET_ENC_PTS, 0), | 83 | API_ENTRY(CPU, CX18_CPU_GET_ENC_PTS, 0), |
84 | API_ENTRY(CPU, CX18_CPU_SET_VFC_PARAM, 0), | ||
84 | API_ENTRY(CPU, CX18_CPU_DE_SET_MDL_ACK, 0), | 85 | API_ENTRY(CPU, CX18_CPU_DE_SET_MDL_ACK, 0), |
85 | API_ENTRY(CPU, CX18_CPU_DE_SET_MDL, API_FAST), | 86 | API_ENTRY(CPU, CX18_CPU_DE_SET_MDL, API_FAST), |
86 | API_ENTRY(CPU, CX18_CPU_DE_RELEASE_MDL, API_SLOW), | 87 | API_ENTRY(CPU, CX18_CPU_DE_RELEASE_MDL, API_SLOW), |
@@ -158,6 +159,72 @@ static void cx18_mdl_send_to_dvb(struct cx18_stream *s, struct cx18_mdl *mdl) | |||
158 | } | 159 | } |
159 | } | 160 | } |
160 | 161 | ||
162 | static void cx18_mdl_send_to_videobuf(struct cx18_stream *s, | ||
163 | struct cx18_mdl *mdl) | ||
164 | { | ||
165 | struct cx18_videobuf_buffer *vb_buf; | ||
166 | struct cx18_buffer *buf; | ||
167 | u8 *p, u; | ||
168 | u32 offset = 0; | ||
169 | int dispatch = 0; | ||
170 | int i; | ||
171 | |||
172 | if (mdl->bytesused == 0) | ||
173 | return; | ||
174 | |||
175 | /* Acquire a videobuf buffer, clone to and and release it */ | ||
176 | spin_lock(&s->vb_lock); | ||
177 | if (list_empty(&s->vb_capture)) | ||
178 | goto out; | ||
179 | |||
180 | vb_buf = list_entry(s->vb_capture.next, struct cx18_videobuf_buffer, | ||
181 | vb.queue); | ||
182 | |||
183 | p = videobuf_to_vmalloc(&vb_buf->vb); | ||
184 | if (!p) | ||
185 | goto out; | ||
186 | |||
187 | offset = vb_buf->bytes_used; | ||
188 | list_for_each_entry(buf, &mdl->buf_list, list) { | ||
189 | if (buf->bytesused == 0) | ||
190 | break; | ||
191 | |||
192 | if ((offset + buf->bytesused) <= vb_buf->vb.bsize) { | ||
193 | memcpy(p + offset, buf->buf, buf->bytesused); | ||
194 | offset += buf->bytesused; | ||
195 | vb_buf->bytes_used += buf->bytesused; | ||
196 | } | ||
197 | } | ||
198 | |||
199 | /* If we've filled the buffer as per the callers res then dispatch it */ | ||
200 | if (vb_buf->bytes_used >= (vb_buf->vb.width * vb_buf->vb.height * 2)) { | ||
201 | dispatch = 1; | ||
202 | vb_buf->bytes_used = 0; | ||
203 | } | ||
204 | |||
205 | /* */ | ||
206 | if (dispatch) { | ||
207 | |||
208 | if (s->pixelformat == V4L2_PIX_FMT_YUYV) { | ||
209 | /* UYVY to YUYV */ | ||
210 | for (i = 0; i < (720 * 480 * 2); i += 2) { | ||
211 | u = *(p + i); | ||
212 | *(p + i) = *(p + i + 1); | ||
213 | *(p + i + 1) = u; | ||
214 | } | ||
215 | } | ||
216 | |||
217 | do_gettimeofday(&vb_buf->vb.ts); | ||
218 | list_del(&vb_buf->vb.queue); | ||
219 | vb_buf->vb.state = VIDEOBUF_DONE; | ||
220 | wake_up(&vb_buf->vb.done); | ||
221 | } | ||
222 | |||
223 | mod_timer(&s->vb_timeout, jiffies + (HZ / 10)); | ||
224 | |||
225 | out: | ||
226 | spin_unlock(&s->vb_lock); | ||
227 | } | ||
161 | 228 | ||
162 | static void cx18_mdl_send_to_alsa(struct cx18 *cx, struct cx18_stream *s, | 229 | static void cx18_mdl_send_to_alsa(struct cx18 *cx, struct cx18_stream *s, |
163 | struct cx18_mdl *mdl) | 230 | struct cx18_mdl *mdl) |
@@ -263,6 +330,9 @@ static void epu_dma_done(struct cx18 *cx, struct cx18_in_work_order *order) | |||
263 | } else { | 330 | } else { |
264 | cx18_enqueue(s, mdl, &s->q_full); | 331 | cx18_enqueue(s, mdl, &s->q_full); |
265 | } | 332 | } |
333 | } else if (s->type == CX18_ENC_STREAM_TYPE_YUV) { | ||
334 | cx18_mdl_send_to_videobuf(s, mdl); | ||
335 | cx18_enqueue(s, mdl, &s->q_free); | ||
266 | } else { | 336 | } else { |
267 | cx18_enqueue(s, mdl, &s->q_full); | 337 | cx18_enqueue(s, mdl, &s->q_full); |
268 | if (s->type == CX18_ENC_STREAM_TYPE_IDX) | 338 | if (s->type == CX18_ENC_STREAM_TYPE_IDX) |