1*437bfbebSnyanmisaka /*
2*437bfbebSnyanmisaka *
3*437bfbebSnyanmisaka * Copyright 2015 Rockchip Electronics Co. LTD
4*437bfbebSnyanmisaka *
5*437bfbebSnyanmisaka * Licensed under the Apache License, Version 2.0 (the "License");
6*437bfbebSnyanmisaka * you may not use this file except in compliance with the License.
7*437bfbebSnyanmisaka * You may obtain a copy of the License at
8*437bfbebSnyanmisaka *
9*437bfbebSnyanmisaka * http://www.apache.org/licenses/LICENSE-2.0
10*437bfbebSnyanmisaka *
11*437bfbebSnyanmisaka * Unless required by applicable law or agreed to in writing, software
12*437bfbebSnyanmisaka * distributed under the License is distributed on an "AS IS" BASIS,
13*437bfbebSnyanmisaka * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14*437bfbebSnyanmisaka * See the License for the specific language governing permissions and
15*437bfbebSnyanmisaka * limitations under the License.
16*437bfbebSnyanmisaka */
17*437bfbebSnyanmisaka
18*437bfbebSnyanmisaka /*
19*437bfbebSnyanmisaka * @file h265_refs.c
20*437bfbebSnyanmisaka * @brief
21*437bfbebSnyanmisaka * @author csy(csy@rock-chips.com)
22*437bfbebSnyanmisaka
23*437bfbebSnyanmisaka * @version 1.0.0
24*437bfbebSnyanmisaka * @history
25*437bfbebSnyanmisaka * 2015.7.15 : Create
26*437bfbebSnyanmisaka */
27*437bfbebSnyanmisaka
28*437bfbebSnyanmisaka #define MODULE_TAG "H265_PARSER_REF"
29*437bfbebSnyanmisaka
30*437bfbebSnyanmisaka #include "mpp_compat_impl.h"
31*437bfbebSnyanmisaka
32*437bfbebSnyanmisaka #include "h265d_parser.h"
33*437bfbebSnyanmisaka #include "h265d_api.h"
34*437bfbebSnyanmisaka
35*437bfbebSnyanmisaka #define HEVC_ALIGN(value, x) ((value + (x-1)) & (~(x-1)))
36*437bfbebSnyanmisaka
mpp_hevc_unref_frame(HEVCContext * s,HEVCFrame * frame,int flags)37*437bfbebSnyanmisaka void mpp_hevc_unref_frame(HEVCContext *s, HEVCFrame *frame, int flags)
38*437bfbebSnyanmisaka {
39*437bfbebSnyanmisaka /* frame->frame can be NULL if context init failed */
40*437bfbebSnyanmisaka if (!frame->frame || (frame->slot_index == 0xff))
41*437bfbebSnyanmisaka return;
42*437bfbebSnyanmisaka
43*437bfbebSnyanmisaka frame->flags &= ~flags;
44*437bfbebSnyanmisaka if (!frame->flags) {
45*437bfbebSnyanmisaka frame->refPicList = NULL;
46*437bfbebSnyanmisaka frame->collocated_ref = NULL;
47*437bfbebSnyanmisaka if (frame->slot_index <= 0x7f) {
48*437bfbebSnyanmisaka h265d_dbg(H265D_DBG_REF, "poc %d clr ref index %d", frame->poc, frame->slot_index);
49*437bfbebSnyanmisaka mpp_buf_slot_clr_flag(s->slots, frame->slot_index, SLOT_CODEC_USE);
50*437bfbebSnyanmisaka }
51*437bfbebSnyanmisaka h265d_dbg(H265D_DBG_REF, "unref_frame poc %d frame->slot_index %d \n", frame->poc, frame->slot_index);
52*437bfbebSnyanmisaka frame->poc = INT_MAX;
53*437bfbebSnyanmisaka frame->slot_index = 0xff;
54*437bfbebSnyanmisaka frame->error_flag = 0;
55*437bfbebSnyanmisaka }
56*437bfbebSnyanmisaka }
57*437bfbebSnyanmisaka
58*437bfbebSnyanmisaka
mpp_hevc_clear_refs(HEVCContext * s)59*437bfbebSnyanmisaka void mpp_hevc_clear_refs(HEVCContext *s)
60*437bfbebSnyanmisaka {
61*437bfbebSnyanmisaka RK_U32 i;
62*437bfbebSnyanmisaka for (i = 0; i < MPP_ARRAY_ELEMS(s->DPB); i++) {
63*437bfbebSnyanmisaka mpp_hevc_unref_frame(s, &s->DPB[i],
64*437bfbebSnyanmisaka HEVC_FRAME_FLAG_SHORT_REF |
65*437bfbebSnyanmisaka HEVC_FRAME_FLAG_LONG_REF);
66*437bfbebSnyanmisaka }
67*437bfbebSnyanmisaka }
68*437bfbebSnyanmisaka
mpp_hevc_flush_dpb(HEVCContext * s)69*437bfbebSnyanmisaka void mpp_hevc_flush_dpb(HEVCContext *s)
70*437bfbebSnyanmisaka {
71*437bfbebSnyanmisaka RK_U32 i;
72*437bfbebSnyanmisaka for (i = 0; i < MPP_ARRAY_ELEMS(s->DPB); i++) {
73*437bfbebSnyanmisaka mpp_hevc_unref_frame(s, &s->DPB[i], ~0);
74*437bfbebSnyanmisaka }
75*437bfbebSnyanmisaka }
76*437bfbebSnyanmisaka
hor_align_64(RK_U32 val)77*437bfbebSnyanmisaka static RK_U32 hor_align_64(RK_U32 val)
78*437bfbebSnyanmisaka {
79*437bfbebSnyanmisaka return MPP_ALIGN(val, 64);
80*437bfbebSnyanmisaka }
81*437bfbebSnyanmisaka
alloc_frame(HEVCContext * s)82*437bfbebSnyanmisaka static HEVCFrame *alloc_frame(HEVCContext *s)
83*437bfbebSnyanmisaka {
84*437bfbebSnyanmisaka RK_U32 i;
85*437bfbebSnyanmisaka MPP_RET ret = MPP_OK;
86*437bfbebSnyanmisaka MppFrameFormat fmt = s->h265dctx->cfg->base.out_fmt & (~MPP_FRAME_FMT_MASK);
87*437bfbebSnyanmisaka
88*437bfbebSnyanmisaka for (i = 0; i < MPP_ARRAY_ELEMS(s->DPB); i++) {
89*437bfbebSnyanmisaka HEVCFrame *frame = &s->DPB[i];
90*437bfbebSnyanmisaka if (frame->slot_index != 0xff) {
91*437bfbebSnyanmisaka continue;
92*437bfbebSnyanmisaka }
93*437bfbebSnyanmisaka
94*437bfbebSnyanmisaka h265d_dbg(H265D_DBG_GLOBAL, "width = %d height = %d", s->h265dctx->width, s->h265dctx->height);
95*437bfbebSnyanmisaka mpp_frame_set_width(frame->frame, s->h265dctx->width);
96*437bfbebSnyanmisaka mpp_frame_set_height(frame->frame, s->h265dctx->height);
97*437bfbebSnyanmisaka mpp_frame_set_hor_stride(frame->frame,
98*437bfbebSnyanmisaka (MPP_ALIGN(s->h265dctx->coded_width, 64) * s->h265dctx->nBitDepth) >> 3);
99*437bfbebSnyanmisaka mpp_frame_set_ver_stride(frame->frame, s->h265dctx->coded_height);
100*437bfbebSnyanmisaka s->h265dctx->pix_fmt &= MPP_FRAME_FMT_MASK;
101*437bfbebSnyanmisaka if (s->is_hdr) {
102*437bfbebSnyanmisaka s->h265dctx->pix_fmt |= MPP_FRAME_HDR;
103*437bfbebSnyanmisaka }
104*437bfbebSnyanmisaka s->h265dctx->pix_fmt |= fmt;
105*437bfbebSnyanmisaka mpp_frame_set_fmt(frame->frame, s->h265dctx->pix_fmt);
106*437bfbebSnyanmisaka
107*437bfbebSnyanmisaka if (MPP_FRAME_FMT_IS_FBC(s->h265dctx->pix_fmt)) {
108*437bfbebSnyanmisaka RK_U32 fbc_hdr_stride = MPP_ALIGN(s->h265dctx->width, 64);
109*437bfbebSnyanmisaka
110*437bfbebSnyanmisaka mpp_slots_set_prop(s->slots, SLOTS_HOR_ALIGN, hor_align_64);
111*437bfbebSnyanmisaka mpp_frame_set_offset_x(frame->frame, 0);
112*437bfbebSnyanmisaka mpp_frame_set_offset_y(frame->frame, 4);
113*437bfbebSnyanmisaka
114*437bfbebSnyanmisaka if (*compat_ext_fbc_buf_size)
115*437bfbebSnyanmisaka mpp_frame_set_ver_stride(frame->frame, s->h265dctx->coded_height + 16);
116*437bfbebSnyanmisaka
117*437bfbebSnyanmisaka if (*compat_ext_fbc_hdr_256_odd)
118*437bfbebSnyanmisaka fbc_hdr_stride = MPP_ALIGN(s->h265dctx->width, 256) | 256;
119*437bfbebSnyanmisaka
120*437bfbebSnyanmisaka mpp_frame_set_fbc_hdr_stride(frame->frame, fbc_hdr_stride);
121*437bfbebSnyanmisaka } else if (MPP_FRAME_FMT_IS_TILE(s->h265dctx->pix_fmt)) {
122*437bfbebSnyanmisaka /* nothing todo */
123*437bfbebSnyanmisaka } else {
124*437bfbebSnyanmisaka if ((s->h265dctx->cfg->base.enable_vproc & MPP_VPROC_MODE_DETECTION) &&
125*437bfbebSnyanmisaka s->h265dctx->width <= 1920 && s->h265dctx->height <= 1088)
126*437bfbebSnyanmisaka mpp_frame_set_mode(frame->frame, MPP_FRAME_FLAG_DEINTERLACED);
127*437bfbebSnyanmisaka }
128*437bfbebSnyanmisaka
129*437bfbebSnyanmisaka if (s->h265dctx->cfg->base.enable_thumbnail && s->h265dctx->hw_info->cap_down_scale)
130*437bfbebSnyanmisaka mpp_frame_set_thumbnail_en(frame->frame, s->h265dctx->cfg->base.enable_thumbnail);
131*437bfbebSnyanmisaka else
132*437bfbebSnyanmisaka mpp_frame_set_thumbnail_en(frame->frame, 0);
133*437bfbebSnyanmisaka
134*437bfbebSnyanmisaka mpp_frame_set_errinfo(frame->frame, 0);
135*437bfbebSnyanmisaka mpp_frame_set_discard(frame->frame, 0);
136*437bfbebSnyanmisaka mpp_frame_set_pts(frame->frame, s->pts);
137*437bfbebSnyanmisaka mpp_frame_set_dts(frame->frame, s->dts);
138*437bfbebSnyanmisaka mpp_frame_set_poc(frame->frame, s->poc);
139*437bfbebSnyanmisaka mpp_frame_set_color_range(frame->frame, s->h265dctx->color_range);
140*437bfbebSnyanmisaka mpp_frame_set_color_primaries(frame->frame, s->sps->vui.colour_primaries);
141*437bfbebSnyanmisaka if (s->alternative_transfer.present)
142*437bfbebSnyanmisaka mpp_frame_set_color_trc(frame->frame,
143*437bfbebSnyanmisaka s->alternative_transfer.preferred_transfer_characteristics);
144*437bfbebSnyanmisaka else
145*437bfbebSnyanmisaka mpp_frame_set_color_trc(frame->frame, s->sps->vui.transfer_characteristic);
146*437bfbebSnyanmisaka mpp_frame_set_colorspace(frame->frame, s->h265dctx->colorspace);
147*437bfbebSnyanmisaka mpp_frame_set_mastering_display(frame->frame, s->mastering_display);
148*437bfbebSnyanmisaka mpp_frame_set_content_light(frame->frame, s->content_light);
149*437bfbebSnyanmisaka
150*437bfbebSnyanmisaka h265d_dbg(H265D_DBG_GLOBAL, "poc %d w_stride %d h_stride %d\n",
151*437bfbebSnyanmisaka s->poc, s->h265dctx->coded_width, s->h265dctx->coded_height);
152*437bfbebSnyanmisaka ret = mpp_buf_slot_get_unused(s->slots, &frame->slot_index);
153*437bfbebSnyanmisaka mpp_assert(ret == MPP_OK);
154*437bfbebSnyanmisaka return frame;
155*437bfbebSnyanmisaka }
156*437bfbebSnyanmisaka mpp_err( "Error allocating frame, DPB full.\n");
157*437bfbebSnyanmisaka return NULL;
158*437bfbebSnyanmisaka }
159*437bfbebSnyanmisaka
mpp_hevc_set_new_ref(HEVCContext * s,MppFrame * mframe,int poc)160*437bfbebSnyanmisaka int mpp_hevc_set_new_ref(HEVCContext *s, MppFrame *mframe, int poc)
161*437bfbebSnyanmisaka {
162*437bfbebSnyanmisaka
163*437bfbebSnyanmisaka HEVCFrame *ref = NULL;
164*437bfbebSnyanmisaka RK_U32 i;
165*437bfbebSnyanmisaka
166*437bfbebSnyanmisaka /* check that this POC doesn't already exist */
167*437bfbebSnyanmisaka for (i = 0; i < MPP_ARRAY_ELEMS(s->DPB); i++) {
168*437bfbebSnyanmisaka HEVCFrame *frame = &s->DPB[i];
169*437bfbebSnyanmisaka
170*437bfbebSnyanmisaka if ((frame->slot_index != 0xff) && frame->sequence == s->seq_decode &&
171*437bfbebSnyanmisaka frame->poc == poc && !s->nuh_layer_id) {
172*437bfbebSnyanmisaka mpp_err( "Duplicate POC in a sequence: %d.\n",
173*437bfbebSnyanmisaka poc);
174*437bfbebSnyanmisaka return MPP_ERR_STREAM;
175*437bfbebSnyanmisaka }
176*437bfbebSnyanmisaka }
177*437bfbebSnyanmisaka
178*437bfbebSnyanmisaka ref = alloc_frame(s);
179*437bfbebSnyanmisaka if (!ref) {
180*437bfbebSnyanmisaka mpp_err( "alloc_frame error\n");
181*437bfbebSnyanmisaka return MPP_ERR_NOMEM;
182*437bfbebSnyanmisaka }
183*437bfbebSnyanmisaka // set hdr dynamic meta
184*437bfbebSnyanmisaka if (s->hdr_dynamic_meta && s->hdr_dynamic) {
185*437bfbebSnyanmisaka mpp_frame_set_hdr_dynamic_meta(ref->frame, s->hdr_dynamic_meta);
186*437bfbebSnyanmisaka s->hdr_dynamic = 0;
187*437bfbebSnyanmisaka }
188*437bfbebSnyanmisaka
189*437bfbebSnyanmisaka *mframe = ref->frame;
190*437bfbebSnyanmisaka s->ref = ref;
191*437bfbebSnyanmisaka ref->poc = poc;
192*437bfbebSnyanmisaka h265d_dbg(H265D_DBG_REF, "alloc frame poc %d slot_index %d", poc, ref->slot_index);
193*437bfbebSnyanmisaka ref->flags = HEVC_FRAME_FLAG_OUTPUT | HEVC_FRAME_FLAG_SHORT_REF;
194*437bfbebSnyanmisaka mpp_buf_slot_set_flag(s->slots, ref->slot_index, SLOT_CODEC_USE);
195*437bfbebSnyanmisaka mpp_buf_slot_set_flag(s->slots, ref->slot_index, SLOT_HAL_OUTPUT);
196*437bfbebSnyanmisaka s->task->output = ref->slot_index;
197*437bfbebSnyanmisaka
198*437bfbebSnyanmisaka ref->sequence = s->seq_decode;
199*437bfbebSnyanmisaka ref->window = s->sps->output_window;
200*437bfbebSnyanmisaka return 0;
201*437bfbebSnyanmisaka }
202*437bfbebSnyanmisaka
find_ref_idx(HEVCContext * s,int poc)203*437bfbebSnyanmisaka static HEVCFrame *find_ref_idx(HEVCContext *s, int poc)
204*437bfbebSnyanmisaka {
205*437bfbebSnyanmisaka RK_U32 i;
206*437bfbebSnyanmisaka RK_S32 LtMask = (1 << s->sps->log2_max_poc_lsb) - 1;
207*437bfbebSnyanmisaka
208*437bfbebSnyanmisaka for (i = 0; i < MPP_ARRAY_ELEMS(s->DPB); i++) {
209*437bfbebSnyanmisaka HEVCFrame *ref = &s->DPB[i];
210*437bfbebSnyanmisaka if ((ref->slot_index != 0xff) && (ref->sequence == s->seq_decode)) {
211*437bfbebSnyanmisaka if ((ref->poc & LtMask) == poc)
212*437bfbebSnyanmisaka return ref;
213*437bfbebSnyanmisaka }
214*437bfbebSnyanmisaka }
215*437bfbebSnyanmisaka
216*437bfbebSnyanmisaka for (i = 0; i < MPP_ARRAY_ELEMS(s->DPB); i++) {
217*437bfbebSnyanmisaka HEVCFrame *ref = &s->DPB[i];
218*437bfbebSnyanmisaka if ((ref->slot_index != 0xff) && ref->sequence == s->seq_decode) {
219*437bfbebSnyanmisaka if (ref->poc == poc || (ref->poc & LtMask) == poc)
220*437bfbebSnyanmisaka return ref;
221*437bfbebSnyanmisaka }
222*437bfbebSnyanmisaka }
223*437bfbebSnyanmisaka mpp_err("cur_poc %d Could not find ref with POC %d\n", s->poc, poc);
224*437bfbebSnyanmisaka return NULL;
225*437bfbebSnyanmisaka }
226*437bfbebSnyanmisaka
mark_ref(HEVCFrame * frame,int flag)227*437bfbebSnyanmisaka static void mark_ref(HEVCFrame *frame, int flag)
228*437bfbebSnyanmisaka {
229*437bfbebSnyanmisaka frame->flags &= ~(HEVC_FRAME_FLAG_LONG_REF | HEVC_FRAME_FLAG_SHORT_REF);
230*437bfbebSnyanmisaka frame->flags |= flag;
231*437bfbebSnyanmisaka }
232*437bfbebSnyanmisaka
generate_missing_ref(HEVCContext * s,int poc)233*437bfbebSnyanmisaka static HEVCFrame *generate_missing_ref(HEVCContext *s, int poc)
234*437bfbebSnyanmisaka {
235*437bfbebSnyanmisaka HEVCFrame *frame;
236*437bfbebSnyanmisaka h265d_dbg(H265D_DBG_REF, "generate_missing_ref in \n");
237*437bfbebSnyanmisaka frame = alloc_frame(s);
238*437bfbebSnyanmisaka if (!frame)
239*437bfbebSnyanmisaka return NULL;
240*437bfbebSnyanmisaka frame->poc = poc;
241*437bfbebSnyanmisaka
242*437bfbebSnyanmisaka mpp_frame_set_errinfo(frame->frame, 1);
243*437bfbebSnyanmisaka mpp_buf_slot_set_prop(s->slots, frame->slot_index, SLOT_FRAME, frame->frame);
244*437bfbebSnyanmisaka mpp_buf_slot_set_flag(s->slots, frame->slot_index, SLOT_CODEC_READY);
245*437bfbebSnyanmisaka mpp_buf_slot_set_flag(s->slots, frame->slot_index, SLOT_CODEC_USE);
246*437bfbebSnyanmisaka mpp_frame_set_poc(frame->frame, poc);
247*437bfbebSnyanmisaka h265d_dbg(H265D_DBG_REF, "generate_missing_ref frame poc %d slot_index %d", poc, frame->slot_index);
248*437bfbebSnyanmisaka frame->sequence = s->seq_decode;
249*437bfbebSnyanmisaka frame->flags = 0;
250*437bfbebSnyanmisaka return frame;
251*437bfbebSnyanmisaka }
252*437bfbebSnyanmisaka
253*437bfbebSnyanmisaka /* add a reference with the given poc to the list and mark it as used in DPB */
add_candidate_ref(HEVCContext * s,RefPicList * list,int poc,int ref_flag,RK_U32 cur_used)254*437bfbebSnyanmisaka static int add_candidate_ref(HEVCContext *s, RefPicList *list,
255*437bfbebSnyanmisaka int poc, int ref_flag, RK_U32 cur_used)
256*437bfbebSnyanmisaka {
257*437bfbebSnyanmisaka HEVCFrame *ref = find_ref_idx(s, poc);
258*437bfbebSnyanmisaka
259*437bfbebSnyanmisaka if (!ref) {
260*437bfbebSnyanmisaka ref = generate_missing_ref(s, poc);
261*437bfbebSnyanmisaka if (!ref)
262*437bfbebSnyanmisaka return MPP_ERR_NOMEM;
263*437bfbebSnyanmisaka
264*437bfbebSnyanmisaka ref->error_flag = 1;
265*437bfbebSnyanmisaka }
266*437bfbebSnyanmisaka
267*437bfbebSnyanmisaka list->list[list->nb_refs] = ref->poc;
268*437bfbebSnyanmisaka list->ref[list->nb_refs] = ref;
269*437bfbebSnyanmisaka list->nb_refs++;
270*437bfbebSnyanmisaka if (ref_flag) {
271*437bfbebSnyanmisaka h265d_dbg(H265D_DBG_REF, "set ref poc = %d ref->slot_index %d", ref->poc, ref->slot_index);
272*437bfbebSnyanmisaka mpp_buf_slot_set_flag(s->slots, ref->slot_index, SLOT_CODEC_USE);
273*437bfbebSnyanmisaka }
274*437bfbebSnyanmisaka mark_ref(ref, ref_flag);
275*437bfbebSnyanmisaka if (ref->error_flag && cur_used) {
276*437bfbebSnyanmisaka s->miss_ref_flag = 1;
277*437bfbebSnyanmisaka }
278*437bfbebSnyanmisaka return 0;
279*437bfbebSnyanmisaka }
280*437bfbebSnyanmisaka
mpp_hevc_frame_rps(HEVCContext * s)281*437bfbebSnyanmisaka RK_S32 mpp_hevc_frame_rps(HEVCContext *s)
282*437bfbebSnyanmisaka {
283*437bfbebSnyanmisaka
284*437bfbebSnyanmisaka const ShortTermRPS *short_rps = s->sh.short_term_rps;
285*437bfbebSnyanmisaka const LongTermRPS *long_rps = &s->sh.long_term_rps;
286*437bfbebSnyanmisaka RefPicList *rps = s->rps;
287*437bfbebSnyanmisaka RK_S32 ret;
288*437bfbebSnyanmisaka RK_U32 i;
289*437bfbebSnyanmisaka
290*437bfbebSnyanmisaka if (!short_rps) {
291*437bfbebSnyanmisaka rps[0].nb_refs = rps[1].nb_refs = 0;
292*437bfbebSnyanmisaka return 0;
293*437bfbebSnyanmisaka }
294*437bfbebSnyanmisaka
295*437bfbebSnyanmisaka /* clear the reference flags on all frames except the current one */
296*437bfbebSnyanmisaka for (i = 0; i < MPP_ARRAY_ELEMS(s->DPB); i++) {
297*437bfbebSnyanmisaka HEVCFrame *frame = &s->DPB[i];
298*437bfbebSnyanmisaka mark_ref(frame, 0);
299*437bfbebSnyanmisaka }
300*437bfbebSnyanmisaka
301*437bfbebSnyanmisaka for (i = 0; i < NB_RPS_TYPE; i++)
302*437bfbebSnyanmisaka rps[i].nb_refs = 0;
303*437bfbebSnyanmisaka
304*437bfbebSnyanmisaka /* add the short refs */
305*437bfbebSnyanmisaka for (i = 0; short_rps && (RK_S32)i < short_rps->num_delta_pocs; i++) {
306*437bfbebSnyanmisaka int poc = s->poc + short_rps->delta_poc[i];
307*437bfbebSnyanmisaka int list;
308*437bfbebSnyanmisaka
309*437bfbebSnyanmisaka if (!short_rps->used[i])
310*437bfbebSnyanmisaka list = ST_FOLL;
311*437bfbebSnyanmisaka else if (i < short_rps->num_negative_pics)
312*437bfbebSnyanmisaka list = ST_CURR_BEF;
313*437bfbebSnyanmisaka else
314*437bfbebSnyanmisaka list = ST_CURR_AFT;
315*437bfbebSnyanmisaka
316*437bfbebSnyanmisaka ret = add_candidate_ref(s, &rps[list], poc, HEVC_FRAME_FLAG_SHORT_REF, ST_FOLL != list);
317*437bfbebSnyanmisaka if (ret < 0)
318*437bfbebSnyanmisaka return ret;
319*437bfbebSnyanmisaka }
320*437bfbebSnyanmisaka
321*437bfbebSnyanmisaka /* add the long refs */
322*437bfbebSnyanmisaka for (i = 0; long_rps && i < long_rps->nb_refs; i++) {
323*437bfbebSnyanmisaka int poc = long_rps->poc[i];
324*437bfbebSnyanmisaka int list = long_rps->used[i] ? LT_CURR : LT_FOLL;
325*437bfbebSnyanmisaka
326*437bfbebSnyanmisaka ret = add_candidate_ref(s, &rps[list], poc, HEVC_FRAME_FLAG_LONG_REF, LT_FOLL != list);
327*437bfbebSnyanmisaka if (ret < 0)
328*437bfbebSnyanmisaka return ret;
329*437bfbebSnyanmisaka }
330*437bfbebSnyanmisaka /* release any frames that are now unused */
331*437bfbebSnyanmisaka for (i = 0; i < MPP_ARRAY_ELEMS(s->DPB); i++) {
332*437bfbebSnyanmisaka mpp_hevc_unref_frame(s, &s->DPB[i], 0);
333*437bfbebSnyanmisaka }
334*437bfbebSnyanmisaka /*
335*437bfbebSnyanmisaka * flush for CRA frame if there has frame poc > cur poc in dpb.
336*437bfbebSnyanmisaka */
337*437bfbebSnyanmisaka if (IS_CRA(s)) {
338*437bfbebSnyanmisaka for (i = 0; i < MPP_ARRAY_ELEMS(s->DPB); i++) {
339*437bfbebSnyanmisaka HEVCFrame *ref = &s->DPB[i];
340*437bfbebSnyanmisaka
341*437bfbebSnyanmisaka if ((ref->slot_index != 0xff) && (ref->poc > s->poc)) {
342*437bfbebSnyanmisaka h265d_flush(s->h265dctx);
343*437bfbebSnyanmisaka break;
344*437bfbebSnyanmisaka }
345*437bfbebSnyanmisaka }
346*437bfbebSnyanmisaka }
347*437bfbebSnyanmisaka
348*437bfbebSnyanmisaka return 0;
349*437bfbebSnyanmisaka }
350*437bfbebSnyanmisaka
mpp_hevc_compute_poc(HEVCContext * s,int poc_lsb)351*437bfbebSnyanmisaka int mpp_hevc_compute_poc(HEVCContext *s, int poc_lsb)
352*437bfbebSnyanmisaka {
353*437bfbebSnyanmisaka RK_S32 max_poc_lsb = 1 << s->sps->log2_max_poc_lsb;
354*437bfbebSnyanmisaka RK_S32 prev_poc_lsb = s->pocTid0 % max_poc_lsb;
355*437bfbebSnyanmisaka RK_S32 prev_poc_msb = s->pocTid0 - prev_poc_lsb;
356*437bfbebSnyanmisaka RK_S32 poc_msb;
357*437bfbebSnyanmisaka
358*437bfbebSnyanmisaka if (poc_lsb < prev_poc_lsb && prev_poc_lsb - poc_lsb >= max_poc_lsb / 2)
359*437bfbebSnyanmisaka poc_msb = prev_poc_msb + max_poc_lsb;
360*437bfbebSnyanmisaka else if (poc_lsb > prev_poc_lsb && poc_lsb - prev_poc_lsb > max_poc_lsb / 2)
361*437bfbebSnyanmisaka poc_msb = prev_poc_msb - max_poc_lsb;
362*437bfbebSnyanmisaka else
363*437bfbebSnyanmisaka poc_msb = prev_poc_msb;
364*437bfbebSnyanmisaka
365*437bfbebSnyanmisaka // For BLA picture types, POCmsb is set to 0.
366*437bfbebSnyanmisaka if (s->nal_unit_type == NAL_BLA_W_LP ||
367*437bfbebSnyanmisaka s->nal_unit_type == NAL_BLA_W_RADL ||
368*437bfbebSnyanmisaka s->nal_unit_type == NAL_BLA_N_LP)
369*437bfbebSnyanmisaka poc_msb = 0;
370*437bfbebSnyanmisaka
371*437bfbebSnyanmisaka return poc_msb + poc_lsb;
372*437bfbebSnyanmisaka }
373*437bfbebSnyanmisaka
mpp_hevc_frame_nb_refs(HEVCContext * s)374*437bfbebSnyanmisaka int mpp_hevc_frame_nb_refs(HEVCContext *s)
375*437bfbebSnyanmisaka {
376*437bfbebSnyanmisaka RK_S32 ret = 0;
377*437bfbebSnyanmisaka RK_S32 i;
378*437bfbebSnyanmisaka const ShortTermRPS *rps = s->sh.short_term_rps;
379*437bfbebSnyanmisaka LongTermRPS *long_rps = &s->sh.long_term_rps;
380*437bfbebSnyanmisaka
381*437bfbebSnyanmisaka if (s->sh.slice_type == I_SLICE) {
382*437bfbebSnyanmisaka return 0;
383*437bfbebSnyanmisaka }
384*437bfbebSnyanmisaka if (rps) {
385*437bfbebSnyanmisaka for (i = 0; (RK_U32)i < rps->num_negative_pics; i++)
386*437bfbebSnyanmisaka ret += !!rps->used[i];
387*437bfbebSnyanmisaka for (; i < rps->num_delta_pocs; i++)
388*437bfbebSnyanmisaka ret += !!rps->used[i];
389*437bfbebSnyanmisaka }
390*437bfbebSnyanmisaka
391*437bfbebSnyanmisaka if (long_rps) {
392*437bfbebSnyanmisaka for (i = 0; i < long_rps->nb_refs; i++)
393*437bfbebSnyanmisaka ret += !!long_rps->used[i];
394*437bfbebSnyanmisaka }
395*437bfbebSnyanmisaka return ret;
396*437bfbebSnyanmisaka }
397*437bfbebSnyanmisaka
398