Merge commit '0ac9f33a9e69c64eee592791be3c5441a6a3d6b7'
authorDerek Buitenhuis <derek.buitenhuis@gmail.com>
Thu, 28 Jan 2016 15:08:10 +0000 (15:08 +0000)
committerDerek Buitenhuis <derek.buitenhuis@gmail.com>
Thu, 28 Jan 2016 15:08:10 +0000 (15:08 +0000)
* commit '0ac9f33a9e69c64eee592791be3c5441a6a3d6b7':
  lavc: Move frame_skip_* to codec private options

Merged-by: Derek Buitenhuis <derek.buitenhuis@gmail.com>
1  2 
libavcodec/avcodec.h
libavcodec/libvpxenc.c
libavcodec/mpegvideo.c
libavcodec/mpegvideo.h
libavcodec/mpegvideo_enc.c
libavcodec/options_table.h

Simple merge
@@@ -92,16 -67,7 +92,17 @@@ typedef struct VP8EncoderContext 
      int error_resilient;
      int crf;
      int static_thresh;
 +    int max_intra_rate;
 +    int rc_undershoot_pct;
 +    int rc_overshoot_pct;
 +
 +    // VP9-only
 +    int lossless;
 +    int tile_columns;
 +    int tile_rows;
 +    int frame_parallel;
 +    int aq_mode;
+     int drop_threshold;
  } VP8Context;
  
  /** String mappings for enum vp8e_enc_control_id */
@@@ -446,64 -242,35 +447,70 @@@ static av_cold int vpx_init(AVCodecCont
      else
          enccfg.g_pass = VPX_RC_ONE_PASS;
  
 -    if (!avctx->bit_rate)
 -        avctx->bit_rate = enccfg.rc_target_bitrate * 1000;
 -    else
 +    if (avctx->rc_min_rate == avctx->rc_max_rate &&
 +        avctx->rc_min_rate == avctx->bit_rate && avctx->bit_rate) {
 +        enccfg.rc_end_usage = VPX_CBR;
 +    } else if (ctx->crf >= 0) {
 +        enccfg.rc_end_usage = VPX_CQ;
 +#if CONFIG_LIBVPX_VP9_ENCODER
 +        if (!avctx->bit_rate && avctx->codec_id == AV_CODEC_ID_VP9)
 +            enccfg.rc_end_usage = VPX_Q;
 +#endif
 +    }
 +
 +    if (avctx->bit_rate) {
          enccfg.rc_target_bitrate = av_rescale_rnd(avctx->bit_rate, 1, 1000,
 -                                              AV_ROUND_NEAR_INF);
 +                                                  AV_ROUND_NEAR_INF);
 +#if CONFIG_LIBVPX_VP9_ENCODER
 +    } else if (enccfg.rc_end_usage == VPX_Q) {
 +#endif
 +    } else {
 +        if (enccfg.rc_end_usage == VPX_CQ) {
 +            enccfg.rc_target_bitrate = 1000000;
 +        } else {
 +            avctx->bit_rate = enccfg.rc_target_bitrate * 1000;
 +            av_log(avctx, AV_LOG_WARNING,
 +                   "Neither bitrate nor constrained quality specified, using default bitrate of %dkbit/sec\n",
 +                   enccfg.rc_target_bitrate);
 +        }
 +    }
  
 -    if (ctx->crf)
 -        enccfg.rc_end_usage = VPX_CQ;
 -    else if (avctx->rc_min_rate == avctx->rc_max_rate &&
 -             avctx->rc_min_rate == avctx->bit_rate)
 -        enccfg.rc_end_usage = VPX_CBR;
 +    if (avctx->codec_id == AV_CODEC_ID_VP9 && ctx->lossless == 1) {
 +        enccfg.rc_min_quantizer =
 +        enccfg.rc_max_quantizer = 0;
 +    } else {
 +        if (avctx->qmin >= 0)
 +            enccfg.rc_min_quantizer = avctx->qmin;
 +        if (avctx->qmax >= 0)
 +            enccfg.rc_max_quantizer = avctx->qmax;
 +    }
  
 -    if (avctx->qmin > 0)
 -        enccfg.rc_min_quantizer = avctx->qmin;
 -    if (avctx->qmax > 0)
 -        enccfg.rc_max_quantizer = avctx->qmax;
 +    if (enccfg.rc_end_usage == VPX_CQ
 +#if CONFIG_LIBVPX_VP9_ENCODER
 +        || enccfg.rc_end_usage == VPX_Q
 +#endif
 +       ) {
 +        if (ctx->crf < enccfg.rc_min_quantizer || ctx->crf > enccfg.rc_max_quantizer) {
 +            av_log(avctx, AV_LOG_ERROR,
 +                   "CQ level %d must be between minimum and maximum quantizer value (%d-%d)\n",
 +                   ctx->crf, enccfg.rc_min_quantizer, enccfg.rc_max_quantizer);
 +            return AVERROR(EINVAL);
 +        }
 +    }
  
