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/avassert.h" | ||
25 | |||
26 | #include "decode.h" | ||
27 | #include "thread.h" | ||
28 | #include "hevc.h" | ||
29 | #include "hevcdec.h" | ||
30 | #include "refstruct.h" | ||
31 | #include "threadframe.h" | ||
32 | |||
33 | 342016 | void ff_hevc_unref_frame(HEVCFrame *frame, int flags) | |
34 | { | ||
35 | /* frame->frame can be NULL if context init failed */ | ||
36 |
3/4✓ Branch 0 taken 342016 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 276882 times.
✓ Branch 3 taken 65134 times.
|
342016 | if (!frame->frame || !frame->frame->buf[0]) |
37 | 276882 | return; | |
38 | |||
39 | 65134 | frame->flags &= ~flags; | |
40 |
2/2✓ Branch 0 taken 9666 times.
✓ Branch 1 taken 55468 times.
|
65134 | if (!frame->flags) { |
41 | 9666 | ff_thread_release_ext_buffer(&frame->tf); | |
42 | 9666 | av_frame_unref(frame->frame_grain); | |
43 | 9666 | frame->needs_fg = 0; | |
44 | |||
45 | 9666 | ff_refstruct_unref(&frame->tab_mvf); | |
46 | |||
47 | 9666 | ff_refstruct_unref(&frame->rpl); | |
48 | 9666 | frame->nb_rpl_elems = 0; | |
49 | 9666 | ff_refstruct_unref(&frame->rpl_tab); | |
50 | 9666 | frame->refPicList = NULL; | |
51 | |||
52 | 9666 | ff_refstruct_unref(&frame->hwaccel_picture_private); | |
53 | } | ||
54 | } | ||
55 | |||
56 | 4576760 | const RefPicList *ff_hevc_get_ref_list(const HEVCContext *s, | |
57 | const HEVCFrame *ref, int x0, int y0) | ||
58 | { | ||
59 | 4576760 | int x_cb = x0 >> s->ps.sps->log2_ctb_size; | |
60 | 4576760 | int y_cb = y0 >> s->ps.sps->log2_ctb_size; | |
61 | 4576760 | int pic_width_cb = s->ps.sps->ctb_width; | |
62 | 4576760 | int ctb_addr_ts = s->ps.pps->ctb_addr_rs_to_ts[y_cb * pic_width_cb + x_cb]; | |
63 | 4576760 | return &ref->rpl_tab[ctb_addr_ts]->refPicList[0]; | |
64 | } | ||
65 | |||
66 | 767 | void ff_hevc_clear_refs(HEVCContext *s) | |
67 | { | ||
68 | int i; | ||
69 |
2/2✓ Branch 0 taken 24544 times.
✓ Branch 1 taken 767 times.
|
25311 | for (i = 0; i < FF_ARRAY_ELEMS(s->DPB); i++) |
70 | 24544 | ff_hevc_unref_frame(&s->DPB[i], | |
71 | HEVC_FRAME_FLAG_SHORT_REF | | ||
72 | HEVC_FRAME_FLAG_LONG_REF); | ||
73 | 767 | } | |
74 | |||
75 | 8 | void ff_hevc_flush_dpb(HEVCContext *s) | |
76 | { | ||
77 | int i; | ||
78 |
2/2✓ Branch 0 taken 256 times.
✓ Branch 1 taken 8 times.
|
264 | for (i = 0; i < FF_ARRAY_ELEMS(s->DPB); i++) |
79 | 256 | ff_hevc_unref_frame(&s->DPB[i], ~0); | |
80 | 8 | } | |
81 | |||
82 | 9599 | static HEVCFrame *alloc_frame(HEVCContext *s) | |
83 | { | ||
84 | int i, j, ret; | ||
85 |
1/2✓ Branch 0 taken 33853 times.
✗ Branch 1 not taken.
|
33853 | for (i = 0; i < FF_ARRAY_ELEMS(s->DPB); i++) { |
86 | 33853 | HEVCFrame *frame = &s->DPB[i]; | |
87 |
2/2✓ Branch 0 taken 24254 times.
✓ Branch 1 taken 9599 times.
|
33853 | if (frame->frame->buf[0]) |
88 | 24254 | continue; | |
89 | |||
90 | 9599 | ret = ff_thread_get_ext_buffer(s->avctx, &frame->tf, | |
91 | AV_GET_BUFFER_FLAG_REF); | ||
92 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 9599 times.
|
9599 | if (ret < 0) |
93 | ✗ | return NULL; | |
94 | |||
95 | 9599 | frame->rpl = ff_refstruct_allocz(s->pkt.nb_nals * sizeof(*frame->rpl)); | |
96 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 9599 times.
|
9599 | if (!frame->rpl) |
97 | ✗ | goto fail; | |
98 | 9599 | frame->nb_rpl_elems = s->pkt.nb_nals; | |
99 | |||
100 | 9599 | frame->tab_mvf = ff_refstruct_pool_get(s->tab_mvf_pool); | |
101 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 9599 times.
|
9599 | if (!frame->tab_mvf) |
102 | ✗ | goto fail; | |
103 | |||
104 | 9599 | frame->rpl_tab = ff_refstruct_pool_get(s->rpl_tab_pool); | |
105 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 9599 times.
|
9599 | if (!frame->rpl_tab) |
106 | ✗ | goto fail; | |
107 | 9599 | frame->ctb_count = s->ps.sps->ctb_width * s->ps.sps->ctb_height; | |
108 |
2/2✓ Branch 0 taken 1490945 times.
✓ Branch 1 taken 9599 times.
|
1500544 | for (j = 0; j < frame->ctb_count; j++) |
109 | 1490945 | frame->rpl_tab[j] = frame->rpl; | |
110 | |||
111 |
2/2✓ Branch 0 taken 15 times.
✓ Branch 1 taken 9584 times.
|
9599 | if (s->sei.picture_timing.picture_struct == AV_PICTURE_STRUCTURE_TOP_FIELD) |
112 | 15 | frame->frame->flags |= AV_FRAME_FLAG_TOP_FIELD_FIRST; | |
113 |
2/2✓ Branch 0 taken 9584 times.
✓ Branch 1 taken 15 times.
|
9599 | if ((s->sei.picture_timing.picture_struct == AV_PICTURE_STRUCTURE_TOP_FIELD) || |
114 |
2/2✓ Branch 0 taken 2 times.
✓ Branch 1 taken 9582 times.
|
9584 | (s->sei.picture_timing.picture_struct == AV_PICTURE_STRUCTURE_BOTTOM_FIELD)) |
115 | 17 | frame->frame->flags |= AV_FRAME_FLAG_INTERLACED; | |
116 | |||
117 | 9599 | ret = ff_hwaccel_frame_priv_alloc(s->avctx, &frame->hwaccel_picture_private); | |
118 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 9599 times.
|
9599 | if (ret < 0) |
119 | ✗ | goto fail; | |
120 | |||
121 | 9599 | return frame; | |
122 | ✗ | fail: | |
123 | ✗ | ff_hevc_unref_frame(frame, ~0); | |
124 | ✗ | return NULL; | |
125 | } | ||
126 | ✗ | av_log(s->avctx, AV_LOG_ERROR, "Error allocating frame, DPB full.\n"); | |
127 | ✗ | return NULL; | |
128 | } | ||
129 | |||
130 | 9535 | int ff_hevc_set_new_ref(HEVCContext *s, AVFrame **frame, int poc) | |
131 | { | ||
132 | HEVCFrame *ref; | ||
133 | int i; | ||
134 | |||
135 | /* check that this POC doesn't already exist */ | ||
136 |
2/2✓ Branch 0 taken 305120 times.
✓ Branch 1 taken 9535 times.
|
314655 | for (i = 0; i < FF_ARRAY_ELEMS(s->DPB); i++) { |
137 | 305120 | HEVCFrame *frame = &s->DPB[i]; | |
138 | |||
139 |
4/4✓ Branch 0 taken 45594 times.
✓ Branch 1 taken 259526 times.
✓ Branch 2 taken 45417 times.
✓ Branch 3 taken 177 times.
|
305120 | if (frame->frame->buf[0] && frame->sequence == s->seq_decode && |
140 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 45417 times.
|
45417 | frame->poc == poc) { |
141 | ✗ | av_log(s->avctx, AV_LOG_ERROR, "Duplicate POC in a sequence: %d.\n", | |
142 | poc); | ||
143 | ✗ | return AVERROR_INVALIDDATA; | |
144 | } | ||
145 | } | ||
146 | |||
147 | 9535 | ref = alloc_frame(s); | |
148 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 9535 times.
|
9535 | if (!ref) |
149 | ✗ | return AVERROR(ENOMEM); | |
150 | |||
151 | 9535 | *frame = ref->frame; | |
152 | 9535 | s->ref = ref; | |
153 | 9535 | s->collocated_ref = NULL; | |
154 | |||
155 |
2/2✓ Branch 0 taken 9529 times.
✓ Branch 1 taken 6 times.
|
9535 | if (s->sh.pic_output_flag) |
156 | 9529 | ref->flags = HEVC_FRAME_FLAG_OUTPUT | HEVC_FRAME_FLAG_SHORT_REF; | |
157 | else | ||
158 | 6 | ref->flags = HEVC_FRAME_FLAG_SHORT_REF; | |
159 | |||
160 | 9535 | ref->poc = poc; | |
161 | 9535 | ref->sequence = s->seq_decode; | |
162 | 9535 | ref->frame->crop_left = s->ps.sps->output_window.left_offset; | |
163 | 9535 | ref->frame->crop_right = s->ps.sps->output_window.right_offset; | |
164 | 9535 | ref->frame->crop_top = s->ps.sps->output_window.top_offset; | |
165 | 9535 | ref->frame->crop_bottom = s->ps.sps->output_window.bottom_offset; | |
166 | |||
167 | 9535 | return 0; | |
168 | } | ||
169 | |||
170 | 9154 | static void unref_missing_refs(HEVCContext *s) | |
171 | { | ||
172 |
2/2✓ Branch 0 taken 292928 times.
✓ Branch 1 taken 9154 times.
|
302082 | for (int i = 0; i < FF_ARRAY_ELEMS(s->DPB); i++) { |
173 | 292928 | HEVCFrame *frame = &s->DPB[i]; | |
174 |
2/2✓ Branch 0 taken 164 times.
✓ Branch 1 taken 292764 times.
|
292928 | if (frame->sequence == HEVC_SEQUENCE_COUNTER_INVALID) { |
175 | 164 | ff_hevc_unref_frame(frame, ~0); | |
176 | } | ||
177 | } | ||
178 | 9154 | } | |
179 | |||
180 | 10023 | int ff_hevc_output_frame(HEVCContext *s, AVFrame *out, int flush) | |
181 | { | ||
182 |
6/6✓ Branch 0 taken 9140 times.
✓ Branch 1 taken 883 times.
✓ Branch 2 taken 327 times.
✓ Branch 3 taken 556 times.
✓ Branch 4 taken 149 times.
✓ Branch 5 taken 407 times.
|
10023 | if (IS_IRAP(s) && s->no_rasl_output_flag == 1) { |
183 | const static int mask = HEVC_FRAME_FLAG_BUMPING | HEVC_FRAME_FLAG_OUTPUT; | ||
184 |
2/2✓ Branch 0 taken 407 times.
✓ Branch 1 taken 13024 times.
|
13431 | for (int i = 0; i < FF_ARRAY_ELEMS(s->DPB); i++) { |
185 | 13024 | HEVCFrame *frame = &s->DPB[i]; | |
186 |
2/2✓ Branch 0 taken 466 times.
✓ Branch 1 taken 12558 times.
|
13024 | if ((frame->flags & mask) == HEVC_FRAME_FLAG_OUTPUT && |
187 |
2/2✓ Branch 0 taken 65 times.
✓ Branch 1 taken 401 times.
|
466 | frame->sequence != s->seq_decode) { |
188 |
2/2✓ Branch 0 taken 26 times.
✓ Branch 1 taken 39 times.
|
65 | if (s->sh.no_output_of_prior_pics_flag == 1) |
189 | 26 | ff_hevc_unref_frame(frame, HEVC_FRAME_FLAG_OUTPUT); | |
190 | else | ||
191 | 39 | frame->flags |= HEVC_FRAME_FLAG_BUMPING; | |
192 | } | ||
193 | } | ||
194 | } | ||
195 | 781 | do { | |
196 | 10804 | int nb_output = 0; | |
197 | 10804 | int min_poc = INT_MAX; | |
198 | int i, min_idx, ret; | ||
199 | |||
200 |
2/2✓ Branch 0 taken 345728 times.
✓ Branch 1 taken 10804 times.
|
356532 | for (i = 0; i < FF_ARRAY_ELEMS(s->DPB); i++) { |
201 | 345728 | HEVCFrame *frame = &s->DPB[i]; | |
202 |
2/2✓ Branch 0 taken 32947 times.
✓ Branch 1 taken 312781 times.
|
345728 | if ((frame->flags & HEVC_FRAME_FLAG_OUTPUT) && |
203 |
2/2✓ Branch 0 taken 32016 times.
✓ Branch 1 taken 931 times.
|
32947 | frame->sequence == s->seq_output) { |
204 | 32016 | nb_output++; | |
205 |
3/4✓ Branch 0 taken 15110 times.
✓ Branch 1 taken 16906 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 15110 times.
|
32016 | if (frame->poc < min_poc || nb_output == 1) { |
206 | 16906 | min_poc = frame->poc; | |
207 | 16906 | min_idx = i; | |
208 | } | ||
209 | } | ||
210 | } | ||
211 | |||
212 | /* wait for more frames before output */ | ||
213 |
5/6✓ Branch 0 taken 10310 times.
✓ Branch 1 taken 494 times.
✓ Branch 2 taken 9491 times.
✓ Branch 3 taken 819 times.
✓ Branch 4 taken 9491 times.
✗ Branch 5 not taken.
|
10804 | if (!flush && s->seq_output == s->seq_decode && s->ps.sps && |
214 |
2/2✓ Branch 0 taken 468 times.
✓ Branch 1 taken 9023 times.
|
9491 | nb_output <= s->ps.sps->temporal_layer[s->ps.sps->max_sub_layers - 1].num_reorder_pics) |
215 | 468 | return 0; | |
216 | |||
217 |
2/2✓ Branch 0 taken 9378 times.
✓ Branch 1 taken 958 times.
|
10336 | if (nb_output) { |
218 | 9378 | HEVCFrame *frame = &s->DPB[min_idx]; | |
219 | |||
220 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 9378 times.
|
9378 | ret = av_frame_ref(out, frame->needs_fg ? frame->frame_grain : frame->frame); |
221 |
2/2✓ Branch 0 taken 2078 times.
✓ Branch 1 taken 7300 times.
|
9378 | if (frame->flags & HEVC_FRAME_FLAG_BUMPING) |
222 | 2078 | ff_hevc_unref_frame(frame, HEVC_FRAME_FLAG_OUTPUT | HEVC_FRAME_FLAG_BUMPING); | |
223 | else | ||
224 | 7300 | ff_hevc_unref_frame(frame, HEVC_FRAME_FLAG_OUTPUT); | |
225 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 9378 times.
|
9378 | if (ret < 0) |
226 | ✗ | return ret; | |
227 | |||
228 |
1/4✗ Branch 0 not taken.
✓ Branch 1 taken 9378 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
|
9378 | if (frame->needs_fg && (ret = av_frame_copy_props(out, frame->frame)) < 0) |
229 | ✗ | return ret; | |
230 | |||
231 |
1/2✓ Branch 0 taken 9378 times.
✗ Branch 1 not taken.
|
9378 | if (!(s->avctx->export_side_data & AV_CODEC_EXPORT_DATA_FILM_GRAIN)) |
232 | 9378 | av_frame_remove_side_data(out, AV_FRAME_DATA_FILM_GRAIN_PARAMS); | |
233 | |||
234 | 9378 | av_log(s->avctx, AV_LOG_DEBUG, | |
235 | "Output frame with POC %d.\n", frame->poc); | ||
236 | 9378 | return 1; | |
237 | } | ||
238 | |||
239 |
2/2✓ Branch 0 taken 781 times.
✓ Branch 1 taken 177 times.
|
958 | if (s->seq_output != s->seq_decode) |
240 | 781 | s->seq_output = (s->seq_output + 1) & HEVC_SEQUENCE_COUNTER_MASK; | |
241 | else | ||
242 | 177 | break; | |
243 | } while (1); | ||
244 | |||
245 | 177 | return 0; | |
246 | } | ||
247 | |||
248 | 8987 | void ff_hevc_bump_frame(HEVCContext *s) | |
249 | { | ||
250 | 8987 | int dpb = 0; | |
251 | 8987 | int min_poc = INT_MAX; | |
252 | int i; | ||
253 | |||
254 |
2/2✓ Branch 0 taken 287584 times.
✓ Branch 1 taken 8987 times.
|
296571 | for (i = 0; i < FF_ARRAY_ELEMS(s->DPB); i++) { |
255 | 287584 | HEVCFrame *frame = &s->DPB[i]; | |
256 |
2/2✓ Branch 0 taken 47693 times.
✓ Branch 1 taken 239891 times.
|
287584 | if ((frame->flags) && |
257 |
2/2✓ Branch 0 taken 47562 times.
✓ Branch 1 taken 131 times.
|
47693 | frame->sequence == s->seq_output && |
258 |
2/2✓ Branch 0 taken 38613 times.
✓ Branch 1 taken 8949 times.
|
47562 | frame->poc != s->poc) { |
259 | 38613 | dpb++; | |
260 | } | ||
261 | } | ||
262 | |||
263 |
3/4✓ Branch 0 taken 8987 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1697 times.
✓ Branch 3 taken 7290 times.
|
8987 | if (s->ps.sps && dpb >= s->ps.sps->temporal_layer[s->ps.sps->max_sub_layers - 1].max_dec_pic_buffering) { |
264 |
2/2✓ Branch 0 taken 54304 times.
✓ Branch 1 taken 1697 times.
|
56001 | for (i = 0; i < FF_ARRAY_ELEMS(s->DPB); i++) { |
265 | 54304 | HEVCFrame *frame = &s->DPB[i]; | |
266 |
2/2✓ Branch 0 taken 10318 times.
✓ Branch 1 taken 43986 times.
|
54304 | if ((frame->flags) && |
267 |
1/2✓ Branch 0 taken 10318 times.
✗ Branch 1 not taken.
|
10318 | frame->sequence == s->seq_output && |
268 |
2/2✓ Branch 0 taken 8621 times.
✓ Branch 1 taken 1697 times.
|
10318 | frame->poc != s->poc) { |
269 |
4/4✓ Branch 0 taken 1446 times.
✓ Branch 1 taken 7175 times.
✓ Branch 2 taken 1444 times.
✓ Branch 3 taken 2 times.
|
8621 | if (frame->flags == HEVC_FRAME_FLAG_OUTPUT && frame->poc < min_poc) { |
270 | 1444 | min_poc = frame->poc; | |
271 | } | ||
272 | } | ||
273 | } | ||
274 | |||
275 |
2/2✓ Branch 0 taken 54304 times.
✓ Branch 1 taken 1697 times.
|
56001 | for (i = 0; i < FF_ARRAY_ELEMS(s->DPB); i++) { |
276 | 54304 | HEVCFrame *frame = &s->DPB[i]; | |
277 |
2/2✓ Branch 0 taken 6790 times.
✓ Branch 1 taken 47514 times.
|
54304 | if (frame->flags & HEVC_FRAME_FLAG_OUTPUT && |
278 |
1/2✓ Branch 0 taken 6790 times.
✗ Branch 1 not taken.
|
6790 | frame->sequence == s->seq_output && |
279 |
2/2✓ Branch 0 taken 2789 times.
✓ Branch 1 taken 4001 times.
|
6790 | frame->poc <= min_poc) { |
280 | 2789 | frame->flags |= HEVC_FRAME_FLAG_BUMPING; | |
281 | } | ||
282 | } | ||
283 | |||
284 | 1697 | dpb--; | |
285 | } | ||
286 | 8987 | } | |
287 | |||
288 | 18436 | static int init_slice_rpl(HEVCContext *s) | |
289 | { | ||
290 | 18436 | HEVCFrame *frame = s->ref; | |
291 | 18436 | int ctb_count = frame->ctb_count; | |
292 | 18436 | int ctb_addr_ts = s->ps.pps->ctb_addr_rs_to_ts[s->sh.slice_segment_addr]; | |
293 | int i; | ||
294 | |||
295 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 18436 times.
|
18436 | if (s->slice_idx >= frame->nb_rpl_elems) |
296 | ✗ | return AVERROR_INVALIDDATA; | |
297 | |||
298 |
2/2✓ Branch 0 taken 1966394 times.
✓ Branch 1 taken 18436 times.
|
1984830 | for (i = ctb_addr_ts; i < ctb_count; i++) |
299 | 1966394 | frame->rpl_tab[i] = frame->rpl + s->slice_idx; | |
300 | |||
301 | 18436 | frame->refPicList = (RefPicList *)frame->rpl_tab[ctb_addr_ts]; | |
302 | |||
303 | 18436 | return 0; | |
304 | } | ||
305 | |||
306 | 18436 | int ff_hevc_slice_rpl(HEVCContext *s) | |
307 | { | ||
308 | 18436 | SliceHeader *sh = &s->sh; | |
309 | |||
310 |
2/2✓ Branch 0 taken 14686 times.
✓ Branch 1 taken 3750 times.
|
18436 | uint8_t nb_list = sh->slice_type == HEVC_SLICE_B ? 2 : 1; |
311 | uint8_t list_idx; | ||
312 | int i, j, ret; | ||
313 | |||
314 | 18436 | ret = init_slice_rpl(s); | |
315 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 18436 times.
|
18436 | if (ret < 0) |
316 | ✗ | return ret; | |
317 | |||
318 | 18436 | if (!(s->rps[ST_CURR_BEF].nb_refs + s->rps[ST_CURR_AFT].nb_refs + | |
319 |
1/4✗ Branch 0 not taken.
✓ Branch 1 taken 18436 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
|
18436 | s->rps[LT_CURR].nb_refs) && !s->ps.pps->pps_curr_pic_ref_enabled_flag) { |
320 | ✗ | av_log(s->avctx, AV_LOG_ERROR, "Zero refs in the frame RPS.\n"); | |
321 | ✗ | return AVERROR_INVALIDDATA; | |
322 | } | ||
323 | |||
324 |
2/2✓ Branch 0 taken 33122 times.
✓ Branch 1 taken 18436 times.
|
51558 | for (list_idx = 0; list_idx < nb_list; list_idx++) { |
325 | 33122 | RefPicList rpl_tmp = { { 0 } }; | |
326 | 33122 | RefPicList *rpl = &s->ref->refPicList[list_idx]; | |
327 | |||
328 | /* The order of the elements is | ||
329 | * ST_CURR_BEF - ST_CURR_AFT - LT_CURR for the L0 and | ||
330 | * ST_CURR_AFT - ST_CURR_BEF - LT_CURR for the L1 */ | ||
331 | 33122 | int cand_lists[3] = { list_idx ? ST_CURR_AFT : ST_CURR_BEF, | |
332 | 33122 | list_idx ? ST_CURR_BEF : ST_CURR_AFT, | |
333 | LT_CURR }; | ||
334 | |||
335 | /* concatenate the candidate lists for the current frame */ | ||
336 |
2/2✓ Branch 0 taken 33140 times.
✓ Branch 1 taken 33122 times.
|
66262 | while (rpl_tmp.nb_refs < sh->nb_refs[list_idx]) { |
337 |
2/2✓ Branch 0 taken 99420 times.
✓ Branch 1 taken 33140 times.
|
132560 | for (i = 0; i < FF_ARRAY_ELEMS(cand_lists); i++) { |
338 | 99420 | RefPicList *rps = &s->rps[cand_lists[i]]; | |
339 |
3/4✓ Branch 0 taken 119794 times.
✓ Branch 1 taken 99420 times.
✓ Branch 2 taken 119794 times.
✗ Branch 3 not taken.
|
219214 | for (j = 0; j < rps->nb_refs && rpl_tmp.nb_refs < HEVC_MAX_REFS; j++) { |
340 | 119794 | rpl_tmp.list[rpl_tmp.nb_refs] = rps->list[j]; | |
341 | 119794 | rpl_tmp.ref[rpl_tmp.nb_refs] = rps->ref[j]; | |
342 | 119794 | rpl_tmp.isLongTerm[rpl_tmp.nb_refs] = i == 2; | |
343 | 119794 | rpl_tmp.nb_refs++; | |
344 | } | ||
345 | } | ||
346 | // Construct RefPicList0, RefPicList1 (8-8, 8-10) | ||
347 |
1/4✗ Branch 0 not taken.
✓ Branch 1 taken 33140 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
|
33140 | if (s->ps.pps->pps_curr_pic_ref_enabled_flag && rpl_tmp.nb_refs < HEVC_MAX_REFS) { |
348 | ✗ | rpl_tmp.list[rpl_tmp.nb_refs] = s->ref->poc; | |
349 | ✗ | rpl_tmp.ref[rpl_tmp.nb_refs] = s->ref; | |
350 | ✗ | rpl_tmp.isLongTerm[rpl_tmp.nb_refs] = 1; | |
351 | ✗ | rpl_tmp.nb_refs++; | |
352 | } | ||
353 | } | ||
354 | |||
355 | /* reorder the references if necessary */ | ||
356 |
2/2✓ Branch 0 taken 1827 times.
✓ Branch 1 taken 31295 times.
|
33122 | if (sh->rpl_modification_flag[list_idx]) { |
357 |
2/2✓ Branch 0 taken 4333 times.
✓ Branch 1 taken 1827 times.
|
6160 | for (i = 0; i < sh->nb_refs[list_idx]; i++) { |
358 | 4333 | int idx = sh->list_entry_lx[list_idx][i]; | |
359 | |||
360 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 4333 times.
|
4333 | if (idx >= rpl_tmp.nb_refs) { |
361 | ✗ | av_log(s->avctx, AV_LOG_ERROR, "Invalid reference index.\n"); | |
362 | ✗ | return AVERROR_INVALIDDATA; | |
363 | } | ||
364 | |||
365 | 4333 | rpl->list[i] = rpl_tmp.list[idx]; | |
366 | 4333 | rpl->ref[i] = rpl_tmp.ref[idx]; | |
367 | 4333 | rpl->isLongTerm[i] = rpl_tmp.isLongTerm[idx]; | |
368 | 4333 | rpl->nb_refs++; | |
369 | } | ||
370 | } else { | ||
371 | 31295 | memcpy(rpl, &rpl_tmp, sizeof(*rpl)); | |
372 | 31295 | rpl->nb_refs = FFMIN(rpl->nb_refs, sh->nb_refs[list_idx]); | |
373 | } | ||
374 | |||
375 | // 8-9 | ||
376 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 33122 times.
|
33122 | if (s->ps.pps->pps_curr_pic_ref_enabled_flag && |
377 | ✗ | !sh->rpl_modification_flag[list_idx] && | |
378 | ✗ | rpl_tmp.nb_refs > sh->nb_refs[L0]) { | |
379 | ✗ | rpl->list[sh->nb_refs[L0] - 1] = s->ref->poc; | |
380 | ✗ | rpl->ref[sh->nb_refs[L0] - 1] = s->ref; | |
381 | } | ||
382 | |||
383 |
2/2✓ Branch 0 taken 18436 times.
✓ Branch 1 taken 14686 times.
|
33122 | if (sh->collocated_list == list_idx && |
384 |
1/2✓ Branch 0 taken 18436 times.
✗ Branch 1 not taken.
|
18436 | sh->collocated_ref_idx < rpl->nb_refs) |
385 | 18436 | s->collocated_ref = rpl->ref[sh->collocated_ref_idx]; | |
386 | } | ||
387 | |||
388 | 18436 | return 0; | |
389 | } | ||
390 | |||
391 | 35135 | static HEVCFrame *find_ref_idx(HEVCContext *s, int poc, uint8_t use_msb) | |
392 | { | ||
393 |
2/2✓ Branch 0 taken 1513 times.
✓ Branch 1 taken 33622 times.
|
35135 | int mask = use_msb ? ~0 : (1 << s->ps.sps->log2_max_poc_lsb) - 1; |
394 | int i; | ||
395 | |||
396 |
2/2✓ Branch 0 taken 152517 times.
✓ Branch 1 taken 64 times.
|
152581 | for (i = 0; i < FF_ARRAY_ELEMS(s->DPB); i++) { |
397 | 152517 | HEVCFrame *ref = &s->DPB[i]; | |
398 |
4/4✓ Branch 0 taken 144742 times.
✓ Branch 1 taken 7775 times.
✓ Branch 2 taken 144567 times.
✓ Branch 3 taken 175 times.
|
152517 | if (ref->frame->buf[0] && ref->sequence == s->seq_decode) { |
399 |
5/6✓ Branch 0 taken 35071 times.
✓ Branch 1 taken 109496 times.
✓ Branch 2 taken 1512 times.
✓ Branch 3 taken 33559 times.
✓ Branch 4 taken 1512 times.
✗ Branch 5 not taken.
|
144567 | if ((ref->poc & mask) == poc && (use_msb || ref->poc != s->poc)) |
400 | 35071 | return ref; | |
401 | } | ||
402 | } | ||
403 | |||
404 |
7/8✓ Branch 0 taken 25 times.
✓ Branch 1 taken 39 times.
✓ Branch 2 taken 22 times.
✓ Branch 3 taken 3 times.
✓ Branch 4 taken 22 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 20 times.
✓ Branch 7 taken 2 times.
|
64 | if (s->nal_unit_type != HEVC_NAL_CRA_NUT && !IS_BLA(s)) |
405 | 20 | av_log(s->avctx, AV_LOG_ERROR, | |
406 | "Could not find ref with POC %d\n", poc); | ||
407 | 64 | return NULL; | |
408 | } | ||
409 | |||
410 | 318909 | static void mark_ref(HEVCFrame *frame, int flag) | |
411 | { | ||
412 | 318909 | frame->flags &= ~(HEVC_FRAME_FLAG_LONG_REF | HEVC_FRAME_FLAG_SHORT_REF); | |
413 | 318909 | frame->flags |= flag; | |
414 | 318909 | } | |
415 | |||
416 | 64 | static HEVCFrame *generate_missing_ref(HEVCContext *s, int poc) | |
417 | { | ||
418 | HEVCFrame *frame; | ||
419 | int i, y; | ||
420 | |||
421 | 64 | frame = alloc_frame(s); | |
422 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 64 times.
|
64 | if (!frame) |
423 | ✗ | return NULL; | |
424 | |||
425 |
1/2✓ Branch 0 taken 64 times.
✗ Branch 1 not taken.
|
64 | if (!s->avctx->hwaccel) { |
426 |
2/2✓ Branch 0 taken 44 times.
✓ Branch 1 taken 20 times.
|
64 | if (!s->ps.sps->pixel_shift) { |
427 |
2/2✓ Branch 0 taken 132 times.
✓ Branch 1 taken 44 times.
|
176 | for (i = 0; frame->frame->data[i]; i++) |
428 | 132 | memset(frame->frame->data[i], 1 << (s->ps.sps->bit_depth - 1), | |
429 | 132 | frame->frame->linesize[i] * AV_CEIL_RSHIFT(s->ps.sps->height, s->ps.sps->vshift[i])); | |
430 | } else { | ||
431 |
2/2✓ Branch 0 taken 60 times.
✓ Branch 1 taken 20 times.
|
80 | for (i = 0; frame->frame->data[i]; i++) |
432 |
2/2✓ Branch 0 taken 71424 times.
✓ Branch 1 taken 60 times.
|
71484 | for (y = 0; y < (s->ps.sps->height >> s->ps.sps->vshift[i]); y++) { |
433 | 71424 | uint8_t *dst = frame->frame->data[i] + y * frame->frame->linesize[i]; | |
434 | 71424 | AV_WN16(dst, 1 << (s->ps.sps->bit_depth - 1)); | |
435 | 71424 | av_memcpy_backptr(dst + 2, 2, 2*(s->ps.sps->width >> s->ps.sps->hshift[i]) - 2); | |
436 | } | ||
437 | } | ||
438 | } | ||
439 | |||
440 | 64 | frame->poc = poc; | |
441 | 64 | frame->sequence = HEVC_SEQUENCE_COUNTER_INVALID; | |
442 | 64 | frame->flags = 0; | |
443 | |||
444 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 64 times.
|
64 | if (s->threads_type == FF_THREAD_FRAME) |
445 | ✗ | ff_thread_report_progress(&frame->tf, INT_MAX, 0); | |
446 | |||
447 | 64 | return frame; | |
448 | } | ||
449 | |||
450 | /* add a reference with the given poc to the list and mark it as used in DPB */ | ||
451 | 35135 | static int add_candidate_ref(HEVCContext *s, RefPicList *list, | |
452 | int poc, int ref_flag, uint8_t use_msb) | ||
453 | { | ||
454 | 35135 | HEVCFrame *ref = find_ref_idx(s, poc, use_msb); | |
455 | |||
456 |
2/4✓ Branch 0 taken 35135 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 35135 times.
|
35135 | if (ref == s->ref || list->nb_refs >= HEVC_MAX_REFS) |
457 | ✗ | return AVERROR_INVALIDDATA; | |
458 | |||
459 |
2/2✓ Branch 0 taken 64 times.
✓ Branch 1 taken 35071 times.
|
35135 | if (!ref) { |
460 | 64 | ref = generate_missing_ref(s, poc); | |
461 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 64 times.
|
64 | if (!ref) |
462 | ✗ | return AVERROR(ENOMEM); | |
463 | } | ||
464 | |||
465 | 35135 | list->list[list->nb_refs] = ref->poc; | |
466 | 35135 | list->ref[list->nb_refs] = ref; | |
467 | 35135 | list->nb_refs++; | |
468 | |||
469 | 35135 | mark_ref(ref, ref_flag); | |
470 | 35135 | return 0; | |
471 | } | ||
472 | |||
473 | 9535 | int ff_hevc_frame_rps(HEVCContext *s) | |
474 | { | ||
475 | 9535 | const ShortTermRPS *short_rps = s->sh.short_term_rps; | |
476 | 9535 | const LongTermRPS *long_rps = &s->sh.long_term_rps; | |
477 | 9535 | RefPicList *rps = s->rps; | |
478 | 9535 | int i, ret = 0; | |
479 | |||
480 |
2/2✓ Branch 0 taken 381 times.
✓ Branch 1 taken 9154 times.
|
9535 | if (!short_rps) { |
481 | 381 | rps[0].nb_refs = rps[1].nb_refs = 0; | |
482 | 381 | return 0; | |
483 | } | ||
484 | |||
485 | 9154 | unref_missing_refs(s); | |
486 | |||
487 | /* clear the reference flags on all frames except the current one */ | ||
488 |
2/2✓ Branch 0 taken 292928 times.
✓ Branch 1 taken 9154 times.
|
302082 | for (i = 0; i < FF_ARRAY_ELEMS(s->DPB); i++) { |
489 | 292928 | HEVCFrame *frame = &s->DPB[i]; | |
490 | |||
491 |
2/2✓ Branch 0 taken 9154 times.
✓ Branch 1 taken 283774 times.
|
292928 | if (frame == s->ref) |
492 | 9154 | continue; | |
493 | |||
494 | 283774 | mark_ref(frame, 0); | |
495 | } | ||
496 | |||
497 |
2/2✓ Branch 0 taken 45770 times.
✓ Branch 1 taken 9154 times.
|
54924 | for (i = 0; i < NB_RPS_TYPE; i++) |
498 | 45770 | rps[i].nb_refs = 0; | |
499 | |||
500 | /* add the short refs */ | ||
501 |
2/2✓ Branch 0 taken 33574 times.
✓ Branch 1 taken 9154 times.
|
42728 | for (i = 0; i < short_rps->num_delta_pocs; i++) { |
502 | 33574 | int poc = s->poc + short_rps->delta_poc[i]; | |
503 | int list; | ||
504 | |||
505 |
2/2✓ Branch 0 taken 1725 times.
✓ Branch 1 taken 31849 times.
|
33574 | if (!short_rps->used[i]) |
506 | 1725 | list = ST_FOLL; | |
507 |
2/2✓ Branch 0 taken 23222 times.
✓ Branch 1 taken 8627 times.
|
31849 | else if (i < short_rps->num_negative_pics) |
508 | 23222 | list = ST_CURR_BEF; | |
509 | else | ||
510 | 8627 | list = ST_CURR_AFT; | |
511 | |||
512 | 33574 | ret = add_candidate_ref(s, &rps[list], poc, HEVC_FRAME_FLAG_SHORT_REF, 1); | |
513 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 33574 times.
|
33574 | if (ret < 0) |
514 | ✗ | goto fail; | |
515 | } | ||
516 | |||
517 | /* add the long refs */ | ||
518 |
2/2✓ Branch 0 taken 1561 times.
✓ Branch 1 taken 9154 times.
|
10715 | for (i = 0; i < long_rps->nb_refs; i++) { |
519 | 1561 | int poc = long_rps->poc[i]; | |
520 |
2/2✓ Branch 0 taken 574 times.
✓ Branch 1 taken 987 times.
|
1561 | int list = long_rps->used[i] ? LT_CURR : LT_FOLL; |
521 | |||
522 | 1561 | ret = add_candidate_ref(s, &rps[list], poc, HEVC_FRAME_FLAG_LONG_REF, long_rps->poc_msb_present[i]); | |
523 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 1561 times.
|
1561 | if (ret < 0) |
524 | ✗ | goto fail; | |
525 | } | ||
526 | |||
527 | 9154 | fail: | |
528 | /* release any frames that are now unused */ | ||
529 |
2/2✓ Branch 0 taken 292928 times.
✓ Branch 1 taken 9154 times.
|
302082 | for (i = 0; i < FF_ARRAY_ELEMS(s->DPB); i++) |
530 | 292928 | ff_hevc_unref_frame(&s->DPB[i], 0); | |
531 | |||
532 | 9154 | return ret; | |
533 | } | ||
534 | |||
535 | 18524 | int ff_hevc_frame_nb_refs(const HEVCContext *s) | |
536 | { | ||
537 | 18524 | int ret = 0; | |
538 | int i; | ||
539 | 18524 | const ShortTermRPS *rps = s->sh.short_term_rps; | |
540 | 18524 | const LongTermRPS *long_rps = &s->sh.long_term_rps; | |
541 | |||
542 |
1/2✓ Branch 0 taken 18524 times.
✗ Branch 1 not taken.
|
18524 | if (rps) { |
543 |
2/2✓ Branch 0 taken 45435 times.
✓ Branch 1 taken 18524 times.
|
63959 | for (i = 0; i < rps->num_negative_pics; i++) |
544 | 45435 | ret += !!rps->used[i]; | |
545 |
2/2✓ Branch 0 taken 20428 times.
✓ Branch 1 taken 18524 times.
|
38952 | for (; i < rps->num_delta_pocs; i++) |
546 | 20428 | ret += !!rps->used[i]; | |
547 | } | ||
548 | |||
549 |
1/2✓ Branch 0 taken 18524 times.
✗ Branch 1 not taken.
|
18524 | if (long_rps) { |
550 |
2/2✓ Branch 0 taken 1420 times.
✓ Branch 1 taken 18524 times.
|
19944 | for (i = 0; i < long_rps->nb_refs; i++) |
551 | 1420 | ret += !!long_rps->used[i]; | |
552 | } | ||
553 | |||
554 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 18524 times.
|
18524 | if (s->ps.pps->pps_curr_pic_ref_enabled_flag) |
555 | ✗ | ret++; | |
556 | |||
557 | 18524 | return ret; | |
558 | } | ||
559 |