This source file includes following definitions.
- start_encoder
 
- create_packet
 
- encode_headers
 
- encode_picture_from_input_buffer
 
#include "encoder/encoder-context.h"
#include "libde265/util.h"
#include <math.h>
encoder_context::encoder_context()
{
  encoder_started=false;
  vps = std::make_shared<video_parameter_set>();
  sps = std::make_shared<seq_parameter_set>();
  pps = std::make_shared<pic_parameter_set>();
  
  
  
  image_spec_is_defined = false;
  parameters_have_been_set = false;
  headers_have_been_sent = false;
  param_image_allocation_userdata = NULL;
  release_func = NULL;
  use_adaptive_context = true; 
  
  
  params.registerParams(params_config);
  algo.registerParams(params_config);
}
encoder_context::~encoder_context()
{
  while (!output_packets.empty()) {
    en265_free_packet(this, output_packets.front());
    output_packets.pop_front();
  }
}
void encoder_context::start_encoder()
{
  if (encoder_started) {
    return;
  }
  if (params.sop_structure() == SOP_Intra) {
    sop = std::shared_ptr<sop_creator_intra_only>(new sop_creator_intra_only());
  }
  else {
    auto s = std::shared_ptr<sop_creator_trivial_low_delay>(new sop_creator_trivial_low_delay());
    s->setParams(params.mSOP_LowDelay);
    sop = s;
  }
  sop->set_encoder_context(this);
  sop->set_encoder_picture_buffer(&picbuf);
  encoder_started=true;
}
en265_packet* encoder_context::create_packet(en265_packet_content_type t)
{
  en265_packet* pck = new en265_packet;
  uint8_t* data = new uint8_t[cabac_encoder.size()];
  memcpy(data, cabac_encoder.data(), cabac_encoder.size());
  pck->version = 1;
  pck->data = data;
  pck->length = cabac_encoder.size();
  pck->frame_number = -1;
  pck->content_type = t;
  pck->complete_picture = 0;
  pck->final_slice = 0;
  pck->dependent_slice = 0;
  
  
  pck->nuh_layer_id = 0;
  pck->nuh_temporal_id = 0;
  pck->encoder_context = this;
  pck->input_image = NULL;
  pck->reconstruction = NULL;
  cabac_encoder.reset();
  return pck;
}
de265_error encoder_context::encode_headers()
{
  nal_header nal;
  
  vps->set_defaults(Profile_Main, 6,2);
  
  sps->set_defaults();
  sps->set_CB_log2size_range( Log2(params.min_cb_size), Log2(params.max_cb_size));
  sps->set_TB_log2size_range( Log2(params.min_tb_size), Log2(params.max_tb_size));
  sps->max_transform_hierarchy_depth_intra = params.max_transform_hierarchy_depth_intra;
  sps->max_transform_hierarchy_depth_inter = params.max_transform_hierarchy_depth_inter;
  if (imgdata->input->get_chroma_format() == de265_chroma_444) {
    sps->chroma_format_idc = CHROMA_444;
  }
  sps->set_resolution(image_width, image_height);
  sop->set_SPS_header_values();
  de265_error err = sps->compute_derived_values(true);
  if (err != DE265_OK) {
    fprintf(stderr,"invalid SPS parameters\n");
    exit(10);
  }
  
  pps->set_defaults();
  pps->sps = sps.get();
  pps->pic_init_qp = algo.getPPS_QP();
  
  pps->deblocking_filter_control_present_flag = true;
  pps->deblocking_filter_override_enabled_flag = false;
  pps->pic_disable_deblocking_filter_flag = true;
  pps->pps_loop_filter_across_slices_enabled_flag = false;
  pps->set_derived_values(sps.get());
  
  en265_packet* pck;
  nal.set(NAL_UNIT_VPS_NUT);
  nal.write(cabac_encoder);
  vps->write(this, cabac_encoder);
  cabac_encoder.add_trailing_bits();
  cabac_encoder.flush_VLC();
  pck = create_packet(EN265_PACKET_VPS);
  pck->nal_unit_type = EN265_NUT_VPS;
  output_packets.push_back(pck);
  nal.set(NAL_UNIT_SPS_NUT);
  nal.write(cabac_encoder);
  sps->write(this, cabac_encoder);
  cabac_encoder.add_trailing_bits();
  cabac_encoder.flush_VLC();
  pck = create_packet(EN265_PACKET_SPS);
  pck->nal_unit_type = EN265_NUT_SPS;
  output_packets.push_back(pck);
  nal.set(NAL_UNIT_PPS_NUT);
  nal.write(cabac_encoder);
  pps->write(this, cabac_encoder, sps.get());
  cabac_encoder.add_trailing_bits();
  cabac_encoder.flush_VLC();
  pck = create_packet(EN265_PACKET_PPS);
  pck->nal_unit_type = EN265_NUT_PPS;
  output_packets.push_back(pck);
  headers_have_been_sent = true;
  return DE265_OK;
}
de265_error encoder_context::encode_picture_from_input_buffer()
{
  if (!picbuf.have_more_frames_to_encode()) {
    return DE265_OK;
  }
  if (!image_spec_is_defined) {
    const image_data* id = picbuf.peek_next_picture_to_encode();
    image_width  = id->input->get_width();
    image_height = id->input->get_height();
    image_spec_is_defined = true;
    ctbs.alloc(image_width, image_height, Log2(params.max_cb_size));
  }
  if (!parameters_have_been_set) {
    algo.setParams(params);
    
    int qp = algo.getPPS_QP();
    
    lambda = 0.0242 * pow(1.27245, qp);
    parameters_have_been_set = true;
  }
  image_data* imgdata;
  imgdata = picbuf.get_next_picture_to_encode();
  assert(imgdata);
  picbuf.mark_encoding_started(imgdata->frame_number);
  this->imgdata = imgdata;
  this->shdr    = &imgdata->shdr;
  loginfo(LogEncoder,"encoding frame %d\n",imgdata->frame_number);
  
  if (!headers_have_been_sent) {
    encode_headers();
  }
  
  
  imgdata->shdr.slice_deblocking_filter_disabled_flag = true;
  imgdata->shdr.slice_loop_filter_across_slices_enabled_flag = false;
  imgdata->shdr.compute_derived_values(pps.get());
  imgdata->shdr.pps = &get_pps();
  
  imgdata->nal.write(cabac_encoder);
  imgdata->shdr.write(this, cabac_encoder, sps.get(), pps.get(), imgdata->nal.nal_unit_type);
  cabac_encoder.add_trailing_bits();
  cabac_encoder.flush_VLC();
  
  cabac_encoder.init_CABAC();
  double psnr = encode_image(this,imgdata->input, algo);
  loginfo(LogEncoder,"  PSNR-Y: %f\n", psnr);
  cabac_encoder.flush_CABAC();
  cabac_encoder.add_trailing_bits();
  cabac_encoder.flush_VLC();
  
  picbuf.set_reconstruction_image(imgdata->frame_number, img);
  
  img=NULL;
  this->imgdata = NULL;
  this->shdr = NULL;
  
  en265_packet* pck = create_packet(EN265_PACKET_SLICE);
  pck->input_image    = imgdata->input;
  pck->reconstruction = imgdata->reconstruction;
  pck->frame_number   = imgdata->frame_number;
  pck->nal_unit_type  = (enum en265_nal_unit_type)imgdata->nal.nal_unit_type;
  pck->nuh_layer_id   = imgdata->nal.nuh_layer_id;
  pck->nuh_temporal_id= imgdata->nal.nuh_temporal_id;
  output_packets.push_back(pck);
  picbuf.mark_encoding_finished(imgdata->frame_number);
  return DE265_OK;
}