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