~ubuntu-branches/ubuntu/trusty/alsa-plugins/trusty

« back to all changes in this revision

Viewing changes to a52/pcm_a52.c

  • Committer: Package Import Robot
  • Author(s): Luke Yelavich
  • Date: 2013-07-26 10:57:49 UTC
  • mfrom: (3.1.16 sid)
  • Revision ID: package-import@ubuntu.com-20130726105749-ymn7cpbi75gmgplw
Tags: 1.0.27-2ubuntu1
* Merge from debian unstable, remaining changes:
  - Create libasound2-plugins-extra package which contains plugins that use
    libav.

Show diffs side-by-side

added added

removed removed

Lines of Context:
27
27
#include <alsa/pcm_plugin.h>
28
28
#include AVCODEC_HEADER
29
29
#include <libavutil/avutil.h>
 
30
 
 
31
#if LIBAVCODEC_VERSION_MAJOR >= 53 && LIBAVCODEC_VERSION_MINOR >= 34
30
32
#include <libavutil/audioconvert.h>
31
33
#include <libavutil/mem.h>
 
34
#define USE_AVCODEC_FRAME
 
35
#endif
 
36
 
 
37
/* some compatibility wrappers */
 
38
#ifndef AV_VERSION_INT
 
39
#define AV_VERSION_INT(a, b, c) (((a) << 16) | ((b) << 8) | (c))
 
40
#endif
 
41
#ifndef LIBAVCODEC_VERSION_INT
 
42
#define LIBAVCODEC_VERSION_INT  AV_VERSION_INT(LIBAVCODEC_VERSION_MAJOR, \
 
43
                                               LIBAVCODEC_VERSION_MINOR, \
 
44
                                               LIBAVCODEC_VERSION_MICRO)
 
45
#endif
 
46
 
 
47
#if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(54, 0, 0)
 
48
#ifndef AV_CH_LAYOUT_STEREO
 
49
#define AV_CH_LAYOUT_STEREO     CH_LAYOUT_STEREO
 
50
#define AV_CH_LAYOUT_QUAD       CH_LAYOUT_QUAD
 
51
#define AV_CH_LAYOUT_5POINT1    CH_LAYOUT_5POINT1
 
52
#endif
 
53
#endif
 
54
 
 
55
#if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(52, 95, 0)
 
56
#ifndef AV_SAMPLE_FMT_S16
 
57
#define AV_SAMPLE_FMT_S16       SAMPLE_FMT_S16
 
58
#endif
 
59
#endif
 
60
 
32
61
 
33
62
struct a52_ctx {
34
63
        snd_pcm_ioplug_t io;
36
65
        AVCodec *codec;
37
66
        AVCodecContext *avctx;
38
67
        snd_pcm_format_t format;
 
68
        int av_format;
39
69
        unsigned int channels;
40
70
        unsigned int rate;
41
71
        unsigned int bitrate;
48
78
        unsigned int slave_period_size;
49
79
        unsigned int slave_buffer_size;
50
80
        snd_pcm_hw_params_t *hw_params;
 
81
#ifdef USE_AVCODEC_FRAME
 
82
        AVFrame *frame;
 
83
        int is_planar;
 
84
#endif
51
85
};
52
86
 
 
87
#ifdef USE_AVCODEC_FRAME
 
88
#define use_planar(rec)         (rec)->is_planar
 
89
#else
 
90
#define use_planar(rec)         0
 
91
#endif
 
92
 
 
93
#if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(53, 34, 0)
 
94
static int do_encode(struct a52_ctx *rec)
 
95
{
 
96
        AVPacket pkt = {
 
97
                .data = rec->outbuf + 8,
 
98
                .size = rec->outbuf_size - 8
 
99
        };
 
100
        int got_frame;
 
101
 
 
102
        avcodec_encode_audio2(rec->avctx, &pkt, rec->frame, &got_frame);
 
103
        return pkt.size;
 
104
}
 
105
#else
 
106
static int do_encode(struct a52_ctx *rec)
 
107
{
 
108
        return avcodec_encode_audio(rec->avctx, rec->outbuf + 8,
 
109
                                    rec->outbuf_size - 8,
 
110
                                    rec->inbuf);
 
111
}
 
112
#endif
 
113
 
