Browse code

huffyuvenc: add a non-deterministic option

Not actually used in huffyuvenc, but rather in setting the frame
threading.

Example for some files:
context=0: 851974 27226 1137281
context=1,ND=0: 471819 22604 972351
context=1,ND=1: 472875 22673 972582

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

Christophe Gisquet authored on 2014/06/13 07:21:44
Showing 3 changed files
... ...
@@ -142,8 +142,16 @@ int ff_frame_thread_encoder_init(AVCodecContext *avctx, AVDictionary *options){
142 142
 
143 143
     if (avctx->codec_id == AV_CODEC_ID_HUFFYUV ||
144 144
         avctx->codec_id == AV_CODEC_ID_FFVHUFF) {
145
+        int warn = 0;
146
+        if (avctx->flags & CODEC_FLAG_PASS1)
147
+            warn = 1;
148
+        else if(avctx->context_model > 0) {
149
+            AVDictionaryEntry *t = av_dict_get(options, "non_deterministic",
150
+                                               NULL, AV_DICT_MATCH_CASE);
151
+            warn = !t || !t->value || !atoi(t->value) ? 1 : 0;
152
+        }
145 153
         // huffyuv does not support these with multiple frame threads currently
146
-        if (avctx->context_model > 0 || (avctx->flags & CODEC_FLAG_PASS1)) {
154
+        if (warn) {
147 155
             av_log(avctx, AV_LOG_WARNING,
148 156
                "Forcing thread count to 1 for huffyuv encoding with first pass or context 1\n");
149 157
             avctx->thread_count = 1;
... ...
@@ -52,6 +52,7 @@ typedef enum Predictor {
52 52
 } Predictor;
53 53
 
54 54
 typedef struct HYuvContext {
55
+    AVClass *class;
55 56
     AVCodecContext *avctx;
56 57
     Predictor predictor;
57 58
     GetBitContext gb;
... ...
@@ -88,6 +89,7 @@ typedef struct HYuvContext {
88 88
     HuffYUVDSPContext hdsp;
89 89
     HuffYUVEncDSPContext hencdsp;
90 90
     LLVidDSPContext llviddsp;
91
+    int non_determ; // non-deterministic, multi-threaded encoder allowed
91 92
 } HYuvContext;
92 93
 
93 94
 void ff_huffyuv_common_init(AVCodecContext *s);
... ...
@@ -34,6 +34,7 @@
34 34
 #include "huffyuvencdsp.h"
35 35
 #include "internal.h"
36 36
 #include "put_bits.h"
37
+#include "libavutil/opt.h"
37 38
 #include "libavutil/pixdesc.h"
38 39
 
39 40
 static inline void diff_bytes(HYuvContext *s, uint8_t *dst,
... ...
@@ -990,6 +991,27 @@ static av_cold int encode_end(AVCodecContext *avctx)
990 990
     return 0;
991 991
 }
992 992
 
993
+static const AVOption options[] = {
994
+    { "non_deterministic", "Allow multithreading for e.g. context=1 at the expense of determinism",
995
+      offsetof(HYuvContext, non_determ), AV_OPT_TYPE_INT, { .i64 = 1 },
996
+      0, 1, AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_ENCODING_PARAM },
997
+    { NULL },
998
+};
999
+
1000
+static const AVClass normal_class = {
1001
+    .class_name = "huffyuv",
1002
+    .item_name  = av_default_item_name,
1003
+    .option     = options,
1004
+    .version    = LIBAVUTIL_VERSION_INT,
1005
+};
1006
+
1007
+static const AVClass ff_class = {
1008
+    .class_name = "ffvhuff",
1009
+    .item_name  = av_default_item_name,
1010
+    .option     = options,
1011
+    .version    = LIBAVUTIL_VERSION_INT,
1012
+};
1013
+
993 1014
 AVCodec ff_huffyuv_encoder = {
994 1015
     .name           = "huffyuv",
995 1016
     .long_name      = NULL_IF_CONFIG_SMALL("Huffyuv / HuffYUV"),
... ...
@@ -1000,6 +1022,7 @@ AVCodec ff_huffyuv_encoder = {
1000 1000
     .encode2        = encode_frame,
1001 1001
     .close          = encode_end,
1002 1002
     .capabilities   = CODEC_CAP_FRAME_THREADS | CODEC_CAP_INTRA_ONLY,
1003
+    .priv_class     = &normal_class,
1003 1004
     .pix_fmts       = (const enum AVPixelFormat[]){
1004 1005
         AV_PIX_FMT_YUV422P, AV_PIX_FMT_RGB24,
1005 1006
         AV_PIX_FMT_RGB32, AV_PIX_FMT_NONE
... ...
@@ -1017,6 +1040,7 @@ AVCodec ff_ffvhuff_encoder = {
1017 1017
     .encode2        = encode_frame,
1018 1018
     .close          = encode_end,
1019 1019
     .capabilities   = CODEC_CAP_FRAME_THREADS | CODEC_CAP_INTRA_ONLY,
1020
+    .priv_class     = &ff_class,
1020 1021
     .pix_fmts       = (const enum AVPixelFormat[]){
1021 1022
         AV_PIX_FMT_YUV420P, AV_PIX_FMT_YUV422P, AV_PIX_FMT_YUV444P, AV_PIX_FMT_YUV411P,
1022 1023
         AV_PIX_FMT_YUV410P, AV_PIX_FMT_YUV440P,