/*
 * MPEG-2/4 AAC ADTS to MPEG-4 Audio Specific Configuration bitstream filter
 * Copyright (c) 2009 Alex Converse <alex.converse@gmail.com>
 *
 * This file is part of FFmpeg.
 *
 * FFmpeg is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * FFmpeg is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with FFmpeg; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
 */

#include "avcodec.h"
#include "aacadtsdec.h"
#include "put_bits.h"
#include "get_bits.h"
#include "mpeg4audio.h"
#include "internal.h"

typedef struct AACBSFContext {
    int first_frame_done;
} AACBSFContext;

/**
 * This filter creates an MPEG-4 AudioSpecificConfig from an MPEG-2/4
 * ADTS header and removes the ADTS header.
 */
static int aac_adtstoasc_filter(AVBitStreamFilterContext *bsfc,
                                AVCodecContext *avctx, const char *args,
                                uint8_t  **poutbuf, int *poutbuf_size,
                                const uint8_t *buf, int      buf_size,
                                int keyframe)
{
    GetBitContext gb;
    PutBitContext pb;
    AACADTSHeaderInfo hdr;

    AACBSFContext *ctx = bsfc->priv_data;

    init_get_bits(&gb, buf, AAC_ADTS_HEADER_SIZE*8);

    *poutbuf = (uint8_t*) buf;
    *poutbuf_size = buf_size;

    if (avctx->extradata)
        if (show_bits(&gb, 12) != 0xfff)
            return 0;

    if (avpriv_aac_parse_header(&gb, &hdr) < 0) {
        av_log(avctx, AV_LOG_ERROR, "Error parsing ADTS frame header!\n");
        return AVERROR_INVALIDDATA;
    }

    if (!hdr.crc_absent && hdr.num_aac_frames > 1) {
        avpriv_report_missing_feature(avctx,
                                      "Multiple RDBs per frame with CRC");
        return AVERROR_PATCHWELCOME;
    }

    buf      += AAC_ADTS_HEADER_SIZE + 2*!hdr.crc_absent;
    buf_size -= AAC_ADTS_HEADER_SIZE + 2*!hdr.crc_absent;

    if (!ctx->first_frame_done) {
        int            pce_size = 0;
        uint8_t        pce_data[MAX_PCE_SIZE];
        if (!hdr.chan_config) {
            init_get_bits(&gb, buf, buf_size * 8);
            if (get_bits(&gb, 3) != 5) {
                avpriv_report_missing_feature(avctx,
                                              "PCE-based channel configuration "
                                              "without PCE as first syntax "
                                              "element");
                return AVERROR_PATCHWELCOME;
            }
            init_put_bits(&pb, pce_data, MAX_PCE_SIZE);
            pce_size = avpriv_copy_pce_data(&pb, &gb)/8;
            flush_put_bits(&pb);
            buf_size -= get_bits_count(&gb)/8;
            buf      += get_bits_count(&gb)/8;
        }
        av_free(avctx->extradata);
        avctx->extradata_size = 2 + pce_size;
        avctx->extradata = av_mallocz(avctx->extradata_size + AV_INPUT_BUFFER_PADDING_SIZE);
        if (!avctx->extradata) {
            avctx->extradata_size = 0;
            return AVERROR(ENOMEM);
        }

        init_put_bits(&pb, avctx->extradata, avctx->extradata_size);
        put_bits(&pb, 5, hdr.object_type);
        put_bits(&pb, 4, hdr.sampling_index);
        put_bits(&pb, 4, hdr.chan_config);
        put_bits(&pb, 1, 0); //frame length - 1024 samples
        put_bits(&pb, 1, 0); //does not depend on core coder
        put_bits(&pb, 1, 0); //is not extension
        flush_put_bits(&pb);
        if (pce_size) {
            memcpy(avctx->extradata + 2, pce_data, pce_size);
        }

        ctx->first_frame_done = 1;
    }

    *poutbuf = (uint8_t*) buf;
    *poutbuf_size = buf_size;

    return 0;
}

AVBitStreamFilter ff_aac_adtstoasc_bsf = {
    .name           = "aac_adtstoasc",
    .priv_data_size = sizeof(AACBSFContext),
    .filter         = aac_adtstoasc_filter,
};
