From 477e3b8530dba722de198564d2edba40e679408c Mon Sep 17 00:00:00 2001 From: gb Date: Mon, 3 May 2010 15:11:32 +0000 Subject: [PATCH] Add gst_vaapi_decoder_ffmpeg_new_from_caps() helper. --- gst-libs/gst/vaapi/gstvaapidecoder.c | 36 ++++++++++++++++++- gst-libs/gst/vaapi/gstvaapidecoder_ffmpeg.c | 56 +++++++++++++++++++++++++++++ gst-libs/gst/vaapi/gstvaapidecoder_ffmpeg.h | 3 ++ gst-libs/gst/vaapi/gstvaapidecoder_priv.h | 2 ++ gst/vaapidecode/gstvaapidecode.c | 37 +++++++------------ gst/vaapidecode/gstvaapidecode.h | 3 +- 6 files changed, 110 insertions(+), 27 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder.c b/gst-libs/gst/vaapi/gstvaapidecoder.c index 326cbf8..9f44130 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder.c @@ -50,7 +50,9 @@ enum { PROP_DISPLAY, PROP_CODEC, - PROP_CODEC_DATA + PROP_CODEC_DATA, + PROP_WIDTH, + PROP_HEIGHT, }; static inline void @@ -285,6 +287,12 @@ gst_vaapi_decoder_set_property( case PROP_CODEC_DATA: set_codec_data(GST_VAAPI_DECODER(object), gst_value_get_buffer(value)); break; + case PROP_WIDTH: + priv->width = g_value_get_uint(value); + break; + case PROP_HEIGHT: + priv->height = g_value_get_uint(value); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); break; @@ -311,6 +319,12 @@ gst_vaapi_decoder_get_property( case PROP_CODEC_DATA: gst_value_set_buffer(value, priv->codec_data); break; + case PROP_WIDTH: + g_value_set_uint(value, priv->width); + break; + case PROP_HEIGHT: + g_value_set_uint(value, priv->height); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); break; @@ -359,6 +373,24 @@ gst_vaapi_decoder_class_init(GstVaapiDecoderClass *klass) "Extra codec data", GST_TYPE_BUFFER, G_PARAM_WRITABLE|G_PARAM_CONSTRUCT_ONLY)); + + g_object_class_install_property + (object_class, + PROP_WIDTH, + g_param_spec_uint("width", + "Width", + "The coded width of the picture", + 0, G_MAXINT32, 0, + G_PARAM_READWRITE|G_PARAM_CONSTRUCT_ONLY)); + + g_object_class_install_property + (object_class, + PROP_HEIGHT, + g_param_spec_uint("height", + "Height", + "The coded height of the picture", + 0, G_MAXINT32, 0, + G_PARAM_READWRITE|G_PARAM_CONSTRUCT_ONLY)); } static void @@ -370,6 +402,8 @@ gst_vaapi_decoder_init(GstVaapiDecoder *decoder) priv->context = NULL; priv->codec = 0; priv->codec_data = NULL; + priv->width = 0; + priv->height = 0; priv->fps_n = 1000; priv->fps_d = 30; priv->buffers = g_queue_new(); diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_ffmpeg.c b/gst-libs/gst/vaapi/gstvaapidecoder_ffmpeg.c index 03b5533..44e99da 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_ffmpeg.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_ffmpeg.c @@ -608,3 +608,59 @@ gst_vaapi_decoder_ffmpeg_new( "codec-data", codec_data, NULL); } + +/** + * st_vaapi_decoder_ffmpeg_new_from_caps: + * @display: a #GstVaapiDisplay + * @caps: a #GstCaps holding codec information + * + * Creates a new #GstVaapiDecoder whose codec is determined from + * @caps. The @caps can hold extra information like codec-data and + * size. + * + * Return value: the newly allocated #GstVaapiDecoder object + */ +GstVaapiDecoder * +gst_vaapi_decoder_ffmpeg_new_from_caps(GstVaapiDisplay *display, GstCaps *caps) +{ + GstStructure *structure; + GstVaapiProfile profile; + GstVaapiCodec codec; + const GValue *v_codec_data; + GstBuffer *codec_data; + gint width, height; + + g_return_val_if_fail(GST_VAAPI_IS_DISPLAY(display), NULL); + g_return_val_if_fail(GST_IS_CAPS(caps), NULL); + + structure = gst_caps_get_structure(caps, 0); + if (!structure) + return NULL; + + profile = gst_vaapi_profile_from_caps(caps); + if (!profile) + return NULL; + + codec = gst_vaapi_profile_get_codec(profile); + if (!codec) + return NULL; + + if (!gst_structure_get_int(structure, "width", &width)) + width = 0; + if (!gst_structure_get_int(structure, "height", &height)) + height = 0; + + v_codec_data = gst_structure_get_value(structure, "codec_data"); + if (v_codec_data) + codec_data = gst_value_get_buffer(v_codec_data); + else + codec_data = NULL; + + return g_object_new(GST_VAAPI_TYPE_DECODER_FFMPEG, + "display", display, + "codec", codec, + "codec-data", codec_data, + "width", width, + "height", height, + NULL); +} diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_ffmpeg.h b/gst-libs/gst/vaapi/gstvaapidecoder_ffmpeg.h index 015ba2f..acf5bf3 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_ffmpeg.h +++ b/gst-libs/gst/vaapi/gstvaapidecoder_ffmpeg.h @@ -86,6 +86,9 @@ gst_vaapi_decoder_ffmpeg_new( GstBuffer *codec_data ); +GstVaapiDecoder * +gst_vaapi_decoder_ffmpeg_new_from_caps(GstVaapiDisplay *display, GstCaps *caps); + G_END_DECLS #endif /* GST_VAAPI_DECODER_FFMPEG_H */ diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_priv.h b/gst-libs/gst/vaapi/gstvaapidecoder_priv.h index 1b4a616..183c499 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_priv.h +++ b/gst-libs/gst/vaapi/gstvaapidecoder_priv.h @@ -92,6 +92,8 @@ struct _GstVaapiDecoderPrivate { GstVaapiContext *context; GstVaapiCodec codec; GstBuffer *codec_data; + guint width; + guint height; guint fps_n; guint fps_d; GQueue *buffers; diff --git a/gst/vaapidecode/gstvaapidecode.c b/gst/vaapidecode/gstvaapidecode.c index 4449b34..ab29f42 100644 --- a/gst/vaapidecode/gstvaapidecode.c +++ b/gst/vaapidecode/gstvaapidecode.c @@ -162,7 +162,6 @@ gst_vaapidecode_create(GstVaapiDecode *decode) { GstVaapiVideoSink *sink; GstVaapiDisplay *display; - GstVaapiCodec codec; /* Look for a downstream vaapisink */ sink = gst_vaapi_video_sink_lookup(GST_ELEMENT(decode)); @@ -175,30 +174,26 @@ gst_vaapidecode_create(GstVaapiDecode *decode) decode->display = g_object_ref(display); - codec = gst_vaapi_profile_get_codec(decode->profile); - if (!codec) - return FALSE; - if (decode->use_ffmpeg) decode->decoder = - gst_vaapi_decoder_ffmpeg_new(display, codec, decode->codec_data); + gst_vaapi_decoder_ffmpeg_new_from_caps(display, decode->decoder_caps); return decode->decoder != NULL; } static void gst_vaapidecode_destroy(GstVaapiDecode *decode) { + if (decode->decoder_caps) { + gst_caps_unref(decode->decoder_caps); + decode->decoder_caps = NULL; + } + if (decode->decoder) { gst_vaapi_decoder_put_buffer(decode->decoder, NULL); g_object_unref(decode->decoder); decode->decoder = NULL; } - if (decode->codec_data) { - gst_buffer_unref(decode->codec_data); - decode->codec_data = NULL; - } - if (decode->display) { g_object_unref(decode->display); decode->display = NULL; @@ -331,7 +326,7 @@ gst_vaapidecode_set_caps(GstPad *pad, GstCaps *caps) GstPad *other_pad; GstCaps *other_caps = NULL; GstStructure *structure; - const GValue *v_width, *v_height, *v_framerate, *v_par, *v_codec_data; + const GValue *v_width, *v_height, *v_framerate, *v_par; if (pad == decode->sinkpad) { other_pad = decode->srcpad; @@ -348,14 +343,9 @@ gst_vaapidecode_set_caps(GstPad *pad, GstCaps *caps) v_height = gst_structure_get_value(structure, "height"); v_framerate = gst_structure_get_value(structure, "framerate"); v_par = gst_structure_get_value(structure, "pixel-aspect-ratio"); - v_codec_data = gst_structure_get_value(structure, "codec_data"); - if (pad == decode->sinkpad) { - decode->profile = gst_vaapi_profile_from_caps(caps); - if (v_codec_data) - decode->codec_data = - gst_buffer_ref(gst_value_get_buffer(v_codec_data)); - } + if (pad == decode->sinkpad) + decode->decoder_caps = gst_caps_ref(caps); structure = gst_caps_get_structure(other_caps, 0); gst_structure_set_value(structure, "width", v_width); @@ -426,11 +416,10 @@ gst_vaapidecode_init(GstVaapiDecode *decode, GstVaapiDecodeClass *klass) { GstElementClass * const element_class = GST_ELEMENT_CLASS(klass); - decode->display = NULL; - decode->profile = 0; - decode->codec_data = NULL; - decode->decoder = NULL; - decode->use_ffmpeg = TRUE; + decode->display = NULL; + decode->decoder = NULL; + decode->decoder_caps = NULL; + decode->use_ffmpeg = TRUE; /* Pad through which data comes in to the element */ decode->sinkpad = gst_pad_new_from_template( diff --git a/gst/vaapidecode/gstvaapidecode.h b/gst/vaapidecode/gstvaapidecode.h index b2b6915..068f198 100644 --- a/gst/vaapidecode/gstvaapidecode.h +++ b/gst/vaapidecode/gstvaapidecode.h @@ -62,9 +62,8 @@ struct _GstVaapiDecode { GstPad *sinkpad; GstPad *srcpad; GstVaapiDisplay *display; - GstVaapiProfile profile; - GstBuffer *codec_data; GstVaapiDecoder *decoder; + GstCaps *decoder_caps; unsigned int use_ffmpeg : 1; }; -- 2.7.4