PROP_DISPLAY,
PROP_CODEC,
- PROP_CODEC_DATA
+ PROP_CODEC_DATA,
+ PROP_WIDTH,
+ PROP_HEIGHT,
};
static inline void
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;
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;
"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
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();
"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);
+}
GstBuffer *codec_data
);
+GstVaapiDecoder *
+gst_vaapi_decoder_ffmpeg_new_from_caps(GstVaapiDisplay *display, GstCaps *caps);
+
G_END_DECLS
#endif /* GST_VAAPI_DECODER_FFMPEG_H */
GstVaapiContext *context;
GstVaapiCodec codec;
GstBuffer *codec_data;
+ guint width;
+ guint height;
guint fps_n;
guint fps_d;
GQueue *buffers;
{
GstVaapiVideoSink *sink;
GstVaapiDisplay *display;
- GstVaapiCodec codec;
/* Look for a downstream vaapisink */
sink = gst_vaapi_video_sink_lookup(GST_ELEMENT(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;
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;
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);
{
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(
GstPad *sinkpad;
GstPad *srcpad;
GstVaapiDisplay *display;
- GstVaapiProfile profile;
- GstBuffer *codec_data;
GstVaapiDecoder *decoder;
+ GstCaps *decoder_caps;
unsigned int use_ffmpeg : 1;
};