/src/ffmpeg/libavcodec/hevc/refs.c
Line | Count | Source (jump to first uncovered line) |
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 "thread.h" |
33 | | #include "libavutil/refstruct.h" |
34 | | |
35 | | void ff_hevc_unref_frame(HEVCFrame *frame, int flags) |
36 | 14.3M | { |
37 | 14.3M | frame->flags &= ~flags; |
38 | 14.3M | if (!(frame->flags & ~HEVC_FRAME_FLAG_CORRUPT)) |
39 | 14.1M | frame->flags = 0; |
40 | 14.3M | if (!frame->flags) { |
41 | 14.1M | ff_progress_frame_unref(&frame->tf); |
42 | 14.1M | av_frame_unref(frame->frame_grain); |
43 | 14.1M | frame->needs_fg = 0; |
44 | | |
45 | 14.1M | av_refstruct_unref(&frame->pps); |
46 | 14.1M | av_refstruct_unref(&frame->tab_mvf); |
47 | | |
48 | 14.1M | av_refstruct_unref(&frame->rpl); |
49 | 14.1M | frame->nb_rpl_elems = 0; |
50 | 14.1M | av_refstruct_unref(&frame->rpl_tab); |
51 | 14.1M | frame->refPicList = NULL; |
52 | | |
53 | 14.1M | av_refstruct_unref(&frame->hwaccel_picture_private); |
54 | 14.1M | } |
55 | 14.3M | } |
56 | | |
57 | | const RefPicList *ff_hevc_get_ref_list(const HEVCFrame *ref, int x0, int y0) |
58 | 11.2M | { |
59 | 11.2M | const HEVCSPS *sps = ref->pps->sps; |
60 | 11.2M | int x_cb = x0 >> sps->log2_ctb_size; |
61 | 11.2M | int y_cb = y0 >> sps->log2_ctb_size; |
62 | 11.2M | int pic_width_cb = sps->ctb_width; |
63 | 11.2M | int ctb_addr_ts = ref->pps->ctb_addr_rs_to_ts[y_cb * pic_width_cb + x_cb]; |
64 | 11.2M | return &ref->rpl_tab[ctb_addr_ts]->refPicList[0]; |
65 | 11.2M | } |
66 | | |
67 | | void ff_hevc_clear_refs(HEVCLayerContext *l) |
68 | 63.1k | { |
69 | 63.1k | int i; |
70 | 2.08M | for (i = 0; i < FF_ARRAY_ELEMS(l->DPB); i++) |
71 | 2.01M | ff_hevc_unref_frame(&l->DPB[i], |
72 | 2.01M | HEVC_FRAME_FLAG_SHORT_REF | |
73 | 2.01M | HEVC_FRAME_FLAG_LONG_REF); |
74 | 63.1k | } |
75 | | |
76 | | void ff_hevc_flush_dpb(HEVCContext *s) |
77 | 127k | { |
78 | 381k | for (int layer = 0; layer < FF_ARRAY_ELEMS(s->layers); layer++) { |
79 | 254k | HEVCLayerContext *l = &s->layers[layer]; |
80 | 8.40M | for (int i = 0; i < FF_ARRAY_ELEMS(l->DPB); i++) |
81 | 8.14M | ff_hevc_unref_frame(&l->DPB[i], ~0); |
82 | 254k | } |
83 | 127k | } |
84 | | |
85 | | static int replace_alpha_plane(AVFrame *alpha, AVFrame *base) |
86 | 0 | { |
87 | 0 | AVBufferRef *base_a = av_frame_get_plane_buffer(base, 3); |
88 | 0 | uintptr_t data = (uintptr_t)alpha->data[0]; |
89 | 0 | int ret; |
90 | |
|
91 | 0 | for (int i = 0; i < FF_ARRAY_ELEMS(alpha->buf) && alpha->buf[i]; i++) { |
92 | 0 | AVBufferRef *buf = alpha->buf[i]; |
93 | 0 | uintptr_t buf_begin = (uintptr_t)buf->data; |
94 | |
|
95 | 0 | if (data >= buf_begin && data < buf_begin + buf->size) { |
96 | 0 | ret = av_buffer_replace(&alpha->buf[i], base_a); |
97 | 0 | if (ret < 0) |
98 | 0 | return ret; |
99 | | |
100 | 0 | alpha->linesize[0] = base->linesize[3]; |
101 | 0 | alpha->data[0] = base->data[3]; |
102 | |
|
103 | 0 | return 0; |
104 | 0 | } |
105 | 0 | } |
106 | | |
107 | 0 | return AVERROR_BUG; |
108 | 0 | } |
109 | | |
110 | | static HEVCFrame *alloc_frame(HEVCContext *s, HEVCLayerContext *l) |
111 | 114k | { |
112 | 114k | const HEVCVPS *vps = l->sps->vps; |
113 | 114k | const int view_id = vps->view_id[s->cur_layer]; |
114 | 114k | int i, j, ret; |
115 | 486k | for (i = 0; i < FF_ARRAY_ELEMS(l->DPB); i++) { |
116 | 486k | HEVCFrame *frame = &l->DPB[i]; |
117 | 486k | if (frame->f) |
118 | 371k | continue; |
119 | | |
120 | 114k | ret = ff_progress_frame_alloc(s->avctx, &frame->tf); |
121 | 114k | if (ret < 0) |
122 | 0 | return NULL; |
123 | | |
124 | | // Add LCEVC SEI metadata here, as it's needed in get_buffer() |
125 | 114k | if (s->sei.common.lcevc.info) { |
126 | 1 | HEVCSEILCEVC *lcevc = &s->sei.common.lcevc; |
127 | 1 | ret = ff_frame_new_side_data_from_buf(s->avctx, frame->tf.f, |
128 | 1 | AV_FRAME_DATA_LCEVC, &lcevc->info); |
129 | 1 | if (ret < 0) |
130 | 0 | goto fail; |
131 | 1 | } |
132 | | |
133 | | // add view ID side data if it's nontrivial |
134 | 114k | if (!ff_hevc_is_alpha_video(s) && (vps->nb_layers > 1 || view_id)) { |
135 | 2.88k | HEVCSEITDRDI *tdrdi = &s->sei.tdrdi; |
136 | 2.88k | AVFrameSideData *sd = av_frame_side_data_new(&frame->f->side_data, |
137 | 2.88k | &frame->f->nb_side_data, |
138 | 2.88k | AV_FRAME_DATA_VIEW_ID, |
139 | 2.88k | sizeof(int), 0); |
140 | 2.88k | if (!sd) |
141 | 0 | goto fail; |
142 | 2.88k | *(int*)sd->data = view_id; |
143 | | |
144 | 2.88k | if (tdrdi->num_ref_displays) { |
145 | 202 | AVStereo3D *stereo_3d; |
146 | | |
147 | 202 | stereo_3d = av_stereo3d_create_side_data(frame->f); |
148 | 202 | if (!stereo_3d) |
149 | 0 | goto fail; |
150 | | |
151 | 202 | stereo_3d->type = AV_STEREO3D_FRAMESEQUENCE; |
152 | 202 | if (tdrdi->left_view_id[0] == view_id) |
153 | 0 | stereo_3d->view = AV_STEREO3D_VIEW_LEFT; |
154 | 202 | else if (tdrdi->right_view_id[0] == view_id) |
155 | 0 | stereo_3d->view = AV_STEREO3D_VIEW_RIGHT; |
156 | 202 | else |
157 | 202 | stereo_3d->view = AV_STEREO3D_VIEW_UNSPEC; |
158 | 202 | } |
159 | 2.88k | } |
160 | | |
161 | 114k | ret = ff_thread_get_buffer(s->avctx, frame->f, AV_GET_BUFFER_FLAG_REF); |
162 | 114k | if (ret < 0) |
163 | 21 | goto fail; |
164 | | |
165 | 114k | frame->rpl = av_refstruct_allocz(s->pkt.nb_nals * sizeof(*frame->rpl)); |
166 | 114k | if (!frame->rpl) |
167 | 0 | goto fail; |
168 | 114k | frame->nb_rpl_elems = s->pkt.nb_nals; |
169 | | |
170 | 114k | frame->tab_mvf = av_refstruct_pool_get(l->tab_mvf_pool); |
171 | 114k | if (!frame->tab_mvf) |
172 | 0 | goto fail; |
173 | | |
174 | 114k | frame->rpl_tab = av_refstruct_pool_get(l->rpl_tab_pool); |
175 | 114k | if (!frame->rpl_tab) |
176 | 0 | goto fail; |
177 | 114k | frame->ctb_count = l->sps->ctb_width * l->sps->ctb_height; |
178 | 7.73M | for (j = 0; j < frame->ctb_count; j++) |
179 | 7.61M | frame->rpl_tab[j] = frame->rpl; |
180 | | |
181 | 114k | if (s->sei.picture_timing.picture_struct == AV_PICTURE_STRUCTURE_TOP_FIELD) |
182 | 511 | frame->f->flags |= AV_FRAME_FLAG_TOP_FIELD_FIRST; |
183 | 114k | if ((s->sei.picture_timing.picture_struct == AV_PICTURE_STRUCTURE_TOP_FIELD) || |
184 | 114k | (s->sei.picture_timing.picture_struct == AV_PICTURE_STRUCTURE_BOTTOM_FIELD)) |
185 | 1.11k | frame->f->flags |= AV_FRAME_FLAG_INTERLACED; |
186 | | |
187 | 114k | ret = ff_hwaccel_frame_priv_alloc(s->avctx, &frame->hwaccel_picture_private); |
188 | 114k | if (ret < 0) |
189 | 0 | goto fail; |
190 | | |
191 | 114k | frame->pps = av_refstruct_ref_c(s->pps); |
192 | 114k | if (l != &s->layers[0] && ff_hevc_is_alpha_video(s)) { |
193 | 0 | AVFrame *alpha = frame->f; |
194 | 0 | AVFrame *base = s->layers[0].cur_frame->f; |
195 | 0 | ret = replace_alpha_plane(alpha, base); |
196 | 0 | if (ret < 0) |
197 | 0 | goto fail; |
198 | 0 | } |
199 | | |
200 | 114k | return frame; |
201 | 21 | fail: |
202 | 21 | ff_hevc_unref_frame(frame, ~0); |
203 | 21 | return NULL; |
204 | 114k | } |
205 | 104 | av_log(s->avctx, AV_LOG_ERROR, "Error allocating frame, DPB full.\n"); |
206 | 104 | return NULL; |
207 | 114k | } |
208 | | |
209 | | int ff_hevc_set_new_ref(HEVCContext *s, HEVCLayerContext *l, int poc) |
210 | 82.4k | { |
211 | 82.4k | HEVCFrame *ref; |
212 | 82.4k | int i; |
213 | 82.4k | int no_output; |
214 | | |
215 | | /* check that this POC doesn't already exist */ |
216 | 2.60M | for (i = 0; i < FF_ARRAY_ELEMS(l->DPB); i++) { |
217 | 2.53M | HEVCFrame *frame = &l->DPB[i]; |
218 | | |
219 | 2.53M | if (frame->f && frame->poc == poc) { |
220 | 3.57k | av_log(s->avctx, AV_LOG_ERROR, "Duplicate POC in a sequence: %d.\n", |
221 | 3.57k | poc); |
222 | 3.57k | return AVERROR_INVALIDDATA; |
223 | 3.57k | } |
224 | 2.53M | } |
225 | | |
226 | 78.9k | ref = alloc_frame(s, l); |
227 | 78.9k | if (!ref) |
228 | 99 | return AVERROR(ENOMEM); |
229 | | |
230 | 78.8k | s->cur_frame = ref; |
231 | 78.8k | l->cur_frame = ref; |
232 | 78.8k | s->collocated_ref = NULL; |
233 | | |
234 | 78.8k | ref->base_layer_frame = (l != &s->layers[0] && s->layers[0].cur_frame) ? |
235 | 78.7k | s->layers[0].cur_frame - s->layers[0].DPB : -1; |
236 | | |
237 | 78.8k | no_output = !IS_IRAP(s) && (s->poc < s->recovery_poc) && |
238 | 78.8k | !(s->avctx->flags & AV_CODEC_FLAG_OUTPUT_CORRUPT) && |
239 | 78.8k | !(s->avctx->flags2 & AV_CODEC_FLAG2_SHOW_ALL); |
240 | 78.8k | if (s->sh.pic_output_flag && !no_output) |
241 | 53.7k | ref->flags = HEVC_FRAME_FLAG_OUTPUT | HEVC_FRAME_FLAG_SHORT_REF; |
242 | 25.0k | else |
243 | 25.0k | ref->flags = HEVC_FRAME_FLAG_SHORT_REF; |
244 | | |
245 | 78.8k | ref->poc = poc; |
246 | 78.8k | ref->f->crop_left = l->sps->output_window.left_offset; |
247 | 78.8k | ref->f->crop_right = l->sps->output_window.right_offset; |
248 | 78.8k | ref->f->crop_top = l->sps->output_window.top_offset; |
249 | 78.8k | ref->f->crop_bottom = l->sps->output_window.bottom_offset; |
250 | | |
251 | 78.8k | return 0; |
252 | 78.9k | } |
253 | | |
254 | | static void unref_missing_refs(HEVCLayerContext *l) |
255 | 78.8k | { |
256 | 2.60M | for (int i = 0; i < FF_ARRAY_ELEMS(l->DPB); i++) { |
257 | 2.52M | HEVCFrame *frame = &l->DPB[i]; |
258 | 2.52M | if (frame->flags & HEVC_FRAME_FLAG_UNAVAILABLE) { |
259 | 17.5k | ff_hevc_unref_frame(frame, ~0); |
260 | 17.5k | } |
261 | 2.52M | } |
262 | 78.8k | } |
263 | | |
264 | | 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 | 138k | { |
268 | 183k | while (1) { |
269 | 183k | int nb_dpb[HEVC_VPS_MAX_LAYERS] = { 0 }; |
270 | 183k | int nb_output = 0; |
271 | 183k | int min_poc = INT_MAX; |
272 | 183k | int min_layer = -1; |
273 | 183k | int min_idx, ret = 0; |
274 | | |
275 | 550k | for (int layer = 0; layer < FF_ARRAY_ELEMS(s->layers); layer++) { |
276 | 367k | HEVCLayerContext *l = &s->layers[layer]; |
277 | | |
278 | 367k | if (!(layers_active_decode & (1 << layer))) |
279 | 201k | continue; |
280 | | |
281 | 5.45M | for (int i = 0; i < FF_ARRAY_ELEMS(l->DPB); i++) { |
282 | 5.28M | HEVCFrame *frame = &l->DPB[i]; |
283 | 5.28M | if (frame->flags & HEVC_FRAME_FLAG_OUTPUT) { |
284 | | // nb_output counts AUs with an output-pending frame |
285 | | // in at least one layer |
286 | 66.2k | if (!(frame->base_layer_frame >= 0 && |
287 | 66.2k | (s->layers[0].DPB[frame->base_layer_frame].flags & HEVC_FRAME_FLAG_OUTPUT))) |
288 | 66.2k | nb_output++; |
289 | 66.2k | if (min_layer < 0 || frame->poc < min_poc) { |
290 | 62.3k | min_poc = frame->poc; |
291 | 62.3k | min_idx = i; |
292 | 62.3k | min_layer = layer; |
293 | 62.3k | } |
294 | 66.2k | } |
295 | 5.28M | nb_dpb[layer] += !!frame->flags; |
296 | 5.28M | } |
297 | 165k | } |
298 | | |
299 | 183k | if (nb_output > max_output || |
300 | 183k | (nb_output && |
301 | 138k | (nb_dpb[0] > max_dpb || nb_dpb[1] > max_dpb))) { |
302 | 44.7k | HEVCFrame *frame = &s->layers[min_layer].DPB[min_idx]; |
303 | 44.7k | AVFrame *f = frame->needs_fg ? frame->frame_grain : frame->f; |
304 | 44.7k | int output = !discard && (layers_active_output & (1 << min_layer)); |
305 | | |
306 | 44.7k | if (output) { |
307 | 44.7k | if (frame->flags & HEVC_FRAME_FLAG_CORRUPT) |
308 | 0 | f->flags |= AV_FRAME_FLAG_CORRUPT; |
309 | 44.7k | f->pkt_dts = s->pkt_dts; |
310 | 44.7k | ret = av_container_fifo_write(s->output_fifo, f, AV_CONTAINER_FIFO_FLAG_REF); |
311 | 44.7k | } |
312 | 44.7k | ff_hevc_unref_frame(frame, HEVC_FRAME_FLAG_OUTPUT); |
313 | 44.7k | if (ret < 0) |
314 | 0 | return ret; |
315 | | |
316 | 44.7k | av_log(s->avctx, AV_LOG_DEBUG, "%s frame with POC %d/%d.\n", |
317 | 44.7k | output ? "Output" : "Discarded", min_layer, frame->poc); |
318 | 44.7k | continue; |
319 | 44.7k | } |
320 | 138k | return 0; |
321 | 183k | } |
322 | 138k | } |
323 | | |
324 | | static int init_slice_rpl(HEVCContext *s) |
325 | 1.73M | { |
326 | 1.73M | HEVCFrame *frame = s->cur_frame; |
327 | 1.73M | int ctb_count = frame->ctb_count; |
328 | 1.73M | int ctb_addr_ts = s->pps->ctb_addr_rs_to_ts[s->sh.slice_segment_addr]; |
329 | 1.73M | int i; |
330 | | |
331 | 1.73M | if (s->slice_idx >= frame->nb_rpl_elems) |
332 | 0 | return AVERROR_INVALIDDATA; |
333 | | |
334 | 5.26M | for (i = ctb_addr_ts; i < ctb_count; i++) |
335 | 3.53M | frame->rpl_tab[i] = frame->rpl + s->slice_idx; |
336 | | |
337 | 1.73M | frame->refPicList = (RefPicList *)frame->rpl_tab[ctb_addr_ts]; |
338 | | |
339 | 1.73M | return 0; |
340 | 1.73M | } |
341 | | |
342 | | int ff_hevc_slice_rpl(HEVCContext *s) |
343 | 17.2k | { |
344 | 17.2k | SliceHeader *sh = &s->sh; |
345 | | |
346 | 17.2k | uint8_t nb_list = sh->slice_type == HEVC_SLICE_B ? 2 : 1; |
347 | 17.2k | uint8_t list_idx; |
348 | 17.2k | int i, j, ret; |
349 | | |
350 | 17.2k | ret = init_slice_rpl(s); |
351 | 17.2k | if (ret < 0) |
352 | 0 | return ret; |
353 | | |
354 | 17.2k | if (!(s->rps[ST_CURR_BEF].nb_refs + s->rps[ST_CURR_AFT].nb_refs + |
355 | 17.2k | s->rps[LT_CURR].nb_refs + |
356 | 17.2k | s->rps[INTER_LAYER0].nb_refs + s->rps[INTER_LAYER1].nb_refs) && |
357 | 17.2k | !s->pps->pps_curr_pic_ref_enabled_flag) { |
358 | 159 | av_log(s->avctx, AV_LOG_ERROR, "Zero refs in the frame RPS.\n"); |
359 | 159 | return AVERROR_INVALIDDATA; |
360 | 159 | } |
361 | | |
362 | 49.8k | for (list_idx = 0; list_idx < nb_list; list_idx++) { |
363 | 32.7k | RefPicList rpl_tmp = { { 0 } }; |
364 | 32.7k | 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 | 32.7k | int cand_lists[] = { list_idx ? ST_CURR_AFT : ST_CURR_BEF, |
370 | 32.7k | list_idx ? INTER_LAYER1 : INTER_LAYER0, |
371 | 32.7k | list_idx ? ST_CURR_BEF : ST_CURR_AFT, |
372 | 32.7k | LT_CURR, |
373 | 32.7k | list_idx ? INTER_LAYER0 : INTER_LAYER1 |
374 | 32.7k | }; |
375 | | |
376 | | /* concatenate the candidate lists for the current frame */ |
377 | 88.4k | while (rpl_tmp.nb_refs < sh->nb_refs[list_idx]) { |
378 | 334k | for (i = 0; i < FF_ARRAY_ELEMS(cand_lists); i++) { |
379 | 278k | RefPicList *rps = &s->rps[cand_lists[i]]; |
380 | 310k | for (j = 0; j < rps->nb_refs && rpl_tmp.nb_refs < HEVC_MAX_REFS; j++) { |
381 | 31.5k | rpl_tmp.list[rpl_tmp.nb_refs] = rps->list[j]; |
382 | 31.5k | 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 | 31.5k | rpl_tmp.isLongTerm[rpl_tmp.nb_refs] = cand_lists[i] == LT_CURR || |
386 | 31.5k | cand_lists[i] == INTER_LAYER0 || |
387 | 31.5k | cand_lists[i] == INTER_LAYER1; |
388 | 31.5k | rpl_tmp.nb_refs++; |
389 | 31.5k | } |
390 | 278k | } |
391 | | // Construct RefPicList0, RefPicList1 (8-8, 8-10) |
392 | 55.7k | if (s->pps->pps_curr_pic_ref_enabled_flag && rpl_tmp.nb_refs < HEVC_MAX_REFS) { |
393 | 42.8k | rpl_tmp.list[rpl_tmp.nb_refs] = s->cur_frame->poc; |
394 | 42.8k | rpl_tmp.ref[rpl_tmp.nb_refs] = s->cur_frame; |
395 | 42.8k | rpl_tmp.isLongTerm[rpl_tmp.nb_refs] = 1; |
396 | 42.8k | rpl_tmp.nb_refs++; |
397 | 42.8k | } |
398 | 55.7k | } |
399 | | |
400 | | /* reorder the references if necessary */ |
401 | 32.7k | if (sh->rpl_modification_flag[list_idx]) { |
402 | 464 | for (i = 0; i < sh->nb_refs[list_idx]; i++) { |
403 | 320 | int idx = sh->list_entry_lx[list_idx][i]; |
404 | | |
405 | 320 | if (idx >= rpl_tmp.nb_refs) { |
406 | 12 | av_log(s->avctx, AV_LOG_ERROR, "Invalid reference index.\n"); |
407 | 12 | return AVERROR_INVALIDDATA; |
408 | 12 | } |
409 | | |
410 | 308 | rpl->list[i] = rpl_tmp.list[idx]; |
411 | 308 | rpl->ref[i] = rpl_tmp.ref[idx]; |
412 | 308 | rpl->isLongTerm[i] = rpl_tmp.isLongTerm[idx]; |
413 | 308 | rpl->nb_refs++; |
414 | 308 | } |
415 | 32.6k | } else { |
416 | 32.6k | memcpy(rpl, &rpl_tmp, sizeof(*rpl)); |
417 | 32.6k | rpl->nb_refs = FFMIN(rpl->nb_refs, sh->nb_refs[list_idx]); |
418 | 32.6k | } |
419 | | |
420 | | // 8-9 |
421 | 32.7k | if (s->pps->pps_curr_pic_ref_enabled_flag && |
422 | 32.7k | !sh->rpl_modification_flag[list_idx] && |
423 | 32.7k | rpl_tmp.nb_refs > sh->nb_refs[L0]) { |
424 | 1.48k | rpl->list[sh->nb_refs[L0] - 1] = s->cur_frame->poc; |
425 | 1.48k | rpl->ref[sh->nb_refs[L0] - 1] = s->cur_frame; |
426 | 1.48k | } |
427 | | |
428 | 32.7k | if (sh->collocated_list == list_idx && |
429 | 32.7k | sh->collocated_ref_idx < rpl->nb_refs) |
430 | 17.0k | s->collocated_ref = rpl->ref[sh->collocated_ref_idx]; |
431 | 32.7k | } |
432 | | |
433 | 17.0k | return 0; |
434 | 17.0k | } |
435 | | |
436 | | static HEVCFrame *find_ref_idx(HEVCContext *s, HEVCLayerContext *l, |
437 | | int poc, uint8_t use_msb) |
438 | 70.7k | { |
439 | 70.7k | int mask = use_msb ? ~0 : (1 << l->sps->log2_max_poc_lsb) - 1; |
440 | 70.7k | int i; |
441 | | |
442 | 2.05M | for (i = 0; i < FF_ARRAY_ELEMS(l->DPB); i++) { |
443 | 1.99M | HEVCFrame *ref = &l->DPB[i]; |
444 | 1.99M | if (ref->f) { |
445 | 429k | if ((ref->poc & mask) == poc && (use_msb || ref->poc != s->poc)) |
446 | 9.25k | return ref; |
447 | 429k | } |
448 | 1.99M | } |
449 | | |
450 | 61.5k | if (s->nal_unit_type != HEVC_NAL_CRA_NUT && !IS_BLA(s)) |
451 | 33.0k | av_log(s->avctx, AV_LOG_ERROR, |
452 | 33.0k | "Could not find ref with POC %d\n", poc); |
453 | 61.5k | return NULL; |
454 | 70.7k | } |
455 | | |
456 | | static void mark_ref(HEVCFrame *frame, int flag) |
457 | 30.0M | { |
458 | 30.0M | frame->flags &= ~(HEVC_FRAME_FLAG_LONG_REF | HEVC_FRAME_FLAG_SHORT_REF); |
459 | 30.0M | frame->flags |= flag; |
460 | 30.0M | } |
461 | | |
462 | | static HEVCFrame *generate_missing_ref(HEVCContext *s, HEVCLayerContext *l, int poc) |
463 | 36.0k | { |
464 | 36.0k | HEVCFrame *frame; |
465 | 36.0k | int i, y; |
466 | | |
467 | 36.0k | frame = alloc_frame(s, l); |
468 | 36.0k | if (!frame) |
469 | 26 | return NULL; |
470 | | |
471 | 36.0k | if (!s->avctx->hwaccel) { |
472 | 36.0k | if (!l->sps->pixel_shift) { |
473 | 93.1k | for (i = 0; frame->f->data[i]; i++) |
474 | 69.8k | memset(frame->f->data[i], 1 << (l->sps->bit_depth - 1), |
475 | 69.8k | frame->f->linesize[i] * AV_CEIL_RSHIFT(l->sps->height, l->sps->vshift[i])); |
476 | 23.2k | } else { |
477 | 50.4k | for (i = 0; frame->f->data[i]; i++) |
478 | 7.90M | for (y = 0; y < (l->sps->height >> l->sps->vshift[i]); y++) { |
479 | 7.86M | uint8_t *dst = frame->f->data[i] + y * frame->f->linesize[i]; |
480 | 7.86M | AV_WN16(dst, 1 << (l->sps->bit_depth - 1)); |
481 | 7.86M | av_memcpy_backptr(dst + 2, 2, 2*(l->sps->width >> l->sps->hshift[i]) - 2); |
482 | 7.86M | } |
483 | 12.7k | } |
484 | 36.0k | } |
485 | | |
486 | 36.0k | frame->poc = poc; |
487 | 36.0k | frame->flags = HEVC_FRAME_FLAG_UNAVAILABLE; |
488 | | |
489 | 36.0k | if (s->avctx->active_thread_type == FF_THREAD_FRAME) |
490 | 0 | ff_progress_frame_report(&frame->tf, INT_MAX); |
491 | | |
492 | 36.0k | return frame; |
493 | 36.0k | } |
494 | | |
495 | | /* add a reference with the given poc to the list and mark it as used in DPB */ |
496 | | static int add_candidate_ref(HEVCContext *s, HEVCLayerContext *l, |
497 | | RefPicList *list, |
498 | | int poc, int ref_flag, uint8_t use_msb) |
499 | 70.7k | { |
500 | 70.7k | HEVCFrame *ref = find_ref_idx(s, l, poc, use_msb); |
501 | | |
502 | 70.7k | if (ref == s->cur_frame || list->nb_refs >= HEVC_MAX_REFS) |
503 | 960 | return AVERROR_INVALIDDATA; |
504 | | |
505 | 69.8k | if (!IS_IRAP(s)) { |
506 | 40.7k | int ref_corrupt = !ref || ref->flags & (HEVC_FRAME_FLAG_CORRUPT | |
507 | 7.71k | HEVC_FRAME_FLAG_UNAVAILABLE); |
508 | 40.7k | int recovering = HEVC_IS_RECOVERING(s); |
509 | | |
510 | 40.7k | if (ref_corrupt && !recovering) { |
511 | 24.9k | if (!(s->avctx->flags & AV_CODEC_FLAG_OUTPUT_CORRUPT) && |
512 | 24.9k | !(s->avctx->flags2 & AV_CODEC_FLAG2_SHOW_ALL)) |
513 | 24.9k | return AVERROR_INVALIDDATA; |
514 | | |
515 | 0 | s->cur_frame->flags |= HEVC_FRAME_FLAG_CORRUPT; |
516 | 0 | } |
517 | 40.7k | } |
518 | | |
519 | 44.8k | if (!ref) { |
520 | 36.0k | ref = generate_missing_ref(s, l, poc); |
521 | 36.0k | if (!ref) |
522 | 26 | return AVERROR(ENOMEM); |
523 | 36.0k | } |
524 | | |
525 | 44.8k | list->list[list->nb_refs] = ref->poc; |
526 | 44.8k | list->ref[list->nb_refs] = ref; |
527 | 44.8k | list->nb_refs++; |
528 | | |
529 | 44.8k | mark_ref(ref, ref_flag); |
530 | 44.8k | return 0; |
531 | 44.8k | } |
532 | | |
533 | | int ff_hevc_frame_rps(HEVCContext *s, HEVCLayerContext *l) |
534 | 78.8k | { |
535 | 78.8k | const ShortTermRPS *short_rps = s->sh.short_term_rps; |
536 | 78.8k | const LongTermRPS *long_rps = &s->sh.long_term_rps; |
537 | 78.8k | RefPicList *rps = s->rps; |
538 | 78.8k | int i, ret = 0; |
539 | | |
540 | 78.8k | unref_missing_refs(l); |
541 | | |
542 | | /* clear the reference flags on all frames except the current one */ |
543 | 2.60M | for (i = 0; i < FF_ARRAY_ELEMS(l->DPB); i++) { |
544 | 2.52M | HEVCFrame *frame = &l->DPB[i]; |
545 | | |
546 | 2.52M | if (frame == s->cur_frame) |
547 | 78.8k | continue; |
548 | | |
549 | 2.44M | mark_ref(frame, 0); |
550 | 2.44M | } |
551 | | |
552 | 630k | for (i = 0; i < NB_RPS_TYPE; i++) |
553 | 551k | rps[i].nb_refs = 0; |
554 | | |
555 | 78.8k | if (!short_rps) |
556 | 40.2k | goto inter_layer; |
557 | | |
558 | | /* add the short refs */ |
559 | 60.2k | for (i = 0; i < short_rps->num_delta_pocs; i++) { |
560 | 46.7k | int poc = s->poc + short_rps->delta_poc[i]; |
561 | 46.7k | int list; |
562 | | |
563 | 46.7k | if (!(short_rps->used & (1 << i))) |
564 | 10.9k | list = ST_FOLL; |
565 | 35.8k | else if (i < short_rps->num_negative_pics) |
566 | 28.9k | list = ST_CURR_BEF; |
567 | 6.92k | else |
568 | 6.92k | list = ST_CURR_AFT; |
569 | | |
570 | 46.7k | ret = add_candidate_ref(s, l, &rps[list], poc, |
571 | 46.7k | HEVC_FRAME_FLAG_SHORT_REF, 1); |
572 | 46.7k | if (ret < 0) |
573 | 25.0k | goto fail; |
574 | 46.7k | } |
575 | | |
576 | | /* add the long refs */ |
577 | 36.5k | for (i = 0; i < long_rps->nb_refs; i++) { |
578 | 23.9k | int poc = long_rps->poc[i]; |
579 | 23.9k | int list = long_rps->used[i] ? LT_CURR : LT_FOLL; |
580 | | |
581 | 23.9k | ret = add_candidate_ref(s, l, &rps[list], poc, |
582 | 23.9k | HEVC_FRAME_FLAG_LONG_REF, long_rps->poc_msb_present[i]); |
583 | 23.9k | if (ret < 0) |
584 | 858 | goto fail; |
585 | 23.9k | } |
586 | | |
587 | 52.8k | inter_layer: |
588 | | /* add inter-layer refs */ |
589 | 52.8k | if (s->sh.inter_layer_pred) { |
590 | 0 | HEVCLayerContext *l0 = &s->layers[0]; |
591 | |
|
592 | 0 | 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 | 0 | if (l0->cur_frame) { |
597 | | // inter-layer refs are treated as short-term here, cf. F.8.1.6 |
598 | 0 | ret = add_candidate_ref(s, l0, &rps[INTER_LAYER0], l0->cur_frame->poc, |
599 | 0 | HEVC_FRAME_FLAG_SHORT_REF, 1); |
600 | 0 | if (ret < 0) |
601 | 0 | goto fail; |
602 | 0 | } |
603 | 0 | } |
604 | | |
605 | 78.8k | fail: |
606 | | /* release any frames that are now unused */ |
607 | 2.60M | for (i = 0; i < FF_ARRAY_ELEMS(l->DPB); i++) |
608 | 2.52M | ff_hevc_unref_frame(&l->DPB[i], 0); |
609 | | |
610 | 78.8k | return ret; |
611 | 52.8k | } |
612 | | |
613 | | int ff_hevc_frame_nb_refs(const SliceHeader *sh, const HEVCPPS *pps, |
614 | | unsigned layer_idx) |
615 | 112k | { |
616 | 112k | int ret = 0; |
617 | 112k | int i; |
618 | 112k | const ShortTermRPS *rps = sh->short_term_rps; |
619 | 112k | const LongTermRPS *long_rps = &sh->long_term_rps; |
620 | | |
621 | 112k | if (rps) { |
622 | 330k | for (i = 0; i < rps->num_negative_pics; i++) |
623 | 229k | ret += !!(rps->used & (1 << i)); |
624 | 229k | for (; i < rps->num_delta_pocs; i++) |
625 | 128k | ret += !!(rps->used & (1 << i)); |
626 | 101k | } |
627 | | |
628 | 112k | if (long_rps) { |
629 | 183k | for (i = 0; i < long_rps->nb_refs; i++) |
630 | 70.9k | ret += !!long_rps->used[i]; |
631 | 112k | } |
632 | | |
633 | 112k | if (sh->inter_layer_pred) { |
634 | 0 | av_assert0(pps->sps->vps->num_direct_ref_layers[layer_idx] < 2); |
635 | 0 | ret++; |
636 | 0 | } |
637 | | |
638 | 112k | if (pps->pps_curr_pic_ref_enabled_flag) |
639 | 28.1k | ret++; |
640 | | |
641 | 112k | return ret; |
642 | 112k | } |