int loopfilter;
char *profile;
int max_nal_size;
+ int skip_frames;
+ int skipped;
} SVCContext;
#define OPENH264_VER_AT_LEAST(maj, min) \
{ "auto", "automatic number of slices according to number of threads", 0, AV_OPT_TYPE_CONST, { .i64 = SM_AUTO_SLICE }, 0, 0, VE, "slice_mode" },
{ "dyn", "Dynamic slicing", 0, AV_OPT_TYPE_CONST, { .i64 = SM_DYN_SLICE }, 0, 0, VE, "slice_mode" },
{ "loopfilter", "enable loop filter", OFFSET(loopfilter), AV_OPT_TYPE_INT, { .i64 = 1 }, 0, 1, VE },
- { "profile", "set profile restrictions", OFFSET(profile), AV_OPT_TYPE_STRING, { 0 }, 0, 0, VE },
- { "max_nal_size", "Set maximum NAL size in bytes", OFFSET(max_nal_size), AV_OPT_TYPE_INT, { 0 }, 0, INT_MAX, VE },
+ { "profile", "set profile restrictions", OFFSET(profile), AV_OPT_TYPE_STRING, { .str = NULL }, 0, 0, VE },
+ { "max_nal_size", "Set maximum NAL size in bytes", OFFSET(max_nal_size), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, INT_MAX, VE },
+ { "allow_skip_frames", "Allow skipping frames to hit the target bitrate", OFFSET(skip_frames), AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, VE },
{ NULL }
};
};
// Convert libopenh264 log level to equivalent ffmpeg log level.
-static int libopenh264_to_libav_log_level(int libopenh264_log_level)
+static int libopenh264_to_ffmpeg_log_level(int libopenh264_log_level)
{
if (libopenh264_log_level >= WELS_LOG_DETAIL) return AV_LOG_TRACE;
else if (libopenh264_log_level >= WELS_LOG_DEBUG) return AV_LOG_DEBUG;
{
// The message will be logged only if the requested EQUIVALENT ffmpeg log level is
// less than or equal to the current ffmpeg log level.
- int equiv_libav_log_level = libopenh264_to_libav_log_level(level);
- av_log(ctx, equiv_libav_log_level, "%s\n", msg);
+ int equiv_ffmpeg_log_level = libopenh264_to_ffmpeg_log_level(level);
+ av_log(ctx, equiv_ffmpeg_log_level, "%s\n", msg);
}
static av_cold int svc_encode_close(AVCodecContext *avctx)
if (s->encoder)
WelsDestroySVCEncoder(s->encoder);
+ if (s->skipped > 0)
+ av_log(avctx, AV_LOG_WARNING, "%d frames skipped\n", s->skipped);
return 0;
}
param.bEnableDenoise = 0;
param.bEnableBackgroundDetection = 1;
param.bEnableAdaptiveQuant = 1;
- param.bEnableFrameSkip = 0;
+ param.bEnableFrameSkip = s->skip_frames;
param.bEnableLongTermReference = 0;
param.iLtrMarkPeriod = 30;
param.uiIntraPeriod = avctx->gop_size;
return AVERROR_UNKNOWN;
}
if (fbi.eFrameType == videoFrameTypeSkip) {
+ s->skipped++;
av_log(avctx, AV_LOG_DEBUG, "frame skipped\n");
return 0;
}