Merge lp:~ubuntu-branches/ubuntu/precise/alsa-plugins/precise-201110201606 into lp:ubuntu/precise/alsa-plugins

Proposed by Ubuntu Package Importer
Status: Needs review
Proposed branch: lp:~ubuntu-branches/ubuntu/precise/alsa-plugins/precise-201110201606
Merge into: lp:ubuntu/precise/alsa-plugins
Diff against target: 888 lines (+820/-0) (has conflicts)
6 files modified
.pc/0006-handle-new-libav.patch/a52/pcm_a52.c (+757/-0)
.pc/applied-patches (+1/-0)
a52/pcm_a52.c (+18/-0)
debian/changelog (+11/-0)
debian/patches/0006-handle-new-libav.patch (+32/-0)
debian/patches/series (+1/-0)
Text conflict in a52/pcm_a52.c
Text conflict in debian/changelog
To merge this branch: bzr merge lp:~ubuntu-branches/ubuntu/precise/alsa-plugins/precise-201110201606
Reviewer Review Type Date Requested Status
Ubuntu branches Pending
Review via email: mp+79978@code.launchpad.net

Description of the change

The package importer has detected a possible inconsistency between the package history in the archive and the history in bzr. As the archive is authoritative the importer has made lp:ubuntu/precise/alsa-plugins reflect what is in the archive and the old bzr branch has been pushed to lp:~ubuntu-branches/ubuntu/precise/alsa-plugins/precise-201110201606. This merge proposal was created so that an Ubuntu developer can review the situations and perform a merge/upload if necessary. There are three typical cases where this can happen.
  1. Where someone pushes a change to bzr and someone else uploads the package without that change. This is the reason that this check is done by the importer. If this appears to be the case then a merge/upload should be done if the changes that were in bzr are still desirable.
  2. The importer incorrectly detected the above situation when someone made a change in bzr and then uploaded it.
  3. The importer incorrectly detected the above situation when someone just uploaded a package and didn't touch bzr.

If this case doesn't appear to be the first situation then set the status of the merge proposal to "Rejected" and help avoid the problem in future by filing a bug at https://bugs.launchpad.net/udd linking to this merge proposal.

(this is an automatically generated message)

To post a comment you must log in.

Unmerged revisions

49. By Daniel T Chen

