mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-27 20:21:24 +00:00
decoder: hevc: Fix decoding when there are RASL pictures present.
-- Set NoRaslOutputFlag based on EOS and EOB Nal units -- Fix PicOutputFlag setting for RASL picture -- Fix prev_poc_lsb/prev_poc_msb calculation -- Drop the RASL frames if NoRaslOutputFlag is TRUE for the associated IRAP picture -- Fixed couple of crashes and added cosmetics
This commit is contained in:
parent
b5425da1de
commit
2ddfcd8bc3
1 changed files with 62 additions and 34 deletions
|
@ -411,6 +411,9 @@ struct _GstVaapiDecoderH265Private
|
||||||
guint is_hvcC:1;
|
guint is_hvcC:1;
|
||||||
guint has_context:1;
|
guint has_context:1;
|
||||||
guint progressive_sequence:1;
|
guint progressive_sequence:1;
|
||||||
|
guint new_bitstream:1;
|
||||||
|
guint prev_nal_is_eos:1; /*previous nal type is EOS */
|
||||||
|
guint associated_irap_NoRaslOutputFlag:1;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -467,6 +470,14 @@ nal_is_bla (guint8 nal_type)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
nal_is_cra (guint8 nal_type)
|
||||||
|
{
|
||||||
|
if (nal_type == GST_H265_NAL_SLICE_CRA_NUT)
|
||||||
|
return TRUE;
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
nal_is_radl (guint8 nal_type)
|
nal_is_radl (guint8 nal_type)
|
||||||
{
|
{
|
||||||
|
@ -829,24 +840,30 @@ dpb_add (GstVaapiDecoderH265 * decoder, GstVaapiPictureH265 * picture)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* C.5.2.2 */
|
||||||
static gboolean
|
static gboolean
|
||||||
dpb_init (GstVaapiDecoderH265 * decoder, GstVaapiPictureH265 * picture,
|
dpb_init (GstVaapiDecoderH265 * decoder, GstVaapiPictureH265 * picture,
|
||||||
GstVaapiParserInfoH265 * pi)
|
GstVaapiParserInfoH265 * pi)
|
||||||
{
|
{
|
||||||
GstVaapiDecoderH265Private *const priv = &decoder->priv;
|
GstVaapiDecoderH265Private *const priv = &decoder->priv;
|
||||||
|
GstH265SliceHdr *const slice_hdr = &pi->data.slice_hdr;
|
||||||
GstH265SPS *const sps = get_sps (decoder);
|
GstH265SPS *const sps = get_sps (decoder);
|
||||||
|
|
||||||
/* Fixme: Not required?? */
|
if (nal_is_irap (pi->nalu.type)
|
||||||
if (nal_is_idr (pi->nalu.type))
|
&& picture->NoRaslOutputFlag && !priv->new_bitstream) {
|
||||||
while (dpb_bump (decoder, picture));
|
|
||||||
|
if (pi->nalu.type == GST_H265_NAL_SLICE_CRA_NUT)
|
||||||
|
picture->NoOutputOfPriorPicsFlag = 1;
|
||||||
|
else
|
||||||
|
picture->NoOutputOfPriorPicsFlag =
|
||||||
|
slice_hdr->no_output_of_prior_pics_flag;
|
||||||
|
|
||||||
/* C.5.2.2 */
|
|
||||||
if (picture->IntraPicFlag &&
|
|
||||||
picture->NoRaslOutputFlag /*&& Fixme: Not picture0 */ ) {
|
|
||||||
if (picture->NoOutputOfPriorPicsFlag)
|
if (picture->NoOutputOfPriorPicsFlag)
|
||||||
dpb_clear (decoder, TRUE);
|
dpb_clear (decoder, TRUE);
|
||||||
else
|
else {
|
||||||
dpb_clear (decoder, FALSE);
|
dpb_clear (decoder, FALSE);
|
||||||
|
while (dpb_bump (decoder, NULL));
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
dpb_clear (decoder, FALSE);
|
dpb_clear (decoder, FALSE);
|
||||||
while ((dpb_get_num_need_output (decoder) >
|
while ((dpb_get_num_need_output (decoder) >
|
||||||
|
@ -961,6 +978,8 @@ gst_vaapi_decoder_h265_create (GstVaapiDecoder * base_decoder)
|
||||||
priv->entrypoint = GST_VAAPI_ENTRYPOINT_VLD;
|
priv->entrypoint = GST_VAAPI_ENTRYPOINT_VLD;
|
||||||
priv->chroma_type = GST_VAAPI_CHROMA_TYPE_YUV420;
|
priv->chroma_type = GST_VAAPI_CHROMA_TYPE_YUV420;
|
||||||
priv->progressive_sequence = TRUE;
|
priv->progressive_sequence = TRUE;
|
||||||
|
priv->new_bitstream = TRUE;
|
||||||
|
priv->prev_nal_is_eos = FALSE;
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1457,7 +1476,7 @@ init_picture_poc (GstVaapiDecoderH265 * decoder,
|
||||||
priv->prev_poc_lsb = priv->poc_lsb;
|
priv->prev_poc_lsb = priv->poc_lsb;
|
||||||
priv->prev_poc_msb = priv->poc_msb;
|
priv->prev_poc_msb = priv->poc_msb;
|
||||||
|
|
||||||
if (!nal_is_irap (nal_type) && picture->NoRaslOutputFlag) {
|
if (!(nal_is_irap (nal_type) && picture->NoRaslOutputFlag)) {
|
||||||
priv->prev_poc_lsb = priv->prev_tid0pic_poc_lsb;
|
priv->prev_poc_lsb = priv->prev_tid0pic_poc_lsb;
|
||||||
priv->prev_poc_msb = priv->prev_tid0pic_poc_msb;
|
priv->prev_poc_msb = priv->prev_tid0pic_poc_msb;
|
||||||
}
|
}
|
||||||
|
@ -1597,6 +1616,7 @@ static gboolean
|
||||||
init_picture (GstVaapiDecoderH265 * decoder,
|
init_picture (GstVaapiDecoderH265 * decoder,
|
||||||
GstVaapiPictureH265 * picture, GstVaapiParserInfoH265 * pi)
|
GstVaapiPictureH265 * picture, GstVaapiParserInfoH265 * pi)
|
||||||
{
|
{
|
||||||
|
GstVaapiDecoderH265Private *const priv = &decoder->priv;
|
||||||
GstVaapiPicture *const base_picture = &picture->base;
|
GstVaapiPicture *const base_picture = &picture->base;
|
||||||
GstH265SliceHdr *const slice_hdr = &pi->data.slice_hdr;
|
GstH265SliceHdr *const slice_hdr = &pi->data.slice_hdr;
|
||||||
|
|
||||||
|
@ -1608,9 +1628,6 @@ init_picture (GstVaapiDecoderH265 * decoder,
|
||||||
GST_VAAPI_PICTURE_FLAG_SET (picture, GST_VAAPI_PICTURE_FLAG_IDR);
|
GST_VAAPI_PICTURE_FLAG_SET (picture, GST_VAAPI_PICTURE_FLAG_IDR);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (nal_is_irap (pi->nalu.type))
|
|
||||||
picture->IntraPicFlag = TRUE;
|
|
||||||
|
|
||||||
if (pi->nalu.type >= GST_H265_NAL_SLICE_BLA_W_LP &&
|
if (pi->nalu.type >= GST_H265_NAL_SLICE_BLA_W_LP &&
|
||||||
pi->nalu.type <= GST_H265_NAL_SLICE_CRA_NUT)
|
pi->nalu.type <= GST_H265_NAL_SLICE_CRA_NUT)
|
||||||
picture->RapPicFlag = TRUE;
|
picture->RapPicFlag = TRUE;
|
||||||
|
@ -1622,34 +1639,28 @@ init_picture (GstVaapiDecoderH265 * decoder,
|
||||||
/*NoRaslOutputFlag ==1 if the current picture is
|
/*NoRaslOutputFlag ==1 if the current picture is
|
||||||
1) an IDR picture
|
1) an IDR picture
|
||||||
2) a BLA picture
|
2) a BLA picture
|
||||||
3) a CRA picture that is the first access unit in the bitstream (Fixme: Not yet added)
|
3) a CRA picture that is the first access unit in the bitstream
|
||||||
4) first picture that follows an end of sequence NAL unit in decoding order (Fixme: Not yet added)
|
4) first picture that follows an end of sequence NAL unit in decoding order
|
||||||
5) has HandleCraAsBlaFlag == 1 (Fixme: Not yet added)
|
5) has HandleCraAsBlaFlag == 1 (set by external means, so not considering )
|
||||||
*/
|
*/
|
||||||
if (nal_is_idr (pi->nalu.type) || nal_is_bla (pi->nalu.type) ||
|
if (nal_is_idr (pi->nalu.type) || nal_is_bla (pi->nalu.type) ||
|
||||||
pi->nalu.type == GST_H265_NAL_SLICE_CRA_NUT) {
|
(nal_is_cra (pi->nalu.type) && priv->new_bitstream)
|
||||||
|
|| priv->prev_nal_is_eos) {
|
||||||
picture->NoRaslOutputFlag = 1;
|
picture->NoRaslOutputFlag = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (nal_is_rasl (pi->
|
if (nal_is_irap (pi->nalu.type)) {
|
||||||
nalu.type) /* Fixme: || NoRaslOutPutFlag of asso irap=1 */ )
|
picture->IntraPicFlag = TRUE;
|
||||||
|
priv->associated_irap_NoRaslOutputFlag = picture->NoRaslOutputFlag;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (nal_is_rasl (pi->nalu.type) && priv->associated_irap_NoRaslOutputFlag)
|
||||||
picture->output_flag = FALSE;
|
picture->output_flag = FALSE;
|
||||||
else
|
else
|
||||||
picture->output_flag = slice_hdr->pic_output_flag;
|
picture->output_flag = slice_hdr->pic_output_flag;
|
||||||
|
|
||||||
init_picture_poc (decoder, picture, pi);
|
init_picture_poc (decoder, picture, pi);
|
||||||
|
|
||||||
/* C.3.2 */
|
|
||||||
if (nal_is_irap (pi->nalu.type)
|
|
||||||
&& picture->NoRaslOutputFlag && picture->poc /*&& Fixme: Not picture0 */ ) {
|
|
||||||
|
|
||||||
if (pi->nalu.type == GST_H265_NAL_SLICE_CRA_NUT)
|
|
||||||
picture->NoOutputOfPriorPicsFlag = 1;
|
|
||||||
else
|
|
||||||
picture->NoOutputOfPriorPicsFlag =
|
|
||||||
slice_hdr->no_output_of_prior_pics_flag;
|
|
||||||
}
|
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1878,7 +1889,7 @@ has_entry_in_rps (GstVaapiPictureH265 * dpb_pic,
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
for (i = 0; i < rps_list_length; i++) {
|
for (i = 0; i < rps_list_length; i++) {
|
||||||
if (rps_list[i]->poc == dpb_pic->poc)
|
if (rps_list[i] && rps_list[i]->poc == dpb_pic->poc)
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
@ -2006,6 +2017,7 @@ derive_and_mark_rps (GstVaapiDecoderH265 * decoder,
|
||||||
priv->NumPocStFoll))
|
priv->NumPocStFoll))
|
||||||
gst_vaapi_picture_h265_set_reference (dpb_pic, 0);
|
gst_vaapi_picture_h265_set_reference (dpb_pic, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Decoding process for reference picture set (8.3.2) */
|
/* Decoding process for reference picture set (8.3.2) */
|
||||||
|
@ -2170,13 +2182,16 @@ decode_picture (GstVaapiDecoderH265 * decoder, GstVaapiDecoderUnit * unit)
|
||||||
if (!init_picture (decoder, picture, pi))
|
if (!init_picture (decoder, picture, pi))
|
||||||
return GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN;
|
return GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN;
|
||||||
|
|
||||||
|
/* Drop all RASL pictures having NoRaslOutputFlag is TRUE for the
|
||||||
|
* associated IRAP picture */
|
||||||
|
if (nal_is_rasl (pi->nalu.type) && priv->associated_irap_NoRaslOutputFlag) {
|
||||||
|
gst_vaapi_picture_replace (&priv->current_picture, NULL);
|
||||||
|
return (GstVaapiDecoderStatus)GST_VAAPI_DECODER_STATUS_DROP_FRAME;
|
||||||
|
}
|
||||||
|
|
||||||
if (!decode_ref_pic_set (decoder, picture, pi))
|
if (!decode_ref_pic_set (decoder, picture, pi))
|
||||||
return GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN;
|
return GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN;
|
||||||
|
|
||||||
/* Fixme: if pic is BLA or CRA,and have NoRaslOutputFlag == 1,
|
|
||||||
invoke 8.3.3 as described in specification for generating
|
|
||||||
unavailable reference pictures */
|
|
||||||
|
|
||||||
if (!dpb_init (decoder, picture, pi))
|
if (!dpb_init (decoder, picture, pi))
|
||||||
return GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN;
|
return GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN;
|
||||||
|
|
||||||
|
@ -2523,10 +2538,22 @@ decode_unit (GstVaapiDecoderH265 * decoder, GstVaapiDecoderUnit * unit)
|
||||||
case GST_H265_NAL_SLICE_IDR_W_RADL:
|
case GST_H265_NAL_SLICE_IDR_W_RADL:
|
||||||
case GST_H265_NAL_SLICE_IDR_N_LP:
|
case GST_H265_NAL_SLICE_IDR_N_LP:
|
||||||
case GST_H265_NAL_SLICE_CRA_NUT:
|
case GST_H265_NAL_SLICE_CRA_NUT:
|
||||||
|
/* slice decoding will get started only after completing all the
|
||||||
|
initialization routines for each picture which is hanlding in
|
||||||
|
start_frame() call back, so the new_bitstream and prev_nal_is_eos
|
||||||
|
flags will have effects starting from the next frame onwards */
|
||||||
|
priv->new_bitstream = FALSE;
|
||||||
|
priv->prev_nal_is_eos = FALSE;
|
||||||
status = decode_slice (decoder, unit);
|
status = decode_slice (decoder, unit);
|
||||||
break;
|
break;
|
||||||
case GST_H265_NAL_EOS:
|
|
||||||
case GST_H265_NAL_EOB:
|
case GST_H265_NAL_EOB:
|
||||||
|
priv->new_bitstream = TRUE;
|
||||||
|
GST_DEBUG
|
||||||
|
("Next AU(if there is any) will be the begining of new bitstream");
|
||||||
|
status = decode_sequence_end (decoder);
|
||||||
|
break;
|
||||||
|
case GST_H265_NAL_EOS:
|
||||||
|
priv->prev_nal_is_eos = TRUE;
|
||||||
status = decode_sequence_end (decoder);
|
status = decode_sequence_end (decoder);
|
||||||
break;
|
break;
|
||||||
case GST_H265_NAL_SUFFIX_SEI:
|
case GST_H265_NAL_SUFFIX_SEI:
|
||||||
|
@ -2772,6 +2799,7 @@ gst_vaapi_decoder_h265_parse (GstVaapiDecoder * base_decoder,
|
||||||
flags |= GST_VAAPI_DECODER_UNIT_FLAG_FRAME_END |
|
flags |= GST_VAAPI_DECODER_UNIT_FLAG_FRAME_END |
|
||||||
GST_VAAPI_DECODER_UNIT_FLAG_AU_END;
|
GST_VAAPI_DECODER_UNIT_FLAG_AU_END;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (pi->nalu.type) {
|
switch (pi->nalu.type) {
|
||||||
case GST_H265_NAL_AUD:
|
case GST_H265_NAL_AUD:
|
||||||
flags |= GST_VAAPI_DECODER_UNIT_FLAG_AU_START;
|
flags |= GST_VAAPI_DECODER_UNIT_FLAG_AU_START;
|
||||||
|
|
Loading…
Reference in a new issue