/*
 * Sony OpenMG (OMA) muxer
 *
 * Copyright (c) 2011 Michael Karcher
 *
 * 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 "avio_internal.h"
#include "id3v2.h"
#include "internal.h"
#include "oma.h"
#include "rawenc.h"

static av_cold int oma_write_header(AVFormatContext *s)
{
    int i;
    AVCodecContext *format;
    int srate_index;
    int isjointstereo;

    format = s->streams[0]->codec;
    /* check for support of the format first */

    for (srate_index = 0; ; srate_index++) {
        if (ff_oma_srate_tab[srate_index] == 0) {
            av_log(s, AV_LOG_ERROR, "Sample rate %d not supported in OpenMG audio\n",
                   format->sample_rate);
            return AVERROR(EINVAL);
        }

        if (ff_oma_srate_tab[srate_index] * 100 == format->sample_rate)
            break;
    }

    /* Metadata; OpenMG does not support ID3v2.4 */
    ff_id3v2_write_simple(s, 3, ID3v2_EA3_MAGIC);

    ffio_wfourcc(s->pb, "EA3\0");
    avio_w8(s->pb, EA3_HEADER_SIZE >> 7);
    avio_w8(s->pb, EA3_HEADER_SIZE & 0x7F);
    avio_wl16(s->pb, 0xFFFF);       /* not encrypted */
    for (i = 0; i < 6; i++)
        avio_wl32(s->pb, 0);        /* Padding + DRM id */

    switch(format->codec_tag) {
    case OMA_CODECID_ATRAC3:
        if (format->channels != 2) {
            av_log(s, AV_LOG_ERROR, "ATRAC3 in OMA is only supported with 2 channels\n");
            return AVERROR(EINVAL);
        }
        if (format->extradata_size == 14) /* WAV format extradata */
            isjointstereo = format->extradata[6] != 0;
        else if(format->extradata_size == 10) /* RM format extradata */
            isjointstereo = format->extradata[8] == 0x12;
        else {
            av_log(s, AV_LOG_ERROR, "ATRAC3: Unsupported extradata size\n");
            return AVERROR(EINVAL);
        }
        avio_wb32(s->pb, (OMA_CODECID_ATRAC3 << 24) |
                         (isjointstereo << 17) |
                         (srate_index << 13) |
                         (format->block_align/8));
        break;
    case OMA_CODECID_ATRAC3P:
        avio_wb32(s->pb, (OMA_CODECID_ATRAC3P << 24) |
                         (srate_index << 13) |
                         (format->channels << 10) |
                         (format->block_align/8 - 1));
        break;
    default:
        av_log(s, AV_LOG_ERROR, "unsupported codec tag %d for write\n",
               format->codec_tag);
        return AVERROR(EINVAL);
    }
    for (i = 0; i < (EA3_HEADER_SIZE - 36)/4; i++)
        avio_wl32(s->pb, 0);        /* Padding */

    return 0;
}

AVOutputFormat ff_oma_muxer = {
    .name              = "oma",
    .long_name         = NULL_IF_CONFIG_SMALL("Sony OpenMG audio"),
    .mime_type         = "audio/x-oma",
    .extensions        = "oma",
    .audio_codec       = AV_CODEC_ID_ATRAC3,
    .write_header      = oma_write_header,
    .write_packet      = ff_raw_write_packet,
    .codec_tag         = (const AVCodecTag* const []){ff_oma_codec_tags, 0},
    .flags             = AVFMT_NOTIMESTAMPS,
};
