/*
 * Copyright (c) 2018 Georg Ottinger. All Rights Reserved.
 *
 * Permission is hereby granted, free of charge, to any person obtaining a
 * copy of this software and associated documentation files (the
 * "Software"), to deal in the Software without restriction, including
 * without limitation the rights to use, copy, modify, merge, publish,
 * distribute, sub license, and/or sell copies of the Software, and to
 * permit persons to whom the Software is furnished to do so, subject to
 * the following conditions:
 *
 * The above copyright notice and this permission notice (including the
 * next paragraph) shall be included in all copies or substantial portions
 * of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
 * IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR
 * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 */

/* This file includes code taken from vp9enc.c (libva-utils) copyright 2017
 * by Intel Cooperation and licensed under same conditions.
 * This file includes code ported from vaapiencoder_vp8.cpp (libyami) copyright
 * by 2014-2016 Intel Corporation. https://github.com/intel/libyami
 * The original copyright and licence statement as below.
 */

 /*
  * Copyright (C) 2014-2016 Intel Corporation. All rights reserved.
  *
  * Licensed 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 <stdbool.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <getopt.h>
#include <unistd.h>
#include <inttypes.h>

#include <sys/time.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/mman.h>
#include <fcntl.h>
#include <assert.h>
#include <time.h>
#include <stdlib.h>
#include <pthread.h>

#include <va/va.h>
#include <va/va_enc_vp8.h>
#include "va_display.h"

#define MAX_XY_RESOLUTION       16364

#define KEY_FRAME               0
#define INTER_FRAME             1

#define NUM_REF_SURFACES        4
#define NUM_INPUT_SURFACES      2
#define NUM_SURFACES_TOTAL      (NUM_REF_SURFACES+NUM_INPUT_SURFACES)
#define SID_INPUT_PICTURE_0     (NUM_REF_SURFACES)
#define SID_INPUT_PICTURE_1     (NUM_REF_SURFACES+1)
#define NUM_BUFFERS             10

#define VP8ENC_OK               0
#define VP8ENC_FAIL             -1
#define PARSE_OPTIONS_OK        0
#define PARSE_OPTIONS_FAIL      -1

#ifndef N_ELEMENTS
#define N_ELEMENTS(array) (sizeof(array)/sizeof(array[0]))
#endif

#ifndef CHECK_VASTATUS
#define CHECK_VASTATUS(va_status,func)                                  \
    if (va_status != VA_STATUS_SUCCESS) {                               \
        fprintf(stderr,"%s:%s (%d) failed,exit\n", __func__, func, __LINE__); \
        exit(1);                                                        \
    }
#endif



static const struct option long_opts[] = {
    {"help", no_argument, NULL, 0 },
    {"rcmode", required_argument, NULL, 1 },
    {"qp", required_argument, NULL, 2 },
    {"intra_period", required_argument, NULL, 3 },
    {"fb", required_argument, NULL, 4 },
    {"lf_level", required_argument, NULL, 5 },
    {"hrd_win", required_argument, NULL, 6},
    {"vbr_max", required_argument, NULL, 7},
    {"fn_num", required_argument, NULL, 8},
    {"error_resilient", no_argument, NULL, 9},
    {"debug", no_argument, NULL, 10},
    {"temp_svc", required_argument, NULL, 11},
    {"repeat", required_argument, NULL, 12},
    {NULL, no_argument, NULL, 0 }
};


static const int default_rc_modes[4] = {
    VA_RC_CQP, // 0
    VA_RC_CBR, // 1
    VA_RC_VBR, // 2
    VA_RC_NONE
};

struct vp8enc_settings {
  int width;
  int height;
  int frame_rate;
  int frame_size;
  int loop_filter_level;
  int clamp_qindex_low;
  int clamp_qindex_high;
  int intra_period;
  int quantization_parameter;
  int frame_bitrate;
  int max_variable_bitrate;
  int rc_mode;
  int num_frames;
  VAEntrypoint vaapi_entry_point;
  int codedbuf_size;
  int hrd_window;
  int error_resilient;
  int debug;
  int temporal_svc_layers;
  int repeat_times;
};


static struct vp8enc_settings settings =
  {
    //Default Values - unless otherwise specified with command line options
    .frame_rate = 30,
    .loop_filter_level = 19,
    .clamp_qindex_low = 9,
    .clamp_qindex_high = 127,
    .intra_period = 30,
    .quantization_parameter = 60,
    .frame_bitrate = -1,
    .max_variable_bitrate = -1,
    .num_frames = 0,
    .rc_mode = VA_RC_CQP,
    .vaapi_entry_point = VAEntrypointEncSlice, //VAEntrypointEncSliceLP would be LowPower Mode - but not supported with VP8Encoder
    .hrd_window = 1500,
    .error_resilient = 0,
    .debug = 0,
    .temporal_svc_layers = 1,
    .repeat_times = 1,
 };

 struct vp8enc_vaapi_context {
     VADisplay display;
     VAProfile profile;
     VAContextID context_id;
     VAConfigID config_id;
     VAEncSequenceParameterBufferVP8 seq_param;
     VAEncPictureParameterBufferVP8 pic_param;
     VAQMatrixBufferVP8 q_matrix;
     VASurfaceID surfaces[NUM_SURFACES_TOTAL];
     VASurfaceID recon_surface, last_ref_surface, golden_ref_surface, alt_ref_surface;
     VASurfaceID input_surface;
     VABufferID codedbuf_buf_id;
     VABufferID va_buffers[NUM_BUFFERS];
     int num_va_buffers;
     int is_golden_refreshed;
     struct {
       VAEncMiscParameterBuffer header;
       VAEncMiscParameterHRD data;
     } hrd_param;
     struct {
       VAEncMiscParameterBuffer header;
       VAEncMiscParameterFrameRate data;
     } frame_rate_param;
     struct {
       VAEncMiscParameterBuffer header;
       VAEncMiscParameterRateControl data;
     } rate_control_param;
     struct {
       pthread_t id;
       int value;
       FILE *input_fp;
       int input_surface_num;
       VASurfaceID input_surface;
       int processed_frame;
     } upload_thread;
};

static struct vp8enc_vaapi_context vaapi_context;


/********************************************
*
* START: IVF Container Releated Stuff
*
********************************************/
static void
vp8enc_write_word(char *ptr, uint32_t value)
{
    uint8_t *tmp;

    tmp = (uint8_t *)ptr;
    *(tmp) = (value >> 0) & 0XFF;
    *(tmp + 1) = (value >> 8) & 0XFF;
}

