/*
 * 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},
    {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;
};


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,
 };

 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);
    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");
}

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 '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)
  {
    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) {
      vaapi_context.upload_thread.processed_frame = current_frame + 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;
}
