decoder: h264: compute view ids only once per slice.
authorGwenole Beauchesne <gwenole.beauchesne@intel.com>
Thu, 22 May 2014 08:04:46 +0000 (10:04 +0200)
committerGwenole Beauchesne <gwenole.beauchesne@intel.com>
Thu, 22 May 2014 08:13:34 +0000 (10:13 +0200)
Optimize lookups of view ids / view order indices by caching the result
of the calculatiosn right into the GstVaapiParserInfoH264 struct. This
terribly simplifies is_new_access_unit() and find_first_field() functions.

gst-libs/gst/vaapi/gstvaapidecoder_h264.c

index d25994fa32e6380ec7a22d4501e40f0952a117ac..e04c2d733f67c35c6c181405e0679a77c468aa22 100644 (file)
@@ -91,7 +91,9 @@ struct _GstVaapiParserInfoH264 {
         GstH264SliceHdr slice_hdr;
     }                   data;
     guint               state;
-    guint               flags; // Same as decoder unit flags (persistent)
+    guint               flags;      // Same as decoder unit flags (persistent)
+    guint               view_id;    // View ID of slice
+    guint               voc;        // View order index (VOIdx) of slice
 };
 
 static void
@@ -1532,6 +1534,7 @@ parse_slice(GstVaapiDecoderH264 *decoder, GstVaapiDecoderUnit *unit)
     GstVaapiParserInfoH264 * const pi = unit->parsed_info;
     GstH264SliceHdr * const slice_hdr = &pi->data.slice_hdr;
     GstH264NalUnit * const nalu = &pi->nalu;
+    GstH264SPS *sps;
     GstH264ParserResult result;
     guint num_views;
 
@@ -1578,11 +1581,16 @@ parse_slice(GstVaapiDecoderH264 *decoder, GstVaapiDecoderUnit *unit)
     if (result != GST_H264_PARSER_OK)
         return get_status(result);
 
-    num_views = get_num_views(slice_hdr->pps->sequence);
+    sps = slice_hdr->pps->sequence;
+
+    /* Update MVC data */
+    num_views = get_num_views(sps);
     if (priv->max_views < num_views) {
         priv->max_views = num_views;
         GST_DEBUG("maximum number of views changed to %u", num_views);
     }
+    pi->view_id = get_view_id(&pi->nalu);
+    pi->voc = get_view_order_index(sps, pi->view_id);
 
     priv->parser_state |= GST_H264_VIDEO_STATE_GOT_SLICE;
     return GST_VAAPI_DECODER_STATUS_SUCCESS;
@@ -2701,14 +2709,13 @@ init_picture(
     picture->output_flag        = TRUE; /* XXX: conformant to Annex A only */
     base_picture->pts           = GST_VAAPI_DECODER_CODEC_FRAME(decoder)->pts;
     base_picture->type          = GST_VAAPI_PICTURE_TYPE_NONE;
+    base_picture->view_id       = pi->view_id;
+    base_picture->voc           = pi->voc;
 
     /* Initialize extensions */
     switch (pi->nalu.extension_type) {
     case GST_H264_NAL_EXTENSION_MVC: {
         GstH264NalUnitExtensionMVC * const mvc = &pi->nalu.extension.mvc;
-        base_picture->view_id = mvc->view_id;
-        base_picture->voc = get_view_order_index(get_sps(decoder),
-            base_picture->view_id);
 
         GST_VAAPI_PICTURE_FLAG_SET(picture, GST_VAAPI_PICTURE_FLAG_MVC);
         if (mvc->inter_view_flag)
@@ -3207,7 +3214,7 @@ is_new_picture(GstVaapiParserInfoH264 *pi, GstVaapiParserInfoH264 *prev_pi)
 
     /* view_id differs in value and VOIdx of current slice_hdr is less
        than the VOIdx of the prev_slice_hdr */
-    CHECK_VALUE(&pi->nalu.extension.mvc, &prev_pi->nalu.extension.mvc, view_id);
+    CHECK_VALUE(pi, prev_pi, view_id);
 
     /* frame_num differs in value, regardless of inferred values to 0 */
     CHECK_VALUE(slice_hdr, prev_slice_hdr, frame_num);
@@ -3255,48 +3262,26 @@ is_new_picture(GstVaapiParserInfoH264 *pi, GstVaapiParserInfoH264 *prev_pi)
 
 /* Detection of a new access unit, assuming we are already in presence
    of a new picture */
-static gboolean
+static inline gboolean
 is_new_access_unit(GstVaapiParserInfoH264 *pi, GstVaapiParserInfoH264 *prev_pi)
 {
-    GstH264SliceHdr * const slice_hdr = &pi->data.slice_hdr;
-    GstH264SliceHdr *prev_slice_hdr;
-    GstH264NalUnitExtensionMVC *mvc, *prev_mvc;
-    gint voc, prev_voc;
-
-    g_return_val_if_fail(is_new_picture(pi, prev_pi), FALSE);
-
-    if (!prev_pi)
-        return TRUE;
-    prev_slice_hdr = &prev_pi->data.slice_hdr;
-
-    mvc = &pi->nalu.extension.mvc;
-    prev_mvc = &prev_pi->nalu.extension.mvc;
-    if (mvc->view_id == prev_mvc->view_id)
+    if (!prev_pi || prev_pi->view_id == pi->view_id)
         return TRUE;
-
-    voc = get_view_order_index(slice_hdr->pps->sequence, mvc->view_id);
-    prev_voc = get_view_order_index(prev_slice_hdr->pps->sequence,
-        prev_mvc->view_id);
-    return voc < prev_voc;
+    return pi->voc < prev_pi->voc;
 }
 
 /* Finds the first field picture corresponding to the supplied picture */
 static GstVaapiPictureH264 *
-find_first_field(GstVaapiDecoderH264 *decoder, GstH264NalUnit *nalu,
-    GstH264SliceHdr *slice_hdr)
+find_first_field(GstVaapiDecoderH264 *decoder, GstVaapiParserInfoH264 *pi)
 {
     GstVaapiDecoderH264Private * const priv = &decoder->priv;
+    GstH264SliceHdr * const slice_hdr = &pi->data.slice_hdr;
     GstVaapiFrameStore *fs;
-    gint voc;
 
     if (!slice_hdr->field_pic_flag)
         return NULL;
 
-    voc = get_view_order_index(get_sps(decoder), get_view_id(nalu));
-    if (voc < 0)
-        return NULL;
-
-    fs = priv->prev_frames[voc];
+    fs = priv->prev_frames[pi->voc];
     if (!fs || gst_vaapi_frame_store_has_frame(fs))
         return NULL;
 
@@ -3336,7 +3321,7 @@ decode_picture(GstVaapiDecoderH264 *decoder, GstVaapiDecoderUnit *unit)
 
     priv->decoder_state = 0;
 
-    first_field = find_first_field(decoder, &pi->nalu, slice_hdr);
+    first_field = find_first_field(decoder, pi);
     if (first_field) {
         /* Re-use current picture where the first field was decoded */
         picture = gst_vaapi_picture_h264_new_field(first_field);