static void
vp8enc_write_dword(char *ptr, uint32_t value)
{
    uint8_t *tmp;

    tmp = (uint8_t *)ptr;
    *(tmp) = (value >> 0) & 0XFF;
    *(tmp + 1) = (value >> 8) & 0XFF;
    *(tmp + 2) = (value >> 16) & 0XFF;
    *(tmp + 3) = (value >> 24) & 0XFF;
}

static void
vp8enc_write_qword(char *ptr, uint64_t value)
{
    uint8_t *tmp;

    tmp = (uint8_t *)ptr;
    *(tmp) = (value >> 0) & 0XFF;
    *(tmp + 1) = (value >> 8) & 0XFF;
    *(tmp + 2) = (value >> 16) & 0XFF;
    *(tmp + 3) = (value >> 24) & 0XFF;
    *(tmp + 4) = (value >> 32) & 0XFF;
    *(tmp + 5) = (value >> 40) & 0XFF;
    *(tmp + 6) = (value >> 48) & 0XFF;
    *(tmp + 7) = (value >> 56) & 0XFF;
}

static void
vp8enc_write_frame_header(FILE *vp8_output,uint32_t data_length, uint64_t timestamp)
{
  char header[12];

  vp8enc_write_dword(header, data_length);
  vp8enc_write_qword(header + 4, timestamp );

  fwrite(header, 1, 12, vp8_output);
}

static void
vp8enc_write_ivf_header(FILE *vp8_file)
{


#define VP8_FOURCC    0x30385056

    char header[32];

    header[0] = 'D';
    header[1] = 'K';
    header[2] = 'I';
    header[3] = 'F';

    vp8enc_write_word(header + 4, 0);
    vp8enc_write_word(header + 6, 32);
    vp8enc_write_dword(header + 8, VP8_FOURCC);
    vp8enc_write_word(header + 12, settings.width);
    vp8enc_write_word(header + 14, settings.height);
    vp8enc_write_dword(header + 16, settings.frame_rate);
    vp8enc_write_dword(header + 20, 1);
    vp8enc_write_dword(header + 24, settings.num_frames * settings.repeat_times);
    vp8enc_write_dword(header + 28, 0);

    fwrite(header, 1, 32, vp8_file);
}

/********************************************
*
* END: IVF Container Releated Stuff
*
********************************************/


/********************************************
*
* START: Read YUV Input File Releated Stuff
*
********************************************/
static void
vp8enc_upload_yuv_to_surface(FILE *yuv_fp, VASurfaceID surface_id, int current_frame)
{
    VAImage surface_image;
    VAStatus va_status;
    void *surface_p = NULL;
    uint8_t *y_src, *u_src, *v_src;
    uint8_t *y_dst, *u_dst, *v_dst;
    int y_size = settings.width * settings.height;
    int u_size = (settings.width >> 1) * (settings.height >> 1);
    int row, col;
    char *yuv_mmap_ptr = NULL;
    unsigned long long frame_start_pos, mmap_start;
    int mmap_size;

    frame_start_pos = (unsigned long long)current_frame * settings.frame_size;

    mmap_start = frame_start_pos & (~0xfff);
    mmap_size = (settings.frame_size + (frame_start_pos & 0xfff) + 0xfff) & (~0xfff);
    yuv_mmap_ptr = mmap(0, mmap_size, PROT_READ, MAP_SHARED,
                fileno(yuv_fp), mmap_start);

    if (yuv_mmap_ptr == MAP_FAILED) {
      fprintf(stderr,"Error: Failed to mmap YUV file.\n");
      assert(0);
    }

    y_src = (uint8_t*)yuv_mmap_ptr+(frame_start_pos & 0xfff);
    u_src = y_src + y_size; /* UV offset for NV12 */
    v_src = y_src + y_size + u_size;


    va_status = vaDeriveImage(vaapi_context.display, surface_id, &surface_image);
    CHECK_VASTATUS(va_status,"vaDeriveImage");

    vaMapBuffer(vaapi_context.display, surface_image.buf, &surface_p);
    assert(VA_STATUS_SUCCESS == va_status);


    y_dst = surface_p + surface_image.offsets[0];
    u_dst = surface_p + surface_image.offsets[1]; /* UV offset for NV12 */
    v_dst = surface_p + surface_image.offsets[2];

    /* Y plane */
    for (row = 0; row < surface_image.height; row++) {
        memcpy(y_dst, y_src, surface_image.width);
        y_dst += surface_image.pitches[0];
        y_src += settings.width;
    }

    if (surface_image.format.fourcc == VA_FOURCC_NV12) { /* UV plane */
        for (row = 0; row < surface_image.height / 2; row++) {
            for (col = 0; col < surface_image.width / 2; col++) {
                u_dst[col * 2] = u_src[col];
                u_dst[col * 2 + 1] = v_src[col];
            }

            u_dst += surface_image.pitches[1];
            u_src += (settings.width / 2);
            v_src += (settings.width / 2);
        }
    } else if (surface_image.format.fourcc == VA_FOURCC_YV12 ||
               surface_image.format.fourcc == VA_FOURCC_I420) {
        const int U = surface_image.format.fourcc == VA_FOURCC_I420 ? 1 : 2;
        const int V = surface_image.format.fourcc == VA_FOURCC_I420 ? 2 : 1;

        u_dst = surface_p + surface_image.offsets[U];
        v_dst = surface_p + surface_image.offsets[V];

        for (row = 0; row < surface_image.height / 2; row++) {
            memcpy(u_dst, u_src, surface_image.width / 2);
            memcpy(v_dst, v_src, surface_image.width / 2);
            u_dst += surface_image.pitches[U];
            v_dst += surface_image.pitches[V];
            u_src += (settings.width / 2);
            v_src += (settings.width / 2);
        }
    }

    vaUnmapBuffer(vaapi_context.display, surface_image.buf);
    vaDestroyImage(vaapi_context.display, surface_image.image_id);

    if (yuv_mmap_ptr)
      munmap(yuv_mmap_ptr, mmap_size);
}

