decoder: use new GstVaapiSurfaceProxy utility functions.

Use new GstVaapiSurfaceProxy internal helper functions to propagate the
necessary GstVideoCodecFrame flags to vaapidecode (GStreamer 0.10).

Also make GstVaapiDecoder push_frame() operate similarly to drop_frame().
i.e. increase the GstVideoCodecFrame reference count in push_frame rather
than gst_vaapi_picture_output().
This commit is contained in:
Gwenole Beauchesne 2013-04-16 18:56:24 +02:00
parent c7dff071c7
commit 87e5717f66
2 changed files with 34 additions and 16 deletions

View file

@ -29,6 +29,7 @@
#include "gstvaapicompat.h"
#include "gstvaapidecoder.h"
#include "gstvaapidecoder_priv.h"
#include "gstvaapisurfaceproxy_priv.h"
#include "gstvaapiutils.h"
#include "gstvaapi_priv.h"
@ -386,12 +387,12 @@ static inline void
push_frame(GstVaapiDecoder *decoder, GstVideoCodecFrame *frame)
{
GstVaapiDecoderPrivate * const priv = decoder->priv;
GstVaapiSurfaceProxy * const proxy = frame->user_data;
GST_DEBUG("queue decoded surface %" GST_VAAPI_ID_FORMAT,
GST_VAAPI_ID_ARGS(gst_vaapi_surface_proxy_get_surface_id(
frame->user_data)));
GST_VAAPI_ID_ARGS(GST_VAAPI_SURFACE_PROXY_SURFACE_ID(proxy)));
g_queue_push_tail(priv->frames, frame);
g_queue_push_tail(priv->frames, gst_video_codec_frame_ref(frame));
}
static inline GstVideoCodecFrame *
@ -399,14 +400,15 @@ pop_frame(GstVaapiDecoder *decoder)
{
GstVaapiDecoderPrivate * const priv = decoder->priv;
GstVideoCodecFrame *frame;
GstVaapiSurfaceProxy *proxy;
frame = g_queue_pop_head(priv->frames);
if (!frame)
return NULL;
proxy = frame->user_data;
GST_DEBUG("dequeue decoded surface %" GST_VAAPI_ID_FORMAT,
GST_VAAPI_ID_ARGS(gst_vaapi_surface_proxy_get_surface_id(
frame->user_data)));
GST_VAAPI_ID_ARGS(GST_VAAPI_SURFACE_PROXY_SURFACE_ID(proxy)));
return frame;
}
@ -745,6 +747,20 @@ gst_vaapi_decoder_get_frame(GstVaapiDecoder *decoder,
if (!out_frame)
return GST_VAAPI_DECODER_STATUS_ERROR_NO_DATA;
#if !GST_CHECK_VERSION(1,0,0)
if (!GST_VIDEO_CODEC_FRAME_IS_DECODE_ONLY(out_frame)) {
const guint flags = GST_VAAPI_SURFACE_PROXY_FLAGS(out_frame->user_data);
guint out_flags = 0;
if (flags & GST_VAAPI_SURFACE_PROXY_FLAG_TFF)
out_flags |= GST_VIDEO_CODEC_FRAME_FLAG_TFF;
if (flags & GST_VAAPI_SURFACE_PROXY_FLAG_RFF)
out_flags |= GST_VIDEO_CODEC_FRAME_FLAG_RFF;
if (flags & GST_VAAPI_SURFACE_PROXY_FLAG_ONEFIELD)
out_flags |= GST_VIDEO_CODEC_FRAME_FLAG_ONEFIELD;
}
#endif
*out_frame_ptr = out_frame;
return GST_VAAPI_DECODER_STATUS_SUCCESS;
}

View file

@ -25,6 +25,7 @@
#include <gst/vaapi/gstvaapicontext.h>
#include "gstvaapidecoder_objects.h"
#include "gstvaapidecoder_priv.h"
#include "gstvaapisurfaceproxy_priv.h"
#include "gstvaapicompat.h"
#include "gstvaapiutils.h"
@ -140,8 +141,8 @@ gst_vaapi_picture_create(
picture->structure = GST_VAAPI_PICTURE_STRUCTURE_FRAME;
GST_VAAPI_PICTURE_FLAG_SET(picture, GST_VAAPI_PICTURE_FLAG_FF);
}
picture->surface = gst_vaapi_surface_proxy_get_surface(picture->proxy);
picture->surface_id = gst_vaapi_surface_get_id(picture->surface);
picture->surface = GST_VAAPI_SURFACE_PROXY_SURFACE(picture->proxy);
picture->surface_id = GST_VAAPI_SURFACE_PROXY_SURFACE_ID(picture->proxy);
picture->param_id = VA_INVALID_ID;
success = vaapi_create_buffer(
@ -297,30 +298,31 @@ gst_vaapi_picture_decode(GstVaapiPicture *picture)
gboolean
gst_vaapi_picture_output(GstVaapiPicture *picture)
{
GstVideoCodecFrame * const out_frame = picture->frame;
GstVaapiSurfaceProxy *proxy;
GstVideoCodecFrame *out_frame;
guint flags = 0;
g_return_val_if_fail(GST_VAAPI_IS_PICTURE(picture), FALSE);
if (!picture->proxy)
return FALSE;
out_frame = gst_video_codec_frame_ref(picture->frame);
proxy = gst_vaapi_surface_proxy_ref(picture->proxy);
gst_video_codec_frame_set_user_data(out_frame,
proxy, (GDestroyNotify)gst_vaapi_mini_object_unref);
out_frame->pts = picture->pts;
if (GST_VAAPI_PICTURE_IS_SKIPPED(picture))
GST_VIDEO_CODEC_FRAME_FLAG_SET(out_frame,
GST_VIDEO_CODEC_FRAME_FLAG_DECODE_ONLY);
#if !GST_CHECK_VERSION(1,0,0)
/* XXX: replaced with GST_VIDEO_BUFFER_FLAG_TFF */
if (GST_VAAPI_PICTURE_IS_TFF(picture))
GST_VIDEO_CODEC_FRAME_FLAG_SET(out_frame,
GST_VIDEO_CODEC_FRAME_FLAG_TFF);
#endif
if (GST_VAAPI_PICTURE_IS_INTERLACED(picture)) {
flags |= GST_VAAPI_SURFACE_PROXY_FLAG_INTERLACED;
if (GST_VAAPI_PICTURE_IS_TFF(picture))
flags |= GST_VAAPI_SURFACE_PROXY_FLAG_TFF;
}
GST_VAAPI_SURFACE_PROXY_FLAG_SET(proxy, flags);
gst_vaapi_decoder_push_frame(GET_DECODER(picture), out_frame);