[Pkg-gstreamer-commits] [gstreamer-vaapi] 55/176: h264: improve robustness when packets are missing.
Vincent Cheng
vcheng at moszumanska.debian.org
Tue Jun 3 08:09:27 UTC 2014
This is an automated email from the git hooks/post-receive script.
vcheng pushed a commit to branch upstream
in repository gstreamer-vaapi.
commit 6fe54964bba22a415424839299ae5a2635f3d24e
Author: Gwenole Beauchesne <gwenole.beauchesne at intel.com>
Date: Tue Dec 10 16:14:27 2013 +0100
h264: improve robustness when packets are missing.
Improve robustness when some expected packets where not received yet
or that were not correctly decoded. For example, don't try to decode
a picture if there was no valid frame headers parsed so far.
https://bugs.freedesktop.org/show_bug.cgi?id=57902
---
gst-libs/gst/vaapi/gstvaapidecoder_h264.c | 55 +++++++++++++++++++++++++++----
1 file changed, 49 insertions(+), 6 deletions(-)
diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_h264.c b/gst-libs/gst/vaapi/gstvaapidecoder_h264.c
index 1d1be55..8d8efa0 100644
--- a/gst-libs/gst/vaapi/gstvaapidecoder_h264.c
+++ b/gst-libs/gst/vaapi/gstvaapidecoder_h264.c
@@ -349,8 +349,23 @@ gst_vaapi_frame_store_has_reference(GstVaapiFrameStore *fs)
#define GST_VAAPI_DECODER_H264_CAST(decoder) \
((GstVaapiDecoderH264 *)(decoder))
+typedef enum {
+ GST_H264_VIDEO_STATE_GOT_SPS = 1 << 0,
+ GST_H264_VIDEO_STATE_GOT_PPS = 1 << 1,
+ GST_H264_VIDEO_STATE_GOT_SLICE = 1 << 2,
+
+ GST_H264_VIDEO_STATE_VALID_PICTURE_HEADERS = (
+ GST_H264_VIDEO_STATE_GOT_SPS |
+ GST_H264_VIDEO_STATE_GOT_PPS),
+ GST_H264_VIDEO_STATE_VALID_PICTURE = (
+ GST_H264_VIDEO_STATE_VALID_PICTURE_HEADERS |
+ GST_H264_VIDEO_STATE_GOT_SLICE)
+} GstH264VideoState;
+
struct _GstVaapiDecoderH264Private {
GstH264NalParser *parser;
+ guint parser_state;
+ guint decoder_state;
GstVaapiPictureH264 *current_picture;
GstVaapiParserInfoH264 *prev_slice_pi;
GstVaapiFrameStore *prev_frame;
@@ -383,8 +398,6 @@ struct _GstVaapiDecoderH264Private {
gboolean prev_pic_structure; // previous picture structure
guint is_opened : 1;
guint is_avcC : 1;
- guint got_sps : 1;
- guint got_pps : 1;
guint has_context : 1;
guint progressive_sequence : 1;
};
@@ -949,12 +962,22 @@ ensure_quant_matrix(GstVaapiDecoderH264 *decoder, GstVaapiPictureH264 *picture)
return GST_VAAPI_DECODER_STATUS_SUCCESS;
}
+static inline gboolean
+is_valid_state(guint state, guint ref_state)
+{
+ return (state & ref_state) == ref_state;
+}
+
static GstVaapiDecoderStatus
decode_current_picture(GstVaapiDecoderH264 *decoder)
{
GstVaapiDecoderH264Private * const priv = &decoder->priv;
GstVaapiPictureH264 * const picture = priv->current_picture;
+ if (!is_valid_state(priv->decoder_state, GST_H264_VIDEO_STATE_VALID_PICTURE))
+ goto drop_frame;
+ priv->decoder_state = 0;
+
if (!picture)
return GST_VAAPI_DECODER_STATUS_SUCCESS;
@@ -972,6 +995,10 @@ error:
/* XXX: fix for cases where first field failed to be decoded */
gst_vaapi_picture_replace(&priv->current_picture, NULL);
return GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN;
+
+drop_frame:
+ priv->decoder_state = 0;
+ return GST_VAAPI_DECODER_STATUS_DROP_FRAME;
}
static GstVaapiDecoderStatus
@@ -984,6 +1011,8 @@ parse_sps(GstVaapiDecoderH264 *decoder, GstVaapiDecoderUnit *unit)
GST_DEBUG("parse SPS");
+ priv->parser_state = 0;
+
/* Variables that don't have inferred values per the H.264
standard but that should get a default value anyway */
sps->log2_max_pic_order_cnt_lsb_minus4 = 0;
@@ -992,7 +1021,7 @@ parse_sps(GstVaapiDecoderH264 *decoder, GstVaapiDecoderUnit *unit)
if (result != GST_H264_PARSER_OK)
return get_status(result);
- priv->got_sps = TRUE;
+ priv->parser_state |= GST_H264_VIDEO_STATE_GOT_SPS;
return GST_VAAPI_DECODER_STATUS_SUCCESS;
}
@@ -1006,6 +1035,8 @@ parse_pps(GstVaapiDecoderH264 *decoder, GstVaapiDecoderUnit *unit)
GST_DEBUG("parse PPS");
+ priv->parser_state &= GST_H264_VIDEO_STATE_GOT_SPS;
+
/* Variables that don't have inferred values per the H.264
standard but that should get a default value anyway */
pps->slice_group_map_type = 0;
@@ -1015,7 +1046,7 @@ parse_pps(GstVaapiDecoderH264 *decoder, GstVaapiDecoderUnit *unit)
if (result != GST_H264_PARSER_OK)
return get_status(result);
- priv->got_pps = TRUE;
+ priv->parser_state |= GST_H264_VIDEO_STATE_GOT_PPS;
return GST_VAAPI_DECODER_STATUS_SUCCESS;
}
@@ -1049,6 +1080,9 @@ parse_slice(GstVaapiDecoderH264 *decoder, GstVaapiDecoderUnit *unit)
GST_DEBUG("parse slice");
+ priv->parser_state &= (GST_H264_VIDEO_STATE_GOT_SPS|
+ GST_H264_VIDEO_STATE_GOT_PPS);
+
/* 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;
@@ -1059,6 +1093,7 @@ parse_slice(GstVaapiDecoderH264 *decoder, GstVaapiDecoderUnit *unit)
if (result != GST_H264_PARSER_OK)
return get_status(result);
+ priv->parser_state |= GST_H264_VIDEO_STATE_GOT_SLICE;
return GST_VAAPI_DECODER_STATUS_SUCCESS;
}
@@ -2502,6 +2537,8 @@ decode_picture(GstVaapiDecoderH264 *decoder, GstVaapiDecoderUnit *unit)
if (status != GST_VAAPI_DECODER_STATUS_SUCCESS)
return status;
+ priv->decoder_state = 0;
+
if (priv->current_picture) {
/* Re-use current picture where the first field was decoded */
picture = gst_vaapi_picture_h264_new_field(priv->current_picture);
@@ -2543,6 +2580,10 @@ decode_picture(GstVaapiDecoderH264 *decoder, GstVaapiDecoderUnit *unit)
return GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN;
if (!fill_picture(decoder, picture, pi))
return GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN;
+
+ priv->decoder_state = priv->parser_state & (
+ GST_H264_VIDEO_STATE_GOT_SPS |
+ GST_H264_VIDEO_STATE_GOT_PPS);
return GST_VAAPI_DECODER_STATUS_SUCCESS;
}
@@ -2704,8 +2745,9 @@ decode_slice(GstVaapiDecoderH264 *decoder, GstVaapiDecoderUnit *unit)
GST_DEBUG("slice (%u bytes)", pi->nalu.size);
- if (!priv->got_sps || !priv->got_pps) {
- GST_ERROR("not initialized yet");
+ if (!is_valid_state(priv->decoder_state,
+ GST_H264_VIDEO_STATE_VALID_PICTURE_HEADERS)) {
+ GST_WARNING("failed to receive enough headers to decode slice");
return GST_VAAPI_DECODER_STATUS_SUCCESS;
}
@@ -2729,6 +2771,7 @@ decode_slice(GstVaapiDecoderH264 *decoder, GstVaapiDecoderUnit *unit)
gst_vaapi_picture_add_slice(GST_VAAPI_PICTURE_CAST(picture), slice);
picture->last_slice_hdr = slice_hdr;
+ priv->decoder_state |= GST_H264_VIDEO_STATE_GOT_SLICE;
return GST_VAAPI_DECODER_STATUS_SUCCESS;
}
--
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-gstreamer/gstreamer-vaapi.git
More information about the Pkg-gstreamer-commits
mailing list