Revision 813dbb44 libavdevice/alsa-audio-common.c

View differences:

libavdevice/alsa-audio-common.c
43 43
    }
44 44
}
45 45

  
46
static void alsa_reorder_s16_out_51(const void *in_v, void *out_v, int n)
47
{
48
    const int16_t *in = in_v;
49
    int16_t *out = out_v;
50

  
51
    while (n-- > 0) {
52
        out[0] = in[0];
53
        out[1] = in[1];
54
        out[2] = in[4];
55
        out[3] = in[5];
56
        out[4] = in[2];
57
        out[5] = in[3];
58
        in  += 6;
59
        out += 6;
60
    }
61
}
62

  
63
static void alsa_reorder_s16_out_71(const void *in_v, void *out_v, int n)
64
{
65
    const int16_t *in = in_v;
66
    int16_t *out = out_v;
67

  
68
    while (n-- > 0) {
69
        out[0] = in[0];
70
        out[1] = in[1];
71
        out[2] = in[4];
72
        out[3] = in[5];
73
        out[4] = in[2];
74
        out[5] = in[3];
75
        out[6] = in[6];
76
        out[7] = in[7];
77
        in  += 8;
78
        out += 8;
79
    }
80
}
81

  
82
#define REORDER_DUMMY ((void *)1)
83

  
84
static av_cold ff_reorder_func find_reorder_func(int codec_id,
85
                                                 int64_t layout,
86
                                                 int out)
87
{
88
    return
89
    codec_id == CODEC_ID_PCM_S16LE || codec_id == CODEC_ID_PCM_S16BE ?
90
        layout == AV_CH_LAYOUT_QUAD ? REORDER_DUMMY :
91
        layout == AV_CH_LAYOUT_5POINT1_BACK ?
92
            out ? alsa_reorder_s16_out_51 : NULL :
93
        layout == AV_CH_LAYOUT_7POINT1 ?
94
            out ? alsa_reorder_s16_out_71 : NULL :
95
            NULL :
96
        NULL;
97
}
98

  
46 99
av_cold int ff_alsa_open(AVFormatContext *ctx, snd_pcm_stream_t mode,
47 100
                         unsigned int *sample_rate,
48 101
                         int channels, enum CodecID *codec_id)
......
54 107
    snd_pcm_t *h;
55 108
    snd_pcm_hw_params_t *hw_params;
56 109
    snd_pcm_uframes_t buffer_size, period_size;
110
    int64_t layout = ctx->streams[0]->codec->channel_layout;
57 111

  
58 112
    if (ctx->filename[0] == 0) audio_device = "default";
59 113
    else                       audio_device = ctx->filename;
......
146 200

  
147 201
    snd_pcm_hw_params_free(hw_params);
148 202

  
203
    if (channels > 2 && layout) {
204
        s->reorder_func = find_reorder_func(*codec_id, layout,
205
                                            mode == SND_PCM_STREAM_PLAYBACK);
206
        if (s->reorder_func == REORDER_DUMMY) {
207
            s->reorder_func = NULL;
208
        } else if (s->reorder_func) {
209
            s->reorder_buf_size = buffer_size;
210
            s->reorder_buf = av_malloc(s->reorder_buf_size * s->frame_size);
211
            if (!s->reorder_buf)
212
                goto fail1;
213
        } else {
214
            char name[16];
215
            av_get_channel_layout_string(name, sizeof(name), channels, layout);
216
            av_log(ctx, AV_LOG_WARNING,
217
                   "ALSA channel layout unknown or unimplemented for %s %s.\n",
218
                   name,
219
                   mode == SND_PCM_STREAM_PLAYBACK ? "playback" : "capture");
220
        }
221
    }
222

  
149 223
    s->h = h;
150 224
    return 0;
151 225

  
......
160 234
{
161 235
    AlsaData *s = s1->priv_data;
162 236

  
237
    av_freep(s->reorder_buf);
163 238
    snd_pcm_close(s->h);
164 239
    return 0;
165 240
}
......
184 259
    }
185 260
    return err;
186 261
}
262

  
263
int ff_alsa_extend_reorder_buf(AlsaData *s, int min_size)
264
{
265
    int size = s->reorder_buf_size;
266
    void *r;
267

  
268
    while (size < min_size)
269
        size *= 2;
270
    r = av_realloc(s->reorder_buf, size * s->frame_size);
271
    if (!r)
272
        return AVERROR(ENOMEM);
273
    s->reorder_buf = r;
274
    s->reorder_buf_size = size;
275
    return 0;
276
}

Also available in: Unified diff