The Look-Ahead Buffer
Encoder Algorithm » High-level Algorithm

A program should call aom_codec_encode() for each frame that needs processing. These frames are internally copied and stored in a fixed-size circular buffer, known as the look-ahead buffer. Other parts of the code will use future frame information to inform current frame decisions; examples include the first-pass algorithm, TPL model, and temporal filter. Note that this buffer also keeps a reference to the last source frame.

The look-ahead buffer is defined in av1/encoder/lookahead.h. It acts as an opaque structure, with an interface to create and free memory associated with it. It supports pushing and popping frames onto the structure in a FIFO fashion. It also allows look-ahead when using the av1_lookahead_peek() function with a non-negative number, and look-behind when -1 is passed in (for the last source frame; e.g., firstpass will use this for motion estimation). The av1_lookahead_depth() function returns the current number of frames stored in it. Note that av1_lookahead_pop() is a bit of a misnomer - it only pops if either the "flush" variable is set, or the buffer is at maximum capacity.

The buffer is stored in the AV1_PRIMARY::lookahead field. It is initialized in the first call to aom_codec_encode(), in the av1_receive_raw_frame() sub-routine. The buffer size is defined by the g_lag_in_frames parameter set in the aom_codec_enc_cfg_t::g_lag_in_frames struct. This can be modified manually but should only be set once. On the command line, the flag "--lag-in-frames" controls it. The default size is 19 for non-realtime usage and 1 for realtime. Note that a maximum value of 35 is enforced.

A frame will stay in the buffer as long as possible. As mentioned above, the av1_lookahead_pop() only removes a frame when either flush is set, or the buffer is full. Note that each call to aom_codec_encode() inserts another frame into the buffer, and pop is called by the sub-function av1_encode_strategy(). The buffer is told to flush when aom_codec_encode() is passed a NULL image pointer. Note that the caller must repeatedly call aom_codec_encode() with a NULL image pointer, until no more packets are available, in order to fully flush the buffer.