Line | Branch | Exec | Source |
---|---|---|---|
1 | /* | ||
2 | * HEVC video decoder | ||
3 | * | ||
4 | * Copyright (C) 2012 - 2013 Guillaume Martres | ||
5 | * Copyright (C) 2012 - 2013 Gildas Cocherel | ||
6 | * | ||
7 | * This file is part of FFmpeg. | ||
8 | * | ||
9 | * FFmpeg is free software; you can redistribute it and/or | ||
10 | * modify it under the terms of the GNU Lesser General Public | ||
11 | * License as published by the Free Software Foundation; either | ||
12 | * version 2.1 of the License, or (at your option) any later version. | ||
13 | * | ||
14 | * FFmpeg is distributed in the hope that it will be useful, | ||
15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
17 | * Lesser General Public License for more details. | ||
18 | * | ||
19 | * You should have received a copy of the GNU Lesser General Public | ||
20 | * License along with FFmpeg; if not, write to the Free Software | ||
21 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA | ||
22 | */ | ||
23 | |||
24 | #include "libavutil/container_fifo.h" | ||
25 | #include "libavutil/mem.h" | ||
26 | #include "libavutil/stereo3d.h" | ||
27 | |||
28 | #include "decode.h" | ||
29 | #include "hevc.h" | ||
30 | #include "hevcdec.h" | ||
31 | #include "progressframe.h" | ||
32 | #include "libavutil/refstruct.h" | ||
33 | |||
34 | 397692 | void ff_hevc_unref_frame(HEVCFrame *frame, int flags) | |
35 | { | ||
36 | 397692 | frame->flags &= ~flags; | |
37 |
2/2✓ Branch 0 taken 339103 times.
✓ Branch 1 taken 58589 times.
|
397692 | if (!(frame->flags & ~HEVC_FRAME_FLAG_CORRUPT)) |
38 | 339103 | frame->flags = 0; | |
39 |
2/2✓ Branch 0 taken 339103 times.
✓ Branch 1 taken 58589 times.
|
397692 | if (!frame->flags) { |
40 | 339103 | ff_progress_frame_unref(&frame->tf); | |
41 | 339103 | av_frame_unref(frame->frame_grain); | |
42 | 339103 | frame->needs_fg = 0; | |
43 | |||
44 | 339103 | av_refstruct_unref(&frame->pps); | |
45 | 339103 | av_refstruct_unref(&frame->tab_mvf); | |
46 | |||
47 | 339103 | av_refstruct_unref(&frame->rpl); | |
48 | 339103 | frame->nb_rpl_elems = 0; | |
49 | 339103 | av_refstruct_unref(&frame->rpl_tab); | |
50 | 339103 | frame->refPicList = NULL; | |
51 | |||
52 | 339103 | av_refstruct_unref(&frame->hwaccel_picture_private); | |
53 | } | ||
54 | 397692 | } | |
55 | |||
56 | 4687824 | const RefPicList *ff_hevc_get_ref_list(const HEVCFrame *ref, int x0, int y0) | |
57 | { | ||
58 | 4687824 | const HEVCSPS *sps = ref->pps->sps; | |
59 | 4687824 | int x_cb = x0 >> sps->log2_ctb_size; | |
60 | 4687824 | int y_cb = y0 >> sps->log2_ctb_size; | |
61 | 4687824 | int pic_width_cb = sps->ctb_width; | |
62 | 4687824 | int ctb_addr_ts = ref->pps->ctb_addr_rs_to_ts[y_cb * pic_width_cb + x_cb]; | |
63 | 4687824 | return &ref->rpl_tab[ctb_addr_ts]->refPicList[0]; | |
64 | } | ||
65 | |||
66 | 835 | void ff_hevc_clear_refs(HEVCLayerContext *l) | |
67 | { | ||
68 | int i; | ||
69 |
2/2✓ Branch 0 taken 26720 times.
✓ Branch 1 taken 835 times.
|
27555 | for (i = 0; i < FF_ARRAY_ELEMS(l->DPB); i++) |
70 | 26720 | ff_hevc_unref_frame(&l->DPB[i], | |
71 | HEVC_FRAME_FLAG_SHORT_REF | | ||
72 | HEVC_FRAME_FLAG_LONG_REF); | ||
73 | 835 | } | |
74 | |||
75 | 8 | void ff_hevc_flush_dpb(HEVCContext *s) | |
76 | { | ||
77 |
2/2✓ Branch 0 taken 16 times.
✓ Branch 1 taken 8 times.
|
24 | for (int layer = 0; layer < FF_ARRAY_ELEMS(s->layers); layer++) { |
78 | 16 | HEVCLayerContext *l = &s->layers[layer]; | |
79 |
2/2✓ Branch 0 taken 512 times.
✓ Branch 1 taken 16 times.
|
528 | for (int i = 0; i < FF_ARRAY_ELEMS(l->DPB); i++) |
80 | 512 | ff_hevc_unref_frame(&l->DPB[i], ~0); | |
81 | } | ||
82 | 8 | } | |
83 | |||
84 | 50 | static int replace_alpha_plane(AVFrame *alpha, AVFrame *base) | |
85 | { | ||
86 | 50 | AVBufferRef *base_a = av_frame_get_plane_buffer(base, 3); | |
87 | 50 | uintptr_t data = (uintptr_t)alpha->data[0]; | |
88 | int ret; | ||
89 | |||
90 |
2/4✓ Branch 0 taken 50 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 50 times.
✗ Branch 3 not taken.
|
50 | for (int i = 0; i < FF_ARRAY_ELEMS(alpha->buf) && alpha->buf[i]; i++) { |
91 | 50 | AVBufferRef *buf = alpha->buf[i]; | |
92 | 50 | uintptr_t buf_begin = (uintptr_t)buf->data; | |
93 | |||
94 |
2/4✓ Branch 0 taken 50 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 50 times.
✗ Branch 3 not taken.
|
50 | if (data >= buf_begin && data < buf_begin + buf->size) { |
95 | 50 | ret = av_buffer_replace(&alpha->buf[i], base_a); | |
96 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 50 times.
|
50 | if (ret < 0) |
97 | ✗ | return ret; | |
98 | |||
99 | 50 | alpha->linesize[0] = base->linesize[3]; | |
100 | 50 | alpha->data[0] = base->data[3]; | |
101 | |||
102 | 50 | return 0; | |
103 | } | ||
104 | } | ||
105 | |||
106 | ✗ | return AVERROR_BUG; | |
107 | } | ||
108 | |||
109 | 10329 | static HEVCFrame *alloc_frame(HEVCContext *s, HEVCLayerContext *l) | |
110 | { | ||
111 | 10329 | const HEVCVPS *vps = l->sps->vps; | |
112 | 10329 | const int view_id = vps->view_id[s->cur_layer]; | |
113 | int i, j, ret; | ||
114 |
1/2✓ Branch 0 taken 36225 times.
✗ Branch 1 not taken.
|
36225 | for (i = 0; i < FF_ARRAY_ELEMS(l->DPB); i++) { |
115 | 36225 | HEVCFrame *frame = &l->DPB[i]; | |
116 |
2/2✓ Branch 0 taken 25896 times.
✓ Branch 1 taken 10329 times.
|
36225 | if (frame->f) |
117 | 25896 | continue; | |
118 | |||
119 | 10329 | ret = ff_progress_frame_alloc(s->avctx, &frame->tf); | |
120 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 10329 times.
|
10329 | if (ret < 0) |
121 | ✗ | return NULL; | |
122 | |||
123 | // Add LCEVC SEI metadata here, as it's needed in get_buffer() | ||
124 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 10329 times.
|
10329 | if (s->sei.common.lcevc.info) { |
125 | ✗ | HEVCSEILCEVC *lcevc = &s->sei.common.lcevc; | |
126 | ✗ | ret = ff_frame_new_side_data_from_buf(s->avctx, frame->tf.f, | |
127 | AV_FRAME_DATA_LCEVC, &lcevc->info); | ||
128 | ✗ | if (ret < 0) | |
129 | ✗ | goto fail; | |
130 | } | ||
131 | |||
132 | // add view ID side data if it's nontrivial | ||
133 |
5/6✓ Branch 1 taken 10229 times.
✓ Branch 2 taken 100 times.
✓ Branch 3 taken 9670 times.
✓ Branch 4 taken 559 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 9670 times.
|
10329 | if (!ff_hevc_is_alpha_video(s) && (vps->nb_layers > 1 || view_id)) { |
134 | 559 | HEVCSEITDRDI *tdrdi = &s->sei.tdrdi; | |
135 | 559 | AVFrameSideData *sd = av_frame_side_data_new(&frame->f->side_data, | |
136 | 559 | &frame->f->nb_side_data, | |
137 | AV_FRAME_DATA_VIEW_ID, | ||
138 | sizeof(int), 0); | ||
139 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 559 times.
|
559 | if (!sd) |
140 | ✗ | goto fail; | |
141 | 559 | *(int*)sd->data = view_id; | |
142 | |||
143 |
2/2✓ Branch 0 taken 22 times.
✓ Branch 1 taken 537 times.
|
559 | if (tdrdi->num_ref_displays) { |
144 | AVStereo3D *stereo_3d; | ||
145 | |||
146 | 22 | stereo_3d = av_stereo3d_create_side_data(frame->f); | |
147 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 22 times.
|
22 | if (!stereo_3d) |
148 | ✗ | goto fail; | |
149 | |||
150 | 22 | stereo_3d->type = AV_STEREO3D_FRAMESEQUENCE; | |
151 |
2/2✓ Branch 0 taken 11 times.
✓ Branch 1 taken 11 times.
|
22 | if (tdrdi->left_view_id[0] == view_id) |
152 | 11 | stereo_3d->view = AV_STEREO3D_VIEW_LEFT; | |
153 |
1/2✓ Branch 0 taken 11 times.
✗ Branch 1 not taken.
|
11 | else if (tdrdi->right_view_id[0] == view_id) |
154 | 11 | stereo_3d->view = AV_STEREO3D_VIEW_RIGHT; | |
155 | else | ||
156 | ✗ | stereo_3d->view = AV_STEREO3D_VIEW_UNSPEC; | |
157 | } | ||
158 | } | ||
159 | |||
160 | 10329 | ret = ff_progress_frame_get_buffer(s->avctx, &frame->tf, | |
161 | AV_GET_BUFFER_FLAG_REF); | ||
162 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 10329 times.
|
10329 | if (ret < 0) |
163 | ✗ | return NULL; | |
164 | |||
165 | 10329 | frame->rpl = av_refstruct_allocz(s->pkt.nb_nals * sizeof(*frame->rpl)); | |
166 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 10329 times.
|
10329 | if (!frame->rpl) |
167 | ✗ | goto fail; | |
168 | 10329 | frame->nb_rpl_elems = s->pkt.nb_nals; | |
169 | |||
170 | 10329 | frame->tab_mvf = av_refstruct_pool_get(l->tab_mvf_pool); | |
171 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 10329 times.
|
10329 | if (!frame->tab_mvf) |
172 | ✗ | goto fail; | |
173 | |||
174 | 10329 | frame->rpl_tab = av_refstruct_pool_get(l->rpl_tab_pool); | |
175 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 10329 times.
|
10329 | if (!frame->rpl_tab) |
176 | ✗ | goto fail; | |
177 | 10329 | frame->ctb_count = l->sps->ctb_width * l->sps->ctb_height; | |
178 |
2/2✓ Branch 0 taken 1662497 times.
✓ Branch 1 taken 10329 times.
|
1672826 | for (j = 0; j < frame->ctb_count; j++) |
179 | 1662497 | frame->rpl_tab[j] = frame->rpl; | |
180 | |||
181 |
2/2✓ Branch 0 taken 15 times.
✓ Branch 1 taken 10314 times.
|
10329 | if (s->sei.picture_timing.picture_struct == AV_PICTURE_STRUCTURE_TOP_FIELD) |
182 | 15 | frame->f->flags |= AV_FRAME_FLAG_TOP_FIELD_FIRST; | |
183 |
2/2✓ Branch 0 taken 10314 times.
✓ Branch 1 taken 15 times.
|
10329 | if ((s->sei.picture_timing.picture_struct == AV_PICTURE_STRUCTURE_TOP_FIELD) || |
184 |
2/2✓ Branch 0 taken 2 times.
✓ Branch 1 taken 10312 times.
|
10314 | (s->sei.picture_timing.picture_struct == AV_PICTURE_STRUCTURE_BOTTOM_FIELD)) |
185 | 17 | frame->f->flags |= AV_FRAME_FLAG_INTERLACED; | |
186 | |||
187 | 10329 | ret = ff_hwaccel_frame_priv_alloc(s->avctx, &frame->hwaccel_picture_private); | |
188 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 10329 times.
|
10329 | if (ret < 0) |
189 | ✗ | goto fail; | |
190 | |||
191 | 10329 | frame->pps = av_refstruct_ref_c(s->pps); | |
192 |
4/4✓ Branch 0 taken 327 times.
✓ Branch 1 taken 10002 times.
✓ Branch 3 taken 50 times.
✓ Branch 4 taken 277 times.
|
10329 | if (l != &s->layers[0] && ff_hevc_is_alpha_video(s)) { |
193 | 50 | AVFrame *alpha = frame->f; | |
194 | 50 | AVFrame *base = s->layers[0].cur_frame->f; | |
195 | 50 | ret = replace_alpha_plane(alpha, base); | |
196 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 50 times.
|
50 | if (ret < 0) |
197 | ✗ | goto fail; | |
198 | } | ||
199 | |||
200 | 10329 | return frame; | |
201 | ✗ | fail: | |
202 | ✗ | ff_hevc_unref_frame(frame, ~0); | |
203 | ✗ | return NULL; | |
204 | } | ||
205 | ✗ | av_log(s->avctx, AV_LOG_ERROR, "Error allocating frame, DPB full.\n"); | |
206 | ✗ | return NULL; | |
207 | } | ||
208 | |||
209 | 10271 | int ff_hevc_set_new_ref(HEVCContext *s, HEVCLayerContext *l, int poc) | |
210 | { | ||
211 | HEVCFrame *ref; | ||
212 | int i; | ||
213 | int no_output; | ||
214 | |||
215 | /* check that this POC doesn't already exist */ | ||
216 |
2/2✓ Branch 0 taken 328672 times.
✓ Branch 1 taken 10271 times.
|
338943 | for (i = 0; i < FF_ARRAY_ELEMS(l->DPB); i++) { |
217 | 328672 | HEVCFrame *frame = &l->DPB[i]; | |
218 | |||
219 |
3/4✓ Branch 0 taken 47442 times.
✓ Branch 1 taken 281230 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 47442 times.
|
328672 | if (frame->f && frame->poc == poc) { |
220 | ✗ | av_log(s->avctx, AV_LOG_ERROR, "Duplicate POC in a sequence: %d.\n", | |
221 | poc); | ||
222 | ✗ | return AVERROR_INVALIDDATA; | |
223 | } | ||
224 | } | ||
225 | |||
226 | 10271 | ref = alloc_frame(s, l); | |
227 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 10271 times.
|
10271 | if (!ref) |
228 | ✗ | return AVERROR(ENOMEM); | |
229 | |||
230 | 10271 | s->cur_frame = ref; | |
231 | 10271 | l->cur_frame = ref; | |
232 | 10271 | s->collocated_ref = NULL; | |
233 | |||
234 |
3/4✓ Branch 0 taken 327 times.
✓ Branch 1 taken 9944 times.
✓ Branch 2 taken 327 times.
✗ Branch 3 not taken.
|
10271 | ref->base_layer_frame = (l != &s->layers[0] && s->layers[0].cur_frame) ? |
235 | 327 | s->layers[0].cur_frame - s->layers[0].DPB : -1; | |
236 | |||
237 |
3/4✗ Branch 0 not taken.
✓ Branch 1 taken 722 times.
✓ Branch 2 taken 11 times.
✓ Branch 3 taken 9538 times.
|
10271 | no_output = !IS_IRAP(s) && (s->poc < s->recovery_poc) && |
238 |
3/4✓ Branch 0 taken 722 times.
✓ Branch 1 taken 9549 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 11 times.
|
20542 | !(s->avctx->flags & AV_CODEC_FLAG_OUTPUT_CORRUPT) && |
239 | ✗ | !(s->avctx->flags2 & AV_CODEC_FLAG2_SHOW_ALL); | |
240 |
3/4✓ Branch 0 taken 10265 times.
✓ Branch 1 taken 6 times.
✓ Branch 2 taken 10265 times.
✗ Branch 3 not taken.
|
10271 | if (s->sh.pic_output_flag && !no_output) |
241 | 10265 | ref->flags = HEVC_FRAME_FLAG_OUTPUT | HEVC_FRAME_FLAG_SHORT_REF; | |
242 | else | ||
243 | 6 | ref->flags = HEVC_FRAME_FLAG_SHORT_REF; | |
244 | |||
245 | 10271 | ref->poc = poc; | |
246 | 10271 | ref->f->crop_left = l->sps->output_window.left_offset; | |
247 | 10271 | ref->f->crop_right = l->sps->output_window.right_offset; | |
248 | 10271 | ref->f->crop_top = l->sps->output_window.top_offset; | |
249 | 10271 | ref->f->crop_bottom = l->sps->output_window.bottom_offset; | |
250 | |||
251 | 10271 | return 0; | |
252 | } | ||
253 | |||
254 | 10271 | static void unref_missing_refs(HEVCLayerContext *l) | |
255 | { | ||
256 |
2/2✓ Branch 0 taken 328672 times.
✓ Branch 1 taken 10271 times.
|
338943 | for (int i = 0; i < FF_ARRAY_ELEMS(l->DPB); i++) { |
257 | 328672 | HEVCFrame *frame = &l->DPB[i]; | |
258 |
2/2✓ Branch 0 taken 37 times.
✓ Branch 1 taken 328635 times.
|
328672 | if (frame->flags & HEVC_FRAME_FLAG_UNAVAILABLE) { |
259 | 37 | ff_hevc_unref_frame(frame, ~0); | |
260 | } | ||
261 | } | ||
262 | 10271 | } | |
263 | |||
264 | 11005 | int ff_hevc_output_frames(HEVCContext *s, | |
265 | unsigned layers_active_decode, unsigned layers_active_output, | ||
266 | unsigned max_output, unsigned max_dpb, int discard) | ||
267 | { | ||
268 | 10135 | while (1) { | |
269 | 21140 | int nb_dpb[HEVC_VPS_MAX_LAYERS] = { 0 }; | |
270 | 21140 | int nb_output = 0; | |
271 | 21140 | int min_poc = INT_MAX; | |
272 | 21140 | int min_layer = -1; | |
273 | 21140 | int min_idx, ret = 0; | |
274 | |||
275 |
2/2✓ Branch 0 taken 42280 times.
✓ Branch 1 taken 21140 times.
|
63420 | for (int layer = 0; layer < FF_ARRAY_ELEMS(s->layers); layer++) { |
276 | 42280 | HEVCLayerContext *l = &s->layers[layer]; | |
277 | |||
278 |
2/2✓ Branch 0 taken 20208 times.
✓ Branch 1 taken 22072 times.
|
42280 | if (!(layers_active_decode & (1 << layer))) |
279 | 20208 | continue; | |
280 | |||
281 |
2/2✓ Branch 0 taken 706304 times.
✓ Branch 1 taken 22072 times.
|
728376 | for (int i = 0; i < FF_ARRAY_ELEMS(l->DPB); i++) { |
282 | 706304 | HEVCFrame *frame = &l->DPB[i]; | |
283 |
2/2✓ Branch 0 taken 56688 times.
✓ Branch 1 taken 649616 times.
|
706304 | if (frame->flags & HEVC_FRAME_FLAG_OUTPUT) { |
284 | // nb_output counts AUs with an output-pending frame | ||
285 | // in at least one layer | ||
286 |
2/2✓ Branch 0 taken 2357 times.
✓ Branch 1 taken 54331 times.
|
56688 | if (!(frame->base_layer_frame >= 0 && |
287 |
2/2✓ Branch 0 taken 339 times.
✓ Branch 1 taken 2018 times.
|
2357 | (s->layers[0].DPB[frame->base_layer_frame].flags & HEVC_FRAME_FLAG_OUTPUT))) |
288 | 54670 | nb_output++; | |
289 |
4/4✓ Branch 0 taken 39067 times.
✓ Branch 1 taken 17621 times.
✓ Branch 2 taken 12820 times.
✓ Branch 3 taken 26247 times.
|
56688 | if (min_layer < 0 || frame->poc < min_poc) { |
290 | 30441 | min_poc = frame->poc; | |
291 | 30441 | min_idx = i; | |
292 | 30441 | min_layer = layer; | |
293 | } | ||
294 | } | ||
295 | 706304 | nb_dpb[layer] += !!frame->flags; | |
296 | } | ||
297 | } | ||
298 | |||
299 |
4/4✓ Branch 0 taken 11454 times.
✓ Branch 1 taken 9686 times.
✓ Branch 2 taken 7935 times.
✓ Branch 3 taken 3519 times.
|
21140 | if (nb_output > max_output || |
300 | 7935 | (nb_output && | |
301 |
4/4✓ Branch 0 taken 7498 times.
✓ Branch 1 taken 437 times.
✓ Branch 2 taken 12 times.
✓ Branch 3 taken 7486 times.
|
7935 | (nb_dpb[0] > max_dpb || nb_dpb[1] > max_dpb))) { |
302 | 10135 | HEVCFrame *frame = &s->layers[min_layer].DPB[min_idx]; | |
303 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 10135 times.
|
10135 | AVFrame *f = frame->needs_fg ? frame->frame_grain : frame->f; |
304 |
4/4✓ Branch 0 taken 10106 times.
✓ Branch 1 taken 29 times.
✓ Branch 2 taken 10056 times.
✓ Branch 3 taken 50 times.
|
10135 | int output = !discard && (layers_active_output & (1 << min_layer)); |
305 | |||
306 |
2/2✓ Branch 0 taken 10056 times.
✓ Branch 1 taken 79 times.
|
10135 | if (output) { |
307 |
2/2✓ Branch 0 taken 51 times.
✓ Branch 1 taken 10005 times.
|
10056 | if (frame->flags & HEVC_FRAME_FLAG_CORRUPT) |
308 | 51 | f->flags |= AV_FRAME_FLAG_CORRUPT; | |
309 | 10056 | f->pkt_dts = s->pkt_dts; | |
310 | 10056 | ret = av_container_fifo_write(s->output_fifo, f, AV_CONTAINER_FIFO_FLAG_REF); | |
311 | } | ||
312 | 10135 | ff_hevc_unref_frame(frame, HEVC_FRAME_FLAG_OUTPUT); | |
313 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 10135 times.
|
10135 | if (ret < 0) |
314 | 11005 | return ret; | |
315 | |||
316 |
2/2✓ Branch 0 taken 10056 times.
✓ Branch 1 taken 79 times.
|
10135 | av_log(s->avctx, AV_LOG_DEBUG, "%s frame with POC %d/%d.\n", |
317 | output ? "Output" : "Discarded", min_layer, frame->poc); | ||
318 | 10135 | continue; | |
319 | } | ||
320 | 11005 | return 0; | |
321 | } | ||
322 | } | ||
323 | |||
324 | 19073 | static int init_slice_rpl(HEVCContext *s) | |
325 | { | ||
326 | 19073 | HEVCFrame *frame = s->cur_frame; | |
327 | 19073 | int ctb_count = frame->ctb_count; | |
328 | 19073 | int ctb_addr_ts = s->pps->ctb_addr_rs_to_ts[s->sh.slice_segment_addr]; | |
329 | int i; | ||
330 | |||
331 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 19073 times.
|
19073 | if (s->slice_idx >= frame->nb_rpl_elems) |
332 | ✗ | return AVERROR_INVALIDDATA; | |
333 | |||
334 |
2/2✓ Branch 0 taken 2117272 times.
✓ Branch 1 taken 19073 times.
|
2136345 | for (i = ctb_addr_ts; i < ctb_count; i++) |
335 | 2117272 | frame->rpl_tab[i] = frame->rpl + s->slice_idx; | |
336 | |||
337 | 19073 | frame->refPicList = (RefPicList *)frame->rpl_tab[ctb_addr_ts]; | |
338 | |||
339 | 19073 | return 0; | |
340 | } | ||
341 | |||
342 | 19073 | int ff_hevc_slice_rpl(HEVCContext *s) | |
343 | { | ||
344 | 19073 | SliceHeader *sh = &s->sh; | |
345 | |||
346 |
2/2✓ Branch 0 taken 15146 times.
✓ Branch 1 taken 3927 times.
|
19073 | uint8_t nb_list = sh->slice_type == HEVC_SLICE_B ? 2 : 1; |
347 | uint8_t list_idx; | ||
348 | int i, j, ret; | ||
349 | |||
350 | 19073 | ret = init_slice_rpl(s); | |
351 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 19073 times.
|
19073 | if (ret < 0) |
352 | ✗ | return ret; | |
353 | |||
354 | 19073 | if (!(s->rps[ST_CURR_BEF].nb_refs + s->rps[ST_CURR_AFT].nb_refs + | |
355 | 19073 | s->rps[LT_CURR].nb_refs + | |
356 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 19073 times.
|
19073 | s->rps[INTER_LAYER0].nb_refs + s->rps[INTER_LAYER1].nb_refs) && |
357 | ✗ | !s->pps->pps_curr_pic_ref_enabled_flag) { | |
358 | ✗ | av_log(s->avctx, AV_LOG_ERROR, "Zero refs in the frame RPS.\n"); | |
359 | ✗ | return AVERROR_INVALIDDATA; | |
360 | } | ||
361 | |||
362 |
2/2✓ Branch 0 taken 34219 times.
✓ Branch 1 taken 19073 times.
|
53292 | for (list_idx = 0; list_idx < nb_list; list_idx++) { |
363 | 34219 | RefPicList rpl_tmp = { { 0 } }; | |
364 | 34219 | RefPicList *rpl = &s->cur_frame->refPicList[list_idx]; | |
365 | |||
366 | /* The order of the elements is | ||
367 | * ST_CURR_BEF - INTER_LAYER0 - ST_CURR_AFT - LT_CURR - INTER_LAYER1 for the L0 and | ||
368 | * ST_CURR_AFT - INTER_LAYER1 - ST_CURR_BEF - LT_CURR - INTER_LAYER0 for the L1 */ | ||
369 | 102657 | int cand_lists[] = { list_idx ? ST_CURR_AFT : ST_CURR_BEF, | |
370 |
2/2✓ Branch 0 taken 15146 times.
✓ Branch 1 taken 19073 times.
|
34219 | list_idx ? INTER_LAYER1 : INTER_LAYER0, |
371 | 34219 | list_idx ? ST_CURR_BEF : ST_CURR_AFT, | |
372 | LT_CURR, | ||
373 |
2/2✓ Branch 0 taken 15146 times.
✓ Branch 1 taken 19073 times.
|
34219 | list_idx ? INTER_LAYER0 : INTER_LAYER1 |
374 | }; | ||
375 | |||
376 | /* concatenate the candidate lists for the current frame */ | ||
377 |
2/2✓ Branch 0 taken 34237 times.
✓ Branch 1 taken 34219 times.
|
68456 | while (rpl_tmp.nb_refs < sh->nb_refs[list_idx]) { |
378 |
2/2✓ Branch 0 taken 171185 times.
✓ Branch 1 taken 34237 times.
|
205422 | for (i = 0; i < FF_ARRAY_ELEMS(cand_lists); i++) { |
379 | 171185 | RefPicList *rps = &s->rps[cand_lists[i]]; | |
380 |
3/4✓ Branch 0 taken 123605 times.
✓ Branch 1 taken 171185 times.
✓ Branch 2 taken 123605 times.
✗ Branch 3 not taken.
|
294790 | for (j = 0; j < rps->nb_refs && rpl_tmp.nb_refs < HEVC_MAX_REFS; j++) { |
381 | 123605 | rpl_tmp.list[rpl_tmp.nb_refs] = rps->list[j]; | |
382 | 123605 | rpl_tmp.ref[rpl_tmp.nb_refs] = rps->ref[j]; | |
383 | // multiview inter-layer refs are treated as long-term here, | ||
384 | // cf. G.8.1.3 | ||
385 | 369775 | rpl_tmp.isLongTerm[rpl_tmp.nb_refs] = cand_lists[i] == LT_CURR || | |
386 |
4/4✓ Branch 0 taken 122565 times.
✓ Branch 1 taken 1040 times.
✓ Branch 2 taken 122176 times.
✓ Branch 3 taken 389 times.
|
245781 | cand_lists[i] == INTER_LAYER0 || |
387 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 122176 times.
|
122176 | cand_lists[i] == INTER_LAYER1; |
388 | 123605 | rpl_tmp.nb_refs++; | |
389 | } | ||
390 | } | ||
391 | // Construct RefPicList0, RefPicList1 (8-8, 8-10) | ||
392 |
1/4✗ Branch 0 not taken.
✓ Branch 1 taken 34237 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
|
34237 | if (s->pps->pps_curr_pic_ref_enabled_flag && rpl_tmp.nb_refs < HEVC_MAX_REFS) { |
393 | ✗ | rpl_tmp.list[rpl_tmp.nb_refs] = s->cur_frame->poc; | |
394 | ✗ | rpl_tmp.ref[rpl_tmp.nb_refs] = s->cur_frame; | |
395 | ✗ | rpl_tmp.isLongTerm[rpl_tmp.nb_refs] = 1; | |
396 | ✗ | rpl_tmp.nb_refs++; | |
397 | } | ||
398 | } | ||
399 | |||
400 | /* reorder the references if necessary */ | ||
401 |
2/2✓ Branch 0 taken 1900 times.
✓ Branch 1 taken 32319 times.
|
34219 | if (sh->rpl_modification_flag[list_idx]) { |
402 |
2/2✓ Branch 0 taken 4554 times.
✓ Branch 1 taken 1900 times.
|
6454 | for (i = 0; i < sh->nb_refs[list_idx]; i++) { |
403 | 4554 | int idx = sh->list_entry_lx[list_idx][i]; | |
404 | |||
405 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 4554 times.
|
4554 | if (idx >= rpl_tmp.nb_refs) { |
406 | ✗ | av_log(s->avctx, AV_LOG_ERROR, "Invalid reference index.\n"); | |
407 | ✗ | return AVERROR_INVALIDDATA; | |
408 | } | ||
409 | |||
410 | 4554 | rpl->list[i] = rpl_tmp.list[idx]; | |
411 | 4554 | rpl->ref[i] = rpl_tmp.ref[idx]; | |
412 | 4554 | rpl->isLongTerm[i] = rpl_tmp.isLongTerm[idx]; | |
413 | 4554 | rpl->nb_refs++; | |
414 | } | ||
415 | } else { | ||
416 | 32319 | memcpy(rpl, &rpl_tmp, sizeof(*rpl)); | |
417 | 32319 | rpl->nb_refs = FFMIN(rpl->nb_refs, sh->nb_refs[list_idx]); | |
418 | } | ||
419 | |||
420 | // 8-9 | ||
421 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 34219 times.
|
34219 | if (s->pps->pps_curr_pic_ref_enabled_flag && |
422 | ✗ | !sh->rpl_modification_flag[list_idx] && | |
423 | ✗ | rpl_tmp.nb_refs > sh->nb_refs[L0]) { | |
424 | ✗ | rpl->list[sh->nb_refs[L0] - 1] = s->cur_frame->poc; | |
425 | ✗ | rpl->ref[sh->nb_refs[L0] - 1] = s->cur_frame; | |
426 | } | ||
427 | |||
428 |
2/2✓ Branch 0 taken 19072 times.
✓ Branch 1 taken 15147 times.
|
34219 | if (sh->collocated_list == list_idx && |
429 |
1/2✓ Branch 0 taken 19072 times.
✗ Branch 1 not taken.
|
19072 | sh->collocated_ref_idx < rpl->nb_refs) |
430 | 19072 | s->collocated_ref = rpl->ref[sh->collocated_ref_idx]; | |
431 | } | ||
432 | |||
433 | 19073 | return 0; | |
434 | } | ||
435 | |||
436 | 37279 | static HEVCFrame *find_ref_idx(HEVCContext *s, HEVCLayerContext *l, | |
437 | int poc, uint8_t use_msb) | ||
438 | { | ||
439 |
2/2✓ Branch 0 taken 1513 times.
✓ Branch 1 taken 35766 times.
|
37279 | int mask = use_msb ? ~0 : (1 << l->sps->log2_max_poc_lsb) - 1; |
440 | int i; | ||
441 | |||
442 |
2/2✓ Branch 0 taken 152289 times.
✓ Branch 1 taken 58 times.
|
152347 | for (i = 0; i < FF_ARRAY_ELEMS(l->DPB); i++) { |
443 | 152289 | HEVCFrame *ref = &l->DPB[i]; | |
444 |
2/2✓ Branch 0 taken 147499 times.
✓ Branch 1 taken 4790 times.
|
152289 | if (ref->f) { |
445 |
5/6✓ Branch 0 taken 37221 times.
✓ Branch 1 taken 110278 times.
✓ Branch 2 taken 1512 times.
✓ Branch 3 taken 35709 times.
✓ Branch 4 taken 1512 times.
✗ Branch 5 not taken.
|
147499 | if ((ref->poc & mask) == poc && (use_msb || ref->poc != s->poc)) |
446 | 37221 | return ref; | |
447 | } | ||
448 | } | ||
449 | |||
450 |
7/8✓ Branch 0 taken 23 times.
✓ Branch 1 taken 35 times.
✓ Branch 2 taken 22 times.
✓ Branch 3 taken 1 times.
✓ Branch 4 taken 22 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 20 times.
✓ Branch 7 taken 2 times.
|
58 | if (s->nal_unit_type != HEVC_NAL_CRA_NUT && !IS_BLA(s)) |
451 | 20 | av_log(s->avctx, AV_LOG_ERROR, | |
452 | "Could not find ref with POC %d\n", poc); | ||
453 | 58 | return NULL; | |
454 | } | ||
455 | |||
456 | 355680 | static void mark_ref(HEVCFrame *frame, int flag) | |
457 | { | ||
458 | 355680 | frame->flags &= ~(HEVC_FRAME_FLAG_LONG_REF | HEVC_FRAME_FLAG_SHORT_REF); | |
459 | 355680 | frame->flags |= flag; | |
460 | 355680 | } | |
461 | |||
462 | 58 | static HEVCFrame *generate_missing_ref(HEVCContext *s, HEVCLayerContext *l, int poc) | |
463 | { | ||
464 | HEVCFrame *frame; | ||
465 | int i, y; | ||
466 | |||
467 | 58 | frame = alloc_frame(s, l); | |
468 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 58 times.
|
58 | if (!frame) |
469 | ✗ | return NULL; | |
470 | |||
471 |
1/2✓ Branch 0 taken 58 times.
✗ Branch 1 not taken.
|
58 | if (!s->avctx->hwaccel) { |
472 |
2/2✓ Branch 0 taken 38 times.
✓ Branch 1 taken 20 times.
|
58 | if (!l->sps->pixel_shift) { |
473 |
2/2✓ Branch 0 taken 114 times.
✓ Branch 1 taken 38 times.
|
152 | for (i = 0; frame->f->data[i]; i++) |
474 | 114 | memset(frame->f->data[i], 1 << (l->sps->bit_depth - 1), | |
475 | 114 | frame->f->linesize[i] * AV_CEIL_RSHIFT(l->sps->height, l->sps->vshift[i])); | |
476 | } else { | ||
477 |
2/2✓ Branch 0 taken 60 times.
✓ Branch 1 taken 20 times.
|
80 | for (i = 0; frame->f->data[i]; i++) |
478 |
2/2✓ Branch 0 taken 71424 times.
✓ Branch 1 taken 60 times.
|
71484 | for (y = 0; y < (l->sps->height >> l->sps->vshift[i]); y++) { |
479 | 71424 | uint8_t *dst = frame->f->data[i] + y * frame->f->linesize[i]; | |
480 | 71424 | AV_WN16(dst, 1 << (l->sps->bit_depth - 1)); | |
481 | 71424 | av_memcpy_backptr(dst + 2, 2, 2*(l->sps->width >> l->sps->hshift[i]) - 2); | |
482 | } | ||
483 | } | ||
484 | } | ||
485 | |||
486 | 58 | frame->poc = poc; | |
487 | 58 | frame->flags = HEVC_FRAME_FLAG_UNAVAILABLE; | |
488 | |||
489 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 58 times.
|
58 | if (s->avctx->active_thread_type == FF_THREAD_FRAME) |
490 | ✗ | ff_progress_frame_report(&frame->tf, INT_MAX); | |
491 | |||
492 | 58 | return frame; | |
493 | } | ||
494 | |||
495 | /* add a reference with the given poc to the list and mark it as used in DPB */ | ||
496 | 37279 | static int add_candidate_ref(HEVCContext *s, HEVCLayerContext *l, | |
497 | RefPicList *list, | ||
498 | int poc, int ref_flag, uint8_t use_msb) | ||
499 | { | ||
500 | 37279 | HEVCFrame *ref = find_ref_idx(s, l, poc, use_msb); | |
501 | |||
502 |
2/4✓ Branch 0 taken 37279 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 37279 times.
|
37279 | if (ref == s->cur_frame || list->nb_refs >= HEVC_MAX_REFS) |
503 | ✗ | return AVERROR_INVALIDDATA; | |
504 | |||
505 |
3/4✓ Branch 0 taken 723 times.
✓ Branch 1 taken 36556 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 723 times.
|
37279 | if (!IS_IRAP(s)) { |
506 |
4/4✓ Branch 0 taken 36536 times.
✓ Branch 1 taken 20 times.
✓ Branch 2 taken 117 times.
✓ Branch 3 taken 36419 times.
|
36556 | int ref_corrupt = !ref || ref->flags & (HEVC_FRAME_FLAG_CORRUPT | |
507 | HEVC_FRAME_FLAG_UNAVAILABLE); | ||
508 |
3/4✓ Branch 0 taken 36533 times.
✓ Branch 1 taken 23 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 36533 times.
|
36556 | int recovering = HEVC_IS_RECOVERING(s); |
509 | |||
510 |
3/4✓ Branch 0 taken 137 times.
✓ Branch 1 taken 36419 times.
✓ Branch 2 taken 137 times.
✗ Branch 3 not taken.
|
36556 | if (ref_corrupt && !recovering) { |
511 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 137 times.
|
137 | if (!(s->avctx->flags & AV_CODEC_FLAG_OUTPUT_CORRUPT) && |
512 | ✗ | !(s->avctx->flags2 & AV_CODEC_FLAG2_SHOW_ALL)) | |
513 | ✗ | return AVERROR_INVALIDDATA; | |
514 | |||
515 | 137 | s->cur_frame->flags |= HEVC_FRAME_FLAG_CORRUPT; | |
516 | } | ||
517 | } | ||
518 | |||
519 |
2/2✓ Branch 0 taken 58 times.
✓ Branch 1 taken 37221 times.
|
37279 | if (!ref) { |
520 | 58 | ref = generate_missing_ref(s, l, poc); | |
521 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 58 times.
|
58 | if (!ref) |
522 | ✗ | return AVERROR(ENOMEM); | |
523 | } | ||
524 | |||
525 | 37279 | list->list[list->nb_refs] = ref->poc; | |
526 | 37279 | list->ref[list->nb_refs] = ref; | |
527 | 37279 | list->nb_refs++; | |
528 | |||
529 | 37279 | mark_ref(ref, ref_flag); | |
530 | 37279 | return 0; | |
531 | } | ||
532 | |||
533 | 10271 | int ff_hevc_frame_rps(HEVCContext *s, HEVCLayerContext *l) | |
534 | { | ||
535 | 10271 | const ShortTermRPS *short_rps = s->sh.short_term_rps; | |
536 | 10271 | const LongTermRPS *long_rps = &s->sh.long_term_rps; | |
537 | 10271 | RefPicList *rps = s->rps; | |
538 | 10271 | int i, ret = 0; | |
539 | |||
540 | 10271 | unref_missing_refs(l); | |
541 | |||
542 | /* clear the reference flags on all frames except the current one */ | ||
543 |
2/2✓ Branch 0 taken 328672 times.
✓ Branch 1 taken 10271 times.
|
338943 | for (i = 0; i < FF_ARRAY_ELEMS(l->DPB); i++) { |
544 | 328672 | HEVCFrame *frame = &l->DPB[i]; | |
545 | |||
546 |
2/2✓ Branch 0 taken 10271 times.
✓ Branch 1 taken 318401 times.
|
328672 | if (frame == s->cur_frame) |
547 | 10271 | continue; | |
548 | |||
549 | 318401 | mark_ref(frame, 0); | |
550 | } | ||
551 | |||
552 |
2/2✓ Branch 0 taken 71897 times.
✓ Branch 1 taken 10271 times.
|
82168 | for (i = 0; i < NB_RPS_TYPE; i++) |
553 | 71897 | rps[i].nb_refs = 0; | |
554 | |||
555 |
2/2✓ Branch 0 taken 420 times.
✓ Branch 1 taken 9851 times.
|
10271 | if (!short_rps) |
556 | 420 | goto inter_layer; | |
557 | |||
558 | /* add the short refs */ | ||
559 |
2/2✓ Branch 0 taken 35486 times.
✓ Branch 1 taken 9851 times.
|
45337 | for (i = 0; i < short_rps->num_delta_pocs; i++) { |
560 | 35486 | int poc = s->poc + short_rps->delta_poc[i]; | |
561 | int list; | ||
562 | |||
563 |
2/2✓ Branch 0 taken 1766 times.
✓ Branch 1 taken 33720 times.
|
35486 | if (!(short_rps->used & (1 << i))) |
564 | 1766 | list = ST_FOLL; | |
565 |
2/2✓ Branch 0 taken 24456 times.
✓ Branch 1 taken 9264 times.
|
33720 | else if (i < short_rps->num_negative_pics) |
566 | 24456 | list = ST_CURR_BEF; | |
567 | else | ||
568 | 9264 | list = ST_CURR_AFT; | |
569 | |||
570 | 35486 | ret = add_candidate_ref(s, l, &rps[list], poc, | |
571 | HEVC_FRAME_FLAG_SHORT_REF, 1); | ||
572 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 35486 times.
|
35486 | if (ret < 0) |
573 | ✗ | goto fail; | |
574 | } | ||
575 | |||
576 | /* add the long refs */ | ||
577 |
2/2✓ Branch 0 taken 1561 times.
✓ Branch 1 taken 9851 times.
|
11412 | for (i = 0; i < long_rps->nb_refs; i++) { |
578 | 1561 | int poc = long_rps->poc[i]; | |
579 |
2/2✓ Branch 0 taken 574 times.
✓ Branch 1 taken 987 times.
|
1561 | int list = long_rps->used[i] ? LT_CURR : LT_FOLL; |
580 | |||
581 | 1561 | ret = add_candidate_ref(s, l, &rps[list], poc, | |
582 | 1561 | HEVC_FRAME_FLAG_LONG_REF, long_rps->poc_msb_present[i]); | |
583 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 1561 times.
|
1561 | if (ret < 0) |
584 | ✗ | goto fail; | |
585 | } | ||
586 | |||
587 | 9851 | inter_layer: | |
588 | /* add inter-layer refs */ | ||
589 |
2/2✓ Branch 0 taken 10039 times.
✓ Branch 1 taken 232 times.
|
10271 | if (s->sh.inter_layer_pred) { |
590 | 232 | HEVCLayerContext *l0 = &s->layers[0]; | |
591 | |||
592 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 232 times.
|
232 | av_assert0(l != l0); |
593 | |||
594 | /* Given the assumption of at most two layers, refPicSet0Flag is | ||
595 | * always 1, so only RefPicSetInterLayer0 can ever contain a frame. */ | ||
596 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 232 times.
|
232 | if (l0->cur_frame) { |
597 | // inter-layer refs are treated as short-term here, cf. F.8.1.6 | ||
598 | 232 | ret = add_candidate_ref(s, l0, &rps[INTER_LAYER0], l0->cur_frame->poc, | |
599 | HEVC_FRAME_FLAG_SHORT_REF, 1); | ||
600 |
1/2✓ Branch 0 taken 232 times.
✗ Branch 1 not taken.
|
232 | if (ret < 0) |
601 | ✗ | goto fail; | |
602 | } | ||
603 | } | ||
604 | |||
605 | 10271 | fail: | |
606 | /* release any frames that are now unused */ | ||
607 |
2/2✓ Branch 0 taken 328672 times.
✓ Branch 1 taken 10271 times.
|
338943 | for (i = 0; i < FF_ARRAY_ELEMS(l->DPB); i++) |
608 | 328672 | ff_hevc_unref_frame(&l->DPB[i], 0); | |
609 | |||
610 | 10271 | return ret; | |
611 | } | ||
612 | |||
613 | 19159 | int ff_hevc_frame_nb_refs(const SliceHeader *sh, const HEVCPPS *pps, | |
614 | unsigned layer_idx) | ||
615 | { | ||
616 | 19159 | int ret = 0; | |
617 | int i; | ||
618 | 19159 | const ShortTermRPS *rps = sh->short_term_rps; | |
619 | 19159 | const LongTermRPS *long_rps = &sh->long_term_rps; | |
620 | |||
621 |
2/2✓ Branch 0 taken 19152 times.
✓ Branch 1 taken 7 times.
|
19159 | if (rps) { |
622 |
2/2✓ Branch 0 taken 46686 times.
✓ Branch 1 taken 19152 times.
|
65838 | for (i = 0; i < rps->num_negative_pics; i++) |
623 | 46686 | ret += !!(rps->used & (1 << i)); | |
624 |
2/2✓ Branch 0 taken 21066 times.
✓ Branch 1 taken 19152 times.
|
40218 | for (; i < rps->num_delta_pocs; i++) |
625 | 21066 | ret += !!(rps->used & (1 << i)); | |
626 | } | ||
627 | |||
628 |
1/2✓ Branch 0 taken 19159 times.
✗ Branch 1 not taken.
|
19159 | if (long_rps) { |
629 |
2/2✓ Branch 0 taken 1421 times.
✓ Branch 1 taken 19159 times.
|
20580 | for (i = 0; i < long_rps->nb_refs; i++) |
630 | 1421 | ret += !!long_rps->used[i]; | |
631 | } | ||
632 | |||
633 |
2/2✓ Branch 0 taken 232 times.
✓ Branch 1 taken 18927 times.
|
19159 | if (sh->inter_layer_pred) { |
634 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 232 times.
|
232 | av_assert0(pps->sps->vps->num_direct_ref_layers[layer_idx] < 2); |
635 | 232 | ret++; | |
636 | } | ||
637 | |||
638 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 19159 times.
|
19159 | if (pps->pps_curr_pic_ref_enabled_flag) |
639 | ✗ | ret++; | |
640 | |||
641 | 19159 | return ret; | |
642 | } | ||
643 |