xref: /rockchip-linux_mpp/mpp/codec/dec/h264/h264d_dpb.c (revision 437bfbeb9567cca9cd9080e3f6954aa9d6a94f18)
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