[FFmpeg-cvslog] h264: move the block starting a new field out of slice_header_parse()

Anton Khirnov git at videolan.org
Wed Jul 27 18:22:27 EEST 2016


ffmpeg | branch: master | Anton Khirnov <anton at khirnov.net> | Tue May 17 14:51:01 2016 +0200| [8d36932c8d33f93ce1afdd5c1f402e7b6655d5ae] | committer: Anton Khirnov

h264: move the block starting a new field out of slice_header_parse()

There is no bitstream parsing in that block and messing with
decoder-global state is not something that belongs into header parsing.

Nothing else in this function depends on the value of current_slice,
except for two validity checks. Those checks are also moved out of
slice_header_parse().

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

 libavcodec/h264_slice.c | 68 ++++++++++++++++++++++++-------------------------
 1 file changed, 33 insertions(+), 35 deletions(-)

diff --git a/libavcodec/h264_slice.c b/libavcodec/h264_slice.c
index 17608b4..c43a0be 100644
--- a/libavcodec/h264_slice.c
+++ b/libavcodec/h264_slice.c
@@ -1177,21 +1177,6 @@ static int h264_slice_header_parse(H264Context *h, H264SliceContext *sl,
 
     sl->first_mb_addr = get_ue_golomb(&sl->gb);
 
-    if (sl->first_mb_addr == 0) { // FIXME better field boundary detection
-        if (h->current_slice && h->cur_pic_ptr && FIELD_PICTURE(h)) {
-            ff_h264_field_end(h, sl, 1);
-        }
-
-        h->current_slice = 0;
-        if (!h->first_field) {
-            if (h->cur_pic_ptr && !h->droppable) {
-                ff_thread_report_progress(&h->cur_pic_ptr->tf, INT_MAX,
-                                          h->picture_structure == PICT_BOTTOM_FIELD);
-            }
-            h->cur_pic_ptr = NULL;
-        }
-    }
-
     slice_type = get_ue_golomb_31(&sl->gb);
     if (slice_type > 9) {
         av_log(h->avctx, AV_LOG_ERROR,
@@ -1226,11 +1211,6 @@ static int h264_slice_header_parse(H264Context *h, H264SliceContext *sl,
                sl->pps_id);
         return AVERROR_INVALIDDATA;
     }
-    if (h->current_slice > 0 &&
-        h->ps.pps != (const PPS*)h->ps.pps_list[sl->pps_id]->data) {
-        av_log(h->avctx, AV_LOG_ERROR, "PPS changed between slices\n");
-        return AVERROR_INVALIDDATA;
-    }
     pps = (const PPS*)h->ps.pps_list[sl->pps_id]->data;
 
     if (!h->ps.sps_list[pps->sps_id]) {
@@ -1265,21 +1245,6 @@ static int h264_slice_header_parse(H264Context *h, H264SliceContext *sl,
     sl->picture_structure      = picture_structure;
     sl->mb_field_decoding_flag = picture_structure != PICT_FRAME;
 
-    if (h->current_slice != 0) {
-        if (h->picture_structure != picture_structure ||
-            h->droppable         != droppable) {
-            av_log(h->avctx, AV_LOG_ERROR,
-                   "Changing field mode (%d -> %d) between slices is not allowed\n",
-                   h->picture_structure, picture_structure);
-            return AVERROR_INVALIDDATA;
-        } else if (!h->cur_pic_ptr) {
-            av_log(h->avctx, AV_LOG_ERROR,
-                   "unset cur_pic_ptr on slice %d\n",
-                   h->current_slice + 1);
-            return AVERROR_INVALIDDATA;
-        }
-    }
-
     if (picture_structure == PICT_FRAME) {
         h->curr_pic_num = h->poc.frame_num;
         h->max_pic_num  = 1 << sps->log2_max_frame_num;
@@ -1430,10 +1395,43 @@ int ff_h264_decode_slice_header(H264Context *h, H264SliceContext *sl,
     if (ret < 0)
         return ret;
 
+    if (sl->first_mb_addr == 0) { // FIXME better field boundary detection
+        if (h->current_slice && h->cur_pic_ptr && FIELD_PICTURE(h)) {
+            ff_h264_field_end(h, sl, 1);
+        }
+
+        h->current_slice = 0;
+        if (!h->first_field) {
+            if (h->cur_pic_ptr && !h->droppable) {
+                ff_thread_report_progress(&h->cur_pic_ptr->tf, INT_MAX,
+                                          h->picture_structure == PICT_BOTTOM_FIELD);
+            }
+            h->cur_pic_ptr = NULL;
+        }
+    }
+
     if (h->current_slice == 0) {
         ret = h264_field_start(h, sl, nal);
         if (ret < 0)
             return ret;
+    } else {
+        if (h->ps.pps != (const PPS*)h->ps.pps_list[sl->pps_id]->data) {
+            av_log(h->avctx, AV_LOG_ERROR, "PPS changed between slices\n");
+            return AVERROR_INVALIDDATA;
+        }
+
+        if (h->picture_structure != sl->picture_structure ||
+            h->droppable         != (nal->ref_idc == 0)) {
+            av_log(h->avctx, AV_LOG_ERROR,
+                   "Changing field mode (%d -> %d) between slices is not allowed\n",
+                   h->picture_structure, sl->picture_structure);
+            return AVERROR_INVALIDDATA;
+        } else if (!h->cur_pic_ptr) {
+            av_log(h->avctx, AV_LOG_ERROR,
+                   "unset cur_pic_ptr on slice %d\n",
+                   h->current_slice + 1);
+            return AVERROR_INVALIDDATA;
+        }
     }
 
     assert(h->mb_num == h->mb_width * h->mb_height);



More information about the ffmpeg-cvslog mailing list