summaryrefslogtreecommitdiffstats
path: root/media/libvpx/libvpx/vp9/encoder/vp9_firstpass.h
blob: a19b04db744277a23ee867e13215c48cacca86c1 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
/*
 *  Copyright (c) 2010 The WebM project authors. All Rights Reserved.
 *
 *  Use of this source code is governed by a BSD-style license
 *  that can be found in the LICENSE file in the root of the source
 *  tree. An additional intellectual property rights grant can be found
 *  in the file PATENTS.  All contributing project authors may
 *  be found in the AUTHORS file in the root of the source tree.
 */

#ifndef VPX_VP9_ENCODER_VP9_FIRSTPASS_H_
#define VPX_VP9_ENCODER_VP9_FIRSTPASS_H_

#include <assert.h>

#include "vp9/common/vp9_onyxc_int.h"
#include "vp9/encoder/vp9_firstpass_stats.h"
#include "vp9/encoder/vp9_lookahead.h"
#include "vp9/encoder/vp9_ratectrl.h"

#ifdef __cplusplus
extern "C" {
#endif

#define INVALID_ROW (-1)

#define MAX_ARF_LAYERS 6
#define SECTION_NOISE_DEF 250.0

typedef struct {
  double frame_mb_intra_factor;
  double frame_mb_brightness_factor;
  double frame_mb_neutral_count;
} FP_MB_FLOAT_STATS;

typedef struct {
  double intra_factor;
  double brightness_factor;
  int64_t coded_error;
  int64_t sr_coded_error;
  int64_t frame_noise_energy;
  int64_t intra_error;
  int intercount;
  int second_ref_count;
  double neutral_count;
  double intra_count_low;   // Coded intra but low variance
  double intra_count_high;  // Coded intra high variance
  int intra_skip_count;
  int image_data_start_row;
  int mvcount;
  int sum_mvr;
  int sum_mvr_abs;
  int sum_mvc;
  int sum_mvc_abs;
  int64_t sum_mvrs;
  int64_t sum_mvcs;
  int sum_in_vectors;
  int intra_smooth_count;
  int new_mv_count;
} FIRSTPASS_DATA;

typedef enum {
  KF_UPDATE = 0,
  LF_UPDATE = 1,
  GF_UPDATE = 2,
  ARF_UPDATE = 3,
  OVERLAY_UPDATE = 4,
  MID_OVERLAY_UPDATE = 5,
  USE_BUF_FRAME = 6,  // Use show existing frame, no ref buffer update
  FRAME_UPDATE_TYPES = 7
} FRAME_UPDATE_TYPE;

#define FC_ANIMATION_THRESH 0.15
typedef enum {
  FC_NORMAL = 0,
  FC_GRAPHICS_ANIMATION = 1,
  FRAME_CONTENT_TYPES = 2
} FRAME_CONTENT_TYPE;

typedef struct {
  unsigned char index;
  RATE_FACTOR_LEVEL rf_level[MAX_STATIC_GF_GROUP_LENGTH + 2];
  FRAME_UPDATE_TYPE update_type[MAX_STATIC_GF_GROUP_LENGTH + 2];
  unsigned char arf_src_offset[MAX_STATIC_GF_GROUP_LENGTH + 2];
  unsigned char layer_depth[MAX_STATIC_GF_GROUP_LENGTH + 2];
  unsigned char frame_gop_index[MAX_STATIC_GF_GROUP_LENGTH + 2];
  int bit_allocation[MAX_STATIC_GF_GROUP_LENGTH + 2];
  int gfu_boost[MAX_STATIC_GF_GROUP_LENGTH + 2];

  int frame_start;
  int frame_end;
  // TODO(jingning): The array size of arf_stack could be reduced.
  int arf_index_stack[MAX_LAG_BUFFERS * 2];
  int top_arf_idx;
  int stack_size;
  int gf_group_size;
  int max_layer_depth;
  int allowed_max_layer_depth;
  int group_noise_energy;
} GF_GROUP;

typedef struct {
  const FIRSTPASS_STATS *stats;
  int num_frames;
} FIRST_PASS_INFO;

static INLINE void fps_init_first_pass_info(FIRST_PASS_INFO *first_pass_info,
                                            const FIRSTPASS_STATS *stats,
                                            int num_frames) {
  first_pass_info->stats = stats;
  first_pass_info->num_frames = num_frames;
}

static INLINE int fps_get_num_frames(const FIRST_PASS_INFO *first_pass_info) {
  return first_pass_info->num_frames;
}

static INLINE const FIRSTPASS_STATS *fps_get_frame_stats(
    const FIRST_PASS_INFO *first_pass_info, int show_idx) {
  if (show_idx < 0 || show_idx >= first_pass_info->num_frames) {
    return NULL;
  }
  return &first_pass_info->stats[show_idx];
}

typedef struct {
  unsigned int section_intra_rating;
  unsigned int key_frame_section_intra_rating;
  FIRSTPASS_STATS total_stats;
  FIRSTPASS_STATS this_frame_stats;
  const FIRSTPASS_STATS *stats_in;
  const FIRSTPASS_STATS *stats_in_start;
  const FIRSTPASS_STATS *stats_in_end;
  FIRST_PASS_INFO first_pass_info;
  FIRSTPASS_STATS total_left_stats;
  int first_pass_done;
  int64_t bits_left;
  double mean_mod_score;
  double normalized_score_left;
  double mb_av_energy;
  double mb_smooth_pct;

  FP_MB_FLOAT_STATS *fp_mb_float_stats;

  // An indication of the content type of the current frame
  FRAME_CONTENT_TYPE fr_content_type;

  // Projected total bits available for a key frame group of frames
  int64_t kf_group_bits;

  // Error score of frames still to be coded in kf group
  double kf_group_error_left;

  double bpm_factor;
  int rolling_arf_group_target_bits;
  int rolling_arf_group_actual_bits;

  int sr_update_lag;
  int kf_zeromotion_pct;
  int last_kfgroup_zeromotion_pct;
  int active_worst_quality;
  int baseline_active_worst_quality;
  int extend_minq;
  int extend_maxq;
  int extend_minq_fast;
  int arnr_strength_adjustment;
  int last_qindex_of_arf_layer[MAX_ARF_LAYERS];

  GF_GROUP gf_group;

  // Vizeir project experimental two pass rate control parameters.
  // When |use_vizier_rc_params| is 1, the following parameters will
  // be overwritten by pass in values. Otherwise, they are initialized
  // by default values.
  int use_vizier_rc_params;
  double active_wq_factor;
  double err_per_mb;
  double sr_default_decay_limit;
  double sr_diff_factor;
  double kf_err_per_mb;
  double kf_frame_min_boost;
  double kf_frame_max_boost_first;  // Max for first kf in a chunk.
  double kf_frame_max_boost_subs;   // Max for subsequent mid chunk kfs.
  double kf_max_total_boost;
  double gf_max_total_boost;
  double gf_frame_max_boost;
  double zm_factor;
} TWO_PASS;

struct VP9_COMP;
struct ThreadData;
struct TileDataEnc;

void vp9_init_first_pass(struct VP9_COMP *cpi);
void vp9_first_pass(struct VP9_COMP *cpi, const struct lookahead_entry *source);
void vp9_end_first_pass(struct VP9_COMP *cpi);

void vp9_first_pass_encode_tile_mb_row(struct VP9_COMP *cpi,
                                       struct ThreadData *td,
                                       FIRSTPASS_DATA *fp_acc_data,
                                       struct TileDataEnc *tile_data,
                                       MV *best_ref_mv, int mb_row);

void vp9_init_second_pass(struct VP9_COMP *cpi);
void vp9_rc_get_second_pass_params(struct VP9_COMP *cpi);
void vp9_init_vizier_params(TWO_PASS *const twopass, int screen_area);

// Post encode update of the rate control parameters for 2-pass
void vp9_twopass_postencode_update(struct VP9_COMP *cpi);

void calculate_coded_size(struct VP9_COMP *cpi, int *scaled_frame_width,
                          int *scaled_frame_height);

struct VP9EncoderConfig;
int vp9_get_frames_to_next_key(const struct VP9EncoderConfig *oxcf,
                               const TWO_PASS *const twopass, int kf_show_idx,
                               int min_gf_interval);
#if CONFIG_RATE_CTRL
/* Call this function to get info about the next group of pictures.
 * This function should be called after vp9_create_compressor() when encoding
 * starts or after vp9_get_compressed_data() when the encoding process of
 * the last group of pictures is just finished.
 */
void vp9_get_next_group_of_picture(const struct VP9_COMP *cpi,
                                   int *first_is_key_frame, int *use_alt_ref,
                                   int *coding_frame_count, int *first_show_idx,
                                   int *last_gop_use_alt_ref);

/*!\brief Call this function before coding a new group of pictures to get
 * information about it.
 * \param[in] oxcf                 Encoder config
 * \param[in] twopass              Twopass info
 * \param[in] frame_info           Frame info
 * \param[in] rc                   Rate control state
 * \param[in] show_idx             Show index of the first frame in the group
 * \param[in] multi_layer_arf      Is multi-layer alternate reference used
 * \param[in] allow_alt_ref        Is alternate reference allowed
 * \param[in] first_is_key_frame   Is the first frame in the group a key frame
 * \param[in] last_gop_use_alt_ref Does the last group use alternate reference
 *
 * \param[out] use_alt_ref         Does this group use alternate reference
 *
 * \return Returns coding frame count
 */
int vp9_get_gop_coding_frame_count(const struct VP9EncoderConfig *oxcf,
                                   const TWO_PASS *const twopass,
                                   const FRAME_INFO *frame_info,
                                   const RATE_CONTROL *rc, int show_idx,
                                   int multi_layer_arf, int allow_alt_ref,
                                   int first_is_key_frame,
                                   int last_gop_use_alt_ref, int *use_alt_ref);

int vp9_get_coding_frame_num(const struct VP9EncoderConfig *oxcf,
                             const TWO_PASS *const twopass,
                             const FRAME_INFO *frame_info, int multi_layer_arf,
                             int allow_alt_ref);

/*!\brief Compute a key frame binary map indicates whether key frames appear
 * in the corresponding positions. The passed in key_frame_map must point to an
 * integer array with length equal to twopass->first_pass_info.num_frames,
 * which is the number of show frames in the video.
 */
void vp9_get_key_frame_map(const struct VP9EncoderConfig *oxcf,
                           const TWO_PASS *const twopass, int *key_frame_map);
#endif  // CONFIG_RATE_CTRL

FIRSTPASS_STATS vp9_get_frame_stats(const TWO_PASS *twopass);
FIRSTPASS_STATS vp9_get_total_stats(const TWO_PASS *twopass);

#ifdef __cplusplus
}  // extern "C"
#endif

#endif  // VPX_VP9_ENCODER_VP9_FIRSTPASS_H_