aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/video/cx18/cx18-mailbox.c
diff options
context:
space:
mode:
authorSteven Toth <stoth@kernellabs.com>2011-04-06 07:32:56 -0400
committerMauro Carvalho Chehab <mchehab@redhat.com>2011-05-20 08:28:43 -0400
commitb7101de3fff596b35e45cd9fb7007caa07e97c9a (patch)
tree1c11baca827c290a1e312180204e8dc0472eabb9 /drivers/media/video/cx18/cx18-mailbox.c
parent5ed9bd02444a00bb1e8ecc1baa8ecdb633afc126 (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.c70
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
162static 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
225out:
226 spin_unlock(&s->vb_lock);
227}
161 228
162static void cx18_mdl_send_to_alsa(struct cx18 *cx, struct cx18_stream *s, 229static 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)