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 <condition_variable> // NOLINT (unapproved c++11 header) 21 #include <cstdint> 22 #include <memory> 23 #include <mutex> // NOLINT (unapproved c++11 header) 24 25 #include "src/loop_restoration_info.h" 26 #include "src/residual_buffer_pool.h" 27 #include "src/symbol_decoder_context.h" 28 #include "src/threading_strategy.h" 29 #include "src/tile_scratch_buffer.h" 30 #include "src/utils/array_2d.h" 31 #include "src/utils/block_parameters_holder.h" 32 #include "src/utils/compiler_attributes.h" 33 #include "src/utils/constants.h" 34 #include "src/utils/dynamic_buffer.h" 35 #include "src/utils/memory.h" 36 #include "src/utils/stack.h" 37 #include "src/utils/types.h" 38 #include "src/yuv_buffer.h" 39 40 namespace libgav1 { 41 42 // Buffer used to store the unfiltered pixels that are necessary for decoding 43 // the next superblock row (for the intra prediction process). 44 using IntraPredictionBuffer = 45 std::array<AlignedDynamicBuffer<uint8_t, kMaxAlignment>, kMaxPlanes>; 46 47 // Buffer to facilitate decoding a frame. This struct is used only within 48 // DecoderImpl::DecodeTiles(). 49 struct FrameScratchBuffer { 50 LoopRestorationInfo loop_restoration_info; 51 Array2D<int16_t> cdef_index; 52 Array2D<TransformSize> inter_transform_sizes; 53 BlockParametersHolder block_parameters_holder; 54 TemporalMotionField motion_field; 55 SymbolDecoderContext symbol_decoder_context; 56 std::unique_ptr<ResidualBufferPool> residual_buffer_pool; 57 // Buffer used to store the cdef borders. This buffer will store 4 rows for 58 // every 64x64 block (4 rows for every 32x32 for chroma with subsampling). The 59 // indices of the rows that are stored are specified in |kCdefBorderRows|. 60 YuvBuffer cdef_border; 61 AlignedDynamicBuffer<uint8_t, 16> superres_coefficients[kNumPlaneTypes]; 62 // Buffer used to temporarily store the input row for applying SuperRes. 63 YuvBuffer superres_line_buffer; 64 // Buffer used to store the loop restoration borders. This buffer will store 4 65 // rows for every 64x64 block (4 rows for every 32x32 for chroma with 66 // subsampling). The indices of the rows that are stored are specified in 67 // |kLoopRestorationBorderRows|. 68 YuvBuffer loop_restoration_border; 69 // The size of this dynamic buffer is |tile_rows|. 70 DynamicBuffer<IntraPredictionBuffer> intra_prediction_buffers; 71 TileScratchBufferPool tile_scratch_buffer_pool; 72 ThreadingStrategy threading_strategy; 73 std::mutex superblock_row_mutex; 74 // The size of this buffer is the number of superblock rows. 75 // |superblock_row_progress[i]| is incremented whenever a tile finishes 76 // decoding superblock row at index i. If the count reaches tile_columns, then 77 // |superblock_row_progress_condvar[i]| is notified. 78 DynamicBuffer<int> superblock_row_progress 79 LIBGAV1_GUARDED_BY(superblock_row_mutex); 80 // The size of this buffer is the number of superblock rows. Used to wait for 81 // |superblock_row_progress[i]| to reach tile_columns. 82 DynamicBuffer<std::condition_variable> superblock_row_progress_condvar; 83 // Used to signal tile decoding failure in the combined multithreading mode. 84 bool tile_decoding_failed LIBGAV1_GUARDED_BY(superblock_row_mutex); 85 }; 86 87 class FrameScratchBufferPool { 88 public: Get()89 std::unique_ptr<FrameScratchBuffer> Get() { 90 std::unique_lock<std::mutex> lock(mutex_); 91 if (!buffers_.Empty()) { 92 return buffers_.Pop(); 93 } 94 lock.unlock(); 95 std::unique_ptr<FrameScratchBuffer> scratch_buffer(new (std::nothrow) 96 FrameScratchBuffer); 97 return scratch_buffer; 98 } 99 Release(std::unique_ptr<FrameScratchBuffer> scratch_buffer)100 void Release(std::unique_ptr<FrameScratchBuffer> scratch_buffer) { 101 std::lock_guard<std::mutex> lock(mutex_); 102 buffers_.Push(std::move(scratch_buffer)); 103 } 104 105 private: 106 std::mutex mutex_; 107 Stack<std::unique_ptr<FrameScratchBuffer>, kMaxThreads> buffers_ 108 LIBGAV1_GUARDED_BY(mutex_); 109 }; 110 111 } // namespace libgav1 112 113 #endif // LIBGAV1_SRC_FRAME_SCRATCH_BUFFER_H_ 114