53
114
/* convert the PCM data to A52 stream in IEC958 */
54
115
static void convert_data(struct a52_ctx *rec)
55
116
{
56
 
        int out_bytes;
 
117
        int out_bytes = do_encode(rec);
57
118
 
58
 
        out_bytes = avcodec_encode_audio(rec->avctx, rec->outbuf + 8,
59
 
                                         rec->outbuf_size - 8,
60
 
                                         rec->inbuf);
61
119
        rec->outbuf[0] = 0xf8; /* sync words */
62
120
        rec->outbuf[1] = 0x72;
63
121
        rec->outbuf[2] = 0x4e;
103
161
/*
104
162
 * drain callback
105
163
 */
 
164
#ifdef USE_AVCODEC_FRAME
 
165
static void clear_remaining_planar_data(snd_pcm_ioplug_t *io)
 
166
{
 
167
        struct a52_ctx *rec = io->private_data;
 
168
        unsigned int i;
 
169
 
 
170
        for (i = 0; i < io->channels; i++)
 
171
                memset(rec->frame->data[i] + rec->filled * 2, 0,
 
172
                       (rec->avctx->frame_size - rec->filled) * 2);
 
173
}
 
174
#else
 
175
#define clear_remaining_planar_data(io) /*NOP*/
 
176
#endif
 
177
 
106
178
static int a52_drain(snd_pcm_ioplug_t *io)
107
179
{
108
180
        struct a52_ctx *rec = io->private_data;
112
184
                if ((err = write_out_pending(io, rec)) < 0)
113
185
                        return err;
114
186
                /* remaining data must be converted and sent out */
115
 
                memset(rec->inbuf + rec->filled * io->channels, 0,
116
 
                       (rec->avctx->frame_size - rec->filled) * io->channels * 2);
 
187
                if (use_planar(rec))
 
188
                        clear_remaining_planar_data(io);
 
189
                else {
 
190
                        memset(rec->inbuf + rec->filled * io->channels, 0,
 
191
                               (rec->avctx->frame_size - rec->filled) * io->channels * 2);
 
192
                }
117
193
                convert_data(rec);
118
194
        }
119
195
        err = write_out_pending(io, rec);
156
232
        short *src, *dst;
157
233
        unsigned int src_step;
158
234
        int err;
 
235
        static unsigned int ch_index[3][6] = {
 
236
                { 0, 1 },
 
237
                { 0, 1, 2, 3 },
 
238
#if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(52, 26, 0)
 
239
                /* current libavcodec expects SMPTE order */
 
240
                { 0, 1, 4, 5, 2, 3 },
 
241
#else
 
242
                /* libavcodec older than r18540 expects A52 order */
 
243
                { 0, 4, 1, 2, 3, 5 },
 
244
#endif
 
245
        };
159
246
 
160
247
        if ((err = write_out_pending(io, rec)) < 0)
161
248
                return err;
164
251
                size = len;
165
252
 
166
253
        dst = rec->inbuf + rec->filled * io->channels;
167
 
        if (interleaved) {
 
254
        if (!use_planar(rec) && interleaved) {
168
255
                memcpy(dst, areas->addr + offset * io->channels * 2,
169
256
                       size * io->channels * 2);
170
257
        } else {
171
258
                unsigned int i, ch, dst_step;
172
259
                short *dst1;
173
 
                static unsigned int ch_index[3][6] = {
174
 
                        { 0, 1 },
175
 
                        { 0, 1, 2, 3 },
176
 
#if LIBAVCODEC_VERSION_MAJOR > 52 || (LIBAVCODEC_VERSION_MAJOR == 52 && LIBAVCODEC_VERSION_MINOR >= 26)
177
 
                        /* current libavcodec expects SMPTE order */
178
 
                        { 0, 1, 4, 5, 2, 3 },
179
 
#else
180
 
                        /* libavcodec older than r18540 expects A52 order */
181
 
                        { 0, 4, 1, 2, 3, 5 },
182
 
#endif
183
 
                };
 
260
 
184
261
                /* flatten copy to n-channel interleaved */
185
262
                dst_step = io->channels;
186
263
                for (ch = 0; ch < io->channels; ch++, dst++) {
187
264
                        const snd_pcm_channel_area_t *ap;
188
265
                        ap = &areas[ch_index[io->channels / 2 - 1][ch]];
189
 
                        dst1 = dst;
190
266
                        src = (short *)(ap->addr +
191
267
                                        (ap->first + offset * ap->step) / 8);
 
268
 
 
269
#ifdef USE_AVCODEC_FRAME
 
270
                        if (use_planar(rec)) {
 
271
                                memcpy(rec->frame->data[ch], src, size * 2);
 
272
                                continue;
 
273
                        }
 
274
#endif
 
275
                        dst1 = dst;
192
276
                        src_step = ap->step / 16; /* in word */
193
277
                        for (i = 0; i < size; i++) {
194
278
                                *dst1 = *src;
415
499
                av_free(rec->avctx);
416
500
                rec->avctx = NULL;
417
501
        }
 
502
 
 
503
#ifdef USE_AVCODEC_FRAME
 
504
        if (rec->frame) {
 
505
                av_freep(&rec->frame->data[0]);
 
506
                rec->inbuf = NULL;
 
507
        }
 
508
#if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(54, 28, 0)
 
509
        avcodec_free_frame(&rec->frame);
 
510
#else
 
511
        av_freep(&rec->frame);
 
512
#endif
 
513
#endif
 
514
 
418
515
        free(rec->inbuf);
419
516
        rec->inbuf = NULL;
420
517
        free(rec->outbuf);
426
523
 *
427
524
 * Allocate internal buffers and set up libavcodec
428
525
 */
429
 
static int a52_prepare(snd_pcm_ioplug_t *io)
 
526
 
 
527
#if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(52, 3, 0)
 
528
static void set_channel_layout(snd_pcm_ioplug_t *io)
430
529
{
431
530
        struct a52_ctx *rec = io->private_data;
432
 
 
433
 
        a52_free(rec);
434
 
 
435
 
        rec->avctx = avcodec_alloc_context3(rec->codec);
436
 
        if (! rec->avctx)
437
 
                return -ENOMEM;
438
 
 
439
 
        rec->avctx->bit_rate = rec->bitrate * 1000;
440
 
        rec->avctx->sample_rate = io->rate;
441
 
        rec->avctx->channels = io->channels;
442
 
#if LIBAVCODEC_VERSION_MAJOR > 52 || (LIBAVCODEC_VERSION_MAJOR == 52 && LIBAVCODEC_VERSION_MINOR >= 95)
443
 
  rec->avctx->sample_fmt = AV_SAMPLE_FMT_S16;
444
 
#else
445
 
  rec->avctx->sample_fmt = SAMPLE_FMT_S16;
446
 
#endif
447
 
#if LIBAVCODEC_VERSION_MAJOR > 52 || (LIBAVCODEC_VERSION_MAJOR == 52 && LIBAVCODEC_VERSION_MINOR >= 3)
448
531
        switch (io->channels) {
449
532
        case 2:
450
533
                rec->avctx->channel_layout = AV_CH_LAYOUT_STEREO;
458
541
        default:
459
542
                break;
460
543
        }
 
544
}
 
545
#else
 
546
#define set_channel_layout(io) /* NOP */
461
547
#endif
462
548
 
463
 
        if (avcodec_open2(rec->avctx, rec->codec, NULL) < 0)
464
 
                return -EINVAL;
465
 
 
 
549
static int alloc_input_buffer(snd_pcm_ioplug_t *io)
 
550
{
 
551
        struct a52_ctx *rec = io->private_data;
 
552
#ifdef USE_AVCODEC_FRAME
 
553
        rec->frame = avcodec_alloc_frame();
 
554
        if (!rec->frame)
 
555
                return -ENOMEM;
 
556
        if (av_samples_alloc(rec->frame->data, rec->frame->linesize,
 
557
                             io->channels, rec->avctx->frame_size,
 
558
                             rec->avctx->sample_fmt, 0) < 0)
 
559
                return -ENOMEM;
 
560
        rec->frame->nb_samples = rec->avctx->frame_size;
 
561
        rec->inbuf = (short *)rec->frame->data[0];
 
562
#else
466
563
        rec->inbuf = malloc(rec->avctx->frame_size * 2 * io->channels);
467
 
        if (! rec->inbuf)
468
 
                return -ENOMEM;
 
564
#endif
 
565
        if (!rec->inbuf)
 
566
                return -ENOMEM;
 
567
        return 0;
 
568
}
 
569
 
 
570
static int a52_prepare(snd_pcm_ioplug_t *io)
 
571
{
 
572
        struct a52_ctx *rec = io->private_data;
 
573
        int err;
 
574
 
 
575
        a52_free(rec);
 
576
 
 
577
#ifdef USE_AVCODEC_FRAME
 
578
        rec->avctx = avcodec_alloc_context3(rec->codec);
 
579
#else
 
580
        rec->avctx = avcodec_alloc_context();
 
581
#endif
 
582
        if (!rec->avctx)
 
583
                return -ENOMEM;
 
584
 
 
585
        rec->avctx->bit_rate = rec->bitrate * 1000;
 
586
        rec->avctx->sample_rate = io->rate;
 
587
        rec->avctx->channels = io->channels;
 
588
        rec->avctx->sample_fmt = rec->av_format;
 
589
 
 
590
        set_channel_layout(io);
 
591
 
 
592
 
 
593
#ifdef USE_AVCODEC_FRAME
 
594
        err = avcodec_open2(rec->avctx, rec->codec, NULL);
 
595
#else
 
596
        err = avcodec_open(rec->avctx, rec->codec);
 
597
#endif
 
598
        if (err < 0)
 
599
                return -EINVAL;
 
600
 
469
601
        rec->outbuf_size = rec->avctx->frame_size * 4;
470
602
        rec->outbuf = malloc(rec->outbuf_size);
471
603
        if (! rec->outbuf)
472
604
                return -ENOMEM;
473
605
 
 
606
        if (alloc_input_buffer(io))
 
607
                return -ENOMEM;
 
608
 
474
609
        rec->transfer = 0;
475
610
        rec->remain = 0;
476
611
        rec->filled = 0;
547
682
 
548
683
static int a52_set_hw_constraint(struct a52_ctx *rec)
549
684
{
550
 
        unsigned int accesses[] = {
 
685
        static unsigned int accesses[] = {
551
686
                SND_PCM_ACCESS_MMAP_INTERLEAVED,
552
687
                SND_PCM_ACCESS_MMAP_NONINTERLEAVED,
553
688
                SND_PCM_ACCESS_RW_INTERLEAVED,
554
689
                SND_PCM_ACCESS_RW_NONINTERLEAVED
555
690
        };
 
691
        static unsigned int accesses_planar[] = {
 
692
                SND_PCM_ACCESS_MMAP_NONINTERLEAVED,
 
693
                SND_PCM_ACCESS_RW_NONINTERLEAVED
 
694
        };
556
695
        unsigned int formats[] = { SND_PCM_FORMAT_S16 };
557
696
        int err;
558
697
        snd_pcm_uframes_t buffer_max;
559
698
        unsigned int period_bytes, max_periods;
560
699
 
561
 
        if ((err = snd_pcm_ioplug_set_param_list(&rec->io, SND_PCM_IOPLUG_HW_ACCESS,
562
 
                                                 ARRAY_SIZE(accesses), accesses)) < 0 ||
563
 
            (err = snd_pcm_ioplug_set_param_list(&rec->io, SND_PCM_IOPLUG_HW_FORMAT,
 
700
        if (use_planar(rec))
 
701
                err = snd_pcm_ioplug_set_param_list(&rec->io,
 
702
                                                    SND_PCM_IOPLUG_HW_ACCESS,
 
703
                                                    ARRAY_SIZE(accesses_planar),
 
704
                                                    accesses_planar);
 
705
        else
 
706
                err = snd_pcm_ioplug_set_param_list(&rec->io,
 
707
                                                    SND_PCM_IOPLUG_HW_ACCESS,
 
708
                                                    ARRAY_SIZE(accesses),
 
709
                                                    accesses);
 
710
        if (err < 0)
 
711
                return err;
 
712
 
 
713
        if ((err = snd_pcm_ioplug_set_param_list(&rec->io, SND_PCM_IOPLUG_HW_FORMAT,
564
714
                                                 ARRAY_SIZE(formats), formats)) < 0 ||
565
715
            (err = snd_pcm_ioplug_set_param_minmax(&rec->io, SND_PCM_IOPLUG_HW_CHANNELS,
566
716
                                                   rec->channels, rec->channels)) < 0 ||
705
855
        rec->channels = channels;
706
856
        rec->format = format;
707
857
 
 
858
#ifndef USE_AVCODEC_FRAME
 
859
        avcodec_init();
 
860
#endif
708
861
        avcodec_register_all();
709
862
 
710
863
        rec->codec = avcodec_find_encoder_by_name("ac3_fixed");
746
899
        rec->io.mmap_rw = 0;
747
900
        rec->io.callback = &a52_ops;
748
901
        rec->io.private_data = rec;
 
902
#ifdef USE_AVCODEC_FRAME
 
903
        rec->av_format = rec->codec->sample_fmts[0];
 
904
        rec->is_planar = av_sample_fmt_is_planar(rec->av_format);
 
905
#else
 
906
        rec->av_format = AV_SAMPLE_FMT_S16;
 
907
#endif
749
908
 
750
909
        err = snd_pcm_ioplug_create(&rec->io, name, stream, mode);
751
910
        if (err < 0)