/src/libavc/decoder/ih264d_dpb_mgr.c
Line | Count | Source |
1 | | /****************************************************************************** |
2 | | * |
3 | | * Copyright (C) 2015 The Android Open Source Project |
4 | | * |
5 | | * Licensed under the Apache License, Version 2.0 (the "License"); |
6 | | * you may not use this file except in compliance with the License. |
7 | | * You may obtain a copy of the License at: |
8 | | * |
9 | | * http://www.apache.org/licenses/LICENSE-2.0 |
10 | | * |
11 | | * Unless required by applicable law or agreed to in writing, software |
12 | | * distributed under the License is distributed on an "AS IS" BASIS, |
13 | | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
14 | | * See the License for the specific language governing permissions and |
15 | | * limitations under the License. |
16 | | * |
17 | | ***************************************************************************** |
18 | | * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore |
19 | | */ |
20 | | #ifdef __ANDROID__ |
21 | | #include <android/log.h> |
22 | | #endif |
23 | | #include "ih264_typedefs.h" |
24 | | #include "ih264_macros.h" |
25 | | #include "ih264_platform_macros.h" |
26 | | #include "iv.h" |
27 | | #include "ih264d_dpb_manager.h" |
28 | | #include "ih264d_bitstrm.h" |
29 | | #include "ih264d_parse_cavlc.h" |
30 | | #include "ih264d_defs.h" |
31 | | #include "ih264d_structs.h" |
32 | | #include "ih264d_process_bslice.h" |
33 | | #include "ih264d_debug.h" |
34 | | #include "ih264d_tables.h" |
35 | | #include "ih264d_error_handler.h" |
36 | | #include "string.h" |
37 | | #include "ih264d_defs.h" |
38 | | #include "ih264_error.h" |
39 | | #include "ih264_buf_mgr.h" |
40 | | #include "assert.h" |
41 | | |
42 | | #ifdef __ANDROID__ |
43 | | #ifndef ALOG |
44 | | #define ALOG(priority, tag, ...) ((void)__android_log_print(ANDROID_##priority, tag, __VA_ARGS__)) |
45 | | #define ALOGE(...) ALOG(LOG_ERROR, NULL, __VA_ARGS__) |
46 | | inline int android_errorWriteLog(int tag, const char* subTag) { |
47 | | ALOGE("android_errorWriteLog(%x, %s)", tag, subTag); |
48 | | return 0; |
49 | | } |
50 | | #endif |
51 | | #endif |
52 | | |
53 | | /*! |
54 | | *************************************************************************** |
55 | | * \file ih264d_dpb_mgr.c |
56 | | * |
57 | | * \brief |
58 | | * Functions for managing the decoded picture buffer |
59 | | * |
60 | | * Detailed_description |
61 | | * |
62 | | * \date |
63 | | * 19-12-2002 |
64 | | * |
65 | | * \author Sriram Sethuraman |
66 | | *************************************************************************** |
67 | | */ |
68 | | |
69 | | /*! |
70 | | ************************************************************************** |
71 | | * \if Function name : ih264d_init_ref_bufs \endif |
72 | | * |
73 | | * \brief |
74 | | * Called at the start for initialization. |
75 | | * |
76 | | * \return |
77 | | * none |
78 | | ************************************************************************** |
79 | | */ |
80 | | void ih264d_init_ref_bufs(dpb_manager_t *ps_dpb_mgr) |
81 | 2.38k | { |
82 | 2.38k | UWORD32 i; |
83 | 2.38k | struct dpb_info_t *ps_dpb_info = ps_dpb_mgr->as_dpb_info; |
84 | 78.6k | for(i = 0; i < MAX_REF_BUFS; i++) |
85 | 76.2k | { |
86 | 76.2k | ps_dpb_info[i].u1_used_as_ref = UNUSED_FOR_REF; |
87 | 76.2k | ps_dpb_info[i].u1_lt_idx = MAX_REF_BUFS + 1; |
88 | 76.2k | ps_dpb_info[i].ps_prev_short = NULL; |
89 | 76.2k | ps_dpb_info[i].ps_prev_long = NULL; |
90 | 76.2k | ps_dpb_info[i].ps_pic_buf = NULL; |
91 | 76.2k | ps_dpb_info[i].s_top_field.u1_reference_info = UNUSED_FOR_REF; |
92 | 76.2k | ps_dpb_info[i].s_bot_field.u1_reference_info = UNUSED_FOR_REF; |
93 | 76.2k | ps_dpb_info[i].s_top_field.u1_long_term_frame_idx = MAX_REF_BUFS + 1; |
94 | 76.2k | ps_dpb_info[i].s_bot_field.u1_long_term_frame_idx = MAX_REF_BUFS + 1; |
95 | | |
96 | 76.2k | } |
97 | 2.38k | ps_dpb_mgr->u1_num_st_ref_bufs = ps_dpb_mgr->u1_num_lt_ref_bufs = 0; |
98 | 2.38k | ps_dpb_mgr->ps_dpb_st_head = NULL; |
99 | 2.38k | ps_dpb_mgr->ps_dpb_ht_head = NULL; |
100 | 2.38k | ps_dpb_mgr->i1_gaps_deleted = 0; |
101 | 2.38k | ps_dpb_mgr->i1_poc_buf_id_entries = 0; |
102 | 2.38k | ps_dpb_mgr->u1_mmco_error_in_seq = 0; |
103 | | |
104 | 2.38k | ps_dpb_mgr->u1_num_gaps = 0; |
105 | 40.4k | for(i = 0; i < MAX_FRAMES; i++) |
106 | 38.1k | { |
107 | 38.1k | ps_dpb_mgr->ai4_gaps_start_frm_num[i] = INVALID_FRAME_NUM; |
108 | 38.1k | ps_dpb_mgr->ai4_gaps_end_frm_num[i] = 0; |
109 | 38.1k | ps_dpb_mgr->ai1_gaps_per_seq[i] = 0; |
110 | 38.1k | ps_dpb_mgr->ai4_poc_buf_id_map[i][0] = -1; |
111 | 38.1k | ps_dpb_mgr->ai4_poc_buf_id_map[i][1] = 0x7fffffff; |
112 | 38.1k | ps_dpb_mgr->ai4_poc_buf_id_map[i][2] = 0; |
113 | 38.1k | } |
114 | | |
115 | 2.38k | } |
116 | | |
117 | | void ih264d_free_ref_pic_mv_bufs(void* pv_dec, UWORD8 pic_buf_id) |
118 | 2.68k | { |
119 | 2.68k | dec_struct_t *ps_dec = (dec_struct_t *)pv_dec; |
120 | | |
121 | 2.68k | if((pic_buf_id == ps_dec->u1_pic_buf_id) && |
122 | 578 | ps_dec->ps_cur_slice->u1_field_pic_flag && |
123 | 293 | (ps_dec->u1_top_bottom_decoded == 0)) |
124 | 43 | { |
125 | 43 | return; |
126 | 43 | } |
127 | | |
128 | 2.64k | ih264_buf_mgr_release((buf_mgr_t *)ps_dec->pv_pic_buf_mgr, |
129 | 2.64k | pic_buf_id, |
130 | 2.64k | BUF_MGR_REF); |
131 | 2.64k | ih264_buf_mgr_release((buf_mgr_t *)ps_dec->pv_mv_buf_mgr, |
132 | 2.64k | ps_dec->as_buf_id_info_map[pic_buf_id].mv_buf_id, |
133 | 2.64k | BUF_MGR_REF); |
134 | 2.64k | } |
135 | | /*! |
136 | | ************************************************************************** |
137 | | * \if Function name : ih264d_delete_lt_node \endif |
138 | | * |
139 | | * \brief |
140 | | * Delete a buffer with a long term index from the LT linked list |
141 | | * |
142 | | * \return |
143 | | * none |
144 | | ************************************************************************** |
145 | | */ |
146 | | WORD32 ih264d_delete_lt_node(dpb_manager_t *ps_dpb_mgr, |
147 | | UWORD32 u4_lt_idx, |
148 | | UWORD8 u1_fld_pic_flag, |
149 | | struct dpb_info_t *ps_lt_node_to_insert, |
150 | | WORD32 *pi4_status) |
151 | 857 | { |
152 | 857 | *pi4_status = 0; |
153 | 857 | if(ps_dpb_mgr->u1_num_lt_ref_bufs > 0) |
154 | 290 | { |
155 | 290 | WORD32 i; |
156 | 290 | struct dpb_info_t *ps_next_dpb; |
157 | | /* ps_unmark_node points to the node to be removed */ |
158 | | /* from long term list. */ |
159 | 290 | struct dpb_info_t *ps_unmark_node; |
160 | | //Find the node with matching LTIndex |
161 | 290 | ps_next_dpb = ps_dpb_mgr->ps_dpb_ht_head; |
162 | 290 | if(ps_next_dpb->u1_lt_idx == u4_lt_idx) |
163 | 56 | { |
164 | 56 | ps_unmark_node = ps_next_dpb; |
165 | 56 | } |
166 | 234 | else |
167 | 234 | { |
168 | 235 | for(i = 1; i < ps_dpb_mgr->u1_num_lt_ref_bufs; i++) |
169 | 68 | { |
170 | 68 | if(ps_next_dpb->ps_prev_long->u1_lt_idx == u4_lt_idx) |
171 | 67 | break; |
172 | 1 | ps_next_dpb = ps_next_dpb->ps_prev_long; |
173 | 1 | } |
174 | 234 | if(i == ps_dpb_mgr->u1_num_lt_ref_bufs) |
175 | 167 | *pi4_status = 1; |
176 | 67 | else |
177 | 67 | ps_unmark_node = ps_next_dpb->ps_prev_long; |
178 | 234 | } |
179 | | |
180 | 290 | if(*pi4_status == 0) |
181 | 123 | { |
182 | 123 | if(u1_fld_pic_flag) |
183 | 45 | { |
184 | 45 | if(ps_lt_node_to_insert != ps_unmark_node) |
185 | 45 | { |
186 | 45 | UWORD8 u1_deleted = 0; |
187 | | /* for the ps_unmark_node mark the corresponding field */ |
188 | | /* field as unused for reference */ |
189 | | |
190 | 45 | if(ps_unmark_node->s_top_field.u1_long_term_frame_idx |
191 | 45 | == u4_lt_idx) |
192 | 37 | { |
193 | 37 | ps_unmark_node->s_top_field.u1_reference_info = |
194 | 37 | UNUSED_FOR_REF; |
195 | 37 | ps_unmark_node->s_top_field.u1_long_term_frame_idx = |
196 | 37 | MAX_REF_BUFS + 1; |
197 | 37 | u1_deleted = 1; |
198 | 37 | } |
199 | 45 | if(ps_unmark_node->s_bot_field.u1_long_term_frame_idx |
200 | 45 | == u4_lt_idx) |
201 | 27 | { |
202 | 27 | ps_unmark_node->s_bot_field.u1_reference_info = |
203 | 27 | UNUSED_FOR_REF; |
204 | 27 | ps_unmark_node->s_bot_field.u1_long_term_frame_idx = |
205 | 27 | MAX_REF_BUFS + 1; |
206 | 27 | u1_deleted = 1; |
207 | 27 | } |
208 | | |
209 | 45 | if(!u1_deleted) |
210 | 8 | { |
211 | | |
212 | 8 | UWORD32 i4_error_code; |
213 | 8 | i4_error_code = ERROR_DBP_MANAGER_T; |
214 | | |
215 | 8 | return i4_error_code; |
216 | 8 | } |
217 | 45 | } |
218 | | |
219 | 37 | ps_unmark_node->u1_used_as_ref = |
220 | 37 | ps_unmark_node->s_top_field.u1_reference_info |
221 | 37 | | ps_unmark_node->s_bot_field.u1_reference_info; |
222 | 37 | } |
223 | 78 | else |
224 | 78 | ps_unmark_node->u1_used_as_ref = UNUSED_FOR_REF; |
225 | | |
226 | 115 | if(UNUSED_FOR_REF == ps_unmark_node->u1_used_as_ref) |
227 | 105 | { |
228 | 105 | if(ps_unmark_node == ps_dpb_mgr->ps_dpb_ht_head) |
229 | 38 | ps_dpb_mgr->ps_dpb_ht_head = ps_next_dpb->ps_prev_long; |
230 | | |
231 | 105 | ps_unmark_node->u1_lt_idx = MAX_REF_BUFS + 1; |
232 | 105 | ps_unmark_node->s_top_field.u1_reference_info = |
233 | 105 | UNUSED_FOR_REF; |
234 | 105 | ps_unmark_node->s_bot_field.u1_reference_info = |
235 | 105 | UNUSED_FOR_REF; |
236 | | // Release the physical buffer |
237 | 105 | ih264d_free_ref_pic_mv_bufs(ps_dpb_mgr->pv_codec_handle, |
238 | 105 | ps_unmark_node->u1_buf_id); |
239 | 105 | ps_next_dpb->ps_prev_long = ps_unmark_node->ps_prev_long; //update link |
240 | 105 | ps_unmark_node->ps_prev_long = NULL; |
241 | 105 | ps_dpb_mgr->u1_num_lt_ref_bufs--; //decrement LT buf count |
242 | 105 | } |
243 | 115 | } |
244 | 290 | } |
245 | 849 | return OK; |
246 | 857 | } |
247 | | |
248 | | /*! |
249 | | ************************************************************************** |
250 | | * \if Function name : ih264d_insert_lt_node \endif |
251 | | * |
252 | | * \brief |
253 | | * Insert a buffer into the LT linked list at a given LT index |
254 | | * |
255 | | * \return |
256 | | * none |
257 | | ************************************************************************** |
258 | | */ |
259 | | WORD32 ih264d_insert_lt_node(dpb_manager_t *ps_dpb_mgr, |
260 | | struct dpb_info_t *ps_mov_node, |
261 | | UWORD32 u4_lt_idx, |
262 | | UWORD8 u1_fld_pic_flag) |
263 | 573 | { |
264 | 573 | UWORD8 u1_mark_top_field_long_term = 0; |
265 | 573 | UWORD8 u1_mark_bot_field_long_term = 0; |
266 | | |
267 | 573 | { |
268 | 573 | if(u1_fld_pic_flag) |
269 | 22 | { |
270 | | /* Assign corresponding field (top or bottom) long_term_frame_idx */ |
271 | | |
272 | 22 | if((ps_mov_node->s_top_field.u1_reference_info == IS_LONG_TERM) |
273 | 20 | && (ps_mov_node->s_bot_field.u1_reference_info |
274 | 20 | == IS_LONG_TERM)) |
275 | 0 | { |
276 | 0 | if(ps_mov_node->u1_lt_idx == u4_lt_idx) |
277 | 0 | u1_mark_bot_field_long_term = 1; |
278 | 0 | else |
279 | 0 | { |
280 | |
|
281 | 0 | UWORD32 i4_error_code; |
282 | 0 | i4_error_code = ERROR_DBP_MANAGER_T; |
283 | |
|
284 | 0 | return i4_error_code; |
285 | |
|
286 | 0 | } |
287 | 0 | } |
288 | 22 | else if(ps_mov_node->s_top_field.u1_reference_info == IS_LONG_TERM) |
289 | 20 | { |
290 | 20 | u1_mark_top_field_long_term = 1; |
291 | 20 | } |
292 | | |
293 | 22 | if(!(u1_mark_top_field_long_term || u1_mark_bot_field_long_term)) |
294 | 2 | { |
295 | 2 | UWORD32 i4_error_code; |
296 | 2 | i4_error_code = ERROR_DBP_MANAGER_T; |
297 | 2 | return i4_error_code; |
298 | 2 | } |
299 | 22 | } |
300 | 551 | else |
301 | 551 | { |
302 | 551 | ps_mov_node->s_top_field.u1_reference_info = IS_LONG_TERM; |
303 | 551 | ps_mov_node->s_bot_field.u1_reference_info = IS_LONG_TERM; |
304 | 551 | ps_mov_node->s_top_field.u1_long_term_frame_idx = u4_lt_idx; |
305 | 551 | ps_mov_node->s_bot_field.u1_long_term_frame_idx = u4_lt_idx; |
306 | 551 | u1_mark_bot_field_long_term = 1; |
307 | 551 | u1_mark_top_field_long_term = 1; |
308 | 551 | } |
309 | | |
310 | 571 | ps_mov_node->u1_lt_idx = u4_lt_idx; //Assign the LT index to the node |
311 | 571 | ps_mov_node->ps_pic_buf->u1_long_term_frm_idx = u4_lt_idx; |
312 | 571 | ps_mov_node->u1_used_as_ref = IS_LONG_TERM; |
313 | | |
314 | | /* Insert the new long term in the LT list with u4_lt_idx */ |
315 | | /* in ascending order. */ |
316 | 571 | if(ps_dpb_mgr->u1_num_lt_ref_bufs > 0) |
317 | 186 | { |
318 | 186 | struct dpb_info_t *ps_next_dpb = ps_dpb_mgr->ps_dpb_ht_head; |
319 | 186 | if(u4_lt_idx < ps_next_dpb->u1_lt_idx) |
320 | 20 | { |
321 | | //LTIndex to be inserted is the smallest LT index |
322 | | //Update head and point prev to the next higher index |
323 | 20 | ps_mov_node->ps_prev_long = ps_next_dpb; |
324 | 20 | ps_dpb_mgr->ps_dpb_ht_head = ps_mov_node; |
325 | 20 | } |
326 | 166 | else |
327 | 166 | { |
328 | 166 | WORD32 i; |
329 | 166 | struct dpb_info_t *ps_nxtDPB = ps_next_dpb; |
330 | 166 | ps_next_dpb = ps_next_dpb->ps_prev_long; |
331 | 166 | for(i = 1; i < ps_dpb_mgr->u1_num_lt_ref_bufs; i++) |
332 | 1 | { |
333 | 1 | if(ps_next_dpb->u1_lt_idx > u4_lt_idx) |
334 | 1 | break; |
335 | 0 | ps_nxtDPB = ps_next_dpb; |
336 | 0 | ps_next_dpb = ps_next_dpb->ps_prev_long; |
337 | 0 | } |
338 | | |
339 | 166 | ps_nxtDPB->ps_prev_long = ps_mov_node; |
340 | 166 | ps_mov_node->ps_prev_long = ps_next_dpb; |
341 | 166 | } |
342 | 186 | } |
343 | 385 | else |
344 | 385 | { |
345 | 385 | ps_dpb_mgr->ps_dpb_ht_head = ps_mov_node; |
346 | 385 | ps_mov_node->ps_prev_long = NULL; |
347 | 385 | } |
348 | | /* Identify the picture buffer as a long term picture buffer */ |
349 | 571 | ps_mov_node->ps_pic_buf->u1_is_short = 0; |
350 | | |
351 | | /* Increment LT buf count only if new LT node inserted */ |
352 | | /* If Increment during top_field is done, don't increment */ |
353 | | /* for bottom field, as both them are part of same pic. */ |
354 | 571 | if(u1_mark_bot_field_long_term) |
355 | 551 | ps_dpb_mgr->u1_num_lt_ref_bufs++; |
356 | | |
357 | 571 | } |
358 | 571 | return OK; |
359 | 573 | } |
360 | | |
361 | | /*! |
362 | | ************************************************************************** |
363 | | * \if Function name : ih264d_insert_st_node \endif |
364 | | * |
365 | | * \brief |
366 | | * Adds a short term reference picture into the ST linked list |
367 | | * |
368 | | * \return |
369 | | * None |
370 | | * |
371 | | * \note |
372 | | * Called only for a new coded picture with nal_ref_idc!=0 |
373 | | ************************************************************************** |
374 | | */ |
375 | | WORD32 ih264d_insert_st_node(dpb_manager_t *ps_dpb_mgr, |
376 | | struct pic_buffer_t *ps_pic_buf, |
377 | | UWORD8 u1_buf_id, |
378 | | UWORD32 u4_cur_pic_num) |
379 | 3.23k | { |
380 | 3.23k | WORD32 i; |
381 | 3.23k | struct dpb_info_t *ps_dpb_info = ps_dpb_mgr->as_dpb_info; |
382 | 3.23k | UWORD8 u1_picture_type = ps_pic_buf->u1_picturetype; |
383 | | /* Find an unused dpb location */ |
384 | 4.38k | for(i = 0; i < MAX_REF_BUFS; i++) |
385 | 4.38k | { |
386 | 4.38k | if((ps_dpb_info[i].ps_pic_buf == ps_pic_buf) |
387 | 207 | && ps_dpb_info[i].u1_used_as_ref) |
388 | 119 | { |
389 | | /*signal an error in the case of frame pic*/ |
390 | 119 | if(ps_dpb_info[i].ps_pic_buf->u1_pic_type == FRM_PIC) |
391 | 41 | { |
392 | 41 | return ERROR_DBP_MANAGER_T; |
393 | 41 | } |
394 | 78 | else |
395 | 78 | { |
396 | | /* Can occur only for field bottom pictures */ |
397 | 78 | ps_dpb_info[i].s_bot_field.u1_reference_info = IS_SHORT_TERM; |
398 | 78 | return OK; |
399 | 78 | } |
400 | 119 | } |
401 | | |
402 | 4.26k | if((ps_dpb_info[i].u1_used_as_ref == UNUSED_FOR_REF) |
403 | 3.11k | && (ps_dpb_info[i].s_top_field.u1_reference_info |
404 | 3.11k | == UNUSED_FOR_REF) |
405 | 3.11k | && (ps_dpb_info[i].s_bot_field.u1_reference_info |
406 | 3.11k | == UNUSED_FOR_REF)) |
407 | 3.11k | break; |
408 | 4.26k | } |
409 | 3.11k | if(i == MAX_REF_BUFS) |
410 | 0 | { |
411 | 0 | UWORD32 i4_error_code; |
412 | 0 | i4_error_code = ERROR_DBP_MANAGER_T; |
413 | 0 | return i4_error_code; |
414 | 0 | } |
415 | | |
416 | | /* Create dpb info */ |
417 | 3.11k | ps_dpb_info[i].ps_pic_buf = ps_pic_buf; |
418 | 3.11k | ps_dpb_info[i].ps_prev_short = ps_dpb_mgr->ps_dpb_st_head; |
419 | 3.11k | ps_dpb_info[i].u1_buf_id = u1_buf_id; |
420 | 3.11k | ps_dpb_info[i].u1_used_as_ref = TRUE; |
421 | 3.11k | ps_dpb_info[i].u1_lt_idx = MAX_REF_BUFS + 1; |
422 | 3.11k | ps_dpb_info[i].i4_frame_num = u4_cur_pic_num; |
423 | 3.11k | ps_dpb_info[i].ps_pic_buf->i4_frame_num = u4_cur_pic_num; |
424 | | |
425 | | /* update the head node of linked list to point to the cur Pic */ |
426 | 3.11k | ps_dpb_mgr->ps_dpb_st_head = ps_dpb_info + i; |
427 | | |
428 | | // Increment Short term bufCount |
429 | 3.11k | ps_dpb_mgr->u1_num_st_ref_bufs++; |
430 | | /* Identify the picture as a short term picture buffer */ |
431 | 3.11k | ps_pic_buf->u1_is_short = IS_SHORT_TERM; |
432 | | |
433 | 3.11k | if((u1_picture_type & 0x03) == FRM_PIC) |
434 | 2.38k | { |
435 | 2.38k | ps_dpb_info[i].u1_used_as_ref = IS_SHORT_TERM; |
436 | 2.38k | ps_dpb_info[i].s_top_field.u1_reference_info = IS_SHORT_TERM; |
437 | 2.38k | ps_dpb_info[i].s_bot_field.u1_reference_info = IS_SHORT_TERM; |
438 | 2.38k | } |
439 | | |
440 | 3.11k | if((u1_picture_type & 0x03) == TOP_FLD) |
441 | 141 | ps_dpb_info[i].s_top_field.u1_reference_info = IS_SHORT_TERM; |
442 | | |
443 | 3.11k | if((u1_picture_type & 0x03) == BOT_FLD) |
444 | 0 | ps_dpb_info[i].s_bot_field.u1_reference_info = IS_SHORT_TERM; |
445 | | |
446 | 3.11k | return OK; |
447 | 3.11k | } |
448 | | |
449 | | /*! |
450 | | ************************************************************************** |
451 | | * \if Function name : ih264d_delete_st_node_or_make_lt \endif |
452 | | * |
453 | | * \brief |
454 | | * Delete short term ref with a given picNum from the ST linked list or |
455 | | * make it an LT node |
456 | | * |
457 | | * \return |
458 | | * 0 - if successful; -1 - otherwise |
459 | | * |
460 | | * \note |
461 | | * Common parts to MMCO==1 and MMCO==3 have been combined here |
462 | | ************************************************************************** |
463 | | */ |
464 | | WORD32 ih264d_delete_st_node_or_make_lt(dpb_manager_t *ps_dpb_mgr, |
465 | | WORD32 i4_pic_num, |
466 | | UWORD32 u4_lt_idx, |
467 | | UWORD8 u1_fld_pic_flag) |
468 | 915 | { |
469 | 915 | WORD32 i; |
470 | 915 | struct dpb_info_t *ps_next_dpb; |
471 | 915 | WORD32 i4_frame_num = i4_pic_num; |
472 | 915 | struct dpb_info_t *ps_unmark_node = NULL; |
473 | 915 | UWORD8 u1_del_node = 0, u1_del_st = 0; |
474 | 915 | UWORD8 u1_reference_type = UNUSED_FOR_REF; |
475 | 915 | WORD32 ret; |
476 | | |
477 | 915 | if(u1_fld_pic_flag) |
478 | 338 | { |
479 | 338 | i4_frame_num = i4_frame_num >> 1; |
480 | | |
481 | 338 | if(u4_lt_idx == (MAX_REF_BUFS + 1)) |
482 | 296 | u1_reference_type = UNUSED_FOR_REF; |
483 | 42 | else |
484 | 42 | u1_reference_type = IS_LONG_TERM; |
485 | 338 | } |
486 | | |
487 | | //Find the node with matching picNum |
488 | 915 | ps_next_dpb = ps_dpb_mgr->ps_dpb_st_head; |
489 | 915 | if((WORD32)ps_next_dpb->i4_frame_num == i4_frame_num) |
490 | 579 | { |
491 | 579 | ps_unmark_node = ps_next_dpb; |
492 | 579 | } |
493 | 336 | else |
494 | 336 | { |
495 | 365 | for(i = 1; i < ps_dpb_mgr->u1_num_st_ref_bufs; i++) |
496 | 58 | { |
497 | 58 | if((WORD32)ps_next_dpb->ps_prev_short->i4_frame_num == i4_frame_num) |
498 | 29 | break; |
499 | 29 | ps_next_dpb = ps_next_dpb->ps_prev_short; |
500 | 29 | } |
501 | | |
502 | 336 | if(i == ps_dpb_mgr->u1_num_st_ref_bufs) |
503 | 307 | { |
504 | 307 | if(ps_dpb_mgr->u1_num_gaps) |
505 | 263 | { |
506 | 263 | ret = ih264d_delete_gap_frm_mmco(ps_dpb_mgr, i4_frame_num, &u1_del_st); |
507 | 263 | if(ret != OK) |
508 | 127 | return ret; |
509 | 263 | } |
510 | 44 | else |
511 | 44 | { |
512 | 44 | UWORD32 i4_error_code; |
513 | 44 | i4_error_code = ERROR_DBP_MANAGER_T; |
514 | | |
515 | 44 | return i4_error_code; |
516 | 44 | } |
517 | | |
518 | 136 | if(u1_del_st) |
519 | 0 | { |
520 | 0 | UWORD32 i4_error_code; |
521 | 0 | i4_error_code = ERROR_DBP_MANAGER_T; |
522 | 0 | return i4_error_code; |
523 | 0 | } |
524 | 136 | else |
525 | 136 | { |
526 | 136 | return 0; |
527 | 136 | } |
528 | 136 | } |
529 | 29 | else |
530 | 29 | ps_unmark_node = ps_next_dpb->ps_prev_short; |
531 | 336 | } |
532 | | |
533 | 608 | if(u1_fld_pic_flag) |
534 | 37 | { |
535 | | /* Mark the corresponding field ( top or bot) as */ |
536 | | /* UNUSED_FOR_REF or IS_LONG_TERM depending on */ |
537 | | /* u1_reference_type. */ |
538 | 37 | if(ps_unmark_node->s_top_field.i4_pic_num == i4_pic_num) |
539 | 28 | { |
540 | 28 | ps_unmark_node->s_top_field.u1_reference_info = u1_reference_type; |
541 | 28 | ps_unmark_node->s_top_field.u1_long_term_frame_idx = u4_lt_idx; |
542 | 28 | { |
543 | 28 | UWORD8 *pu1_src = ps_unmark_node->ps_pic_buf->pu1_col_zero_flag; |
544 | 28 | WORD32 i4_size = ((ps_dpb_mgr->u2_pic_wd |
545 | 28 | * ps_dpb_mgr->u2_pic_ht) >> 5); |
546 | | /* memset the colocated zero u4_flag buffer */ |
547 | 28 | memset(pu1_src, 0, i4_size); |
548 | 28 | } |
549 | 28 | } |
550 | | |
551 | 9 | else if(ps_unmark_node->s_bot_field.i4_pic_num == i4_pic_num) |
552 | 7 | { |
553 | | |
554 | 7 | ps_unmark_node->s_bot_field.u1_reference_info = u1_reference_type; |
555 | 7 | ps_unmark_node->s_bot_field.u1_long_term_frame_idx = u4_lt_idx; |
556 | 7 | { |
557 | 7 | UWORD8 *pu1_src = |
558 | 7 | ps_unmark_node->ps_pic_buf->pu1_col_zero_flag |
559 | 7 | + ((ps_dpb_mgr->u2_pic_wd |
560 | 7 | * ps_dpb_mgr->u2_pic_ht) |
561 | 7 | >> 5); |
562 | 7 | WORD32 i4_size = ((ps_dpb_mgr->u2_pic_wd |
563 | 7 | * ps_dpb_mgr->u2_pic_ht) >> 5); |
564 | | /* memset the colocated zero u4_flag buffer */ |
565 | 7 | memset(pu1_src, 0, i4_size); |
566 | 7 | } |
567 | 7 | } |
568 | 37 | ps_unmark_node->u1_used_as_ref = |
569 | 37 | ps_unmark_node->s_top_field.u1_reference_info |
570 | 37 | | ps_unmark_node->s_bot_field.u1_reference_info; |
571 | 37 | } |
572 | 571 | else |
573 | 571 | { |
574 | 571 | ps_unmark_node->u1_used_as_ref = UNUSED_FOR_REF; |
575 | 571 | ps_unmark_node->s_top_field.u1_reference_info = UNUSED_FOR_REF; |
576 | 571 | ps_unmark_node->s_bot_field.u1_reference_info = UNUSED_FOR_REF; |
577 | | |
578 | 571 | { |
579 | 571 | UWORD8 *pu1_src = ps_unmark_node->ps_pic_buf->pu1_col_zero_flag; |
580 | | |
581 | 571 | WORD32 i4_size = ((ps_dpb_mgr->u2_pic_wd |
582 | 571 | * ps_dpb_mgr->u2_pic_ht) >> 4); |
583 | | /* memset the colocated zero u4_flag buffer */ |
584 | 571 | memset(pu1_src, 0, i4_size); |
585 | 571 | } |
586 | 571 | } |
587 | | |
588 | 608 | if(!(ps_unmark_node->u1_used_as_ref & IS_SHORT_TERM)) |
589 | 592 | { |
590 | 592 | if(ps_unmark_node == ps_dpb_mgr->ps_dpb_st_head) |
591 | 573 | ps_dpb_mgr->ps_dpb_st_head = ps_next_dpb->ps_prev_short; |
592 | 19 | else |
593 | 19 | ps_next_dpb->ps_prev_short = ps_unmark_node->ps_prev_short; //update link |
594 | 592 | ps_dpb_mgr->u1_num_st_ref_bufs--; //decrement ST buf count |
595 | 592 | u1_del_node = 1; |
596 | 592 | } |
597 | | |
598 | 608 | if(u4_lt_idx == MAX_REF_BUFS + 1) |
599 | 27 | { |
600 | 27 | if(u1_del_node) |
601 | 21 | { |
602 | | // Release the physical buffer |
603 | 21 | ih264d_free_ref_pic_mv_bufs(ps_dpb_mgr->pv_codec_handle, |
604 | 21 | ps_unmark_node->u1_buf_id); |
605 | 21 | ps_unmark_node->ps_prev_short = NULL; |
606 | 21 | } |
607 | 27 | } |
608 | 581 | else |
609 | 581 | { |
610 | 581 | WORD32 i4_status; |
611 | | //If another node has the same LT index, delete that node |
612 | 581 | ret = ih264d_delete_lt_node(ps_dpb_mgr, u4_lt_idx, |
613 | 581 | u1_fld_pic_flag, ps_unmark_node, &i4_status); |
614 | 581 | if(ret != OK) |
615 | 8 | return ret; |
616 | | // Now insert the short term node as a long term node |
617 | 573 | ret = ih264d_insert_lt_node(ps_dpb_mgr, ps_unmark_node, u4_lt_idx, |
618 | 573 | u1_fld_pic_flag); |
619 | 573 | if(ret != OK) |
620 | 2 | return ret; |
621 | 573 | } |
622 | 598 | return OK; |
623 | 608 | } |
624 | | /*! |
625 | | ************************************************************************** |
626 | | * \if Function name : ih264d_reset_ref_bufs \endif |
627 | | * |
628 | | * \brief |
629 | | * Called if MMCO==5/7 or on the first slice of an IDR picture |
630 | | * |
631 | | * \return |
632 | | * none |
633 | | ************************************************************************** |
634 | | */ |
635 | | void ih264d_reset_ref_bufs(dpb_manager_t *ps_dpb_mgr) |
636 | 5.26k | { |
637 | 5.26k | WORD32 i; |
638 | 5.26k | struct dpb_info_t *ps_dpb_info = ps_dpb_mgr->as_dpb_info; |
639 | | |
640 | 173k | for(i = 0; i < MAX_REF_BUFS; i++) |
641 | 168k | { |
642 | 168k | if(ps_dpb_info[i].u1_used_as_ref) |
643 | 1.91k | { |
644 | 1.91k | ps_dpb_info[i].u1_used_as_ref = UNUSED_FOR_REF; |
645 | 1.91k | ps_dpb_info[i].u1_lt_idx = MAX_REF_BUFS + 1; |
646 | 1.91k | ps_dpb_info[i].ps_prev_short = NULL; |
647 | 1.91k | ps_dpb_info[i].ps_prev_long = NULL; |
648 | 1.91k | ps_dpb_info[i].ps_pic_buf = NULL; |
649 | 1.91k | ps_dpb_info[i].s_top_field.u1_reference_info = UNUSED_FOR_REF; |
650 | 1.91k | ps_dpb_info[i].s_bot_field.u1_reference_info = UNUSED_FOR_REF; |
651 | 1.91k | ps_dpb_info[i].s_top_field.u1_long_term_frame_idx = MAX_REF_BUFS + 1; |
652 | 1.91k | ps_dpb_info[i].s_bot_field.u1_long_term_frame_idx = MAX_REF_BUFS + 1; |
653 | | |
654 | | //Release physical buffer |
655 | 1.91k | ih264d_free_ref_pic_mv_bufs(ps_dpb_mgr->pv_codec_handle, |
656 | 1.91k | ps_dpb_info[i].u1_buf_id); |
657 | 1.91k | } |
658 | 168k | } |
659 | 5.26k | ps_dpb_mgr->u1_num_st_ref_bufs = ps_dpb_mgr->u1_num_lt_ref_bufs = 0; |
660 | 5.26k | ps_dpb_mgr->ps_dpb_st_head = NULL; |
661 | 5.26k | ps_dpb_mgr->ps_dpb_ht_head = NULL; |
662 | 5.26k | ps_dpb_mgr->u1_mmco_error_in_seq = 0; |
663 | | |
664 | | /* release all gaps */ |
665 | 5.26k | ps_dpb_mgr->u1_num_gaps = 0; |
666 | 89.4k | for(i = 0; i < MAX_FRAMES; i++) |
667 | 84.1k | { |
668 | 84.1k | ps_dpb_mgr->ai4_gaps_start_frm_num[i] = INVALID_FRAME_NUM; |
669 | 84.1k | ps_dpb_mgr->ai4_gaps_end_frm_num[i] = 0; |
670 | 84.1k | ps_dpb_mgr->ai1_gaps_per_seq[i] = 0; |
671 | 84.1k | } |
672 | 5.26k | } |
673 | | |
674 | | /*! |
675 | | ************************************************************************** |
676 | | * \if Function name : Name \endif |
677 | | * |
678 | | * \brief |
679 | | * create the default index list after an MMCO |
680 | | * |
681 | | * \return |
682 | | * 0 - if no_error; -1 - error |
683 | | * |
684 | | ************************************************************************** |
685 | | */ |
686 | | WORD32 ih264d_update_default_index_list(dpb_manager_t *ps_dpb_mgr) |
687 | 4.68k | { |
688 | 4.68k | WORD32 i; |
689 | 4.68k | struct dpb_info_t *ps_next_dpb = ps_dpb_mgr->ps_dpb_st_head; |
690 | | |
691 | 10.8k | for(i = 0; i < ps_dpb_mgr->u1_num_st_ref_bufs; i++) |
692 | 6.18k | { |
693 | 6.18k | ps_dpb_mgr->ps_def_dpb[i] = ps_next_dpb->ps_pic_buf; |
694 | 6.18k | ps_next_dpb = ps_next_dpb->ps_prev_short; |
695 | 6.18k | } |
696 | | |
697 | 4.68k | ps_next_dpb = ps_dpb_mgr->ps_dpb_ht_head; |
698 | 5.39k | for(;i< ps_dpb_mgr->u1_num_st_ref_bufs + ps_dpb_mgr->u1_num_lt_ref_bufs; i++) |
699 | 717 | { |
700 | 717 | ps_dpb_mgr->ps_def_dpb[i] = ps_next_dpb->ps_pic_buf; |
701 | 717 | ps_next_dpb = ps_next_dpb->ps_prev_long; |
702 | 717 | } |
703 | 4.68k | return 0; |
704 | 4.68k | } |
705 | | |
706 | | /*! |
707 | | ************************************************************************** |
708 | | * \if Function name : ref_idx_reordering \endif |
709 | | * |
710 | | * \brief |
711 | | * Parse the bitstream and reorder indices for the current slice |
712 | | * |
713 | | * \return |
714 | | * 0 - if no_error; -1 - error |
715 | | * |
716 | | * \note |
717 | | * Called only if ref_idx_reordering_flag_l0 is decoded as 1 |
718 | | * Remove error checking for unmatching picNum or LTIndex later (if not needed) |
719 | | * \para |
720 | | * This section implements 7.3.3.1 and 8.2.6.4 |
721 | | * Uses the default index list as the starting point and |
722 | | * remaps the picNums sent to the next higher index in the |
723 | | * modified list. The unmodified ones are copied from the |
724 | | * default to modified list retaining their order in the default list. |
725 | | * |
726 | | ************************************************************************** |
727 | | */ |
728 | | WORD32 ih264d_ref_idx_reordering(dec_struct_t *ps_dec, UWORD8 uc_lx) |
729 | 3.27k | { |
730 | 3.27k | dpb_manager_t *ps_dpb_mgr = ps_dec->ps_dpb_mgr; |
731 | 3.27k | UWORD16 u4_cur_pic_num = ps_dec->ps_cur_slice->u2_frame_num; |
732 | | /*< Maximum Picture Number Minus 1 */ |
733 | 3.27k | UWORD32 ui_max_frame_num = |
734 | 3.27k | ps_dec->ps_cur_sps->u2_u4_max_pic_num_minus1 + 1; |
735 | | |
736 | 3.27k | WORD32 i, count = 0; |
737 | 3.27k | UWORD32 ui_remapIdc, ui_nextUev; |
738 | 3.27k | WORD16 u2_pred_frame_num = u4_cur_pic_num; |
739 | 3.27k | WORD32 i_temp; |
740 | 3.27k | UWORD16 u2_def_mod_flag = 0; /* Flag to keep track of which indices have been remapped */ |
741 | 3.27k | UWORD8 modCount = 0; |
742 | 3.27k | UWORD32 *pu4_bitstrm_buf = ps_dec->ps_bitstrm->pu4_buffer; |
743 | 3.27k | UWORD32 *pu4_bitstrm_ofst = &ps_dec->ps_bitstrm->u4_ofst; |
744 | 3.27k | dec_slice_params_t *ps_cur_slice = ps_dec->ps_cur_slice; |
745 | 3.27k | UWORD8 u1_field_pic_flag = ps_cur_slice->u1_field_pic_flag; |
746 | | |
747 | 3.27k | if(u1_field_pic_flag) |
748 | 800 | { |
749 | 800 | u4_cur_pic_num = u4_cur_pic_num * 2 + 1; |
750 | 800 | ui_max_frame_num = ui_max_frame_num * 2; |
751 | 800 | } |
752 | | |
753 | 3.27k | u2_pred_frame_num = u4_cur_pic_num; |
754 | | |
755 | 3.27k | ui_remapIdc = ih264d_uev(pu4_bitstrm_ofst, pu4_bitstrm_buf); |
756 | | |
757 | 4.75k | while((ui_remapIdc != 3) |
758 | 4.32k | && (count < ps_cur_slice->u1_num_ref_idx_lx_active[uc_lx])) |
759 | 4.21k | { |
760 | 4.21k | ui_nextUev = ih264d_uev(pu4_bitstrm_ofst, pu4_bitstrm_buf); |
761 | 4.21k | if(ui_remapIdc != 2) |
762 | 3.83k | { |
763 | 3.83k | if(ui_nextUev > ui_max_frame_num) |
764 | 26 | return ERROR_DBP_MANAGER_T; |
765 | | |
766 | 3.81k | ui_nextUev = ui_nextUev + 1; |
767 | | |
768 | 3.81k | if(ui_remapIdc == 0) |
769 | 2.92k | { |
770 | | // diffPicNum is -ve |
771 | 2.92k | i_temp = (WORD32)u2_pred_frame_num - (WORD32)ui_nextUev; |
772 | 2.92k | if(i_temp < 0) |
773 | 589 | i_temp += ui_max_frame_num; |
774 | 2.92k | } |
775 | 886 | else |
776 | 886 | { |
777 | | // diffPicNum is +ve |
778 | 886 | i_temp = (WORD32)u2_pred_frame_num + (WORD32)ui_nextUev; |
779 | 886 | if(i_temp >= (WORD32)ui_max_frame_num) |
780 | 53 | i_temp -= ui_max_frame_num; |
781 | 886 | } |
782 | | /* Find the dpb with the matching picNum (picNum==frameNum for framePic) */ |
783 | | |
784 | 3.81k | if(i_temp > u4_cur_pic_num) |
785 | 922 | i_temp = i_temp - ui_max_frame_num; |
786 | | |
787 | 7.96k | for(i = 0; i < (ps_cur_slice->u1_initial_list_size[uc_lx]); i++) |
788 | 5.58k | { |
789 | 5.58k | if(ps_dpb_mgr->ps_init_dpb[uc_lx][i]->i4_pic_num == i_temp) |
790 | 1.42k | break; |
791 | 5.58k | } |
792 | 3.81k | if(i == (ps_cur_slice->u1_initial_list_size[uc_lx])) |
793 | 2.38k | { |
794 | 2.38k | UWORD32 i4_error_code; |
795 | 2.38k | i4_error_code = ERROR_DBP_MANAGER_T; |
796 | 2.38k | return i4_error_code; |
797 | 2.38k | } |
798 | | |
799 | 1.42k | u2_def_mod_flag |= (1 << i); |
800 | 1.42k | ps_dpb_mgr->ps_mod_dpb[uc_lx][modCount++] = |
801 | 1.42k | ps_dpb_mgr->ps_init_dpb[uc_lx][i]; |
802 | 1.42k | u2_pred_frame_num = i_temp; //update predictor to be the picNum just obtained |
803 | 1.42k | } |
804 | 374 | else //2 |
805 | 374 | { |
806 | 374 | UWORD8 u1_lt_idx; |
807 | | |
808 | 374 | if(ui_nextUev > (MAX_REF_BUFS + 1)) |
809 | 0 | return ERROR_DBP_MANAGER_T; |
810 | | |
811 | 374 | u1_lt_idx = (UWORD8)ui_nextUev; |
812 | | |
813 | 970 | for(i = 0; i < (ps_cur_slice->u1_initial_list_size[uc_lx]); i++) |
814 | 651 | { |
815 | 651 | if(!ps_dpb_mgr->ps_init_dpb[uc_lx][i]->u1_is_short) |
816 | 66 | { |
817 | 66 | if(ps_dpb_mgr->ps_init_dpb[uc_lx][i]->u1_long_term_pic_num |
818 | 66 | == u1_lt_idx) |
819 | 55 | break; |
820 | 66 | } |
821 | 651 | } |
822 | 374 | if(i == (ps_cur_slice->u1_initial_list_size[uc_lx])) |
823 | 319 | { |
824 | 319 | UWORD32 i4_error_code; |
825 | 319 | i4_error_code = ERROR_DBP_MANAGER_T; |
826 | 319 | return i4_error_code; |
827 | 319 | } |
828 | | |
829 | 55 | u2_def_mod_flag |= (1 << i); |
830 | 55 | ps_dpb_mgr->ps_mod_dpb[uc_lx][modCount++] = |
831 | 55 | ps_dpb_mgr->ps_init_dpb[uc_lx][i]; |
832 | 55 | } |
833 | | |
834 | 1.48k | ui_remapIdc = ih264d_uev(pu4_bitstrm_ofst, pu4_bitstrm_buf); |
835 | | /* Get the remapping_idc - 0/1/2/3 */ |
836 | 1.48k | count++; |
837 | 1.48k | } |
838 | | |
839 | | //Handle the ref indices that were not remapped |
840 | 2.19k | for(i = 0; i < (ps_cur_slice->u1_num_ref_idx_lx_active[uc_lx]); i++) |
841 | 1.65k | { |
842 | 1.65k | if(!(u2_def_mod_flag & (1 << i))) |
843 | 800 | ps_dpb_mgr->ps_mod_dpb[uc_lx][modCount++] = |
844 | 800 | ps_dpb_mgr->ps_init_dpb[uc_lx][i]; |
845 | 1.65k | } |
846 | 543 | return OK; |
847 | 3.27k | } |
848 | | /*! |
849 | | ************************************************************************** |
850 | | * \if Function name : ih264d_read_mmco_commands \endif |
851 | | * |
852 | | * \brief |
853 | | * Parses MMCO commands and stores them in a structure for later use. |
854 | | * |
855 | | * \return |
856 | | * 0 - No error; -1 - Error |
857 | | * |
858 | | * \note |
859 | | * This function stores MMCO commands in structure only for the first time. |
860 | | * In case of MMCO commands being issued for same Picture Number, they are |
861 | | * just parsed and not stored them in the structure. |
862 | | * |
863 | | ************************************************************************** |
864 | | */ |
865 | | WORD32 ih264d_read_mmco_commands(struct _DecStruct * ps_dec) |
866 | 81.1k | { |
867 | 81.1k | dec_pic_params_t *ps_pps = ps_dec->ps_cur_pps; |
868 | 81.1k | dec_seq_params_t *ps_sps = ps_pps->ps_sps; |
869 | 81.1k | dec_bit_stream_t *ps_bitstrm = ps_dec->ps_bitstrm; |
870 | 81.1k | dpb_commands_t *ps_dpb_cmds = &(ps_dec->s_dpb_cmds_scratch); |
871 | 81.1k | dec_slice_params_t * ps_slice = ps_dec->ps_cur_slice; |
872 | 81.1k | WORD32 j; |
873 | 81.1k | UWORD8 u1_buf_mode; |
874 | 81.1k | struct MMCParams *ps_mmc_params; |
875 | 81.1k | UWORD32 *pu4_bitstrm_buf = ps_dec->ps_bitstrm->pu4_buffer; |
876 | 81.1k | UWORD32 *pu4_bitstrm_ofst = &ps_bitstrm->u4_ofst; |
877 | 81.1k | UWORD32 u4_bit_ofst = ps_dec->ps_bitstrm->u4_ofst; |
878 | | |
879 | 81.1k | ps_slice->u1_mmco_equalto5 = 0; |
880 | 81.1k | { |
881 | 81.1k | if(ps_dec->u1_nal_unit_type == IDR_SLICE_NAL) |
882 | 22.9k | { |
883 | 22.9k | ps_slice->u1_no_output_of_prior_pics_flag = |
884 | 22.9k | ih264d_get_bit_h264(ps_bitstrm); |
885 | 22.9k | COPYTHECONTEXT("SH: no_output_of_prior_pics_flag", |
886 | 22.9k | ps_slice->u1_no_output_of_prior_pics_flag); |
887 | 22.9k | ps_slice->u1_long_term_reference_flag = ih264d_get_bit_h264( |
888 | 22.9k | ps_bitstrm); |
889 | 22.9k | COPYTHECONTEXT("SH: long_term_reference_flag", |
890 | 22.9k | ps_slice->u1_long_term_reference_flag); |
891 | 22.9k | ps_dpb_cmds->u1_idr_pic = 1; |
892 | 22.9k | ps_dpb_cmds->u1_no_output_of_prior_pics_flag = |
893 | 22.9k | ps_slice->u1_no_output_of_prior_pics_flag; |
894 | 22.9k | ps_dpb_cmds->u1_long_term_reference_flag = |
895 | 22.9k | ps_slice->u1_long_term_reference_flag; |
896 | 22.9k | } |
897 | 58.2k | else |
898 | 58.2k | { |
899 | 58.2k | u1_buf_mode = ih264d_get_bit_h264(ps_bitstrm); //0 - sliding window; 1 - arbitrary |
900 | 58.2k | COPYTHECONTEXT("SH: adaptive_ref_pic_buffering_flag", u1_buf_mode); |
901 | 58.2k | ps_dpb_cmds->u1_buf_mode = u1_buf_mode; |
902 | 58.2k | j = 0; |
903 | | |
904 | 58.2k | if(u1_buf_mode == 1) |
905 | 21.8k | { |
906 | 21.8k | UWORD32 u4_mmco; |
907 | 21.8k | UWORD32 u4_diff_pic_num; |
908 | 21.8k | UWORD32 u4_lt_idx, u4_max_lt_idx_plus1; |
909 | | |
910 | 21.8k | u4_mmco = ih264d_uev(pu4_bitstrm_ofst, |
911 | 21.8k | pu4_bitstrm_buf); |
912 | 72.5k | while(u4_mmco != END_OF_MMCO) |
913 | 50.7k | { |
914 | 50.7k | if (j >= MAX_REF_BUFS) |
915 | 62 | { |
916 | | #ifdef __ANDROID__ |
917 | | ALOGE("b/25818142"); |
918 | | android_errorWriteLog(0x534e4554, "25818142"); |
919 | | #endif |
920 | 62 | ps_dpb_cmds->u1_num_of_commands = 0; |
921 | 62 | return -1; |
922 | 62 | } |
923 | 50.6k | ps_mmc_params = &ps_dpb_cmds->as_mmc_params[j]; |
924 | 50.6k | ps_mmc_params->u4_mmco = u4_mmco; |
925 | 50.6k | switch(u4_mmco) |
926 | 50.6k | { |
927 | 9.33k | case MARK_ST_PICNUM_AS_NONREF: |
928 | 9.33k | u4_diff_pic_num = ih264d_uev(pu4_bitstrm_ofst, |
929 | 9.33k | pu4_bitstrm_buf); |
930 | | //Get absDiffPicnumMinus1 |
931 | 9.33k | ps_mmc_params->u4_diff_pic_num = u4_diff_pic_num; |
932 | 9.33k | break; |
933 | | |
934 | 9.15k | case MARK_LT_INDEX_AS_NONREF: |
935 | 9.15k | u4_lt_idx = ih264d_uev(pu4_bitstrm_ofst, |
936 | 9.15k | pu4_bitstrm_buf); |
937 | 9.15k | ps_mmc_params->u4_lt_idx = u4_lt_idx; |
938 | 9.15k | break; |
939 | | |
940 | 5.15k | case MARK_ST_PICNUM_AS_LT_INDEX: |
941 | 5.15k | u4_diff_pic_num = ih264d_uev(pu4_bitstrm_ofst, |
942 | 5.15k | pu4_bitstrm_buf); |
943 | 5.15k | ps_mmc_params->u4_diff_pic_num = u4_diff_pic_num; |
944 | 5.15k | u4_lt_idx = ih264d_uev(pu4_bitstrm_ofst, |
945 | 5.15k | pu4_bitstrm_buf); |
946 | 5.15k | ps_mmc_params->u4_lt_idx = u4_lt_idx; |
947 | 5.15k | break; |
948 | | |
949 | 7.73k | case SET_MAX_LT_INDEX: |
950 | 7.73k | { |
951 | 7.73k | u4_max_lt_idx_plus1 = ih264d_uev(pu4_bitstrm_ofst, |
952 | 7.73k | pu4_bitstrm_buf); |
953 | 7.73k | if (u4_max_lt_idx_plus1 > ps_sps->u1_num_ref_frames) |
954 | 4 | { |
955 | | /* Invalid max LT ref index */ |
956 | 4 | return -1; |
957 | 4 | } |
958 | 7.73k | ps_mmc_params->u4_max_lt_idx_plus1 = u4_max_lt_idx_plus1; |
959 | 7.73k | break; |
960 | 7.73k | } |
961 | 5.03k | case RESET_REF_PICTURES: |
962 | 5.03k | { |
963 | 5.03k | ps_slice->u1_mmco_equalto5 = 1; |
964 | 5.03k | break; |
965 | 7.73k | } |
966 | | |
967 | 7.80k | case SET_LT_INDEX: |
968 | 7.80k | u4_lt_idx = ih264d_uev(pu4_bitstrm_ofst, |
969 | 7.80k | pu4_bitstrm_buf); |
970 | 7.80k | ps_mmc_params->u4_lt_idx = u4_lt_idx; |
971 | 7.80k | break; |
972 | | |
973 | 6.47k | default: |
974 | 6.47k | break; |
975 | 50.6k | } |
976 | 50.6k | u4_mmco = ih264d_uev(pu4_bitstrm_ofst, |
977 | 50.6k | pu4_bitstrm_buf); |
978 | | |
979 | 50.6k | j++; |
980 | 50.6k | } |
981 | 21.8k | ps_dpb_cmds->u1_num_of_commands = j; |
982 | 21.8k | } |
983 | 58.2k | } |
984 | 81.0k | ps_dpb_cmds->u1_dpb_commands_read = 1; |
985 | 81.0k | ps_dpb_cmds->u1_dpb_commands_read_slc = 1; |
986 | | |
987 | 81.0k | } |
988 | 0 | u4_bit_ofst = ps_dec->ps_bitstrm->u4_ofst - u4_bit_ofst; |
989 | 81.0k | return u4_bit_ofst; |
990 | 81.1k | } |
991 | | |
992 | | /*! |
993 | | ************************************************************************** |
994 | | * \if Function name : ih264d_do_mmco_buffer \endif |
995 | | * |
996 | | * \brief |
997 | | * Perform decoded picture buffer memory management control operations |
998 | | * |
999 | | * \return |
1000 | | * 0 - No error; -1 - Error |
1001 | | * |
1002 | | * \note |
1003 | | * Bitstream is also parsed here to get the MMCOs |
1004 | | * |
1005 | | ************************************************************************** |
1006 | | */ |
1007 | | WORD32 ih264d_do_mmco_buffer(dpb_commands_t *ps_dpb_cmds, |
1008 | | dpb_manager_t *ps_dpb_mgr, |
1009 | | UWORD8 u1_numRef_frames_for_seq, /*!< num_ref_frames from active SeqParSet*/ |
1010 | | UWORD32 u4_cur_pic_num, |
1011 | | UWORD32 u2_u4_max_pic_num_minus1, |
1012 | | UWORD8 u1_nal_unit_type, |
1013 | | struct pic_buffer_t *ps_pic_buf, |
1014 | | UWORD8 u1_buf_id, |
1015 | | UWORD8 u1_fld_pic_flag, |
1016 | | UWORD8 u1_curr_pic_in_err) |
1017 | 1.46k | { |
1018 | 1.46k | WORD32 i; |
1019 | 1.46k | UWORD8 u1_buf_mode, u1_marked_lt; |
1020 | 1.46k | struct dpb_info_t *ps_next_dpb; |
1021 | 1.46k | UWORD8 u1_num_gaps; |
1022 | 1.46k | UWORD8 u1_del_node = 1; |
1023 | 1.46k | UWORD8 u1_insert_st_pic = 1; |
1024 | 1.46k | WORD32 ret; |
1025 | 1.46k | UNUSED(u1_nal_unit_type); |
1026 | 1.46k | UNUSED(u2_u4_max_pic_num_minus1); |
1027 | 1.46k | u1_buf_mode = ps_dpb_cmds->u1_buf_mode; //0 - sliding window; 1 - Adaptive |
1028 | 1.46k | u1_marked_lt = 0; |
1029 | 1.46k | u1_num_gaps = ps_dpb_mgr->u1_num_gaps; |
1030 | | |
1031 | 1.46k | if(!u1_buf_mode) |
1032 | 908 | { |
1033 | | //Sliding window - implements 8.2.5.3 |
1034 | 908 | if((ps_dpb_mgr->u1_num_st_ref_bufs |
1035 | 908 | + ps_dpb_mgr->u1_num_lt_ref_bufs + u1_num_gaps) |
1036 | 908 | == u1_numRef_frames_for_seq) |
1037 | 517 | { |
1038 | 517 | UWORD8 u1_new_node_flag = 1; |
1039 | 517 | if((0 == ps_dpb_mgr->u1_num_st_ref_bufs) && (0 == u1_num_gaps)) |
1040 | 45 | { |
1041 | 45 | UWORD32 i4_error_code; |
1042 | 45 | i4_error_code = ERROR_DBP_MANAGER_T; |
1043 | 45 | return i4_error_code; |
1044 | 45 | } |
1045 | | |
1046 | | // Chase the links to reach the last but one picNum, if available |
1047 | 472 | ps_next_dpb = ps_dpb_mgr->ps_dpb_st_head; |
1048 | | |
1049 | 472 | if(ps_dpb_mgr->u1_num_st_ref_bufs > 1) |
1050 | 25 | { |
1051 | 25 | if(ps_next_dpb->i4_frame_num == (WORD32)u4_cur_pic_num) |
1052 | 15 | { |
1053 | | /* Incase of filed pictures top_field has been allocated */ |
1054 | | /* picture buffer and complementary bottom field pair comes */ |
1055 | | /* then the sliding window mechanism should not allocate a */ |
1056 | | /* new node */ |
1057 | 15 | u1_new_node_flag = 0; |
1058 | 15 | } |
1059 | | |
1060 | 90 | for(i = 1; i < (ps_dpb_mgr->u1_num_st_ref_bufs - 1); i++) |
1061 | 65 | { |
1062 | 65 | if(ps_next_dpb == NULL) |
1063 | 0 | { |
1064 | 0 | UWORD32 i4_error_code; |
1065 | 0 | i4_error_code = ERROR_DBP_MANAGER_T; |
1066 | 0 | return i4_error_code; |
1067 | 0 | } |
1068 | 65 | if(ps_next_dpb->i4_frame_num == (WORD32)u4_cur_pic_num) |
1069 | 34 | { |
1070 | | /* Incase of field pictures top_field has been allocated */ |
1071 | | /* picture buffer and complementary bottom field pair comes */ |
1072 | | /* then the sliding window mechanism should not allocate a */ |
1073 | | /* new node */ |
1074 | 34 | u1_new_node_flag = 0; |
1075 | 34 | } |
1076 | 65 | ps_next_dpb = ps_next_dpb->ps_prev_short; |
1077 | 65 | } |
1078 | | |
1079 | 25 | if(ps_next_dpb->ps_prev_short->ps_prev_short != NULL) |
1080 | 0 | { |
1081 | 0 | UWORD32 i4_error_code; |
1082 | 0 | i4_error_code = ERROR_DBP_MANAGER_T; |
1083 | 0 | return i4_error_code; |
1084 | 0 | } |
1085 | | |
1086 | 25 | if(u1_new_node_flag) |
1087 | 8 | { |
1088 | 8 | if(u1_num_gaps) |
1089 | 0 | { |
1090 | 0 | ret = ih264d_delete_gap_frm_sliding(ps_dpb_mgr, |
1091 | 0 | ps_next_dpb->ps_prev_short->i4_frame_num, |
1092 | 0 | &u1_del_node); |
1093 | 0 | if(ret != OK) |
1094 | 0 | return ret; |
1095 | 0 | } |
1096 | | |
1097 | 8 | if(u1_del_node) |
1098 | 8 | { |
1099 | 8 | ps_dpb_mgr->u1_num_st_ref_bufs--; |
1100 | 8 | ps_next_dpb->ps_prev_short->u1_used_as_ref = |
1101 | 8 | UNUSED_FOR_REF; |
1102 | 8 | ps_next_dpb->ps_prev_short->s_top_field.u1_reference_info = |
1103 | 8 | UNUSED_FOR_REF; |
1104 | 8 | ps_next_dpb->ps_prev_short->s_bot_field.u1_reference_info = |
1105 | 8 | UNUSED_FOR_REF; |
1106 | 8 | ih264d_free_ref_pic_mv_bufs(ps_dpb_mgr->pv_codec_handle, |
1107 | 8 | ps_next_dpb->ps_prev_short->u1_buf_id); |
1108 | 8 | ps_next_dpb->ps_prev_short->ps_pic_buf = NULL; |
1109 | 8 | ps_next_dpb->ps_prev_short = NULL; |
1110 | 8 | } |
1111 | 8 | } |
1112 | 25 | } |
1113 | 447 | else |
1114 | 447 | { |
1115 | 447 | if(ps_dpb_mgr->u1_num_st_ref_bufs) |
1116 | 396 | { |
1117 | 396 | ret = ih264d_delete_gap_frm_sliding(ps_dpb_mgr, |
1118 | 396 | ps_next_dpb->i4_frame_num, |
1119 | 396 | &u1_del_node); |
1120 | 396 | if(ret != OK) |
1121 | 0 | return ret; |
1122 | 396 | if((ps_next_dpb->i4_frame_num != (WORD32)u4_cur_pic_num) |
1123 | 26 | && u1_del_node) |
1124 | 26 | { |
1125 | 26 | ps_dpb_mgr->u1_num_st_ref_bufs--; |
1126 | 26 | ps_next_dpb->u1_used_as_ref = FALSE; |
1127 | 26 | ps_next_dpb->s_top_field.u1_reference_info = |
1128 | 26 | UNUSED_FOR_REF; |
1129 | 26 | ps_next_dpb->s_bot_field.u1_reference_info = |
1130 | 26 | UNUSED_FOR_REF; |
1131 | 26 | ih264d_free_ref_pic_mv_bufs(ps_dpb_mgr->pv_codec_handle, |
1132 | 26 | ps_next_dpb->u1_buf_id); |
1133 | 26 | ps_next_dpb->ps_pic_buf = NULL; |
1134 | 26 | ps_next_dpb->ps_prev_short = NULL; |
1135 | 26 | ps_dpb_mgr->ps_dpb_st_head = NULL; |
1136 | 26 | ps_next_dpb = NULL; |
1137 | 26 | } |
1138 | 370 | else if(ps_next_dpb->i4_frame_num == (WORD32)u4_cur_pic_num) |
1139 | 370 | { |
1140 | 370 | if(u1_curr_pic_in_err) |
1141 | 0 | { |
1142 | 0 | u1_insert_st_pic = 0; |
1143 | 0 | } |
1144 | 370 | else if(ps_dpb_mgr->u1_num_st_ref_bufs > 0) |
1145 | 370 | { |
1146 | 370 | ps_dpb_mgr->u1_num_st_ref_bufs--; |
1147 | 370 | ps_next_dpb->u1_used_as_ref = FALSE; |
1148 | 370 | ps_next_dpb->s_top_field.u1_reference_info = |
1149 | 370 | UNUSED_FOR_REF; |
1150 | 370 | ps_next_dpb->s_bot_field.u1_reference_info = |
1151 | 370 | UNUSED_FOR_REF; |
1152 | 370 | ih264d_free_ref_pic_mv_bufs(ps_dpb_mgr->pv_codec_handle, |
1153 | 370 | ps_next_dpb->u1_buf_id); |
1154 | 370 | ps_next_dpb->ps_pic_buf = NULL; |
1155 | 370 | ps_next_dpb = NULL; |
1156 | 370 | } |
1157 | 370 | } |
1158 | 396 | } |
1159 | 51 | else |
1160 | 51 | { |
1161 | 51 | ret = ih264d_delete_gap_frm_sliding(ps_dpb_mgr, |
1162 | 51 | INVALID_FRAME_NUM, |
1163 | 51 | &u1_del_node); |
1164 | 51 | if(ret != OK) |
1165 | 0 | return ret; |
1166 | 51 | if(u1_del_node) |
1167 | 3 | { |
1168 | 3 | UWORD32 i4_error_code; |
1169 | 3 | i4_error_code = ERROR_DBP_MANAGER_T; |
1170 | 3 | return i4_error_code; |
1171 | 3 | } |
1172 | 51 | } |
1173 | 447 | } |
1174 | 472 | } |
1175 | 908 | } |
1176 | 561 | else |
1177 | 561 | { |
1178 | | //Adaptive memory control - implements 8.2.5.4 |
1179 | 561 | UWORD32 u4_mmco; |
1180 | 561 | UWORD32 u4_diff_pic_num; |
1181 | 561 | WORD32 i4_pic_num; |
1182 | 561 | UWORD32 u4_lt_idx; |
1183 | 561 | WORD32 j; |
1184 | 561 | struct MMCParams *ps_mmc_params; |
1185 | | |
1186 | 2.70k | for(j = 0; j < ps_dpb_cmds->u1_num_of_commands; j++) |
1187 | 2.32k | { |
1188 | 2.32k | ps_mmc_params = &ps_dpb_cmds->as_mmc_params[j]; |
1189 | 2.32k | u4_mmco = ps_mmc_params->u4_mmco; //Get MMCO |
1190 | | |
1191 | 2.32k | switch(u4_mmco) |
1192 | 2.32k | { |
1193 | 380 | case MARK_ST_PICNUM_AS_NONREF: |
1194 | 380 | { |
1195 | | |
1196 | 380 | { |
1197 | 380 | UWORD32 i4_cur_pic_num = u4_cur_pic_num; |
1198 | 380 | WORD64 i8_pic_num; |
1199 | 380 | u4_diff_pic_num = ps_mmc_params->u4_diff_pic_num; //Get absDiffPicnumMinus1 |
1200 | 380 | if(u1_fld_pic_flag) |
1201 | 343 | i4_cur_pic_num = i4_cur_pic_num * 2 + 1; |
1202 | 380 | i8_pic_num = ((WORD64)i4_cur_pic_num - ((WORD64)u4_diff_pic_num + 1)); |
1203 | 380 | if(IS_OUT_OF_RANGE_S32(i8_pic_num)) |
1204 | 1 | { |
1205 | 1 | return ERROR_DBP_MANAGER_T; |
1206 | 1 | } |
1207 | 379 | i4_pic_num = i8_pic_num; |
1208 | 379 | } |
1209 | | |
1210 | 379 | if(ps_dpb_mgr->u1_num_st_ref_bufs > 0) |
1211 | 322 | { |
1212 | 322 | ret = ih264d_delete_st_node_or_make_lt(ps_dpb_mgr, |
1213 | 322 | i4_pic_num, |
1214 | 322 | MAX_REF_BUFS + 1, |
1215 | 322 | u1_fld_pic_flag); |
1216 | 322 | if(ret != OK) |
1217 | 159 | return ret; |
1218 | 322 | } |
1219 | 57 | else |
1220 | 57 | { |
1221 | 57 | UWORD8 u1_dummy; |
1222 | 57 | ret = ih264d_delete_gap_frm_mmco(ps_dpb_mgr, i4_pic_num, &u1_dummy); |
1223 | 57 | if(ret != OK) |
1224 | 2 | return ret; |
1225 | 57 | } |
1226 | 218 | break; |
1227 | 379 | } |
1228 | 276 | case MARK_LT_INDEX_AS_NONREF: |
1229 | 276 | { |
1230 | 276 | WORD32 i4_status; |
1231 | 276 | u4_lt_idx = ps_mmc_params->u4_lt_idx; //Get long term index |
1232 | 276 | ret = ih264d_delete_lt_node(ps_dpb_mgr, |
1233 | 276 | u4_lt_idx, |
1234 | 276 | u1_fld_pic_flag, |
1235 | 276 | 0, &i4_status); |
1236 | 276 | if(ret != OK) |
1237 | 0 | return ret; |
1238 | 276 | if(i4_status) |
1239 | 0 | { |
1240 | 0 | UWORD32 i4_error_code; |
1241 | 0 | i4_error_code = ERROR_DBP_MANAGER_T; |
1242 | 0 | return i4_error_code; |
1243 | 0 | } |
1244 | 276 | break; |
1245 | 276 | } |
1246 | | |
1247 | 276 | case MARK_ST_PICNUM_AS_LT_INDEX: |
1248 | 132 | { |
1249 | 132 | { |
1250 | 132 | UWORD32 i4_cur_pic_num = u4_cur_pic_num; |
1251 | 132 | WORD64 i8_pic_num; |
1252 | 132 | u4_diff_pic_num = ps_mmc_params->u4_diff_pic_num; //Get absDiffPicnumMinus1 |
1253 | 132 | if(u1_fld_pic_flag) |
1254 | 130 | i4_cur_pic_num = i4_cur_pic_num * 2 + 1; |
1255 | | |
1256 | 132 | i8_pic_num = (WORD64)i4_cur_pic_num - ((WORD64)u4_diff_pic_num + 1); |
1257 | 132 | if(IS_OUT_OF_RANGE_S32(i8_pic_num)) |
1258 | 0 | { |
1259 | 0 | return ERROR_DBP_MANAGER_T; |
1260 | 0 | } |
1261 | 132 | i4_pic_num = i8_pic_num; |
1262 | 132 | } |
1263 | | |
1264 | 0 | u4_lt_idx = ps_mmc_params->u4_lt_idx; //Get long term index |
1265 | | |
1266 | 132 | if((ps_dpb_mgr->u1_max_lt_frame_idx == NO_LONG_TERM_INDICIES) || |
1267 | 132 | (u4_lt_idx > ps_dpb_mgr->u1_max_lt_frame_idx)) |
1268 | 5 | { |
1269 | 5 | return ERROR_DBP_MANAGER_T; |
1270 | 5 | } |
1271 | | |
1272 | 127 | if(ps_dpb_mgr->u1_num_st_ref_bufs > 0) |
1273 | 0 | { |
1274 | 0 | ret = ih264d_delete_st_node_or_make_lt(ps_dpb_mgr, |
1275 | 0 | i4_pic_num, u4_lt_idx, |
1276 | 0 | u1_fld_pic_flag); |
1277 | 0 | if(ret != OK) |
1278 | 0 | return ret; |
1279 | 0 | } |
1280 | 127 | break; |
1281 | 127 | } |
1282 | 255 | case SET_MAX_LT_INDEX: |
1283 | 255 | { |
1284 | 255 | UWORD8 uc_numLT = ps_dpb_mgr->u1_num_lt_ref_bufs; |
1285 | 255 | u4_lt_idx = ps_mmc_params->u4_max_lt_idx_plus1; //Get Max_long_term_index_plus1 |
1286 | 255 | if(u4_lt_idx <= ps_dpb_mgr->u1_max_lt_frame_idx |
1287 | 47 | && uc_numLT > 0) |
1288 | 23 | { |
1289 | 23 | struct dpb_info_t *ps_nxtDPB; |
1290 | | //Set all LT buffers with index >= u4_lt_idx to nonreference |
1291 | 23 | ps_nxtDPB = ps_dpb_mgr->ps_dpb_ht_head; |
1292 | 23 | ps_next_dpb = ps_nxtDPB->ps_prev_long; |
1293 | 23 | if(ps_nxtDPB->u1_lt_idx >= u4_lt_idx) |
1294 | 0 | { |
1295 | 0 | i = 0; |
1296 | 0 | ps_dpb_mgr->ps_dpb_ht_head = NULL; |
1297 | 0 | } |
1298 | 23 | else |
1299 | 23 | { |
1300 | 23 | for(i = 1; i < uc_numLT; i++) |
1301 | 23 | { |
1302 | 23 | if(ps_next_dpb->u1_lt_idx >= u4_lt_idx) |
1303 | 23 | break; |
1304 | 0 | ps_nxtDPB = ps_next_dpb; |
1305 | 0 | ps_next_dpb = ps_next_dpb->ps_prev_long; |
1306 | 0 | } |
1307 | 23 | ps_nxtDPB->ps_prev_long = NULL; //Terminate the link of the closest LTIndex that is <=Max |
1308 | 23 | } |
1309 | 23 | ps_dpb_mgr->u1_num_lt_ref_bufs = i; |
1310 | 23 | if(i == 0) |
1311 | 0 | ps_next_dpb = ps_nxtDPB; |
1312 | | |
1313 | 46 | for(; i < uc_numLT; i++) |
1314 | 23 | { |
1315 | 23 | ps_nxtDPB = ps_next_dpb; |
1316 | 23 | ps_nxtDPB->u1_lt_idx = MAX_REF_BUFS + 1; |
1317 | 23 | ps_nxtDPB->u1_used_as_ref = UNUSED_FOR_REF; |
1318 | 23 | ps_nxtDPB->s_top_field.u1_reference_info = |
1319 | 23 | UNUSED_FOR_REF; |
1320 | 23 | ps_nxtDPB->s_bot_field.u1_reference_info = |
1321 | 23 | UNUSED_FOR_REF; |
1322 | | |
1323 | 23 | ps_nxtDPB->ps_pic_buf = NULL; |
1324 | | //Release buffer |
1325 | 23 | ih264d_free_ref_pic_mv_bufs(ps_dpb_mgr->pv_codec_handle, |
1326 | 23 | ps_nxtDPB->u1_buf_id); |
1327 | 23 | ps_next_dpb = ps_nxtDPB->ps_prev_long; |
1328 | 23 | ps_nxtDPB->ps_prev_long = NULL; |
1329 | 23 | } |
1330 | 23 | } |
1331 | 255 | if(u4_lt_idx == 0) |
1332 | 5 | { |
1333 | 5 | ps_dpb_mgr->u1_max_lt_frame_idx = NO_LONG_TERM_INDICIES; |
1334 | 5 | } |
1335 | 250 | else |
1336 | 250 | { |
1337 | 250 | ps_dpb_mgr->u1_max_lt_frame_idx = u4_lt_idx - 1; |
1338 | 250 | } |
1339 | | |
1340 | 255 | break; |
1341 | 127 | } |
1342 | 297 | case SET_LT_INDEX: |
1343 | 297 | { |
1344 | 297 | u4_lt_idx = ps_mmc_params->u4_lt_idx; //Get long term index |
1345 | 297 | if((ps_dpb_mgr->u1_max_lt_frame_idx == NO_LONG_TERM_INDICIES) || |
1346 | 293 | (u4_lt_idx > ps_dpb_mgr->u1_max_lt_frame_idx)) |
1347 | 4 | { |
1348 | 4 | return ERROR_DBP_MANAGER_T; |
1349 | 4 | } |
1350 | 293 | ret = ih264d_insert_st_node(ps_dpb_mgr, ps_pic_buf, u1_buf_id, |
1351 | 293 | u4_cur_pic_num); |
1352 | 293 | if(ret != OK) |
1353 | 0 | return ret; |
1354 | | |
1355 | 293 | if(ps_dpb_mgr->u1_num_st_ref_bufs > 0) |
1356 | | |
1357 | 293 | { |
1358 | 293 | ret = ih264d_delete_st_node_or_make_lt(ps_dpb_mgr, |
1359 | 293 | u4_cur_pic_num, |
1360 | 293 | u4_lt_idx, |
1361 | 293 | u1_fld_pic_flag); |
1362 | 293 | if(ret != OK) |
1363 | 12 | return ret; |
1364 | 293 | } |
1365 | 0 | else |
1366 | 0 | { |
1367 | 0 | return ERROR_DBP_MANAGER_T; |
1368 | 0 | } |
1369 | | |
1370 | 281 | u1_marked_lt = 1; |
1371 | 281 | break; |
1372 | 293 | } |
1373 | | |
1374 | 982 | default: |
1375 | 982 | break; |
1376 | 2.32k | } |
1377 | 2.13k | if(u4_mmco == RESET_REF_PICTURES || u4_mmco == RESET_ALL_PICTURES) |
1378 | 415 | { |
1379 | 415 | ih264d_reset_ref_bufs(ps_dpb_mgr); |
1380 | 415 | u4_cur_pic_num = 0; |
1381 | 415 | } |
1382 | 2.13k | } |
1383 | 561 | } |
1384 | 1.23k | if(!u1_marked_lt && u1_insert_st_pic) |
1385 | 1.09k | { |
1386 | 1.09k | ret = ih264d_insert_st_node(ps_dpb_mgr, ps_pic_buf, u1_buf_id, |
1387 | 1.09k | u4_cur_pic_num); |
1388 | 1.09k | if(ret != OK) |
1389 | 41 | return ret; |
1390 | 1.09k | } |
1391 | 1.19k | return OK; |
1392 | 1.23k | } |
1393 | | |
1394 | | /*****************************************************************************/ |
1395 | | /* */ |
1396 | | /* Function Name : ih264d_release_pics_in_dpb */ |
1397 | | /* */ |
1398 | | /* Description : This function deletes all pictures from DPB */ |
1399 | | /* */ |
1400 | | /* Inputs : h_pic_buf_api: pointer to picture buffer API */ |
1401 | | /* u1_disp_bufs: number pictures ready for display */ |
1402 | | /* */ |
1403 | | /* Globals : None */ |
1404 | | /* Outputs : None */ |
1405 | | /* Returns : None */ |
1406 | | /* */ |
1407 | | /* Issues : None */ |
1408 | | /* */ |
1409 | | /* Revision History: */ |
1410 | | /* */ |
1411 | | /* DD MM YYYY Author(s) Changes (Describe the changes made) */ |
1412 | | /* 22 06 2005 NS Draft */ |
1413 | | /* */ |
1414 | | /*****************************************************************************/ |
1415 | | void ih264d_release_pics_in_dpb(void *pv_dec, |
1416 | | UWORD8 u1_disp_bufs) |
1417 | 0 | { |
1418 | 0 | WORD8 i; |
1419 | 0 | dec_struct_t *ps_dec = (dec_struct_t *)pv_dec; |
1420 | |
|
1421 | 0 | for(i = 0; i < u1_disp_bufs; i++) |
1422 | 0 | { |
1423 | 0 | ih264_buf_mgr_release((buf_mgr_t *)ps_dec->pv_pic_buf_mgr, |
1424 | 0 | i, |
1425 | 0 | BUF_MGR_REF); |
1426 | 0 | ih264_buf_mgr_release((buf_mgr_t *)ps_dec->pv_mv_buf_mgr, |
1427 | 0 | ps_dec->as_buf_id_info_map[i].mv_buf_id, |
1428 | 0 | BUF_MGR_REF); |
1429 | 0 | } |
1430 | 0 | } |
1431 | | |
1432 | | /*****************************************************************************/ |
1433 | | /* */ |
1434 | | /* Function Name : ih264d_delete_gap_frm_sliding */ |
1435 | | /* */ |
1436 | | /* Description : This function deletes a picture from the list of gaps, */ |
1437 | | /* if the frame number of gap frame is lesser than the one */ |
1438 | | /* to be deleted by sliding window */ |
1439 | | /* Inputs : ps_dpb_mgr: pointer to dpb manager */ |
1440 | | /* i4_frame_num: frame number of picture that's going to */ |
1441 | | /* be deleted by sliding window */ |
1442 | | /* pu1_del_node: holds 0 if a gap is deleted else 1 */ |
1443 | | /* Globals : None */ |
1444 | | /* Processing : Function searches for frame number lesser than */ |
1445 | | /* i4_frame_num in the gaps list */ |
1446 | | /* Outputs : None */ |
1447 | | /* Returns : None */ |
1448 | | /* */ |
1449 | | /* Issues : None */ |
1450 | | /* */ |
1451 | | /* Revision History: */ |
1452 | | /* */ |
1453 | | /* DD MM YYYY Author(s) Changes (Describe the changes made) */ |
1454 | | /* 22 06 2005 NS Draft */ |
1455 | | /* */ |
1456 | | /*****************************************************************************/ |
1457 | | WORD32 ih264d_delete_gap_frm_sliding(dpb_manager_t *ps_dpb_mgr, |
1458 | | WORD32 i4_frame_num, |
1459 | | UWORD8 *pu1_del_node) |
1460 | 4.46M | { |
1461 | 4.46M | WORD8 i1_gap_idx, i, j, j_min; |
1462 | 4.46M | WORD32 *pi4_gaps_start_frm_num, *pi4_gaps_end_frm_num, i4_gap_frame_num; |
1463 | 4.46M | WORD32 i4_start_frm_num, i4_end_frm_num; |
1464 | 4.46M | WORD32 i4_max_frm_num; |
1465 | 4.46M | WORD32 i4_frm_num, i4_gap_frm_num_min; |
1466 | | |
1467 | | /* find the least frame num from gaps and current DPB node */ |
1468 | | /* Delete the least one */ |
1469 | 4.46M | *pu1_del_node = 1; |
1470 | 4.46M | if(0 == ps_dpb_mgr->u1_num_gaps) |
1471 | 354 | return OK; |
1472 | 4.46M | pi4_gaps_start_frm_num = ps_dpb_mgr->ai4_gaps_start_frm_num; |
1473 | 4.46M | pi4_gaps_end_frm_num = ps_dpb_mgr->ai4_gaps_end_frm_num; |
1474 | 4.46M | i4_gap_frame_num = INVALID_FRAME_NUM; |
1475 | 4.46M | i4_max_frm_num = ps_dpb_mgr->i4_max_frm_num; |
1476 | | |
1477 | 4.46M | i1_gap_idx = -1; |
1478 | 4.46M | if(INVALID_FRAME_NUM != i4_frame_num) |
1479 | 1.72k | { |
1480 | 1.72k | i4_gap_frame_num = i4_frame_num; |
1481 | 29.2k | for(i = 0; i < MAX_FRAMES; i++) |
1482 | 27.5k | { |
1483 | 27.5k | i4_start_frm_num = pi4_gaps_start_frm_num[i]; |
1484 | 27.5k | if(INVALID_FRAME_NUM != i4_start_frm_num) |
1485 | 3.52k | { |
1486 | 3.52k | i4_end_frm_num = pi4_gaps_end_frm_num[i]; |
1487 | 3.52k | if(i4_end_frm_num < i4_max_frm_num) |
1488 | 3.52k | { |
1489 | 3.52k | if(i4_start_frm_num <= i4_gap_frame_num) |
1490 | 3.20k | { |
1491 | 3.20k | i4_gap_frame_num = i4_start_frm_num; |
1492 | 3.20k | i1_gap_idx = i; |
1493 | 3.20k | } |
1494 | 3.52k | } |
1495 | 0 | else |
1496 | 0 | { |
1497 | 0 | if(((i4_start_frm_num <= i4_gap_frame_num) |
1498 | 0 | && (i4_gap_frame_num <= i4_max_frm_num)) |
1499 | 0 | || ((i4_start_frm_num >= i4_gap_frame_num) |
1500 | 0 | && ((i4_gap_frame_num |
1501 | 0 | + i4_max_frm_num) |
1502 | 0 | >= i4_end_frm_num))) |
1503 | 0 | { |
1504 | 0 | i4_gap_frame_num = i4_start_frm_num; |
1505 | 0 | i1_gap_idx = i; |
1506 | 0 | } |
1507 | 0 | } |
1508 | 3.52k | } |
1509 | 27.5k | } |
1510 | 1.72k | } |
1511 | 4.46M | else |
1512 | 4.46M | { |
1513 | | /* no valid short term buffers, delete one gap from the least start */ |
1514 | | /* of gap sequence */ |
1515 | 4.46M | i4_gap_frame_num = pi4_gaps_start_frm_num[0]; |
1516 | 4.46M | i1_gap_idx = 0; |
1517 | 71.4M | for(i = 1; i < MAX_FRAMES; i++) |
1518 | 66.9M | { |
1519 | 66.9M | if(INVALID_FRAME_NUM != pi4_gaps_start_frm_num[i]) |
1520 | 2.23M | { |
1521 | 2.23M | if(pi4_gaps_start_frm_num[i] < i4_gap_frame_num) |
1522 | 2.22M | { |
1523 | 2.22M | i4_gap_frame_num = pi4_gaps_start_frm_num[i]; |
1524 | 2.22M | i1_gap_idx = i; |
1525 | 2.22M | } |
1526 | 2.23M | } |
1527 | 66.9M | } |
1528 | 4.46M | if(INVALID_FRAME_NUM == i4_gap_frame_num) |
1529 | 31 | { |
1530 | 31 | UWORD32 i4_error_code; |
1531 | 31 | i4_error_code = ERROR_DBP_MANAGER_T; |
1532 | 31 | return i4_error_code; |
1533 | 31 | } |
1534 | 4.46M | } |
1535 | | |
1536 | 4.46M | if(-1 != i1_gap_idx) |
1537 | 4.46M | { |
1538 | | /* find least frame_num in the poc_map, which is in this range */ |
1539 | 4.46M | i4_start_frm_num = pi4_gaps_start_frm_num[i1_gap_idx]; |
1540 | 4.46M | if(i4_start_frm_num < 0) |
1541 | 1.05k | i4_start_frm_num += i4_max_frm_num; |
1542 | 4.46M | i4_end_frm_num = pi4_gaps_end_frm_num[i1_gap_idx]; |
1543 | 4.46M | if(i4_end_frm_num < 0) |
1544 | 4.43M | i4_end_frm_num += i4_max_frm_num; |
1545 | | |
1546 | 4.46M | i4_gap_frm_num_min = 0xfffffff; |
1547 | 4.46M | j_min = MAX_FRAMES; |
1548 | 75.9M | for(j = 0; j < MAX_FRAMES; j++) |
1549 | 71.4M | { |
1550 | 71.4M | i4_frm_num = ps_dpb_mgr->ai4_poc_buf_id_map[j][2]; |
1551 | 71.4M | if((i4_start_frm_num <= i4_frm_num) |
1552 | 66.9M | && (i4_end_frm_num >= i4_frm_num)) |
1553 | 66.7M | { |
1554 | 66.7M | if(i4_frm_num < i4_gap_frm_num_min) |
1555 | 5.57M | { |
1556 | 5.57M | j_min = j; |
1557 | 5.57M | i4_gap_frm_num_min = i4_frm_num; |
1558 | 5.57M | } |
1559 | 66.7M | } |
1560 | 71.4M | } |
1561 | | |
1562 | 4.46M | if(j_min != MAX_FRAMES) |
1563 | 4.46M | { |
1564 | | |
1565 | 4.46M | ps_dpb_mgr->ai4_poc_buf_id_map[j_min][0] = -1; |
1566 | 4.46M | ps_dpb_mgr->ai4_poc_buf_id_map[j_min][1] = 0x7fffffff; |
1567 | 4.46M | ps_dpb_mgr->ai4_poc_buf_id_map[j_min][2] = GAP_FRAME_NUM; |
1568 | 4.46M | ps_dpb_mgr->i1_gaps_deleted++; |
1569 | | |
1570 | 4.46M | ps_dpb_mgr->ai1_gaps_per_seq[i1_gap_idx]--; |
1571 | 4.46M | ps_dpb_mgr->u1_num_gaps--; |
1572 | 4.46M | *pu1_del_node = 0; |
1573 | 4.46M | if(0 == ps_dpb_mgr->ai1_gaps_per_seq[i1_gap_idx]) |
1574 | 296 | { |
1575 | 296 | ps_dpb_mgr->ai4_gaps_start_frm_num[i1_gap_idx] = |
1576 | 296 | INVALID_FRAME_NUM; |
1577 | 296 | ps_dpb_mgr->ai4_gaps_end_frm_num[i1_gap_idx] = 0; |
1578 | 296 | } |
1579 | 4.46M | } |
1580 | 4.46M | } |
1581 | | |
1582 | 4.46M | return OK; |
1583 | 4.46M | } |
1584 | | |
1585 | | /*****************************************************************************/ |
1586 | | /* */ |
1587 | | /* Function Name : ih264d_delete_gap_frm_mmco */ |
1588 | | /* */ |
1589 | | /* Description : This function deletes a picture from the list of gaps, */ |
1590 | | /* if the frame number (specified by mmco commands) to be */ |
1591 | | /* deleted is in the range by gap sequence. */ |
1592 | | /* */ |
1593 | | /* Inputs : ps_dpb_mgr: pointer to dpb manager */ |
1594 | | /* i4_frame_num: frame number of picture that's going to */ |
1595 | | /* be deleted by mmco */ |
1596 | | /* pu1_del_node: holds 0 if a gap is deleted else 1 */ |
1597 | | /* Globals : None */ |
1598 | | /* Processing : Function searches for frame number lesser in the range */ |
1599 | | /* specified by gap sequence */ |
1600 | | /* Outputs : None */ |
1601 | | /* Returns : None */ |
1602 | | /* */ |
1603 | | /* Issues : None */ |
1604 | | /* */ |
1605 | | /* Revision History: */ |
1606 | | /* */ |
1607 | | /* DD MM YYYY Author(s) Changes (Describe the changes made) */ |
1608 | | /* 22 06 2005 NS Draft */ |
1609 | | /* */ |
1610 | | /*****************************************************************************/ |
1611 | | WORD32 ih264d_delete_gap_frm_mmco(dpb_manager_t *ps_dpb_mgr, |
1612 | | WORD32 i4_frame_num, |
1613 | | UWORD8 *pu1_del_node) |
1614 | 320 | { |
1615 | 320 | WORD8 i, j; |
1616 | 320 | WORD32 *pi4_start, *pi4_end; |
1617 | 320 | WORD32 i4_start_frm_num, i4_end_frm_num, i4_max_frm_num; |
1618 | | |
1619 | | /* find the least frame num from gaps and current DPB node */ |
1620 | | /* Delete the gaps */ |
1621 | 320 | *pu1_del_node = 1; |
1622 | 320 | pi4_start = ps_dpb_mgr->ai4_gaps_start_frm_num; |
1623 | 320 | pi4_end = ps_dpb_mgr->ai4_gaps_end_frm_num; |
1624 | 320 | i4_max_frm_num = ps_dpb_mgr->i4_max_frm_num; |
1625 | | |
1626 | 320 | if(0 == ps_dpb_mgr->u1_num_gaps) |
1627 | 55 | return OK; |
1628 | | |
1629 | 265 | if(i4_frame_num < 0) |
1630 | 0 | i4_frame_num += i4_max_frm_num; |
1631 | 395 | for(i = 0; i < MAX_FRAMES; i++) |
1632 | 394 | { |
1633 | 394 | i4_start_frm_num = pi4_start[i]; |
1634 | 394 | if(i4_start_frm_num < 0) |
1635 | 1 | i4_start_frm_num += i4_max_frm_num; |
1636 | 394 | if(INVALID_FRAME_NUM != i4_start_frm_num) |
1637 | 385 | { |
1638 | 385 | i4_end_frm_num = pi4_end[i]; |
1639 | 385 | if(i4_end_frm_num < 0) |
1640 | 8 | i4_end_frm_num += i4_max_frm_num; |
1641 | | |
1642 | 385 | if((i4_frame_num >= i4_start_frm_num) |
1643 | 385 | && (i4_frame_num <= i4_end_frm_num)) |
1644 | 264 | { |
1645 | 264 | break; |
1646 | 264 | } |
1647 | 121 | else |
1648 | 121 | { |
1649 | 121 | if(((i4_frame_num + i4_max_frm_num) >= i4_start_frm_num) |
1650 | 121 | && ((i4_frame_num + i4_max_frm_num) |
1651 | 121 | <= i4_end_frm_num)) |
1652 | 0 | { |
1653 | 0 | UWORD32 i4_error_code; |
1654 | 0 | i4_error_code = ERROR_DBP_MANAGER_T; |
1655 | 0 | return i4_error_code; |
1656 | 0 | } |
1657 | 121 | } |
1658 | 385 | } |
1659 | 394 | } |
1660 | | |
1661 | | /* find frame_num index, in the poc_map which needs to be deleted */ |
1662 | 3.89k | for(j = 0; j < MAX_FRAMES; j++) |
1663 | 3.76k | { |
1664 | 3.76k | if(i4_frame_num == ps_dpb_mgr->ai4_poc_buf_id_map[j][2]) |
1665 | 136 | break; |
1666 | 3.76k | } |
1667 | | |
1668 | 265 | if(MAX_FRAMES != i) |
1669 | 264 | { |
1670 | 264 | if(j == MAX_FRAMES) |
1671 | 128 | { |
1672 | 128 | UWORD32 i4_error_code; |
1673 | 128 | i4_error_code = ERROR_DBP_MANAGER_T; |
1674 | 128 | return i4_error_code; |
1675 | 128 | } |
1676 | | |
1677 | 136 | ps_dpb_mgr->ai4_poc_buf_id_map[j][0] = -1; |
1678 | 136 | ps_dpb_mgr->ai4_poc_buf_id_map[j][1] = 0x7fffffff; |
1679 | 136 | ps_dpb_mgr->ai4_poc_buf_id_map[j][2] = GAP_FRAME_NUM; |
1680 | 136 | ps_dpb_mgr->i1_gaps_deleted++; |
1681 | | |
1682 | 136 | ps_dpb_mgr->ai1_gaps_per_seq[i]--; |
1683 | 136 | ps_dpb_mgr->u1_num_gaps--; |
1684 | 136 | *pu1_del_node = 0; |
1685 | 136 | if(0 == ps_dpb_mgr->ai1_gaps_per_seq[i]) |
1686 | 9 | { |
1687 | 9 | ps_dpb_mgr->ai4_gaps_start_frm_num[i] = INVALID_FRAME_NUM; |
1688 | 9 | ps_dpb_mgr->ai4_gaps_end_frm_num[i] = 0; |
1689 | 9 | } |
1690 | 136 | } |
1691 | 1 | else |
1692 | 1 | { |
1693 | 1 | UWORD32 i4_error_code; |
1694 | 1 | i4_error_code = ERROR_DBP_MANAGER_T; |
1695 | 1 | return i4_error_code; |
1696 | 1 | } |
1697 | | |
1698 | 136 | return OK; |
1699 | 265 | } |
1700 | | |
1701 | | /*! |
1702 | | ************************************************************************** |
1703 | | * \if Function name : ih264d_do_mmco_for_gaps \endif |
1704 | | * |
1705 | | * \brief |
1706 | | * Perform decoded picture buffer memory management control operations |
1707 | | * |
1708 | | * \return |
1709 | | * 0 - No error; -1 - Error |
1710 | | * |
1711 | | * \note |
1712 | | * Bitstream is also parsed here to get the MMCOs |
1713 | | * |
1714 | | ************************************************************************** |
1715 | | */ |
1716 | | WORD32 ih264d_do_mmco_for_gaps(dpb_manager_t *ps_dpb_mgr, |
1717 | | UWORD8 u1_num_ref_frames /*!< num_ref_frames from active SeqParSet*/ |
1718 | | ) |
1719 | 4.47M | { |
1720 | 4.47M | struct dpb_info_t *ps_next_dpb; |
1721 | 4.47M | UWORD8 u1_num_gaps; |
1722 | 4.47M | UWORD8 u1_st_ref_bufs, u1_lt_ref_bufs, u1_del_node; |
1723 | 4.47M | WORD8 i; |
1724 | 4.47M | WORD32 i4_frame_gaps = 1; |
1725 | 4.47M | WORD32 ret; |
1726 | | |
1727 | | //Sliding window - implements 8.2.5.3, flush out buffers |
1728 | 4.47M | u1_st_ref_bufs = ps_dpb_mgr->u1_num_st_ref_bufs; |
1729 | 4.47M | u1_lt_ref_bufs = ps_dpb_mgr->u1_num_lt_ref_bufs; |
1730 | | |
1731 | 8.94M | while(1) |
1732 | 8.94M | { |
1733 | 8.94M | u1_num_gaps = ps_dpb_mgr->u1_num_gaps; |
1734 | 8.94M | if((u1_st_ref_bufs + u1_lt_ref_bufs + u1_num_gaps + i4_frame_gaps) |
1735 | 8.94M | > u1_num_ref_frames) |
1736 | 4.46M | { |
1737 | 4.46M | if(0 == (u1_st_ref_bufs + u1_num_gaps)) |
1738 | 1.44k | { |
1739 | 1.44k | i4_frame_gaps = 0; |
1740 | 1.44k | ps_dpb_mgr->u1_num_gaps = (u1_num_ref_frames |
1741 | 1.44k | - u1_lt_ref_bufs); |
1742 | 1.44k | } |
1743 | 4.46M | else |
1744 | 4.46M | { |
1745 | 4.46M | u1_del_node = 1; |
1746 | 4.46M | ps_next_dpb = ps_dpb_mgr->ps_dpb_st_head; |
1747 | | |
1748 | 4.46M | if(u1_st_ref_bufs > 1) |
1749 | 176 | { |
1750 | 197 | for(i = 1; i < (u1_st_ref_bufs - 1); i++) |
1751 | 21 | { |
1752 | 21 | if(ps_next_dpb == NULL) |
1753 | 0 | { |
1754 | 0 | UWORD32 i4_error_code; |
1755 | 0 | i4_error_code = ERROR_DBP_MANAGER_T; |
1756 | 0 | return i4_error_code; |
1757 | 0 | } |
1758 | 21 | ps_next_dpb = ps_next_dpb->ps_prev_short; |
1759 | 21 | } |
1760 | | |
1761 | 176 | if(ps_next_dpb->ps_prev_short->ps_prev_short != NULL) |
1762 | 133 | { |
1763 | 133 | return ERROR_DBP_MANAGER_T; |
1764 | 133 | } |
1765 | | |
1766 | 43 | if(u1_num_gaps) |
1767 | 40 | { |
1768 | 40 | ret = ih264d_delete_gap_frm_sliding(ps_dpb_mgr, |
1769 | 40 | ps_next_dpb->ps_prev_short->i4_frame_num, |
1770 | 40 | &u1_del_node); |
1771 | 40 | if(ret != OK) |
1772 | 0 | return ret; |
1773 | 40 | } |
1774 | | |
1775 | 43 | if(u1_del_node) |
1776 | 17 | { |
1777 | 17 | u1_st_ref_bufs--; |
1778 | 17 | ps_next_dpb->ps_prev_short->u1_used_as_ref = |
1779 | 17 | UNUSED_FOR_REF; |
1780 | 17 | ps_next_dpb->ps_prev_short->s_top_field.u1_reference_info = |
1781 | 17 | UNUSED_FOR_REF; |
1782 | 17 | ps_next_dpb->ps_prev_short->s_bot_field.u1_reference_info = |
1783 | 17 | UNUSED_FOR_REF; |
1784 | 17 | ih264d_free_ref_pic_mv_bufs(ps_dpb_mgr->pv_codec_handle, |
1785 | 17 | ps_next_dpb->ps_prev_short->u1_buf_id); |
1786 | 17 | ps_next_dpb->ps_prev_short->ps_pic_buf = NULL; |
1787 | 17 | ps_next_dpb->ps_prev_short = NULL; |
1788 | 17 | } |
1789 | 43 | } |
1790 | 4.46M | else |
1791 | 4.46M | { |
1792 | 4.46M | if(u1_st_ref_bufs) |
1793 | 1.79k | { |
1794 | 1.79k | if(u1_num_gaps) |
1795 | 1.63k | { |
1796 | 1.63k | ret = ih264d_delete_gap_frm_sliding(ps_dpb_mgr, |
1797 | 1.63k | ps_next_dpb->i4_frame_num, |
1798 | 1.63k | &u1_del_node); |
1799 | 1.63k | if(ret != OK) |
1800 | 0 | return ret; |
1801 | 1.63k | } |
1802 | | |
1803 | 1.79k | if(u1_del_node) |
1804 | 201 | { |
1805 | 201 | u1_st_ref_bufs--; |
1806 | 201 | ps_next_dpb->u1_used_as_ref = FALSE; |
1807 | 201 | ps_next_dpb->s_top_field.u1_reference_info = |
1808 | 201 | UNUSED_FOR_REF; |
1809 | 201 | ps_next_dpb->s_bot_field.u1_reference_info = |
1810 | 201 | UNUSED_FOR_REF; |
1811 | 201 | ih264d_free_ref_pic_mv_bufs(ps_dpb_mgr->pv_codec_handle, |
1812 | 201 | ps_next_dpb->u1_buf_id); |
1813 | 201 | ps_next_dpb->ps_pic_buf = NULL; |
1814 | 201 | ps_next_dpb = NULL; |
1815 | 201 | ps_dpb_mgr->ps_dpb_st_head = NULL; |
1816 | 201 | ps_dpb_mgr->u1_num_st_ref_bufs = u1_st_ref_bufs; |
1817 | 201 | } |
1818 | 1.79k | } |
1819 | 4.46M | else |
1820 | 4.46M | { |
1821 | 4.46M | ret = ih264d_delete_gap_frm_sliding(ps_dpb_mgr, |
1822 | 4.46M | INVALID_FRAME_NUM, |
1823 | 4.46M | &u1_del_node); |
1824 | 4.46M | if(ret != OK) |
1825 | 31 | return ret; |
1826 | 4.46M | if(u1_del_node) |
1827 | 39 | { |
1828 | 39 | return ERROR_DBP_MANAGER_T; |
1829 | 39 | } |
1830 | 4.46M | } |
1831 | 4.46M | } |
1832 | 4.46M | } |
1833 | 4.46M | } |
1834 | 4.47M | else |
1835 | 4.47M | { |
1836 | 4.47M | ps_dpb_mgr->u1_num_gaps += i4_frame_gaps; |
1837 | 4.47M | break; |
1838 | 4.47M | } |
1839 | 8.94M | } |
1840 | | |
1841 | 4.47M | ps_dpb_mgr->u1_num_st_ref_bufs = u1_st_ref_bufs; |
1842 | | |
1843 | 4.47M | return OK; |
1844 | 4.47M | } |
1845 | | /****************************************************************************/ |
1846 | | /* */ |
1847 | | /* Function Name : ih264d_free_node_from_dpb */ |
1848 | | /* */ |
1849 | | /* Description : */ |
1850 | | /* */ |
1851 | | /* Inputs : */ |
1852 | | /* */ |
1853 | | /* Globals : */ |
1854 | | /* */ |
1855 | | /* Processing : */ |
1856 | | /* */ |
1857 | | /* Outputs : */ |
1858 | | /* */ |
1859 | | /* Returns : */ |
1860 | | /* */ |
1861 | | /* Known Issues : */ |
1862 | | /* */ |
1863 | | /* Revision History */ |
1864 | | /* */ |
1865 | | /* DD MM YY Author Changes */ |
1866 | | /* Sarat */ |
1867 | | /****************************************************************************/ |
1868 | | /**** Function Added for Error Resilience *****/ |
1869 | | WORD32 ih264d_free_node_from_dpb(dpb_manager_t *ps_dpb_mgr, |
1870 | | UWORD32 u4_cur_pic_num, |
1871 | | UWORD8 u1_numRef_frames_for_seq) |
1872 | 0 | { |
1873 | 0 | WORD32 i; |
1874 | 0 | UWORD8 u1_num_gaps = ps_dpb_mgr->u1_num_gaps; |
1875 | 0 | struct dpb_info_t *ps_next_dpb; |
1876 | 0 | UWORD8 u1_del_node = 1; |
1877 | 0 | WORD32 ret; |
1878 | | |
1879 | | //Sliding window - implements 8.2.5.3 |
1880 | 0 | if((ps_dpb_mgr->u1_num_st_ref_bufs + ps_dpb_mgr->u1_num_lt_ref_bufs |
1881 | 0 | + u1_num_gaps) == u1_numRef_frames_for_seq) |
1882 | 0 | { |
1883 | 0 | UWORD8 u1_new_node_flag = 1; |
1884 | 0 | if((0 == ps_dpb_mgr->u1_num_st_ref_bufs) && (0 == u1_num_gaps)) |
1885 | 0 | { |
1886 | 0 | return ERROR_DBP_MANAGER_T; |
1887 | 0 | } |
1888 | | |
1889 | | // Chase the links to reach the last but one picNum, if available |
1890 | 0 | ps_next_dpb = ps_dpb_mgr->ps_dpb_st_head; |
1891 | |
|
1892 | 0 | if(ps_dpb_mgr->u1_num_st_ref_bufs > 1) |
1893 | 0 | { |
1894 | 0 | if(ps_next_dpb->i4_frame_num == (WORD32)u4_cur_pic_num) |
1895 | 0 | { |
1896 | | /* Incase of filed pictures top_field has been allocated */ |
1897 | | /* picture buffer and complementary bottom field pair comes */ |
1898 | | /* then the sliding window mechanism should not allocate a */ |
1899 | | /* new node */ |
1900 | 0 | u1_new_node_flag = 0; |
1901 | 0 | } |
1902 | |
|
1903 | 0 | for(i = 1; i < (ps_dpb_mgr->u1_num_st_ref_bufs - 1); i++) |
1904 | 0 | { |
1905 | 0 | if(ps_next_dpb == NULL) |
1906 | 0 | return ERROR_DBP_MANAGER_T; |
1907 | | |
1908 | 0 | if(ps_next_dpb->i4_frame_num == (WORD32)u4_cur_pic_num) |
1909 | 0 | { |
1910 | | /* Incase of field pictures top_field has been allocated */ |
1911 | | /* picture buffer and complementary bottom field pair comes */ |
1912 | | /* then the sliding window mechanism should not allocate a */ |
1913 | | /* new node */ |
1914 | 0 | u1_new_node_flag = 0; |
1915 | 0 | } |
1916 | 0 | ps_next_dpb = ps_next_dpb->ps_prev_short; |
1917 | 0 | } |
1918 | | |
1919 | 0 | if(ps_next_dpb->ps_prev_short->ps_prev_short != NULL) |
1920 | 0 | return ERROR_DBP_MANAGER_T; |
1921 | | |
1922 | 0 | if(u1_new_node_flag) |
1923 | 0 | { |
1924 | 0 | if(u1_num_gaps) |
1925 | 0 | { |
1926 | 0 | ret = ih264d_delete_gap_frm_sliding(ps_dpb_mgr, |
1927 | 0 | ps_next_dpb->ps_prev_short->i4_frame_num, |
1928 | 0 | &u1_del_node); |
1929 | 0 | if(ret != OK) |
1930 | 0 | return ret; |
1931 | 0 | } |
1932 | | |
1933 | 0 | if(u1_del_node) |
1934 | 0 | { |
1935 | 0 | ps_dpb_mgr->u1_num_st_ref_bufs--; |
1936 | 0 | ps_next_dpb->ps_prev_short->u1_used_as_ref = UNUSED_FOR_REF; |
1937 | 0 | ps_next_dpb->ps_prev_short->s_top_field.u1_reference_info = |
1938 | 0 | UNUSED_FOR_REF; |
1939 | 0 | ps_next_dpb->ps_prev_short->s_bot_field.u1_reference_info = |
1940 | 0 | UNUSED_FOR_REF; |
1941 | 0 | ih264d_free_ref_pic_mv_bufs(ps_dpb_mgr->pv_codec_handle, |
1942 | 0 | ps_next_dpb->ps_prev_short->u1_buf_id); |
1943 | 0 | ps_next_dpb->ps_prev_short->ps_pic_buf = NULL; |
1944 | 0 | ps_next_dpb->ps_prev_short = NULL; |
1945 | 0 | } |
1946 | 0 | } |
1947 | 0 | } |
1948 | 0 | else |
1949 | 0 | { |
1950 | 0 | if(ps_dpb_mgr->u1_num_st_ref_bufs) |
1951 | 0 | { |
1952 | 0 | ret = ih264d_delete_gap_frm_sliding(ps_dpb_mgr, |
1953 | 0 | ps_next_dpb->i4_frame_num, |
1954 | 0 | &u1_del_node); |
1955 | 0 | if(ret != OK) |
1956 | 0 | return ret; |
1957 | 0 | if((ps_next_dpb->i4_frame_num != (WORD32)u4_cur_pic_num) |
1958 | 0 | && u1_del_node) |
1959 | 0 | { |
1960 | 0 | ps_dpb_mgr->u1_num_st_ref_bufs--; |
1961 | 0 | ps_next_dpb->u1_used_as_ref = FALSE; |
1962 | 0 | ps_next_dpb->s_top_field.u1_reference_info = UNUSED_FOR_REF; |
1963 | 0 | ps_next_dpb->s_bot_field.u1_reference_info = UNUSED_FOR_REF; |
1964 | 0 | ih264d_free_ref_pic_mv_bufs(ps_dpb_mgr->pv_codec_handle, |
1965 | 0 | ps_next_dpb->u1_buf_id); |
1966 | 0 | ps_next_dpb->ps_pic_buf = NULL; |
1967 | 0 | ps_next_dpb = NULL; |
1968 | 0 | } |
1969 | 0 | } |
1970 | 0 | else |
1971 | 0 | { |
1972 | 0 | ret = ih264d_delete_gap_frm_sliding(ps_dpb_mgr, INVALID_FRAME_NUM, &u1_del_node); |
1973 | 0 | if(ret != OK) |
1974 | 0 | return ret; |
1975 | 0 | if(u1_del_node) |
1976 | 0 | return ERROR_DBP_MANAGER_T; |
1977 | 0 | } |
1978 | 0 | } |
1979 | 0 | } |
1980 | 0 | return OK; |
1981 | 0 | } |
1982 | | /*****************************************************************************/ |
1983 | | /* */ |
1984 | | /* Function Name : ih264d_delete_nonref_nondisplay_pics */ |
1985 | | /* */ |
1986 | | /* Description : */ |
1987 | | /* */ |
1988 | | /* */ |
1989 | | /* Inputs : */ |
1990 | | /* Globals : */ |
1991 | | /* Processing : */ |
1992 | | /* */ |
1993 | | /* Outputs : */ |
1994 | | /* Returns : */ |
1995 | | /* */ |
1996 | | /* Issues : */ |
1997 | | /* */ |
1998 | | /* Revision History: */ |
1999 | | /* */ |
2000 | | /* DD MM YYYY Author(s) Changes (Describe the changes made) */ |
2001 | | /* 05 06 2007 Varun Draft */ |
2002 | | /* */ |
2003 | | /*****************************************************************************/ |
2004 | | |
2005 | | void ih264d_delete_nonref_nondisplay_pics(dpb_manager_t *ps_dpb_mgr) |
2006 | 8.95M | { |
2007 | 8.95M | WORD8 i; |
2008 | 8.95M | WORD32 (*i4_poc_buf_id_map)[3] = ps_dpb_mgr->ai4_poc_buf_id_map; |
2009 | | |
2010 | | /* remove all gaps marked as unused for ref */ |
2011 | 21.0M | for(i = 0; (i < MAX_FRAMES) && ps_dpb_mgr->i1_gaps_deleted; i++) |
2012 | 12.1M | { |
2013 | 12.1M | if(GAP_FRAME_NUM == i4_poc_buf_id_map[i][2]) |
2014 | 4.46M | { |
2015 | 4.46M | ps_dpb_mgr->i1_gaps_deleted--; |
2016 | 4.46M | ps_dpb_mgr->i1_poc_buf_id_entries--; |
2017 | 4.46M | i4_poc_buf_id_map[i][0] = -1; |
2018 | 4.46M | i4_poc_buf_id_map[i][1] = 0x7fffffff; |
2019 | 4.46M | i4_poc_buf_id_map[i][2] = 0; |
2020 | 4.46M | } |
2021 | 12.1M | } |
2022 | 8.95M | } |
2023 | | /*****************************************************************************/ |
2024 | | /* */ |
2025 | | /* Function Name : ih264d_insert_pic_in_display_list */ |
2026 | | /* */ |
2027 | | /* Description : */ |
2028 | | /* */ |
2029 | | /* */ |
2030 | | /* Inputs : */ |
2031 | | /* Globals : */ |
2032 | | /* Processing : */ |
2033 | | /* */ |
2034 | | /* Outputs : */ |
2035 | | /* Returns : */ |
2036 | | /* */ |
2037 | | /* Issues : */ |
2038 | | /* */ |
2039 | | /* Revision History: */ |
2040 | | /* */ |
2041 | | /* DD MM YYYY Author(s) Changes (Describe the changes made) */ |
2042 | | /* 05 06 2007 Varun Draft */ |
2043 | | /* */ |
2044 | | /*****************************************************************************/ |
2045 | | |
2046 | | WORD32 ih264d_insert_pic_in_display_list(dpb_manager_t *ps_dpb_mgr, |
2047 | | UWORD8 u1_buf_id, |
2048 | | WORD32 i4_display_poc, |
2049 | | UWORD32 u4_frame_num) |
2050 | 4.48M | { |
2051 | 4.48M | WORD8 i; |
2052 | 4.48M | WORD32 (*i4_poc_buf_id_map)[3] = ps_dpb_mgr->ai4_poc_buf_id_map; |
2053 | | |
2054 | 12.2M | for(i = 0; i < MAX_FRAMES; i++) |
2055 | 12.2M | { |
2056 | | /* Find an empty slot */ |
2057 | 12.2M | if(i4_poc_buf_id_map[i][0] == -1) |
2058 | 4.48M | { |
2059 | 4.48M | if(GAP_FRAME_NUM == i4_poc_buf_id_map[i][2]) |
2060 | 0 | ps_dpb_mgr->i1_gaps_deleted--; |
2061 | 4.48M | else |
2062 | 4.48M | ps_dpb_mgr->i1_poc_buf_id_entries++; |
2063 | | |
2064 | 4.48M | i4_poc_buf_id_map[i][0] = u1_buf_id; |
2065 | 4.48M | i4_poc_buf_id_map[i][1] = i4_display_poc; |
2066 | 4.48M | i4_poc_buf_id_map[i][2] = u4_frame_num; |
2067 | | |
2068 | 4.48M | break; |
2069 | 4.48M | } |
2070 | 12.2M | } |
2071 | | |
2072 | 4.48M | if(MAX_FRAMES == i) |
2073 | 63 | { |
2074 | | |
2075 | 63 | UWORD32 i4_error_code; |
2076 | 63 | i4_error_code = ERROR_GAPS_IN_FRM_NUM; |
2077 | 63 | return i4_error_code; |
2078 | 63 | } |
2079 | 4.48M | return OK; |
2080 | 4.48M | } |
2081 | | |