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