1*09537850SAkhilesh Sanikop /* 2*09537850SAkhilesh Sanikop * Copyright 2020 The libgav1 Authors 3*09537850SAkhilesh Sanikop * 4*09537850SAkhilesh Sanikop * Licensed under the Apache License, Version 2.0 (the "License"); 5*09537850SAkhilesh Sanikop * you may not use this file except in compliance with the License. 6*09537850SAkhilesh Sanikop * You may obtain a copy of the License at 7*09537850SAkhilesh Sanikop * 8*09537850SAkhilesh Sanikop * http://www.apache.org/licenses/LICENSE-2.0 9*09537850SAkhilesh Sanikop * 10*09537850SAkhilesh Sanikop * Unless required by applicable law or agreed to in writing, software 11*09537850SAkhilesh Sanikop * distributed under the License is distributed on an "AS IS" BASIS, 12*09537850SAkhilesh Sanikop * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13*09537850SAkhilesh Sanikop * See the License for the specific language governing permissions and 14*09537850SAkhilesh Sanikop * limitations under the License. 15*09537850SAkhilesh Sanikop */ 16*09537850SAkhilesh Sanikop 17*09537850SAkhilesh Sanikop #ifndef LIBGAV1_SRC_FRAME_SCRATCH_BUFFER_H_ 18*09537850SAkhilesh Sanikop #define LIBGAV1_SRC_FRAME_SCRATCH_BUFFER_H_ 19*09537850SAkhilesh Sanikop 20*09537850SAkhilesh Sanikop #include <array> 21*09537850SAkhilesh Sanikop #include <condition_variable> // NOLINT (unapproved c++11 header) 22*09537850SAkhilesh Sanikop #include <cstdint> 23*09537850SAkhilesh Sanikop #include <memory> 24*09537850SAkhilesh Sanikop #include <mutex> // NOLINT (unapproved c++11 header) 25*09537850SAkhilesh Sanikop #include <new> 26*09537850SAkhilesh Sanikop #include <utility> 27*09537850SAkhilesh Sanikop 28*09537850SAkhilesh Sanikop #include "src/loop_restoration_info.h" 29*09537850SAkhilesh Sanikop #include "src/residual_buffer_pool.h" 30*09537850SAkhilesh Sanikop #include "src/symbol_decoder_context.h" 31*09537850SAkhilesh Sanikop #include "src/threading_strategy.h" 32*09537850SAkhilesh Sanikop #include "src/tile_scratch_buffer.h" 33*09537850SAkhilesh Sanikop #include "src/utils/array_2d.h" 34*09537850SAkhilesh Sanikop #include "src/utils/block_parameters_holder.h" 35*09537850SAkhilesh Sanikop #include "src/utils/compiler_attributes.h" 36*09537850SAkhilesh Sanikop #include "src/utils/constants.h" 37*09537850SAkhilesh Sanikop #include "src/utils/dynamic_buffer.h" 38*09537850SAkhilesh Sanikop #include "src/utils/memory.h" 39*09537850SAkhilesh Sanikop #include "src/utils/stack.h" 40*09537850SAkhilesh Sanikop #include "src/utils/types.h" 41*09537850SAkhilesh Sanikop #include "src/yuv_buffer.h" 42*09537850SAkhilesh Sanikop 43*09537850SAkhilesh Sanikop namespace libgav1 { 44*09537850SAkhilesh Sanikop 45*09537850SAkhilesh Sanikop // Buffer used to store the unfiltered pixels that are necessary for decoding 46*09537850SAkhilesh Sanikop // the next superblock row (for the intra prediction process). 47*09537850SAkhilesh Sanikop using IntraPredictionBuffer = 48*09537850SAkhilesh Sanikop std::array<AlignedDynamicBuffer<uint8_t, kMaxAlignment>, kMaxPlanes>; 49*09537850SAkhilesh Sanikop 50*09537850SAkhilesh Sanikop // Buffer to facilitate decoding a frame. This struct is used only within 51*09537850SAkhilesh Sanikop // DecoderImpl::DecodeTiles(). 52*09537850SAkhilesh Sanikop // The alignment requirement is due to the SymbolDecoderContext member 53*09537850SAkhilesh Sanikop // symbol_decoder_context and the TileScratchBufferPool member 54*09537850SAkhilesh Sanikop // tile_scratch_buffer_pool. 55*09537850SAkhilesh Sanikop struct FrameScratchBuffer : public MaxAlignedAllocable { 56*09537850SAkhilesh Sanikop LoopRestorationInfo loop_restoration_info; 57*09537850SAkhilesh Sanikop Array2D<int8_t> cdef_index; 58*09537850SAkhilesh Sanikop // Encodes the block skip information as a bitmask for the entire frame which 59*09537850SAkhilesh Sanikop // will be used by the cdef process. 60*09537850SAkhilesh Sanikop // 61*09537850SAkhilesh Sanikop // * The size of this array is rows4x4 / 2 * column4x4 / 16. 62*09537850SAkhilesh Sanikop // * Each row of the bitmasks array (cdef_skip) stores the bitmask for 2 rows 63*09537850SAkhilesh Sanikop // of 4x4 blocks. 64*09537850SAkhilesh Sanikop // * Each entry in the row will store the skip information for 16 4x4 blocks 65*09537850SAkhilesh Sanikop // (8 bits). 66*09537850SAkhilesh Sanikop // * If any of the four 4x4 blocks in the 8x8 block is not a skip block, then 67*09537850SAkhilesh Sanikop // the corresponding bit (as described below) will be set to 1. 68*09537850SAkhilesh Sanikop // * For the 4x4 block at column4x4 the bit index is (column4x4 >> 1). 69*09537850SAkhilesh Sanikop Array2D<uint8_t> cdef_skip; 70*09537850SAkhilesh Sanikop Array2D<TransformSize> inter_transform_sizes; 71*09537850SAkhilesh Sanikop BlockParametersHolder block_parameters_holder; 72*09537850SAkhilesh Sanikop TemporalMotionField motion_field; 73*09537850SAkhilesh Sanikop SymbolDecoderContext symbol_decoder_context; 74*09537850SAkhilesh Sanikop std::unique_ptr<ResidualBufferPool> residual_buffer_pool; 75*09537850SAkhilesh Sanikop // Buffer used to store the cdef borders. This buffer will store 4 rows for 76*09537850SAkhilesh Sanikop // every 64x64 block (4 rows for every 32x32 for chroma with subsampling). The 77*09537850SAkhilesh Sanikop // indices of the rows that are stored are specified in |kCdefBorderRows|. 78*09537850SAkhilesh Sanikop YuvBuffer cdef_border; 79*09537850SAkhilesh Sanikop AlignedDynamicBuffer<uint8_t, 16> superres_coefficients[kNumPlaneTypes]; 80*09537850SAkhilesh Sanikop // Buffer used to temporarily store the input row for applying SuperRes. 81*09537850SAkhilesh Sanikop YuvBuffer superres_line_buffer; 82*09537850SAkhilesh Sanikop // Buffer used to store the loop restoration borders. This buffer will store 4 83*09537850SAkhilesh Sanikop // rows for every 64x64 block (4 rows for every 32x32 for chroma with 84*09537850SAkhilesh Sanikop // subsampling). The indices of the rows that are stored are specified in 85*09537850SAkhilesh Sanikop // |kLoopRestorationBorderRows|. 86*09537850SAkhilesh Sanikop YuvBuffer loop_restoration_border; 87*09537850SAkhilesh Sanikop // The size of this dynamic buffer is |tile_rows|. 88*09537850SAkhilesh Sanikop DynamicBuffer<IntraPredictionBuffer> intra_prediction_buffers; 89*09537850SAkhilesh Sanikop TileScratchBufferPool tile_scratch_buffer_pool; 90*09537850SAkhilesh Sanikop ThreadingStrategy threading_strategy; 91*09537850SAkhilesh Sanikop std::mutex superblock_row_mutex; 92*09537850SAkhilesh Sanikop // The size of this buffer is the number of superblock rows. 93*09537850SAkhilesh Sanikop // |superblock_row_progress[i]| is incremented whenever a tile finishes 94*09537850SAkhilesh Sanikop // decoding superblock row at index i. If the count reaches tile_columns, then 95*09537850SAkhilesh Sanikop // |superblock_row_progress_condvar[i]| is notified. 96*09537850SAkhilesh Sanikop DynamicBuffer<int> superblock_row_progress 97*09537850SAkhilesh Sanikop LIBGAV1_GUARDED_BY(superblock_row_mutex); 98*09537850SAkhilesh Sanikop // The size of this buffer is the number of superblock rows. Used to wait for 99*09537850SAkhilesh Sanikop // |superblock_row_progress[i]| to reach tile_columns. 100*09537850SAkhilesh Sanikop DynamicBuffer<std::condition_variable> superblock_row_progress_condvar; 101*09537850SAkhilesh Sanikop // Used to signal tile decoding failure in the combined multithreading mode. 102*09537850SAkhilesh Sanikop bool tile_decoding_failed LIBGAV1_GUARDED_BY(superblock_row_mutex); 103*09537850SAkhilesh Sanikop }; 104*09537850SAkhilesh Sanikop 105*09537850SAkhilesh Sanikop class FrameScratchBufferPool { 106*09537850SAkhilesh Sanikop public: Get()107*09537850SAkhilesh Sanikop std::unique_ptr<FrameScratchBuffer> Get() { 108*09537850SAkhilesh Sanikop std::unique_lock<std::mutex> lock(mutex_); 109*09537850SAkhilesh Sanikop if (!buffers_.Empty()) { 110*09537850SAkhilesh Sanikop return buffers_.Pop(); 111*09537850SAkhilesh Sanikop } 112*09537850SAkhilesh Sanikop lock.unlock(); 113*09537850SAkhilesh Sanikop std::unique_ptr<FrameScratchBuffer> scratch_buffer(new (std::nothrow) 114*09537850SAkhilesh Sanikop FrameScratchBuffer); 115*09537850SAkhilesh Sanikop return scratch_buffer; 116*09537850SAkhilesh Sanikop } 117*09537850SAkhilesh Sanikop Release(std::unique_ptr<FrameScratchBuffer> scratch_buffer)118*09537850SAkhilesh Sanikop void Release(std::unique_ptr<FrameScratchBuffer> scratch_buffer) { 119*09537850SAkhilesh Sanikop std::lock_guard<std::mutex> lock(mutex_); 120*09537850SAkhilesh Sanikop buffers_.Push(std::move(scratch_buffer)); 121*09537850SAkhilesh Sanikop } 122*09537850SAkhilesh Sanikop 123*09537850SAkhilesh Sanikop private: 124*09537850SAkhilesh Sanikop std::mutex mutex_; 125*09537850SAkhilesh Sanikop Stack<std::unique_ptr<FrameScratchBuffer>, kMaxThreads> buffers_ 126*09537850SAkhilesh Sanikop LIBGAV1_GUARDED_BY(mutex_); 127*09537850SAkhilesh Sanikop }; 128*09537850SAkhilesh Sanikop 129*09537850SAkhilesh Sanikop } // namespace libgav1 130*09537850SAkhilesh Sanikop 131*09537850SAkhilesh Sanikop #endif // LIBGAV1_SRC_FRAME_SCRATCH_BUFFER_H_ 132