/src/libavc/decoder/ih264d_dpb_mgr.c
Line | Count | Source (jump to first uncovered line) |
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 | 84.2k | { |
82 | 84.2k | UWORD32 i; |
83 | 84.2k | struct dpb_info_t *ps_dpb_info = ps_dpb_mgr->as_dpb_info; |
84 | 2.78M | for(i = 0; i < MAX_REF_BUFS; i++) |
85 | 2.69M | { |
86 | 2.69M | ps_dpb_info[i].u1_used_as_ref = UNUSED_FOR_REF; |
87 | 2.69M | ps_dpb_info[i].u1_lt_idx = MAX_REF_BUFS + 1; |
88 | 2.69M | ps_dpb_info[i].ps_prev_short = NULL; |
89 | 2.69M | ps_dpb_info[i].ps_prev_long = NULL; |
90 | 2.69M | ps_dpb_info[i].ps_pic_buf = NULL; |
91 | 2.69M | ps_dpb_info[i].s_top_field.u1_reference_info = UNUSED_FOR_REF; |
92 | 2.69M | ps_dpb_info[i].s_bot_field.u1_reference_info = UNUSED_FOR_REF; |
93 | 2.69M | ps_dpb_info[i].s_top_field.u1_long_term_frame_idx = MAX_REF_BUFS + 1; |
94 | 2.69M | ps_dpb_info[i].s_bot_field.u1_long_term_frame_idx = MAX_REF_BUFS + 1; |
95 | | |
96 | 2.69M | } |
97 | 84.2k | ps_dpb_mgr->u1_num_st_ref_bufs = ps_dpb_mgr->u1_num_lt_ref_bufs = 0; |
98 | 84.2k | ps_dpb_mgr->ps_dpb_st_head = NULL; |
99 | 84.2k | ps_dpb_mgr->ps_dpb_ht_head = NULL; |
100 | 84.2k | ps_dpb_mgr->i1_gaps_deleted = 0; |
101 | 84.2k | ps_dpb_mgr->i1_poc_buf_id_entries = 0; |
102 | 84.2k | ps_dpb_mgr->u1_mmco_error_in_seq = 0; |
103 | | |
104 | 84.2k | ps_dpb_mgr->u1_num_gaps = 0; |
105 | 1.43M | for(i = 0; i < MAX_FRAMES; i++) |
106 | 1.34M | { |
107 | 1.34M | ps_dpb_mgr->ai4_gaps_start_frm_num[i] = INVALID_FRAME_NUM; |
108 | 1.34M | ps_dpb_mgr->ai4_gaps_end_frm_num[i] = 0; |
109 | 1.34M | ps_dpb_mgr->ai1_gaps_per_seq[i] = 0; |
110 | 1.34M | ps_dpb_mgr->ai4_poc_buf_id_map[i][0] = -1; |
111 | 1.34M | ps_dpb_mgr->ai4_poc_buf_id_map[i][1] = 0x7fffffff; |
112 | 1.34M | ps_dpb_mgr->ai4_poc_buf_id_map[i][2] = 0; |
113 | 1.34M | } |
114 | | |
115 | 84.2k | } |
116 | | |
117 | | void ih264d_free_ref_pic_mv_bufs(void* pv_dec, UWORD8 pic_buf_id) |
118 | 110k | { |
119 | 110k | dec_struct_t *ps_dec = (dec_struct_t *)pv_dec; |
120 | | |
121 | 110k | if((pic_buf_id == ps_dec->u1_pic_buf_id) && |
122 | 110k | ps_dec->ps_cur_slice->u1_field_pic_flag && |
123 | 110k | (ps_dec->u1_top_bottom_decoded == 0)) |
124 | 799 | { |
125 | 799 | return; |
126 | 799 | } |
127 | | |
128 | 109k | ih264_buf_mgr_release((buf_mgr_t *)ps_dec->pv_pic_buf_mgr, |
129 | 109k | pic_buf_id, |
130 | 109k | BUF_MGR_REF); |
131 | 109k | ih264_buf_mgr_release((buf_mgr_t *)ps_dec->pv_mv_buf_mgr, |
132 | 109k | ps_dec->as_buf_id_info_map[pic_buf_id].mv_buf_id, |
133 | 109k | BUF_MGR_REF); |
134 | 109k | } |
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 | 22.5k | { |
152 | 22.5k | *pi4_status = 0; |
153 | 22.5k | if(ps_dpb_mgr->u1_num_lt_ref_bufs > 0) |
154 | 2.90k | { |
155 | 2.90k | WORD32 i; |
156 | 2.90k | struct dpb_info_t *ps_next_dpb; |
157 | | /* ps_unmark_node points to the node to be removed */ |
158 | | /* from long term list. */ |
159 | 2.90k | struct dpb_info_t *ps_unmark_node; |
160 | | //Find the node with matching LTIndex |
161 | 2.90k | ps_next_dpb = ps_dpb_mgr->ps_dpb_ht_head; |
162 | 2.90k | if(ps_next_dpb->u1_lt_idx == u4_lt_idx) |
163 | 970 | { |
164 | 970 | ps_unmark_node = ps_next_dpb; |
165 | 970 | } |
166 | 1.93k | else |
167 | 1.93k | { |
168 | 3.09k | for(i = 1; i < ps_dpb_mgr->u1_num_lt_ref_bufs; i++) |
169 | 1.72k | { |
170 | 1.72k | if(ps_next_dpb->ps_prev_long->u1_lt_idx == u4_lt_idx) |
171 | 565 | break; |
172 | 1.16k | ps_next_dpb = ps_next_dpb->ps_prev_long; |
173 | 1.16k | } |
174 | 1.93k | if(i == ps_dpb_mgr->u1_num_lt_ref_bufs) |
175 | 1.36k | *pi4_status = 1; |
176 | 565 | else |
177 | 565 | ps_unmark_node = ps_next_dpb->ps_prev_long; |
178 | 1.93k | } |
179 | | |
180 | 2.90k | if(*pi4_status == 0) |
181 | 1.53k | { |
182 | 1.53k | if(u1_fld_pic_flag) |
183 | 4 | { |
184 | 4 | if(ps_lt_node_to_insert != ps_unmark_node) |
185 | 4 | { |
186 | 4 | UWORD8 u1_deleted = 0; |
187 | | /* for the ps_unmark_node mark the corresponding field */ |
188 | | /* field as unused for reference */ |
189 | | |
190 | 4 | if(ps_unmark_node->s_top_field.u1_long_term_frame_idx |
191 | 4 | == u4_lt_idx) |
192 | 4 | { |
193 | 4 | ps_unmark_node->s_top_field.u1_reference_info = |
194 | 4 | UNUSED_FOR_REF; |
195 | 4 | ps_unmark_node->s_top_field.u1_long_term_frame_idx = |
196 | 4 | MAX_REF_BUFS + 1; |
197 | 4 | u1_deleted = 1; |
198 | 4 | } |
199 | 4 | if(ps_unmark_node->s_bot_field.u1_long_term_frame_idx |
200 | 4 | == u4_lt_idx) |
201 | 4 | { |
202 | 4 | ps_unmark_node->s_bot_field.u1_reference_info = |
203 | 4 | UNUSED_FOR_REF; |
204 | 4 | ps_unmark_node->s_bot_field.u1_long_term_frame_idx = |
205 | 4 | MAX_REF_BUFS + 1; |
206 | 4 | u1_deleted = 1; |
207 | 4 | } |
208 | | |
209 | 4 | if(!u1_deleted) |
210 | 0 | { |
211 | |
|
212 | 0 | UWORD32 i4_error_code; |
213 | 0 | i4_error_code = ERROR_DBP_MANAGER_T; |
214 | |
|
215 | 0 | return i4_error_code; |
216 | 0 | } |
217 | 4 | } |
218 | | |
219 | 4 | ps_unmark_node->u1_used_as_ref = |
220 | 4 | ps_unmark_node->s_top_field.u1_reference_info |
221 | 4 | | ps_unmark_node->s_bot_field.u1_reference_info; |
222 | 4 | } |
223 | 1.53k | else |
224 | 1.53k | ps_unmark_node->u1_used_as_ref = UNUSED_FOR_REF; |
225 | | |
226 | 1.53k | if(UNUSED_FOR_REF == ps_unmark_node->u1_used_as_ref) |
227 | 1.53k | { |
228 | 1.53k | if(ps_unmark_node == ps_dpb_mgr->ps_dpb_ht_head) |
229 | 970 | ps_dpb_mgr->ps_dpb_ht_head = ps_next_dpb->ps_prev_long; |
230 | | |
231 | 1.53k | ps_unmark_node->u1_lt_idx = MAX_REF_BUFS + 1; |
232 | 1.53k | ps_unmark_node->s_top_field.u1_reference_info = |
233 | 1.53k | UNUSED_FOR_REF; |
234 | 1.53k | ps_unmark_node->s_bot_field.u1_reference_info = |
235 | 1.53k | UNUSED_FOR_REF; |
236 | | // Release the physical buffer |
237 | 1.53k | ih264d_free_ref_pic_mv_bufs(ps_dpb_mgr->pv_codec_handle, |
238 | 1.53k | ps_unmark_node->u1_buf_id); |
239 | 1.53k | ps_next_dpb->ps_prev_long = ps_unmark_node->ps_prev_long; //update link |
240 | 1.53k | ps_unmark_node->ps_prev_long = NULL; |
241 | 1.53k | ps_dpb_mgr->u1_num_lt_ref_bufs--; //decrement LT buf count |
242 | 1.53k | } |
243 | 1.53k | } |
244 | 2.90k | } |
245 | 22.5k | return OK; |
246 | 22.5k | } |
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 | 19.9k | { |
264 | 19.9k | UWORD8 u1_mark_top_field_long_term = 0; |
265 | 19.9k | UWORD8 u1_mark_bot_field_long_term = 0; |
266 | | |
267 | 19.9k | { |
268 | 19.9k | if(u1_fld_pic_flag) |
269 | 301 | { |
270 | | /* Assign corresponding field (top or bottom) long_term_frame_idx */ |
271 | | |
272 | 301 | if((ps_mov_node->s_top_field.u1_reference_info == IS_LONG_TERM) |
273 | 301 | && (ps_mov_node->s_bot_field.u1_reference_info |
274 | 95 | == IS_LONG_TERM)) |
275 | 11 | { |
276 | 11 | if(ps_mov_node->u1_lt_idx == u4_lt_idx) |
277 | 0 | u1_mark_bot_field_long_term = 1; |
278 | 11 | else |
279 | 11 | { |
280 | | |
281 | 11 | UWORD32 i4_error_code; |
282 | 11 | i4_error_code = ERROR_DBP_MANAGER_T; |
283 | | |
284 | 11 | return i4_error_code; |
285 | | |
286 | 11 | } |
287 | 11 | } |
288 | 290 | else if(ps_mov_node->s_top_field.u1_reference_info == IS_LONG_TERM) |
289 | 84 | { |
290 | 84 | u1_mark_top_field_long_term = 1; |
291 | 84 | } |
292 | | |
293 | 290 | if(!(u1_mark_top_field_long_term || u1_mark_bot_field_long_term)) |
294 | 206 | { |
295 | 206 | UWORD32 i4_error_code; |
296 | 206 | i4_error_code = ERROR_DBP_MANAGER_T; |
297 | 206 | return i4_error_code; |
298 | 206 | } |
299 | 290 | } |
300 | 19.6k | else |
301 | 19.6k | { |
302 | 19.6k | ps_mov_node->s_top_field.u1_reference_info = IS_LONG_TERM; |
303 | 19.6k | ps_mov_node->s_bot_field.u1_reference_info = IS_LONG_TERM; |
304 | 19.6k | ps_mov_node->s_top_field.u1_long_term_frame_idx = u4_lt_idx; |
305 | 19.6k | ps_mov_node->s_bot_field.u1_long_term_frame_idx = u4_lt_idx; |
306 | 19.6k | u1_mark_bot_field_long_term = 1; |
307 | 19.6k | u1_mark_top_field_long_term = 1; |
308 | 19.6k | } |
309 | | |
310 | 19.6k | ps_mov_node->u1_lt_idx = u4_lt_idx; //Assign the LT index to the node |
311 | 19.6k | ps_mov_node->ps_pic_buf->u1_long_term_frm_idx = u4_lt_idx; |
312 | 19.6k | 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 | 19.6k | if(ps_dpb_mgr->u1_num_lt_ref_bufs > 0) |
317 | 1.78k | { |
318 | 1.78k | struct dpb_info_t *ps_next_dpb = ps_dpb_mgr->ps_dpb_ht_head; |
319 | 1.78k | if(u4_lt_idx < ps_next_dpb->u1_lt_idx) |
320 | 225 | { |
321 | | //LTIndex to be inserted is the smallest LT index |
322 | | //Update head and point prev to the next higher index |
323 | 225 | ps_mov_node->ps_prev_long = ps_next_dpb; |
324 | 225 | ps_dpb_mgr->ps_dpb_ht_head = ps_mov_node; |
325 | 225 | } |
326 | 1.55k | else |
327 | 1.55k | { |
328 | 1.55k | WORD32 i; |
329 | 1.55k | struct dpb_info_t *ps_nxtDPB = ps_next_dpb; |
330 | 1.55k | ps_next_dpb = ps_next_dpb->ps_prev_long; |
331 | 2.42k | for(i = 1; i < ps_dpb_mgr->u1_num_lt_ref_bufs; i++) |
332 | 1.12k | { |
333 | 1.12k | if(ps_next_dpb->u1_lt_idx > u4_lt_idx) |
334 | 257 | break; |
335 | 863 | ps_nxtDPB = ps_next_dpb; |
336 | 863 | ps_next_dpb = ps_next_dpb->ps_prev_long; |
337 | 863 | } |
338 | | |
339 | 1.55k | ps_nxtDPB->ps_prev_long = ps_mov_node; |
340 | 1.55k | ps_mov_node->ps_prev_long = ps_next_dpb; |
341 | 1.55k | } |
342 | 1.78k | } |
343 | 17.9k | else |
344 | 17.9k | { |
345 | 17.9k | ps_dpb_mgr->ps_dpb_ht_head = ps_mov_node; |
346 | 17.9k | ps_mov_node->ps_prev_long = NULL; |
347 | 17.9k | } |
348 | | /* Identify the picture buffer as a long term picture buffer */ |
349 | 19.6k | 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 | 19.6k | if(u1_mark_bot_field_long_term) |
355 | 19.6k | ps_dpb_mgr->u1_num_lt_ref_bufs++; |
356 | | |
357 | 19.6k | } |
358 | 19.6k | return OK; |
359 | 19.9k | } |
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 | 138k | { |
380 | 138k | WORD32 i; |
381 | 138k | struct dpb_info_t *ps_dpb_info = ps_dpb_mgr->as_dpb_info; |
382 | 138k | UWORD8 u1_picture_type = ps_pic_buf->u1_picturetype; |
383 | | /* Find an unused dpb location */ |
384 | 161k | for(i = 0; i < MAX_REF_BUFS; i++) |
385 | 161k | { |
386 | 161k | if((ps_dpb_info[i].ps_pic_buf == ps_pic_buf) |
387 | 161k | && ps_dpb_info[i].u1_used_as_ref) |
388 | 1.71k | { |
389 | | /*signal an error in the case of frame pic*/ |
390 | 1.71k | if(ps_dpb_info[i].ps_pic_buf->u1_pic_type == FRM_PIC) |
391 | 524 | { |
392 | 524 | return ERROR_DBP_MANAGER_T; |
393 | 524 | } |
394 | 1.19k | else |
395 | 1.19k | { |
396 | | /* Can occur only for field bottom pictures */ |
397 | 1.19k | ps_dpb_info[i].s_bot_field.u1_reference_info = IS_SHORT_TERM; |
398 | 1.19k | return OK; |
399 | 1.19k | } |
400 | 1.71k | } |
401 | | |
402 | 159k | if((ps_dpb_info[i].u1_used_as_ref == UNUSED_FOR_REF) |
403 | 159k | && (ps_dpb_info[i].s_top_field.u1_reference_info |
404 | 137k | == UNUSED_FOR_REF) |
405 | 159k | && (ps_dpb_info[i].s_bot_field.u1_reference_info |
406 | 137k | == UNUSED_FOR_REF)) |
407 | 137k | break; |
408 | 159k | } |
409 | 137k | 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 | 137k | ps_dpb_info[i].ps_pic_buf = ps_pic_buf; |
418 | 137k | ps_dpb_info[i].ps_prev_short = ps_dpb_mgr->ps_dpb_st_head; |
419 | 137k | ps_dpb_info[i].u1_buf_id = u1_buf_id; |
420 | 137k | ps_dpb_info[i].u1_used_as_ref = TRUE; |
421 | 137k | ps_dpb_info[i].u1_lt_idx = MAX_REF_BUFS + 1; |
422 | 137k | ps_dpb_info[i].i4_frame_num = u4_cur_pic_num; |
423 | 137k | 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 | 137k | ps_dpb_mgr->ps_dpb_st_head = ps_dpb_info + i; |
427 | | |
428 | | // Increment Short term bufCount |
429 | 137k | ps_dpb_mgr->u1_num_st_ref_bufs++; |
430 | | /* Identify the picture as a short term picture buffer */ |
431 | 137k | ps_pic_buf->u1_is_short = IS_SHORT_TERM; |
432 | | |
433 | 137k | if((u1_picture_type & 0x03) == FRM_PIC) |
434 | 129k | { |
435 | 129k | ps_dpb_info[i].u1_used_as_ref = IS_SHORT_TERM; |
436 | 129k | ps_dpb_info[i].s_top_field.u1_reference_info = IS_SHORT_TERM; |
437 | 129k | ps_dpb_info[i].s_bot_field.u1_reference_info = IS_SHORT_TERM; |
438 | 129k | } |
439 | | |
440 | 137k | if((u1_picture_type & 0x03) == TOP_FLD) |
441 | 4.40k | ps_dpb_info[i].s_top_field.u1_reference_info = IS_SHORT_TERM; |
442 | | |
443 | 137k | if((u1_picture_type & 0x03) == BOT_FLD) |
444 | 0 | ps_dpb_info[i].s_bot_field.u1_reference_info = IS_SHORT_TERM; |
445 | | |
446 | 137k | return OK; |
447 | 137k | } |
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 | 21.4k | { |
469 | 21.4k | WORD32 i; |
470 | 21.4k | struct dpb_info_t *ps_next_dpb; |
471 | 21.4k | WORD32 i4_frame_num = i4_pic_num; |
472 | 21.4k | struct dpb_info_t *ps_unmark_node = NULL; |
473 | 21.4k | UWORD8 u1_del_node = 0, u1_del_st = 0; |
474 | 21.4k | UWORD8 u1_reference_type = UNUSED_FOR_REF; |
475 | 21.4k | WORD32 ret; |
476 | | |
477 | 21.4k | if(u1_fld_pic_flag) |
478 | 1.11k | { |
479 | 1.11k | i4_frame_num = i4_frame_num >> 1; |
480 | | |
481 | 1.11k | if(u4_lt_idx == (MAX_REF_BUFS + 1)) |
482 | 405 | u1_reference_type = UNUSED_FOR_REF; |
483 | 711 | else |
484 | 711 | u1_reference_type = IS_LONG_TERM; |
485 | 1.11k | } |
486 | | |
487 | | //Find the node with matching picNum |
488 | 21.4k | ps_next_dpb = ps_dpb_mgr->ps_dpb_st_head; |
489 | 21.4k | if((WORD32)ps_next_dpb->i4_frame_num == i4_frame_num) |
490 | 20.1k | { |
491 | 20.1k | ps_unmark_node = ps_next_dpb; |
492 | 20.1k | } |
493 | 1.33k | else |
494 | 1.33k | { |
495 | 1.84k | for(i = 1; i < ps_dpb_mgr->u1_num_st_ref_bufs; i++) |
496 | 683 | { |
497 | 683 | if((WORD32)ps_next_dpb->ps_prev_short->i4_frame_num == i4_frame_num) |
498 | 173 | break; |
499 | 510 | ps_next_dpb = ps_next_dpb->ps_prev_short; |
500 | 510 | } |
501 | | |
502 | 1.33k | if(i == ps_dpb_mgr->u1_num_st_ref_bufs) |
503 | 1.15k | { |
504 | 1.15k | if(ps_dpb_mgr->u1_num_gaps) |
505 | 245 | { |
506 | 245 | ret = ih264d_delete_gap_frm_mmco(ps_dpb_mgr, i4_frame_num, &u1_del_st); |
507 | 245 | if(ret != OK) |
508 | 71 | return ret; |
509 | 245 | } |
510 | 913 | else |
511 | 913 | { |
512 | 913 | UWORD32 i4_error_code; |
513 | 913 | i4_error_code = ERROR_DBP_MANAGER_T; |
514 | | |
515 | 913 | return i4_error_code; |
516 | 913 | } |
517 | | |
518 | 174 | 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 | 174 | else |
525 | 174 | { |
526 | 174 | return 0; |
527 | 174 | } |
528 | 174 | } |
529 | 173 | else |
530 | 173 | ps_unmark_node = ps_next_dpb->ps_prev_short; |
531 | 1.33k | } |
532 | | |
533 | 20.3k | if(u1_fld_pic_flag) |
534 | 491 | { |
535 | | /* Mark the corresponding field ( top or bot) as */ |
536 | | /* UNUSED_FOR_REF or IS_LONG_TERM depending on */ |
537 | | /* u1_reference_type. */ |
538 | 491 | if(ps_unmark_node->s_top_field.i4_pic_num == i4_pic_num) |
539 | 142 | { |
540 | 142 | ps_unmark_node->s_top_field.u1_reference_info = u1_reference_type; |
541 | 142 | ps_unmark_node->s_top_field.u1_long_term_frame_idx = u4_lt_idx; |
542 | 142 | { |
543 | 142 | UWORD8 *pu1_src = ps_unmark_node->ps_pic_buf->pu1_col_zero_flag; |
544 | 142 | WORD32 i4_size = ((ps_dpb_mgr->u2_pic_wd |
545 | 142 | * ps_dpb_mgr->u2_pic_ht) >> 5); |
546 | | /* memset the colocated zero u4_flag buffer */ |
547 | 142 | memset(pu1_src, 0, i4_size); |
548 | 142 | } |
549 | 142 | } |
550 | | |
551 | 349 | else if(ps_unmark_node->s_bot_field.i4_pic_num == i4_pic_num) |
552 | 280 | { |
553 | | |
554 | 280 | ps_unmark_node->s_bot_field.u1_reference_info = u1_reference_type; |
555 | 280 | ps_unmark_node->s_bot_field.u1_long_term_frame_idx = u4_lt_idx; |
556 | 280 | { |
557 | 280 | UWORD8 *pu1_src = |
558 | 280 | ps_unmark_node->ps_pic_buf->pu1_col_zero_flag |
559 | 280 | + ((ps_dpb_mgr->u2_pic_wd |
560 | 280 | * ps_dpb_mgr->u2_pic_ht) |
561 | 280 | >> 5); |
562 | 280 | WORD32 i4_size = ((ps_dpb_mgr->u2_pic_wd |
563 | 280 | * ps_dpb_mgr->u2_pic_ht) >> 5); |
564 | | /* memset the colocated zero u4_flag buffer */ |
565 | 280 | memset(pu1_src, 0, i4_size); |
566 | 280 | } |
567 | 280 | } |
568 | 491 | ps_unmark_node->u1_used_as_ref = |
569 | 491 | ps_unmark_node->s_top_field.u1_reference_info |
570 | 491 | | ps_unmark_node->s_bot_field.u1_reference_info; |
571 | 491 | } |
572 | 19.8k | else |
573 | 19.8k | { |
574 | 19.8k | ps_unmark_node->u1_used_as_ref = UNUSED_FOR_REF; |
575 | 19.8k | ps_unmark_node->s_top_field.u1_reference_info = UNUSED_FOR_REF; |
576 | 19.8k | ps_unmark_node->s_bot_field.u1_reference_info = UNUSED_FOR_REF; |
577 | | |
578 | 19.8k | { |
579 | 19.8k | UWORD8 *pu1_src = ps_unmark_node->ps_pic_buf->pu1_col_zero_flag; |
580 | | |
581 | 19.8k | WORD32 i4_size = ((ps_dpb_mgr->u2_pic_wd |
582 | 19.8k | * ps_dpb_mgr->u2_pic_ht) >> 4); |
583 | | /* memset the colocated zero u4_flag buffer */ |
584 | 19.8k | memset(pu1_src, 0, i4_size); |
585 | 19.8k | } |
586 | 19.8k | } |
587 | | |
588 | 20.3k | if(!(ps_unmark_node->u1_used_as_ref & IS_SHORT_TERM)) |
589 | 19.9k | { |
590 | 19.9k | if(ps_unmark_node == ps_dpb_mgr->ps_dpb_st_head) |
591 | 19.8k | ps_dpb_mgr->ps_dpb_st_head = ps_next_dpb->ps_prev_short; |
592 | 173 | else |
593 | 173 | ps_next_dpb->ps_prev_short = ps_unmark_node->ps_prev_short; //update link |
594 | 19.9k | ps_dpb_mgr->u1_num_st_ref_bufs--; //decrement ST buf count |
595 | 19.9k | u1_del_node = 1; |
596 | 19.9k | } |
597 | | |
598 | 20.3k | if(u4_lt_idx == MAX_REF_BUFS + 1) |
599 | 417 | { |
600 | 417 | if(u1_del_node) |
601 | 272 | { |
602 | | // Release the physical buffer |
603 | 272 | ih264d_free_ref_pic_mv_bufs(ps_dpb_mgr->pv_codec_handle, |
604 | 272 | ps_unmark_node->u1_buf_id); |
605 | 272 | ps_unmark_node->ps_prev_short = NULL; |
606 | 272 | } |
607 | 417 | } |
608 | 19.9k | else |
609 | 19.9k | { |
610 | 19.9k | WORD32 i4_status; |
611 | | //If another node has the same LT index, delete that node |
612 | 19.9k | ret = ih264d_delete_lt_node(ps_dpb_mgr, u4_lt_idx, |
613 | 19.9k | u1_fld_pic_flag, ps_unmark_node, &i4_status); |
614 | 19.9k | if(ret != OK) |
615 | 0 | return ret; |
616 | | // Now insert the short term node as a long term node |
617 | 19.9k | ret = ih264d_insert_lt_node(ps_dpb_mgr, ps_unmark_node, u4_lt_idx, |
618 | 19.9k | u1_fld_pic_flag); |
619 | 19.9k | if(ret != OK) |
620 | 217 | return ret; |
621 | 19.9k | } |
622 | 20.1k | return OK; |
623 | 20.3k | } |
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 | 234k | { |
637 | 234k | WORD32 i; |
638 | 234k | struct dpb_info_t *ps_dpb_info = ps_dpb_mgr->as_dpb_info; |
639 | | |
640 | 7.75M | for(i = 0; i < MAX_REF_BUFS; i++) |
641 | 7.51M | { |
642 | 7.51M | if(ps_dpb_info[i].u1_used_as_ref) |
643 | 101k | { |
644 | 101k | ps_dpb_info[i].u1_used_as_ref = UNUSED_FOR_REF; |
645 | 101k | ps_dpb_info[i].u1_lt_idx = MAX_REF_BUFS + 1; |
646 | 101k | ps_dpb_info[i].ps_prev_short = NULL; |
647 | 101k | ps_dpb_info[i].ps_prev_long = NULL; |
648 | 101k | ps_dpb_info[i].ps_pic_buf = NULL; |
649 | 101k | ps_dpb_info[i].s_top_field.u1_reference_info = UNUSED_FOR_REF; |
650 | 101k | ps_dpb_info[i].s_bot_field.u1_reference_info = UNUSED_FOR_REF; |
651 | 101k | ps_dpb_info[i].s_top_field.u1_long_term_frame_idx = MAX_REF_BUFS + 1; |
652 | 101k | ps_dpb_info[i].s_bot_field.u1_long_term_frame_idx = MAX_REF_BUFS + 1; |
653 | | |
654 | | //Release physical buffer |
655 | 101k | ih264d_free_ref_pic_mv_bufs(ps_dpb_mgr->pv_codec_handle, |
656 | 101k | ps_dpb_info[i].u1_buf_id); |
657 | 101k | } |
658 | 7.51M | } |
659 | 234k | ps_dpb_mgr->u1_num_st_ref_bufs = ps_dpb_mgr->u1_num_lt_ref_bufs = 0; |
660 | 234k | ps_dpb_mgr->ps_dpb_st_head = NULL; |
661 | 234k | ps_dpb_mgr->ps_dpb_ht_head = NULL; |
662 | 234k | ps_dpb_mgr->u1_mmco_error_in_seq = 0; |
663 | | |
664 | | /* release all gaps */ |
665 | 234k | ps_dpb_mgr->u1_num_gaps = 0; |
666 | 3.99M | for(i = 0; i < MAX_FRAMES; i++) |
667 | 3.75M | { |
668 | 3.75M | ps_dpb_mgr->ai4_gaps_start_frm_num[i] = INVALID_FRAME_NUM; |
669 | 3.75M | ps_dpb_mgr->ai4_gaps_end_frm_num[i] = 0; |
670 | 3.75M | ps_dpb_mgr->ai1_gaps_per_seq[i] = 0; |
671 | 3.75M | } |
672 | 234k | } |
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 | 144k | { |
688 | 144k | WORD32 i; |
689 | 144k | struct dpb_info_t *ps_next_dpb = ps_dpb_mgr->ps_dpb_st_head; |
690 | | |
691 | 298k | for(i = 0; i < ps_dpb_mgr->u1_num_st_ref_bufs; i++) |
692 | 153k | { |
693 | 153k | ps_dpb_mgr->ps_def_dpb[i] = ps_next_dpb->ps_pic_buf; |
694 | 153k | ps_next_dpb = ps_next_dpb->ps_prev_short; |
695 | 153k | } |
696 | | |
697 | 144k | ps_next_dpb = ps_dpb_mgr->ps_dpb_ht_head; |
698 | 165k | for(;i< ps_dpb_mgr->u1_num_st_ref_bufs + ps_dpb_mgr->u1_num_lt_ref_bufs; i++) |
699 | 20.7k | { |
700 | 20.7k | ps_dpb_mgr->ps_def_dpb[i] = ps_next_dpb->ps_pic_buf; |
701 | 20.7k | ps_next_dpb = ps_next_dpb->ps_prev_long; |
702 | 20.7k | } |
703 | 144k | return 0; |
704 | 144k | } |
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 | 90.8k | { |
730 | 90.8k | dpb_manager_t *ps_dpb_mgr = ps_dec->ps_dpb_mgr; |
731 | 90.8k | UWORD16 u4_cur_pic_num = ps_dec->ps_cur_slice->u2_frame_num; |
732 | | /*< Maximum Picture Number Minus 1 */ |
733 | 90.8k | UWORD32 ui_max_frame_num = |
734 | 90.8k | ps_dec->ps_cur_sps->u2_u4_max_pic_num_minus1 + 1; |
735 | | |
736 | 90.8k | WORD32 i, count = 0; |
737 | 90.8k | UWORD32 ui_remapIdc, ui_nextUev; |
738 | 90.8k | WORD16 u2_pred_frame_num = u4_cur_pic_num; |
739 | 90.8k | WORD32 i_temp; |
740 | 90.8k | UWORD16 u2_def_mod_flag = 0; /* Flag to keep track of which indices have been remapped */ |
741 | 90.8k | UWORD8 modCount = 0; |
742 | 90.8k | UWORD32 *pu4_bitstrm_buf = ps_dec->ps_bitstrm->pu4_buffer; |
743 | 90.8k | UWORD32 *pu4_bitstrm_ofst = &ps_dec->ps_bitstrm->u4_ofst; |
744 | 90.8k | dec_slice_params_t *ps_cur_slice = ps_dec->ps_cur_slice; |
745 | 90.8k | UWORD8 u1_field_pic_flag = ps_cur_slice->u1_field_pic_flag; |
746 | | |
747 | 90.8k | if(u1_field_pic_flag) |
748 | 4.60k | { |
749 | 4.60k | u4_cur_pic_num = u4_cur_pic_num * 2 + 1; |
750 | 4.60k | ui_max_frame_num = ui_max_frame_num * 2; |
751 | 4.60k | } |
752 | | |
753 | 90.8k | u2_pred_frame_num = u4_cur_pic_num; |
754 | | |
755 | 90.8k | ui_remapIdc = ih264d_uev(pu4_bitstrm_ofst, pu4_bitstrm_buf); |
756 | | |
757 | 97.4k | while((ui_remapIdc != 3) |
758 | 97.4k | && (count < ps_cur_slice->u1_num_ref_idx_lx_active[uc_lx])) |
759 | 92.2k | { |
760 | 92.2k | ui_nextUev = ih264d_uev(pu4_bitstrm_ofst, pu4_bitstrm_buf); |
761 | 92.2k | if(ui_remapIdc != 2) |
762 | 84.7k | { |
763 | 84.7k | if(ui_nextUev > ui_max_frame_num) |
764 | 4.25k | return ERROR_DBP_MANAGER_T; |
765 | | |
766 | 80.5k | ui_nextUev = ui_nextUev + 1; |
767 | | |
768 | 80.5k | if(ui_remapIdc == 0) |
769 | 59.9k | { |
770 | | // diffPicNum is -ve |
771 | 59.9k | i_temp = (WORD32)u2_pred_frame_num - (WORD32)ui_nextUev; |
772 | 59.9k | if(i_temp < 0) |
773 | 12.8k | i_temp += ui_max_frame_num; |
774 | 59.9k | } |
775 | 20.5k | else |
776 | 20.5k | { |
777 | | // diffPicNum is +ve |
778 | 20.5k | i_temp = (WORD32)u2_pred_frame_num + (WORD32)ui_nextUev; |
779 | 20.5k | if(i_temp >= (WORD32)ui_max_frame_num) |
780 | 2.45k | i_temp -= ui_max_frame_num; |
781 | 20.5k | } |
782 | | /* Find the dpb with the matching picNum (picNum==frameNum for framePic) */ |
783 | | |
784 | 80.5k | if(i_temp > u4_cur_pic_num) |
785 | 28.9k | i_temp = i_temp - ui_max_frame_num; |
786 | | |
787 | 161k | for(i = 0; i < (ps_cur_slice->u1_initial_list_size[uc_lx]); i++) |
788 | 86.8k | { |
789 | 86.8k | if(ps_dpb_mgr->ps_init_dpb[uc_lx][i]->i4_pic_num == i_temp) |
790 | 6.02k | break; |
791 | 86.8k | } |
792 | 80.5k | if(i == (ps_cur_slice->u1_initial_list_size[uc_lx])) |
793 | 74.4k | { |
794 | 74.4k | UWORD32 i4_error_code; |
795 | 74.4k | i4_error_code = ERROR_DBP_MANAGER_T; |
796 | 74.4k | return i4_error_code; |
797 | 74.4k | } |
798 | | |
799 | 6.02k | u2_def_mod_flag |= (1 << i); |
800 | 6.02k | ps_dpb_mgr->ps_mod_dpb[uc_lx][modCount++] = |
801 | 6.02k | ps_dpb_mgr->ps_init_dpb[uc_lx][i]; |
802 | 6.02k | u2_pred_frame_num = i_temp; //update predictor to be the picNum just obtained |
803 | 6.02k | } |
804 | 7.49k | else //2 |
805 | 7.49k | { |
806 | 7.49k | UWORD8 u1_lt_idx; |
807 | | |
808 | 7.49k | if(ui_nextUev > (MAX_REF_BUFS + 1)) |
809 | 530 | return ERROR_DBP_MANAGER_T; |
810 | | |
811 | 6.96k | u1_lt_idx = (UWORD8)ui_nextUev; |
812 | | |
813 | 13.8k | for(i = 0; i < (ps_cur_slice->u1_initial_list_size[uc_lx]); i++) |
814 | 7.47k | { |
815 | 7.47k | if(!ps_dpb_mgr->ps_init_dpb[uc_lx][i]->u1_is_short) |
816 | 1.00k | { |
817 | 1.00k | if(ps_dpb_mgr->ps_init_dpb[uc_lx][i]->u1_long_term_pic_num |
818 | 1.00k | == u1_lt_idx) |
819 | 604 | break; |
820 | 1.00k | } |
821 | 7.47k | } |
822 | 6.96k | if(i == (ps_cur_slice->u1_initial_list_size[uc_lx])) |
823 | 6.36k | { |
824 | 6.36k | UWORD32 i4_error_code; |
825 | 6.36k | i4_error_code = ERROR_DBP_MANAGER_T; |
826 | 6.36k | return i4_error_code; |
827 | 6.36k | } |
828 | | |
829 | 604 | u2_def_mod_flag |= (1 << i); |
830 | 604 | ps_dpb_mgr->ps_mod_dpb[uc_lx][modCount++] = |
831 | 604 | ps_dpb_mgr->ps_init_dpb[uc_lx][i]; |
832 | 604 | } |
833 | | |
834 | 6.62k | ui_remapIdc = ih264d_uev(pu4_bitstrm_ofst, pu4_bitstrm_buf); |
835 | | /* Get the remapping_idc - 0/1/2/3 */ |
836 | 6.62k | count++; |
837 | 6.62k | } |
838 | | |
839 | | //Handle the ref indices that were not remapped |
840 | 16.8k | for(i = 0; i < (ps_cur_slice->u1_num_ref_idx_lx_active[uc_lx]); i++) |
841 | 11.7k | { |
842 | 11.7k | if(!(u2_def_mod_flag & (1 << i))) |
843 | 8.51k | ps_dpb_mgr->ps_mod_dpb[uc_lx][modCount++] = |
844 | 8.51k | ps_dpb_mgr->ps_init_dpb[uc_lx][i]; |
845 | 11.7k | } |
846 | 5.16k | return OK; |
847 | 90.8k | } |
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 | 231k | { |
867 | 231k | dec_pic_params_t *ps_pps = ps_dec->ps_cur_pps; |
868 | 231k | dec_seq_params_t *ps_sps = ps_pps->ps_sps; |
869 | 231k | dec_bit_stream_t *ps_bitstrm = ps_dec->ps_bitstrm; |
870 | 231k | dpb_commands_t *ps_dpb_cmds = &(ps_dec->s_dpb_cmds_scratch); |
871 | 231k | dec_slice_params_t * ps_slice = ps_dec->ps_cur_slice; |
872 | 231k | WORD32 j; |
873 | 231k | UWORD8 u1_buf_mode; |
874 | 231k | struct MMCParams *ps_mmc_params; |
875 | 231k | UWORD32 *pu4_bitstrm_buf = ps_dec->ps_bitstrm->pu4_buffer; |
876 | 231k | UWORD32 *pu4_bitstrm_ofst = &ps_bitstrm->u4_ofst; |
877 | 231k | UWORD32 u4_bit_ofst = ps_dec->ps_bitstrm->u4_ofst; |
878 | | |
879 | 231k | ps_slice->u1_mmco_equalto5 = 0; |
880 | 231k | { |
881 | 231k | if(ps_dec->u1_nal_unit_type == IDR_SLICE_NAL) |
882 | 168k | { |
883 | 168k | ps_slice->u1_no_output_of_prior_pics_flag = |
884 | 168k | ih264d_get_bit_h264(ps_bitstrm); |
885 | 168k | COPYTHECONTEXT("SH: no_output_of_prior_pics_flag", |
886 | 168k | ps_slice->u1_no_output_of_prior_pics_flag); |
887 | 168k | ps_slice->u1_long_term_reference_flag = ih264d_get_bit_h264( |
888 | 168k | ps_bitstrm); |
889 | 168k | COPYTHECONTEXT("SH: long_term_reference_flag", |
890 | 168k | ps_slice->u1_long_term_reference_flag); |
891 | 168k | ps_dpb_cmds->u1_idr_pic = 1; |
892 | 168k | ps_dpb_cmds->u1_no_output_of_prior_pics_flag = |
893 | 168k | ps_slice->u1_no_output_of_prior_pics_flag; |
894 | 168k | ps_dpb_cmds->u1_long_term_reference_flag = |
895 | 168k | ps_slice->u1_long_term_reference_flag; |
896 | 168k | } |
897 | 63.1k | else |
898 | 63.1k | { |
899 | 63.1k | u1_buf_mode = ih264d_get_bit_h264(ps_bitstrm); //0 - sliding window; 1 - arbitrary |
900 | 63.1k | COPYTHECONTEXT("SH: adaptive_ref_pic_buffering_flag", u1_buf_mode); |
901 | 63.1k | ps_dpb_cmds->u1_buf_mode = u1_buf_mode; |
902 | 63.1k | j = 0; |
903 | | |
904 | 63.1k | if(u1_buf_mode == 1) |
905 | 36.7k | { |
906 | 36.7k | UWORD32 u4_mmco; |
907 | 36.7k | UWORD32 u4_diff_pic_num; |
908 | 36.7k | UWORD32 u4_lt_idx, u4_max_lt_idx_plus1; |
909 | | |
910 | 36.7k | u4_mmco = ih264d_uev(pu4_bitstrm_ofst, |
911 | 36.7k | pu4_bitstrm_buf); |
912 | 158k | while(u4_mmco != END_OF_MMCO) |
913 | 122k | { |
914 | 122k | if (j >= MAX_REF_BUFS) |
915 | 770 | { |
916 | | #ifdef __ANDROID__ |
917 | | ALOGE("b/25818142"); |
918 | | android_errorWriteLog(0x534e4554, "25818142"); |
919 | | #endif |
920 | 770 | ps_dpb_cmds->u1_num_of_commands = 0; |
921 | 770 | return -1; |
922 | 770 | } |
923 | 122k | ps_mmc_params = &ps_dpb_cmds->as_mmc_params[j]; |
924 | 122k | ps_mmc_params->u4_mmco = u4_mmco; |
925 | 122k | switch(u4_mmco) |
926 | 122k | { |
927 | 18.4k | case MARK_ST_PICNUM_AS_NONREF: |
928 | 18.4k | u4_diff_pic_num = ih264d_uev(pu4_bitstrm_ofst, |
929 | 18.4k | pu4_bitstrm_buf); |
930 | | //Get absDiffPicnumMinus1 |
931 | 18.4k | ps_mmc_params->u4_diff_pic_num = u4_diff_pic_num; |
932 | 18.4k | break; |
933 | | |
934 | 15.8k | case MARK_LT_INDEX_AS_NONREF: |
935 | 15.8k | u4_lt_idx = ih264d_uev(pu4_bitstrm_ofst, |
936 | 15.8k | pu4_bitstrm_buf); |
937 | 15.8k | ps_mmc_params->u4_lt_idx = u4_lt_idx; |
938 | 15.8k | break; |
939 | | |
940 | 4.33k | case MARK_ST_PICNUM_AS_LT_INDEX: |
941 | 4.33k | u4_diff_pic_num = ih264d_uev(pu4_bitstrm_ofst, |
942 | 4.33k | pu4_bitstrm_buf); |
943 | 4.33k | ps_mmc_params->u4_diff_pic_num = u4_diff_pic_num; |
944 | 4.33k | u4_lt_idx = ih264d_uev(pu4_bitstrm_ofst, |
945 | 4.33k | pu4_bitstrm_buf); |
946 | 4.33k | ps_mmc_params->u4_lt_idx = u4_lt_idx; |
947 | 4.33k | break; |
948 | | |
949 | 15.0k | case SET_MAX_LT_INDEX: |
950 | 15.0k | { |
951 | 15.0k | u4_max_lt_idx_plus1 = ih264d_uev(pu4_bitstrm_ofst, |
952 | 15.0k | pu4_bitstrm_buf); |
953 | 15.0k | if (u4_max_lt_idx_plus1 > ps_sps->u1_num_ref_frames) |
954 | 441 | { |
955 | | /* Invalid max LT ref index */ |
956 | 441 | return -1; |
957 | 441 | } |
958 | 14.5k | ps_mmc_params->u4_max_lt_idx_plus1 = u4_max_lt_idx_plus1; |
959 | 14.5k | break; |
960 | 15.0k | } |
961 | 7.36k | case RESET_REF_PICTURES: |
962 | 7.36k | { |
963 | 7.36k | ps_slice->u1_mmco_equalto5 = 1; |
964 | 7.36k | break; |
965 | 15.0k | } |
966 | | |
967 | 12.0k | case SET_LT_INDEX: |
968 | 12.0k | u4_lt_idx = ih264d_uev(pu4_bitstrm_ofst, |
969 | 12.0k | pu4_bitstrm_buf); |
970 | 12.0k | ps_mmc_params->u4_lt_idx = u4_lt_idx; |
971 | 12.0k | break; |
972 | | |
973 | 49.0k | default: |
974 | 49.0k | break; |
975 | 122k | } |
976 | 121k | u4_mmco = ih264d_uev(pu4_bitstrm_ofst, |
977 | 121k | pu4_bitstrm_buf); |
978 | | |
979 | 121k | j++; |
980 | 121k | } |
981 | 35.5k | ps_dpb_cmds->u1_num_of_commands = j; |
982 | 35.5k | } |
983 | 63.1k | } |
984 | 230k | ps_dpb_cmds->u1_dpb_commands_read = 1; |
985 | 230k | ps_dpb_cmds->u1_dpb_commands_read_slc = 1; |
986 | | |
987 | 230k | } |
988 | 0 | u4_bit_ofst = ps_dec->ps_bitstrm->u4_ofst - u4_bit_ofst; |
989 | 230k | return u4_bit_ofst; |
990 | 231k | } |
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 | 21.5k | { |
1018 | 21.5k | WORD32 i; |
1019 | 21.5k | UWORD8 u1_buf_mode, u1_marked_lt; |
1020 | 21.5k | struct dpb_info_t *ps_next_dpb; |
1021 | 21.5k | UWORD8 u1_num_gaps; |
1022 | 21.5k | UWORD8 u1_del_node = 1; |
1023 | 21.5k | UWORD8 u1_insert_st_pic = 1; |
1024 | 21.5k | WORD32 ret; |
1025 | 21.5k | UNUSED(u1_nal_unit_type); |
1026 | 21.5k | UNUSED(u2_u4_max_pic_num_minus1); |
1027 | 21.5k | u1_buf_mode = ps_dpb_cmds->u1_buf_mode; //0 - sliding window; 1 - Adaptive |
1028 | 21.5k | u1_marked_lt = 0; |
1029 | 21.5k | u1_num_gaps = ps_dpb_mgr->u1_num_gaps; |
1030 | | |
1031 | 21.5k | if(!u1_buf_mode) |
1032 | 14.1k | { |
1033 | | //Sliding window - implements 8.2.5.3 |
1034 | 14.1k | if((ps_dpb_mgr->u1_num_st_ref_bufs |
1035 | 14.1k | + ps_dpb_mgr->u1_num_lt_ref_bufs + u1_num_gaps) |
1036 | 14.1k | == u1_numRef_frames_for_seq) |
1037 | 5.92k | { |
1038 | 5.92k | UWORD8 u1_new_node_flag = 1; |
1039 | 5.92k | if((0 == ps_dpb_mgr->u1_num_st_ref_bufs) && (0 == u1_num_gaps)) |
1040 | 523 | { |
1041 | 523 | UWORD32 i4_error_code; |
1042 | 523 | i4_error_code = ERROR_DBP_MANAGER_T; |
1043 | 523 | return i4_error_code; |
1044 | 523 | } |
1045 | | |
1046 | | // Chase the links to reach the last but one picNum, if available |
1047 | 5.40k | ps_next_dpb = ps_dpb_mgr->ps_dpb_st_head; |
1048 | | |
1049 | 5.40k | if(ps_dpb_mgr->u1_num_st_ref_bufs > 1) |
1050 | 1.49k | { |
1051 | 1.49k | if(ps_next_dpb->i4_frame_num == (WORD32)u4_cur_pic_num) |
1052 | 404 | { |
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 | 404 | u1_new_node_flag = 0; |
1058 | 404 | } |
1059 | | |
1060 | 3.36k | for(i = 1; i < (ps_dpb_mgr->u1_num_st_ref_bufs - 1); i++) |
1061 | 1.86k | { |
1062 | 1.86k | 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 | 1.86k | if(ps_next_dpb->i4_frame_num == (WORD32)u4_cur_pic_num) |
1069 | 442 | { |
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 | 442 | u1_new_node_flag = 0; |
1075 | 442 | } |
1076 | 1.86k | ps_next_dpb = ps_next_dpb->ps_prev_short; |
1077 | 1.86k | } |
1078 | | |
1079 | 1.49k | if(ps_next_dpb->ps_prev_short->ps_prev_short != NULL) |
1080 | 36 | { |
1081 | 36 | UWORD32 i4_error_code; |
1082 | 36 | i4_error_code = ERROR_DBP_MANAGER_T; |
1083 | 36 | return i4_error_code; |
1084 | 36 | } |
1085 | | |
1086 | 1.46k | if(u1_new_node_flag) |
1087 | 1.02k | { |
1088 | 1.02k | if(u1_num_gaps) |
1089 | 65 | { |
1090 | 65 | ret = ih264d_delete_gap_frm_sliding(ps_dpb_mgr, |
1091 | 65 | ps_next_dpb->ps_prev_short->i4_frame_num, |
1092 | 65 | &u1_del_node); |
1093 | 65 | if(ret != OK) |
1094 | 0 | return ret; |
1095 | 65 | } |
1096 | | |
1097 | 1.02k | if(u1_del_node) |
1098 | 992 | { |
1099 | 992 | ps_dpb_mgr->u1_num_st_ref_bufs--; |
1100 | 992 | ps_next_dpb->ps_prev_short->u1_used_as_ref = |
1101 | 992 | UNUSED_FOR_REF; |
1102 | 992 | ps_next_dpb->ps_prev_short->s_top_field.u1_reference_info = |
1103 | 992 | UNUSED_FOR_REF; |
1104 | 992 | ps_next_dpb->ps_prev_short->s_bot_field.u1_reference_info = |
1105 | 992 | UNUSED_FOR_REF; |
1106 | 992 | ih264d_free_ref_pic_mv_bufs(ps_dpb_mgr->pv_codec_handle, |
1107 | 992 | ps_next_dpb->ps_prev_short->u1_buf_id); |
1108 | 992 | ps_next_dpb->ps_prev_short->ps_pic_buf = NULL; |
1109 | 992 | ps_next_dpb->ps_prev_short = NULL; |
1110 | 992 | } |
1111 | 1.02k | } |
1112 | 1.46k | } |
1113 | 3.90k | else |
1114 | 3.90k | { |
1115 | 3.90k | if(ps_dpb_mgr->u1_num_st_ref_bufs) |
1116 | 3.48k | { |
1117 | 3.48k | ret = ih264d_delete_gap_frm_sliding(ps_dpb_mgr, |
1118 | 3.48k | ps_next_dpb->i4_frame_num, |
1119 | 3.48k | &u1_del_node); |
1120 | 3.48k | if(ret != OK) |
1121 | 0 | return ret; |
1122 | 3.48k | if((ps_next_dpb->i4_frame_num != (WORD32)u4_cur_pic_num) |
1123 | 3.48k | && u1_del_node) |
1124 | 822 | { |
1125 | 822 | ps_dpb_mgr->u1_num_st_ref_bufs--; |
1126 | 822 | ps_next_dpb->u1_used_as_ref = FALSE; |
1127 | 822 | ps_next_dpb->s_top_field.u1_reference_info = |
1128 | 822 | UNUSED_FOR_REF; |
1129 | 822 | ps_next_dpb->s_bot_field.u1_reference_info = |
1130 | 822 | UNUSED_FOR_REF; |
1131 | 822 | ih264d_free_ref_pic_mv_bufs(ps_dpb_mgr->pv_codec_handle, |
1132 | 822 | ps_next_dpb->u1_buf_id); |
1133 | 822 | ps_next_dpb->ps_pic_buf = NULL; |
1134 | 822 | ps_next_dpb->ps_prev_short = NULL; |
1135 | 822 | ps_dpb_mgr->ps_dpb_st_head = NULL; |
1136 | 822 | ps_next_dpb = NULL; |
1137 | 822 | } |
1138 | 2.65k | else if(ps_next_dpb->i4_frame_num == (WORD32)u4_cur_pic_num) |
1139 | 2.57k | { |
1140 | 2.57k | if(u1_curr_pic_in_err) |
1141 | 0 | { |
1142 | 0 | u1_insert_st_pic = 0; |
1143 | 0 | } |
1144 | 2.57k | else if(ps_dpb_mgr->u1_num_st_ref_bufs > 0) |
1145 | 2.57k | { |
1146 | 2.57k | ps_dpb_mgr->u1_num_st_ref_bufs--; |
1147 | 2.57k | ps_next_dpb->u1_used_as_ref = FALSE; |
1148 | 2.57k | ps_next_dpb->s_top_field.u1_reference_info = |
1149 | 2.57k | UNUSED_FOR_REF; |
1150 | 2.57k | ps_next_dpb->s_bot_field.u1_reference_info = |
1151 | 2.57k | UNUSED_FOR_REF; |
1152 | 2.57k | ih264d_free_ref_pic_mv_bufs(ps_dpb_mgr->pv_codec_handle, |
1153 | 2.57k | ps_next_dpb->u1_buf_id); |
1154 | 2.57k | ps_next_dpb->ps_pic_buf = NULL; |
1155 | 2.57k | ps_next_dpb = NULL; |
1156 | 2.57k | } |
1157 | 2.57k | } |
1158 | 3.48k | } |
1159 | 423 | else |
1160 | 423 | { |
1161 | 423 | ret = ih264d_delete_gap_frm_sliding(ps_dpb_mgr, |
1162 | 423 | INVALID_FRAME_NUM, |
1163 | 423 | &u1_del_node); |
1164 | 423 | if(ret != OK) |
1165 | 12 | return ret; |
1166 | 411 | if(u1_del_node) |
1167 | 25 | { |
1168 | 25 | UWORD32 i4_error_code; |
1169 | 25 | i4_error_code = ERROR_DBP_MANAGER_T; |
1170 | 25 | return i4_error_code; |
1171 | 25 | } |
1172 | 411 | } |
1173 | 3.90k | } |
1174 | 5.40k | } |
1175 | 14.1k | } |
1176 | 7.40k | else |
1177 | 7.40k | { |
1178 | | //Adaptive memory control - implements 8.2.5.4 |
1179 | 7.40k | UWORD32 u4_mmco; |
1180 | 7.40k | UWORD32 u4_diff_pic_num; |
1181 | 7.40k | WORD32 i4_pic_num; |
1182 | 7.40k | UWORD32 u4_lt_idx; |
1183 | 7.40k | WORD32 j; |
1184 | 7.40k | struct MMCParams *ps_mmc_params; |
1185 | | |
1186 | 46.2k | for(j = 0; j < ps_dpb_cmds->u1_num_of_commands; j++) |
1187 | 40.9k | { |
1188 | 40.9k | ps_mmc_params = &ps_dpb_cmds->as_mmc_params[j]; |
1189 | 40.9k | u4_mmco = ps_mmc_params->u4_mmco; //Get MMCO |
1190 | | |
1191 | 40.9k | switch(u4_mmco) |
1192 | 40.9k | { |
1193 | 3.87k | case MARK_ST_PICNUM_AS_NONREF: |
1194 | 3.87k | { |
1195 | | |
1196 | 3.87k | { |
1197 | 3.87k | UWORD32 i4_cur_pic_num = u4_cur_pic_num; |
1198 | 3.87k | WORD64 i8_pic_num; |
1199 | 3.87k | u4_diff_pic_num = ps_mmc_params->u4_diff_pic_num; //Get absDiffPicnumMinus1 |
1200 | 3.87k | if(u1_fld_pic_flag) |
1201 | 851 | i4_cur_pic_num = i4_cur_pic_num * 2 + 1; |
1202 | 3.87k | i8_pic_num = ((WORD64)i4_cur_pic_num - ((WORD64)u4_diff_pic_num + 1)); |
1203 | 3.87k | if(IS_OUT_OF_RANGE_S32(i8_pic_num)) |
1204 | 264 | { |
1205 | 264 | return ERROR_DBP_MANAGER_T; |
1206 | 264 | } |
1207 | 3.61k | i4_pic_num = i8_pic_num; |
1208 | 3.61k | } |
1209 | | |
1210 | 3.61k | if(ps_dpb_mgr->u1_num_st_ref_bufs > 0) |
1211 | 1.07k | { |
1212 | 1.07k | ret = ih264d_delete_st_node_or_make_lt(ps_dpb_mgr, |
1213 | 1.07k | i4_pic_num, |
1214 | 1.07k | MAX_REF_BUFS + 1, |
1215 | 1.07k | u1_fld_pic_flag); |
1216 | 1.07k | if(ret != OK) |
1217 | 512 | return ret; |
1218 | 1.07k | } |
1219 | 2.53k | else |
1220 | 2.53k | { |
1221 | 2.53k | UWORD8 u1_dummy; |
1222 | 2.53k | ret = ih264d_delete_gap_frm_mmco(ps_dpb_mgr, i4_pic_num, &u1_dummy); |
1223 | 2.53k | if(ret != OK) |
1224 | 44 | return ret; |
1225 | 2.53k | } |
1226 | 3.05k | break; |
1227 | 3.61k | } |
1228 | 3.05k | case MARK_LT_INDEX_AS_NONREF: |
1229 | 2.67k | { |
1230 | 2.67k | WORD32 i4_status; |
1231 | 2.67k | u4_lt_idx = ps_mmc_params->u4_lt_idx; //Get long term index |
1232 | 2.67k | ret = ih264d_delete_lt_node(ps_dpb_mgr, |
1233 | 2.67k | u4_lt_idx, |
1234 | 2.67k | u1_fld_pic_flag, |
1235 | 2.67k | 0, &i4_status); |
1236 | 2.67k | if(ret != OK) |
1237 | 0 | return ret; |
1238 | 2.67k | if(i4_status) |
1239 | 113 | { |
1240 | 113 | UWORD32 i4_error_code; |
1241 | 113 | i4_error_code = ERROR_DBP_MANAGER_T; |
1242 | 113 | return i4_error_code; |
1243 | 113 | } |
1244 | 2.56k | break; |
1245 | 2.67k | } |
1246 | | |
1247 | 2.56k | case MARK_ST_PICNUM_AS_LT_INDEX: |
1248 | 1.89k | { |
1249 | 1.89k | { |
1250 | 1.89k | UWORD32 i4_cur_pic_num = u4_cur_pic_num; |
1251 | 1.89k | WORD64 i8_pic_num; |
1252 | 1.89k | u4_diff_pic_num = ps_mmc_params->u4_diff_pic_num; //Get absDiffPicnumMinus1 |
1253 | 1.89k | if(u1_fld_pic_flag) |
1254 | 355 | i4_cur_pic_num = i4_cur_pic_num * 2 + 1; |
1255 | | |
1256 | 1.89k | i8_pic_num = (WORD64)i4_cur_pic_num - ((WORD64)u4_diff_pic_num + 1); |
1257 | 1.89k | if(IS_OUT_OF_RANGE_S32(i8_pic_num)) |
1258 | 135 | { |
1259 | 135 | return ERROR_DBP_MANAGER_T; |
1260 | 135 | } |
1261 | 1.75k | i4_pic_num = i8_pic_num; |
1262 | 1.75k | } |
1263 | | |
1264 | 0 | u4_lt_idx = ps_mmc_params->u4_lt_idx; //Get long term index |
1265 | | |
1266 | 1.75k | if((ps_dpb_mgr->u1_max_lt_frame_idx == NO_LONG_TERM_INDICIES) || |
1267 | 1.75k | (u4_lt_idx > ps_dpb_mgr->u1_max_lt_frame_idx)) |
1268 | 459 | { |
1269 | 459 | return ERROR_DBP_MANAGER_T; |
1270 | 459 | } |
1271 | | |
1272 | 1.29k | if(ps_dpb_mgr->u1_num_st_ref_bufs > 0) |
1273 | 412 | { |
1274 | 412 | ret = ih264d_delete_st_node_or_make_lt(ps_dpb_mgr, |
1275 | 412 | i4_pic_num, u4_lt_idx, |
1276 | 412 | u1_fld_pic_flag); |
1277 | 412 | if(ret != OK) |
1278 | 141 | return ret; |
1279 | 412 | } |
1280 | 1.15k | break; |
1281 | 1.29k | } |
1282 | 12.4k | case SET_MAX_LT_INDEX: |
1283 | 12.4k | { |
1284 | 12.4k | UWORD8 uc_numLT = ps_dpb_mgr->u1_num_lt_ref_bufs; |
1285 | 12.4k | u4_lt_idx = ps_mmc_params->u4_max_lt_idx_plus1; //Get Max_long_term_index_plus1 |
1286 | 12.4k | if(u4_lt_idx <= ps_dpb_mgr->u1_max_lt_frame_idx |
1287 | 12.4k | && uc_numLT > 0) |
1288 | 2.00k | { |
1289 | 2.00k | struct dpb_info_t *ps_nxtDPB; |
1290 | | //Set all LT buffers with index >= u4_lt_idx to nonreference |
1291 | 2.00k | ps_nxtDPB = ps_dpb_mgr->ps_dpb_ht_head; |
1292 | 2.00k | ps_next_dpb = ps_nxtDPB->ps_prev_long; |
1293 | 2.00k | if(ps_nxtDPB->u1_lt_idx >= u4_lt_idx) |
1294 | 727 | { |
1295 | 727 | i = 0; |
1296 | 727 | ps_dpb_mgr->ps_dpb_ht_head = NULL; |
1297 | 727 | } |
1298 | 1.27k | else |
1299 | 1.27k | { |
1300 | 1.66k | for(i = 1; i < uc_numLT; i++) |
1301 | 1.00k | { |
1302 | 1.00k | if(ps_next_dpb->u1_lt_idx >= u4_lt_idx) |
1303 | 620 | break; |
1304 | 383 | ps_nxtDPB = ps_next_dpb; |
1305 | 383 | ps_next_dpb = ps_next_dpb->ps_prev_long; |
1306 | 383 | } |
1307 | 1.27k | ps_nxtDPB->ps_prev_long = NULL; //Terminate the link of the closest LTIndex that is <=Max |
1308 | 1.27k | } |
1309 | 2.00k | ps_dpb_mgr->u1_num_lt_ref_bufs = i; |
1310 | 2.00k | if(i == 0) |
1311 | 727 | ps_next_dpb = ps_nxtDPB; |
1312 | | |
1313 | 3.47k | for(; i < uc_numLT; i++) |
1314 | 1.47k | { |
1315 | 1.47k | ps_nxtDPB = ps_next_dpb; |
1316 | 1.47k | ps_nxtDPB->u1_lt_idx = MAX_REF_BUFS + 1; |
1317 | 1.47k | ps_nxtDPB->u1_used_as_ref = UNUSED_FOR_REF; |
1318 | 1.47k | ps_nxtDPB->s_top_field.u1_reference_info = |
1319 | 1.47k | UNUSED_FOR_REF; |
1320 | 1.47k | ps_nxtDPB->s_bot_field.u1_reference_info = |
1321 | 1.47k | UNUSED_FOR_REF; |
1322 | | |
1323 | 1.47k | ps_nxtDPB->ps_pic_buf = NULL; |
1324 | | //Release buffer |
1325 | 1.47k | ih264d_free_ref_pic_mv_bufs(ps_dpb_mgr->pv_codec_handle, |
1326 | 1.47k | ps_nxtDPB->u1_buf_id); |
1327 | 1.47k | ps_next_dpb = ps_nxtDPB->ps_prev_long; |
1328 | 1.47k | ps_nxtDPB->ps_prev_long = NULL; |
1329 | 1.47k | } |
1330 | 2.00k | } |
1331 | 12.4k | if(u4_lt_idx == 0) |
1332 | 954 | { |
1333 | 954 | ps_dpb_mgr->u1_max_lt_frame_idx = NO_LONG_TERM_INDICIES; |
1334 | 954 | } |
1335 | 11.5k | else |
1336 | 11.5k | { |
1337 | 11.5k | ps_dpb_mgr->u1_max_lt_frame_idx = u4_lt_idx - 1; |
1338 | 11.5k | } |
1339 | | |
1340 | 12.4k | break; |
1341 | 1.29k | } |
1342 | 4.03k | case SET_LT_INDEX: |
1343 | 4.03k | { |
1344 | 4.03k | u4_lt_idx = ps_mmc_params->u4_lt_idx; //Get long term index |
1345 | 4.03k | if((ps_dpb_mgr->u1_max_lt_frame_idx == NO_LONG_TERM_INDICIES) || |
1346 | 4.03k | (u4_lt_idx > ps_dpb_mgr->u1_max_lt_frame_idx)) |
1347 | 290 | { |
1348 | 290 | return ERROR_DBP_MANAGER_T; |
1349 | 290 | } |
1350 | 3.74k | ret = ih264d_insert_st_node(ps_dpb_mgr, ps_pic_buf, u1_buf_id, |
1351 | 3.74k | u4_cur_pic_num); |
1352 | 3.74k | if(ret != OK) |
1353 | 104 | return ret; |
1354 | | |
1355 | 3.64k | if(ps_dpb_mgr->u1_num_st_ref_bufs > 0) |
1356 | | |
1357 | 3.62k | { |
1358 | 3.62k | ret = ih264d_delete_st_node_or_make_lt(ps_dpb_mgr, |
1359 | 3.62k | u4_cur_pic_num, |
1360 | 3.62k | u4_lt_idx, |
1361 | 3.62k | u1_fld_pic_flag); |
1362 | 3.62k | if(ret != OK) |
1363 | 21 | return ret; |
1364 | 3.62k | } |
1365 | 16 | else |
1366 | 16 | { |
1367 | 16 | return ERROR_DBP_MANAGER_T; |
1368 | 16 | } |
1369 | | |
1370 | 3.60k | u1_marked_lt = 1; |
1371 | 3.60k | break; |
1372 | 3.64k | } |
1373 | | |
1374 | 16.0k | default: |
1375 | 16.0k | break; |
1376 | 40.9k | } |
1377 | 38.8k | if(u4_mmco == RESET_REF_PICTURES || u4_mmco == RESET_ALL_PICTURES) |
1378 | 3.63k | { |
1379 | 3.63k | ih264d_reset_ref_bufs(ps_dpb_mgr); |
1380 | 3.63k | u4_cur_pic_num = 0; |
1381 | 3.63k | } |
1382 | 38.8k | } |
1383 | 7.40k | } |
1384 | 18.8k | if(!u1_marked_lt && u1_insert_st_pic) |
1385 | 17.0k | { |
1386 | 17.0k | ret = ih264d_insert_st_node(ps_dpb_mgr, ps_pic_buf, u1_buf_id, |
1387 | 17.0k | u4_cur_pic_num); |
1388 | 17.0k | if(ret != OK) |
1389 | 420 | return ret; |
1390 | 17.0k | } |
1391 | 18.4k | return OK; |
1392 | 18.8k | } |
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 | 1 | { |
1418 | 1 | WORD8 i; |
1419 | 1 | dec_struct_t *ps_dec = (dec_struct_t *)pv_dec; |
1420 | | |
1421 | 19 | for(i = 0; i < u1_disp_bufs; i++) |
1422 | 18 | { |
1423 | 18 | ih264_buf_mgr_release((buf_mgr_t *)ps_dec->pv_pic_buf_mgr, |
1424 | 18 | i, |
1425 | 18 | BUF_MGR_REF); |
1426 | 18 | ih264_buf_mgr_release((buf_mgr_t *)ps_dec->pv_mv_buf_mgr, |
1427 | 18 | ps_dec->as_buf_id_info_map[i].mv_buf_id, |
1428 | 18 | BUF_MGR_REF); |
1429 | 18 | } |
1430 | 1 | } |
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 | 1.51M | { |
1461 | 1.51M | WORD8 i1_gap_idx, i, j, j_min; |
1462 | 1.51M | WORD32 *pi4_gaps_start_frm_num, *pi4_gaps_end_frm_num, i4_gap_frame_num; |
1463 | 1.51M | WORD32 i4_start_frm_num, i4_end_frm_num; |
1464 | 1.51M | WORD32 i4_max_frm_num; |
1465 | 1.51M | 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 | 1.51M | *pu1_del_node = 1; |
1470 | 1.51M | if(0 == ps_dpb_mgr->u1_num_gaps) |
1471 | 3.28k | return OK; |
1472 | 1.50M | pi4_gaps_start_frm_num = ps_dpb_mgr->ai4_gaps_start_frm_num; |
1473 | 1.50M | pi4_gaps_end_frm_num = ps_dpb_mgr->ai4_gaps_end_frm_num; |
1474 | 1.50M | i4_gap_frame_num = INVALID_FRAME_NUM; |
1475 | 1.50M | i4_max_frm_num = ps_dpb_mgr->i4_max_frm_num; |
1476 | | |
1477 | 1.50M | i1_gap_idx = -1; |
1478 | 1.50M | if(INVALID_FRAME_NUM != i4_frame_num) |
1479 | 433k | { |
1480 | 433k | i4_gap_frame_num = i4_frame_num; |
1481 | 7.36M | for(i = 0; i < MAX_FRAMES; i++) |
1482 | 6.93M | { |
1483 | 6.93M | i4_start_frm_num = pi4_gaps_start_frm_num[i]; |
1484 | 6.93M | if(INVALID_FRAME_NUM != i4_start_frm_num) |
1485 | 626k | { |
1486 | 626k | i4_end_frm_num = pi4_gaps_end_frm_num[i]; |
1487 | 626k | if(i4_end_frm_num < i4_max_frm_num) |
1488 | 626k | { |
1489 | 626k | if(i4_start_frm_num <= i4_gap_frame_num) |
1490 | 621k | { |
1491 | 621k | i4_gap_frame_num = i4_start_frm_num; |
1492 | 621k | i1_gap_idx = i; |
1493 | 621k | } |
1494 | 626k | } |
1495 | 278 | else |
1496 | 278 | { |
1497 | 278 | if(((i4_start_frm_num <= i4_gap_frame_num) |
1498 | 278 | && (i4_gap_frame_num <= i4_max_frm_num)) |
1499 | 278 | || ((i4_start_frm_num >= i4_gap_frame_num) |
1500 | 111 | && ((i4_gap_frame_num |
1501 | 90 | + i4_max_frm_num) |
1502 | 90 | >= i4_end_frm_num))) |
1503 | 203 | { |
1504 | 203 | i4_gap_frame_num = i4_start_frm_num; |
1505 | 203 | i1_gap_idx = i; |
1506 | 203 | } |
1507 | 278 | } |
1508 | 626k | } |
1509 | 6.93M | } |
1510 | 433k | } |
1511 | 1.07M | else |
1512 | 1.07M | { |
1513 | | /* no valid short term buffers, delete one gap from the least start */ |
1514 | | /* of gap sequence */ |
1515 | 1.07M | i4_gap_frame_num = pi4_gaps_start_frm_num[0]; |
1516 | 1.07M | i1_gap_idx = 0; |
1517 | 17.1M | for(i = 1; i < MAX_FRAMES; i++) |
1518 | 16.1M | { |
1519 | 16.1M | if(INVALID_FRAME_NUM != pi4_gaps_start_frm_num[i]) |
1520 | 1.02M | { |
1521 | 1.02M | if(pi4_gaps_start_frm_num[i] < i4_gap_frame_num) |
1522 | 579k | { |
1523 | 579k | i4_gap_frame_num = pi4_gaps_start_frm_num[i]; |
1524 | 579k | i1_gap_idx = i; |
1525 | 579k | } |
1526 | 1.02M | } |
1527 | 16.1M | } |
1528 | 1.07M | if(INVALID_FRAME_NUM == i4_gap_frame_num) |
1529 | 329 | { |
1530 | 329 | UWORD32 i4_error_code; |
1531 | 329 | i4_error_code = ERROR_DBP_MANAGER_T; |
1532 | 329 | return i4_error_code; |
1533 | 329 | } |
1534 | 1.07M | } |
1535 | | |
1536 | 1.50M | if(-1 != i1_gap_idx) |
1537 | 1.50M | { |
1538 | | /* find least frame_num in the poc_map, which is in this range */ |
1539 | 1.50M | i4_start_frm_num = pi4_gaps_start_frm_num[i1_gap_idx]; |
1540 | 1.50M | if(i4_start_frm_num < 0) |
1541 | 3.68k | i4_start_frm_num += i4_max_frm_num; |
1542 | 1.50M | i4_end_frm_num = pi4_gaps_end_frm_num[i1_gap_idx]; |
1543 | 1.50M | if(i4_end_frm_num < 0) |
1544 | 9.84k | i4_end_frm_num += i4_max_frm_num; |
1545 | | |
1546 | 1.50M | i4_gap_frm_num_min = 0xfffffff; |
1547 | 1.50M | j_min = MAX_FRAMES; |
1548 | 25.6M | for(j = 0; j < MAX_FRAMES; j++) |
1549 | 24.0M | { |
1550 | 24.0M | i4_frm_num = ps_dpb_mgr->ai4_poc_buf_id_map[j][2]; |
1551 | 24.0M | if((i4_start_frm_num <= i4_frm_num) |
1552 | 24.0M | && (i4_end_frm_num >= i4_frm_num)) |
1553 | 6.34M | { |
1554 | 6.34M | if(i4_frm_num < i4_gap_frm_num_min) |
1555 | 2.95M | { |
1556 | 2.95M | j_min = j; |
1557 | 2.95M | i4_gap_frm_num_min = i4_frm_num; |
1558 | 2.95M | } |
1559 | 6.34M | } |
1560 | 24.0M | } |
1561 | | |
1562 | 1.50M | if(j_min != MAX_FRAMES) |
1563 | 1.50M | { |
1564 | | |
1565 | 1.50M | ps_dpb_mgr->ai4_poc_buf_id_map[j_min][0] = -1; |
1566 | 1.50M | ps_dpb_mgr->ai4_poc_buf_id_map[j_min][1] = 0x7fffffff; |
1567 | 1.50M | ps_dpb_mgr->ai4_poc_buf_id_map[j_min][2] = GAP_FRAME_NUM; |
1568 | 1.50M | ps_dpb_mgr->i1_gaps_deleted++; |
1569 | | |
1570 | 1.50M | ps_dpb_mgr->ai1_gaps_per_seq[i1_gap_idx]--; |
1571 | 1.50M | ps_dpb_mgr->u1_num_gaps--; |
1572 | 1.50M | *pu1_del_node = 0; |
1573 | 1.50M | if(0 == ps_dpb_mgr->ai1_gaps_per_seq[i1_gap_idx]) |
1574 | 1.97k | { |
1575 | 1.97k | ps_dpb_mgr->ai4_gaps_start_frm_num[i1_gap_idx] = |
1576 | 1.97k | INVALID_FRAME_NUM; |
1577 | 1.97k | ps_dpb_mgr->ai4_gaps_end_frm_num[i1_gap_idx] = 0; |
1578 | 1.97k | } |
1579 | 1.50M | } |
1580 | 1.50M | } |
1581 | | |
1582 | 1.50M | return OK; |
1583 | 1.50M | } |
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 | 2.77k | { |
1615 | 2.77k | WORD8 i, j; |
1616 | 2.77k | WORD32 *pi4_start, *pi4_end; |
1617 | 2.77k | 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 | 2.77k | *pu1_del_node = 1; |
1622 | 2.77k | pi4_start = ps_dpb_mgr->ai4_gaps_start_frm_num; |
1623 | 2.77k | pi4_end = ps_dpb_mgr->ai4_gaps_end_frm_num; |
1624 | 2.77k | i4_max_frm_num = ps_dpb_mgr->i4_max_frm_num; |
1625 | | |
1626 | 2.77k | if(0 == ps_dpb_mgr->u1_num_gaps) |
1627 | 2.36k | return OK; |
1628 | | |
1629 | 414 | if(i4_frame_num < 0) |
1630 | 143 | i4_frame_num += i4_max_frm_num; |
1631 | 1.86k | for(i = 0; i < MAX_FRAMES; i++) |
1632 | 1.79k | { |
1633 | 1.79k | i4_start_frm_num = pi4_start[i]; |
1634 | 1.79k | if(i4_start_frm_num < 0) |
1635 | 487 | i4_start_frm_num += i4_max_frm_num; |
1636 | 1.79k | if(INVALID_FRAME_NUM != i4_start_frm_num) |
1637 | 738 | { |
1638 | 738 | i4_end_frm_num = pi4_end[i]; |
1639 | 738 | if(i4_end_frm_num < 0) |
1640 | 498 | i4_end_frm_num += i4_max_frm_num; |
1641 | | |
1642 | 738 | if((i4_frame_num >= i4_start_frm_num) |
1643 | 738 | && (i4_frame_num <= i4_end_frm_num)) |
1644 | 341 | { |
1645 | 341 | break; |
1646 | 341 | } |
1647 | 397 | else |
1648 | 397 | { |
1649 | 397 | if(((i4_frame_num + i4_max_frm_num) >= i4_start_frm_num) |
1650 | 397 | && ((i4_frame_num + i4_max_frm_num) |
1651 | 393 | <= i4_end_frm_num)) |
1652 | 4 | { |
1653 | 4 | UWORD32 i4_error_code; |
1654 | 4 | i4_error_code = ERROR_DBP_MANAGER_T; |
1655 | 4 | return i4_error_code; |
1656 | 4 | } |
1657 | 397 | } |
1658 | 738 | } |
1659 | 1.79k | } |
1660 | | |
1661 | | /* find frame_num index, in the poc_map which needs to be deleted */ |
1662 | 2.79k | for(j = 0; j < MAX_FRAMES; j++) |
1663 | 2.71k | { |
1664 | 2.71k | if(i4_frame_num == ps_dpb_mgr->ai4_poc_buf_id_map[j][2]) |
1665 | 325 | break; |
1666 | 2.71k | } |
1667 | | |
1668 | 410 | if(MAX_FRAMES != i) |
1669 | 341 | { |
1670 | 341 | if(j == MAX_FRAMES) |
1671 | 42 | { |
1672 | 42 | UWORD32 i4_error_code; |
1673 | 42 | i4_error_code = ERROR_DBP_MANAGER_T; |
1674 | 42 | return i4_error_code; |
1675 | 42 | } |
1676 | | |
1677 | 299 | ps_dpb_mgr->ai4_poc_buf_id_map[j][0] = -1; |
1678 | 299 | ps_dpb_mgr->ai4_poc_buf_id_map[j][1] = 0x7fffffff; |
1679 | 299 | ps_dpb_mgr->ai4_poc_buf_id_map[j][2] = GAP_FRAME_NUM; |
1680 | 299 | ps_dpb_mgr->i1_gaps_deleted++; |
1681 | | |
1682 | 299 | ps_dpb_mgr->ai1_gaps_per_seq[i]--; |
1683 | 299 | ps_dpb_mgr->u1_num_gaps--; |
1684 | 299 | *pu1_del_node = 0; |
1685 | 299 | if(0 == ps_dpb_mgr->ai1_gaps_per_seq[i]) |
1686 | 7 | { |
1687 | 7 | ps_dpb_mgr->ai4_gaps_start_frm_num[i] = INVALID_FRAME_NUM; |
1688 | 7 | ps_dpb_mgr->ai4_gaps_end_frm_num[i] = 0; |
1689 | 7 | } |
1690 | 299 | } |
1691 | 69 | else |
1692 | 69 | { |
1693 | 69 | UWORD32 i4_error_code; |
1694 | 69 | i4_error_code = ERROR_DBP_MANAGER_T; |
1695 | 69 | return i4_error_code; |
1696 | 69 | } |
1697 | | |
1698 | 299 | return OK; |
1699 | 410 | } |
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 | 1.51M | { |
1720 | 1.51M | struct dpb_info_t *ps_next_dpb; |
1721 | 1.51M | UWORD8 u1_num_gaps; |
1722 | 1.51M | UWORD8 u1_st_ref_bufs, u1_lt_ref_bufs, u1_del_node; |
1723 | 1.51M | WORD8 i; |
1724 | 1.51M | WORD32 i4_frame_gaps = 1; |
1725 | 1.51M | WORD32 ret; |
1726 | | |
1727 | | //Sliding window - implements 8.2.5.3, flush out buffers |
1728 | 1.51M | u1_st_ref_bufs = ps_dpb_mgr->u1_num_st_ref_bufs; |
1729 | 1.51M | u1_lt_ref_bufs = ps_dpb_mgr->u1_num_lt_ref_bufs; |
1730 | | |
1731 | 3.02M | while(1) |
1732 | 3.02M | { |
1733 | 3.02M | u1_num_gaps = ps_dpb_mgr->u1_num_gaps; |
1734 | 3.02M | if((u1_st_ref_bufs + u1_lt_ref_bufs + u1_num_gaps + i4_frame_gaps) |
1735 | 3.02M | > u1_num_ref_frames) |
1736 | 1.51M | { |
1737 | 1.51M | if(0 == (u1_st_ref_bufs + u1_num_gaps)) |
1738 | 3.11k | { |
1739 | 3.11k | i4_frame_gaps = 0; |
1740 | 3.11k | ps_dpb_mgr->u1_num_gaps = (u1_num_ref_frames |
1741 | 3.11k | - u1_lt_ref_bufs); |
1742 | 3.11k | } |
1743 | 1.50M | else |
1744 | 1.50M | { |
1745 | 1.50M | u1_del_node = 1; |
1746 | 1.50M | ps_next_dpb = ps_dpb_mgr->ps_dpb_st_head; |
1747 | | |
1748 | 1.50M | if(u1_st_ref_bufs > 1) |
1749 | 766 | { |
1750 | 1.05k | for(i = 1; i < (u1_st_ref_bufs - 1); i++) |
1751 | 285 | { |
1752 | 285 | 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 | 285 | ps_next_dpb = ps_next_dpb->ps_prev_short; |
1759 | 285 | } |
1760 | | |
1761 | 766 | if(ps_next_dpb->ps_prev_short->ps_prev_short != NULL) |
1762 | 22 | { |
1763 | 22 | return ERROR_DBP_MANAGER_T; |
1764 | 22 | } |
1765 | | |
1766 | 744 | if(u1_num_gaps) |
1767 | 683 | { |
1768 | 683 | ret = ih264d_delete_gap_frm_sliding(ps_dpb_mgr, |
1769 | 683 | ps_next_dpb->ps_prev_short->i4_frame_num, |
1770 | 683 | &u1_del_node); |
1771 | 683 | if(ret != OK) |
1772 | 0 | return ret; |
1773 | 683 | } |
1774 | | |
1775 | 744 | if(u1_del_node) |
1776 | 288 | { |
1777 | 288 | u1_st_ref_bufs--; |
1778 | 288 | ps_next_dpb->ps_prev_short->u1_used_as_ref = |
1779 | 288 | UNUSED_FOR_REF; |
1780 | 288 | ps_next_dpb->ps_prev_short->s_top_field.u1_reference_info = |
1781 | 288 | UNUSED_FOR_REF; |
1782 | 288 | ps_next_dpb->ps_prev_short->s_bot_field.u1_reference_info = |
1783 | 288 | UNUSED_FOR_REF; |
1784 | 288 | ih264d_free_ref_pic_mv_bufs(ps_dpb_mgr->pv_codec_handle, |
1785 | 288 | ps_next_dpb->ps_prev_short->u1_buf_id); |
1786 | 288 | ps_next_dpb->ps_prev_short->ps_pic_buf = NULL; |
1787 | 288 | ps_next_dpb->ps_prev_short = NULL; |
1788 | 288 | } |
1789 | 744 | } |
1790 | 1.50M | else |
1791 | 1.50M | { |
1792 | 1.50M | if(u1_st_ref_bufs) |
1793 | 433k | { |
1794 | 433k | if(u1_num_gaps) |
1795 | 432k | { |
1796 | 432k | ret = ih264d_delete_gap_frm_sliding(ps_dpb_mgr, |
1797 | 432k | ps_next_dpb->i4_frame_num, |
1798 | 432k | &u1_del_node); |
1799 | 432k | if(ret != OK) |
1800 | 0 | return ret; |
1801 | 432k | } |
1802 | | |
1803 | 433k | if(u1_del_node) |
1804 | 1.66k | { |
1805 | 1.66k | u1_st_ref_bufs--; |
1806 | 1.66k | ps_next_dpb->u1_used_as_ref = FALSE; |
1807 | 1.66k | ps_next_dpb->s_top_field.u1_reference_info = |
1808 | 1.66k | UNUSED_FOR_REF; |
1809 | 1.66k | ps_next_dpb->s_bot_field.u1_reference_info = |
1810 | 1.66k | UNUSED_FOR_REF; |
1811 | 1.66k | ih264d_free_ref_pic_mv_bufs(ps_dpb_mgr->pv_codec_handle, |
1812 | 1.66k | ps_next_dpb->u1_buf_id); |
1813 | 1.66k | ps_next_dpb->ps_pic_buf = NULL; |
1814 | 1.66k | ps_next_dpb = NULL; |
1815 | 1.66k | ps_dpb_mgr->ps_dpb_st_head = NULL; |
1816 | 1.66k | ps_dpb_mgr->u1_num_st_ref_bufs = u1_st_ref_bufs; |
1817 | 1.66k | } |
1818 | 433k | } |
1819 | 1.07M | else |
1820 | 1.07M | { |
1821 | 1.07M | ret = ih264d_delete_gap_frm_sliding(ps_dpb_mgr, |
1822 | 1.07M | INVALID_FRAME_NUM, |
1823 | 1.07M | &u1_del_node); |
1824 | 1.07M | if(ret != OK) |
1825 | 317 | return ret; |
1826 | 1.07M | if(u1_del_node) |
1827 | 812 | { |
1828 | 812 | return ERROR_DBP_MANAGER_T; |
1829 | 812 | } |
1830 | 1.07M | } |
1831 | 1.50M | } |
1832 | 1.50M | } |
1833 | 1.51M | } |
1834 | 1.51M | else |
1835 | 1.51M | { |
1836 | 1.51M | ps_dpb_mgr->u1_num_gaps += i4_frame_gaps; |
1837 | 1.51M | break; |
1838 | 1.51M | } |
1839 | 3.02M | } |
1840 | | |
1841 | 1.51M | ps_dpb_mgr->u1_num_st_ref_bufs = u1_st_ref_bufs; |
1842 | | |
1843 | 1.51M | return OK; |
1844 | 1.51M | } |
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 | 3.32M | { |
2007 | 3.32M | WORD8 i; |
2008 | 3.32M | 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 | 11.7M | for(i = 0; (i < MAX_FRAMES) && ps_dpb_mgr->i1_gaps_deleted; i++) |
2012 | 8.43M | { |
2013 | 8.43M | if(GAP_FRAME_NUM == i4_poc_buf_id_map[i][2]) |
2014 | 1.50M | { |
2015 | 1.50M | ps_dpb_mgr->i1_gaps_deleted--; |
2016 | 1.50M | ps_dpb_mgr->i1_poc_buf_id_entries--; |
2017 | 1.50M | i4_poc_buf_id_map[i][0] = -1; |
2018 | 1.50M | i4_poc_buf_id_map[i][1] = 0x7fffffff; |
2019 | 1.50M | i4_poc_buf_id_map[i][2] = 0; |
2020 | 1.50M | } |
2021 | 8.43M | } |
2022 | 3.32M | } |
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 | 1.68M | { |
2051 | 1.68M | WORD8 i; |
2052 | 1.68M | WORD32 (*i4_poc_buf_id_map)[3] = ps_dpb_mgr->ai4_poc_buf_id_map; |
2053 | | |
2054 | 8.80M | for(i = 0; i < MAX_FRAMES; i++) |
2055 | 8.80M | { |
2056 | | /* Find an empty slot */ |
2057 | 8.80M | if(i4_poc_buf_id_map[i][0] == -1) |
2058 | 1.67M | { |
2059 | 1.67M | if(GAP_FRAME_NUM == i4_poc_buf_id_map[i][2]) |
2060 | 0 | ps_dpb_mgr->i1_gaps_deleted--; |
2061 | 1.67M | else |
2062 | 1.67M | ps_dpb_mgr->i1_poc_buf_id_entries++; |
2063 | | |
2064 | 1.67M | i4_poc_buf_id_map[i][0] = u1_buf_id; |
2065 | 1.67M | i4_poc_buf_id_map[i][1] = i4_display_poc; |
2066 | 1.67M | i4_poc_buf_id_map[i][2] = u4_frame_num; |
2067 | | |
2068 | 1.67M | break; |
2069 | 1.67M | } |
2070 | 8.80M | } |
2071 | | |
2072 | 1.68M | if(MAX_FRAMES == i) |
2073 | 571 | { |
2074 | | |
2075 | 571 | UWORD32 i4_error_code; |
2076 | 571 | i4_error_code = ERROR_GAPS_IN_FRM_NUM; |
2077 | 571 | return i4_error_code; |
2078 | 571 | } |
2079 | 1.67M | return OK; |
2080 | 1.68M | } |
2081 | | |