Browse code

avcodec/libx264: Implement reference frame count limiting based on level

This makes libavcodec/libx264.c behave more similar to the x264 command line
util

Fixes Ticket3307

Implementation based on x264

Signed-off-by: Michael Niedermayer <michaelni@gmx.at>

Michael Niedermayer authored on 2014/04/12 11:23:20
Showing 3 changed files
... ...
@@ -22,6 +22,7 @@ version <next>:
22 22
 - On2 AVC (Audio for Video) decoder
23 23
 - support for decoding through DXVA2 in ffmpeg
24 24
 - libbs2b-based stereo-to-binaural audio filter
25
+- libx264 reference frames count limiting depending on level
25 26
 
26 27
 
27 28
 version 2.2:
... ...
@@ -19,6 +19,7 @@
19 19
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20 20
  */
21 21
 
22
+#include "libavutil/eval.h"
22 23
 #include "libavutil/internal.h"
23 24
 #include "libavutil/opt.h"
24 25
 #include "libavutil/mem.h"
... ...
@@ -426,6 +427,28 @@ static av_cold int X264_init(AVCodecContext *avctx)
426 426
         x4->params.rc.f_qcompress       = avctx->qcompress; /* 0.0 => cbr, 1.0 => constant qp */
427 427
     if (avctx->refs >= 0)
428 428
         x4->params.i_frame_reference    = avctx->refs;
429
+    else if (x4->level) {
430
+        int i;
431
+        int mbn = FF_CEIL_RSHIFT(avctx->width, 4) * FF_CEIL_RSHIFT(avctx->height, 4);
432
+        int level_id = -1;
433
+        char *tail;
434
+        int scale = X264_BUILD < 129 ? 384 : 1;
435
+
436
+        if (!strcmp(x4->level, "1b")) {
437
+            level_id = 9;
438
+        } else if (strlen(x4->level) <= 3){
439
+            level_id = av_strtod(x4->level, &tail) * 10 + 0.5;
440
+            if (*tail)
441
+                level_id = -1;
442
+        }
443
+        if (level_id <= 0)
444
+            av_log(avctx, AV_LOG_WARNING, "Failed to parse level\n");
445
+
446
+        for (i = 0; i<x264_levels[i].level_idc; i++)
447
+            if (x264_levels[i].level_idc == level_id)
448
+                x4->params.i_frame_reference = av_clip(x264_levels[i].dpb / mbn / scale, 1, x4->params.i_frame_reference);
449
+    }
450
+
429 451
     if (avctx->trellis >= 0)
430 452
         x4->params.analyse.i_trellis    = avctx->trellis;
431 453
     if (avctx->me_range >= 0)
... ...
@@ -30,7 +30,7 @@
30 30
 
31 31
 #define LIBAVCODEC_VERSION_MAJOR 55
32 32
 #define LIBAVCODEC_VERSION_MINOR  61
33
-#define LIBAVCODEC_VERSION_MICRO 100
33
+#define LIBAVCODEC_VERSION_MICRO 101
34 34
 
35 35
 #define LIBAVCODEC_VERSION_INT  AV_VERSION_INT(LIBAVCODEC_VERSION_MAJOR, \
36 36
                                                LIBAVCODEC_VERSION_MINOR, \