/*
 * HEVC Annex B format parser
 *
 * Copyright (C) 2012 - 2013 Guillaume Martres
 *
 * 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 "libavutil/common.h"

#include "golomb.h"
#include "hevc.h"
#include "parser.h"

#define START_CODE 0x000001 ///< start_code_prefix_one_3bytes

#define IS_IRAP_NAL(nal) (nal->type >= 16 && nal->type <= 23)

#define ADVANCED_PARSER CONFIG_HEVC_DECODER

typedef struct HEVCParserContext {
    ParseContext pc;

    HEVCPacket pkt;
    HEVCParamSets ps;

    int parsed_extradata;

#if ADVANCED_PARSER
    HEVCContext h;
#endif
} HEVCParserContext;

#if !ADVANCED_PARSER
static int hevc_parse_slice_header(AVCodecParserContext *s, HEVCNAL *nal,
                                   AVCodecContext *avctx)
{
    HEVCParserContext *ctx = s->priv_data;
    GetBitContext *gb = &nal->gb;

    HEVCPPS *pps;
    HEVCSPS *sps;
    unsigned int pps_id;

    get_bits1(gb);          // first slice in pic
    if (IS_IRAP_NAL(nal))
        get_bits1(gb);      // no output of prior pics

    pps_id = get_ue_golomb_long(gb);
    if (pps_id >= MAX_PPS_COUNT || !ctx->ps.pps_list[pps_id]) {
        av_log(avctx, AV_LOG_ERROR, "PPS id out of range: %d\n", pps_id);
        return AVERROR_INVALIDDATA;
    }
    pps = (HEVCPPS*)ctx->ps.pps_list[pps_id]->data;
    sps = (HEVCSPS*)ctx->ps.sps_list[pps->sps_id]->data;

    /* export the stream parameters */
    s->coded_width  = sps->width;
    s->coded_height = sps->height;
    s->width        = sps->output_width;
    s->height       = sps->output_height;
    s->format       = sps->pix_fmt;
    avctx->profile  = sps->ptl.general_ptl.profile_idc;
    avctx->level    = sps->ptl.general_ptl.level_idc;

    /* ignore the rest for now*/

    return 0;
}

static int parse_nal_units(AVCodecParserContext *s, const uint8_t *buf,
                           int buf_size, AVCodecContext *avctx)
{
    HEVCParserContext *ctx = s->priv_data;
    int ret, i;

    ret = ff_hevc_split_packet(NULL, &ctx->pkt, buf, buf_size, avctx, 0, 0);
    if (ret < 0)
        return ret;

    for (i = 0; i < ctx->pkt.nb_nals; i++) {
        HEVCNAL *nal = &ctx->pkt.nals[i];

        /* ignore everything except parameter sets and VCL NALUs */
        switch (nal->type) {
        case NAL_VPS: ff_hevc_decode_nal_vps(&nal->gb, avctx, &ctx->ps);    break;
        case NAL_SPS: ff_hevc_decode_nal_sps(&nal->gb, avctx, &ctx->ps, 1); break;
        case NAL_PPS: ff_hevc_decode_nal_pps(&nal->gb, avctx, &ctx->ps);    break;
        case NAL_TRAIL_R:
        case NAL_TRAIL_N:
        case NAL_TSA_N:
        case NAL_TSA_R:
        case NAL_STSA_N:
        case NAL_STSA_R:
        case NAL_BLA_W_LP:
        case NAL_BLA_W_RADL:
        case NAL_BLA_N_LP:
        case NAL_IDR_W_RADL:
        case NAL_IDR_N_LP:
        case NAL_CRA_NUT:
        case NAL_RADL_N:
        case NAL_RADL_R:
        case NAL_RASL_N:
        case NAL_RASL_R:
            if (buf == avctx->extradata) {
                av_log(avctx, AV_LOG_ERROR, "Invalid NAL unit: %d\n", nal->type);
                return AVERROR_INVALIDDATA;
            }
            hevc_parse_slice_header(s, nal, avctx);
            break;
        }
    }

    return 0;
}
#endif

/**
 * Find the end of the current frame in the bitstream.
 * @return the position of the first byte of the next frame, or END_NOT_FOUND
 */
