summaryrefslogtreecommitdiff
path: root/gst-libs/gst
diff options
context:
space:
mode:
authorGwenole Beauchesne <gwenole.beauchesne@intel.com>2012-10-23 14:50:14 +0200
committerGwenole Beauchesne <gwenole.beauchesne@intel.com>2012-11-16 16:50:30 +0100
commit2475e56bdca5ec191ff9a23d1f56a0fc3322f70f (patch)
tree2c81c524960fb39bd85836ebe43f2967c9ef3ae3 /gst-libs/gst
parent9f75916766947b30a0319813376d6282db03ea79 (diff)
h264: optimize handling of scaling lists.
Don't copy scaling lists twice to an intermediate state. Rather, directly use the scaling lists from GstH264PPS since they would match those provided by SPS header, if necessary. i.e. if PPS-specific scaling lists are not available in the bitstream.
Diffstat (limited to 'gst-libs/gst')
-rw-r--r--gst-libs/gst/vaapi/gstvaapidecoder_h264.c108
1 files changed, 69 insertions, 39 deletions
diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_h264.c b/gst-libs/gst/vaapi/gstvaapidecoder_h264.c
index 6c4adf71..76a3d5c4 100644
--- a/gst-libs/gst/vaapi/gstvaapidecoder_h264.c
+++ b/gst-libs/gst/vaapi/gstvaapidecoder_h264.c
@@ -279,8 +279,6 @@ struct _GstVaapiDecoderH264Private {
guint mb_y;
guint mb_width;
guint mb_height;
- guint8 scaling_list_4x4[6][16];
- guint8 scaling_list_8x8[6][64];
gint32 field_poc[2]; // 0:TopFieldOrderCnt / 1:BottomFieldOrderCnt
gint32 poc_msb; // PicOrderCntMsb
gint32 poc_lsb; // pic_order_cnt_lsb (from slice_header())
@@ -658,17 +656,77 @@ ensure_context(GstVaapiDecoderH264 *decoder, GstH264SPS *sps)
return GST_VAAPI_DECODER_STATUS_SUCCESS;
}
+static void
+fill_iq_matrix_4x4(VAIQMatrixBufferH264 *iq_matrix, const GstH264PPS *pps)
+{
+ const guint8 (* const ScalingList4x4)[6][16] = &pps->scaling_lists_4x4;
+ guint i, j;
+
+ /* There are always 6 4x4 scaling lists */
+ g_assert(G_N_ELEMENTS(iq_matrix->ScalingList4x4) == 6);
+ g_assert(G_N_ELEMENTS(iq_matrix->ScalingList4x4[0]) == 16);
+
+ if (sizeof(iq_matrix->ScalingList4x4[0][0]) == 1)
+ memcpy(iq_matrix->ScalingList4x4, *ScalingList4x4,
+ sizeof(iq_matrix->ScalingList4x4));
+ else {
+ for (i = 0; i < G_N_ELEMENTS(iq_matrix->ScalingList4x4); i++) {
+ for (j = 0; j < G_N_ELEMENTS(iq_matrix->ScalingList4x4[i]); j++)
+ iq_matrix->ScalingList4x4[i][j] = (*ScalingList4x4)[i][j];
+ }
+ }
+}
+
+static void
+fill_iq_matrix_8x8(VAIQMatrixBufferH264 *iq_matrix, const GstH264PPS *pps)
+{
+ const guint8 (* const ScalingList8x8)[6][64] = &pps->scaling_lists_8x8;
+ const GstH264SPS * const sps = pps->sequence;
+ guint i, j, n;
+
+ /* If chroma_format_idc != 3, there are up to 2 8x8 scaling lists */
+ if (!pps->transform_8x8_mode_flag)
+ return;
+
+ g_assert(G_N_ELEMENTS(iq_matrix->ScalingList8x8) >= 2);
+ g_assert(G_N_ELEMENTS(iq_matrix->ScalingList8x8[0]) == 64);
+
+ if (sizeof(iq_matrix->ScalingList8x8[0][0]) == 1)
+ memcpy(iq_matrix->ScalingList8x8, *ScalingList8x8,
+ sizeof(iq_matrix->ScalingList8x8));
+ else {
+ n = (sps->chroma_format_idc != 3) ? 2 : 6;
+ for (i = 0; i < n; i++) {
+ for (j = 0; j < G_N_ELEMENTS(iq_matrix->ScalingList8x8[i]); j++)
+ iq_matrix->ScalingList8x8[i][j] = (*ScalingList8x8)[i][j];
+ }
+ }
+}
+
static GstVaapiDecoderStatus
-ensure_quant_matrix(GstVaapiDecoderH264 *decoder, GstH264PPS *pps)
+ensure_quant_matrix(GstVaapiDecoderH264 *decoder, GstVaapiPictureH264 *picture)
{
GstVaapiDecoderH264Private * const priv = decoder->priv;
+ GstH264SPS * const sps = priv->sps;
+ GstH264PPS * const pps = priv->pps;
+ GstVaapiPicture * const base_picture = &picture->base;
+ VAIQMatrixBufferH264 *iq_matrix;
- if (priv->pps != pps) {
- memcpy(priv->scaling_list_4x4, pps->scaling_lists_4x4,
- sizeof(priv->scaling_list_4x4));
- memcpy(priv->scaling_list_8x8, pps->scaling_lists_8x8,
- sizeof(priv->scaling_list_8x8));
+ base_picture->iq_matrix = GST_VAAPI_IQ_MATRIX_NEW(H264, decoder);
+ if (!base_picture->iq_matrix) {
+ GST_ERROR("failed to allocate IQ matrix");
+ return GST_VAAPI_DECODER_STATUS_ERROR_ALLOCATION_FAILED;
}
+ iq_matrix = base_picture->iq_matrix->param;
+
+ /* XXX: we can only support 4:2:0 or 4:2:2 since ScalingLists8x8[]
+ is not large enough to hold lists for 4:4:4 */
+ if (sps->chroma_format_idc == 3)
+ return GST_VAAPI_DECODER_STATUS_ERROR_UNSUPPORTED_CHROMA_FORMAT;
+
+ fill_iq_matrix_4x4(iq_matrix, pps);
+ fill_iq_matrix_8x8(iq_matrix, pps);
+
return GST_VAAPI_DECODER_STATUS_SUCCESS;
}
@@ -1993,26 +2051,6 @@ fill_picture(
return TRUE;
}
-static gboolean
-fill_quant_matrix(GstVaapiDecoderH264 *decoder, GstVaapiPictureH264 *picture)
-{
- GstVaapiDecoderH264Private * const priv = decoder->priv;
- VAIQMatrixBufferH264 * const iq_matrix = picture->base.iq_matrix->param;
-
- /* XXX: we can only support 4:2:0 or 4:2:2 since ScalingLists8x8[]
- is not large enough to hold lists for 4:4:4 */
- if (priv->sps->chroma_format_idc == 3 &&
- sizeof(iq_matrix->ScalingList8x8) != sizeof(priv->scaling_list_8x8))
- return FALSE;
-
- /* Fill in VAIQMatrixBufferH264 */
- memcpy(iq_matrix->ScalingList4x4, priv->scaling_list_4x4,
- sizeof(iq_matrix->ScalingList4x4));
- memcpy(iq_matrix->ScalingList8x8, priv->scaling_list_8x8,
- sizeof(iq_matrix->ScalingList8x8));
- return TRUE;
-}
-
static GstVaapiDecoderStatus
decode_picture(GstVaapiDecoderH264 *decoder, GstH264NalUnit *nalu, GstH264SliceHdr *slice_hdr)
{
@@ -2038,21 +2076,15 @@ decode_picture(GstVaapiDecoderH264 *decoder, GstH264NalUnit *nalu, GstH264SliceH
}
priv->current_picture = picture;
- picture->base.iq_matrix = GST_VAAPI_IQ_MATRIX_NEW(H264, decoder);
- if (!picture->base.iq_matrix) {
- GST_ERROR("failed to allocate IQ matrix");
- return GST_VAAPI_DECODER_STATUS_ERROR_ALLOCATION_FAILED;
- }
+ priv->sps = sps;
+ priv->pps = pps;
- status = ensure_quant_matrix(decoder, pps);
+ status = ensure_quant_matrix(decoder, picture);
if (status != GST_VAAPI_DECODER_STATUS_SUCCESS) {
GST_ERROR("failed to reset quantizer matrix");
return status;
}
- priv->sps = sps;
- priv->pps = pps;
-
if (!init_picture(decoder, picture, slice_hdr, nalu))
return GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN;
if (!fill_picture(decoder, picture, slice_hdr, nalu))
@@ -2063,8 +2095,6 @@ decode_picture(GstVaapiDecoderH264 *decoder, GstH264NalUnit *nalu, GstH264SliceH
static gboolean
decode_picture_end(GstVaapiDecoderH264 *decoder, GstVaapiPictureH264 *picture)
{
- if (!fill_quant_matrix(decoder, picture))
- return FALSE;
if (!exec_ref_pic_marking(decoder, picture))
return FALSE;
if (!dpb_add(decoder, picture))