debian/patches/0006-handle-new-libav.patch: Backport upstream git
commits 40c129a and 826dafa so that the a52 plugin works again.
(LP: #872871)

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== added directory '.pc/0006-handle-new-libav.patch'
2=== added directory '.pc/0006-handle-new-libav.patch/a52'
3=== added file '.pc/0006-handle-new-libav.patch/a52/pcm_a52.c'
4--- .pc/0006-handle-new-libav.patch/a52/pcm_a52.c 1970-01-01 00:00:00 +0000
5+++ .pc/0006-handle-new-libav.patch/a52/pcm_a52.c 2011-10-20 16:12:25 +0000
6@@ -0,0 +1,757 @@
7+/*
8+ * A52 Output Plugin
9+ *
10+ * Copyright (c) 2006 by Takashi Iwai <tiwai@suse.de>
11+ *
12+ * This library is free software; you can redistribute it and/or modify
13+ * it under the terms of the GNU Lesser General Public License as
14+ * published by the Free Software Foundation; either version 2.1 of
15+ * the License, or (at your option) any later version.
16+ *
17+ * This program is distributed in the hope that it will be useful,
18+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
19+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20+ * GNU Lesser General Public License for more details.
21+ *
22+ * You should have received a copy of the GNU Lesser General Public
23+ * License along with this library; if not, write to the Free Software
24+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
25+ */
26+
27+#include <stdio.h>
28+#include <string.h>
29+#define __USE_XOPEN
30+#include <unistd.h>
31+#include <alsa/asoundlib.h>
32+#include <alsa/pcm_external.h>
33+#include <alsa/pcm_plugin.h>
34+#include AVCODEC_HEADER
35+
36+struct a52_ctx {
37+ snd_pcm_ioplug_t io;
38+ snd_pcm_t *slave;
39+ AVCodec *codec;
40+ AVCodecContext *avctx;
41+ snd_pcm_format_t format;
42+ unsigned int channels;
43+ unsigned int rate;
44+ unsigned int bitrate;
45+ short *inbuf;
46+ unsigned char *outbuf;
47+ int outbuf_size;
48+ snd_pcm_uframes_t transfer;
49+ int remain;
50+ int filled;
51+ unsigned int slave_period_size;
52+ unsigned int slave_buffer_size;
53+ snd_pcm_hw_params_t *hw_params;
54+};
55+
56+/* convert the PCM data to A52 stream in IEC958 */
57+static void convert_data(struct a52_ctx *rec)
58+{
59+ int out_bytes;
60+
61+ out_bytes = avcodec_encode_audio(rec->avctx, rec->outbuf + 8,
62+ rec->outbuf_size - 8,
63+ rec->inbuf);
64+ rec->outbuf[0] = 0xf8; /* sync words */
65+ rec->outbuf[1] = 0x72;
66+ rec->outbuf[2] = 0x4e;
67+ rec->outbuf[3] = 0x1f;
68+ rec->outbuf[4] = rec->outbuf[13] & 7; /* bsmod */
69+ rec->outbuf[5] = 0x01; /* data type */
70+ rec->outbuf[6] = ((out_bytes * 8) >> 8) & 0xff;
71+ rec->outbuf[7] = (out_bytes * 8) & 0xff;
72+ /* swap bytes for little-endian 16bit */
73+ if (rec->format == SND_PCM_FORMAT_S16_LE)
74+ swab(rec->outbuf, rec->outbuf, out_bytes + 8);
75+ memset(rec->outbuf + 8 + out_bytes, 0,
76+ rec->outbuf_size - 8 - out_bytes);
77+ rec->remain = rec->outbuf_size / 4;
78+ rec->filled = 0;
79+}
80+
81+/* write pending encoded data to the slave pcm */
82+static int write_out_pending(snd_pcm_ioplug_t *io, struct a52_ctx *rec)
83+{
84+ int err, ofs = 0;
85+
86+ if (! rec->remain)
87+ return 0;
88+
89+ while (rec->remain) {
90+ err = snd_pcm_writei(rec->slave, rec->outbuf + ofs, rec->remain);
91+ if (err < 0) {
92+ if (err == -EPIPE)
93+ io->state = SND_PCM_STATE_XRUN;
94+ return err;
95+ } else if (! err)
96+ break;
97+ if (err < rec->remain)
98+ ofs += (rec->remain - err) * 4;
99+ rec->remain -= err;
100+ }
101+ if (rec->remain && ofs)
102+ memmove(rec->outbuf, rec->outbuf + ofs, rec->remain * 4);
103+ return 0;
104+}
105+
106+/*
107+ * drain callback
108+ */
109+static int a52_drain(snd_pcm_ioplug_t *io)
110+{
111+ struct a52_ctx *rec = io->private_data;
112+ int err;
113+
114+ if (rec->filled) {
115+ if ((err = write_out_pending(io, rec)) < 0)
116+ return err;
117+ /* remaining data must be converted and sent out */
118+ memset(rec->inbuf + rec->filled * io->channels, 0,
119+ (rec->avctx->frame_size - rec->filled) * io->channels * 2);
120+ convert_data(rec);
121+ }
122+ err = write_out_pending(io, rec);
123+ if (err < 0)
124+ return err;
125+ snd_pcm_drain(rec->slave);
126+ return 0;
127+}
128+
129+/* check whether the areas consist of a continuous interleaved stream */
130+static int check_interleaved(const snd_pcm_channel_area_t *areas,
131+ unsigned int channels)
132+{
133+ unsigned int ch;
134+
135+ if (channels > 4) /* we need re-routing for 6 channels */
136+ return 0;
137+
138+ for (ch = 0; ch < channels; ch++) {
139+ if (areas[ch].addr != areas[0].addr ||
140+ areas[ch].first != ch * 16 ||
141+ areas[ch].step != channels * 16)
142+ return 0;
143+ }
144+ return 1;
145+}
146+
147+/* Fill the input PCM to the internal buffer until a52 frames,
148+ * then covert and write it out.
149+ *
150+ * Returns the number of processed frames.
151+ */
152+static int fill_data(snd_pcm_ioplug_t *io,
153+ const snd_pcm_channel_area_t *areas,
154+ unsigned int offset, unsigned int size,
155+ int interleaved)
156+{
157+ struct a52_ctx *rec = io->private_data;
158+ unsigned int len = rec->avctx->frame_size - rec->filled;
159+ short *src, *dst;
160+ unsigned int src_step;
161+ int err;
162+
163+ if ((err = write_out_pending(io, rec)) < 0)
164+ return err;
165+
166+ if (size > len)
167+ size = len;
168+
169+ dst = rec->inbuf + rec->filled * io->channels;
170+ if (interleaved) {
171+ memcpy(dst, areas->addr + offset * io->channels * 2,
172+ size * io->channels * 2);
173+ } else {
174+ unsigned int i, ch, dst_step;
175+ short *dst1;
176+ static unsigned int ch_index[3][6] = {
177+ { 0, 1 },
178+ { 0, 1, 2, 3 },
179+#if LIBAVCODEC_VERSION_MAJOR > 52 || (LIBAVCODEC_VERSION_MAJOR == 52 && LIBAVCODEC_VERSION_MINOR >= 26)
180+ /* current libavcodec expects SMPTE order */
181+ { 0, 1, 4, 5, 2, 3 },
182+#else
183+ /* libavcodec older than r18540 expects A52 order */
184+ { 0, 4, 1, 2, 3, 5 },
185+#endif
186+ };
187+ /* flatten copy to n-channel interleaved */
188+ dst_step = io->channels;
189+ for (ch = 0; ch < io->channels; ch++, dst++) {
190+ const snd_pcm_channel_area_t *ap;
191+ ap = &areas[ch_index[io->channels / 2 - 1][ch]];
192+ dst1 = dst;
193+ src = (short *)(ap->addr +
194+ (ap->first + offset * ap->step) / 8);
195+ src_step = ap->step / 16; /* in word */
196+ for (i = 0; i < size; i++) {
197+ *dst1 = *src;
198+ src += src_step;
199+ dst1 += dst_step;
200+ }
201+ }
202+ }
203+ rec->filled += size;
204+ if (rec->filled == rec->avctx->frame_size) {
205+ convert_data(rec);
206+ write_out_pending(io, rec);
207+ }
208+ return (int)size;
209+}
210+
211+/*
212+ * transfer callback
213+ */
214+static snd_pcm_sframes_t a52_transfer(snd_pcm_ioplug_t *io,
215+ const snd_pcm_channel_area_t *areas,
216+ snd_pcm_uframes_t offset,
217+ snd_pcm_uframes_t size)
218+{
219+ struct a52_ctx *rec = io->private_data;
220+ snd_pcm_sframes_t result = 0;
221+ int err = 0;
222+ int interleaved = check_interleaved(areas, io->channels);
223+
224+ do {
225+ err = fill_data(io, areas, offset, size, interleaved);
226+ if (err < 0)
227+ break;
228+ offset += (unsigned int)err;
229+ size -= (unsigned int)err;
230+ result += err;
231+ rec->transfer += err;
232+ } while (size);
233+ return result > 0 ? result : err;
234+}
235+
236+/*
237+ * pointer callback
238+ *
239+ * Calculate the current position from the delay of slave PCM
240+ */
241+static snd_pcm_sframes_t a52_pointer(snd_pcm_ioplug_t *io)
242+{
243+ struct a52_ctx *rec = io->private_data;
244+ snd_pcm_sframes_t delay;
245+ snd_pcm_state_t state;
246+ int err;
247+
248+ state = snd_pcm_state(rec->slave);
249+ switch (state) {
250+ case SND_PCM_STATE_RUNNING:
251+ case SND_PCM_STATE_DRAINING:
252+ if ((err = snd_pcm_delay(rec->slave, &delay)) < 0)
253+ return err;
254+ break;
255+ case SND_PCM_STATE_XRUN:
256+ case SND_PCM_STATE_SUSPENDED:
257+ return -EPIPE;
258+ default:
259+ return 0;
260+ }
261+
262+ if (delay < 0 || delay >= (snd_pcm_sframes_t)rec->slave_buffer_size)
263+ delay = 0;
264+ delay = (snd_pcm_sframes_t)io->appl_ptr - delay;
265+ if (delay < 0) {
266+ delay += io->buffer_size;
267+ if (delay < 0)
268+ delay = 0;
269+ }
270+ delay %= io->buffer_size;
271+ return delay;
272+}
273+
274+/* set up the fixed parameters of slave PCM hw_parmas */
275+static int a52_slave_hw_params_half(struct a52_ctx *rec)
276+{
277+ int err;
278+
279+ if ((err = snd_pcm_hw_params_malloc(&rec->hw_params)) < 0)
280+ return err;
281+
282+ if ((err = snd_pcm_hw_params_any(rec->slave, rec->hw_params)) < 0) {
283+ SNDERR("Cannot get slave hw_params");
284+ goto out;
285+ }
286+ if ((err = snd_pcm_hw_params_set_access(rec->slave, rec->hw_params,
287+ SND_PCM_ACCESS_RW_INTERLEAVED)) < 0) {
288+ SNDERR("Cannot set slave access RW_INTERLEAVED");
289+ goto out;
290+ }
291+ if ((err = snd_pcm_hw_params_set_channels(rec->slave, rec->hw_params, 2)) < 0) {
292+ SNDERR("Cannot set slave channels 2");
293+ goto out;
294+ }
295+ if ((err = snd_pcm_hw_params_set_format(rec->slave, rec->hw_params,
296+ rec->format)) < 0) {
297+ SNDERR("Cannot set slave format");
298+ goto out;
299+ }
300+ if ((err = snd_pcm_hw_params_set_rate(rec->slave, rec->hw_params, rec->rate, 0)) < 0) {
301+ SNDERR("Cannot set slave rate %d", rec->rate);
302+ goto out;
303+ }
304+ return 0;
305+
306+ out:
307+ free(rec->hw_params);
308+ rec->hw_params = NULL;
309+ return err;
310+}
311+
312+/*
313+ * hw_params callback
314+ *
315+ * Set up slave PCM according to the current parameters
316+ */
317+static int a52_hw_params(snd_pcm_ioplug_t *io,
318+ snd_pcm_hw_params_t *params ATTRIBUTE_UNUSED)
319+{
320+ struct a52_ctx *rec = io->private_data;
321+ snd_pcm_uframes_t period_size;
322+ snd_pcm_uframes_t buffer_size;
323+ int err;
324+
325+ if (! rec->hw_params) {
326+ err = a52_slave_hw_params_half(rec);
327+ if (err < 0)
328+ return err;
329+ }
330+ period_size = io->period_size;
331+ if ((err = snd_pcm_hw_params_set_period_size_near(rec->slave, rec->hw_params,
332+ &period_size, NULL)) < 0) {
333+ SNDERR("Cannot set slave period size %ld", period_size);
334+ return err;
335+ }
336+ buffer_size = io->buffer_size;
337+ if ((err = snd_pcm_hw_params_set_buffer_size_near(rec->slave, rec->hw_params,
338+ &buffer_size)) < 0) {
339+ SNDERR("Cannot set slave buffer size %ld", buffer_size);
340+ return err;
341+ }
342+ if ((err = snd_pcm_hw_params(rec->slave, rec->hw_params)) < 0) {
343+ SNDERR("Cannot set slave hw_params");
344+ return err;
345+ }
346+ rec->slave_period_size = period_size;
347+ rec->slave_buffer_size = buffer_size;
348+
349+ return 0;
350+}
351+
352+/*
353+ * hw_free callback
354+ */
355+static int a52_hw_free(snd_pcm_ioplug_t *io)
356+{
357+ struct a52_ctx *rec = io->private_data;
358+
359+ free(rec->hw_params);
360+ rec->hw_params = NULL;
361+ return snd_pcm_hw_free(rec->slave);
362+}
363+
364+/*
365+ * sw_params callback
366+ *
367+ * Set up slave PCM sw_params
368+ */
369+static int a52_sw_params(snd_pcm_ioplug_t *io, snd_pcm_sw_params_t *params)
370+{
371+ struct a52_ctx *rec = io->private_data;
372+ snd_pcm_sw_params_t *sparams;
373+ snd_pcm_uframes_t avail_min, start_threshold;
374+ int len;
375+
376+ snd_pcm_sw_params_get_avail_min(params, &avail_min);
377+ snd_pcm_sw_params_get_start_threshold(params, &start_threshold);
378+
379+ len = avail_min;
380+ len += (int)rec->slave_buffer_size - (int)io->buffer_size;
381+ if (len < 0)
382+ avail_min = 1;
383+ else
384+ avail_min = len;
385+ snd_pcm_sw_params_alloca(&sparams);
386+ snd_pcm_sw_params_current(rec->slave, sparams);
387+ snd_pcm_sw_params_set_avail_min(rec->slave, sparams, avail_min);
388+ snd_pcm_sw_params_set_start_threshold(rec->slave, sparams,
389+ start_threshold);
390+
391+ return snd_pcm_sw_params(rec->slave, sparams);
392+}
393+
394+/*
395+ * start and stop callbacks - just trigger slave PCM
396+ */
397+static int a52_start(snd_pcm_ioplug_t *io)
398+{
399+ struct a52_ctx *rec = io->private_data;
400+
401+ snd_pcm_start(rec->slave);
402+ return 0;
403+}
404+
405+static int a52_stop(snd_pcm_ioplug_t *io)
406+{
407+ struct a52_ctx *rec = io->private_data;
408+
409+ snd_pcm_drop(rec->slave);
410+ return 0;
411+}
412+
413+/* release resources */
414+static void a52_free(struct a52_ctx *rec)
415+{
416+ if (rec->avctx) {
417+ avcodec_close(rec->avctx);
418+ av_free(rec->avctx);
419+ rec->avctx = NULL;
420+ }
421+ free(rec->inbuf);
422+ rec->inbuf = NULL;
423+ free(rec->outbuf);
424+ rec->outbuf = NULL;
425+}
426+
427+/*
428+ * prepare callback
429+ *
430+ * Allocate internal buffers and set up libavcodec
431+ */
432+static int a52_prepare(snd_pcm_ioplug_t *io)
433+{
434+ struct a52_ctx *rec = io->private_data;
435+
436+ a52_free(rec);
437+
438+ rec->avctx = avcodec_alloc_context();
439+ if (! rec->avctx)
440+ return -ENOMEM;
441+
442+ rec->avctx->bit_rate = rec->bitrate * 1000;
443+ rec->avctx->sample_rate = io->rate;
444+ rec->avctx->channels = io->channels;
445+#if LIBAVCODEC_VERSION_MAJOR > 52 || (LIBAVCODEC_VERSION_MAJOR == 52 && LIBAVCODEC_VERSION_MINOR >= 3)
446+ switch (io->channels) {
447+ case 2:
448+ rec->avctx->channel_layout = CH_LAYOUT_STEREO;
449+ break;
450+ case 4:
451+ rec->avctx->channel_layout = CH_LAYOUT_QUAD;
452+ break;
453+ case 6:
454+ rec->avctx->channel_layout = CH_LAYOUT_5POINT1;
455+ break;
456+ default:
457+ break;
458+ }
459+#endif
460+
461+ if (avcodec_open(rec->avctx, rec->codec) < 0)
462+ return -EINVAL;
463+
464+ rec->inbuf = malloc(rec->avctx->frame_size * 2 * io->channels);
465+ if (! rec->inbuf)
466+ return -ENOMEM;
467+ rec->outbuf_size = rec->avctx->frame_size * 4;
468+ rec->outbuf = malloc(rec->outbuf_size);
469+ if (! rec->outbuf)
470+ return -ENOMEM;
471+
472+ rec->transfer = 0;
473+ rec->remain = 0;
474+ rec->filled = 0;
475+
476+ return snd_pcm_prepare(rec->slave);
477+}
478+
479+/*
480+ * poll-related callbacks - just pass to slave PCM
481+ */
482+static int a52_poll_descriptors_count(snd_pcm_ioplug_t *io)
483+{
484+ struct a52_ctx *rec = io->private_data;
485+ return snd_pcm_poll_descriptors_count(rec->slave);
486+}
487+
488+static int a52_poll_descriptors(snd_pcm_ioplug_t *io, struct pollfd *pfd,
489+ unsigned int space)
490+{
491+ struct a52_ctx *rec = io->private_data;
492+ return snd_pcm_poll_descriptors(rec->slave, pfd, space);
493+}
494+
495+static int a52_poll_revents(snd_pcm_ioplug_t *io, struct pollfd *pfd,
496+ unsigned int nfds, unsigned short *revents)
497+{
498+ struct a52_ctx *rec = io->private_data;
499+ return snd_pcm_poll_descriptors_revents(rec->slave, pfd, nfds, revents);
500+}
501+
502+/*
503+ * close callback
504+ */
505+static int a52_close(snd_pcm_ioplug_t *io)
506+{
507+ struct a52_ctx *rec = io->private_data;
508+
509+ a52_free(rec);
510+ if (rec->slave)
511+ snd_pcm_close(rec->slave);
512+ return 0;
513+}
514+
515+/*
516+ * callback table
517+ */
518+static snd_pcm_ioplug_callback_t a52_ops = {
519+ .start = a52_start,
520+ .stop = a52_stop,
521+ .pointer = a52_pointer,
522+ .transfer = a52_transfer,
523+ .close = a52_close,
524+ .hw_params = a52_hw_params,
525+ .hw_free = a52_hw_free,
526+ .sw_params = a52_sw_params,
527+ .prepare = a52_prepare,
528+ .drain = a52_drain,
529+ .poll_descriptors_count = a52_poll_descriptors_count,
530+ .poll_descriptors = a52_poll_descriptors,
531+ .poll_revents = a52_poll_revents,
532+};
533+
534+/*
535+ * set up h/w constraints
536+ *
537+ * set the period size identical with A52 frame size.
538+ * the max buffer size is calculated from the max buffer size
539+ * of the slave PCM
540+ */
541+
542+#define A52_FRAME_SIZE 1536
543+
544+#define ARRAY_SIZE(ary) (sizeof(ary)/sizeof(ary[0]))
545+
546+static int a52_set_hw_constraint(struct a52_ctx *rec)
547+{
548+ unsigned int accesses[] = {
549+ SND_PCM_ACCESS_MMAP_INTERLEAVED,
550+ SND_PCM_ACCESS_MMAP_NONINTERLEAVED,
551+ SND_PCM_ACCESS_RW_INTERLEAVED,
552+ SND_PCM_ACCESS_RW_NONINTERLEAVED
553+ };
554+ unsigned int formats[] = { SND_PCM_FORMAT_S16 };
555+ int err;
556+ snd_pcm_uframes_t buffer_max;
557+ unsigned int period_bytes, max_periods;
558+
559+ if ((err = snd_pcm_ioplug_set_param_list(&rec->io, SND_PCM_IOPLUG_HW_ACCESS,
560+ ARRAY_SIZE(accesses), accesses)) < 0 ||
561+ (err = snd_pcm_ioplug_set_param_list(&rec->io, SND_PCM_IOPLUG_HW_FORMAT,
562+ ARRAY_SIZE(formats), formats)) < 0 ||
563+ (err = snd_pcm_ioplug_set_param_minmax(&rec->io, SND_PCM_IOPLUG_HW_CHANNELS,
564+ rec->channels, rec->channels)) < 0 ||
565+ (err = snd_pcm_ioplug_set_param_minmax(&rec->io, SND_PCM_IOPLUG_HW_RATE,
566+ rec->rate, rec->rate)) < 0)
567+ return err;
568+
569+ if ((err = a52_slave_hw_params_half(rec)) < 0)
570+ return err;
571+
572+ snd_pcm_hw_params_get_buffer_size_max(rec->hw_params, &buffer_max);
573+ period_bytes = A52_FRAME_SIZE * 2 * rec->channels;
574+ max_periods = buffer_max / A52_FRAME_SIZE;
575+
576+ if ((err = snd_pcm_ioplug_set_param_minmax(&rec->io, SND_PCM_IOPLUG_HW_PERIOD_BYTES,
577+ period_bytes, period_bytes)) < 0 ||
578+ (err = snd_pcm_ioplug_set_param_minmax(&rec->io, SND_PCM_IOPLUG_HW_PERIODS,
579+ 2, max_periods)) < 0)
580+ return err;
581+
582+ return 0;
583+}
584+
585+/*
586+ * Main entry point
587+ */
588+SND_PCM_PLUGIN_DEFINE_FUNC(a52)
589+{
590+ snd_config_iterator_t i, next;
591+ int err;
592+ const char *card = NULL;
593+ const char *pcm_string = NULL;
594+ unsigned int rate = 48000;
595+ unsigned int bitrate = 448;
596+ unsigned int channels = 6;
597+ snd_pcm_format_t format = SND_PCM_FORMAT_S16_LE;
598+ char devstr[128], tmpcard[8];
599+ struct a52_ctx *rec;
600+
601+ if (stream != SND_PCM_STREAM_PLAYBACK) {
602+ SNDERR("a52 is only for playback");
603+ return -EINVAL;
604+ }
605+
606+ snd_config_for_each(i, next, conf) {
607+ snd_config_t *n = snd_config_iterator_entry(i);
608+ const char *id;
609+ if (snd_config_get_id(n, &id) < 0)
610+ continue;
611+ if (strcmp(id, "comment") == 0 || strcmp(id, "type") == 0 || strcmp(id, "hint") == 0)
612+ continue;
613+ if (strcmp(id, "card") == 0) {
614+ if (snd_config_get_string(n, &card) < 0) {
615+ long val;
616+ err = snd_config_get_integer(n, &val);
617+ if (err < 0) {
618+ SNDERR("Invalid type for %s", id);
619+ return -EINVAL;
620+ }
621+ snprintf(tmpcard, sizeof(tmpcard), "%ld", val);
622+ card = tmpcard;
623+ }
624+ continue;
625+ }
626+ if (strcmp(id, "slavepcm") == 0) {
627+ if (snd_config_get_string(n, &pcm_string) < 0) {
628+ SNDERR("a52 slavepcm must be a string");
629+ return -EINVAL;
630+ }
631+ continue;
632+ }
633+ if (strcmp(id, "rate") == 0) {
634+ long val;
635+ if (snd_config_get_integer(n, &val) < 0) {
636+ SNDERR("Invalid type for %s", id);
637+ return -EINVAL;
638+ }
639+ rate = val;
640+ if (rate != 44100 && rate != 48000) {
641+ SNDERR("rate must be 44100 or 48000");
642+ return -EINVAL;
643+ }
644+ continue;
645+ }
646+ if (strcmp(id, "bitrate") == 0) {
647+ long val;
648+ if (snd_config_get_integer(n, &val) < 0) {
649+ SNDERR("Invalid type for %s", id);
650+ return -EINVAL;
651+ }
652+ bitrate = val;
653+ if (bitrate < 128 || bitrate > 1000) {
654+ SNDERR("Invalid bitrate value %d", bitrate);
655+ return -EINVAL;
656+ }
657+ continue;
658+ }
659+ if (strcmp(id, "channels") == 0) {
660+ long val;
661+ if (snd_config_get_integer(n, &val) < 0) {
662+ SNDERR("Invalid type for %s", id);
663+ return -EINVAL;
664+ }
665+ channels = val;
666+ if (channels != 2 && channels != 4 && channels != 6) {
667+ SNDERR("channels must be 2, 4 or 6");
668+ return -EINVAL;
669+ }
670+ continue;
671+ }
672+ if (strcmp(id, "format") == 0) {
673+ const char *str;
674+ err = snd_config_get_string(n, &str);
675+ if (err < 0) {
676+ SNDERR("invalid type for %s", id);
677+ return -EINVAL;
678+ }
679+ format = snd_pcm_format_value(str);
680+ if (format == SND_PCM_FORMAT_UNKNOWN) {
681+ SNDERR("unknown format %s", str);
682+ return -EINVAL;
683+ }
684+ if (format != SND_PCM_FORMAT_S16_LE &&
685+ format != SND_PCM_FORMAT_S16_BE) {
686+ SNDERR("Only S16_LE/BE formats are allowed");
687+ return -EINVAL;
688+ }
689+ continue;
690+ }
691+ SNDERR("Unknown field %s", id);
692+ return -EINVAL;
693+ }
694+
695+ rec = calloc(1, sizeof(*rec));
696+ if (! rec) {
697+ SNDERR("cannot allocate");
698+ return -ENOMEM;
699+ }
700+
701+ rec->rate = rate;
702+ rec->bitrate = bitrate;
703+ rec->channels = channels;
704+ rec->format = format;
705+
706+ avcodec_init();
707+ avcodec_register_all();
708+ rec->codec = avcodec_find_encoder(CODEC_ID_AC3);
709+ if (! rec->codec) {
710+ SNDERR("Cannot find codec engine");
711+ err = -EINVAL;
712+ goto error;
713+ }
714+
715+ if (! pcm_string) {
716+ snprintf(devstr, sizeof(devstr),
717+ "iec958:{AES0 0x%x AES1 0x%x AES2 0x%x AES3 0x%x %s%s}",
718+ IEC958_AES0_CON_EMPHASIS_NONE | IEC958_AES0_NONAUDIO |
719+ IEC958_AES0_CON_NOT_COPYRIGHT,
720+ IEC958_AES1_CON_ORIGINAL | IEC958_AES1_CON_PCM_CODER,
721+ 0, rate == 48000 ? IEC958_AES3_CON_FS_48000 : IEC958_AES3_CON_FS_44100,
722+ card ? " CARD " : "",
723+ card ? card : "");
724+ err = snd_pcm_open(&rec->slave, devstr, stream, mode);
725+ if (err < 0)
726+ goto error;
727+ /* in case the slave doesn't support S16 format */
728+ err = snd_pcm_linear_open(&rec->slave, NULL, SND_PCM_FORMAT_S16,
729+ rec->slave, 1);
730+ if (err < 0)
731+ goto error;
732+ } else {
733+ err = snd_pcm_open(&rec->slave, pcm_string, stream, mode);
734+ if (err < 0)
735+ goto error;
736+ }
737+
738+ rec->io.version = SND_PCM_IOPLUG_VERSION;
739+ rec->io.name = "A52 Output Plugin";
740+ rec->io.mmap_rw = 0;
741+ rec->io.callback = &a52_ops;
742+ rec->io.private_data = rec;
743+
744+ err = snd_pcm_ioplug_create(&rec->io, name, stream, mode);
745+ if (err < 0)
746+ goto error;
747+
748+ if ((err = a52_set_hw_constraint(rec)) < 0) {
749+ snd_pcm_ioplug_delete(&rec->io);
750+ return err;
751+ }
752+
753+ *pcmp = rec->io.pcm;
754+ return 0;
755+
756+ error:
757+ if (rec->slave)
758+ snd_pcm_close(rec->slave);
759+ free(rec);
760+ return err;
761+}
762+
763+SND_PCM_PLUGIN_SYMBOL(a52);
764
765=== modified file '.pc/applied-patches'
766--- .pc/applied-patches 2011-10-18 19:47:15 +0000
767+++ .pc/applied-patches 2011-10-20 16:12:25 +0000
768@@ -3,3 +3,4 @@
769 0004-jack-Fix-hanging-applications-when-using-jack-plugin.patch
770 arcam-av_uses_pthreads.patch
771 0005-pulse-only-underrun-if-no-more-data-has-been-written.patch
772+0006-handle-new-libav.patch
773
774=== modified file 'a52/pcm_a52.c'
775--- a52/pcm_a52.c 2011-10-18 19:47:15 +0000
776+++ a52/pcm_a52.c 2011-10-20 16:12:25 +0000
777@@ -436,7 +436,15 @@
778 rec->avctx->bit_rate = rec->bitrate * 1000;
779 rec->avctx->sample_rate = io->rate;
780 rec->avctx->channels = io->channels;
781+<<<<<<< TREE
782 rec->avctx->sample_fmt = AV_SAMPLE_FMT_S16;
783+=======
784+#if LIBAVCODEC_VERSION_MAJOR > 52 || (LIBAVCODEC_VERSION_MAJOR == 52 && LIBAVCODEC_VERSION_MINOR >= 95)
785+ rec->avctx->sample_fmt = AV_SAMPLE_FMT_S16;
786+#else
787+ rec->avctx->sample_fmt = SAMPLE_FMT_S16;
788+#endif
789+>>>>>>> MERGE-SOURCE
790 #if LIBAVCODEC_VERSION_MAJOR > 52 || (LIBAVCODEC_VERSION_MAJOR == 52 && LIBAVCODEC_VERSION_MINOR >= 3)
791 switch (io->channels) {
792 case 2:
793@@ -700,6 +708,7 @@
794
795 avcodec_init();
796 avcodec_register_all();
797+<<<<<<< TREE
798
799 rec->codec = avcodec_find_encoder_by_name("ac3_fixed");
800 if (rec->codec == NULL)
801@@ -707,6 +716,15 @@
802 if (rec->codec == NULL)
803 rec->codec = avcodec_find_encoder(CODEC_ID_AC3);
804 if (rec->codec == NULL) {
805+=======
806+
807+ rec->codec = avcodec_find_encoder_by_name("ac3_fixed");
808+ if (rec->codec == NULL)
809+ rec->codec = avcodec_find_encoder_by_name("ac3");
810+ if (rec->codec == NULL)
811+ rec->codec = avcodec_find_encoder(CODEC_ID_AC3);
812+ if (rec->codec == NULL) {
813+>>>>>>> MERGE-SOURCE
814 SNDERR("Cannot find codec engine");
815 err = -EINVAL;
816 goto error;
817
818=== modified file 'debian/changelog'
819--- debian/changelog 2011-10-18 19:47:15 +0000
820+++ debian/changelog 2011-10-20 16:12:25 +0000
821@@ -1,3 +1,4 @@
822+<<<<<<< TREE
823 alsa-plugins (1.0.24-3ubuntu1) precise; urgency=low
824
825 * Merge from debian unstable, remaining changes:
826@@ -56,6 +57,16 @@
827
828 -- Jordi Mallach <jordi@debian.org> Sat, 16 Jul 2011 15:25:35 +0200
829
830+=======
831+alsa-plugins (1.0.24-0ubuntu6.1) oneiric-proposed; urgency=low
832+
833+ * debian/patches/0006-handle-new-libav.patch: Backport upstream git
834+ commits 40c129a and 826dafa so that the a52 plugin works again.
835+ (LP: #872871)
836+
837+ -- Daniel T Chen <crimsun@ubuntu.com> Wed, 12 Oct 2011 11:08:02 -0400
838+
839+>>>>>>> MERGE-SOURCE
840 alsa-plugins (1.0.24-0ubuntu6) oneiric; urgency=low
841
842 * Use the new PulseAudio API for better underrun handling (LP: #805940)
843
844=== added file 'debian/patches/0006-handle-new-libav.patch'
845--- debian/patches/0006-handle-new-libav.patch 1970-01-01 00:00:00 +0000
846+++ debian/patches/0006-handle-new-libav.patch 2011-10-20 16:12:25 +0000
847@@ -0,0 +1,32 @@
848+Index: alsa-plugins-1.0.24/a52/pcm_a52.c
849+===================================================================
850+--- alsa-plugins-1.0.24.orig/a52/pcm_a52.c 2011-10-12 11:07:33.000000000 -0400
851++++ alsa-plugins-1.0.24/a52/pcm_a52.c 2011-10-12 11:07:46.000000000 -0400
852+@@ -436,6 +436,11 @@
853+ rec->avctx->bit_rate = rec->bitrate * 1000;
854+ rec->avctx->sample_rate = io->rate;
855+ rec->avctx->channels = io->channels;
856++#if LIBAVCODEC_VERSION_MAJOR > 52 || (LIBAVCODEC_VERSION_MAJOR == 52 && LIBAVCODEC_VERSION_MINOR >= 95)
857++ rec->avctx->sample_fmt = AV_SAMPLE_FMT_S16;
858++#else
859++ rec->avctx->sample_fmt = SAMPLE_FMT_S16;
860++#endif
861+ #if LIBAVCODEC_VERSION_MAJOR > 52 || (LIBAVCODEC_VERSION_MAJOR == 52 && LIBAVCODEC_VERSION_MINOR >= 3)
862+ switch (io->channels) {
863+ case 2:
864+@@ -699,8 +704,13 @@
865+
866+ avcodec_init();
867+ avcodec_register_all();
868+- rec->codec = avcodec_find_encoder(CODEC_ID_AC3);
869+- if (! rec->codec) {
870++
871++ rec->codec = avcodec_find_encoder_by_name("ac3_fixed");
872++ if (rec->codec == NULL)
873++ rec->codec = avcodec_find_encoder_by_name("ac3");
874++ if (rec->codec == NULL)
875++ rec->codec = avcodec_find_encoder(CODEC_ID_AC3);
876++ if (rec->codec == NULL) {
877+ SNDERR("Cannot find codec engine");
878+ err = -EINVAL;
879+ goto error;
880
881=== modified file 'debian/patches/series'
882--- debian/patches/series 2011-10-18 19:47:15 +0000
883+++ debian/patches/series 2011-10-20 16:12:25 +0000
884@@ -4,3 +4,4 @@
885 0004-jack-Fix-hanging-applications-when-using-jack-plugin.patch
886 arcam-av_uses_pthreads.patch
887 0005-pulse-only-underrun-if-no-more-data-has-been-written.patch
888+0006-handle-new-libav.patch

Subscribers

People subscribed via source and target branches

to all changes: