/src/libde265/libde265/decctx.h
Line | Count | Source (jump to first uncovered line) |
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 | 1.77k | #define DE265_MAX_VPS_SETS 16 // this is the maximum as defined in the standard |
41 | 12.5k | #define DE265_MAX_SPS_SETS 16 // this is the maximum as defined in the standard |
42 | 16.9k | #define DE265_MAX_PPS_SETS 64 // this is the maximum as defined in the standard |
43 | | |
44 | 17.5k | #define 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 | | int CtbAddrInRS; |
59 | | int CtbAddrInTS; |
60 | | |
61 | | int 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; |
97 | | int CuQpDelta; |
98 | | int IsCuChromaQpOffsetCoded; |
99 | | int CuQpOffsetCb, CuQpOffsetCr; |
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; |
113 | | struct de265_image *img; |
114 | | slice_segment_header* shdr; |
115 | | |
116 | | image_unit* imgunit; |
117 | | slice_unit* sliceunit; |
118 | | thread_task* task; // executing thread_task or NULL if not multi-threaded |
119 | | |
120 | | private: |
121 | | thread_context(const thread_context&); // not allowed |
122 | | const thread_context& operator=(const thread_context&); // not allowed |
123 | | }; |
124 | | |
125 | | |
126 | | |
127 | | class error_queue |
128 | | { |
129 | | public: |
130 | | error_queue(); |
131 | | |
132 | | void add_warning(de265_error warning, bool once); |
133 | | de265_error get_warning(); |
134 | | |
135 | | private: |
136 | | de265_error warnings[MAX_WARNINGS]; |
137 | | int nWarnings; |
138 | | de265_error warnings_shown[MAX_WARNINGS]; // warnings that have already occurred |
139 | | int nWarningsShown; |
140 | | }; |
141 | | |
142 | | |
143 | | |
144 | | class slice_unit |
145 | | { |
146 | | public: |
147 | | slice_unit(decoder_context* decctx); |
148 | | ~slice_unit(); |
149 | | |
150 | | NAL_unit* nal; // we are the owner |
151 | | slice_segment_header* shdr; // not the owner (de265_image is owner) |
152 | | bitreader reader; |
153 | | |
154 | | image_unit* imgunit; |
155 | | |
156 | | bool flush_reorder_buffer; |
157 | | |
158 | | |
159 | | // decoding status |
160 | | |
161 | | enum SliceDecodingProgress { Unprocessed, |
162 | | InProgress, |
163 | | Decoded |
164 | | } state; |
165 | | |
166 | | de265_progress_lock finished_threads; |
167 | | int nThreads; |
168 | | |
169 | | int first_decoded_CTB_RS; // TODO |
170 | | int last_decoded_CTB_RS; // TODO |
171 | | |
172 | | void allocate_thread_contexts(int n); |
173 | 8.13k | thread_context* get_thread_context(int n) { |
174 | 8.13k | assert(n < nThreadContexts); |
175 | 8.13k | return &thread_contexts[n]; |
176 | 8.13k | } |
177 | 0 | int num_thread_contexts() const { return nThreadContexts; } |
178 | | |
179 | | private: |
180 | | thread_context* thread_contexts; /* NOTE: cannot use std::vector, because thread_context has |
181 | | no copy constructor. */ |
182 | | int nThreadContexts; |
183 | | |
184 | | public: |
185 | | decoder_context* ctx; |
186 | | |
187 | | private: |
188 | | slice_unit(const slice_unit&); // not allowed |
189 | | const slice_unit& operator=(const slice_unit&); // not allowed |
190 | | }; |
191 | | |
192 | | |
193 | | class image_unit |
194 | | { |
195 | | public: |
196 | | image_unit(); |
197 | | ~image_unit(); |
198 | | |
199 | | de265_image* img; |
200 | | de265_image sao_output; // if SAO is used, this is allocated and used as SAO output buffer |
201 | | |
202 | | std::vector<slice_unit*> slice_units; |
203 | | std::vector<sei_message> suffix_SEIs; |
204 | | |
205 | 4.10k | slice_unit* get_next_unprocessed_slice_segment() const { |
206 | 4.44k | for (size_t i=0;i<slice_units.size();i++) { |
207 | 4.34k | if (slice_units[i]->state == slice_unit::Unprocessed) { |
208 | 4.00k | return slice_units[i]; |
209 | 4.00k | } |
210 | 4.34k | } |
211 | | |
212 | 106 | return NULL; |
213 | 4.10k | } |
214 | | |
215 | 4.03k | slice_unit* get_prev_slice_segment(slice_unit* s) const { |
216 | 4.09k | for (size_t i=1; i<slice_units.size(); i++) { |
217 | 239 | if (slice_units[i]==s) { |
218 | 178 | return slice_units[i-1]; |
219 | 178 | } |
220 | 239 | } |
221 | | |
222 | 3.85k | return NULL; |
223 | 4.03k | } |
224 | | |
225 | 4.13k | slice_unit* get_next_slice_segment(slice_unit* s) const { |
226 | 4.37k | for (size_t i=0; i<slice_units.size()-1; i++) { |
227 | 394 | if (slice_units[i]==s) { |
228 | 154 | return slice_units[i+1]; |
229 | 154 | } |
230 | 394 | } |
231 | | |
232 | 3.98k | return NULL; |
233 | 4.13k | } |
234 | | |
235 | 0 | void dump_slices() const { |
236 | 0 | for (size_t i=0; i<slice_units.size(); i++) { |
237 | 0 | printf("[%zu] = %p\n",i,slice_units[i]); |
238 | 0 | } |
239 | 0 | } |
240 | | |
241 | 4.03k | bool all_slice_segments_processed() const { |
242 | 4.03k | if (slice_units.size()==0) return true; |
243 | 4.03k | if (slice_units.back()->state != slice_unit::Unprocessed) return true; |
244 | 5 | return false; |
245 | 4.03k | } |
246 | | |
247 | 4.00k | bool is_first_slice_segment(const slice_unit* s) const { |
248 | 4.00k | if (slice_units.size()==0) return false; |
249 | 4.00k | return (slice_units[0] == s); |
250 | 4.00k | } |
251 | | |
252 | | enum { Invalid, // headers not read yet |
253 | | Unknown, // SPS/PPS available |
254 | | Reference, // will be used as reference |
255 | | Leaf // not a reference picture |
256 | | } role; |
257 | | |
258 | | enum { Unprocessed, |
259 | | InProgress, |
260 | | Decoded, |
261 | | Dropped // will not be decoded |
262 | | } state; |
263 | | |
264 | | std::vector<thread_task*> tasks; // we are the owner |
265 | | |
266 | | /* Saved context models for WPP. |
267 | | There is one saved model for the initialization of each CTB row. |
268 | | The array is unused for non-WPP streams. */ |
269 | | std::vector<context_model_table> ctx_models; // TODO: move this into image ? |
270 | | }; |
271 | | |
272 | | |
273 | | class base_context : public error_queue |
274 | | { |
275 | | public: |
276 | | base_context(); |
277 | 4.52k | virtual ~base_context() { } |
278 | | |
279 | | // --- accelerated DSP functions --- |
280 | | |
281 | | void set_acceleration_functions(enum de265_acceleration); |
282 | | |
283 | | struct acceleration_functions acceleration; // CPU optimized functions |
284 | | |
285 | | //virtual /* */ de265_image* get_image(int dpb_index) { return dpb.get_image(dpb_index); } |
286 | | virtual const de265_image* get_image(int frame_id) const = 0; |
287 | | virtual bool has_image(int frame_id) const = 0; |
288 | | }; |
289 | | |
290 | | |
291 | | class decoder_context : public base_context { |
292 | | public: |
293 | | decoder_context(); |
294 | | ~decoder_context(); |
295 | | |
296 | | de265_error start_thread_pool(int nThreads); |
297 | | void stop_thread_pool(); |
298 | | |
299 | | void reset(); |
300 | | |
301 | 4.10k | bool has_sps(int id) const { return (bool)sps[id]; } |
302 | 4.35k | bool has_pps(int id) const { return (bool)pps[id]; } |
303 | | |
304 | 4.09k | std::shared_ptr<const seq_parameter_set> get_shared_sps(int id) { return sps[id]; } |
305 | 4.18k | std::shared_ptr<const pic_parameter_set> get_shared_pps(int id) { return pps[id]; } |
306 | | |
307 | 358 | /* */ seq_parameter_set* get_sps(int id) { return sps[id].get(); } |
308 | 0 | const seq_parameter_set* get_sps(int id) const { return sps[id].get(); } |
309 | 338 | /* */ pic_parameter_set* get_pps(int id) { return pps[id].get(); } |
310 | 0 | const pic_parameter_set* get_pps(int id) const { return pps[id].get(); } |
311 | | |
312 | | /* |
313 | | const slice_segment_header* get_SliceHeader_atCtb(int ctb) { |
314 | | return img->slices[img->get_SliceHeaderIndex_atIndex(ctb)]; |
315 | | } |
316 | | */ |
317 | | |
318 | 8.21k | uint8_t get_nal_unit_type() const { return nal_unit_type; } |
319 | 4.36k | bool get_RapPicFlag() const { return RapPicFlag; } |
320 | | |
321 | | de265_error decode_NAL(NAL_unit* nal); |
322 | | |
323 | | de265_error decode(int* more); |
324 | | de265_error decode_some(bool* did_work); |
325 | | |
326 | | de265_error decode_slice_unit_sequential(image_unit* imgunit, slice_unit* sliceunit); |
327 | | de265_error decode_slice_unit_parallel(image_unit* imgunit, slice_unit* sliceunit); |
328 | | de265_error decode_slice_unit_WPP(image_unit* imgunit, slice_unit* sliceunit); |
329 | | de265_error decode_slice_unit_tiles(image_unit* imgunit, slice_unit* sliceunit); |
330 | | |
331 | | |
332 | | void process_nal_hdr(nal_header*); |
333 | | |
334 | | bool process_slice_segment_header(slice_segment_header*, |
335 | | de265_error*, de265_PTS pts, |
336 | | nal_header* nal_hdr, void* user_data); |
337 | | |
338 | | //void push_current_picture_to_output_queue(); |
339 | | de265_error push_picture_to_output_queue(image_unit*); |
340 | | |
341 | | |
342 | | // --- parameters --- |
343 | | |
344 | | bool param_sei_check_hash; |
345 | | bool param_conceal_stream_errors; |
346 | | bool param_suppress_faulty_pictures; |
347 | | |
348 | | int param_sps_headers_fd; |
349 | | int param_vps_headers_fd; |
350 | | int param_pps_headers_fd; |
351 | | int param_slice_headers_fd; |
352 | | |
353 | | bool param_disable_deblocking; |
354 | | bool param_disable_sao; |
355 | | //bool param_disable_mc_residual_idct; // not implemented yet |
356 | | //bool param_disable_intra_residual_idct; // not implemented yet |
357 | | |
358 | | void set_image_allocation_functions(de265_image_allocation* allocfunc, void* userdata); |
359 | | |
360 | | de265_image_allocation param_image_allocation_functions; |
361 | | void* param_image_allocation_userdata; |
362 | | |
363 | | |
364 | | // --- input stream data --- |
365 | | |
366 | | NAL_Parser nal_parser; |
367 | | |
368 | | |
369 | 4.52k | int get_num_worker_threads() const { return num_worker_threads; } |
370 | | |
371 | 0 | /* */ de265_image* get_image(int dpb_index) { return dpb.get_image(dpb_index); } |
372 | 11.1M | const de265_image* get_image(int dpb_index) const { return dpb.get_image(dpb_index); } |
373 | | |
374 | 1.67M | bool has_image(int dpb_index) const { return dpb_index>=0 && dpb_index<dpb.size(); } |
375 | | |
376 | 5.97k | de265_image* get_next_picture_in_output_queue() { return dpb.get_next_picture_in_output_queue(); } |
377 | 28.1k | int num_pictures_in_output_queue() const { return dpb.num_pictures_in_output_queue(); } |
378 | 2.99k | void pop_next_picture_in_output_queue() { dpb.pop_next_picture_in_output_queue(); } |
379 | | |
380 | | private: |
381 | | de265_error read_vps_NAL(bitreader&); |
382 | | de265_error read_sps_NAL(bitreader&); |
383 | | de265_error read_pps_NAL(bitreader&); |
384 | | de265_error read_sei_NAL(bitreader& reader, bool suffix); |
385 | | de265_error read_eos_NAL(bitreader& reader); |
386 | | de265_error read_slice_NAL(bitreader&, NAL_unit* nal, nal_header& nal_hdr); |
387 | | |
388 | | private: |
389 | | // --- internal data --- |
390 | | |
391 | | std::shared_ptr<video_parameter_set> vps[ DE265_MAX_VPS_SETS ]; |
392 | | std::shared_ptr<seq_parameter_set> sps[ DE265_MAX_SPS_SETS ]; |
393 | | std::shared_ptr<pic_parameter_set> pps[ DE265_MAX_PPS_SETS ]; |
394 | | |
395 | | std::shared_ptr<video_parameter_set> current_vps; |
396 | | std::shared_ptr<seq_parameter_set> current_sps; |
397 | | std::shared_ptr<pic_parameter_set> current_pps; |
398 | | |
399 | | public: |
400 | | thread_pool thread_pool_; |
401 | | |
402 | | private: |
403 | | int num_worker_threads; |
404 | | |
405 | | |
406 | | public: |
407 | | // --- frame dropping --- |
408 | | |
409 | | void set_limit_TID(int tid); |
410 | | int get_highest_TID() const; |
411 | 0 | int get_current_TID() const { return current_HighestTid; } |
412 | | int change_framerate(int more_vs_less); // 1: more, -1: less |
413 | | void set_framerate_ratio(int percent); |
414 | | |
415 | | private: |
416 | | // input parameters |
417 | | int limit_HighestTid; // never switch to a layer above this one |
418 | | int framerate_ratio; |
419 | | |
420 | | // current control parameters |
421 | | int goal_HighestTid; // this is the layer we want to decode at |
422 | | int layer_framerate_ratio; // ratio of frames to keep in the current layer |
423 | | |
424 | | int current_HighestTid; // the layer which we are currently decoding |
425 | | |
426 | | struct { |
427 | | int8_t tid; |
428 | | int8_t ratio; |
429 | | } framedrop_tab[100+1]; |
430 | | int framedrop_tid_index[6+1]; |
431 | | |
432 | | void compute_framedrop_table(); |
433 | | void calc_tid_and_framerate_ratio(); |
434 | | |
435 | | private: |
436 | | // --- decoded picture buffer --- |
437 | | |
438 | | decoded_picture_buffer dpb; |
439 | | |
440 | | int current_image_poc_lsb; |
441 | | bool first_decoded_picture; |
442 | | bool NoRaslOutputFlag; |
443 | | bool HandleCraAsBlaFlag; |
444 | | bool FirstAfterEndOfSequenceNAL; |
445 | | |
446 | | int PicOrderCntMsb; |
447 | | int prevPicOrderCntLsb; // at precTid0Pic |
448 | | int prevPicOrderCntMsb; // at precTid0Pic |
449 | | |
450 | | de265_image* img; |
451 | | |
452 | | public: |
453 | | const slice_segment_header* previous_slice_header; /* Remember the last slice for a successive |
454 | | dependent slice. */ |
455 | | |
456 | | |
457 | | // --- motion compensation --- |
458 | | |
459 | | public: |
460 | | int PocLsbLt[MAX_NUM_REF_PICS]; |
461 | | int UsedByCurrPicLt[MAX_NUM_REF_PICS]; |
462 | | int DeltaPocMsbCycleLt[MAX_NUM_REF_PICS]; |
463 | | private: |
464 | | int CurrDeltaPocMsbPresentFlag[MAX_NUM_REF_PICS]; |
465 | | int FollDeltaPocMsbPresentFlag[MAX_NUM_REF_PICS]; |
466 | | |
467 | | // The number of entries in the lists below. |
468 | | int NumPocStCurrBefore; |
469 | | int NumPocStCurrAfter; |
470 | | int NumPocStFoll; |
471 | | int NumPocLtCurr; |
472 | | int NumPocLtFoll; |
473 | | |
474 | | // These lists contain absolute POC values. |
475 | | int PocStCurrBefore[MAX_NUM_REF_PICS]; // used for reference in current picture, smaller POC |
476 | | int PocStCurrAfter[MAX_NUM_REF_PICS]; // used for reference in current picture, larger POC |
477 | | int PocStFoll[MAX_NUM_REF_PICS]; // not used for reference in current picture, but in future picture |
478 | | int PocLtCurr[MAX_NUM_REF_PICS]; // used in current picture |
479 | | int PocLtFoll[MAX_NUM_REF_PICS]; // used in some future picture |
480 | | |
481 | | // These lists contain indices into the DPB. |
482 | | int RefPicSetStCurrBefore[MAX_NUM_REF_PICS]; |
483 | | int RefPicSetStCurrAfter[MAX_NUM_REF_PICS]; |
484 | | int RefPicSetStFoll[MAX_NUM_REF_PICS]; |
485 | | int RefPicSetLtCurr[MAX_NUM_REF_PICS]; |
486 | | int RefPicSetLtFoll[MAX_NUM_REF_PICS]; |
487 | | |
488 | | |
489 | | // --- parameters derived from parameter sets --- |
490 | | |
491 | | // NAL |
492 | | |
493 | | uint8_t nal_unit_type; |
494 | | |
495 | | char IdrPicFlag; |
496 | | char RapPicFlag; |
497 | | |
498 | | |
499 | | // --- image unit queue --- |
500 | | |
501 | | std::vector<image_unit*> image_units; |
502 | | |
503 | | bool flush_reorder_buffer_at_this_frame; |
504 | | |
505 | | private: |
506 | | void init_thread_context(thread_context* tctx); |
507 | | void add_task_decode_CTB_row(thread_context* tctx, bool firstSliceSubstream, int ctbRow); |
508 | | void add_task_decode_slice_segment(thread_context* tctx, bool firstSliceSubstream, |
509 | | int ctbX,int ctbY); |
510 | | |
511 | | void mark_whole_slice_as_processed(image_unit* imgunit, |
512 | | slice_unit* sliceunit, |
513 | | int progress); |
514 | | |
515 | | void process_picture_order_count(slice_segment_header* hdr); |
516 | | |
517 | | /* |
518 | | If there is no space for a new image, returns the negative value of an de265_error. |
519 | | I.e. you can check for error by return_value<0, which is error (-return_value); |
520 | | */ |
521 | | int generate_unavailable_reference_picture(const seq_parameter_set* sps, |
522 | | int POC, bool longTerm); |
523 | | de265_error process_reference_picture_set(slice_segment_header* hdr); |
524 | | bool construct_reference_picture_lists(slice_segment_header* hdr); |
525 | | |
526 | | |
527 | | void remove_images_from_dpb(const std::vector<int>& removeImageList); |
528 | | void run_postprocessing_filters_sequential(struct de265_image* img); |
529 | | void run_postprocessing_filters_parallel(image_unit* img); |
530 | | }; |
531 | | |
532 | | |
533 | | #endif |