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>
This commit is contained in:
Christophe Gisquet 2014-06-13 00:21:44 +02:00 committed by Michael Niedermayer
parent 6380f2e367
commit 1467780772
3 changed files with 35 additions and 1 deletions

View File

@ -142,8 +142,16 @@ int ff_frame_thread_encoder_init(AVCodecContext *avctx, AVDictionary *options){
if (avctx->codec_id == AV_CODEC_ID_HUFFYUV || if (avctx->codec_id == AV_CODEC_ID_HUFFYUV ||
avctx->codec_id == AV_CODEC_ID_FFVHUFF) { avctx->codec_id == AV_CODEC_ID_FFVHUFF) {
int warn = 0;
if (avctx->flags & CODEC_FLAG_PASS1)
warn = 1;
else if(avctx->context_model > 0) {
AVDictionaryEntry *t = av_dict_get(options, "non_deterministic",
NULL, AV_DICT_MATCH_CASE);
warn = !t || !t->value || !atoi(t->value) ? 1 : 0;
}
// huffyuv does not support these with multiple frame threads currently // huffyuv does not support these with multiple frame threads currently
if (avctx->context_model > 0 || (avctx->flags & CODEC_FLAG_PASS1)) { if (warn) {
av_log(avctx, AV_LOG_WARNING, av_log(avctx, AV_LOG_WARNING,
"Forcing thread count to 1 for huffyuv encoding with first pass or context 1\n"); "Forcing thread count to 1 for huffyuv encoding with first pass or context 1\n");
avctx->thread_count = 1; avctx->thread_count = 1;

View File

@ -52,6 +52,7 @@ typedef enum Predictor {
} Predictor; } Predictor;
typedef struct HYuvContext { typedef struct HYuvContext {
AVClass *class;
AVCodecContext *avctx; AVCodecContext *avctx;
Predictor predictor; Predictor predictor;
GetBitContext gb; GetBitContext gb;
@ -88,6 +89,7 @@ typedef struct HYuvContext {
HuffYUVDSPContext hdsp; HuffYUVDSPContext hdsp;
HuffYUVEncDSPContext hencdsp; HuffYUVEncDSPContext hencdsp;
LLVidDSPContext llviddsp; LLVidDSPContext llviddsp;
int non_determ; // non-deterministic, multi-threaded encoder allowed
} HYuvContext; } HYuvContext;
void ff_huffyuv_common_init(AVCodecContext *s); void ff_huffyuv_common_init(AVCodecContext *s);

View File

@ -34,6 +34,7 @@
#include "huffyuvencdsp.h" #include "huffyuvencdsp.h"
#include "internal.h" #include "internal.h"
#include "put_bits.h" #include "put_bits.h"
#include "libavutil/opt.h"
#include "libavutil/pixdesc.h" #include "libavutil/pixdesc.h"
static inline void diff_bytes(HYuvContext *s, uint8_t *dst, static inline void diff_bytes(HYuvContext *s, uint8_t *dst,
@ -990,6 +991,27 @@ static av_cold int encode_end(AVCodecContext *avctx)
return 0; return 0;
} }
static const AVOption options[] = {
{ "non_deterministic", "Allow multithreading for e.g. context=1 at the expense of determinism",
offsetof(HYuvContext, non_determ), AV_OPT_TYPE_INT, { .i64 = 1 },
0, 1, AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_ENCODING_PARAM },
{ NULL },
};
static const AVClass normal_class = {
.class_name = "huffyuv",
.item_name = av_default_item_name,
.option = options,
.version = LIBAVUTIL_VERSION_INT,
};
static const AVClass ff_class = {
.class_name = "ffvhuff",
.item_name = av_default_item_name,
.option = options,
.version = LIBAVUTIL_VERSION_INT,
};
AVCodec ff_huffyuv_encoder = { AVCodec ff_huffyuv_encoder = {
.name = "huffyuv", .name = "huffyuv",
.long_name = NULL_IF_CONFIG_SMALL("Huffyuv / HuffYUV"), .long_name = NULL_IF_CONFIG_SMALL("Huffyuv / HuffYUV"),
@ -1000,6 +1022,7 @@ AVCodec ff_huffyuv_encoder = {
.encode2 = encode_frame, .encode2 = encode_frame,
.close = encode_end, .close = encode_end,
.capabilities = CODEC_CAP_FRAME_THREADS | CODEC_CAP_INTRA_ONLY, .capabilities = CODEC_CAP_FRAME_THREADS | CODEC_CAP_INTRA_ONLY,
.priv_class = &normal_class,
.pix_fmts = (const enum AVPixelFormat[]){ .pix_fmts = (const enum AVPixelFormat[]){
AV_PIX_FMT_YUV422P, AV_PIX_FMT_RGB24, AV_PIX_FMT_YUV422P, AV_PIX_FMT_RGB24,
AV_PIX_FMT_RGB32, AV_PIX_FMT_NONE AV_PIX_FMT_RGB32, AV_PIX_FMT_NONE
@ -1017,6 +1040,7 @@ AVCodec ff_ffvhuff_encoder = {
.encode2 = encode_frame, .encode2 = encode_frame,
.close = encode_end, .close = encode_end,
.capabilities = CODEC_CAP_FRAME_THREADS | CODEC_CAP_INTRA_ONLY, .capabilities = CODEC_CAP_FRAME_THREADS | CODEC_CAP_INTRA_ONLY,
.priv_class = &ff_class,
.pix_fmts = (const enum AVPixelFormat[]){ .pix_fmts = (const enum AVPixelFormat[]){
AV_PIX_FMT_YUV420P, AV_PIX_FMT_YUV422P, AV_PIX_FMT_YUV444P, AV_PIX_FMT_YUV411P, AV_PIX_FMT_YUV420P, AV_PIX_FMT_YUV422P, AV_PIX_FMT_YUV444P, AV_PIX_FMT_YUV411P,
AV_PIX_FMT_YUV410P, AV_PIX_FMT_YUV440P, AV_PIX_FMT_YUV410P, AV_PIX_FMT_YUV440P,