1 /* 2 * Copyright 2019 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_DECODER_IMPL_H_ 18 #define LIBGAV1_SRC_DECODER_IMPL_H_ 19 20 #include <array> 21 #include <condition_variable> // NOLINT (unapproved c++11 header) 22 #include <cstddef> 23 #include <cstdint> 24 #include <memory> 25 #include <mutex> // NOLINT (unapproved c++11 header) 26 #include <vector> 27 28 #include "src/buffer_pool.h" 29 #include "src/decoder_state.h" 30 #include "src/dsp/constants.h" 31 #include "src/frame_scratch_buffer.h" 32 #include "src/gav1/decoder_buffer.h" 33 #include "src/gav1/decoder_settings.h" 34 #include "src/gav1/status_code.h" 35 #include "src/obu_parser.h" 36 #include "src/quantizer.h" 37 #include "src/residual_buffer_pool.h" 38 #include "src/symbol_decoder_context.h" 39 #include "src/tile.h" 40 #include "src/utils/array_2d.h" 41 #include "src/utils/block_parameters_holder.h" 42 #include "src/utils/compiler_attributes.h" 43 #include "src/utils/constants.h" 44 #include "src/utils/memory.h" 45 #include "src/utils/queue.h" 46 #include "src/utils/segmentation_map.h" 47 #include "src/utils/types.h" 48 49 namespace libgav1 { 50 51 struct TemporalUnit; 52 53 struct EncodedFrame { EncodedFrameEncodedFrame54 EncodedFrame(ObuParser* const obu, const DecoderState& state, 55 const RefCountedBufferPtr& frame, int position_in_temporal_unit) 56 : sequence_header(obu->sequence_header()), 57 frame_header(obu->frame_header()), 58 state(state), 59 temporal_unit(nullptr), 60 frame(frame), 61 position_in_temporal_unit(position_in_temporal_unit) { 62 obu->MoveTileBuffers(&tile_buffers); 63 frame->MarkFrameAsStarted(); 64 } 65 66 const ObuSequenceHeader sequence_header; 67 const ObuFrameHeader frame_header; 68 Vector<TileBuffer> tile_buffers; 69 DecoderState state; 70 TemporalUnit* temporal_unit; 71 RefCountedBufferPtr frame; 72 const int position_in_temporal_unit; 73 }; 74 75 struct TemporalUnit : public Allocable { 76 // The default constructor is invoked by the Queue<TemporalUnit>::Init() 77 // method. Queue<> does not use the default-constructed elements, so it is 78 // safe for the default constructor to not initialize the members. 79 TemporalUnit() = default; TemporalUnitTemporalUnit80 TemporalUnit(const uint8_t* data, size_t size, int64_t user_private_data, 81 void* buffer_private_data) 82 : data(data), 83 size(size), 84 user_private_data(user_private_data), 85 buffer_private_data(buffer_private_data), 86 decoded(false), 87 status(kStatusOk), 88 has_displayable_frame(false), 89 output_frame_position(-1), 90 decoded_count(0), 91 output_layer_count(0), 92 released_input_buffer(false) {} 93 94 const uint8_t* data; 95 size_t size; 96 int64_t user_private_data; 97 void* buffer_private_data; 98 99 // The following members are used only in frame parallel mode. 100 bool decoded; 101 StatusCode status; 102 bool has_displayable_frame; 103 int output_frame_position; 104 105 Vector<EncodedFrame> frames; 106 size_t decoded_count; 107 108 // The struct (and the counter) is used to support output of multiple layers 109 // within a single temporal unit. The decoding process will store the output 110 // frames in |output_layers| in the order they are finished decoding. At the 111 // end of the decoding process, this array will be sorted in reverse order of 112 // |position_in_temporal_unit|. DequeueFrame() will then return the frames in 113 // reverse order (so that the entire process can run with a single counter 114 // variable). 115 struct OutputLayer { 116 // Used by std::sort to sort |output_layers| in reverse order of 117 // |position_in_temporal_unit|. 118 bool operator<(const OutputLayer& rhs) const { 119 return position_in_temporal_unit > rhs.position_in_temporal_unit; 120 } 121 122 RefCountedBufferPtr frame; 123 int position_in_temporal_unit = 0; 124 } output_layers[kMaxLayers]; 125 // Number of entries in |output_layers|. 126 int output_layer_count; 127 // Flag to ensure that we release the input buffer only once if there are 128 // multiple output layers. 129 bool released_input_buffer; 130 }; 131 132 class DecoderImpl : public Allocable { 133 public: 134 // The constructor saves a const reference to |*settings|. Therefore 135 // |*settings| must outlive the DecoderImpl object. On success, |*output| 136 // contains a pointer to the newly-created DecoderImpl object. On failure, 137 // |*output| is not modified. 138 static StatusCode Create(const DecoderSettings* settings, 139 std::unique_ptr<DecoderImpl>* output); 140 ~DecoderImpl(); 141 StatusCode EnqueueFrame(const uint8_t* data, size_t size, 142 int64_t user_private_data, void* buffer_private_data); 143 StatusCode DequeueFrame(const DecoderBuffer** out_ptr); GetMaxBitdepth()144 static constexpr int GetMaxBitdepth() { 145 static_assert(LIBGAV1_MAX_BITDEPTH == 8 || LIBGAV1_MAX_BITDEPTH == 10 || 146 LIBGAV1_MAX_BITDEPTH == 12, 147 "LIBGAV1_MAX_BITDEPTH must be 8, 10 or 12."); 148 return LIBGAV1_MAX_BITDEPTH; 149 } 150 std::vector<int> GetFrameQps(); 151 152 private: 153 explicit DecoderImpl(const DecoderSettings* settings); 154 StatusCode Init(); 155 // Called when the first frame is enqueued. It does the OBU parsing for one 156 // temporal unit to retrieve the tile configuration and sets up the frame 157 // threading if frame parallel mode is allowed. It also initializes the 158 // |temporal_units_| queue based on the number of frame threads. 159 // 160 // The following are the limitations of the current implementation: 161 // * It assumes that all frames in the video have the same tile 162 // configuration. The frame parallel threading model will not be updated 163 // based on tile configuration changes mid-stream. 164 // * The above assumption holds true even when there is a new coded video 165 // sequence (i.e.) a new sequence header. 166 StatusCode InitializeFrameThreadPoolAndTemporalUnitQueue(const uint8_t* data, 167 size_t size); 168 // Used only in frame parallel mode. Signals failure and waits until the 169 // worker threads are aborted if |status| is a failure status. If |status| is 170 // equal to kStatusOk or kStatusTryAgain, this function does not do anything. 171 // Always returns the input parameter |status| as the return value. 172 // 173 // This function is called only from the application thread (from 174 // EnqueueFrame() and DequeueFrame()). 175 StatusCode SignalFailure(StatusCode status); 176 177 void ReleaseOutputFrame(); 178 179 // Decodes all the frames contained in the given temporal unit. Used only in 180 // non frame parallel mode. 181 StatusCode DecodeTemporalUnit(const TemporalUnit& temporal_unit, 182 const DecoderBuffer** out_ptr); 183 // Used only in frame parallel mode. Does the OBU parsing for |data| and 184 // schedules the individual frames for decoding in the |frame_thread_pool_|. 185 StatusCode ParseAndSchedule(const uint8_t* data, size_t size, 186 int64_t user_private_data, 187 void* buffer_private_data); 188 // Decodes the |encoded_frame| and updates the 189 // |encoded_frame->temporal_unit|'s parameters if the decoded frame is a 190 // displayable frame. Used only in frame parallel mode. 191 StatusCode DecodeFrame(EncodedFrame* encoded_frame); 192 193 // Populates |buffer_| with values from |frame|. Adds a reference to |frame| 194 // in |output_frame_|. 195 StatusCode CopyFrameToOutputBuffer(const RefCountedBufferPtr& frame); 196 StatusCode DecodeTiles(const ObuSequenceHeader& sequence_header, 197 const ObuFrameHeader& frame_header, 198 const Vector<TileBuffer>& tile_buffers, 199 const DecoderState& state, 200 FrameScratchBuffer* frame_scratch_buffer, 201 RefCountedBuffer* current_frame); 202 // Applies film grain synthesis to the |displayable_frame| and stores the film 203 // grain applied frame into |film_grain_frame|. Returns kStatusOk on success. 204 StatusCode ApplyFilmGrain(const ObuSequenceHeader& sequence_header, 205 const ObuFrameHeader& frame_header, 206 const RefCountedBufferPtr& displayable_frame, 207 RefCountedBufferPtr* film_grain_frame, 208 ThreadPool* thread_pool); 209 210 bool IsNewSequenceHeader(const ObuParser& obu); 211 HasFailure()212 bool HasFailure() { 213 std::lock_guard<std::mutex> lock(mutex_); 214 return failure_status_ != kStatusOk; 215 } 216 217 // Initializes the |quantizer_matrix_| if necessary and sets 218 // |quantizer_matrix_initialized_| to true. 219 bool MaybeInitializeQuantizerMatrix(const ObuFrameHeader& frame_header); 220 221 // Allocates and generates the |wedge_masks_| if necessary and sets 222 // |wedge_masks_initialized_| to true. 223 bool MaybeInitializeWedgeMasks(FrameType frame_type); 224 225 // Elements in this queue cannot be moved with std::move since the 226 // |EncodedFrame.temporal_unit| stores a pointer to elements in this queue. 227 Queue<TemporalUnit> temporal_units_; 228 DecoderState state_; 229 230 DecoderBuffer buffer_ = {}; 231 // |output_frame_| holds a reference to the output frame on behalf of 232 // |buffer_|. 233 RefCountedBufferPtr output_frame_; 234 235 // Queue of output frames that are to be returned in the DequeueFrame() calls. 236 // If |settings_.output_all_layers| is false, this queue will never contain 237 // more than 1 element. This queue is used only when |is_frame_parallel_| is 238 // false. 239 Queue<RefCountedBufferPtr> output_frame_queue_; 240 241 BufferPool buffer_pool_; 242 WedgeMaskArray wedge_masks_; 243 bool wedge_masks_initialized_ = false; 244 QuantizerMatrix quantizer_matrix_; 245 bool quantizer_matrix_initialized_ = false; 246 FrameScratchBufferPool frame_scratch_buffer_pool_; 247 248 // Used to synchronize the accesses into |temporal_units_| in order to update 249 // the "decoded" state of a temporal unit. 250 std::mutex mutex_; 251 std::condition_variable decoded_condvar_; 252 bool is_frame_parallel_; 253 std::unique_ptr<ThreadPool> frame_thread_pool_; 254 255 // In frame parallel mode, there are two primary points of failure: 256 // 1) ParseAndSchedule() 257 // 2) DecodeTiles() 258 // Both of these functions have to respond to the other one failing by 259 // aborting whatever they are doing. This variable is used to accomplish that. 260 // If |failure_status_| is not kStatusOk, then the two functions will try to 261 // abort as early as they can. 262 StatusCode failure_status_ = kStatusOk LIBGAV1_GUARDED_BY(mutex_); 263 264 ObuSequenceHeader sequence_header_ = {}; 265 // If true, sequence_header is valid. 266 bool has_sequence_header_ = false; 267 268 const DecoderSettings& settings_; 269 bool seen_first_frame_ = false; 270 271 std::vector<int> frame_mean_qps_; 272 int frame_mean_qp_ = 0; 273 }; 274 275 } // namespace libgav1 276 277 #endif // LIBGAV1_SRC_DECODER_IMPL_H_ 278