]> git.sesse.net Git - ffmpeg/blobdiff - libavcodec/libopenh264enc.c
mjpegdec: consider chroma subsampling in size check
[ffmpeg] / libavcodec / libopenh264enc.c
index 01cf2522e434e98270d3c7f0c304a022044d074d..2f63da1219a462e691e7d52e2506378b4642e13f 100644 (file)
@@ -38,6 +38,8 @@ typedef struct SVCContext {
     int loopfilter;
     char *profile;
     int max_nal_size;
+    int skip_frames;
+    int skipped;
 } SVCContext;
 
 #define OPENH264_VER_AT_LEAST(maj, min) \
@@ -53,8 +55,9 @@ static const AVOption options[] = {
         { "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 }
 };
 
@@ -63,7 +66,7 @@ static const AVClass class = {
 };
 
 // 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;
@@ -83,8 +86,8 @@ static void libopenh264_trace_callback(void *ctx, int level, char const *msg)
 {
     // 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)
@@ -93,6 +96,8 @@ 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;
 }
 
@@ -144,7 +149,7 @@ static av_cold int svc_encode_init(AVCodecContext *avctx)
     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;
@@ -250,6 +255,7 @@ static int svc_encode_frame(AVCodecContext *avctx, AVPacket *avpkt,
         return AVERROR_UNKNOWN;
     }
     if (fbi.eFrameType == videoFrameTypeSkip) {
+        s->skipped++;
         av_log(avctx, AV_LOG_DEBUG, "frame skipped\n");
         return 0;
     }