Exemplo n.º 1
0
static gboolean
sink_setcaps(GstPad *pad,
	     GstCaps *caps)
{
	GstDspVpp *self;
	GstDspBase *base;
	GstCaps *out_caps;
	gboolean ret;

	self = GST_DSP_VPP(GST_PAD_PARENT(pad));
	base = GST_DSP_BASE(self);

	{
		gchar *str = gst_caps_to_string(caps);
		pr_info(self, "sink caps: %s", str);
		g_free(str);
	}

	base->codec = &td_vpp_codec;

	du_port_alloc_buffers(base->ports[0], 4);
	du_port_alloc_buffers(base->ports[1], 4);

	out_caps = gst_caps_new_empty();
	configure_caps(self, caps, out_caps);
	base->tmp_caps = out_caps;

	ret = gst_pad_set_caps(pad, caps);

	if (!ret)
		return FALSE;

	return TRUE;
}
Exemplo n.º 2
0
static gboolean
sink_setcaps(GstPad *pad,
	     GstCaps *caps)
{
	GstDspADec *self;
	GstDspBase *base;
	GstStructure *in_struc;
	const char *name;
	GstCaps *out_caps;

	self = GST_DSP_ADEC(GST_PAD_PARENT(pad));
	base = GST_DSP_BASE(self);

	{
		gchar *str = gst_caps_to_string(caps);
		pr_info(self, "sink caps: %s", str);
		g_free(str);
	}

	in_struc = gst_caps_get_structure(caps, 0);

	name = gst_structure_get_name(in_struc);
	if (strcmp(name, "audio/mpeg") == 0) {
		int version = 1;

		gst_structure_get_int(in_struc, "mpegversion", &version);
		if (version == 2 || version == 4) {
			base->alg = GSTDSP_AACDEC;
			base->codec = &td_aacdec_codec;
		}
	}

	du_port_alloc_buffers(base->ports[0], 4);
	du_port_alloc_buffers(base->ports[1], 4);

	out_caps = gst_caps_new_empty();
	configure_caps(self, caps, out_caps);
	base->tmp_caps = out_caps;

	return TRUE;
}
Exemplo n.º 3
0
static gboolean
sink_setcaps(GstPad *pad,
	     GstCaps *caps)
{
	GstDspVEnc *self;
	GstDspBase *base;
	GstStructure *in_struc;
	GstCaps *out_caps;
	GstStructure *out_struc;
	gint width = 0, height = 0;
	GstCaps *allowed_caps;
	gint tgt_level = -1;
	struct td_codec *codec;

	self = GST_DSP_VENC(GST_PAD_PARENT(pad));
	base = GST_DSP_BASE(self);
	codec = base->codec;

	if (!codec)
		return FALSE;

#ifdef DEBUG
	{
		gchar *str = gst_caps_to_string(caps);
		pr_info(self, "sink caps: %s", str);
		g_free(str);
	}
#endif

	in_struc = gst_caps_get_structure(caps, 0);

	out_caps = gst_caps_new_empty();

	switch (base->alg) {
	case GSTDSP_JPEGENC:
		out_struc = gst_structure_new("image/jpeg",
					      NULL);
		break;
	case GSTDSP_H263ENC:
		out_struc = gst_structure_new("video/x-h263",
					      "variant", G_TYPE_STRING, "itu",
					      NULL);
		break;
	case GSTDSP_MP4VENC:
		out_struc = gst_structure_new("video/mpeg",
					      "mpegversion", G_TYPE_INT, 4,
					      "systemstream", G_TYPE_BOOLEAN, FALSE,
					      NULL);
		break;
	case GSTDSP_H264ENC:
		out_struc = gst_structure_new("video/x-h264",
					      "alignment", G_TYPE_STRING, "au",
					      NULL);
		break;
	default:
		return FALSE;
	}

	if (gst_structure_get_int(in_struc, "width", &width))
		gst_structure_set(out_struc, "width", G_TYPE_INT, width, NULL);
	if (gst_structure_get_int(in_struc, "height", &height))
		gst_structure_set(out_struc, "height", G_TYPE_INT, height, NULL);
	gst_structure_get_fourcc(in_struc, "format", &self->color_format);

	switch (base->alg) {
	case GSTDSP_H263ENC:
	case GSTDSP_MP4VENC:
	case GSTDSP_H264ENC:
		base->output_buffer_size = width * height / 2;
		break;
	case GSTDSP_JPEGENC:
		if (width % 2 || height % 2)
			return FALSE;
		if (self->color_format == GST_MAKE_FOURCC('I', '4', '2', '0'))
			base->input_buffer_size = ROUND_UP(width, 16) * ROUND_UP(height, 16) * 3 / 2;
		else
			base->input_buffer_size = ROUND_UP(width, 16) * ROUND_UP(height, 16) * 2;
		base->output_buffer_size = width * height;
		if (self->quality < 10)
			base->output_buffer_size /= 10;
		else if (self->quality < 100)
			base->output_buffer_size /= (100 / self->quality);
		break;
	default:
		break;
	}

	if (base->node)
		goto skip_setup;

	switch (base->alg) {
	case GSTDSP_JPEGENC:
		du_port_alloc_buffers(base->ports[0], 1);
#if SN_API > 1
		du_port_alloc_buffers(base->ports[1], 2);
#else
		/* old versions of the sn can't handle 2 buffers */
		/*
		 * Some constrained pipelines might starve because of this. You
		 * might want to try enable-last-buffer=false on some sinks.
		 * TODO Is there any way around this?
		 */
		du_port_alloc_buffers(base->ports[1], 1);
#endif
		break;
	default:
		du_port_alloc_buffers(base->ports[0], 2);
		du_port_alloc_buffers(base->ports[1], 4);
		break;
	}

skip_setup:
	self->width = width;
	self->height = height;

	{
		const GValue *framerate = NULL;
		framerate = gst_structure_get_value(in_struc, "framerate");
		if (framerate) {
			gst_structure_set_value(out_struc, "framerate", framerate);
			/* calculate nearest integer */
			self->framerate = (gst_value_get_fraction_numerator(framerate) * 2 /
					   gst_value_get_fraction_denominator(framerate) + 1) / 2;
		}
	}

	/* see if downstream caps express something */
	allowed_caps = gst_pad_get_allowed_caps(base->srcpad);
	if (allowed_caps) {
		if (gst_caps_get_size(allowed_caps) > 0) {
			GstStructure *s;
			s = gst_caps_get_structure(allowed_caps, 0);
			gst_structure_get_int(s, "level", &tgt_level);
			if (base->alg == GSTDSP_H264ENC) {
				const char *stream_format;
				stream_format = gst_structure_get_string(s, "stream-format");
				if (stream_format && !strcmp(stream_format, "avc"))
					self->priv.h264.bytestream = false;
				else
					stream_format = "byte-stream";
				gst_structure_set(out_struc, "stream-format", G_TYPE_STRING, stream_format, NULL);
			}
		}
		gst_caps_unref(allowed_caps);
	}

	check_supported_levels(self, tgt_level);

	if (self->bitrate == 0)
		self->bitrate = self->max_bitrate;
	else if (self->bitrate > self->max_bitrate)
		self->bitrate = self->max_bitrate;

	gst_caps_append_structure(out_caps, out_struc);

#ifdef DEBUG
	{
		gchar *str = gst_caps_to_string(out_caps);
		pr_info(self, "src caps: %s", str);
		g_free(str);
	}
#endif

	if (!gst_pad_take_caps(base->srcpad, out_caps))
		return FALSE;

	if (base->node)
		return TRUE;

	base->node = create_node(self);
	if (!base->node) {
		pr_err(self, "dsp node creation failed");
		return FALSE;
	}

	if (codec->setup_params)
		codec->setup_params(base);

	if (!gstdsp_start(base)) {
		pr_err(self, "dsp start failed");
		return FALSE;
	}

	if (codec->send_params)
		codec->send_params(base, base->node);

	return TRUE;
}