dpb: drop GstVaapiDpb2 interface, keep only one class.

Keep only one DPB interface and rename gst_vaapi_dpb2_get_references()
to gst_vaapi_dpb_get_neighbours() so that to retrieve pictures in DPB
around the specified picture POC.
This commit is contained in:
Gwenole Beauchesne 2013-01-14 10:21:53 +01:00
parent eafdd771ae
commit 6f4e01258d
3 changed files with 155 additions and 87 deletions

View file

@ -25,6 +25,13 @@
#define DEBUG 1 #define DEBUG 1
#include "gstvaapidebug.h" #include "gstvaapidebug.h"
G_GNUC_INTERNAL
GType
gst_vaapi_dpb2_get_type(void) G_GNUC_CONST;
#define GST_VAAPI_TYPE_DPB2 \
(gst_vaapi_dpb2_get_type())
/* ------------------------------------------------------------------------- */ /* ------------------------------------------------------------------------- */
/* --- Common Decoded Picture Buffer utilities --- */ /* --- Common Decoded Picture Buffer utilities --- */
/* ------------------------------------------------------------------------- */ /* ------------------------------------------------------------------------- */
@ -177,6 +184,45 @@ gst_vaapi_dpb_base_add(GstVaapiDpb *dpb, GstVaapiPicture *picture)
return TRUE; return TRUE;
} }
void
gst_vaapi_dpb_base_get_neighbours(
GstVaapiDpb *dpb,
GstVaapiPicture *picture,
GstVaapiPicture **prev_picture_ptr,
GstVaapiPicture **next_picture_ptr
)
{
GstVaapiPicture *prev_picture = NULL;
GstVaapiPicture *next_picture = NULL;
guint i;
/* Find the first picture with POC > specified picture POC */
for (i = 0; i < dpb->num_pictures; i++) {
GstVaapiPicture * const ref_picture = dpb->pictures[i];
if (ref_picture->poc == picture->poc) {
if (i > 0)
prev_picture = dpb->pictures[i - 1];
if (i + 1 < dpb->num_pictures)
next_picture = dpb->pictures[i + 1];
break;
}
else if (ref_picture->poc > picture->poc) {
next_picture = ref_picture;
if (i > 0)
prev_picture = dpb->pictures[i - 1];
break;
}
}
g_assert(next_picture ? next_picture->poc > picture->poc : TRUE);
g_assert(prev_picture ? prev_picture->poc < picture->poc : TRUE);
if (prev_picture_ptr)
*prev_picture_ptr = prev_picture;
if (next_picture_ptr)
*next_picture_ptr = next_picture;
}
static void static void
gst_vaapi_dpb_finalize(GstMiniObject *object) gst_vaapi_dpb_finalize(GstMiniObject *object)
{ {
@ -209,6 +255,15 @@ gst_vaapi_dpb_class_init(GstVaapiDpbClass *klass)
object_class->finalize = gst_vaapi_dpb_finalize; object_class->finalize = gst_vaapi_dpb_finalize;
klass->flush = gst_vaapi_dpb_base_flush; klass->flush = gst_vaapi_dpb_base_flush;
klass->add = gst_vaapi_dpb_base_add; klass->add = gst_vaapi_dpb_base_add;
klass->get_neighbours = gst_vaapi_dpb_base_get_neighbours;
}
GstVaapiDpb *
gst_vaapi_dpb_new(guint max_pictures)
{
if (G_LIKELY(max_pictures == 2))
return dpb_new(GST_VAAPI_TYPE_DPB2, max_pictures);
return dpb_new(GST_VAAPI_TYPE_DPB, max_pictures);
} }
void void
@ -246,22 +301,94 @@ gst_vaapi_dpb_size(GstVaapiDpb *dpb)
return dpb->num_pictures; return dpb->num_pictures;
} }
void
gst_vaapi_dpb_get_neighbours(
GstVaapiDpb *dpb,
GstVaapiPicture *picture,
GstVaapiPicture **prev_picture_ptr,
GstVaapiPicture **next_picture_ptr
)
{
GstVaapiDpbClass *klass;
g_return_if_fail(GST_VAAPI_IS_DPB(dpb));
g_return_if_fail(GST_VAAPI_IS_PICTURE(picture));
klass = GST_VAAPI_DPB_GET_CLASS(dpb);
if (G_UNLIKELY(!klass || !klass->get_neighbours))
return;
klass->get_neighbours(dpb, picture, prev_picture_ptr, next_picture_ptr);
}
/* ------------------------------------------------------------------------- */ /* ------------------------------------------------------------------------- */
/* --- Decoded Picture Buffer (optimized for 2 reference pictures) --- */ /* --- Decoded Picture Buffer (optimized for 2 reference pictures) --- */
/* ------------------------------------------------------------------------- */ /* ------------------------------------------------------------------------- */
/* At most two reference pictures for DPB2*/ typedef struct _GstVaapiDpb2 GstVaapiDpb2;
#define MAX_DPB2_REFERENCES 2 typedef struct _GstVaapiDpb2Class GstVaapiDpb2Class;
#define GST_VAAPI_DPB2_CAST(obj) \
((GstVaapiDpb2 *)(obj))
#define GST_VAAPI_DPB2(obj) \
(G_TYPE_CHECK_INSTANCE_CAST((obj), \
GST_VAAPI_TYPE_DPB2, \
GstVaapiDpb2))
#define GST_VAAPI_DPB2_CLASS(klass) \
(G_TYPE_CHECK_CLASS_CAST((klass), \
GST_VAAPI_TYPE_DPB2, \
GstVaapiDpb2Class))
#define GST_VAAPI_IS_DPB2(obj) \
(G_TYPE_CHECK_INSTANCE_TYPE((obj), GST_VAAPI_TYPE_DPB2))
#define GST_VAAPI_IS_DPB2_CLASS(klass) \
(G_TYPE_CHECK_CLASS_TYPE((klass), GST_VAAPI_TYPE_DPB2))
#define GST_VAAPI_DPB2_GET_CLASS(obj) \
(G_TYPE_INSTANCE_GET_CLASS((obj), \
GST_VAAPI_TYPE_DPB2, \
GstVaapiDpb2Class))
/**
* GstVaapiDpb2:
*
* A decoded picture buffer (DPB2) object.
*/
struct _GstVaapiDpb2 {
/*< private >*/
GstVaapiDpb parent_instance;
};
/**
* GstVaapiDpb2Class:
*
* The #GstVaapiDpb2 base class.
*/
struct _GstVaapiDpb2Class {
/*< private >*/
GstVaapiDpbClass parent_class;
};
G_DEFINE_TYPE(GstVaapiDpb2, gst_vaapi_dpb2, GST_VAAPI_TYPE_DPB) G_DEFINE_TYPE(GstVaapiDpb2, gst_vaapi_dpb2, GST_VAAPI_TYPE_DPB)
static void
gst_vaapi_dpb2_get_neighbours(
GstVaapiDpb *dpb,
GstVaapiPicture *picture,
GstVaapiPicture **prev_picture_ptr,
GstVaapiPicture **next_picture_ptr
);
static gboolean static gboolean
gst_vaapi_dpb2_add(GstVaapiDpb *dpb, GstVaapiPicture *picture) gst_vaapi_dpb2_add(GstVaapiDpb *dpb, GstVaapiPicture *picture)
{ {
GstVaapiPicture *ref_picture; GstVaapiPicture *ref_picture;
gint index = -1; gint index = -1;
g_return_val_if_fail(GST_VAAPI_IS_DPB2(dpb), FALSE); g_return_val_if_fail(GST_VAAPI_IS_DPB(dpb), FALSE);
g_return_val_if_fail(dpb->max_pictures == 2, FALSE);
/* /*
* Purpose: only store reference decoded pictures into the DPB * Purpose: only store reference decoded pictures into the DPB
@ -271,7 +398,7 @@ gst_vaapi_dpb2_add(GstVaapiDpb *dpb, GstVaapiPicture *picture)
* - ... thus causing older reference pictures to be output, if not already * - ... thus causing older reference pictures to be output, if not already
* - the oldest reference picture is replaced with the new reference picture * - the oldest reference picture is replaced with the new reference picture
*/ */
if (G_LIKELY(dpb->num_pictures == MAX_DPB2_REFERENCES)) { if (G_LIKELY(dpb->num_pictures == 2)) {
index = (dpb->pictures[0]->poc > dpb->pictures[1]->poc); index = (dpb->pictures[0]->poc > dpb->pictures[1]->poc);
ref_picture = dpb->pictures[index]; ref_picture = dpb->pictures[index];
if (!GST_VAAPI_PICTURE_IS_OUTPUT(ref_picture)) { if (!GST_VAAPI_PICTURE_IS_OUTPUT(ref_picture)) {
@ -300,27 +427,23 @@ gst_vaapi_dpb2_class_init(GstVaapiDpb2Class *klass)
GstVaapiDpbClass * const dpb_class = GST_VAAPI_DPB_CLASS(klass); GstVaapiDpbClass * const dpb_class = GST_VAAPI_DPB_CLASS(klass);
dpb_class->add = gst_vaapi_dpb2_add; dpb_class->add = gst_vaapi_dpb2_add;
} dpb_class->get_neighbours = gst_vaapi_dpb2_get_neighbours;
GstVaapiDpb *
gst_vaapi_dpb2_new(void)
{
return dpb_new(GST_VAAPI_TYPE_DPB2, MAX_DPB2_REFERENCES);
} }
void void
gst_vaapi_dpb2_get_references( gst_vaapi_dpb2_get_neighbours(
GstVaapiDpb *dpb, GstVaapiDpb *dpb,
GstVaapiPicture *picture, GstVaapiPicture *picture,
GstVaapiPicture **prev_picture_ptr, GstVaapiPicture **prev_picture_ptr,
GstVaapiPicture **next_picture_ptr GstVaapiPicture **next_picture_ptr
) )
{ {
GstVaapiPicture *ref_picture, *ref_pictures[MAX_DPB2_REFERENCES]; GstVaapiPicture *ref_picture, *ref_pictures[2];
GstVaapiPicture **picture_ptr; GstVaapiPicture **picture_ptr;
guint i, index; guint i, index;
g_return_if_fail(GST_VAAPI_IS_DPB2(dpb)); g_return_if_fail(GST_VAAPI_IS_DPB(dpb));
g_return_if_fail(dpb->max_pictures == 2);
g_return_if_fail(GST_VAAPI_IS_PICTURE(picture)); g_return_if_fail(GST_VAAPI_IS_PICTURE(picture));
ref_pictures[0] = NULL; ref_pictures[0] = NULL;

View file

@ -28,8 +28,6 @@ G_BEGIN_DECLS
typedef struct _GstVaapiDpb GstVaapiDpb; typedef struct _GstVaapiDpb GstVaapiDpb;
typedef struct _GstVaapiDpbClass GstVaapiDpbClass; typedef struct _GstVaapiDpbClass GstVaapiDpbClass;
typedef struct _GstVaapiDpb2 GstVaapiDpb2;
typedef struct _GstVaapiDpb2Class GstVaapiDpb2Class;
/* ------------------------------------------------------------------------- */ /* ------------------------------------------------------------------------- */
/* --- Base Decoded Picture Buffer --- */ /* --- Base Decoded Picture Buffer --- */
@ -89,12 +87,18 @@ struct _GstVaapiDpbClass {
/*< protected >*/ /*< protected >*/
void (*flush) (GstVaapiDpb *dpb); void (*flush) (GstVaapiDpb *dpb);
gboolean (*add) (GstVaapiDpb *dpb, GstVaapiPicture *picture); gboolean (*add) (GstVaapiDpb *dpb, GstVaapiPicture *picture);
void (*get_neighbours) (GstVaapiDpb *dpb, GstVaapiPicture *picture,
GstVaapiPicture **prev_picture_ptr, GstVaapiPicture **next_picture_ptr);
}; };
G_GNUC_INTERNAL G_GNUC_INTERNAL
GType GType
gst_vaapi_dpb_get_type(void) G_GNUC_CONST; gst_vaapi_dpb_get_type(void) G_GNUC_CONST;
G_GNUC_INTERNAL
GstVaapiDpb *
gst_vaapi_dpb_new(guint max_pictures);
G_GNUC_INTERNAL G_GNUC_INTERNAL
void void
gst_vaapi_dpb_flush(GstVaapiDpb *dpb); gst_vaapi_dpb_flush(GstVaapiDpb *dpb);
@ -107,6 +111,15 @@ G_GNUC_INTERNAL
guint guint
gst_vaapi_dpb_size(GstVaapiDpb *dpb); gst_vaapi_dpb_size(GstVaapiDpb *dpb);
G_GNUC_INTERNAL
void
gst_vaapi_dpb_get_neighbours(
GstVaapiDpb *dpb,
GstVaapiPicture *picture,
GstVaapiPicture **prev_picture_ptr,
GstVaapiPicture **next_picture_ptr
);
static inline gpointer static inline gpointer
gst_vaapi_dpb_ref(gpointer ptr) gst_vaapi_dpb_ref(gpointer ptr)
{ {
@ -119,74 +132,6 @@ gst_vaapi_dpb_unref(gpointer ptr)
gst_mini_object_unref(GST_MINI_OBJECT(ptr)); gst_mini_object_unref(GST_MINI_OBJECT(ptr));
} }
/* ------------------------------------------------------------------------- */
/* --- Decoded Picture Buffer (optimized for 2 reference pictures) --- */
/* ------------------------------------------------------------------------- */
#define GST_VAAPI_TYPE_DPB2 \
(gst_vaapi_dpb2_get_type())
#define GST_VAAPI_DPB2_CAST(obj) \
((GstVaapiDpb2 *)(obj))
#define GST_VAAPI_DPB2(obj) \
(G_TYPE_CHECK_INSTANCE_CAST((obj), \
GST_VAAPI_TYPE_DPB2, \
GstVaapiDpb2))
#define GST_VAAPI_DPB2_CLASS(klass) \
(G_TYPE_CHECK_CLASS_CAST((klass), \
GST_VAAPI_TYPE_DPB2, \
GstVaapiDpb2Class))
#define GST_VAAPI_IS_DPB2(obj) \
(G_TYPE_CHECK_INSTANCE_TYPE((obj), GST_VAAPI_TYPE_DPB2))
#define GST_VAAPI_IS_DPB2_CLASS(klass) \
(G_TYPE_CHECK_CLASS_TYPE((klass), GST_VAAPI_TYPE_DPB2))
#define GST_VAAPI_DPB2_GET_CLASS(obj) \
(G_TYPE_INSTANCE_GET_CLASS((obj), \
GST_VAAPI_TYPE_DPB2, \
GstVaapiDpb2Class))
/**
* GstVaapiDpb2:
*
* A decoded picture buffer (DPB2) object.
*/
struct _GstVaapiDpb2 {
/*< private >*/
GstVaapiDpb parent_instance;
};
/**
* GstVaapiDpb2Class:
*
* The #GstVaapiDpb2 base class.
*/
struct _GstVaapiDpb2Class {
/*< private >*/
GstVaapiDpbClass parent_class;
};
G_GNUC_INTERNAL
GType
gst_vaapi_dpb2_get_type(void) G_GNUC_CONST;
G_GNUC_INTERNAL
GstVaapiDpb *
gst_vaapi_dpb2_new(void);
G_GNUC_INTERNAL
void
gst_vaapi_dpb2_get_references(
GstVaapiDpb *dpb,
GstVaapiPicture *picture,
GstVaapiPicture **prev_picture_ptr,
GstVaapiPicture **next_picture_ptr
);
G_END_DECLS G_END_DECLS
#endif /* GST_VAAPI_DECODER_DPB */ #endif /* GST_VAAPI_DECODER_DPB */

View file

@ -386,7 +386,7 @@ gst_vaapi_decoder_mpeg2_open(GstVaapiDecoderMpeg2 *decoder)
gst_vaapi_decoder_mpeg2_close(decoder); gst_vaapi_decoder_mpeg2_close(decoder);
priv->dpb = gst_vaapi_dpb2_new(); priv->dpb = gst_vaapi_dpb_new(2);
if (!priv->dpb) if (!priv->dpb)
return FALSE; return FALSE;
@ -1044,7 +1044,7 @@ fill_picture(GstVaapiDecoderMpeg2 *decoder, GstVaapiPicture *picture)
COPY_FIELD(picture_coding_extension, bits, repeat_first_field); COPY_FIELD(picture_coding_extension, bits, repeat_first_field);
COPY_FIELD(picture_coding_extension, bits, progressive_frame); COPY_FIELD(picture_coding_extension, bits, progressive_frame);
gst_vaapi_dpb2_get_references(priv->dpb, picture, gst_vaapi_dpb_get_neighbours(priv->dpb, picture,
&prev_picture, &next_picture); &prev_picture, &next_picture);
switch (pic_hdr->pic_type) { switch (pic_hdr->pic_type) {