Exemplo n.º 1
0
static GstStateChangeReturn
change_state(GstElement *element, GstStateChange transition)
{
	GstStateChangeReturn ret;
	struct obj *self;

	self = (struct obj *)element;

	GST_DEBUG_OBJECT (self, "State change: %s -> %s",
			  gst_element_state_get_name (GST_STATE_TRANSITION_CURRENT (transition)),
			  gst_element_state_get_name (GST_STATE_TRANSITION_NEXT (transition)));

	switch (transition) {
	case GST_STATE_CHANGE_NULL_TO_READY:
		self->initialized = false;
		break;

	default:
		break;
	}

	ret = parent_class->change_state(element, transition);

	if (ret == GST_STATE_CHANGE_FAILURE)
		return ret;

	switch (transition) {
	case GST_STATE_CHANGE_READY_TO_NULL:
		if (self->av_ctx) {
			gst_av_codec_close(self->av_ctx);
			av_freep(&self->av_ctx->extradata);
			av_freep(&self->av_ctx);
		}
		break;

	default:
		break;
	}

	GST_DEBUG_OBJECT (self, "State_change return: %s",
			  gst_element_state_change_return_get_name (ret));

	return ret;
}
Exemplo n.º 2
0
static GstStateChangeReturn
change_state(GstElement *element, GstStateChange transition)
{
	GstStateChangeReturn ret;
	struct obj *self;

	self = (struct obj *)element;

	switch (transition) {
	case GST_STATE_CHANGE_NULL_TO_READY:
		self->av_ctx = avcodec_alloc_context();
		self->initialized = false;
		break;

	default:
		break;
	}

	ret = parent_class->change_state(element, transition);

	if (ret == GST_STATE_CHANGE_FAILURE)
		return ret;

	switch (transition) {
	case GST_STATE_CHANGE_READY_TO_NULL:
		if (self->av_ctx) {
			gst_av_codec_close(self->av_ctx);
			av_freep(&self->av_ctx);
		}
		break;

	default:
		break;
	}

	return ret;
}
Exemplo n.º 3
0
static gboolean
sink_setcaps(GstPad *pad, GstCaps *caps)
{
	struct obj *self;
	GstStructure *in_struc;
	const char *name;
	int codec_id;
	const GValue *codec_data;
	GstBuffer *buf;
	AVCodecContext *ctx;

	self = (struct obj *)((GstObject *)pad)->parent;
	ctx = self->av_ctx;

	if (ctx) {
		/* reset */
		get_delayed(self);
		gst_av_codec_close(ctx);
		av_freep(&ctx->extradata);
		av_freep(&self->av_ctx);
		self->initialized = false;
	}

	in_struc = gst_caps_get_structure(caps, 0);

	name = gst_structure_get_name(in_struc);
	if (strcmp(name, "video/x-h263") == 0)
		codec_id = CODEC_ID_H263;
	else if (strcmp(name, "video/x-h264") == 0)
		codec_id = CODEC_ID_H264;
	else if (strcmp(name, "video/mpeg") == 0) {
		int version;
		gst_structure_get_int(in_struc, "mpegversion", &version);
		switch (version) {
		case 4:
			codec_id = CODEC_ID_MPEG4;
			break;
		case 2:
			codec_id = CODEC_ID_MPEG2VIDEO;
			break;
		case 1:
			codec_id = CODEC_ID_MPEG1VIDEO;
			break;
		default:
			codec_id = CODEC_ID_NONE;
			break;
		}
	}
	else if (strcmp(name, "video/x-divx") == 0) {
		int version;
		gst_structure_get_int(in_struc, "divxversion", &version);
		switch (version) {
		case 5:
		case 4:
			codec_id = CODEC_ID_MPEG4;
			break;
		case 3:
			codec_id = CODEC_ID_MSMPEG4V3;
			break;
		default:
			codec_id = CODEC_ID_NONE;
			break;
		}
	}
	else if (strcmp(name, "video/x-xvid") == 0)
		codec_id = CODEC_ID_MPEG4;
	else if (strcmp(name, "video/x-3ivx") == 0)
		codec_id = CODEC_ID_MPEG4;
	else if (strcmp(name, "video/x-vp8") == 0)
		codec_id = CODEC_ID_VP8;
	else if (strcmp(name, "video/x-theora") == 0)
		codec_id = CODEC_ID_THEORA;
	else if (strcmp(name, "video/x-wmv") == 0) {
		int version;
		gst_structure_get_int(in_struc, "wmvversion", &version);
		switch (version) {
		case 3: {
			guint32 fourcc;
			codec_id = CODEC_ID_WMV3;
			if (gst_structure_get_fourcc(in_struc, "fourcc", &fourcc) ||
					gst_structure_get_fourcc(in_struc, "format", &fourcc))
			{
				if (fourcc == GST_MAKE_FOURCC('W', 'V', 'C', '1'))
					codec_id = CODEC_ID_VC1;
			}
			break;
		}
		case 2:
			codec_id = CODEC_ID_WMV2;
			break;
		case 1:
			codec_id = CODEC_ID_WMV1;
			break;
		default:
			codec_id = CODEC_ID_NONE;
			break;
		}

	}
	else
		codec_id = CODEC_ID_NONE;

	self->codec = avcodec_find_decoder(codec_id);
	if (!self->codec)
		return false;

	switch (codec_id) {
	case CODEC_ID_H263:
		self->parse_func = gst_av_h263_parse;
		break;
	case CODEC_ID_H264:
		self->parse_func = gst_av_h264_parse;
		break;
	case CODEC_ID_MPEG4:
		self->parse_func = gst_av_mpeg4_parse;
		break;
	}

	self->av_ctx = ctx = avcodec_alloc_context3(self->codec);

	ctx->get_buffer = get_buffer;
	ctx->release_buffer = release_buffer;
	ctx->reget_buffer = reget_buffer;
	ctx->opaque = self;
	ctx->flags |= CODEC_FLAG_EMU_EDGE;

	gst_structure_get_int(in_struc, "width", &ctx->width);
	gst_structure_get_int(in_struc, "height", &ctx->height);

	gst_structure_get_fraction(in_struc, "pixel-aspect-ratio",
			&ctx->sample_aspect_ratio.num, &ctx->sample_aspect_ratio.den);

	gst_structure_get_fraction(in_struc, "framerate",
			&ctx->time_base.den, &ctx->time_base.num);

	/* bug in xvimagesink? */
	if (!ctx->time_base.num)
		ctx->time_base = (AVRational){ 1, 0 };

	if (codec_id == CODEC_ID_THEORA) {
		get_theora_extradata(ctx, in_struc);
		goto next;
	}

	codec_data = gst_structure_get_value(in_struc, "codec_data");
	if (!codec_data)
		goto next;
	buf = gst_value_get_buffer(codec_data);
	if (!buf)
		goto next;
	ctx->extradata = av_malloc(buf->size + FF_INPUT_BUFFER_PADDING_SIZE);
	memcpy(ctx->extradata, buf->data, buf->size);
	memset(ctx->extradata + buf->size, 0, FF_INPUT_BUFFER_PADDING_SIZE);
	ctx->extradata_size = buf->size;

	if (self->parse_func)
		self->parse_func(self, buf);

next:
	return true;
}