blob: 9160f309b309fa99dbe4facec9fab93db69bfa86 [file] [log] [blame]
#ifndef LIBGAV1_SRC_DECODER_SCRATCH_BUFFER_H_
#define LIBGAV1_SRC_DECODER_SCRATCH_BUFFER_H_
#include <cstdint>
#include <mutex> // NOLINT (unapproved c++11 header)
#include "src/dsp/constants.h"
#include "src/utils/compiler_attributes.h"
#include "src/utils/constants.h"
#include "src/utils/memory.h"
#include "src/utils/stack.h"
namespace libgav1 {
// Buffer to facilitate decoding a superblock.
struct DecoderScratchBuffer : public Allocable {
static constexpr int kBlockDecodedStride = 34;
private:
#if LIBGAV1_MAX_BITDEPTH >= 10
static constexpr int kPixelSize = 2;
#else
static constexpr int kPixelSize = 1;
#endif
public:
// The following prediction modes need a prediction mask:
// kCompoundPredictionTypeDiffWeighted, kCompoundPredictionTypeWedge,
// kCompoundPredictionTypeIntra. They are mutually exclusive. This buffer is
// used to store the prediction mask during the inter prediction process. The
// mask only needs to be created for the Y plane and is used for the U & V
// planes.
alignas(kMaxAlignment) uint8_t
prediction_mask[kMaxSuperBlockSizeSquareInPixels];
// For each instance of the DecoderScratchBuffer, only one of the following
// buffers will be used at any given time, so it is ok to share them in a
// union.
union {
// Union usage note: This is used only by functions in the "inter"
// prediction path.
//
// Buffers used for inter prediction process.
alignas(kMaxAlignment) uint16_t
prediction_buffer[2][kMaxSuperBlockSizeSquareInPixels];
struct {
// Union usage note: This is used only by functions in the "intra"
// prediction path.
//
// Buffer used for storing subsampled luma samples needed for CFL
// prediction. This buffer is used to avoid repetition of the subsampling
// for the V plane when it is already done for the U plane.
int16_t cfl_luma_buffer[kCflLumaBufferStride][kCflLumaBufferStride];
// Union usage note: This is used only by the
// Tile::ReadTransformCoefficients() function (and the helper functions
// that it calls). This cannot be shared with |cfl_luma_buffer| since
// |cfl_luma_buffer| has to live across the 3 plane loop in
// Tile::TransformBlock.
//
// Buffer used by Tile::ReadTransformCoefficients() to store the quantized
// coefficients until the dequantization process is performed.
int32_t quantized_buffer[kQuantizedCoefficientBufferSize];
};
};
// Buffer used for convolve. The maximum size required for this buffer is:
// maximum block height (with scaling) = 2 * 128 = 256.
// maximum block stride (with scaling and border aligned to 16) =
// (2 * 128 + 7 + 9) * pixel_size = 272 * pixel_size.
alignas(kMaxAlignment) uint8_t
convolve_block_buffer[256 * 272 * DecoderScratchBuffer::kPixelSize];
// Flag indicating whether the data in |cfl_luma_buffer| is valid.
bool cfl_luma_buffer_valid;
// Equivalent to BlockDecoded array in the spec. This stores the decoded
// state of every 4x4 block in a superblock. It has 1 row/column border on
// all 4 sides (hence the 34x34 dimension instead of 32x32). Note that the
// spec uses "-1" as an index to access the left and top borders. In the
// code, we treat the index (1, 1) as equivalent to the spec's (0, 0). So
// all accesses into this array will be offset by +1 when compared with the
// spec.
bool block_decoded[kMaxPlanes][kBlockDecodedStride][kBlockDecodedStride];
};
class DecoderScratchBufferPool {
public:
std::unique_ptr<DecoderScratchBuffer> Get() {
std::lock_guard<std::mutex> lock(mutex_);
if (buffers_.Empty()) {
std::unique_ptr<DecoderScratchBuffer> scratch_buffer(
new (std::nothrow) DecoderScratchBuffer);
return scratch_buffer;
}
return buffers_.Pop();
}
void Release(std::unique_ptr<DecoderScratchBuffer> scratch_buffer) {
std::lock_guard<std::mutex> lock(mutex_);
buffers_.Push(std::move(scratch_buffer));
}
private:
std::mutex mutex_;
// We will never need more than kMaxThreads scratch buffers since that is the
// maximum amount of work that will be done at any given time.
Stack<std::unique_ptr<DecoderScratchBuffer>, kMaxThreads> buffers_
LIBGAV1_GUARDED_BY(mutex_);
};
} // namespace libgav1
#endif // LIBGAV1_SRC_DECODER_SCRATCH_BUFFER_H_