Add gst_vaapi_decoder_ffmpeg_new_from_caps() helper.

This commit is contained in:
gb 2010-05-03 15:11:32 +00:00 committed by Gwenole Beauchesne
parent fa7505c0c5
commit 477e3b8530
6 changed files with 110 additions and 27 deletions

View file

@ -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();

View file

@ -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);
}

View file

@ -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 */

View file

@ -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;

View file

@ -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(

View file

@ -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;
};