/*
 * Copyright (c) 2008 BBC, Anuradha Suraparaju <asuraparaju at gmail dot 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
 */

/**
* @file
* function definitions common to libschroedinger decoder and encoder
*/

#include "libschroedinger.h"
#include "libavutil/mem.h"

static const SchroVideoFormatInfo ff_schro_video_format_info[] = {
    { 640,  480,  24000, 1001},
    { 176,  120,  15000, 1001},
    { 176,  144,  25,    2   },
    { 352,  240,  15000, 1001},
    { 352,  288,  25,    2   },
    { 704,  480,  15000, 1001},
    { 704,  576,  25,    2   },
    { 720,  480,  30000, 1001},
    { 720,  576,  25,    1   },
    { 1280, 720,  60000, 1001},
    { 1280, 720,  50,    1   },
    { 1920, 1080, 30000, 1001},
    { 1920, 1080, 25,    1   },
    { 1920, 1080, 60000, 1001},
    { 1920, 1080, 50,    1   },
    { 2048, 1080, 24,    1   },
    { 4096, 2160, 24,    1   },
};

static unsigned int get_video_format_idx(AVCodecContext *avccontext)
{
    unsigned int ret_idx = 0;
    unsigned int idx;
    unsigned int num_formats = sizeof(ff_schro_video_format_info) /
                               sizeof(ff_schro_video_format_info[0]);

    for (idx = 1; idx < num_formats; ++idx) {
        const SchroVideoFormatInfo *vf = &ff_schro_video_format_info[idx];
        if (avccontext->width  == vf->width &&
            avccontext->height == vf->height) {
            ret_idx = idx;
            if (avccontext->time_base.den == vf->frame_rate_num &&
                avccontext->time_base.num == vf->frame_rate_denom)
                return idx;
        }
    }
    return ret_idx;
}

void ff_schro_queue_init(FFSchroQueue *queue)
{
    queue->p_head = queue->p_tail = NULL;
    queue->size = 0;
}

void ff_schro_queue_free(FFSchroQueue *queue, void (*free_func)(void *))
{
    while (queue->p_head)
        free_func(ff_schro_queue_pop(queue));
}

int ff_schro_queue_push_back(FFSchroQueue *queue, void *p_data)
{
    FFSchroQueueElement *p_new = av_mallocz(sizeof(FFSchroQueueElement));

    if (!p_new)
        return -1;

    p_new->data = p_data;

    if (!queue->p_head)
        queue->p_head = p_new;
    else
        queue->p_tail->next = p_new;
    queue->p_tail = p_new;

    ++queue->size;
    return 0;
}

void *ff_schro_queue_pop(FFSchroQueue *queue)
{
    FFSchroQueueElement *top = queue->p_head;

    if (top) {
        void *data = top->data;
        queue->p_head = queue->p_head->next;
        --queue->size;
        av_freep(&top);
        return data;
    }

    return NULL;
}

/**
* Schroedinger video preset table. Ensure that this tables matches up correctly
* with the ff_schro_video_format_info table.
*/
static const SchroVideoFormatEnum ff_schro_video_formats[]={
    SCHRO_VIDEO_FORMAT_CUSTOM     ,
    SCHRO_VIDEO_FORMAT_QSIF       ,
    SCHRO_VIDEO_FORMAT_QCIF       ,
    SCHRO_VIDEO_FORMAT_SIF        ,
    SCHRO_VIDEO_FORMAT_CIF        ,
    SCHRO_VIDEO_FORMAT_4SIF       ,
    SCHRO_VIDEO_FORMAT_4CIF       ,
    SCHRO_VIDEO_FORMAT_SD480I_60  ,
    SCHRO_VIDEO_FORMAT_SD576I_50  ,
    SCHRO_VIDEO_FORMAT_HD720P_60  ,
    SCHRO_VIDEO_FORMAT_HD720P_50  ,
    SCHRO_VIDEO_FORMAT_HD1080I_60 ,
    SCHRO_VIDEO_FORMAT_HD1080I_50 ,
    SCHRO_VIDEO_FORMAT_HD1080P_60 ,
    SCHRO_VIDEO_FORMAT_HD1080P_50 ,
    SCHRO_VIDEO_FORMAT_DC2K_24    ,
    SCHRO_VIDEO_FORMAT_DC4K_24    ,
};

SchroVideoFormatEnum ff_get_schro_video_format_preset(AVCodecContext *avccontext)
{
    unsigned int num_formats = sizeof(ff_schro_video_formats) /
                               sizeof(ff_schro_video_formats[0]);

    unsigned int idx = get_video_format_idx(avccontext);

    return (idx < num_formats) ? ff_schro_video_formats[idx] :
                                 SCHRO_VIDEO_FORMAT_CUSTOM;
}

int ff_get_schro_frame_format (SchroChromaFormat schro_pix_fmt,
                               SchroFrameFormat  *schro_frame_fmt)
{
    unsigned int num_formats = sizeof(schro_pixel_format_map) /
                               sizeof(schro_pixel_format_map[0]);

    int idx;

    for (idx = 0; idx < num_formats; ++idx) {
        if (schro_pixel_format_map[idx].schro_pix_fmt == schro_pix_fmt) {
            *schro_frame_fmt = schro_pixel_format_map[idx].schro_frame_fmt;
            return 0;
        }
    }
    return -1;
}

static void free_schro_frame(SchroFrame *frame, void *priv)
{
    AVPicture *p_pic = priv;

    if (!p_pic)
        return;

    avpicture_free(p_pic);
    av_freep(&p_pic);
}

SchroFrame *ff_create_schro_frame(AVCodecContext *avccontext,
                                  SchroFrameFormat schro_frame_fmt)
{
    AVPicture *p_pic;
    SchroFrame *p_frame;
    int y_width, uv_width;
    int y_height, uv_height;
    int i;

    y_width   = avccontext->width;
    y_height  = avccontext->height;
    uv_width  = y_width  >> (SCHRO_FRAME_FORMAT_H_SHIFT(schro_frame_fmt));
    uv_height = y_height >> (SCHRO_FRAME_FORMAT_V_SHIFT(schro_frame_fmt));

    p_pic = av_mallocz(sizeof(AVPicture));
    if (!p_pic || avpicture_alloc(p_pic, avccontext->pix_fmt, y_width, y_height) < 0) {
        av_free(p_pic);
        return NULL;
    }

    p_frame         = schro_frame_new();
    p_frame->format = schro_frame_fmt;
    p_frame->width  = y_width;
    p_frame->height = y_height;
    schro_frame_set_free_callback(p_frame, free_schro_frame, (void *)p_pic);

    for (i = 0; i < 3; ++i) {
        p_frame->components[i].width  = i ? uv_width : y_width;
        p_frame->components[i].stride = p_pic->linesize[i];
        p_frame->components[i].height = i ? uv_height : y_height;
        p_frame->components[i].length =
                 p_frame->components[i].stride * p_frame->components[i].height;
        p_frame->components[i].data   = p_pic->data[i];

        if (i) {
            p_frame->components[i].v_shift =
                SCHRO_FRAME_FORMAT_V_SHIFT(p_frame->format);
            p_frame->components[i].h_shift =
                SCHRO_FRAME_FORMAT_H_SHIFT(p_frame->format);
        }
    }

    return p_frame;
}
