media/libvpx/vp9/vp9_cx_iface.c

Thu, 15 Jan 2015 15:59:08 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Thu, 15 Jan 2015 15:59:08 +0100
branch
TOR_BUG_9701
changeset 10
ac0c01689b40
permissions
-rw-r--r--

Implement a real Private Browsing Mode condition by changing the API/ABI;
This solves Tor bug #9701, complying with disk avoidance documented in
https://www.torproject.org/projects/torbrowser/design/#disk-avoidance.

     1 /*
     2  *  Copyright (c) 2010 The WebM project authors. All Rights Reserved.
     3  *
     4  *  Use of this source code is governed by a BSD-style license
     5  *  that can be found in the LICENSE file in the root of the source
     6  *  tree. An additional intellectual property rights grant can be found
     7  *  in the file PATENTS.  All contributing project authors may
     8  *  be found in the AUTHORS file in the root of the source tree.
     9  */
    11 #include <stdlib.h>
    12 #include <string.h>
    14 #include "vpx/vpx_codec.h"
    15 #include "vpx/internal/vpx_codec_internal.h"
    16 #include "./vpx_version.h"
    17 #include "vp9/encoder/vp9_onyx_int.h"
    18 #include "vpx/vp8cx.h"
    19 #include "vp9/encoder/vp9_firstpass.h"
    20 #include "vp9/common/vp9_onyx.h"
    21 #include "vp9/vp9_iface_common.h"
    23 struct vp9_extracfg {
    24   struct vpx_codec_pkt_list *pkt_list;
    25   int                         cpu_used;  /* available cpu percentage in 1/16 */
    26   unsigned int                enable_auto_alt_ref;
    27   unsigned int                noise_sensitivity;
    28   unsigned int                Sharpness;
    29   unsigned int                static_thresh;
    30   unsigned int                tile_columns;
    31   unsigned int                tile_rows;
    32   unsigned int                arnr_max_frames;
    33   unsigned int                arnr_strength;
    34   unsigned int                arnr_type;
    35   unsigned int                experimental;
    36   vp8e_tuning                 tuning;
    37   unsigned int                cq_level;         /* constrained quality level */
    38   unsigned int                rc_max_intra_bitrate_pct;
    39   unsigned int                lossless;
    40   unsigned int                frame_parallel_decoding_mode;
    41   unsigned int                aq_mode;
    42 };
    44 struct extraconfig_map {
    45   int                 usage;
    46   struct vp9_extracfg cfg;
    47 };
    49 static const struct extraconfig_map extracfg_map[] = {
    50   {
    51     0,
    52     { // NOLINT
    53       NULL,
    54       0,                          /* cpu_used      */
    55       1,                          /* enable_auto_alt_ref */
    56       0,                          /* noise_sensitivity */
    57       0,                          /* Sharpness */
    58       0,                          /* static_thresh */
    59       0,                          /* tile_columns */
    60       0,                          /* tile_rows */
    61       7,                          /* arnr_max_frames */
    62       5,                          /* arnr_strength */
    63       3,                          /* arnr_type*/
    64       0,                          /* experimental mode */
    65       0,                          /* tuning*/
    66       10,                         /* cq_level */
    67       0,                          /* rc_max_intra_bitrate_pct */
    68       0,                          /* lossless */
    69       0,                          /* frame_parallel_decoding_mode */
    70       0,                          /* aq_mode */
    71     }
    72   }
    73 };
    75 struct vpx_codec_alg_priv {
    76   vpx_codec_priv_t        base;
    77   vpx_codec_enc_cfg_t     cfg;
    78   struct vp9_extracfg     vp8_cfg;
    79   VP9_CONFIG              oxcf;
    80   VP9_PTR             cpi;
    81   unsigned char          *cx_data;
    82   unsigned int            cx_data_sz;
    83   unsigned char          *pending_cx_data;
    84   unsigned int            pending_cx_data_sz;
    85   int                     pending_frame_count;
    86   uint32_t                pending_frame_sizes[8];
    87   uint32_t                pending_frame_magnitude;
    88   vpx_image_t             preview_img;
    89   vp8_postproc_cfg_t      preview_ppcfg;
    90   vpx_codec_pkt_list_decl(64) pkt_list;
    91   unsigned int                fixed_kf_cntr;
    92 };
    94 static VP9_REFFRAME ref_frame_to_vp9_reframe(vpx_ref_frame_type_t frame) {
    95   switch (frame) {
    96     case VP8_LAST_FRAME:
    97       return VP9_LAST_FLAG;
    98     case VP8_GOLD_FRAME:
    99       return VP9_GOLD_FLAG;
   100     case VP8_ALTR_FRAME:
   101       return VP9_ALT_FLAG;
   102   }
   103   assert(!"Invalid Reference Frame");
   104   return VP9_LAST_FLAG;
   105 }
   107 static vpx_codec_err_t
   108 update_error_state(vpx_codec_alg_priv_t                 *ctx,
   109                    const struct vpx_internal_error_info *error) {
   110   vpx_codec_err_t res;
   112   if ((res = error->error_code))
   113     ctx->base.err_detail = error->has_detail
   114                            ? error->detail
   115                            : NULL;
   117   return res;
   118 }
   121 #undef ERROR
   122 #define ERROR(str) do {\
   123     ctx->base.err_detail = str;\
   124     return VPX_CODEC_INVALID_PARAM;\
   125   } while (0)
   127 #define RANGE_CHECK(p, memb, lo, hi) do {\
   128     if (!(((p)->memb == lo || (p)->memb > (lo)) && (p)->memb <= hi)) \
   129       ERROR(#memb " out of range ["#lo".."#hi"]");\
   130   } while (0)
   132 #define RANGE_CHECK_HI(p, memb, hi) do {\
   133     if (!((p)->memb <= (hi))) \
   134       ERROR(#memb " out of range [.."#hi"]");\
   135   } while (0)
   137 #define RANGE_CHECK_LO(p, memb, lo) do {\
   138     if (!((p)->memb >= (lo))) \
   139       ERROR(#memb " out of range ["#lo"..]");\
   140   } while (0)
   142 #define RANGE_CHECK_BOOL(p, memb) do {\
   143     if (!!((p)->memb) != (p)->memb) ERROR(#memb " expected boolean");\
   144   } while (0)
   146 static vpx_codec_err_t validate_config(vpx_codec_alg_priv_t      *ctx,
   147                                        const vpx_codec_enc_cfg_t *cfg,
   148                                        const struct vp9_extracfg *vp8_cfg) {
   149   RANGE_CHECK(cfg, g_w,                   1, 65535); /* 16 bits available */
   150   RANGE_CHECK(cfg, g_h,                   1, 65535); /* 16 bits available */
   151   RANGE_CHECK(cfg, g_timebase.den,        1, 1000000000);
   152   RANGE_CHECK(cfg, g_timebase.num,        1, cfg->g_timebase.den);
   153   RANGE_CHECK_HI(cfg, g_profile,          3);
   155   RANGE_CHECK_HI(cfg, rc_max_quantizer,   63);
   156   RANGE_CHECK_HI(cfg, rc_min_quantizer,   cfg->rc_max_quantizer);
   157   RANGE_CHECK_BOOL(vp8_cfg, lossless);
   158   if (vp8_cfg->lossless) {
   159     RANGE_CHECK_HI(cfg, rc_max_quantizer, 0);
   160     RANGE_CHECK_HI(cfg, rc_min_quantizer, 0);
   161   }
   162   RANGE_CHECK(vp8_cfg, aq_mode,           0, AQ_MODES_COUNT - 1);
   164   RANGE_CHECK_HI(cfg, g_threads,          64);
   165   RANGE_CHECK_HI(cfg, g_lag_in_frames,    MAX_LAG_BUFFERS);
   166   RANGE_CHECK(cfg, rc_end_usage,          VPX_VBR, VPX_Q);
   167   RANGE_CHECK_HI(cfg, rc_undershoot_pct,  1000);
   168   RANGE_CHECK_HI(cfg, rc_overshoot_pct,   1000);
   169   RANGE_CHECK_HI(cfg, rc_2pass_vbr_bias_pct, 100);
   170   RANGE_CHECK(cfg, kf_mode,               VPX_KF_DISABLED, VPX_KF_AUTO);
   171   // RANGE_CHECK_BOOL(cfg,                 g_delete_firstpassfile);
   172   RANGE_CHECK_BOOL(cfg,                   rc_resize_allowed);
   173   RANGE_CHECK_HI(cfg, rc_dropframe_thresh,   100);
   174   RANGE_CHECK_HI(cfg, rc_resize_up_thresh,   100);
   175   RANGE_CHECK_HI(cfg, rc_resize_down_thresh, 100);
   176   RANGE_CHECK(cfg,        g_pass,         VPX_RC_ONE_PASS, VPX_RC_LAST_PASS);
   178   RANGE_CHECK(cfg, ss_number_layers,      1,
   179               VPX_SS_MAX_LAYERS); /*Spatial layers max */
   180   /* VP8 does not support a lower bound on the keyframe interval in
   181    * automatic keyframe placement mode.
   182    */
   183   if (cfg->kf_mode != VPX_KF_DISABLED && cfg->kf_min_dist != cfg->kf_max_dist
   184       && cfg->kf_min_dist > 0)
   185     ERROR("kf_min_dist not supported in auto mode, use 0 "
   186           "or kf_max_dist instead.");
   188   RANGE_CHECK_BOOL(vp8_cfg,               enable_auto_alt_ref);
   189   RANGE_CHECK(vp8_cfg, cpu_used,           -16, 16);
   191   RANGE_CHECK_HI(vp8_cfg, noise_sensitivity,  6);
   193   RANGE_CHECK(vp8_cfg, tile_columns, 0, 6);
   194   RANGE_CHECK(vp8_cfg, tile_rows, 0, 2);
   195   RANGE_CHECK_HI(vp8_cfg, Sharpness,       7);
   196   RANGE_CHECK(vp8_cfg, arnr_max_frames, 0, 15);
   197   RANGE_CHECK_HI(vp8_cfg, arnr_strength,   6);
   198   RANGE_CHECK(vp8_cfg, arnr_type,       1, 3);
   199   RANGE_CHECK(vp8_cfg, cq_level, 0, 63);
   201   if (cfg->g_pass == VPX_RC_LAST_PASS) {
   202     size_t           packet_sz = sizeof(FIRSTPASS_STATS);
   203     int              n_packets = (int)(cfg->rc_twopass_stats_in.sz / packet_sz);
   204     FIRSTPASS_STATS *stats;
   206     if (!cfg->rc_twopass_stats_in.buf)
   207       ERROR("rc_twopass_stats_in.buf not set.");
   209     if (cfg->rc_twopass_stats_in.sz % packet_sz)
   210       ERROR("rc_twopass_stats_in.sz indicates truncated packet.");
   212     if (cfg->rc_twopass_stats_in.sz < 2 * packet_sz)
   213       ERROR("rc_twopass_stats_in requires at least two packets.");
   215     stats = (void *)((char *)cfg->rc_twopass_stats_in.buf
   216                      + (n_packets - 1) * packet_sz);
   218     if ((int)(stats->count + 0.5) != n_packets - 1)
   219       ERROR("rc_twopass_stats_in missing EOS stats packet");
   220   }
   222   return VPX_CODEC_OK;
   223 }
   226 static vpx_codec_err_t validate_img(vpx_codec_alg_priv_t *ctx,
   227                                     const vpx_image_t    *img) {
   228   switch (img->fmt) {
   229     case VPX_IMG_FMT_YV12:
   230     case VPX_IMG_FMT_I420:
   231     case VPX_IMG_FMT_I422:
   232     case VPX_IMG_FMT_I444:
   233       break;
   234     default:
   235       ERROR("Invalid image format. Only YV12, I420, I422, I444 images are "
   236             "supported.");
   237   }
   239   if ((img->d_w != ctx->cfg.g_w) || (img->d_h != ctx->cfg.g_h))
   240     ERROR("Image size must match encoder init configuration size");
   242   return VPX_CODEC_OK;
   243 }
   246 static vpx_codec_err_t set_vp9e_config(VP9_CONFIG *oxcf,
   247                                        vpx_codec_enc_cfg_t cfg,
   248                                        struct vp9_extracfg vp8_cfg) {
   249   oxcf->version = cfg.g_profile | (vp8_cfg.experimental ? 0x4 : 0);
   250   oxcf->width   = cfg.g_w;
   251   oxcf->height  = cfg.g_h;
   252   /* guess a frame rate if out of whack, use 30 */
   253   oxcf->framerate = (double)(cfg.g_timebase.den)
   254                     / (double)(cfg.g_timebase.num);
   256   if (oxcf->framerate > 180) {
   257     oxcf->framerate = 30;
   258   }
   260   switch (cfg.g_pass) {
   261     case VPX_RC_ONE_PASS:
   262       oxcf->Mode = MODE_GOODQUALITY;
   263       break;
   264     case VPX_RC_FIRST_PASS:
   265       oxcf->Mode = MODE_FIRSTPASS;
   266       break;
   267     case VPX_RC_LAST_PASS:
   268       oxcf->Mode = MODE_SECONDPASS_BEST;
   269       break;
   270   }
   272   if (cfg.g_pass == VPX_RC_FIRST_PASS) {
   273     oxcf->allow_lag     = 0;
   274     oxcf->lag_in_frames = 0;
   275   } else {
   276     oxcf->allow_lag     = (cfg.g_lag_in_frames) > 0;
   277     oxcf->lag_in_frames = cfg.g_lag_in_frames;
   278   }
   280   // VBR only supported for now.
   281   // CBR code has been deprectated for experimental phase.
   282   // CQ mode not yet tested
   283   oxcf->end_usage        = USAGE_LOCAL_FILE_PLAYBACK;
   284   if (cfg.rc_end_usage == VPX_CQ)
   285     oxcf->end_usage      = USAGE_CONSTRAINED_QUALITY;
   286   else if (cfg.rc_end_usage == VPX_Q)
   287     oxcf->end_usage      = USAGE_CONSTANT_QUALITY;
   288   else if (cfg.rc_end_usage == VPX_CBR)
   289     oxcf->end_usage = USAGE_STREAM_FROM_SERVER;
   291   oxcf->target_bandwidth         = cfg.rc_target_bitrate;
   292   oxcf->rc_max_intra_bitrate_pct = vp8_cfg.rc_max_intra_bitrate_pct;
   294   oxcf->best_allowed_q          = cfg.rc_min_quantizer;
   295   oxcf->worst_allowed_q         = cfg.rc_max_quantizer;
   296   oxcf->cq_level                = vp8_cfg.cq_level;
   297   oxcf->fixed_q = -1;
   299   oxcf->under_shoot_pct         = cfg.rc_undershoot_pct;
   300   oxcf->over_shoot_pct          = cfg.rc_overshoot_pct;
   302   oxcf->maximum_buffer_size     = cfg.rc_buf_sz;
   303   oxcf->starting_buffer_level   = cfg.rc_buf_initial_sz;
   304   oxcf->optimal_buffer_level    = cfg.rc_buf_optimal_sz;
   306   oxcf->two_pass_vbrbias         = cfg.rc_2pass_vbr_bias_pct;
   307   oxcf->two_pass_vbrmin_section  = cfg.rc_2pass_vbr_minsection_pct;
   308   oxcf->two_pass_vbrmax_section  = cfg.rc_2pass_vbr_maxsection_pct;
   310   oxcf->auto_key               = cfg.kf_mode == VPX_KF_AUTO
   311                                  && cfg.kf_min_dist != cfg.kf_max_dist;
   312   // oxcf->kf_min_dist         = cfg.kf_min_dis;
   313   oxcf->key_freq               = cfg.kf_max_dist;
   315   // oxcf->delete_first_pass_file = cfg.g_delete_firstpassfile;
   316   // strcpy(oxcf->first_pass_file, cfg.g_firstpass_file);
   318   oxcf->cpu_used               =  vp8_cfg.cpu_used;
   319   oxcf->encode_breakout        =  vp8_cfg.static_thresh;
   320   oxcf->play_alternate         =  vp8_cfg.enable_auto_alt_ref;
   321   oxcf->noise_sensitivity      =  vp8_cfg.noise_sensitivity;
   322   oxcf->Sharpness              =  vp8_cfg.Sharpness;
   324   oxcf->two_pass_stats_in      =  cfg.rc_twopass_stats_in;
   325   oxcf->output_pkt_list        =  vp8_cfg.pkt_list;
   327   oxcf->arnr_max_frames = vp8_cfg.arnr_max_frames;
   328   oxcf->arnr_strength   = vp8_cfg.arnr_strength;
   329   oxcf->arnr_type       = vp8_cfg.arnr_type;
   331   oxcf->tuning = vp8_cfg.tuning;
   333   oxcf->tile_columns = vp8_cfg.tile_columns;
   334   oxcf->tile_rows    = vp8_cfg.tile_rows;
   336   oxcf->lossless = vp8_cfg.lossless;
   338   oxcf->error_resilient_mode         = cfg.g_error_resilient;
   339   oxcf->frame_parallel_decoding_mode = vp8_cfg.frame_parallel_decoding_mode;
   341   oxcf->aq_mode = vp8_cfg.aq_mode;
   343   oxcf->ss_number_layers = cfg.ss_number_layers;
   344   /*
   345   printf("Current VP9 Settings: \n");
   346   printf("target_bandwidth: %d\n", oxcf->target_bandwidth);
   347   printf("noise_sensitivity: %d\n", oxcf->noise_sensitivity);
   348   printf("Sharpness: %d\n",    oxcf->Sharpness);
   349   printf("cpu_used: %d\n",  oxcf->cpu_used);
   350   printf("Mode: %d\n",     oxcf->Mode);
   351   // printf("delete_first_pass_file: %d\n",  oxcf->delete_first_pass_file);
   352   printf("auto_key: %d\n",  oxcf->auto_key);
   353   printf("key_freq: %d\n", oxcf->key_freq);
   354   printf("end_usage: %d\n", oxcf->end_usage);
   355   printf("under_shoot_pct: %d\n", oxcf->under_shoot_pct);
   356   printf("over_shoot_pct: %d\n", oxcf->over_shoot_pct);
   357   printf("starting_buffer_level: %d\n", oxcf->starting_buffer_level);
   358   printf("optimal_buffer_level: %d\n",  oxcf->optimal_buffer_level);
   359   printf("maximum_buffer_size: %d\n", oxcf->maximum_buffer_size);
   360   printf("fixed_q: %d\n",  oxcf->fixed_q);
   361   printf("worst_allowed_q: %d\n", oxcf->worst_allowed_q);
   362   printf("best_allowed_q: %d\n", oxcf->best_allowed_q);
   363   printf("two_pass_vbrbias: %d\n",  oxcf->two_pass_vbrbias);
   364   printf("two_pass_vbrmin_section: %d\n", oxcf->two_pass_vbrmin_section);
   365   printf("two_pass_vbrmax_section: %d\n", oxcf->two_pass_vbrmax_section);
   366   printf("allow_lag: %d\n", oxcf->allow_lag);
   367   printf("lag_in_frames: %d\n", oxcf->lag_in_frames);
   368   printf("play_alternate: %d\n", oxcf->play_alternate);
   369   printf("Version: %d\n", oxcf->Version);
   370   printf("encode_breakout: %d\n", oxcf->encode_breakout);
   371   printf("error resilient: %d\n", oxcf->error_resilient_mode);
   372   printf("frame parallel detokenization: %d\n",
   373          oxcf->frame_parallel_decoding_mode);
   374   */
   375   return VPX_CODEC_OK;
   376 }
   378 static vpx_codec_err_t vp9e_set_config(vpx_codec_alg_priv_t       *ctx,
   379                                        const vpx_codec_enc_cfg_t  *cfg) {
   380   vpx_codec_err_t res;
   382   if ((cfg->g_w != ctx->cfg.g_w) || (cfg->g_h != ctx->cfg.g_h))
   383     ERROR("Cannot change width or height after initialization");
   385   /* Prevent increasing lag_in_frames. This check is stricter than it needs
   386    * to be -- the limit is not increasing past the first lag_in_frames
   387    * value, but we don't track the initial config, only the last successful
   388    * config.
   389    */
   390   if ((cfg->g_lag_in_frames > ctx->cfg.g_lag_in_frames))
   391     ERROR("Cannot increase lag_in_frames");
   393   res = validate_config(ctx, cfg, &ctx->vp8_cfg);
   395   if (!res) {
   396     ctx->cfg = *cfg;
   397     set_vp9e_config(&ctx->oxcf, ctx->cfg, ctx->vp8_cfg);
   398     vp9_change_config(ctx->cpi, &ctx->oxcf);
   399   }
   401   return res;
   402 }
   405 int vp9_reverse_trans(int q);
   408 static vpx_codec_err_t get_param(vpx_codec_alg_priv_t *ctx,
   409                                  int                   ctrl_id,
   410                                  va_list               args) {
   411   void *arg = va_arg(args, void *);
   413 #define MAP(id, var) case id: *(RECAST(id, arg)) = var; break
   415   if (!arg)
   416     return VPX_CODEC_INVALID_PARAM;
   418   switch (ctrl_id) {
   419       MAP(VP8E_GET_LAST_QUANTIZER, vp9_get_quantizer(ctx->cpi));
   420       MAP(VP8E_GET_LAST_QUANTIZER_64,
   421           vp9_reverse_trans(vp9_get_quantizer(ctx->cpi)));
   422   }
   424   return VPX_CODEC_OK;
   425 #undef MAP
   426 }
   429 static vpx_codec_err_t set_param(vpx_codec_alg_priv_t *ctx,
   430                                  int                   ctrl_id,
   431                                  va_list               args) {
   432   vpx_codec_err_t     res  = VPX_CODEC_OK;
   433   struct vp9_extracfg xcfg = ctx->vp8_cfg;
   435 #define MAP(id, var) case id: var = CAST(id, args); break;
   437   switch (ctrl_id) {
   438       MAP(VP8E_SET_CPUUSED,                 xcfg.cpu_used);
   439       MAP(VP8E_SET_ENABLEAUTOALTREF,        xcfg.enable_auto_alt_ref);
   440       MAP(VP8E_SET_NOISE_SENSITIVITY,       xcfg.noise_sensitivity);
   441       MAP(VP8E_SET_SHARPNESS,               xcfg.Sharpness);
   442       MAP(VP8E_SET_STATIC_THRESHOLD,        xcfg.static_thresh);
   443       MAP(VP9E_SET_TILE_COLUMNS,            xcfg.tile_columns);
   444       MAP(VP9E_SET_TILE_ROWS,               xcfg.tile_rows);
   445       MAP(VP8E_SET_ARNR_MAXFRAMES,          xcfg.arnr_max_frames);
   446       MAP(VP8E_SET_ARNR_STRENGTH,           xcfg.arnr_strength);
   447       MAP(VP8E_SET_ARNR_TYPE,               xcfg.arnr_type);
   448       MAP(VP8E_SET_TUNING,                  xcfg.tuning);
   449       MAP(VP8E_SET_CQ_LEVEL,                xcfg.cq_level);
   450       MAP(VP8E_SET_MAX_INTRA_BITRATE_PCT,   xcfg.rc_max_intra_bitrate_pct);
   451       MAP(VP9E_SET_LOSSLESS,                xcfg.lossless);
   452       MAP(VP9E_SET_FRAME_PARALLEL_DECODING, xcfg.frame_parallel_decoding_mode);
   453       MAP(VP9E_SET_AQ_MODE,                 xcfg.aq_mode);
   454   }
   456   res = validate_config(ctx, &ctx->cfg, &xcfg);
   458   if (!res) {
   459     ctx->vp8_cfg = xcfg;
   460     set_vp9e_config(&ctx->oxcf, ctx->cfg, ctx->vp8_cfg);
   461     vp9_change_config(ctx->cpi, &ctx->oxcf);
   462   }
   464   return res;
   465 #undef MAP
   466 }
   469 static vpx_codec_err_t vp9e_common_init(vpx_codec_ctx_t *ctx,
   470                                         int              experimental) {
   471   vpx_codec_err_t            res = VPX_CODEC_OK;
   472   struct vpx_codec_alg_priv *priv;
   473   vpx_codec_enc_cfg_t       *cfg;
   474   unsigned int               i;
   476   VP9_PTR optr;
   478   if (!ctx->priv) {
   479     priv = calloc(1, sizeof(struct vpx_codec_alg_priv));
   481     if (!priv) {
   482       return VPX_CODEC_MEM_ERROR;
   483     }
   485     ctx->priv = &priv->base;
   486     ctx->priv->sz = sizeof(*ctx->priv);
   487     ctx->priv->iface = ctx->iface;
   488     ctx->priv->alg_priv = priv;
   489     ctx->priv->init_flags = ctx->init_flags;
   490     ctx->priv->enc.total_encoders = 1;
   492     if (ctx->config.enc) {
   493       /* Update the reference to the config structure to an
   494        * internal copy.
   495        */
   496       ctx->priv->alg_priv->cfg = *ctx->config.enc;
   497       ctx->config.enc = &ctx->priv->alg_priv->cfg;
   498     }
   500     cfg =  &ctx->priv->alg_priv->cfg;
   502     /* Select the extra vp6 configuration table based on the current
   503      * usage value. If the current usage value isn't found, use the
   504      * values for usage case 0.
   505      */
   506     for (i = 0;
   507          extracfg_map[i].usage && extracfg_map[i].usage != cfg->g_usage;
   508          i++) {}
   510     priv->vp8_cfg = extracfg_map[i].cfg;
   511     priv->vp8_cfg.pkt_list = &priv->pkt_list.head;
   512     priv->vp8_cfg.experimental = experimental;
   514     // TODO(agrange) Check the limits set on this buffer, or the check that is
   515     // applied in vp9e_encode.
   516     priv->cx_data_sz = priv->cfg.g_w * priv->cfg.g_h * 3 / 2 * 8;
   517 //    priv->cx_data_sz = priv->cfg.g_w * priv->cfg.g_h * 3 / 2 * 2;
   519     if (priv->cx_data_sz < 4096) priv->cx_data_sz = 4096;
   521     priv->cx_data = malloc(priv->cx_data_sz);
   523     if (!priv->cx_data) {
   524       return VPX_CODEC_MEM_ERROR;
   525     }
   527     vp9_initialize_enc();
   529     res = validate_config(priv, &priv->cfg, &priv->vp8_cfg);
   531     if (!res) {
   532       set_vp9e_config(&ctx->priv->alg_priv->oxcf,
   533                       ctx->priv->alg_priv->cfg,
   534                       ctx->priv->alg_priv->vp8_cfg);
   535       optr = vp9_create_compressor(&ctx->priv->alg_priv->oxcf);
   537       if (!optr)
   538         res = VPX_CODEC_MEM_ERROR;
   539       else
   540         ctx->priv->alg_priv->cpi = optr;
   541     }
   542   }
   544   return res;
   545 }
   548 static vpx_codec_err_t vp9e_init(vpx_codec_ctx_t *ctx,
   549                                  vpx_codec_priv_enc_mr_cfg_t *data) {
   550   return vp9e_common_init(ctx, 0);
   551 }
   554 #if CONFIG_EXPERIMENTAL
   555 static vpx_codec_err_t vp9e_exp_init(vpx_codec_ctx_t *ctx,
   556                                      vpx_codec_priv_enc_mr_cfg_t *data) {
   557   return vp9e_common_init(ctx, 1);
   558 }
   559 #endif
   562 static vpx_codec_err_t vp9e_destroy(vpx_codec_alg_priv_t *ctx) {
   563   free(ctx->cx_data);
   564   vp9_remove_compressor(&ctx->cpi);
   565   free(ctx);
   566   return VPX_CODEC_OK;
   567 }
   569 static void pick_quickcompress_mode(vpx_codec_alg_priv_t  *ctx,
   570                                     unsigned long          duration,
   571                                     unsigned long          deadline) {
   572   unsigned int new_qc;
   574   /* Use best quality mode if no deadline is given. */
   575   if (deadline)
   576     new_qc = MODE_GOODQUALITY;
   577   else
   578     new_qc = MODE_BESTQUALITY;
   580   if (ctx->cfg.g_pass == VPX_RC_FIRST_PASS)
   581     new_qc = MODE_FIRSTPASS;
   582   else if (ctx->cfg.g_pass == VPX_RC_LAST_PASS)
   583     new_qc = (new_qc == MODE_BESTQUALITY)
   584              ? MODE_SECONDPASS_BEST
   585              : MODE_SECONDPASS;
   587   if (ctx->oxcf.Mode != new_qc) {
   588     ctx->oxcf.Mode = new_qc;
   589     vp9_change_config(ctx->cpi, &ctx->oxcf);
   590   }
   591 }
   594 static int write_superframe_index(vpx_codec_alg_priv_t *ctx) {
   595   uint8_t marker = 0xc0;
   596   unsigned int mask;
   597   int mag, index_sz;
   599   assert(ctx->pending_frame_count);
   600   assert(ctx->pending_frame_count <= 8);
   602   /* Add the number of frames to the marker byte */
   603   marker |= ctx->pending_frame_count - 1;
   605   /* Choose the magnitude */
   606   for (mag = 0, mask = 0xff; mag < 4; mag++) {
   607     if (ctx->pending_frame_magnitude < mask)
   608       break;
   609     mask <<= 8;
   610     mask |= 0xff;
   611   }
   612   marker |= mag << 3;
   614   /* Write the index */
   615   index_sz = 2 + (mag + 1) * ctx->pending_frame_count;
   616   if (ctx->pending_cx_data_sz + index_sz < ctx->cx_data_sz) {
   617     uint8_t *x = ctx->pending_cx_data + ctx->pending_cx_data_sz;
   618     int i, j;
   620     *x++ = marker;
   621     for (i = 0; i < ctx->pending_frame_count; i++) {
   622       int this_sz = ctx->pending_frame_sizes[i];
   624       for (j = 0; j <= mag; j++) {
   625         *x++ = this_sz & 0xff;
   626         this_sz >>= 8;
   627       }
   628     }
   629     *x++ = marker;
   630     ctx->pending_cx_data_sz += index_sz;
   631   }
   632   return index_sz;
   633 }
   635 static vpx_codec_err_t vp9e_encode(vpx_codec_alg_priv_t  *ctx,
   636                                    const vpx_image_t     *img,
   637                                    vpx_codec_pts_t        pts,
   638                                    unsigned long          duration,
   639                                    vpx_enc_frame_flags_t  flags,
   640                                    unsigned long          deadline) {
   641   vpx_codec_err_t res = VPX_CODEC_OK;
   643   if (img)
   644     res = validate_img(ctx, img);
   646   pick_quickcompress_mode(ctx, duration, deadline);
   647   vpx_codec_pkt_list_init(&ctx->pkt_list);
   649   /* Handle Flags */
   650   if (((flags & VP8_EFLAG_NO_UPD_GF) && (flags & VP8_EFLAG_FORCE_GF))
   651       || ((flags & VP8_EFLAG_NO_UPD_ARF) && (flags & VP8_EFLAG_FORCE_ARF))) {
   652     ctx->base.err_detail = "Conflicting flags.";
   653     return VPX_CODEC_INVALID_PARAM;
   654   }
   656   if (flags & (VP8_EFLAG_NO_REF_LAST | VP8_EFLAG_NO_REF_GF
   657                | VP8_EFLAG_NO_REF_ARF)) {
   658     int ref = 7;
   660     if (flags & VP8_EFLAG_NO_REF_LAST)
   661       ref ^= VP9_LAST_FLAG;
   663     if (flags & VP8_EFLAG_NO_REF_GF)
   664       ref ^= VP9_GOLD_FLAG;
   666     if (flags & VP8_EFLAG_NO_REF_ARF)
   667       ref ^= VP9_ALT_FLAG;
   669     vp9_use_as_reference(ctx->cpi, ref);
   670   }
   672   if (flags & (VP8_EFLAG_NO_UPD_LAST | VP8_EFLAG_NO_UPD_GF
   673                | VP8_EFLAG_NO_UPD_ARF | VP8_EFLAG_FORCE_GF
   674                | VP8_EFLAG_FORCE_ARF)) {
   675     int upd = 7;
   677     if (flags & VP8_EFLAG_NO_UPD_LAST)
   678       upd ^= VP9_LAST_FLAG;
   680     if (flags & VP8_EFLAG_NO_UPD_GF)
   681       upd ^= VP9_GOLD_FLAG;
   683     if (flags & VP8_EFLAG_NO_UPD_ARF)
   684       upd ^= VP9_ALT_FLAG;
   686     vp9_update_reference(ctx->cpi, upd);
   687   }
   689   if (flags & VP8_EFLAG_NO_UPD_ENTROPY) {
   690     vp9_update_entropy(ctx->cpi, 0);
   691   }
   693   /* Handle fixed keyframe intervals */
   694   if (ctx->cfg.kf_mode == VPX_KF_AUTO
   695       && ctx->cfg.kf_min_dist == ctx->cfg.kf_max_dist) {
   696     if (++ctx->fixed_kf_cntr > ctx->cfg.kf_min_dist) {
   697       flags |= VPX_EFLAG_FORCE_KF;
   698       ctx->fixed_kf_cntr = 1;
   699     }
   700   }
   702   /* Initialize the encoder instance on the first frame*/
   703   if (!res && ctx->cpi) {
   704     unsigned int lib_flags;
   705     YV12_BUFFER_CONFIG sd;
   706     int64_t dst_time_stamp, dst_end_time_stamp;
   707     unsigned long size, cx_data_sz;
   708     unsigned char *cx_data;
   710     /* Set up internal flags */
   711     if (ctx->base.init_flags & VPX_CODEC_USE_PSNR)
   712       ((VP9_COMP *)ctx->cpi)->b_calculate_psnr = 1;
   714     // if (ctx->base.init_flags & VPX_CODEC_USE_OUTPUT_PARTITION)
   715     //    ((VP9_COMP *)ctx->cpi)->output_partition = 1;
   717     /* Convert API flags to internal codec lib flags */
   718     lib_flags = (flags & VPX_EFLAG_FORCE_KF) ? FRAMEFLAGS_KEY : 0;
   720     /* vp8 use 10,000,000 ticks/second as time stamp */
   721     dst_time_stamp = pts * 10000000 * ctx->cfg.g_timebase.num
   722                      / ctx->cfg.g_timebase.den;
   723     dst_end_time_stamp = (pts + duration) * 10000000 * ctx->cfg.g_timebase.num /
   724                          ctx->cfg.g_timebase.den;
   726     if (img != NULL) {
   727       res = image2yuvconfig(img, &sd);
   729       if (vp9_receive_raw_frame(ctx->cpi, lib_flags,
   730                                 &sd, dst_time_stamp, dst_end_time_stamp)) {
   731         VP9_COMP *cpi = (VP9_COMP *)ctx->cpi;
   732         res = update_error_state(ctx, &cpi->common.error);
   733       }
   734     }
   736     cx_data = ctx->cx_data;
   737     cx_data_sz = ctx->cx_data_sz;
   738     lib_flags = 0;
   740     /* Any pending invisible frames? */
   741     if (ctx->pending_cx_data) {
   742       memmove(cx_data, ctx->pending_cx_data, ctx->pending_cx_data_sz);
   743       ctx->pending_cx_data = cx_data;
   744       cx_data += ctx->pending_cx_data_sz;
   745       cx_data_sz -= ctx->pending_cx_data_sz;
   747       /* TODO: this is a minimal check, the underlying codec doesn't respect
   748        * the buffer size anyway.
   749        */
   750       if (cx_data_sz < ctx->cx_data_sz / 2) {
   751         ctx->base.err_detail = "Compressed data buffer too small";
   752         return VPX_CODEC_ERROR;
   753       }
   754     }
   756     while (cx_data_sz >= ctx->cx_data_sz / 2 &&
   757            -1 != vp9_get_compressed_data(ctx->cpi, &lib_flags, &size,
   758                                          cx_data, &dst_time_stamp,
   759                                          &dst_end_time_stamp, !img)) {
   760       if (size) {
   761         vpx_codec_pts_t    round, delta;
   762         vpx_codec_cx_pkt_t pkt;
   763         VP9_COMP *cpi = (VP9_COMP *)ctx->cpi;
   765         /* Pack invisible frames with the next visible frame */
   766         if (!cpi->common.show_frame) {
   767           if (!ctx->pending_cx_data)
   768             ctx->pending_cx_data = cx_data;
   769           ctx->pending_cx_data_sz += size;
   770           ctx->pending_frame_sizes[ctx->pending_frame_count++] = size;
   771           ctx->pending_frame_magnitude |= size;
   772           cx_data += size;
   773           cx_data_sz -= size;
   774           continue;
   775         }
   777         /* Add the frame packet to the list of returned packets. */
   778         round = (vpx_codec_pts_t)1000000 * ctx->cfg.g_timebase.num / 2 - 1;
   779         delta = (dst_end_time_stamp - dst_time_stamp);
   780         pkt.kind = VPX_CODEC_CX_FRAME_PKT;
   781         pkt.data.frame.pts =
   782           (dst_time_stamp * ctx->cfg.g_timebase.den + round)
   783           / ctx->cfg.g_timebase.num / 10000000;
   784         pkt.data.frame.duration = (unsigned long)
   785           ((delta * ctx->cfg.g_timebase.den + round)
   786           / ctx->cfg.g_timebase.num / 10000000);
   787         pkt.data.frame.flags = lib_flags << 16;
   789         if (lib_flags & FRAMEFLAGS_KEY)
   790           pkt.data.frame.flags |= VPX_FRAME_IS_KEY;
   792         if (!cpi->common.show_frame) {
   793           pkt.data.frame.flags |= VPX_FRAME_IS_INVISIBLE;
   795           // This timestamp should be as close as possible to the
   796           // prior PTS so that if a decoder uses pts to schedule when
   797           // to do this, we start right after last frame was decoded.
   798           // Invisible frames have no duration.
   799           pkt.data.frame.pts = ((cpi->last_time_stamp_seen
   800                                  * ctx->cfg.g_timebase.den + round)
   801                                 / ctx->cfg.g_timebase.num / 10000000) + 1;
   802           pkt.data.frame.duration = 0;
   803         }
   805         if (cpi->droppable)
   806           pkt.data.frame.flags |= VPX_FRAME_IS_DROPPABLE;
   808         /*if (cpi->output_partition)
   809         {
   810             int i;
   811             const int num_partitions = 1;
   813             pkt.data.frame.flags |= VPX_FRAME_IS_FRAGMENT;
   815             for (i = 0; i < num_partitions; ++i)
   816             {
   817                 pkt.data.frame.buf = cx_data;
   818                 pkt.data.frame.sz = cpi->partition_sz[i];
   819                 pkt.data.frame.partition_id = i;
   820                 // don't set the fragment bit for the last partition
   821                 if (i == (num_partitions - 1))
   822                     pkt.data.frame.flags &= ~VPX_FRAME_IS_FRAGMENT;
   823                 vpx_codec_pkt_list_add(&ctx->pkt_list.head, &pkt);
   824                 cx_data += cpi->partition_sz[i];
   825                 cx_data_sz -= cpi->partition_sz[i];
   826             }
   827         }
   828         else*/
   829         {
   830           if (ctx->pending_cx_data) {
   831             ctx->pending_frame_sizes[ctx->pending_frame_count++] = size;
   832             ctx->pending_frame_magnitude |= size;
   833             ctx->pending_cx_data_sz += size;
   834             size += write_superframe_index(ctx);
   835             pkt.data.frame.buf = ctx->pending_cx_data;
   836             pkt.data.frame.sz  = ctx->pending_cx_data_sz;
   837             ctx->pending_cx_data = NULL;
   838             ctx->pending_cx_data_sz = 0;
   839             ctx->pending_frame_count = 0;
   840             ctx->pending_frame_magnitude = 0;
   841           } else {
   842             pkt.data.frame.buf = cx_data;
   843             pkt.data.frame.sz  = size;
   844           }
   845           pkt.data.frame.partition_id = -1;
   846           vpx_codec_pkt_list_add(&ctx->pkt_list.head, &pkt);
   847           cx_data += size;
   848           cx_data_sz -= size;
   849         }
   850       }
   851     }
   852   }
   854   return res;
   855 }
   858 static const vpx_codec_cx_pkt_t *vp9e_get_cxdata(vpx_codec_alg_priv_t  *ctx,
   859                                                  vpx_codec_iter_t      *iter) {
   860   return vpx_codec_pkt_list_get(&ctx->pkt_list.head, iter);
   861 }
   863 static vpx_codec_err_t vp9e_set_reference(vpx_codec_alg_priv_t *ctx,
   864                                           int ctr_id,
   865                                           va_list args) {
   866   vpx_ref_frame_t *data = va_arg(args, vpx_ref_frame_t *);
   868   if (data) {
   869     vpx_ref_frame_t *frame = (vpx_ref_frame_t *)data;
   870     YV12_BUFFER_CONFIG sd;
   872     image2yuvconfig(&frame->img, &sd);
   873     vp9_set_reference_enc(ctx->cpi, ref_frame_to_vp9_reframe(frame->frame_type),
   874                           &sd);
   875     return VPX_CODEC_OK;
   876   } else {
   877     return VPX_CODEC_INVALID_PARAM;
   878   }
   879 }
   881 static vpx_codec_err_t vp9e_copy_reference(vpx_codec_alg_priv_t *ctx,
   882                                            int ctr_id,
   883                                            va_list args) {
   884   vpx_ref_frame_t *data = va_arg(args, vpx_ref_frame_t *);
   886   if (data) {
   887     vpx_ref_frame_t *frame = (vpx_ref_frame_t *)data;
   888     YV12_BUFFER_CONFIG sd;
   890     image2yuvconfig(&frame->img, &sd);
   891     vp9_copy_reference_enc(ctx->cpi,
   892                            ref_frame_to_vp9_reframe(frame->frame_type), &sd);
   893     return VPX_CODEC_OK;
   894   } else {
   895     return VPX_CODEC_INVALID_PARAM;
   896   }
   897 }
   899 static vpx_codec_err_t get_reference(vpx_codec_alg_priv_t *ctx,
   900                                      int ctr_id,
   901                                      va_list args) {
   902   vp9_ref_frame_t *data = va_arg(args, vp9_ref_frame_t *);
   904   if (data) {
   905     YV12_BUFFER_CONFIG* fb;
   907     vp9_get_reference_enc(ctx->cpi, data->idx, &fb);
   908     yuvconfig2image(&data->img, fb, NULL);
   909     return VPX_CODEC_OK;
   910   } else {
   911     return VPX_CODEC_INVALID_PARAM;
   912   }
   913 }
   915 static vpx_codec_err_t vp9e_set_previewpp(vpx_codec_alg_priv_t *ctx,
   916                                           int ctr_id,
   917                                           va_list args) {
   918 #if CONFIG_VP9_POSTPROC
   919   vp8_postproc_cfg_t *data = va_arg(args, vp8_postproc_cfg_t *);
   920   (void)ctr_id;
   922   if (data) {
   923     ctx->preview_ppcfg = *((vp8_postproc_cfg_t *)data);
   924     return VPX_CODEC_OK;
   925   } else {
   926     return VPX_CODEC_INVALID_PARAM;
   927   }
   928 #else
   929   (void)ctx;
   930   (void)ctr_id;
   931   (void)args;
   932   return VPX_CODEC_INCAPABLE;
   933 #endif
   934 }
   937 static vpx_image_t *vp9e_get_preview(vpx_codec_alg_priv_t *ctx) {
   938   YV12_BUFFER_CONFIG sd;
   939   vp9_ppflags_t flags = {0};
   941   if (ctx->preview_ppcfg.post_proc_flag) {
   942     flags.post_proc_flag        = ctx->preview_ppcfg.post_proc_flag;
   943     flags.deblocking_level      = ctx->preview_ppcfg.deblocking_level;
   944     flags.noise_level           = ctx->preview_ppcfg.noise_level;
   945   }
   947   if (0 == vp9_get_preview_raw_frame(ctx->cpi, &sd, &flags)) {
   948     yuvconfig2image(&ctx->preview_img, &sd, NULL);
   949     return &ctx->preview_img;
   950   } else {
   951     return NULL;
   952   }
   953 }
   955 static vpx_codec_err_t vp9e_update_entropy(vpx_codec_alg_priv_t *ctx,
   956                                            int ctr_id,
   957                                            va_list args) {
   958   int update = va_arg(args, int);
   959   vp9_update_entropy(ctx->cpi, update);
   960   return VPX_CODEC_OK;
   961 }
   963 static vpx_codec_err_t vp9e_update_reference(vpx_codec_alg_priv_t *ctx,
   964                                              int ctr_id,
   965                                              va_list args) {
   966   int update = va_arg(args, int);
   967   vp9_update_reference(ctx->cpi, update);
   968   return VPX_CODEC_OK;
   969 }
   971 static vpx_codec_err_t vp9e_use_reference(vpx_codec_alg_priv_t *ctx,
   972                                           int ctr_id,
   973                                           va_list args) {
   974   int reference_flag = va_arg(args, int);
   975   vp9_use_as_reference(ctx->cpi, reference_flag);
   976   return VPX_CODEC_OK;
   977 }
   979 static vpx_codec_err_t vp9e_set_roi_map(vpx_codec_alg_priv_t *ctx,
   980                                         int ctr_id,
   981                                         va_list args) {
   982   // TODO(yaowu): Need to re-implement and test for VP9.
   983   return VPX_CODEC_INVALID_PARAM;
   984 }
   987 static vpx_codec_err_t vp9e_set_activemap(vpx_codec_alg_priv_t *ctx,
   988                                           int ctr_id,
   989                                           va_list args) {
   990   // TODO(yaowu): Need to re-implement and test for VP9.
   991   return VPX_CODEC_INVALID_PARAM;
   992 }
   994 static vpx_codec_err_t vp9e_set_scalemode(vpx_codec_alg_priv_t *ctx,
   995                                           int ctr_id,
   996                                           va_list args) {
   997   vpx_scaling_mode_t *data =  va_arg(args, vpx_scaling_mode_t *);
   999   if (data) {
  1000     int res;
  1001     vpx_scaling_mode_t scalemode = *(vpx_scaling_mode_t *)data;
  1002     res = vp9_set_internal_size(ctx->cpi,
  1003                                 (VPX_SCALING)scalemode.h_scaling_mode,
  1004                                 (VPX_SCALING)scalemode.v_scaling_mode);
  1006     if (!res) {
  1007       return VPX_CODEC_OK;
  1008     } else {
  1009       return VPX_CODEC_INVALID_PARAM;
  1011   } else {
  1012     return VPX_CODEC_INVALID_PARAM;
  1016 static vpx_codec_err_t vp9e_set_svc(vpx_codec_alg_priv_t *ctx, int ctr_id,
  1017                                     va_list args) {
  1018   int data = va_arg(args, int);
  1019   vp9_set_svc(ctx->cpi, data);
  1020   return VPX_CODEC_OK;
  1023 static vpx_codec_err_t vp9e_set_svc_parameters(vpx_codec_alg_priv_t *ctx,
  1024                                                int ctr_id, va_list args) {
  1025   vpx_svc_parameters_t *data = va_arg(args, vpx_svc_parameters_t *);
  1026   VP9_COMP *cpi = (VP9_COMP *)ctx->cpi;
  1027   vpx_svc_parameters_t params;
  1029   if (data == NULL) {
  1030     return VPX_CODEC_INVALID_PARAM;
  1033   params = *(vpx_svc_parameters_t *)data;
  1035   cpi->current_layer = params.layer;
  1036   cpi->lst_fb_idx = params.lst_fb_idx;
  1037   cpi->gld_fb_idx = params.gld_fb_idx;
  1038   cpi->alt_fb_idx = params.alt_fb_idx;
  1040   if (vp9_set_size_literal(ctx->cpi, params.width, params.height) != 0) {
  1041     return VPX_CODEC_INVALID_PARAM;
  1044   ctx->cfg.rc_max_quantizer = params.max_quantizer;
  1045   ctx->cfg.rc_min_quantizer = params.min_quantizer;
  1047   set_vp9e_config(&ctx->oxcf, ctx->cfg, ctx->vp8_cfg);
  1048   vp9_change_config(ctx->cpi, &ctx->oxcf);
  1050   return VPX_CODEC_OK;
  1053 static vpx_codec_ctrl_fn_map_t vp9e_ctf_maps[] = {
  1054   {VP8_SET_REFERENCE,                 vp9e_set_reference},
  1055   {VP8_COPY_REFERENCE,                vp9e_copy_reference},
  1056   {VP8_SET_POSTPROC,                  vp9e_set_previewpp},
  1057   {VP8E_UPD_ENTROPY,                  vp9e_update_entropy},
  1058   {VP8E_UPD_REFERENCE,                vp9e_update_reference},
  1059   {VP8E_USE_REFERENCE,                vp9e_use_reference},
  1060   {VP8E_SET_ROI_MAP,                  vp9e_set_roi_map},
  1061   {VP8E_SET_ACTIVEMAP,                vp9e_set_activemap},
  1062   {VP8E_SET_SCALEMODE,                vp9e_set_scalemode},
  1063   {VP8E_SET_CPUUSED,                  set_param},
  1064   {VP8E_SET_NOISE_SENSITIVITY,        set_param},
  1065   {VP8E_SET_ENABLEAUTOALTREF,         set_param},
  1066   {VP8E_SET_SHARPNESS,                set_param},
  1067   {VP8E_SET_STATIC_THRESHOLD,         set_param},
  1068   {VP9E_SET_TILE_COLUMNS,             set_param},
  1069   {VP9E_SET_TILE_ROWS,                set_param},
  1070   {VP8E_GET_LAST_QUANTIZER,           get_param},
  1071   {VP8E_GET_LAST_QUANTIZER_64,        get_param},
  1072   {VP8E_SET_ARNR_MAXFRAMES,           set_param},
  1073   {VP8E_SET_ARNR_STRENGTH,            set_param},
  1074   {VP8E_SET_ARNR_TYPE,                set_param},
  1075   {VP8E_SET_TUNING,                   set_param},
  1076   {VP8E_SET_CQ_LEVEL,                 set_param},
  1077   {VP8E_SET_MAX_INTRA_BITRATE_PCT,    set_param},
  1078   {VP9E_SET_LOSSLESS,                 set_param},
  1079   {VP9E_SET_FRAME_PARALLEL_DECODING,  set_param},
  1080   {VP9E_SET_AQ_MODE,                  set_param},
  1081   {VP9_GET_REFERENCE,                 get_reference},
  1082   {VP9E_SET_SVC,                      vp9e_set_svc},
  1083   {VP9E_SET_SVC_PARAMETERS,           vp9e_set_svc_parameters},
  1084   { -1, NULL},
  1085 };
  1087 static vpx_codec_enc_cfg_map_t vp9e_usage_cfg_map[] = {
  1089     0,
  1090     {  // NOLINT
  1091       0,                  /* g_usage */
  1092       0,                  /* g_threads */
  1093       0,                  /* g_profile */
  1095       320,                /* g_width */
  1096       240,                /* g_height */
  1097       {1, 30},            /* g_timebase */
  1099       0,                  /* g_error_resilient */
  1101       VPX_RC_ONE_PASS,    /* g_pass */
  1103       25,                 /* g_lag_in_frames */
  1105       0,                  /* rc_dropframe_thresh */
  1106       0,                  /* rc_resize_allowed */
  1107       60,                 /* rc_resize_down_thresold */
  1108       30,                 /* rc_resize_up_thresold */
  1110       VPX_VBR,            /* rc_end_usage */
  1111 #if VPX_ENCODER_ABI_VERSION > (1 + VPX_CODEC_ABI_VERSION)
  1112       {0},                /* rc_twopass_stats_in */
  1113 #endif
  1114       256,                /* rc_target_bandwidth */
  1115       0,                  /* rc_min_quantizer */
  1116       63,                 /* rc_max_quantizer */
  1117       100,                /* rc_undershoot_pct */
  1118       100,                /* rc_overshoot_pct */
  1120       6000,               /* rc_max_buffer_size */
  1121       4000,               /* rc_buffer_initial_size; */
  1122       5000,               /* rc_buffer_optimal_size; */
  1124       50,                 /* rc_two_pass_vbrbias  */
  1125       0,                  /* rc_two_pass_vbrmin_section */
  1126       2000,               /* rc_two_pass_vbrmax_section */
  1128       /* keyframing settings (kf) */
  1129       VPX_KF_AUTO,        /* g_kfmode*/
  1130       0,                  /* kf_min_dist */
  1131       9999,               /* kf_max_dist */
  1133       VPX_SS_DEFAULT_LAYERS, /* ss_number_layers */
  1135 #if VPX_ENCODER_ABI_VERSION == (1 + VPX_CODEC_ABI_VERSION)
  1136       1,                  /* g_delete_first_pass_file */
  1137       "vp8.fpf"           /* first pass filename */
  1138 #endif
  1140   },
  1141   { -1, {NOT_IMPLEMENTED}}
  1142 };
  1145 #ifndef VERSION_STRING
  1146 #define VERSION_STRING
  1147 #endif
  1148 CODEC_INTERFACE(vpx_codec_vp9_cx) = {
  1149   "WebM Project VP9 Encoder" VERSION_STRING,
  1150   VPX_CODEC_INTERNAL_ABI_VERSION,
  1151   VPX_CODEC_CAP_ENCODER | VPX_CODEC_CAP_PSNR |
  1152   VPX_CODEC_CAP_OUTPUT_PARTITION,
  1153   /* vpx_codec_caps_t          caps; */
  1154   vp9e_init,          /* vpx_codec_init_fn_t       init; */
  1155   vp9e_destroy,       /* vpx_codec_destroy_fn_t    destroy; */
  1156   vp9e_ctf_maps,      /* vpx_codec_ctrl_fn_map_t  *ctrl_maps; */
  1157   NOT_IMPLEMENTED,    /* vpx_codec_get_mmap_fn_t   get_mmap; */
  1158   NOT_IMPLEMENTED,    /* vpx_codec_set_mmap_fn_t   set_mmap; */
  1159   {  // NOLINT
  1160     NOT_IMPLEMENTED,    /* vpx_codec_peek_si_fn_t    peek_si; */
  1161     NOT_IMPLEMENTED,    /* vpx_codec_get_si_fn_t     get_si; */
  1162     NOT_IMPLEMENTED,    /* vpx_codec_decode_fn_t     decode; */
  1163     NOT_IMPLEMENTED,    /* vpx_codec_frame_get_fn_t  frame_get; */
  1164   },
  1165   {  // NOLINT
  1166     vp9e_usage_cfg_map, /* vpx_codec_enc_cfg_map_t    peek_si; */
  1167     vp9e_encode,        /* vpx_codec_encode_fn_t      encode; */
  1168     vp9e_get_cxdata,    /* vpx_codec_get_cx_data_fn_t   frame_get; */
  1169     vp9e_set_config,
  1170     NOT_IMPLEMENTED,
  1171     vp9e_get_preview,
  1172   } /* encoder functions */
  1173 };
  1176 #if CONFIG_EXPERIMENTAL
  1178 CODEC_INTERFACE(vpx_codec_vp9x_cx) = {
  1179   "VP8 Experimental Encoder" VERSION_STRING,
  1180   VPX_CODEC_INTERNAL_ABI_VERSION,
  1181   VPX_CODEC_CAP_ENCODER | VPX_CODEC_CAP_PSNR,
  1182   /* vpx_codec_caps_t          caps; */
  1183   vp9e_exp_init,      /* vpx_codec_init_fn_t       init; */
  1184   vp9e_destroy,       /* vpx_codec_destroy_fn_t    destroy; */
  1185   vp9e_ctf_maps,      /* vpx_codec_ctrl_fn_map_t  *ctrl_maps; */
  1186   NOT_IMPLEMENTED,    /* vpx_codec_get_mmap_fn_t   get_mmap; */
  1187   NOT_IMPLEMENTED,    /* vpx_codec_set_mmap_fn_t   set_mmap; */
  1188   {  // NOLINT
  1189     NOT_IMPLEMENTED,    /* vpx_codec_peek_si_fn_t    peek_si; */
  1190     NOT_IMPLEMENTED,    /* vpx_codec_get_si_fn_t     get_si; */
  1191     NOT_IMPLEMENTED,    /* vpx_codec_decode_fn_t     decode; */
  1192     NOT_IMPLEMENTED,    /* vpx_codec_frame_get_fn_t  frame_get; */
  1193   },
  1194   {  // NOLINT
  1195     vp9e_usage_cfg_map, /* vpx_codec_enc_cfg_map_t    peek_si; */
  1196     vp9e_encode,        /* vpx_codec_encode_fn_t      encode; */
  1197     vp9e_get_cxdata,    /* vpx_codec_get_cx_data_fn_t   frame_get; */
  1198     vp9e_set_config,
  1199     NOT_IMPLEMENTED,
  1200     vp9e_get_preview,
  1201   } /* encoder functions */
  1202 };
  1203 #endif

mercurial