Regularly update and expose decoder caps.

This commit is contained in:
gb 2010-05-15 15:33:20 +00:00 committed by Gwenole Beauchesne
parent a777a98f2f
commit 86d0b2ade9
5 changed files with 156 additions and 4 deletions

View file

@ -452,6 +452,7 @@ GstVaapiDecoderStatus
<TITLE>GstVaapiDecoder</TITLE> <TITLE>GstVaapiDecoder</TITLE>
GstVaapiDecoder GstVaapiDecoder
GstVaapiDecoderClass GstVaapiDecoderClass
gst_vaapi_decoder_get_caps
gst_vaapi_decoder_put_buffer gst_vaapi_decoder_put_buffer
gst_vaapi_decoder_get_surface gst_vaapi_decoder_get_surface
<SUBSECTION Standard> <SUBSECTION Standard>

View file

@ -183,6 +183,8 @@ set_caps(GstVaapiDecoder *decoder, GstCaps *caps)
if (!profile) if (!profile)
return; return;
priv->caps = gst_caps_copy(caps);
priv->codec = gst_vaapi_profile_get_codec(profile); priv->codec = gst_vaapi_profile_get_codec(profile);
if (!priv->codec) if (!priv->codec)
return; return;
@ -197,6 +199,11 @@ set_caps(GstVaapiDecoder *decoder, GstCaps *caps)
priv->fps_d = v2; 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"); v_codec_data = gst_structure_get_value(structure, "codec_data");
if (v_codec_data) if (v_codec_data)
set_codec_data(decoder, gst_value_get_buffer(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); set_codec_data(decoder, NULL);
if (priv->caps) {
gst_caps_unref(priv->caps);
priv->caps = NULL;
}
if (priv->context) { if (priv->context) {
g_object_unref(priv->context); g_object_unref(priv->context);
priv->context = NULL; priv->context = NULL;
@ -280,6 +292,9 @@ gst_vaapi_decoder_get_property(
case PROP_DISPLAY: case PROP_DISPLAY:
g_value_set_object(value, priv->display); g_value_set_object(value, priv->display);
break; break;
case PROP_CAPS:
gst_value_set_caps(value, priv->caps);
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;
@ -317,7 +332,7 @@ gst_vaapi_decoder_class_init(GstVaapiDecoderClass *klass)
g_param_spec_pointer("caps", g_param_spec_pointer("caps",
"Decoder caps", "Decoder caps",
"The decoder caps", "The decoder caps",
G_PARAM_WRITABLE|G_PARAM_CONSTRUCT_ONLY)); G_PARAM_READWRITE|G_PARAM_CONSTRUCT_ONLY));
} }
static void static void
@ -327,16 +342,34 @@ gst_vaapi_decoder_init(GstVaapiDecoder *decoder)
decoder->priv = priv; decoder->priv = priv;
priv->context = NULL; priv->context = NULL;
priv->caps = NULL;
priv->codec = 0; priv->codec = 0;
priv->codec_data = NULL; priv->codec_data = NULL;
priv->width = 0; priv->width = 0;
priv->height = 0; priv->height = 0;
priv->fps_n = 1000; priv->fps_n = 0;
priv->fps_d = 30; priv->fps_d = 0;
priv->par_n = 0;
priv->par_d = 0;
priv->buffers = g_queue_new(); priv->buffers = g_queue_new();
priv->surfaces = 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: * gst_vaapi_decoder_put_buffer:
* @decoder: a #GstVaapiDecoder * @decoder: a #GstVaapiDecoder
@ -399,6 +432,84 @@ gst_vaapi_decoder_get_surface(
return proxy; 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 gboolean
gst_vaapi_decoder_ensure_context( gst_vaapi_decoder_ensure_context(
GstVaapiDecoder *decoder, GstVaapiDecoder *decoder,
@ -410,6 +521,8 @@ gst_vaapi_decoder_ensure_context(
{ {
GstVaapiDecoderPrivate * const priv = decoder->priv; GstVaapiDecoderPrivate * const priv = decoder->priv;
gst_vaapi_decoder_set_picture_size(decoder, width, height);
if (priv->context) if (priv->context)
return gst_vaapi_context_reset(priv->context, return gst_vaapi_context_reset(priv->context,
profile, entrypoint, width, height); profile, entrypoint, width, height);

View file

@ -110,6 +110,9 @@ struct _GstVaapiDecoderClass {
GType GType
gst_vaapi_decoder_get_type(void); gst_vaapi_decoder_get_type(void);
GstCaps *
gst_vaapi_decoder_get_caps(GstVaapiDecoder *decoder);
gboolean gboolean
gst_vaapi_decoder_put_buffer(GstVaapiDecoder *decoder, GstBuffer *buf); gst_vaapi_decoder_put_buffer(GstVaapiDecoder *decoder, GstBuffer *buf);

View file

@ -167,6 +167,18 @@ get_context(AVCodecContext *avctx)
if (!avctx->coded_width || !avctx->coded_height) if (!avctx->coded_width || !avctx->coded_height)
return NULL; 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( success = gst_vaapi_decoder_ensure_context(
decoder, decoder,
vactx->profile, vactx->profile,

View file

@ -112,16 +112,40 @@ G_BEGIN_DECLS
struct _GstVaapiDecoderPrivate { struct _GstVaapiDecoderPrivate {
GstVaapiDisplay *display; GstVaapiDisplay *display;
GstVaapiContext *context; GstVaapiContext *context;
GstCaps *caps;
GstVaapiCodec codec; GstVaapiCodec codec;
GstBuffer *codec_data; GstBuffer *codec_data;
guint width; guint width;
guint height; guint height;
guint fps_n; guint fps_n;
guint fps_d; guint fps_d;
guint par_n;
guint par_d;
GQueue *buffers; GQueue *buffers;
GQueue *surfaces; 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 gboolean
gst_vaapi_decoder_ensure_context( gst_vaapi_decoder_ensure_context(
GstVaapiDecoder *decoder, GstVaapiDecoder *decoder,
@ -149,4 +173,3 @@ gst_vaapi_decoder_push_surface(
G_END_DECLS G_END_DECLS
#endif /* GST_VAAPI_DECODER_PRIV_H */ #endif /* GST_VAAPI_DECODER_PRIV_H */