diff options
author | Sreerenj Balachandran <sreerenj.balachandran@intel.com> | 2015-04-16 14:13:21 +0300 |
---|---|---|
committer | Sreerenj Balachandran <sreerenj.balachandran@intel.com> | 2015-04-16 14:13:21 +0300 |
commit | 2ddfcd8bc373e093d446c0f74ab52902932534cf (patch) | |
tree | 3deaac2e2e508399c0f7aa5d36635d871cc529cb /gst-libs | |
parent | b5425da1de221b678c8819df543f2775f1cf1ad7 (diff) |
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
Diffstat (limited to 'gst-libs')
-rw-r--r-- | gst-libs/gst/vaapi/gstvaapidecoder_h265.c | 96 |
1 files changed, 62 insertions, 34 deletions
diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_h265.c b/gst-libs/gst/vaapi/gstvaapidecoder_h265.c index 72a1bff4..764fbd82 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_h265.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_h265.c @@ -411,6 +411,9 @@ struct _GstVaapiDecoderH265Private guint is_hvcC:1; guint has_context: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; }; /** @@ -468,6 +471,14 @@ nal_is_bla (guint8 nal_type) } static gboolean +nal_is_cra (guint8 nal_type) +{ + if (nal_type == GST_H265_NAL_SLICE_CRA_NUT) + return TRUE; + return FALSE; +} + +static gboolean nal_is_radl (guint8 nal_type) { if ((nal_type >= GST_H265_NAL_SLICE_RADL_N) && @@ -829,24 +840,30 @@ dpb_add (GstVaapiDecoderH265 * decoder, GstVaapiPictureH265 * picture) } +/* C.5.2.2 */ static gboolean dpb_init (GstVaapiDecoderH265 * decoder, GstVaapiPictureH265 * picture, GstVaapiParserInfoH265 * pi) { GstVaapiDecoderH265Private *const priv = &decoder->priv; + GstH265SliceHdr *const slice_hdr = &pi->data.slice_hdr; GstH265SPS *const sps = get_sps (decoder); - /* Fixme: Not required?? */ - if (nal_is_idr (pi->nalu.type)) - while (dpb_bump (decoder, picture)); + if (nal_is_irap (pi->nalu.type) + && picture->NoRaslOutputFlag && !priv->new_bitstream) { + + 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) dpb_clear (decoder, TRUE); - else + else { dpb_clear (decoder, FALSE); + while (dpb_bump (decoder, NULL)); + } } else { dpb_clear (decoder, FALSE); 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->chroma_type = GST_VAAPI_CHROMA_TYPE_YUV420; priv->progressive_sequence = TRUE; + priv->new_bitstream = TRUE; + priv->prev_nal_is_eos = FALSE; return TRUE; } @@ -1457,7 +1476,7 @@ init_picture_poc (GstVaapiDecoderH265 * decoder, priv->prev_poc_lsb = priv->poc_lsb; 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_msb = priv->prev_tid0pic_poc_msb; } @@ -1597,6 +1616,7 @@ static gboolean init_picture (GstVaapiDecoderH265 * decoder, GstVaapiPictureH265 * picture, GstVaapiParserInfoH265 * pi) { + GstVaapiDecoderH265Private *const priv = &decoder->priv; GstVaapiPicture *const base_picture = &picture->base; 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); } - if (nal_is_irap (pi->nalu.type)) - picture->IntraPicFlag = TRUE; - if (pi->nalu.type >= GST_H265_NAL_SLICE_BLA_W_LP && pi->nalu.type <= GST_H265_NAL_SLICE_CRA_NUT) picture->RapPicFlag = TRUE; @@ -1622,34 +1639,28 @@ init_picture (GstVaapiDecoderH265 * decoder, /*NoRaslOutputFlag ==1 if the current picture is 1) an IDR picture 2) a BLA picture - 3) a CRA picture that is the first access unit in the bitstream (Fixme: Not yet added) - 4) first picture that follows an end of sequence NAL unit in decoding order (Fixme: Not yet added) - 5) has HandleCraAsBlaFlag == 1 (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 + 5) has HandleCraAsBlaFlag == 1 (set by external means, so not considering ) */ 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; } - if (nal_is_rasl (pi-> - nalu.type) /* Fixme: || NoRaslOutPutFlag of asso irap=1 */ ) + if (nal_is_irap (pi->nalu.type)) { + picture->IntraPicFlag = TRUE; + priv->associated_irap_NoRaslOutputFlag = picture->NoRaslOutputFlag; + } + + if (nal_is_rasl (pi->nalu.type) && priv->associated_irap_NoRaslOutputFlag) picture->output_flag = FALSE; else picture->output_flag = slice_hdr->pic_output_flag; 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; } @@ -1878,7 +1889,7 @@ has_entry_in_rps (GstVaapiPictureH265 * dpb_pic, return FALSE; 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 FALSE; @@ -2006,6 +2017,7 @@ derive_and_mark_rps (GstVaapiDecoderH265 * decoder, priv->NumPocStFoll)) gst_vaapi_picture_h265_set_reference (dpb_pic, 0); } + } /* 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)) 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)) 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)) 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_N_LP: 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); break; - case GST_H265_NAL_EOS: 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); break; 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 | GST_VAAPI_DECODER_UNIT_FLAG_AU_END; } + switch (pi->nalu.type) { case GST_H265_NAL_AUD: flags |= GST_VAAPI_DECODER_UNIT_FLAG_AU_START; |