[FFmpeg-cvslog] Merge commit 'ed9a20ebe4a89de119ea97bdccf688ece8c6648c' into merge-libav-new

Clément Bœsch git at videolan.org
Wed Jun 29 17:36:14 CEST 2016


ffmpeg | branch: master | Clément Bœsch <clement at stupeflix.com> | Wed Jun 29 17:31:44 2016 +0200| [2aff557c6acbce2b2b604c6c620c66c892260062] | committer: Clément Bœsch

Merge commit 'ed9a20ebe4a89de119ea97bdccf688ece8c6648c' into merge-libav-new

* commit 'ed9a20ebe4a89de119ea97bdccf688ece8c6648c':
  h264: split reading the ref list modifications and actually building the ref list

ref_modifications.val are read as u32 instead of u8 in FFmpeg.

Merged-by: Clément Bœsch <clement at stupeflix.com>

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

 libavcodec/h264.h       |    8 +-
 libavcodec/h264_refs.c  |  197 ++++++++++++++++++++++++++---------------------
 libavcodec/h264_slice.c |    3 +
 3 files changed, 119 insertions(+), 89 deletions(-)

diff --git a/libavcodec/h264.h b/libavcodec/h264.h
index 50fd45a..2544e9d 100644
--- a/libavcodec/h264.h
+++ b/libavcodec/h264.h
@@ -406,6 +406,11 @@ typedef struct H264SliceContext {
     H264Ref ref_list[2][48];        /**< 0..15: frame refs, 16..47: mbaff field refs.
                                          *   Reordered version of default_ref_list
                                          *   according to picture reordering in slice header */
+    struct {
+        uint8_t op;
+        uint32_t val;
+    } ref_modifications[2][32];
+    int nb_ref_modifications[2];
 
     const uint8_t *intra_pcm_ptr;
     int16_t *dc_val_base;
@@ -714,7 +719,8 @@ int ff_h264_get_slice_type(const H264SliceContext *sl);
  */
 int ff_h264_alloc_tables(H264Context *h);
 
-int ff_h264_decode_ref_pic_list_reordering(H264Context *h, H264SliceContext *sl);
+int ff_h264_decode_ref_pic_list_reordering(const H264Context *h, H264SliceContext *sl);
+int ff_h264_build_ref_list(H264Context *h, H264SliceContext *sl);
 void ff_h264_remove_all_refs(H264Context *h);
 
 /**
diff --git a/libavcodec/h264_refs.c b/libavcodec/h264_refs.c
index 15957a3..c7676c4 100644
--- a/libavcodec/h264_refs.c
+++ b/libavcodec/h264_refs.c
@@ -295,7 +295,7 @@ static void h264_fill_mbaff_ref_list(H264SliceContext *sl)
     }
 }
 
-int ff_h264_decode_ref_pic_list_reordering(H264Context *h, H264SliceContext *sl)
+int ff_h264_build_ref_list(H264Context *h, H264SliceContext *sl)
 {
     int list, index, pic_structure;
 
@@ -305,102 +305,88 @@ int ff_h264_decode_ref_pic_list_reordering(H264Context *h, H264SliceContext *sl)
     h264_initialise_ref_list(h, sl);
 
     for (list = 0; list < sl->list_count; list++) {
-        if (get_bits1(&sl->gb)) {    // ref_pic_list_modification_flag_l[01]
-            int pred = h->curr_pic_num;
-
-            for (index = 0; ; index++) {
-                unsigned int modification_of_pic_nums_idc = get_ue_golomb_31(&sl->gb);
-                unsigned int pic_id;
-                int i;
-                H264Picture *ref = NULL;
-
-                if (modification_of_pic_nums_idc == 3)
-                    break;
-
-                if (index >= sl->ref_count[list]) {
-                    av_log(h->avctx, AV_LOG_ERROR, "reference count overflow\n");
-                    return -1;
+        int pred = h->curr_pic_num;
+
+        for (index = 0; index < sl->nb_ref_modifications[list]; index++) {
+            unsigned int modification_of_pic_nums_idc = sl->ref_modifications[list][index].op;
+            unsigned int                          val = sl->ref_modifications[list][index].val;
+            unsigned int pic_id;
+            int i;
+            H264Picture *ref = NULL;
+
+            switch (modification_of_pic_nums_idc) {
+            case 0:
+            case 1: {
+                const unsigned int abs_diff_pic_num = val + 1;
+                int frame_num;
+
+                if (abs_diff_pic_num > h->max_pic_num) {
+                    av_log(h->avctx, AV_LOG_ERROR,
+                           "abs_diff_pic_num overflow\n");
+                    return AVERROR_INVALIDDATA;
                 }
 
-                switch (modification_of_pic_nums_idc) {
-                case 0:
-                case 1: {
-                    const unsigned int abs_diff_pic_num = get_ue_golomb_long(&sl->gb) + 1;
-                    int frame_num;
-
-                    if (abs_diff_pic_num > h->max_pic_num) {
-                        av_log(h->avctx, AV_LOG_ERROR,
-                               "abs_diff_pic_num overflow\n");
-                        return AVERROR_INVALIDDATA;
-                    }
-
-                    if (modification_of_pic_nums_idc == 0)
-                        pred -= abs_diff_pic_num;
-                    else
-                        pred += abs_diff_pic_num;
-                    pred &= h->max_pic_num - 1;
-
-                    frame_num = pic_num_extract(h, pred, &pic_structure);
-
-                    for (i = h->short_ref_count - 1; i >= 0; i--) {
-                        ref = h->short_ref[i];
-                        assert(ref->reference);
-                        assert(!ref->long_ref);
-                        if (ref->frame_num == frame_num &&
-                            (ref->reference & pic_structure))
-                            break;
-                    }
-                    if (i >= 0)
-                        ref->pic_id = pred;
-                    break;
+                if (modification_of_pic_nums_idc == 0)
+                    pred -= abs_diff_pic_num;
+                else
+                    pred += abs_diff_pic_num;
+                pred &= h->max_pic_num - 1;
+
+                frame_num = pic_num_extract(h, pred, &pic_structure);
+
+                for (i = h->short_ref_count - 1; i >= 0; i--) {
+                    ref = h->short_ref[i];
+                    assert(ref->reference);
+                    assert(!ref->long_ref);
+                    if (ref->frame_num == frame_num &&
+                        (ref->reference & pic_structure))
+                        break;
                 }
-                case 2: {
-                    int long_idx;
-                    pic_id = get_ue_golomb(&sl->gb); // long_term_pic_idx
+                if (i >= 0)
+                    ref->pic_id = pred;
+                break;
+            }
+            case 2: {
+                int long_idx;
+                pic_id = val; // long_term_pic_idx
 
-                    long_idx = pic_num_extract(h, pic_id, &pic_structure);
+                long_idx = pic_num_extract(h, pic_id, &pic_structure);
 
-                    if (long_idx > 31U) {
-                        av_log(h->avctx, AV_LOG_ERROR,
-                               "long_term_pic_idx overflow\n");
-                        return AVERROR_INVALIDDATA;
-                    }
-                    ref = h->long_ref[long_idx];
-                    assert(!(ref && !ref->reference));
-                    if (ref && (ref->reference & pic_structure) && !mismatches_ref(h, ref)) {
-                        ref->pic_id = pic_id;
-                        assert(ref->long_ref);
-                        i = 0;
-                    } else {
-                        i = -1;
-                    }
-                    break;
-                }
-                default:
+                if (long_idx > 31U) {
                     av_log(h->avctx, AV_LOG_ERROR,
-                           "illegal modification_of_pic_nums_idc %u\n",
-                           modification_of_pic_nums_idc);
+                           "long_term_pic_idx overflow\n");
                     return AVERROR_INVALIDDATA;
                 }
-
-                if (i < 0) {
-                    av_log(h->avctx, AV_LOG_ERROR,
-                           "reference picture missing during reorder\n");
-                    memset(&sl->ref_list[list][index], 0, sizeof(sl->ref_list[0][0])); // FIXME
+                ref = h->long_ref[long_idx];
+                assert(!(ref && !ref->reference));
+                if (ref && (ref->reference & pic_structure)) {
+                    ref->pic_id = pic_id;
+                    assert(ref->long_ref);
+                    i = 0;
                 } else {
-                    for (i = index; i + 1 < sl->ref_count[list]; i++) {
-                        if (sl->ref_list[list][i].parent &&
-                            ref->long_ref == sl->ref_list[list][i].parent->long_ref &&
-                            ref->pic_id   == sl->ref_list[list][i].pic_id)
-                            break;
-                    }
-                    for (; i > index; i--) {
-                        sl->ref_list[list][i] = sl->ref_list[list][i - 1];
-                    }
-                    ref_from_h264pic(&sl->ref_list[list][index], ref);
-                    if (FIELD_PICTURE(h)) {
-                        pic_as_field(&sl->ref_list[list][index], pic_structure);
-                    }
+                    i = -1;
+                }
+                break;
+            }
+            }
+
+            if (i < 0) {
+                av_log(h->avctx, AV_LOG_ERROR,
+                       "reference picture missing during reorder\n");
+                memset(&sl->ref_list[list][index], 0, sizeof(sl->ref_list[0][0])); // FIXME
+            } else {
+                for (i = index; i + 1 < sl->ref_count[list]; i++) {
+                    if (sl->ref_list[list][i].parent &&
+                        ref->long_ref == sl->ref_list[list][i].parent->long_ref &&
+                        ref->pic_id   == sl->ref_list[list][i].pic_id)
+                        break;
+                }
+                for (; i > index; i--) {
+                    sl->ref_list[list][i] = sl->ref_list[list][i - 1];
+                }
+                ref_from_h264pic(&sl->ref_list[list][index], ref);
+                if (FIELD_PICTURE(h)) {
+                    pic_as_field(&sl->ref_list[list][index], pic_structure);
                 }
             }
         }
@@ -429,6 +415,41 @@ int ff_h264_decode_ref_pic_list_reordering(H264Context *h, H264SliceContext *sl)
     return 0;
 }
 
+int ff_h264_decode_ref_pic_list_reordering(const H264Context *h, H264SliceContext *sl)
+{
+    int list, index;
+
+    sl->nb_ref_modifications[0] = 0;
+    sl->nb_ref_modifications[1] = 0;
+
+    for (list = 0; list < sl->list_count; list++) {
+        if (!get_bits1(&sl->gb))    // ref_pic_list_modification_flag_l[01]
+            continue;
+
+        for (index = 0; ; index++) {
+            unsigned int op = get_ue_golomb_31(&sl->gb);
+
+            if (op == 3)
+                break;
+
+            if (index >= sl->ref_count[list]) {
+                av_log(h->avctx, AV_LOG_ERROR, "reference count overflow\n");
+                return AVERROR_INVALIDDATA;
+            } else if (op > 2) {
+                av_log(h->avctx, AV_LOG_ERROR,
+                       "illegal modification_of_pic_nums_idc %u\n",
+                       op);
+                return AVERROR_INVALIDDATA;
+            }
+            sl->ref_modifications[list][index].val = get_ue_golomb_long(&sl->gb);
+            sl->ref_modifications[list][index].op  = op;
+            sl->nb_ref_modifications[list]++;
+        }
+    }
+
+    return 0;
+}
+
 /**
  * Mark a picture as no longer needed for reference. The refmask
  * argument allows unreferencing of individual fields or the whole frame.
diff --git a/libavcodec/h264_slice.c b/libavcodec/h264_slice.c
index 0c36c8f..5cfb34f 100644
--- a/libavcodec/h264_slice.c
+++ b/libavcodec/h264_slice.c
@@ -1597,6 +1597,9 @@ static int h264_slice_header_parse(H264Context *h, H264SliceContext *sl)
            sl->ref_count[1] = sl->ref_count[0] = 0;
            return ret;
        }
+       ret = ff_h264_build_ref_list(h, sl);
+       if (ret < 0)
+           return ret;
     }
 
     if ((pps->weighted_pred && sl->slice_type_nos == AV_PICTURE_TYPE_P) ||


======================================================================

diff --cc libavcodec/h264.h
index 50fd45a,b4e5f3a..2544e9d
--- a/libavcodec/h264.h
+++ b/libavcodec/h264.h
@@@ -406,6 -391,11 +406,11 @@@ typedef struct H264SliceContext 
      H264Ref ref_list[2][48];        /**< 0..15: frame refs, 16..47: mbaff field refs.
                                           *   Reordered version of default_ref_list
                                           *   according to picture reordering in slice header */
+     struct {
+         uint8_t op;
 -        uint8_t val;
++        uint32_t val;
+     } ref_modifications[2][32];
+     int nb_ref_modifications[2];
  
      const uint8_t *intra_pcm_ptr;
      int16_t *dc_val_base;
@@@ -714,7 -661,8 +719,8 @@@ int ff_h264_get_slice_type(const H264Sl
   */
  int ff_h264_alloc_tables(H264Context *h);
  
- int ff_h264_decode_ref_pic_list_reordering(H264Context *h, H264SliceContext *sl);
+ int ff_h264_decode_ref_pic_list_reordering(const H264Context *h, H264SliceContext *sl);
 -int ff_h264_build_ref_list(const H264Context *h, H264SliceContext *sl);
++int ff_h264_build_ref_list(H264Context *h, H264SliceContext *sl);
  void ff_h264_remove_all_refs(H264Context *h);
  
  /**
diff --cc libavcodec/h264_refs.c
index 15957a3,ce3806c..c7676c4
--- a/libavcodec/h264_refs.c
+++ b/libavcodec/h264_refs.c
@@@ -295,7 -252,7 +295,7 @@@ static void h264_fill_mbaff_ref_list(H2
      }
  }
  
- int ff_h264_decode_ref_pic_list_reordering(H264Context *h, H264SliceContext *sl)
 -int ff_h264_build_ref_list(const H264Context *h, H264SliceContext *sl)
++int ff_h264_build_ref_list(H264Context *h, H264SliceContext *sl)
  {
      int list, index, pic_structure;
  
@@@ -305,102 -262,88 +305,88 @@@
      h264_initialise_ref_list(h, sl);
  
      for (list = 0; list < sl->list_count; list++) {
-         if (get_bits1(&sl->gb)) {    // ref_pic_list_modification_flag_l[01]
-             int pred = h->curr_pic_num;
- 
-             for (index = 0; ; index++) {
-                 unsigned int modification_of_pic_nums_idc = get_ue_golomb_31(&sl->gb);
-                 unsigned int pic_id;
-                 int i;
-                 H264Picture *ref = NULL;
- 
-                 if (modification_of_pic_nums_idc == 3)
-                     break;
- 
-                 if (index >= sl->ref_count[list]) {
-                     av_log(h->avctx, AV_LOG_ERROR, "reference count overflow\n");
-                     return -1;
+         int pred = h->curr_pic_num;
+ 
+         for (index = 0; index < sl->nb_ref_modifications[list]; index++) {
+             unsigned int modification_of_pic_nums_idc = sl->ref_modifications[list][index].op;
+             unsigned int                          val = sl->ref_modifications[list][index].val;
+             unsigned int pic_id;
+             int i;
+             H264Picture *ref = NULL;
+ 
+             switch (modification_of_pic_nums_idc) {
+             case 0:
+             case 1: {
+                 const unsigned int abs_diff_pic_num = val + 1;
+                 int frame_num;
+ 
+                 if (abs_diff_pic_num > h->max_pic_num) {
+                     av_log(h->avctx, AV_LOG_ERROR,
+                            "abs_diff_pic_num overflow\n");
+                     return AVERROR_INVALIDDATA;
                  }
  
-                 switch (modification_of_pic_nums_idc) {
-                 case 0:
-                 case 1: {
-                     const unsigned int abs_diff_pic_num = get_ue_golomb_long(&sl->gb) + 1;
-                     int frame_num;
- 
-                     if (abs_diff_pic_num > h->max_pic_num) {
-                         av_log(h->avctx, AV_LOG_ERROR,
-                                "abs_diff_pic_num overflow\n");
-                         return AVERROR_INVALIDDATA;
-                     }
- 
-                     if (modification_of_pic_nums_idc == 0)
-                         pred -= abs_diff_pic_num;
-                     else
-                         pred += abs_diff_pic_num;
-                     pred &= h->max_pic_num - 1;
- 
-                     frame_num = pic_num_extract(h, pred, &pic_structure);
- 
-                     for (i = h->short_ref_count - 1; i >= 0; i--) {
-                         ref = h->short_ref[i];
-                         assert(ref->reference);
-                         assert(!ref->long_ref);
-                         if (ref->frame_num == frame_num &&
-                             (ref->reference & pic_structure))
-                             break;
-                     }
-                     if (i >= 0)
-                         ref->pic_id = pred;
-                     break;
-                 }
-                 case 2: {
-                     int long_idx;
-                     pic_id = get_ue_golomb(&sl->gb); // long_term_pic_idx
- 
-                     long_idx = pic_num_extract(h, pic_id, &pic_structure);
- 
-                     if (long_idx > 31U) {
-                         av_log(h->avctx, AV_LOG_ERROR,
-                                "long_term_pic_idx overflow\n");
-                         return AVERROR_INVALIDDATA;
-                     }
-                     ref = h->long_ref[long_idx];
-                     assert(!(ref && !ref->reference));
-                     if (ref && (ref->reference & pic_structure) && !mismatches_ref(h, ref)) {
-                         ref->pic_id = pic_id;
-                         assert(ref->long_ref);
-                         i = 0;
-                     } else {
-                         i = -1;
-                     }
-                     break;
+                 if (modification_of_pic_nums_idc == 0)
+                     pred -= abs_diff_pic_num;
+                 else
+                     pred += abs_diff_pic_num;
+                 pred &= h->max_pic_num - 1;
+ 
+                 frame_num = pic_num_extract(h, pred, &pic_structure);
+ 
+                 for (i = h->short_ref_count - 1; i >= 0; i--) {
+                     ref = h->short_ref[i];
+                     assert(ref->reference);
+                     assert(!ref->long_ref);
+                     if (ref->frame_num == frame_num &&
+                         (ref->reference & pic_structure))
+                         break;
                  }
-                 default:
+                 if (i >= 0)
+                     ref->pic_id = pred;
+                 break;
+             }
+             case 2: {
+                 int long_idx;
+                 pic_id = val; // long_term_pic_idx
+ 
+                 long_idx = pic_num_extract(h, pic_id, &pic_structure);
+ 
 -                if (long_idx > 31) {
++                if (long_idx > 31U) {
                      av_log(h->avctx, AV_LOG_ERROR,
-                            "illegal modification_of_pic_nums_idc %u\n",
-                            modification_of_pic_nums_idc);
+                            "long_term_pic_idx overflow\n");
                      return AVERROR_INVALIDDATA;
                  }
- 
-                 if (i < 0) {
-                     av_log(h->avctx, AV_LOG_ERROR,
-                            "reference picture missing during reorder\n");
-                     memset(&sl->ref_list[list][index], 0, sizeof(sl->ref_list[0][0])); // FIXME
+                 ref = h->long_ref[long_idx];
+                 assert(!(ref && !ref->reference));
+                 if (ref && (ref->reference & pic_structure)) {
+                     ref->pic_id = pic_id;
+                     assert(ref->long_ref);
+                     i = 0;
                  } else {
-                     for (i = index; i + 1 < sl->ref_count[list]; i++) {
-                         if (sl->ref_list[list][i].parent &&
-                             ref->long_ref == sl->ref_list[list][i].parent->long_ref &&
-                             ref->pic_id   == sl->ref_list[list][i].pic_id)
-                             break;
-                     }
-                     for (; i > index; i--) {
-                         sl->ref_list[list][i] = sl->ref_list[list][i - 1];
-                     }
-                     ref_from_h264pic(&sl->ref_list[list][index], ref);
-                     if (FIELD_PICTURE(h)) {
-                         pic_as_field(&sl->ref_list[list][index], pic_structure);
-                     }
+                     i = -1;
+                 }
+                 break;
+             }
+             }
+ 
+             if (i < 0) {
+                 av_log(h->avctx, AV_LOG_ERROR,
+                        "reference picture missing during reorder\n");
+                 memset(&sl->ref_list[list][index], 0, sizeof(sl->ref_list[0][0])); // FIXME
+             } else {
+                 for (i = index; i + 1 < sl->ref_count[list]; i++) {
+                     if (sl->ref_list[list][i].parent &&
+                         ref->long_ref == sl->ref_list[list][i].parent->long_ref &&
+                         ref->pic_id   == sl->ref_list[list][i].pic_id)
+                         break;
+                 }
+                 for (; i > index; i--) {
+                     sl->ref_list[list][i] = sl->ref_list[list][i - 1];
+                 }
+                 ref_from_h264pic(&sl->ref_list[list][index], ref);
+                 if (FIELD_PICTURE(h)) {
+                     pic_as_field(&sl->ref_list[list][index], pic_structure);
                  }
              }
          }
@@@ -429,6 -366,41 +415,41 @@@
      return 0;
  }
  
+ int ff_h264_decode_ref_pic_list_reordering(const H264Context *h, H264SliceContext *sl)
+ {
+     int list, index;
+ 
+     sl->nb_ref_modifications[0] = 0;
+     sl->nb_ref_modifications[1] = 0;
+ 
+     for (list = 0; list < sl->list_count; list++) {
+         if (!get_bits1(&sl->gb))    // ref_pic_list_modification_flag_l[01]
+             continue;
+ 
+         for (index = 0; ; index++) {
+             unsigned int op = get_ue_golomb_31(&sl->gb);
+ 
+             if (op == 3)
+                 break;
+ 
+             if (index >= sl->ref_count[list]) {
+                 av_log(h->avctx, AV_LOG_ERROR, "reference count overflow\n");
+                 return AVERROR_INVALIDDATA;
+             } else if (op > 2) {
+                 av_log(h->avctx, AV_LOG_ERROR,
+                        "illegal modification_of_pic_nums_idc %u\n",
+                        op);
+                 return AVERROR_INVALIDDATA;
+             }
 -            sl->ref_modifications[list][index].val = get_ue_golomb(&sl->gb);
++            sl->ref_modifications[list][index].val = get_ue_golomb_long(&sl->gb);
+             sl->ref_modifications[list][index].op  = op;
+             sl->nb_ref_modifications[list]++;
+         }
+     }
+ 
+     return 0;
+ }
+ 
  /**
   * Mark a picture as no longer needed for reference. The refmask
   * argument allows unreferencing of individual fields or the whole frame.



More information about the ffmpeg-cvslog mailing list