aboutsummaryrefslogtreecommitdiff
path: root/third_party/libaom/source/libaom/av1/encoder/tpl_model.h
blob: c764d9223986cacd13d9278f6ad0cfae9c5ac394 (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
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
/*
 * Copyright (c) 2019, Alliance for Open Media. All rights reserved
 *
 * This source code is subject to the terms of the BSD 2 Clause License and
 * the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License
 * was not distributed with this source code in the LICENSE file, you can
 * obtain it at www.aomedia.org/license/software. If the Alliance for Open
 * Media Patent License 1.0 was not distributed with this source code in the
 * PATENTS file, you can obtain it at www.aomedia.org/license/patent.
 */

#ifndef AOM_AV1_ENCODER_TPL_MODEL_H_
#define AOM_AV1_ENCODER_TPL_MODEL_H_

#ifdef __cplusplus
extern "C" {
#endif

/*!\cond */

struct AV1_PRIMARY;
struct AV1_COMP;
struct AV1_SEQ_CODING_TOOLS;
struct EncodeFrameParams;
struct EncodeFrameInput;

#include "config/aom_config.h"

#include "aom_scale/yv12config.h"

#include "av1/common/mv.h"
#include "av1/common/scale.h"
#include "av1/encoder/block.h"
#include "av1/encoder/lookahead.h"

static INLINE BLOCK_SIZE convert_length_to_bsize(int length) {
  switch (length) {
    case 64: return BLOCK_64X64;
    case 32: return BLOCK_32X32;
    case 16: return BLOCK_16X16;
    case 8: return BLOCK_8X8;
    case 4: return BLOCK_4X4;
    default:
      assert(0 && "Invalid block size for tpl model");
      return BLOCK_16X16;
  }
}

typedef struct AV1TplRowMultiThreadSync {
#if CONFIG_MULTITHREAD
  // Synchronization objects for top-right dependency.
  pthread_mutex_t *mutex_;
  pthread_cond_t *cond_;
#endif
  // Buffer to store the macroblock whose encoding is complete.
  // num_finished_cols[i] stores the number of macroblocks which finished
  // encoding in the ith macroblock row.
  int *num_finished_cols;
  // Number of extra macroblocks of the top row to be complete for encoding
  // of the current macroblock to start. A value of 1 indicates top-right
  // dependency.
  int sync_range;
  // Number of macroblock rows.
  int rows;
  // Number of threads processing the current tile.
  int num_threads_working;
} AV1TplRowMultiThreadSync;

typedef struct AV1TplRowMultiThreadInfo {
  // Row synchronization related function pointers.
  void (*sync_read_ptr)(AV1TplRowMultiThreadSync *tpl_mt_sync, int r, int c);
  void (*sync_write_ptr)(AV1TplRowMultiThreadSync *tpl_mt_sync, int r, int c,
                         int cols);
} AV1TplRowMultiThreadInfo;

// TODO(jingning): This needs to be cleaned up next.

// TPL stats buffers are prepared for every frame in the GOP,
// including (internal) overlays and (internal) arfs.
// In addition, frames in the lookahead that are outside of the GOP
// are also used.
// Thus it should use
// (gop_length) + (# overlays) + (MAX_LAG_BUFFERS - gop_len) =
// MAX_LAG_BUFFERS + (# overlays)
// 2 * MAX_LAG_BUFFERS is therefore a safe estimate.
// TODO(bohanli): test setting it to 1.5 * MAX_LAG_BUFFER
#define MAX_TPL_FRAME_IDX (2 * MAX_LAG_BUFFERS)
// The first REF_FRAMES + 1 buffers are reserved.
// tpl_data->tpl_frame starts after REF_FRAMES + 1
#define MAX_LENGTH_TPL_FRAME_STATS (MAX_TPL_FRAME_IDX + REF_FRAMES + 1)
#define MAX_TPL_EXTEND (MAX_LAG_BUFFERS - MAX_GF_INTERVAL)
#define TPL_DEP_COST_SCALE_LOG2 4

#define TPL_EPSILON 0.0000001

typedef struct TplTxfmStats {
  double abs_coeff_sum[256];  // Assume we are using 16x16 transform block
  int txfm_block_count;
  int coeff_num;
} TplTxfmStats;

typedef struct TplDepStats {
  int64_t intra_cost;
  int64_t inter_cost;
  int64_t srcrf_dist;
  int64_t recrf_dist;
  int64_t cmp_recrf_dist[2];
  int64_t srcrf_rate;
  int64_t recrf_rate;
  int64_t srcrf_sse;
  int64_t cmp_recrf_rate[2];
  int64_t mc_dep_rate;
  int64_t mc_dep_dist;
  int_mv mv[INTER_REFS_PER_FRAME];
  int ref_frame_index[2];
  int64_t pred_error[INTER_REFS_PER_FRAME];
} TplDepStats;

typedef struct TplDepFrame {
  uint8_t is_valid;
  TplDepStats *tpl_stats_ptr;
  const YV12_BUFFER_CONFIG *gf_picture;
  YV12_BUFFER_CONFIG *rec_picture;
  int ref_map_index[REF_FRAMES];
  int stride;
  int width;
  int height;
  int mi_rows;
  int mi_cols;
  int base_rdmult;
  uint32_t frame_display_index;
} TplDepFrame;

/*!\endcond */
/*!
 * \brief Params related to temporal dependency model.
 */
typedef struct TplParams {
  /*!
   * Block granularity of tpl score storage.
   */
  uint8_t tpl_stats_block_mis_log2;

  /*!
   * Tpl motion estimation block 1d size. tpl_bsize_1d >= 16.
   */
  uint8_t tpl_bsize_1d;

  /*!
   * Buffer to store the frame level tpl information for each frame in a gf
   * group. tpl_stats_buffer[i] stores the tpl information of ith frame in a gf
   * group
   */
  TplDepFrame tpl_stats_buffer[MAX_LENGTH_TPL_FRAME_STATS];

  /*!
   * Buffer to store tpl stats at block granularity.
   * tpl_stats_pool[i][j] stores the tpl stats of jth block of ith frame in a gf
   * group.
   */
  TplDepStats *tpl_stats_pool[MAX_LAG_BUFFERS];

  /*!
   * Buffer to store tpl transform stats per frame.
   * txfm_stats_list[i] stores the TplTxfmStats of the ith frame in a gf group.
   */
  TplTxfmStats txfm_stats_list[MAX_LENGTH_TPL_FRAME_STATS];

  /*!
   * Buffer to store tpl reconstructed frame.
   * tpl_rec_pool[i] stores the reconstructed frame of ith frame in a gf group.
   */
  YV12_BUFFER_CONFIG tpl_rec_pool[MAX_LAG_BUFFERS];

  /*!
   * Pointer to tpl_stats_buffer.
   */
  TplDepFrame *tpl_frame;

  /*!
   * Scale factors for the current frame.
   */
  struct scale_factors sf;

  /*!
   * GF group index of the current frame.
   */
  int frame_idx;

  /*!
   * Array of pointers to the frame buffers holding the source frame.
   * src_ref_frame[i] stores the pointer to the source frame of the ith
   * reference frame type.
   */
  const YV12_BUFFER_CONFIG *src_ref_frame[INTER_REFS_PER_FRAME];

  /*!
   * Array of pointers to the frame buffers holding the tpl reconstructed frame.
   * ref_frame[i] stores the pointer to the tpl reconstructed frame of the ith
   * reference frame type.
   */
  const YV12_BUFFER_CONFIG *ref_frame[INTER_REFS_PER_FRAME];

  /*!
   * Parameters related to synchronization for top-right dependency in row based
   * multi-threading of tpl
   */
  AV1TplRowMultiThreadSync tpl_mt_sync;

  /*!
   * Frame border for tpl frame.
   */
  int border_in_pixels;

#if CONFIG_BITRATE_ACCURACY
  /*
   * Estimated and actual GOP bitrate.
   */
  double estimated_gop_bitrate;
  double actual_gop_bitrate;
#endif
} TplParams;

/*!\brief Allocate buffers used by tpl model
 *
 * \param[in]    Top-level encode/decode structure
 * \param[in]    lag_in_frames  number of lookahead frames
 *
 * \param[out]   tpl_data  tpl data structure
 */

void av1_setup_tpl_buffers(struct AV1_PRIMARY *const ppi,
                           CommonModeInfoParams *const mi_params, int width,
                           int height, int byte_alignment, int lag_in_frames);

/*!\brief Implements temporal dependency modelling for a GOP (GF/ARF
 * group) and selects between 16 and 32 frame GOP structure.
 *
 *\ingroup tpl_modelling
 *
 * \param[in]    cpi           Top - level encoder instance structure
 * \param[in]    gop_eval      Flag if it is in the GOP length decision stage
 * \param[in]    frame_params  Per frame encoding parameters
 * \param[in]    frame_input   Input frame buffers
 *
 * \return Indicates whether or not we should use a longer GOP length.
 */
int av1_tpl_setup_stats(struct AV1_COMP *cpi, int gop_eval,
                        const struct EncodeFrameParams *const frame_params,
                        const struct EncodeFrameInput *const frame_input);

/*!\cond */

void av1_tpl_preload_rc_estimate(
    struct AV1_COMP *cpi, const struct EncodeFrameParams *const frame_params);

int av1_tpl_ptr_pos(int mi_row, int mi_col, int stride, uint8_t right_shift);

void av1_init_tpl_stats(TplParams *const tpl_data);

void av1_tpl_rdmult_setup(struct AV1_COMP *cpi);

void av1_tpl_rdmult_setup_sb(struct AV1_COMP *cpi, MACROBLOCK *const x,
                             BLOCK_SIZE sb_size, int mi_row, int mi_col);

void av1_mc_flow_dispenser_row(struct AV1_COMP *cpi,
                               TplTxfmStats *tpl_txfm_stats, MACROBLOCK *x,
                               int mi_row, BLOCK_SIZE bsize, TX_SIZE tx_size);

/*!\brief  Compute the entropy of an exponential probability distribution
 * function (pdf) subjected to uniform quantization.
 *
 * pdf(x) = b*exp(-b*x)
 *
 *\ingroup tpl_modelling
 *
 * \param[in]    q_step        quantizer step size
 * \param[in]    b             parameter of exponential distribution
 *
 * \return entropy cost
 */
double av1_exponential_entropy(double q_step, double b);

/*!\brief  Compute the entropy of a Laplace probability distribution
 * function (pdf) subjected to non-uniform quantization.
 *
 * pdf(x) = 0.5*b*exp(-0.5*b*|x|)
 *
 *\ingroup tpl_modelling
 *
 * \param[in]    q_step          quantizer step size for non-zero bins
 * \param[in]    b               parameter of Laplace distribution
 * \param[in]    zero_bin_ratio  zero bin's size is zero_bin_ratio * q_step
 *
 * \return entropy cost
 */
double av1_laplace_entropy(double q_step, double b, double zero_bin_ratio);

/*!\brief  Compute the frame rate using transform block stats
 *
 * Assume each position i in the transform block is of Laplace distribution
 * with mean absolute deviation abs_coeff_mean[i]
 *
 * Then we can use av1_laplace_entropy() to compute the expected frame
 * rate.
 *
 *\ingroup tpl_modelling
 *
 * \param[in]    q_index         quantizer index
 * \param[in]    block_count     number of transform blocks
 * \param[in]    abs_coeff_mean  array of mean absolute deviation
 * \param[in]    coeff_num       number of coefficients per transform block
 *
 * \return expected frame rate
 */
double av1_laplace_estimate_frame_rate(int q_index, int block_count,
                                       const double *abs_coeff_mean,
                                       int coeff_num);

/*
 *!\brief Compute the number of bits needed to encode a GOP
 *
 * \param[in]    q_index_list    array of q_index, one per frame
 * \param[in]    frame_count     number of frames in the GOP
 * \param[in]    stats           array of transform stats, one per frame
 *
 */
double av1_estimate_gop_bitrate(const unsigned char *q_index_list,
                                const int frame_count,
                                const TplTxfmStats *stats);

/*
 *!\brief Init TplTxfmStats
 *
 * \param[in]    tpl_txfm_stats  a structure for storing transform stats
 *
 *
 */
void av1_init_tpl_txfm_stats(TplTxfmStats *tpl_txfm_stats);

/*
 *!\brief Accumulate TplTxfmStats
 *
 * \param[in]  sub_stats          a structure for storing sub transform stats
 * \param[out] accumulated_stats  a structure for storing accumulated transform
 *stats
 *
 */
void av1_accumulate_tpl_txfm_stats(const TplTxfmStats *sub_stats,
                                   TplTxfmStats *accumulated_stats);

/*
 *!\brief Record a transform block into  TplTxfmStats
 *
 * \param[in]  tpl_txfm_stats     A structure for storing transform stats
 * \param[out] coeff              An array of transform coefficients. Its size
 *                                should equal to tpl_txfm_stats.coeff_num.
 *
 */
void av1_record_tpl_txfm_block(TplTxfmStats *tpl_txfm_stats,
                               const tran_low_t *coeff);

/*!\brief  Estimate coefficient entropy using Laplace dsitribution
 *
 *\ingroup tpl_modelling
 *
 * This function is equivalent to -log2(laplace_prob()), where laplace_prob() is
 * defined in tpl_model_test.cc
 *
 * \param[in]    q_step          quantizer step size without any scaling
 * \param[in]    b               mean absolute deviation of Laplace distribution
 * \param[in]    zero_bin_ratio  zero bin's size is zero_bin_ratio * q_step
 * \param[in]    qcoeff          quantized coefficient
 *
 * \return estimated coefficient entropy
 *
 */
double av1_estimate_coeff_entropy(double q_step, double b,
                                  double zero_bin_ratio, int qcoeff);

/*!\brief  Estimate entropy of a transform block using Laplace dsitribution
 *
 *\ingroup tpl_modelling
 *
 * \param[in]    q_index         quantizer index
 * \param[in]    abs_coeff_mean  array of mean absolute deviations
 * \param[in]    qcoeff_arr      array of quantized coefficients
 * \param[in]    coeff_num       number of coefficients per transform block
 *
 * \return estimated transform block entropy
 *
 */
double av1_estimate_txfm_block_entropy(int q_index,
                                       const double *abs_coeff_mean,
                                       int *qcoeff_arr, int coeff_num);

// TODO(angiebird): Add doxygen description here.
int64_t av1_delta_rate_cost(int64_t delta_rate, int64_t recrf_dist,
                            int64_t srcrf_dist, int pix_num);

/*!\brief  Compute the overlap area between two blocks with the same size
 *
 *\ingroup tpl_modelling
 *
 * If there is no overlap, this function should return zero.
 *
 * \param[in]    row_a  row position of the first block
 * \param[in]    col_a  column position of the first block
 * \param[in]    row_b  row position of the second block
 * \param[in]    col_b  column position of the second block
 * \param[in]    width  width shared by the two blocks
 * \param[in]    height height shared by the two blocks
 *
 * \return overlap area of the two blocks
 */
int av1_get_overlap_area(int row_a, int col_a, int row_b, int col_b, int width,
                         int height);

/*!\endcond */
#ifdef __cplusplus
}  // extern "C"
#endif

#endif  // AOM_AV1_ENCODER_TPL_MODEL_H_