[FFmpeg-devel] [RFC] [PATCH] huffyuvenc, multithread and context=1

Christophe Gisquet christophe.gisquet at gmail.com
Tue Jun 10 22:28:24 CEST 2014


context=1 allows to specify huffman codes for the current frame,
whether they are obtained through multipass, determined through the
previous frame statistics or manually specified.

It is sometimes useful (often I see the context=1 file being almost
half of the context=0 one), but multithreading is disabled.

Indeed, the huffman codes depends on past encoding, and multithreading
kind of randomizes which frames were encoded before. Furthermore, the
stats lies within the codec context.

The attached patch 0001 does 2 main things:
- prepass on the image before determining the huffman codes (therefore
they are used for the current frame not the next one for a marginal
encoding improvement); however that's a ~20% speed penalty
- allow multithreading now that the encoding is reproducible

Patch 0001 as-is is debatable (besides being ugly and adding 100+KB to
the function stack). On the other hand, patch 0002 is a quick hack,
trading deterministic behavior (bad for fate but in practice bearable)
for speed.

Case in point for 1000 frames of a 1920x1080 VC1 video, without
writing the output (hard drive speed being a limiting factor):
- context 0: 1286434kB, ~42fps conversion
- context 1: 653038kB, ~24fps
- context 1, patch 0001: 651001kB, ~38fps / 21fps(1 thread)
- context 1, patch 0002 (non-deterministic, should worsen with thread
count): ~657xxxkB, ~40fps

This makes me wonder what is preferable. The non-deterministic option
is probably 10-20% faster for a suboptimal encoding (here around 1%
rate increase, but that depends on how random the frames are).

-------------- next part --------------
diff --git a/libavcodec/frame_thread_encoder.c b/libavcodec/frame_thread_encoder.c
index 9e17698..68bea1a 100644
--- a/libavcodec/frame_thread_encoder.c
+++ b/libavcodec/frame_thread_encoder.c
@@ -140,16 +140,6 @@ int ff_frame_thread_encoder_init(AVCodecContext *avctx, AVDictionary *options){
                "MJPEG CBR encoding works badly with frame multi-threading, consider "
                "using -threads 1, -thread_type slice or a constant quantizer.\n");
-    if (avctx->codec_id == AV_CODEC_ID_HUFFYUV ||
-        avctx->codec_id == AV_CODEC_ID_FFVHUFF) {
-        // huffyuv does not support these with multiple frame threads currently
-        if (avctx->context_model > 0 || (avctx->flags & CODEC_FLAG_PASS1)) {
-            av_log(avctx, AV_LOG_WARNING,
-               "Forcing thread count to 1 for huffyuv encoding with first pass or context 1\n");
-            avctx->thread_count = 1;
-        }
-    }
     if(!avctx->thread_count) {
         avctx->thread_count = av_cpu_count();
         avctx->thread_count = FFMIN(avctx->thread_count, MAX_THREADS);
-------------- next part --------------
A non-text attachment was scrubbed...
Name: 0001-huffyuvenc-allow-multithread-encoding-with-stats.patch
Type: text/x-patch
Size: 15509 bytes
Desc: not available
URL: <https://ffmpeg.org/pipermail/ffmpeg-devel/attachments/20140610/cc1c7d58/attachment.bin>

More information about the ffmpeg-devel mailing list