static void *
vp8enc_upload_thread_function(void *data)
{
    vp8enc_upload_yuv_to_surface(vaapi_context.upload_thread.input_fp, vaapi_context.upload_thread.input_surface,vaapi_context.upload_thread.processed_frame);

    return NULL;
}
/********************************************
*
* END: Read YUV Input File Releated Stuff
*
********************************************/

void vp8enc_init_QMatrix(VAQMatrixBufferVP8 *qMatrix)
{
  // When segmentation is disabled, only quantization_index[0] will be used
  size_t i;
  for (i = 0; i < N_ELEMENTS(qMatrix->quantization_index); i++) {
      qMatrix->quantization_index[i] = settings.quantization_parameter;
  }

  for (i = 0; i < N_ELEMENTS(qMatrix->quantization_index_delta); i++) {
      qMatrix->quantization_index_delta[i] = 0;
  }
}

void vp8enc_init_SequenceParameterBuffer(VAEncSequenceParameterBufferVP8* seqParam)
{
  size_t i;

  memset(seqParam, 0, sizeof(VAEncSequenceParameterBufferVP8));

  seqParam->frame_width = settings.width;
  seqParam->frame_height = settings.height;

  if(settings.frame_bitrate > 0)
    seqParam->bits_per_second = settings.frame_bitrate * 1000;
  else
    seqParam->bits_per_second = 0;

  seqParam->intra_period = settings.intra_period;
  seqParam->error_resilient = settings.error_resilient;

  for (i = 0; i < N_ELEMENTS(seqParam->reference_frames); i++)
     seqParam->reference_frames[i] = VA_INVALID_ID;
}

void vp8enc_init_PictureParameterBuffer(VAEncPictureParameterBufferVP8 *picParam)
{
  size_t i;
  memset(picParam, 0, sizeof(VAEncPictureParameterBufferVP8));

  picParam->ref_last_frame = VA_INVALID_SURFACE;
  picParam->ref_gf_frame = VA_INVALID_SURFACE;
  picParam->ref_arf_frame = VA_INVALID_SURFACE;

  /* always show it */
  picParam->pic_flags.bits.show_frame = 1;

  for (i = 0; i < N_ELEMENTS(picParam->loop_filter_level); i++) {
      picParam->loop_filter_level[i] = settings.loop_filter_level;
  }

  picParam->clamp_qindex_low = settings.clamp_qindex_low;
  picParam->clamp_qindex_high = settings.clamp_qindex_high;

}

void vp8enc_set_refreshparameter_for_svct_2layers(VAEncPictureParameterBufferVP8 *picParam, int current_frame, int *is_golden_refreshed)
{
  //Pattern taken from libyami

  picParam->ref_flags.bits.no_ref_arf = 1;

  if(! *is_golden_refreshed)
    picParam->ref_flags.bits.no_ref_gf = 1;

  switch(current_frame % 2) {
    case 0:
      //Layer 0
      picParam->pic_flags.bits.refresh_last = 1;
      picParam->ref_flags.bits.no_ref_gf = 1;
      picParam->ref_flags.bits.temporal_id = 0;
      break;
    case 1:
      //Layer 1
      picParam->pic_flags.bits.refresh_golden_frame = 1;
      *is_golden_refreshed = 1;
      picParam->ref_flags.bits.temporal_id = 1;
      break;
  }
}

void vp8enc_set_refreshparameter_for_svct_3layers(VAEncPictureParameterBufferVP8 *picParam, int current_frame,int *is_golden_refreshed)
{
  //Pattern taken from libyami - Note that the alternate frame is never referenced,
  //this is because, libyami implementation suggests to be able to drop individual
  //frames from Layer 2 on bad network connections
  picParam->ref_flags.bits.no_ref_arf = 1;

  if(! *is_golden_refreshed)
    picParam->ref_flags.bits.no_ref_gf = 1;

  switch(current_frame % 4) {
    case 0:
      //Layer 0
      picParam->pic_flags.bits.refresh_last = 1;
      picParam->ref_flags.bits.no_ref_gf = 1;
      picParam->ref_flags.bits.temporal_id = 0;
      break;
    case 1:
    case 3:
      //Layer 2
      picParam->pic_flags.bits.refresh_alternate_frame  = 1;
      picParam->ref_flags.bits.temporal_id = 2;
      break;
    case 2:
      //Layer 1
      picParam->pic_flags.bits.refresh_golden_frame = 1;
      *is_golden_refreshed = 1;
      picParam->ref_flags.bits.temporal_id = 1;
      break;
  }
}

