1*77c1e3ccSAndroid Build Coastguard Worker /*
2*77c1e3ccSAndroid Build Coastguard Worker * Copyright (c) 2019, Alliance for Open Media. All rights reserved.
3*77c1e3ccSAndroid Build Coastguard Worker *
4*77c1e3ccSAndroid Build Coastguard Worker * This source code is subject to the terms of the BSD 2 Clause License and
5*77c1e3ccSAndroid Build Coastguard Worker * the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License
6*77c1e3ccSAndroid Build Coastguard Worker * was not distributed with this source code in the LICENSE file, you can
7*77c1e3ccSAndroid Build Coastguard Worker * obtain it at www.aomedia.org/license/software. If the Alliance for Open
8*77c1e3ccSAndroid Build Coastguard Worker * Media Patent License 1.0 was not distributed with this source code in the
9*77c1e3ccSAndroid Build Coastguard Worker * PATENTS file, you can obtain it at www.aomedia.org/license/patent.
10*77c1e3ccSAndroid Build Coastguard Worker */
11*77c1e3ccSAndroid Build Coastguard Worker
12*77c1e3ccSAndroid Build Coastguard Worker #ifndef AOM_AV1_ENCODER_LEVEL_H_
13*77c1e3ccSAndroid Build Coastguard Worker #define AOM_AV1_ENCODER_LEVEL_H_
14*77c1e3ccSAndroid Build Coastguard Worker
15*77c1e3ccSAndroid Build Coastguard Worker #include "av1/common/enums.h"
16*77c1e3ccSAndroid Build Coastguard Worker
17*77c1e3ccSAndroid Build Coastguard Worker struct AV1_COMP;
18*77c1e3ccSAndroid Build Coastguard Worker
19*77c1e3ccSAndroid Build Coastguard Worker // AV1 Level Specifications
20*77c1e3ccSAndroid Build Coastguard Worker typedef struct {
21*77c1e3ccSAndroid Build Coastguard Worker AV1_LEVEL level;
22*77c1e3ccSAndroid Build Coastguard Worker int max_picture_size;
23*77c1e3ccSAndroid Build Coastguard Worker int max_h_size;
24*77c1e3ccSAndroid Build Coastguard Worker int max_v_size;
25*77c1e3ccSAndroid Build Coastguard Worker int max_header_rate;
26*77c1e3ccSAndroid Build Coastguard Worker int max_tile_rate;
27*77c1e3ccSAndroid Build Coastguard Worker int max_tiles;
28*77c1e3ccSAndroid Build Coastguard Worker int max_tile_cols;
29*77c1e3ccSAndroid Build Coastguard Worker int64_t max_display_rate;
30*77c1e3ccSAndroid Build Coastguard Worker int64_t max_decode_rate;
31*77c1e3ccSAndroid Build Coastguard Worker double main_mbps;
32*77c1e3ccSAndroid Build Coastguard Worker double high_mbps;
33*77c1e3ccSAndroid Build Coastguard Worker double main_cr;
34*77c1e3ccSAndroid Build Coastguard Worker double high_cr;
35*77c1e3ccSAndroid Build Coastguard Worker } AV1LevelSpec;
36*77c1e3ccSAndroid Build Coastguard Worker
37*77c1e3ccSAndroid Build Coastguard Worker typedef struct {
38*77c1e3ccSAndroid Build Coastguard Worker int64_t ts_start;
39*77c1e3ccSAndroid Build Coastguard Worker int64_t ts_end;
40*77c1e3ccSAndroid Build Coastguard Worker size_t encoded_size_in_bytes;
41*77c1e3ccSAndroid Build Coastguard Worker int pic_size;
42*77c1e3ccSAndroid Build Coastguard Worker int frame_header_count;
43*77c1e3ccSAndroid Build Coastguard Worker int tiles;
44*77c1e3ccSAndroid Build Coastguard Worker int show_frame;
45*77c1e3ccSAndroid Build Coastguard Worker int show_existing_frame;
46*77c1e3ccSAndroid Build Coastguard Worker } FrameRecord;
47*77c1e3ccSAndroid Build Coastguard Worker
48*77c1e3ccSAndroid Build Coastguard Worker // Record frame info. in a rolling window.
49*77c1e3ccSAndroid Build Coastguard Worker #define FRAME_WINDOW_SIZE 256
50*77c1e3ccSAndroid Build Coastguard Worker typedef struct {
51*77c1e3ccSAndroid Build Coastguard Worker FrameRecord buf[FRAME_WINDOW_SIZE];
52*77c1e3ccSAndroid Build Coastguard Worker int num; // Number of FrameRecord stored in the buffer.
53*77c1e3ccSAndroid Build Coastguard Worker int start; // Buffer index of the first FrameRecord.
54*77c1e3ccSAndroid Build Coastguard Worker } FrameWindowBuffer;
55*77c1e3ccSAndroid Build Coastguard Worker
56*77c1e3ccSAndroid Build Coastguard Worker typedef struct {
57*77c1e3ccSAndroid Build Coastguard Worker int max_bitrate; // Max bitrate in any 1-second window, in bps.
58*77c1e3ccSAndroid Build Coastguard Worker int max_tile_size;
59*77c1e3ccSAndroid Build Coastguard Worker int max_superres_tile_width;
60*77c1e3ccSAndroid Build Coastguard Worker int min_cropped_tile_width;
61*77c1e3ccSAndroid Build Coastguard Worker int min_cropped_tile_height;
62*77c1e3ccSAndroid Build Coastguard Worker int tile_width_is_valid;
63*77c1e3ccSAndroid Build Coastguard Worker int min_frame_width;
64*77c1e3ccSAndroid Build Coastguard Worker int min_frame_height;
65*77c1e3ccSAndroid Build Coastguard Worker double total_compressed_size; // In bytes.
66*77c1e3ccSAndroid Build Coastguard Worker double total_time_encoded; // In seconds.
67*77c1e3ccSAndroid Build Coastguard Worker double min_cr;
68*77c1e3ccSAndroid Build Coastguard Worker } AV1LevelStats;
69*77c1e3ccSAndroid Build Coastguard Worker
70*77c1e3ccSAndroid Build Coastguard Worker // The following data structures are for the decoder model.
71*77c1e3ccSAndroid Build Coastguard Worker typedef struct {
72*77c1e3ccSAndroid Build Coastguard Worker int decoder_ref_count;
73*77c1e3ccSAndroid Build Coastguard Worker int player_ref_count;
74*77c1e3ccSAndroid Build Coastguard Worker int display_index;
75*77c1e3ccSAndroid Build Coastguard Worker FRAME_TYPE frame_type;
76*77c1e3ccSAndroid Build Coastguard Worker double presentation_time;
77*77c1e3ccSAndroid Build Coastguard Worker } FRAME_BUFFER;
78*77c1e3ccSAndroid Build Coastguard Worker
79*77c1e3ccSAndroid Build Coastguard Worker // Interval of bits transmission for a DFG(Decodable Frame Group).
80*77c1e3ccSAndroid Build Coastguard Worker typedef struct {
81*77c1e3ccSAndroid Build Coastguard Worker double first_bit_arrival_time; // Time when the first bit arrives.
82*77c1e3ccSAndroid Build Coastguard Worker double last_bit_arrival_time; // Time when the last bit arrives.
83*77c1e3ccSAndroid Build Coastguard Worker // Removal time means the time when the bits to be decoded are removed from
84*77c1e3ccSAndroid Build Coastguard Worker // the smoothing buffer. Removal time is essentially the time when the
85*77c1e3ccSAndroid Build Coastguard Worker // decoding of the frame starts.
86*77c1e3ccSAndroid Build Coastguard Worker double removal_time;
87*77c1e3ccSAndroid Build Coastguard Worker } DFG_INTERVAL;
88*77c1e3ccSAndroid Build Coastguard Worker
89*77c1e3ccSAndroid Build Coastguard Worker #define DFG_INTERVAL_QUEUE_SIZE 64
90*77c1e3ccSAndroid Build Coastguard Worker typedef struct {
91*77c1e3ccSAndroid Build Coastguard Worker int head;
92*77c1e3ccSAndroid Build Coastguard Worker int size;
93*77c1e3ccSAndroid Build Coastguard Worker double total_interval;
94*77c1e3ccSAndroid Build Coastguard Worker DFG_INTERVAL buf[DFG_INTERVAL_QUEUE_SIZE];
95*77c1e3ccSAndroid Build Coastguard Worker } DFG_INTERVAL_QUEUE;
96*77c1e3ccSAndroid Build Coastguard Worker
97*77c1e3ccSAndroid Build Coastguard Worker enum {
98*77c1e3ccSAndroid Build Coastguard Worker RESOURCE_MODE = 0, // Resource availability mode.
99*77c1e3ccSAndroid Build Coastguard Worker SCHEDULE_MODE // Decoding schedule mode.
100*77c1e3ccSAndroid Build Coastguard Worker } UENUM1BYTE(DECODER_MODEL_MODE);
101*77c1e3ccSAndroid Build Coastguard Worker
102*77c1e3ccSAndroid Build Coastguard Worker enum {
103*77c1e3ccSAndroid Build Coastguard Worker DECODER_MODEL_OK = 0,
104*77c1e3ccSAndroid Build Coastguard Worker DECODE_BUFFER_AVAILABLE_LATE,
105*77c1e3ccSAndroid Build Coastguard Worker DECODE_FRAME_BUF_UNAVAILABLE,
106*77c1e3ccSAndroid Build Coastguard Worker DECODE_EXISTING_FRAME_BUF_EMPTY,
107*77c1e3ccSAndroid Build Coastguard Worker DISPLAY_FRAME_LATE,
108*77c1e3ccSAndroid Build Coastguard Worker SMOOTHING_BUFFER_UNDERFLOW,
109*77c1e3ccSAndroid Build Coastguard Worker SMOOTHING_BUFFER_OVERFLOW,
110*77c1e3ccSAndroid Build Coastguard Worker DECODER_MODEL_DISABLED
111*77c1e3ccSAndroid Build Coastguard Worker } UENUM1BYTE(DECODER_MODEL_STATUS);
112*77c1e3ccSAndroid Build Coastguard Worker
113*77c1e3ccSAndroid Build Coastguard Worker #define BUFFER_POOL_MAX_SIZE 10
114*77c1e3ccSAndroid Build Coastguard Worker typedef struct {
115*77c1e3ccSAndroid Build Coastguard Worker DECODER_MODEL_STATUS status;
116*77c1e3ccSAndroid Build Coastguard Worker DECODER_MODEL_MODE mode;
117*77c1e3ccSAndroid Build Coastguard Worker bool is_low_delay_mode;
118*77c1e3ccSAndroid Build Coastguard Worker AV1_LEVEL level;
119*77c1e3ccSAndroid Build Coastguard Worker int encoder_buffer_delay; // In units of 1/90000 seconds.
120*77c1e3ccSAndroid Build Coastguard Worker int decoder_buffer_delay; // In units of 1/90000 seconds.
121*77c1e3ccSAndroid Build Coastguard Worker int num_ticks_per_picture;
122*77c1e3ccSAndroid Build Coastguard Worker int initial_display_delay; // In units of frames.
123*77c1e3ccSAndroid Build Coastguard Worker int64_t decode_rate;
124*77c1e3ccSAndroid Build Coastguard Worker double display_clock_tick; // In units of seconds.
125*77c1e3ccSAndroid Build Coastguard Worker double current_time; // In units of seconds.
126*77c1e3ccSAndroid Build Coastguard Worker double initial_presentation_delay; // In units of seconds.
127*77c1e3ccSAndroid Build Coastguard Worker double bit_rate; // Bits per second.
128*77c1e3ccSAndroid Build Coastguard Worker
129*77c1e3ccSAndroid Build Coastguard Worker int num_frame;
130*77c1e3ccSAndroid Build Coastguard Worker int num_decoded_frame;
131*77c1e3ccSAndroid Build Coastguard Worker int num_shown_frame;
132*77c1e3ccSAndroid Build Coastguard Worker int vbi[REF_FRAMES]; // Virtual buffer index.
133*77c1e3ccSAndroid Build Coastguard Worker FRAME_BUFFER frame_buffer_pool[BUFFER_POOL_MAX_SIZE];
134*77c1e3ccSAndroid Build Coastguard Worker DFG_INTERVAL_QUEUE dfg_interval_queue;
135*77c1e3ccSAndroid Build Coastguard Worker
136*77c1e3ccSAndroid Build Coastguard Worker // Information for the DFG(Decodable Frame Group) being processed.
137*77c1e3ccSAndroid Build Coastguard Worker double first_bit_arrival_time;
138*77c1e3ccSAndroid Build Coastguard Worker double last_bit_arrival_time;
139*77c1e3ccSAndroid Build Coastguard Worker size_t coded_bits;
140*77c1e3ccSAndroid Build Coastguard Worker
141*77c1e3ccSAndroid Build Coastguard Worker // Information for the frame being processed.
142*77c1e3ccSAndroid Build Coastguard Worker double removal_time;
143*77c1e3ccSAndroid Build Coastguard Worker double presentation_time;
144*77c1e3ccSAndroid Build Coastguard Worker int decode_samples;
145*77c1e3ccSAndroid Build Coastguard Worker int display_samples;
146*77c1e3ccSAndroid Build Coastguard Worker
147*77c1e3ccSAndroid Build Coastguard Worker double max_display_rate;
148*77c1e3ccSAndroid Build Coastguard Worker double max_decode_rate;
149*77c1e3ccSAndroid Build Coastguard Worker } DECODER_MODEL;
150*77c1e3ccSAndroid Build Coastguard Worker
151*77c1e3ccSAndroid Build Coastguard Worker typedef struct {
152*77c1e3ccSAndroid Build Coastguard Worker AV1LevelStats level_stats;
153*77c1e3ccSAndroid Build Coastguard Worker AV1LevelSpec level_spec;
154*77c1e3ccSAndroid Build Coastguard Worker FrameWindowBuffer frame_window_buffer;
155*77c1e3ccSAndroid Build Coastguard Worker DECODER_MODEL decoder_models[SEQ_LEVELS];
156*77c1e3ccSAndroid Build Coastguard Worker } AV1LevelInfo;
157*77c1e3ccSAndroid Build Coastguard Worker
158*77c1e3ccSAndroid Build Coastguard Worker typedef struct AV1LevelParams {
159*77c1e3ccSAndroid Build Coastguard Worker // Specifies the level that the coded video sequence conforms to for each
160*77c1e3ccSAndroid Build Coastguard Worker // operating point.
161*77c1e3ccSAndroid Build Coastguard Worker AV1_LEVEL target_seq_level_idx[MAX_NUM_OPERATING_POINTS];
162*77c1e3ccSAndroid Build Coastguard Worker // Bit mask to indicate whether to keep level stats for corresponding
163*77c1e3ccSAndroid Build Coastguard Worker // operating points.
164*77c1e3ccSAndroid Build Coastguard Worker uint32_t keep_level_stats;
165*77c1e3ccSAndroid Build Coastguard Worker // Level information for each operating point.
166*77c1e3ccSAndroid Build Coastguard Worker AV1LevelInfo *level_info[MAX_NUM_OPERATING_POINTS];
167*77c1e3ccSAndroid Build Coastguard Worker } AV1LevelParams;
168*77c1e3ccSAndroid Build Coastguard Worker
is_in_operating_point(int operating_point,int temporal_layer_id,int spatial_layer_id)169*77c1e3ccSAndroid Build Coastguard Worker static inline int is_in_operating_point(int operating_point,
170*77c1e3ccSAndroid Build Coastguard Worker int temporal_layer_id,
171*77c1e3ccSAndroid Build Coastguard Worker int spatial_layer_id) {
172*77c1e3ccSAndroid Build Coastguard Worker if (!operating_point) return 1;
173*77c1e3ccSAndroid Build Coastguard Worker
174*77c1e3ccSAndroid Build Coastguard Worker return ((operating_point >> temporal_layer_id) & 1) &&
175*77c1e3ccSAndroid Build Coastguard Worker ((operating_point >> (spatial_layer_id + 8)) & 1);
176*77c1e3ccSAndroid Build Coastguard Worker }
177*77c1e3ccSAndroid Build Coastguard Worker
178*77c1e3ccSAndroid Build Coastguard Worker void av1_init_level_info(struct AV1_COMP *cpi);
179*77c1e3ccSAndroid Build Coastguard Worker
180*77c1e3ccSAndroid Build Coastguard Worker void av1_update_level_info(struct AV1_COMP *cpi, size_t size, int64_t ts_start,
181*77c1e3ccSAndroid Build Coastguard Worker int64_t ts_end);
182*77c1e3ccSAndroid Build Coastguard Worker
183*77c1e3ccSAndroid Build Coastguard Worker // Return sequence level indices in seq_level_idx[MAX_NUM_OPERATING_POINTS].
184*77c1e3ccSAndroid Build Coastguard Worker aom_codec_err_t av1_get_seq_level_idx(const SequenceHeader *seq_params,
185*77c1e3ccSAndroid Build Coastguard Worker const AV1LevelParams *level_params,
186*77c1e3ccSAndroid Build Coastguard Worker int *seq_level_idx);
187*77c1e3ccSAndroid Build Coastguard Worker
188*77c1e3ccSAndroid Build Coastguard Worker aom_codec_err_t av1_get_target_seq_level_idx(const SequenceHeader *seq_params,
189*77c1e3ccSAndroid Build Coastguard Worker const AV1LevelParams *level_params,
190*77c1e3ccSAndroid Build Coastguard Worker int *target_seq_level_idx);
191*77c1e3ccSAndroid Build Coastguard Worker
192*77c1e3ccSAndroid Build Coastguard Worker // This function uses the decoder model to check whether there could be
193*77c1e3ccSAndroid Build Coastguard Worker // SMOOTHING_BUFFER_UNDERFLOW or SMOOTHING_BUFFER_OVERFLOW. It does not
194*77c1e3ccSAndroid Build Coastguard Worker // update the content of decoder_model, and can be used to target certain
195*77c1e3ccSAndroid Build Coastguard Worker // encoding level in the recode loop.
196*77c1e3ccSAndroid Build Coastguard Worker DECODER_MODEL_STATUS av1_decoder_model_try_smooth_buf(
197*77c1e3ccSAndroid Build Coastguard Worker const struct AV1_COMP *const cpi, size_t coded_bits,
198*77c1e3ccSAndroid Build Coastguard Worker const DECODER_MODEL *const decoder_model);
199*77c1e3ccSAndroid Build Coastguard Worker
200*77c1e3ccSAndroid Build Coastguard Worker // Return max bitrate(bps) for given level.
201*77c1e3ccSAndroid Build Coastguard Worker double av1_get_max_bitrate_for_level(AV1_LEVEL level_index, int tier,
202*77c1e3ccSAndroid Build Coastguard Worker BITSTREAM_PROFILE profile);
203*77c1e3ccSAndroid Build Coastguard Worker
204*77c1e3ccSAndroid Build Coastguard Worker // Get max number of tiles and tile columns for given level.
205*77c1e3ccSAndroid Build Coastguard Worker void av1_get_max_tiles_for_level(AV1_LEVEL level_index, int *const max_tiles,
206*77c1e3ccSAndroid Build Coastguard Worker int *const max_tile_cols);
207*77c1e3ccSAndroid Build Coastguard Worker
208*77c1e3ccSAndroid Build Coastguard Worker // Return minimum compression ratio for given level.
209*77c1e3ccSAndroid Build Coastguard Worker double av1_get_min_cr_for_level(AV1_LEVEL level_index, int tier,
210*77c1e3ccSAndroid Build Coastguard Worker int is_still_picture);
211*77c1e3ccSAndroid Build Coastguard Worker #endif // AOM_AV1_ENCODER_LEVEL_H_
212