/*
 * G.729 bit format muxer and demuxer
 * Copyright (c) 2007-2008 Vladimir Voroshilov
 *
 * 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 "avformat.h"
#include "internal.h"
#include "libavcodec/get_bits.h"
#include "libavcodec/put_bits.h"

#define MAX_FRAME_SIZE 10

#define SYNC_WORD  0x6b21
#define BIT_0      0x7f
#define BIT_1      0x81

#if CONFIG_BIT_DEMUXER
static int probe(AVProbeData *p)
{
    int i = 0, j, valid = 0;

    while (2 * i + 3 < p->buf_size){
        if (AV_RL16(&p->buf[2 * i++]) != SYNC_WORD)
            return 0;
        j = AV_RL16(&p->buf[2 * i++]);
        if (j != 0 && j != 0x10 && j != 0x40 && j != 0x50 && j != 0x76)
            return 0;
        if (j)
            valid++;
        i += j;
    }
    if (valid > 10)
        return AVPROBE_SCORE_MAX;
    if (valid > 2)
        return AVPROBE_SCORE_EXTENSION - 1;
    return 0;
}

static int read_header(AVFormatContext *s)
{
    AVStream* st;

    st=avformat_new_stream(s, NULL);
    if (!st)
        return AVERROR(ENOMEM);

    st->codecpar->codec_type = AVMEDIA_TYPE_AUDIO;
    st->codecpar->codec_id=AV_CODEC_ID_G729;
    st->codecpar->sample_rate=8000;
    st->codecpar->block_align = 16;
    st->codecpar->channels=1;

    avpriv_set_pts_info(st, 64, 1, 100);
    return 0;
}

static int read_packet(AVFormatContext *s,
                          AVPacket *pkt)
{
    AVIOContext *pb = s->pb;
    PutBitContext pbo;
    uint16_t buf[8 * MAX_FRAME_SIZE + 2];
    int packet_size;
    uint16_t* src=buf;
    int i, j, ret;
    int64_t pos= avio_tell(pb);

    if(avio_feof(pb))
        return AVERROR_EOF;

    avio_rl16(pb); // sync word
    packet_size = avio_rl16(pb) / 8;
    if(packet_size > MAX_FRAME_SIZE)
        return AVERROR_INVALIDDATA;

    ret = avio_read(pb, (uint8_t*)buf, (8 * packet_size) * sizeof(uint16_t));
    if(ret<0)
        return ret;
    if(ret != 8 * packet_size * sizeof(uint16_t))
        return AVERROR(EIO);

    if (av_new_packet(pkt, packet_size) < 0)
        return AVERROR(ENOMEM);

    init_put_bits(&pbo, pkt->data, packet_size);
    for(j=0; j < packet_size; j++)
        for(i=0; i<8;i++)
            put_bits(&pbo,1, AV_RL16(src++) == BIT_1 ? 1 : 0);

    flush_put_bits(&pbo);

    pkt->duration=1;
    pkt->pos = pos;
    return 0;
}

AVInputFormat ff_bit_demuxer = {
    .name        = "bit",
    .long_name   = NULL_IF_CONFIG_SMALL("G.729 BIT file format"),
    .read_probe  = probe,
    .read_header = read_header,
    .read_packet = read_packet,
    .extensions  = "bit",
};
#endif

#if CONFIG_BIT_MUXER
static int write_header(AVFormatContext *s)
{
    AVCodecParameters *par = s->streams[0]->codecpar;

    if ((par->codec_id != AV_CODEC_ID_G729) || par->channels != 1) {
        av_log(s, AV_LOG_ERROR,
               "only codec g729 with 1 channel is supported by this format\n");
        return AVERROR(EINVAL);
    }

    par->bits_per_coded_sample = 16;
    par->block_align = (par->bits_per_coded_sample * par->channels) >> 3;

    return 0;
}

static int write_packet(AVFormatContext *s, AVPacket *pkt)
{
    AVIOContext *pb = s->pb;
    GetBitContext gb;
    int i;

    if (pkt->size != 10)
        return AVERROR(EINVAL);

    avio_wl16(pb, SYNC_WORD);
    avio_wl16(pb, 8 * pkt->size);

    init_get_bits(&gb, pkt->data, 8 * pkt->size);
    for (i = 0; i < 8 * pkt->size; i++)
        avio_wl16(pb, get_bits1(&gb) ? BIT_1 : BIT_0);

    return 0;
}

AVOutputFormat ff_bit_muxer = {
    .name         = "bit",
    .long_name    = NULL_IF_CONFIG_SMALL("G.729 BIT file format"),
    .mime_type    = "audio/bit",
    .extensions   = "bit",
    .audio_codec  = AV_CODEC_ID_G729,
    .video_codec  = AV_CODEC_ID_NONE,
    .write_header = write_header,
    .write_packet = write_packet,
};
#endif
