mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-06-05 15:08:53 +00:00
vc1: fix bitplanes decoding.
This commit is contained in:
parent
e686c440c7
commit
5aea02a66f
3 changed files with 151 additions and 1 deletions
|
@ -615,6 +615,9 @@ gst_vaapi_decoder_push_surface_proxy(
|
||||||
static void
|
static void
|
||||||
destroy_iq_matrix(GstVaapiDecoder *decoder, GstVaapiIqMatrix *iq_matrix);
|
destroy_iq_matrix(GstVaapiDecoder *decoder, GstVaapiIqMatrix *iq_matrix);
|
||||||
|
|
||||||
|
static void
|
||||||
|
destroy_bitplane(GstVaapiDecoder *decoder, GstVaapiBitPlane *bitplane);
|
||||||
|
|
||||||
static void
|
static void
|
||||||
destroy_slice(GstVaapiDecoder *decoder, GstVaapiSlice *slice);
|
destroy_slice(GstVaapiDecoder *decoder, GstVaapiSlice *slice);
|
||||||
|
|
||||||
|
@ -643,6 +646,11 @@ destroy_picture(GstVaapiDecoder *decoder, GstVaapiPicture *picture)
|
||||||
picture->iq_matrix = NULL;
|
picture->iq_matrix = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (picture->bitplane) {
|
||||||
|
destroy_bitplane(decoder, picture->bitplane);
|
||||||
|
picture->bitplane = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
picture->surface = NULL;
|
picture->surface = NULL;
|
||||||
picture->surface_id = VA_INVALID_ID;
|
picture->surface_id = VA_INVALID_ID;
|
||||||
|
|
||||||
|
@ -669,6 +677,7 @@ create_picture(GstVaapiDecoder *decoder)
|
||||||
picture->param = NULL;
|
picture->param = NULL;
|
||||||
picture->slices = NULL;
|
picture->slices = NULL;
|
||||||
picture->iq_matrix = NULL;
|
picture->iq_matrix = NULL;
|
||||||
|
picture->bitplane = NULL;
|
||||||
picture->pts = GST_CLOCK_TIME_NONE;
|
picture->pts = GST_CLOCK_TIME_NONE;
|
||||||
|
|
||||||
picture->surface = gst_vaapi_context_get_surface(priv->context);
|
picture->surface = gst_vaapi_context_get_surface(priv->context);
|
||||||
|
@ -752,6 +761,50 @@ gst_vaapi_decoder_new_iq_matrix(GstVaapiDecoder *decoder)
|
||||||
return create_iq_matrix(decoder);
|
return create_iq_matrix(decoder);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
destroy_bitplane(GstVaapiDecoder *decoder, GstVaapiBitPlane *bitplane)
|
||||||
|
{
|
||||||
|
GstVaapiDecoderPrivate * const priv = decoder->priv;
|
||||||
|
|
||||||
|
vaapi_destroy_buffer(priv->va_display, &bitplane->data_id);
|
||||||
|
bitplane->data = NULL;
|
||||||
|
g_slice_free(GstVaapiBitPlane, bitplane);
|
||||||
|
}
|
||||||
|
|
||||||
|
static GstVaapiBitPlane *
|
||||||
|
create_bitplane(GstVaapiDecoder *decoder, guint size)
|
||||||
|
{
|
||||||
|
GstVaapiDecoderPrivate * const priv = decoder->priv;
|
||||||
|
GstVaapiBitPlane *bitplane;
|
||||||
|
|
||||||
|
bitplane = g_slice_new(GstVaapiBitPlane);
|
||||||
|
if (!bitplane)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
bitplane->data_id = VA_INVALID_ID;
|
||||||
|
|
||||||
|
bitplane->data = vaapi_create_buffer(
|
||||||
|
priv->va_display,
|
||||||
|
priv->va_context,
|
||||||
|
VABitPlaneBufferType,
|
||||||
|
size,
|
||||||
|
&bitplane->data_id
|
||||||
|
);
|
||||||
|
if (!bitplane->data)
|
||||||
|
goto error;
|
||||||
|
return bitplane;
|
||||||
|
|
||||||
|
error:
|
||||||
|
destroy_bitplane(decoder, bitplane);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
GstVaapiBitPlane *
|
||||||
|
gst_vaapi_decoder_new_bitplane(GstVaapiDecoder *decoder, guint size)
|
||||||
|
{
|
||||||
|
return create_bitplane(decoder, size);
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
destroy_slice(GstVaapiDecoder *decoder, GstVaapiSlice *slice)
|
destroy_slice(GstVaapiDecoder *decoder, GstVaapiSlice *slice)
|
||||||
{
|
{
|
||||||
|
@ -836,6 +889,7 @@ gst_vaapi_decoder_decode_picture(
|
||||||
{
|
{
|
||||||
GstVaapiDecoderPrivate * const priv = decoder->priv;
|
GstVaapiDecoderPrivate * const priv = decoder->priv;
|
||||||
GstVaapiIqMatrix * const iq_matrix = picture->iq_matrix;
|
GstVaapiIqMatrix * const iq_matrix = picture->iq_matrix;
|
||||||
|
GstVaapiBitPlane * const bitplane = picture->bitplane;
|
||||||
GstVaapiSlice *slice;
|
GstVaapiSlice *slice;
|
||||||
VABufferID va_buffers[3];
|
VABufferID va_buffers[3];
|
||||||
guint i, n_va_buffers = 0;
|
guint i, n_va_buffers = 0;
|
||||||
|
@ -851,6 +905,11 @@ gst_vaapi_decoder_decode_picture(
|
||||||
va_buffers[n_va_buffers++] = iq_matrix->param_id;
|
va_buffers[n_va_buffers++] = iq_matrix->param_id;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (bitplane) {
|
||||||
|
vaapi_unmap_buffer(priv->va_display, bitplane->data_id, (void **)&bitplane->data);
|
||||||
|
va_buffers[n_va_buffers++] = bitplane->data_id;
|
||||||
|
}
|
||||||
|
|
||||||
status = vaBeginPicture(
|
status = vaBeginPicture(
|
||||||
priv->va_display,
|
priv->va_display,
|
||||||
priv->va_context,
|
priv->va_context,
|
||||||
|
|
|
@ -113,6 +113,7 @@ typedef struct _GstVaapiCodecInfo GstVaapiCodecInfo;
|
||||||
typedef struct _GstVaapiPicture GstVaapiPicture;
|
typedef struct _GstVaapiPicture GstVaapiPicture;
|
||||||
typedef struct _GstVaapiSlice GstVaapiSlice;
|
typedef struct _GstVaapiSlice GstVaapiSlice;
|
||||||
typedef struct _GstVaapiIqMatrix GstVaapiIqMatrix;
|
typedef struct _GstVaapiIqMatrix GstVaapiIqMatrix;
|
||||||
|
typedef struct _GstVaapiBitPlane GstVaapiBitPlane;
|
||||||
|
|
||||||
enum _GstVaapiPictureType {
|
enum _GstVaapiPictureType {
|
||||||
GST_VAAPI_PICTURE_TYPE_NONE = 0, // Undefined
|
GST_VAAPI_PICTURE_TYPE_NONE = 0, // Undefined
|
||||||
|
@ -153,6 +154,7 @@ struct _GstVaapiPicture {
|
||||||
void *param;
|
void *param;
|
||||||
GPtrArray *slices;
|
GPtrArray *slices;
|
||||||
GstVaapiIqMatrix *iq_matrix;
|
GstVaapiIqMatrix *iq_matrix;
|
||||||
|
GstVaapiBitPlane *bitplane;
|
||||||
GstClockTime pts;
|
GstClockTime pts;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -167,6 +169,11 @@ struct _GstVaapiIqMatrix {
|
||||||
void *param;
|
void *param;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct _GstVaapiBitPlane {
|
||||||
|
VABufferID data_id;
|
||||||
|
guint8 *data;
|
||||||
|
};
|
||||||
|
|
||||||
struct _GstVaapiDecoderPrivate {
|
struct _GstVaapiDecoderPrivate {
|
||||||
GstVaapiDisplay *display;
|
GstVaapiDisplay *display;
|
||||||
VADisplay va_display;
|
VADisplay va_display;
|
||||||
|
@ -250,6 +257,10 @@ GstVaapiIqMatrix *
|
||||||
gst_vaapi_decoder_new_iq_matrix(GstVaapiDecoder *decoder)
|
gst_vaapi_decoder_new_iq_matrix(GstVaapiDecoder *decoder)
|
||||||
attribute_hidden;
|
attribute_hidden;
|
||||||
|
|
||||||
|
GstVaapiBitPlane *
|
||||||
|
gst_vaapi_decoder_new_bitplane(GstVaapiDecoder *decoder, guint size)
|
||||||
|
attribute_hidden;
|
||||||
|
|
||||||
GstVaapiSlice *
|
GstVaapiSlice *
|
||||||
gst_vaapi_decoder_new_slice(
|
gst_vaapi_decoder_new_slice(
|
||||||
GstVaapiDecoder *decoder,
|
GstVaapiDecoder *decoder,
|
||||||
|
|
|
@ -54,6 +54,7 @@ struct _GstVaapiDecoderVC1Private {
|
||||||
GstVC1SeqHdr seq_hdr;
|
GstVC1SeqHdr seq_hdr;
|
||||||
GstVC1EntryPointHdr entrypoint_hdr;
|
GstVC1EntryPointHdr entrypoint_hdr;
|
||||||
GstVC1FrameHdr frame_hdr;
|
GstVC1FrameHdr frame_hdr;
|
||||||
|
GstVC1BitPlanes *bitplanes;
|
||||||
GstVaapiPicture *current_picture;
|
GstVaapiPicture *current_picture;
|
||||||
GstVaapiPicture *next_picture;
|
GstVaapiPicture *next_picture;
|
||||||
GstVaapiPicture *prev_picture;
|
GstVaapiPicture *prev_picture;
|
||||||
|
@ -117,6 +118,11 @@ gst_vaapi_decoder_vc1_close(GstVaapiDecoderVC1 *decoder)
|
||||||
priv->sub_buffer = NULL;
|
priv->sub_buffer = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (priv->bitplanes) {
|
||||||
|
gst_vc1_bitplanes_free(priv->bitplanes);
|
||||||
|
priv->bitplanes = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
if (priv->tsb) {
|
if (priv->tsb) {
|
||||||
gst_vaapi_tsb_destroy(priv->tsb);
|
gst_vaapi_tsb_destroy(priv->tsb);
|
||||||
priv->tsb = NULL;
|
priv->tsb = NULL;
|
||||||
|
@ -133,6 +139,10 @@ gst_vaapi_decoder_vc1_open(GstVaapiDecoderVC1 *decoder, GstBuffer *buffer)
|
||||||
priv->tsb = gst_vaapi_tsb_new();
|
priv->tsb = gst_vaapi_tsb_new();
|
||||||
if (!priv->tsb)
|
if (!priv->tsb)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
|
priv->bitplanes = gst_vc1_bitplanes_new();
|
||||||
|
if (!priv->bitplanes)
|
||||||
|
return FALSE;
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -584,6 +594,22 @@ has_OVERFLAGS_bitplane(GstVaapiDecoderVC1 *decoder)
|
||||||
pic->condover == GST_VC1_CONDOVER_SELECT);
|
pic->condover == GST_VC1_CONDOVER_SELECT);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline void
|
||||||
|
pack_bitplanes(GstVaapiBitPlane *bitplane, guint n, const guint8 *bitplanes[3], guint x, guint y, guint stride)
|
||||||
|
{
|
||||||
|
const guint dst_index = n / 2;
|
||||||
|
const guint src_index = y * stride + x;
|
||||||
|
guint8 v = 0;
|
||||||
|
|
||||||
|
if (bitplanes[0])
|
||||||
|
v |= bitplanes[0][src_index];
|
||||||
|
if (bitplanes[1])
|
||||||
|
v |= bitplanes[1][src_index] << 1;
|
||||||
|
if (bitplanes[2])
|
||||||
|
v |= bitplanes[2][src_index] << 2;
|
||||||
|
bitplane->data[dst_index] = (bitplane->data[dst_index] << 4) | v;
|
||||||
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
fill_picture_structc(GstVaapiDecoderVC1 *decoder, GstVaapiPicture *picture)
|
fill_picture_structc(GstVaapiDecoderVC1 *decoder, GstVaapiPicture *picture)
|
||||||
{
|
{
|
||||||
|
@ -701,6 +727,7 @@ fill_picture_advanced(GstVaapiDecoderVC1 *decoder, GstVaapiPicture *picture)
|
||||||
static gboolean
|
static gboolean
|
||||||
fill_picture(GstVaapiDecoderVC1 *decoder, GstVaapiPicture *picture)
|
fill_picture(GstVaapiDecoderVC1 *decoder, GstVaapiPicture *picture)
|
||||||
{
|
{
|
||||||
|
GstVaapiDecoder * const base_decoder = GST_VAAPI_DECODER(decoder);
|
||||||
GstVaapiDecoderVC1Private * const priv = decoder->priv;
|
GstVaapiDecoderVC1Private * const priv = decoder->priv;
|
||||||
VAPictureParameterBufferVC1 * const pic_param = picture->param;
|
VAPictureParameterBufferVC1 * const pic_param = picture->param;
|
||||||
GstVC1SeqHdr * const seq_hdr = &priv->seq_hdr;
|
GstVC1SeqHdr * const seq_hdr = &priv->seq_hdr;
|
||||||
|
@ -759,6 +786,49 @@ fill_picture(GstVaapiDecoderVC1 *decoder, GstVaapiPicture *picture)
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (pic_param->bitplane_present.value) {
|
||||||
|
const guint8 *bitplanes[3];
|
||||||
|
guint x, y, n;
|
||||||
|
|
||||||
|
switch (picture->type) {
|
||||||
|
case GST_VAAPI_PICTURE_TYPE_P:
|
||||||
|
bitplanes[0] = pic_param->bitplane_present.flags.bp_direct_mb ? priv->bitplanes->directmb : NULL;
|
||||||
|
bitplanes[1] = pic_param->bitplane_present.flags.bp_skip_mb ? priv->bitplanes->skipmb : NULL;
|
||||||
|
bitplanes[2] = pic_param->bitplane_present.flags.bp_mv_type_mb ? priv->bitplanes->mvtypemb : NULL;
|
||||||
|
break;
|
||||||
|
case GST_VAAPI_PICTURE_TYPE_B:
|
||||||
|
bitplanes[0] = pic_param->bitplane_present.flags.bp_direct_mb ? priv->bitplanes->directmb : NULL;
|
||||||
|
bitplanes[1] = pic_param->bitplane_present.flags.bp_skip_mb ? priv->bitplanes->skipmb : NULL;
|
||||||
|
bitplanes[2] = NULL; /* XXX: interlaced frame (FORWARD plane) */
|
||||||
|
break;
|
||||||
|
case GST_VAAPI_PICTURE_TYPE_BI:
|
||||||
|
case GST_VAAPI_PICTURE_TYPE_I:
|
||||||
|
bitplanes[0] = NULL; /* XXX: interlaced frame (FIELDTX plane) */
|
||||||
|
bitplanes[1] = pic_param->bitplane_present.flags.bp_ac_pred ? priv->bitplanes->acpred : NULL;
|
||||||
|
bitplanes[2] = pic_param->bitplane_present.flags.bp_overflags ? priv->bitplanes->overflags : NULL;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
bitplanes[0] = NULL;
|
||||||
|
bitplanes[1] = NULL;
|
||||||
|
bitplanes[2] = NULL;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
picture->bitplane = gst_vaapi_decoder_new_bitplane(
|
||||||
|
base_decoder,
|
||||||
|
(seq_hdr->mb_width * seq_hdr->mb_height + 1) / 2
|
||||||
|
);
|
||||||
|
if (!picture->bitplane)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
n = 0;
|
||||||
|
for (y = 0; y < seq_hdr->mb_height; y++)
|
||||||
|
for (x = 0; x < seq_hdr->mb_width; x++, n++)
|
||||||
|
pack_bitplanes(picture->bitplane, n, bitplanes, x, y, seq_hdr->mb_stride);
|
||||||
|
if (n & 1) /* move last nibble to the high order */
|
||||||
|
picture->bitplane->data[n/2] <<= 4;
|
||||||
|
}
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -794,8 +864,18 @@ decode_frame(GstVaapiDecoderVC1 *decoder, guchar *buf, guint buf_size)
|
||||||
}
|
}
|
||||||
picture = priv->current_picture;
|
picture = priv->current_picture;
|
||||||
|
|
||||||
|
if (!gst_vc1_bitplanes_ensure_size(priv->bitplanes, seq_hdr)) {
|
||||||
|
GST_DEBUG("failed to allocate bitplanes");
|
||||||
|
return GST_VAAPI_DECODER_STATUS_ERROR_ALLOCATION_FAILED;
|
||||||
|
}
|
||||||
|
|
||||||
memset(frame_hdr, 0, sizeof(*frame_hdr));
|
memset(frame_hdr, 0, sizeof(*frame_hdr));
|
||||||
result = gst_vc1_parse_frame_header(buf, buf_size, frame_hdr, seq_hdr, NULL);
|
result = gst_vc1_parse_frame_header(
|
||||||
|
buf, buf_size,
|
||||||
|
frame_hdr,
|
||||||
|
seq_hdr,
|
||||||
|
priv->bitplanes
|
||||||
|
);
|
||||||
if (result != GST_VC1_PARSER_OK) {
|
if (result != GST_VC1_PARSER_OK) {
|
||||||
GST_DEBUG("failed to parse frame layer");
|
GST_DEBUG("failed to parse frame layer");
|
||||||
return get_status(result);
|
return get_status(result);
|
||||||
|
|
Loading…
Reference in a new issue