mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-06-06 07:28:53 +00:00
Add gst_vaapi_decoder_ffmpeg_new_from_caps() helper.
This commit is contained in:
parent
fa7505c0c5
commit
477e3b8530
6 changed files with 110 additions and 27 deletions
|
@ -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();
|
||||||
|
|
|
@ -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);
|
||||||
|
}
|
||||||
|
|
|
@ -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 */
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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(
|
||||||
|
|
|
@ -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;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue