1 /*
2 *
3 * Copyright 2015 Rockchip Electronics Co. LTD
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 #define MODULE_TAG "h264d_dpb"
19
20 #include <stdio.h>
21 #include <string.h>
22
23 #include "mpp_common.h"
24 #include "mpp_buf_slot.h"
25
26 #include "h264d_scalist.h"
27 #include "h264d_dpb.h"
28 #include "h264d_init.h"
29
30 #ifndef INT_MIN
31 #define INT_MIN (-2147483647 - 1) /* minimum (signed) int value */
32 #endif
33 #ifndef INT_MAX
34 #define INT_MAX 2147483647 /* maximum (signed) int value */
35 #endif
RoundLog2(RK_S32 iValue)36 static RK_S32 RoundLog2(RK_S32 iValue)
37 {
38 RK_S32 iRet = 0;
39 RK_S32 iValue_square = iValue * iValue;
40
41 while ((1 << (iRet + 1)) <= iValue_square) {
42 ++iRet;
43 }
44 iRet = (iRet + 1) >> 1;
45
46 return iRet;
47 }
48
getDpbSize(H264dVideoCtx_t * p_Vid,H264_SPS_t * active_sps)49 static RK_S32 getDpbSize(H264dVideoCtx_t *p_Vid, H264_SPS_t *active_sps)
50 {
51 RK_S32 size = 0, num_views = 0;
52 RK_S32 pic_size = (active_sps->pic_width_in_mbs_minus1 + 1)
53 * (active_sps->pic_height_in_map_units_minus1 + 1) * (active_sps->frame_mbs_only_flag ? 1 : 2) * 384;
54
55 switch (active_sps->level_idc) {
56 case 9:
57 size = 152064;
58 break;
59 case 10:
60 size = 152064;
61 break;
62 case 11:
63 if (!is_prext_profile(active_sps->profile_idc) && (active_sps->constrained_set3_flag == 1))
64 size = 152064;
65 else
66 size = 345600;
67 break;
68 case 12:
69 size = 912384;
70 break;
71 case 13:
72 size = 912384;
73 break;
74 case 20:
75 size = 912384;
76 break;
77 case 21:
78 size = 1824768;
79 break;
80 case 22:
81 size = 3110400;
82 break;
83 case 30:
84 size = 3110400;
85 break;
86 case 31:
87 size = 6912000;
88 break;
89 case 32:
90 size = 7864320;
91 break;
92 case 40:
93 size = 12582912;
94 break;
95 case 41:
96 size = 12582912;
97 break;
98 case 42:
99 size = 13369344;
100 break;
101 case 50:
102 size = 42393600;
103 break;
104 case 51:
105 size = 70778880;
106 break;
107 case 52:
108 size = 70778880;
109 break;
110 default:
111 size = 0;
112 break;
113 }
114 size /= pic_size;
115 if (p_Vid->active_mvc_sps_flag &&
116 (p_Vid->profile_idc == H264_PROFILE_MVC_HIGH || p_Vid->profile_idc == H264_PROFILE_STEREO_HIGH)) {
117 num_views = p_Vid->active_subsps->num_views_minus1 + 1;
118 size = MPP_MIN(2 * size, MPP_MAX(1, RoundLog2(num_views)) * 16) / num_views;
119 } else {
120 size = MPP_MIN(size, 16);
121 }
122 if (active_sps->vui_parameters_present_flag && active_sps->vui_seq_parameters.bitstream_restriction_flag) {
123 RK_S32 size_vui = 0;
124 if ((RK_S32)active_sps->vui_seq_parameters.max_dec_frame_buffering > size) {
125 H264D_WARNNING("warnnig: max_dec_frame_buffering larger than MaxDpbSize");
126 }
127 size_vui = MPP_MAX(1, active_sps->vui_seq_parameters.max_dec_frame_buffering);
128 if (size_vui < size) {
129 H264D_WARNNING("warning: max_dec_frame_buffering(%d) is less than dpb_size(%d) calculated from Profile/Level.\n", size_vui, size);
130 }
131 size = size_vui;
132 }
133
134 if (size < active_sps->max_num_ref_frames) {
135 H264D_WARNNING("warnning: DPB size is less than max_num_ref_frames, level(%d), pic_size(%d), max_num_ref_frames(%d).\n",
136 active_sps->level_idc, pic_size, active_sps->max_num_ref_frames);
137 size = MPP_MIN(active_sps->max_num_ref_frames, 16);
138 }
139
140 return size;
141 }
142
get_pic_num_x(H264_StorePic_t * p,RK_S32 difference_of_pic_nums_minus1)143 static RK_S32 get_pic_num_x(H264_StorePic_t *p, RK_S32 difference_of_pic_nums_minus1)
144 {
145 RK_S32 currPicNum;
146
147 if (p->structure == FRAME)
148 currPicNum = p->frame_num;
149 else
150 currPicNum = 2 * p->frame_num + 1;
151
152 return currPicNum - (difference_of_pic_nums_minus1 + 1);
153 }
154
unmark_for_reference(H264_DecCtx_t * p_Dec,H264_FrameStore_t * fs)155 static void unmark_for_reference(H264_DecCtx_t *p_Dec, H264_FrameStore_t* fs)
156 {
157 H264_StorePic_t *cur_pic = NULL;
158 if (fs->is_used & 1) {
159 if (fs->top_field) {
160 fs->top_field->used_for_reference = 0;
161 cur_pic = fs->top_field;
162 }
163 }
164 if (fs->is_used & 2) {
165 if (fs->bottom_field) {
166 fs->bottom_field->used_for_reference = 0;
167 cur_pic = fs->bottom_field;
168 }
169 }
170 if (fs->is_used == 3) {
171 if (fs->top_field && fs->bottom_field) {
172 fs->top_field->used_for_reference = 0;
173 fs->bottom_field->used_for_reference = 0;
174 }
175 fs->frame->used_for_reference = 0;
176 cur_pic = fs->frame;
177 }
178 fs->is_reference = 0;
179 (void)cur_pic;
180 (void)p_Dec;
181 }
182
is_short_term_reference(H264_FrameStore_t * fs)183 static RK_U32 is_short_term_reference(H264_FrameStore_t* fs)
184 {
185 if (fs->is_used == 3) { // frame
186 if ((fs->frame->used_for_reference) && (!fs->frame->is_long_term)) {
187 return 1;
188 }
189 }
190
191 if (fs->is_used & 1) { // top field
192 if (fs->top_field) {
193 if ((fs->top_field->used_for_reference) && (!fs->top_field->is_long_term)) {
194 return 1;
195 }
196 }
197 }
198
199 if (fs->is_used & 2) { // bottom field
200 if (fs->bottom_field) {
201 if ((fs->bottom_field->used_for_reference) && (!fs->bottom_field->is_long_term)) {
202 return 1;
203 }
204 }
205 }
206 return 0;
207 }
208
is_long_term_reference(H264_FrameStore_t * fs)209 static RK_U32 is_long_term_reference(H264_FrameStore_t* fs)
210 {
211
212 if (fs->is_used == 3) { // frame
213 if ((fs->frame->used_for_reference) && (fs->frame->is_long_term)) {
214 return 1;
215 }
216 }
217
218 if (fs->is_used & 1) { // top field
219 if (fs->top_field) {
220 if ((fs->top_field->used_for_reference) && (fs->top_field->is_long_term)) {
221 return 1;
222 }
223 }
224 }
225
226 if (fs->is_used & 2) { // bottom field
227 if (fs->bottom_field) {
228 if ((fs->bottom_field->used_for_reference) && (fs->bottom_field->is_long_term)) {
229 return 1;
230 }
231 }
232 }
233 return 0;
234 }
235
unmark_for_long_term_reference(H264_FrameStore_t * fs)236 static void unmark_for_long_term_reference(H264_FrameStore_t* fs)
237 {
238 if (fs->is_used & 1) {
239 if (fs->top_field) {
240 fs->top_field->used_for_reference = 0;
241 fs->top_field->is_long_term = 0;
242 }
243 }
244 if (fs->is_used & 2) {
245 if (fs->bottom_field) {
246 fs->bottom_field->used_for_reference = 0;
247 fs->bottom_field->is_long_term = 0;
248 }
249 }
250 if (fs->is_used == 3) {
251 if (fs->top_field && fs->bottom_field) {
252 fs->top_field->used_for_reference = 0;
253 fs->top_field->is_long_term = 0;
254 fs->bottom_field->used_for_reference = 0;
255 fs->bottom_field->is_long_term = 0;
256 }
257 fs->frame->used_for_reference = 0;
258 fs->frame->is_long_term = 0;
259 }
260
261 fs->is_reference = 0;
262 fs->is_long_term = 0;
263 }
264
mm_unmark_short_term_for_reference(H264_DpbBuf_t * p_Dpb,H264_StorePic_t * p,RK_S32 difference_of_pic_nums_minus1)265 static void mm_unmark_short_term_for_reference(H264_DpbBuf_t *p_Dpb, H264_StorePic_t *p, RK_S32 difference_of_pic_nums_minus1)
266 {
267 RK_S32 picNumX = 0;
268 RK_U32 i = 0;
269
270 picNumX = get_pic_num_x(p, difference_of_pic_nums_minus1);
271
272 for (i = 0; i < p_Dpb->ref_frames_in_buffer; i++) {
273 if (p->structure == FRAME) {
274 if ((p_Dpb->fs_ref[i]->is_reference == 3) && (p_Dpb->fs_ref[i]->is_long_term == 0)) {
275 if (p_Dpb->fs_ref[i]->frame->pic_num == picNumX) {
276 unmark_for_reference(p_Dpb->p_Vid->p_Dec, p_Dpb->fs_ref[i]);
277 return;
278 }
279 }
280 } else {
281 if ((p_Dpb->fs_ref[i]->is_reference & 1) && (!(p_Dpb->fs_ref[i]->is_long_term & 1))) {
282 if (p_Dpb->fs_ref[i]->top_field->pic_num == picNumX) {
283 p_Dpb->fs_ref[i]->top_field->used_for_reference = 0;
284 p_Dpb->fs_ref[i]->is_reference &= 2;
285 if (p_Dpb->fs_ref[i]->is_used == 3) {
286 p_Dpb->fs_ref[i]->frame->used_for_reference = 0;
287 }
288 return;
289 }
290 }
291 if ((p_Dpb->fs_ref[i]->is_reference & 2) && (!(p_Dpb->fs_ref[i]->is_long_term & 2))) {
292 if (p_Dpb->fs_ref[i]->bottom_field->pic_num == picNumX) {
293 p_Dpb->fs_ref[i]->bottom_field->used_for_reference = 0;
294 p_Dpb->fs_ref[i]->is_reference &= 1;
295 if (p_Dpb->fs_ref[i]->is_used == 3) {
296 p_Dpb->fs_ref[i]->frame->used_for_reference = 0;
297 }
298 return;
299 }
300 }
301 }
302 }
303 }
304
mm_unmark_long_term_for_reference(H264_DpbBuf_t * p_Dpb,H264_StorePic_t * p,RK_S32 long_term_pic_num)305 static void mm_unmark_long_term_for_reference(H264_DpbBuf_t *p_Dpb, H264_StorePic_t *p, RK_S32 long_term_pic_num)
306 {
307 RK_U32 i = 0;
308
309 for (i = 0; i < p_Dpb->ltref_frames_in_buffer; i++) {
310 if (p->structure == FRAME) {
311 if ((p_Dpb->fs_ltref[i]->is_reference == 3) && (p_Dpb->fs_ltref[i]->is_long_term == 3)) {
312 if (p_Dpb->fs_ltref[i]->frame->long_term_pic_num == long_term_pic_num) {
313 unmark_for_long_term_reference(p_Dpb->fs_ltref[i]);
314 }
315 }
316 } else {
317 if ((p_Dpb->fs_ltref[i]->is_reference & 1) && ((p_Dpb->fs_ltref[i]->is_long_term & 1))) {
318 if (p_Dpb->fs_ltref[i]->top_field->long_term_pic_num == long_term_pic_num) {
319 p_Dpb->fs_ltref[i]->top_field->used_for_reference = 0;
320 p_Dpb->fs_ltref[i]->top_field->is_long_term = 0;
321 p_Dpb->fs_ltref[i]->is_reference &= 2;
322 p_Dpb->fs_ltref[i]->is_long_term &= 2;
323 if (p_Dpb->fs_ltref[i]->is_used == 3) {
324 p_Dpb->fs_ltref[i]->frame->used_for_reference = 0;
325 p_Dpb->fs_ltref[i]->frame->is_long_term = 0;
326 }
327 return;
328 }
329 }
330 if ((p_Dpb->fs_ltref[i]->is_reference & 2) && ((p_Dpb->fs_ltref[i]->is_long_term & 2))) {
331 if (p_Dpb->fs_ltref[i]->bottom_field->long_term_pic_num == long_term_pic_num) {
332 p_Dpb->fs_ltref[i]->bottom_field->used_for_reference = 0;
333 p_Dpb->fs_ltref[i]->bottom_field->is_long_term = 0;
334 p_Dpb->fs_ltref[i]->is_reference &= 1;
335 p_Dpb->fs_ltref[i]->is_long_term &= 1;
336 if (p_Dpb->fs_ltref[i]->is_used == 3) {
337 p_Dpb->fs_ltref[i]->frame->used_for_reference = 0;
338 p_Dpb->fs_ltref[i]->frame->is_long_term = 0;
339 }
340 return;
341 }
342 }
343 }
344 }
345 }
346
unmark_long_term_frame_for_reference_by_frame_idx(H264_DpbBuf_t * p_Dpb,RK_S32 long_term_frame_idx)347 static void unmark_long_term_frame_for_reference_by_frame_idx(H264_DpbBuf_t *p_Dpb, RK_S32 long_term_frame_idx)
348 {
349 RK_U32 i = 0;
350 for (i = 0; i < p_Dpb->ltref_frames_in_buffer; i++) {
351 if (p_Dpb->fs_ltref[i]->long_term_frame_idx == long_term_frame_idx) {
352 unmark_for_long_term_reference(p_Dpb->fs_ltref[i]);
353 }
354 }
355 }
356
unmark_long_term_field_for_reference_by_frame_idx(H264_DpbBuf_t * p_Dpb,RK_S32 structure,RK_S32 long_term_frame_idx,RK_S32 mark_current,RK_U32 curr_frame_num,RK_S32 curr_pic_num)357 static MPP_RET unmark_long_term_field_for_reference_by_frame_idx(H264_DpbBuf_t *p_Dpb, RK_S32 structure,
358 RK_S32 long_term_frame_idx, RK_S32 mark_current, RK_U32 curr_frame_num, RK_S32 curr_pic_num)
359 {
360 RK_U8 i = 0;
361 MPP_RET ret = MPP_ERR_UNKNOW;
362 H264dVideoCtx_t *p_Vid = p_Dpb->p_Vid;
363
364 VAL_CHECK(ret, structure != FRAME);
365 if (curr_pic_num < 0)
366 curr_pic_num += (2 * p_Vid->max_frame_num);
367
368 for (i = 0; i < p_Dpb->ltref_frames_in_buffer; i++) {
369 if (p_Dpb->fs_ltref[i]->long_term_frame_idx == long_term_frame_idx) {
370 if (structure == TOP_FIELD) {
371 if (p_Dpb->fs_ltref[i]->is_long_term == 3) {
372 unmark_for_long_term_reference(p_Dpb->fs_ltref[i]);
373 } else {
374 if (p_Dpb->fs_ltref[i]->is_long_term == 1) {
375 unmark_for_long_term_reference(p_Dpb->fs_ltref[i]);
376 } else {
377 if (mark_current) {
378 if (p_Dpb->last_picture) {
379 if ((p_Dpb->last_picture != p_Dpb->fs_ltref[i]) || p_Dpb->last_picture->frame_num != curr_frame_num)
380 unmark_for_long_term_reference(p_Dpb->fs_ltref[i]);
381 } else {
382 unmark_for_long_term_reference(p_Dpb->fs_ltref[i]);
383 }
384 } else {
385 if ((p_Dpb->fs_ltref[i]->frame_num) != (unsigned)(curr_pic_num >> 1)) {
386 unmark_for_long_term_reference(p_Dpb->fs_ltref[i]);
387 }
388 }
389 }
390 }
391 }
392 if (structure == BOTTOM_FIELD) {
393 if (p_Dpb->fs_ltref[i]->is_long_term == 3) {
394 unmark_for_long_term_reference(p_Dpb->fs_ltref[i]);
395 } else {
396 if (p_Dpb->fs_ltref[i]->is_long_term == 2) {
397 unmark_for_long_term_reference(p_Dpb->fs_ltref[i]);
398 } else {
399 if (mark_current) {
400 if (p_Dpb->last_picture) {
401 if ((p_Dpb->last_picture != p_Dpb->fs_ltref[i]) || p_Dpb->last_picture->frame_num != curr_frame_num)
402 unmark_for_long_term_reference(p_Dpb->fs_ltref[i]);
403 } else {
404 unmark_for_long_term_reference(p_Dpb->fs_ltref[i]);
405 }
406 } else {
407 if ((p_Dpb->fs_ltref[i]->frame_num) != (unsigned)(curr_pic_num >> 1)) {
408 unmark_for_long_term_reference(p_Dpb->fs_ltref[i]);
409 }
410 }
411 }
412 }
413 }
414 }
415 }
416 return ret = MPP_OK;
417 __FAILED:
418 return ret;
419 }
420
mark_pic_long_term(H264_DpbBuf_t * p_Dpb,H264_StorePic_t * p,RK_S32 long_term_frame_idx,RK_S32 picNumX)421 static void mark_pic_long_term(H264_DpbBuf_t *p_Dpb, H264_StorePic_t* p, RK_S32 long_term_frame_idx, RK_S32 picNumX)
422 {
423 RK_U32 i = 0;
424 RK_S32 add_top = 0, add_bottom = 0;
425
426 if (p->structure == FRAME) {
427 for (i = 0; i < p_Dpb->ref_frames_in_buffer; i++) {
428 if (p_Dpb->fs_ref[i]->is_reference == 3) {
429 if ((!p_Dpb->fs_ref[i]->frame->is_long_term) && (p_Dpb->fs_ref[i]->frame->pic_num == picNumX)) {
430 p_Dpb->fs_ref[i]->long_term_frame_idx = p_Dpb->fs_ref[i]->frame->long_term_frame_idx = long_term_frame_idx;
431 p_Dpb->fs_ref[i]->frame->long_term_pic_num = long_term_frame_idx;
432 p_Dpb->fs_ref[i]->frame->is_long_term = 1;
433
434 if (p_Dpb->fs_ref[i]->top_field && p_Dpb->fs_ref[i]->bottom_field) {
435 p_Dpb->fs_ref[i]->top_field->long_term_frame_idx = p_Dpb->fs_ref[i]->bottom_field->long_term_frame_idx = long_term_frame_idx;
436 p_Dpb->fs_ref[i]->top_field->long_term_pic_num = long_term_frame_idx;
437 p_Dpb->fs_ref[i]->bottom_field->long_term_pic_num = long_term_frame_idx;
438 p_Dpb->fs_ref[i]->top_field->is_long_term = p_Dpb->fs_ref[i]->bottom_field->is_long_term = 1;
439 }
440 p_Dpb->fs_ref[i]->is_long_term = 3;
441 return;
442 }
443 }
444 }
445 H264D_WARNNING("reference frame for long term marking not found.");
446 } else {
447 if (p->structure == TOP_FIELD) {
448 add_top = 1;
449 add_bottom = 0;
450 } else {
451 add_top = 0;
452 add_bottom = 1;
453 }
454 for (i = 0; i < p_Dpb->ref_frames_in_buffer; i++) {
455 if (p_Dpb->fs_ref[i]->is_reference & 1) {
456 if ((!p_Dpb->fs_ref[i]->top_field->is_long_term) && (p_Dpb->fs_ref[i]->top_field->pic_num == picNumX)) {
457 if ((p_Dpb->fs_ref[i]->is_long_term) && (p_Dpb->fs_ref[i]->long_term_frame_idx != long_term_frame_idx)) {
458 H264D_WARNNING("assigning long_term_frame_idx different from other field.");
459 }
460 p_Dpb->fs_ref[i]->long_term_frame_idx = p_Dpb->fs_ref[i]->top_field->long_term_frame_idx = long_term_frame_idx;
461 p_Dpb->fs_ref[i]->top_field->long_term_pic_num = 2 * long_term_frame_idx + add_top;
462 p_Dpb->fs_ref[i]->top_field->is_long_term = 1;
463 p_Dpb->fs_ref[i]->is_long_term |= 1;
464 if (p_Dpb->fs_ref[i]->is_long_term == 3) {
465 p_Dpb->fs_ref[i]->frame->is_long_term = 1;
466 p_Dpb->fs_ref[i]->frame->long_term_frame_idx = p_Dpb->fs_ref[i]->frame->long_term_pic_num = long_term_frame_idx;
467 }
468 return;
469 }
470 }
471 if (p_Dpb->fs_ref[i]->is_reference & 2) {
472 if ((!p_Dpb->fs_ref[i]->bottom_field->is_long_term) && (p_Dpb->fs_ref[i]->bottom_field->pic_num == picNumX)) {
473 if ((p_Dpb->fs_ref[i]->is_long_term) && (p_Dpb->fs_ref[i]->long_term_frame_idx != long_term_frame_idx)) {
474 H264D_WARNNING("assigning long_term_frame_idx different from other field.");
475 }
476
477 p_Dpb->fs_ref[i]->long_term_frame_idx = p_Dpb->fs_ref[i]->bottom_field->long_term_frame_idx
478 = long_term_frame_idx;
479 p_Dpb->fs_ref[i]->bottom_field->long_term_pic_num = 2 * long_term_frame_idx + add_bottom;
480 p_Dpb->fs_ref[i]->bottom_field->is_long_term = 1;
481 p_Dpb->fs_ref[i]->is_long_term |= 2;
482 if (p_Dpb->fs_ref[i]->is_long_term == 3) {
483 p_Dpb->fs_ref[i]->frame->is_long_term = 1;
484 p_Dpb->fs_ref[i]->frame->long_term_frame_idx = p_Dpb->fs_ref[i]->frame->long_term_pic_num = long_term_frame_idx;
485 }
486 return;
487 }
488 }
489 }
490 H264D_WARNNING("reference field for long term marking not found.");
491 }
492 }
493
mm_assign_long_term_frame_idx(H264_DpbBuf_t * p_Dpb,H264_StorePic_t * p,RK_S32 difference_of_pic_nums_minus1,RK_S32 long_term_frame_idx)494 static MPP_RET mm_assign_long_term_frame_idx(H264_DpbBuf_t *p_Dpb, H264_StorePic_t* p, RK_S32 difference_of_pic_nums_minus1, RK_S32 long_term_frame_idx)
495 {
496 RK_S32 picNumX = 0;
497 RK_U32 i = 0;
498 MPP_RET ret = MPP_ERR_UNKNOW;
499
500 picNumX = get_pic_num_x(p, difference_of_pic_nums_minus1);
501 //!< remove frames/fields with same long_term_frame_idx
502 if (p->structure == FRAME) {
503 unmark_long_term_frame_for_reference_by_frame_idx(p_Dpb, long_term_frame_idx);
504 } else {
505 PictureStructure structure = FRAME;
506
507 for (i = 0; i < p_Dpb->ref_frames_in_buffer; i++) {
508 if (p_Dpb->fs_ref[i]->is_reference & 1) {
509 if (p_Dpb->fs_ref[i]->top_field->pic_num == picNumX) {
510 structure = TOP_FIELD;
511 break;
512 }
513 }
514 if (p_Dpb->fs_ref[i]->is_reference & 2) {
515 if (p_Dpb->fs_ref[i]->bottom_field->pic_num == picNumX) {
516 structure = BOTTOM_FIELD;
517 break;
518 }
519 }
520 }
521 VAL_CHECK(ret, structure != FRAME);
522 FUN_CHECK(ret = unmark_long_term_field_for_reference_by_frame_idx(p_Dpb, structure, long_term_frame_idx, 0, 0, picNumX));
523 }
524 mark_pic_long_term(p_Dpb, p, long_term_frame_idx, picNumX);
525
526 return ret = MPP_OK;
527 __FAILED:
528 return ret;
529 }
530
mm_update_max_long_term_frame_idx(H264_DpbBuf_t * p_Dpb,RK_S32 max_long_term_frame_idx_plus1)531 static void mm_update_max_long_term_frame_idx(H264_DpbBuf_t *p_Dpb, RK_S32 max_long_term_frame_idx_plus1)
532 {
533 RK_U32 i = 0;
534
535 p_Dpb->max_long_term_pic_idx = max_long_term_frame_idx_plus1 - 1;
536
537 // check for invalid frames
538 for (i = 0; i < p_Dpb->ltref_frames_in_buffer; i++) {
539 if (p_Dpb->fs_ltref[i]->long_term_frame_idx > p_Dpb->max_long_term_pic_idx) {
540 unmark_for_long_term_reference(p_Dpb->fs_ltref[i]);
541 }
542 }
543 }
544
mm_unmark_all_short_term_for_reference(H264_DpbBuf_t * p_Dpb)545 static void mm_unmark_all_short_term_for_reference(H264_DpbBuf_t *p_Dpb)
546 {
547 RK_U32 i = 0;
548 for (i = 0; i < p_Dpb->ref_frames_in_buffer; i++) {
549 unmark_for_reference(p_Dpb->p_Vid->p_Dec, p_Dpb->fs_ref[i]);
550 }
551 update_ref_list(p_Dpb);
552 }
553
mm_unmark_all_long_term_for_reference(H264_DpbBuf_t * p_Dpb)554 static void mm_unmark_all_long_term_for_reference(H264_DpbBuf_t *p_Dpb)
555 {
556 mm_update_max_long_term_frame_idx(p_Dpb, 0);
557 }
558
mm_mark_current_picture_long_term(H264_DpbBuf_t * p_Dpb,H264_StorePic_t * p,RK_S32 long_term_frame_idx)559 static void mm_mark_current_picture_long_term(H264_DpbBuf_t *p_Dpb, H264_StorePic_t *p, RK_S32 long_term_frame_idx)
560 {
561 // remove long term pictures with same long_term_frame_idx
562 if (p->structure == FRAME) {
563 unmark_long_term_frame_for_reference_by_frame_idx(p_Dpb, long_term_frame_idx);
564 } else {
565 unmark_long_term_field_for_reference_by_frame_idx(p_Dpb, p->structure, long_term_frame_idx, 1, p->pic_num, 0);
566 }
567
568 p->is_long_term = 1;
569 p->long_term_frame_idx = long_term_frame_idx;
570 }
571
sliding_window_memory_management(H264_DpbBuf_t * p_Dpb)572 static void sliding_window_memory_management(H264_DpbBuf_t *p_Dpb)
573 {
574 RK_U32 i = 0;
575
576 // if this is a reference pic with sliding window, unmark first ref frame
577 if (p_Dpb->ref_frames_in_buffer == MPP_MAX(1, p_Dpb->num_ref_frames) - p_Dpb->ltref_frames_in_buffer) {
578 for (i = 0; i < p_Dpb->used_size; i++) {
579 if (p_Dpb->fs[i]->is_reference && (!(p_Dpb->fs[i]->is_long_term))) {
580 unmark_for_reference(p_Dpb->p_Vid->p_Dec, p_Dpb->fs[i]);
581 update_ref_list(p_Dpb);
582 break;
583 }
584 }
585 }
586 }
587
check_num_ref(H264_DpbBuf_t * p_Dpb)588 static void check_num_ref(H264_DpbBuf_t *p_Dpb)
589 {
590
591 if ((RK_S32)(p_Dpb->ltref_frames_in_buffer + p_Dpb->ref_frames_in_buffer) > MPP_MAX(1, p_Dpb->num_ref_frames)) {
592 sliding_window_memory_management(p_Dpb);
593 H264D_WARNNING("Max number of reference frames exceeded");
594 }
595 }
596
is_used_for_reference(H264_FrameStore_t * fs)597 static RK_U32 is_used_for_reference(H264_FrameStore_t* fs)
598 {
599 RK_U8 is_used_flag = 0;
600
601 if (!fs) {
602 return 0;
603 }
604 if (fs->is_reference) {
605 return is_used_flag = 1;
606 }
607
608 if (fs->is_used == 3) { // frame
609 if (fs->frame->used_for_reference) {
610 return is_used_flag = 1;
611 }
612 }
613
614 if (fs->is_used & 1) { // top field
615 if (fs->top_field) {
616 if (fs->top_field->used_for_reference) {
617 return is_used_flag = 1;
618 }
619 }
620 }
621
622 if (fs->is_used & 2) { // bottom field
623 if (fs->bottom_field) {
624 if (fs->bottom_field->used_for_reference) {
625 return is_used_flag = 1;
626 }
627 }
628 }
629 return is_used_flag = 0;
630 }
631
free_dpb_mark(H264_DecCtx_t * p_Dec,H264_DpbMark_t * p_mark,RK_S32 structure)632 static void free_dpb_mark(H264_DecCtx_t *p_Dec, H264_DpbMark_t *p_mark, RK_S32 structure)
633 {
634 if (structure == FRAME) {
635 p_mark->top_used = (p_mark->top_used > 0) ? (p_mark->top_used - 1) : 0;
636 p_mark->bot_used = (p_mark->bot_used > 0) ? (p_mark->bot_used - 1) : 0;
637 } else if (structure == TOP_FIELD) {
638 p_mark->top_used = (p_mark->top_used > 0) ? (p_mark->top_used - 1) : 0;
639 } else if (structure == BOTTOM_FIELD) {
640 p_mark->bot_used = (p_mark->bot_used > 0) ? (p_mark->bot_used - 1) : 0;
641 }
642 if (p_mark->top_used == 0 && p_mark->bot_used == 0
643 && p_mark->out_flag == 0 && (p_mark->slot_idx >= 0)) {
644 mpp_buf_slot_clr_flag(p_Dec->frame_slots, p_mark->slot_idx, SLOT_CODEC_USE);
645 reset_dpb_mark(p_mark);
646 }
647 }
648
remove_frame_from_dpb(H264_DpbBuf_t * p_Dpb,RK_S32 pos)649 static MPP_RET remove_frame_from_dpb(H264_DpbBuf_t *p_Dpb, RK_S32 pos)
650 {
651 RK_U32 i = 0;
652 MPP_RET ret = MPP_ERR_UNKNOW;
653 H264_FrameStore_t* tmp = NULL;
654 H264_FrameStore_t* fs = NULL;
655 H264_DecCtx_t *p_Dec = NULL;
656
657 INP_CHECK(ret, !p_Dpb);
658 fs = p_Dpb->fs[pos];
659 INP_CHECK(ret, !fs);
660 INP_CHECK(ret, !p_Dpb->p_Vid);
661 p_Dec = p_Dpb->p_Vid->p_Dec;
662 INP_CHECK(ret, !p_Dec);
663
664 switch (fs->is_used) {
665 case 3:
666 if (fs->frame) free_storable_picture(p_Dec, fs->frame);
667 if (fs->top_field) free_storable_picture(p_Dec, fs->top_field);
668 if (fs->bottom_field) free_storable_picture(p_Dec, fs->bottom_field);
669 fs->frame = NULL;
670 fs->top_field = NULL;
671 fs->bottom_field = NULL;
672 break;
673 case 2:
674 if (fs->bottom_field) free_storable_picture(p_Dec, fs->bottom_field);
675 fs->bottom_field = NULL;
676 break;
677 case 1:
678 if (fs->top_field) free_storable_picture(p_Dec, fs->top_field);
679 fs->top_field = NULL;
680 break;
681 case 0:
682 break;
683 default:
684 H264D_ERR("invalid frame store type.");
685 goto __FAILED;
686 }
687
688 fs->is_used = 0;
689 fs->is_long_term = 0;
690 fs->is_reference = 0;
691 fs->is_orig_reference = 0;
692
693 // move empty framestore to end of buffer
694 tmp = p_Dpb->fs[pos];
695
696 for (i = pos; i < p_Dpb->used_size - 1; i++) {
697 p_Dpb->fs[i] = p_Dpb->fs[i + 1];
698 }
699 p_Dpb->fs[p_Dpb->used_size - 1] = tmp;
700 p_Dpb->used_size--;
701
702 return ret = MPP_OK;
703 __RETURN:
704 return ret;
705 __FAILED:
706 return ret = MPP_NOK;
707
708
709 }
710
remove_unused_frame_from_dpb(H264_DpbBuf_t * p_Dpb)711 static MPP_RET remove_unused_frame_from_dpb(H264_DpbBuf_t *p_Dpb)
712 {
713 RK_U32 i = 0;
714 MPP_RET ret = MPP_ERR_UNKNOW;
715 INP_CHECK(ret, !p_Dpb);
716 // check for frames that were already output and no longer used for reference
717 for (i = 0; i < p_Dpb->used_size; i++) {
718 if (p_Dpb->fs[i]) {
719 if (p_Dpb->fs[i]->is_output && (!is_used_for_reference(p_Dpb->fs[i]))) {
720 FUN_CHECK(ret = remove_frame_from_dpb(p_Dpb, i));
721 return MPP_OK;
722 }
723 }
724 }
725 __RETURN:
726 return ret;
727 __FAILED:
728 return ret;
729 }
730
get_smallest_poc(H264_DpbBuf_t * p_Dpb,RK_S32 * poc,RK_S32 * pos)731 static RK_S32 get_smallest_poc(H264_DpbBuf_t *p_Dpb, RK_S32 *poc, RK_S32 *pos)
732 {
733 RK_U32 i = 0;
734 RK_S32 find_flag = 0;
735 RK_S32 min_pos = -1;
736 RK_S32 min_poc = INT_MAX;
737
738 *pos = -1;
739 *poc = INT_MAX;
740 for (i = 0; i < p_Dpb->used_size; i++) {
741 if (min_poc > p_Dpb->fs[i]->poc) {
742 min_poc = p_Dpb->fs[i]->poc;
743 min_pos = i;
744 }
745 if ((*poc > p_Dpb->fs[i]->poc) && (!p_Dpb->fs[i]->is_output)) {
746 *poc = p_Dpb->fs[i]->poc;
747 *pos = i;
748 find_flag = 1;
749 }
750 }
751 if (!find_flag) {
752 *poc = min_poc;
753 *pos = min_pos;
754 }
755
756 return find_flag;
757 }
758
alloc_frame_store()759 static H264_FrameStore_t *alloc_frame_store()
760 {
761 MPP_RET ret = MPP_ERR_UNKNOW;
762 H264_FrameStore_t *f = mpp_calloc(H264_FrameStore_t, 1);
763 MEM_CHECK(ret, f);
764
765 f->is_used = 0;
766 f->is_reference = 0;
767 f->is_long_term = 0;
768 f->is_orig_reference = 0;
769 f->is_output = 0;
770
771 f->frame = NULL;
772 f->top_field = NULL;
773 f->bottom_field = NULL;
774
775 return f;
776 __FAILED:
777 (void)ret;
778 return NULL;
779 }
780
dpb_combine_field_yuv(H264dVideoCtx_t * p_Vid,H264_FrameStore_t * fs,RK_U8 combine_flag)781 static MPP_RET dpb_combine_field_yuv(H264dVideoCtx_t *p_Vid, H264_FrameStore_t *fs, RK_U8 combine_flag)
782 {
783 MPP_RET ret = MPP_ERR_UNKNOW;
784
785 if (!fs->frame) {
786 fs->frame = alloc_storable_picture(p_Vid, FRAME);
787 MEM_CHECK(ret, fs->frame);
788 ASSERT(fs->top_field->colmv_no_used_flag == fs->bottom_field->colmv_no_used_flag);
789 fs->frame->colmv_no_used_flag = fs->top_field->colmv_no_used_flag;
790 if (combine_flag) {
791 ASSERT(fs->top_field->mem_mark->mark_idx == fs->bottom_field->mem_mark->mark_idx);
792 ASSERT(fs->top_field->mem_mark->slot_idx == fs->bottom_field->mem_mark->slot_idx);
793 fs->frame->mem_malloc_type = fs->top_field->mem_malloc_type;
794 fs->frame->mem_mark = fs->top_field->mem_mark;
795 } else if (fs->is_used == 0x01) { // unpaired, have top
796 ASSERT(fs->bottom_field->mem_malloc_type == Mem_UnPaired);
797 fs->frame->mem_mark = fs->top_field->mem_mark;
798 } else if (fs->is_used == 0x02) { // unpaired, have bottom
799 ASSERT(fs->top_field->mem_malloc_type == Mem_UnPaired);
800 fs->frame->mem_mark = fs->bottom_field->mem_mark;
801 } else {
802 ASSERT(fs->is_used == 0x03);
803 fs->frame->mem_malloc_type = fs->top_field->mem_malloc_type;
804 fs->frame->mem_mark = fs->top_field->mem_mark;
805 }
806 }
807 fs->poc = fs->frame->poc = fs->frame->frame_poc = MPP_MIN(fs->top_field->poc, fs->bottom_field->poc);
808 fs->bottom_field->frame_poc = fs->top_field->frame_poc = fs->frame->poc;
809 fs->bottom_field->top_poc = fs->frame->top_poc = fs->top_field->poc;
810 fs->top_field->bottom_poc = fs->frame->bottom_poc = fs->bottom_field->poc;
811 fs->frame->used_for_reference = (fs->top_field->used_for_reference && fs->bottom_field->used_for_reference);
812 fs->frame->is_long_term = (fs->top_field->is_long_term && fs->bottom_field->is_long_term);
813 if (fs->frame->is_long_term) {
814 fs->frame->long_term_frame_idx = fs->long_term_frame_idx;
815 }
816 fs->frame->top_field = fs->top_field;
817 fs->frame->bottom_field = fs->bottom_field;
818 fs->frame->frame = fs->frame;
819 fs->frame->chroma_format_idc = fs->top_field->chroma_format_idc;
820
821 fs->frame->frame_cropping_flag = fs->top_field->frame_cropping_flag;
822 if (fs->frame->frame_cropping_flag) {
823 fs->frame->frame_crop_top_offset = fs->top_field->frame_crop_top_offset;
824 fs->frame->frame_crop_bottom_offset = fs->top_field->frame_crop_bottom_offset;
825 fs->frame->frame_crop_left_offset = fs->top_field->frame_crop_left_offset;
826 fs->frame->frame_crop_right_offset = fs->top_field->frame_crop_right_offset;
827 }
828 fs->top_field->frame = fs->bottom_field->frame = fs->frame;
829 fs->top_field->top_field = fs->top_field;
830 fs->top_field->bottom_field = fs->bottom_field;
831 fs->bottom_field->top_field = fs->top_field;
832 fs->bottom_field->bottom_field = fs->bottom_field;
833
834 fs->frame->is_mmco_5 = fs->top_field->is_mmco_5 || fs->bottom_field->is_mmco_5;
835 fs->frame->poc_mmco5 = MPP_MIN(fs->top_field->top_poc_mmco5, fs->bottom_field->bot_poc_mmco5);
836 fs->frame->top_poc_mmco5 = fs->top_field->top_poc_mmco5;
837 fs->frame->bot_poc_mmco5 = fs->top_field->bot_poc_mmco5;
838
839 return ret = MPP_OK;
840 __FAILED:
841 return ret ;
842 }
843
write_picture(H264_StorePic_t * p,H264dVideoCtx_t * p_Vid)844 static void write_picture(H264_StorePic_t *p, H264dVideoCtx_t *p_Vid)
845 {
846 MppFrame mframe = NULL;
847 H264_DpbMark_t *p_mark = NULL;
848 H264dErrCtx_t *p_err = &p_Vid->p_Dec->errctx;
849
850 p_mark = p->mem_mark;
851 if ((p->mem_malloc_type == Mem_Malloc
852 || p->mem_malloc_type == Mem_TopOnly
853 || p->mem_malloc_type == Mem_BotOnly)
854 && p->structure == FRAME && p_mark->out_flag) {
855 mpp_buf_slot_get_prop(p_Vid->p_Dec->frame_slots, p_mark->slot_idx, SLOT_FRAME_PTR, &mframe);
856
857 //!< discard unpaired
858 if (p->mem_malloc_type == Mem_TopOnly || p->mem_malloc_type == Mem_BotOnly) {
859 if (p_err->used_ref_flag) {
860 mpp_frame_set_errinfo(mframe, MPP_FRAME_ERR_UNKNOW);
861 } else {
862 mpp_frame_set_discard(mframe, MPP_FRAME_ERR_UNKNOW);
863 }
864 }
865 //!< discard less than first i frame poc
866 if ((p_err->i_slice_no < 2) && (p->poc < p_err->first_iframe_poc)) {
867 if (p_err->used_ref_flag && p_err->first_iframe_is_output) {
868 if ((p->slice_type % 5) == H264_B_SLICE)
869 mpp_frame_set_discard(mframe, MPP_FRAME_ERR_UNKNOW);
870 else
871 mpp_frame_set_errinfo(mframe, MPP_FRAME_ERR_UNKNOW);
872 } else {
873 if (p_Vid->dpb_fast_out)
874 mpp_frame_set_discard(mframe, MPP_FRAME_ERR_UNKNOW);
875 }
876 }
877
878 if (p_Vid->p_Dec->mvc_valid) {
879 H264_DpbMark_t *match_mark = NULL;
880 H264_DpbMark_t *out_mark_list[2] = {NULL, NULL};
881 RK_U32 i = 0;
882 RK_S32 match_flag = 0;
883 RK_U32 is_base_view = p_mark->pic->layer_id == 0 ? 1 : 0;
884
885 // find pic with the same poc at base view
886 for (i = 0; i < MAX_MARK_SIZE; i++) {
887 match_mark = &p_Vid->p_Dec->dpb_mark[i];
888
889 if (!match_mark || !match_mark->pic || !match_mark->out_flag || match_mark->slot_idx < 0)
890 continue;
891
892 if (match_mark->pic->layer_id != p_mark->pic->layer_id) {
893 if (match_mark->pic->poc < p_mark->pic->poc) {
894 match_flag = 1;
895 break;
896 } else if (match_mark->pic->poc == p_mark->pic->poc) {
897 match_flag = 2;
898 break;
899 } else {
900 match_flag = 0;
901 }
902 }
903 }
904
905 if (!match_flag) {
906 H264D_DBG(H264D_DBG_DPB_INFO, "no other view matched with current view_id %d, poc %d",
907 p_mark->pic->layer_id, p_mark->pic->poc);
908 out_mark_list[0] = p_mark;
909 } else if (match_flag == 1) {
910 H264D_DBG(H264D_DBG_DPB_INFO, "find match view at %d, slot_idx %d, view_id %d, poc %d",
911 i, match_mark->slot_idx, match_mark->pic->layer_id, match_mark->pic->poc);
912 out_mark_list[0] = match_mark;
913 out_mark_list[1] = p_mark;
914 } else if (match_flag == 2) {
915 H264D_DBG(H264D_DBG_DPB_INFO, "find match view at %d, slot_idx %d, view_id %d, poc %d",
916 i, match_mark->slot_idx, match_mark->pic->layer_id, match_mark->pic->poc);
917 if (is_base_view) {
918 out_mark_list[0] = p_mark;
919 out_mark_list[1] = match_mark;
920 } else {
921 out_mark_list[0] = match_mark;
922 out_mark_list[1] = p_mark;
923 }
924 }
925
926 for (i = 0; i < 2; i++) {
927 if (out_mark_list[i]) {
928 mpp_buf_slot_set_flag(p_Vid->p_Dec->frame_slots, out_mark_list[i]->slot_idx, SLOT_QUEUE_USE);
929 mpp_buf_slot_enqueue(p_Vid->p_Dec->frame_slots, out_mark_list[i]->slot_idx, QUEUE_DISPLAY);
930 out_mark_list[i]->out_flag = 0;
931 p_Vid->p_Dec->last_frame_slot_idx = out_mark_list[i]->slot_idx;
932 }
933 }
934 } else {
935 H264D_DBG(H264D_DBG_DPB_INFO, "display frame view_id %d slot_idx %d poc %d",
936 p_mark->pic->layer_id, p_mark->slot_idx, p_mark->pic->poc);
937 mpp_buf_slot_set_flag(p_Vid->p_Dec->frame_slots, p_mark->slot_idx, SLOT_QUEUE_USE);
938 mpp_buf_slot_enqueue(p_Vid->p_Dec->frame_slots, p_mark->slot_idx, QUEUE_DISPLAY);
939 p_Vid->p_Dec->last_frame_slot_idx = p_mark->slot_idx;
940 p_mark->out_flag = 0;
941 }
942 }
943 }
944
write_unpaired_field(H264dVideoCtx_t * p_Vid,H264_FrameStore_t * fs)945 static MPP_RET write_unpaired_field(H264dVideoCtx_t *p_Vid, H264_FrameStore_t *fs)
946 {
947 MPP_RET ret = MPP_ERR_UNKNOW;
948 H264_StorePic_t *p = NULL;
949
950 VAL_CHECK(ret, fs->is_used < 3);
951 if (fs->is_used & 0x01) { // we have a top field, construct an empty bottom field
952 p = fs->top_field;
953 fs->bottom_field = alloc_storable_picture(p_Vid, BOTTOM_FIELD);
954 MEM_CHECK(ret, fs->bottom_field);
955 fs->bottom_field->mem_malloc_type = Mem_UnPaired;
956 fs->bottom_field->chroma_format_idc = p->chroma_format_idc;
957 FUN_CHECK(ret = dpb_combine_field_yuv(p_Vid, fs, 0));
958 fs->frame->view_id = fs->view_id;
959 fs->frame->mem_malloc_type = Mem_TopOnly;
960 H264D_WARNNING("write frame, line %d", __LINE__);
961 write_picture(fs->frame, p_Vid);
962 }
963
964 if (fs->is_used & 0x02) { // we have a bottom field, construct an empty top field
965 p = fs->bottom_field;
966 fs->top_field = alloc_storable_picture(p_Vid, TOP_FIELD);
967 MEM_CHECK(ret, fs->top_field);
968 fs->top_field->mem_malloc_type = Mem_UnPaired;
969 fs->top_field->chroma_format_idc = p->chroma_format_idc;
970 fs->top_field->frame_cropping_flag = fs->bottom_field->frame_cropping_flag;
971 if (fs->top_field->frame_cropping_flag) {
972 fs->top_field->frame_crop_top_offset = fs->bottom_field->frame_crop_top_offset;
973 fs->top_field->frame_crop_bottom_offset = fs->bottom_field->frame_crop_bottom_offset;
974 fs->top_field->frame_crop_left_offset = fs->bottom_field->frame_crop_left_offset;
975 fs->top_field->frame_crop_right_offset = fs->bottom_field->frame_crop_right_offset;
976 }
977 FUN_CHECK(ret = dpb_combine_field_yuv(p_Vid, fs, 0));
978 fs->frame->view_id = fs->view_id;
979 fs->frame->mem_malloc_type = Mem_BotOnly;
980 H264D_WARNNING("write frame, line %d", __LINE__);
981 write_picture(fs->frame, p_Vid);
982 }
983 fs->is_used = 3;
984
985 return ret = MPP_OK;
986 __FAILED:
987 return ret;
988 }
989
flush_direct_output(H264dVideoCtx_t * p_Vid)990 static MPP_RET flush_direct_output(H264dVideoCtx_t *p_Vid)
991 {
992 MPP_RET ret = MPP_ERR_UNKNOW;
993
994 FUN_CHECK(ret = write_unpaired_field(p_Vid, &p_Vid->out_buffer));
995 free_storable_picture(p_Vid->p_Dec, p_Vid->out_buffer.frame);
996 p_Vid->out_buffer.frame = NULL;
997 free_storable_picture(p_Vid->p_Dec, p_Vid->out_buffer.top_field);
998 p_Vid->out_buffer.top_field = NULL;
999 free_storable_picture(p_Vid->p_Dec, p_Vid->out_buffer.bottom_field);
1000 p_Vid->out_buffer.bottom_field = NULL;
1001 p_Vid->out_buffer.is_used = 0;
1002
1003 return ret = MPP_OK;
1004 __FAILED:
1005 return ret;
1006 }
1007
write_stored_frame(H264dVideoCtx_t * p_Vid,H264_DpbBuf_t * p_Dpb,H264_FrameStore_t * fs)1008 static MPP_RET write_stored_frame(H264dVideoCtx_t *p_Vid, H264_DpbBuf_t *p_Dpb, H264_FrameStore_t *fs)
1009 {
1010 MPP_RET ret = MPP_ERR_UNKNOW;
1011 INP_CHECK(ret, !p_Vid);
1012 INP_CHECK(ret, !fs);
1013 //!< make sure no direct output field is pending
1014 FUN_CHECK(ret = flush_direct_output(p_Vid));
1015
1016 if (fs->is_used < 3) {
1017 FUN_CHECK(ret = write_unpaired_field(p_Vid, fs));
1018 if (fs->top_field) free_storable_picture(p_Vid->p_Dec, fs->top_field);
1019 if (fs->bottom_field) free_storable_picture(p_Vid->p_Dec, fs->bottom_field);
1020 fs->top_field = NULL;
1021 fs->bottom_field = NULL;
1022 } else {
1023 H264D_WARNNING("write frame, line %d", __LINE__);
1024 write_picture(fs->frame, p_Vid);
1025 }
1026 p_Dpb->last_output_poc = fs->poc;
1027 fs->is_output = 1;
1028
1029 return ret = MPP_OK;
1030 __RETURN:
1031 return ret;
1032 __FAILED:
1033 return ret;
1034 }
1035
output_one_frame_from_dpb(H264_DpbBuf_t * p_Dpb)1036 static MPP_RET output_one_frame_from_dpb(H264_DpbBuf_t *p_Dpb)
1037 {
1038 RK_S32 poc = 0, pos = 0;
1039 MPP_RET ret = MPP_ERR_UNKNOW;
1040 H264dVideoCtx_t *p_Vid = p_Dpb->p_Vid;
1041
1042 //!< find smallest POC
1043 if (get_smallest_poc(p_Dpb, &poc, &pos)) {
1044 //!< JVT-P072 ends
1045 H264D_WARNNING("write_stored_frame, line %d", __LINE__);
1046 FUN_CHECK(ret = write_stored_frame(p_Vid, p_Dpb, p_Dpb->fs[pos]));
1047 //!< free frame store and move empty store to end of buffer
1048 if (!is_used_for_reference(p_Dpb->fs[pos])) {
1049 FUN_CHECK(ret = remove_frame_from_dpb(p_Dpb, pos));
1050 }
1051 }
1052 return ret = MPP_OK;
1053 __FAILED:
1054 return ret;
1055 }
1056
adaptive_memory_management(H264_DpbBuf_t * p_Dpb,H264_StorePic_t * p)1057 static MPP_RET adaptive_memory_management(H264_DpbBuf_t *p_Dpb, H264_StorePic_t *p)
1058 {
1059 H264_DRPM_t *tmp_drpm = NULL;
1060 MPP_RET ret = MPP_ERR_UNKNOW;
1061 H264dVideoCtx_t *p_Vid = p_Dpb->p_Vid;
1062
1063 p_Vid->last_has_mmco_5 = 0;
1064 VAL_CHECK(ret, !p->idr_flag && p->adaptive_ref_pic_buffering_flag);
1065 while (p->dec_ref_pic_marking_buffer) {
1066 tmp_drpm = p->dec_ref_pic_marking_buffer;
1067 switch (tmp_drpm->memory_management_control_operation) {
1068 case 0:
1069 VAL_CHECK(ret, tmp_drpm->Next == NULL);
1070 break;
1071 case 1:
1072 mm_unmark_short_term_for_reference(p_Dpb, p, tmp_drpm->difference_of_pic_nums_minus1);
1073 update_ref_list(p_Dpb);
1074 break;
1075 case 2:
1076 mm_unmark_long_term_for_reference(p_Dpb, p, tmp_drpm->long_term_pic_num);
1077 update_ltref_list(p_Dpb);
1078 break;
1079 case 3:
1080 mm_assign_long_term_frame_idx(p_Dpb, p, tmp_drpm->difference_of_pic_nums_minus1, tmp_drpm->long_term_frame_idx);
1081 update_ref_list(p_Dpb);
1082 update_ltref_list(p_Dpb);
1083 break;
1084 case 4:
1085 mm_update_max_long_term_frame_idx(p_Dpb, tmp_drpm->max_long_term_frame_idx_plus1);
1086 update_ltref_list(p_Dpb);
1087 break;
1088 case 5:
1089 mm_unmark_all_short_term_for_reference(p_Dpb);
1090 mm_unmark_all_long_term_for_reference(p_Dpb);
1091 p_Vid->last_has_mmco_5 = 1;
1092 break;
1093 case 6:
1094 //!< conceal max_long_term_frame_idx_plus1
1095 if (!tmp_drpm->max_long_term_frame_idx_plus1) {
1096 tmp_drpm->max_long_term_frame_idx_plus1 = p_Dpb->num_ref_frames;
1097 }
1098 mm_mark_current_picture_long_term(p_Dpb, p, tmp_drpm->long_term_frame_idx);
1099 check_num_ref(p_Dpb);
1100 break;
1101 default:
1102 ret = MPP_NOK;
1103 goto __FAILED;
1104 }
1105 p->dec_ref_pic_marking_buffer = tmp_drpm->Next;
1106 }
1107 if (p_Vid->last_has_mmco_5) { //!< similar IDR frame
1108 p->pic_num = p->frame_num = 0;
1109 switch (p->structure) {
1110 case TOP_FIELD:
1111 p->is_mmco_5 = 1;
1112 p->top_poc_mmco5 = p->top_poc;
1113 p->poc = p->top_poc = 0;
1114 break;
1115
1116 case BOTTOM_FIELD:
1117 p->is_mmco_5 = 1;
1118 p->bot_poc_mmco5 = p->bottom_poc;
1119 p->poc = p->bottom_poc = 0;
1120 break;
1121
1122 case FRAME:
1123 p->is_mmco_5 = 1;
1124 p->top_poc_mmco5 = p->top_poc;
1125 p->bot_poc_mmco5 = p->bottom_poc;
1126 p->poc_mmco5 = MPP_MIN(p->top_poc, p->bottom_poc);
1127 p->top_poc -= p->poc;
1128 p->bottom_poc -= p->poc;
1129
1130 p->poc = MPP_MIN(p->top_poc, p->bottom_poc);
1131 p->frame_poc = p->poc;
1132 break;
1133
1134 }
1135 if (p->layer_id == 0) {
1136 FUN_CHECK(ret = flush_dpb(p_Vid->p_Dpb_layer[0], 1));
1137 } else {
1138 FUN_CHECK(ret = flush_dpb(p_Vid->p_Dpb_layer[1], 2));
1139 }
1140 }
1141 return ret = MPP_OK;
1142 __FAILED:
1143 return ret;
1144 }
1145
dpb_split_field(H264dVideoCtx_t * p_Vid,H264_FrameStore_t * fs)1146 static MPP_RET dpb_split_field(H264dVideoCtx_t *p_Vid, H264_FrameStore_t *fs)
1147 {
1148 MPP_RET ret = MPP_ERR_UNKNOW;
1149 H264_StorePic_t *frame = fs->frame;
1150 H264_StorePic_t *fs_top = NULL, *fs_btm = NULL;
1151
1152 fs->poc = frame->poc;
1153 if (!frame->frame_mbs_only_flag) {
1154 fs_top = fs->top_field = alloc_storable_picture(p_Vid, TOP_FIELD);
1155 fs_btm = fs->bottom_field = alloc_storable_picture(p_Vid, BOTTOM_FIELD);
1156 MEM_CHECK(ret, fs_top && fs_btm);
1157 fs_top->colmv_no_used_flag = frame->colmv_no_used_flag;
1158 fs_btm->colmv_no_used_flag = frame->colmv_no_used_flag;
1159
1160 if (frame->mem_malloc_type == Mem_Malloc || frame->mem_malloc_type == Mem_Clone) {
1161 fs_top->mem_mark = frame->mem_mark;
1162 fs_btm->mem_mark = frame->mem_mark;
1163 fs_top->mem_malloc_type = frame->mem_malloc_type;
1164 fs_btm->mem_malloc_type = frame->mem_malloc_type;
1165 frame->mem_mark->bot_used += 1; // picture memory add 1
1166 frame->mem_mark->top_used += 1;
1167 }
1168 fs_top->poc = frame->top_poc;
1169 fs_btm->poc = frame->bottom_poc;
1170 fs_top->layer_id = frame->layer_id;
1171 fs_btm->layer_id = frame->layer_id;
1172
1173 fs_top->view_id = frame->view_id;
1174 fs_btm->view_id = frame->view_id;
1175 fs_top->frame_poc = frame->frame_poc;
1176
1177 fs_top->bottom_poc = fs_btm->bottom_poc = frame->bottom_poc;
1178 fs_top->top_poc = fs_btm->top_poc = frame->top_poc;
1179 fs_btm->frame_poc = frame->frame_poc;
1180
1181 fs_top->used_for_reference = fs_btm->used_for_reference = frame->used_for_reference;
1182 fs_top->is_long_term = fs_btm->is_long_term = frame->is_long_term;
1183 fs->long_term_frame_idx = fs_top->long_term_frame_idx = fs_btm->long_term_frame_idx = frame->long_term_frame_idx;
1184 fs_top->mb_aff_frame_flag = fs_btm->mb_aff_frame_flag = frame->mb_aff_frame_flag;
1185
1186 frame->top_field = fs_top;
1187 frame->bottom_field = fs_btm;
1188 frame->frame = frame;
1189 fs_top->bottom_field = fs_btm;
1190 fs_top->frame = frame;
1191 fs_top->top_field = fs_top;
1192 fs_btm->top_field = fs_top;
1193 fs_btm->frame = frame;
1194 fs_btm->bottom_field = fs_btm;
1195
1196 fs_top->is_mmco_5 = frame->is_mmco_5;
1197 fs_btm->is_mmco_5 = frame->is_mmco_5;
1198 fs_top->poc_mmco5 = frame->poc_mmco5;
1199 fs_btm->poc_mmco5 = frame->poc_mmco5;
1200 fs_top->top_poc_mmco5 = frame->top_poc_mmco5;
1201 fs_btm->bot_poc_mmco5 = frame->bot_poc_mmco5;
1202
1203 fs_top->view_id = fs_btm->view_id = fs->view_id;
1204 fs_top->inter_view_flag = fs->inter_view_flag[0];
1205 fs_btm->inter_view_flag = fs->inter_view_flag[1];
1206
1207 fs_top->chroma_format_idc = fs_btm->chroma_format_idc = frame->chroma_format_idc;
1208 fs_top->iCodingType = fs_btm->iCodingType = frame->iCodingType;
1209 fs_top->slice_type = fs_btm->slice_type = frame->slice_type;
1210 } else {
1211 fs->top_field = NULL;
1212 fs->bottom_field = NULL;
1213 frame->top_field = NULL;
1214 frame->bottom_field = NULL;
1215 frame->frame = frame;
1216 }
1217 return ret = MPP_OK;
1218 __FAILED:
1219 mpp_mem_pool_put_f(p_Vid->pic_st, fs->top_field);
1220 mpp_mem_pool_put_f(p_Vid->pic_st, fs->bottom_field);
1221 fs->top_field = NULL;
1222 fs->bottom_field = NULL;
1223 return ret;
1224 }
1225
dpb_combine_field(H264dVideoCtx_t * p_Vid,H264_FrameStore_t * fs,RK_U8 combine_flag)1226 static MPP_RET dpb_combine_field(H264dVideoCtx_t *p_Vid, H264_FrameStore_t *fs, RK_U8 combine_flag)
1227 {
1228 MPP_RET ret = MPP_ERR_UNKNOW;
1229
1230 FUN_CHECK(ret = dpb_combine_field_yuv(p_Vid, fs, combine_flag));
1231 fs->frame->layer_id = fs->layer_id;
1232 fs->frame->view_id = fs->view_id;
1233 fs->frame->iCodingType = fs->top_field->iCodingType; //FIELD_CODING;
1234 fs->frame->frame_num = fs->top_field->frame_num;
1235 fs->frame->is_output = fs->is_output;
1236 fs->frame->slice_type = fs->slice_type;
1237
1238 return ret = MPP_OK;
1239 __FAILED:
1240 return ret;
1241 }
1242
direct_output(H264dVideoCtx_t * p_Vid,H264_DpbBuf_t * p_Dpb,H264_StorePic_t * p)1243 static MPP_RET direct_output(H264dVideoCtx_t *p_Vid, H264_DpbBuf_t *p_Dpb, H264_StorePic_t *p)
1244 {
1245 MPP_RET ret = MPP_ERR_UNKNOW;
1246
1247 memcpy(&p_Vid->old_pic, p, sizeof(H264_StorePic_t));
1248 p_Vid->last_pic = &p_Vid->old_pic;
1249 if (p->structure == FRAME) {
1250 //!< we have a frame (or complementary field pair), so output it directly
1251 FUN_CHECK(ret = flush_direct_output(p_Vid));
1252 H264D_WARNNING("write frame, line %d", __LINE__);
1253 write_picture(p, p_Vid);
1254 p_Dpb->last_output_poc = p->poc;
1255 free_storable_picture(p_Vid->p_Dec, p);
1256 p_Dpb->last_picture = NULL;
1257 p_Vid->out_buffer.is_used = 0;
1258 p_Vid->out_buffer.is_directout = 0;
1259 goto __RETURN;
1260 }
1261
1262 if (p->structure == TOP_FIELD) {
1263 if (p_Vid->out_buffer.is_used & 1) {
1264 FUN_CHECK(ret = flush_direct_output(p_Vid));
1265 }
1266 p_Vid->out_buffer.top_field = p;
1267 p_Vid->out_buffer.is_used |= 1;
1268 p_Vid->out_buffer.frame_num = p->pic_num;
1269 p_Vid->out_buffer.is_directout = 1;
1270 p_Dpb->last_picture = &p_Vid->out_buffer;
1271 }
1272
1273 if (p->structure == BOTTOM_FIELD) {
1274 if (p_Vid->out_buffer.is_used & 2) {
1275 FUN_CHECK(ret = flush_direct_output(p_Vid));
1276 }
1277 p_Vid->out_buffer.bottom_field = p;
1278 p_Vid->out_buffer.is_used |= 2;
1279 p_Vid->out_buffer.frame_num = p->pic_num;
1280 p_Vid->out_buffer.is_directout = 1;
1281 p_Dpb->last_picture = &p_Vid->out_buffer;
1282 }
1283
1284 if (p_Vid->out_buffer.is_used == 3) {
1285 //!< we have both fields, so output them
1286 FUN_CHECK(ret = dpb_combine_field_yuv(p_Vid, &p_Vid->out_buffer, 0));
1287 p_Vid->out_buffer.frame->view_id = p_Vid->out_buffer.view_id;
1288 H264D_WARNNING("write frame, line %d", __LINE__);
1289 write_picture(p_Vid->out_buffer.frame, p_Vid);
1290 free_storable_picture(p_Vid->p_Dec, p_Vid->out_buffer.frame);
1291 p_Vid->out_buffer.frame = NULL;
1292 free_storable_picture(p_Vid->p_Dec, p_Vid->out_buffer.top_field);
1293 p_Vid->out_buffer.top_field = NULL;
1294 free_storable_picture(p_Vid->p_Dec, p_Vid->out_buffer.bottom_field);
1295 p_Vid->out_buffer.bottom_field = NULL;
1296 p_Vid->out_buffer.is_used = 0;
1297 p_Vid->out_buffer.is_directout = 0;
1298 p_Dpb->last_output_poc = p->poc;
1299 p_Dpb->last_picture = NULL;
1300 }
1301
1302 __RETURN:
1303 return ret = MPP_OK;
1304 __FAILED:
1305 return ret;
1306 }
1307
output_dpb_normal(H264_DpbBuf_t * p_Dpb)1308 static MPP_RET output_dpb_normal(H264_DpbBuf_t *p_Dpb)
1309 {
1310 MPP_RET ret = MPP_NOK;
1311 RK_S32 min_poc = 0;
1312 RK_S32 min_pos = 0;
1313 RK_S32 poc_inc = 0;
1314
1315 while ((p_Dpb->last_output_poc > INT_MIN)
1316 && (get_smallest_poc(p_Dpb, &min_poc, &min_pos))) {
1317 poc_inc = min_poc - p_Dpb->last_output_poc;
1318 if ((p_Dpb->last_output_poc > INT_MIN) && (abs(poc_inc) & 0x1))
1319 p_Dpb->poc_interval = 1;
1320 if ((min_poc - p_Dpb->last_output_poc) <= p_Dpb->poc_interval) {
1321 FUN_CHECK(ret = write_stored_frame(p_Dpb->p_Vid, p_Dpb, p_Dpb->fs[min_pos]));
1322 } else {
1323 break;
1324 }
1325 }
1326 while (!remove_unused_frame_from_dpb(p_Dpb));
1327
1328 return MPP_OK;
1329 __FAILED:
1330 return ret;
1331 }
output_dpb_fastplay(H264_DpbBuf_t * p_Dpb,H264_FrameStore_t * fs,RK_U32 is_i_frm)1332 static MPP_RET output_dpb_fastplay(H264_DpbBuf_t *p_Dpb, H264_FrameStore_t *fs, RK_U32 is_i_frm)
1333 {
1334 MPP_RET ret = MPP_NOK;
1335
1336 if ((p_Dpb->p_Vid->dpb_fast_out && is_i_frm)) {
1337 FUN_CHECK(ret = write_stored_frame(p_Dpb->p_Vid, p_Dpb, fs));
1338 } else
1339 output_dpb_normal(p_Dpb);
1340
1341 return MPP_OK;
1342 __FAILED:
1343 return ret;
1344 }
output_dpb_fastplay_once(H264_DpbBuf_t * p_Dpb,H264_FrameStore_t * fs,RK_U32 is_i_frm)1345 static MPP_RET output_dpb_fastplay_once(H264_DpbBuf_t *p_Dpb, H264_FrameStore_t *fs, RK_U32 is_i_frm)
1346 {
1347 MPP_RET ret = MPP_NOK;
1348
1349 if (p_Dpb->p_Vid->dpb_fast_out && is_i_frm && !p_Dpb->p_Vid->dpb_first_fast_played) {
1350 FUN_CHECK(ret = write_stored_frame(p_Dpb->p_Vid, p_Dpb, fs));
1351 p_Dpb->p_Vid->dpb_first_fast_played = 1;
1352 } else {
1353 // disable fast play once in the second gop
1354 if (p_Dpb->p_Vid->dpb_fast_out && is_i_frm && p_Dpb->p_Vid->dpb_first_fast_played) {
1355 p_Dpb->p_Vid->dpb_fast_out = MPP_DISABLE_FAST_PLAY;
1356 }
1357 output_dpb_normal(p_Dpb);
1358 }
1359
1360 return MPP_OK;
1361 __FAILED:
1362 return ret;
1363 }
1364
scan_dpb_output(H264_DpbBuf_t * p_Dpb,H264_StorePic_t * p)1365 static MPP_RET scan_dpb_output(H264_DpbBuf_t *p_Dpb, H264_StorePic_t *p)
1366 {
1367 MPP_RET ret = MPP_NOK;
1368 H264_FrameStore_t *fs = p_Dpb->fs[p_Dpb->used_size - 1];
1369
1370 if (fs->is_used == 3) {
1371 H264dErrCtx_t *p_err = &p_Dpb->p_Vid->p_Dec->errctx;
1372 RK_U32 is_i_frm = p_err->i_slice_no < 2 && p_Dpb->last_output_poc == INT_MIN;
1373
1374 if (p_Dpb->p_Vid->p_Dec->cfg->base.fast_out)
1375 FUN_CHECK(ret = write_stored_frame(p_Dpb->p_Vid, p_Dpb, fs));
1376 else {
1377 switch (p_Dpb->p_Vid->p_Dec->cfg->base.enable_fast_play) {
1378 case MPP_DISABLE_FAST_PLAY:
1379 FUN_CHECK(ret = output_dpb_normal(p_Dpb));
1380 break;
1381 case MPP_ENABLE_FAST_PLAY:
1382 FUN_CHECK(ret = output_dpb_fastplay(p_Dpb, fs, is_i_frm));
1383 break;
1384 case MPP_ENABLE_FAST_PLAY_ONCE:
1385 FUN_CHECK(ret = output_dpb_fastplay_once(p_Dpb, fs, is_i_frm));
1386 break;
1387 default:
1388 H264D_ERR("unsupport output mode");
1389 }
1390 }
1391
1392 if (is_i_frm)
1393 p_err->first_iframe_is_output = fs->is_output;
1394 }
1395 (void )p;
1396 return MPP_OK;
1397 __FAILED:
1398 return ret;
1399 }
1400
flush_one_dpb_mark(H264_DecCtx_t * p_Dec,H264_DpbMark_t * p_mark)1401 static void flush_one_dpb_mark(H264_DecCtx_t *p_Dec, H264_DpbMark_t *p_mark)
1402 {
1403 if (NULL == p_mark)
1404 return;
1405 if (p_mark->out_flag && (p_mark->slot_idx >= 0)) {
1406 MppFrame mframe = NULL;
1407
1408 mpp_buf_slot_get_prop(p_Dec->frame_slots, p_mark->slot_idx, SLOT_FRAME_PTR, &mframe);
1409 if (mframe) {
1410 H264D_DBG(H264D_DBG_SLOT_FLUSH, "[DPB_BUF_FLUSH] slot_idx=%d, top_used=%d, bot_used=%d",
1411 p_mark->slot_idx, p_mark->top_used, p_mark->bot_used);
1412 mpp_frame_set_discard(mframe, 1);
1413 mpp_buf_slot_set_flag(p_Dec->frame_slots, p_mark->slot_idx, SLOT_QUEUE_USE);
1414 mpp_buf_slot_enqueue(p_Dec->frame_slots, p_mark->slot_idx, QUEUE_DISPLAY);
1415 mpp_buf_slot_clr_flag(p_Dec->frame_slots, p_mark->slot_idx, SLOT_CODEC_USE);
1416 p_Dec->last_frame_slot_idx = p_mark->slot_idx;
1417 }
1418 reset_dpb_mark(p_mark);
1419 return;
1420 }
1421 H264D_DBG(H264D_DBG_WARNNING, "out_flag %d slot_idx %d\n", p_mark->out_flag, p_mark->slot_idx);
1422 }
1423
1424 /*!
1425 ***********************************************************************
1426 * \brief
1427 * store picture to dpb
1428 ***********************************************************************
1429 */
1430 //extern "C"
store_picture_in_dpb(H264_DpbBuf_t * p_Dpb,H264_StorePic_t * p)1431 MPP_RET store_picture_in_dpb(H264_DpbBuf_t *p_Dpb, H264_StorePic_t *p)
1432 {
1433 MPP_RET ret = MPP_ERR_UNKNOW;
1434 H264dVideoCtx_t *p_Vid = p_Dpb->p_Vid;
1435 RK_U32 max_buf_size = 0;
1436
1437 VAL_CHECK(ret, NULL != p); //!< if frame, check for new store
1438 //!< set use flag
1439 if (p->mem_mark && (p->mem_mark->slot_idx >= 0)) {
1440 mpp_buf_slot_set_flag(p_Vid->p_Dec->frame_slots, p->mem_mark->slot_idx, SLOT_CODEC_USE);
1441 } else {
1442 H264D_ERR("error, p->mem_mark == NULL");
1443 }
1444 //!< deal with all frames in dpb
1445 p_Vid->last_has_mmco_5 = 0;
1446 p_Vid->last_pic_bottom_field = p->structure == BOTTOM_FIELD;
1447 if (p->idr_flag) {
1448 FUN_CHECK(ret = idr_memory_management(p_Dpb, p));
1449 } else { //!< adaptive memory management
1450 if (p->used_for_reference && p->adaptive_ref_pic_buffering_flag) {
1451 FUN_CHECK(ret = adaptive_memory_management(p_Dpb, p));
1452 }
1453 }
1454 //!< if necessary, combine top and botteom to frame
1455 if (get_field_dpb_combine_flag(p_Dpb->last_picture, p)) {
1456 if (p_Dpb->last_picture->is_directout) {
1457 FUN_CHECK(ret = direct_output(p_Vid, p_Dpb, p)); //!< output frame
1458 } else {
1459 FUN_CHECK(ret = insert_picture_in_dpb(p_Vid, p_Dpb->last_picture, p, 1)); //!< field_dpb_combine
1460 scan_dpb_output(p_Dpb, p);
1461 }
1462 memcpy(&p_Vid->old_pic, p, sizeof(H264_StorePic_t));
1463 p_Vid->last_pic = &p_Vid->old_pic;
1464 p_Dpb->last_picture = NULL;
1465 goto __RETURN;
1466 }
1467 //!< sliding window
1468 if (!p->idr_flag && p->used_for_reference && !p->adaptive_ref_pic_buffering_flag) {
1469 ASSERT(!p->idr_flag);
1470 sliding_window_memory_management(p_Dpb);
1471 p->is_long_term = 0;
1472 }
1473 while (!remove_unused_frame_from_dpb(p_Dpb));
1474 H264D_DBG(H264D_DBG_DPB_INFO, "before out, dpb[%d] used_size %d, size %d",
1475 p_Dpb->layer_id, p_Dpb->used_size, p_Dpb->size);
1476 //!< when full output one frame or more then setting max_buf_size
1477 max_buf_size = p_Vid->p_Inp->max_buf_size;
1478 if (max_buf_size)
1479 H264D_DBG(H264D_DBG_DPB_INFO, "max_buf_size=%d\n", max_buf_size);
1480 while (p_Dpb->used_size >= p_Dpb->size ||
1481 (max_buf_size && p_Dpb->used_size >= max_buf_size)) {
1482 RK_S32 min_poc = 0, min_pos = 0;
1483 RK_S32 find_flag = 0;
1484
1485 remove_unused_frame_from_dpb(p_Dpb);
1486 find_flag = get_smallest_poc(p_Dpb, &min_poc, &min_pos);
1487 if (!p->used_for_reference) {
1488 if ((!find_flag) || (p->poc < min_poc)) {
1489 FUN_CHECK(ret = direct_output(p_Vid, p_Dpb, p)); //!< output frame
1490 goto __RETURN;
1491 }
1492 }
1493 //!< used for reference, but not find, then flush a frame in the first
1494 if ((!find_flag) || (p->poc < min_poc)) {
1495 min_pos = 0;
1496 unmark_for_reference(p_Vid->p_Dec, p_Dpb->fs[min_pos]);
1497 if (!p_Dpb->fs[min_pos]->is_output) {
1498 H264D_WARNNING("write_stored_frame, line %d", __LINE__);
1499 FUN_CHECK(ret = write_stored_frame(p_Vid, p_Dpb, p_Dpb->fs[min_pos]));
1500 }
1501 FUN_CHECK(ret = remove_frame_from_dpb(p_Dpb, min_pos));
1502 p->is_long_term = 0;
1503 } else {
1504 FUN_CHECK(ret = output_one_frame_from_dpb(p_Dpb));
1505 }
1506 }
1507 H264D_DBG(H264D_DBG_DPB_INFO, "after out, dpb[%d] used_size %d, size %d",
1508 p_Dpb->layer_id, p_Dpb->used_size, p_Dpb->size);
1509 //!< store current decoder picture at end of dpb
1510 FUN_CHECK(ret = insert_picture_in_dpb(p_Vid, p_Dpb->fs[p_Dpb->used_size], p, 0));
1511 if (p->structure != FRAME) {
1512 p_Dpb->last_picture = p_Dpb->fs[p_Dpb->used_size];
1513 } else {
1514 p_Dpb->last_picture = NULL;
1515 }
1516 memcpy(&p_Vid->old_pic, p, sizeof(H264_StorePic_t));
1517 p_Vid->last_pic = &p_Vid->old_pic;
1518
1519 p_Dpb->used_size++;
1520 H264D_DBG(H264D_DBG_DPB_INFO, "[DPB_size] p_Dpb->used_size=%d", p_Dpb->used_size);
1521 if (!p_Vid->p_Dec->mvc_valid)
1522 scan_dpb_output(p_Dpb, p);
1523 update_ref_list(p_Dpb);
1524 update_ltref_list(p_Dpb);
1525
1526 __RETURN:
1527 return ret = MPP_OK;
1528 __FAILED:
1529 flush_one_dpb_mark(p_Vid->p_Dec, p->mem_mark);
1530 return ret;
1531 }
1532
1533 /*!
1534 ***********************************************************************
1535 * \brief
1536 * free frame store picture
1537 ***********************************************************************
1538 */
1539 //extern "C"
free_frame_store(H264_DecCtx_t * p_Dec,H264_FrameStore_t * f)1540 void free_frame_store(H264_DecCtx_t *p_Dec, H264_FrameStore_t* f)
1541 {
1542 if (f) {
1543 if (f->frame) {
1544 free_storable_picture(p_Dec, f->frame);
1545 f->frame = NULL;
1546 }
1547 if (f->top_field) {
1548 free_storable_picture(p_Dec, f->top_field);
1549 f->top_field = NULL;
1550 }
1551 if (f->bottom_field) {
1552 free_storable_picture(p_Dec, f->bottom_field);
1553 f->bottom_field = NULL;
1554 }
1555 MPP_FREE(f);
1556 }
1557 }
1558
1559 /*!
1560 ***********************************************************************
1561 * \brief
1562 * free dpb
1563 ***********************************************************************
1564 */
1565 //extern "C"
free_dpb(H264_DpbBuf_t * p_Dpb)1566 void free_dpb(H264_DpbBuf_t *p_Dpb)
1567 {
1568 RK_U32 i = 0;
1569 H264dVideoCtx_t *p_Vid = p_Dpb->p_Vid;
1570
1571 if (p_Dpb->fs) {
1572 for (i = 0; i < p_Dpb->allocated_size; i++) {
1573 free_frame_store(p_Vid->p_Dec, p_Dpb->fs[i]);
1574 p_Dpb->fs[i] = NULL;
1575 }
1576 MPP_FREE(p_Dpb->fs);
1577 }
1578 MPP_FREE(p_Dpb->fs_ref);
1579 MPP_FREE(p_Dpb->fs_ltref);
1580 if (p_Dpb->fs_ilref) {
1581 for (i = 0; i < 1; i++) {
1582 free_frame_store(p_Vid->p_Dec, p_Dpb->fs_ilref[i]);
1583 p_Dpb->fs_ilref[i] = NULL;
1584 }
1585 MPP_FREE(p_Dpb->fs_ilref);
1586 }
1587 p_Dpb->last_output_view_id = -1;
1588 p_Dpb->last_output_poc = INT_MIN;
1589 p_Dpb->init_done = 0;
1590 if (p_Vid->no_ref_pic) {
1591 free_storable_picture(p_Vid->p_Dec, p_Vid->no_ref_pic);
1592 p_Vid->no_ref_pic = NULL;
1593 }
1594 }
1595
1596 /*!
1597 ***********************************************************************
1598 * \brief
1599 * alloc one picture
1600 ***********************************************************************
1601 */
1602 //extern "C"
update_ref_list(H264_DpbBuf_t * p_Dpb)1603 void update_ref_list(H264_DpbBuf_t *p_Dpb)
1604 {
1605 RK_U8 i = 0, j = 0;
1606 for (i = 0, j = 0; i < p_Dpb->used_size; i++) {
1607 if (is_short_term_reference(p_Dpb->fs[i])) {
1608 p_Dpb->fs_ref[j++] = p_Dpb->fs[i];
1609 }
1610 }
1611
1612 p_Dpb->ref_frames_in_buffer = j;
1613
1614 while (j < p_Dpb->size) {
1615 p_Dpb->fs_ref[j++] = NULL;
1616 }
1617 }
1618 /*!
1619 ***********************************************************************
1620 * \brief
1621 * alloc one picture
1622 ***********************************************************************
1623 */
1624 //extern "C"
update_ltref_list(H264_DpbBuf_t * p_Dpb)1625 void update_ltref_list(H264_DpbBuf_t *p_Dpb)
1626 {
1627 RK_U8 i = 0, j = 0;
1628 for (i = 0, j = 0; i < p_Dpb->used_size; i++) {
1629 if (is_long_term_reference(p_Dpb->fs[i])) {
1630 p_Dpb->fs_ltref[j++] = p_Dpb->fs[i];
1631 }
1632 }
1633
1634 p_Dpb->ltref_frames_in_buffer = j;
1635
1636 while (j < p_Dpb->size) {
1637 p_Dpb->fs_ltref[j++] = NULL;
1638 }
1639 }
1640
1641 /*!
1642 ***********************************************************************
1643 * \brief
1644 * alloc one picture
1645 ***********************************************************************
1646 */
1647 //extern "C"
idr_memory_management(H264_DpbBuf_t * p_Dpb,H264_StorePic_t * p)1648 MPP_RET idr_memory_management(H264_DpbBuf_t *p_Dpb, H264_StorePic_t *p)
1649 {
1650 RK_U32 i = 0;
1651 RK_S32 type = -1;
1652 MPP_RET ret = MPP_ERR_UNKNOW;
1653 H264dErrCtx_t *p_err = &p_Dpb->p_Vid->p_Dec->errctx;
1654
1655 if (p->no_output_of_prior_pics_flag) {
1656 //!< free all stored pictures
1657 for (i = 0; i < p_Dpb->used_size; i++) {
1658 //!< reset all reference settings
1659 //Set is_output flag to true to avoid real output this frame to
1660 //display queue. These frames will be mark as unused and remove from
1661 //dpb at flush_dpb
1662 p_Dpb->fs[i]->is_output = 1;
1663 }
1664 }
1665
1666 type = (p->layer_id == 0) ? 1 : 2;
1667 FUN_CHECK(ret = flush_dpb(p_Dpb, type));
1668
1669 p_Dpb->last_picture = NULL;
1670
1671 update_ref_list(p_Dpb);
1672 update_ltref_list(p_Dpb);
1673 p_Dpb->last_output_poc = INT_MIN;
1674 p_err->i_slice_no = 1;
1675
1676 if (p->long_term_reference_flag) {
1677 p_Dpb->max_long_term_pic_idx = 0;
1678 p->is_long_term = 1;
1679 p->long_term_frame_idx = 0;
1680 } else {
1681 p_Dpb->max_long_term_pic_idx = -1;
1682 p->is_long_term = 0;
1683 }
1684 p_Dpb->last_output_view_id = -1;
1685
1686 return ret = MPP_OK;
1687
1688 __FAILED:
1689 for (i = 0; i < p_Dpb->used_size; i++) { // when error and free malloc buf
1690 free_frame_store(p_Dpb->p_Vid->p_Dec, p_Dpb->fs[i]);
1691 }
1692 return ret;
1693 }
1694
1695
1696 /*!
1697 ***********************************************************************
1698 * \brief
1699 * alloc one picture
1700 ***********************************************************************
1701 */
1702 //extern "C"
insert_picture_in_dpb(H264dVideoCtx_t * p_Vid,H264_FrameStore_t * fs,H264_StorePic_t * p,RK_U8 combine_flag)1703 MPP_RET insert_picture_in_dpb(H264dVideoCtx_t *p_Vid, H264_FrameStore_t *fs, H264_StorePic_t *p, RK_U8 combine_flag)
1704 {
1705 MPP_RET ret = MPP_ERR_UNKNOW;
1706
1707 ASSERT(p != NULL);
1708 ASSERT(fs != NULL);
1709
1710 switch (p->structure) {
1711 case FRAME:
1712 fs->frame = p;
1713 fs->is_used = 3;
1714 if (p->used_for_reference) {
1715 fs->is_reference = 3;
1716 fs->is_orig_reference = 3;
1717 if (p->is_long_term) {
1718 fs->is_long_term = 3;
1719 fs->long_term_frame_idx = p->long_term_frame_idx;
1720 }
1721 }
1722 fs->inter_view_flag[0] = fs->inter_view_flag[1] = p->inter_view_flag;
1723 fs->anchor_pic_flag[0] = fs->anchor_pic_flag[1] = p->anchor_pic_flag;
1724 FUN_CHECK(ret = dpb_split_field(p_Vid, fs));
1725 fs->poc = p->poc;
1726 break;
1727 case TOP_FIELD:
1728 fs->top_field = p;
1729 fs->is_used |= 1;
1730 fs->inter_view_flag[0] = p->inter_view_flag;
1731 fs->anchor_pic_flag[0] = p->anchor_pic_flag;
1732 if (p->used_for_reference) {
1733 fs->is_reference |= 1;
1734 fs->is_orig_reference |= 1;
1735 if (p->is_long_term) {
1736 fs->is_long_term |= 1;
1737 fs->long_term_frame_idx = p->long_term_frame_idx;
1738 }
1739 }
1740 if (fs->is_used == 3) {
1741 FUN_CHECK(ret = dpb_combine_field(p_Vid, fs, combine_flag));
1742 } else {
1743 fs->poc = p->poc;
1744 }
1745 break;
1746 case BOTTOM_FIELD:
1747 fs->bottom_field = p;
1748 fs->is_used |= 2;
1749 fs->inter_view_flag[1] = p->inter_view_flag;
1750 fs->anchor_pic_flag[1] = p->anchor_pic_flag;
1751 if (p->used_for_reference) {
1752 fs->is_reference |= 2;
1753 fs->is_orig_reference |= 2;
1754 if (p->is_long_term) {
1755 fs->is_long_term |= 2;
1756 fs->long_term_frame_idx = p->long_term_frame_idx;
1757 }
1758 }
1759 if (fs->is_used == 3) {
1760 FUN_CHECK(ret = dpb_combine_field(p_Vid, fs, combine_flag));
1761 } else {
1762 fs->poc = p->poc;
1763 }
1764 break;
1765 }
1766 fs->layer_id = p->layer_id;
1767 fs->view_id = p->view_id;
1768 fs->frame_num = p->pic_num;
1769 fs->is_output = p->is_output;
1770 fs->slice_type = p->slice_type;
1771 fs->structure = p->structure;
1772
1773 return ret = MPP_OK;
1774 __FAILED:
1775 return ret;
1776 }
1777
1778
1779 /*!
1780 ***********************************************************************
1781 * \brief
1782 * alloc one picture
1783 ***********************************************************************
1784 */
1785 //extern "C"
free_storable_picture(H264_DecCtx_t * p_Dec,H264_StorePic_t * p)1786 void free_storable_picture(H264_DecCtx_t *p_Dec, H264_StorePic_t *p)
1787 {
1788 if (p) {
1789 if (p->mem_malloc_type == Mem_Malloc
1790 || p->mem_malloc_type == Mem_Clone) {
1791 free_dpb_mark(p_Dec, p->mem_mark, p->structure);
1792 }
1793 if (p->mem_malloc_type == Mem_TopOnly) {
1794 free_dpb_mark(p_Dec, p->mem_mark, TOP_FIELD);
1795 }
1796 if (p->mem_malloc_type == Mem_BotOnly) {
1797 free_dpb_mark(p_Dec, p->mem_mark, BOTTOM_FIELD);
1798 }
1799 mpp_mem_pool_put_f(p_Dec->p_Vid->pic_st, p);
1800 }
1801 }
1802
1803 /*!
1804 ***********************************************************************
1805 * \brief
1806 * alloc one picture
1807 ***********************************************************************
1808 */
1809 //extern "C"
alloc_storable_picture(H264dVideoCtx_t * p_Vid,RK_S32 structure)1810 H264_StorePic_t *alloc_storable_picture(H264dVideoCtx_t *p_Vid, RK_S32 structure)
1811 {
1812 MPP_RET ret = MPP_ERR_UNKNOW;
1813 H264_StorePic_t *s = mpp_mem_pool_get_f(p_Vid->pic_st);
1814
1815 MEM_CHECK(ret, s);
1816 s->view_id = -1;
1817 s->structure = structure;
1818 (void)p_Vid;
1819
1820 return s;
1821 __FAILED:
1822 (void)ret;
1823 return NULL;
1824 }
1825
1826 /*!
1827 ***********************************************************************
1828 * \brief
1829 * alloc one picture
1830 ***********************************************************************
1831 */
1832 //extern "C"
get_field_dpb_combine_flag(H264_FrameStore_t * p_last,H264_StorePic_t * p)1833 RK_U32 get_field_dpb_combine_flag(H264_FrameStore_t *p_last, H264_StorePic_t *p)
1834 {
1835 RK_U32 combine_flag = 0;
1836
1837 if ((p->structure == TOP_FIELD) || (p->structure == BOTTOM_FIELD)) {
1838 // check for frame store with same pic_number
1839 if (p_last) {
1840 if ((RK_S32)p_last->frame_num == p->pic_num) {
1841 if (((p->structure == TOP_FIELD) && (p_last->is_used == 2))
1842 || ((p->structure == BOTTOM_FIELD) && (p_last->is_used == 1))) {
1843 #if 1
1844 if ((p->used_for_reference && p_last->is_orig_reference) ||
1845 (!p->used_for_reference && !p_last->is_orig_reference)) {
1846 combine_flag = 1;
1847 }
1848 #else
1849 combine_flag = 1;
1850 #endif
1851 }
1852 }
1853 /* set err to unpaired filed */
1854 if (!combine_flag) {
1855 struct h264_store_pic_t *pic = NULL;
1856
1857 pic = p_last->structure == TOP_FIELD ? p_last->top_field : p_last->bottom_field;
1858 if (pic && pic->mem_mark->mframe && !pic->combine_flag)
1859 mpp_frame_set_errinfo(pic->mem_mark->mframe, 1);
1860 }
1861 }
1862 }
1863 return combine_flag;
1864 }
1865
enlarge_dpb(H264_DpbBuf_t * p_Dpb,RK_U32 size)1866 static MPP_RET enlarge_dpb(H264_DpbBuf_t *p_Dpb, RK_U32 size)
1867 {
1868 RK_U32 i = 0;
1869 MPP_RET ret = MPP_ERR_UNKNOW;
1870 void *tmp;
1871
1872 if (!p_Dpb || !size || !p_Dpb->init_done)
1873 return MPP_ERR_VALUE;
1874
1875 if (p_Dpb->size >= size) {
1876 H264D_WARNNING("DPB could not be shrinked!\n");
1877 return MPP_ERR_VALUE;
1878 }
1879
1880 tmp = mpp_calloc(H264_FrameStore_t*, size);
1881 memcpy(tmp, p_Dpb->fs, sizeof(H264_FrameStore_t*) * p_Dpb->size);
1882 mpp_free(p_Dpb->fs);
1883 p_Dpb->fs = tmp;
1884
1885 tmp = mpp_calloc(H264_FrameStore_t*, size);
1886 memcpy(tmp, p_Dpb->fs_ref, sizeof(H264_FrameStore_t*) * p_Dpb->size);
1887 mpp_free(p_Dpb->fs_ref);
1888 p_Dpb->fs_ref = tmp;
1889
1890 tmp = mpp_calloc(H264_FrameStore_t*, size);
1891 memcpy(tmp, p_Dpb->fs_ltref, sizeof(H264_FrameStore_t*) * p_Dpb->size);
1892 mpp_free(p_Dpb->fs_ltref);
1893 p_Dpb->fs_ltref = tmp;
1894
1895 tmp = mpp_calloc(H264_FrameStore_t*, size);
1896 memcpy(tmp, p_Dpb->fs_ilref, sizeof(H264_FrameStore_t*) * p_Dpb->size);
1897 mpp_free(p_Dpb->fs_ilref);
1898 p_Dpb->fs_ilref = tmp;
1899
1900 for (i = p_Dpb->size; i < size; i++) {
1901 p_Dpb->fs[i] = alloc_frame_store();
1902 MEM_CHECK(ret, p_Dpb->fs[i]);
1903 p_Dpb->fs_ref[i] = NULL;
1904 p_Dpb->fs_ltref[i] = NULL;
1905 p_Dpb->fs[i]->layer_id = -1;
1906 p_Dpb->fs[i]->view_id = -1;
1907 p_Dpb->fs[i]->inter_view_flag[0] = p_Dpb->fs[i]->inter_view_flag[1] = 0;
1908 p_Dpb->fs[i]->anchor_pic_flag[0] = p_Dpb->fs[i]->anchor_pic_flag[1] = 0;
1909 }
1910
1911 p_Dpb->size = size;
1912 p_Dpb->allocated_size = size;
1913 return ret = MPP_OK;
1914
1915 __FAILED:
1916 return ret;
1917 }
1918
check_mvc_dpb(H264dVideoCtx_t * p_Vid,H264_DpbBuf_t * p_Dpb_layer_0,H264_DpbBuf_t * p_Dpb_layer_1)1919 MPP_RET check_mvc_dpb(H264dVideoCtx_t *p_Vid, H264_DpbBuf_t *p_Dpb_layer_0, H264_DpbBuf_t* p_Dpb_layer_1)
1920 {
1921 MPP_RET ret = MPP_OK;
1922
1923 if (!p_Vid || !p_Dpb_layer_0 || !p_Dpb_layer_1 || !p_Dpb_layer_0->init_done) {
1924 return ret = MPP_ERR_VALUE;
1925 }
1926
1927 H264D_DBG(H264D_DBG_DPB_INFO, "p_Dpb[0].size %d vs p_Dpb[1].size %d\n",
1928 p_Dpb_layer_0->size, p_Dpb_layer_1->size);
1929
1930 p_Dpb_layer_0->size = MPP_MIN(p_Dpb_layer_0->size, MAX_DPB_SIZE / 2);
1931 p_Dpb_layer_1->size = MPP_MIN(p_Dpb_layer_1->size, MAX_DPB_SIZE / 2);
1932
1933 if (p_Dpb_layer_0->size == p_Dpb_layer_1->size) {
1934 ret = MPP_OK;
1935 } else if (p_Dpb_layer_0->size > p_Dpb_layer_1->size) {
1936 ret = enlarge_dpb(p_Dpb_layer_1, p_Dpb_layer_0->size);
1937 H264D_DBG(H264D_DBG_DPB_INFO, "Enlarge DPB[1] to %d", p_Dpb_layer_0->size);
1938 } else {
1939 ret = enlarge_dpb(p_Dpb_layer_0, p_Dpb_layer_1->size);
1940 H264D_DBG(H264D_DBG_DPB_INFO, "Enlarge DPB[0] to %d", p_Dpb_layer_1->size);
1941 }
1942
1943 p_Vid->dpb_size[0] = p_Dpb_layer_0->size;
1944 p_Vid->dpb_size[1] = p_Dpb_layer_1->size;
1945
1946 return ret;
1947 }
1948
1949 /*!
1950 ***********************************************************************
1951 * \brief
1952 * init dpb
1953 ***********************************************************************
1954 */
1955 //extern "C"
init_dpb(H264dVideoCtx_t * p_Vid,H264_DpbBuf_t * p_Dpb,RK_S32 type)1956 MPP_RET init_dpb(H264dVideoCtx_t *p_Vid, H264_DpbBuf_t *p_Dpb, RK_S32 type) // type=1 AVC type=2 MVC
1957 {
1958 RK_U32 i = 0;
1959 MPP_RET ret = MPP_ERR_UNKNOW;
1960 H264_SPS_t *active_sps = p_Vid->active_sps;
1961 RK_U32 dpb_size;
1962
1963 if (!active_sps) {
1964 ret = MPP_NOK;
1965 goto __FAILED;
1966 }
1967 p_Dpb->p_Vid = p_Vid;
1968 if (p_Dpb->init_done) {
1969 free_dpb(p_Dpb);
1970 }
1971 dpb_size = getDpbSize(p_Vid, active_sps);
1972 p_Dpb->size = MPP_MAX(1, dpb_size);
1973 p_Dpb->allocated_size = p_Dpb->size;
1974 p_Dpb->num_ref_frames = active_sps->max_num_ref_frames;
1975 if (active_sps->max_dec_frame_buffering < active_sps->max_num_ref_frames) {
1976 H264D_WARNNING("DPB size at specified level is smaller than reference frames");
1977 }
1978 p_Dpb->used_size = 0;
1979 p_Dpb->last_picture = NULL;
1980 p_Dpb->ref_frames_in_buffer = 0;
1981 p_Dpb->ltref_frames_in_buffer = 0;
1982 //--------
1983 p_Dpb->fs = mpp_calloc(H264_FrameStore_t*, p_Dpb->size);
1984 p_Dpb->fs_ref = mpp_calloc(H264_FrameStore_t*, p_Dpb->size);
1985 p_Dpb->fs_ltref = mpp_calloc(H264_FrameStore_t*, p_Dpb->size);
1986 p_Dpb->fs_ilref = mpp_calloc(H264_FrameStore_t*, 1); //!< inter-layer reference (for multi-layered codecs)
1987 MEM_CHECK(ret, p_Dpb->fs && p_Dpb->fs_ref && p_Dpb->fs_ltref && p_Dpb->fs_ilref);
1988 for (i = 0; i < p_Dpb->size; i++) {
1989 p_Dpb->fs[i] = alloc_frame_store();
1990 MEM_CHECK(ret, p_Dpb->fs[i]);
1991 p_Dpb->fs_ref[i] = NULL;
1992 p_Dpb->fs_ltref[i] = NULL;
1993 p_Dpb->fs[i]->layer_id = -1;
1994 p_Dpb->fs[i]->view_id = -1;
1995 p_Dpb->fs[i]->inter_view_flag[0] = p_Dpb->fs[i]->inter_view_flag[1] = 0;
1996 p_Dpb->fs[i]->anchor_pic_flag[0] = p_Dpb->fs[i]->anchor_pic_flag[1] = 0;
1997 }
1998 if (type == 2) {
1999 p_Dpb->fs_ilref[0] = alloc_frame_store();
2000 MEM_CHECK(ret, p_Dpb->fs_ilref[0]);
2001 //!< These may need some cleanups
2002 p_Dpb->fs_ilref[0]->view_id = -1;
2003 p_Dpb->fs_ilref[0]->inter_view_flag[0] = p_Dpb->fs_ilref[0]->inter_view_flag[1] = 0;
2004 p_Dpb->fs_ilref[0]->anchor_pic_flag[0] = p_Dpb->fs_ilref[0]->anchor_pic_flag[1] = 0;
2005 //!< given that this is in a different buffer, do we even need proc_flag anymore?
2006 } else {
2007 p_Dpb->fs_ilref[0] = NULL;
2008 }
2009 //!< allocate a dummy storable picture
2010 if (!p_Vid->no_ref_pic) {
2011 p_Vid->no_ref_pic = alloc_storable_picture(p_Vid, FRAME);
2012 MEM_CHECK(ret, p_Vid->no_ref_pic);
2013 p_Vid->no_ref_pic->top_field = p_Vid->no_ref_pic;
2014 p_Vid->no_ref_pic->bottom_field = p_Vid->no_ref_pic;
2015 p_Vid->no_ref_pic->frame = p_Vid->no_ref_pic;
2016 }
2017 p_Dpb->last_output_poc = INT_MIN;
2018 p_Dpb->last_output_view_id = -1;
2019 p_Vid->last_has_mmco_5 = 0;
2020 p_Dpb->init_done = 1;
2021
2022 return ret = MPP_OK;
2023 __FAILED:
2024 return ret;
2025 }
2026 /*!
2027 ***********************************************************************
2028 * \brief
2029 * flush dpb
2030 ***********************************************************************
2031 */
2032 //extern "C"
flush_dpb(H264_DpbBuf_t * p_Dpb,RK_S32 type)2033 MPP_RET flush_dpb(H264_DpbBuf_t *p_Dpb, RK_S32 type)
2034 {
2035 RK_U32 i = 0;
2036 MPP_RET ret = MPP_ERR_UNKNOW;
2037
2038 INP_CHECK(ret, !p_Dpb);
2039 //!< diagnostics
2040 if (!p_Dpb->init_done) {
2041 goto __RETURN;
2042 }
2043 H264D_DBG(H264D_DBG_DPB_INFO, "dpb layer %d, used_size %d",
2044 p_Dpb->layer_id, p_Dpb->used_size);
2045 //!< mark all frames unused
2046 for (i = 0; i < p_Dpb->used_size; i++) {
2047 if (p_Dpb->fs[i] && p_Dpb->p_Vid) {
2048 VAL_CHECK(ret, p_Dpb->fs[i]->layer_id == p_Dpb->layer_id);
2049 unmark_for_reference(p_Dpb->p_Vid->p_Dec, p_Dpb->fs[i]);
2050 }
2051 }
2052 while (!remove_unused_frame_from_dpb(p_Dpb));
2053 //!< output frames in POC order
2054 while (p_Dpb->used_size) {
2055 FUN_CHECK(ret = output_one_frame_from_dpb(p_Dpb));
2056 }
2057 p_Dpb->last_output_poc = INT_MIN;
2058 (void)type;
2059 __RETURN:
2060 return ret = MPP_OK;
2061 __FAILED:
2062 return ret;
2063 }
2064 /*!
2065 ***********************************************************************
2066 * \brief
2067 * write out all frames
2068 ***********************************************************************
2069 */
2070 //extern "C"
output_dpb(H264_DecCtx_t * p_Dec,H264_DpbBuf_t * p_Dpb)2071 MPP_RET output_dpb(H264_DecCtx_t *p_Dec, H264_DpbBuf_t *p_Dpb)
2072 {
2073 MPP_RET ret = MPP_ERR_UNKNOW;
2074
2075 while (!remove_unused_frame_from_dpb(p_Dpb));
2076
2077 (void)p_Dec;
2078 return ret = MPP_OK;
2079 }
2080 /*!
2081 ***********************************************************************
2082 * \brief
2083 * parse sps and process sps
2084 ***********************************************************************
2085 */
2086 //extern "C"
exit_picture(H264dVideoCtx_t * p_Vid,H264_StorePic_t ** dec_pic)2087 MPP_RET exit_picture(H264dVideoCtx_t *p_Vid, H264_StorePic_t **dec_pic)
2088 {
2089 MPP_RET ret = MPP_ERR_UNKNOW;
2090
2091 //!< return if the last picture has already been finished
2092 if (!(*dec_pic) || !p_Vid->exit_picture_flag
2093 || !p_Vid->have_outpicture_flag || !p_Vid->iNumOfSlicesDecoded) {
2094 goto __RETURN;
2095 }
2096 FUN_CHECK(ret = store_picture_in_dpb(p_Vid->p_Dpb_layer[(*dec_pic)->layer_id], *dec_pic));
2097 *dec_pic = NULL;
2098
2099 __RETURN:
2100 return ret = MPP_OK;
2101 __FAILED:
2102 return ret;
2103 }
2104