static int hevc_find_frame_end(AVCodecParserContext *s, const uint8_t *buf,
                               int buf_size)
{
    int i;
    ParseContext *pc = s->priv_data;

    for (i = 0; i < buf_size; i++) {
        int nut;

        pc->state64 = (pc->state64 << 8) | buf[i];

        if (((pc->state64 >> 3 * 8) & 0xFFFFFF) != START_CODE)
            continue;

        nut = (pc->state64 >> 2 * 8 + 1) & 0x3F;
        // Beginning of access unit
        if ((nut >= NAL_VPS && nut <= NAL_AUD) || nut == NAL_SEI_PREFIX ||
            (nut >= 41 && nut <= 44) || (nut >= 48 && nut <= 55)) {
            if (pc->frame_start_found) {
                pc->frame_start_found = 0;
                return i - 5;
            }
        } else if (nut <= NAL_RASL_R ||
                   (nut >= NAL_BLA_W_LP && nut <= NAL_CRA_NUT)) {
            int first_slice_segment_in_pic_flag = buf[i] >> 7;
            if (first_slice_segment_in_pic_flag) {
                if (!pc->frame_start_found) {
                    pc->frame_start_found = 1;
                } else { // First slice of next frame found
                    pc->frame_start_found = 0;
                    return i - 5;
                }
            }
        }
    }

    return END_NOT_FOUND;
}

#if ADVANCED_PARSER
/**
 * Parse NAL units of found picture and decode some basic information.
 *
 * @param s parser context.
 * @param avctx codec context.
 * @param buf buffer with field/frame data.
 * @param buf_size size of the buffer.
 */
