/*
 * FLV Encoding specific code.
 *
 * 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 "flv.h"
#include "h263.h"
#include "h263data.h"
#include "mpegvideo.h"
#include "mpegvideodata.h"

void ff_flv_encode_picture_header(MpegEncContext *s, int picture_number)
{
    int format;

    avpriv_align_put_bits(&s->pb);

    put_bits(&s->pb, 17, 1);
    /* 0: H.263 escape codes 1: 11-bit escape codes */
    put_bits(&s->pb, 5, (s->h263_flv - 1));
    put_bits(&s->pb, 8,
             (((int64_t) s->picture_number * 30 * s->avctx->time_base.num) /   // FIXME use timestamp
              s->avctx->time_base.den) & 0xff);   /* TemporalReference */
    if (s->width == 352 && s->height == 288)
        format = 2;
    else if (s->width == 176 && s->height == 144)
        format = 3;
    else if (s->width == 128 && s->height == 96)
        format = 4;
    else if (s->width == 320 && s->height == 240)
        format = 5;
    else if (s->width == 160 && s->height == 120)
        format = 6;
    else if (s->width <= 255 && s->height <= 255)
        format = 0;   /* use 1 byte width & height */
    else
        format = 1;   /* use 2 bytes width & height */
    put_bits(&s->pb, 3, format);   /* PictureSize */
    if (format == 0) {
        put_bits(&s->pb, 8, s->width);
        put_bits(&s->pb, 8, s->height);
    } else if (format == 1) {
        put_bits(&s->pb, 16, s->width);
        put_bits(&s->pb, 16, s->height);
    }
    put_bits(&s->pb, 2, s->pict_type == AV_PICTURE_TYPE_P);   /* PictureType */
    put_bits(&s->pb, 1, 1);   /* DeblockingFlag: on */
    put_bits(&s->pb, 5, s->qscale);   /* Quantizer */
    put_bits(&s->pb, 1, 0);   /* ExtraInformation */

    if (s->h263_aic) {
        s->y_dc_scale_table =
        s->c_dc_scale_table = ff_aic_dc_scale_table;
    } else {
        s->y_dc_scale_table =
        s->c_dc_scale_table = ff_mpeg1_dc_scale_table;
    }
}

void ff_flv2_encode_ac_esc(PutBitContext *pb, int slevel, int level,
                           int run, int last)
{
    if (level < 64) { // 7-bit level
        put_bits(pb, 1, 0);
        put_bits(pb, 1, last);
        put_bits(pb, 6, run);

        put_sbits(pb, 7, slevel);
    } else {
        /* 11-bit level */
        put_bits(pb, 1, 1);
        put_bits(pb, 1, last);
        put_bits(pb, 6, run);

        put_sbits(pb, 11, slevel);
    }
}

static const AVClass flv_class = {
    .class_name = "flv encoder",
    .item_name  = av_default_item_name,
    .option     = ff_mpv_generic_options,
    .version    = LIBAVUTIL_VERSION_INT,
};

AVCodec ff_flv_encoder = {
    .name           = "flv",
    .long_name      = NULL_IF_CONFIG_SMALL("FLV / Sorenson Spark / Sorenson H.263 (Flash Video)"),
    .type           = AVMEDIA_TYPE_VIDEO,
    .id             = AV_CODEC_ID_FLV1,
    .priv_data_size = sizeof(MpegEncContext),
    .init           = ff_mpv_encode_init,
    .encode2        = ff_mpv_encode_picture,
    .close          = ff_mpv_encode_end,
    .pix_fmts       = (const enum AVPixelFormat[]) { AV_PIX_FMT_YUV420P,
                                                     AV_PIX_FMT_NONE},
    .priv_class     = &flv_class,
};
