static int pcm_decode_frame(AVCodecContext *avctx,
                            void *data, int *data_size,
                            const uint8_t *buf, int buf_size)
{
    PCMDecode *s = avctx->priv_data;
    int c, n;
    short *samples;
    const uint8_t *src, *src2[MAX_CHANNELS];
    samples = data;
    src = buf;
    n= av_get_bits_per_sample(avctx->codec_id)/8;
    if(n && buf_size % n){
        av_log(avctx, AV_LOG_ERROR, "invalid PCM packet\n");
        return -1;
    }
    if(avctx->channels <= 0 || avctx->channels > MAX_CHANNELS){
        av_log(avctx, AV_LOG_ERROR, "PCM channels out of bounds\n");
        return -1;
    }
    buf_size= FFMIN(buf_size, *data_size/2);
    *data_size=0;
    n = buf_size/avctx->channels;
    for(c=0;c<avctx->channels;c++)
        src2[c] = &src[c*n];
    switch(avctx->codec->id) {
    case CODEC_ID_PCM_S32LE:
        decode_to16(4, 1, 0, &src, &samples, buf_size);
        break;
    case CODEC_ID_PCM_S32BE:
        decode_to16(4, 0, 0, &src, &samples, buf_size);
        break;
    case CODEC_ID_PCM_U32LE:
        decode_to16(4, 1, 1, &src, &samples, buf_size);
        break;
    case CODEC_ID_PCM_U32BE:
        decode_to16(4, 0, 1, &src, &samples, buf_size);
        break;
    case CODEC_ID_PCM_S24LE:
        decode_to16(3, 1, 0, &src, &samples, buf_size);
        break;
    case CODEC_ID_PCM_S24BE:
        decode_to16(3, 0, 0, &src, &samples, buf_size);
        break;
    case CODEC_ID_PCM_U24LE:
        decode_to16(3, 1, 1, &src, &samples, buf_size);
        break;
    case CODEC_ID_PCM_U24BE:
        decode_to16(3, 0, 1, &src, &samples, buf_size);
        break;
    case CODEC_ID_PCM_S24DAUD:
        n = buf_size / 3;
        for(;n>0;n--) {
          uint32_t v = bytestream_get_be24(&src);
          v >>= 4;
          *samples++ = ff_reverse[(v >> 8) & 0xff] +
                       (ff_reverse[v & 0xff] << 8);
        }
        break;
    case CODEC_ID_PCM_S16LE:
        n = buf_size >> 1;
        for(;n>0;n--) {
            *samples++ = bytestream_get_le16(&src);
        }
        break;
    case CODEC_ID_PCM_S16LE_PLANAR:
        for(n>>=1;n>0;n--)
            for(c=0;c<avctx->channels;c++)
                *samples++ = bytestream_get_le16(&src2[c]);
        src = src2[avctx->channels-1];
        break;
    case CODEC_ID_PCM_S16BE:
        n = buf_size >> 1;
        for(;n>0;n--) {
            *samples++ = bytestream_get_be16(&src);
        }
        break;
    case CODEC_ID_PCM_U16LE:
        n = buf_size >> 1;
        for(;n>0;n--) {
            *samples++ = bytestream_get_le16(&src) - 0x8000;
        }
        break;
    case CODEC_ID_PCM_U16BE:
        n = buf_size >> 1;
        for(;n>0;n--) {
            *samples++ = bytestream_get_be16(&src) - 0x8000;
        }
        break;
    case CODEC_ID_PCM_S8:
        n = buf_size;
        for(;n>0;n--) {
            *samples++ = *src++ << 8;
        }
        break;
    case CODEC_ID_PCM_U8:
        n = buf_size;
        for(;n>0;n--) {
            *samples++ = ((int)*src++ - 128) << 8;
        }
        break;
    case CODEC_ID_PCM_ZORK:
        n = buf_size;
        for(;n>0;n--) {
            int x= *src++;
            if(x&128) x-= 128;
            else      x = -x;
            *samples++ = x << 8;
        }
        break;
    case CODEC_ID_PCM_ALAW:
    case CODEC_ID_PCM_MULAW:
        n = buf_size;
        for(;n>0;n--) {
            *samples++ = s->table[*src++];
        }
        break;
    default:
        return -1;
    }
    *data_size = (uint8_t *)samples - (uint8_t *)data;
    return src - buf;
}
['static int pcm_decode_frame(AVCodecContext *avctx,\n                            void *data, int *data_size,\n                            const uint8_t *buf, int buf_size)\n{\n    PCMDecode *s = avctx->priv_data;\n    int c, n;\n    short *samples;\n    const uint8_t *src, *src2[MAX_CHANNELS];\n    samples = data;\n    src = buf;\n    n= av_get_bits_per_sample(avctx->codec_id)/8;\n    if(n && buf_size % n){\n        av_log(avctx, AV_LOG_ERROR, "invalid PCM packet\\n");\n        return -1;\n    }\n    if(avctx->channels <= 0 || avctx->channels > MAX_CHANNELS){\n        av_log(avctx, AV_LOG_ERROR, "PCM channels out of bounds\\n");\n        return -1;\n    }\n    buf_size= FFMIN(buf_size, *data_size/2);\n    *data_size=0;\n    n = buf_size/avctx->channels;\n    for(c=0;c<avctx->channels;c++)\n        src2[c] = &src[c*n];\n    switch(avctx->codec->id) {\n    case CODEC_ID_PCM_S32LE:\n        decode_to16(4, 1, 0, &src, &samples, buf_size);\n        break;\n    case CODEC_ID_PCM_S32BE:\n        decode_to16(4, 0, 0, &src, &samples, buf_size);\n        break;\n    case CODEC_ID_PCM_U32LE:\n        decode_to16(4, 1, 1, &src, &samples, buf_size);\n        break;\n    case CODEC_ID_PCM_U32BE:\n        decode_to16(4, 0, 1, &src, &samples, buf_size);\n        break;\n    case CODEC_ID_PCM_S24LE:\n        decode_to16(3, 1, 0, &src, &samples, buf_size);\n        break;\n    case CODEC_ID_PCM_S24BE:\n        decode_to16(3, 0, 0, &src, &samples, buf_size);\n        break;\n    case CODEC_ID_PCM_U24LE:\n        decode_to16(3, 1, 1, &src, &samples, buf_size);\n        break;\n    case CODEC_ID_PCM_U24BE:\n        decode_to16(3, 0, 1, &src, &samples, buf_size);\n        break;\n    case CODEC_ID_PCM_S24DAUD:\n        n = buf_size / 3;\n        for(;n>0;n--) {\n          uint32_t v = bytestream_get_be24(&src);\n          v >>= 4;\n          *samples++ = ff_reverse[(v >> 8) & 0xff] +\n                       (ff_reverse[v & 0xff] << 8);\n        }\n        break;\n    case CODEC_ID_PCM_S16LE:\n        n = buf_size >> 1;\n        for(;n>0;n--) {\n            *samples++ = bytestream_get_le16(&src);\n        }\n        break;\n    case CODEC_ID_PCM_S16LE_PLANAR:\n        for(n>>=1;n>0;n--)\n            for(c=0;c<avctx->channels;c++)\n                *samples++ = bytestream_get_le16(&src2[c]);\n        src = src2[avctx->channels-1];\n        break;\n    case CODEC_ID_PCM_S16BE:\n        n = buf_size >> 1;\n        for(;n>0;n--) {\n            *samples++ = bytestream_get_be16(&src);\n        }\n        break;\n    case CODEC_ID_PCM_U16LE:\n        n = buf_size >> 1;\n        for(;n>0;n--) {\n            *samples++ = bytestream_get_le16(&src) - 0x8000;\n        }\n        break;\n    case CODEC_ID_PCM_U16BE:\n        n = buf_size >> 1;\n        for(;n>0;n--) {\n            *samples++ = bytestream_get_be16(&src) - 0x8000;\n        }\n        break;\n    case CODEC_ID_PCM_S8:\n        n = buf_size;\n        for(;n>0;n--) {\n            *samples++ = *src++ << 8;\n        }\n        break;\n    case CODEC_ID_PCM_U8:\n        n = buf_size;\n        for(;n>0;n--) {\n            *samples++ = ((int)*src++ - 128) << 8;\n        }\n        break;\n    case CODEC_ID_PCM_ZORK:\n        n = buf_size;\n        for(;n>0;n--) {\n            int x= *src++;\n            if(x&128) x-= 128;\n            else      x = -x;\n            *samples++ = x << 8;\n        }\n        break;\n    case CODEC_ID_PCM_ALAW:\n    case CODEC_ID_PCM_MULAW:\n        n = buf_size;\n        for(;n>0;n--) {\n            *samples++ = s->table[*src++];\n        }\n        break;\n    default:\n        return -1;\n    }\n    *data_size = (uint8_t *)samples - (uint8_t *)data;\n    return src - buf;\n}']