[FFmpeg-cvslog] h264: derive the delay from the level when it's not present

Anton Khirnov git at videolan.org
Thu Dec 17 13:09:04 CET 2015


ffmpeg | branch: master | Anton Khirnov <anton at khirnov.net> | Tue Oct 20 19:04:57 2015 +0200| [b09ad37c83841c399abb7f2503a2ab214d0c2d48] | committer: Anton Khirnov

h264: derive the delay from the level when it's not present

Fall back to maximum DPB size if the level is unknown.

This should be more spec-compliant and does not depend on the caller
setting has_b_frames before opening the decoder.

The old behaviour, when the delay is supplied by the caller setting
has_b_frames, can still be obtained by setting strict_std_compliance
below normal.

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

 libavcodec/h264.c    |   15 ++++-----------
 libavcodec/h264_ps.c |   33 +++++++++++++++++++++++++++++++++
 2 files changed, 37 insertions(+), 11 deletions(-)

diff --git a/libavcodec/h264.c b/libavcodec/h264.c
index ec57d6d..6b12b30 100644
--- a/libavcodec/h264.c
+++ b/libavcodec/h264.c
@@ -851,18 +851,11 @@ static void decode_postinit(H264Context *h, int setup_finished)
     // FIXME do something with unavailable reference frames
 
     /* Sort B-frames into display order */
-
-    if (h->sps.bitstream_restriction_flag &&
-        h->avctx->has_b_frames < h->sps.num_reorder_frames) {
-        h->avctx->has_b_frames = h->sps.num_reorder_frames;
-        h->low_delay           = 0;
-    }
-
-    if (h->avctx->strict_std_compliance >= FF_COMPLIANCE_STRICT &&
-        !h->sps.bitstream_restriction_flag) {
-        h->avctx->has_b_frames = MAX_DELAYED_PIC_COUNT - 1;
-        h->low_delay           = 0;
+    if (h->sps.bitstream_restriction_flag ||
+        h->avctx->strict_std_compliance >= FF_COMPLIANCE_NORMAL) {
+        h->avctx->has_b_frames = FFMAX(h->avctx->has_b_frames, h->sps.num_reorder_frames);
     }
+    h->low_delay = !h->avctx->has_b_frames;
 
     pics = 0;
     while (h->delayed_pic[pics])
diff --git a/libavcodec/h264_ps.c b/libavcodec/h264_ps.c
index fa9fa7d..6b29966 100644
--- a/libavcodec/h264_ps.c
+++ b/libavcodec/h264_ps.c
@@ -105,6 +105,26 @@ static const uint8_t default_scaling8[2][64] = {
       24, 25, 27, 28, 30, 32, 33, 35 }
 };
 
+/* maximum number of MBs in the DPB for a given level */
+static const int level_max_dpb_mbs[][2] = {
+    { 10, 396       },
+    { 11, 900       },
+    { 12, 2376      },
+    { 13, 2376      },
+    { 20, 2376      },
+    { 21, 4752      },
+    { 22, 8100      },
+    { 30, 8100      },
+    { 31, 18000     },
+    { 32, 20480     },
+    { 40, 32768     },
+    { 41, 32768     },
+    { 42, 34816     },
+    { 50, 110400    },
+    { 51, 184320    },
+    { 52, 184320    },
+};
+
 static inline int decode_hrd_parameters(H264Context *h, SPS *sps)
 {
     int cpb_count, i;
@@ -501,6 +521,19 @@ int ff_h264_decode_seq_parameter_set(H264Context *h)
             goto fail;
     }
 
+    /* if the maximum delay is not stored in the SPS, derive it based on the
+     * level */
+    if (!sps->bitstream_restriction_flag) {
+        sps->num_reorder_frames = MAX_DELAYED_PIC_COUNT - 1;
+        for (i = 0; i < FF_ARRAY_ELEMS(level_max_dpb_mbs); i++) {
+            if (level_max_dpb_mbs[i][0] == sps->level_idc) {
+                sps->num_reorder_frames = FFMIN(level_max_dpb_mbs[i][1] / (sps->mb_width * sps->mb_height),
+                                                sps->num_reorder_frames);
+                break;
+            }
+        }
+    }
+
     if (!sps->sar.den)
         sps->sar.den = 1;
 



More information about the ffmpeg-cvslog mailing list