• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 = &ll;     // 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