static inline int parse_nal_units(AVCodecParserContext *s, const uint8_t *buf,
                           int buf_size, AVCodecContext *avctx)
{
    HEVCParserContext *ctx = s->priv_data;
    HEVCContext       *h   = &ctx->h;
    GetBitContext      *gb;
    SliceHeader        *sh = &h->sh;
    HEVCParamSets *ps = &h->ps;
    HEVCPacket   *pkt = &ctx->pkt;
    const uint8_t *buf_end = buf + buf_size;
    int state = -1, i;
    HEVCNAL *nal;
    int is_global = buf == avctx->extradata;

    if (!h->HEVClc)
        h->HEVClc = av_mallocz(sizeof(HEVCLocalContext));
    if (!h->HEVClc)
        return AVERROR(ENOMEM);

    gb = &h->HEVClc->gb;

    /* set some sane default values */
    s->pict_type         = AV_PICTURE_TYPE_I;
    s->key_frame         = 0;
    s->picture_structure = AV_PICTURE_STRUCTURE_UNKNOWN;

    h->avctx = avctx;

    if (!buf_size)
        return 0;

    if (pkt->nals_allocated < 1) {
        HEVCNAL *tmp = av_realloc_array(pkt->nals, 1, sizeof(*tmp));
        if (!tmp)
            return AVERROR(ENOMEM);
        pkt->nals = tmp;
        memset(pkt->nals, 0, sizeof(*tmp));
        pkt->nals_allocated = 1;
    }

    nal = &pkt->nals[0];

    for (;;) {
        int src_length, consumed;
        int ret;
        buf = avpriv_find_start_code(buf, buf_end, &state);
        if (--buf + 2 >= buf_end)
            break;
        src_length = buf_end - buf;

        h->nal_unit_type = (*buf >> 1) & 0x3f;
        h->temporal_id   = (*(buf + 1) & 0x07) - 1;
        if (h->nal_unit_type <= NAL_CRA_NUT) {
            // Do not walk the whole buffer just to decode slice segment header
            if (src_length > 20)
                src_length = 20;
        }

        consumed = ff_hevc_extract_rbsp(NULL, buf, src_length, nal);
        if (consumed < 0)
            return consumed;

        ret = init_get_bits8(gb, nal->data + 2, nal->size);
        if (ret < 0)
            return ret;

        switch (h->nal_unit_type) {
        case NAL_VPS:
            ff_hevc_decode_nal_vps(gb, avctx, ps);
            break;
        case NAL_SPS:
            ff_hevc_decode_nal_sps(gb, avctx, ps, 1);
            break;
        case NAL_PPS:
            ff_hevc_decode_nal_pps(gb, avctx, ps);
            break;
        case NAL_SEI_PREFIX:
        case NAL_SEI_SUFFIX:
            ff_hevc_decode_nal_sei(h);
            break;
        case NAL_TRAIL_N:
        case NAL_TRAIL_R:
        case NAL_TSA_N:
        case NAL_TSA_R:
        case NAL_STSA_N:
        case NAL_STSA_R:
        case NAL_RADL_N:
        case NAL_RADL_R:
        case NAL_RASL_N:
        case NAL_RASL_R:
        case NAL_BLA_W_LP:
        case NAL_BLA_W_RADL:
        case NAL_BLA_N_LP:
        case NAL_IDR_W_RADL:
        case NAL_IDR_N_LP:
        case NAL_CRA_NUT:

            if (is_global) {
                av_log(avctx, AV_LOG_ERROR, "Invalid NAL unit: %d\n", h->nal_unit_type);
                return AVERROR_INVALIDDATA;
            }

            sh->first_slice_in_pic_flag = get_bits1(gb);
            s->picture_structure = h->picture_struct;
            s->field_order = h->picture_struct;

            if (IS_IRAP(h)) {
                s->key_frame = 1;
                sh->no_output_of_prior_pics_flag = get_bits1(gb);
            }

            sh->pps_id = get_ue_golomb(gb);
            if (sh->pps_id >= MAX_PPS_COUNT || !ps->pps_list[sh->pps_id]) {
                av_log(avctx, AV_LOG_ERROR, "PPS id out of range: %d\n", sh->pps_id);
                return AVERROR_INVALIDDATA;
            }
            ps->pps = (HEVCPPS*)ps->pps_list[sh->pps_id]->data;

            if (ps->pps->sps_id >= MAX_SPS_COUNT || !ps->sps_list[ps->pps->sps_id]) {
                av_log(avctx, AV_LOG_ERROR, "SPS id out of range: %d\n", ps->pps->sps_id);
                return AVERROR_INVALIDDATA;
            }
            if (ps->sps != (HEVCSPS*)ps->sps_list[ps->pps->sps_id]->data) {
                ps->sps = (HEVCSPS*)ps->sps_list[ps->pps->sps_id]->data;
                ps->vps = (HEVCVPS*)ps->vps_list[ps->sps->vps_id]->data;
            }

            if (!sh->first_slice_in_pic_flag) {
                int slice_address_length;

                if (ps->pps->dependent_slice_segments_enabled_flag)
                    sh->dependent_slice_segment_flag = get_bits1(gb);
                else
                    sh->dependent_slice_segment_flag = 0;

                slice_address_length = av_ceil_log2_c(ps->sps->ctb_width *
                                                      ps->sps->ctb_height);
                sh->slice_segment_addr = get_bitsz(gb, slice_address_length);
                if (sh->slice_segment_addr >= ps->sps->ctb_width * ps->sps->ctb_height) {
                    av_log(avctx, AV_LOG_ERROR, "Invalid slice segment address: %u.\n",
                           sh->slice_segment_addr);
                    return AVERROR_INVALIDDATA;
                }
            } else
                sh->dependent_slice_segment_flag = 0;

            if (sh->dependent_slice_segment_flag)
                break;

            for (i = 0; i < ps->pps->num_extra_slice_header_bits; i++)
                skip_bits(gb, 1); // slice_reserved_undetermined_flag[]

            sh->slice_type = get_ue_golomb(gb);
            if (!(sh->slice_type == I_SLICE || sh->slice_type == P_SLICE ||
                  sh->slice_type == B_SLICE)) {
                av_log(avctx, AV_LOG_ERROR, "Unknown slice type: %d.\n",
                       sh->slice_type);
                return AVERROR_INVALIDDATA;
            }
            s->pict_type = sh->slice_type == B_SLICE ? AV_PICTURE_TYPE_B :
                           sh->slice_type == P_SLICE ? AV_PICTURE_TYPE_P :
                                                       AV_PICTURE_TYPE_I;

            if (ps->pps->output_flag_present_flag)
                sh->pic_output_flag = get_bits1(gb);

            if (ps->sps->separate_colour_plane_flag)
                sh->colour_plane_id = get_bits(gb, 2);

            if (!IS_IDR(h)) {
                sh->pic_order_cnt_lsb = get_bits(gb, ps->sps->log2_max_poc_lsb);
                s->output_picture_number = h->poc = ff_hevc_compute_poc(h, sh->pic_order_cnt_lsb);
            } else
                s->output_picture_number = h->poc = 0;

            if (h->temporal_id == 0 &&
                h->nal_unit_type != NAL_TRAIL_N &&
                h->nal_unit_type != NAL_TSA_N &&
                h->nal_unit_type != NAL_STSA_N &&
                h->nal_unit_type != NAL_RADL_N &&
                h->nal_unit_type != NAL_RASL_N &&
                h->nal_unit_type != NAL_RADL_R &&
                h->nal_unit_type != NAL_RASL_R)
                h->pocTid0 = h->poc;

            return 0; /* no need to evaluate the rest */
        }
        buf += consumed;
    }
    /* didn't find a picture! */
    if (!is_global)
        av_log(h->avctx, AV_LOG_ERROR, "missing picture in access unit\n");
    return -1;
}
#endif

