Exemplo n.º 1
0
static void wait_worker_and_cache_frame(vpx_codec_alg_priv_t *ctx) {
  YV12_BUFFER_CONFIG sd;
  vp9_ppflags_t flags = {0, 0, 0};
  const VPxWorkerInterface *const winterface = vpx_get_worker_interface();
  VPxWorker *const worker = &ctx->frame_workers[ctx->next_output_worker_id];
  FrameWorkerData *const frame_worker_data = (FrameWorkerData *)worker->data1;
  ctx->next_output_worker_id =
      (ctx->next_output_worker_id + 1) % ctx->num_frame_workers;
  // TODO(hkuang): Add worker error handling here.
  winterface->sync(worker);
  frame_worker_data->received_frame = 0;
  ++ctx->available_threads;

  check_resync(ctx, frame_worker_data->pbi);

  if (vp9_get_raw_frame(frame_worker_data->pbi, &sd, &flags) == 0) {
    VP9_COMMON *const cm = &frame_worker_data->pbi->common;
    RefCntBuffer *const frame_bufs = cm->buffer_pool->frame_bufs;
    ctx->frame_cache[ctx->frame_cache_write].fb_idx = cm->new_fb_idx;
    yuvconfig2image(&ctx->frame_cache[ctx->frame_cache_write].img, &sd,
                    frame_worker_data->user_priv);
    ctx->frame_cache[ctx->frame_cache_write].img.fb_priv =
        frame_bufs[cm->new_fb_idx].raw_frame_buffer.priv;
    ctx->frame_cache_write =
        (ctx->frame_cache_write + 1) % FRAME_CACHE_SIZE;
    ++ctx->num_cache_frames;
  }
}
Exemplo n.º 2
0
static vpx_image_t *vp8_get_frame(vpx_codec_alg_priv_t  *ctx,
                                  vpx_codec_iter_t      *iter)
{
    vpx_image_t *img = NULL;

    /* iter acts as a flip flop, so an image is only returned on the first
     * call to get_frame.
     */
    if (!(*iter) && ctx->yv12_frame_buffers.pbi[0])
    {
        YV12_BUFFER_CONFIG sd;
        int64_t time_stamp = 0, time_end_stamp = 0;
        vp8_ppflags_t flags = {0};

        if (ctx->base.init_flags & VPX_CODEC_USE_POSTPROC)
        {
            flags.post_proc_flag= ctx->postproc_cfg.post_proc_flag
#if CONFIG_POSTPROC_VISUALIZER

                                | ((ctx->dbg_color_ref_frame_flag != 0) ? VP8D_DEBUG_CLR_FRM_REF_BLKS : 0)
                                | ((ctx->dbg_color_mb_modes_flag != 0) ? VP8D_DEBUG_CLR_BLK_MODES : 0)
                                | ((ctx->dbg_color_b_modes_flag != 0) ? VP8D_DEBUG_CLR_BLK_MODES : 0)
                                | ((ctx->dbg_display_mv_flag != 0) ? VP8D_DEBUG_DRAW_MV : 0)
#endif
                                ;
            flags.deblocking_level      = ctx->postproc_cfg.deblocking_level;
            flags.noise_level           = ctx->postproc_cfg.noise_level;
#if CONFIG_POSTPROC_VISUALIZER
            flags.display_ref_frame_flag= ctx->dbg_color_ref_frame_flag;
            flags.display_mb_modes_flag = ctx->dbg_color_mb_modes_flag;
            flags.display_b_modes_flag  = ctx->dbg_color_b_modes_flag;
            flags.display_mv_flag       = ctx->dbg_display_mv_flag;
#endif
        }

        if (0 == vp8dx_get_raw_frame(ctx->yv12_frame_buffers.pbi[0], &sd,
                                     &time_stamp, &time_end_stamp, &flags))
        {
            yuvconfig2image(&ctx->img, &sd, ctx->user_priv);

            img = &ctx->img;
            *iter = img;
        }
    }

    return img;
}
Exemplo n.º 3
0
static vpx_codec_err_t decode_one(vpx_codec_alg_priv_t *ctx,
                                  const uint8_t **data, unsigned int data_sz,
                                  void *user_priv, int64_t deadline) {
  YV12_BUFFER_CONFIG sd = { 0 };
  int64_t time_stamp = 0, time_end_stamp = 0;
  vp9_ppflags_t flags = {0};
  VP9_COMMON *cm = NULL;

  ctx->img_avail = 0;

  // Determine the stream parameters. Note that we rely on peek_si to
  // validate that we have a buffer that does not wrap around the top
  // of the heap.
  if (!ctx->si.h) {
    const vpx_codec_err_t res =
        ctx->base.iface->dec.peek_si(*data, data_sz, &ctx->si);
    if (res != VPX_CODEC_OK)
      return res;
  }

  // Initialize the decoder instance on the first frame
  if (!ctx->decoder_init) {
    init_decoder(ctx);
    if (ctx->pbi == NULL)
      return VPX_CODEC_ERROR;

    ctx->decoder_init = 1;
  }

  cm = &ctx->pbi->common;

  if (vp9_receive_compressed_data(ctx->pbi, data_sz, data, deadline))
    return update_error_state(ctx, &cm->error);

  if (ctx->base.init_flags & VPX_CODEC_USE_POSTPROC)
    set_ppflags(ctx, &flags);

  if (vp9_get_raw_frame(ctx->pbi, &sd, &time_stamp, &time_end_stamp, &flags))
    return update_error_state(ctx, &cm->error);

  yuvconfig2image(&ctx->img, &sd, user_priv);
  ctx->img.fb_priv = cm->frame_bufs[cm->new_fb_idx].raw_frame_buffer.priv;
  ctx->img_avail = 1;

  return VPX_CODEC_OK;
}
Exemplo n.º 4
0
static vpx_image_t *decoder_get_frame(vpx_codec_alg_priv_t *ctx,
                                      vpx_codec_iter_t *iter) {
  vpx_image_t *img = NULL;

  // iter acts as a flip flop, so an image is only returned on the first
  // call to get_frame.
  if (*iter == NULL && ctx->pbi != NULL) {
    YV12_BUFFER_CONFIG sd;
    vp9_ppflags_t flags = {0, 0, 0};

    if (vp9_get_raw_frame(ctx->pbi, &sd, &flags) == 0) {
      VP9_COMMON *cm = &ctx->pbi->common;
      yuvconfig2image(&ctx->img, &sd, NULL);
      ctx->img.fb_priv = cm->frame_bufs[cm->new_fb_idx].raw_frame_buffer.priv;
      img = &ctx->img;
      *iter = img;
    }
  }

  return img;
}
Exemplo n.º 5
0
static vpx_image_t *decoder_get_frame(vpx_codec_alg_priv_t *ctx,
                                      vpx_codec_iter_t *iter) {
  vpx_image_t *img = NULL;

  // Only return frame when all the cpu are busy or
  // application fluhsed the decoder in frame parallel decode.
  if (ctx->frame_parallel_decode && ctx->available_threads > 0 &&
      !ctx->flushed) {
    return NULL;
  }

  // Output the frames in the cache first.
  if (ctx->num_cache_frames > 0) {
    release_last_output_frame(ctx);
    ctx->last_show_frame  = ctx->frame_cache[ctx->frame_cache_read].fb_idx;
    if (ctx->need_resync)
      return NULL;
    img = &ctx->frame_cache[ctx->frame_cache_read].img;
    ctx->frame_cache_read = (ctx->frame_cache_read + 1) % FRAME_CACHE_SIZE;
    --ctx->num_cache_frames;
    return img;
  }

  // iter acts as a flip flop, so an image is only returned on the first
  // call to get_frame.
  if (*iter == NULL && ctx->frame_workers != NULL) {
    do {
      YV12_BUFFER_CONFIG sd;
      vp9_ppflags_t flags = {0, 0, 0};
      const VPxWorkerInterface *const winterface = vpx_get_worker_interface();
      VPxWorker *const worker =
          &ctx->frame_workers[ctx->next_output_worker_id];
      FrameWorkerData *const frame_worker_data =
          (FrameWorkerData *)worker->data1;
      ctx->next_output_worker_id =
          (ctx->next_output_worker_id + 1) % ctx->num_frame_workers;
      if (ctx->base.init_flags & VPX_CODEC_USE_POSTPROC)
        set_ppflags(ctx, &flags);
      // Wait for the frame from worker thread.
      if (winterface->sync(worker)) {
        // Check if worker has received any frames.
        if (frame_worker_data->received_frame == 1) {
          ++ctx->available_threads;
          frame_worker_data->received_frame = 0;
          check_resync(ctx, frame_worker_data->pbi);
        }
        if (vp9_get_raw_frame(frame_worker_data->pbi, &sd, &flags) == 0) {
          VP9_COMMON *const cm = &frame_worker_data->pbi->common;
          RefCntBuffer *const frame_bufs = cm->buffer_pool->frame_bufs;
          release_last_output_frame(ctx);
          ctx->last_show_frame = frame_worker_data->pbi->common.new_fb_idx;
          if (ctx->need_resync)
            return NULL;
          yuvconfig2image(&ctx->img, &sd, frame_worker_data->user_priv);
          ctx->img.fb_priv = frame_bufs[cm->new_fb_idx].raw_frame_buffer.priv;
          img = &ctx->img;
          return img;
        }
      } else {
        // Decoding failed. Release the worker thread.
        frame_worker_data->received_frame = 0;
        ++ctx->available_threads;
        ctx->need_resync = 1;
        if (ctx->flushed != 1)
          return NULL;
      }
    } while (ctx->next_output_worker_id != ctx->next_submit_worker_id);
  }
  return NULL;
}
Exemplo n.º 6
0
static vpx_codec_err_t decode_one(vpx_codec_alg_priv_t *ctx,
                                  const uint8_t **data, unsigned int data_sz,
                                  void *user_priv, int64_t deadline) {
  vpx_codec_err_t res = VPX_CODEC_OK;

  ctx->img_avail = 0;

  // Determine the stream parameters. Note that we rely on peek_si to
  // validate that we have a buffer that does not wrap around the top
  // of the heap.
  if (!ctx->si.h)
    res = ctx->base.iface->dec.peek_si(*data, data_sz, &ctx->si);

  /* Initialize the decoder instance on the first frame*/
  if (!res && !ctx->decoder_init) {
    VP9D_CONFIG oxcf;
    struct VP9Decompressor *optr;

    vp9_initialize_dec();

    oxcf.width = ctx->si.w;
    oxcf.height = ctx->si.h;
    oxcf.version = 9;
    oxcf.max_threads = ctx->cfg.threads;
    oxcf.inv_tile_order = ctx->invert_tile_order;
    optr = vp9_create_decompressor(&oxcf);

    // If postprocessing was enabled by the application and a
    // configuration has not been provided, default it.
    if (!ctx->postproc_cfg_set &&
        (ctx->base.init_flags & VPX_CODEC_USE_POSTPROC)) {
      ctx->postproc_cfg.post_proc_flag = VP8_DEBLOCK | VP8_DEMACROBLOCK;
      ctx->postproc_cfg.deblocking_level = 4;
      ctx->postproc_cfg.noise_level = 0;
    }

    if (!optr) {
      res = VPX_CODEC_ERROR;
    } else {
      VP9D_COMP *const pbi = (VP9D_COMP*)optr;
      VP9_COMMON *const cm = &pbi->common;

      // Set index to not initialized.
      cm->new_fb_idx = -1;

      if (ctx->get_ext_fb_cb != NULL && ctx->release_ext_fb_cb != NULL) {
        cm->get_fb_cb = ctx->get_ext_fb_cb;
        cm->release_fb_cb = ctx->release_ext_fb_cb;
        cm->cb_priv = ctx->ext_priv;
      } else {
        cm->get_fb_cb = vp9_get_frame_buffer;
        cm->release_fb_cb = vp9_release_frame_buffer;

        if (vp9_alloc_internal_frame_buffers(&cm->int_frame_buffers))
          vpx_internal_error(&cm->error, VPX_CODEC_MEM_ERROR,
                             "Failed to initialize internal frame buffers");
        cm->cb_priv = &cm->int_frame_buffers;
      }

      ctx->pbi = optr;
    }

    ctx->decoder_init = 1;
  }

  if (!res && ctx->pbi) {
    VP9D_COMP *const pbi = ctx->pbi;
    VP9_COMMON *const cm = &pbi->common;
    YV12_BUFFER_CONFIG sd;
    int64_t time_stamp = 0, time_end_stamp = 0;
    vp9_ppflags_t flags = {0};

    if (ctx->base.init_flags & VPX_CODEC_USE_POSTPROC) {
      flags.post_proc_flag =
#if CONFIG_POSTPROC_VISUALIZER
          (ctx->dbg_color_ref_frame_flag ? VP9D_DEBUG_CLR_FRM_REF_BLKS : 0) |
          (ctx->dbg_color_mb_modes_flag ? VP9D_DEBUG_CLR_BLK_MODES : 0) |
          (ctx->dbg_color_b_modes_flag ? VP9D_DEBUG_CLR_BLK_MODES : 0) |
          (ctx->dbg_display_mv_flag ? VP9D_DEBUG_DRAW_MV : 0) |
#endif
          ctx->postproc_cfg.post_proc_flag;

      flags.deblocking_level = ctx->postproc_cfg.deblocking_level;
      flags.noise_level = ctx->postproc_cfg.noise_level;
#if CONFIG_POSTPROC_VISUALIZER
      flags.display_ref_frame_flag = ctx->dbg_color_ref_frame_flag;
      flags.display_mb_modes_flag = ctx->dbg_color_mb_modes_flag;
      flags.display_b_modes_flag = ctx->dbg_color_b_modes_flag;
      flags.display_mv_flag = ctx->dbg_display_mv_flag;
#endif
    }

    if (vp9_receive_compressed_data(pbi, data_sz, data, deadline))
      res = update_error_state(ctx, &cm->error);

    if (!res && 0 == vp9_get_raw_frame(pbi, &sd, &time_stamp,
                                       &time_end_stamp, &flags)) {
      yuvconfig2image(&ctx->img, &sd, user_priv);

      ctx->img.fb_priv = cm->frame_bufs[cm->new_fb_idx].raw_frame_buffer.priv;
      ctx->img_avail = 1;
    }
  }

  return res;
}
Exemplo n.º 7
0
static vpx_codec_err_t decode_one(vpx_codec_alg_priv_t  *ctx,
                                  const uint8_t        **data,
                                  unsigned int           data_sz,
                                  void                  *user_priv,
                                  long                   deadline) {
  vpx_codec_err_t res = VPX_CODEC_OK;

  ctx->img_avail = 0;

  /* Determine the stream parameters. Note that we rely on peek_si to
   * validate that we have a buffer that does not wrap around the top
   * of the heap.
   */
  if (!ctx->si.h)
    res = ctx->base.iface->dec.peek_si(*data, data_sz, &ctx->si);


  /* Perform deferred allocations, if required */
  if (!res && ctx->defer_alloc) {
    int i;

    for (i = 1; !res && i < NELEMENTS(ctx->mmaps); i++) {
      vpx_codec_dec_cfg_t cfg;

      cfg.w = ctx->si.w;
      cfg.h = ctx->si.h;
      ctx->mmaps[i].id = vp8_mem_req_segs[i].id;
      ctx->mmaps[i].sz = vp8_mem_req_segs[i].sz;
      ctx->mmaps[i].align = vp8_mem_req_segs[i].align;
      ctx->mmaps[i].flags = vp8_mem_req_segs[i].flags;

      if (!ctx->mmaps[i].sz)
        ctx->mmaps[i].sz = vp8_mem_req_segs[i].calc_sz(&cfg,
                                                       ctx->base.init_flags);

      res = vp8_mmap_alloc(&ctx->mmaps[i]);
    }

    if (!res)
      vp8_finalize_mmaps(ctx);

    ctx->defer_alloc = 0;
  }

  /* Initialize the decoder instance on the first frame*/
  if (!res && !ctx->decoder_init) {
    res = vp8_validate_mmaps(&ctx->si, ctx->mmaps, ctx->base.init_flags);

    if (!res) {
      VP9D_CONFIG oxcf;
      VP9D_PTR optr;

      vp9_initialize_dec();

      oxcf.Width = ctx->si.w;
      oxcf.Height = ctx->si.h;
      oxcf.Version = 9;
      oxcf.postprocess = 0;
      oxcf.max_threads = ctx->cfg.threads;
      optr = vp9_create_decompressor(&oxcf);

      /* If postprocessing was enabled by the application and a
       * configuration has not been provided, default it.
       */
      if (!ctx->postproc_cfg_set
          && (ctx->base.init_flags & VPX_CODEC_USE_POSTPROC)) {
        ctx->postproc_cfg.post_proc_flag =
          VP8_DEBLOCK | VP8_DEMACROBLOCK;
        ctx->postproc_cfg.deblocking_level = 4;
        ctx->postproc_cfg.noise_level = 0;
      }

      if (!optr)
        res = VPX_CODEC_ERROR;
      else
        ctx->pbi = optr;
    }

    ctx->decoder_init = 1;
  }

  if (!res && ctx->pbi) {
    YV12_BUFFER_CONFIG sd;
    int64_t time_stamp = 0, time_end_stamp = 0;
    vp9_ppflags_t flags = {0};

    if (ctx->base.init_flags & VPX_CODEC_USE_POSTPROC) {
      flags.post_proc_flag = ctx->postproc_cfg.post_proc_flag
#if CONFIG_POSTPROC_VISUALIZER

                             | ((ctx->dbg_color_ref_frame_flag != 0) ? VP9D_DEBUG_CLR_FRM_REF_BLKS : 0)
                             | ((ctx->dbg_color_mb_modes_flag != 0) ? VP9D_DEBUG_CLR_BLK_MODES : 0)
                             | ((ctx->dbg_color_b_modes_flag != 0) ? VP9D_DEBUG_CLR_BLK_MODES : 0)
                             | ((ctx->dbg_display_mv_flag != 0) ? VP9D_DEBUG_DRAW_MV : 0)
#endif
;
      flags.deblocking_level      = ctx->postproc_cfg.deblocking_level;
      flags.noise_level           = ctx->postproc_cfg.noise_level;
#if CONFIG_POSTPROC_VISUALIZER
      flags.display_ref_frame_flag = ctx->dbg_color_ref_frame_flag;
      flags.display_mb_modes_flag = ctx->dbg_color_mb_modes_flag;
      flags.display_b_modes_flag  = ctx->dbg_color_b_modes_flag;
      flags.display_mv_flag       = ctx->dbg_display_mv_flag;
#endif
    }

    if (vp9_receive_compressed_data(ctx->pbi, data_sz, data, deadline)) {
      VP9D_COMP *pbi = (VP9D_COMP *)ctx->pbi;
      res = update_error_state(ctx, &pbi->common.error);
    }

    if (!res && 0 == vp9_get_raw_frame(ctx->pbi, &sd, &time_stamp,
                                       &time_end_stamp, &flags)) {
      yuvconfig2image(&ctx->img, &sd, user_priv);
      ctx->img_avail = 1;
    }
  }

  return res;
}
Exemplo n.º 8
0
static vpx_codec_err_t decode_one_recon_ex(vpx_codec_alg_priv_t *ctx,
                                  const uint8_t **data, unsigned int data_sz,
                                  void *user_priv, int64_t deadline, void *texture) {
  vpx_codec_err_t res = VPX_CODEC_OK;

  VP9D_COMP *pbi;
  VP9D_COMP *pbi_storage;
  VP9D_COMP *my_pbi;
  static int flag = 0;
  int i_is_last_frame = 0;
  int ret = -1;

  struct vpx_usec_timer timer;
  unsigned long yuv2rgb_time = 0;
  unsigned long decode_time = 0;

  // ctx->img_avail = 0;
  vpx_usec_timer_start(&timer);
  if (data_sz == 0) {
    pbi = (VP9D_COMP *)ctx->pbi;
    if (!pbi->l_bufpool_flag_output) {
      return 0;
    }
  }

  /* Determine the stream parameters. Note that we rely on peek_si to
   * validate that we have a buffer that does not wrap around the top
   * of the heap.
   */
  if (!ctx->si.h)
    res = ctx->base.iface->dec.peek_si(*data, data_sz, &ctx->si);


  /* Perform deferred allocations, if required */
  if (!res && ctx->defer_alloc) {
    int i;

    for (i = 1; !res && i < NELEMENTS(ctx->mmaps); i++) {
      vpx_codec_dec_cfg_t cfg;

      cfg.w = ctx->si.w;
      cfg.h = ctx->si.h;
      ctx->mmaps[i].id = vp9_mem_req_segs[i].id;
      ctx->mmaps[i].sz = vp9_mem_req_segs[i].sz;
      ctx->mmaps[i].align = vp9_mem_req_segs[i].align;
      ctx->mmaps[i].flags = vp9_mem_req_segs[i].flags;

      if (!ctx->mmaps[i].sz)
        ctx->mmaps[i].sz = vp9_mem_req_segs[i].calc_sz(&cfg,
                                                       ctx->base.init_flags);

      res = vpx_mmap_alloc(&ctx->mmaps[i]);
    }

    if (!res)
      vp9_finalize_mmaps(ctx);

    ctx->defer_alloc = 0;
  }

  /* Initialize the decoder instance on the first frame*/
  if (!res && !ctx->decoder_init) {
    res = vpx_validate_mmaps(&ctx->si, ctx->mmaps,
                             vp9_mem_req_segs, NELEMENTS(vp9_mem_req_segs),
                             ctx->base.init_flags);

    if (!res) {
      VP9D_CONFIG oxcf;
      VP9D_PTR optr;

      VP9D_COMP *const new_pbi = vpx_memalign(32, sizeof(VP9D_COMP));
      VP9D_COMP *const new_pbi_two = vpx_memalign(32, sizeof(VP9D_COMP));

      vp9_initialize_dec();

      oxcf.width = ctx->si.w;
      oxcf.height = ctx->si.h;
      oxcf.version = 9;
      oxcf.postprocess = 0;
      oxcf.max_threads = ctx->cfg.threads;
      oxcf.inv_tile_order = ctx->invert_tile_order;
      optr = vp9_create_decompressor_recon(&oxcf);

      vp9_zero(*new_pbi);
      vp9_zero(*new_pbi_two);

      // If postprocessing was enabled by the application and a
      // configuration has not been provided, default it.
      if (!ctx->postproc_cfg_set &&
          (ctx->base.init_flags & VPX_CODEC_USE_POSTPROC)) {
        ctx->postproc_cfg.post_proc_flag = VP8_DEBLOCK | VP8_DEMACROBLOCK;
        ctx->postproc_cfg.deblocking_level = 4;
        ctx->postproc_cfg.noise_level = 0;
      }

      if (!optr) {
        res = VPX_CODEC_ERROR;
      } else {
        VP9D_COMP *const pbi = (VP9D_COMP*)optr;
        VP9_COMMON *const cm = &pbi->common;

        VP9_COMMON *const cm0 = &new_pbi->common;
        VP9_COMMON *const cm1 = &new_pbi_two->common;

        if (ctx->fb_list != NULL && ctx->realloc_fb_cb != NULL &&
            ctx->fb_count > 0) {
          cm->fb_list = ctx->fb_list;
          cm->fb_count = ctx->fb_count;
          cm->realloc_fb_cb = ctx->realloc_fb_cb;
          cm->user_priv = ctx->user_priv;
          CpuFlag = 1;
        } else {
          CpuFlag = 0;
          cm->fb_count = FRAME_BUFFERS;
        }
        cm->fb_lru = ctx->fb_lru;
        CHECK_MEM_ERROR(cm, cm->yv12_fb,
                        vpx_calloc(cm->fb_count, sizeof(*cm->yv12_fb)));
        CHECK_MEM_ERROR(cm, cm->fb_idx_ref_cnt,
                        vpx_calloc(cm->fb_count, sizeof(*cm->fb_idx_ref_cnt)));
        if (cm->fb_lru) {
          CHECK_MEM_ERROR(cm, cm->fb_idx_ref_lru,
                          vpx_calloc(cm->fb_count,
                                     sizeof(*cm->fb_idx_ref_lru)));
        }
        ctx->pbi = optr;

        ctx->storage_pbi[0] = new_pbi;
        ctx->storage_pbi[1] = new_pbi_two;

        // cm 0
        if (ctx->fb_list != NULL && ctx->realloc_fb_cb != NULL &&
            ctx->fb_count > 0) {
          cm0->fb_list = ctx->fb_list;
          cm0->fb_count = ctx->fb_count;
          cm0->realloc_fb_cb = ctx->realloc_fb_cb;
          cm0->user_priv = ctx->user_priv;
        } else {
          cm0->fb_count = FRAME_BUFFERS;
        }
        cm0->fb_lru = ctx->fb_lru;
        // CHECK_MEM_ERROR(cm, cm->yv12_fb,
                        // vpx_calloc(cm->fb_count, sizeof(*cm->yv12_fb)));
        CHECK_MEM_ERROR(cm0, cm0->fb_idx_ref_cnt,
                        vpx_calloc(cm0->fb_count, sizeof(*cm0->fb_idx_ref_cnt)));
        if (cm0->fb_lru) {
          CHECK_MEM_ERROR(cm0, cm0->fb_idx_ref_lru,
                          vpx_calloc(cm0->fb_count,
                                     sizeof(*cm0->fb_idx_ref_lru)));
        }

        // cm 1
        if (ctx->fb_list != NULL && ctx->realloc_fb_cb != NULL &&
            ctx->fb_count > 0) {
          cm1->fb_list = ctx->fb_list;
          cm1->fb_count = ctx->fb_count;
          cm1->realloc_fb_cb = ctx->realloc_fb_cb;
          cm1->user_priv = ctx->user_priv;
        } else {
          cm1->fb_count = FRAME_BUFFERS;
        }
        cm1->fb_lru = ctx->fb_lru;
        // CHECK_MEM_ERROR(cm, cm->yv12_fb,
                        // vpx_calloc(cm->fb_count, sizeof(*cm->yv12_fb)));
        CHECK_MEM_ERROR(cm1, cm1->fb_idx_ref_cnt,
                        vpx_calloc(cm1->fb_count, sizeof(*cm1->fb_idx_ref_cnt)));
        if (cm1->fb_lru) {
          CHECK_MEM_ERROR(cm1, cm1->fb_idx_ref_lru,
                          vpx_calloc(cm1->fb_count,
                                     sizeof(*cm1->fb_idx_ref_lru)));
        }

      }
    }

    ctx->decoder_init = 1;
  }

  if (!res && ctx->pbi) {
    YV12_BUFFER_CONFIG sd;
    int64_t time_stamp = 0, time_end_stamp = 0;
    vp9_ppflags_t flags = {0};

    if (ctx->base.init_flags & VPX_CODEC_USE_POSTPROC) {
      flags.post_proc_flag =
#if CONFIG_POSTPROC_VISUALIZER
          (ctx->dbg_color_ref_frame_flag ? VP9D_DEBUG_CLR_FRM_REF_BLKS : 0) |
          (ctx->dbg_color_mb_modes_flag ? VP9D_DEBUG_CLR_BLK_MODES : 0) |
          (ctx->dbg_color_b_modes_flag ? VP9D_DEBUG_CLR_BLK_MODES : 0) |
          (ctx->dbg_display_mv_flag ? VP9D_DEBUG_DRAW_MV : 0) |
#endif
          ctx->postproc_cfg.post_proc_flag;

      flags.deblocking_level = ctx->postproc_cfg.deblocking_level;
      flags.noise_level = ctx->postproc_cfg.noise_level;
#if CONFIG_POSTPROC_VISUALIZER
      flags.display_ref_frame_flag = ctx->dbg_color_ref_frame_flag;
      flags.display_mb_modes_flag = ctx->dbg_color_mb_modes_flag;
      flags.display_b_modes_flag = ctx->dbg_color_b_modes_flag;
      flags.display_mv_flag = ctx->dbg_display_mv_flag;
#endif
    }

#if 0
    if (vp9_receive_compressed_data(ctx->pbi, data_sz, data, deadline)) {
      VP9D_COMP *pbi = (VP9D_COMP*)ctx->pbi;
      res = update_error_state(ctx, &pbi->common.error);
    }

    if (!res && 0 == vp9_get_raw_frame(ctx->pbi, &sd, &time_stamp,
                                       &time_end_stamp, &flags)) {
      yuvconfig2image(&ctx->img, &sd, user_priv);
      ctx->img_avail = 1;
    }
#endif
    
    if (data_sz == 0) {
      i_is_last_frame = 1;
    }
    
    if (vp9_receive_compressed_data_recon(ctx->pbi, ctx->storage_pbi, data_sz, data,
      deadline, i_is_last_frame)) {
      pbi = (VP9D_COMP *)ctx->pbi;
      if (pbi->l_bufpool_flag_output == 0)
        pbi_storage = (VP9D_COMP *)ctx->storage_pbi[1];
      else
        pbi_storage = (VP9D_COMP *)ctx->storage_pbi[pbi->l_bufpool_flag_output & 1];
      res = update_error_state(ctx, &pbi_storage->common.error);
    }
	vpx_usec_timer_mark(&timer);
    decode_time = (unsigned int)vpx_usec_timer_elapsed(&timer);
    if (ctx->pbi) {
      pbi = (VP9D_COMP *)ctx->pbi;
      if (pbi->l_bufpool_flag_output) {
        ret = vp9_get_raw_frame(ctx->storage_pbi[pbi->l_bufpool_flag_output & 1],
              &sd, &time_stamp, &time_end_stamp, &flags);
        if (!pbi->res && 0 == ret ) {
          //for render
          my_pbi = (VP9D_COMP *)(ctx->storage_pbi[pbi->l_bufpool_flag_output & 1]);
          yuv2rgba_ocl_obj.y_plane_offset = my_pbi->common.frame_to_show->y_buffer - 
                                                inter_ocl_obj.buffer_pool_map_ptr;
          yuv2rgba_ocl_obj.u_plane_offset = my_pbi->common.frame_to_show->u_buffer - 
                                                inter_ocl_obj.buffer_pool_map_ptr;
          yuv2rgba_ocl_obj.v_plane_offset = my_pbi->common.frame_to_show->v_buffer - 
                                                inter_ocl_obj.buffer_pool_map_ptr;
 
          yuv2rgba_ocl_obj.Y_stride =  my_pbi->common.frame_to_show->y_stride;
          yuv2rgba_ocl_obj.UV_stride =  my_pbi->common.frame_to_show->uv_stride;
          yuv2rgba_ocl_obj.globalThreads[0] =  my_pbi->common.width >> 1;
          yuv2rgba_ocl_obj.globalThreads[1] =  my_pbi->common.height >> 1;
 
		  vpx_usec_timer_start(&timer);
          vp9_yuv2rgba(&yuv2rgba_ocl_obj, texture);
		  vpx_usec_timer_mark(&timer);
          yuv2rgb_time = (unsigned int)vpx_usec_timer_elapsed(&timer);
	      fprintf(pLog, "decode one frame time(without YUV to RGB): %lu us\n"
			            "the whole time of YUV to RGB:  %lu us\n", decode_time, yuv2rgb_time);
          // for render end
          yuvconfig2image(&ctx->img, &sd, user_priv);
          ctx->img_avail = 1;
        }