]> git.sesse.net Git - ffmpeg/blobdiff - libavcodec/libopenh264enc.c
avcodec.h: split AVCodec API into its own header
[ffmpeg] / libavcodec / libopenh264enc.c
index dc3bd536a8a7e1d8c16f9f5a1e0451d4bec4364b..f63aa52348cad26ebd20e23608880ce75a2abb49 100644 (file)
@@ -44,11 +44,14 @@ typedef struct SVCContext {
     ISVCEncoder *encoder;
     int slice_mode;
     int loopfilter;
-    char *profile;
+    int profile;
     int max_nal_size;
     int skip_frames;
     int skipped;
-    int cabac;
+#if FF_API_OPENH264_CABAC
+    int cabac;                      // deprecated
+#endif
+    int coder;
 
     // rate control mode
     int rc_mode;
@@ -56,11 +59,13 @@ typedef struct SVCContext {
 
 #define OFFSET(x) offsetof(SVCContext, x)
 #define VE AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_ENCODING_PARAM
+#define DEPRECATED AV_OPT_FLAG_DEPRECATED
 static const AVOption options[] = {
+#if FF_API_OPENH264_SLICE_MODE
 #if OPENH264_VER_AT_LEAST(1, 6)
-    { "slice_mode", "set slice mode", OFFSET(slice_mode), AV_OPT_TYPE_INT, { .i64 = SM_FIXEDSLCNUM_SLICE }, SM_SINGLE_SLICE, SM_RESERVED, VE, "slice_mode" },
+    { "slice_mode", "set slice mode, use slices/max_nal_size", OFFSET(slice_mode), AV_OPT_TYPE_INT, { .i64 = SM_FIXEDSLCNUM_SLICE }, SM_SINGLE_SLICE, SM_RESERVED, VE|DEPRECATED, "slice_mode" },
 #else
-    { "slice_mode", "set slice mode", OFFSET(slice_mode), AV_OPT_TYPE_INT, { .i64 = SM_AUTO_SLICE }, SM_SINGLE_SLICE, SM_RESERVED, VE, "slice_mode" },
+    { "slice_mode", "set slice mode, use slices/max_nal_size", OFFSET(slice_mode), AV_OPT_TYPE_INT, { .i64 = SM_AUTO_SLICE }, SM_SINGLE_SLICE, SM_RESERVED, VE|DEPRECATED, "slice_mode" },
 #endif
         { "fixed", "a fixed number of slices", 0, AV_OPT_TYPE_CONST, { .i64 = SM_FIXEDSLCNUM_SLICE }, 0, 0, VE, "slice_mode" },
 #if OPENH264_VER_AT_LEAST(1, 6)
@@ -70,12 +75,26 @@ static const AVOption options[] = {
         { "rowmb", "one slice per row of macroblocks", 0, AV_OPT_TYPE_CONST, { .i64 = SM_ROWMB_SLICE }, 0, 0, VE, "slice_mode" },
         { "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" },
+#endif
 #endif
     { "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, { .str = NULL }, 0, 0, VE },
+    { "profile", "set profile restrictions", OFFSET(profile), AV_OPT_TYPE_INT, { .i64 = FF_PROFILE_UNKNOWN }, FF_PROFILE_UNKNOWN, 0xffff, VE, "profile" },
+#define PROFILE(name, value)  name, NULL, 0, AV_OPT_TYPE_CONST, { .i64 = value }, 0, 0, VE, "profile"
+        { PROFILE("constrained_baseline", FF_PROFILE_H264_CONSTRAINED_BASELINE) },
+        { PROFILE("main",                 FF_PROFILE_H264_MAIN) },
+        { PROFILE("high",                 FF_PROFILE_H264_HIGH) },
+#undef PROFILE
     { "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 },
-    { "cabac", "Enable cabac", OFFSET(cabac), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 1, VE },
+#if FF_API_OPENH264_CABAC
+    { "cabac", "Enable cabac(deprecated, use coder)", OFFSET(cabac), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 1, VE|DEPRECATED },
+#endif
+    { "coder", "Coder type",  OFFSET(coder), AV_OPT_TYPE_INT, { .i64 = -1 }, -1, 1, VE, "coder" },
+        { "default",          NULL, 0, AV_OPT_TYPE_CONST, { .i64 = -1 }, INT_MIN, INT_MAX, VE, "coder" },
+        { "cavlc",            NULL, 0, AV_OPT_TYPE_CONST, { .i64 = 0 },  INT_MIN, INT_MAX, VE, "coder" },
+        { "cabac",            NULL, 0, AV_OPT_TYPE_CONST, { .i64 = 1 },  INT_MIN, INT_MAX, VE, "coder" },
+        { "vlc",              NULL, 0, AV_OPT_TYPE_CONST, { .i64 = 0 },  INT_MIN, INT_MAX, VE, "coder" },
+        { "ac",               NULL, 0, AV_OPT_TYPE_CONST, { .i64 = 1 },  INT_MIN, INT_MAX, VE, "coder" },
 
     { "rc_mode", "Select rate control mode", OFFSET(rc_mode), AV_OPT_TYPE_INT, { .i64 = RC_QUALITY_MODE }, RC_OFF_MODE, RC_TIMESTAMP_MODE, VE, "rc_mode" },
         { "off",       "bit rate control off",                                                 0, AV_OPT_TYPE_CONST, { .i64 = RC_OFF_MODE },         0, 0, VE, "rc_mode" },
@@ -137,13 +156,6 @@ static av_cold int svc_encode_init(AVCodecContext *avctx)
 
     (*s->encoder)->GetDefaultParams(s->encoder, &param);
 
-#if FF_API_CODER_TYPE
-FF_DISABLE_DEPRECATION_WARNINGS
-    if (!s->cabac)
-        s->cabac = avctx->coder_type == FF_CODER_TYPE_AC;
-FF_ENABLE_DEPRECATION_WARNINGS
-#endif
-
     param.fMaxFrameRate              = 1/av_q2d(avctx->time_base);
     param.iPicWidth                  = avctx->width;
     param.iPicHeight                 = avctx->height;
@@ -173,10 +185,66 @@ FF_ENABLE_DEPRECATION_WARNINGS
     param.iLoopFilterDisableIdc      = !s->loopfilter;
     param.iEntropyCodingModeFlag     = 0;
     param.iMultipleThreadIdc         = avctx->thread_count;
-    if (s->profile && !strcmp(s->profile, "main"))
+
+    /* Allow specifying the libopenh264 profile through AVCodecContext. */
+    if (FF_PROFILE_UNKNOWN == s->profile &&
+        FF_PROFILE_UNKNOWN != avctx->profile)
+        switch (avctx->profile) {
+        case FF_PROFILE_H264_HIGH:
+        case FF_PROFILE_H264_MAIN:
+        case FF_PROFILE_H264_CONSTRAINED_BASELINE:
+            s->profile = avctx->profile;
+            break;
+        default:
+            av_log(avctx, AV_LOG_WARNING,
+                   "Unsupported avctx->profile: %d.\n", avctx->profile);
+            break;
+        }
+
+#if FF_API_CODER_TYPE && FF_API_OPENH264_CABAC
+FF_DISABLE_DEPRECATION_WARNINGS
+    if (s->coder < 0 && avctx->coder_type == FF_CODER_TYPE_AC)
+        s->coder = 1;
+
+    if (s->coder < 0)
+        s->coder = s->cabac;
+FF_ENABLE_DEPRECATION_WARNINGS
+#endif
+
+    if (s->profile == FF_PROFILE_UNKNOWN && s->coder >= 0)
+        s->profile = s->coder == 0 ? FF_PROFILE_H264_CONSTRAINED_BASELINE :
+#if OPENH264_VER_AT_LEAST(1, 8)
+                                     FF_PROFILE_H264_HIGH;
+#else
+                                     FF_PROFILE_H264_MAIN;
+#endif
+
+    switch (s->profile) {
+#if OPENH264_VER_AT_LEAST(1, 8)
+    case FF_PROFILE_H264_HIGH:
         param.iEntropyCodingModeFlag = 1;
-    else if (!s->profile && s->cabac)
+        av_log(avctx, AV_LOG_VERBOSE, "Using CABAC, "
+                "select EProfileIdc PRO_HIGH in libopenh264.\n");
+        break;
+#else
+    case FF_PROFILE_H264_MAIN:
         param.iEntropyCodingModeFlag = 1;
+        av_log(avctx, AV_LOG_VERBOSE, "Using CABAC, "
+                "select EProfileIdc PRO_MAIN in libopenh264.\n");
+        break;
+#endif
+    case FF_PROFILE_H264_CONSTRAINED_BASELINE:
+    case FF_PROFILE_UNKNOWN:
+        param.iEntropyCodingModeFlag = 0;
+        av_log(avctx, AV_LOG_VERBOSE, "Using CAVLC, "
+               "select EProfileIdc PRO_BASELINE in libopenh264.\n");
+        break;
+    default:
+        param.iEntropyCodingModeFlag = 0;
+        av_log(avctx, AV_LOG_WARNING, "Unsupported profile, "
+               "select EProfileIdc PRO_BASELINE in libopenh264.\n");
+        break;
+    }
 
     param.sSpatialLayers[0].iVideoWidth         = param.iPicWidth;
     param.sSpatialLayers[0].iVideoHeight        = param.iPicHeight;
@@ -244,6 +312,8 @@ FF_ENABLE_DEPRECATION_WARNINGS
     param.sSpatialLayers[0].sSliceCfg.uiSliceMode               = s->slice_mode;
     param.sSpatialLayers[0].sSliceCfg.sSliceArgument.uiSliceNum = avctx->slices;
 #endif
+    if (avctx->slices == 0 && s->slice_mode == SM_FIXEDSLCNUM_SLICE)
+        av_log(avctx, AV_LOG_WARNING, "Slice count will be set automatically\n");
 
     if (s->slice_mode == SM_SIZELIMITED_SLICE) {
         if (s->max_nal_size) {