static void
destroy_heap(
    const char         *name,
    object_heap_p       heap,
    destroy_heap_func_t destroy_func,
    void               *user_data
)
{
    object_base_p obj;
    object_heap_iterator iter;

    if (!heap)
        return;

    obj = object_heap_first(heap, &iter);
    while (obj) {
        xvba_information_message("vaTerminate(): %s ID 0x%08x is still allocated, destroying\n", name, obj->id);
        if (destroy_func)
            destroy_func(obj, user_data);
        else
            object_heap_free(heap, obj);
        obj = object_heap_next(heap, &iter);
    }
    object_heap_destroy(heap);
}
static VOID
media_destroy_heap (struct object_heap *heap,
		    VOID (*func) (struct object_heap * heap,
				  struct object_base * object))
{
  struct object_base *object;
  object_heap_iterator iter;

  object = object_heap_first (heap, &iter);

  while (object)
    {
      if (func)
	func (heap, object);

      object = object_heap_next (heap, &iter);
    }

  object_heap_destroy (heap);
}
BOOL
media_driver_data_init (VADriverContextP ctx)
{
  MEDIA_DRV_CONTEXT *drv_ctx = NULL;
  MEDIA_DRV_ASSERT (ctx);
  drv_ctx = ctx->pDriverData;
  if (IS_GEN75 (drv_ctx->drv_data.device_id))
    drv_ctx->codec_info = &gen75_hw_codec_info;
  else if (IS_GEN7 (drv_ctx->drv_data.device_id))
    drv_ctx->codec_info = &gen7_hw_codec_info;
  else if (IS_GEN8(drv_ctx->drv_data.device_id))
    drv_ctx->codec_info = &gen8_hw_codec_info;
  else if (IS_CHERRYVIEW(drv_ctx->drv_data.device_id))
    drv_ctx->codec_info = &chv_hw_codec_info;
  else
    return false;

  if (object_heap_init (&drv_ctx->config_heap,
			sizeof (struct object_config), CONFIG_ID_OFFSET))
    goto err_config_heap;
  if (object_heap_init (&drv_ctx->context_heap,
			sizeof (struct object_context), CONTEXT_ID_OFFSET))
    goto err_context_heap;

  if (object_heap_init (&drv_ctx->surface_heap,
			sizeof (struct object_surface), SURFACE_ID_OFFSET))
    goto err_surface_heap;
  if (object_heap_init (&drv_ctx->buffer_heap,
			sizeof (struct object_buffer), BUFFER_ID_OFFSET))
    goto err_buffer_heap;
  if (object_heap_init (&drv_ctx->image_heap,
			sizeof (struct object_image), IMAGE_ID_OFFSET))
    goto err_image_heap;

  if (object_heap_init (&drv_ctx->subpic_heap,
                        sizeof (struct object_subpic), IMAGE_ID_OFFSET))
    goto err_subpic_heap;

  drv_ctx->batch =
    media_batchbuffer_new (&drv_ctx->drv_data, I915_EXEC_RENDER, 0);
  drv_ctx->pp_batch =
    media_batchbuffer_new (&drv_ctx->drv_data, I915_EXEC_RENDER, 0);
  drv_ctx->render_batch =
    media_batchbuffer_new (&drv_ctx->drv_data, I915_EXEC_RENDER, 0);
  media_drv_mutex_init (&drv_ctx->render_mutex);
  media_drv_mutex_init (&drv_ctx->pp_mutex);

  return true;

err_subpic_heap:
  object_heap_destroy(&drv_ctx->subpic_heap);

err_image_heap:
  object_heap_destroy (&drv_ctx->buffer_heap);
err_buffer_heap:
  object_heap_destroy (&drv_ctx->surface_heap);
err_surface_heap:
  object_heap_destroy (&drv_ctx->context_heap);
err_context_heap:
  object_heap_destroy (&drv_ctx->config_heap);
err_config_heap:
  return false;
}