void vp8enc_reset_picture_parameter_references(VAEncPictureParameterBufferVP8 *picParam)
{
  picParam->ref_last_frame = VA_INVALID_SURFACE;
  picParam->ref_gf_frame = VA_INVALID_SURFACE;
  picParam->ref_arf_frame = VA_INVALID_SURFACE;
  picParam->pic_flags.bits.refresh_last = 0;
  picParam->pic_flags.bits.refresh_golden_frame = 0;
  picParam->pic_flags.bits.refresh_alternate_frame = 0;
  picParam->pic_flags.bits.copy_buffer_to_golden = 0;
  picParam->pic_flags.bits.copy_buffer_to_alternate = 0;
  picParam->ref_flags.bits.no_ref_last = 0;
  picParam->ref_flags.bits.no_ref_gf = 0;
  picParam->ref_flags.bits.no_ref_arf = 0;
}

void vp8enc_update_picture_parameter(int frame_type, int current_frame)
{
  VAEncPictureParameterBufferVP8 *picParam = &vaapi_context.pic_param;

  picParam->reconstructed_frame = vaapi_context.recon_surface;

  vp8enc_reset_picture_parameter_references(picParam);

  if (frame_type == KEY_FRAME)
  {
    picParam->ref_flags.bits.force_kf = 1;
    picParam->pic_flags.bits.frame_type = KEY_FRAME;
    vaapi_context.is_golden_refreshed = 0;
    return;
  }

  // INTER_FRAME
  picParam->ref_flags.bits.force_kf = 0;
  picParam->pic_flags.bits.frame_type = INTER_FRAME;

  switch(settings.temporal_svc_layers)
  {
    case 1:
      //Standard behavoir only 1 Temporal Layer
      picParam->pic_flags.bits.refresh_last = 1;
      picParam->pic_flags.bits.copy_buffer_to_golden = 1;
      picParam->pic_flags.bits.copy_buffer_to_alternate = 2;
      picParam->ref_flags.bits.temporal_id = 0;
      break;
    case 2:
      //2 Temporal Layers
      vp8enc_set_refreshparameter_for_svct_2layers(picParam,current_frame,&vaapi_context.is_golden_refreshed);
      break;
    case 3:
      //3 Temporal Layers
      vp8enc_set_refreshparameter_for_svct_3layers(picParam,current_frame,&vaapi_context.is_golden_refreshed);
      break;
    default:
      //should never happen
      fprintf(stderr,"Error: Only 1,2 or 3 TemporalLayers supported.\n");
      assert(0);
      break;
  }

  if(!picParam->ref_flags.bits.no_ref_last)
    picParam->ref_last_frame = vaapi_context.last_ref_surface;
  if(!picParam->ref_flags.bits.no_ref_gf)
    picParam->ref_gf_frame = vaapi_context.golden_ref_surface;
  if(!picParam->ref_flags.bits.no_ref_arf)
    picParam->ref_arf_frame = vaapi_context.alt_ref_surface;

}

VASurfaceID vp8enc_get_unused_surface()
{
  VASurfaceID current_surface;
  size_t i = 0;

  for (i = 0; i < NUM_REF_SURFACES; i++) {
        current_surface = vaapi_context.surfaces[i];

        if(current_surface != vaapi_context.last_ref_surface && current_surface != vaapi_context.golden_ref_surface && current_surface != vaapi_context.alt_ref_surface)
          return current_surface;
  }

  //No unused surface found - should never happen.
  fprintf(stderr, "Error: No unused surface found!\n");
  assert(0);

}

VASurfaceID vp8enc_update_reference(VASurfaceID current_surface, VASurfaceID second_copy_surface, bool refresh_with_recon, int copy_flag)
{
  if(refresh_with_recon)
    return vaapi_context.recon_surface;
  switch(copy_flag)
  {
    case 0:
      return current_surface;
    case 1:
      return vaapi_context.last_ref_surface;
    case 2:
      return second_copy_surface;
    default: // should never happen
      fprintf(stderr, "Error: Invalid copy_buffer_to_X flag\n");
      assert(0);
  }

  return VA_INVALID_ID; // should never happen
}


void vp8enc_update_reference_list(int frame_type)
{

  VAEncPictureParameterBufferVP8 *picParam = &vaapi_context.pic_param;

  if (frame_type == KEY_FRAME)
  {
     vaapi_context.last_ref_surface = vaapi_context.recon_surface;
     vaapi_context.golden_ref_surface = vaapi_context.recon_surface;
     vaapi_context.alt_ref_surface = vaapi_context.recon_surface;
  } else { // INTER_FRAME
     //check refresh_X and copy_buffer_to_golden_X and update references accordingly
     if(picParam->pic_flags.bits.refresh_last)
       vaapi_context.last_ref_surface = vaapi_context.recon_surface;
     vaapi_context.golden_ref_surface = vp8enc_update_reference(vaapi_context.golden_ref_surface,vaapi_context.alt_ref_surface,picParam->pic_flags.bits.refresh_golden_frame, picParam->pic_flags.bits.copy_buffer_to_golden );
     vaapi_context.alt_ref_surface = vp8enc_update_reference(vaapi_context.alt_ref_surface,vaapi_context.golden_ref_surface,picParam->pic_flags.bits.refresh_alternate_frame, picParam->pic_flags.bits.copy_buffer_to_alternate );
  }

  vaapi_context.recon_surface = vp8enc_get_unused_surface();
}

