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

« back to all changes in this revision

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