static int hevc_parse(AVCodecParserContext *s,
                      AVCodecContext *avctx,
                      const uint8_t **poutbuf, int *poutbuf_size,
                      const uint8_t *buf, int buf_size)
{
    int next;
    HEVCParserContext *ctx = s->priv_data;
    ParseContext *pc = &ctx->pc;

    if (avctx->extradata && !ctx->parsed_extradata) {
        parse_nal_units(s, avctx->extradata, avctx->extradata_size, avctx);
        ctx->parsed_extradata = 1;
    }

    if (s->flags & PARSER_FLAG_COMPLETE_FRAMES) {
        next = buf_size;
    } else {
        next = hevc_find_frame_end(s, buf, buf_size);
        if (ff_combine_frame(pc, next, &buf, &buf_size) < 0) {
            *poutbuf      = NULL;
            *poutbuf_size = 0;
            return buf_size;
        }
    }

    parse_nal_units(s, buf, buf_size, avctx);

    *poutbuf      = buf;
    *poutbuf_size = buf_size;
    return next;
}

// Split after the parameter sets at the beginning of the stream if they exist.
static int hevc_split(AVCodecContext *avctx, const uint8_t *buf, int buf_size)
{
    const uint8_t *ptr = buf, *end = buf + buf_size;
    uint32_t state = -1;
    int has_vps = 0;
    int has_sps = 0;
    int has_pps = 0;
    int nut;

    while (ptr < end) {
        ptr = avpriv_find_start_code(ptr, end, &state);
        if ((state >> 8) != START_CODE)
            break;
        nut = (state >> 1) & 0x3F;
        if (nut == NAL_VPS)
            has_vps = 1;
        else if (nut == NAL_SPS)
            has_sps = 1;
        else if (nut == NAL_PPS)
            has_pps = 1;
        else if ((nut != NAL_SEI_PREFIX || has_pps) &&
                  nut != NAL_AUD) {
            if (has_vps && has_sps) {
                while (ptr - 4 > buf && ptr[-5] == 0)
                    ptr--;
                return ptr - 4 - buf;
            }
        }
    }
    return 0;
}

static void hevc_parser_close(AVCodecParserContext *s)
{
    HEVCParserContext *ctx = s->priv_data;
    int i;

#if ADVANCED_PARSER
    HEVCContext  *h  = &ctx->h;

    for (i = 0; i < FF_ARRAY_ELEMS(h->ps.vps_list); i++)
        av_buffer_unref(&h->ps.vps_list[i]);
    for (i = 0; i < FF_ARRAY_ELEMS(h->ps.sps_list); i++)
        av_buffer_unref(&h->ps.sps_list[i]);
    for (i = 0; i < FF_ARRAY_ELEMS(h->ps.pps_list); i++)
        av_buffer_unref(&h->ps.pps_list[i]);

    h->ps.sps = NULL;

    av_freep(&h->HEVClc);
#endif

    for (i = 0; i < FF_ARRAY_ELEMS(ctx->ps.vps_list); i++)
        av_buffer_unref(&ctx->ps.vps_list[i]);
    for (i = 0; i < FF_ARRAY_ELEMS(ctx->ps.sps_list); i++)
        av_buffer_unref(&ctx->ps.sps_list[i]);
    for (i = 0; i < FF_ARRAY_ELEMS(ctx->ps.pps_list); i++)
        av_buffer_unref(&ctx->ps.pps_list[i]);

    ctx->ps.sps = NULL;

    for (i = 0; i < ctx->pkt.nals_allocated; i++) {
        av_freep(&ctx->pkt.nals[i].rbsp_buffer);
        av_freep(&ctx->pkt.nals[i].skipped_bytes_pos);
    }
    av_freep(&ctx->pkt.nals);
    ctx->pkt.nals_allocated = 0;

    av_freep(&ctx->pc.buffer);
}

AVCodecParser ff_hevc_parser = {
    .codec_ids      = { AV_CODEC_ID_HEVC },
    .priv_data_size = sizeof(HEVCParserContext),
    .parser_parse   = hevc_parse,
    .parser_close   = hevc_parser_close,
    .split          = hevc_split,
};