void vp8enc_init_MiscParameterBuffers(VAEncMiscParameterHRD *hrd, VAEncMiscParameterFrameRate *frame_rate, VAEncMiscParameterRateControl *rate_control)
{
  if(hrd != NULL)
  {
    if(settings.frame_bitrate)
    {
      hrd->initial_buffer_fullness = settings.frame_bitrate * settings.hrd_window / 2;
      hrd->buffer_size = settings.frame_bitrate * settings.hrd_window;
    } else {
      hrd->initial_buffer_fullness = 0;
      hrd->buffer_size = 0;
    }
  }

  if(frame_rate != NULL)
  {
    frame_rate->framerate = settings.frame_rate;
  }

  if (rate_control != NULL)
  {
    rate_control->window_size = settings.hrd_window;
    rate_control->initial_qp = settings.quantization_parameter;
    rate_control->min_qp = settings.clamp_qindex_low;
    //rate_control->rc_flags.bits.disable_bit_stuffing = 1;

    if(settings.rc_mode == VA_RC_VBR)
    {
      rate_control->bits_per_second = settings.max_variable_bitrate * 1000;
      rate_control->target_percentage = (settings.frame_bitrate * 100) / settings.max_variable_bitrate;
    } else {
      rate_control->bits_per_second = settings.frame_bitrate * 1000;
      rate_control->target_percentage = 95;

    }
  }
}

void vp8enc_create_EncoderPipe()
{
  VAEntrypoint entrypoints[5];
  int num_entrypoints;
  int i;
  bool entrypoint_found;
  VAConfigAttrib conf_attrib[2];
  VASurfaceAttrib surface_attrib;
  int major_ver, minor_ver;
  VAStatus va_status;

  vaapi_context.display = va_open_display();
  va_status = vaInitialize(vaapi_context.display, &major_ver, &minor_ver);
  CHECK_VASTATUS(va_status, "vaInitialize");

  vaQueryConfigEntrypoints(vaapi_context.display, vaapi_context.profile, entrypoints,
                           &num_entrypoints);

  entrypoint_found = true;
  for(i = 0; i < num_entrypoints;i++)
  {
    if (entrypoints[i] == settings.vaapi_entry_point)
      entrypoint_found = true;
  }

  if(entrypoint_found == false)
  {
    fprintf(stderr,"Error: VAEntrypoint not found!\n");
    assert(0);
  }

  /* find out the format for the render target, and rate control mode */
  conf_attrib[0].type = VAConfigAttribRTFormat;
  conf_attrib[1].type = VAConfigAttribRateControl;
  vaGetConfigAttributes(vaapi_context.display, vaapi_context.profile, settings.vaapi_entry_point,
                        &conf_attrib[0], 2);

  if ((conf_attrib[0].value & VA_RT_FORMAT_YUV420) == 0) {
      fprintf(stderr, "Error: Input colorspace YUV420 not supported, exit\n");
      assert(0);
  }

  if ((conf_attrib[1].value & settings.rc_mode) == 0) {
      /* Can't find matched RC mode */
      fprintf(stderr, "Error: Can't find the desired RC mode, exit\n");
      assert(0);
  }

  conf_attrib[0].value = VA_RT_FORMAT_YUV420; /* set to desired RT format */
  conf_attrib[1].value = settings.rc_mode; /* set to desired RC mode */

  va_status = vaCreateConfig(vaapi_context.display, vaapi_context.profile, settings.vaapi_entry_point,
                             &conf_attrib[0], 2,&vaapi_context.config_id);
  CHECK_VASTATUS(va_status, "vaCreateConfig");

  surface_attrib.type = VASurfaceAttribPixelFormat;
  surface_attrib.flags = VA_SURFACE_ATTRIB_SETTABLE;
  surface_attrib.value.type = VAGenericValueTypeInteger;
  surface_attrib.value.value.i = VA_FOURCC_NV12;

  // Create surface (Reference Surfaces + Input Surfaces)
  va_status = vaCreateSurfaces(
      vaapi_context.display,
      VA_RT_FORMAT_YUV420, settings.width, settings.height,
      vaapi_context.surfaces, NUM_SURFACES_TOTAL,
      &surface_attrib, 1
  );

  CHECK_VASTATUS(va_status, "vaCreateSurfaces");

  vaapi_context.recon_surface = vaapi_context.surfaces[0];
  vaapi_context.last_ref_surface = VA_INVALID_SURFACE;
  vaapi_context.golden_ref_surface = VA_INVALID_SURFACE;
  vaapi_context.alt_ref_surface = VA_INVALID_SURFACE;
  vaapi_context.input_surface = vaapi_context.surfaces[NUM_REF_SURFACES]; // input surfaces trail the reference surfaces

  /* Create a context for this Encoder pipe */
  /* the surface is added to the render_target list when creating the context */
  va_status = vaCreateContext(vaapi_context.display, vaapi_context.config_id,
                              settings.width, settings.height,
                              VA_PROGRESSIVE,
                              vaapi_context.surfaces, NUM_SURFACES_TOTAL,
                              &vaapi_context.context_id);

  CHECK_VASTATUS(va_status, "vaCreateContext");


}

void vp8enc_destory_EncoderPipe()
{
    pthread_join(vaapi_context.upload_thread.id,NULL);
    vaDestroySurfaces(vaapi_context.display, vaapi_context.surfaces, NUM_SURFACES_TOTAL);
    vaDestroyContext(vaapi_context.display,vaapi_context.context_id);
    vaDestroyConfig(vaapi_context.display,vaapi_context.config_id);
    vaTerminate(vaapi_context.display);
    va_close_display(vaapi_context.display);
}


