diff options
author | Devin Heitmueller <dheitmueller@kernellabs.com> | 2010-01-18 19:29:51 -0500 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@redhat.com> | 2010-02-26 13:10:43 -0500 |
commit | 9972de904216828c9f9f9d638df52206aa2bacd1 (patch) | |
tree | 6f0fdaa8835a32ad348782debbe3d4a68168237b | |
parent | 8ef22f794ea5577505bc71e468183585f429afde (diff) |
V4L/DVB: cx18: overhaul ALSA PCM device handling so it works
Add code so that the PCM ALSA device actually works, and update the
cx18-streams mechanism so that it passes the data off to the cx18-alsa module.
This work was sponsored by ONELAN Limited.
Signed-off-by: Devin Heitmueller <dheitmueller@kernellabs.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
-rw-r--r-- | drivers/media/video/cx18/cx18-alsa-pcm.c | 243 | ||||
-rw-r--r-- | drivers/media/video/cx18/cx18-alsa-pcm.h | 4 | ||||
-rw-r--r-- | drivers/media/video/cx18/cx18-alsa.h | 4 | ||||
-rw-r--r-- | drivers/media/video/cx18/cx18-driver.h | 3 | ||||
-rw-r--r-- | drivers/media/video/cx18/cx18-mailbox.c | 46 |
5 files changed, 293 insertions, 7 deletions
diff --git a/drivers/media/video/cx18/cx18-alsa-pcm.c b/drivers/media/video/cx18/cx18-alsa-pcm.c index e3157cec5ac3..a6502af0771e 100644 --- a/drivers/media/video/cx18/cx18-alsa-pcm.c +++ b/drivers/media/video/cx18/cx18-alsa-pcm.c | |||
@@ -3,6 +3,9 @@ | |||
3 | * ALSA interface to cx18 PCM capture streams | 3 | * ALSA interface to cx18 PCM capture streams |
4 | * | 4 | * |
5 | * Copyright (C) 2009 Andy Walls <awalls@radix.net> | 5 | * Copyright (C) 2009 Andy Walls <awalls@radix.net> |
6 | * Copyright (C) 2009 Devin Heitmueller <dheitmueller@kernellabs.com> | ||
7 | * | ||
8 | * Portions of this work were sponsored by ONELAN Limited. | ||
6 | * | 9 | * |
7 | * This program is free software; you can redistribute it and/or modify | 10 | * This program is free software; you can redistribute it and/or modify |
8 | * it under the terms of the GNU General Public License as published by | 11 | * it under the terms of the GNU General Public License as published by |
@@ -29,8 +32,44 @@ | |||
29 | #include <sound/pcm.h> | 32 | #include <sound/pcm.h> |
30 | 33 | ||
31 | #include "cx18-driver.h" | 34 | #include "cx18-driver.h" |
35 | #include "cx18-queue.h" | ||
36 | #include "cx18-streams.h" | ||
37 | #include "cx18-fileops.h" | ||
32 | #include "cx18-alsa.h" | 38 | #include "cx18-alsa.h" |
33 | 39 | ||
40 | extern int cx18_alsa_debug; | ||
41 | |||
42 | #define dprintk(fmt, arg...) do { \ | ||
43 | if (cx18_alsa_debug) \ | ||
44 | printk(KERN_INFO "cx18-alsa %s: " fmt, \ | ||
45 | __func__, ##arg); \ | ||
46 | } while (0) | ||
47 | |||
48 | /* Forward Declaration */ | ||
49 | void cx18_alsa_announce_pcm_data(struct snd_cx18_card *cxsc, u8 *pcm_data, | ||
50 | size_t num_bytes); | ||
51 | |||
52 | static struct snd_pcm_hardware snd_cx18_hw_capture = { | ||
53 | .info = SNDRV_PCM_INFO_BLOCK_TRANSFER | | ||
54 | SNDRV_PCM_INFO_MMAP | | ||
55 | SNDRV_PCM_INFO_INTERLEAVED | | ||
56 | SNDRV_PCM_INFO_MMAP_VALID, | ||
57 | |||
58 | .formats = SNDRV_PCM_FMTBIT_S16_LE, | ||
59 | |||
60 | .rates = SNDRV_PCM_RATE_CONTINUOUS | SNDRV_PCM_RATE_KNOT, | ||
61 | |||
62 | .rate_min = 48000, | ||
63 | .rate_max = 48000, | ||
64 | .channels_min = 2, | ||
65 | .channels_max = 2, | ||
66 | .buffer_bytes_max = 62720 * 8, /* just about the value in usbaudio.c */ | ||
67 | .period_bytes_min = 64, /* 12544/2, */ | ||
68 | .period_bytes_max = 12544, | ||
69 | .periods_min = 2, | ||
70 | .periods_max = 98, /* 12544, */ | ||
71 | }; | ||
72 | |||
34 | static int snd_cx18_pcm_capture_open(struct snd_pcm_substream *substream) | 73 | static int snd_cx18_pcm_capture_open(struct snd_pcm_substream *substream) |
35 | { | 74 | { |
36 | struct snd_cx18_card *cxsc = snd_pcm_substream_chip(substream); | 75 | struct snd_cx18_card *cxsc = snd_pcm_substream_chip(substream); |
@@ -38,11 +77,76 @@ static int snd_cx18_pcm_capture_open(struct snd_pcm_substream *substream) | |||
38 | struct v4l2_device *v4l2_dev = cxsc->v4l2_dev; | 77 | struct v4l2_device *v4l2_dev = cxsc->v4l2_dev; |
39 | struct snd_card *sc = cxsc->sc; | 78 | struct snd_card *sc = cxsc->sc; |
40 | struct cx18 *cx = to_cx18(v4l2_dev); | 79 | struct cx18 *cx = to_cx18(v4l2_dev); |
80 | struct cx18_stream *s; | ||
81 | struct cx18_open_id *item; | ||
82 | int ret; | ||
83 | |||
84 | /* Instruct the cx18 to start sending packets */ | ||
85 | s = &cx->streams[CX18_ENC_STREAM_TYPE_PCM]; | ||
86 | |||
87 | /* Allocate memory */ | ||
88 | item = kmalloc(sizeof(struct cx18_open_id), GFP_KERNEL); | ||
89 | if (NULL == item) { | ||
90 | CX18_DEBUG_WARN("nomem on v4l2 open\n"); | ||
91 | return -ENOMEM; | ||
92 | } | ||
93 | item->cx = cx; | ||
94 | item->type = s->type; | ||
95 | item->open_id = cx->open_id++; | ||
96 | |||
97 | /* See if the stream is available */ | ||
98 | if (cx18_claim_stream(item, item->type)) { | ||
99 | /* No, it's already in use */ | ||
100 | return -EBUSY; | ||
101 | } | ||
102 | |||
103 | if (test_bit(CX18_F_S_STREAMOFF, &s->s_flags) || | ||
104 | test_and_set_bit(CX18_F_S_STREAMING, &s->s_flags)) { | ||
105 | /* We're already streaming. No additional action required */ | ||
106 | return 0; | ||
107 | } | ||
108 | |||
109 | |||
110 | runtime->hw = snd_cx18_hw_capture; | ||
111 | snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIODS); | ||
112 | cxsc->capture_pcm_substream = substream; | ||
113 | runtime->private_data = cx; | ||
114 | |||
115 | cx->pcm_announce_callback = cx18_alsa_announce_pcm_data; | ||
116 | |||
117 | /* Not currently streaming, so start it up */ | ||
118 | set_bit(CX18_F_S_STREAMING, &s->s_flags); | ||
119 | ret = cx18_start_v4l2_encode_stream(s); | ||
120 | |||
41 | return 0; | 121 | return 0; |
42 | } | 122 | } |
43 | 123 | ||
44 | static int snd_cx18_pcm_capture_close(struct snd_pcm_substream *substream) | 124 | static int snd_cx18_pcm_capture_close(struct snd_pcm_substream *substream) |
45 | { | 125 | { |
126 | unsigned long flags; | ||
127 | struct snd_cx18_card *cxsc = snd_pcm_substream_chip(substream); | ||
128 | struct v4l2_device *v4l2_dev = cxsc->v4l2_dev; | ||
129 | struct cx18 *cx = to_cx18(v4l2_dev); | ||
130 | struct cx18_stream *s; | ||
131 | int ret; | ||
132 | |||
133 | /* Instruct the cx18 to stop sending packets */ | ||
134 | s = &cx->streams[CX18_ENC_STREAM_TYPE_PCM]; | ||
135 | ret = cx18_stop_v4l2_encode_stream(s, 0); | ||
136 | clear_bit(CX18_F_S_STREAMING, &s->s_flags); | ||
137 | |||
138 | cx18_release_stream(s); | ||
139 | |||
140 | cx->pcm_announce_callback = NULL; | ||
141 | |||
142 | spin_lock_irqsave(&cxsc->slock, flags); | ||
143 | if (substream->runtime->dma_area) { | ||
144 | dprintk("freeing pcm capture region\n"); | ||
145 | vfree(substream->runtime->dma_area); | ||
146 | substream->runtime->dma_area = NULL; | ||
147 | } | ||
148 | spin_unlock_irqrestore(&cxsc->slock, flags); | ||
149 | |||
46 | return 0; | 150 | return 0; |
47 | } | 151 | } |
48 | 152 | ||
@@ -52,9 +156,37 @@ static int snd_cx18_pcm_ioctl(struct snd_pcm_substream *substream, | |||
52 | return snd_pcm_lib_ioctl(substream, cmd, arg); | 156 | return snd_pcm_lib_ioctl(substream, cmd, arg); |
53 | } | 157 | } |
54 | 158 | ||
159 | |||
160 | static int snd_pcm_alloc_vmalloc_buffer(struct snd_pcm_substream *subs, | ||
161 | size_t size) | ||
162 | { | ||
163 | struct snd_pcm_runtime *runtime = subs->runtime; | ||
164 | |||
165 | dprintk("Allocating vbuffer\n"); | ||
166 | if (runtime->dma_area) { | ||
167 | if (runtime->dma_bytes > size) | ||
168 | return 0; | ||
169 | |||
170 | vfree(runtime->dma_area); | ||
171 | } | ||
172 | runtime->dma_area = vmalloc(size); | ||
173 | if (!runtime->dma_area) | ||
174 | return -ENOMEM; | ||
175 | |||
176 | runtime->dma_bytes = size; | ||
177 | |||
178 | return 0; | ||
179 | } | ||
180 | |||
55 | static int snd_cx18_pcm_hw_params(struct snd_pcm_substream *substream, | 181 | static int snd_cx18_pcm_hw_params(struct snd_pcm_substream *substream, |
56 | struct snd_pcm_hw_params *params) | 182 | struct snd_pcm_hw_params *params) |
57 | { | 183 | { |
184 | int ret; | ||
185 | |||
186 | dprintk("%s called\n", __func__); | ||
187 | |||
188 | ret = snd_pcm_alloc_vmalloc_buffer(substream, | ||
189 | params_buffer_bytes(params)); | ||
58 | return 0; | 190 | return 0; |
59 | } | 191 | } |
60 | 192 | ||
@@ -65,6 +197,11 @@ static int snd_cx18_pcm_hw_free(struct snd_pcm_substream *substream) | |||
65 | 197 | ||
66 | static int snd_cx18_pcm_prepare(struct snd_pcm_substream *substream) | 198 | static int snd_cx18_pcm_prepare(struct snd_pcm_substream *substream) |
67 | { | 199 | { |
200 | struct snd_cx18_card *cxsc = snd_pcm_substream_chip(substream); | ||
201 | |||
202 | cxsc->hwptr_done_capture = 0; | ||
203 | cxsc->capture_transfer_done = 0; | ||
204 | |||
68 | return 0; | 205 | return 0; |
69 | } | 206 | } |
70 | 207 | ||
@@ -76,7 +213,24 @@ static int snd_cx18_pcm_trigger(struct snd_pcm_substream *substream, int cmd) | |||
76 | static | 213 | static |
77 | snd_pcm_uframes_t snd_cx18_pcm_pointer(struct snd_pcm_substream *substream) | 214 | snd_pcm_uframes_t snd_cx18_pcm_pointer(struct snd_pcm_substream *substream) |
78 | { | 215 | { |
79 | return 0; | 216 | unsigned long flags; |
217 | snd_pcm_uframes_t hwptr_done; | ||
218 | struct snd_cx18_card *cxsc = snd_pcm_substream_chip(substream); | ||
219 | |||
220 | spin_lock_irqsave(&cxsc->slock, flags); | ||
221 | hwptr_done = cxsc->hwptr_done_capture; | ||
222 | spin_unlock_irqrestore(&cxsc->slock, flags); | ||
223 | |||
224 | return hwptr_done; | ||
225 | } | ||
226 | |||
227 | |||
228 | static struct page *snd_pcm_get_vmalloc_page(struct snd_pcm_substream *subs, | ||
229 | unsigned long offset) | ||
230 | { | ||
231 | void *pageptr = subs->runtime->dma_area + offset; | ||
232 | |||
233 | return vmalloc_to_page(pageptr); | ||
80 | } | 234 | } |
81 | 235 | ||
82 | static struct snd_pcm_ops snd_cx18_pcm_capture_ops = { | 236 | static struct snd_pcm_ops snd_cx18_pcm_capture_ops = { |
@@ -88,9 +242,86 @@ static struct snd_pcm_ops snd_cx18_pcm_capture_ops = { | |||
88 | .prepare = snd_cx18_pcm_prepare, | 242 | .prepare = snd_cx18_pcm_prepare, |
89 | .trigger = snd_cx18_pcm_trigger, | 243 | .trigger = snd_cx18_pcm_trigger, |
90 | .pointer = snd_cx18_pcm_pointer, | 244 | .pointer = snd_cx18_pcm_pointer, |
245 | .page = snd_pcm_get_vmalloc_page, | ||
91 | }; | 246 | }; |
92 | 247 | ||
93 | int __init snd_cx18_pcm_create(struct snd_cx18_card *cxsc) | 248 | void cx18_alsa_announce_pcm_data(struct snd_cx18_card *cxsc, u8 *pcm_data, |
249 | size_t num_bytes) | ||
250 | { | ||
251 | struct snd_pcm_substream *substream; | ||
252 | struct snd_pcm_runtime *runtime; | ||
253 | unsigned int oldptr; | ||
254 | unsigned int stride; | ||
255 | int period_elapsed = 0; | ||
256 | int length; | ||
257 | |||
258 | dprintk("cx18 alsa announce ptr=%p data=%p num_bytes=%d\n", cxsc, | ||
259 | pcm_data, num_bytes); | ||
260 | |||
261 | substream = cxsc->capture_pcm_substream; | ||
262 | if (substream == NULL) { | ||
263 | dprintk("substream was NULL\n"); | ||
264 | return; | ||
265 | } | ||
266 | |||
267 | runtime = substream->runtime; | ||
268 | if (runtime == NULL) { | ||
269 | dprintk("runtime was NULL\n"); | ||
270 | return; | ||
271 | } | ||
272 | |||
273 | stride = runtime->frame_bits >> 3; | ||
274 | if (stride == 0) { | ||
275 | dprintk("stride is zero\n"); | ||
276 | return; | ||
277 | } | ||
278 | |||
279 | length = num_bytes / stride; | ||
280 | if (length == 0) { | ||
281 | dprintk("%s: length was zero\n", __func__); | ||
282 | return; | ||
283 | } | ||
284 | |||
285 | if (runtime->dma_area == NULL) { | ||
286 | dprintk("dma area was NULL - ignoring\n"); | ||
287 | return; | ||
288 | } | ||
289 | |||
290 | oldptr = cxsc->hwptr_done_capture; | ||
291 | if (oldptr + length >= runtime->buffer_size) { | ||
292 | unsigned int cnt = | ||
293 | runtime->buffer_size - oldptr; | ||
294 | memcpy(runtime->dma_area + oldptr * stride, pcm_data, | ||
295 | cnt * stride); | ||
296 | memcpy(runtime->dma_area, pcm_data + cnt * stride, | ||
297 | length * stride - cnt * stride); | ||
298 | } else { | ||
299 | memcpy(runtime->dma_area + oldptr * stride, pcm_data, | ||
300 | length * stride); | ||
301 | } | ||
302 | snd_pcm_stream_lock(substream); | ||
303 | |||
304 | cxsc->hwptr_done_capture += length; | ||
305 | if (cxsc->hwptr_done_capture >= | ||
306 | runtime->buffer_size) | ||
307 | cxsc->hwptr_done_capture -= | ||
308 | runtime->buffer_size; | ||
309 | |||
310 | cxsc->capture_transfer_done += length; | ||
311 | if (cxsc->capture_transfer_done >= | ||
312 | runtime->period_size) { | ||
313 | cxsc->capture_transfer_done -= | ||
314 | runtime->period_size; | ||
315 | period_elapsed = 1; | ||
316 | } | ||
317 | |||
318 | snd_pcm_stream_unlock(substream); | ||
319 | |||
320 | if (period_elapsed) | ||
321 | snd_pcm_period_elapsed(substream); | ||
322 | } | ||
323 | |||
324 | int snd_cx18_pcm_create(struct snd_cx18_card *cxsc) | ||
94 | { | 325 | { |
95 | struct snd_pcm *sp; | 326 | struct snd_pcm *sp; |
96 | struct snd_card *sc = cxsc->sc; | 327 | struct snd_card *sc = cxsc->sc; |
@@ -108,6 +339,14 @@ int __init snd_cx18_pcm_create(struct snd_cx18_card *cxsc) | |||
108 | __func__, ret); | 339 | __func__, ret); |
109 | goto err_exit; | 340 | goto err_exit; |
110 | } | 341 | } |
342 | |||
343 | spin_lock_init(&cxsc->slock); | ||
344 | |||
345 | snd_pcm_set_ops(sp, SNDRV_PCM_STREAM_CAPTURE, &snd_cx18_pcm_capture_ops); | ||
346 | sp->info_flags = 0; | ||
347 | sp->private_data = cxsc; | ||
348 | strcpy(sp->name, "Conexant cx23418 Capture"); | ||
349 | |||
111 | return 0; | 350 | return 0; |
112 | 351 | ||
113 | err_exit: | 352 | err_exit: |
diff --git a/drivers/media/video/cx18/cx18-alsa-pcm.h b/drivers/media/video/cx18/cx18-alsa-pcm.h index ff47a1ebe800..325662c647a0 100644 --- a/drivers/media/video/cx18/cx18-alsa-pcm.h +++ b/drivers/media/video/cx18/cx18-alsa-pcm.h | |||
@@ -21,3 +21,7 @@ | |||
21 | */ | 21 | */ |
22 | 22 | ||
23 | int __init snd_cx18_pcm_create(struct snd_cx18_card *cxsc); | 23 | int __init snd_cx18_pcm_create(struct snd_cx18_card *cxsc); |
24 | |||
25 | /* Used by cx18-mailbox to announce the PCM data to the module */ | ||
26 | void cx18_alsa_announce_pcm_data(struct snd_cx18_card *card, u8 *pcm_data, | ||
27 | size_t num_bytes); | ||
diff --git a/drivers/media/video/cx18/cx18-alsa.h b/drivers/media/video/cx18/cx18-alsa.h index ea8576fd5786..2546779b7313 100644 --- a/drivers/media/video/cx18/cx18-alsa.h +++ b/drivers/media/video/cx18/cx18-alsa.h | |||
@@ -24,6 +24,10 @@ struct snd_card; | |||
24 | struct snd_cx18_card { | 24 | struct snd_cx18_card { |
25 | struct v4l2_device *v4l2_dev; | 25 | struct v4l2_device *v4l2_dev; |
26 | struct snd_card *sc; | 26 | struct snd_card *sc; |
27 | unsigned int capture_transfer_done; | ||
28 | unsigned int hwptr_done_capture; | ||
29 | struct snd_pcm_substream *capture_pcm_substream; | ||
30 | spinlock_t slock; | ||
27 | }; | 31 | }; |
28 | 32 | ||
29 | extern int cx18_alsa_debug; | 33 | extern int cx18_alsa_debug; |
diff --git a/drivers/media/video/cx18/cx18-driver.h b/drivers/media/video/cx18/cx18-driver.h index fcb99531dab3..22634cf6a96a 100644 --- a/drivers/media/video/cx18/cx18-driver.h +++ b/drivers/media/video/cx18/cx18-driver.h | |||
@@ -575,6 +575,9 @@ struct cx18 { | |||
575 | int stream_buf_size[CX18_MAX_STREAMS]; /* Stream buffer size */ | 575 | int stream_buf_size[CX18_MAX_STREAMS]; /* Stream buffer size */ |
576 | struct cx18_stream streams[CX18_MAX_STREAMS]; /* Stream data */ | 576 | struct cx18_stream streams[CX18_MAX_STREAMS]; /* Stream data */ |
577 | struct snd_cx18_card *alsa; /* ALSA interface for PCM capture stream */ | 577 | struct snd_cx18_card *alsa; /* ALSA interface for PCM capture stream */ |
578 | void (*pcm_announce_callback)(struct snd_cx18_card *card, u8 *pcm_data, | ||
579 | size_t num_bytes); | ||
580 | |||
578 | unsigned long i_flags; /* global cx18 flags */ | 581 | unsigned long i_flags; /* global cx18 flags */ |
579 | atomic_t ana_capturing; /* count number of active analog capture streams */ | 582 | atomic_t ana_capturing; /* count number of active analog capture streams */ |
580 | atomic_t tot_capturing; /* total count number of active capture streams */ | 583 | atomic_t tot_capturing; /* total count number of active capture streams */ |
diff --git a/drivers/media/video/cx18/cx18-mailbox.c b/drivers/media/video/cx18/cx18-mailbox.c index 0ac0e2c993a5..6dcce297752f 100644 --- a/drivers/media/video/cx18/cx18-mailbox.c +++ b/drivers/media/video/cx18/cx18-mailbox.c | |||
@@ -29,6 +29,7 @@ | |||
29 | #include "cx18-mailbox.h" | 29 | #include "cx18-mailbox.h" |
30 | #include "cx18-queue.h" | 30 | #include "cx18-queue.h" |
31 | #include "cx18-streams.h" | 31 | #include "cx18-streams.h" |
32 | #include "cx18-alsa-pcm.h" /* FIXME make configurable */ | ||
32 | 33 | ||
33 | static const char *rpu_str[] = { "APU", "CPU", "EPU", "HPU" }; | 34 | static const char *rpu_str[] = { "APU", "CPU", "EPU", "HPU" }; |
34 | 35 | ||
@@ -157,6 +158,34 @@ static void cx18_mdl_send_to_dvb(struct cx18_stream *s, struct cx18_mdl *mdl) | |||
157 | } | 158 | } |
158 | } | 159 | } |
159 | 160 | ||
161 | |||
162 | static void cx18_mdl_send_to_alsa(struct cx18 *cx, struct cx18_stream *s, | ||
163 | struct cx18_mdl *mdl) | ||
164 | { | ||
165 | struct cx18_buffer *buf; | ||
166 | |||
167 | if (mdl->bytesused == 0) | ||
168 | return; | ||
169 | |||
170 | /* We ignore mdl and buf readpos accounting here - it doesn't matter */ | ||
171 | |||
172 | /* The likely case */ | ||
173 | if (list_is_singular(&mdl->buf_list)) { | ||
174 | buf = list_first_entry(&mdl->buf_list, struct cx18_buffer, | ||
175 | list); | ||
176 | if (buf->bytesused) | ||
177 | cx->pcm_announce_callback(cx->alsa, buf->buf, | ||
178 | buf->bytesused); | ||
179 | return; | ||
180 | } | ||
181 | |||
182 | list_for_each_entry(buf, &mdl->buf_list, list) { | ||
183 | if (buf->bytesused == 0) | ||
184 | break; | ||
185 | cx->pcm_announce_callback(cx->alsa, buf->buf, buf->bytesused); | ||
186 | } | ||
187 | } | ||
188 | |||
160 | static void epu_dma_done(struct cx18 *cx, struct cx18_in_work_order *order) | 189 | static void epu_dma_done(struct cx18 *cx, struct cx18_in_work_order *order) |
161 | { | 190 | { |
162 | u32 handle, mdl_ack_count, id; | 191 | u32 handle, mdl_ack_count, id; |
@@ -223,15 +252,22 @@ static void epu_dma_done(struct cx18 *cx, struct cx18_in_work_order *order) | |||
223 | CX18_DEBUG_HI_DMA("%s recv bytesused = %d\n", | 252 | CX18_DEBUG_HI_DMA("%s recv bytesused = %d\n", |
224 | s->name, mdl->bytesused); | 253 | s->name, mdl->bytesused); |
225 | 254 | ||
226 | if (s->type != CX18_ENC_STREAM_TYPE_TS) { | 255 | if (s->type == CX18_ENC_STREAM_TYPE_TS) { |
256 | cx18_mdl_send_to_dvb(s, mdl); | ||
257 | cx18_enqueue(s, mdl, &s->q_free); | ||
258 | } else if (s->type == CX18_ENC_STREAM_TYPE_PCM) { | ||
259 | /* Pass the data to cx18-alsa */ | ||
260 | if (cx->pcm_announce_callback != NULL) { | ||
261 | cx18_mdl_send_to_alsa(cx, s, mdl); | ||
262 | cx18_enqueue(s, mdl, &s->q_free); | ||
263 | } else { | ||
264 | cx18_enqueue(s, mdl, &s->q_full); | ||
265 | } | ||
266 | } else { | ||
227 | cx18_enqueue(s, mdl, &s->q_full); | 267 | cx18_enqueue(s, mdl, &s->q_full); |
228 | if (s->type == CX18_ENC_STREAM_TYPE_IDX) | 268 | if (s->type == CX18_ENC_STREAM_TYPE_IDX) |
229 | cx18_stream_rotate_idx_mdls(cx); | 269 | cx18_stream_rotate_idx_mdls(cx); |
230 | } | 270 | } |
231 | else { | ||
232 | cx18_mdl_send_to_dvb(s, mdl); | ||
233 | cx18_enqueue(s, mdl, &s->q_free); | ||
234 | } | ||
235 | } | 271 | } |
236 | /* Put as many MDLs as possible back into fw use */ | 272 | /* Put as many MDLs as possible back into fw use */ |
237 | cx18_stream_load_fw_queue(s); | 273 | cx18_stream_load_fw_queue(s); |