diff --git a/docs/reference/libs/libs-sections.txt b/docs/reference/libs/libs-sections.txt
index 3db23a75a8..a37b4579e2 100644
--- a/docs/reference/libs/libs-sections.txt
+++ b/docs/reference/libs/libs-sections.txt
@@ -452,6 +452,7 @@ GstVaapiDecoderStatus
GstVaapiDecoder
GstVaapiDecoder
GstVaapiDecoderClass
+gst_vaapi_decoder_get_caps
gst_vaapi_decoder_put_buffer
gst_vaapi_decoder_get_surface
diff --git a/gst-libs/gst/vaapi/gstvaapidecoder.c b/gst-libs/gst/vaapi/gstvaapidecoder.c
index 7fb4e86b73..4fe84cbe7c 100644
--- a/gst-libs/gst/vaapi/gstvaapidecoder.c
+++ b/gst-libs/gst/vaapi/gstvaapidecoder.c
@@ -183,6 +183,8 @@ set_caps(GstVaapiDecoder *decoder, GstCaps *caps)
if (!profile)
return;
+ priv->caps = gst_caps_copy(caps);
+
priv->codec = gst_vaapi_profile_get_codec(profile);
if (!priv->codec)
return;
@@ -197,6 +199,11 @@ set_caps(GstVaapiDecoder *decoder, GstCaps *caps)
priv->fps_d = v2;
}
+ if (gst_structure_get_fraction(structure, "pixel-aspect-ratio", &v1, &v2)) {
+ priv->par_n = v1;
+ priv->par_d = v2;
+ }
+
v_codec_data = gst_structure_get_value(structure, "codec_data");
if (v_codec_data)
set_codec_data(decoder, gst_value_get_buffer(v_codec_data));
@@ -217,6 +224,11 @@ gst_vaapi_decoder_finalize(GObject *object)
set_codec_data(decoder, NULL);
+ if (priv->caps) {
+ gst_caps_unref(priv->caps);
+ priv->caps = NULL;
+ }
+
if (priv->context) {
g_object_unref(priv->context);
priv->context = NULL;
@@ -280,6 +292,9 @@ gst_vaapi_decoder_get_property(
case PROP_DISPLAY:
g_value_set_object(value, priv->display);
break;
+ case PROP_CAPS:
+ gst_value_set_caps(value, priv->caps);
+ break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
break;
@@ -317,7 +332,7 @@ gst_vaapi_decoder_class_init(GstVaapiDecoderClass *klass)
g_param_spec_pointer("caps",
"Decoder caps",
"The decoder caps",
- G_PARAM_WRITABLE|G_PARAM_CONSTRUCT_ONLY));
+ G_PARAM_READWRITE|G_PARAM_CONSTRUCT_ONLY));
}
static void
@@ -327,16 +342,34 @@ gst_vaapi_decoder_init(GstVaapiDecoder *decoder)
decoder->priv = priv;
priv->context = NULL;
+ priv->caps = NULL;
priv->codec = 0;
priv->codec_data = NULL;
priv->width = 0;
priv->height = 0;
- priv->fps_n = 1000;
- priv->fps_d = 30;
+ priv->fps_n = 0;
+ priv->fps_d = 0;
+ priv->par_n = 0;
+ priv->par_d = 0;
priv->buffers = g_queue_new();
priv->surfaces = g_queue_new();
}
+/**
+ * gst_vaapi_decoder_get_caps:
+ * @decoder: a #GstVaapiDecoder
+ *
+ * Retrieves the @decoder caps. The deocder owns the returned caps, so
+ * use gst_caps_ref() whenever necessary.
+ *
+ * Return value: the @decoder caps
+ */
+GstCaps *
+gst_vaapi_decoder_get_caps(GstVaapiDecoder *decoder)
+{
+ return decoder->priv->caps;
+}
+
/**
* gst_vaapi_decoder_put_buffer:
* @decoder: a #GstVaapiDecoder
@@ -399,6 +432,84 @@ gst_vaapi_decoder_get_surface(
return proxy;
}
+void
+gst_vaapi_decoder_set_picture_size(
+ GstVaapiDecoder *decoder,
+ guint width,
+ guint height
+)
+{
+ GstVaapiDecoderPrivate * const priv = decoder->priv;
+
+ g_object_freeze_notify(G_OBJECT(decoder));
+
+ if (priv->width != width) {
+ GST_DEBUG("picture width changed to %d", width);
+ priv->width = width;
+ gst_caps_set_simple(priv->caps, "width", G_TYPE_INT, width, NULL);
+ g_object_notify(G_OBJECT(decoder), "caps");
+ }
+
+ if (priv->height != height) {
+ GST_DEBUG("picture height changed to %d", height);
+ priv->height = height;
+ gst_caps_set_simple(priv->caps, "height", G_TYPE_INT, height, NULL);
+ g_object_notify(G_OBJECT(decoder), "caps");
+ }
+
+ g_object_thaw_notify(G_OBJECT(decoder));
+}
+
+void
+gst_vaapi_decoder_set_framerate(
+ GstVaapiDecoder *decoder,
+ guint fps_n,
+ guint fps_d
+)
+{
+ GstVaapiDecoderPrivate * const priv = decoder->priv;
+
+ if (!fps_n || !fps_d)
+ return;
+
+ if (priv->fps_n != fps_n || priv->fps_d != fps_d) {
+ GST_DEBUG("framerate changed to %u/%u", fps_n, fps_d);
+ priv->fps_n = fps_n;
+ priv->fps_d = fps_d;
+ gst_caps_set_simple(
+ priv->caps,
+ "framerate", GST_TYPE_FRACTION, fps_n, fps_d,
+ NULL
+ );
+ g_object_notify(G_OBJECT(decoder), "caps");
+ }
+}
+
+void
+gst_vaapi_decoder_set_pixel_aspect_ratio(
+ GstVaapiDecoder *decoder,
+ guint par_n,
+ guint par_d
+)
+{
+ GstVaapiDecoderPrivate * const priv = decoder->priv;
+
+ if (!par_n || !par_d)
+ return;
+
+ if (priv->par_n != par_n || priv->par_d != par_d) {
+ GST_DEBUG("pixel-aspect-ratio changed to %u/%u", par_n, par_d);
+ priv->par_n = par_n;
+ priv->par_d = par_d;
+ gst_caps_set_simple(
+ priv->caps,
+ "pixel-aspect-ratio", GST_TYPE_FRACTION, par_n, par_d,
+ NULL
+ );
+ g_object_notify(G_OBJECT(decoder), "caps");
+ }
+}
+
gboolean
gst_vaapi_decoder_ensure_context(
GstVaapiDecoder *decoder,
@@ -410,6 +521,8 @@ gst_vaapi_decoder_ensure_context(
{
GstVaapiDecoderPrivate * const priv = decoder->priv;
+ gst_vaapi_decoder_set_picture_size(decoder, width, height);
+
if (priv->context)
return gst_vaapi_context_reset(priv->context,
profile, entrypoint, width, height);
diff --git a/gst-libs/gst/vaapi/gstvaapidecoder.h b/gst-libs/gst/vaapi/gstvaapidecoder.h
index 53a54d3a51..f7210d3311 100644
--- a/gst-libs/gst/vaapi/gstvaapidecoder.h
+++ b/gst-libs/gst/vaapi/gstvaapidecoder.h
@@ -110,6 +110,9 @@ struct _GstVaapiDecoderClass {
GType
gst_vaapi_decoder_get_type(void);
+GstCaps *
+gst_vaapi_decoder_get_caps(GstVaapiDecoder *decoder);
+
gboolean
gst_vaapi_decoder_put_buffer(GstVaapiDecoder *decoder, GstBuffer *buf);
diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_ffmpeg.c b/gst-libs/gst/vaapi/gstvaapidecoder_ffmpeg.c
index 5537ea30f9..b94a02a86d 100644
--- a/gst-libs/gst/vaapi/gstvaapidecoder_ffmpeg.c
+++ b/gst-libs/gst/vaapi/gstvaapidecoder_ffmpeg.c
@@ -167,6 +167,18 @@ get_context(AVCodecContext *avctx)
if (!avctx->coded_width || !avctx->coded_height)
return NULL;
+ gst_vaapi_decoder_set_framerate(
+ decoder,
+ avctx->time_base.den / avctx->ticks_per_frame,
+ avctx->time_base.num
+ );
+
+ gst_vaapi_decoder_set_pixel_aspect_ratio(
+ decoder,
+ avctx->sample_aspect_ratio.num,
+ avctx->sample_aspect_ratio.den
+ );
+
success = gst_vaapi_decoder_ensure_context(
decoder,
vactx->profile,
diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_priv.h b/gst-libs/gst/vaapi/gstvaapidecoder_priv.h
index 2dd028508c..546d93b8e6 100644
--- a/gst-libs/gst/vaapi/gstvaapidecoder_priv.h
+++ b/gst-libs/gst/vaapi/gstvaapidecoder_priv.h
@@ -112,16 +112,40 @@ G_BEGIN_DECLS
struct _GstVaapiDecoderPrivate {
GstVaapiDisplay *display;
GstVaapiContext *context;
+ GstCaps *caps;
GstVaapiCodec codec;
GstBuffer *codec_data;
guint width;
guint height;
guint fps_n;
guint fps_d;
+ guint par_n;
+ guint par_d;
GQueue *buffers;
GQueue *surfaces;
};
+void
+gst_vaapi_decoder_set_picture_size(
+ GstVaapiDecoder *decoder,
+ guint width,
+ guint height
+) attribute_hidden;
+
+void
+gst_vaapi_decoder_set_framerate(
+ GstVaapiDecoder *decoder,
+ guint fps_n,
+ guint fps_d
+) attribute_hidden;
+
+void
+gst_vaapi_decoder_set_pixel_aspect_ratio(
+ GstVaapiDecoder *decoder,
+ guint par_n,
+ guint par_d
+) attribute_hidden;
+
gboolean
gst_vaapi_decoder_ensure_context(
GstVaapiDecoder *decoder,
@@ -149,4 +173,3 @@ gst_vaapi_decoder_push_surface(
G_END_DECLS
#endif /* GST_VAAPI_DECODER_PRIV_H */
-