void vp8enc_init_VaapiContext()
{
  size_t i;
  vaapi_context.profile = VAProfileVP8Version0_3;

  vp8enc_init_SequenceParameterBuffer(&vaapi_context.seq_param);
  vp8enc_init_PictureParameterBuffer(&vaapi_context.pic_param);
  vp8enc_init_QMatrix(&vaapi_context.q_matrix);

  vaapi_context.hrd_param.header.type = VAEncMiscParameterTypeHRD;
  vaapi_context.frame_rate_param.header.type = VAEncMiscParameterTypeFrameRate;
  vaapi_context.rate_control_param.header.type = VAEncMiscParameterTypeRateControl;
  vp8enc_init_MiscParameterBuffers(&vaapi_context.hrd_param.data, &vaapi_context.frame_rate_param.data,&vaapi_context.rate_control_param.data);

  for(i = 0; i < N_ELEMENTS(vaapi_context.va_buffers);i++)
    vaapi_context.va_buffers[i] = VA_INVALID_ID;
  vaapi_context.num_va_buffers = 0;

  vaapi_context.is_golden_refreshed = 0;
}



static int
vp8enc_store_coded_buffer(FILE *vp8_fp,uint64_t timestamp)
{
    VACodedBufferSegment *coded_buffer_segment;
    uint8_t *coded_mem;
    int data_length;
    VAStatus va_status;
    VASurfaceStatus surface_status;
    size_t w_items;

    va_status = vaSyncSurface(vaapi_context.display, vaapi_context.recon_surface);
    CHECK_VASTATUS(va_status,"vaSyncSurface");

    surface_status = 0;
    va_status = vaQuerySurfaceStatus(vaapi_context.display, vaapi_context.recon_surface, &surface_status);
    CHECK_VASTATUS(va_status,"vaQuerySurfaceStatus");

    va_status = vaMapBuffer(vaapi_context.display, vaapi_context.codedbuf_buf_id, (void **)(&coded_buffer_segment));
    CHECK_VASTATUS(va_status,"vaMapBuffer");
    coded_mem = coded_buffer_segment->buf;

    if (coded_buffer_segment->status & VA_CODED_BUF_STATUS_SLICE_OVERFLOW_MASK) {
        fprintf(stderr,"Error: CodeBuffer Size too small\n");
        vaUnmapBuffer(vaapi_context.display, vaapi_context.codedbuf_buf_id);
        assert(0);
    }

    data_length = coded_buffer_segment->size;

    vp8enc_write_frame_header(vp8_fp, data_length,timestamp);

    do {
        w_items = fwrite(coded_mem, data_length, 1, vp8_fp);
    } while (w_items != 1);

    if(settings.debug)
      fprintf(stderr,"Timestamp: %ld Bytes written %d\n",timestamp,data_length);

    vaUnmapBuffer(vaapi_context.display, vaapi_context.codedbuf_buf_id);

    return 0;
}

size_t vp8enc_get_FileSize(FILE *fp)
{
  struct stat st;
  fstat(fileno(fp), &st);
  return st.st_size;
}

int vp8enc_prepare_buffers(int frame_type)
{
  int num_buffers = 0;
  VABufferID *va_buffers;
  VAStatus va_status;
  VAEncPictureParameterBufferVP8 *picParam = &vaapi_context.pic_param;


  va_buffers = vaapi_context.va_buffers;
  /* coded buffer */
  va_status = vaCreateBuffer(vaapi_context.display,
                               vaapi_context.context_id,
                               VAEncCodedBufferType,
                               settings.codedbuf_size, 1, NULL,
                               &vaapi_context.codedbuf_buf_id);
  CHECK_VASTATUS(va_status,"vaCreateBuffer");

  /* sequence parameter set */
  va_status = vaCreateBuffer(vaapi_context.display,
                             vaapi_context.context_id,
                             VAEncSequenceParameterBufferType,
                             sizeof(vaapi_context.seq_param), 1, &vaapi_context.seq_param,
                             va_buffers);
  CHECK_VASTATUS(va_status,"vaCreateBuffer");

  va_buffers ++; num_buffers++;

  /* picture parameter set */
  picParam->coded_buf = vaapi_context.codedbuf_buf_id;

  va_status = vaCreateBuffer(vaapi_context.display,
                             vaapi_context.context_id,
                             VAEncPictureParameterBufferType,
                             sizeof(vaapi_context.pic_param), 1, &vaapi_context.pic_param,
                             va_buffers);
  CHECK_VASTATUS(va_status,"vaCreateBuffer");
  va_buffers ++; num_buffers++;



  /* hrd parameter */
  vaCreateBuffer(vaapi_context.display,
                 vaapi_context.context_id,
                 VAEncMiscParameterBufferType,
                 sizeof(vaapi_context.hrd_param), 1, &vaapi_context.hrd_param,
                 va_buffers);
  CHECK_VASTATUS(va_status, "vaCreateBuffer");

  va_buffers ++; num_buffers++;

  /* QMatrix */
  va_status = vaCreateBuffer(vaapi_context.display,
                       vaapi_context.context_id,
                       VAQMatrixBufferType,
                       sizeof(vaapi_context.q_matrix), 1, &vaapi_context.q_matrix,
                       va_buffers);
  CHECK_VASTATUS(va_status,"vaCreateBuffer");


  va_buffers ++; num_buffers++;
  /* Create the Misc FR/RC buffer under non-CQP mode */
  if (settings.rc_mode != VA_RC_CQP && frame_type == KEY_FRAME) {
    vaCreateBuffer(vaapi_context.display,
                       vaapi_context.context_id,
                       VAEncMiscParameterBufferType,
                       sizeof(vaapi_context.frame_rate_param),1,&vaapi_context.frame_rate_param,
                       va_buffers);
    CHECK_VASTATUS(va_status, "vaCreateBuffer");

    va_buffers ++; num_buffers++;

    vaCreateBuffer(vaapi_context.display,
                       vaapi_context.context_id,
                       VAEncMiscParameterBufferType,
                       sizeof(vaapi_context.rate_control_param),1,&vaapi_context.rate_control_param,
                       va_buffers);
    CHECK_VASTATUS(va_status, "vaCreateBuffer");

    va_buffers ++; num_buffers++;
  }

  vaapi_context.num_va_buffers = num_buffers;

  return num_buffers;
}




