hevc: properly handle no_rasl_output_flag when removing pictures from the DPB
authorHendrik Leppkes <h.leppkes@gmail.com>
Sat, 12 Sep 2015 19:50:24 +0000 (21:50 +0200)
committerHendrik Leppkes <h.leppkes@gmail.com>
Sat, 19 Sep 2015 22:17:32 +0000 (00:17 +0200)
Fixes ticket #4185.

Reviewed-By: Mickael Raulet <Mickael.Raulet@insa-rennes.fr>
Signed-off-by: Hendrik Leppkes <h.leppkes@gmail.com>
libavcodec/hevc.c
libavcodec/hevc.h
libavcodec/hevc_refs.c

index 8d4db22..e45f4a4 100644 (file)
@@ -809,6 +809,8 @@ static int hls_slice_header(HEVCContext *s)
     s->HEVClc->tu.cu_qp_offset_cb = 0;
     s->HEVClc->tu.cu_qp_offset_cr = 0;
 
+    s->no_rasl_output_flag = IS_IDR(s) || IS_BLA(s) || (s->nal_unit_type == NAL_CRA_NUT && s->last_eos);
+
     return 0;
 }
 
@@ -3135,6 +3137,7 @@ static int hevc_update_thread_context(AVCodecContext *dst,
     s->pocTid0    = s0->pocTid0;
     s->max_ra     = s0->max_ra;
     s->eos        = s0->eos;
+    s->no_rasl_output_flag = s0->no_rasl_output_flag;
 
     s->is_nalff        = s0->is_nalff;
     s->nal_length_size = s0->nal_length_size;
@@ -3239,6 +3242,7 @@ static av_cold int hevc_decode_init(AVCodecContext *avctx)
 
     s->enable_parallel_tiles = 0;
     s->picture_struct = 0;
+    s->eos = 1;
 
     if(avctx->active_thread_type & FF_THREAD_SLICE)
         s->threads_number = avctx->thread_count;
@@ -3280,6 +3284,7 @@ static void hevc_decode_flush(AVCodecContext *avctx)
     HEVCContext *s = avctx->priv_data;
     ff_hevc_flush_dpb(s);
     s->max_ra = INT_MAX;
+    s->eos = 1;
 }
 
 #define OFFSET(x) offsetof(HEVCContext, x)
index 32d6da9..66b9a2f 100644 (file)
@@ -866,6 +866,7 @@ typedef struct HEVCContext {
     int bs_height;
 
     int is_decoded;
+    int no_rasl_output_flag;
 
     HEVCPredContext hpc;
     HEVCDSPContext hevcdsp;
index e85ce89..611ad45 100644 (file)
@@ -174,7 +174,7 @@ int ff_hevc_output_frame(HEVCContext *s, AVFrame *out, int flush)
         int min_poc   = INT_MAX;
         int i, min_idx, ret;
 
-        if (s->sh.no_output_of_prior_pics_flag == 1) {
+        if (s->sh.no_output_of_prior_pics_flag == 1 && s->no_rasl_output_flag == 1) {
             for (i = 0; i < FF_ARRAY_ELEMS(s->DPB); i++) {
                 HEVCFrame *frame = &s->DPB[i];
                 if (!(frame->flags & HEVC_FRAME_FLAG_BUMPING) && frame->poc != s->poc &&