• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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