decoder: h264: properly handle Prefix NAL units.
authorSreerenj Balachandran <sreerenj.balachandran@intel.com>
Thu, 31 Oct 2013 11:32:55 +0000 (19:32 +0800)
committerGwenole Beauchesne <gwenole.beauchesne@intel.com>
Wed, 21 May 2014 17:59:52 +0000 (19:59 +0200)
Always cache the previous NAL unit so that we could check whether
there is a Prefix NAL unit immediately preceding the current slice
or IDR NAL unit. In that case, the NAL unit metadata is copied into
the current NAL unit. Otherwise, some default values are inferred,
tentatively. e.g. view_id shall be set to 0 and inter_view_flag to 1.

[infer default values for slice if previous NAL was not a Prefix]
Signed-off-by: Gwenole Beauchesne <gwenole.beauchesne@intel.com>
gst-libs/gst/vaapi/gstvaapidecoder_h264.c

index d0a6217ca6a3f7037d96831b5541bdb9aa83b197..e44a7efb881ca8145f5c59cf70894698e90de0fd 100644 (file)
@@ -393,6 +393,7 @@ struct _GstVaapiDecoderH264Private {
     GstVaapiParserInfoH264     *active_sps;
     GstVaapiParserInfoH264     *pps[GST_H264_MAX_PPS_COUNT];
     GstVaapiParserInfoH264     *active_pps;
+    GstVaapiParserInfoH264     *prev_pi;
     GstVaapiParserInfoH264     *prev_slice_pi;
     GstVaapiFrameStore         *prev_frame;
     GstVaapiFrameStore         *dpb[16];
@@ -750,6 +751,7 @@ gst_vaapi_decoder_h264_close(GstVaapiDecoderH264 *decoder)
 
     gst_vaapi_picture_replace(&priv->current_picture, NULL);
     gst_vaapi_parser_info_h264_replace(&priv->prev_slice_pi, NULL);
+    gst_vaapi_parser_info_h264_replace(&priv->prev_pi, NULL);
 
     dpb_clear(decoder, NULL);
 
@@ -1180,6 +1182,7 @@ parse_slice(GstVaapiDecoderH264 *decoder, GstVaapiDecoderUnit *unit)
     GstVaapiDecoderH264Private * const priv = &decoder->priv;
     GstVaapiParserInfoH264 * const pi = unit->parsed_info;
     GstH264SliceHdr * const slice_hdr = &pi->data.slice_hdr;
+    GstH264NalUnit * const nalu = &pi->nalu;
     GstH264ParserResult result;
 
     GST_DEBUG("parse slice");
@@ -1187,6 +1190,34 @@ parse_slice(GstVaapiDecoderH264 *decoder, GstVaapiDecoderUnit *unit)
     priv->parser_state &= (GST_H264_VIDEO_STATE_GOT_SPS|
                            GST_H264_VIDEO_STATE_GOT_PPS);
 
+    /* Propagate Prefix NAL unit info, if necessary */
+    switch (nalu->type) {
+    case GST_H264_NAL_SLICE:
+    case GST_H264_NAL_SLICE_IDR: {
+        GstVaapiParserInfoH264 * const prev_pi = priv->prev_pi;
+        if (prev_pi && prev_pi->nalu.type == GST_H264_NAL_PREFIX_UNIT) {
+            /* MVC sequences shall have a Prefix NAL unit immediately
+               preceding this NAL unit */
+            pi->nalu.extension_type = prev_pi->nalu.extension_type;
+            pi->nalu.extension = prev_pi->nalu.extension;
+        }
+        else {
+            /* In the very unlikely case there is no Prefix NAL unit
+               immediately preceding this NAL unit, try to infer some
+               defaults (H.7.4.1.1) */
+            GstH264NalUnitExtensionMVC * const mvc = &pi->nalu.extension.mvc;
+            mvc->non_idr_flag = !(nalu->type == GST_H264_NAL_SLICE_IDR);
+            nalu->idr_pic_flag = !mvc->non_idr_flag;
+            mvc->priority_id = 0;
+            mvc->view_id = 0;
+            mvc->temporal_id = 0;
+            mvc->anchor_pic_flag = 0;
+            mvc->inter_view_flag = 1;
+        }
+        break;
+    }
+    }
+
     /* Variables that don't have inferred values per the H.264
        standard but that should get a default value anyway */
     slice_hdr->cabac_init_idc = 0;
@@ -3273,6 +3304,7 @@ gst_vaapi_decoder_h264_parse(GstVaapiDecoder *base_decoder,
 
     pi->nalu.data = NULL;
     pi->state = priv->parser_state;
+    gst_vaapi_parser_info_h264_replace(&priv->prev_pi, pi);
     return GST_VAAPI_DECODER_STATUS_SUCCESS;
 }