Beispiel #1
0
static GstMemory *
_fallback_mem_copy (GstMemory * mem, gssize offset, gssize size)
{
  GstMemory *copy;
  GstMapInfo sinfo, dinfo;
  GstAllocationParams params = { 0, mem->align, 0, 0, };
  GstAllocator *allocator;

  if (!gst_memory_map (mem, &sinfo, GST_MAP_READ))
    return NULL;

  if (size == -1)
    size = sinfo.size > offset ? sinfo.size - offset : 0;

  /* use the same allocator as the memory we copy  */
  allocator = mem->allocator;
  if (GST_OBJECT_FLAG_IS_SET (allocator, GST_ALLOCATOR_FLAG_CUSTOM_ALLOC))
    allocator = NULL;
  copy = gst_allocator_alloc (allocator, size, &params);

  if (!gst_memory_map (copy, &dinfo, GST_MAP_WRITE)) {
    GST_CAT_WARNING (GST_CAT_MEMORY, "could not write map memory %p", copy);
    gst_allocator_free (mem->allocator, copy);
    gst_memory_unmap (mem, &sinfo);
    return NULL;
  }

  GST_CAT_DEBUG (GST_CAT_PERFORMANCE,
      "memcpy %" G_GSSIZE_FORMAT " memory %p -> %p", size, mem, copy);
  memcpy (dinfo.data, sinfo.data + offset, size);
  gst_memory_unmap (copy, &dinfo);
  gst_memory_unmap (mem, &sinfo);

  return copy;
}
Beispiel #2
0
static gboolean gst_imx_vpu_base_enc_stop(GstVideoEncoder *encoder)
{
	gboolean ret;
	GstImxVpuBaseEnc *vpu_base_enc;

	ret = TRUE;

	vpu_base_enc = GST_IMX_VPU_BASE_ENC(encoder);

	if (vpu_base_enc->framebuffers != NULL)
	{
		gst_object_unref(vpu_base_enc->framebuffers);
		vpu_base_enc->framebuffers = NULL;
	}
	if (vpu_base_enc->output_phys_buffer != NULL)
	{
		gst_allocator_free(gst_imx_vpu_enc_allocator_obtain(), (GstMemory *)(vpu_base_enc->output_phys_buffer));
		vpu_base_enc->output_phys_buffer = NULL;
	}

	gst_imx_vpu_base_enc_close_encoder(vpu_base_enc);
	gst_imx_vpu_base_enc_free_enc_mem_blocks(vpu_base_enc);

	gst_imx_vpu_base_enc_unload();

	return ret;
}
Beispiel #3
0
static void gst_imx_vpu_base_enc_close_encoder(GstImxVpuBaseEnc *vpu_base_enc)
{
	VpuEncRetCode enc_ret;

	if (vpu_base_enc->internal_input_buffer != NULL) {
		gst_buffer_unref(vpu_base_enc->internal_input_buffer);
		vpu_base_enc->internal_input_buffer = NULL;
	}
	if (vpu_base_enc->internal_bufferpool != NULL) {
		gst_object_unref(vpu_base_enc->internal_bufferpool);
		vpu_base_enc->internal_bufferpool = NULL;
	}

	if (vpu_base_enc->output_phys_buffer != NULL)
	{
		gst_allocator_free(gst_imx_vpu_enc_allocator_obtain(), (GstMemory *)(vpu_base_enc->output_phys_buffer));
		vpu_base_enc->output_phys_buffer = NULL;
	}

	if (vpu_base_enc->vpu_inst_opened)
	{
		enc_ret = VPU_EncClose(vpu_base_enc->handle);
		if (enc_ret != VPU_ENC_RET_SUCCESS)
			GST_ERROR_OBJECT(vpu_base_enc, "closing encoder failed: %s", gst_imx_vpu_strerror(enc_ret));

		vpu_base_enc->vpu_inst_opened = FALSE;
	}
}
Beispiel #4
0
static void
_gst_memory_free (GstMemory * mem)
{
    GST_CAT_DEBUG (GST_CAT_MEMORY, "free memory %p", mem);

    if (mem->parent) {
        gst_memory_unlock (mem->parent, GST_LOCK_FLAG_EXCLUSIVE);
        gst_memory_unref (mem->parent);
    }

    gst_allocator_free (mem->allocator, mem);
}
Beispiel #5
0
static gboolean gst_fsl_vpu_base_enc_stop(GstVideoEncoder *encoder)
{
	gboolean ret;
	VpuEncRetCode enc_ret;
	GstFslVpuBaseEnc *vpu_base_enc;
	GstFslVpuBaseEncClass *klass;

	ret = TRUE;

	vpu_base_enc = GST_FSL_VPU_BASE_ENC(encoder);
	klass = GST_FSL_VPU_BASE_ENC_CLASS(G_OBJECT_GET_CLASS(vpu_base_enc));

	if (vpu_base_enc->framebuffers != NULL)
	{
		gst_object_unref(vpu_base_enc->framebuffers);
		vpu_base_enc->framebuffers = NULL;
	}
	if (vpu_base_enc->output_phys_buffer != NULL)
	{
		gst_allocator_free(gst_fsl_vpu_enc_allocator_obtain(), (GstMemory *)(vpu_base_enc->output_phys_buffer));
		vpu_base_enc->output_phys_buffer = NULL;
	}

	gst_fsl_vpu_base_enc_close_encoder(vpu_base_enc);
	gst_fsl_vpu_base_enc_free_enc_mem_blocks(vpu_base_enc);

	g_mutex_lock(&inst_counter_mutex);
	if (klass->inst_counter > 0)
	{
		--klass->inst_counter;
		if (klass->inst_counter == 0)
		{
			enc_ret = VPU_EncUnLoad();
			if (enc_ret != VPU_ENC_RET_SUCCESS)
			{
				GST_ERROR_OBJECT(vpu_base_enc, "unloading VPU encoder failed: %s", gst_fsl_vpu_strerror(enc_ret));
			}
			else
				GST_INFO_OBJECT(vpu_base_enc, "VPU encoder unloaded");
		}
	}
	g_mutex_unlock(&inst_counter_mutex);

	return ret;
}
Beispiel #6
0
gboolean gst_imx_vpu_free_phys_mem_blocks(GstImxPhysMemAllocator *phys_mem_allocator, GSList **phys_mem_blocks)
{
	GSList *mem_block_node;

	setup_debug_category();

	g_assert(phys_mem_blocks != NULL);

	mem_block_node = *phys_mem_blocks;
	if (mem_block_node == NULL)
		return TRUE;

	for (; mem_block_node != NULL; mem_block_node = mem_block_node->next)
	{
		GstMemory *memory = (GstMemory *)(mem_block_node->data);
		gst_allocator_free((GstAllocator *)phys_mem_allocator, memory);
		GST_INFO("freed phys memory block with %u bytes at phys addr 0x%x", memory->size, ((GstImxPhysMemory *)memory)->phys_addr);
	}

	g_slist_free(*phys_mem_blocks);
	*phys_mem_blocks = NULL;

	return TRUE;
}
Beispiel #7
0
static gboolean gst_fsl_vpu_base_enc_set_format(GstVideoEncoder *encoder, GstVideoCodecState *state)
{
	VpuEncRetCode ret;
	GstVideoCodecState *output_state;
	GstFslVpuBaseEncClass *klass;
	GstFslVpuBaseEnc *vpu_base_enc;
	
	vpu_base_enc = GST_FSL_VPU_BASE_ENC(encoder);
	klass = GST_FSL_VPU_BASE_ENC_CLASS(G_OBJECT_GET_CLASS(vpu_base_enc));

	g_assert(klass->set_open_params != NULL);
	g_assert(klass->get_output_caps != NULL);

	/* Close old encoder instance */
	gst_fsl_vpu_base_enc_close_encoder(vpu_base_enc);

	/* Clean up existing framebuffers structure;
	 * if some previous and still existing buffer pools depend on this framebuffers
	 * structure, they will extend its lifetime, since they ref'd it
	 */
	if (vpu_base_enc->framebuffers != NULL)
	{
		gst_object_unref(vpu_base_enc->framebuffers);
		vpu_base_enc->framebuffers = NULL;
	}

	if (vpu_base_enc->output_phys_buffer != NULL)
	{
		gst_allocator_free(gst_fsl_vpu_enc_allocator_obtain(), (GstMemory *)(vpu_base_enc->output_phys_buffer));
		vpu_base_enc->output_phys_buffer = NULL;
	}

	memset(&(vpu_base_enc->open_param), 0, sizeof(VpuEncOpenParam));

	/* These params are usually not set by derived classes */
	vpu_base_enc->open_param.nPicWidth = GST_VIDEO_INFO_WIDTH(&(state->info));
	vpu_base_enc->open_param.nPicHeight = GST_VIDEO_INFO_HEIGHT(&(state->info));
	vpu_base_enc->open_param.nFrameRate = (GST_VIDEO_INFO_FPS_N(&(state->info)) & 0xffffUL) | (((GST_VIDEO_INFO_FPS_D(&(state->info)) - 1) & 0xffffUL) << 16);
	vpu_base_enc->open_param.sMirror = VPU_ENC_MIRDIR_NONE; /* don't use VPU rotation (IPU has better performance) */
	vpu_base_enc->open_param.nBitRate = vpu_base_enc->bitrate;
	vpu_base_enc->open_param.nGOPSize = vpu_base_enc->gop_size;
	vpu_base_enc->open_param.nUserGamma = (int)(32768 * vpu_base_enc->qp_smoothing);
	vpu_base_enc->open_param.nAvcIntra16x16OnlyModeEnable = vpu_base_enc->intra_16x16_only ? 1 : 0;
	vpu_base_enc->open_param.nRcIntervalMode = 1;
	/* These params are defaults, and are often overwritten by derived classes */
	vpu_base_enc->open_param.nUserQpMax = -1;
	vpu_base_enc->open_param.nUserQpMin = -1;
	vpu_base_enc->open_param.nRcIntraQp = -1;

	GST_DEBUG_OBJECT(vpu_base_enc, "setting bitrate to %u kbps and GOP size to %u", vpu_base_enc->open_param.nBitRate, vpu_base_enc->open_param.nGOPSize);

	/* Give the derived class a chance to set params */
	if (!klass->set_open_params(vpu_base_enc, &(vpu_base_enc->open_param)))
	{
		GST_ERROR_OBJECT(vpu_base_enc, "derived class could not set open params");
		return FALSE;
	}

	/* The actual initialization; requires bitstream information (such as the codec type), which
	 * is determined by the fill_param_set call before */
	ret = VPU_EncOpen(&(vpu_base_enc->handle), &(vpu_base_enc->mem_info), &(vpu_base_enc->open_param));
	if (ret != VPU_ENC_RET_SUCCESS)
	{
		GST_ERROR_OBJECT(vpu_base_enc, "opening new VPU handle failed: %s", gst_fsl_vpu_strerror(ret));
		return FALSE;
	}

	vpu_base_enc->vpu_inst_opened = TRUE;

	/* configure AFTER setting vpu_inst_opened to TRUE, to make sure that in case of
	   config failure the VPU handle is closed in the finalizer */

	ret = VPU_EncConfig(vpu_base_enc->handle, VPU_ENC_CONF_NONE, NULL);
	if (ret != VPU_ENC_RET_SUCCESS)
	{
		GST_ERROR_OBJECT(vpu_base_enc, "could not apply default configuration: %s", gst_fsl_vpu_strerror(ret));
		return FALSE;
	}

	ret = VPU_EncGetInitialInfo(vpu_base_enc->handle, &(vpu_base_enc->init_info));
	if (ret != VPU_ENC_RET_SUCCESS)
	{
		GST_ERROR_OBJECT(vpu_base_enc, "retrieving init info failed: %s", gst_fsl_vpu_strerror(ret));
		return FALSE;
	}

	/* Framebuffers are created in handle_frame(), to make sure the actual stride is used */

	/* Set the output state, using caps defined by the derived class */
	output_state = gst_video_encoder_set_output_state(
		encoder,
		klass->get_output_caps(vpu_base_enc),
		state
	);
	gst_video_codec_state_unref(output_state);

	vpu_base_enc->video_info = state->info;

	return TRUE;
}
Beispiel #8
0
static gboolean gst_imx_vpu_base_enc_set_format(GstVideoEncoder *encoder, GstVideoCodecState *state)
{
	VpuEncRetCode ret;
	GstVideoCodecState *output_state;
	GstImxVpuBaseEncClass *klass;
	GstImxVpuBaseEnc *vpu_base_enc;
	int param;
	
	vpu_base_enc = GST_IMX_VPU_BASE_ENC(encoder);
	klass = GST_IMX_VPU_BASE_ENC_CLASS(G_OBJECT_GET_CLASS(vpu_base_enc));

	g_assert(klass->set_open_params != NULL);
	g_assert(klass->get_output_caps != NULL);

	/* Close old encoder instance */
	gst_imx_vpu_base_enc_close_encoder(vpu_base_enc);

	/* Clean up existing framebuffers structure;
	 * if some previous and still existing buffer pools depend on this framebuffers
	 * structure, they will extend its lifetime, since they ref'd it
	 */
	if (vpu_base_enc->framebuffers != NULL)
	{
		gst_object_unref(vpu_base_enc->framebuffers);
		vpu_base_enc->framebuffers = NULL;
	}

	if (vpu_base_enc->output_phys_buffer != NULL)
	{
		gst_allocator_free(gst_imx_vpu_enc_allocator_obtain(), (GstMemory *)(vpu_base_enc->output_phys_buffer));
		vpu_base_enc->output_phys_buffer = NULL;
	}

	memset(&(vpu_base_enc->open_param), 0, sizeof(VpuEncOpenParam));

	/* These params are usually not set by derived classes */
	vpu_base_enc->open_param.nPicWidth = GST_VIDEO_INFO_WIDTH(&(state->info));
	vpu_base_enc->open_param.nPicHeight = GST_VIDEO_INFO_HEIGHT(&(state->info));
	vpu_base_enc->open_param.nFrameRate = (GST_VIDEO_INFO_FPS_N(&(state->info)) & 0xffffUL) | (((GST_VIDEO_INFO_FPS_D(&(state->info)) - 1) & 0xffffUL) << 16);
	vpu_base_enc->open_param.sMirror = VPU_ENC_MIRDIR_NONE; /* don't use VPU mirroring (IPU has better performance) */
	vpu_base_enc->open_param.nBitRate = vpu_base_enc->bitrate;
	vpu_base_enc->open_param.nGOPSize = vpu_base_enc->gop_size;

	GST_INFO_OBJECT(vpu_base_enc, "setting bitrate to %u kbps and GOP size to %u", vpu_base_enc->open_param.nBitRate, vpu_base_enc->open_param.nGOPSize);

	/* These are default settings from VPU_EncOpenSimp */
	vpu_base_enc->open_param.sliceMode.sliceMode = 0; /* 1 slice per picture */
	vpu_base_enc->open_param.sliceMode.sliceSizeMode = 0; /* sliceSize is bits */
	vpu_base_enc->open_param.sliceMode.sliceSize = 4000;
	vpu_base_enc->open_param.nRcIntraQp = -1;
	vpu_base_enc->open_param.nUserGamma = 0.75 * 32768;

	if (vpu_base_enc->slice_size) {
		vpu_base_enc->open_param.sliceMode.sliceMode = 1;	/* 0: 1 slice per picture; 1: Multiple slices per picture */
		if (vpu_base_enc->slice_size < 0) {
			vpu_base_enc->open_param.sliceMode.sliceSizeMode = 1; /* 1: sliceSize defined by MB number*/
			vpu_base_enc->open_param.sliceMode.sliceSize = -vpu_base_enc->slice_size;  /* Size of a slice in MB numbers */
		} else {
			vpu_base_enc->open_param.sliceMode.sliceSizeMode = 0; /* 1: sliceSize defined by bits */
			vpu_base_enc->open_param.sliceMode.sliceSize = vpu_base_enc->slice_size;  /* Size of a slice in bits */
		}
	}

	vpu_base_enc->open_param.nIntraRefresh = vpu_base_enc->intra_refresh;

	/* Give the derived class a chance to set params */
	if (!klass->set_open_params(vpu_base_enc, state, &(vpu_base_enc->open_param)))
	{
		GST_ERROR_OBJECT(vpu_base_enc, "derived class could not set open params");
		return FALSE;
	}

	/* The actual initialization; requires bitstream information (such as the codec type), which
	 * is determined by the fill_param_set call before */
	ret = VPU_EncOpen(&(vpu_base_enc->handle), &(vpu_base_enc->mem_info), &(vpu_base_enc->open_param));
	if (ret != VPU_ENC_RET_SUCCESS)
	{
		GST_ERROR_OBJECT(vpu_base_enc, "opening new VPU handle failed: %s", gst_imx_vpu_strerror(ret));
		return FALSE;
	}

	vpu_base_enc->vpu_inst_opened = TRUE;

	/* configure AFTER setting vpu_inst_opened to TRUE, to make sure that in case of
	   config failure the VPU handle is closed in the finalizer */

	if (vpu_base_enc->bitrate != 0)
	{
		param = vpu_base_enc->bitrate;
		ret = VPU_EncConfig(vpu_base_enc->handle, VPU_ENC_CONF_BIT_RATE, &param);
		if (ret != VPU_ENC_RET_SUCCESS)
		{
			GST_ERROR_OBJECT(vpu_base_enc, "could not configure bitrate: %s", gst_imx_vpu_strerror(ret));
			return FALSE;
		}
	}

	if (vpu_base_enc->intra_refresh != 0)
	{
		param = vpu_base_enc->intra_refresh;
		ret = VPU_EncConfig(vpu_base_enc->handle, VPU_ENC_CONF_INTRA_REFRESH, &param);
		if (ret != VPU_ENC_RET_SUCCESS)
		{
			GST_ERROR_OBJECT(vpu_base_enc, "could not configure intra refresh period: %s", gst_imx_vpu_strerror(ret));
			return FALSE;
		}
	}

	ret = VPU_EncGetInitialInfo(vpu_base_enc->handle, &(vpu_base_enc->init_info));
	if (ret != VPU_ENC_RET_SUCCESS)
	{
		GST_ERROR_OBJECT(vpu_base_enc, "retrieving init info failed: %s", gst_imx_vpu_strerror(ret));
		return FALSE;
	}

	/* Framebuffers are created in handle_frame(), to make sure the actual stride is used */

	/* Set the output state, using caps defined by the derived class */
	output_state = gst_video_encoder_set_output_state(
		encoder,
		klass->get_output_caps(vpu_base_enc),
		state
	);
	gst_video_codec_state_unref(output_state);

	vpu_base_enc->video_info = state->info;

	return TRUE;
}