/src/libde265/libde265/decctx.cc
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 | | #include "decctx.h" |
22 | | #include "util.h" |
23 | | #include "sao.h" |
24 | | #include "sei.h" |
25 | | #include "deblock.h" |
26 | | |
27 | | #include <string.h> |
28 | | #include <assert.h> |
29 | | #include <stdlib.h> |
30 | | #include <stdio.h> |
31 | | #include <math.h> |
32 | | |
33 | | #include "fallback.h" |
34 | | |
35 | | #ifdef HAVE_CONFIG_H |
36 | | #include "config.h" |
37 | | #endif |
38 | | |
39 | | #ifdef HAVE_SSE4_1 |
40 | | #include "x86/sse.h" |
41 | | #endif |
42 | | |
43 | | #ifdef HAVE_ARM |
44 | | #include "arm/arm.h" |
45 | | #endif |
46 | | |
47 | | #define SAVE_INTERMEDIATE_IMAGES 0 |
48 | | |
49 | | #if SAVE_INTERMEDIATE_IMAGES |
50 | | #include "visualize.h" |
51 | | #endif |
52 | | |
53 | | extern void thread_decode_CTB_row(void* d); |
54 | | extern void thread_decode_slice_segment(void* d); |
55 | | |
56 | | |
57 | | thread_context::thread_context() |
58 | 19.7k | { |
59 | | /* |
60 | | CtbAddrInRS = 0; |
61 | | CtbAddrInTS = 0; |
62 | | |
63 | | CtbX = 0; |
64 | | CtbY = 0; |
65 | | */ |
66 | | |
67 | | /* |
68 | | refIdx[0] = refIdx[1] = 0; |
69 | | mvd[0][0] = mvd[0][1] = mvd[1][0] = mvd[1][1] = 0; |
70 | | merge_flag = 0; |
71 | | merge_idx = 0; |
72 | | mvp_lX_flag[0] = mvp_lX_flag[1] = 0; |
73 | | inter_pred_idc = 0; |
74 | | */ |
75 | | |
76 | | /* |
77 | | enum IntraPredMode IntraPredModeC; // chroma intra-prediction mode for current CB |
78 | | */ |
79 | | |
80 | | /* |
81 | | cu_transquant_bypass_flag = false; |
82 | | memset(transform_skip_flag,0, 3*sizeof(uint8_t)); |
83 | | */ |
84 | | |
85 | | |
86 | | //memset(coeffList,0,sizeof(int16_t)*3*32*32); |
87 | | //memset(coeffPos,0,sizeof(int16_t)*3*32*32); |
88 | | //memset(nCoeff,0,sizeof(int16_t)*3); |
89 | | |
90 | | |
91 | | |
92 | 19.7k | IsCuQpDeltaCoded = false; |
93 | 19.7k | CuQpDelta = 0; |
94 | | |
95 | 19.7k | IsCuChromaQpOffsetCoded = false; |
96 | 19.7k | CuQpOffsetCb = 0; |
97 | 19.7k | CuQpOffsetCr = 0; |
98 | | |
99 | | /* |
100 | | currentQPY = 0; |
101 | | currentQG_x = 0; |
102 | | currentQG_y = 0; |
103 | | lastQPYinPreviousQG = 0; |
104 | | */ |
105 | | |
106 | | /* |
107 | | qPYPrime = 0; |
108 | | qPCbPrime = 0; |
109 | | qPCrPrime = 0; |
110 | | */ |
111 | | |
112 | | /* |
113 | | memset(&cabac_decoder, 0, sizeof(CABAC_decoder)); |
114 | | memset(&ctx_model, 0, sizeof(ctx_model)); |
115 | | */ |
116 | | |
117 | 19.7k | decctx = NULL; |
118 | 19.7k | img = NULL; |
119 | 19.7k | shdr = NULL; |
120 | | |
121 | 19.7k | imgunit = NULL; |
122 | 19.7k | sliceunit = NULL; |
123 | | |
124 | | |
125 | | //memset(this,0,sizeof(thread_context)); |
126 | | |
127 | | // There is a interesting issue here. When aligning _coeffBuf to 16 bytes offset with |
128 | | // __attribute__((align(16))), the following statement is optimized away since the |
129 | | // compiler assumes that the pointer would be 16-byte aligned. However, this is not the |
130 | | // case when the structure has been dynamically allocated. In this case, the base can |
131 | | // also be at 8 byte offsets (at least with MingW,32 bit). |
132 | 19.7k | int offset = ((uintptr_t)_coeffBuf) & 0xf; |
133 | | |
134 | 19.7k | if (offset == 0) { |
135 | 0 | coeffBuf = _coeffBuf; // correctly aligned already |
136 | 0 | } |
137 | 19.7k | else { |
138 | 19.7k | coeffBuf = (int16_t *) (((uint8_t *)_coeffBuf) + (16-offset)); |
139 | 19.7k | } |
140 | | |
141 | 19.7k | memset(coeffBuf, 0, 32*32*sizeof(int16_t)); |
142 | 19.7k | } |
143 | | |
144 | | |
145 | | slice_unit::slice_unit(decoder_context* decctx) |
146 | | : nal(NULL), |
147 | | shdr(NULL), |
148 | | imgunit(NULL), |
149 | 7.15k | flush_reorder_buffer(false), |
150 | 7.15k | nThreads(0), |
151 | 7.15k | first_decoded_CTB_RS(-1), |
152 | 7.15k | last_decoded_CTB_RS(-1), |
153 | | thread_contexts(NULL), |
154 | 7.15k | ctx(decctx) |
155 | 7.15k | { |
156 | 7.15k | state = Unprocessed; |
157 | 7.15k | nThreadContexts = 0; |
158 | 7.15k | } |
159 | | |
160 | | slice_unit::~slice_unit() |
161 | 7.15k | { |
162 | 7.15k | ctx->nal_parser.free_NAL_unit(nal); |
163 | | |
164 | 7.15k | if (thread_contexts) { |
165 | 3.03k | delete[] thread_contexts; |
166 | 3.03k | } |
167 | 7.15k | } |
168 | | |
169 | | |
170 | | void slice_unit::allocate_thread_contexts(int n) |
171 | 3.03k | { |
172 | 3.03k | assert(thread_contexts==NULL); |
173 | | |
174 | 3.03k | thread_contexts = new thread_context[n]; |
175 | 3.03k | nThreadContexts = n; |
176 | 3.03k | } |
177 | | |
178 | | |
179 | | image_unit::image_unit() |
180 | 7.04k | { |
181 | 7.04k | img=NULL; |
182 | 7.04k | role=Invalid; |
183 | 7.04k | state=Unprocessed; |
184 | 7.04k | } |
185 | | |
186 | | |
187 | | image_unit::~image_unit() |
188 | 7.04k | { |
189 | 14.2k | for (size_t i=0;i<slice_units.size();i++) { |
190 | 7.15k | delete slice_units[i]; |
191 | 7.15k | } |
192 | | |
193 | 939k | for (size_t i=0;i<tasks.size();i++) { |
194 | 932k | delete tasks[i]; |
195 | 932k | } |
196 | 7.04k | } |
197 | | |
198 | | |
199 | | base_context::base_context() |
200 | 8.80k | { |
201 | 8.80k | set_acceleration_functions(de265_acceleration_AUTO); |
202 | 8.80k | } |
203 | | |
204 | | |
205 | | decoder_context::decoder_context() |
206 | 8.80k | { |
207 | | //memset(ctx, 0, sizeof(decoder_context)); |
208 | | |
209 | | // --- parameters --- |
210 | | |
211 | 8.80k | param_sei_check_hash = false; |
212 | 8.80k | param_conceal_stream_errors = true; |
213 | 8.80k | param_suppress_faulty_pictures = false; |
214 | | |
215 | 8.80k | param_disable_deblocking = false; |
216 | 8.80k | param_disable_sao = false; |
217 | | //param_disable_mc_residual_idct = false; |
218 | | //param_disable_intra_residual_idct = false; |
219 | | |
220 | | // --- processing --- |
221 | | |
222 | 8.80k | param_sps_headers_fd = -1; |
223 | 8.80k | param_vps_headers_fd = -1; |
224 | 8.80k | param_pps_headers_fd = -1; |
225 | 8.80k | param_slice_headers_fd = -1; |
226 | | |
227 | 8.80k | param_image_allocation_functions = de265_image::default_image_allocation; |
228 | 8.80k | param_image_allocation_userdata = NULL; |
229 | | |
230 | | /* |
231 | | memset(&vps, 0, sizeof(video_parameter_set)*DE265_MAX_VPS_SETS); |
232 | | memset(&sps, 0, sizeof(seq_parameter_set) *DE265_MAX_SPS_SETS); |
233 | | memset(&pps, 0, sizeof(pic_parameter_set) *DE265_MAX_PPS_SETS); |
234 | | memset(&slice,0,sizeof(slice_segment_header)*DE265_MAX_SLICES); |
235 | | */ |
236 | | |
237 | 8.80k | current_vps = NULL; |
238 | 8.80k | current_sps = NULL; |
239 | 8.80k | current_pps = NULL; |
240 | | |
241 | | //memset(&thread_pool,0,sizeof(struct thread_pool)); |
242 | 8.80k | num_worker_threads = 0; |
243 | | |
244 | | |
245 | | // frame-rate |
246 | | |
247 | 8.80k | limit_HighestTid = 6; // decode all temporal layers (up to layer 6) |
248 | 8.80k | framerate_ratio = 100; // decode all 100% |
249 | | |
250 | 8.80k | goal_HighestTid = 6; |
251 | 8.80k | current_HighestTid = 6; |
252 | 8.80k | layer_framerate_ratio = 100; |
253 | | |
254 | 8.80k | compute_framedrop_table(); |
255 | | |
256 | | |
257 | | // |
258 | | |
259 | 8.80k | current_image_poc_lsb = 0; |
260 | 8.80k | first_decoded_picture = 0; |
261 | 8.80k | NoRaslOutputFlag = 0; |
262 | 8.80k | HandleCraAsBlaFlag = 0; |
263 | 8.80k | FirstAfterEndOfSequenceNAL = 0; |
264 | 8.80k | PicOrderCntMsb = 0; |
265 | 8.80k | prevPicOrderCntLsb = 0; |
266 | 8.80k | prevPicOrderCntMsb = 0; |
267 | 8.80k | img = NULL; |
268 | 8.80k | previous_slice_header = nullptr; |
269 | | |
270 | | /* |
271 | | int PocLsbLt[MAX_NUM_REF_PICS]; |
272 | | int UsedByCurrPicLt[MAX_NUM_REF_PICS]; |
273 | | int DeltaPocMsbCycleLt[MAX_NUM_REF_PICS]; |
274 | | int CurrDeltaPocMsbPresentFlag[MAX_NUM_REF_PICS]; |
275 | | int FollDeltaPocMsbPresentFlag[MAX_NUM_REF_PICS]; |
276 | | |
277 | | int NumPocStCurrBefore; |
278 | | int NumPocStCurrAfter; |
279 | | int NumPocStFoll; |
280 | | int NumPocLtCurr; |
281 | | int NumPocLtFoll; |
282 | | |
283 | | // These lists contain absolute POC values. |
284 | | int PocStCurrBefore[MAX_NUM_REF_PICS]; // used for reference in current picture, smaller POC |
285 | | int PocStCurrAfter[MAX_NUM_REF_PICS]; // used for reference in current picture, larger POC |
286 | | int PocStFoll[MAX_NUM_REF_PICS]; // not used for reference in current picture, but in future picture |
287 | | int PocLtCurr[MAX_NUM_REF_PICS]; // used in current picture |
288 | | int PocLtFoll[MAX_NUM_REF_PICS]; // used in some future picture |
289 | | |
290 | | // These lists contain indices into the DPB. |
291 | | int RefPicSetStCurrBefore[DE265_DPB_SIZE]; |
292 | | int RefPicSetStCurrAfter[DE265_DPB_SIZE]; |
293 | | int RefPicSetStFoll[DE265_DPB_SIZE]; |
294 | | int RefPicSetLtCurr[DE265_DPB_SIZE]; |
295 | | int RefPicSetLtFoll[DE265_DPB_SIZE]; |
296 | | |
297 | | |
298 | | uint8_t nal_unit_type; |
299 | | |
300 | | char IdrPicFlag; |
301 | | char RapPicFlag; |
302 | | */ |
303 | | |
304 | | |
305 | | |
306 | | // --- internal data --- |
307 | | |
308 | 8.80k | first_decoded_picture = true; |
309 | | //ctx->FirstAfterEndOfSequenceNAL = true; |
310 | | //ctx->last_RAP_picture_NAL_type = NAL_UNIT_UNDEFINED; |
311 | | |
312 | | //de265_init_image(&ctx->coeff); |
313 | | |
314 | | // --- decoded picture buffer --- |
315 | | |
316 | 8.80k | current_image_poc_lsb = -1; // any invalid number |
317 | 8.80k | } |
318 | | |
319 | | |
320 | | decoder_context::~decoder_context() |
321 | 8.80k | { |
322 | 8.82k | while (!image_units.empty()) { |
323 | 25 | delete image_units.back(); |
324 | 25 | image_units.pop_back(); |
325 | 25 | } |
326 | 8.80k | } |
327 | | |
328 | | |
329 | | void decoder_context::set_image_allocation_functions(de265_image_allocation* allocfunc, |
330 | | void* userdata) |
331 | 0 | { |
332 | 0 | if (allocfunc) { |
333 | 0 | param_image_allocation_functions = *allocfunc; |
334 | 0 | param_image_allocation_userdata = userdata; |
335 | 0 | } |
336 | 0 | else { |
337 | 0 | assert(false); // actually, it makes no sense to reset the allocation functions |
338 | | |
339 | 0 | param_image_allocation_functions = de265_image::default_image_allocation; |
340 | 0 | param_image_allocation_userdata = NULL; |
341 | 0 | } |
342 | 0 | } |
343 | | |
344 | | |
345 | | de265_error decoder_context::start_thread_pool(int nThreads) |
346 | 8.80k | { |
347 | 8.80k | ::start_thread_pool(&thread_pool_, nThreads); |
348 | | |
349 | 8.80k | num_worker_threads = nThreads; |
350 | | |
351 | 8.80k | return DE265_OK; |
352 | 8.80k | } |
353 | | |
354 | | |
355 | | void decoder_context::stop_thread_pool() |
356 | 8.80k | { |
357 | 8.80k | if (get_num_worker_threads()>0) { |
358 | | //flush_thread_pool(&ctx->thread_pool); |
359 | 8.80k | ::stop_thread_pool(&thread_pool_); |
360 | 8.80k | } |
361 | 8.80k | } |
362 | | |
363 | | |
364 | | void decoder_context::reset() |
365 | 0 | { |
366 | 0 | if (num_worker_threads>0) { |
367 | | //flush_thread_pool(&ctx->thread_pool); |
368 | 0 | ::stop_thread_pool(&thread_pool_); |
369 | 0 | } |
370 | | |
371 | | // -------------------------------------------------- |
372 | |
|
373 | | #if 0 |
374 | | ctx->end_of_stream = false; |
375 | | ctx->pending_input_NAL = NULL; |
376 | | ctx->current_vps = NULL; |
377 | | ctx->current_sps = NULL; |
378 | | ctx->current_pps = NULL; |
379 | | ctx->num_worker_threads = 0; |
380 | | ctx->current_image_poc_lsb = 0; |
381 | | ctx->first_decoded_picture = 0; |
382 | | ctx->NoRaslOutputFlag = 0; |
383 | | ctx->HandleCraAsBlaFlag = 0; |
384 | | ctx->FirstAfterEndOfSequenceNAL = 0; |
385 | | ctx->PicOrderCntMsb = 0; |
386 | | ctx->prevPicOrderCntLsb = 0; |
387 | | ctx->prevPicOrderCntMsb = 0; |
388 | | ctx->NumPocStCurrBefore=0; |
389 | | ctx->NumPocStCurrAfter=0; |
390 | | ctx->NumPocStFoll=0; |
391 | | ctx->NumPocLtCurr=0; |
392 | | ctx->NumPocLtFoll=0; |
393 | | ctx->nal_unit_type=0; |
394 | | ctx->IdrPicFlag=0; |
395 | | ctx->RapPicFlag=0; |
396 | | #endif |
397 | |
|
398 | 0 | img = NULL; |
399 | | |
400 | | |
401 | | // TODO: remove all pending image_units |
402 | | |
403 | | |
404 | | // --- decoded picture buffer --- |
405 | |
|
406 | 0 | current_image_poc_lsb = -1; // any invalid number |
407 | 0 | first_decoded_picture = true; |
408 | | |
409 | | |
410 | | // --- remove all pictures from output queue --- |
411 | | |
412 | | // there was a bug the peek_next_image did not return NULL on empty output queues. |
413 | | // This was (indirectly) fixed by recreating the DPB buffer, but it should actually |
414 | | // be sufficient to clear it like this. |
415 | | // The error showed while scrubbing the ToS video in VLC. |
416 | 0 | dpb.clear(); |
417 | |
|
418 | 0 | nal_parser.remove_pending_input_data(); |
419 | | |
420 | |
|
421 | 0 | while (!image_units.empty()) { |
422 | 0 | delete image_units.back(); |
423 | 0 | image_units.pop_back(); |
424 | 0 | } |
425 | | |
426 | | // --- start threads again --- |
427 | |
|
428 | 0 | if (num_worker_threads>0) { |
429 | | // TODO: need error checking |
430 | 0 | start_thread_pool(num_worker_threads); |
431 | 0 | } |
432 | 0 | } |
433 | | |
434 | | void base_context::set_acceleration_functions(enum de265_acceleration l) |
435 | 8.80k | { |
436 | | // fill scalar functions first (so that function table is completely filled) |
437 | | |
438 | 8.80k | init_acceleration_functions_fallback(&acceleration); |
439 | | |
440 | | |
441 | | // override functions with optimized variants |
442 | | |
443 | 8.80k | #ifdef HAVE_SSE4_1 |
444 | 8.80k | if (l>=de265_acceleration_SSE) { |
445 | 8.80k | init_acceleration_functions_sse(&acceleration); |
446 | 8.80k | } |
447 | 8.80k | #endif |
448 | | #ifdef HAVE_ARM |
449 | | if (l>=de265_acceleration_ARM) { |
450 | | init_acceleration_functions_arm(&acceleration); |
451 | | } |
452 | | #endif |
453 | 8.80k | } |
454 | | |
455 | | |
456 | | void decoder_context::init_thread_context(thread_context* tctx) |
457 | 14.5k | { |
458 | | // zero scrap memory for coefficient blocks |
459 | 14.5k | memset(tctx->_coeffBuf, 0, sizeof(tctx->_coeffBuf)); // TODO: check if we can safely remove this |
460 | | |
461 | 14.5k | tctx->currentQG_x = -1; |
462 | 14.5k | tctx->currentQG_y = -1; |
463 | | |
464 | | |
465 | | |
466 | | // --- find QPY that was active at the end of the previous slice --- |
467 | | |
468 | | // find the previous CTB in TS order |
469 | | |
470 | 14.5k | const pic_parameter_set& pps = tctx->img->get_pps(); |
471 | 14.5k | const seq_parameter_set& sps = tctx->img->get_sps(); |
472 | | |
473 | | |
474 | 14.5k | if (tctx->shdr->slice_segment_address > 0) { |
475 | 143 | int prevCtb = pps.CtbAddrTStoRS[ pps.CtbAddrRStoTS[tctx->shdr->slice_segment_address] -1 ]; |
476 | | |
477 | 143 | int ctbX = prevCtb % sps.PicWidthInCtbsY; |
478 | 143 | int ctbY = prevCtb / sps.PicWidthInCtbsY; |
479 | | |
480 | | |
481 | | // take the pixel at the bottom right corner (but consider that the image size might be smaller) |
482 | | |
483 | 143 | int x = ((ctbX+1) << sps.Log2CtbSizeY)-1; |
484 | 143 | int y = ((ctbY+1) << sps.Log2CtbSizeY)-1; |
485 | | |
486 | 143 | x = std::min(x,sps.pic_width_in_luma_samples-1); |
487 | 143 | y = std::min(y,sps.pic_height_in_luma_samples-1); |
488 | | |
489 | | //printf("READ QPY: %d %d -> %d (should %d)\n",x,y,imgunit->img->get_QPY(x,y), tc.currentQPY); |
490 | | |
491 | | //if (tctx->shdr->dependent_slice_segment_flag) { // TODO: do we need this condition ? |
492 | 143 | tctx->currentQPY = tctx->img->get_QPY(x,y); |
493 | | //} |
494 | 143 | } |
495 | 14.5k | } |
496 | | |
497 | | |
498 | | void decoder_context::add_task_decode_CTB_row(thread_context* tctx, |
499 | | bool firstSliceSubstream, |
500 | | int ctbRow) |
501 | 8.51k | { |
502 | 8.51k | thread_task_ctb_row* task = new thread_task_ctb_row; |
503 | 8.51k | task->firstSliceSubstream = firstSliceSubstream; |
504 | 8.51k | task->tctx = tctx; |
505 | 8.51k | task->debug_startCtbRow = ctbRow; |
506 | 8.51k | tctx->task = task; |
507 | | |
508 | 8.51k | add_task(&thread_pool_, task); |
509 | | |
510 | 8.51k | tctx->imgunit->tasks.push_back(task); |
511 | 8.51k | } |
512 | | |
513 | | |
514 | | void decoder_context::add_task_decode_slice_segment(thread_context* tctx, bool firstSliceSubstream, |
515 | | int ctbx,int ctby) |
516 | 1.81k | { |
517 | 1.81k | thread_task_slice_segment* task = new thread_task_slice_segment; |
518 | 1.81k | task->firstSliceSubstream = firstSliceSubstream; |
519 | 1.81k | task->tctx = tctx; |
520 | 1.81k | task->debug_startCtbX = ctbx; |
521 | 1.81k | task->debug_startCtbY = ctby; |
522 | 1.81k | tctx->task = task; |
523 | | |
524 | 1.81k | add_task(&thread_pool_, task); |
525 | | |
526 | 1.81k | tctx->imgunit->tasks.push_back(task); |
527 | 1.81k | } |
528 | | |
529 | | |
530 | | de265_error decoder_context::read_vps_NAL(bitreader& reader) |
531 | 3.49k | { |
532 | 3.49k | logdebug(LogHeaders,"---> read VPS\n"); |
533 | | |
534 | 3.49k | std::shared_ptr<video_parameter_set> new_vps = std::make_shared<video_parameter_set>(); |
535 | 3.49k | de265_error err = new_vps->read(this,&reader); |
536 | 3.49k | if (err != DE265_OK) { |
537 | 61 | return err; |
538 | 61 | } |
539 | | |
540 | 3.43k | if (param_vps_headers_fd>=0) { |
541 | 0 | new_vps->dump(param_vps_headers_fd); |
542 | 0 | } |
543 | | |
544 | 3.43k | vps[ new_vps->video_parameter_set_id ] = new_vps; |
545 | | |
546 | 3.43k | return DE265_OK; |
547 | 3.49k | } |
548 | | |
549 | | de265_error decoder_context::read_sps_NAL(bitreader& reader) |
550 | 8.48k | { |
551 | 8.48k | logdebug(LogHeaders,"----> read SPS\n"); |
552 | | |
553 | 8.48k | std::shared_ptr<seq_parameter_set> new_sps = std::make_shared<seq_parameter_set>(); |
554 | 8.48k | de265_error err; |
555 | | |
556 | 8.48k | if ((err=new_sps->read(this, &reader)) != DE265_OK) { |
557 | 668 | return err; |
558 | 668 | } |
559 | | |
560 | 7.81k | if (param_sps_headers_fd>=0) { |
561 | 0 | new_sps->dump(param_sps_headers_fd); |
562 | 0 | } |
563 | | |
564 | 7.81k | sps[ new_sps->seq_parameter_set_id ] = new_sps; |
565 | | |
566 | | // Remove the all PPS that referenced the old SPS because parameters may have changed and we do not want to |
567 | | // get the SPS and PPS parameters (e.g. image size) out of sync. |
568 | | |
569 | 500k | for (auto& p : pps) { |
570 | 500k | if (p && p->seq_parameter_set_id == new_sps->seq_parameter_set_id) { |
571 | 20 | p = nullptr; |
572 | 20 | } |
573 | 500k | } |
574 | | |
575 | 7.81k | return DE265_OK; |
576 | 8.48k | } |
577 | | |
578 | | de265_error decoder_context::read_pps_NAL(bitreader& reader) |
579 | 7.75k | { |
580 | 7.75k | logdebug(LogHeaders,"----> read PPS\n"); |
581 | | |
582 | 7.75k | std::shared_ptr<pic_parameter_set> new_pps = std::make_shared<pic_parameter_set>(); |
583 | | |
584 | 7.75k | bool success = new_pps->read(&reader,this); |
585 | 7.75k | if (!success) { |
586 | 202 | return DE265_WARNING_PPS_HEADER_INVALID; |
587 | 202 | } |
588 | | |
589 | 7.55k | if (param_pps_headers_fd>=0) { |
590 | 0 | new_pps->dump(param_pps_headers_fd); |
591 | 0 | } |
592 | | |
593 | 7.55k | pps[ (int)new_pps->pic_parameter_set_id ] = new_pps; |
594 | | |
595 | 7.55k | return DE265_OK; |
596 | 7.75k | } |
597 | | |
598 | | de265_error decoder_context::read_sei_NAL(bitreader& reader, bool suffix) |
599 | 62 | { |
600 | 62 | logdebug(LogHeaders,"----> read SEI\n"); |
601 | | |
602 | 62 | sei_message sei; |
603 | | |
604 | | //push_current_picture_to_output_queue(); |
605 | | |
606 | 62 | de265_error err = DE265_OK; |
607 | | |
608 | 62 | if ((err=read_sei(&reader,&sei, suffix, current_sps.get())) == DE265_OK) { |
609 | 61 | dump_sei(&sei, current_sps.get()); |
610 | | |
611 | 61 | if (image_units.empty()==false && suffix) { |
612 | 4 | image_units.back()->suffix_SEIs.push_back(sei); |
613 | 4 | } |
614 | 61 | } |
615 | 1 | else { |
616 | 1 | add_warning(err, false); |
617 | 1 | } |
618 | | |
619 | 62 | return err; |
620 | 62 | } |
621 | | |
622 | | de265_error decoder_context::read_eos_NAL(bitreader& reader) |
623 | 0 | { |
624 | 0 | FirstAfterEndOfSequenceNAL = true; |
625 | 0 | return DE265_OK; |
626 | 0 | } |
627 | | |
628 | | de265_error decoder_context::read_slice_NAL(bitreader& reader, NAL_unit* nal, nal_header& nal_hdr) |
629 | 7.71k | { |
630 | 7.71k | logdebug(LogHeaders,"---> read slice segment header\n"); |
631 | | |
632 | | |
633 | | // --- read slice header --- |
634 | | |
635 | 7.71k | slice_segment_header* shdr = new slice_segment_header; |
636 | 7.71k | bool continueDecoding; |
637 | 7.71k | de265_error err = shdr->read(&reader,this, &continueDecoding); |
638 | 7.71k | if (!continueDecoding) { |
639 | 405 | if (img) { img->integrity = INTEGRITY_NOT_DECODED; } |
640 | 405 | nal_parser.free_NAL_unit(nal); |
641 | 405 | delete shdr; |
642 | 405 | return err; |
643 | 405 | } |
644 | | |
645 | 7.30k | if (param_slice_headers_fd>=0) { |
646 | 0 | shdr->dump_slice_segment_header(this, param_slice_headers_fd); |
647 | 0 | } |
648 | | |
649 | | |
650 | 7.30k | if (process_slice_segment_header(shdr, &err, nal->pts, &nal_hdr, nal->user_data) == false) |
651 | 150 | { |
652 | 150 | if (img!=NULL) img->integrity = INTEGRITY_NOT_DECODED; |
653 | 150 | nal_parser.free_NAL_unit(nal); |
654 | 150 | delete shdr; |
655 | 150 | return err; |
656 | 150 | } |
657 | | |
658 | 7.15k | this->img->add_slice_segment_header(shdr); |
659 | | |
660 | 7.15k | skip_bits(&reader,1); // TODO: why? |
661 | 7.15k | prepare_for_CABAC(&reader); |
662 | | |
663 | | |
664 | | // modify entry_point_offsets |
665 | | |
666 | 7.15k | int headerLength = reader.data - nal->data(); |
667 | 19.8k | for (int i=0;i<shdr->num_entry_point_offsets;i++) { |
668 | 12.7k | shdr->entry_point_offset[i] -= nal->num_skipped_bytes_before(shdr->entry_point_offset[i], |
669 | 12.7k | headerLength); |
670 | 12.7k | } |
671 | | |
672 | | |
673 | | |
674 | | // --- start a new image if this is the first slice --- |
675 | | |
676 | 7.15k | if (shdr->first_slice_segment_in_pic_flag) { |
677 | 7.04k | image_unit* imgunit = new image_unit; |
678 | 7.04k | imgunit->img = this->img; |
679 | 7.04k | image_units.push_back(imgunit); |
680 | 7.04k | } |
681 | | |
682 | | |
683 | | // --- add slice to current picture --- |
684 | | |
685 | 7.15k | if ( ! image_units.empty() ) { |
686 | | |
687 | 7.15k | slice_unit* sliceunit = new slice_unit(this); |
688 | 7.15k | sliceunit->nal = nal; |
689 | 7.15k | sliceunit->shdr = shdr; |
690 | 7.15k | sliceunit->reader = reader; |
691 | | |
692 | 7.15k | sliceunit->flush_reorder_buffer = flush_reorder_buffer_at_this_frame; |
693 | | |
694 | | |
695 | 7.15k | image_units.back()->slice_units.push_back(sliceunit); |
696 | 7.15k | } |
697 | 3 | else { |
698 | 3 | nal_parser.free_NAL_unit(nal); |
699 | 3 | } |
700 | | |
701 | 7.15k | bool did_work; |
702 | 7.15k | err = decode_some(&did_work); |
703 | | |
704 | 7.15k | return DE265_OK; |
705 | 7.30k | } |
706 | | |
707 | | |
708 | | template <class T> void pop_front(std::vector<T>& vec) |
709 | 7.02k | { |
710 | 7.05k | for (size_t i=1;i<vec.size();i++) |
711 | 35 | vec[i-1] = vec[i]; |
712 | | |
713 | 7.02k | vec.pop_back(); |
714 | 7.02k | } |
715 | | |
716 | | |
717 | | de265_error decoder_context::decode_some(bool* did_work) |
718 | 7.31k | { |
719 | 7.31k | de265_error err = DE265_OK; |
720 | | |
721 | 7.31k | *did_work = false; |
722 | | |
723 | 7.31k | if (image_units.empty()) { return DE265_OK; } // nothing to do |
724 | | |
725 | | |
726 | | // decode something if there is work to do |
727 | | |
728 | 7.30k | if ( ! image_units.empty() ) { // && ! image_units[0]->slice_units.empty() ) { |
729 | | |
730 | 7.30k | image_unit* imgunit = image_units[0]; |
731 | 7.30k | slice_unit* sliceunit = imgunit->get_next_unprocessed_slice_segment(); |
732 | | |
733 | 7.30k | if (sliceunit != NULL) { |
734 | | |
735 | | //pop_front(imgunit->slice_units); |
736 | | |
737 | 7.14k | if (sliceunit->flush_reorder_buffer) { |
738 | 7.00k | dpb.flush_reorder_buffer(); |
739 | 7.00k | } |
740 | | |
741 | 7.14k | *did_work = true; |
742 | | |
743 | | //err = decode_slice_unit_sequential(imgunit, sliceunit); |
744 | 7.14k | err = decode_slice_unit_parallel(imgunit, sliceunit); |
745 | 7.14k | if (err) { |
746 | 121 | return err; |
747 | 121 | } |
748 | | |
749 | | //delete sliceunit; |
750 | 7.14k | } |
751 | 7.30k | } |
752 | | |
753 | | |
754 | | |
755 | | // if we decoded all slices of the current image and there will not |
756 | | // be added any more slices to the image, output the image |
757 | | |
758 | 7.18k | if ( ( image_units.size()>=2 && image_units[0]->all_slice_segments_processed()) || |
759 | 7.18k | ( image_units.size()>=1 && image_units[0]->all_slice_segments_processed() && |
760 | 7.15k | nal_parser.number_of_NAL_units_pending()==0 && |
761 | 7.15k | (nal_parser.is_end_of_stream() || nal_parser.is_end_of_frame()) )) { |
762 | | |
763 | 7.02k | image_unit* imgunit = image_units[0]; |
764 | | |
765 | 7.02k | *did_work=true; |
766 | | |
767 | | |
768 | | // mark all CTBs as decoded even if they are not, because faulty input |
769 | | // streams could miss part of the picture |
770 | | // TODO: this will not work when slice decoding is parallel to post-filtering, |
771 | | // so we will have to replace this with keeping track of which CTB should have |
772 | | // been decoded (but aren't because of the input stream being faulty) |
773 | | |
774 | 7.02k | imgunit->img->mark_all_CTB_progress(CTB_PROGRESS_PREFILTER); |
775 | | |
776 | | |
777 | | |
778 | | // run post-processing filters (deblocking & SAO) |
779 | | |
780 | 7.02k | if (img->decctx->num_worker_threads) |
781 | 7.02k | run_postprocessing_filters_parallel(imgunit); |
782 | 0 | else |
783 | 0 | run_postprocessing_filters_sequential(imgunit->img); |
784 | | |
785 | | // process suffix SEIs |
786 | | |
787 | 7.02k | for (size_t i=0;i<imgunit->suffix_SEIs.size();i++) { |
788 | 4 | const sei_message& sei = imgunit->suffix_SEIs[i]; |
789 | | |
790 | 4 | err = process_sei(&sei, imgunit->img); |
791 | 4 | if (err != DE265_OK) |
792 | 0 | break; |
793 | 4 | } |
794 | | |
795 | | |
796 | 7.02k | push_picture_to_output_queue(imgunit); |
797 | | |
798 | | // remove just decoded image unit from queue |
799 | | |
800 | 7.02k | delete imgunit; |
801 | | |
802 | 7.02k | pop_front(image_units); |
803 | 7.02k | } |
804 | | |
805 | 7.18k | return err; |
806 | 7.30k | } |
807 | | |
808 | | |
809 | | de265_error decoder_context::decode_slice_unit_sequential(image_unit* imgunit, |
810 | | slice_unit* sliceunit) |
811 | 4.05k | { |
812 | 4.05k | de265_error err = DE265_OK; |
813 | | |
814 | | /* |
815 | | printf("decode slice POC=%d addr=%d, img=%p\n", |
816 | | sliceunit->shdr->slice_pic_order_cnt_lsb, |
817 | | sliceunit->shdr->slice_segment_address, |
818 | | imgunit->img); |
819 | | */ |
820 | | |
821 | 4.05k | remove_images_from_dpb(sliceunit->shdr->RemoveReferencesList); |
822 | | |
823 | 4.05k | if (sliceunit->shdr->slice_segment_address >= imgunit->img->get_pps().CtbAddrRStoTS.size()) { |
824 | 0 | return DE265_ERROR_CTB_OUTSIDE_IMAGE_AREA; |
825 | 0 | } |
826 | | |
827 | | |
828 | 4.05k | struct thread_context tctx; |
829 | | |
830 | 4.05k | tctx.shdr = sliceunit->shdr; |
831 | 4.05k | tctx.img = imgunit->img; |
832 | 4.05k | tctx.decctx = this; |
833 | 4.05k | tctx.imgunit = imgunit; |
834 | 4.05k | tctx.sliceunit= sliceunit; |
835 | 4.05k | tctx.CtbAddrInTS = imgunit->img->get_pps().CtbAddrRStoTS[tctx.shdr->slice_segment_address]; |
836 | 4.05k | tctx.task = NULL; |
837 | | |
838 | 4.05k | init_thread_context(&tctx); |
839 | | |
840 | 4.05k | if (sliceunit->reader.bytes_remaining <= 0) { |
841 | 4 | return DE265_ERROR_PREMATURE_END_OF_SLICE; |
842 | 4 | } |
843 | | |
844 | 4.05k | init_CABAC_decoder(&tctx.cabac_decoder, |
845 | 4.05k | sliceunit->reader.data, |
846 | 4.05k | sliceunit->reader.bytes_remaining); |
847 | | |
848 | | // alloc CABAC-model array if entropy_coding_sync is enabled |
849 | | |
850 | 4.05k | if (imgunit->img->get_pps().entropy_coding_sync_enabled_flag && |
851 | 4.05k | sliceunit->shdr->first_slice_segment_in_pic_flag) { |
852 | 0 | imgunit->ctx_models.resize( (img->get_sps().PicHeightInCtbsY-1) ); //* CONTEXT_MODEL_TABLE_LENGTH ); |
853 | 0 | } |
854 | | |
855 | 4.05k | sliceunit->nThreads=1; |
856 | | |
857 | 4.05k | err=read_slice_segment_data(&tctx); |
858 | | |
859 | 4.05k | sliceunit->finished_threads.set_progress(1); |
860 | | |
861 | 4.05k | return err; |
862 | 4.05k | } |
863 | | |
864 | | |
865 | | void decoder_context::mark_whole_slice_as_processed(image_unit* imgunit, |
866 | | slice_unit* sliceunit, |
867 | | int progress) |
868 | 7.19k | { |
869 | | //printf("mark whole slice\n"); |
870 | | |
871 | | |
872 | | // mark all CTBs upto the next slice segment as processed |
873 | | |
874 | 7.19k | slice_unit* nextSegment = imgunit->get_next_slice_segment(sliceunit); |
875 | 7.19k | if (nextSegment) { |
876 | | /* |
877 | | printf("mark whole slice between %d and %d\n", |
878 | | sliceunit->shdr->slice_segment_address, |
879 | | nextSegment->shdr->slice_segment_address); |
880 | | */ |
881 | | |
882 | 103 | for (int ctb=sliceunit->shdr->slice_segment_address; |
883 | 13.3k | ctb < nextSegment->shdr->slice_segment_address; |
884 | 13.2k | ctb++) |
885 | 13.2k | { |
886 | 13.2k | if (ctb >= imgunit->img->number_of_ctbs()) |
887 | 0 | break; |
888 | | |
889 | 13.2k | imgunit->img->ctb_progress[ctb].set_progress(progress); |
890 | 13.2k | } |
891 | 103 | } |
892 | 7.19k | } |
893 | | |
894 | | |
895 | | de265_error decoder_context::decode_slice_unit_parallel(image_unit* imgunit, |
896 | | slice_unit* sliceunit) |
897 | 7.14k | { |
898 | 7.14k | de265_error err = DE265_OK; |
899 | | |
900 | 7.14k | remove_images_from_dpb(sliceunit->shdr->RemoveReferencesList); |
901 | | |
902 | | /* |
903 | | printf("-------- decode --------\n"); |
904 | | printf("IMAGE UNIT %p\n",imgunit); |
905 | | sliceunit->shdr->dump_slice_segment_header(sliceunit->ctx, 1); |
906 | | imgunit->dump_slices(); |
907 | | */ |
908 | | |
909 | 7.14k | de265_image* img = imgunit->img; |
910 | 7.14k | const pic_parameter_set& pps = img->get_pps(); |
911 | | |
912 | 7.14k | sliceunit->state = slice_unit::InProgress; |
913 | | |
914 | 7.14k | bool use_WPP = (img->decctx->num_worker_threads > 0 && |
915 | 7.14k | pps.entropy_coding_sync_enabled_flag); |
916 | | |
917 | 7.14k | bool use_tiles = (img->decctx->num_worker_threads > 0 && |
918 | 7.14k | pps.tiles_enabled_flag); |
919 | | |
920 | | |
921 | | // TODO: remove this warning later when we do frame-parallel decoding |
922 | 7.14k | if (img->decctx->num_worker_threads > 0 && |
923 | 7.14k | pps.entropy_coding_sync_enabled_flag == false && |
924 | 7.14k | pps.tiles_enabled_flag == false) { |
925 | | |
926 | 4.05k | img->decctx->add_warning(DE265_WARNING_NO_WPP_CANNOT_USE_MULTITHREADING, true); |
927 | 4.05k | } |
928 | | |
929 | | |
930 | | // If this is the first slice segment, mark all CTBs before this as processed |
931 | | // (the real first slice segment could be missing). |
932 | | |
933 | 7.14k | if (imgunit->is_first_slice_segment(sliceunit)) { |
934 | 7.04k | slice_segment_header* shdr = sliceunit->shdr; |
935 | 7.04k | int firstCTB = shdr->slice_segment_address; |
936 | | |
937 | 7.04k | for (int ctb=0;ctb<firstCTB;ctb++) { |
938 | | //printf("mark pre progress %d\n",ctb); |
939 | 0 | img->ctb_progress[ctb].set_progress(CTB_PROGRESS_PREFILTER); |
940 | 0 | } |
941 | 7.04k | } |
942 | | |
943 | | |
944 | | // if there is a previous slice that has been completely decoded, |
945 | | // mark all CTBs until the start of this slice as completed |
946 | | |
947 | | //printf("this slice: %p\n",sliceunit); |
948 | 7.14k | slice_unit* prevSlice = imgunit->get_prev_slice_segment(sliceunit); |
949 | | //if (prevSlice) printf("prev slice state: %d\n",prevSlice->state); |
950 | 7.14k | if (prevSlice && prevSlice->state == slice_unit::Decoded) { |
951 | 103 | mark_whole_slice_as_processed(imgunit,prevSlice,CTB_PROGRESS_PREFILTER); |
952 | 103 | } |
953 | | |
954 | | |
955 | | // TODO: even though we cannot split this into several tasks, we should run it |
956 | | // as a background thread |
957 | 7.14k | if (!use_WPP && !use_tiles) { |
958 | | //printf("SEQ\n"); |
959 | 4.05k | err = decode_slice_unit_sequential(imgunit, sliceunit); |
960 | 4.05k | sliceunit->state = slice_unit::Decoded; |
961 | 4.05k | mark_whole_slice_as_processed(imgunit,sliceunit,CTB_PROGRESS_PREFILTER); |
962 | 4.05k | return err; |
963 | 4.05k | } |
964 | | |
965 | | |
966 | 3.09k | if (use_WPP && use_tiles) { |
967 | | // TODO: this is not allowed ... output some warning or error |
968 | | |
969 | 60 | return DE265_WARNING_PPS_HEADER_INVALID; |
970 | 60 | } |
971 | | |
972 | | |
973 | 3.03k | if (use_WPP) { |
974 | | //printf("WPP\n"); |
975 | 1.62k | err = decode_slice_unit_WPP(imgunit, sliceunit); |
976 | 1.62k | sliceunit->state = slice_unit::Decoded; |
977 | 1.62k | mark_whole_slice_as_processed(imgunit,sliceunit,CTB_PROGRESS_PREFILTER); |
978 | 1.62k | return err; |
979 | 1.62k | } |
980 | 1.41k | else if (use_tiles) { |
981 | | //printf("TILE\n"); |
982 | 1.41k | err = decode_slice_unit_tiles(imgunit, sliceunit); |
983 | 1.41k | sliceunit->state = slice_unit::Decoded; |
984 | 1.41k | mark_whole_slice_as_processed(imgunit,sliceunit,CTB_PROGRESS_PREFILTER); |
985 | 1.41k | return err; |
986 | 1.41k | } |
987 | | |
988 | 0 | assert(false); |
989 | 0 | return err; |
990 | 0 | } |
991 | | |
992 | | |
993 | | de265_error decoder_context::decode_slice_unit_WPP(image_unit* imgunit, |
994 | | slice_unit* sliceunit) |
995 | 1.62k | { |
996 | 1.62k | de265_error err = DE265_OK; |
997 | | |
998 | 1.62k | de265_image* img = imgunit->img; |
999 | 1.62k | slice_segment_header* shdr = sliceunit->shdr; |
1000 | 1.62k | const pic_parameter_set& pps = img->get_pps(); |
1001 | | |
1002 | 1.62k | int nRows = shdr->num_entry_point_offsets +1; |
1003 | 1.62k | int ctbsWidth = img->get_sps().PicWidthInCtbsY; |
1004 | | |
1005 | | |
1006 | 1.62k | assert(img->num_threads_active() == 0); |
1007 | | |
1008 | | |
1009 | | // reserve space to store entropy coding context models for each CTB row |
1010 | | |
1011 | 1.62k | if (shdr->first_slice_segment_in_pic_flag) { |
1012 | | // reserve space for nRows-1 because we don't need to save the CABAC model in the last CTB row |
1013 | 1.60k | imgunit->ctx_models.resize( (img->get_sps().PicHeightInCtbsY-1) ); //* CONTEXT_MODEL_TABLE_LENGTH ); |
1014 | 1.60k | } |
1015 | | |
1016 | | |
1017 | 1.62k | sliceunit->allocate_thread_contexts(nRows); |
1018 | | |
1019 | | |
1020 | | // first CTB in this slice |
1021 | 1.62k | int ctbAddrRS = shdr->slice_segment_address; |
1022 | 1.62k | int ctbRow = ctbAddrRS / ctbsWidth; |
1023 | | |
1024 | 10.1k | for (int entryPt=0;entryPt<nRows;entryPt++) { |
1025 | | // entry points other than the first start at CTB rows |
1026 | 8.62k | if (entryPt>0) { |
1027 | 7.00k | ctbRow++; |
1028 | 7.00k | ctbAddrRS = ctbRow * ctbsWidth; |
1029 | 7.00k | } |
1030 | 1.62k | else if (nRows>1 && (ctbAddrRS % ctbsWidth) != 0) { |
1031 | | // If slice segment consists of several WPP rows, each of them |
1032 | | // has to start at a row. |
1033 | | |
1034 | | //printf("does not start at start\n"); |
1035 | | |
1036 | 2 | err = DE265_WARNING_SLICEHEADER_INVALID; |
1037 | 2 | break; |
1038 | 2 | } |
1039 | | |
1040 | | |
1041 | | // prepare thread context |
1042 | | |
1043 | 8.62k | thread_context* tctx = sliceunit->get_thread_context(entryPt); |
1044 | | |
1045 | 8.62k | tctx->shdr = shdr; |
1046 | 8.62k | tctx->decctx = img->decctx; |
1047 | 8.62k | tctx->img = img; |
1048 | 8.62k | tctx->imgunit = imgunit; |
1049 | 8.62k | tctx->sliceunit= sliceunit; |
1050 | 8.62k | tctx->CtbAddrInTS = pps.CtbAddrRStoTS[ctbAddrRS]; |
1051 | | |
1052 | 8.62k | init_thread_context(tctx); |
1053 | | |
1054 | | |
1055 | | // init CABAC |
1056 | | |
1057 | 8.62k | int dataStartIndex; |
1058 | 8.62k | if (entryPt==0) { dataStartIndex=0; } |
1059 | 7.00k | else { dataStartIndex=shdr->entry_point_offset[entryPt-1]; } |
1060 | | |
1061 | 8.62k | int dataEnd; |
1062 | 8.62k | if (entryPt==nRows-1) dataEnd = sliceunit->reader.bytes_remaining; |
1063 | 7.11k | else dataEnd = shdr->entry_point_offset[entryPt]; |
1064 | | |
1065 | 8.62k | if (dataStartIndex<0 || dataEnd>sliceunit->reader.bytes_remaining || |
1066 | 8.62k | dataEnd <= dataStartIndex) { |
1067 | | //printf("WPP premature end\n"); |
1068 | 111 | err = DE265_ERROR_PREMATURE_END_OF_SLICE; |
1069 | 111 | break; |
1070 | 111 | } |
1071 | | |
1072 | 8.51k | init_CABAC_decoder(&tctx->cabac_decoder, |
1073 | 8.51k | &sliceunit->reader.data[dataStartIndex], |
1074 | 8.51k | dataEnd-dataStartIndex); |
1075 | | |
1076 | | // add task |
1077 | | |
1078 | | //printf("start task for ctb-row: %d\n",ctbRow); |
1079 | 8.51k | img->thread_start(1); |
1080 | 8.51k | sliceunit->nThreads++; |
1081 | 8.51k | add_task_decode_CTB_row(tctx, entryPt==0, ctbRow); |
1082 | 8.51k | } |
1083 | | |
1084 | | #if 0 |
1085 | | for (;;) { |
1086 | | printf("q:%d r:%d b:%d f:%d\n", |
1087 | | img->nThreadsQueued, |
1088 | | img->nThreadsRunning, |
1089 | | img->nThreadsBlocked, |
1090 | | img->nThreadsFinished); |
1091 | | |
1092 | | if (img->debug_is_completed()) break; |
1093 | | |
1094 | | usleep(1000); |
1095 | | } |
1096 | | #endif |
1097 | | |
1098 | 1.62k | img->wait_for_completion(); |
1099 | | |
1100 | 10.1k | for (size_t i=0;i<imgunit->tasks.size();i++) |
1101 | 8.51k | delete imgunit->tasks[i]; |
1102 | 1.62k | imgunit->tasks.clear(); |
1103 | | |
1104 | 1.62k | return DE265_OK; |
1105 | 1.62k | } |
1106 | | |
1107 | | de265_error decoder_context::decode_slice_unit_tiles(image_unit* imgunit, |
1108 | | slice_unit* sliceunit) |
1109 | 1.41k | { |
1110 | 1.41k | de265_error err = DE265_OK; |
1111 | | |
1112 | 1.41k | de265_image* img = imgunit->img; |
1113 | 1.41k | slice_segment_header* shdr = sliceunit->shdr; |
1114 | 1.41k | const pic_parameter_set& pps = img->get_pps(); |
1115 | | |
1116 | 1.41k | int nTiles = shdr->num_entry_point_offsets +1; |
1117 | 1.41k | int ctbsWidth = img->get_sps().PicWidthInCtbsY; |
1118 | | |
1119 | | |
1120 | 1.41k | assert(img->num_threads_active() == 0); |
1121 | | |
1122 | 1.41k | sliceunit->allocate_thread_contexts(nTiles); |
1123 | | |
1124 | | |
1125 | | // first CTB in this slice |
1126 | 1.41k | int ctbAddrRS = shdr->slice_segment_address; |
1127 | 1.41k | int tileID = pps.TileIdRS[ctbAddrRS]; |
1128 | | |
1129 | 3.22k | for (int entryPt=0;entryPt<nTiles;entryPt++) { |
1130 | | // entry points other than the first start at tile beginnings |
1131 | 1.86k | if (entryPt>0) { |
1132 | 456 | tileID++; |
1133 | | |
1134 | 456 | if (tileID >= pps.num_tile_columns * pps.num_tile_rows) { |
1135 | 35 | err = DE265_WARNING_SLICEHEADER_INVALID; |
1136 | 35 | break; |
1137 | 35 | } |
1138 | | |
1139 | 421 | int ctbX = pps.colBd[tileID % pps.num_tile_columns]; |
1140 | 421 | int ctbY = pps.rowBd[tileID / pps.num_tile_columns]; |
1141 | 421 | ctbAddrRS = ctbY * ctbsWidth + ctbX; |
1142 | 421 | } |
1143 | | |
1144 | | // set thread context |
1145 | | |
1146 | 1.83k | thread_context* tctx = sliceunit->get_thread_context(entryPt); |
1147 | | |
1148 | 1.83k | tctx->shdr = shdr; |
1149 | 1.83k | tctx->decctx = img->decctx; |
1150 | 1.83k | tctx->img = img; |
1151 | 1.83k | tctx->imgunit = imgunit; |
1152 | 1.83k | tctx->sliceunit= sliceunit; |
1153 | 1.83k | tctx->CtbAddrInTS = pps.CtbAddrRStoTS[ctbAddrRS]; |
1154 | | |
1155 | 1.83k | init_thread_context(tctx); |
1156 | | |
1157 | | |
1158 | | // init CABAC |
1159 | | |
1160 | 1.83k | int dataStartIndex; |
1161 | 1.83k | if (entryPt==0) { dataStartIndex=0; } |
1162 | 421 | else { dataStartIndex=shdr->entry_point_offset[entryPt-1]; } |
1163 | | |
1164 | 1.83k | int dataEnd; |
1165 | 1.83k | if (entryPt==nTiles-1) dataEnd = sliceunit->reader.bytes_remaining; |
1166 | 473 | else dataEnd = shdr->entry_point_offset[entryPt]; |
1167 | | |
1168 | 1.83k | if (dataStartIndex<0 || dataEnd>sliceunit->reader.bytes_remaining || |
1169 | 1.83k | dataEnd <= dataStartIndex) { |
1170 | 21 | err = DE265_ERROR_PREMATURE_END_OF_SLICE; |
1171 | 21 | break; |
1172 | 21 | } |
1173 | | |
1174 | 1.81k | init_CABAC_decoder(&tctx->cabac_decoder, |
1175 | 1.81k | &sliceunit->reader.data[dataStartIndex], |
1176 | 1.81k | dataEnd-dataStartIndex); |
1177 | | |
1178 | | // add task |
1179 | | |
1180 | | //printf("add tiles thread\n"); |
1181 | 1.81k | img->thread_start(1); |
1182 | 1.81k | sliceunit->nThreads++; |
1183 | 1.81k | add_task_decode_slice_segment(tctx, entryPt==0, |
1184 | 1.81k | ctbAddrRS % ctbsWidth, |
1185 | 1.81k | ctbAddrRS / ctbsWidth); |
1186 | 1.81k | } |
1187 | | |
1188 | 1.41k | img->wait_for_completion(); |
1189 | | |
1190 | 3.22k | for (size_t i=0;i<imgunit->tasks.size();i++) |
1191 | 1.81k | delete imgunit->tasks[i]; |
1192 | 1.41k | imgunit->tasks.clear(); |
1193 | | |
1194 | 1.41k | return err; |
1195 | 1.41k | } |
1196 | | |
1197 | | |
1198 | | de265_error decoder_context::decode_NAL(NAL_unit* nal) |
1199 | 38.4k | { |
1200 | | //return decode_NAL_OLD(nal); |
1201 | | |
1202 | 38.4k | decoder_context* ctx = this; |
1203 | | |
1204 | 38.4k | de265_error err = DE265_OK; |
1205 | | |
1206 | 38.4k | bitreader reader; |
1207 | 38.4k | bitreader_init(&reader, nal->data(), nal->size()); |
1208 | | |
1209 | 38.4k | nal_header nal_hdr; |
1210 | 38.4k | nal_hdr.read(&reader); |
1211 | 38.4k | ctx->process_nal_hdr(&nal_hdr); |
1212 | | |
1213 | 38.4k | if (nal_hdr.nuh_layer_id > 0) { |
1214 | | // Discard all NAL units with nuh_layer_id > 0 |
1215 | | // These will have to be handled by an SHVC decoder. |
1216 | 4.99k | nal_parser.free_NAL_unit(nal); |
1217 | 4.99k | return DE265_OK; |
1218 | 4.99k | } |
1219 | | |
1220 | 33.4k | loginfo(LogHighlevel,"NAL: 0x%x 0x%x - unit type:%s temporal id:%d\n", |
1221 | 33.4k | nal->data()[0], nal->data()[1], |
1222 | 33.4k | get_NAL_name(nal_hdr.nal_unit_type), |
1223 | 33.4k | nal_hdr.nuh_temporal_id); |
1224 | | |
1225 | | /* |
1226 | | printf("NAL: 0x%x 0x%x - unit type:%s temporal id:%d\n", |
1227 | | nal->data()[0], nal->data()[1], |
1228 | | get_NAL_name(nal_hdr.nal_unit_type), |
1229 | | nal_hdr.nuh_temporal_id); |
1230 | | */ |
1231 | | |
1232 | | // throw away NALs from higher TIDs than currently selected |
1233 | | // TODO: better online switching of HighestTID |
1234 | | |
1235 | | //printf("hTid: %d\n", current_HighestTid); |
1236 | | |
1237 | 33.4k | if (nal_hdr.nuh_temporal_id > current_HighestTid) { |
1238 | 5.90k | nal_parser.free_NAL_unit(nal); |
1239 | 5.90k | return DE265_OK; |
1240 | 5.90k | } |
1241 | | |
1242 | | |
1243 | 27.5k | if (nal_hdr.nal_unit_type<32) { |
1244 | 7.71k | err = read_slice_NAL(reader, nal, nal_hdr); |
1245 | 7.71k | } |
1246 | 19.8k | else switch (nal_hdr.nal_unit_type) { |
1247 | 3.49k | case NAL_UNIT_VPS_NUT: |
1248 | 3.49k | err = read_vps_NAL(reader); |
1249 | 3.49k | nal_parser.free_NAL_unit(nal); |
1250 | 3.49k | break; |
1251 | | |
1252 | 8.48k | case NAL_UNIT_SPS_NUT: |
1253 | 8.48k | err = read_sps_NAL(reader); |
1254 | 8.48k | nal_parser.free_NAL_unit(nal); |
1255 | 8.48k | break; |
1256 | | |
1257 | 7.75k | case NAL_UNIT_PPS_NUT: |
1258 | 7.75k | err = read_pps_NAL(reader); |
1259 | 7.75k | nal_parser.free_NAL_unit(nal); |
1260 | 7.75k | break; |
1261 | | |
1262 | 30 | case NAL_UNIT_PREFIX_SEI_NUT: |
1263 | 62 | case NAL_UNIT_SUFFIX_SEI_NUT: |
1264 | 62 | err = read_sei_NAL(reader, nal_hdr.nal_unit_type==NAL_UNIT_SUFFIX_SEI_NUT); |
1265 | 62 | nal_parser.free_NAL_unit(nal); |
1266 | 62 | break; |
1267 | | |
1268 | 21 | case NAL_UNIT_EOS_NUT: |
1269 | 21 | ctx->FirstAfterEndOfSequenceNAL = true; |
1270 | 21 | nal_parser.free_NAL_unit(nal); |
1271 | 21 | break; |
1272 | | |
1273 | 20 | default: |
1274 | 20 | nal_parser.free_NAL_unit(nal); |
1275 | 20 | break; |
1276 | 19.8k | } |
1277 | | |
1278 | 27.5k | return err; |
1279 | 27.5k | } |
1280 | | |
1281 | | |
1282 | | de265_error decoder_context::decode(int* more) |
1283 | 44.0k | { |
1284 | 44.0k | decoder_context* ctx = this; |
1285 | | |
1286 | | // if the stream has ended, and no more NALs are to be decoded, flush all pictures |
1287 | | |
1288 | 44.0k | if (ctx->nal_parser.get_NAL_queue_length() == 0 && |
1289 | 44.0k | (ctx->nal_parser.is_end_of_stream() || ctx->nal_parser.is_end_of_frame()) && |
1290 | 44.0k | ctx->image_units.empty()) { |
1291 | | |
1292 | | // flush all pending pictures into output queue |
1293 | | |
1294 | | // ctx->push_current_picture_to_output_queue(); // TODO: not with new queue |
1295 | 5.44k | ctx->dpb.flush_reorder_buffer(); |
1296 | | |
1297 | 5.44k | if (more) { *more = ctx->dpb.num_pictures_in_output_queue(); } |
1298 | | |
1299 | 5.44k | return DE265_OK; |
1300 | 5.44k | } |
1301 | | |
1302 | | |
1303 | | // if NAL-queue is empty, we need more data |
1304 | | // -> input stalled |
1305 | | |
1306 | 38.5k | if (ctx->nal_parser.is_end_of_stream() == false && |
1307 | 38.5k | ctx->nal_parser.is_end_of_frame() == false && |
1308 | 38.5k | ctx->nal_parser.get_NAL_queue_length() == 0) { |
1309 | 0 | if (more) { *more=1; } |
1310 | |
|
1311 | 0 | return DE265_ERROR_WAITING_FOR_INPUT_DATA; |
1312 | 0 | } |
1313 | | |
1314 | | |
1315 | | // when there are no free image buffers in the DPB, pause decoding |
1316 | | // -> output stalled |
1317 | | |
1318 | 38.5k | if (!ctx->dpb.has_free_dpb_picture(false)) { |
1319 | 2 | if (more) *more = 1; |
1320 | 2 | return DE265_ERROR_IMAGE_BUFFER_FULL; |
1321 | 2 | } |
1322 | | |
1323 | | |
1324 | | // decode one NAL from the queue |
1325 | | |
1326 | 38.5k | de265_error err = DE265_OK; |
1327 | 38.5k | bool did_work = false; |
1328 | | |
1329 | 38.5k | if (ctx->nal_parser.get_NAL_queue_length()) { // number_of_NAL_units_pending()) { |
1330 | 38.4k | NAL_unit* nal = ctx->nal_parser.pop_from_NAL_queue(); |
1331 | 38.4k | assert(nal); |
1332 | 38.4k | err = ctx->decode_NAL(nal); |
1333 | | // ctx->nal_parser.free_NAL_unit(nal); TODO: do not free NAL with new loop |
1334 | 38.4k | did_work=true; |
1335 | 38.4k | } |
1336 | 155 | else if (ctx->nal_parser.is_end_of_frame() == true && |
1337 | 155 | ctx->image_units.empty()) { |
1338 | 0 | if (more) { *more=1; } |
1339 | |
|
1340 | 0 | return DE265_ERROR_WAITING_FOR_INPUT_DATA; |
1341 | 0 | } |
1342 | 155 | else { |
1343 | 155 | err = decode_some(&did_work); |
1344 | 155 | } |
1345 | | |
1346 | 38.5k | if (more) { |
1347 | | // decoding error is assumed to be unrecoverable |
1348 | 38.5k | *more = (err==DE265_OK && did_work); |
1349 | 38.5k | } |
1350 | | |
1351 | 38.5k | return err; |
1352 | 38.5k | } |
1353 | | |
1354 | | |
1355 | | void decoder_context::process_nal_hdr(nal_header* nal) |
1356 | 38.4k | { |
1357 | 38.4k | nal_unit_type = nal->nal_unit_type; |
1358 | | |
1359 | 38.4k | IdrPicFlag = isIdrPic(nal->nal_unit_type); |
1360 | 38.4k | RapPicFlag = isRapPic(nal->nal_unit_type); |
1361 | 38.4k | } |
1362 | | |
1363 | | |
1364 | | |
1365 | | /* 8.3.1 |
1366 | | */ |
1367 | | void decoder_context::process_picture_order_count(slice_segment_header* hdr) |
1368 | 7.17k | { |
1369 | 7.17k | loginfo(LogHeaders,"POC computation. lsb:%d prev.pic.lsb:%d msb:%d\n", |
1370 | 7.17k | hdr->slice_pic_order_cnt_lsb, |
1371 | 7.17k | prevPicOrderCntLsb, |
1372 | 7.17k | PicOrderCntMsb); |
1373 | | |
1374 | 7.17k | if (isIRAP(nal_unit_type) && |
1375 | 7.17k | NoRaslOutputFlag) |
1376 | 7.12k | { |
1377 | 7.12k | PicOrderCntMsb=0; |
1378 | | |
1379 | | |
1380 | | // flush all images from reorder buffer |
1381 | | |
1382 | 7.12k | flush_reorder_buffer_at_this_frame = true; |
1383 | | //ctx->dpb.flush_reorder_buffer(); |
1384 | 7.12k | } |
1385 | 48 | else |
1386 | 48 | { |
1387 | 48 | int MaxPicOrderCntLsb = current_sps->MaxPicOrderCntLsb; |
1388 | | |
1389 | 48 | if ((hdr->slice_pic_order_cnt_lsb < prevPicOrderCntLsb) && |
1390 | 48 | (prevPicOrderCntLsb - hdr->slice_pic_order_cnt_lsb) >= MaxPicOrderCntLsb/2) { |
1391 | 9 | PicOrderCntMsb = prevPicOrderCntMsb + MaxPicOrderCntLsb; |
1392 | 9 | } |
1393 | 39 | else if ((hdr->slice_pic_order_cnt_lsb > prevPicOrderCntLsb) && |
1394 | 39 | (hdr->slice_pic_order_cnt_lsb - prevPicOrderCntLsb) > MaxPicOrderCntLsb/2) { |
1395 | 20 | PicOrderCntMsb = prevPicOrderCntMsb - MaxPicOrderCntLsb; |
1396 | 20 | } |
1397 | 19 | else { |
1398 | 19 | PicOrderCntMsb = prevPicOrderCntMsb; |
1399 | 19 | } |
1400 | 48 | } |
1401 | | |
1402 | 7.17k | img->PicOrderCntVal = PicOrderCntMsb + hdr->slice_pic_order_cnt_lsb; |
1403 | 7.17k | img->picture_order_cnt_lsb = hdr->slice_pic_order_cnt_lsb; |
1404 | | |
1405 | 7.17k | loginfo(LogHeaders,"POC computation. new msb:%d POC=%d\n", |
1406 | 7.17k | PicOrderCntMsb, |
1407 | 7.17k | img->PicOrderCntVal); |
1408 | | |
1409 | 7.17k | if (img->nal_hdr.nuh_temporal_id==0 && |
1410 | 7.17k | !isSublayerNonReference(nal_unit_type) && |
1411 | 7.17k | !isRASL(nal_unit_type) && |
1412 | 7.17k | !isRADL(nal_unit_type)) |
1413 | 7.09k | { |
1414 | 7.09k | loginfo(LogHeaders,"set prevPicOrderCntLsb/Msb\n"); |
1415 | | |
1416 | 7.09k | prevPicOrderCntLsb = hdr->slice_pic_order_cnt_lsb; |
1417 | 7.09k | prevPicOrderCntMsb = PicOrderCntMsb; |
1418 | 7.09k | } |
1419 | 7.17k | } |
1420 | | |
1421 | | |
1422 | | /* 8.3.3.2 |
1423 | | Returns DPB index of the generated picture. |
1424 | | */ |
1425 | | int decoder_context::generate_unavailable_reference_picture(const seq_parameter_set* sps, |
1426 | | int POC, bool longTerm) |
1427 | 10.4k | { |
1428 | 10.4k | assert(dpb.has_free_dpb_picture(true)); |
1429 | | |
1430 | 10.4k | std::shared_ptr<const seq_parameter_set> current_sps = this->sps[ (int)current_pps->seq_parameter_set_id ]; |
1431 | | |
1432 | 10.4k | int idx = dpb.new_image(current_sps, this, 0,0, false); |
1433 | 10.4k | if (idx<0) { |
1434 | 0 | return idx; |
1435 | 0 | } |
1436 | | |
1437 | 10.4k | de265_image* img = dpb.get_image(idx); |
1438 | | |
1439 | 10.4k | img->fill_image(1<<(sps->BitDepth_Y-1), |
1440 | 10.4k | 1<<(sps->BitDepth_C-1), |
1441 | 10.4k | 1<<(sps->BitDepth_C-1)); |
1442 | | |
1443 | 10.4k | img->fill_pred_mode(MODE_INTRA); |
1444 | | |
1445 | 10.4k | img->PicOrderCntVal = POC; |
1446 | 10.4k | img->picture_order_cnt_lsb = POC & (sps->MaxPicOrderCntLsb-1); |
1447 | 10.4k | img->PicOutputFlag = false; |
1448 | 10.4k | img->PicState = (longTerm ? UsedForLongTermReference : UsedForShortTermReference); |
1449 | 10.4k | img->integrity = INTEGRITY_UNAVAILABLE_REFERENCE; |
1450 | | |
1451 | 10.4k | return idx; |
1452 | 10.4k | } |
1453 | | |
1454 | | |
1455 | | /* 8.3.2 invoked once per picture |
1456 | | |
1457 | | This function will mark pictures in the DPB as 'unused' or 'used for long-term reference' |
1458 | | */ |
1459 | | de265_error decoder_context::process_reference_picture_set(slice_segment_header* hdr) |
1460 | 7.17k | { |
1461 | 7.17k | std::vector<int> removeReferencesList; |
1462 | | |
1463 | 7.17k | const int currentID = img->get_ID(); |
1464 | | |
1465 | | |
1466 | 7.17k | if (isIRAP(nal_unit_type) && NoRaslOutputFlag) { |
1467 | | |
1468 | 7.12k | int currentPOC = img->PicOrderCntVal; |
1469 | | |
1470 | | // reset DPB |
1471 | | |
1472 | | /* The standard says: "When the current picture is an IRAP picture with NoRaslOutputFlag |
1473 | | equal to 1, all reference pictures currently in the DPB (if any) are marked as |
1474 | | "unused for reference". |
1475 | | |
1476 | | This seems to be wrong as it also throws out the first CRA picture in a stream like |
1477 | | RAP_A (decoding order: CRA,POC=64, RASL,POC=60). Removing only the pictures with |
1478 | | lower POCs seems to be compliant to the reference decoder. |
1479 | | */ |
1480 | | |
1481 | 14.3k | for (size_t i=0;i<dpb.size();i++) { |
1482 | 7.25k | de265_image* img = dpb.get_image(i); |
1483 | | |
1484 | 7.25k | if (img->PicState != UnusedForReference && |
1485 | 7.25k | img->PicOrderCntVal < currentPOC && |
1486 | 7.25k | img->removed_at_picture_id > img->get_ID()) { |
1487 | | |
1488 | 84 | removeReferencesList.push_back(img->get_ID()); |
1489 | 84 | img->removed_at_picture_id = img->get_ID(); |
1490 | | |
1491 | | //printf("will remove ID %d (a)\n",img->get_ID()); |
1492 | 84 | } |
1493 | 7.25k | } |
1494 | 7.12k | } |
1495 | | |
1496 | | |
1497 | 7.17k | if (isIDR(nal_unit_type)) { |
1498 | | |
1499 | | // clear all reference pictures |
1500 | | |
1501 | 609 | NumPocStCurrBefore = 0; |
1502 | 609 | NumPocStCurrAfter = 0; |
1503 | 609 | NumPocStFoll = 0; |
1504 | 609 | NumPocLtCurr = 0; |
1505 | 609 | NumPocLtFoll = 0; |
1506 | 609 | } |
1507 | 6.56k | else { |
1508 | 6.56k | const ref_pic_set* rps = &hdr->CurrRps; |
1509 | | |
1510 | | // (8-98) |
1511 | | |
1512 | 6.56k | int i,j,k; |
1513 | | |
1514 | | // scan ref-pic-set for smaller POCs and fill into PocStCurrBefore / PocStFoll |
1515 | | |
1516 | 6.56k | for (i=0, j=0, k=0; |
1517 | 9.33k | i<rps->NumNegativePics; |
1518 | 6.56k | i++) |
1519 | 2.77k | { |
1520 | 2.77k | if (rps->UsedByCurrPicS0[i]) { |
1521 | 2.15k | PocStCurrBefore[j++] = img->PicOrderCntVal + rps->DeltaPocS0[i]; |
1522 | | //printf("PocStCurrBefore = %d\n",PocStCurrBefore[j-1]); |
1523 | 2.15k | } |
1524 | 613 | else { |
1525 | 613 | PocStFoll[k++] = img->PicOrderCntVal + rps->DeltaPocS0[i]; |
1526 | 613 | } |
1527 | 2.77k | } |
1528 | | |
1529 | 6.56k | NumPocStCurrBefore = j; |
1530 | | |
1531 | | |
1532 | | // scan ref-pic-set for larger POCs and fill into PocStCurrAfter / PocStFoll |
1533 | | |
1534 | 6.56k | for (i=0, j=0; |
1535 | 11.9k | i<rps->NumPositivePics; |
1536 | 6.56k | i++) |
1537 | 5.36k | { |
1538 | 5.36k | if (rps->UsedByCurrPicS1[i]) { |
1539 | 4.64k | PocStCurrAfter[j++] = img->PicOrderCntVal + rps->DeltaPocS1[i]; |
1540 | | //printf("PocStCurrAfter = %d\n",PocStCurrAfter[j-1]); |
1541 | 4.64k | } |
1542 | 715 | else { |
1543 | 715 | PocStFoll[k++] = img->PicOrderCntVal + rps->DeltaPocS1[i]; |
1544 | 715 | } |
1545 | 5.36k | } |
1546 | | |
1547 | 6.56k | NumPocStCurrAfter = j; |
1548 | 6.56k | NumPocStFoll = k; |
1549 | | |
1550 | | |
1551 | | // find used / future long-term references |
1552 | | |
1553 | 6.56k | for (i=0, j=0, k=0; |
1554 | | //i<current_sps->num_long_term_ref_pics_sps + hdr->num_long_term_pics; |
1555 | 11.5k | i<hdr->num_long_term_sps + hdr->num_long_term_pics; |
1556 | 6.56k | i++) |
1557 | 5.01k | { |
1558 | 5.01k | int pocLt = PocLsbLt[i]; |
1559 | | |
1560 | 5.01k | if (hdr->delta_poc_msb_present_flag[i]) { |
1561 | 2.18k | int currentPictureMSB = img->PicOrderCntVal - hdr->slice_pic_order_cnt_lsb; |
1562 | 2.18k | pocLt += currentPictureMSB |
1563 | 2.18k | - DeltaPocMsbCycleLt[i] * current_sps->MaxPicOrderCntLsb; |
1564 | 2.18k | } |
1565 | | |
1566 | 5.01k | if (UsedByCurrPicLt[i]) { |
1567 | 3.09k | PocLtCurr[j] = pocLt; |
1568 | 3.09k | CurrDeltaPocMsbPresentFlag[j] = hdr->delta_poc_msb_present_flag[i]; |
1569 | 3.09k | j++; |
1570 | 3.09k | } |
1571 | 1.91k | else { |
1572 | 1.91k | PocLtFoll[k] = pocLt; |
1573 | 1.91k | FollDeltaPocMsbPresentFlag[k] = hdr->delta_poc_msb_present_flag[i]; |
1574 | 1.91k | k++; |
1575 | 1.91k | } |
1576 | 5.01k | } |
1577 | | |
1578 | 6.56k | NumPocLtCurr = j; |
1579 | 6.56k | NumPocLtFoll = k; |
1580 | 6.56k | } |
1581 | | |
1582 | | |
1583 | | // (old 8-99) / (new 8-106) |
1584 | | // 1. |
1585 | | |
1586 | 7.17k | std::vector<char> picInAnyList(dpb.size(), false); |
1587 | | |
1588 | | |
1589 | 7.17k | dpb.log_dpb_content(); |
1590 | | |
1591 | 10.2k | for (int i=0;i<NumPocLtCurr;i++) { |
1592 | 3.09k | int k; |
1593 | 3.09k | if (!CurrDeltaPocMsbPresentFlag[i]) { |
1594 | 1.38k | k = dpb.DPB_index_of_picture_with_LSB(PocLtCurr[i], currentID, true); |
1595 | 1.38k | } |
1596 | 1.71k | else { |
1597 | 1.71k | k = dpb.DPB_index_of_picture_with_POC(PocLtCurr[i], currentID, true); |
1598 | 1.71k | } |
1599 | | |
1600 | 3.09k | RefPicSetLtCurr[i] = k; // -1 == "no reference picture" |
1601 | 3.09k | if (k>=0) picInAnyList[k]=true; |
1602 | 2.55k | else { |
1603 | | // TODO, CHECK: is it ok that we generate a picture with POC = LSB (PocLtCurr) |
1604 | | // We do not know the correct MSB |
1605 | 2.55k | int concealedPicture = generate_unavailable_reference_picture(current_sps.get(), |
1606 | 2.55k | PocLtCurr[i], true); |
1607 | 2.55k | if (concealedPicture<0) { |
1608 | 0 | return (de265_error)(-concealedPicture); |
1609 | 0 | } |
1610 | 2.55k | picInAnyList.resize(dpb.size(), false); // adjust size of array to hold new picture |
1611 | | |
1612 | 2.55k | RefPicSetLtCurr[i] = k = concealedPicture; |
1613 | 2.55k | picInAnyList[concealedPicture]=true; |
1614 | 2.55k | } |
1615 | | |
1616 | 3.09k | if (dpb.get_image(k)->integrity != INTEGRITY_CORRECT) { |
1617 | 2.85k | img->integrity = INTEGRITY_DERIVED_FROM_FAULTY_REFERENCE; |
1618 | 2.85k | } |
1619 | 3.09k | } |
1620 | | |
1621 | | |
1622 | 9.09k | for (int i=0;i<NumPocLtFoll;i++) { |
1623 | 1.91k | int k; |
1624 | 1.91k | if (!FollDeltaPocMsbPresentFlag[i]) { |
1625 | 1.44k | k = dpb.DPB_index_of_picture_with_LSB(PocLtFoll[i], currentID, true); |
1626 | 1.44k | } |
1627 | 472 | else { |
1628 | 472 | k = dpb.DPB_index_of_picture_with_POC(PocLtFoll[i], currentID, true); |
1629 | 472 | } |
1630 | | |
1631 | 1.91k | RefPicSetLtFoll[i] = k; // -1 == "no reference picture" |
1632 | 1.91k | if (k>=0) picInAnyList[k]=true; |
1633 | 1.24k | else { |
1634 | 1.24k | int concealedPicture = k = generate_unavailable_reference_picture(current_sps.get(), |
1635 | 1.24k | PocLtFoll[i], true); |
1636 | 1.24k | if (concealedPicture<0) { |
1637 | 0 | return (de265_error)(-concealedPicture); |
1638 | 0 | } |
1639 | 1.24k | picInAnyList.resize(dpb.size(), false); // adjust size of array to hold new picture |
1640 | | |
1641 | 1.24k | RefPicSetLtFoll[i] = concealedPicture; |
1642 | 1.24k | picInAnyList[concealedPicture]=true; |
1643 | 1.24k | } |
1644 | 1.91k | } |
1645 | | |
1646 | | |
1647 | | // 2. Mark all pictures in RefPicSetLtCurr / RefPicSetLtFoll as UsedForLongTermReference |
1648 | | |
1649 | 10.2k | for (int i=0;i<NumPocLtCurr;i++) { |
1650 | 3.09k | dpb.get_image(RefPicSetLtCurr[i])->PicState = UsedForLongTermReference; |
1651 | 3.09k | } |
1652 | | |
1653 | 9.09k | for (int i=0;i<NumPocLtFoll;i++) { |
1654 | 1.91k | dpb.get_image(RefPicSetLtFoll[i])->PicState = UsedForLongTermReference; |
1655 | 1.91k | } |
1656 | | |
1657 | | |
1658 | | // 3. |
1659 | | |
1660 | 9.33k | for (int i=0;i<NumPocStCurrBefore;i++) { |
1661 | 2.15k | int k = dpb.DPB_index_of_picture_with_POC(PocStCurrBefore[i], currentID); |
1662 | | |
1663 | | //printf("st curr before, poc=%d -> idx=%d\n",PocStCurrBefore[i], k); |
1664 | | |
1665 | 2.15k | RefPicSetStCurrBefore[i] = k; // -1 == "no reference picture" |
1666 | 2.15k | if (k>=0) picInAnyList[k]=true; |
1667 | 2.05k | else { |
1668 | 2.05k | int concealedPicture = generate_unavailable_reference_picture(current_sps.get(), |
1669 | 2.05k | PocStCurrBefore[i], false); |
1670 | 2.05k | if (concealedPicture<0) { |
1671 | 0 | return (de265_error)(-concealedPicture); |
1672 | 0 | } |
1673 | 2.05k | RefPicSetStCurrBefore[i] = k = concealedPicture; |
1674 | | |
1675 | 2.05k | picInAnyList.resize(dpb.size(), false); // adjust size of array to hold new picture |
1676 | 2.05k | picInAnyList[concealedPicture] = true; |
1677 | | |
1678 | | //printf(" concealed: %d\n", concealedPicture); |
1679 | 2.05k | } |
1680 | | |
1681 | 2.15k | if (dpb.get_image(k)->integrity != INTEGRITY_CORRECT) { |
1682 | 2.10k | img->integrity = INTEGRITY_DERIVED_FROM_FAULTY_REFERENCE; |
1683 | 2.10k | } |
1684 | 2.15k | } |
1685 | | |
1686 | 11.8k | for (int i=0;i<NumPocStCurrAfter;i++) { |
1687 | 4.64k | int k = dpb.DPB_index_of_picture_with_POC(PocStCurrAfter[i], currentID); |
1688 | | |
1689 | | //printf("st curr after, poc=%d -> idx=%d\n",PocStCurrAfter[i], k); |
1690 | | |
1691 | 4.64k | RefPicSetStCurrAfter[i] = k; // -1 == "no reference picture" |
1692 | 4.64k | if (k>=0) picInAnyList[k]=true; |
1693 | 4.57k | else { |
1694 | 4.57k | int concealedPicture = generate_unavailable_reference_picture(current_sps.get(), |
1695 | 4.57k | PocStCurrAfter[i], false); |
1696 | 4.57k | if (concealedPicture<0) { |
1697 | 0 | return (de265_error)(-concealedPicture); |
1698 | 0 | } |
1699 | 4.57k | RefPicSetStCurrAfter[i] = k = concealedPicture; |
1700 | | |
1701 | | |
1702 | 4.57k | picInAnyList.resize(dpb.size(), false); // adjust size of array to hold new picture |
1703 | 4.57k | picInAnyList[concealedPicture]=true; |
1704 | | |
1705 | | //printf(" concealed: %d\n", concealedPicture); |
1706 | 4.57k | } |
1707 | | |
1708 | 4.64k | if (dpb.get_image(k)->integrity != INTEGRITY_CORRECT) { |
1709 | 4.64k | img->integrity = INTEGRITY_DERIVED_FROM_FAULTY_REFERENCE; |
1710 | 4.64k | } |
1711 | 4.64k | } |
1712 | | |
1713 | 8.50k | for (int i=0;i<NumPocStFoll;i++) { |
1714 | 1.32k | int k = dpb.DPB_index_of_picture_with_POC(PocStFoll[i], currentID); |
1715 | | // if (k<0) { assert(false); } // IGNORE |
1716 | | |
1717 | 1.32k | RefPicSetStFoll[i] = k; // -1 == "no reference picture" |
1718 | 1.32k | if (k>=0) picInAnyList[k]=true; |
1719 | 1.32k | } |
1720 | | |
1721 | | // 4. any picture that is not marked for reference is put into the "UnusedForReference" state |
1722 | | |
1723 | 25.0k | for (int i=0;i<dpb.size();i++) |
1724 | 17.9k | if (i>=picInAnyList.size() || !picInAnyList[i]) // no reference |
1725 | 6.97k | { |
1726 | 6.97k | de265_image* dpbimg = dpb.get_image(i); |
1727 | 6.97k | if (dpbimg != img && // not the current picture |
1728 | 6.97k | dpbimg->removed_at_picture_id > img->get_ID()) // has not been removed before |
1729 | 166 | { |
1730 | 166 | if (dpbimg->PicState != UnusedForReference) { |
1731 | 166 | removeReferencesList.push_back(dpbimg->get_ID()); |
1732 | | //printf("will remove ID %d (b)\n",dpbimg->get_ID()); |
1733 | | |
1734 | 166 | dpbimg->removed_at_picture_id = img->get_ID(); |
1735 | 166 | } |
1736 | 166 | } |
1737 | 6.97k | } |
1738 | | |
1739 | 7.17k | hdr->RemoveReferencesList = removeReferencesList; |
1740 | | |
1741 | | //remove_images_from_dpb(hdr->RemoveReferencesList); |
1742 | | |
1743 | 7.17k | return DE265_OK; |
1744 | 7.17k | } |
1745 | | |
1746 | | |
1747 | | // 8.3.4 |
1748 | | // Returns whether we can continue decoding (or whether there is a severe error). |
1749 | | /* Called at beginning of each slice. |
1750 | | |
1751 | | Constructs |
1752 | | - the RefPicList[2][], containing indices into the DPB, and |
1753 | | - the RefPicList_POC[2][], containing POCs. |
1754 | | - LongTermRefPic[2][] is also set to true if it is a long-term reference |
1755 | | */ |
1756 | | bool decoder_context::construct_reference_picture_lists(slice_segment_header* hdr) |
1757 | 4.68k | { |
1758 | 4.68k | int NumPocTotalCurr = hdr->NumPocTotalCurr; |
1759 | 4.68k | int NumRpsCurrTempList0 = libde265_max(hdr->num_ref_idx_l0_active, NumPocTotalCurr); |
1760 | | |
1761 | | // TODO: fold code for both lists together |
1762 | | |
1763 | 4.68k | int RefPicListTemp0[3*MAX_NUM_REF_PICS]; // TODO: what would be the correct maximum ? |
1764 | 4.68k | int RefPicListTemp1[3*MAX_NUM_REF_PICS]; // TODO: what would be the correct maximum ? |
1765 | 4.68k | char isLongTerm[2][3*MAX_NUM_REF_PICS]; |
1766 | | |
1767 | 4.68k | memset(isLongTerm,0,2*3*MAX_NUM_REF_PICS); |
1768 | | |
1769 | | /* --- Fill RefPicListTmp0 with reference pictures in this order: |
1770 | | 1) short term, past POC |
1771 | | 2) short term, future POC |
1772 | | 3) long term |
1773 | | */ |
1774 | | |
1775 | 4.68k | int rIdx=0; |
1776 | 12.1k | while (rIdx < NumRpsCurrTempList0) { |
1777 | 11.0k | for (int i=0;i<NumPocStCurrBefore && rIdx<NumRpsCurrTempList0; rIdx++,i++) |
1778 | 3.54k | RefPicListTemp0[rIdx] = RefPicSetStCurrBefore[i]; |
1779 | | |
1780 | 12.3k | for (int i=0;i<NumPocStCurrAfter && rIdx<NumRpsCurrTempList0; rIdx++,i++) |
1781 | 4.81k | RefPicListTemp0[rIdx] = RefPicSetStCurrAfter[i]; |
1782 | | |
1783 | 11.2k | for (int i=0;i<NumPocLtCurr && rIdx<NumRpsCurrTempList0; rIdx++,i++) { |
1784 | 3.69k | RefPicListTemp0[rIdx] = RefPicSetLtCurr[i]; |
1785 | 3.69k | isLongTerm[0][rIdx] = true; |
1786 | 3.69k | } |
1787 | | |
1788 | | // This check is to prevent an endless loop when no images are added above. |
1789 | 7.54k | if (rIdx==0) { |
1790 | 64 | add_warning(DE265_WARNING_FAULTY_REFERENCE_PICTURE_LIST, false); |
1791 | 64 | return false; |
1792 | 64 | } |
1793 | 7.54k | } |
1794 | | |
1795 | | /* |
1796 | | if (hdr->num_ref_idx_l0_active > 16) { |
1797 | | add_warning(DE265_WARNING_NONEXISTING_REFERENCE_PICTURE_ACCESSED, false); |
1798 | | return false; |
1799 | | } |
1800 | | */ |
1801 | | |
1802 | 4.62k | assert(hdr->num_ref_idx_l0_active <= 16); |
1803 | 13.4k | for (rIdx=0; rIdx<hdr->num_ref_idx_l0_active; rIdx++) { |
1804 | 8.93k | int idx = hdr->ref_pic_list_modification_flag_l0 ? hdr->list_entry_l0[rIdx] : rIdx; |
1805 | | |
1806 | 8.93k | hdr->RefPicList[0][rIdx] = RefPicListTemp0[idx]; |
1807 | 8.93k | hdr->LongTermRefPic[0][rIdx] = isLongTerm[0][idx]; |
1808 | | |
1809 | | // remember POC of referenced image (needed in motion.c, derive_collocated_motion_vector) |
1810 | 8.93k | de265_image* img_0_rIdx = dpb.get_image(hdr->RefPicList[0][rIdx]); |
1811 | 8.93k | if (img_0_rIdx==NULL) { |
1812 | 64 | return false; |
1813 | 64 | } |
1814 | 8.86k | hdr->RefPicList_POC[0][rIdx] = img_0_rIdx->PicOrderCntVal; |
1815 | 8.86k | hdr->RefPicList_PicState[0][rIdx] = img_0_rIdx->PicState; |
1816 | 8.86k | } |
1817 | | |
1818 | | |
1819 | | /* --- Fill RefPicListTmp1 with reference pictures in this order: |
1820 | | 1) short term, future POC |
1821 | | 2) short term, past POC |
1822 | | 3) long term |
1823 | | */ |
1824 | | |
1825 | 4.55k | if (hdr->slice_type == SLICE_TYPE_B) { |
1826 | 3.91k | int NumRpsCurrTempList1 = libde265_max(hdr->num_ref_idx_l1_active, NumPocTotalCurr); |
1827 | | |
1828 | 3.91k | int rIdx=0; |
1829 | 9.74k | while (rIdx < NumRpsCurrTempList1) { |
1830 | 9.48k | for (int i=0;i<NumPocStCurrAfter && rIdx<NumRpsCurrTempList1; rIdx++,i++) { |
1831 | 3.65k | RefPicListTemp1[rIdx] = RefPicSetStCurrAfter[i]; |
1832 | 3.65k | } |
1833 | | |
1834 | 8.69k | for (int i=0;i<NumPocStCurrBefore && rIdx<NumRpsCurrTempList1; rIdx++,i++) { |
1835 | 2.86k | RefPicListTemp1[rIdx] = RefPicSetStCurrBefore[i]; |
1836 | 2.86k | } |
1837 | | |
1838 | 8.75k | for (int i=0;i<NumPocLtCurr && rIdx<NumRpsCurrTempList1; rIdx++,i++) { |
1839 | 2.92k | RefPicListTemp1[rIdx] = RefPicSetLtCurr[i]; |
1840 | 2.92k | isLongTerm[1][rIdx] = true; |
1841 | 2.92k | } |
1842 | | |
1843 | | // This check is to prevent an endless loop when no images are added above. |
1844 | 5.83k | if (rIdx==0) { |
1845 | 0 | add_warning(DE265_WARNING_FAULTY_REFERENCE_PICTURE_LIST, false); |
1846 | 0 | return false; |
1847 | 0 | } |
1848 | 5.83k | } |
1849 | | |
1850 | 3.91k | if (hdr->num_ref_idx_l0_active > 16) { |
1851 | 0 | add_warning(DE265_WARNING_NONEXISTING_REFERENCE_PICTURE_ACCESSED, false); |
1852 | 0 | return false; |
1853 | 0 | } |
1854 | | |
1855 | 3.91k | assert(hdr->num_ref_idx_l1_active <= 16); |
1856 | 10.9k | for (rIdx=0; rIdx<hdr->num_ref_idx_l1_active; rIdx++) { |
1857 | 7.01k | int idx = hdr->ref_pic_list_modification_flag_l1 ? hdr->list_entry_l1[rIdx] : rIdx; |
1858 | | |
1859 | 7.01k | hdr->RefPicList[1][rIdx] = RefPicListTemp1[idx]; |
1860 | 7.01k | hdr->LongTermRefPic[1][rIdx] = isLongTerm[1][idx]; |
1861 | | |
1862 | | // remember POC of referenced imaged (needed in motion.c, derive_collocated_motion_vector) |
1863 | 7.01k | de265_image* img_1_rIdx = dpb.get_image(hdr->RefPicList[1][rIdx]); |
1864 | 7.01k | if (img_1_rIdx == NULL) { return false; } |
1865 | 7.01k | hdr->RefPicList_POC[1][rIdx] = img_1_rIdx->PicOrderCntVal; |
1866 | 7.01k | hdr->RefPicList_PicState[1][rIdx] = img_1_rIdx->PicState; |
1867 | 7.01k | } |
1868 | 3.91k | } |
1869 | | |
1870 | | |
1871 | | // show reference picture lists |
1872 | | |
1873 | 4.55k | loginfo(LogHeaders,"RefPicList[0] ="); |
1874 | 13.4k | for (rIdx=0; rIdx<hdr->num_ref_idx_l0_active; rIdx++) { |
1875 | 8.86k | loginfo(LogHeaders,"* [%d]=%d (LT=%d)", |
1876 | 8.86k | hdr->RefPicList[0][rIdx], |
1877 | 8.86k | hdr->RefPicList_POC[0][rIdx], |
1878 | 8.86k | hdr->LongTermRefPic[0][rIdx] |
1879 | 8.86k | ); |
1880 | 8.86k | } |
1881 | 4.55k | loginfo(LogHeaders,"*\n"); |
1882 | | |
1883 | 4.55k | if (hdr->slice_type == SLICE_TYPE_B) { |
1884 | 3.91k | loginfo(LogHeaders,"RefPicList[1] ="); |
1885 | 10.9k | for (rIdx=0; rIdx<hdr->num_ref_idx_l1_active; rIdx++) { |
1886 | 7.01k | loginfo(LogHeaders,"* [%d]=%d (LT=%d)", |
1887 | 7.01k | hdr->RefPicList[1][rIdx], |
1888 | 7.01k | hdr->RefPicList_POC[1][rIdx], |
1889 | 7.01k | hdr->LongTermRefPic[1][rIdx] |
1890 | 7.01k | ); |
1891 | 7.01k | } |
1892 | 3.91k | loginfo(LogHeaders,"*\n"); |
1893 | 3.91k | } |
1894 | | |
1895 | 4.55k | return true; |
1896 | 4.55k | } |
1897 | | |
1898 | | |
1899 | | |
1900 | | void decoder_context::run_postprocessing_filters_sequential(de265_image* img) |
1901 | 0 | { |
1902 | | #if SAVE_INTERMEDIATE_IMAGES |
1903 | | char buf[1000]; |
1904 | | sprintf(buf,"pre-lf-%05d.yuv", img->PicOrderCntVal); |
1905 | | write_picture_to_file(img, buf); |
1906 | | #endif |
1907 | |
|
1908 | 0 | if (!img->decctx->param_disable_deblocking) { |
1909 | 0 | apply_deblocking_filter(img); |
1910 | 0 | } |
1911 | |
|
1912 | | #if SAVE_INTERMEDIATE_IMAGES |
1913 | | sprintf(buf,"pre-sao-%05d.yuv", img->PicOrderCntVal); |
1914 | | write_picture_to_file(img, buf); |
1915 | | #endif |
1916 | |
|
1917 | 0 | if (!img->decctx->param_disable_sao) { |
1918 | 0 | apply_sample_adaptive_offset_sequential(img); |
1919 | 0 | } |
1920 | |
|
1921 | | #if SAVE_INTERMEDIATE_IMAGES |
1922 | | sprintf(buf,"sao-%05d.yuv", img->PicOrderCntVal); |
1923 | | write_picture_to_file(img, buf); |
1924 | | #endif |
1925 | 0 | } |
1926 | | |
1927 | | |
1928 | | void decoder_context::run_postprocessing_filters_parallel(image_unit* imgunit) |
1929 | 7.02k | { |
1930 | 7.02k | de265_image* img = imgunit->img; |
1931 | | |
1932 | 7.02k | int saoWaitsForProgress = CTB_PROGRESS_PREFILTER; |
1933 | 7.02k | bool waitForCompletion = false; |
1934 | | |
1935 | 7.02k | if (!img->decctx->param_disable_deblocking) { |
1936 | 7.02k | add_deblocking_tasks(imgunit); |
1937 | 7.02k | saoWaitsForProgress = CTB_PROGRESS_DEBLK_H; |
1938 | 7.02k | } |
1939 | | |
1940 | 7.02k | if (!img->decctx->param_disable_sao) { |
1941 | 7.02k | waitForCompletion |= add_sao_tasks(imgunit, saoWaitsForProgress); |
1942 | | //apply_sample_adaptive_offset(img); |
1943 | 7.02k | } |
1944 | | |
1945 | 7.02k | img->wait_for_completion(); |
1946 | 7.02k | } |
1947 | | |
1948 | | /* |
1949 | | void decoder_context::push_current_picture_to_output_queue() |
1950 | | { |
1951 | | push_picture_to_output_queue(img); |
1952 | | } |
1953 | | */ |
1954 | | |
1955 | | de265_error decoder_context::push_picture_to_output_queue(image_unit* imgunit) |
1956 | 7.02k | { |
1957 | 7.02k | de265_image* outimg = imgunit->img; |
1958 | | |
1959 | 7.02k | if (outimg==NULL) { return DE265_OK; } |
1960 | | |
1961 | | |
1962 | | // push image into output queue |
1963 | | |
1964 | 7.02k | if (outimg->PicOutputFlag) { |
1965 | 6.02k | loginfo(LogDPB,"new picture has output-flag=true\n"); |
1966 | | |
1967 | 6.02k | if (outimg->integrity != INTEGRITY_CORRECT && |
1968 | 6.02k | param_suppress_faulty_pictures) { |
1969 | 0 | } |
1970 | 6.02k | else { |
1971 | 6.02k | dpb.insert_image_into_reorder_buffer(outimg); |
1972 | 6.02k | } |
1973 | | |
1974 | 6.02k | loginfo(LogDPB,"push image %d into reordering queue\n", outimg->PicOrderCntVal); |
1975 | 6.02k | } |
1976 | | |
1977 | | // check for full reorder buffers |
1978 | | |
1979 | 7.02k | int maxNumPicsInReorderBuffer = 0; |
1980 | | |
1981 | | // TODO: I'd like to have the has_vps() check somewhere else (not decode the picture at all) |
1982 | 7.02k | if (outimg->has_vps()) { |
1983 | 2.94k | int sublayer = outimg->get_vps().vps_max_sub_layers -1; |
1984 | 2.94k | maxNumPicsInReorderBuffer = outimg->get_vps().layer[sublayer].vps_max_num_reorder_pics; |
1985 | 2.94k | } |
1986 | | |
1987 | 7.02k | if (dpb.num_pictures_in_reorder_buffer() > maxNumPicsInReorderBuffer) { |
1988 | 5.98k | dpb.output_next_picture_in_reorder_buffer(); |
1989 | 5.98k | } |
1990 | | |
1991 | 7.02k | dpb.log_dpb_queues(); |
1992 | | |
1993 | 7.02k | return DE265_OK; |
1994 | 7.02k | } |
1995 | | |
1996 | | |
1997 | | // returns whether we can continue decoding the stream or whether we should give up |
1998 | | bool decoder_context::process_slice_segment_header(slice_segment_header* hdr, |
1999 | | de265_error* err, de265_PTS pts, |
2000 | | nal_header* nal_hdr, |
2001 | | void* user_data) |
2002 | 7.30k | { |
2003 | 7.30k | *err = DE265_OK; |
2004 | | |
2005 | 7.30k | flush_reorder_buffer_at_this_frame = false; |
2006 | | |
2007 | | |
2008 | | // get PPS and SPS for this slice |
2009 | | |
2010 | 7.30k | int pps_id = hdr->slice_pic_parameter_set_id; |
2011 | 7.30k | if (pps[pps_id]==nullptr || pps[pps_id]->pps_read==false) { |
2012 | 0 | logerror(LogHeaders, "PPS %d has not been read\n", pps_id); |
2013 | 0 | img->decctx->add_warning(DE265_WARNING_NONEXISTING_PPS_REFERENCED, false); |
2014 | 0 | return false; |
2015 | 0 | } |
2016 | | |
2017 | 7.30k | current_pps = pps[pps_id]; |
2018 | 7.30k | current_sps = sps[ (int)current_pps->seq_parameter_set_id ]; |
2019 | 7.30k | current_vps = vps[ (int)current_sps->video_parameter_set_id ]; |
2020 | | |
2021 | 7.30k | calc_tid_and_framerate_ratio(); |
2022 | | |
2023 | | |
2024 | | // --- prepare decoding of new picture --- |
2025 | | |
2026 | 7.30k | if (hdr->first_slice_segment_in_pic_flag) { |
2027 | | |
2028 | | // previous picture has been completely decoded |
2029 | | |
2030 | | //ctx->push_current_picture_to_output_queue(); |
2031 | | |
2032 | 7.18k | current_image_poc_lsb = hdr->slice_pic_order_cnt_lsb; |
2033 | | |
2034 | | |
2035 | 7.18k | seq_parameter_set* sps = current_sps.get(); |
2036 | | |
2037 | | |
2038 | | // --- find and allocate image buffer for decoding --- |
2039 | | |
2040 | 7.18k | int image_buffer_idx; |
2041 | 7.18k | bool isOutputImage = (!sps->sample_adaptive_offset_enabled_flag || param_disable_sao); |
2042 | 7.18k | image_buffer_idx = dpb.new_image(current_sps, this, pts, user_data, isOutputImage); |
2043 | 7.18k | if (image_buffer_idx < 0) { |
2044 | 7 | *err = (de265_error)(-image_buffer_idx); |
2045 | 7 | return false; |
2046 | 7 | } |
2047 | | |
2048 | 7.17k | /*de265_image* */ img = dpb.get_image(image_buffer_idx); |
2049 | 7.17k | img->nal_hdr = *nal_hdr; |
2050 | | |
2051 | | // Note: sps is already set in new_image() -> ??? still the case with shared_ptr ? |
2052 | | |
2053 | 7.17k | img->set_headers(current_vps, current_sps, current_pps); |
2054 | | |
2055 | 7.17k | img->decctx = this; |
2056 | | |
2057 | 7.17k | img->clear_metadata(); |
2058 | | |
2059 | | |
2060 | 7.17k | if (isIRAP(nal_unit_type)) { |
2061 | 7.13k | if (isIDR(nal_unit_type) || |
2062 | 7.13k | isBLA(nal_unit_type) || |
2063 | 7.13k | first_decoded_picture || |
2064 | 7.13k | FirstAfterEndOfSequenceNAL) |
2065 | 7.12k | { |
2066 | 7.12k | NoRaslOutputFlag = true; |
2067 | 7.12k | FirstAfterEndOfSequenceNAL = false; |
2068 | 7.12k | } |
2069 | 5 | else if (0) // TODO: set HandleCraAsBlaFlag by external means |
2070 | 0 | { |
2071 | 0 | } |
2072 | 5 | else |
2073 | 5 | { |
2074 | 5 | NoRaslOutputFlag = false; |
2075 | 5 | HandleCraAsBlaFlag = false; |
2076 | 5 | } |
2077 | 7.13k | } |
2078 | | |
2079 | | |
2080 | 7.17k | if (isRASL(nal_unit_type) && |
2081 | 7.17k | NoRaslOutputFlag) |
2082 | 2 | { |
2083 | 2 | img->PicOutputFlag = false; |
2084 | 2 | } |
2085 | 7.17k | else |
2086 | 7.17k | { |
2087 | 7.17k | img->PicOutputFlag = !!hdr->pic_output_flag; |
2088 | 7.17k | } |
2089 | | |
2090 | 7.17k | process_picture_order_count(hdr); |
2091 | | |
2092 | 7.17k | if (hdr->first_slice_segment_in_pic_flag) { |
2093 | | // mark picture so that it is not overwritten by unavailable reference frames |
2094 | 7.17k | img->PicState = UsedForShortTermReference; |
2095 | | |
2096 | 7.17k | *err = process_reference_picture_set(hdr); |
2097 | 7.17k | if (*err != DE265_OK) { |
2098 | 0 | return false; |
2099 | 0 | } |
2100 | 7.17k | } |
2101 | | |
2102 | 7.17k | img->PicState = UsedForShortTermReference; |
2103 | | |
2104 | 7.17k | log_set_current_POC(img->PicOrderCntVal); |
2105 | | |
2106 | | |
2107 | | // next image is not the first anymore |
2108 | | |
2109 | 7.17k | first_decoded_picture = false; |
2110 | 7.17k | } |
2111 | 126 | else { |
2112 | | // claims to be not the first slice, but there is no active image available |
2113 | | |
2114 | 126 | if (img == NULL) { |
2115 | 13 | return false; |
2116 | 13 | } |
2117 | 126 | } |
2118 | | |
2119 | 7.28k | if (hdr->slice_type == SLICE_TYPE_B || |
2120 | 7.28k | hdr->slice_type == SLICE_TYPE_P) |
2121 | 4.68k | { |
2122 | 4.68k | bool success = construct_reference_picture_lists(hdr); |
2123 | 4.68k | if (!success) { |
2124 | 130 | return false; |
2125 | 130 | } |
2126 | 4.68k | } |
2127 | | |
2128 | | //printf("process slice segment header\n"); |
2129 | | |
2130 | 7.15k | loginfo(LogHeaders,"end of process-slice-header\n"); |
2131 | 7.15k | dpb.log_dpb_content(); |
2132 | | |
2133 | | |
2134 | 7.15k | if (hdr->dependent_slice_segment_flag==0) { |
2135 | 7.12k | hdr->SliceAddrRS = hdr->slice_segment_address; |
2136 | 7.12k | } else { |
2137 | 35 | hdr->SliceAddrRS = previous_slice_header->SliceAddrRS; |
2138 | 35 | } |
2139 | | |
2140 | 7.15k | previous_slice_header = hdr; |
2141 | | |
2142 | | |
2143 | 7.15k | loginfo(LogHeaders,"SliceAddrRS = %d\n",hdr->SliceAddrRS); |
2144 | | |
2145 | 7.15k | return true; |
2146 | 7.28k | } |
2147 | | |
2148 | | |
2149 | | void decoder_context::remove_images_from_dpb(const std::vector<int>& removeImageList) |
2150 | 11.2k | { |
2151 | 11.5k | for (size_t i=0;i<removeImageList.size();i++) { |
2152 | 338 | int idx = dpb.DPB_index_of_picture_with_ID( removeImageList[i] ); |
2153 | 338 | if (idx>=0) { |
2154 | | //printf("remove ID %d\n", removeImageList[i]); |
2155 | 338 | de265_image* dpbimg = dpb.get_image( idx ); |
2156 | 338 | dpbimg->PicState = UnusedForReference; |
2157 | 338 | } |
2158 | 338 | } |
2159 | 11.2k | } |
2160 | | |
2161 | | |
2162 | | |
2163 | | /* |
2164 | | . 0 1 2 <- goal_HighestTid |
2165 | | +-----+-----+-----+ |
2166 | | | -0->| -1->| -2->| |
2167 | | +-----+-----+-----+ |
2168 | | 0 33 66 100 <- framerate_ratio |
2169 | | */ |
2170 | | |
2171 | | int decoder_context::get_highest_TID() const |
2172 | 23.2k | { |
2173 | 23.2k | if (current_sps) { return current_sps->sps_max_sub_layers-1; } |
2174 | 8.80k | if (current_vps) { return current_vps->vps_max_sub_layers-1; } |
2175 | | |
2176 | 8.80k | return 6; |
2177 | 8.80k | } |
2178 | | |
2179 | | void decoder_context::set_limit_TID(int max_tid) |
2180 | 0 | { |
2181 | 0 | limit_HighestTid = max_tid; |
2182 | 0 | calc_tid_and_framerate_ratio(); |
2183 | 0 | } |
2184 | | |
2185 | | int decoder_context::change_framerate(int more) |
2186 | 0 | { |
2187 | 0 | if (current_sps == NULL) { return framerate_ratio; } |
2188 | | |
2189 | 0 | int highestTid = get_highest_TID(); |
2190 | |
|
2191 | 0 | assert(more>=-1 && more<=1); |
2192 | | |
2193 | 0 | goal_HighestTid += more; |
2194 | 0 | goal_HighestTid = std::max(goal_HighestTid, 0); |
2195 | 0 | goal_HighestTid = std::min(goal_HighestTid, highestTid); |
2196 | |
|
2197 | 0 | framerate_ratio = framedrop_tid_index[goal_HighestTid]; |
2198 | |
|
2199 | 0 | calc_tid_and_framerate_ratio(); |
2200 | |
|
2201 | 0 | return framerate_ratio; |
2202 | 0 | } |
2203 | | |
2204 | | void decoder_context::set_framerate_ratio(int percent) |
2205 | 0 | { |
2206 | 0 | framerate_ratio = percent; |
2207 | 0 | calc_tid_and_framerate_ratio(); |
2208 | 0 | } |
2209 | | |
2210 | | void decoder_context::compute_framedrop_table() |
2211 | 15.9k | { |
2212 | 15.9k | int highestTID = get_highest_TID(); |
2213 | | |
2214 | 84.9k | for (int tid=highestTID ; tid>=0 ; tid--) { |
2215 | 68.9k | int lower = 100 * tid /(highestTID+1); |
2216 | 68.9k | int higher = 100 * (tid+1)/(highestTID+1); |
2217 | | |
2218 | 1.73M | for (int l=lower; l<=higher; l++) { |
2219 | 1.66M | int ratio = 100 * (l-lower) / (higher-lower); |
2220 | | |
2221 | | // if we would exceed our TID limit, decode the highest TID at full frame-rate |
2222 | 1.66M | if (tid > limit_HighestTid) { |
2223 | 0 | tid = limit_HighestTid; |
2224 | 0 | ratio = 100; |
2225 | 0 | } |
2226 | | |
2227 | 1.66M | framedrop_tab[l].tid = tid; |
2228 | 1.66M | framedrop_tab[l].ratio = ratio; |
2229 | 1.66M | } |
2230 | | |
2231 | 68.9k | framedrop_tid_index[tid] = higher; |
2232 | 68.9k | } |
2233 | | |
2234 | | #if 0 |
2235 | | for (int i=0;i<=100;i++) { |
2236 | | printf("%d%%: %d/%d",i, framedrop_tab[i].tid, framedrop_tab[i].ratio); |
2237 | | for (int k=0;k<=highestTID;k++) { |
2238 | | if (framedrop_tid_index[k] == i) printf(" ** TID=%d **",k); |
2239 | | } |
2240 | | printf("\n"); |
2241 | | } |
2242 | | #endif |
2243 | 15.9k | } |
2244 | | |
2245 | | void decoder_context::calc_tid_and_framerate_ratio() |
2246 | 7.30k | { |
2247 | 7.30k | int highestTID = get_highest_TID(); |
2248 | | |
2249 | | |
2250 | | // if number of temporal layers changed, we have to recompute the framedrop table |
2251 | | |
2252 | 7.30k | if (framedrop_tab[100].tid != highestTID) { |
2253 | 7.14k | compute_framedrop_table(); |
2254 | 7.14k | } |
2255 | | |
2256 | 7.30k | goal_HighestTid = framedrop_tab[framerate_ratio].tid; |
2257 | 7.30k | layer_framerate_ratio = framedrop_tab[framerate_ratio].ratio; |
2258 | | |
2259 | | // TODO: for now, we switch immediately |
2260 | 7.30k | current_HighestTid = goal_HighestTid; |
2261 | 7.30k | } |
2262 | | |
2263 | | |
2264 | | void error_queue::add_warning(de265_error warning, bool once) |
2265 | 22.6k | { |
2266 | | // check if warning was already shown |
2267 | 22.6k | bool add=true; |
2268 | 22.6k | if (once) { |
2269 | 4.05k | for (int i=0;i<nWarningsShown;i++) { |
2270 | 93 | if (warnings_shown[i] == warning) { |
2271 | 93 | add=false; |
2272 | 93 | break; |
2273 | 93 | } |
2274 | 93 | } |
2275 | 4.05k | } |
2276 | | |
2277 | 22.6k | if (!add) { |
2278 | 93 | return; |
2279 | 93 | } |
2280 | | |
2281 | | |
2282 | | // if this is a one-time warning, remember that it was shown |
2283 | | |
2284 | 22.5k | if (once) { |
2285 | 3.96k | if (nWarningsShown < MAX_WARNINGS) { |
2286 | 3.96k | warnings_shown[nWarningsShown++] = warning; |
2287 | 3.96k | } |
2288 | 3.96k | } |
2289 | | |
2290 | | |
2291 | | // add warning to output queue |
2292 | | |
2293 | 22.5k | if (nWarnings == MAX_WARNINGS) { |
2294 | 3.00k | warnings[MAX_WARNINGS-1] = DE265_WARNING_WARNING_BUFFER_FULL; |
2295 | 3.00k | return; |
2296 | 3.00k | } |
2297 | | |
2298 | 19.5k | warnings[nWarnings++] = warning; |
2299 | 19.5k | } |
2300 | | |
2301 | | error_queue::error_queue() |
2302 | 8.80k | { |
2303 | 8.80k | nWarnings = 0; |
2304 | 8.80k | nWarningsShown = 0; |
2305 | 8.80k | } |
2306 | | |
2307 | | de265_error error_queue::get_warning() |
2308 | 0 | { |
2309 | 0 | if (nWarnings==0) { |
2310 | 0 | return DE265_OK; |
2311 | 0 | } |
2312 | | |
2313 | 0 | de265_error warn = warnings[0]; |
2314 | 0 | nWarnings--; |
2315 | 0 | memmove(warnings, &warnings[1], nWarnings*sizeof(de265_error)); |
2316 | |
|
2317 | 0 | return warn; |
2318 | 0 | } |