static int get_stream_info(AVCodecContext *avctx)

{

    FDKAACDecContext *s   = avctx->priv_data;

    CStreamInfo *info     = aacDecoder_GetStreamInfo(s->handle);

    int channel_counts[0x24] = { 0 };

    int i, ch_error       = 0;

    uint64_t ch_layout    = 0;



    if (!info) {

        av_log(avctx, AV_LOG_ERROR, "Unable to get stream info\n");

        return AVERROR_UNKNOWN;

    }



    if (info->sampleRate <= 0) {

        av_log(avctx, AV_LOG_ERROR, "Stream info not initialized\n");

        return AVERROR_UNKNOWN;

    }

    avctx->sample_rate = info->sampleRate;

    avctx->frame_size  = info->frameSize;



    for (i = 0; i < info->numChannels; i++) {

        AUDIO_CHANNEL_TYPE ctype = info->pChannelType[i];

        if (ctype <= ACT_NONE || ctype > FF_ARRAY_ELEMS(channel_counts)) {

            av_log(avctx, AV_LOG_WARNING, "unknown channel type\n");

            break;

        }

        channel_counts[ctype]++;

    }

    av_log(avctx, AV_LOG_DEBUG,

           "%d channels - front:%d side:%d back:%d lfe:%d top:%d\n",

           info->numChannels,

           channel_counts[ACT_FRONT], channel_counts[ACT_SIDE],

           channel_counts[ACT_BACK],  channel_counts[ACT_LFE],

           channel_counts[ACT_FRONT_TOP] + channel_counts[ACT_SIDE_TOP] +

           channel_counts[ACT_BACK_TOP]  + channel_counts[ACT_TOP]);



    switch (channel_counts[ACT_FRONT]) {

    case 4:

        ch_layout |= AV_CH_LAYOUT_STEREO | AV_CH_FRONT_LEFT_OF_CENTER |

                     AV_CH_FRONT_RIGHT_OF_CENTER;

        break;

    case 3:

        ch_layout |= AV_CH_LAYOUT_STEREO | AV_CH_FRONT_CENTER;

        break;

    case 2:

        ch_layout |= AV_CH_LAYOUT_STEREO;

        break;

    case 1:

        ch_layout |= AV_CH_FRONT_CENTER;

        break;

    default:

        av_log(avctx, AV_LOG_WARNING,

               "unsupported number of front channels: %d\n",

               channel_counts[ACT_FRONT]);

        ch_error = 1;

        break;

    }

    if (channel_counts[ACT_SIDE] > 0) {

        if (channel_counts[ACT_SIDE] == 2) {

            ch_layout |= AV_CH_SIDE_LEFT | AV_CH_SIDE_RIGHT;

        } else {

            av_log(avctx, AV_LOG_WARNING,

                   "unsupported number of side channels: %d\n",

                   channel_counts[ACT_SIDE]);

            ch_error = 1;

        }

    }

    if (channel_counts[ACT_BACK] > 0) {

        switch (channel_counts[ACT_BACK]) {

        case 3:

            ch_layout |= AV_CH_BACK_LEFT | AV_CH_BACK_RIGHT | AV_CH_BACK_CENTER;

            break;

        case 2:

            ch_layout |= AV_CH_BACK_LEFT | AV_CH_BACK_RIGHT;

            break;

        case 1:

            ch_layout |= AV_CH_BACK_CENTER;

            break;

        default:

            av_log(avctx, AV_LOG_WARNING,

                   "unsupported number of back channels: %d\n",

                   channel_counts[ACT_BACK]);

            ch_error = 1;

            break;

        }

    }

    if (channel_counts[ACT_LFE] > 0) {

        if (channel_counts[ACT_LFE] == 1) {

            ch_layout |= AV_CH_LOW_FREQUENCY;

        } else {

            av_log(avctx, AV_LOG_WARNING,

                   "unsupported number of LFE channels: %d\n",

                   channel_counts[ACT_LFE]);

            ch_error = 1;

        }

    }

    if (!ch_error &&

        av_get_channel_layout_nb_channels(ch_layout) != info->numChannels) {

        av_log(avctx, AV_LOG_WARNING, "unsupported channel configuration\n");

        ch_error = 1;

    }

    if (ch_error)

        avctx->channel_layout = 0;

    else

        avctx->channel_layout = ch_layout;



    avctx->channels = info->numChannels;



    return 0;

}