static void
vp8enc_render_picture()
{
    VAStatus va_status;

    va_status = vaBeginPicture(vaapi_context.display,
                               vaapi_context.context_id,
                               vaapi_context.input_surface);
    CHECK_VASTATUS(va_status,"vaBeginPicture");


    va_status = vaRenderPicture(vaapi_context.display,
                                vaapi_context.context_id,
                                vaapi_context.va_buffers,
                                vaapi_context.num_va_buffers);
    CHECK_VASTATUS(va_status,"vaRenderPicture");

    va_status = vaEndPicture(vaapi_context.display, vaapi_context.context_id);
    CHECK_VASTATUS(va_status,"vaEndPicture");

}

void vp8enc_destroy_buffers()
{
  int i;
  VAStatus va_status;

  for(i = 0; i < vaapi_context.num_va_buffers; i++) {
    if (vaapi_context.va_buffers[i] != VA_INVALID_ID) {
      va_status = vaDestroyBuffer(vaapi_context.display, vaapi_context.va_buffers[i]);
      CHECK_VASTATUS(va_status,"vaDestroyBuffer");
      vaapi_context.va_buffers[i] = VA_INVALID_ID;
    }
  }

  if (vaapi_context.codedbuf_buf_id != VA_INVALID_ID) {
    va_status = vaDestroyBuffer(vaapi_context.display, vaapi_context.codedbuf_buf_id);
    CHECK_VASTATUS(va_status,"vaDestroyBuffer");
    vaapi_context.codedbuf_buf_id = VA_INVALID_ID;
  }

}
void vp8enc_show_help ()
{
  printf("Usage: vp8enc <width> <height> <input_yuvfile> <output_vp8> additional_option\n");
  printf("output_vp8 should use *.ivf\n");
  printf("The additional option is listed\n");
  printf("-f <frame rate> \n");
  printf("--intra_period <key_frame interval>\n");
  printf("--qp <quantization parameter> \n");
  printf("--rcmode <rate control mode> 0: CQP, 1: CBR, 2: VBR\n");
  printf("--fb <bitrate> (kbps unit)\n");
  printf("--lf_level <loop filter level>  [0-63]\n");
  printf("--hrd_win <num>  [1000-8000]\n");
  printf("--vbr_max <num> (kbps unit. It should be greater than fb)\n");
  printf("--fn_num <num>\n  how many frames to be encoded\n");
  printf("--error_resilient Turn on Error resilient mode\n");
  printf("--debug Turn debug info on\n");
  printf("--temp_svc <num> Number of temporal layers 2 or 3\n");
  printf("--repeat <num> Number of times to repeat the encoding\n");
}

void parameter_check(const char *param, int val, int min, int max)
{
  if(val < min || val > max)
  {
    fprintf(stderr,"Error: %s out of range (%d..%d) \n",param,min,max);
    exit(VP8ENC_FAIL);
  }
}

void parameter_check_positive(const char *param, int val, int min)
{
  if(val < 1)
  {
    fprintf(stderr,"Error: %s demands a positive value greater than %d \n",param,min);
    exit(VP8ENC_FAIL);
  }
}

int parse_options(int ac,char *av[])
{
  int c, long_index, tmp_input;
  while (1) {
      c = getopt_long_only(ac,av,"hf:?",long_opts,&long_index);

      if (c == -1)
          break;

      switch(c) {
      case 'f':
          tmp_input = atoi(optarg);
          parameter_check_positive("-f",tmp_input,1);
          settings.frame_rate = tmp_input;
          break;
      case 1:
          tmp_input = atoi(optarg);
          parameter_check("--rcmode", tmp_input, 0, 2);
          settings.rc_mode = default_rc_modes[tmp_input];
          break;
      case 2:
          tmp_input = atoi(optarg);
          parameter_check("--qp", tmp_input, 0, 255);
          settings.quantization_parameter = tmp_input;
          break;
      case 3:
          tmp_input = atoi(optarg);
          parameter_check_positive("--intra_period",tmp_input,1);
          settings.intra_period = tmp_input;
          break;
      case 4:
          tmp_input = atoi(optarg);
          parameter_check_positive("--fb",tmp_input,1);
          settings.frame_bitrate = tmp_input;
          break;
      case 5:
          tmp_input = atoi(optarg);
          parameter_check("--lf_level",tmp_input, 0, 63);
          settings.loop_filter_level = tmp_input;
          break;
      case 6:
          tmp_input = atoi(optarg);
          parameter_check("--hrd_win",tmp_input,1000,8000);
          settings.hrd_window = tmp_input;
          break;
      case 7:
          tmp_input = atoi(optarg);
          parameter_check_positive("--vbr_max",tmp_input,1);
          settings.max_variable_bitrate = tmp_input;
          break;
      case 8:
          tmp_input = atoi(optarg);
          parameter_check_positive("--fn_num" ,tmp_input,1);
          settings.num_frames = tmp_input;
          break;
      case 9:
          settings.error_resilient = 1;
          break;
      case 10:
          settings.debug = 1;
          break;
      case 11:
          tmp_input = atoi(optarg);
          parameter_check("--temp_svc",tmp_input,2,3);
          settings.temporal_svc_layers = tmp_input;
          break;
      case 12:
          tmp_input = atoi(optarg);
          parameter_check("--repeat", tmp_input, 1, 1000000);
          settings.repeat_times = tmp_input;
          break;
      case 'h':
      case 0:
      default:
          return PARSE_OPTIONS_FAIL;
          break;
    }
  }
  return PARSE_OPTIONS_OK;
}

