/src/libde265/libde265/decctx.h
Line | Count | Source |
1 | | /* |
2 | | * H.265 video codec. |
3 | | * Copyright (c) 2013-2014 struktur AG, Dirk Farin <farin@struktur.de> |
4 | | * |
5 | | * This file is part of libde265. |
6 | | * |
7 | | * libde265 is free software: you can redistribute it and/or modify |
8 | | * it under the terms of the GNU Lesser General Public License as |
9 | | * published by the Free Software Foundation, either version 3 of |
10 | | * the License, or (at your option) any later version. |
11 | | * |
12 | | * libde265 is distributed in the hope that it will be useful, |
13 | | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
14 | | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
15 | | * GNU Lesser General Public License for more details. |
16 | | * |
17 | | * You should have received a copy of the GNU Lesser General Public License |
18 | | * along with libde265. If not, see <http://www.gnu.org/licenses/>. |
19 | | */ |
20 | | |
21 | | #ifndef DE265_DECCTX_H |
22 | | #define DE265_DECCTX_H |
23 | | |
24 | | #include "libde265/vps.h" |
25 | | #include "libde265/sps.h" |
26 | | #include "libde265/pps.h" |
27 | | #include "libde265/nal.h" |
28 | | #include "libde265/slice.h" |
29 | | #include "libde265/image.h" |
30 | | #include "libde265/motion.h" |
31 | | #include "libde265/de265.h" |
32 | | #include "libde265/dpb.h" |
33 | | #include "libde265/sei.h" |
34 | | #include "libde265/threads.h" |
35 | | #include "libde265/acceleration.h" |
36 | | #include "libde265/nal-parser.h" |
37 | | |
38 | | #include <memory> |
39 | | |
40 | | constexpr int DE265_MAX_VPS_SETS = 16; // this is the maximum as defined in the standard |
41 | | constexpr int DE265_MAX_SPS_SETS = 16; // this is the maximum as defined in the standard |
42 | | constexpr int DE265_MAX_PPS_SETS = 64; // this is the maximum as defined in the standard |
43 | | |
44 | | constexpr int MAX_WARNINGS = 20; |
45 | | |
46 | | |
47 | | class slice_segment_header; |
48 | | class image_unit; |
49 | | class slice_unit; |
50 | | class decoder_context; |
51 | | |
52 | | |
53 | | class thread_context |
54 | | { |
55 | | public: |
56 | | thread_context(); |
57 | | |
58 | | uint32_t CtbAddrInRS; |
59 | | uint32_t CtbAddrInTS; |
60 | | |
61 | | uint16_t CtbX, CtbY; |
62 | | |
63 | | |
64 | | // motion vectors |
65 | | |
66 | | PBMotionCoding motion; |
67 | | |
68 | | |
69 | | // prediction |
70 | | |
71 | | // enum IntraPredMode IntraPredModeC[4]; // chroma intra-prediction mode for current CB |
72 | | int ResScaleVal; |
73 | | |
74 | | |
75 | | // residual data |
76 | | |
77 | | uint8_t cu_transquant_bypass_flag; |
78 | | uint8_t transform_skip_flag[3]; |
79 | | uint8_t explicit_rdpcm_flag; |
80 | | uint8_t explicit_rdpcm_dir; |
81 | | |
82 | | // we need 16 bytes of extra memory (8*int16) to shift the base for the |
83 | | // alignment required for SSE code ! |
84 | | int16_t _coeffBuf[(32*32)+8]; |
85 | | int16_t *coeffBuf; // the base pointer for into _coeffBuf, aligned to 16 bytes |
86 | | |
87 | | int16_t coeffList[3][32*32]; |
88 | | int16_t coeffPos[3][32*32]; |
89 | | int16_t nCoeff[3]; |
90 | | |
91 | | int32_t residual_luma[32*32]; // only used when cross-comp-prediction is enabled |
92 | | |
93 | | |
94 | | // quantization |
95 | | |
96 | | int IsCuQpDeltaCoded = 0; |
97 | | int CuQpDelta = 0; |
98 | | int IsCuChromaQpOffsetCoded = 0; |
99 | | int CuQpOffsetCb = 0, CuQpOffsetCr = 0; |
100 | | |
101 | | int currentQPY; |
102 | | int currentQG_x, currentQG_y; |
103 | | int lastQPYinPreviousQG; |
104 | | |
105 | | int qPYPrime, qPCbPrime, qPCrPrime; |
106 | | |
107 | | CABAC_decoder cabac_decoder; |
108 | | |
109 | | context_model_table ctx_model; |
110 | | uint8_t StatCoeff[4]; |
111 | | |
112 | | decoder_context* decctx = nullptr; |
113 | | struct de265_image *img = nullptr; |
114 | | slice_segment_header* shdr = nullptr; |
115 | | |
116 | | image_unit* imgunit = nullptr; |
117 | | slice_unit* sliceunit = nullptr; |
118 | | thread_task* task; // executing thread_task or nullptr if not multi-threaded |
119 | | |
120 | | thread_context(const thread_context&) = delete; |
121 | | thread_context& operator=(const thread_context&) = delete; |
122 | | }; |
123 | | |
124 | | |
125 | | |
126 | | class error_queue |
127 | | { |
128 | | public: |
129 | | void add_warning(de265_error warning, bool once); |
130 | | de265_error get_warning(); |
131 | | |
132 | | private: |
133 | | std::mutex m_mutex; |
134 | | std::vector<de265_error> warnings; |
135 | | std::vector<de265_error> warnings_shown; // warnings that have already occurred |
136 | | }; |
137 | | |
138 | | |
139 | | |
140 | | class slice_unit |
141 | | { |
142 | | public: |
143 | | slice_unit(decoder_context* decctx); |
144 | | ~slice_unit(); |
145 | | |
146 | | NAL_unit* nal; // we are the owner |
147 | | slice_segment_header* shdr; // not the owner (de265_image is owner) |
148 | | bitreader reader; |
149 | | |
150 | | image_unit* imgunit; |
151 | | |
152 | | bool flush_reorder_buffer; |
153 | | |
154 | | |
155 | | // decoding status |
156 | | |
157 | | enum SliceDecodingProgress { Unprocessed, |
158 | | InProgress, |
159 | | Decoded |
160 | | } state; |
161 | | |
162 | | de265_progress_lock finished_threads; |
163 | | int nThreads; |
164 | | |
165 | | int first_decoded_CTB_RS; // TODO |
166 | | int last_decoded_CTB_RS; // TODO |
167 | | |
168 | | void allocate_thread_contexts(int n); |
169 | 5.64k | thread_context* get_thread_context(int n) { |
170 | 5.64k | assert(n < nThreadContexts); |
171 | 5.64k | return &thread_contexts[n]; |
172 | 5.64k | } |
173 | 0 | int num_thread_contexts() const { return nThreadContexts; } |
174 | | |
175 | | private: |
176 | | thread_context* thread_contexts; /* NOTE: cannot use std::vector, because thread_context has |
177 | | no copy constructor. */ |
178 | | int nThreadContexts; |
179 | | |
180 | | public: |
181 | | decoder_context* ctx; |
182 | | |
183 | | slice_unit(const slice_unit&) = delete; |
184 | | slice_unit& operator=(const slice_unit&) = delete; |
185 | | }; |
186 | | |
187 | | |
188 | | class image_unit |
189 | | { |
190 | | public: |
191 | | image_unit(); |
192 | | ~image_unit(); |
193 | | |
194 | | de265_image* img = nullptr; |
195 | | de265_image sao_output; // if SAO is used, this is allocated and used as SAO output buffer |
196 | | |
197 | | std::vector<slice_unit*> slice_units; |
198 | | std::vector<sei_message> suffix_SEIs; |
199 | | |
200 | 6.71k | slice_unit* get_next_unprocessed_slice_segment() const { |
201 | 9.98k | for (size_t i=0;i<slice_units.size();i++) { |
202 | 8.33k | if (slice_units[i]->state == slice_unit::Unprocessed) { |
203 | 5.06k | return slice_units[i]; |
204 | 5.06k | } |
205 | 8.33k | } |
206 | | |
207 | 1.65k | return nullptr; |
208 | 6.71k | } |
209 | | |
210 | 5.25k | slice_unit* get_prev_slice_segment(slice_unit* s) const { |
211 | 5.61k | for (size_t i=1; i<slice_units.size(); i++) { |
212 | 1.32k | if (slice_units[i]==s) { |
213 | 971 | return slice_units[i-1]; |
214 | 971 | } |
215 | 1.32k | } |
216 | | |
217 | 4.28k | return nullptr; |
218 | 5.25k | } |
219 | | |
220 | 5.83k | slice_unit* get_next_slice_segment(slice_unit* s) const { |
221 | 7.02k | for (size_t i=0; i<slice_units.size()-1; i++) { |
222 | 2.00k | if (slice_units[i]==s) { |
223 | 818 | return slice_units[i+1]; |
224 | 818 | } |
225 | 2.00k | } |
226 | | |
227 | 5.01k | return nullptr; |
228 | 5.83k | } |
229 | | |
230 | 0 | void dump_slices() const { |
231 | 0 | for (size_t i=0; i<slice_units.size(); i++) { |
232 | 0 | printf("[%zu] = %p\n",i,static_cast<void*>(slice_units[i])); |
233 | 0 | } |
234 | 0 | } |
235 | | |
236 | 6.40k | bool all_slice_segments_processed() const { |
237 | 6.40k | if (slice_units.size()==0) return true; |
238 | 6.40k | if (slice_units.back()->state != slice_unit::Unprocessed) return true; |
239 | 17 | return false; |
240 | 6.40k | } |
241 | | |
242 | 5.06k | bool is_first_slice_segment(const slice_unit* s) const { |
243 | 5.06k | if (slice_units.size()==0) return false; |
244 | 5.06k | return (slice_units[0] == s); |
245 | 5.06k | } |
246 | | |
247 | | enum { Invalid, // headers not read yet |
248 | | Unknown, // SPS/PPS available |
249 | | Reference, // will be used as reference |
250 | | Leaf // not a reference picture |
251 | | } role = Invalid; |
252 | | |
253 | | enum { Unprocessed, |
254 | | InProgress, |
255 | | Decoded, |
256 | | Dropped // will not be decoded |
257 | | } state = Unprocessed; |
258 | | |
259 | | std::vector<thread_task*> tasks; // we are the owner |
260 | | |
261 | | /* Saved context models for WPP. |
262 | | There is one saved model for the initialization of each CTB row. |
263 | | The array is unused for non-WPP streams. */ |
264 | | std::vector<context_model_table> ctx_models; // TODO: move this into image ? |
265 | | }; |
266 | | |
267 | | |
268 | | class base_context : public error_queue |
269 | | { |
270 | | public: |
271 | | base_context(); |
272 | 5.68k | virtual ~base_context() { } |
273 | | |
274 | | // --- accelerated DSP functions --- |
275 | | |
276 | | void set_acceleration_functions(enum de265_acceleration); |
277 | | |
278 | | struct acceleration_functions acceleration; // CPU optimized functions |
279 | | |
280 | | //virtual /* */ de265_image* get_image(uint16_t dpb_index) { return dpb.get_image(dpb_index); } |
281 | | virtual const de265_image* get_image(uint16_t frame_id) const = 0; |
282 | | virtual bool has_image(uint16_t frame_id) const = 0; |
283 | | }; |
284 | | |
285 | | |
286 | | class decoder_context : public base_context { |
287 | | public: |
288 | | decoder_context(); |
289 | | ~decoder_context(); |
290 | | |
291 | | de265_error start_thread_pool(int nThreads); |
292 | | void stop_thread_pool(); |
293 | | |
294 | | void reset(); |
295 | | |
296 | 5.13k | bool has_sps(int id) const { return sps[id] != nullptr; } |
297 | 8.97k | bool has_pps(int id) const { return pps[id] != nullptr; } |
298 | | |
299 | 4.50k | std::shared_ptr<const seq_parameter_set> get_shared_sps(int id) { return sps[id]; } |
300 | 7.67k | std::shared_ptr<const pic_parameter_set> get_shared_pps(int id) { return pps[id]; } |
301 | | |
302 | 942 | /* */ seq_parameter_set* get_sps(int id) { return sps[id].get(); } |
303 | 0 | const seq_parameter_set* get_sps(int id) const { return sps[id].get(); } |
304 | 662 | /* */ pic_parameter_set* get_pps(int id) { return pps[id].get(); } |
305 | 0 | const pic_parameter_set* get_pps(int id) const { return pps[id].get(); } |
306 | | |
307 | | /* |
308 | | const slice_segment_header* get_SliceHeader_atCtb(int ctb) { |
309 | | return img->slices[img->get_SliceHeaderIndex_atIndex(ctb)]; |
310 | | } |
311 | | */ |
312 | | |
313 | 13.5k | uint8_t get_nal_unit_type() const { return nal_unit_type; } |
314 | 9.01k | bool get_RapPicFlag() const { return RapPicFlag; } |
315 | | |
316 | | de265_error decode_NAL(NAL_unit* nal); |
317 | | |
318 | | de265_error decode(int* more); |
319 | | de265_error decode_some(bool* did_work); |
320 | | |
321 | | de265_error decode_slice_unit_sequential(image_unit* imgunit, slice_unit* sliceunit); |
322 | | de265_error decode_slice_unit_parallel(image_unit* imgunit, slice_unit* sliceunit); |
323 | | de265_error decode_slice_unit_WPP(image_unit* imgunit, slice_unit* sliceunit); |
324 | | de265_error decode_slice_unit_tiles(image_unit* imgunit, slice_unit* sliceunit); |
325 | | |
326 | | |
327 | | void process_nal_hdr(nal_header*); |
328 | | |
329 | | bool process_slice_segment_header(slice_segment_header*, |
330 | | de265_error*, de265_PTS pts, |
331 | | nal_header* nal_hdr, void* user_data); |
332 | | |
333 | | //void push_current_picture_to_output_queue(); |
334 | | de265_error push_picture_to_output_queue(image_unit*); |
335 | | |
336 | | |
337 | | // --- parameters --- |
338 | | |
339 | | bool param_sei_check_hash = false; |
340 | | bool param_conceal_stream_errors = true; |
341 | | bool param_suppress_faulty_pictures = false; |
342 | | |
343 | | int param_sps_headers_fd = -1; |
344 | | int param_vps_headers_fd = -1; |
345 | | int param_pps_headers_fd = -1; |
346 | | int param_slice_headers_fd = -1; |
347 | | |
348 | | bool param_disable_deblocking = false; |
349 | | bool param_disable_sao = false; |
350 | | //bool param_disable_mc_residual_idct; // not implemented yet |
351 | | //bool param_disable_intra_residual_idct; // not implemented yet |
352 | | |
353 | | void set_image_allocation_functions(de265_image_allocation* allocfunc, void* userdata); |
354 | | |
355 | | de265_image_allocation param_image_allocation_functions; // initialized in constructor |
356 | | void* param_image_allocation_userdata = nullptr; |
357 | | |
358 | | |
359 | | // --- input stream data --- |
360 | | |
361 | | NAL_Parser nal_parser; |
362 | | |
363 | | |
364 | 5.68k | int get_num_worker_threads() const { return num_worker_threads; } |
365 | | |
366 | 0 | /* */ de265_image* get_image(uint16_t dpb_index) { return dpb.get_image(dpb_index); } |
367 | 1.21M | const de265_image* get_image(uint16_t dpb_index) const override { return dpb.get_image(dpb_index); } |
368 | | |
369 | 65.5k | bool has_image(uint16_t dpb_index) const override { return dpb_index<dpb.size(); } |
370 | | |
371 | 8.23k | de265_image* get_next_picture_in_output_queue() { return dpb.get_next_picture_in_output_queue(); } |
372 | 88.0k | int num_pictures_in_output_queue() const { return dpb.num_pictures_in_output_queue(); } |
373 | 4.13k | void pop_next_picture_in_output_queue() { dpb.pop_next_picture_in_output_queue(); } |
374 | | |
375 | | private: |
376 | | de265_error read_vps_NAL(bitreader&); |
377 | | de265_error read_sps_NAL(bitreader&); |
378 | | de265_error read_pps_NAL(bitreader&); |
379 | | de265_error read_sei_NAL(bitreader& reader, bool suffix); |
380 | | de265_error read_eos_NAL(bitreader& reader); |
381 | | de265_error read_slice_NAL(bitreader&, NAL_unit* nal, nal_header& nal_hdr); |
382 | | |
383 | | private: |
384 | | // --- internal data --- |
385 | | |
386 | | std::shared_ptr<video_parameter_set> vps[ DE265_MAX_VPS_SETS ]; |
387 | | std::shared_ptr<seq_parameter_set> sps[ DE265_MAX_SPS_SETS ]; |
388 | | std::shared_ptr<pic_parameter_set> pps[ DE265_MAX_PPS_SETS ]; |
389 | | |
390 | | std::shared_ptr<video_parameter_set> current_vps; |
391 | | std::shared_ptr<seq_parameter_set> current_sps; |
392 | | std::shared_ptr<pic_parameter_set> current_pps; |
393 | | |
394 | | public: |
395 | | thread_pool thread_pool_; |
396 | | |
397 | | private: |
398 | | int num_worker_threads = 0; |
399 | | |
400 | | |
401 | | public: |
402 | | // --- frame dropping --- |
403 | | |
404 | | void set_limit_TID(int tid); |
405 | | int get_highest_TID() const; |
406 | 0 | int get_current_TID() const { return current_HighestTid; } |
407 | | int change_framerate(int more_vs_less); // 1: more, -1: less |
408 | | void set_framerate_ratio(int percent); |
409 | | |
410 | | private: |
411 | | // input parameters |
412 | | int limit_HighestTid = 6; // never switch to a layer above this one |
413 | | int framerate_ratio = 100; |
414 | | |
415 | | // current control parameters |
416 | | int goal_HighestTid = 6; // this is the layer we want to decode at |
417 | | int layer_framerate_ratio = 100; // ratio of frames to keep in the current layer |
418 | | |
419 | | int current_HighestTid = 6; // the layer which we are currently decoding |
420 | | |
421 | | struct { |
422 | | int8_t tid; |
423 | | int8_t ratio; |
424 | | } framedrop_tab[100+1]; |
425 | | int framedrop_tid_index[6+1]; |
426 | | |
427 | | void compute_framedrop_table(); |
428 | | void calc_tid_and_framerate_ratio(); |
429 | | |
430 | | private: |
431 | | // --- decoded picture buffer --- |
432 | | |
433 | | decoded_picture_buffer dpb; |
434 | | |
435 | | int current_image_poc_lsb = -1; |
436 | | bool first_decoded_picture = true; |
437 | | bool NoRaslOutputFlag = false; |
438 | | bool HandleCraAsBlaFlag = false; |
439 | | bool FirstAfterEndOfSequenceNAL = false; |
440 | | |
441 | | int PicOrderCntMsb = 0; |
442 | | int prevPicOrderCntLsb = 0; // at precTid0Pic |
443 | | int prevPicOrderCntMsb = 0; // at precTid0Pic |
444 | | |
445 | | de265_image* img = nullptr; |
446 | | |
447 | | public: |
448 | | const slice_segment_header* previous_slice_header = nullptr; /* Remember the last slice for a successive |
449 | | dependent slice. */ |
450 | | |
451 | | |
452 | | // --- motion compensation --- |
453 | | |
454 | | public: |
455 | | int PocLsbLt[MAX_NUM_REF_PICS]{}; |
456 | | int UsedByCurrPicLt[MAX_NUM_REF_PICS]{}; |
457 | | uint32_t DeltaPocMsbCycleLt[MAX_NUM_REF_PICS]{}; |
458 | | private: |
459 | | int CurrDeltaPocMsbPresentFlag[MAX_NUM_REF_PICS]{}; |
460 | | int FollDeltaPocMsbPresentFlag[MAX_NUM_REF_PICS]{}; |
461 | | |
462 | | // The number of entries in the lists below. |
463 | | int NumPocStCurrBefore = 0; |
464 | | int NumPocStCurrAfter = 0; |
465 | | int NumPocStFoll = 0; |
466 | | int NumPocLtCurr = 0; |
467 | | int NumPocLtFoll = 0; |
468 | | |
469 | | // These lists contain absolute POC values. |
470 | | int PocStCurrBefore[MAX_NUM_REF_PICS]{}; // used for reference in current picture, smaller POC |
471 | | int PocStCurrAfter[MAX_NUM_REF_PICS]{}; // used for reference in current picture, larger POC |
472 | | int PocStFoll[MAX_NUM_REF_PICS]{}; // not used for reference in current picture, but in future picture |
473 | | int PocLtCurr[MAX_NUM_REF_PICS]{}; // used in current picture |
474 | | int PocLtFoll[MAX_NUM_REF_PICS]{}; // used in some future picture |
475 | | |
476 | | // These lists contain indices into the DPB. |
477 | | int RefPicSetStCurrBefore[MAX_NUM_REF_PICS]{}; |
478 | | int RefPicSetStCurrAfter[MAX_NUM_REF_PICS]{}; |
479 | | int RefPicSetStFoll[MAX_NUM_REF_PICS]{}; |
480 | | int RefPicSetLtCurr[MAX_NUM_REF_PICS]{}; |
481 | | int RefPicSetLtFoll[MAX_NUM_REF_PICS]{}; |
482 | | |
483 | | |
484 | | // --- parameters derived from parameter sets --- |
485 | | |
486 | | // NAL |
487 | | |
488 | | uint8_t nal_unit_type = 0; |
489 | | |
490 | | bool IdrPicFlag = false; |
491 | | bool RapPicFlag = false; |
492 | | |
493 | | |
494 | | // --- image unit queue --- |
495 | | |
496 | | std::vector<image_unit*> image_units; |
497 | | |
498 | | bool flush_reorder_buffer_at_this_frame = false; |
499 | | |
500 | | private: |
501 | | void init_thread_context(thread_context* tctx); |
502 | | void add_task_decode_CTB_row(thread_context* tctx, bool firstSliceSubstream, int ctbRow); |
503 | | void add_task_decode_slice_segment(thread_context* tctx, bool firstSliceSubstream, |
504 | | int ctbX,int ctbY); |
505 | | |
506 | | void mark_whole_slice_as_processed(image_unit* imgunit, |
507 | | slice_unit* sliceunit, |
508 | | int progress); |
509 | | |
510 | | void process_picture_order_count(slice_segment_header* hdr); |
511 | | |
512 | | /* |
513 | | If there is no space for a new image, returns the negative value of an de265_error. |
514 | | I.e. you can check for error by return_value<0, which is error (-return_value); |
515 | | */ |
516 | | int generate_unavailable_reference_picture(const seq_parameter_set* sps, |
517 | | int POC, bool longTerm); |
518 | | de265_error process_reference_picture_set(slice_segment_header* hdr); |
519 | | bool construct_reference_picture_lists(slice_segment_header* hdr); |
520 | | |
521 | | |
522 | | void remove_images_from_dpb(const std::vector<int>& removeImageList); |
523 | | void run_postprocessing_filters_sequential(struct de265_image* img); |
524 | | void run_postprocessing_filters_parallel(image_unit* img); |
525 | | }; |
526 | | |
527 | | |
528 | | #endif |