/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */

#include "config.h"
#include "ffmpeg-compat.h"
#include "log.h"
#include "video.h"

#include <libavcodec/avcodec.h>
#include <libavutil/common.h>
#include <libavutil/imgutils.h>
#include <guacamole/client.h>

#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>

/**
 * Writes a single packet of video data to the current output file. If an error
 * occurs preventing the packet from being written, messages describing the
 * error are logged.
 *
 * @param video
 *     The video associated with the output file that the given packet should
 *     be written to.
 *
 * @param data
 *     The buffer of data containing the video packet which should be written.
 *
 * @param size
 *     The number of bytes within the video packet.
 *
 * @return
 *     Zero if the packet was written successfully, non-zero otherwise.
 */
static int guacenc_write_packet(guacenc_video* video, void* data, int size) {

    int ret;

#if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(54,1,0)

    AVPacket pkt;

    /* Have to create a packet around the encoded data we have */
    av_init_packet(&pkt);

    if (video->context->coded_frame->pts != AV_NOPTS_VALUE) {
        pkt.pts = av_rescale_q(video->context->coded_frame->pts,
                video->context->time_base,
                video->output_stream->time_base);
    }
    if (video->context->coded_frame->key_frame) {
        pkt->flags |= AV_PKT_FLAG_KEY;
    }

    pkt.data = data;
    pkt.size = size;
    pkt.stream_index = video->output_stream->index;
    ret = av_interleaved_write_frame(video->container_format_context, &pkt);

#else

    /* We know data is already a packet if we're using a newer libavcodec */
    AVPacket* pkt = (AVPacket*) data;
    av_packet_rescale_ts(pkt, video->context->time_base, video->output_stream->time_base);
    pkt->stream_index = video->output_stream->index;
    ret = av_interleaved_write_frame(video->container_format_context, pkt);

#endif


    if (ret != 0) {
        guacenc_log(GUAC_LOG_ERROR, "Unable to write frame "
                "#%" PRId64 ": %s", video->next_pts, strerror(errno));
        return -1;
    }

    /* Data was written successfully */
    guacenc_log(GUAC_LOG_DEBUG, "Frame #%08" PRId64 ": wrote %i bytes",
            video->next_pts, size);

    return ret;
}

int guacenc_avcodec_encode_video(guacenc_video* video, AVFrame* frame) {

/* For libavcodec < 54.1.0: packets were handled as raw malloc'd buffers */
#if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(54,1,0)

    AVCodecContext* context = video->context;

    /* Calculate appropriate buffer size */
    int length = FF_MIN_BUFFER_SIZE + 12 * context->width * context->height;

    /* Allocate space for output */
    uint8_t* data = malloc(length);
    if (data == NULL)
        return -1;

    /* Encode packet of video data */
    int used = avcodec_encode_video(context, data, length, frame);
    if (used < 0) {
        guacenc_log(GUAC_LOG_WARNING, "Error encoding frame #%" PRId64,
                video->next_pts);
        free(data);
        return -1;
    }

    /* Report if no data needs to be written */
    if (used == 0) {
        free(data);
        return 0;
    }

    /* Write data, logging any errors */
    guacenc_write_packet(video, data, used);
    free(data);
    return 1;

#else

    /* Init video packet */
    AVPacket packet;
    av_init_packet(&packet);

    /* Request that encoder allocate data for packet */
    packet.data = NULL;
    packet.size = 0;

/* For libavcodec < 57.37.100: input/output was not decoupled */
#if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(57,37,100)

    /* Write frame to video */
    int got_data;
    if (avcodec_encode_video2(video->context, &packet, frame, &got_data) < 0) {
        guacenc_log(GUAC_LOG_WARNING, "Error encoding frame #%" PRId64,
                video->next_pts);
        return -1;
    }

    /* Write corresponding data to file */
    if (got_data) {
        guacenc_write_packet(video, (void*) &packet, packet.size);
        av_packet_unref(&packet);
    }

#else

    /* Write frame to video */
    int result = avcodec_send_frame(video->context, frame);

    /* Stop once encoded has been flushed */
    if (result == AVERROR_EOF)
        return 0;

    /* Abort on error */
    else if (result < 0) {
        guacenc_log(GUAC_LOG_WARNING, "Error encoding frame #%" PRId64,
                video->next_pts);
        return -1;
    }

    /* Flush all available packets */
    int got_data = 0;
    while (avcodec_receive_packet(video->context, &packet) == 0) {

        /* Data was received */
        got_data = 1;

        /* Attempt to write data to output file */
        guacenc_write_packet(video, (void*) &packet, packet.size);
        av_packet_unref(&packet);

    }

#endif

    /* Frame may have been queued for later writing / reordering */
    if (!got_data)
        guacenc_log(GUAC_LOG_DEBUG, "Frame #%08" PRId64 ": queued for later",
                video->next_pts);

    return got_data;

#endif
}

AVCodecContext* guacenc_build_avcodeccontext(AVStream* stream, AVCodec* codec, 
        int bitrate, int width, int height, int gop_size, int qmax, int qmin,
        int pix_fmt, AVRational time_base) {

#if LIBAVFORMAT_VERSION_INT < AV_VERSION_INT(57, 33, 100)
    stream->codec->bit_rate = bitrate;
    stream->codec->width = width;
    stream->codec->height = height;
    stream->codec->gop_size = gop_size;
    stream->codec->qmax = qmax;
    stream->codec->qmin = qmin;
    stream->codec->pix_fmt = pix_fmt;
    stream->codec->time_base = time_base;
#if LIBAVFORMAT_VERSION_INT >= AV_VERSION_INT(55, 44, 100)
    stream->time_base = time_base;
#endif
    return stream->codec;
#else
    AVCodecContext* context = avcodec_alloc_context3(codec);
    if (context) {
        context->bit_rate = bitrate;
        context->width = width;
        context->height = height;
        context->gop_size = gop_size;
        context->qmax = qmax;
        context->qmin = qmin;
        context->pix_fmt = pix_fmt;
        context->time_base = time_base;
        stream->time_base = time_base;
    }
    return context;
#endif

}

int guacenc_open_avcodec(AVCodecContext *avcodec_context,
        AVCodec *codec, AVDictionary **options,
        AVStream* stream) {

    int ret = avcodec_open2(avcodec_context, codec, options);

#if LIBAVFORMAT_VERSION_INT >= AV_VERSION_INT(57, 33, 100)
    /* Copy stream parameters to the muxer */
    int codecpar_ret = avcodec_parameters_from_context(stream->codecpar, avcodec_context);
    if (codecpar_ret < 0)
        return codecpar_ret;
#endif

    return ret;

}
