mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-01-13 02:45:35 +00:00
Make sure gst_vaapi_decoder_get_surface() gets unblocked on error.
This commit is contained in:
parent
1def875b95
commit
1c48fa3a23
1 changed files with 74 additions and 27 deletions
|
@ -37,6 +37,13 @@
|
||||||
|
|
||||||
G_DEFINE_TYPE(GstVaapiDecoder, gst_vaapi_decoder, G_TYPE_OBJECT);
|
G_DEFINE_TYPE(GstVaapiDecoder, gst_vaapi_decoder, G_TYPE_OBJECT);
|
||||||
|
|
||||||
|
/* XXX: Make it a GstVaapiDecodedSurface + propagate PTS */
|
||||||
|
typedef struct _DecodedSurface DecodedSurface;
|
||||||
|
struct _DecodedSurface {
|
||||||
|
GstVaapiSurfaceProxy *proxy;
|
||||||
|
GstVaapiDecoderStatus status;
|
||||||
|
};
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
PROP_0,
|
PROP_0,
|
||||||
|
|
||||||
|
@ -54,6 +61,12 @@ gst_vaapi_decoder_stop(GstVaapiDecoder *decoder);
|
||||||
static GstBuffer *
|
static GstBuffer *
|
||||||
pop_buffer(GstVaapiDecoder *decoder);
|
pop_buffer(GstVaapiDecoder *decoder);
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
push_surface(GstVaapiDecoder *decoder, GstVaapiSurface *surface);
|
||||||
|
|
||||||
|
static DecodedSurface *
|
||||||
|
pop_surface(GstVaapiDecoder *decoder, GTimeVal *end_time);
|
||||||
|
|
||||||
static gpointer
|
static gpointer
|
||||||
decoder_thread_cb(gpointer data)
|
decoder_thread_cb(gpointer data)
|
||||||
{
|
{
|
||||||
|
@ -72,6 +85,8 @@ decoder_thread_cb(gpointer data)
|
||||||
case GST_VAAPI_DECODER_STATUS_ERROR_NO_DATA:
|
case GST_VAAPI_DECODER_STATUS_ERROR_NO_DATA:
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
/* Send an empty surface to signal an error */
|
||||||
|
push_surface(decoder, NULL);
|
||||||
priv->decoder_thread_cancel = TRUE;
|
priv->decoder_thread_cancel = TRUE;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -164,6 +179,50 @@ pop_buffer(GstVaapiDecoder *decoder)
|
||||||
return buffer;
|
return buffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline DecodedSurface *
|
||||||
|
create_surface(void)
|
||||||
|
{
|
||||||
|
return g_slice_new0(DecodedSurface);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void
|
||||||
|
destroy_surface(DecodedSurface *ds)
|
||||||
|
{
|
||||||
|
g_slice_free(DecodedSurface, ds);
|
||||||
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
push_surface(GstVaapiDecoder *decoder, GstVaapiSurface *surface)
|
||||||
|
{
|
||||||
|
GstVaapiDecoderPrivate * const priv = decoder->priv;
|
||||||
|
GstVaapiDecoderStatus status = priv->decoder_status;
|
||||||
|
DecodedSurface *ds;
|
||||||
|
|
||||||
|
ds = create_surface();
|
||||||
|
if (!ds)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
if (surface) {
|
||||||
|
GST_DEBUG("queue decoded surface %" GST_VAAPI_ID_FORMAT,
|
||||||
|
GST_VAAPI_ID_ARGS(GST_VAAPI_OBJECT_ID(surface)));
|
||||||
|
ds->proxy = gst_vaapi_surface_proxy_new(priv->context, surface);
|
||||||
|
if (!ds->proxy)
|
||||||
|
status = GST_VAAPI_DECODER_STATUS_ERROR_ALLOCATION_FAILED;
|
||||||
|
}
|
||||||
|
ds->status = status;
|
||||||
|
|
||||||
|
g_async_queue_push(priv->surfaces, ds);
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline DecodedSurface *
|
||||||
|
pop_surface(GstVaapiDecoder *decoder, GTimeVal *end_time)
|
||||||
|
{
|
||||||
|
GstVaapiDecoderPrivate * const priv = decoder->priv;
|
||||||
|
|
||||||
|
return g_async_queue_timed_pop(priv->surfaces, end_time);
|
||||||
|
}
|
||||||
|
|
||||||
static inline void
|
static inline void
|
||||||
set_codec_data(GstVaapiDecoder *decoder, GstBuffer *codec_data)
|
set_codec_data(GstVaapiDecoder *decoder, GstBuffer *codec_data)
|
||||||
{
|
{
|
||||||
|
@ -179,12 +238,12 @@ set_codec_data(GstVaapiDecoder *decoder, GstBuffer *codec_data)
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
clear_async_queue(GAsyncQueue *q)
|
clear_async_queue(GAsyncQueue *q, GDestroyNotify destroy)
|
||||||
{
|
{
|
||||||
guint i, qlen = g_async_queue_length(q);
|
guint i, qlen = g_async_queue_length(q);
|
||||||
|
|
||||||
for (i = 0; i < qlen; i++)
|
for (i = 0; i < qlen; i++)
|
||||||
g_object_unref(g_async_queue_pop(q));
|
destroy(g_async_queue_pop(q));
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -203,13 +262,13 @@ gst_vaapi_decoder_finalize(GObject *object)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (priv->buffers) {
|
if (priv->buffers) {
|
||||||
clear_async_queue(priv->buffers);
|
clear_async_queue(priv->buffers, (GDestroyNotify)g_object_unref);
|
||||||
g_object_unref(priv->buffers);
|
g_object_unref(priv->buffers);
|
||||||
priv->buffers = NULL;
|
priv->buffers = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (priv->surfaces) {
|
if (priv->surfaces) {
|
||||||
clear_async_queue(priv->surfaces);
|
clear_async_queue(priv->surfaces, (GDestroyNotify)destroy_surface);
|
||||||
g_object_unref(priv->surfaces);
|
g_object_unref(priv->surfaces);
|
||||||
priv->surfaces = NULL;
|
priv->surfaces = NULL;
|
||||||
}
|
}
|
||||||
|
@ -532,24 +591,20 @@ _gst_vaapi_decoder_get_surface(
|
||||||
GstVaapiDecoderStatus *pstatus
|
GstVaapiDecoderStatus *pstatus
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
GstVaapiDecoderPrivate * const priv = decoder->priv;
|
|
||||||
GstVaapiDecoderStatus status;
|
GstVaapiDecoderStatus status;
|
||||||
GstVaapiSurface *surface;
|
GstVaapiSurfaceProxy *proxy;
|
||||||
GstVaapiSurfaceProxy *proxy = NULL;
|
DecodedSurface *ds;
|
||||||
|
|
||||||
surface = g_async_queue_timed_pop(priv->surfaces, end_time);
|
ds = pop_surface(decoder, end_time);
|
||||||
|
if (ds) {
|
||||||
if (surface) {
|
proxy = ds->proxy;
|
||||||
proxy = gst_vaapi_surface_proxy_new(priv->context, surface);
|
status = ds->status;
|
||||||
status = (proxy ?
|
destroy_surface(ds);
|
||||||
GST_VAAPI_DECODER_STATUS_SUCCESS :
|
|
||||||
GST_VAAPI_DECODER_STATUS_ERROR_ALLOCATION_FAILED);
|
|
||||||
g_object_unref(surface);
|
|
||||||
}
|
}
|
||||||
else if (end_time)
|
else {
|
||||||
|
proxy = NULL;
|
||||||
status = GST_VAAPI_DECODER_STATUS_TIMEOUT;
|
status = GST_VAAPI_DECODER_STATUS_TIMEOUT;
|
||||||
else
|
}
|
||||||
status = priv->decoder_status;
|
|
||||||
|
|
||||||
if (pstatus)
|
if (pstatus)
|
||||||
*pstatus = status;
|
*pstatus = status;
|
||||||
|
@ -629,13 +684,5 @@ gst_vaapi_decoder_push_surface(
|
||||||
GstVaapiSurface *surface
|
GstVaapiSurface *surface
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
GstVaapiDecoderPrivate * const priv = decoder->priv;
|
return push_surface(decoder, surface);
|
||||||
|
|
||||||
g_return_val_if_fail(GST_VAAPI_IS_SURFACE(surface), FALSE);
|
|
||||||
|
|
||||||
GST_DEBUG("queue decoded surface %" GST_VAAPI_ID_FORMAT,
|
|
||||||
GST_VAAPI_ID_ARGS(GST_VAAPI_OBJECT_ID(surface)));
|
|
||||||
|
|
||||||
g_async_queue_push(priv->surfaces, g_object_ref(surface));
|
|
||||||
return TRUE;
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue