1
2 /*!
3 ***********************************************************************
4 * \file: h264_dpb_ctl.c
5 *
6 ***********************************************************************
7 */
8
9 #include "viddec_fw_debug.h"
10 #include "viddec_parser_ops.h"
11
12 #include "viddec_fw_workload.h"
13 #include "viddec_pm.h"
14 #include "viddec_h264_parse.h"
15
16
17
18 //#include <limits.h>
19 #include "h264parse.h"
20 #include "h264parse_dpb.h"
21 //#include "h264_debug.h"
22
23 #ifndef NULL
24 #define NULL 0
25 #endif
26 //#ifndef USER_MODE
27 //#define NULL 0
28 //#endif
29
30 ////////////////////////// Declare Globals///////////////////////////////
31 frame_store *active_fs;
32
33 /* ------------------------------------------------------------------------------------------ */
34 /* ------------------------------------------------------------------------------------------ */
35 /* ------------------------------------------------------------------------------------------ */
36 ///////////////////////// DPB init //////////////////////////////////////////
37 //////////////////////////////////////////////////////////////////////////////
38 // Init DPB
39 // Description: init dpb, which should be called while open
40 //
41 //////////////////////////////////////////////////////////////////////////////
42
h264_init_dpb(h264_DecodedPictureBuffer * p_dpb)43 void h264_init_dpb(h264_DecodedPictureBuffer * p_dpb)
44 {
45 int32_t i;
46
47 //// Init DPB to zero
48 //h264_memset(p_dpb, 0x0, sizeof(h264_DecodedPictureBuffer) );
49
50
51 for(i=0;i<NUM_DPB_FRAME_STORES;i++)
52 {
53 p_dpb->fs[i].fs_idc = MPD_DPB_FS_NULL_IDC;
54 p_dpb->fs_dpb_idc[i] = MPD_DPB_FS_NULL_IDC;
55 }
56 p_dpb->used_size = 0;
57 p_dpb->fs_dec_idc = MPD_DPB_FS_NULL_IDC;
58 p_dpb->fs_non_exist_idc = MPD_DPB_FS_NULL_IDC;
59
60 return;
61 }
62
63
64 ///////////////////////// Reference list management //////////////////////////
65
66 /* ------------------------------------------------------------------------------------------ */
67 /* ------------------------------------------------------------------------------------------ */
68 /* ------------------------------------------------------------------------------------------ */
69 //////////////////////////////////////////////////////////////////////////////
70 // h264_dpb_add_ref_list ()
71 //
72 // Adds an idc to the long term reference list
73 //////////////////////////////////////////////////////////////////////////////
h264_dpb_add_ref_list(h264_DecodedPictureBuffer * p_dpb,int32_t ref_idc)74 void h264_dpb_add_ref_list(h264_DecodedPictureBuffer * p_dpb, int32_t ref_idc)
75 {
76 p_dpb->fs_ref_idc[p_dpb->ref_frames_in_buffer] = ref_idc;
77 p_dpb->ref_frames_in_buffer++;
78 }
79 /* ------------------------------------------------------------------------------------------ */
80 /* ------------------------------------------------------------------------------------------ */
81 /* ------------------------------------------------------------------------------------------ */
82 //////////////////////////////////////////////////////////////////////////////
83 // h264_dpb_add_ltref_list ()
84 //
85 // Adds an idc to the long term reference list
86 //////////////////////////////////////////////////////////////////////////////
h264_dpb_add_ltref_list(h264_DecodedPictureBuffer * p_dpb,int32_t ref_idc)87 void h264_dpb_add_ltref_list(h264_DecodedPictureBuffer * p_dpb, int32_t ref_idc)
88 {
89 p_dpb->fs_ltref_idc[p_dpb->ltref_frames_in_buffer] = ref_idc;
90 p_dpb->ltref_frames_in_buffer++;
91 }
92 /* ------------------------------------------------------------------------------------------ */
93 /* ------------------------------------------------------------------------------------------ */
94 /* ------------------------------------------------------------------------------------------ */
95 //////////////////////////////////////////////////////////////////////////////
96 // h264_dpb_update_all_ref_lists (h264_DecodedPictureBuffer * p_dpb,int32_t NonExisting)
97 //
98 // Decide whether the current picture needs to be added to the reference lists
99 // active_fs should be set-up prior to calling this function
100 //
101 // Check if we need to search the lists here
102 // or can we go straight to adding to ref lists..
103 //////////////////////////////////////////////////////////////////////////////
104
h264_dpb_insert_ref_lists(h264_DecodedPictureBuffer * p_dpb,int32_t NonExisting)105 void h264_dpb_insert_ref_lists(h264_DecodedPictureBuffer * p_dpb, int32_t NonExisting)
106 {
107 if(NonExisting)
108 h264_dpb_set_active_fs(p_dpb,p_dpb->fs_non_exist_idc);
109 else
110 h264_dpb_set_active_fs(p_dpb, p_dpb->fs_dec_idc);
111
112 //if(active_fs->is_reference)
113 if(active_fs->frame.used_for_reference)
114 {
115 if(viddec_h264_get_is_long_term(active_fs))
116 {
117 if(viddec_h264_get_dec_structure(active_fs) == FRAME)
118 h264_dpb_add_ltref_list(p_dpb, active_fs->fs_idc);
119 else
120 {
121 uint32_t found_in_list = 0, i = 0;
122 for (i = 0; (i < p_dpb->ltref_frames_in_buffer) && (found_in_list == 0); i++) {
123 if(p_dpb->fs_ltref_idc[i] == active_fs->fs_idc) found_in_list = 1;
124 }
125
126 if(found_in_list == 0) h264_dpb_add_ltref_list(p_dpb, active_fs->fs_idc);
127 }
128 }
129 else
130 {
131 if(viddec_h264_get_dec_structure(active_fs) == FRAME) {
132 h264_dpb_add_ref_list(p_dpb, active_fs->fs_idc);
133 } else
134 {
135 uint32_t found_in_list = 0, i = 0;
136
137 for (i = 0; (i < p_dpb->ref_frames_in_buffer) && (found_in_list == 0); i++)
138 {
139 if(p_dpb->fs_ref_idc[i] == active_fs->fs_idc) found_in_list = 1;
140 }
141
142 if(found_in_list == 0) h264_dpb_add_ref_list(p_dpb, active_fs->fs_idc);
143 }
144 }
145 }
146
147 return;
148
149 }
150
151 /* ------------------------------------------------------------------------------------------ */
152 /* ------------------------------------------------------------------------------------------ */
153 /* ------------------------------------------------------------------------------------------ */
154 //////////////////////////////////////////////////////////////////////////////
155 // Set active fs
156 //////////////////////////////////////////////////////////////////////////////
157
h264_dpb_set_active_fs(h264_DecodedPictureBuffer * p_dpb,int32_t index)158 void h264_dpb_set_active_fs(h264_DecodedPictureBuffer * p_dpb, int32_t index)
159 {
160 active_fs = &p_dpb->fs[index];
161 }
162 /* ------------------------------------------------------------------------------------------ */
163 /* ------------------------------------------------------------------------------------------ */
164 /* ------------------------------------------------------------------------------------------ */
165 //////////////////////////////////////////////////////////////////////////////
166 // Sort reference list
167 //////////////////////////////////////////////////////////////////////////////
168
h264_list_sort(uint8_t * list,int32_t * sort_indices,int32_t size,int32_t desc)169 void h264_list_sort(uint8_t *list, int32_t *sort_indices, int32_t size, int32_t desc)
170 {
171 int32_t j, k, temp, idc;
172
173 // Dodgy looking for embedded code here...
174 if(size > 1)
175 {
176 for (j = 0; j < size-1; j = j + 1) {
177 for (k = j + 1; k < size; k = k + 1) {
178 if ((desc & (sort_indices[j] < sort_indices[k]))|
179 (~desc & (sort_indices[j] > sort_indices[k])) )
180 {
181 temp = sort_indices[k];
182 sort_indices[k] = sort_indices[j];
183 sort_indices[j] = temp;
184 idc = list[k];
185 list[k] = list[j];
186 list[j] = idc;
187 }
188 }
189 }
190 }
191 }
192
193 /* ------------------------------------------------------------------------------------------ */
194 /* ------------------------------------------------------------------------------------------ */
195 /* ------------------------------------------------------------------------------------------ */
196 //////////////////////////////////////////////////////////////////////////////
197 // h264_dpb_pic_is_bottom_field_ref ()
198 //
199 // Used to sort a list based on a corresponding sort indices
200 //////////////////////////////////////////////////////////////////////////////
201
h264_dpb_pic_is_bottom_field_ref(int32_t long_term)202 int32_t h264_dpb_pic_is_bottom_field_ref(int32_t long_term)
203 {
204 int32_t temp;
205 if(long_term) temp = ((active_fs->bottom_field.used_for_reference) && (active_fs->bottom_field.is_long_term)) ? 1 : 0;
206 else temp = ((active_fs->bottom_field.used_for_reference) && !(active_fs->bottom_field.is_long_term)) ? 1 : 0;
207
208 return temp;
209 }
210 /* ------------------------------------------------------------------------------------------ */
211 /* ------------------------------------------------------------------------------------------ */
212 /* ------------------------------------------------------------------------------------------ */
213 //////////////////////////////////////////////////////////////////////////////
214 // h264_dpb_pic_is_top_field_ref ()
215 //
216 // Used to sort a list based on a corresponding sort indices
217 //////////////////////////////////////////////////////////////////////////////
218
h264_dpb_pic_is_top_field_ref(int32_t long_term)219 int32_t h264_dpb_pic_is_top_field_ref(int32_t long_term)
220 {
221 int32_t temp;
222 if(long_term)
223 temp = ((active_fs->top_field.used_for_reference) && (active_fs->top_field.is_long_term)) ? 1 : 0;
224 else
225 temp = ((active_fs->top_field.used_for_reference) && !(active_fs->top_field.is_long_term)) ? 1 : 0;
226
227 return temp;
228 }
229
230
231 /* ------------------------------------------------------------------------------------------ */
232 /* ------------------------------------------------------------------------------------------ */
233 /* ------------------------------------------------------------------------------------------ */
234 //////////////////////////////////////////////////////////////////////////////
235 // h264_dpb_gen_pic_list_from_frame_list ()
236 //
237 // Used to sort a list based on a corresponding sort indices
238 //////////////////////////////////////////////////////////////////////////////
239
h264_dpb_gen_pic_list_from_frame_list(h264_DecodedPictureBuffer * p_dpb,uint8_t * pic_list,uint8_t * frame_list,int32_t currPicStructure,int32_t list_size,int32_t long_term)240 int32_t h264_dpb_gen_pic_list_from_frame_list(h264_DecodedPictureBuffer *p_dpb, uint8_t *pic_list, uint8_t *frame_list, int32_t currPicStructure, int32_t list_size, int32_t long_term)
241 {
242 int32_t top_idx, bot_idx, got_pic, list_idx;
243 int32_t lterm;
244
245 list_idx = 0;
246 lterm = (long_term)? 1:0;
247
248 if(list_size){
249
250
251 top_idx = 0;
252 bot_idx = 0;
253
254 if (currPicStructure == TOP_FIELD) {
255 while ((top_idx < list_size)||(bot_idx < list_size))
256 {
257 /////////////////////////////////////////// ref Top Field
258 got_pic = 0;
259 while ((top_idx < list_size) & ~got_pic)
260 {
261 h264_dpb_set_active_fs(p_dpb, frame_list[top_idx]);
262 if ((viddec_h264_get_is_used(active_fs))&0x1)
263 {
264 if(h264_dpb_pic_is_top_field_ref(long_term))
265 {
266 pic_list[list_idx] = PUT_LIST_LONG_TERM_BITS(lterm) + frame_list[top_idx] + PUT_LIST_INDEX_FIELD_BIT(0); // top_field
267 list_idx++;
268 got_pic = 1;
269 }
270 }
271 top_idx++;
272 }
273
274 /////////////////////////////////////////// ref Bottom Field
275 got_pic = 0;
276 while ((bot_idx < list_size) & ~got_pic)
277 {
278 h264_dpb_set_active_fs(p_dpb, frame_list[bot_idx]);
279 if ((viddec_h264_get_is_used(active_fs))&0x2)
280 {
281 if(h264_dpb_pic_is_bottom_field_ref(long_term))
282 {
283 pic_list[list_idx] = PUT_LIST_LONG_TERM_BITS(lterm) + frame_list[bot_idx] + PUT_LIST_INDEX_FIELD_BIT(1); // bottom_field
284 list_idx++;
285 got_pic = 1;
286 }
287 }
288 bot_idx++;
289 }
290 }
291 }
292
293 /////////////////////////////////////////////// current Bottom Field
294 if (currPicStructure == BOTTOM_FIELD) {
295 while ((top_idx < list_size)||(bot_idx < list_size))
296 {
297 /////////////////////////////////////////// ref Top Field
298 got_pic = 0;
299 while ((bot_idx < list_size) && (!(got_pic)))
300 {
301 h264_dpb_set_active_fs(p_dpb, frame_list[bot_idx]);
302 if ((viddec_h264_get_is_used(active_fs))&0x2) {
303 if(h264_dpb_pic_is_bottom_field_ref(long_term)) {
304 // short term ref pic
305 pic_list[list_idx] = PUT_LIST_LONG_TERM_BITS(lterm) + frame_list[bot_idx] + PUT_LIST_INDEX_FIELD_BIT(1); // bottom_field
306 list_idx++;
307 got_pic = 1;
308 }
309 }
310 bot_idx++;
311 }
312
313 /////////////////////////////////////////// ref Bottom Field
314 got_pic = 0;
315 while ((top_idx < list_size) && (!(got_pic)))
316 {
317 h264_dpb_set_active_fs(p_dpb, frame_list[top_idx]);
318 if ((viddec_h264_get_is_used(active_fs))&0x1) {
319 if(h264_dpb_pic_is_top_field_ref(long_term)){
320 // short term ref pic
321 pic_list[list_idx] = PUT_LIST_LONG_TERM_BITS(lterm) + frame_list[top_idx] + PUT_LIST_INDEX_FIELD_BIT(0); // top_field
322 list_idx++;
323 got_pic = 1;
324 }
325 }
326 top_idx++;
327 }
328 }
329 }
330 }
331
332 return list_idx;
333 }
334
335 /* ------------------------------------------------------------------------------------------ */
336 /* ------------------------------------------------------------------------------------------ */
337 /* ------------------------------------------------------------------------------------------ */
338 //////////////////////////////////////////////////////////////////////////////
339 // h264_dpb_remove_ref_list ()
340 //
341 // Removes an idc from the refernce list and updates list after
342 //
343
h264_dpb_remove_ref_list(h264_DecodedPictureBuffer * p_dpb,int32_t ref_idc)344 void h264_dpb_remove_ref_list(h264_DecodedPictureBuffer * p_dpb, int32_t ref_idc)
345 {
346 uint8_t idx = 0;
347 int32_t Found = 0;
348
349 while ((idx < p_dpb->ref_frames_in_buffer) && (!(Found)))
350 {
351 if (p_dpb->fs_ref_idc[idx] == ref_idc)
352 Found = 1;
353 else
354 idx++;
355 }
356
357 if (Found)
358 {
359 // Move the remainder of the list up one
360 while(idx < p_dpb->ref_frames_in_buffer - 1) {
361 p_dpb->fs_ref_idc[idx] = p_dpb->fs_ref_idc[idx + 1];
362 idx ++;
363 }
364
365 p_dpb->fs_ref_idc[idx] = MPD_DPB_FS_NULL_IDC; // Clear the last one
366 p_dpb->ref_frames_in_buffer--;
367 }
368
369 return;
370 }
371 /* ------------------------------------------------------------------------------------------ */
372 /* ------------------------------------------------------------------------------------------ */
373 /* ------------------------------------------------------------------------------------------ */
374 //////////////////////////////////////////////////////////////////////////////
375 // h264_dpb_remove_ltref_list ()
376 //
377 // Removes an idc from the long term reference list and updates list after
378 //////////////////////////////////////////////////////////////////////////////
379
h264_dpb_remove_ltref_list(h264_DecodedPictureBuffer * p_dpb,int32_t ref_idc)380 void h264_dpb_remove_ltref_list(h264_DecodedPictureBuffer * p_dpb,int32_t ref_idc)
381 {
382 uint8_t idx = 0;
383 int32_t Found = 0;
384
385 while ((idx < p_dpb->ltref_frames_in_buffer) && (!(Found)))
386 {
387 if (p_dpb->fs_ltref_idc[idx] == ref_idc) Found = 1;
388 else idx++;
389 }
390
391 if (Found)
392 {
393 // Move the remainder of the list up one
394 while(idx <(uint8_t)(p_dpb->ltref_frames_in_buffer - 1))
395 {
396 p_dpb->fs_ltref_idc[idx] = p_dpb->fs_ltref_idc[idx + 1];
397 idx ++;
398 }
399 p_dpb->fs_ltref_idc[idx] = MPD_DPB_FS_NULL_IDC; // Clear the last one
400
401 p_dpb->ltref_frames_in_buffer--;
402 }
403
404 return;
405 }
406
407
408 /* ------------------------------------------------------------------------------------------ */
409 /* ------------------------------------------------------------------------------------------ */
410 /* ------------------------------------------------------------------------------------------ */
411 //////////////////////////////////////////////////////////////////////////////
412 // h264_dpb_init_lists ()
413 //
414 // Used to initialise the reference lists
415 // Also assigns picture numbers and long term picture numbers if P OR B slice
416 //////////////////////////////////////////////////////////////////////////////
h264_dpb_update_ref_lists(h264_Info * pInfo)417 void h264_dpb_update_ref_lists(h264_Info * pInfo)
418 {
419 h264_DecodedPictureBuffer * p_dpb = &pInfo->dpb;
420
421 int32_t MaxFrameNum = 1 << (pInfo->active_SPS.log2_max_frame_num_minus4 + 4);
422
423 uint8_t list0idx, list0idx_1, listltidx;
424 uint8_t idx;
425
426 uint8_t add_top, add_bottom, diff;
427 uint8_t list_idc;
428 uint8_t check_non_existing, skip_picture;
429
430
431 uint8_t gen_pic_fs_list0[16];
432 uint8_t gen_pic_fs_list1[16];
433 uint8_t gen_pic_fs_listlt[16];
434 uint8_t gen_pic_pic_list[32]; // check out these sizes...
435
436 uint8_t sort_fs_idc[16];
437 int32_t list_sort_number[16];
438
439 #ifdef DUMP_HEADER_INFO
440 static int cc1 = 0;
441 //OS_INFO("-------------cc1= %d\n",cc1); /////// DEBUG info
442 if(cc1 == 255)
443 idx = 0;
444 #endif
445
446 list0idx = list0idx_1 = listltidx = 0;
447
448 if (pInfo->SliceHeader.structure == FRAME)
449 {
450 ////////////////////////////////////////////////// short term handling
451 for (idx = 0; idx < p_dpb->ref_frames_in_buffer; idx++)
452 {
453 h264_dpb_set_active_fs(p_dpb, p_dpb->fs_ref_idc[idx]);
454
455 if((viddec_h264_get_is_used(active_fs) == 3)&&(active_fs->frame.used_for_reference == 3))
456 {
457 if (active_fs->frame_num > pInfo->img.frame_num)
458 active_fs->frame_num_wrap = active_fs->frame_num - MaxFrameNum;
459 else
460 active_fs->frame_num_wrap = active_fs->frame_num;
461
462 active_fs->frame.pic_num = active_fs->frame_num_wrap;
463
464 // Use this opportunity to sort list for a p-frame
465 if(pInfo->SliceHeader.slice_type == h264_PtypeP)
466 {
467 sort_fs_idc[list0idx] = p_dpb->fs_ref_idc[idx];
468 list_sort_number[list0idx] = active_fs->frame.pic_num;
469 list0idx++;
470 }
471 }
472 }
473
474 if(pInfo->SliceHeader.slice_type == h264_PtypeP)
475 {
476 h264_list_sort(sort_fs_idc, list_sort_number, list0idx, 1);
477 for (idx = 0; idx < list0idx; idx++)
478 p_dpb->listX_0[idx] = (sort_fs_idc[idx]); // frame
479
480 p_dpb->listXsize[0] = list0idx;
481 }
482
483 ////////////////////////////////////////////////// long term handling
484 for (idx = 0; idx < p_dpb->ltref_frames_in_buffer; idx++)
485 {
486 h264_dpb_set_active_fs(p_dpb, p_dpb->fs_ltref_idc[idx]);
487 if ((viddec_h264_get_is_used(active_fs) == 3) && (viddec_h264_get_is_long_term(active_fs) == 3) && (active_fs->frame.used_for_reference == 3))
488 {
489 active_fs->frame.long_term_pic_num = active_fs->frame.long_term_frame_idx;
490
491 if(pInfo->SliceHeader.slice_type == h264_PtypeP)
492 {
493 sort_fs_idc[list0idx-p_dpb->listXsize[0]] = p_dpb->fs_ltref_idc[idx];
494 list_sort_number[list0idx-p_dpb->listXsize[0]] = active_fs->frame.long_term_pic_num;
495 list0idx++;
496 }
497 }
498 }
499
500 if(pInfo->SliceHeader.slice_type == h264_PtypeP)
501 {
502 h264_list_sort(sort_fs_idc, list_sort_number, list0idx-p_dpb->listXsize[0], 0);
503 for (idx = p_dpb->listXsize[0]; idx < list0idx; idx++) {
504 p_dpb->listX_0[idx] = (1<<6) + sort_fs_idc[idx-p_dpb->listXsize[0]];
505 }
506 p_dpb->listXsize[0] = list0idx;
507 }
508 }
509 else /// Field base
510 {
511 if (pInfo->SliceHeader.structure == TOP_FIELD)
512 {
513 add_top = 1;
514 add_bottom = 0;
515 }
516 else
517 {
518 add_top = 0;
519 add_bottom = 1;
520 }
521
522 ////////////////////////////////////////////P0: Short term handling
523 for (idx = 0; idx < p_dpb->ref_frames_in_buffer; idx++)
524 {
525 h264_dpb_set_active_fs(p_dpb, p_dpb->fs_ref_idc[idx]);
526 if (active_fs->frame.used_for_reference)
527 {
528 if(active_fs->frame_num > pInfo->SliceHeader.frame_num) {
529 active_fs->frame_num_wrap = active_fs->frame_num - MaxFrameNum;
530 } else {
531 active_fs->frame_num_wrap = active_fs->frame_num;
532 }
533
534 if ((active_fs->frame.used_for_reference)&0x1) {
535 active_fs->top_field.pic_num = (active_fs->frame_num_wrap << 1) + add_top;
536 }
537
538 if ((active_fs->frame.used_for_reference)&0x2) {
539 active_fs->bottom_field.pic_num = (active_fs->frame_num_wrap << 1) + add_bottom;
540 }
541
542 if(pInfo->SliceHeader.slice_type == h264_PtypeP) {
543 sort_fs_idc[list0idx] = p_dpb->fs_ref_idc[idx];
544 list_sort_number[list0idx] = active_fs->frame_num_wrap;
545 list0idx++;
546 }
547 }
548 }
549
550 if(pInfo->SliceHeader.slice_type == h264_PtypeP)
551 {
552 h264_list_sort(sort_fs_idc, list_sort_number, list0idx, 1);
553 for (idx = 0; idx < list0idx; idx++) {
554 gen_pic_fs_list0[idx] = sort_fs_idc[idx];
555 }
556
557 p_dpb->listXsize[0] = 0;
558 p_dpb->listXsize[0] = h264_dpb_gen_pic_list_from_frame_list(p_dpb, gen_pic_pic_list, gen_pic_fs_list0, pInfo->img.structure, list0idx, 0);
559
560 for (idx = 0; idx < p_dpb->listXsize[0]; idx++)
561 {
562 p_dpb->listX_0[idx] = gen_pic_pic_list[idx];
563 }
564 }
565
566 ////////////////////////////////////////////P0: long term handling
567 for (idx = 0; idx < p_dpb->ltref_frames_in_buffer; idx++)
568 {
569 h264_dpb_set_active_fs(p_dpb, p_dpb->fs_ltref_idc[idx]);
570
571 if (viddec_h264_get_is_long_term(active_fs)&0x1) {
572 active_fs->top_field.long_term_pic_num = (active_fs->top_field.long_term_frame_idx << 1) + add_top;
573 }
574
575 if (viddec_h264_get_is_long_term(active_fs)&0x2) {
576 active_fs->bottom_field.long_term_pic_num = (active_fs->bottom_field.long_term_frame_idx << 1) + add_bottom;
577 }
578
579 if(pInfo->SliceHeader.slice_type == h264_PtypeP)
580 {
581 sort_fs_idc[listltidx] = p_dpb->fs_ltref_idc[idx];
582 list_sort_number[listltidx] = active_fs->long_term_frame_idx;
583 listltidx++;
584 }
585 }
586
587 if(pInfo->SliceHeader.slice_type == h264_PtypeP)
588 {
589 h264_list_sort(sort_fs_idc, list_sort_number, listltidx, 0);
590 for (idx = 0; idx < listltidx; idx++) {
591 gen_pic_fs_listlt[idx] = sort_fs_idc[idx];
592 }
593 list0idx_1 = h264_dpb_gen_pic_list_from_frame_list(p_dpb, gen_pic_pic_list, gen_pic_fs_listlt, pInfo->img.structure, listltidx, 1);
594
595 for (idx = 0; idx < list0idx_1; idx++) {
596 p_dpb->listX_0[p_dpb->listXsize[0]+idx] = gen_pic_pic_list[idx];
597 }
598 p_dpb->listXsize[0] += list0idx_1;
599 }
600 }
601
602
603 if (pInfo->SliceHeader.slice_type == h264_PtypeI)
604 {
605 p_dpb->listXsize[0] = 0;
606 p_dpb->listXsize[1] = 0;
607 return;
608 }
609
610 if(pInfo->SliceHeader.slice_type == h264_PtypeP)
611 {
612 //// Forward done above
613 p_dpb->listXsize[1] = 0;
614 }
615
616
617 // B-Slice
618 // Do not include non-existing frames for B-pictures when cnt_type is zero
619
620 if(pInfo->SliceHeader.slice_type == h264_PtypeB)
621 {
622 list0idx = list0idx_1 = listltidx = 0;
623 skip_picture = 0;
624
625 if(pInfo->active_SPS.pic_order_cnt_type == 0)
626 check_non_existing = 1;
627 else
628 check_non_existing = 0;
629
630 if (pInfo->SliceHeader.structure == FRAME)
631 {
632 for (idx = 0; idx < p_dpb->ref_frames_in_buffer; idx++)
633 {
634 h264_dpb_set_active_fs(p_dpb, p_dpb->fs_ref_idc[idx]);
635 if (viddec_h264_get_is_used(active_fs) == 3)
636 {
637 if(check_non_existing)
638 {
639 if(viddec_h264_get_is_non_existent(active_fs)) skip_picture = 1;
640 else skip_picture = 0;
641 }
642
643 if(skip_picture == 0)
644 {
645 if ((active_fs->frame.used_for_reference==3) && (!(active_fs->frame.is_long_term)))
646 {
647 if (pInfo->img.framepoc >= active_fs->frame.poc)
648 {
649 sort_fs_idc[list0idx] = p_dpb->fs_ref_idc[idx];
650 list_sort_number[list0idx] = active_fs->frame.poc;
651 list0idx++;
652 }
653 }
654 }
655 }
656 }
657
658 h264_list_sort(sort_fs_idc, list_sort_number, list0idx, 1);
659 for (idx = 0; idx < list0idx; idx++) {
660 p_dpb->listX_0[idx] = sort_fs_idc[idx];
661 }
662
663 list0idx_1 = list0idx;
664
665 /////////////////////////////////////////B0: Short term handling
666 for (idx = 0; idx < p_dpb->ref_frames_in_buffer; idx++)
667 {
668 h264_dpb_set_active_fs(p_dpb, p_dpb->fs_ref_idc[idx]);
669
670 if (viddec_h264_get_is_used(active_fs) == 3)
671 {
672 if(check_non_existing)
673 {
674 if(viddec_h264_get_is_non_existent(active_fs)) skip_picture = 1;
675 else skip_picture = 0;
676 }
677
678 if(skip_picture == 0)
679 {
680 if ((active_fs->frame.used_for_reference) && (!(active_fs->frame.is_long_term)))
681 {
682 if (pInfo->img.framepoc < active_fs->frame.poc)
683 {
684 sort_fs_idc[list0idx-list0idx_1] = p_dpb->fs_ref_idc[idx];
685 list_sort_number[list0idx-list0idx_1] = active_fs->frame.poc;
686 list0idx++;
687 }
688 }
689 }
690 }
691 }
692
693 h264_list_sort(sort_fs_idc, list_sort_number, list0idx-list0idx_1, 0);
694 for (idx = list0idx_1; idx < list0idx; idx++) {
695 p_dpb->listX_0[idx] = sort_fs_idc[idx-list0idx_1];
696 }
697
698 for (idx = 0; idx < list0idx_1; idx++) {
699 p_dpb->listX_1[list0idx-list0idx_1+idx] = p_dpb->listX_0[idx];
700 }
701
702 for (idx = list0idx_1; idx < list0idx; idx++) {
703 p_dpb->listX_1[idx-list0idx_1] = p_dpb->listX_0[idx];
704 }
705
706 p_dpb->listXsize[0] = list0idx;
707 p_dpb->listXsize[1] = list0idx;
708
709 /////////////////////////////////////////B0: long term handling
710 list0idx = 0;
711
712 // Can non-existent pics be set as long term??
713 for (idx = 0; idx < p_dpb->ltref_frames_in_buffer; idx++)
714 {
715 h264_dpb_set_active_fs(p_dpb, p_dpb->fs_ltref_idc[idx]);
716
717 if ((viddec_h264_get_is_used(active_fs) == 3) && (viddec_h264_get_is_long_term(active_fs) == 3))
718 {
719 // if we have two fields, both must be long-term
720 sort_fs_idc[list0idx] = p_dpb->fs_ltref_idc[idx];
721 list_sort_number[list0idx] = active_fs->frame.long_term_pic_num;
722 list0idx++;
723 }
724 }
725
726 h264_list_sort(sort_fs_idc, list_sort_number, list0idx, 0);
727 for (idx = p_dpb->listXsize[0]; idx < (p_dpb->listXsize[0]+list0idx); idx = idx + 1)
728 {
729 p_dpb->listX_0[idx] = (1<<6) + sort_fs_idc[idx-p_dpb->listXsize[0]];
730 p_dpb->listX_1[idx] = (1<<6) + sort_fs_idc[idx-p_dpb->listXsize[0]];
731 }
732
733 p_dpb->listXsize[0] += list0idx;
734 p_dpb->listXsize[1] += list0idx;
735 }
736 else // Field
737 {
738 for (idx = 0; idx < p_dpb->ref_frames_in_buffer; idx++)
739 {
740 h264_dpb_set_active_fs(p_dpb, p_dpb->fs_ref_idc[idx]);
741
742 if (viddec_h264_get_is_used(active_fs)) {
743 if(check_non_existing) {
744 if(viddec_h264_get_is_non_existent(active_fs))
745 skip_picture = 1;
746 else
747 skip_picture = 0;
748 }
749
750 if(skip_picture == 0) {
751 if (pInfo->img.ThisPOC >= active_fs->frame.poc) {
752 sort_fs_idc[list0idx] = p_dpb->fs_ref_idc[idx];
753 list_sort_number[list0idx] = active_fs->frame.poc;
754 list0idx++;
755 }
756 }
757 }
758 }
759
760 h264_list_sort(sort_fs_idc, list_sort_number, list0idx, 1);
761 for (idx = 0; idx < list0idx; idx = idx + 1) {
762 gen_pic_fs_list0[idx] = sort_fs_idc[idx];
763 }
764
765 list0idx_1 = list0idx;
766
767 ///////////////////////////////////////////// B1: Short term handling
768 for (idx = 0; idx < p_dpb->ref_frames_in_buffer; idx++)
769 {
770 h264_dpb_set_active_fs(p_dpb, p_dpb->fs_ref_idc[idx]);
771 if (viddec_h264_get_is_used(active_fs))
772 {
773 if(check_non_existing) {
774 if(viddec_h264_get_is_non_existent(active_fs))
775 skip_picture = 1;
776 else
777 skip_picture = 0;
778 }
779
780 if(skip_picture == 0) {
781 if (pInfo->img.ThisPOC < active_fs->frame.poc) {
782 sort_fs_idc[list0idx-list0idx_1] = p_dpb->fs_ref_idc[idx];
783 list_sort_number[list0idx-list0idx_1] = active_fs->frame.poc;
784 list0idx++;
785 }
786 }
787 }
788 }
789
790 ///// Generate frame list from sorted fs
791 /////
792 h264_list_sort(sort_fs_idc, list_sort_number, list0idx-list0idx_1, 0);
793 for (idx = list0idx_1; idx < list0idx; idx++)
794 gen_pic_fs_list0[idx] = sort_fs_idc[idx-list0idx_1];
795
796 for (idx = 0; idx < list0idx_1; idx++)
797 gen_pic_fs_list1[list0idx-list0idx_1+idx] = gen_pic_fs_list0[idx];
798
799 for (idx = list0idx_1; idx < list0idx; idx++)
800 gen_pic_fs_list1[idx-list0idx_1] = gen_pic_fs_list0[idx];
801
802 ///// Generate List_X0
803 /////
804 p_dpb->listXsize[0] = h264_dpb_gen_pic_list_from_frame_list(p_dpb, gen_pic_pic_list, gen_pic_fs_list0, pInfo->img.structure, list0idx, 0);
805
806 for (idx = 0; idx < p_dpb->listXsize[0]; idx++)
807 p_dpb->listX_0[idx] = gen_pic_pic_list[idx];
808
809 //// Generate List X1
810 ////
811 p_dpb->listXsize[1] = h264_dpb_gen_pic_list_from_frame_list(p_dpb, gen_pic_pic_list, gen_pic_fs_list1, pInfo->img.structure, list0idx, 0);
812
813 for (idx = 0; idx < p_dpb->listXsize[1]; idx++)
814 p_dpb->listX_1[idx] = gen_pic_pic_list[idx];
815
816 ///////////////////////////////////////////// B1: long term handling
817 for (idx = 0; idx < p_dpb->ltref_frames_in_buffer; idx++)
818 {
819 h264_dpb_set_active_fs(p_dpb, p_dpb->fs_ltref_idc[idx]);
820 sort_fs_idc[listltidx] = p_dpb->fs_ltref_idc[idx];
821 list_sort_number[listltidx] = active_fs->long_term_frame_idx;
822 listltidx++;
823 }
824
825 h264_list_sort(sort_fs_idc, list_sort_number, listltidx, 0);
826 for (idx = 0; idx < listltidx; idx++)
827 gen_pic_fs_listlt[idx] = sort_fs_idc[idx];
828
829 list0idx_1 = h264_dpb_gen_pic_list_from_frame_list(p_dpb, gen_pic_pic_list, gen_pic_fs_listlt, pInfo->img.structure, listltidx, 1);
830
831 for (idx = 0; idx < list0idx_1; idx++)
832 {
833 p_dpb->listX_0[p_dpb->listXsize[0]+idx] = gen_pic_pic_list[idx];
834 p_dpb->listX_1[p_dpb->listXsize[1]+idx] = gen_pic_pic_list[idx];
835 }
836
837 p_dpb->listXsize[0] += list0idx_1;
838 p_dpb->listXsize[1] += list0idx_1;
839 }
840 }
841
842 // Setup initial list sizes at this point
843 p_dpb->nInitListSize[0] = p_dpb->listXsize[0];
844 p_dpb->nInitListSize[1] = p_dpb->listXsize[1];
845 if(pInfo->SliceHeader.slice_type != h264_PtypeI)
846 {
847 if ((p_dpb->listXsize[0]==p_dpb->listXsize[1]) && (p_dpb->listXsize[0] > 1))
848 {
849 // check if lists are identical, if yes swap first two elements of listX[1]
850 diff = 0;
851 for (idx = 0; idx < p_dpb->listXsize[0]; idx = idx + 1)
852 {
853 if (p_dpb->listX_0[idx] != p_dpb->listX_1[idx]) diff = 1;
854 }
855
856
857 if (!(diff))
858 {
859 list_idc = p_dpb->listX_1[0];
860 p_dpb->listX_1[0] = p_dpb->listX_1[1];
861 p_dpb->listX_1[1] = list_idc;
862 }
863 }
864
865 // set max size
866 if (p_dpb->listXsize[0] > pInfo->SliceHeader.num_ref_idx_l0_active)
867 {
868 p_dpb->listXsize[0] = pInfo->SliceHeader.num_ref_idx_l0_active;
869 }
870
871
872 if (p_dpb->listXsize[1] > pInfo->SliceHeader.num_ref_idx_l1_active)
873 {
874 p_dpb->listXsize[1] = pInfo->SliceHeader.num_ref_idx_l1_active;
875 }
876
877
878
879 }
880
881
882
883 /// DPB reorder list
884 h264_dpb_reorder_lists(pInfo);
885
886 return;
887 } //// End of init_dpb_list
888
889
890 /* ------------------------------------------------------------------------------------------ */
891 /* ------------------------------------------------------------------------------------------ */
892 /* ------------------------------------------------------------------------------------------ */
893 //////////////////////////////////////////////////////////////////////////////
894 // h264_dpb_get_short_term_pic ()
895 //
896 // Sets active_fs to point to frame store containing picture with given picNum
897 // Sets field_flag, bottom_field and err_flag based on the picture and whether
898 // it is available or not...
899 //
h264_dpb_get_short_term_pic(h264_Info * pInfo,int32_t pic_num,int32_t * bottom_field_bit)900 static frame_param_ptr h264_dpb_get_short_term_pic(h264_Info * pInfo,int32_t pic_num, int32_t *bottom_field_bit)
901 {
902 register uint32_t idx;
903 register frame_param_ptr temp_fs;
904
905 h264_DecodedPictureBuffer *p_dpb = &pInfo->dpb;
906
907 *bottom_field_bit = 0;
908 for (idx = 0; idx < p_dpb->ref_frames_in_buffer; idx++)
909 {
910 temp_fs = &p_dpb->fs[p_dpb->fs_ref_idc[idx]];
911 if (pInfo->SliceHeader.structure == FRAME)
912 {
913 if(temp_fs->frame.used_for_reference == 3)
914 if (!(temp_fs->frame.is_long_term))
915 if (temp_fs->frame.pic_num == pic_num) return temp_fs;
916 }
917 else // current picture is a field
918 {
919 if (temp_fs->frame.used_for_reference&0x1)
920 if (!(temp_fs->top_field.is_long_term))
921 if (temp_fs->top_field.pic_num == pic_num)
922 {
923 return temp_fs;
924 }
925
926 if (temp_fs->frame.used_for_reference&0x2)
927 if (!(temp_fs->bottom_field.is_long_term))
928 if (temp_fs->bottom_field.pic_num == pic_num)
929 {
930 *bottom_field_bit = PUT_LIST_INDEX_FIELD_BIT(1);
931 return temp_fs;
932 }
933 }
934 }
935 return NULL;
936 }
937
938 /* ------------------------------------------------------------------------------------------ */
939 /* ------------------------------------------------------------------------------------------ */
940 /* ------------------------------------------------------------------------------------------ */
941 //////////////////////////////////////////////////////////////////////////////
942 // h264_dpb_get_long_term_pic ()
943 //
944 // Sets active_fs to point to frame store containing picture with given picNum
945 //
946
h264_dpb_get_long_term_pic(h264_Info * pInfo,int32_t long_term_pic_num,int32_t * bottom_field_bit)947 static frame_param_ptr h264_dpb_get_long_term_pic(h264_Info * pInfo,int32_t long_term_pic_num, int32_t *bottom_field_bit)
948 {
949 register uint32_t idx;
950 register frame_param_ptr temp_fs;
951 h264_DecodedPictureBuffer *p_dpb = &pInfo->dpb;
952
953 *bottom_field_bit = 0;
954 for (idx = 0; idx < p_dpb->ltref_frames_in_buffer; idx++)
955 {
956 temp_fs = &p_dpb->fs[p_dpb->fs_ltref_idc[idx]];
957 if (pInfo->SliceHeader.structure == FRAME)
958 {
959 if (temp_fs->frame.used_for_reference == 3)
960 if (temp_fs->frame.is_long_term)
961 if (temp_fs->frame.long_term_pic_num == long_term_pic_num)
962 return temp_fs;
963 }
964 else
965 {
966 if (temp_fs->frame.used_for_reference&0x1)
967 if (temp_fs->top_field.is_long_term)
968 if (temp_fs->top_field.long_term_pic_num == long_term_pic_num)
969 return temp_fs;
970
971 if (temp_fs->frame.used_for_reference&0x2)
972 if (temp_fs->bottom_field.is_long_term)
973 if (temp_fs->bottom_field.long_term_pic_num == long_term_pic_num)
974 {
975 *bottom_field_bit = PUT_LIST_INDEX_FIELD_BIT(1);
976 return temp_fs;
977 }
978 }
979 }
980 return NULL;
981 }
982
983 /* ------------------------------------------------------------------------------------------ */
984 /* ------------------------------------------------------------------------------------------ */
985 /* ------------------------------------------------------------------------------------------ */
986 //////////////////////////////////////////////////////////////////////////////
987 // h264_dpb_reorder_ref_pic_list ()
988 //
989 // Used to sort a list based on a corresponding sort indices
990 //
991
992 struct list_value_t
993 {
994 int32_t value;
995 struct list_value_t *next;
996 };
997
998 struct linked_list_t
999 {
1000 struct list_value_t *begin;
1001 struct list_value_t *end;
1002 struct list_value_t *entry;
1003 struct list_value_t *prev_entry;
1004 struct list_value_t list[32];
1005 };
1006
linked_list_initialize(struct linked_list_t * lp,uint8_t * vp,int32_t size)1007 static void linked_list_initialize (struct linked_list_t *lp, uint8_t *vp, int32_t size)
1008 {
1009 struct list_value_t *lvp;
1010
1011 lvp = lp->list;
1012 lp->begin = lvp;
1013 lp->entry = lvp;
1014 lp->end = lvp + (size-1);
1015 lp->prev_entry = NULL;
1016
1017 while (lvp <= lp->end)
1018 {
1019 lvp->value = *(vp++);
1020 lvp->next = lvp + 1;
1021 lvp++;
1022 }
1023 lp->end->next = NULL;
1024 return;
1025 }
1026 /* ------------------------------------------------------------------------------------------ */
1027 /* ------------------------------------------------------------------------------------------ */
1028 /* ------------------------------------------------------------------------------------------ */
linked_list_reorder(struct linked_list_t * lp,int32_t list_value)1029 static void linked_list_reorder (struct linked_list_t *lp, int32_t list_value)
1030 {
1031 register struct list_value_t *lvp = lp->entry;
1032 register struct list_value_t *lvp_prev;
1033
1034 if (lvp == NULL) {
1035 lp->end->value = list_value; // replace the end entry
1036 } else if ((lp->begin==lp->end)||(lvp==lp->end)) // replece the begin/end entry and set the entry to NULL
1037 {
1038 lp->entry->value = list_value;
1039 lp->prev_entry = lp->entry;
1040 lp->entry = NULL;
1041 }
1042 else if (lvp->value==list_value) // the entry point matches
1043 {
1044 lp->prev_entry = lvp;
1045 lp->entry = lvp->next;
1046 }
1047 else if (lvp->next == lp->end) // the entry is just before the end
1048 {
1049 // replace the end and swap the end and entry points
1050 // lvp
1051 // prev_entry => entry => old_end
1052 // old_end & new_prev_entry => new_end & entry
1053 lp->end->value = list_value;
1054
1055 if (lp->prev_entry)
1056 lp->prev_entry->next = lp->end;
1057 else
1058 lp->begin = lp->end;
1059
1060 lp->prev_entry = lp->end;
1061 lp->end->next = lvp;
1062 lp->end = lvp;
1063 lvp->next = NULL;
1064 }
1065 else
1066 {
1067 lvp_prev = NULL;
1068 while (lvp->next) // do not check the end but we'll be in the loop at least once
1069 {
1070 if (lvp->value == list_value) break;
1071 lvp_prev = lvp;
1072 lvp = lvp->next;
1073 }
1074 lvp->value = list_value; // force end matches
1075
1076 // remove lvp from the list
1077 lvp_prev->next = lvp->next;
1078 if (lvp==lp->end) lp->end = lvp_prev;
1079
1080 // insert lvp in front of lp->entry
1081 if (lp->entry==lp->begin)
1082 {
1083 lvp->next = lp->begin;
1084 lp->begin = lvp;
1085 }
1086 else
1087 {
1088 lvp->next = lp->entry;
1089 lp->prev_entry->next = lvp;
1090 }
1091 lp->prev_entry = lvp;
1092 }
1093 return;
1094 }
1095 /* ------------------------------------------------------------------------------------------ */
1096 /* ------------------------------------------------------------------------------------------ */
1097 /* ------------------------------------------------------------------------------------------ */
linked_list_output(struct linked_list_t * lp,int32_t * vp)1098 static void linked_list_output (struct linked_list_t *lp, int32_t *vp)
1099 {
1100 register int32_t *ip1;
1101 register struct list_value_t *lvp;
1102
1103 lvp = lp->begin;
1104 ip1 = vp;
1105 while (lvp)
1106 {
1107 *(ip1++) = lvp->value;
1108 lvp = lvp->next;
1109 }
1110 return;
1111 }
1112 /* ------------------------------------------------------------------------------------------ */
1113 /* ------------------------------------------------------------------------------------------ */
1114 /* ------------------------------------------------------------------------------------------ */
h264_dpb_reorder_ref_pic_list(h264_Info * pInfo,int32_t list_num,int32_t num_ref_idx_active)1115 int32_t h264_dpb_reorder_ref_pic_list(h264_Info * pInfo,int32_t list_num, int32_t num_ref_idx_active)
1116 {
1117 h264_DecodedPictureBuffer *p_dpb = &pInfo->dpb;
1118 uint8_t *remapping_of_pic_nums_idc;
1119 list_reordering_num_t *list_reordering_num;
1120 int32_t bottom_field_bit;
1121
1122 int32_t maxPicNum, currPicNum, picNumLXNoWrap, picNumLXPred, pic_num;
1123 int32_t refIdxLX;
1124 int32_t i;
1125
1126 int32_t PicList[32] = {0};
1127 struct linked_list_t ll;
1128 struct linked_list_t *lp = ≪ // should consider use the scratch space
1129
1130 // declare these below as registers gave me 23 cy/MB for the worst frames in Allegro_Combined_CABAC_07_HD, YHu
1131 register frame_param_ptr temp_fs;
1132 register int32_t temp;
1133 register uint8_t *ip1;
1134
1135 maxPicNum = 1 << (pInfo->active_SPS.log2_max_frame_num_minus4 + 4);
1136
1137
1138 if (list_num == 0) // i.e list 0
1139 {
1140 ip1 = p_dpb->listX_0;
1141 remapping_of_pic_nums_idc = pInfo->SliceHeader.sh_refpic_l0.reordering_of_pic_nums_idc;
1142 list_reordering_num = pInfo->SliceHeader.sh_refpic_l0.list_reordering_num;
1143 }
1144 else
1145 {
1146 ip1 = p_dpb->listX_1;
1147 remapping_of_pic_nums_idc = pInfo->SliceHeader.sh_refpic_l1.reordering_of_pic_nums_idc;
1148 list_reordering_num = pInfo->SliceHeader.sh_refpic_l1.list_reordering_num;
1149 }
1150
1151
1152 linked_list_initialize (lp, ip1, num_ref_idx_active);
1153
1154 currPicNum = pInfo->SliceHeader.frame_num;
1155 if (pInfo->SliceHeader.structure != FRAME)
1156 {
1157
1158 /* The reason it is + 1 I think, is because the list is based on polarity
1159 expand later...
1160 */
1161 maxPicNum <<= 1;
1162 currPicNum <<= 1;
1163 currPicNum++;
1164 }
1165
1166 picNumLXPred = currPicNum;
1167 refIdxLX = 0;
1168
1169 for (i = 0; remapping_of_pic_nums_idc[i] != 3; i++)
1170 {
1171 if(i > MAX_NUM_REF_FRAMES)
1172 {
1173 break;
1174 }
1175
1176 if (remapping_of_pic_nums_idc[i] < 2) // - short-term re-ordering
1177 {
1178 temp = (list_reordering_num[i].abs_diff_pic_num_minus1 + 1);
1179 if (remapping_of_pic_nums_idc[i] == 0)
1180 {
1181 temp = picNumLXPred - temp;
1182 if (temp < 0 ) picNumLXNoWrap = temp + maxPicNum;
1183 else picNumLXNoWrap = temp;
1184 }
1185 else // (remapping_of_pic_nums_idc[i] == 1)
1186 {
1187 temp += picNumLXPred;
1188 if (temp >= maxPicNum) picNumLXNoWrap = temp - maxPicNum;
1189 else picNumLXNoWrap = temp;
1190 }
1191
1192 // Updates for next iteration of the loop
1193 picNumLXPred = picNumLXNoWrap;
1194
1195 if (picNumLXNoWrap > currPicNum ) pic_num = picNumLXNoWrap - maxPicNum;
1196 else pic_num = picNumLXNoWrap;
1197
1198 temp_fs = h264_dpb_get_short_term_pic(pInfo, pic_num, &bottom_field_bit);
1199 if (temp_fs)
1200 {
1201 temp = bottom_field_bit + PUT_FS_IDC_BITS(temp_fs->fs_idc);
1202 linked_list_reorder (lp, temp);
1203 }
1204 }
1205 else //(remapping_of_pic_nums_idc[i] == 2) long-term re-ordering
1206 {
1207 pic_num = list_reordering_num[i].long_term_pic_num;
1208
1209 temp_fs = h264_dpb_get_long_term_pic(pInfo, pic_num, &bottom_field_bit);
1210 if (temp_fs)
1211 {
1212 temp = PUT_LIST_LONG_TERM_BITS(1) + bottom_field_bit + PUT_FS_IDC_BITS(temp_fs->fs_idc);
1213 linked_list_reorder (lp, temp);
1214 }
1215 }
1216 }
1217
1218 linked_list_output (lp, PicList);
1219
1220 if(0 == list_num )
1221 {
1222 for(i=0; i<num_ref_idx_active; i++)
1223 {
1224 pInfo->slice_ref_list0[i]=(uint8_t)PicList[i];
1225 }
1226 }
1227 else
1228 {
1229 for(i=0; i<num_ref_idx_active; i++)
1230 {
1231 pInfo->slice_ref_list1[i]=(uint8_t)PicList[i];
1232 }
1233 }
1234
1235
1236 // Instead of updating the now reordered list here, just write it down...
1237 // This way, we can continue to hold the initialised list in p_dpb->listX_0
1238 // and therefore not need to update it every slice
1239
1240 //h264_dpb_write_list(list_num, PicList, num_ref_idx_active);
1241
1242 return num_ref_idx_active;
1243 }
1244
1245 /* ------------------------------------------------------------------------------------------ */
1246 /* ------------------------------------------------------------------------------------------ */
1247 /* ------------------------------------------------------------------------------------------ */
1248
1249
h264_dpb_RP_check_list(h264_Info * pInfo)1250 void h264_dpb_RP_check_list (h264_Info * pInfo)
1251 {
1252 h264_DecodedPictureBuffer *p_dpb = &pInfo->dpb;
1253 uint8_t *p_list = pInfo->slice_ref_list0;
1254
1255 //
1256 // If the decoding start from RP and without exact point, all B frames belong to previous GOP should be throw away!
1257 //
1258
1259 if((pInfo->SliceHeader.slice_type == h264_PtypeB)&&(pInfo->sei_b_state_ready ==0) && pInfo->sei_rp_received) {
1260 pInfo->wl_err_curr |= VIDDEC_FW_WORKLOAD_ERR_NOTDECODABLE;
1261 pInfo->wl_err_curr |= (FRAME << FIELD_ERR_OFFSET);
1262 }
1263
1264
1265 //
1266 // Repare Ref list if it damaged with RP recovery only
1267 //
1268 if((pInfo->SliceHeader.slice_type == h264_PtypeP) && pInfo->sei_rp_received)
1269 {
1270
1271 int32_t idx, rp_found = 0;
1272
1273 if(pInfo->SliceHeader.num_ref_idx_l0_active == 1)
1274 {
1275 if(pInfo->SliceHeader.sh_refpic_l0.ref_pic_list_reordering_flag)
1276 {
1277 p_list = pInfo->slice_ref_list0;
1278 }
1279 else
1280 {
1281 p_list = pInfo->dpb.listX_0;
1282 //pInfo->sei_rp_received = 0;
1283 //return;
1284 }
1285
1286
1287 for(idx = 0; idx < p_dpb->used_size; idx++) {
1288 if(p_dpb->fs_dpb_idc[idx] == pInfo->last_I_frame_idc) {
1289 rp_found = 1;
1290 break;
1291 }
1292 }
1293 if(rp_found) {
1294 #if 0
1295 int32_t poc;
1296
1297 ///// Clear long-term ref list
1298 for (idx = 0; idx < p_dpb->ltref_frames_in_buffer; idx++)
1299 {
1300 h264_dpb_unmark_for_reference(p_dpb, p_dpb->fs_ltref_idc[0]);
1301 h264_dpb_remove_ltref_list(p_dpb, p_dpb->fs_ltref_idc[0]);
1302 }
1303
1304 ///// Clear short-term ref list
1305 //while(p_dpb->used_size>1)
1306 for(idx = 0; idx < p_dpb->used_size; idx++)
1307 {
1308 int32_t idx_pos;
1309 //// find smallest non-output POC
1310 h264_dpb_get_smallest_poc(p_dpb, &poc, &idx_pos);
1311
1312 //// Remove all frames in previous GOP
1313 if ((idx_pos != MPD_DPB_FS_NULL_IDC) && (p_dpb->fs_dpb_idc[idx_pos] != pInfo->last_I_frame_idc))
1314 {
1315 // Remove from ref-list
1316 h264_dpb_unmark_for_reference(p_dpb, p_dpb->fs_dpb_idc[idx_pos]);
1317 h264_dpb_remove_ref_list(p_dpb, p_dpb->fs_dpb_idc[idx_pos]);
1318
1319 // Output from DPB
1320 //h264_dpb_set_active_fs(p_dpb, p_dpb->fs_dpb_idc[idx]);
1321 //if((active_fs->is_output == 0) && (active_fs->is_non_existent == 0))
1322 {
1323 //int32_t existing;
1324 //h264_dpb_frame_output(pInfo, p_dpb->fs_dpb_idc[idx], 0, &existing);
1325 //p_dpb->last_output_poc = poc;
1326 }
1327 //h264_dpb_remove_frame_from_dpb(p_dpb, idx); // Remove dpb.fs_dpb_idc[pos]
1328
1329 }
1330 }
1331 #endif
1332 ///// Set the reference to last I frame
1333 if( (pInfo->last_I_frame_idc!=255)&&(pInfo->last_I_frame_idc!=p_list[0]))
1334 {
1335 /// Repaire the reference list now
1336 h264_dpb_unmark_for_reference(p_dpb, p_list[0]);
1337 h264_dpb_remove_ref_list(p_dpb, p_list[0]);
1338 p_list[0] = pInfo->last_I_frame_idc;
1339 }
1340
1341 }
1342 }
1343
1344 pInfo->sei_rp_received = 0;
1345 pInfo->sei_b_state_ready = 1;
1346
1347 }
1348
1349
1350 return;
1351 }
1352
1353
1354 /* ------------------------------------------------------------------------------------------ */
1355 /* ------------------------------------------------------------------------------------------ */
1356 /* ------------------------------------------------------------------------------------------ */
1357 //////////////////////////////////////////////////////////////////////////////
1358 // h264_dpb_reorder_lists ()
1359 //
1360 // Used to sort a list based on a corresponding sort indices
1361 //
1362
h264_dpb_reorder_lists(h264_Info * pInfo)1363 void h264_dpb_reorder_lists(h264_Info * pInfo)
1364 {
1365 int32_t currSliceType = pInfo->SliceHeader.slice_type;
1366
1367 if (currSliceType == h264_PtypeP )
1368 {
1369 /////////////////////////////////////////////// Reordering reference list for P slice
1370 /// Forward reordering
1371 if (pInfo->SliceHeader.sh_refpic_l0.ref_pic_list_reordering_flag)
1372 h264_dpb_reorder_ref_pic_list(pInfo, 0, pInfo->SliceHeader.num_ref_idx_l0_active);
1373 else
1374 {
1375
1376 }
1377 pInfo->dpb.listXsize[0]=pInfo->SliceHeader.num_ref_idx_l0_active;
1378 } else if (currSliceType == h264_PtypeB)
1379 {
1380 /////////////////////////////////////////////// Reordering reference list for B slice
1381 /// Forward reordering
1382 if (pInfo->SliceHeader.sh_refpic_l0.ref_pic_list_reordering_flag)
1383 h264_dpb_reorder_ref_pic_list(pInfo, 0, pInfo->SliceHeader.num_ref_idx_l0_active);
1384 else
1385 {
1386
1387 }
1388 pInfo->dpb.listXsize[0]=pInfo->SliceHeader.num_ref_idx_l0_active;
1389
1390 /// Backward reordering
1391 if (pInfo->SliceHeader.sh_refpic_l1.ref_pic_list_reordering_flag)
1392 h264_dpb_reorder_ref_pic_list(pInfo, 1, pInfo->SliceHeader.num_ref_idx_l1_active);
1393 else
1394 {
1395
1396 }
1397 pInfo->dpb.listXsize[1]=pInfo->SliceHeader.num_ref_idx_l1_active;
1398 }
1399
1400 //// Check if need recover reference list with previous recovery point
1401 h264_dpb_RP_check_list(pInfo);
1402
1403
1404 return;
1405 }
1406
1407 ////////////////////////////////////////// DPB management //////////////////////
1408
1409 //////////////////////////////////////////////////////////////////////////////
1410 // avc_dpb_get_non_output_frame_number ()
1411 //
1412 // get total non output frame number in the DPB.
1413 //
avc_dpb_get_non_output_frame_number(h264_Info * pInfo)1414 static int32_t avc_dpb_get_non_output_frame_number(h264_Info * pInfo)
1415 {
1416 int32_t idx;
1417 int32_t number=0;
1418 h264_DecodedPictureBuffer *p_dpb = &pInfo->dpb;
1419
1420 for (idx = 0; idx < p_dpb->used_size; idx++)
1421 {
1422 h264_dpb_set_active_fs(p_dpb, p_dpb->fs_dpb_idc[idx]);
1423
1424 if (viddec_h264_get_is_output(active_fs) == 0)
1425 {
1426 (number)++;
1427 }
1428 }
1429
1430 return number;
1431 }
1432
1433
1434 /* ------------------------------------------------------------------------------------------ */
1435 /* ------------------------------------------------------------------------------------------ */
1436 /* ------------------------------------------------------------------------------------------ */
1437 //// Store previous picture in DPB, and then update DPB queue, remove unused frames from DPB
1438
h264_dpb_store_previous_picture_in_dpb(h264_Info * pInfo,int32_t NonExisting,int32_t use_old)1439 void h264_dpb_store_previous_picture_in_dpb(h264_Info * pInfo,int32_t NonExisting, int32_t use_old)
1440 {
1441 h264_DecodedPictureBuffer *p_dpb = &pInfo->dpb;
1442
1443 int32_t used_for_reference;
1444 int32_t is_direct_output;
1445 int32_t second_field_stored = 0;
1446 int32_t poc;
1447 int32_t pos;
1448 int32_t flag;
1449 int32_t first_field_non_ref = 0;
1450 int32_t idr_flag;
1451
1452 if(NonExisting) {
1453 if(p_dpb->fs_non_exist_idc == MPD_DPB_FS_NULL_IDC)
1454 return;
1455 h264_dpb_set_active_fs(p_dpb, p_dpb->fs_non_exist_idc);
1456 } else {
1457 if(p_dpb->fs_dec_idc == MPD_DPB_FS_NULL_IDC)
1458 return;
1459 h264_dpb_set_active_fs(p_dpb, p_dpb->fs_dec_idc);
1460 }
1461
1462 if(NonExisting == 0)
1463 {
1464 //active_fs->sps_disp_index = (next_sps_disp_entry == 0)? 7 : next_sps_disp_entry - 1;
1465 pInfo->img.last_has_mmco_5 = 0;
1466 pInfo->img.last_pic_bottom_field = pInfo->img.bottom_field_flag;
1467
1468 //used_for_reference = (use_old) ? !(old_pInfo->img.old_disposable_flag) : !(pInfo->img.disposable_flag);
1469 used_for_reference = (use_old) ? !(pInfo->old_slice.nal_ref_idc==0) : !(pInfo->SliceHeader.nal_ref_idc==0);
1470
1471 switch (viddec_h264_get_dec_structure(active_fs))
1472 {
1473 case(TOP_FIELD) : {
1474 active_fs->top_field.used_for_reference = used_for_reference;
1475 viddec_h264_set_is_top_used(active_fs, 1);
1476 //active_fs->crc_field_coded = 1;
1477 }break;
1478 case(BOTTOM_FIELD): {
1479 active_fs->bottom_field.used_for_reference = used_for_reference << 1;
1480 viddec_h264_set_is_bottom_used(active_fs, 1);
1481 //active_fs->crc_field_coded = 1;
1482 }break;
1483 default: {
1484 active_fs->frame.used_for_reference = used_for_reference?3:0;
1485 viddec_h264_set_is_frame_used(active_fs, 3);
1486 //if(pInfo->img.MbaffFrameFlag) active_fs->crc_field_coded = 1;
1487
1488 }break;
1489 }
1490
1491 //freeze_assert = use_old ? old_pInfo->img.sei_freeze_this_image : pInfo->img.sei_freeze_this_image;
1492 //if (freeze_assert) sei_information.disp_frozen = 1;
1493
1494 idr_flag = use_old ? pInfo->old_slice.idr_flag : pInfo->SliceHeader.idr_flag;
1495 if (idr_flag) {
1496 h264_dpb_idr_memory_management (pInfo, &pInfo->active_SPS, pInfo->img.no_output_of_prior_pics_flag);
1497 } else {
1498 // adaptive memory management
1499 if (used_for_reference & pInfo->SliceHeader.sh_dec_refpic.adaptive_ref_pic_marking_mode_flag) {
1500 h264_dpb_adaptive_memory_management(pInfo);
1501 }
1502 }
1503 // Reset the active frame store - could have changed in mem management ftns
1504 h264_dpb_set_active_fs(p_dpb, p_dpb->fs_dec_idc);
1505
1506 if ((viddec_h264_get_dec_structure(active_fs) == TOP_FIELD)||(viddec_h264_get_dec_structure(active_fs) == BOTTOM_FIELD))
1507 {
1508 // check for frame store with same pic_number -- always true in my case, YH
1509 // when we allocate frame store for the second field, we make sure the frame store for the second
1510 // field is the one that contains the first field of the frame- see h264_dpb_init_frame_store()
1511 // This is different from JM model.
1512 // In this way we don't need to move image data around and can reduce memory bandwidth.
1513 // simply check if the check if the other field has been decoded or not
1514
1515 if (viddec_h264_get_is_used(active_fs) != 0)
1516 {
1517 if(pInfo->img.second_field)
1518 {
1519 h264_dpb_insert_picture_in_dpb(pInfo, used_for_reference, 0, NonExisting, use_old);
1520 second_field_stored = 1;
1521 }
1522 }
1523 }
1524 }
1525 else
1526 { // Set up locals for non-existing frames
1527 used_for_reference = 1;
1528
1529 active_fs->frame.used_for_reference = used_for_reference?3:0;
1530 viddec_h264_set_is_frame_used(active_fs, 3);
1531 viddec_h264_set_dec_structure(active_fs, FRAME);
1532 pInfo->img.structure = FRAME;
1533 }
1534
1535 is_direct_output = 0;
1536 if (NonExisting == 0)
1537 {
1538 if(p_dpb->used_size >= p_dpb->BumpLevel)
1539 {
1540 // non-reference frames may be output directly
1541 h264_dpb_set_active_fs(p_dpb, p_dpb->fs_dec_idc);
1542
1543 if ((used_for_reference == 0) && (viddec_h264_get_is_used(active_fs) == 3))
1544 {
1545 h264_dpb_get_smallest_poc (p_dpb, &poc, &pos);
1546 h264_dpb_set_active_fs(p_dpb, p_dpb->fs_dec_idc);
1547 if ((pos == MPD_DPB_FS_NULL_IDC) || (pInfo->img.ThisPOC < poc))
1548 {
1549 is_direct_output = 1;
1550 }
1551 }
1552 }
1553 }
1554
1555 if (NonExisting) {
1556 h264_dpb_sliding_window_memory_management(p_dpb, NonExisting, pInfo->active_SPS.num_ref_frames);
1557 } else if(pInfo->SliceHeader.idr_flag == 0) {
1558 if(used_for_reference){
1559 if(pInfo->img.second_field == 0) {
1560 if (pInfo->SliceHeader.sh_dec_refpic.adaptive_ref_pic_marking_mode_flag == 0) {
1561 h264_dpb_sliding_window_memory_management(p_dpb, NonExisting, pInfo->active_SPS.num_ref_frames);
1562 }
1563 }
1564 }
1565 }
1566
1567 h264_dpb_remove_unused_frame_from_dpb(p_dpb, &flag);
1568
1569 //if (is_direct_output == 0)
1570 {
1571 if ((pInfo->img.second_field == 0) || (NonExisting))
1572 {
1573 h264_dpb_insert_picture_in_dpb(pInfo, used_for_reference, 1, NonExisting, use_old);
1574 }
1575
1576 // In an errored stream we saw a condition where
1577 // p_dpb->ref_frames_in_buffer + p_dpb->ltref_frames_in_buffer > p_dpb->BumpLevel,
1578 // which in itself is an error, but this means first_field_non_ref will
1579 // not get set and causes problems for h264_dpb_queue_update()
1580 if((pInfo->img.structure != FRAME) && (pInfo->img.second_field == 0)) {
1581 if(used_for_reference == 0)
1582 if(p_dpb->ref_frames_in_buffer + p_dpb->ltref_frames_in_buffer == p_dpb->BumpLevel)
1583 first_field_non_ref = 1;
1584 }
1585
1586 }
1587
1588 if(NonExisting)
1589 h264_dpb_set_active_fs(p_dpb, p_dpb->fs_non_exist_idc);
1590 else
1591 h264_dpb_set_active_fs(p_dpb, p_dpb->fs_dec_idc);
1592
1593 if(NonExisting == 0)
1594 {
1595 if((pInfo->img.second_field == 1) || (pInfo->img.structure == FRAME))
1596 {
1597 //h264_send_new_decoded_frame();
1598 if((p_dpb->OutputCtrl) && (is_direct_output == 0))
1599 h264_dpb_output_one_frame_from_dpb(pInfo, 0, 0,pInfo->active_SPS.num_ref_frames);
1600
1601 // Pictures inserted by this point - check if we have reached the specified output
1602 // level (if one has been specified) so we can begin on next call
1603
1604 /*
1605 Fixed HSD 212625---------------should compare OutputLevel with non-output frame number in dpb, not the used number in dpb
1606 if((p_dpb->OutputLevelValid)&&(p_dpb->OutputCtrl == 0))
1607 {
1608 if(p_dpb->used_size == p_dpb->OutputLevel)
1609 p_dpb->OutputCtrl = 1;
1610 }
1611 */
1612
1613 if(p_dpb->OutputLevelValid)
1614 {
1615 int32_t non_output_frame_number=0;
1616 non_output_frame_number = avc_dpb_get_non_output_frame_number(pInfo);
1617
1618 if(non_output_frame_number == p_dpb->OutputLevel)
1619 p_dpb->OutputCtrl = 1;
1620 else
1621 p_dpb->OutputCtrl = 0;
1622 }
1623 else {
1624 p_dpb->OutputCtrl = 0;
1625 }
1626 }
1627 }
1628
1629 while(p_dpb->used_size > (p_dpb->BumpLevel + first_field_non_ref))
1630 //while(p_dpb->used_size > p_dpb->BumpLevel)
1631 {
1632 h264_dpb_queue_update(pInfo, 1, 0, 0,pInfo->active_SPS.num_ref_frames); // flush a frame
1633 //h264_dpb_remove_unused_frame_from_dpb(p_dpb, &flag);
1634 }
1635
1636 //
1637 // Do not output "direct output" pictures until the sempahore has been set that the pic is
1638 // decoded!!
1639 //
1640 if(is_direct_output) {
1641 h264_dpb_queue_update(pInfo, 1, 1, 0,pInfo->active_SPS.num_ref_frames);
1642 //h264_dpb_remove_unused_frame_from_dpb(p_dpb, &flag);
1643 }
1644
1645 //
1646 // Add reference pictures into Reference list
1647 //
1648 if(used_for_reference) {
1649 h264_dpb_insert_ref_lists(&pInfo->dpb, NonExisting);
1650 }
1651
1652 h264_dpb_remove_unused_frame_from_dpb(p_dpb, &flag);
1653
1654
1655 return;
1656 } ////////////// End of DPB store pic
1657
1658
1659 /* ------------------------------------------------------------------------------------------ */
1660 /* ------------------------------------------------------------------------------------------ */
1661 /* ------------------------------------------------------------------------------------------ */
1662 //////////////////////////////////////////////////////////////////////////////
1663 // h264_dpb_insert_picture_in_dpb ()
1664 //
1665 // Insert the decoded picture into the DPB. A free DPB position is necessary
1666 // for frames, .
1667 // This ftn tends to fill out the framestore's top level parameters from the
1668 // storable picture's parameters within it. It is called from h264_dpb_store_picture_in_dpb()
1669 //
1670 // This function finishes by updating the reference lists - this means it must be called after
1671 // h264_dpb_sliding_window_memory_management()
1672 //
1673 // In the case of a frame it will call h264_dpb_split_field()
1674 // In the case of the second field of a complementary field pair it calls h264_dpb_combine_field()
1675 //
1676
h264_dpb_insert_picture_in_dpb(h264_Info * pInfo,int32_t used_for_reference,int32_t add2dpb,int32_t NonExisting,int32_t use_old)1677 void h264_dpb_insert_picture_in_dpb(h264_Info * pInfo,int32_t used_for_reference, int32_t add2dpb, int32_t NonExisting, int32_t use_old)
1678 {
1679 h264_DecodedPictureBuffer *p_dpb = &pInfo->dpb;
1680
1681 if(NonExisting == 0) {
1682 h264_dpb_set_active_fs(p_dpb, p_dpb->fs_dec_idc);
1683 active_fs->frame_num = (use_old) ? pInfo->old_slice.frame_num : pInfo->SliceHeader.frame_num;
1684 }
1685 else {
1686 h264_dpb_set_active_fs(p_dpb, p_dpb->fs_non_exist_idc);
1687 active_fs->frame_num = active_fs->frame.pic_num;
1688 }
1689
1690 if (add2dpb) {
1691 p_dpb->fs_dpb_idc[p_dpb->used_size] = active_fs->fs_idc;
1692 p_dpb->used_size++;
1693 }
1694
1695
1696 switch (viddec_h264_get_dec_structure(active_fs))
1697 {
1698 case FRAME :{
1699 viddec_h264_set_is_frame_used(active_fs, 3);
1700 active_fs->frame.used_for_reference = used_for_reference?3:0;
1701 if (used_for_reference)
1702 {
1703 active_fs->frame.used_for_reference = 3;
1704 if (active_fs->frame.is_long_term)
1705 viddec_h264_set_is_frame_long_term(active_fs, 3);
1706 }
1707 // Split frame to 2 fields for prediction
1708 h264_dpb_split_field(pInfo);
1709
1710 }break;
1711 case TOP_FIELD :{
1712 viddec_h264_set_is_top_used(active_fs, 1);
1713
1714 active_fs->top_field.used_for_reference = used_for_reference;
1715 if (used_for_reference)
1716 {
1717 active_fs->frame.used_for_reference |= 0x1;
1718 if (active_fs->top_field.is_long_term)
1719 {
1720 viddec_h264_set_is_top_long_term(active_fs, 1);
1721 active_fs->long_term_frame_idx = active_fs->top_field.long_term_frame_idx;
1722 }
1723 }
1724 if (viddec_h264_get_is_used(active_fs) == 3) {
1725 h264_dpb_combine_field(use_old); // generate frame view
1726 }
1727 else
1728 {
1729 active_fs->frame.poc = active_fs->top_field.poc;
1730 }
1731
1732 }break;
1733 case BOTTOM_FIELD :{
1734 viddec_h264_set_is_bottom_used(active_fs, 1);
1735
1736 active_fs->bottom_field.used_for_reference = (used_for_reference<<1);
1737 if (used_for_reference)
1738 {
1739 active_fs->frame.used_for_reference |= 0x2;
1740 if (active_fs->bottom_field.is_long_term)
1741 {
1742 viddec_h264_set_is_bottom_long_term(active_fs, 1);
1743 active_fs->long_term_frame_idx = active_fs->bottom_field.long_term_frame_idx;
1744 }
1745 }
1746 if (viddec_h264_get_is_used(active_fs) == 3) {
1747 h264_dpb_combine_field(use_old); // generate frame view
1748 }
1749 else
1750 {
1751 active_fs->frame.poc = active_fs->bottom_field.poc;
1752 }
1753
1754 }break;
1755 }
1756 /*
1757 if ( gRestartMode.LastRestartType == RESTART_SEI )
1758 {
1759 if ( active_fs->open_gop_entry ) dpb.WaitSeiRecovery = 1;
1760 }
1761
1762 gRestartMode.LastRestartType = 0xFFFF;
1763 */
1764
1765 return;
1766 } ////// End of insert picture in DPB
1767
1768 /* ------------------------------------------------------------------------------------------ */
1769 /* ------------------------------------------------------------------------------------------ */
1770 /* ------------------------------------------------------------------------------------------ */
1771 //////////////////////////////////////////////////////////////////////////////
1772 // h264_dpb_mm_unmark_short_term_for_reference ()
1773 //
1774 // Adaptive Memory Management: Mark short term picture unused
1775 //
1776
h264_dpb_mm_unmark_short_term_for_reference(h264_Info * pInfo,int32_t difference_of_pic_nums_minus1)1777 void h264_dpb_mm_unmark_short_term_for_reference(h264_Info * pInfo, int32_t difference_of_pic_nums_minus1)
1778 {
1779 int32_t picNumX;
1780 int32_t currPicNum;
1781 uint32_t idx;
1782 int32_t unmark_done;
1783 h264_DecodedPictureBuffer *p_dpb = &pInfo->dpb;
1784
1785 if (pInfo->img.structure == FRAME)
1786 currPicNum = pInfo->img.frame_num;
1787 else
1788 currPicNum = (pInfo->img.frame_num << 1) + 1;
1789
1790 picNumX = currPicNum - (difference_of_pic_nums_minus1 + 1);
1791
1792 unmark_done = 0;
1793
1794 for (idx =0; (idx < p_dpb->ref_frames_in_buffer) && (!(unmark_done)); idx++)
1795 {
1796 h264_dpb_set_active_fs(p_dpb, p_dpb->fs_ref_idc[idx]);
1797
1798 if (pInfo->img.structure == FRAME)
1799 {
1800 /* If all pic numbers in the list are different (and they should be)
1801 we should terminate the for loop the moment we match pic numbers,
1802 no need to continue to check - hence set unmark_done
1803 */
1804
1805 if ((active_fs->frame.used_for_reference == 3) && (viddec_h264_get_is_long_term(active_fs) == 0) &&
1806 (active_fs->frame.pic_num == picNumX))
1807 {
1808 h264_dpb_unmark_for_reference(p_dpb, active_fs->fs_idc);
1809 h264_dpb_remove_ref_list(p_dpb, active_fs->fs_idc);
1810 unmark_done = 1;
1811 }
1812 }
1813 else
1814 {
1815 /*
1816 If we wish to unmark a short-term picture by picture number when the current picture
1817 is a field, we have to unmark the corresponding field as unused for reference,
1818 and also if it was part of a frame or complementary reference field pair, the
1819 frame is to be marked as unused. However the opposite field may still be used as a
1820 reference for future fields
1821
1822 How will this affect the reference list update ftn coming after??
1823
1824 */
1825 if ((active_fs->frame.used_for_reference&0x1) && (!(viddec_h264_get_is_long_term(active_fs)&0x01))&&
1826 (active_fs->top_field.pic_num == picNumX) )
1827 {
1828 active_fs->top_field.used_for_reference = 0;
1829 active_fs->frame.used_for_reference &= 2;
1830
1831 unmark_done = 1;
1832
1833 //Check if other field is used for short-term reference, if not remove from list...
1834 if(active_fs->bottom_field.used_for_reference == 0)
1835 h264_dpb_remove_ref_list(p_dpb, p_dpb->fs_ref_idc[idx]);
1836 }
1837 if ((active_fs->frame.used_for_reference&0x2) && (!(viddec_h264_get_is_long_term(active_fs)&0x2)) &&
1838 (active_fs->bottom_field.pic_num == picNumX) )
1839 {
1840 active_fs->bottom_field.used_for_reference = 0;
1841 active_fs->frame.used_for_reference &= 1;
1842
1843 unmark_done = 1;
1844
1845 //Check if other field is used for reference, if not remove from list...
1846 if(active_fs->top_field.used_for_reference == 0)
1847 h264_dpb_remove_ref_list(p_dpb, p_dpb->fs_ref_idc[idx]);
1848 }
1849 }
1850 }
1851
1852 return;
1853 }
1854
1855 /* ------------------------------------------------------------------------------------------ */
1856 /* ------------------------------------------------------------------------------------------ */
1857 /* ------------------------------------------------------------------------------------------ */
1858 ////////////////////////////////////////////////////////////////////////////////////
1859 // h264_dpb_mm_unmark_long_term_for_reference ()
1860 //
1861 // Adaptive Memory Management: Mark long term picture unused
1862 //
1863 // In a frame situation the long_term_pic_num will refer to another frame.
1864 // Thus we can call h264_dpb_unmark_for_long_term_reference() and then remove the picture
1865 // from the list
1866 //
1867 // If the current picture is a field, long_term_pic_num will refer to another field
1868 // It is also the case that each individual field should have a unique picture number
1869 // 8.2.5.4.2 suggests that when curr pic is a field, an mmco == 2 operation
1870 // should be accompanied by a second op to unmark the other field as being unused
1871 ///////////////////////////////////////////////////////////////////////////////////
1872
h264_dpb_mm_unmark_long_term_for_reference(h264_Info * pInfo,int32_t long_term_pic_num)1873 void h264_dpb_mm_unmark_long_term_for_reference (h264_Info * pInfo, int32_t long_term_pic_num)
1874 {
1875 uint32_t idx;
1876 int32_t unmark_done;
1877 h264_DecodedPictureBuffer *p_dpb = &pInfo->dpb;
1878
1879 unmark_done = 0;
1880 for (idx = 0; (idx < p_dpb->ltref_frames_in_buffer) && (!(unmark_done)); idx++)
1881 {
1882 h264_dpb_set_active_fs(p_dpb, p_dpb->fs_ltref_idc[idx]);
1883
1884 if (pInfo->img.structure == FRAME)
1885 {
1886 if ((active_fs->frame.used_for_reference==3) && (viddec_h264_get_is_long_term(active_fs)==3) &&
1887 (active_fs->frame.long_term_pic_num == long_term_pic_num))
1888 {
1889 h264_dpb_unmark_for_long_term_reference(p_dpb, p_dpb->fs_ltref_idc[idx]);
1890 h264_dpb_remove_ltref_list(p_dpb, p_dpb->fs_ltref_idc[idx]);
1891 unmark_done = 1;
1892 }
1893 }
1894 else
1895 {
1896 /// Check top field
1897 if ((active_fs->frame.used_for_reference&0x1) && (viddec_h264_get_is_long_term(active_fs)&0x1) &&
1898 (active_fs->top_field.long_term_pic_num == long_term_pic_num) )
1899 {
1900 active_fs->top_field.used_for_reference = 0;
1901 active_fs->top_field.is_long_term = 0;
1902 active_fs->frame.used_for_reference &= 2;
1903 viddec_h264_set_is_frame_long_term(active_fs, 2);
1904
1905 unmark_done = 1;
1906
1907 //Check if other field is used for long term reference, if not remove from list...
1908 if ((active_fs->bottom_field.used_for_reference == 0) || (active_fs->bottom_field.is_long_term == 0))
1909 h264_dpb_remove_ltref_list(p_dpb, p_dpb->fs_ltref_idc[idx]);
1910 }
1911
1912 /// Check Bottom field
1913 if ((active_fs->frame.used_for_reference&0x2) && (viddec_h264_get_is_long_term(active_fs)&0x2) &&
1914 (active_fs->bottom_field.long_term_pic_num == long_term_pic_num) )
1915 {
1916 active_fs->bottom_field.used_for_reference = 0;
1917 active_fs->bottom_field.is_long_term = 0;
1918 active_fs->frame.used_for_reference &= 1;
1919 viddec_h264_set_is_frame_long_term(active_fs, 1);
1920
1921 unmark_done = 1;
1922 //Check if other field is used for long term reference, if not remove from list...
1923 if ((active_fs->top_field.used_for_reference == 0) || (active_fs->top_field.is_long_term == 0))
1924 {
1925 h264_dpb_remove_ltref_list(p_dpb, p_dpb->fs_ltref_idc[idx]);
1926 }
1927 }
1928 } // field structure
1929 } //for(idx)
1930
1931 return;
1932 }
1933 /* ------------------------------------------------------------------------------------------ */
1934 /* ------------------------------------------------------------------------------------------ */
1935 /* ------------------------------------------------------------------------------------------ */
1936 //////////////////////////////////////////////////////////////////////////////
1937 // h264_dpb_get_pic_struct_by_pic_num
1938 //
1939 // Searches the fields appearing in short term reference list
1940 // Returns the polarity of the field with pic_num = picNumX
1941 //////////////////////////////////////////////////////////////////////////////
1942
h264_dpb_get_pic_struct_by_pic_num(h264_DecodedPictureBuffer * p_dpb,int32_t picNumX)1943 int32_t h264_dpb_get_pic_struct_by_pic_num(h264_DecodedPictureBuffer *p_dpb, int32_t picNumX)
1944 {
1945 uint32_t idx;
1946 int32_t pic_struct = INVALID;
1947 int32_t found = 0;
1948
1949 for (idx =0; (idx < p_dpb->ref_frames_in_buffer) && (!(found)); idx++)
1950 {
1951 h264_dpb_set_active_fs(p_dpb, p_dpb->fs_ref_idc[idx]);
1952
1953 if ((active_fs->frame.used_for_reference&0x1) && (!(viddec_h264_get_is_long_term(active_fs)&0x01))&&
1954 (active_fs->top_field.pic_num == picNumX) )
1955 {
1956 found = 1;
1957 pic_struct = TOP_FIELD;
1958
1959 }
1960 if ((active_fs->frame.used_for_reference&0x2) && (!(viddec_h264_get_is_long_term(active_fs)&0x2)) &&
1961 (active_fs->bottom_field.pic_num == picNumX) )
1962 {
1963 found = 1;
1964 pic_struct = BOTTOM_FIELD;
1965
1966 }
1967 }
1968
1969 return pic_struct;
1970 }
1971 /* ------------------------------------------------------------------------------------------ */
1972 /* ------------------------------------------------------------------------------------------ */
1973 /* ------------------------------------------------------------------------------------------ */
1974 //////////////////////////////////////////////////////////////////////////////
1975 // h264_dpb_mm_assign_long_term_frame_idx ()
1976 //
1977 // Assign a long term frame index to a short term picture
1978 // Both lists must be updated as part of this process...
1979 //////////////////////////////////////////////////////////////////////////////
1980
h264_dpb_mm_assign_long_term_frame_idx(h264_Info * pInfo,int32_t difference_of_pic_nums_minus1,int32_t long_term_frame_idx)1981 void h264_dpb_mm_assign_long_term_frame_idx(h264_Info * pInfo, int32_t difference_of_pic_nums_minus1, int32_t long_term_frame_idx)
1982 {
1983 h264_DecodedPictureBuffer *p_dpb = &pInfo->dpb;
1984 int32_t picNumX;
1985 int32_t currPicNum;
1986 int32_t polarity = 0;
1987
1988 if (pInfo->img.structure == FRAME) {
1989 currPicNum = pInfo->img.frame_num;
1990 } else {
1991 currPicNum = (pInfo->img.frame_num << 1) + 1;
1992 }
1993
1994 picNumX = currPicNum - (difference_of_pic_nums_minus1 + 1);
1995
1996 // remove frames / fields with same long_term_frame_idx
1997 if (pInfo->img.structure == FRAME) {
1998 h264_dpb_unmark_long_term_frame_for_reference_by_frame_idx(p_dpb, long_term_frame_idx);
1999 } else {
2000 polarity = h264_dpb_get_pic_struct_by_pic_num(p_dpb, picNumX);
2001
2002 if(polarity != INVALID)
2003 h264_dpb_unmark_long_term_field_for_reference_by_frame_idx(p_dpb, long_term_frame_idx, active_fs->fs_idc, polarity);
2004 }
2005
2006 h264_dpb_mark_pic_long_term(pInfo, long_term_frame_idx, picNumX);
2007
2008 return;
2009 }
2010 /* ------------------------------------------------------------------------------------------ */
2011 /* ------------------------------------------------------------------------------------------ */
2012 /* ------------------------------------------------------------------------------------------ */
2013 //////////////////////////////////////////////////////////////////////////////
2014 // h264_dpb_mm_update_max_long_term_frame_idx ()
2015 //
2016 // Set new max long_term_frame_idx
2017 //
2018
h264_dpb_mm_update_max_long_term_frame_idx(h264_DecodedPictureBuffer * p_dpb,int32_t max_long_term_frame_idx_plus1)2019 void h264_dpb_mm_update_max_long_term_frame_idx(h264_DecodedPictureBuffer *p_dpb,int32_t max_long_term_frame_idx_plus1)
2020 {
2021 //h264_DecodedPictureBuffer *p_dpb = &pInfo->dpb;
2022 int32_t idx;
2023 int32_t temp;
2024 int32_t removed_count;
2025 int32_t idx2 = 0;
2026
2027 p_dpb->max_long_term_pic_idx = max_long_term_frame_idx_plus1 - 1;
2028
2029 temp = p_dpb->ltref_frames_in_buffer;
2030 removed_count = 0;
2031
2032 // check for invalid frames
2033 for (idx = 0; idx < temp; idx++)
2034 {
2035 idx2 = idx - removed_count;
2036 h264_dpb_set_active_fs(p_dpb, p_dpb->fs_ltref_idc[idx2]);
2037
2038 if (active_fs->long_term_frame_idx > p_dpb->max_long_term_pic_idx)
2039 {
2040 removed_count++;
2041 h264_dpb_unmark_for_long_term_reference(p_dpb, p_dpb->fs_ltref_idc[idx2]);
2042 h264_dpb_remove_ltref_list(p_dpb, p_dpb->fs_ltref_idc[idx2]);
2043 }
2044 }
2045 return;
2046 }
2047 /* ------------------------------------------------------------------------------------------ */
2048 /* ------------------------------------------------------------------------------------------ */
2049 /* ------------------------------------------------------------------------------------------ */
2050 //////////////////////////////////////////////////////////////////////////////
2051 // h264_dpb_mm_unmark_all_short_term_for_reference ()
2052 //
2053 // Unmark all short term refernce pictures
2054 //
2055
h264_dpb_mm_unmark_all_short_term_for_reference(h264_DecodedPictureBuffer * p_dpb)2056 void h264_dpb_mm_unmark_all_short_term_for_reference (h264_DecodedPictureBuffer *p_dpb)
2057 {
2058 int32_t idx;
2059 int32_t temp = p_dpb->ref_frames_in_buffer;
2060
2061 for (idx = 0; idx < temp; idx++)
2062 {
2063 h264_dpb_unmark_for_reference(p_dpb, p_dpb->fs_ref_idc[0]);
2064 h264_dpb_remove_ref_list(p_dpb, p_dpb->fs_ref_idc[0]);
2065 }
2066 return;
2067 }
2068 /* ------------------------------------------------------------------------------------------ */
2069 /* ------------------------------------------------------------------------------------------ */
2070 /* ------------------------------------------------------------------------------------------ */
2071 //////////////////////////////////////////////////////////////////////////////
2072 // h264_dpb_mm_mark_current_picture_long_term ()
2073 //
2074 // Marks the current picture as long term after unmarking any long term picture
2075 // already assigned with the same long term frame index
2076 //
2077
h264_dpb_mm_mark_current_picture_long_term(h264_DecodedPictureBuffer * p_dpb,int32_t long_term_frame_idx)2078 void h264_dpb_mm_mark_current_picture_long_term(h264_DecodedPictureBuffer *p_dpb, int32_t long_term_frame_idx)
2079 {
2080 int32_t picNumX;
2081 h264_dpb_set_active_fs(p_dpb, p_dpb->fs_dec_idc);
2082
2083 if (viddec_h264_get_dec_structure(active_fs) == FRAME)
2084 {
2085 h264_dpb_unmark_long_term_frame_for_reference_by_frame_idx(p_dpb, long_term_frame_idx);
2086 h264_dpb_set_active_fs(p_dpb, p_dpb->fs_dec_idc);
2087 active_fs->frame.is_long_term = 1;
2088 active_fs->frame.long_term_frame_idx = long_term_frame_idx;
2089 active_fs->frame.long_term_pic_num = long_term_frame_idx;
2090 }
2091 else
2092 {
2093 if(viddec_h264_get_dec_structure(active_fs) == TOP_FIELD)
2094 {
2095 picNumX = (active_fs->top_field.pic_num << 1) + 1;
2096 active_fs->top_field.is_long_term = 1;
2097 active_fs->top_field.long_term_frame_idx = long_term_frame_idx;
2098
2099 // Assign long-term pic num
2100 active_fs->top_field.long_term_pic_num = (long_term_frame_idx << 1) + 1;
2101 }
2102 else
2103 {
2104 picNumX = (active_fs->bottom_field.pic_num << 1) + 1;
2105 active_fs->bottom_field.is_long_term = 1;
2106 active_fs->bottom_field.long_term_frame_idx = long_term_frame_idx;
2107
2108 // Assign long-term pic num
2109 active_fs->bottom_field.long_term_pic_num = (long_term_frame_idx << 1) + 1;
2110
2111 }
2112 h264_dpb_unmark_long_term_field_for_reference_by_frame_idx(p_dpb, long_term_frame_idx, p_dpb->fs_dec_idc, viddec_h264_get_dec_structure(active_fs));
2113 }
2114 // Add to long term list
2115 //h264_dpb_add_ltref_list(p_dpb->fs_dec_idc);
2116
2117 return;
2118 }
2119 /* ------------------------------------------------------------------------------------------ */
2120 /* ------------------------------------------------------------------------------------------ */
2121 /* ------------------------------------------------------------------------------------------ */
2122 //////////////////////////////////////////////////////////////////////////////
2123 // h264_dpb_unmark_long_term_frame_for_reference_by_frame_idx ()
2124 //
2125 // Mark a long-term reference frame or complementary field pair unused for referemce
2126 // NOTE: Obviously this ftn cannot be used to unmark individual fields...
2127 //////////////////////////////////////////////////////////////////////////////
2128
h264_dpb_unmark_long_term_frame_for_reference_by_frame_idx(h264_DecodedPictureBuffer * p_dpb,int32_t long_term_frame_idx)2129 void h264_dpb_unmark_long_term_frame_for_reference_by_frame_idx(h264_DecodedPictureBuffer *p_dpb, int32_t long_term_frame_idx)
2130 {
2131 uint32_t idx;
2132 for(idx =0; idx < p_dpb->ltref_frames_in_buffer; idx++)
2133 {
2134 h264_dpb_set_active_fs(p_dpb, p_dpb->fs_ltref_idc[idx]);
2135
2136 if (active_fs->long_term_frame_idx == long_term_frame_idx)
2137 {
2138 h264_dpb_unmark_for_long_term_reference(p_dpb, p_dpb->fs_ltref_idc[idx]);
2139 h264_dpb_remove_ltref_list(p_dpb, p_dpb->fs_ltref_idc[idx]);
2140 }
2141 }
2142 return;
2143 }
2144
2145 /* ------------------------------------------------------------------------------------------ */
2146 /* ------------------------------------------------------------------------------------------ */
2147 /* ------------------------------------------------------------------------------------------ */
2148 //////////////////////////////////////////////////////////////////////////////
2149 // h264_dpb_unmark_long_term_field_for_reference_by_frame_idx ()
2150 //
2151 // Mark a long-term reference field unused for reference. However if it is the
2152 // complementary field (opposite polarity) of the picture stored in fs_idc,
2153 // we do not unmark it
2154 //////////////////////////////////////////////////////////////////////////////
2155
h264_dpb_unmark_long_term_field_for_reference_by_frame_idx(h264_DecodedPictureBuffer * p_dpb,int32_t long_term_frame_idx,int32_t fs_idc,int32_t polarity)2156 void h264_dpb_unmark_long_term_field_for_reference_by_frame_idx(h264_DecodedPictureBuffer *p_dpb, int32_t long_term_frame_idx, int32_t fs_idc, int32_t polarity)
2157 {
2158 uint32_t idx;
2159 int32_t found = 0;
2160 int32_t is_complement = 0;
2161
2162 for (idx = 0; (idx < p_dpb->ltref_frames_in_buffer) && (found == 0); idx++)
2163 {
2164 h264_dpb_set_active_fs(p_dpb, p_dpb->fs_ltref_idc[idx]);
2165 if (active_fs->long_term_frame_idx == long_term_frame_idx)
2166 {
2167 if(active_fs->fs_idc == fs_idc)
2168 {
2169 // Again these seem like redundant checks but for safety while until JM is updated
2170 if (polarity == TOP_FIELD)
2171 is_complement = (active_fs->bottom_field.is_long_term)? 1:0;
2172 else if(polarity == BOTTOM_FIELD)
2173 is_complement = (active_fs->top_field.is_long_term) ? 1:0;
2174 }
2175 found = 1;
2176 }
2177 }
2178
2179 if(found) {
2180 if(is_complement == 0)
2181 {
2182 h264_dpb_unmark_for_long_term_reference(p_dpb, p_dpb->fs_ltref_idc[idx-1]);
2183 h264_dpb_remove_ltref_list(p_dpb, p_dpb->fs_ltref_idc[idx-1]);
2184 }
2185 }
2186
2187 return;
2188 }
2189
2190
2191 /* ------------------------------------------------------------------------------------------ */
2192 /* ------------------------------------------------------------------------------------------ */
2193 /* ------------------------------------------------------------------------------------------ */
2194 //////////////////////////////////////////////////////////////////////////////
2195 // h264_dpb_mark_pic_long_term ()
2196 //
2197 // This is used on a picture already in the dpb - i.e. not for the current picture
2198 // dpb_split / dpb_combine field will perform ftnality in that case
2199 //
2200 // Marks a picture as used for long-term reference. Adds it to the long-term
2201 // reference list. Also removes it from the short term reference list if required
2202 //
2203 // Note: if the current picture is a frame, the picture to be marked will be a
2204 // short-term reference frame or short-term complemenetary reference field pair
2205 // We use the pic_num assigned to the frame part of the structure to locate it
2206 // Both its fields will have their long_term_frame_idx and long_term_pic_num
2207 // assigned to be equal to long_term_frame_idx
2208 //
2209 // If the current picture is a field, the picture to be marked will be a
2210 // short-term reference field. We use the pic_nums assigned to the field parts of
2211 // the structure to identify the appropriate field. We assign the long_term_frame_idx
2212 // of the field equal to long_term_frame_idx.
2213 //
2214 // We also check to see if this marking has resulted in both fields of the frame
2215 // becoming long_term. If it has, we update the frame part of the structure by
2216 // setting its long_term_frame_idx
2217 //////////////////////////////////////////////////////////////////////////////
2218
h264_dpb_mark_pic_long_term(h264_Info * pInfo,int32_t long_term_frame_idx,int32_t picNumX)2219 void h264_dpb_mark_pic_long_term(h264_Info * pInfo, int32_t long_term_frame_idx, int32_t picNumX)
2220 {
2221 h264_DecodedPictureBuffer *p_dpb = &pInfo->dpb;
2222 uint32_t idx;
2223 int32_t mark_done;
2224 int32_t polarity = 0;
2225
2226 mark_done = 0;
2227
2228 if (pInfo->img.structure == FRAME)
2229 {
2230 for (idx = 0; (idx < p_dpb->ref_frames_in_buffer) && (!(mark_done)); idx++)
2231 {
2232 h264_dpb_set_active_fs(p_dpb, p_dpb->fs_ref_idc[idx]);
2233
2234 if (active_fs->frame.used_for_reference == 3)
2235 {
2236 if ((!(active_fs->frame.is_long_term))&&(active_fs->frame.pic_num == picNumX))
2237 {
2238 active_fs->long_term_frame_idx = long_term_frame_idx;
2239 active_fs->frame.long_term_frame_idx = long_term_frame_idx;
2240 active_fs->top_field.long_term_frame_idx = long_term_frame_idx;
2241 active_fs->bottom_field.long_term_frame_idx = long_term_frame_idx;
2242
2243 active_fs->frame.is_long_term = 1;
2244 active_fs->top_field.is_long_term = 1;
2245 active_fs->bottom_field.is_long_term = 1;
2246
2247 viddec_h264_set_is_frame_long_term(active_fs, 3);
2248 mark_done = 1;
2249
2250 // Assign long-term pic num
2251 active_fs->frame.long_term_pic_num = long_term_frame_idx;
2252 active_fs->top_field.long_term_pic_num = long_term_frame_idx;
2253 active_fs->bottom_field.long_term_pic_num = long_term_frame_idx;
2254 // Add to long term list
2255 h264_dpb_add_ltref_list(p_dpb, p_dpb->fs_ref_idc[idx]);
2256 // Remove from short-term list
2257 h264_dpb_remove_ref_list(p_dpb, p_dpb->fs_ref_idc[idx]);
2258 }
2259 }
2260 }
2261 }
2262 else
2263 {
2264 polarity = h264_dpb_get_pic_struct_by_pic_num(p_dpb, picNumX);
2265 active_fs->long_term_frame_idx = long_term_frame_idx; /////BUG
2266
2267 if(polarity == TOP_FIELD)
2268 {
2269 active_fs->top_field.long_term_frame_idx = long_term_frame_idx;
2270 active_fs->top_field.is_long_term = 1;
2271 viddec_h264_set_is_top_long_term(active_fs, 1);
2272
2273 // Assign long-term pic num
2274 active_fs->top_field.long_term_pic_num = (long_term_frame_idx << 1) + ((pInfo->img.structure == TOP_FIELD) ? 1 : 0);
2275
2276 }
2277 else if (polarity == BOTTOM_FIELD)
2278 {
2279 active_fs->bottom_field.long_term_frame_idx = long_term_frame_idx;
2280 active_fs->bottom_field.is_long_term = 1;
2281 viddec_h264_set_is_bottom_long_term(active_fs, 1);
2282
2283 // Assign long-term pic num
2284 active_fs->bottom_field.long_term_pic_num = (long_term_frame_idx << 1) + ((pInfo->img.structure == BOTTOM_FIELD) ? 1 : 0);
2285 }
2286
2287 if (viddec_h264_get_is_long_term(active_fs) == 3)
2288 {
2289 active_fs->frame.is_long_term = 1;
2290 active_fs->frame.long_term_frame_idx = long_term_frame_idx;
2291 h264_dpb_remove_ref_list(p_dpb, active_fs->fs_idc);
2292 }
2293 else
2294 {
2295 // We need to add this idc to the long term ref list...
2296 h264_dpb_add_ltref_list(p_dpb, active_fs->fs_idc);
2297
2298 // If the opposite field is not a short term reference, remove it from the
2299 // short term list. Since we know top field is a reference but both are not long term
2300 // we can simply check that both fields are not references...
2301 if(active_fs->frame.used_for_reference != 3)
2302 h264_dpb_remove_ref_list(p_dpb, active_fs->fs_idc);
2303 }
2304 }
2305 return;
2306 } ///// End of mark pic long term
2307
2308
2309 /* ------------------------------------------------------------------------------------------ */
2310 /* ------------------------------------------------------------------------------------------ */
2311 /* ------------------------------------------------------------------------------------------ */
2312 //////////////////////////////////////////////////////////////////////////////
2313 // h264_dpb_adaptive_memory_management ()
2314 //
2315 // Perform Adaptive memory control decoded reference picture marking process
2316 //////////////////////////////////////////////////////////////////////////////
2317
h264_dpb_adaptive_memory_management(h264_Info * pInfo)2318 void h264_dpb_adaptive_memory_management (h264_Info * pInfo)
2319 {
2320 h264_DecodedPictureBuffer *p_dpb = &pInfo->dpb;
2321 int32_t idx;
2322
2323 idx = 0;
2324
2325 while (idx < pInfo->SliceHeader.sh_dec_refpic.dec_ref_pic_marking_count)
2326 {
2327 switch(pInfo->SliceHeader.sh_dec_refpic.memory_management_control_operation[idx])
2328 {
2329 case 1:{ //Mark a short-term reference picture as �unused for reference?
2330 h264_dpb_mm_unmark_short_term_for_reference(pInfo,
2331 pInfo->SliceHeader.sh_dec_refpic.difference_of_pic_num_minus1[idx]);
2332 } break;
2333 case 2:{ //Mark a long-term reference picture as �unused for reference?
2334 h264_dpb_mm_unmark_long_term_for_reference(pInfo,
2335 pInfo->SliceHeader.sh_dec_refpic.long_term_pic_num[idx]);
2336 }break;
2337 case 3:{ //Mark a short-term reference picture as "used for long-term reference" and assign a long-term frame index to it
2338 h264_dpb_mm_assign_long_term_frame_idx(pInfo,
2339 pInfo->SliceHeader.sh_dec_refpic.difference_of_pic_num_minus1[idx],
2340 pInfo->SliceHeader.sh_dec_refpic.long_term_frame_idx[idx]);
2341 }break;
2342 case 4:{ //Specify the maximum long-term frame index and
2343 //mark all long-term reference pictureshaving long-term frame indices greater than
2344 //the maximum value as "unused for reference"
2345 h264_dpb_mm_update_max_long_term_frame_idx (&pInfo->dpb,
2346 pInfo->SliceHeader.sh_dec_refpic.max_long_term_frame_idx_plus1[idx]);
2347 }break;
2348 case 5:{ //Mark all reference pictures as "unused for reference" and set the MaxLongTermFrameIdx variable to
2349 // "no long-term frame indices"
2350 h264_dpb_mm_unmark_all_short_term_for_reference(&pInfo->dpb);
2351 h264_dpb_mm_update_max_long_term_frame_idx(&pInfo->dpb, 0);
2352 pInfo->img.last_has_mmco_5 = 1;
2353 }break;
2354 case 6:{ //Mark the current picture as "used for long-term reference" and assign a long-term frame index to it
2355 h264_dpb_mm_mark_current_picture_long_term(&pInfo->dpb,
2356 pInfo->SliceHeader.sh_dec_refpic.long_term_frame_idx[idx]);
2357 }break;
2358 }
2359 idx++;
2360 }
2361
2362
2363 if (pInfo->img.last_has_mmco_5)
2364 {
2365 pInfo->img.frame_num = 0;
2366 pInfo->SliceHeader.frame_num=0;
2367 h264_dpb_set_active_fs(p_dpb, p_dpb->fs_dec_idc);
2368
2369 if (viddec_h264_get_dec_structure(active_fs) == FRAME)
2370 {
2371 pInfo->img.bottompoc -= active_fs->frame.poc;
2372 pInfo->img.toppoc -= active_fs->frame.poc;
2373
2374
2375 active_fs->frame.poc = 0;
2376 active_fs->frame.pic_num = 0;
2377 active_fs->frame_num = 0;
2378 }
2379
2380 else if (viddec_h264_get_dec_structure(active_fs) == TOP_FIELD)
2381 {
2382 active_fs->top_field.poc = active_fs->top_field.pic_num = 0;
2383 pInfo->img.toppoc = active_fs->top_field.poc;
2384 }
2385 else if (viddec_h264_get_dec_structure(active_fs) == BOTTOM_FIELD)
2386 {
2387 active_fs->bottom_field.poc = active_fs->bottom_field.pic_num = 0;
2388 pInfo->img.bottompoc = 0;
2389 }
2390
2391 h264_dpb_flush_dpb(pInfo, 1, pInfo->img.second_field,pInfo->active_SPS.num_ref_frames);
2392 }
2393 // Reset the marking count operations for the current picture...
2394 pInfo->SliceHeader.sh_dec_refpic.dec_ref_pic_marking_count = 0;
2395
2396 return;
2397 } ////// End of adaptive memory management
2398
2399 /* ------------------------------------------------------------------------------------------ */
2400 /* ------------------------------------------------------------------------------------------ */
2401 /* ------------------------------------------------------------------------------------------ */
2402 //////////////////////////////////////////////////////////////////////////////
2403 // h264_dpb_gaps_in_frame_num_mem_management ()
2404 //
2405 // Produces a set of frame_nums pertaining to "non-existing" pictures
2406 // Calls h264_dpb_store_picture_in_dpb
2407 //////////////////////////////////////////////////////////////////////////////
2408
h264_dpb_gaps_in_frame_num_mem_management(h264_Info * pInfo)2409 void h264_dpb_gaps_in_frame_num_mem_management(h264_Info * pInfo)
2410 {
2411 int32_t temp_frame_num = 0;
2412 int32_t idx, prev_idc;
2413 int32_t prev_frame_num_plus1_wrap;
2414 uint32_t temp;
2415 int32_t MaxFrameNum = 1 << (pInfo->active_SPS.log2_max_frame_num_minus4 + 4);
2416 seq_param_set_used_ptr active_sps = &pInfo->active_SPS;
2417 h264_DecodedPictureBuffer *p_dpb = &pInfo->dpb;
2418
2419 pInfo->img.gaps_in_frame_num = 0;
2420
2421 // pInfo->img.last_has_mmco_5 set thru store_picture_in_dpb
2422 if (pInfo->img.last_has_mmco_5)
2423 {
2424 // If the previous picture was an unpaired field, mark it as a dangler
2425 if(p_dpb->used_size)
2426 {
2427 idx = p_dpb->used_size-1;
2428 prev_idc = p_dpb->fs_dpb_idc[idx];
2429 if (prev_idc != MPD_DPB_FS_NULL_IDC)
2430 {
2431 h264_dpb_set_active_fs(p_dpb, p_dpb->fs_dpb_idc[idx]);
2432 active_fs->frame_num =0;
2433 }
2434 }
2435 pInfo->img.PreviousFrameNumOffset = 0;
2436 //CONFORMANCE_ISSUE
2437 pInfo->img.PreviousFrameNum = 0;
2438
2439 }
2440
2441 // Check for gaps in frame_num
2442 if(pInfo->SliceHeader.idr_flag) {
2443 pInfo->img.PreviousFrameNum = pInfo->img.frame_num;
2444 }
2445 // Have we re-started following a recovery point message?
2446 /*
2447 else if(got_sei_recovery || aud_got_restart){
2448 pInfo->img.PreviousFrameNum = pInfo->img.frame_num;
2449 //got_sei_recovery = 0;
2450 //aud_got_restart = 0;
2451 }
2452 */
2453 else if(pInfo->img.frame_num != pInfo->img.PreviousFrameNum)
2454 {
2455 if (MaxFrameNum)
2456 ldiv_mod_u((uint32_t)(pInfo->img.PreviousFrameNum + 1), (uint32_t)MaxFrameNum, &temp);
2457
2458 prev_frame_num_plus1_wrap = temp;
2459 if(pInfo->img.frame_num != prev_frame_num_plus1_wrap)
2460 {
2461 pInfo->img.gaps_in_frame_num = (pInfo->img.frame_num < pInfo->img.PreviousFrameNum)? ((MaxFrameNum + pInfo->img.frame_num -1) - pInfo->img.PreviousFrameNum): (pInfo->img.frame_num - pInfo->img.PreviousFrameNum - 1);
2462 // We should test for an error here - should infer an unintentional loss of pictures
2463 }
2464 }
2465
2466
2467 //if(active_sps->gaps_in_frame_num_value_allowed_flag == 0) {
2468 if(pInfo->img.gaps_in_frame_num && (active_sps->gaps_in_frame_num_value_allowed_flag == 0)) {
2469 // infer an unintentional loss of pictures
2470 // only invoke following process for a conforming bitstream
2471 // when gaps_in_frame_num_value_allowed_flag is equal to 1
2472 pInfo->img.gaps_in_frame_num = 0;
2473
2474 //mfd_printf("ERROR STREAM??\n");
2475 ////// Error handling here----
2476 }
2477
2478 /////// Removed following OLO source (Sodaville H.D)
2479 //else if (pInfo->img.gaps_in_frame_num > active_sps->num_ref_frames) {
2480 // // No need to produce any more non-existent frames than the amount required to flush the dpb
2481 // pInfo->img.gaps_in_frame_num = active_sps->num_ref_frames;
2482 //mfd_printf("gaps in frame: %d\n", gaps_in_frame_num);
2483 //}
2484
2485 // If the previous picture was an unpaired field, mark it as a dangler
2486 if(p_dpb->used_size)
2487 {
2488 idx = p_dpb->used_size-1;
2489 prev_idc = p_dpb->fs_dpb_idc[idx];
2490 if (prev_idc != MPD_DPB_FS_NULL_IDC)
2491 {
2492 h264_dpb_set_active_fs(p_dpb, p_dpb->fs_dpb_idc[idx]);
2493 if(viddec_h264_get_is_used(active_fs) != 3) {
2494 h264_dpb_mark_dangling_field(p_dpb, active_fs->fs_idc); //, DANGLING_TYPE_GAP_IN_FRAME
2495 }
2496 }
2497 }
2498
2499 while(temp_frame_num < pInfo->img.gaps_in_frame_num)
2500 {
2501 h264_dpb_assign_frame_store(pInfo, 1);
2502
2503 // Set up initial markings - not sure if all are needed
2504 viddec_h264_set_dec_structure(active_fs, FRAME);
2505
2506 if(MaxFrameNum)
2507 ldiv_mod_u((uint32_t)(pInfo->img.PreviousFrameNum + 1), (uint32_t)MaxFrameNum, &temp);
2508
2509 active_fs->frame.pic_num = temp;
2510 active_fs->long_term_frame_idx = 0;
2511 active_fs->frame.long_term_pic_num = 0;
2512 viddec_h264_set_is_frame_long_term(active_fs, 0);
2513
2514 // Note the call below will overwrite some aspects of the img structure with info relating to the
2515 // non-existent picture
2516 // However, since this is called before h264_hdr_decoding_poc() for the current existing picture
2517 // it should be o.k.
2518 if(pInfo->img.pic_order_cnt_type)
2519 h264_hdr_decoding_poc(pInfo, 1, temp);
2520
2521 pInfo->img.structure = FRAME;
2522 active_fs->frame.poc = pInfo->img.framepoc;
2523
2524 // call store_picture_in_dpb
2525
2526 h264_dpb_store_previous_picture_in_dpb(pInfo, 1, 0);
2527
2528 h264_hdr_post_poc(pInfo, 1, temp, 0);
2529
2530 temp_frame_num++;
2531 }
2532 }
2533
2534 /* ------------------------------------------------------------------------------------------ */
2535 /* ------------------------------------------------------------------------------------------ */
2536 /* ------------------------------------------------------------------------------------------ */
2537
2538 //////////////////////////////////////////////////////////////////////////////
2539 // h264_dpb_unmark_for_reference ()
2540 //
2541 // Mark FrameStore unused for reference. Removes it from the short term reference list
2542 //////////////////////////////////////////////////////////////////////////////
2543
h264_dpb_unmark_for_reference(h264_DecodedPictureBuffer * p_dpb,int32_t fs_idc)2544 void h264_dpb_unmark_for_reference(h264_DecodedPictureBuffer *p_dpb, int32_t fs_idc)
2545 {
2546 h264_dpb_set_active_fs(p_dpb, fs_idc);
2547
2548 if (viddec_h264_get_is_used(active_fs)&0x1) active_fs->top_field.used_for_reference = 0;
2549 if (viddec_h264_get_is_used(active_fs)&0x2) active_fs->bottom_field.used_for_reference = 0;
2550 if (viddec_h264_get_is_used(active_fs) == 3) active_fs->frame.used_for_reference = 0;
2551
2552 active_fs->frame.used_for_reference = 0;
2553 return;
2554 }
2555
2556
2557 /* ------------------------------------------------------------------------------------------ */
2558 /* ------------------------------------------------------------------------------------------ */
2559 /* ------------------------------------------------------------------------------------------ */
2560 //////////////////////////////////////////////////////////////////////////////
2561 // h264_dpb_unmark_for_long_term_reference ()
2562 //
2563 // mark FrameStore unused for reference and reset long term flags
2564 // This function does not remove it form the long term list
2565 //////////////////////////////////////////////////////////////////////////////
2566
h264_dpb_unmark_for_long_term_reference(h264_DecodedPictureBuffer * p_dpb,int32_t fs_idc)2567 void h264_dpb_unmark_for_long_term_reference(h264_DecodedPictureBuffer *p_dpb, int32_t fs_idc)
2568 {
2569 h264_dpb_set_active_fs(p_dpb, fs_idc);
2570
2571 if (viddec_h264_get_is_used(active_fs)&0x1)
2572 {
2573 active_fs->top_field.used_for_reference = 0;
2574 active_fs->top_field.is_long_term = 0;
2575 }
2576
2577 if (viddec_h264_get_is_used(active_fs)&0x2)
2578 {
2579 active_fs->bottom_field.used_for_reference = 0;
2580 active_fs->bottom_field.is_long_term = 0;
2581 }
2582 if (viddec_h264_get_is_used(active_fs) == 3)
2583 {
2584 active_fs->frame.used_for_reference = 0;
2585 active_fs->frame.is_long_term = 0;
2586 }
2587
2588 active_fs->frame.used_for_reference = 0;
2589 viddec_h264_set_is_frame_long_term(active_fs, 0);
2590
2591 return;
2592 }
2593
2594
2595 /* ------------------------------------------------------------------------------------------ */
2596 /* ------------------------------------------------------------------------------------------ */
2597 /* ------------------------------------------------------------------------------------------ */
2598 //////////////////////////////////////////////////////////////////////////////
2599 // h264_dpb_mark_dangling_field
2600 //
2601 // Tells HW previous field was dangling
2602 // Marks it in SW as so
2603 // Takes appropriate actions. - sys_data needs thought through...
2604 //////////////////////////////////////////////////////////////////////////////
2605
h264_dpb_mark_dangling_field(h264_DecodedPictureBuffer * p_dpb,int32_t fs_idc)2606 void h264_dpb_mark_dangling_field(h264_DecodedPictureBuffer *p_dpb, int32_t fs_idc)
2607 {
2608
2609 h264_dpb_set_active_fs(p_dpb, fs_idc);
2610
2611 //PRINTF(MFD_NONE, " fs_idc = %d DANGLING_TYPE = %d \n", fs_idc, reason);
2612 /*
2613 Make the check that it has not already been marked
2614 This covers the situation of a dangling field followed by a
2615 frame which is direct output (i.e. never entered into the dpb).
2616 In this case we could attempt to mark the prev unpaired field
2617 as a dangler twice which would upset the HW dpb_disp_q count
2618 */
2619
2620 if(viddec_h264_get_is_dangling(active_fs) == 0)
2621 {
2622 switch(viddec_h264_get_dec_structure(active_fs))
2623 {
2624 case TOP_FIELD:
2625 viddec_h264_set_is_dangling(active_fs, 1);
2626 //PRINTF(MFD_NONE, "FN:%d fs_idc=%d FRAME_FLAG_DANGLING_TOP_FIELD\n ", (h264_frame_number+1), active_fs->fs_idc);
2627 break;
2628 case BOTTOM_FIELD:
2629 //PRINTF(MFD_NONE, " FN:%d fs_idc=%d FRAME_FLAG_DANGLING_BOTTOM_FIELD \n ", (h264_frame_number+1), active_fs->fs_idc);
2630 viddec_h264_set_is_dangling(active_fs, 1);
2631 break;
2632 default:
2633 //PRINTF(MFD_NONE, "FN:%d fs_idc=%d DANGLING: FATAL_ERROR\n ", (h264_frame_number+1), active_fs->fs_idc);
2634 break;
2635 }
2636
2637 //h264_send_new_decoded_frame();
2638 }
2639 return;
2640 }
2641
2642 /* ------------------------------------------------------------------------------------------ */
2643 /* ------------------------------------------------------------------------------------------ */
2644 /* ------------------------------------------------------------------------------------------ */
2645
2646
2647 //////////////////////////////////////////////////////////////////////////////
2648 // h264_dpb_is_used_for_reference ()
2649 //
2650 // Check if one of the frames/fields in active_fs is used for reference
2651 //
h264_dpb_is_used_for_reference(int32_t * flag)2652 void h264_dpb_is_used_for_reference(int32_t * flag)
2653 {
2654
2655 /* Check out below for embedded */
2656 *flag = 0;
2657 if (active_fs->frame.used_for_reference)
2658 *flag = 1;
2659 else if (viddec_h264_get_is_used(active_fs) ==3) // frame
2660 *flag = active_fs->frame.used_for_reference;
2661 else
2662 {
2663 if (viddec_h264_get_is_used(active_fs)&0x1) // top field
2664 *flag = active_fs->top_field.used_for_reference;
2665 if (viddec_h264_get_is_used(active_fs)&0x2) // bottom field
2666 *flag = *flag || active_fs->bottom_field.used_for_reference;
2667 }
2668 }
2669
2670 /* ------------------------------------------------------------------------------------------ */
2671 /* ------------------------------------------------------------------------------------------ */
2672 /* ------------------------------------------------------------------------------------------ */
2673 //////////////////////////////////////////////////////////////////////////////
2674 // h264_dpb_idr_memory_management ()
2675 //
2676 // Perform Memory management for idr pictures
2677 //////////////////////////////////////////////////////////////////////////////
2678
h264_dpb_idr_memory_management(h264_Info * pInfo,seq_param_set_used_ptr active_sps,int32_t no_output_of_prior_pics_flag)2679 void h264_dpb_idr_memory_management (h264_Info * pInfo,seq_param_set_used_ptr active_sps, int32_t no_output_of_prior_pics_flag)
2680 {
2681 h264_DecodedPictureBuffer *p_dpb = &pInfo->dpb;
2682 uint32_t idx;
2683 uint32_t i;
2684 int32_t DPB_size;
2685 int32_t FrameSizeInBytes, FrameSizeInMbs;
2686 uint32_t data;
2687 int32_t num_ref_frames = active_sps->num_ref_frames;
2688 int32_t level_idc = active_sps->level_idc;
2689 uint32_t temp_bump_level=0;
2690
2691
2692 /// H.D-----
2693 /// There are 2 kinds of dpb flush defined, one is with display, the other is without display
2694 /// The function name dpb_flush actually is just the first, and the 2nd one is for error case or no_prior_output
2695 /// We will rewrite the code below to make it clean and clear
2696 ///
2697 if (no_output_of_prior_pics_flag)
2698 {
2699
2700 // free all stored pictures
2701 for (idx = 0; idx < p_dpb->used_size; idx = idx + 1)
2702 {
2703 h264_dpb_set_active_fs(p_dpb, p_dpb->fs_dpb_idc[idx]);
2704
2705 //mfd_printf(" directly freeing fs_idc = %d DSN = 0x%x \n",active_fs->fs_idc, active_fs->first_dsn);
2706 viddec_h264_set_is_frame_used(active_fs, 0);
2707 //if( (active_fs->frame_sent == 0x01) && (active_fs->is_output == 0x0))
2708 {
2709 //DECODED_FRAME sent but not DISPLAY_FRAME
2710 h264_dpb_unmark_for_reference(p_dpb, active_fs->fs_idc);
2711 h264_dpb_remove_ref_list(p_dpb, active_fs->fs_idc);
2712 //h264_send_new_display_frame(0x01); //send ignore_frame signal to Host
2713
2714 /// Add into drop-out list for all frms in dpb without display
2715 if(!(viddec_h264_get_is_non_existent(active_fs))) {
2716 if( viddec_h264_get_is_output(&(p_dpb->fs[p_dpb->fs_dpb_idc[idx]])) ) { //// This frame has been displayed but not released
2717 p_dpb->frame_id_need_to_be_removed[p_dpb->frame_numbers_need_to_be_removed] = p_dpb->fs_dpb_idc[idx];
2718 p_dpb->frame_numbers_need_to_be_removed ++;
2719 } else { //// This frame will be removed without display
2720 p_dpb->frame_id_need_to_be_dropped[p_dpb->frame_numbers_need_to_be_dropped] = p_dpb->fs_dpb_idc[idx];
2721 p_dpb->frame_numbers_need_to_be_dropped ++;
2722 }
2723 }
2724 }
2725
2726 }
2727
2728 ////////////////////////////////////////// Reset Reference list
2729 for (i = 0; i < p_dpb->ref_frames_in_buffer; i++)
2730 p_dpb->fs_ref_idc[i] = MPD_DPB_FS_NULL_IDC;
2731
2732 for (i = 0; i < p_dpb->ltref_frames_in_buffer; i++)
2733 p_dpb->fs_ltref_idc[i] = MPD_DPB_FS_NULL_IDC;
2734
2735 ////////////////////////////////////////// Reset DPB and dpb list
2736 for (i = 0; i < p_dpb->used_size; i++) {
2737 p_dpb->fs[p_dpb->fs_dpb_idc[i]].fs_idc = MPD_DPB_FS_NULL_IDC;
2738 p_dpb->fs_dpb_idc[i] = MPD_DPB_FS_NULL_IDC;
2739 }
2740
2741 p_dpb->used_size = 0;
2742 p_dpb->ref_frames_in_buffer = 0;
2743 p_dpb->ltref_frames_in_buffer = 0;
2744
2745 p_dpb->last_output_poc = 0x80000000;
2746 }
2747 else {
2748 h264_dpb_flush_dpb(pInfo, 1, pInfo->img.second_field, num_ref_frames);
2749 }
2750
2751 if (p_dpb->fs_dec_idc != MPD_DPB_FS_NULL_IDC) // added condition for use of DPB initialization
2752 {
2753 h264_dpb_set_active_fs(p_dpb, p_dpb->fs_dec_idc);
2754 if (pInfo->img.long_term_reference_flag)
2755 {
2756 p_dpb->max_long_term_pic_idx = 0;
2757 switch (viddec_h264_get_dec_structure(active_fs))
2758 {
2759 case FRAME : active_fs->frame.is_long_term = 1;
2760 case TOP_FIELD : active_fs->top_field.is_long_term = 1;
2761 case BOTTOM_FIELD : active_fs->bottom_field.is_long_term = 1;
2762 }
2763 active_fs->long_term_frame_idx = 0;
2764 }
2765 else
2766 {
2767 p_dpb->max_long_term_pic_idx = MPD_DPB_FS_NULL_IDC;
2768 viddec_h264_set_is_frame_long_term(active_fs, 0);
2769 }
2770 }
2771
2772 p_dpb->OutputLevel = 0;
2773 p_dpb->OutputLevelValid = 0;
2774 p_dpb->OutputCtrl = 0;
2775
2776
2777 // Set up bumping level - do this every time a parameters set is activated...
2778 if(active_sps->sps_disp.vui_parameters_present_flag)
2779 {
2780 if(active_sps->sps_disp.vui_seq_parameters.bitstream_restriction_flag)
2781 {
2782 //p_dpb->OutputLevel = active_sps->sps_disp.vui_seq_parameters.num_reorder_frames;
2783 //p_dpb->OutputLevelValid = 1;
2784 }
2785 }
2786
2787 // Set up bumping level - do this every time a parameters set is activated...
2788 switch(level_idc)
2789 {
2790 case h264_Level1b:
2791 case h264_Level1:
2792 {
2793 if ((active_sps->profile_idc < 100) && ((active_sps->constraint_set_flags & 0x1) == 0)) {
2794 DPB_size = 338;
2795 }
2796 else {
2797 DPB_size = 149;
2798 }
2799
2800 break;
2801 }
2802 case h264_Level11:
2803 {
2804 DPB_size = 338;
2805 break;
2806 }
2807 case h264_Level12:
2808 case h264_Level13:
2809 case h264_Level2:
2810 {
2811 DPB_size = 891;
2812 break;
2813 }
2814 case h264_Level21:
2815 {
2816 DPB_size = 1782;
2817 break;
2818 }
2819 case h264_Level22:
2820 case h264_Level3:
2821 {
2822 DPB_size = 3038;
2823 break;
2824 }
2825 case h264_Level31:
2826 {
2827 DPB_size = 6750;
2828 break;
2829 }
2830 case h264_Level32:
2831 {
2832 DPB_size = 7680;
2833 break;
2834 }
2835 case h264_Level4:
2836 case h264_Level41:
2837 {
2838 DPB_size = 12288;
2839 break;
2840 }
2841 case h264_Level42:
2842 {
2843 DPB_size = 13056;
2844 break;
2845 }
2846 case h264_Level5:
2847 {
2848 DPB_size = 41400;
2849 break;
2850 }
2851 case h264_Level51:
2852 {
2853 DPB_size = 69120;
2854 break;
2855 }
2856 default : DPB_size = 69120; break;
2857 }
2858
2859 FrameSizeInMbs = pInfo->img.PicWidthInMbs * pInfo->img.FrameHeightInMbs;
2860 FrameSizeInBytes = (FrameSizeInMbs << 8) + (FrameSizeInMbs << 7);
2861
2862 if(FrameSizeInBytes)
2863 {
2864
2865 temp_bump_level = ldiv_mod_u((DPB_size << 10), FrameSizeInBytes, &data);
2866
2867 if(temp_bump_level > 255)
2868 {
2869 p_dpb->BumpLevel = 255;
2870 }
2871 else
2872 {
2873 p_dpb->BumpLevel = (uint8_t)temp_bump_level;
2874 }
2875 }
2876
2877 if (p_dpb->BumpLevel == 0)
2878 p_dpb->BumpLevel = active_sps->num_ref_frames + 1;
2879
2880 if (p_dpb->BumpLevel > 16)
2881 p_dpb->BumpLevel = 16;
2882
2883
2884 if(active_sps->sps_disp.vui_parameters_present_flag && active_sps->sps_disp.vui_seq_parameters.bitstream_restriction_flag) {
2885
2886 if (active_sps->sps_disp.vui_seq_parameters.max_dec_frame_buffering > p_dpb->BumpLevel) {
2887 //MFD_PARSER_DEBUG(ERROR_H264_DPB);
2888 //// err handling here
2889 }
2890 else {
2891 p_dpb->BumpLevel = (active_sps->sps_disp.vui_seq_parameters.max_dec_frame_buffering > 1) ?
2892 (active_sps->sps_disp.vui_seq_parameters.max_dec_frame_buffering) : 1;
2893 }
2894 }
2895
2896
2897 // A new sequence means automatic frame release
2898 //sei_information.disp_frozen = 0;
2899
2900 return;
2901 } //// End --- dpb_idr_memory_management
2902
2903 /* ------------------------------------------------------------------------------------------ */
2904 /* ------------------------------------------------------------------------------------------ */
2905 /* ------------------------------------------------------------------------------------------ */
2906 //////////////////////////////////////////////////////////////////////////////
2907 // h264_dpb_remove_frame_from_dpb ()
2908 //
2909 // remove one frame from DPB
2910 // The parameter index, is the location of the frame to be removed in the
2911 // fs_dpb_idc list. The used size is decremented by one
2912 //////////////////////////////////////////////////////////////////////////////
2913
h264_dpb_remove_frame_from_dpb(h264_DecodedPictureBuffer * p_dpb,int32_t idx)2914 void h264_dpb_remove_frame_from_dpb(h264_DecodedPictureBuffer *p_dpb, int32_t idx)
2915 {
2916 int32_t fs_idc;
2917 uint32_t i;
2918
2919 fs_idc = p_dpb->fs_dpb_idc[idx];
2920
2921 h264_dpb_set_active_fs(p_dpb, fs_idc);
2922 viddec_h264_set_is_frame_used(active_fs, 0);
2923
2924 //add to support frame relocation interface to host
2925 if(!(viddec_h264_get_is_non_existent(active_fs)))
2926 {
2927 p_dpb->frame_id_need_to_be_removed[p_dpb->frame_numbers_need_to_be_removed] = p_dpb->fs[fs_idc].fs_idc;
2928 p_dpb->frame_numbers_need_to_be_removed ++;
2929 }
2930
2931 ///////////////////////////////////////// Reset FS
2932 p_dpb->fs[fs_idc].fs_idc = MPD_DPB_FS_NULL_IDC;
2933
2934 /////Remove unused frame from dpb-list
2935 i = idx;
2936 while( (i + 1)< p_dpb->used_size)
2937 {
2938 p_dpb->fs_dpb_idc[i] = p_dpb->fs_dpb_idc[i + 1];
2939 i ++;
2940 }
2941 p_dpb->fs_dpb_idc[i] = MPD_DPB_FS_NULL_IDC;
2942
2943 ////////////////////////////
2944 p_dpb->used_size--;
2945
2946 return;
2947 }
2948
2949 /* ------------------------------------------------------------------------------------------ */
2950 /* ------------------------------------------------------------------------------------------ */
2951 /* ------------------------------------------------------------------------------------------ */
2952
2953 //////////////////////////////////////////////////////////////////////////////
2954 // h264_dpb_remove_unused_frame_from_dpb ()
2955 //
2956 // Remove a picture from DPB which is no longer needed.
2957 // Search for a frame which is not used for reference and has previously been placed
2958 // in the output queue - if find one call h264_dpb_remove_frame_from_dpb() and
2959 // set flag 1
2960 //////////////////////////////////////////////////////////////////////////////
2961
h264_dpb_remove_unused_frame_from_dpb(h264_DecodedPictureBuffer * p_dpb,int32_t * flag)2962 void h264_dpb_remove_unused_frame_from_dpb(h264_DecodedPictureBuffer *p_dpb, int32_t * flag)
2963 {
2964 uint32_t idx;
2965 int32_t first_non_exist_valid, non_exist_idx;
2966 int32_t used_for_reference = 0;
2967
2968 *flag = 0;
2969 first_non_exist_valid = 0x0;
2970 non_exist_idx = 0x0;
2971
2972 for (idx = 0; (idx < p_dpb->used_size) && (*flag == 0); idx++)
2973 {
2974 h264_dpb_set_active_fs(p_dpb, p_dpb->fs_dpb_idc[idx]);
2975 h264_dpb_is_used_for_reference(&used_for_reference);
2976
2977 //if( (used_for_reference == 0x0 ) && active_fs->is_output && active_fs->is_non_existent == 0x0)
2978 //{
2979 //PRINTF(MFD_NONE, " requesting to send FREE: fs_idc = %d fb_id = %d \n", active_fs->fs_idc, active_fs->fb_id);
2980 //dpb_release_fb(&h264_dpb, active_fs->fb_id, 1);
2981 //}
2982
2983 if (viddec_h264_get_is_output(active_fs) && (used_for_reference == 0))
2984 {
2985 h264_dpb_remove_frame_from_dpb(p_dpb, idx);
2986 *flag = 1;
2987 }
2988 /*
2989 /////// Removed following OLO source (Sodaville H.D)
2990 else if ( (first_non_exist_valid == 0x0) && active_fs->is_non_existent )
2991 {
2992 first_non_exist_valid = 0x01;
2993 non_exist_idx = idx;
2994 }
2995 */
2996 }
2997 /*
2998 /////// Removed following OLO source (Sodaville H.D)
2999 if ( *flag == 0x0 && first_non_exist_valid) {
3000 h264_dpb_remove_frame_from_dpb(p_dpb,non_exist_idx);
3001 *flag = 1;
3002 }
3003 */
3004 return;
3005 } //// End of h264_dpb_remove_unused_frame_from_dpb
3006
3007
3008 /* ------------------------------------------------------------------------------------------ */
3009 /* ------------------------------------------------------------------------------------------ */
3010 /* ------------------------------------------------------------------------------------------ */
3011 //////////////////////////////////////////////////////////////////////////////
3012 // h264_dpb_get_smallest_poc ()
3013 //
3014 // find smallest POC in the DPB which has not as yet been output
3015 // This function only checks for frames and dangling fields...
3016 // unless the dpb used size is one, in which case it will accept an unpaired field
3017 //////////////////////////////////////////////////////////////////////////////
h264_dpb_get_smallest_poc(h264_DecodedPictureBuffer * p_dpb,int32_t * poc,int32_t * pos)3018 void h264_dpb_get_smallest_poc(h264_DecodedPictureBuffer *p_dpb, int32_t *poc, int32_t *pos)
3019 {
3020 int32_t poc_int;
3021 uint32_t idx;
3022 int32_t first_non_output = 1;
3023
3024 *pos = MPD_DPB_FS_NULL_IDC;
3025
3026 h264_dpb_set_active_fs(p_dpb, p_dpb->fs_dpb_idc[0]);
3027 poc_int = active_fs->frame.poc;
3028
3029 for (idx = 0; idx < p_dpb->used_size; idx++)
3030 {
3031 h264_dpb_set_active_fs(p_dpb, p_dpb->fs_dpb_idc[idx]);
3032
3033 if (viddec_h264_get_is_output(active_fs) == 0)
3034 {
3035 //PRINTF(MFD_NONE, " active_fs->fs_idc = %d active_fs->is_used = %d, active_fs->is_dangling = %d , active_fs->poc = %d \n", active_fs->fs_idc, active_fs->is_used, active_fs->is_dangling, active_fs->poc);
3036 if ((viddec_h264_get_is_used(active_fs) == 3) || (viddec_h264_get_is_dangling(active_fs)))
3037 {
3038 if (first_non_output)
3039 {
3040 *pos = idx;
3041 first_non_output = 0;
3042 poc_int = active_fs->frame.poc;
3043 }
3044 else if (poc_int > active_fs->frame.poc)
3045 {
3046 poc_int = active_fs->frame.poc;
3047 *pos = idx;
3048 }
3049 }
3050 else if (p_dpb->used_size == 1)
3051 {
3052 poc_int = active_fs->frame.poc;
3053 *pos = idx;
3054 }
3055 }
3056 }
3057
3058 *poc = poc_int;
3059
3060 return;
3061 }
3062
3063 /* ------------------------------------------------------------------------------------------ */
3064 /* ------------------------------------------------------------------------------------------ */
3065 /* ------------------------------------------------------------------------------------------ */
3066 //////////////////////////////////////////////////////////////////////////////
3067 // h264_dpb_split_field ()
3068 //
3069 // Extract field information from a frame
3070 //////////////////////////////////////////////////////////////////////////////
3071
h264_dpb_split_field(h264_Info * pInfo)3072 void h264_dpb_split_field (h264_Info * pInfo)
3073 {
3074
3075 //active_fs->frame.poc = active_fs->frame.poc;
3076 // active_fs->top_field.poc = active_fs->frame.poc;
3077 // This line changed on 11/05/05 KMc
3078 active_fs->top_field.poc = pInfo->img.toppoc;
3079 active_fs->bottom_field.poc = pInfo->img.bottompoc;
3080
3081 active_fs->top_field.used_for_reference = active_fs->frame.used_for_reference & 1;
3082 active_fs->bottom_field.used_for_reference = active_fs->frame.used_for_reference >> 1;
3083
3084 active_fs->top_field.is_long_term = active_fs->frame.is_long_term;
3085 active_fs->bottom_field.is_long_term = active_fs->frame.is_long_term;
3086
3087 active_fs->long_term_frame_idx = active_fs->frame.long_term_frame_idx;
3088 active_fs->top_field.long_term_frame_idx = active_fs->frame.long_term_frame_idx;
3089 active_fs->bottom_field.long_term_frame_idx = active_fs->frame.long_term_frame_idx;
3090
3091
3092 // Assign field mvs attached to MB-Frame buffer to the proper buffer
3093 //! Generate field MVs from Frame MVs
3094 // ...
3095 // these will be done in RTL through using proper memory mapping
3096 return;
3097 }
3098
3099
3100 /* ------------------------------------------------------------------------------------------ */
3101 /* ------------------------------------------------------------------------------------------ */
3102 /* ------------------------------------------------------------------------------------------ */
3103 //////////////////////////////////////////////////////////////////////////////
3104 // h264_dpb_combine_field (int32_t use_old)
3105 //
3106 // Generate a frame from top and bottom fields
3107 //////////////////////////////////////////////////////////////////////////////
3108
h264_dpb_combine_field(int32_t use_old)3109 void h264_dpb_combine_field(int32_t use_old)
3110 {
3111
3112 //remove warning
3113 use_old = use_old;
3114
3115 active_fs->frame.poc = (active_fs->top_field.poc < active_fs->bottom_field.poc)?
3116 active_fs->top_field.poc: active_fs->bottom_field.poc;
3117
3118 //active_fs->frame.poc = active_fs->poc;
3119
3120
3121 active_fs->frame.used_for_reference = active_fs->top_field.used_for_reference |(active_fs->bottom_field.used_for_reference);
3122
3123 active_fs->frame.is_long_term = active_fs->top_field.is_long_term |(active_fs->bottom_field.is_long_term <<1);
3124
3125 if (active_fs->frame.is_long_term)
3126 active_fs->frame.long_term_frame_idx = active_fs->long_term_frame_idx;
3127
3128 return;
3129
3130 }
3131
3132 /* ------------------------------------------------------------------------------------------ */
3133 /* ------------------------------------------------------------------------------------------ */
3134 /* ------------------------------------------------------------------------------------------ */
3135
3136 //////////////////////////////////////////////////////////////////////////////
3137 // h264_dpb_sliding_window_memory_management ()
3138 //
3139 // Perform Sliding window decoded reference picture marking process
3140 // It must be the reference frame, complementary reference field pair
3141 // or non-paired reference field that has the smallest value of
3142 // FrameNumWrap which is marked as unused for reference. Note : We CANNOT
3143 // simply use frame_num!!!!
3144 //
3145 // Although we hold frame_num_wrap in SW, currently, this is not
3146 // being updated for every picture (the b-picture parameter non-update
3147 // phenomenon of the reference software)
3148 //////////////////////////////////////////////////////////////////////////////
3149
h264_dpb_sliding_window_memory_management(h264_DecodedPictureBuffer * p_dpb,int32_t NonExisting,int32_t num_ref_frames)3150 void h264_dpb_sliding_window_memory_management(h264_DecodedPictureBuffer *p_dpb, int32_t NonExisting, int32_t num_ref_frames)
3151 {
3152 // if this is a reference pic with sliding window, unmark first ref frame
3153 // should this be (p_dpb->ref_frames_in_buffer + p_dpb->ltref_frames_in_buffer)
3154 // Rem: adaptive marking can be on a slice by slice basis so we
3155 // could have pictures merked as long term reference in adaptive marking and then
3156 // the marking mode changed back to sliding_window_memory_management
3157 if (p_dpb->ref_frames_in_buffer >= (num_ref_frames - p_dpb->ltref_frames_in_buffer))
3158 {
3159 h264_dpb_unmark_for_reference(p_dpb, p_dpb->fs_ref_idc[0]);
3160 h264_dpb_remove_ref_list(p_dpb, p_dpb->fs_ref_idc[0]);
3161
3162 if(NonExisting == 0)
3163 {
3164 h264_dpb_set_active_fs(p_dpb, p_dpb->fs_dec_idc);
3165 viddec_h264_set_is_frame_long_term(active_fs, 0);
3166 }
3167 }
3168 }
3169
3170 /* ------------------------------------------------------------------------------------------ */
3171 /* ------------------------------------------------------------------------------------------ */
3172 /* ------------------------------------------------------------------------------------------ */
3173 //////////////////////////////////////////////////////////////////////////////
3174 // h264_dpb_store_picture_in_dpb ()
3175 //
3176 // First we run the marking procedure.
3177 // Then, before we add the current frame_store to the list of refernce stores we run some checks
3178 // These include checking the number of existing reference frames
3179 // in DPB and if necessary, flushing frames.
3180 //
3181 // \param NonExisting
3182 // If non-zero this is called to store a non-existing frame resulting from gaps_in_frame_num
3183 //////////////////////////////////////////////////////////////////////////////
3184
3185 //////////////////////////////////////////////////////////////////////////////
3186 // h264_dpb_frame_output ()
3187 //
3188 // If direct == 1, Directly output a frame without storing it in the p_dpb->
3189 // Therefore we must set is_used to 0, which I guess means it will not appear
3190 // in the fs_dpb_idc list and is_output to 1 which means it should be in the
3191 // fs_output_idc list.
3192 //
3193 // If it is a non-existing pcture we do not actually place it in the output queue
3194 //////////////////////////////////////////////////////////////////////////////
3195
h264_dpb_frame_output(h264_Info * pInfo,int32_t fs_idc,int32_t direct,int32_t * existing)3196 void h264_dpb_frame_output(h264_Info * pInfo,int32_t fs_idc, int32_t direct, int32_t * existing)
3197 {
3198 h264_DecodedPictureBuffer *p_dpb = &pInfo->dpb;
3199
3200 h264_dpb_set_active_fs(p_dpb, fs_idc);
3201
3202 //h264_dpb_push_output_queue();
3203 if(pInfo->sei_information.disp_frozen)
3204 {
3205 // check pocs
3206 if(active_fs->top_field.poc >= pInfo->sei_information.freeze_POC)
3207 {
3208 if(active_fs->top_field.poc < pInfo->sei_information.release_POC)
3209 {
3210 viddec_h264_set_is_top_skipped(active_fs, 1);
3211 }
3212 else
3213 {
3214 pInfo->sei_information.disp_frozen = 0;
3215 }
3216 }
3217
3218 if(active_fs->bottom_field.poc >= pInfo->sei_information.freeze_POC)
3219 {
3220 if(active_fs->bottom_field.poc < pInfo->sei_information.release_POC)
3221 {
3222 viddec_h264_set_is_bottom_skipped(active_fs, 1);
3223 }
3224 else
3225 {
3226 pInfo->sei_information.disp_frozen = 0;
3227 }
3228 }
3229 }
3230
3231 if ( viddec_h264_get_broken_link_picture(active_fs) )
3232 pInfo->sei_information.broken_link = 1;
3233
3234 if( pInfo->sei_information.broken_link)
3235 {
3236 // Check if this was the recovery point picture - going to have recovery point on
3237 // a frame basis
3238 if(viddec_h264_get_recovery_pt_picture(active_fs))
3239 {
3240 pInfo->sei_information.broken_link = 0;
3241 // Also reset wait on sei recovery point picture
3242 p_dpb->WaitSeiRecovery = 0;
3243 }
3244 else
3245 {
3246 viddec_h264_set_is_frame_skipped(active_fs, 3);
3247 }
3248 }
3249 else
3250 {
3251 // even if this is not a broken - link, we need to follow SEI recovery point rules
3252 // Did we use SEI recovery point for th elast restart?
3253 if ( p_dpb->WaitSeiRecovery )
3254 {
3255 if ( viddec_h264_get_recovery_pt_picture(active_fs) ) {
3256 p_dpb->WaitSeiRecovery = 0;
3257 } else {
3258 viddec_h264_set_is_frame_skipped(active_fs, 3);
3259 }
3260 }
3261 }
3262
3263 if ( p_dpb->SuspendOutput )
3264 {
3265 if ( viddec_h264_get_open_gop_entry(active_fs) ) {
3266 p_dpb->SuspendOutput = 0;
3267 } else{
3268 viddec_h264_set_is_frame_skipped(active_fs, 3);
3269 }
3270 }
3271
3272 //h264_send_new_display_frame(0x0);
3273 viddec_h264_set_is_output(active_fs, 1);
3274
3275 if(viddec_h264_get_is_non_existent(active_fs) == 0)
3276 {
3277 *existing = 1;
3278 p_dpb->frame_id_need_to_be_displayed[p_dpb->frame_numbers_need_to_be_displayed]=active_fs->fs_idc;
3279 p_dpb->frame_numbers_need_to_be_displayed++;
3280
3281 //if(direct)
3282 //h264_dpb_remove_frame_from_dpb(p_dpb, active_fs->fs_idc); // Remove dpb.fs_dpb_idc[pos]
3283 }
3284 else
3285 {
3286 *existing = 0;
3287 }
3288
3289 if(direct) {
3290 viddec_h264_set_is_frame_used(active_fs, 0);
3291 active_fs->frame.used_for_reference = 0;
3292 active_fs->top_field.used_for_reference = 0;
3293 active_fs->bottom_field.used_for_reference = 0;
3294 active_fs->fs_idc = MPD_DPB_FS_NULL_IDC;
3295 }
3296 return;
3297 } ///////// End of dpb frame output
3298
3299
3300 /* ------------------------------------------------------------------------------------------ */
3301 /* ------------------------------------------------------------------------------------------ */
3302 /* ------------------------------------------------------------------------------------------ */
3303 //////////////////////////////////////////////////////////////////////////////
3304 // h264_dpb_output_one_frame_from_dpb ()
3305 //
3306 // Output one frame stored in the DPB. Basiclly this results in its placment
3307 // in the fs_output_idc list.
3308 // Placement in the output queue should cause an automatic removal from the dpb
3309 // if the frame store is not being used as a reference
3310 // This may need another param for a frame request so that it definitely outputs one non-exiosting frame
3311 //////////////////////////////////////////////////////////////////////////////
h264_dpb_output_one_frame_from_dpb(h264_Info * pInfo,int32_t direct,int32_t request,int32_t num_ref_frames)3312 int32_t h264_dpb_output_one_frame_from_dpb(h264_Info* pInfo,int32_t direct, int32_t request, int32_t num_ref_frames)
3313 {
3314 h264_DecodedPictureBuffer *p_dpb = &pInfo->dpb;
3315 int32_t poc;
3316 int32_t pos;
3317 int32_t used_for_reference;
3318
3319 int32_t existing = 0;
3320 int32_t is_refused = 0;
3321 int32_t is_pushed = 0;
3322
3323 //remove warning
3324 request = request;
3325
3326 if(direct)
3327 {
3328 h264_dpb_frame_output(pInfo, p_dpb->fs_dec_idc, 1, &existing);
3329 }
3330 else
3331 {
3332 if(p_dpb->used_size != 0)
3333 {
3334 // Should this be dpb.not_as_yet_output_num > 0 ??
3335 // There should maybe be a is_refused == 0 condition instead...
3336 while ((p_dpb->used_size > 0) && (existing == 0) && (is_refused == 0))
3337 {
3338 // find smallest non-output POC
3339 h264_dpb_get_smallest_poc(p_dpb, &poc, &pos);
3340 if (pos != MPD_DPB_FS_NULL_IDC)
3341 {
3342 // put it into the output queue
3343 h264_dpb_frame_output(pInfo, p_dpb->fs_dpb_idc[pos], 0, &existing);
3344
3345 p_dpb->last_output_poc = poc;
3346 if (existing) is_pushed = 1;
3347 // If non-reference, free frame store and move empty store to end of buffer
3348
3349 h264_dpb_is_used_for_reference(&used_for_reference);
3350 if (!(used_for_reference))
3351 h264_dpb_remove_frame_from_dpb(p_dpb, pos); // Remove dpb.fs_dpb_idc[pos]
3352 }
3353 else
3354 {
3355 int32_t flag;
3356 uint32_t idx;
3357
3358 // This is basically an error condition caused by too many reference frames in the DPB.
3359 // It should only happen in errored streams, and can happen if this picture had an MMCO,
3360 // thus disabling h264_dpb_sliding_window_memory_management(), which would normally have
3361 // unmarked the oldest reference frame.
3362 h264_dpb_sliding_window_memory_management(p_dpb, 0,num_ref_frames);
3363 h264_dpb_remove_unused_frame_from_dpb(p_dpb, &flag);
3364
3365 if (flag == 0) {
3366 for (idx = 0; idx < p_dpb->used_size; idx++)
3367 {
3368 h264_dpb_set_active_fs(p_dpb, p_dpb->fs_dpb_idc[idx]);
3369 h264_dpb_is_used_for_reference(&used_for_reference);
3370
3371 if (used_for_reference) {
3372 break;
3373 }
3374 }
3375
3376 if (idx < p_dpb->used_size) {
3377 // Short term
3378 h264_dpb_unmark_for_reference(p_dpb, p_dpb->fs_dpb_idc[idx]);
3379 h264_dpb_remove_ref_list(p_dpb, p_dpb->fs_dpb_idc[idx]);
3380
3381 // Long term
3382 h264_dpb_unmark_for_long_term_reference(p_dpb, p_dpb->fs_dpb_idc[idx]);
3383 h264_dpb_remove_ltref_list(p_dpb, p_dpb->fs_dpb_idc[idx]);
3384
3385 // Remove from DPB
3386 h264_dpb_remove_unused_frame_from_dpb(p_dpb, &flag);
3387 }
3388 }
3389 return 1;
3390 }
3391 }
3392 }
3393 }
3394
3395 return is_pushed;
3396 }
3397
3398
3399 /* ------------------------------------------------------------------------------------------ */
3400 /* ------------------------------------------------------------------------------------------ */
3401 /* ------------------------------------------------------------------------------------------ */
3402
3403 //////////////////////////////////////////////////////////////////////////////
3404 // h264_dpb_queue_update
3405 //
3406 // This should be called anytime the output queue might be changed
3407 //////////////////////////////////////////////////////////////////////////////
3408
h264_dpb_queue_update(h264_Info * pInfo,int32_t push,int32_t direct,int32_t frame_request,int32_t num_ref_frames)3409 int32_t h264_dpb_queue_update(h264_Info* pInfo,int32_t push, int32_t direct, int32_t frame_request, int32_t num_ref_frames)
3410 {
3411
3412 int32_t frame_output = 0;
3413
3414 if(push)
3415 {
3416 frame_output = h264_dpb_output_one_frame_from_dpb(pInfo, direct, 0, num_ref_frames);
3417 }
3418 else if(frame_request)
3419 {
3420 frame_output = h264_dpb_output_one_frame_from_dpb(pInfo, 0, 1,num_ref_frames);
3421 }
3422
3423
3424 return frame_output;
3425
3426 }
3427
3428 /* ------------------------------------------------------------------------------------------ */
3429 /* ------------------------------------------------------------------------------------------ */
3430 /* ------------------------------------------------------------------------------------------ */
3431
3432 //////////////////////////////////////////////////////////////////////////////
3433 // h264_dpb_flush_dpb ()
3434 //
3435 // Unmarks all reference pictures in the short-term and long term lists and
3436 // in doing so resets the lists.
3437 //
3438 // Flushing the dpb, adds all the current frames in the dpb, not already on the output list
3439 // to the output list and removes them from the dpb (they will all be marked as unused for
3440 // reference first)
3441 //////////////////////////////////////////////////////////////////////////////
3442
h264_dpb_flush_dpb(h264_Info * pInfo,int32_t output_all,int32_t keep_complement,int32_t num_ref_frames)3443 void h264_dpb_flush_dpb (h264_Info* pInfo,int32_t output_all, int32_t keep_complement, int32_t num_ref_frames)
3444 {
3445 h264_DecodedPictureBuffer *p_dpb = &pInfo->dpb;
3446
3447 int32_t idx, flag;
3448 int32_t ref_frames_in_buffer;
3449
3450 ref_frames_in_buffer = p_dpb->ref_frames_in_buffer;
3451
3452 for (idx = 0; idx < ref_frames_in_buffer; idx++){
3453 h264_dpb_unmark_for_reference(p_dpb, p_dpb->fs_ref_idc[0]);
3454 h264_dpb_remove_ref_list(p_dpb, p_dpb->fs_ref_idc[0]);
3455 }
3456
3457 ref_frames_in_buffer = p_dpb->ltref_frames_in_buffer;
3458
3459 for (idx = 0; idx < ref_frames_in_buffer; idx++)
3460 {
3461 h264_dpb_unmark_for_long_term_reference(p_dpb, p_dpb->fs_ltref_idc[0]);
3462 h264_dpb_remove_ltref_list(p_dpb, p_dpb->fs_ltref_idc[0]);
3463 }
3464
3465 // output frames in POC order
3466 if (output_all) {
3467 while (p_dpb->used_size - keep_complement) {
3468 h264_dpb_queue_update(pInfo, 1, 0, 0,num_ref_frames);
3469 }
3470 }
3471
3472 flag = 1;
3473 while (flag) {
3474 h264_dpb_remove_unused_frame_from_dpb(p_dpb, &flag);
3475 }
3476
3477 return;
3478 }
3479
3480 /* ------------------------------------------------------------------------------------------ */
3481 /* ------------------------------------------------------------------------------------------ */
3482 /* ------------------------------------------------------------------------------------------ */
3483 //////////////////////////////////////////////////////////////////////////////
3484 // h264_dpb_reset_dpb ()
3485 //
3486 // Used to reset the contents of dpb
3487 // Must calculate memory (aligned) pointers for each of the possible frame stores
3488 //
3489 // Also want to calculate possible max dpb size in terms of frames
3490 // We should have an active SPS when we call this ftn to calc bumping level
3491 //////////////////////////////////////////////////////////////////////////////
h264_dpb_reset_dpb(h264_Info * pInfo,int32_t PicWidthInMbs,int32_t FrameHeightInMbs,int32_t SizeChange,int32_t no_output_of_prior_pics_flag)3492 void h264_dpb_reset_dpb(h264_Info * pInfo,int32_t PicWidthInMbs, int32_t FrameHeightInMbs, int32_t SizeChange, int32_t no_output_of_prior_pics_flag)
3493 {
3494 h264_DecodedPictureBuffer *p_dpb = &pInfo->dpb;
3495
3496 int32_t num_ref_frames = pInfo->active_SPS.num_ref_frames;
3497
3498
3499 // If half way through a frame then Frame in progress will still be high,
3500 // so mark the previous field as a dangling field. This is also needed to
3501 // keep cs7050_sif_dpb_disp_numb_ptr correct. Better to reset instead?
3502 if(p_dpb->used_size)
3503 {
3504 int32_t idx;
3505 idx = p_dpb->used_size-1;
3506 if (p_dpb->fs_dpb_idc[idx] != MPD_DPB_FS_NULL_IDC)
3507 {
3508 h264_dpb_set_active_fs(p_dpb, p_dpb->fs_dpb_idc[idx]);
3509
3510 if(viddec_h264_get_is_used(active_fs) != 3)
3511 h264_dpb_mark_dangling_field(p_dpb, active_fs->fs_idc); //, DANGLING_TYPE_DPB_RESET
3512 }
3513 }
3514
3515 // initialize software DPB
3516 if(active_fs) {
3517 viddec_h264_set_dec_structure(active_fs, INVALID);
3518 }
3519 h264_dpb_idr_memory_management(pInfo, &pInfo->active_SPS, no_output_of_prior_pics_flag); // implied no_output_of_prior_pics_flag==1
3520
3521
3522 // May always be a size change which calls this function now...
3523 // could eliminate below branch
3524 if(SizeChange)
3525 {
3526
3527 /***
3528 Note : 21/03/2005 14:16
3529 Danger asociated with resetting curr_alloc_mem as it would allow the FW top reallocate
3530 frame stores from 0 -> NUM_FRAME_STORES again - could lead to queue overflow and corruption
3531
3532 Placed in size change condition in the hope that this will only ensure dpb is empty
3533 and thus this behaviour is valid before continuing again
3534 ***/
3535
3536
3537 p_dpb->PicWidthInMbs = PicWidthInMbs;
3538 p_dpb->FrameHeightInMbs = FrameHeightInMbs;
3539
3540 p_dpb->fs_dec_idc = MPD_DPB_FS_NULL_IDC;
3541 //Flush the current DPB.
3542 h264_dpb_flush_dpb(pInfo, 1,0,num_ref_frames);
3543 }
3544
3545 return;
3546 } ///// End of reset DPB
3547
3548 /* ------------------------------------------------------------------------------------------ */
3549 /* ------------------------------------------------------------------------------------------ */
3550 /* ------------------------------------------------------------------------------------------ */
3551 // ---------------------------------------------------------------------------
3552 // Note that if an 'missing_pip_fb' condition exists, the message will
3553 // sent to the host each time setup_free_fb is called. However, since this
3554 // condition is not expected to happen if pre-defined steps are followed, we let
3555 // it be for now and will change it if required. Basically, as long as host
3556 // enables PiP after adding PiP buffers and disables PiP before removing buffers
3557 // and matches PiP fb_id's with normal decode fb_id's this condition should
3558 // not occur.
3559 // ---------------------------------------------------------------------------
dpb_setup_free_fb(h264_DecodedPictureBuffer * p_dpb,uint8_t * fb_id,pip_setting_t * pip_setting)3560 int32_t dpb_setup_free_fb( h264_DecodedPictureBuffer *p_dpb, uint8_t* fb_id, pip_setting_t* pip_setting )
3561 {
3562 uint8_t idx;
3563
3564 //remove warning
3565 pip_setting = pip_setting;
3566
3567
3568 for (idx = 0; idx < NUM_DPB_FRAME_STORES; idx++)
3569 {
3570 if (p_dpb->fs[idx].fs_idc == MPD_DPB_FS_NULL_IDC)
3571 {
3572 *fb_id = idx;
3573 break;
3574 }
3575 }
3576
3577 if(idx == NUM_DPB_FRAME_STORES)
3578 return 1;
3579
3580 p_dpb->fs[idx].fs_idc = idx;
3581
3582 return 0;
3583
3584 }
3585
3586 /* ------------------------------------------------------------------------------------------ */
3587 /* ------------------------------------------------------------------------------------------ */
3588 /* ------------------------------------------------------------------------------------------ */
3589 //////////////////////////////////////////////////////////////////////////////
3590 // h264_dpb_assign_frame_store ()
3591 //
3592 // may need a non-existing option parameter
3593 //
3594
h264_dpb_assign_frame_store(h264_Info * pInfo,int32_t NonExisting)3595 int32_t h264_dpb_assign_frame_store(h264_Info * pInfo, int32_t NonExisting)
3596 {
3597 uint8_t idc = MPD_DPB_FS_NULL_IDC;
3598 pip_setting_t pip_setting;
3599 h264_DecodedPictureBuffer *p_dpb = &pInfo->dpb;
3600
3601
3602 while( dpb_setup_free_fb(p_dpb, &idc, &pip_setting) != 0 ) {
3603 ///
3604 /// Generally this is triggered a error case, no more frame buffer avaliable for next
3605 /// What we do here is just remove one with min-POC before get more info
3606 ///
3607
3608 int32_t pos = 0, poc = 0, existing = 1;
3609
3610 // find smallest non-output POC
3611 h264_dpb_get_smallest_poc(p_dpb, &poc, &pos);
3612 if (pos != MPD_DPB_FS_NULL_IDC)
3613 {
3614 // put it into the output queue
3615 h264_dpb_frame_output(pInfo, p_dpb->fs_dpb_idc[pos], 0, &existing);
3616 p_dpb->last_output_poc = poc;
3617 h264_dpb_remove_frame_from_dpb(p_dpb, pos); // Remove dpb.fs_dpb_idc[pos]
3618 }
3619 }
3620
3621
3622 if(NonExisting) {
3623 p_dpb->fs_non_exist_idc = idc;
3624 }else {
3625 p_dpb->fs_dec_idc = idc;
3626 }
3627
3628 //add to support frame relocation interface to host
3629 if(!NonExisting)
3630 {
3631 p_dpb->frame_numbers_need_to_be_allocated = 1;
3632 p_dpb->frame_id_need_to_be_allocated = p_dpb->fs_dec_idc;
3633 }
3634
3635
3636 ///////////////////////////////h264_dpb_reset_fs();
3637 h264_dpb_set_active_fs(p_dpb, idc);
3638 active_fs->fs_flag_1 = 0;
3639 active_fs->fs_flag_2 = 0;
3640 viddec_h264_set_is_non_existent(active_fs, NonExisting);
3641 viddec_h264_set_is_output(active_fs, (NonExisting?1:0));
3642
3643 active_fs->pic_type = ((FRAME_TYPE_INVALID<<FRAME_TYPE_TOP_OFFSET)|(FRAME_TYPE_INVALID<<FRAME_TYPE_BOTTOM_OFFSET)); //----
3644
3645 // Only put members in here which will not be reset somewhere else
3646 // and which could be used before they are overwritten again with
3647 // new valid values
3648 // eg ->is_used is reset on removal from dpb, no need for it here
3649 // ->poc would only be changed when we overwrite on insert_Picture_in_dpb()
3650 // but would be used by get_smallest_poc()
3651 // ->top.poc would also not be overwritten until a new valid value comes along,
3652 // but I don't think it is used before then so no need to reset
3653 //active_fs->is_long_term = 0;
3654 active_fs->frame.used_for_reference = 0;
3655 active_fs->frame.poc = 0;
3656
3657 return 1;
3658 }
3659
3660
3661 /* ------------------------------------------------------------------------------------------ */
3662 /* ------------------------------------------------------------------------------------------ */
3663 /* ------------------------------------------------------------------------------------------ */
3664 //////////////////////////////////////////////////////////////////////////////
3665 // h264_dpb_update_queue_dangling_field (h264_Info * pInfo)
3666 //
3667 // Update DPB for Dangling field special case
3668 //
h264_dpb_update_queue_dangling_field(h264_Info * pInfo)3669 void h264_dpb_update_queue_dangling_field(h264_Info * pInfo)
3670 {
3671 h264_DecodedPictureBuffer *dpb_ptr = &pInfo->dpb;
3672 int32_t prev_pic_unpaired_field = 0;
3673
3674 if(dpb_ptr->used_size > dpb_ptr->BumpLevel)
3675 {
3676 if (dpb_ptr->fs_dpb_idc[dpb_ptr->used_size-1] != MPD_DPB_FS_NULL_IDC)
3677 {
3678 h264_dpb_set_active_fs(dpb_ptr, dpb_ptr->fs_dpb_idc[dpb_ptr->used_size-1]);
3679 if(viddec_h264_get_is_used(active_fs) != 3)
3680 {
3681 prev_pic_unpaired_field = 1;
3682 }
3683 }
3684
3685 if (pInfo->img.structure != FRAME)
3686 {
3687 // To prove this is the second field,
3688 // 1) The previous picture is an (as yet) unpaired field
3689 if(prev_pic_unpaired_field)
3690 {
3691 // If we establish the previous pic was an unpaired field and this picture is not
3692 // its complement, the previous picture was a dangling field
3693 if(pInfo->img.second_field == 0) {
3694 while(dpb_ptr->used_size > dpb_ptr->BumpLevel)
3695 h264_dpb_queue_update(pInfo, 1, 0, 0,pInfo->active_SPS.num_ref_frames); // flush a frame
3696 }
3697 }
3698 }
3699 else if (prev_pic_unpaired_field) {
3700 while(dpb_ptr->used_size > dpb_ptr->BumpLevel)
3701 h264_dpb_queue_update(pInfo, 1, 0, 0,pInfo->active_SPS.num_ref_frames); // flush a frame
3702 }
3703 }
3704
3705
3706 return;
3707 } ///// End of init Frame Store
3708
3709
3710 /* ------------------------------------------------------------------------------------------ */
3711 /* ------------------------------------------------------------------------------------------ */
3712 /* ------------------------------------------------------------------------------------------ */
3713 //////////////////////////////////////////////////////////////////////////////
3714 // h264_dpb_init_frame_store (h264_Info * pInfo)
3715 //
3716 // Set the frame store to be used in decoding the picture
3717 //
3718
h264_dpb_init_frame_store(h264_Info * pInfo)3719 void h264_dpb_init_frame_store(h264_Info * pInfo)
3720 {
3721 h264_DecodedPictureBuffer *dpb_ptr = &pInfo->dpb;
3722
3723 int32_t free_fs_found;
3724 int32_t idx = 0;
3725 int32_t prev_pic_unpaired_field = 0;
3726 int32_t prev_idc = MPD_DPB_FS_NULL_IDC;
3727 int32_t structure = pInfo->img.structure;
3728
3729 if(dpb_ptr->used_size)
3730 {
3731 idx = dpb_ptr->used_size-1;
3732 prev_idc = dpb_ptr->fs_dpb_idc[idx];
3733 }
3734
3735 if (prev_idc != MPD_DPB_FS_NULL_IDC)
3736 {
3737 h264_dpb_set_active_fs(dpb_ptr, dpb_ptr->fs_dpb_idc[dpb_ptr->used_size-1]);
3738 if(viddec_h264_get_is_used(active_fs) != 3)
3739 {
3740 //PRINTF(MFD_NONE, " FN: %d active_fs->is_used = %d \n", (h264_frame_number+1), active_fs->is_used);
3741 prev_pic_unpaired_field = 1;
3742 }
3743 }
3744
3745 //if ((pInfo->img.curr_has_mmco_5) || (pInfo->img.idr_flag)) curr_fld_not_prev_comp = 1;
3746
3747 if (structure != FRAME)
3748 {
3749
3750 // To prove this is the second field,
3751 // 1) The previous picture is an (as yet) unpaired field
3752 if(prev_pic_unpaired_field)
3753 {
3754 // If we establish the previous pic was an unpaired field and this picture is not
3755 // its complement, the previous picture was a dangling field
3756 if(pInfo->img.second_field == 0)
3757 h264_dpb_mark_dangling_field(dpb_ptr, active_fs->fs_idc); //, DANGLING_TYPE_FIELD
3758 }
3759 }
3760 else if (prev_pic_unpaired_field) {
3761 h264_dpb_mark_dangling_field(dpb_ptr, active_fs->fs_idc); //, DANGLING_TYPE_FRAME
3762 }
3763
3764 free_fs_found = 0;
3765
3766 // If this is not a second field, we must find a free space for the current picture
3767 if (!(pInfo->img.second_field))
3768 {
3769 dpb_ptr->fs_dec_idc = MPD_DPB_FS_NULL_IDC;
3770 free_fs_found = h264_dpb_assign_frame_store(pInfo, 0);
3771 //h264_frame_number++;
3772 //PRINTF(MFD_NONE, " FN: %d (inc) fs_idc = %d \n", (h264_frame_number+1), dpb.fs_dec_idc);
3773 }
3774
3775 h264_dpb_set_active_fs(dpb_ptr, dpb_ptr->fs_dec_idc);
3776
3777 ////////////// TODO: THe following init
3778 #if 1
3779 if( pInfo->img.second_field) {
3780 //active_fs->second_dsn = pInfo->img.dsn;
3781 //active_fs->prev_dsn = pInfo->img.prev_dsn;
3782 if (active_fs->pic_type == FRAME_TYPE_IDR ||
3783 active_fs->pic_type == FRAME_TYPE_I) {
3784
3785 viddec_h264_set_first_field_intra(active_fs, 1);
3786 } else {
3787 viddec_h264_set_first_field_intra(active_fs, 0);
3788 }
3789
3790 }
3791 else {
3792 //active_fs->first_dsn = pInfo->img.dsn;
3793 //active_fs->prev_dsn = pInfo->img.prev_dsn;
3794 viddec_h264_set_first_field_intra(active_fs, 0);
3795 }
3796
3797 if (pInfo->img.structure == FRAME) {
3798 //active_fs->second_dsn = 0x0;
3799 }
3800
3801 if ( pInfo->sei_information.broken_link_pic )
3802 {
3803 viddec_h264_set_broken_link_picture(active_fs, 1);
3804 pInfo->sei_information.broken_link_pic = 0;
3805 }
3806
3807 if ((pInfo->img.frame_num == pInfo->sei_information.recovery_frame_num)&&(pInfo->SliceHeader.nal_ref_idc != 0))
3808 viddec_h264_set_recovery_pt_picture(active_fs, 1);
3809
3810 //if ((( gRestartMode.aud ) || ( gRestartMode.sei )) && ( !gRestartMode.idr))
3811 if(pInfo->img.recovery_point_found == 6)
3812 {
3813 viddec_h264_set_open_gop_entry(active_fs, 1);
3814 pInfo->dpb.SuspendOutput = 1;
3815 }
3816 #endif
3817
3818 if ((pInfo->img.second_field) || (free_fs_found))
3819 {
3820 viddec_h264_set_dec_structure(active_fs, pInfo->img.structure);
3821 viddec_h264_set_is_output(active_fs, 0);
3822
3823 switch(pInfo->img.structure)
3824 {
3825 case (FRAME) :{
3826 active_fs->frame.pic_num = pInfo->img.frame_num;
3827 active_fs->frame.long_term_frame_idx = 0;
3828 active_fs->frame.long_term_pic_num = 0;
3829 active_fs->frame.used_for_reference = 0;
3830 active_fs->frame.is_long_term = 0;
3831 //active_fs->frame.structure = pInfo->img.structure;
3832 active_fs->frame.poc = pInfo->img.framepoc;
3833 }break;
3834 case (TOP_FIELD) :{
3835 active_fs->top_field.pic_num = pInfo->img.frame_num;
3836 active_fs->top_field.long_term_frame_idx = 0;
3837 active_fs->top_field.long_term_pic_num = 0;
3838 active_fs->top_field.used_for_reference = 0;
3839 active_fs->top_field.is_long_term = 0;
3840 //active_fs->top_field.structure = pInfo->img.structure;
3841 active_fs->top_field.poc = pInfo->img.toppoc;
3842 }break;
3843 case(BOTTOM_FIELD) :{
3844 active_fs->bottom_field.pic_num = pInfo->img.frame_num;
3845 active_fs->bottom_field.long_term_frame_idx = 0;
3846 active_fs->bottom_field.long_term_pic_num = 0;
3847 active_fs->bottom_field.used_for_reference = 0;
3848 active_fs->bottom_field.is_long_term = 0;
3849 //active_fs->bottom_field.structure = pInfo->img.structure;
3850 active_fs->bottom_field.poc = pInfo->img.bottompoc;
3851 }break;
3852 }
3853 }
3854 else
3855 {
3856 // Need to drop a frame or something here
3857 }
3858
3859 return;
3860 } ///// End of init Frame Store
3861
3862
3863 /* ------------------------------------------------------------------------------------------ */
3864 /* ------------------------------------------------------------------------------------------ */
3865 /* ------------------------------------------------------------------------------------------ */
3866 //////////////////////////////////////////////////////////////////////////////
3867 // Decoding POC for current Picture
3868 // 1) pic_order_cnt_type (0, 1, 2)
3869 //
3870 //////////////////////////////////////////////////////////////////////////////
3871
h264_hdr_decoding_poc(h264_Info * pInfo,int32_t NonExisting,int32_t frame_num)3872 void h264_hdr_decoding_poc (h264_Info * pInfo,int32_t NonExisting, int32_t frame_num)
3873 {
3874 int32_t MaxPicOrderCntLsb = (1<<(pInfo->active_SPS.log2_max_pic_order_cnt_lsb_minus4+4));
3875 int32_t delta_pic_order_count[2];
3876 int32_t MaxFrameNum = 1 << (pInfo->active_SPS.log2_max_frame_num_minus4 + 4);
3877
3878 int32_t AbsFrameNum =0;
3879 int32_t ExpectedDeltaPerPicOrderCntCycle =0;
3880 int32_t PicOrderCntCycleCnt = 0;
3881 int32_t FrameNumInPicOrderCntCycle =0;
3882 int32_t ExpectedPicOrderCnt =0;
3883
3884 int32_t actual_frame_num =0;
3885
3886
3887
3888 if(NonExisting) actual_frame_num = frame_num;
3889 else actual_frame_num = pInfo->img.frame_num;
3890
3891 switch (pInfo->active_SPS.pic_order_cnt_type)
3892 {
3893 case 0:
3894 if(NonExisting != 0) break;
3895
3896 if (pInfo->SliceHeader.idr_flag)
3897 {
3898 pInfo->img.PicOrderCntMsb = 0;
3899 pInfo->img.PrevPicOrderCntLsb = 0;
3900 }
3901 else if (pInfo->img.last_has_mmco_5)
3902 {
3903 if (pInfo->img.last_pic_bottom_field)
3904 {
3905 pInfo->img.PicOrderCntMsb = 0;
3906 pInfo->img.PrevPicOrderCntLsb = 0;
3907 }
3908 else
3909 {
3910 pInfo->img.PicOrderCntMsb = 0;
3911 pInfo->img.PrevPicOrderCntLsb = pInfo->img.toppoc;
3912 }
3913 }
3914
3915 // Calculate the MSBs of current picture
3916 if((pInfo->img.pic_order_cnt_lsb < pInfo->img.PrevPicOrderCntLsb) &&
3917 ((pInfo->img.PrevPicOrderCntLsb - pInfo->img.pic_order_cnt_lsb )>=(MaxPicOrderCntLsb>>1)) )
3918 {
3919 pInfo->img.CurrPicOrderCntMsb = pInfo->img.PicOrderCntMsb + MaxPicOrderCntLsb;
3920 } else if ((pInfo->img.pic_order_cnt_lsb > pInfo->img.PrevPicOrderCntLsb) &&
3921 ((pInfo->img.pic_order_cnt_lsb - pInfo->img.PrevPicOrderCntLsb ) > (MaxPicOrderCntLsb>>1)) )
3922 {
3923 pInfo->img.CurrPicOrderCntMsb = pInfo->img.PicOrderCntMsb - MaxPicOrderCntLsb;
3924 } else
3925 {
3926 pInfo->img.CurrPicOrderCntMsb = pInfo->img.PicOrderCntMsb;
3927 }
3928
3929 // 2nd
3930
3931 if(pInfo->img.field_pic_flag==0)
3932 {
3933 //frame pix
3934 pInfo->img.toppoc = pInfo->img.CurrPicOrderCntMsb + pInfo->img.pic_order_cnt_lsb;
3935 pInfo->img.bottompoc = pInfo->img.toppoc + pInfo->img.delta_pic_order_cnt_bottom;
3936 pInfo->img.ThisPOC = pInfo->img.framepoc = (pInfo->img.toppoc < pInfo->img.bottompoc)? pInfo->img.toppoc : pInfo->img.bottompoc; // POC200301
3937 }
3938 else if (pInfo->img.bottom_field_flag==0)
3939 { //top field
3940 pInfo->img.ThisPOC= pInfo->img.toppoc = pInfo->img.CurrPicOrderCntMsb + pInfo->img.pic_order_cnt_lsb;
3941 }
3942 else
3943 { //bottom field
3944 pInfo->img.ThisPOC= pInfo->img.bottompoc = pInfo->img.CurrPicOrderCntMsb + pInfo->img.pic_order_cnt_lsb;
3945 }
3946 pInfo->img.framepoc=pInfo->img.ThisPOC;
3947
3948 if ( pInfo->img.frame_num != pInfo->old_slice.frame_num)
3949 pInfo->img.PreviousFrameNum = pInfo->img.frame_num;
3950
3951 if(pInfo->SliceHeader.nal_ref_idc)
3952 {
3953 pInfo->img.PrevPicOrderCntLsb = pInfo->img.pic_order_cnt_lsb;
3954 pInfo->img.PicOrderCntMsb = pInfo->img.CurrPicOrderCntMsb;
3955 }
3956
3957 break;
3958 case 1: {
3959 if(NonExisting)
3960 {
3961 delta_pic_order_count[0] = 0;
3962 delta_pic_order_count[1] = 0;
3963 }
3964 else
3965 {
3966 delta_pic_order_count[0] = ( pInfo->img.delta_pic_order_always_zero_flag ) ? 0 : pInfo->img.delta_pic_order_cnt[0];
3967 delta_pic_order_count[1] = ( pInfo->img.delta_pic_order_always_zero_flag ) ? 0 :
3968 ( (!pInfo->active_PPS.pic_order_present_flag) && (!(pInfo->img.field_pic_flag))) ? 0 :
3969 pInfo->img.delta_pic_order_cnt[1];
3970 }
3971
3972 // this if branch should not be taken during processing of a gap_in_frame_num pic since
3973 // an IDR picture cannot produce non-existent frames...
3974 if(pInfo->SliceHeader.idr_flag)
3975 {
3976 pInfo->img.FrameNumOffset = 0;
3977 }
3978 else
3979 {
3980
3981 if (actual_frame_num < pInfo->img.PreviousFrameNum)
3982 {
3983 pInfo->img.FrameNumOffset = pInfo->img.PreviousFrameNumOffset + MaxFrameNum;
3984 }
3985 else
3986 {
3987 pInfo->img.FrameNumOffset = pInfo->img.PreviousFrameNumOffset;
3988 }
3989 }
3990
3991 // pInfo->img.num_ref_frames_in_pic_order_cnt_cycle set from SPS
3992 // so constant between existent and non-existent frames
3993 if (pInfo->img.num_ref_frames_in_pic_order_cnt_cycle)
3994 AbsFrameNum = pInfo->img.FrameNumOffset + actual_frame_num;
3995 else
3996 AbsFrameNum = 0;
3997
3998 // pInfo->img.disposable_flag should never be true for a non-existent frame since these are always
3999 // references...
4000 if ((pInfo->SliceHeader.nal_ref_idc == 0) && (AbsFrameNum > 0)) AbsFrameNum = AbsFrameNum - 1;
4001
4002 // 3rd
4003 ExpectedDeltaPerPicOrderCntCycle = pInfo->active_SPS.expectedDeltaPerPOCCycle;
4004
4005 if (AbsFrameNum)
4006 {
4007 // Rem: pInfo->img.num_ref_frames_in_pic_order_cnt_cycle takes max value of 255 (8 bit)
4008 // Frame NUm may be 2^16 (17 bits)
4009 // I guess we really have to treat AbsFrameNum as a 32 bit number
4010 uint32_t temp = 0;
4011 int32_t i=0;
4012 int32_t offset_for_ref_frame[MAX_NUM_REF_FRAMES_IN_PIC_ORDER_CNT_CYCLE];
4013
4014 if (pInfo->img.num_ref_frames_in_pic_order_cnt_cycle)
4015 PicOrderCntCycleCnt = ldiv_mod_u((uint32_t)(AbsFrameNum-1), (uint32_t)pInfo->img.num_ref_frames_in_pic_order_cnt_cycle, &temp);
4016
4017 ExpectedPicOrderCnt = mult_u((uint32_t)PicOrderCntCycleCnt, (uint32_t)ExpectedDeltaPerPicOrderCntCycle);
4018
4019 FrameNumInPicOrderCntCycle = temp;
4020
4021 //ExpectedPicOrderCnt +=pInfo->active_SPS.expectedDeltaPerPOCCycle;
4022 #ifndef USER_MODE
4023 h264_Parse_Copy_Offset_Ref_Frames_From_DDR(pInfo, offset_for_ref_frame, pInfo->active_SPS.seq_parameter_set_id);
4024 for (i = 0; i <= FrameNumInPicOrderCntCycle; i++)
4025 ExpectedPicOrderCnt += offset_for_ref_frame[i];
4026 #else
4027 for (i = 0; i <= FrameNumInPicOrderCntCycle; i++)
4028 ExpectedPicOrderCnt += pInfo->active_SPS.offset_for_ref_frame[i];
4029 #endif
4030 }
4031 else {
4032 ExpectedPicOrderCnt = 0;
4033 }
4034
4035 if (pInfo->SliceHeader.nal_ref_idc == 0)
4036 ExpectedPicOrderCnt += pInfo->img.offset_for_non_ref_pic;
4037
4038 if (!(pInfo->img.field_pic_flag))
4039 {
4040 pInfo->img.toppoc = ExpectedPicOrderCnt + delta_pic_order_count[0];
4041 pInfo->img.bottompoc = pInfo->img.toppoc + pInfo->img.offset_for_top_to_bottom_field + delta_pic_order_count[1];
4042 pInfo->img.framepoc = (pInfo->img.toppoc < pInfo->img.bottompoc)? pInfo->img.toppoc : pInfo->img.bottompoc;
4043 pInfo->img.ThisPOC = pInfo->img.framepoc;
4044 }
4045 else if (!(pInfo->img.bottom_field_flag))
4046 {
4047 //top field
4048 pInfo->img.toppoc = ExpectedPicOrderCnt + delta_pic_order_count[0];
4049 pInfo->img.ThisPOC = pInfo->img.toppoc;
4050 pInfo->img.bottompoc = 0;
4051 }
4052 else
4053 {
4054 //bottom field
4055 pInfo->img.toppoc = 0;
4056 pInfo->img.bottompoc = ExpectedPicOrderCnt + pInfo->img.offset_for_top_to_bottom_field + delta_pic_order_count[0];
4057 pInfo->img.ThisPOC = pInfo->img.bottompoc;
4058 }
4059
4060 //CONFORMANCE_ISSUE
4061 pInfo->img.framepoc=pInfo->img.ThisPOC;
4062
4063 //CONFORMANCE_ISSUE
4064 pInfo->img.PreviousFrameNum=pInfo->img.frame_num;
4065 pInfo->img.PreviousFrameNumOffset=pInfo->img.FrameNumOffset;
4066
4067 }
4068 break;
4069 case 2: { // POC MODE 2
4070 if (pInfo->SliceHeader.idr_flag)
4071 {
4072 pInfo->img.FrameNumOffset = 0;
4073 pInfo->img.framepoc = 0;
4074 pInfo->img.toppoc = 0;
4075 pInfo->img.bottompoc = 0;
4076 pInfo->img.ThisPOC = 0;
4077 }
4078 else
4079 {
4080 if (pInfo->img.last_has_mmco_5)
4081 {
4082 pInfo->img.PreviousFrameNum = 0;
4083 pInfo->img.PreviousFrameNumOffset = 0;
4084 }
4085 if (actual_frame_num < pInfo->img.PreviousFrameNum)
4086 pInfo->img.FrameNumOffset = pInfo->img.PreviousFrameNumOffset + MaxFrameNum;
4087 else
4088 pInfo->img.FrameNumOffset = pInfo->img.PreviousFrameNumOffset;
4089
4090 AbsFrameNum = pInfo->img.FrameNumOffset + actual_frame_num;
4091 if (pInfo->SliceHeader.nal_ref_idc == 0) pInfo->img.ThisPOC = (AbsFrameNum<<1) - 1;
4092 else pInfo->img.ThisPOC = (AbsFrameNum<<1);
4093
4094 if (!(pInfo->img.field_pic_flag))
4095 {
4096 pInfo->img.toppoc = pInfo->img.ThisPOC;
4097 pInfo->img.bottompoc = pInfo->img.ThisPOC;
4098 pInfo->img.framepoc = pInfo->img.ThisPOC;
4099 }
4100 else if (!(pInfo->img.bottom_field_flag))
4101 {
4102 pInfo->img.toppoc = pInfo->img.ThisPOC;
4103 pInfo->img.framepoc = pInfo->img.ThisPOC;
4104 }
4105 else
4106 {
4107 pInfo->img.bottompoc = pInfo->img.ThisPOC;
4108 pInfo->img.framepoc = pInfo->img.ThisPOC;
4109 }
4110 }
4111
4112 //CONFORMANCE_ISSUE
4113 pInfo->img.PreviousFrameNum = pInfo->img.frame_num;
4114 pInfo->img.PreviousFrameNumOffset = pInfo->img.FrameNumOffset;
4115 }
4116 break;
4117 default:
4118 break;
4119 }
4120
4121 return;
4122 } //// End of decoding_POC
4123
4124 /* ------------------------------------------------------------------------------------------ */
4125 /* ------------------------------------------------------------------------------------------ */
4126 /* ------------------------------------------------------------------------------------------ */
4127 //////////////////////////////////////////////////////////////////////////////
4128 // h264_hdr_post_poc ()
4129 //
4130 //////////////////////////////////////////////////////////////////////////////
4131
h264_hdr_post_poc(h264_Info * pInfo,int32_t NonExisting,int32_t frame_num,int32_t use_old)4132 void h264_hdr_post_poc(h264_Info* pInfo, int32_t NonExisting, int32_t frame_num, int32_t use_old)
4133 {
4134 int32_t actual_frame_num = (NonExisting)? frame_num :
4135 (use_old)? pInfo->old_slice.frame_num :
4136 pInfo->img.frame_num;
4137
4138 int32_t disposable_flag = (use_old)?(pInfo->old_slice.nal_ref_idc == 0) :
4139 (pInfo->SliceHeader.nal_ref_idc == 0);
4140
4141 switch(pInfo->img.pic_order_cnt_type)
4142 {
4143 case 0: {
4144 pInfo->img.PreviousFrameNum = actual_frame_num;
4145 if ((disposable_flag == 0) && (NonExisting == 0))
4146 {
4147 pInfo->img.PrevPicOrderCntLsb = (use_old)? pInfo->old_slice.pic_order_cnt_lsb :
4148 pInfo->SliceHeader.pic_order_cnt_lsb;
4149 pInfo->img.PicOrderCntMsb = pInfo->img.CurrPicOrderCntMsb;
4150 }
4151 }
4152 break;
4153 case 1: {
4154 pInfo->img.PreviousFrameNum = actual_frame_num;
4155 pInfo->img.PreviousFrameNumOffset = pInfo->img.FrameNumOffset;
4156 }
4157 break;
4158 case 2: {
4159 pInfo->img.PreviousFrameNum = actual_frame_num;
4160 pInfo->img.PreviousFrameNumOffset = pInfo->img.FrameNumOffset;
4161
4162 }break;
4163
4164 default: {
4165 }break;
4166 }
4167
4168 return;
4169 } ///// End of h264_hdr_post_poc
4170
4171
4172