[FFmpeg-cvslog] hevc: only write to max_ra and pocTid0 in the first slice.

Ronald S. Bultje git at videolan.org
Thu Apr 13 03:31:12 EEST 2017


ffmpeg | branch: release/3.3 | Ronald S. Bultje <rsbultje at gmail.com> | Mon Apr  3 09:51:10 2017 -0400| [d1cae50a046763bf14d74e899d90e4ef0be5b551] | committer: Michael Niedermayer

hevc: only write to max_ra and pocTid0 in the first slice.

Values from subsequent values are guaranteed to be identical (since
poc and nal_unit_type are checked to be the same between slices), so
this doesn't affect output in any way, but does resolve the remaining
reported race conditions (by tsan) in fate-hevc.

In practice, this fixes tsan warnings like this:

WARNING: ThreadSanitizer: data race (pid=25334)
  Read of size 4 at 0x7d9c0001adcc by main thread (mutexes: write M1386):
    #0 hevc_update_thread_context src/libavcodec/hevcdec.c:3310 (ffmpeg+0x000000b41c7c)
[..]
  Previous write of size 4 at 0x7d9c0001adcc by thread T1 (mutexes: write M1383):
    #0 hls_slice_header src/libavcodec/hevcdec.c:596 (ffmpeg+0x000000b43a22)

(cherry picked from commit 1f50baa2b2da7fdbfccf0662883f38a763ff6619)
Signed-off-by: Michael Niedermayer <michael at niedermayer.cc>

> http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=d1cae50a046763bf14d74e899d90e4ef0be5b551
---

 libavcodec/hevcdec.c | 32 ++++++++++++++++----------------
 1 file changed, 16 insertions(+), 16 deletions(-)

diff --git a/libavcodec/hevcdec.c b/libavcodec/hevcdec.c
index ef21595c44..f9e8ff0c9f 100644
--- a/libavcodec/hevcdec.c
+++ b/libavcodec/hevcdec.c
@@ -585,7 +585,7 @@ static int hls_slice_header(HEVCContext *s)
         }
 
         /* 8.3.1 */
-        if (s->temporal_id == 0 &&
+        if (sh->first_slice_in_pic_flag && s->temporal_id == 0 &&
             s->nal_unit_type != HEVC_NAL_TRAIL_N &&
             s->nal_unit_type != HEVC_NAL_TSA_N   &&
             s->nal_unit_type != HEVC_NAL_STSA_N  &&
@@ -2771,25 +2771,25 @@ static int decode_nal_unit(HEVCContext *s, const H2645NAL *nal)
         if (ret < 0)
             return ret;
 
-        if (s->max_ra == INT_MAX) {
-            if (s->nal_unit_type == HEVC_NAL_CRA_NUT || IS_BLA(s)) {
-                s->max_ra = s->poc;
+        if (s->sh.first_slice_in_pic_flag) {
+            if (s->max_ra == INT_MAX) {
+                if (s->nal_unit_type == HEVC_NAL_CRA_NUT || IS_BLA(s)) {
+                    s->max_ra = s->poc;
+                } else {
+                    if (IS_IDR(s))
+                        s->max_ra = INT_MIN;
+                }
+            }
+
+            if ((s->nal_unit_type == HEVC_NAL_RASL_R || s->nal_unit_type == HEVC_NAL_RASL_N) &&
+                s->poc <= s->max_ra) {
+                s->is_decoded = 0;
+                break;
             } else {
-                if (IS_IDR(s))
+                if (s->nal_unit_type == HEVC_NAL_RASL_R && s->poc > s->max_ra)
                     s->max_ra = INT_MIN;
             }
-        }
-
-        if ((s->nal_unit_type == HEVC_NAL_RASL_R || s->nal_unit_type == HEVC_NAL_RASL_N) &&
-            s->poc <= s->max_ra) {
-            s->is_decoded = 0;
-            break;
-        } else {
-            if (s->nal_unit_type == HEVC_NAL_RASL_R && s->poc > s->max_ra)
-                s->max_ra = INT_MIN;
-        }
 
-        if (s->sh.first_slice_in_pic_flag) {
             ret = hevc_frame_start(s);
             if (ret < 0)
                 return ret;



More information about the ffmpeg-cvslog mailing list