/***************************************************************************
                          divx_encode.cpp  -  description

		Encoder for Divx 5.0.5

                             -------------------
    begin                : Sun Feb 17 2002
    copyright            : (C) 2002 by mean
    email                : fixounet@free.fr
 ***************************************************************************/

/***************************************************************************
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU General Public License as published by  *
 *   the Free Software Foundation; either version 2 of the License, or     *
 *   (at your option) any later version.                                   *
 *                                                                         *
 ***************************************************************************/

#include "config.h"

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>


#include "avi_vars.h"
#include "prototype.h"
#ifdef BIG_ENDIAN
#undef BIG_ENDIAN
#endif
//#include "decore.h"
#include "config.h"
#ifdef USE_DIVX
#include "ADM_codecs/ADM_divxInc.h"
#include "ADM_colorspace/colorspace.h"
#include "ADM_codecs/ADM_divxEncode.h"

#include "ADM_toolkit/toolkit.hxx"
#include <ADM_assert.h>

static ENC_RESULT result;
static tagDivXBitmapInfoHeader tag;
static SETTINGS setting;

myENC_RESULT res;

divxEncoder::divxEncoder (uint32_t width, uint32_t height):encoder (width,
	 height)
{
  _init = 0;
  _handle = NULL;
}
uint8_t divxEncoder::stopEncoder (void)
{
  int
    ret;

  ADM_assert (_init);
  ret = encore (_handle, ENC_OPT_RELEASE, 0, 0);
  _init = 0;
  if (ret == ENC_OK)
    return 1;
  return 0;
}
//
//      Return encoding result from the last encoded frame
//



uint8_t divxEncoder::init (uint32_t val, uint32_t fps1000)
{
  UNUSED_ARG (val);
  UNUSED_ARG (fps1000);
  ADM_assert (0);
}

uint8_t
  divxEncoder::encode (uint8_t * in,
		       uint8_t * out, uint32_t * len, uint32_t * flags)
{

  int ret;
  ENC_FRAME frame;

  ADM_assert (_init);
  memset (&frame, 0, sizeof (frame));
  frame.image = in;
  frame.bitstream = out;

  ret = encore (_handle, ENC_OPT_ENCODE, &frame, &result);
  if (ENC_OK != ret)
    {
      printf ("Error encoding frame divx :%d \n", ret);
      return 0;
    }
  *len = (uint32_t) frame.length;
  *flags = 0;
  switch (result.cType)
    {
    case '0':
      *flags = 0;
      *len = 0;
      break;
    case 'I':
      *flags = AVI_KEY_FRAME;
      break;
    case 'P':
      break;
    case 'B':
      *flags = AVI_B_FRAME;
      break;

    }
  return 1;
}
uint8_t divxEncoder::params (uint32_t fps1000)
{

  if (ENCORE_VERSION != encore (0, ENC_OPT_VERSION, 0, 0))
    //? interfaces are incompatible, encoding can?t be performed
    {
      printf ("\n Header & lib mismatch for divx !!!\n");
      return 0;
    }

  memset (&tag, 0, sizeof (tag));
  //tag.biSize=sizeof(tag);
  tag.biWidth = _w;
  tag.biHeight = _h;
  tag.biBitCount = 24;
  tag.biCompression = fourCC::get ((uint8_t *) "YV12");

  memset (&setting, 0, sizeof (setting));
  setting.use_bidirect = 0;
  setting.input_frame_period = fps1000;
  setting.input_clock = fps1000;
  setting.complexity_modulation = 0.5;
  setting.quality = 5;

  return 1;
}

/**--------------------------------------
	Initialiaze divxencoder
	in constant quantizer mode
------------------------------------------
*/

uint8_t divxEncoderCQ::init (uint32_t q, uint32_t fps1000)
{
  UNUSED_ARG (fps1000);
  _q = q;

  printf (" Compressing %lu x %lu video in qz %lu\n", _w, _h, _q);

// check header and lib match -> good idea !


  if (!params (fps1000))
    return 0;

  setting.vbr_mode = RCMODE_1PASS_CONSTANT_Q;
  setting.quantizer = _q;
  ADM_assert (0 == _init);

  if (ENC_OK != encore ((void *) &_handle, ENC_OPT_INIT, &tag, &setting))
    {
      printf ("\n error initializing divx !\n");
      return 0;

    }
  printf ("\n Divx initialized  OK in CQ mode!\n");
  _init = 1;
  return 1;
}
/**--------------------------------------
	Initialiaze divxencoder
	in constant bitrate mode
------------------------------------------
*/

uint8_t divxEncoderCBR::init (uint32_t q, uint32_t fps1000)
{
  UNUSED_ARG (fps1000);
  _br = q;

  printf (" Compressing %lu x %lu video in CBR %lu\n", _w, _h, _br);

// check header and lib match -> good idea !

  if (!params (fps1000))
    return 0;

  setting.vbr_mode = RCMODE_502_1PASS;	//RCMODE_VBV_1PASS;
  setting.bitrate = _br;
  ADM_assert (0 == _init);

  if (ENC_OK != encore ((void *) &_handle, ENC_OPT_INIT, &tag, &setting))
    {
      printf ("\n error initializing divx !\n");
      return 0;

    }
  _init = 1;
  printf ("\n Divx initialized OK in CBR mode  !\n");
  return 1;
}



#endif
