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_DISPLAY,
PROP_CODEC, PROP_CODEC,
PROP_CODEC_DATA PROP_CODEC_DATA,
PROP_WIDTH,
PROP_HEIGHT,
}; };
static inline void static inline void
@ -285,6 +287,12 @@ gst_vaapi_decoder_set_property(
case PROP_CODEC_DATA: case PROP_CODEC_DATA:
set_codec_data(GST_VAAPI_DECODER(object), gst_value_get_buffer(value)); set_codec_data(GST_VAAPI_DECODER(object), gst_value_get_buffer(value));
break; break;
case PROP_WIDTH:
priv->width = g_value_get_uint(value);
break;
case PROP_HEIGHT:
priv->height = g_value_get_uint(value);
break;
default: default:
G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
break; break;
@ -311,6 +319,12 @@ gst_vaapi_decoder_get_property(
case PROP_CODEC_DATA: case PROP_CODEC_DATA:
gst_value_set_buffer(value, priv->codec_data); gst_value_set_buffer(value, priv->codec_data);
break; break;
case PROP_WIDTH:
g_value_set_uint(value, priv->width);
break;
case PROP_HEIGHT:
g_value_set_uint(value, priv->height);
break;
default: default:
G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
break; break;
@ -359,6 +373,24 @@ gst_vaapi_decoder_class_init(GstVaapiDecoderClass *klass)
"Extra codec data", "Extra codec data",
GST_TYPE_BUFFER, GST_TYPE_BUFFER,
G_PARAM_WRITABLE|G_PARAM_CONSTRUCT_ONLY)); 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 static void
@ -370,6 +402,8 @@ gst_vaapi_decoder_init(GstVaapiDecoder *decoder)
priv->context = NULL; priv->context = NULL;
priv->codec = 0; priv->codec = 0;
priv->codec_data = NULL; priv->codec_data = NULL;
priv->width = 0;
priv->height = 0;
priv->fps_n = 1000; priv->fps_n = 1000;
priv->fps_d = 30; priv->fps_d = 30;
priv->buffers = g_queue_new(); priv->buffers = g_queue_new();

View file

@ -608,3 +608,59 @@ gst_vaapi_decoder_ffmpeg_new(
"codec-data", codec_data, "codec-data", codec_data,
NULL); 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 GstBuffer *codec_data
); );
GstVaapiDecoder *
gst_vaapi_decoder_ffmpeg_new_from_caps(GstVaapiDisplay *display, GstCaps *caps);
G_END_DECLS G_END_DECLS
#endif /* GST_VAAPI_DECODER_FFMPEG_H */ #endif /* GST_VAAPI_DECODER_FFMPEG_H */

View file

@ -92,6 +92,8 @@ struct _GstVaapiDecoderPrivate {
GstVaapiContext *context; GstVaapiContext *context;
GstVaapiCodec codec; GstVaapiCodec codec;
GstBuffer *codec_data; GstBuffer *codec_data;
guint width;
guint height;
guint fps_n; guint fps_n;
guint fps_d; guint fps_d;
GQueue *buffers; GQueue *buffers;

View file

@ -162,7 +162,6 @@ gst_vaapidecode_create(GstVaapiDecode *decode)
{ {
GstVaapiVideoSink *sink; GstVaapiVideoSink *sink;
GstVaapiDisplay *display; GstVaapiDisplay *display;
GstVaapiCodec codec;
/* Look for a downstream vaapisink */ /* Look for a downstream vaapisink */
sink = gst_vaapi_video_sink_lookup(GST_ELEMENT(decode)); sink = gst_vaapi_video_sink_lookup(GST_ELEMENT(decode));
@ -175,30 +174,26 @@ gst_vaapidecode_create(GstVaapiDecode *decode)
decode->display = g_object_ref(display); decode->display = g_object_ref(display);
codec = gst_vaapi_profile_get_codec(decode->profile);
if (!codec)
return FALSE;
if (decode->use_ffmpeg) if (decode->use_ffmpeg)
decode->decoder = 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; return decode->decoder != NULL;
} }
static void static void
gst_vaapidecode_destroy(GstVaapiDecode *decode) gst_vaapidecode_destroy(GstVaapiDecode *decode)
{ {
if (decode->decoder_caps) {
gst_caps_unref(decode->decoder_caps);
decode->decoder_caps = NULL;
}
if (decode->decoder) { if (decode->decoder) {
gst_vaapi_decoder_put_buffer(decode->decoder, NULL); gst_vaapi_decoder_put_buffer(decode->decoder, NULL);
g_object_unref(decode->decoder); g_object_unref(decode->decoder);
decode->decoder = NULL; decode->decoder = NULL;
} }
if (decode->codec_data) {
gst_buffer_unref(decode->codec_data);
decode->codec_data = NULL;
}
if (decode->display) { if (decode->display) {
g_object_unref(decode->display); g_object_unref(decode->display);
decode->display = NULL; decode->display = NULL;
@ -331,7 +326,7 @@ gst_vaapidecode_set_caps(GstPad *pad, GstCaps *caps)
GstPad *other_pad; GstPad *other_pad;
GstCaps *other_caps = NULL; GstCaps *other_caps = NULL;
GstStructure *structure; 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) { if (pad == decode->sinkpad) {
other_pad = decode->srcpad; 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_height = gst_structure_get_value(structure, "height");
v_framerate = gst_structure_get_value(structure, "framerate"); v_framerate = gst_structure_get_value(structure, "framerate");
v_par = gst_structure_get_value(structure, "pixel-aspect-ratio"); v_par = gst_structure_get_value(structure, "pixel-aspect-ratio");
v_codec_data = gst_structure_get_value(structure, "codec_data");
if (pad == decode->sinkpad) { if (pad == decode->sinkpad)
decode->profile = gst_vaapi_profile_from_caps(caps); decode->decoder_caps = gst_caps_ref(caps);
if (v_codec_data)
decode->codec_data =
gst_buffer_ref(gst_value_get_buffer(v_codec_data));
}
structure = gst_caps_get_structure(other_caps, 0); structure = gst_caps_get_structure(other_caps, 0);
gst_structure_set_value(structure, "width", v_width); 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); GstElementClass * const element_class = GST_ELEMENT_CLASS(klass);
decode->display = NULL; decode->display = NULL;
decode->profile = 0; decode->decoder = NULL;
decode->codec_data = NULL; decode->decoder_caps = NULL;
decode->decoder = NULL; decode->use_ffmpeg = TRUE;
decode->use_ffmpeg = TRUE;
/* Pad through which data comes in to the element */ /* Pad through which data comes in to the element */
decode->sinkpad = gst_pad_new_from_template( decode->sinkpad = gst_pad_new_from_template(

View file

@ -62,9 +62,8 @@ struct _GstVaapiDecode {
GstPad *sinkpad; GstPad *sinkpad;
GstPad *srcpad; GstPad *srcpad;
GstVaapiDisplay *display; GstVaapiDisplay *display;
GstVaapiProfile profile;
GstBuffer *codec_data;
GstVaapiDecoder *decoder; GstVaapiDecoder *decoder;
GstCaps *decoder_caps;
unsigned int use_ffmpeg : 1; unsigned int use_ffmpeg : 1;
}; };