int main(int argc, char *argv[])
{
  int current_frame, frame_type;
  FILE *fp_vp8_output = NULL;
  FILE *fp_yuv_input = NULL;
  uint64_t timestamp;
  struct timeval t1,t2;
  double fps, elapsed_time;


  if(argc < 5) {
      vp8enc_show_help();
      return VP8ENC_FAIL;
  }

  if(parse_options(argc-4, &argv[4]) != PARSE_OPTIONS_OK)
  {
    vp8enc_show_help();
    return VP8ENC_FAIL;
  }

  settings.width = atoi(argv[1]);
  parameter_check("Width", settings.width, 16, MAX_XY_RESOLUTION);

  settings.height = atoi(argv[2]);
  parameter_check("Height", settings.height, 16, MAX_XY_RESOLUTION);

  if( settings.rc_mode == VA_RC_VBR && settings.max_variable_bitrate < settings.frame_bitrate)
  {
      fprintf(stderr,"Error: max. variable bitrate should be greater than frame bitrate (--vbr_max >= --fb)\n");
      return VP8ENC_FAIL;
  }

  if(argv[3]) {
    fp_yuv_input = fopen(argv[3],"rb");
  }
  if(fp_yuv_input == NULL)
  {
    fprintf(stderr,"Error: Couldn't open input file.\n");
    return VP8ENC_FAIL;
  }
  vaapi_context.upload_thread.input_fp = fp_yuv_input;

  fp_vp8_output = fopen(argv[4],"wb");
  if(fp_vp8_output == NULL)
  {
    fprintf(stderr,"Error: Couldn't open output file.\n");
    return VP8ENC_FAIL;
  }

  if( settings.temporal_svc_layers == 2 && settings.intra_period % 2)
      fprintf(stderr,"Warning: Choose Key-Frame interval (--intra_period) to be integer mutliply of 2 to match temporal layer pattern");

  if ( settings.temporal_svc_layers == 3 && settings.intra_period % 4 )
      fprintf(stderr,"Warning: Choose Key-Frame interval (--intra_period) to be integer mutliply of 4 to match temporal layer pattern");


  settings.frame_size = settings.width * settings.height * 3 / 2; //NV12 Colorspace - For a 2x2 group of pixels, you have 4 Y samples and 1 U and 1 V sample.
  if(!settings.num_frames)
    settings.num_frames = vp8enc_get_FileSize(fp_yuv_input)/(size_t)settings.frame_size;
  settings.codedbuf_size = settings.width * settings.height; //just a generous assumptions

  fprintf(stderr,"Info: Encoding total of %d frames.\n",settings.num_frames);

  gettimeofday(&t1,0); //Measure Runtime

  vp8enc_init_VaapiContext();
  vp8enc_create_EncoderPipe();

  vp8enc_write_ivf_header(fp_vp8_output);

  current_frame = 0;
  timestamp = 0;
  vaapi_context.input_surface = vaapi_context.surfaces[SID_INPUT_PICTURE_0];
  vaapi_context.upload_thread.input_surface_num = SID_INPUT_PICTURE_0;

  while (current_frame < settings.num_frames * settings.repeat_times)
  {
    fprintf(stderr,"\rProcessing frame: %d",current_frame);

    if ( (current_frame % settings.intra_period) == 0)
      frame_type = KEY_FRAME;
    else
      frame_type = INTER_FRAME;

    if(current_frame == 0) {
      // Preload first input_surface
      vp8enc_upload_yuv_to_surface(fp_yuv_input, vaapi_context.input_surface, current_frame); //prefill
    } else {
      // wait for input processing thread to finish
      pthread_join(vaapi_context.upload_thread.id, NULL);
      vaapi_context.input_surface = vaapi_context.upload_thread.input_surface;
    }

    // Start Upload thread
    if((current_frame + 1) < settings.num_frames * settings.repeat_times) {
      vaapi_context.upload_thread.processed_frame = (current_frame % settings.num_frames - 1) + 1;

      if(vaapi_context.upload_thread.input_surface_num == SID_INPUT_PICTURE_0)
        vaapi_context.upload_thread.input_surface_num = SID_INPUT_PICTURE_1;
      else
        vaapi_context.upload_thread.input_surface_num = SID_INPUT_PICTURE_0;

      vaapi_context.upload_thread.input_surface = vaapi_context.surfaces[vaapi_context.upload_thread.input_surface_num];
      vaapi_context.upload_thread.value = pthread_create(&vaapi_context.upload_thread.id,NULL,vp8enc_upload_thread_function,NULL);
    }


    vp8enc_update_picture_parameter(frame_type, current_frame);
    vp8enc_prepare_buffers(frame_type);

    vp8enc_render_picture();

    vp8enc_store_coded_buffer(fp_vp8_output, timestamp);
    vp8enc_destroy_buffers();

    vp8enc_update_reference_list(frame_type);

    current_frame ++;
    timestamp ++;
  }

  vp8enc_destory_EncoderPipe();
  fclose(fp_vp8_output);
  fclose(fp_yuv_input);

  gettimeofday(&t2,0);
  elapsed_time = (double)(t2.tv_sec-t1.tv_sec)+(double)(t2.tv_usec-t1.tv_usec)/1000000.0;
  fps = (double)current_frame/elapsed_time;

  fprintf(stderr, "\nProcessed %d frames in %.0f ms (%.2f FPS)\n",current_frame,elapsed_time*1000.0,fps);

  return VP8ENC_OK;
}