-     enccfg.rc_dropframe_thresh = avctx->frame_skip_threshold;
+ #if FF_API_PRIVATE_OPT
+ FF_DISABLE_DEPRECATION_WARNINGS
+     if (avctx->frame_skip_threshold)
+         ctx->drop_threshold = avctx->frame_skip_threshold;
+ FF_ENABLE_DEPRECATION_WARNINGS
+ #endif
+     enccfg.rc_dropframe_thresh = ctx->drop_threshold;
  
      //0-100 (0 => CBR, 100 => VBR)
 -    enccfg.rc_2pass_vbr_bias_pct           = round(avctx->qcompress * 100);
 -    enccfg.rc_2pass_vbr_minsection_pct     =
 -        avctx->rc_min_rate * 100LL / avctx->bit_rate;
 +    enccfg.rc_2pass_vbr_bias_pct           = lrint(avctx->qcompress * 100);
 +    if (avctx->bit_rate)
 +        enccfg.rc_2pass_vbr_minsection_pct =
 +            avctx->rc_min_rate * 100LL / avctx->bit_rate;
      if (avctx->rc_max_rate)
          enccfg.rc_2pass_vbr_maxsection_pct =
              avctx->rc_max_rate * 100LL / avctx->bit_rate;
@@@ -979,79 -576,35 +986,80 @@@ static int vp8_encode(AVCodecContext *a
  
  #define OFFSET(x) offsetof(VP8Context, x)
  #define VE AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_ENCODING_PARAM
 -static const AVOption options[] = {
 -    { "cpu-used",        "Quality/Speed ratio modifier",           OFFSET(cpu_used),        AV_OPT_TYPE_INT, {.i64 = 1}, INT_MIN, INT_MAX, VE},
 -    { "auto-alt-ref",    "Enable use of alternate reference "
 -                         "frames (2-pass only)",                   OFFSET(auto_alt_ref),    AV_OPT_TYPE_INT, {.i64 = -1},      -1,      1,       VE},
 -    { "lag-in-frames",   "Number of frames to look ahead for "
 -                         "alternate reference frame selection",    OFFSET(lag_in_frames),   AV_OPT_TYPE_INT, {.i64 = -1},      -1,      INT_MAX, VE},
 -    { "arnr-maxframes",  "altref noise reduction max frame count", OFFSET(arnr_max_frames), AV_OPT_TYPE_INT, {.i64 = -1},      -1,      INT_MAX, VE},
 -    { "arnr-strength",   "altref noise reduction filter strength", OFFSET(arnr_strength),   AV_OPT_TYPE_INT, {.i64 = -1},      -1,      INT_MAX, VE},
 -    { "arnr-type",       "altref noise reduction filter type",     OFFSET(arnr_type),       AV_OPT_TYPE_INT, {.i64 = -1},      -1,      INT_MAX, VE, "arnr_type"},
 -    { "backward",        NULL, 0, AV_OPT_TYPE_CONST, {.i64 = 1}, 0, 0, VE, "arnr_type" },
 -    { "forward",         NULL, 0, AV_OPT_TYPE_CONST, {.i64 = 2}, 0, 0, VE, "arnr_type" },
 -    { "centered",        NULL, 0, AV_OPT_TYPE_CONST, {.i64 = 3}, 0, 0, VE, "arnr_type" },
 -    { "deadline",        "Time to spend encoding, in microseconds.", OFFSET(deadline),      AV_OPT_TYPE_INT, {.i64 = VPX_DL_GOOD_QUALITY}, INT_MIN, INT_MAX, VE, "quality"},
 -    { "best",            NULL, 0, AV_OPT_TYPE_CONST, {.i64 = VPX_DL_BEST_QUALITY}, 0, 0, VE, "quality"},
 -    { "good",            NULL, 0, AV_OPT_TYPE_CONST, {.i64 = VPX_DL_GOOD_QUALITY}, 0, 0, VE, "quality"},
 -    { "realtime",        NULL, 0, AV_OPT_TYPE_CONST, {.i64 = VPX_DL_REALTIME},     0, 0, VE, "quality"},
 -    { "error-resilient", "Error resilience configuration", OFFSET(error_resilient), AV_OPT_TYPE_FLAGS, {.i64 = 0}, INT_MIN, INT_MAX, VE, "er"},
 -#ifdef VPX_ERROR_RESILIENT_DEFAULT
 -    { "default",         "Improve resiliency against losses of whole frames", 0, AV_OPT_TYPE_CONST, {.i64 = VPX_ERROR_RESILIENT_DEFAULT}, 0, 0, VE, "er"},
 -    { "partitions",      "The frame partitions are independently decodable "
 -                         "by the bool decoder, meaning that partitions can be decoded even "
 -                         "though earlier partitions have been lost. Note that intra predicition"
 -                         " is still done over the partition boundary.",       0, AV_OPT_TYPE_CONST, {.i64 = VPX_ERROR_RESILIENT_PARTITIONS}, 0, 0, VE, "er"},
 +
 +#ifndef VPX_ERROR_RESILIENT_DEFAULT
 +#define VPX_ERROR_RESILIENT_DEFAULT 1
 +#define VPX_ERROR_RESILIENT_PARTITIONS 2
  #endif
 -    { "crf",              "Select the quality for constant quality mode", offsetof(VP8Context, crf), AV_OPT_TYPE_INT, {.i64 = 0}, 0, 63, VE },
 -    { "static-thresh",    "A change threshold on blocks below which they will be skipped by the encoder", OFFSET(static_thresh), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, INT_MAX, VE },
 -    { "drop-threshold",   "Frame drop threshold", offsetof(VP8Context, drop_threshold), AV_OPT_TYPE_INT, {.i64 = 0 }, INT_MIN, INT_MAX, VE },
 +
 +#define COMMON_OPTIONS \
 +    { "auto-alt-ref",    "Enable use of alternate reference " \
 +                         "frames (2-pass only)",                   OFFSET(auto_alt_ref),    AV_OPT_TYPE_BOOL, {.i64 = -1},     -1,      1,       VE}, \
 +    { "lag-in-frames",   "Number of frames to look ahead for " \
 +                         "alternate reference frame selection",    OFFSET(lag_in_frames),   AV_OPT_TYPE_INT, {.i64 = -1},      -1,      INT_MAX, VE}, \
 +    { "arnr-maxframes",  "altref noise reduction max frame count", OFFSET(arnr_max_frames), AV_OPT_TYPE_INT, {.i64 = -1},      -1,      INT_MAX, VE}, \
 +    { "arnr-strength",   "altref noise reduction filter strength", OFFSET(arnr_strength),   AV_OPT_TYPE_INT, {.i64 = -1},      -1,      INT_MAX, VE}, \
 +    { "arnr-type",       "altref noise reduction filter type",     OFFSET(arnr_type),       AV_OPT_TYPE_INT, {.i64 = -1},      -1,      INT_MAX, VE, "arnr_type"}, \
 +    { "backward",        NULL, 0, AV_OPT_TYPE_CONST, {.i64 = 1}, 0, 0, VE, "arnr_type" }, \
 +    { "forward",         NULL, 0, AV_OPT_TYPE_CONST, {.i64 = 2}, 0, 0, VE, "arnr_type" }, \
 +    { "centered",        NULL, 0, AV_OPT_TYPE_CONST, {.i64 = 3}, 0, 0, VE, "arnr_type" }, \
 +    { "deadline",        "Time to spend encoding, in microseconds.", OFFSET(deadline),      AV_OPT_TYPE_INT, {.i64 = VPX_DL_GOOD_QUALITY}, INT_MIN, INT_MAX, VE, "quality"}, \
 +    { "best",            NULL, 0, AV_OPT_TYPE_CONST, {.i64 = VPX_DL_BEST_QUALITY}, 0, 0, VE, "quality"}, \
 +    { "good",            NULL, 0, AV_OPT_TYPE_CONST, {.i64 = VPX_DL_GOOD_QUALITY}, 0, 0, VE, "quality"}, \
 +    { "realtime",        NULL, 0, AV_OPT_TYPE_CONST, {.i64 = VPX_DL_REALTIME},     0, 0, VE, "quality"}, \
 +    { "error-resilient", "Error resilience configuration", OFFSET(error_resilient), AV_OPT_TYPE_FLAGS, {.i64 = 0}, INT_MIN, INT_MAX, VE, "er"}, \
 +    { "max-intra-rate",  "Maximum I-frame bitrate (pct) 0=unlimited",  OFFSET(max_intra_rate),  AV_OPT_TYPE_INT,  {.i64 = -1}, -1,      INT_MAX, VE}, \
 +    { "default",         "Improve resiliency against losses of whole frames", 0, AV_OPT_TYPE_CONST, {.i64 = VPX_ERROR_RESILIENT_DEFAULT}, 0, 0, VE, "er"}, \
 +    { "partitions",      "The frame partitions are independently decodable " \
 +                         "by the bool decoder, meaning that partitions can be decoded even " \
 +                         "though earlier partitions have been lost. Note that intra predicition" \
 +                         " is still done over the partition boundary.",       0, AV_OPT_TYPE_CONST, {.i64 = VPX_ERROR_RESILIENT_PARTITIONS}, 0, 0, VE, "er"}, \
 +    { "crf",              "Select the quality for constant quality mode", offsetof(VP8Context, crf), AV_OPT_TYPE_INT, {.i64 = -1}, -1, 63, VE }, \
 +    { "static-thresh",    "A change threshold on blocks below which they will be skipped by the encoder", OFFSET(static_thresh), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, INT_MAX, VE }, \
++    { "drop-threshold",   "Frame drop threshold", offsetof(VP8Context, drop_threshold), AV_OPT_TYPE_INT, {.i64 = 0 }, INT_MIN, INT_MAX, VE }, \
 +    { "undershoot-pct",  "Datarate undershoot (min) target (%)", OFFSET(rc_undershoot_pct), AV_OPT_TYPE_INT, { .i64 = -1 }, -1, 100, VE }, \
 +    { "overshoot-pct",   "Datarate overshoot (max) target (%)", OFFSET(rc_overshoot_pct), AV_OPT_TYPE_INT, { .i64 = -1 }, -1, 1000, VE }, \
 +
 +#define LEGACY_OPTIONS \
 +    {"speed", "", offsetof(VP8Context, cpu_used), AV_OPT_TYPE_INT, {.i64 = 1}, -16, 16, VE}, \
 +    {"quality", "", offsetof(VP8Context, deadline), AV_OPT_TYPE_INT, {.i64 = VPX_DL_GOOD_QUALITY}, INT_MIN, INT_MAX, VE, "quality"}, \
 +    {"vp8flags", "", offsetof(VP8Context, flags), AV_OPT_TYPE_FLAGS, {.i64 = 0}, 0, UINT_MAX, VE, "flags"}, \
 +    {"error_resilient", "enable error resilience", 0, AV_OPT_TYPE_CONST, {.i64 = VP8F_ERROR_RESILIENT}, INT_MIN, INT_MAX, VE, "flags"}, \
 +    {"altref", "enable use of alternate reference frames (VP8/2-pass only)", 0, AV_OPT_TYPE_CONST, {.i64 = VP8F_AUTO_ALT_REF}, INT_MIN, INT_MAX, VE, "flags"}, \
 +    {"arnr_max_frames", "altref noise reduction max frame count", offsetof(VP8Context, arnr_max_frames), AV_OPT_TYPE_INT, {.i64 = 0}, 0, 15, VE}, \
 +    {"arnr_strength", "altref noise reduction filter strength", offsetof(VP8Context, arnr_strength), AV_OPT_TYPE_INT, {.i64 = 3}, 0, 6, VE}, \
 +    {"arnr_type", "altref noise reduction filter type", offsetof(VP8Context, arnr_type), AV_OPT_TYPE_INT, {.i64 = 3}, 1, 3, VE}, \
 +    {"rc_lookahead", "Number of frames to look ahead for alternate reference frame selection", offsetof(VP8Context, lag_in_frames), AV_OPT_TYPE_INT, {.i64 = 25}, 0, 25, VE}, \
 +
 +#if CONFIG_LIBVPX_VP8_ENCODER
 +static const AVOption vp8_options[] = {
 +    COMMON_OPTIONS
 +    { "cpu-used",        "Quality/Speed ratio modifier",                OFFSET(cpu_used),        AV_OPT_TYPE_INT, {.i64 = 1}, -16, 16, VE},
 +    LEGACY_OPTIONS
      { NULL }
  };
 +#endif
 +
 +#if CONFIG_LIBVPX_VP9_ENCODER
 +static const AVOption vp9_options[] = {
 +    COMMON_OPTIONS
 +    { "cpu-used",        "Quality/Speed ratio modifier",                OFFSET(cpu_used),        AV_OPT_TYPE_INT, {.i64 = 1},  -8, 8, VE},
 +    { "lossless",        "Lossless mode",                               OFFSET(lossless),        AV_OPT_TYPE_INT, {.i64 = -1}, -1, 1, VE},
 +    { "tile-columns",    "Number of tile columns to use, log2",         OFFSET(tile_columns),    AV_OPT_TYPE_INT, {.i64 = -1}, -1, 6, VE},
 +    { "tile-rows",       "Number of tile rows to use, log2",            OFFSET(tile_rows),       AV_OPT_TYPE_INT, {.i64 = -1}, -1, 2, VE},
 +    { "frame-parallel",  "Enable frame parallel decodability features", OFFSET(frame_parallel),  AV_OPT_TYPE_BOOL,{.i64 = -1}, -1, 1, VE},
 +    { "aq-mode",         "adaptive quantization mode",                  OFFSET(aq_mode),         AV_OPT_TYPE_INT, {.i64 = -1}, -1, 3, VE, "aq_mode"},
 +    { "none",            "Aq not used",         0, AV_OPT_TYPE_CONST, {.i64 = 0}, 0, 0, VE, "aq_mode" },
 +    { "variance",        "Variance based Aq",   0, AV_OPT_TYPE_CONST, {.i64 = 1}, 0, 0, VE, "aq_mode" },
 +    { "complexity",      "Complexity based Aq", 0, AV_OPT_TYPE_CONST, {.i64 = 2}, 0, 0, VE, "aq_mode" },
 +    { "cyclic",          "Cyclic Refresh Aq",   0, AV_OPT_TYPE_CONST, {.i64 = 3}, 0, 0, VE, "aq_mode" },
 +    LEGACY_OPTIONS
 +    { NULL }
 +};
 +#endif
 +
 +#undef COMMON_OPTIONS
 +#undef LEGACY_OPTIONS
  
  static const AVCodecDefault defaults[] = {
      { "qmin",             "-1" },
@@@ -2509,7 -1530,7 +2509,7 @@@ void mpv_decode_mb_internal(MpegEncCont
      else if (!is_mpeg12 && (s->h263_pred || s->h263_aic))
          s->mbintra_table[mb_xy]=1;
  
-     if ((s->avctx->flags & AV_CODEC_FLAG_PSNR) || s->avctx->frame_skip_threshold || s->avctx->frame_skip_factor ||
 -    if ((s->avctx->flags & AV_CODEC_FLAG_PSNR) ||
++    if ((s->avctx->flags & AV_CODEC_FLAG_PSNR) || s->frame_skip_threshold || s->frame_skip_factor ||
          !(s->encoding && (s->intra_only || s->pict_type == AV_PICTURE_TYPE_B) &&
            s->avctx->mb_decision != FF_MB_DECISION_RD)) { // FIXME precalc
          uint8_t *dest_y, *dest_cb, *dest_cr;
@@@ -560,17 -544,26 +566,34 @@@ typedef struct MpegEncContext 
  #define FF_MPV_FLAG_NAQ          0x0010
  #define FF_MPV_FLAG_MV0          0x0020
  
 +enum rc_strategy {
 +    MPV_RC_STRATEGY_FFMPEG,
 +    MPV_RC_STRATEGY_XVID,
 +    NB_MPV_RC_STRATEGY
 +};
 +
+ #define FF_MPV_OPT_CMP_FUNC \
+ { "sad",    "Sum of absolute differences, fast", 0, AV_OPT_TYPE_CONST, {.i64 = FF_CMP_SAD }, INT_MIN, INT_MAX, FF_MPV_OPT_FLAGS, "cmp_func" }, \
+ { "sse",    "Sum of squared errors", 0, AV_OPT_TYPE_CONST, {.i64 = FF_CMP_SSE }, INT_MIN, INT_MAX, FF_MPV_OPT_FLAGS, "cmp_func" }, \
+ { "satd",   "Sum of absolute Hadamard transformed differences", 0, AV_OPT_TYPE_CONST, {.i64 = FF_CMP_SATD }, INT_MIN, INT_MAX, FF_MPV_OPT_FLAGS, "cmp_func" }, \
+ { "dct",    "Sum of absolute DCT transformed differences", 0, AV_OPT_TYPE_CONST, {.i64 = FF_CMP_DCT }, INT_MIN, INT_MAX, FF_MPV_OPT_FLAGS, "cmp_func" }, \
+ { "psnr",   "Sum of squared quantization errors, low quality", 0, AV_OPT_TYPE_CONST, {.i64 = FF_CMP_PSNR }, INT_MIN, INT_MAX, FF_MPV_OPT_FLAGS, "cmp_func" }, \
+ { "bit",    "Number of bits needed for the block", 0, AV_OPT_TYPE_CONST, {.i64 = FF_CMP_BIT }, INT_MIN, INT_MAX, FF_MPV_OPT_FLAGS, "cmp_func" }, \
+ { "rd",     "Rate distortion optimal, slow", 0, AV_OPT_TYPE_CONST, {.i64 = FF_CMP_RD }, INT_MIN, INT_MAX, FF_MPV_OPT_FLAGS, "cmp_func" }, \
+ { "zero",   "Zero", 0, AV_OPT_TYPE_CONST, {.i64 = FF_CMP_ZERO }, INT_MIN, INT_MAX, FF_MPV_OPT_FLAGS, "cmp_func" }, \
+ { "vsad",   "Sum of absolute vertical differences", 0, AV_OPT_TYPE_CONST, {.i64 = FF_CMP_VSAD }, INT_MIN, INT_MAX, FF_MPV_OPT_FLAGS, "cmp_func" }, \
+ { "vsse",   "Sum of squared vertical differences", 0, AV_OPT_TYPE_CONST, {.i64 = FF_CMP_VSSE }, INT_MIN, INT_MAX, FF_MPV_OPT_FLAGS, "cmp_func" }, \
+ { "nsse",   "Noise preserving sum of squared differences", 0, AV_OPT_TYPE_CONST, {.i64 = FF_CMP_NSSE }, INT_MIN, INT_MAX, FF_MPV_OPT_FLAGS, "cmp_func" }, \
+ { "dct264", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_CMP_DCT264 }, INT_MIN, INT_MAX, FF_MPV_OPT_FLAGS, "cmp_func" }, \
+ { "dctmax", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_CMP_DCTMAX }, INT_MIN, INT_MAX, FF_MPV_OPT_FLAGS, "cmp_func" }, \
+ { "chroma", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_CMP_CHROMA }, INT_MIN, INT_MAX, FF_MPV_OPT_FLAGS, "cmp_func" }
 +#ifndef FF_MPV_OFFSET
  #define FF_MPV_OFFSET(x) offsetof(MpegEncContext, x)
 +#endif
  #define FF_MPV_OPT_FLAGS (AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_ENCODING_PARAM)
  #define FF_MPV_COMMON_OPTS \
+ FF_MPV_OPT_CMP_FUNC, \
  { "mpv_flags",      "Flags common for all mpegvideo-based encoders.", FF_MPV_OFFSET(mpv_flags), AV_OPT_TYPE_FLAGS, { .i64 = 0 }, INT_MIN, INT_MAX, FF_MPV_OPT_FLAGS, "mpv_flags" },\
  { "skip_rd",        "RD optimal MB level residual skipping", 0, AV_OPT_TYPE_CONST, { .i64 = FF_MPV_FLAG_SKIP_RD },    0, 0, FF_MPV_OPT_FLAGS, "mpv_flags" },\
  { "strict_gop",     "Strictly enforce gop size",             0, AV_OPT_TYPE_CONST, { .i64 = FF_MPV_FLAG_STRICT_GOP }, 0, 0, FF_MPV_OPT_FLAGS, "mpv_flags" },\
@@@ -1317,12 -1162,12 +1330,12 @@@ static int skip_check(MpegEncContext *s
                  uint8_t *rptr = ref->f->data[plane] + 8 * (x + y * stride);
                  int v = s->mecc.frame_skip_cmp[1](s, dptr, rptr, stride, 8);
  
-                 switch (FFABS(s->avctx->frame_skip_exp)) {
 -                switch (s->frame_skip_exp) {
++                switch (FFABS(s->frame_skip_exp)) {
                  case 0: score    =  FFMAX(score, v);          break;
                  case 1: score   += FFABS(v);                  break;
 -                case 2: score   += v * v;                     break;
 -                case 3: score64 += FFABS(v * v * (int64_t)v); break;
 -                case 4: score64 += v * v * (int64_t)(v * v);  break;
 +                case 2: score64 += v * (int64_t)v;                       break;
 +                case 3: score64 += FFABS(v * (int64_t)v * v);            break;
 +                case 4: score64 += (v * (int64_t)v) * (v * (int64_t)v);  break;
                  }
              }
          }
  
      if (score)
          score64 = score;
-     if (s->avctx->frame_skip_exp < 0)
++    if (s->frame_skip_exp < 0)
 +        score64 = pow(score64 / (double)(s->mb_width * s->mb_height),
-                       -1.0/s->avctx->frame_skip_exp);
++                      -1.0/s->frame_skip_exp);
  
-     if (score64 < s->avctx->frame_skip_threshold)
+     if (score64 < s->frame_skip_threshold)
          return 1;
-     if (score64 < ((s->avctx->frame_skip_factor * (int64_t)s->lambda) >> 8))
+     if (score64 < ((s->frame_skip_factor * (int64_t) s->lambda) >> 8))
          return 1;
      return 0;
  }
@@@ -1485,19 -1324,6 +1498,19 @@@ static int select_input_picture(MpegEnc
  
      /* set next picture type & ordering */
      if (!s->reordered_input_picture[0] && s->input_picture[0]) {
-         if (s->avctx->frame_skip_threshold || s->avctx->frame_skip_factor) {
++        if (s->frame_skip_threshold || s->frame_skip_factor) {
 +            if (s->picture_in_gop_number < s->gop_size &&
 +                s->next_picture_ptr &&
 +                skip_check(s, s->input_picture[0], s->next_picture_ptr)) {
 +                // FIXME check that te gop check above is +-1 correct
 +                av_frame_unref(s->input_picture[0]->f);
 +
 +                ff_vbv_update(s, 0);
 +
 +                goto no_output_pic;
 +            }
 +        }
 +
          if (/*s->picture_in_gop_number >= s->gop_size ||*/
              !s->next_picture_ptr || s->intra_only) {
              s->reordered_input_picture[0] = s->input_picture[0];
@@@ -375,13 -361,9 +375,14 @@@ static const AVOption avcodec_options[
  {"dts_96_24", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_PROFILE_DTS_96_24 }, INT_MIN, INT_MAX, A|E, "profile"},
  {"dts_hd_hra", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_PROFILE_DTS_HD_HRA }, INT_MIN, INT_MAX, A|E, "profile"},
  {"dts_hd_ma", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_PROFILE_DTS_HD_MA }, INT_MIN, INT_MAX, A|E, "profile"},
 +{"mpeg4_sp",   NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_PROFILE_MPEG4_SIMPLE }, INT_MIN, INT_MAX, V|E, "profile"},
 +{"mpeg4_core", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_PROFILE_MPEG4_CORE }, INT_MIN, INT_MAX, V|E, "profile"},
 +{"mpeg4_main", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_PROFILE_MPEG4_MAIN }, INT_MIN, INT_MAX, V|E, "profile"},
 +{"mpeg4_asp",  NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_PROFILE_MPEG4_ADVANCED_SIMPLE }, INT_MIN, INT_MAX, V|E, "profile"},
  {"level", NULL, OFFSET(level), AV_OPT_TYPE_INT, {.i64 = FF_LEVEL_UNKNOWN }, INT_MIN, INT_MAX, V|A|E, "level"},
  {"unknown", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_LEVEL_UNKNOWN }, INT_MIN, INT_MAX, V|A|E, "level"},
 +{"lowres", "decode at 1= 1/2, 2=1/4, 3=1/8 resolutions", OFFSET(lowres), AV_OPT_TYPE_INT, {.i64 = 0 }, 0, INT_MAX, V|A|D},
+ #if FF_API_PRIVATE_OPT
  {"skip_threshold", "frame skip threshold", OFFSET(frame_skip_threshold), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX, V|E},
  {"skip_factor", "frame skip factor", OFFSET(frame_skip_factor), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX, V|E},
  {"skip_exp", "frame skip exponent", OFFSET(frame_skip_exp), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX, V|E},