mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-12-21 15:56:42 +00:00
libs: decoder: h265: skip all pictures prior the first I-frame
Don't try to decode until the first I-frame is received within the currently active sequence. i965 H265 decoder don't show any artifact but it crashes. Fixes: #98
This commit is contained in:
parent
6fb5387d5b
commit
1168d6d548
1 changed files with 23 additions and 1 deletions
|
@ -334,6 +334,8 @@ typedef enum
|
||||||
GST_H265_VIDEO_STATE_GOT_SPS = 1 << 1,
|
GST_H265_VIDEO_STATE_GOT_SPS = 1 << 1,
|
||||||
GST_H265_VIDEO_STATE_GOT_PPS = 1 << 2,
|
GST_H265_VIDEO_STATE_GOT_PPS = 1 << 2,
|
||||||
GST_H265_VIDEO_STATE_GOT_SLICE = 1 << 3,
|
GST_H265_VIDEO_STATE_GOT_SLICE = 1 << 3,
|
||||||
|
GST_H265_VIDEO_STATE_GOT_I_FRAME = 1 << 4, /* persistent across SPS */
|
||||||
|
GST_H265_VIDEO_STATE_GOT_P_SLICE = 1 << 5, /* predictive (all non-intra) */
|
||||||
|
|
||||||
GST_H265_VIDEO_STATE_VALID_PICTURE_HEADERS =
|
GST_H265_VIDEO_STATE_VALID_PICTURE_HEADERS =
|
||||||
(GST_H265_VIDEO_STATE_GOT_SPS | GST_H265_VIDEO_STATE_GOT_PPS),
|
(GST_H265_VIDEO_STATE_GOT_SPS | GST_H265_VIDEO_STATE_GOT_PPS),
|
||||||
|
@ -583,6 +585,11 @@ ensure_sps (GstVaapiDecoderH265 * decoder, GstH265SPS * sps)
|
||||||
GstVaapiDecoderH265Private *const priv = &decoder->priv;
|
GstVaapiDecoderH265Private *const priv = &decoder->priv;
|
||||||
GstVaapiParserInfoH265 *const pi = priv->sps[sps->id];
|
GstVaapiParserInfoH265 *const pi = priv->sps[sps->id];
|
||||||
|
|
||||||
|
/* Propagate "got I-frame" state to the next SPS unit if the current
|
||||||
|
* sequence was not ended */
|
||||||
|
if (pi && priv->active_sps)
|
||||||
|
pi->state |= (priv->active_sps->state & GST_H265_VIDEO_STATE_GOT_I_FRAME);
|
||||||
|
|
||||||
gst_vaapi_parser_info_h265_replace (&priv->active_sps, pi);
|
gst_vaapi_parser_info_h265_replace (&priv->active_sps, pi);
|
||||||
return pi ? &pi->data.sps : NULL;
|
return pi ? &pi->data.sps : NULL;
|
||||||
}
|
}
|
||||||
|
@ -1317,12 +1324,20 @@ static GstVaapiDecoderStatus
|
||||||
decode_current_picture (GstVaapiDecoderH265 * decoder)
|
decode_current_picture (GstVaapiDecoderH265 * decoder)
|
||||||
{
|
{
|
||||||
GstVaapiDecoderH265Private *const priv = &decoder->priv;
|
GstVaapiDecoderH265Private *const priv = &decoder->priv;
|
||||||
|
GstVaapiParserInfoH265 *const sps_pi = decoder->priv.active_sps;
|
||||||
GstVaapiPictureH265 *const picture = priv->current_picture;
|
GstVaapiPictureH265 *const picture = priv->current_picture;
|
||||||
|
|
||||||
if (!is_valid_state (priv->decoder_state, GST_H265_VIDEO_STATE_VALID_PICTURE)) {
|
if (!is_valid_state (priv->decoder_state, GST_H265_VIDEO_STATE_VALID_PICTURE)) {
|
||||||
goto drop_frame;
|
goto drop_frame;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
priv->decoder_state |= sps_pi->state;
|
||||||
|
if (!(priv->decoder_state & GST_H265_VIDEO_STATE_GOT_I_FRAME)) {
|
||||||
|
if (priv->decoder_state & GST_H265_VIDEO_STATE_GOT_P_SLICE)
|
||||||
|
goto drop_frame;
|
||||||
|
sps_pi->state |= GST_H265_VIDEO_STATE_GOT_I_FRAME;
|
||||||
|
}
|
||||||
|
|
||||||
priv->decoder_state = 0;
|
priv->decoder_state = 0;
|
||||||
/* FIXME: Use SEI header values */
|
/* FIXME: Use SEI header values */
|
||||||
priv->pic_structure = GST_VAAPI_PICTURE_STRUCTURE_FRAME;
|
priv->pic_structure = GST_VAAPI_PICTURE_STRUCTURE_FRAME;
|
||||||
|
@ -1459,6 +1474,8 @@ parse_slice (GstVaapiDecoderH265 * decoder, GstVaapiDecoderUnit * unit)
|
||||||
return get_status (result);
|
return get_status (result);
|
||||||
|
|
||||||
priv->parser_state |= GST_H265_VIDEO_STATE_GOT_SLICE;
|
priv->parser_state |= GST_H265_VIDEO_STATE_GOT_SLICE;
|
||||||
|
if (!GST_H265_IS_I_SLICE (slice_hdr))
|
||||||
|
priv->parser_state |= GST_H265_VIDEO_STATE_GOT_P_SLICE;
|
||||||
return GST_VAAPI_DECODER_STATUS_SUCCESS;
|
return GST_VAAPI_DECODER_STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1548,9 +1565,15 @@ static GstVaapiDecoderStatus
|
||||||
decode_sequence_end (GstVaapiDecoderH265 * decoder)
|
decode_sequence_end (GstVaapiDecoderH265 * decoder)
|
||||||
{
|
{
|
||||||
GstVaapiDecoderStatus status;
|
GstVaapiDecoderStatus status;
|
||||||
|
GstVaapiParserInfoH265 *const sps_pi = decoder->priv.active_sps;
|
||||||
|
|
||||||
GST_DEBUG ("decode sequence-end");
|
GST_DEBUG ("decode sequence-end");
|
||||||
|
|
||||||
|
/* Sequence ended, don't try to propagate "got I-frame" state beyond
|
||||||
|
* this point */
|
||||||
|
if (sps_pi)
|
||||||
|
sps_pi->state &= ~GST_H265_VIDEO_STATE_GOT_I_FRAME;
|
||||||
|
|
||||||
status = decode_current_picture (decoder);
|
status = decode_current_picture (decoder);
|
||||||
if (status != GST_VAAPI_DECODER_STATUS_SUCCESS)
|
if (status != GST_VAAPI_DECODER_STATUS_SUCCESS)
|
||||||
return status;
|
return status;
|
||||||
|
@ -2718,7 +2741,6 @@ decode_slice (GstVaapiDecoderH265 * decoder, GstVaapiDecoderUnit * unit)
|
||||||
|
|
||||||
gst_vaapi_picture_add_slice (GST_VAAPI_PICTURE_CAST (picture), slice);
|
gst_vaapi_picture_add_slice (GST_VAAPI_PICTURE_CAST (picture), slice);
|
||||||
picture->last_slice_hdr = slice_hdr;
|
picture->last_slice_hdr = slice_hdr;
|
||||||
priv->decoder_state |= GST_H265_VIDEO_STATE_GOT_SLICE;
|
|
||||||
return GST_VAAPI_DECODER_STATUS_SUCCESS;
|
return GST_VAAPI_DECODER_STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue