void*
vp_os_aligned_realloc(void* ptr, size_t size, size_t align_size)
{
  void* ptr_ret;
  void* aligned_ptr;

  if( size == 0 )
  {
    ptr_ret = NULL;
    if( ptr != NULL )
      vp_os_aligned_free(ptr);
  }
  else
  {
    if( ptr != NULL )
    {
      int* ptr2 = (int*)ptr - 1;
      size_t old_size;

      aligned_ptr = ptr;

      old_size = *ptr2--;

      ptr_ret = vp_os_aligned_malloc(size, align_size);

      // Compute smallest size
      if( size > old_size )
      {
        size = old_size;
      }

      // Copy old data
      vp_os_memcpy( ptr_ret, aligned_ptr, size );

      vp_os_free( ((char*)ptr - *ptr2) );
    }
    else
    {
      ptr_ret = vp_os_aligned_malloc(size, align_size);
    }
  }

  return ptr_ret;
}
static C_RESULT video_codec_open_private( video_controller_t* controller, codec_type_t codec_type, bool_t keep_stream )
{
  C_RESULT res;
  // Data used to initialize macroblock's cache
  int32_t i;
  int16_t* cache;
  video_macroblock_t* mb;

  // Close any previously allocated codec for this controller
  video_codec_close_private( controller, keep_stream);

  controller->mode            = 0;
  controller->use_me          = FALSE;
  controller->do_azq          = FALSE;
  controller->aq              = 0;
  controller->bq              = 0;
  controller->target_bitrate  = VLIB_DEFAULT_BITRATE;
  controller->num_frames      = 0;
  controller->picture_type    = 0;
  controller->width           = 0;
  controller->height          = 0;
  controller->num_blockline   = 0;
  controller->mb_blockline    = 0;
  controller->blockline       = 0;
  controller->picture_complete= 0;
  controller->quant           = DEFAULT_QUANTIZATION;
  controller->dquant          = 0;
  controller->Qp              = 0;
  controller->invQp           = 1;
  controller->gobs            = NULL;
  controller->cache           = NULL;
  controller->codec_type      = 0;
  controller->video_codec     = NULL;

  if( controller->blockline_cache == NULL )
  {
    // We alloc two buffers to be compatible with an asynchronous DCT
    // When a DCT will be performed on one buffer, we will be able to use the other for caching or computing purpose
    // DCT_BUFFER_SIZE = MAX_NUM_MACRO_BLOCKS_PER_CALL * 6 * MCU_BLOCK_SIZE
    controller->blockline_cache = (int16_t*)vp_os_aligned_malloc( 2*DCT_BUFFER_SIZE*sizeof(int16_t), VLIB_ALLOC_ALIGN );
  }
  if (controller->cache_mbs == NULL)
  {
    controller->cache_mbs = vp_os_malloc( 2 * MAX_NUM_MACRO_BLOCKS_PER_CALL * sizeof(video_macroblock_t) );
    mb = &controller->cache_mbs[0];
    cache = controller->blockline_cache;
    for(i = 2*MAX_NUM_MACRO_BLOCKS_PER_CALL; i > 0; i-- )
    {
      mb->data = cache;
      cache   += MCU_BLOCK_SIZE*6;
      mb ++;
    }
  }

  // TODO: choix dynamique de codec, le packetizer init n'est pas appellé lors d'un changement de codec dynamique
  if (keep_stream == FALSE)
    video_packetizer_init( controller );
  video_quantizer_init( controller );

  switch( codec_type )
  {
    case UVLC_CODEC:
      uvlc_codec_alloc( controller );
      break;

    case P263_CODEC:
      p263_codec_alloc( controller );
      break;

    case P264_CODEC:
      p264_codec_alloc( controller );
      break;

    default:
      controller->video_codec = NULL;
      break;
  }

  if( controller->video_codec != NULL )
  {
    controller->codec_type = codec_type;
    res = C_OK;
  }
  else
  {
    res = C_FAIL;
  }

  video_utils_init( controller );

  return res;
}