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/mem.h" | ||
25 | |||
26 | #include "container_fifo.h" | ||
27 | #include "decode.h" | ||
28 | #include "hevc.h" | ||
29 | #include "hevcdec.h" | ||
30 | #include "progressframe.h" | ||
31 | #include "refstruct.h" | ||
32 | |||
33 | 342311 | void ff_hevc_unref_frame(HEVCFrame *frame, int flags) | |
34 | { | ||
35 | 342311 | frame->flags &= ~flags; | |
36 |
2/2✓ Branch 0 taken 287489 times.
✓ Branch 1 taken 54822 times.
|
342311 | if (!frame->flags) { |
37 | 287489 | ff_progress_frame_unref(&frame->tf); | |
38 | 287489 | av_frame_unref(frame->frame_grain); | |
39 | 287489 | frame->needs_fg = 0; | |
40 | |||
41 | 287489 | ff_refstruct_unref(&frame->pps); | |
42 | 287489 | ff_refstruct_unref(&frame->tab_mvf); | |
43 | |||
44 | 287489 | ff_refstruct_unref(&frame->rpl); | |
45 | 287489 | frame->nb_rpl_elems = 0; | |
46 | 287489 | ff_refstruct_unref(&frame->rpl_tab); | |
47 | 287489 | frame->refPicList = NULL; | |
48 | |||
49 | 287489 | ff_refstruct_unref(&frame->hwaccel_picture_private); | |
50 | } | ||
51 | 342311 | } | |
52 | |||
53 | 4580604 | const RefPicList *ff_hevc_get_ref_list(const HEVCFrame *ref, int x0, int y0) | |
54 | { | ||
55 | 4580604 | const HEVCSPS *sps = ref->pps->sps; | |
56 | 4580604 | int x_cb = x0 >> sps->log2_ctb_size; | |
57 | 4580604 | int y_cb = y0 >> sps->log2_ctb_size; | |
58 | 4580604 | int pic_width_cb = sps->ctb_width; | |
59 | 4580604 | int ctb_addr_ts = ref->pps->ctb_addr_rs_to_ts[y_cb * pic_width_cb + x_cb]; | |
60 | 4580604 | return &ref->rpl_tab[ctb_addr_ts]->refPicList[0]; | |
61 | } | ||
62 | |||
63 | 771 | void ff_hevc_clear_refs(HEVCLayerContext *l) | |
64 | { | ||
65 | int i; | ||
66 |
2/2✓ Branch 0 taken 24672 times.
✓ Branch 1 taken 771 times.
|
25443 | for (i = 0; i < FF_ARRAY_ELEMS(l->DPB); i++) |
67 | 24672 | ff_hevc_unref_frame(&l->DPB[i], | |
68 | HEVC_FRAME_FLAG_SHORT_REF | | ||
69 | HEVC_FRAME_FLAG_LONG_REF); | ||
70 | 771 | } | |
71 | |||
72 | 8 | void ff_hevc_flush_dpb(HEVCContext *s) | |
73 | { | ||
74 |
2/2✓ Branch 0 taken 8 times.
✓ Branch 1 taken 8 times.
|
16 | for (int layer = 0; layer < FF_ARRAY_ELEMS(s->layers); layer++) { |
75 | 8 | HEVCLayerContext *l = &s->layers[layer]; | |
76 |
2/2✓ Branch 0 taken 256 times.
✓ Branch 1 taken 8 times.
|
264 | for (int i = 0; i < FF_ARRAY_ELEMS(l->DPB); i++) |
77 | 256 | ff_hevc_unref_frame(&l->DPB[i], ~0); | |
78 | } | ||
79 | 8 | } | |
80 | |||
81 | 9599 | static HEVCFrame *alloc_frame(HEVCContext *s, HEVCLayerContext *l) | |
82 | { | ||
83 | int i, j, ret; | ||
84 |
1/2✓ Branch 0 taken 34012 times.
✗ Branch 1 not taken.
|
34012 | for (i = 0; i < FF_ARRAY_ELEMS(l->DPB); i++) { |
85 | 34012 | HEVCFrame *frame = &l->DPB[i]; | |
86 |
2/2✓ Branch 0 taken 24413 times.
✓ Branch 1 taken 9599 times.
|
34012 | if (frame->f) |
87 | 24413 | continue; | |
88 | |||
89 | 9599 | ret = ff_progress_frame_get_buffer(s->avctx, &frame->tf, | |
90 | AV_GET_BUFFER_FLAG_REF); | ||
91 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 9599 times.
|
9599 | if (ret < 0) |
92 | ✗ | return NULL; | |
93 | |||
94 | 9599 | frame->rpl = ff_refstruct_allocz(s->pkt.nb_nals * sizeof(*frame->rpl)); | |
95 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 9599 times.
|
9599 | if (!frame->rpl) |
96 | ✗ | goto fail; | |
97 | 9599 | frame->nb_rpl_elems = s->pkt.nb_nals; | |
98 | |||
99 | 9599 | frame->tab_mvf = ff_refstruct_pool_get(l->tab_mvf_pool); | |
100 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 9599 times.
|
9599 | if (!frame->tab_mvf) |
101 | ✗ | goto fail; | |
102 | |||
103 | 9599 | frame->rpl_tab = ff_refstruct_pool_get(l->rpl_tab_pool); | |
104 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 9599 times.
|
9599 | if (!frame->rpl_tab) |
105 | ✗ | goto fail; | |
106 | 9599 | frame->ctb_count = l->sps->ctb_width * l->sps->ctb_height; | |
107 |
2/2✓ Branch 0 taken 1493871 times.
✓ Branch 1 taken 9599 times.
|
1503470 | for (j = 0; j < frame->ctb_count; j++) |
108 | 1493871 | frame->rpl_tab[j] = frame->rpl; | |
109 | |||
110 |
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) |
111 | 15 | frame->f->flags |= AV_FRAME_FLAG_TOP_FIELD_FIRST; | |
112 |
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) || |
113 |
2/2✓ Branch 0 taken 2 times.
✓ Branch 1 taken 9582 times.
|
9584 | (s->sei.picture_timing.picture_struct == AV_PICTURE_STRUCTURE_BOTTOM_FIELD)) |
114 | 17 | frame->f->flags |= AV_FRAME_FLAG_INTERLACED; | |
115 | |||
116 | 9599 | ret = ff_hwaccel_frame_priv_alloc(s->avctx, &frame->hwaccel_picture_private); | |
117 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 9599 times.
|
9599 | if (ret < 0) |
118 | ✗ | goto fail; | |
119 | |||
120 | 9599 | frame->pps = ff_refstruct_ref_c(s->pps); | |
121 | |||
122 | 9599 | return frame; | |
123 | ✗ | fail: | |
124 | ✗ | ff_hevc_unref_frame(frame, ~0); | |
125 | ✗ | return NULL; | |
126 | } | ||
127 | ✗ | av_log(s->avctx, AV_LOG_ERROR, "Error allocating frame, DPB full.\n"); | |
128 | ✗ | return NULL; | |
129 | } | ||
130 | |||
131 | 9541 | int ff_hevc_set_new_ref(HEVCContext *s, HEVCLayerContext *l, int poc) | |
132 | { | ||
133 | HEVCFrame *ref; | ||
134 | int i; | ||
135 | |||
136 | /* check that this POC doesn't already exist */ | ||
137 |
2/2✓ Branch 0 taken 305312 times.
✓ Branch 1 taken 9541 times.
|
314853 | for (i = 0; i < FF_ARRAY_ELEMS(l->DPB); i++) { |
138 | 305312 | HEVCFrame *frame = &l->DPB[i]; | |
139 | |||
140 |
3/4✓ Branch 0 taken 44915 times.
✓ Branch 1 taken 260397 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 44915 times.
|
305312 | if (frame->f && 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 | 9541 | ref = alloc_frame(s, l); | |
148 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 9541 times.
|
9541 | if (!ref) |
149 | ✗ | return AVERROR(ENOMEM); | |
150 | |||
151 | 9541 | s->cur_frame = ref; | |
152 | 9541 | s->collocated_ref = NULL; | |
153 | |||
154 |
2/2✓ Branch 0 taken 9535 times.
✓ Branch 1 taken 6 times.
|
9541 | if (s->sh.pic_output_flag) |
155 | 9535 | ref->flags = HEVC_FRAME_FLAG_OUTPUT | HEVC_FRAME_FLAG_SHORT_REF; | |
156 | else | ||
157 | 6 | ref->flags = HEVC_FRAME_FLAG_SHORT_REF; | |
158 | |||
159 | 9541 | ref->poc = poc; | |
160 | 9541 | ref->f->crop_left = l->sps->output_window.left_offset; | |
161 | 9541 | ref->f->crop_right = l->sps->output_window.right_offset; | |
162 | 9541 | ref->f->crop_top = l->sps->output_window.top_offset; | |
163 | 9541 | ref->f->crop_bottom = l->sps->output_window.bottom_offset; | |
164 | |||
165 | 9541 | return 0; | |
166 | } | ||
167 | |||
168 | 9157 | static void unref_missing_refs(HEVCLayerContext *l) | |
169 | { | ||
170 |
2/2✓ Branch 0 taken 293024 times.
✓ Branch 1 taken 9157 times.
|
302181 | for (int i = 0; i < FF_ARRAY_ELEMS(l->DPB); i++) { |
171 | 293024 | HEVCFrame *frame = &l->DPB[i]; | |
172 |
2/2✓ Branch 0 taken 37 times.
✓ Branch 1 taken 292987 times.
|
293024 | if (frame->flags & HEVC_FRAME_FLAG_UNAVAILABLE) { |
173 | 37 | ff_hevc_unref_frame(frame, ~0); | |
174 | } | ||
175 | } | ||
176 | 9157 | } | |
177 | |||
178 | 10236 | int ff_hevc_output_frames(HEVCContext *s, HEVCLayerContext *l, | |
179 | unsigned max_output, unsigned max_dpb, int discard) | ||
180 | { | ||
181 | 9410 | while (1) { | |
182 | 19646 | int nb_dpb = 0; | |
183 | 19646 | int nb_output = 0; | |
184 | 19646 | int min_poc = INT_MAX; | |
185 | int i, min_idx, ret; | ||
186 | |||
187 |
2/2✓ Branch 0 taken 628672 times.
✓ Branch 1 taken 19646 times.
|
648318 | for (i = 0; i < FF_ARRAY_ELEMS(l->DPB); i++) { |
188 | 628672 | HEVCFrame *frame = &l->DPB[i]; | |
189 |
2/2✓ Branch 0 taken 51259 times.
✓ Branch 1 taken 577413 times.
|
628672 | if (frame->flags & HEVC_FRAME_FLAG_OUTPUT) { |
190 | 51259 | nb_output++; | |
191 |
3/4✓ Branch 0 taken 23133 times.
✓ Branch 1 taken 28126 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 23133 times.
|
51259 | if (frame->poc < min_poc || nb_output == 1) { |
192 | 28126 | min_poc = frame->poc; | |
193 | 28126 | min_idx = i; | |
194 | } | ||
195 | } | ||
196 | 628672 | nb_dpb += !!frame->flags; | |
197 | } | ||
198 | |||
199 |
4/4✓ Branch 0 taken 10658 times.
✓ Branch 1 taken 8988 times.
✓ Branch 2 taken 7418 times.
✓ Branch 3 taken 3240 times.
|
19646 | if (nb_output > max_output || |
200 |
2/2✓ Branch 0 taken 422 times.
✓ Branch 1 taken 6996 times.
|
7418 | (nb_output && nb_dpb > max_dpb)) { |
201 | 9410 | HEVCFrame *frame = &l->DPB[min_idx]; | |
202 | |||
203 |
2/2✓ Branch 0 taken 9384 times.
✓ Branch 1 taken 26 times.
|
9410 | ret = discard ? 0 : |
204 | 9384 | ff_container_fifo_write(s->output_fifo, | |
205 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 9384 times.
|
9384 | frame->needs_fg ? frame->frame_grain : frame->f); |
206 | 9410 | ff_hevc_unref_frame(frame, HEVC_FRAME_FLAG_OUTPUT); | |
207 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 9410 times.
|
9410 | if (ret < 0) |
208 | ✗ | return ret; | |
209 | |||
210 |
2/2✓ Branch 0 taken 26 times.
✓ Branch 1 taken 9384 times.
|
9410 | av_log(s->avctx, AV_LOG_DEBUG, "%s frame with POC %d.\n", |
211 | discard ? "Discarded" : "Output", frame->poc); | ||
212 | 9410 | continue; | |
213 | } | ||
214 | 10236 | return 0; | |
215 | } | ||
216 | } | ||
217 | |||
218 | 18439 | static int init_slice_rpl(HEVCContext *s) | |
219 | { | ||
220 | 18439 | HEVCFrame *frame = s->cur_frame; | |
221 | 18439 | int ctb_count = frame->ctb_count; | |
222 | 18439 | int ctb_addr_ts = s->pps->ctb_addr_rs_to_ts[s->sh.slice_segment_addr]; | |
223 | int i; | ||
224 | |||
225 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 18439 times.
|
18439 | if (s->slice_idx >= frame->nb_rpl_elems) |
226 | ✗ | return AVERROR_INVALIDDATA; | |
227 | |||
228 |
2/2✓ Branch 0 taken 1967924 times.
✓ Branch 1 taken 18439 times.
|
1986363 | for (i = ctb_addr_ts; i < ctb_count; i++) |
229 | 1967924 | frame->rpl_tab[i] = frame->rpl + s->slice_idx; | |
230 | |||
231 | 18439 | frame->refPicList = (RefPicList *)frame->rpl_tab[ctb_addr_ts]; | |
232 | |||
233 | 18439 | return 0; | |
234 | } | ||
235 | |||
236 | 18439 | int ff_hevc_slice_rpl(HEVCContext *s) | |
237 | { | ||
238 | 18439 | SliceHeader *sh = &s->sh; | |
239 | |||
240 |
2/2✓ Branch 0 taken 14689 times.
✓ Branch 1 taken 3750 times.
|
18439 | uint8_t nb_list = sh->slice_type == HEVC_SLICE_B ? 2 : 1; |
241 | uint8_t list_idx; | ||
242 | int i, j, ret; | ||
243 | |||
244 | 18439 | ret = init_slice_rpl(s); | |
245 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 18439 times.
|
18439 | if (ret < 0) |
246 | ✗ | return ret; | |
247 | |||
248 | 18439 | if (!(s->rps[ST_CURR_BEF].nb_refs + s->rps[ST_CURR_AFT].nb_refs + | |
249 |
1/4✗ Branch 0 not taken.
✓ Branch 1 taken 18439 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
|
18439 | s->rps[LT_CURR].nb_refs) && !s->pps->pps_curr_pic_ref_enabled_flag) { |
250 | ✗ | av_log(s->avctx, AV_LOG_ERROR, "Zero refs in the frame RPS.\n"); | |
251 | ✗ | return AVERROR_INVALIDDATA; | |
252 | } | ||
253 | |||
254 |
2/2✓ Branch 0 taken 33128 times.
✓ Branch 1 taken 18439 times.
|
51567 | for (list_idx = 0; list_idx < nb_list; list_idx++) { |
255 | 33128 | RefPicList rpl_tmp = { { 0 } }; | |
256 | 33128 | RefPicList *rpl = &s->cur_frame->refPicList[list_idx]; | |
257 | |||
258 | /* The order of the elements is | ||
259 | * ST_CURR_BEF - ST_CURR_AFT - LT_CURR for the L0 and | ||
260 | * ST_CURR_AFT - ST_CURR_BEF - LT_CURR for the L1 */ | ||
261 | 33128 | int cand_lists[3] = { list_idx ? ST_CURR_AFT : ST_CURR_BEF, | |
262 | 33128 | list_idx ? ST_CURR_BEF : ST_CURR_AFT, | |
263 | LT_CURR }; | ||
264 | |||
265 | /* concatenate the candidate lists for the current frame */ | ||
266 |
2/2✓ Branch 0 taken 33146 times.
✓ Branch 1 taken 33128 times.
|
66274 | while (rpl_tmp.nb_refs < sh->nb_refs[list_idx]) { |
267 |
2/2✓ Branch 0 taken 99438 times.
✓ Branch 1 taken 33146 times.
|
132584 | for (i = 0; i < FF_ARRAY_ELEMS(cand_lists); i++) { |
268 | 99438 | RefPicList *rps = &s->rps[cand_lists[i]]; | |
269 |
3/4✓ Branch 0 taken 119806 times.
✓ Branch 1 taken 99438 times.
✓ Branch 2 taken 119806 times.
✗ Branch 3 not taken.
|
219244 | for (j = 0; j < rps->nb_refs && rpl_tmp.nb_refs < HEVC_MAX_REFS; j++) { |
270 | 119806 | rpl_tmp.list[rpl_tmp.nb_refs] = rps->list[j]; | |
271 | 119806 | rpl_tmp.ref[rpl_tmp.nb_refs] = rps->ref[j]; | |
272 | 119806 | rpl_tmp.isLongTerm[rpl_tmp.nb_refs] = i == 2; | |
273 | 119806 | rpl_tmp.nb_refs++; | |
274 | } | ||
275 | } | ||
276 | // Construct RefPicList0, RefPicList1 (8-8, 8-10) | ||
277 |
1/4✗ Branch 0 not taken.
✓ Branch 1 taken 33146 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
|
33146 | if (s->pps->pps_curr_pic_ref_enabled_flag && rpl_tmp.nb_refs < HEVC_MAX_REFS) { |
278 | ✗ | rpl_tmp.list[rpl_tmp.nb_refs] = s->cur_frame->poc; | |
279 | ✗ | rpl_tmp.ref[rpl_tmp.nb_refs] = s->cur_frame; | |
280 | ✗ | rpl_tmp.isLongTerm[rpl_tmp.nb_refs] = 1; | |
281 | ✗ | rpl_tmp.nb_refs++; | |
282 | } | ||
283 | } | ||
284 | |||
285 | /* reorder the references if necessary */ | ||
286 |
2/2✓ Branch 0 taken 1827 times.
✓ Branch 1 taken 31301 times.
|
33128 | if (sh->rpl_modification_flag[list_idx]) { |
287 |
2/2✓ Branch 0 taken 4333 times.
✓ Branch 1 taken 1827 times.
|
6160 | for (i = 0; i < sh->nb_refs[list_idx]; i++) { |
288 | 4333 | int idx = sh->list_entry_lx[list_idx][i]; | |
289 | |||
290 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 4333 times.
|
4333 | if (idx >= rpl_tmp.nb_refs) { |
291 | ✗ | av_log(s->avctx, AV_LOG_ERROR, "Invalid reference index.\n"); | |
292 | ✗ | return AVERROR_INVALIDDATA; | |
293 | } | ||
294 | |||
295 | 4333 | rpl->list[i] = rpl_tmp.list[idx]; | |
296 | 4333 | rpl->ref[i] = rpl_tmp.ref[idx]; | |
297 | 4333 | rpl->isLongTerm[i] = rpl_tmp.isLongTerm[idx]; | |
298 | 4333 | rpl->nb_refs++; | |
299 | } | ||
300 | } else { | ||
301 | 31301 | memcpy(rpl, &rpl_tmp, sizeof(*rpl)); | |
302 | 31301 | rpl->nb_refs = FFMIN(rpl->nb_refs, sh->nb_refs[list_idx]); | |
303 | } | ||
304 | |||
305 | // 8-9 | ||
306 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 33128 times.
|
33128 | if (s->pps->pps_curr_pic_ref_enabled_flag && |
307 | ✗ | !sh->rpl_modification_flag[list_idx] && | |
308 | ✗ | rpl_tmp.nb_refs > sh->nb_refs[L0]) { | |
309 | ✗ | rpl->list[sh->nb_refs[L0] - 1] = s->cur_frame->poc; | |
310 | ✗ | rpl->ref[sh->nb_refs[L0] - 1] = s->cur_frame; | |
311 | } | ||
312 | |||
313 |
2/2✓ Branch 0 taken 18439 times.
✓ Branch 1 taken 14689 times.
|
33128 | if (sh->collocated_list == list_idx && |
314 |
1/2✓ Branch 0 taken 18439 times.
✗ Branch 1 not taken.
|
18439 | sh->collocated_ref_idx < rpl->nb_refs) |
315 | 18439 | s->collocated_ref = rpl->ref[sh->collocated_ref_idx]; | |
316 | } | ||
317 | |||
318 | 18439 | return 0; | |
319 | } | ||
320 | |||
321 | 35142 | static HEVCFrame *find_ref_idx(HEVCContext *s, HEVCLayerContext *l, | |
322 | int poc, uint8_t use_msb) | ||
323 | { | ||
324 |
2/2✓ Branch 0 taken 1513 times.
✓ Branch 1 taken 33629 times.
|
35142 | int mask = use_msb ? ~0 : (1 << l->sps->log2_max_poc_lsb) - 1; |
325 | int i; | ||
326 | |||
327 |
2/2✓ Branch 0 taken 145462 times.
✓ Branch 1 taken 58 times.
|
145520 | for (i = 0; i < FF_ARRAY_ELEMS(l->DPB); i++) { |
328 | 145462 | HEVCFrame *ref = &l->DPB[i]; | |
329 |
2/2✓ Branch 0 taken 140958 times.
✓ Branch 1 taken 4504 times.
|
145462 | if (ref->f) { |
330 |
5/6✓ Branch 0 taken 35084 times.
✓ Branch 1 taken 105874 times.
✓ Branch 2 taken 1512 times.
✓ Branch 3 taken 33572 times.
✓ Branch 4 taken 1512 times.
✗ Branch 5 not taken.
|
140958 | if ((ref->poc & mask) == poc && (use_msb || ref->poc != s->poc)) |
331 | 35084 | return ref; | |
332 | } | ||
333 | } | ||
334 | |||
335 |
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)) |
336 | 20 | av_log(s->avctx, AV_LOG_ERROR, | |
337 | "Could not find ref with POC %d\n", poc); | ||
338 | 58 | return NULL; | |
339 | } | ||
340 | |||
341 | 319009 | static void mark_ref(HEVCFrame *frame, int flag) | |
342 | { | ||
343 | 319009 | frame->flags &= ~(HEVC_FRAME_FLAG_LONG_REF | HEVC_FRAME_FLAG_SHORT_REF); | |
344 | 319009 | frame->flags |= flag; | |
345 | 319009 | } | |
346 | |||
347 | 58 | static HEVCFrame *generate_missing_ref(HEVCContext *s, HEVCLayerContext *l, int poc) | |
348 | { | ||
349 | HEVCFrame *frame; | ||
350 | int i, y; | ||
351 | |||
352 | 58 | frame = alloc_frame(s, l); | |
353 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 58 times.
|
58 | if (!frame) |
354 | ✗ | return NULL; | |
355 | |||
356 |
1/2✓ Branch 0 taken 58 times.
✗ Branch 1 not taken.
|
58 | if (!s->avctx->hwaccel) { |
357 |
2/2✓ Branch 0 taken 38 times.
✓ Branch 1 taken 20 times.
|
58 | if (!l->sps->pixel_shift) { |
358 |
2/2✓ Branch 0 taken 114 times.
✓ Branch 1 taken 38 times.
|
152 | for (i = 0; frame->f->data[i]; i++) |
359 | 114 | memset(frame->f->data[i], 1 << (l->sps->bit_depth - 1), | |
360 | 114 | frame->f->linesize[i] * AV_CEIL_RSHIFT(l->sps->height, l->sps->vshift[i])); | |
361 | } else { | ||
362 |
2/2✓ Branch 0 taken 60 times.
✓ Branch 1 taken 20 times.
|
80 | for (i = 0; frame->f->data[i]; i++) |
363 |
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++) { |
364 | 71424 | uint8_t *dst = frame->f->data[i] + y * frame->f->linesize[i]; | |
365 | 71424 | AV_WN16(dst, 1 << (l->sps->bit_depth - 1)); | |
366 | 71424 | av_memcpy_backptr(dst + 2, 2, 2*(l->sps->width >> l->sps->hshift[i]) - 2); | |
367 | } | ||
368 | } | ||
369 | } | ||
370 | |||
371 | 58 | frame->poc = poc; | |
372 | 58 | frame->flags = HEVC_FRAME_FLAG_UNAVAILABLE; | |
373 | |||
374 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 58 times.
|
58 | if (s->avctx->active_thread_type == FF_THREAD_FRAME) |
375 | ✗ | ff_progress_frame_report(&frame->tf, INT_MAX); | |
376 | |||
377 | 58 | return frame; | |
378 | } | ||
379 | |||
380 | /* add a reference with the given poc to the list and mark it as used in DPB */ | ||
381 | 35142 | static int add_candidate_ref(HEVCContext *s, HEVCLayerContext *l, | |
382 | RefPicList *list, | ||
383 | int poc, int ref_flag, uint8_t use_msb) | ||
384 | { | ||
385 | 35142 | HEVCFrame *ref = find_ref_idx(s, l, poc, use_msb); | |
386 | |||
387 |
2/4✓ Branch 0 taken 35142 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 35142 times.
|
35142 | if (ref == s->cur_frame || list->nb_refs >= HEVC_MAX_REFS) |
388 | ✗ | return AVERROR_INVALIDDATA; | |
389 | |||
390 |
2/2✓ Branch 0 taken 58 times.
✓ Branch 1 taken 35084 times.
|
35142 | if (!ref) { |
391 | 58 | ref = generate_missing_ref(s, l, poc); | |
392 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 58 times.
|
58 | if (!ref) |
393 | ✗ | return AVERROR(ENOMEM); | |
394 | } | ||
395 | |||
396 | 35142 | list->list[list->nb_refs] = ref->poc; | |
397 | 35142 | list->ref[list->nb_refs] = ref; | |
398 | 35142 | list->nb_refs++; | |
399 | |||
400 | 35142 | mark_ref(ref, ref_flag); | |
401 | 35142 | return 0; | |
402 | } | ||
403 | |||
404 | 9541 | int ff_hevc_frame_rps(HEVCContext *s, HEVCLayerContext *l) | |
405 | { | ||
406 | 9541 | const ShortTermRPS *short_rps = s->sh.short_term_rps; | |
407 | 9541 | const LongTermRPS *long_rps = &s->sh.long_term_rps; | |
408 | 9541 | RefPicList *rps = s->rps; | |
409 | 9541 | int i, ret = 0; | |
410 | |||
411 |
2/2✓ Branch 0 taken 384 times.
✓ Branch 1 taken 9157 times.
|
9541 | if (!short_rps) { |
412 | 384 | rps[0].nb_refs = rps[1].nb_refs = 0; | |
413 | 384 | return 0; | |
414 | } | ||
415 | |||
416 | 9157 | unref_missing_refs(l); | |
417 | |||
418 | /* clear the reference flags on all frames except the current one */ | ||
419 |
2/2✓ Branch 0 taken 293024 times.
✓ Branch 1 taken 9157 times.
|
302181 | for (i = 0; i < FF_ARRAY_ELEMS(l->DPB); i++) { |
420 | 293024 | HEVCFrame *frame = &l->DPB[i]; | |
421 | |||
422 |
2/2✓ Branch 0 taken 9157 times.
✓ Branch 1 taken 283867 times.
|
293024 | if (frame == s->cur_frame) |
423 | 9157 | continue; | |
424 | |||
425 | 283867 | mark_ref(frame, 0); | |
426 | } | ||
427 | |||
428 |
2/2✓ Branch 0 taken 45785 times.
✓ Branch 1 taken 9157 times.
|
54942 | for (i = 0; i < NB_RPS_TYPE; i++) |
429 | 45785 | rps[i].nb_refs = 0; | |
430 | |||
431 | /* add the short refs */ | ||
432 |
2/2✓ Branch 0 taken 33581 times.
✓ Branch 1 taken 9157 times.
|
42738 | for (i = 0; i < short_rps->num_delta_pocs; i++) { |
433 | 33581 | int poc = s->poc + short_rps->delta_poc[i]; | |
434 | int list; | ||
435 | |||
436 |
2/2✓ Branch 0 taken 1726 times.
✓ Branch 1 taken 31855 times.
|
33581 | if (!(short_rps->used & (1 << i))) |
437 | 1726 | list = ST_FOLL; | |
438 |
2/2✓ Branch 0 taken 23225 times.
✓ Branch 1 taken 8630 times.
|
31855 | else if (i < short_rps->num_negative_pics) |
439 | 23225 | list = ST_CURR_BEF; | |
440 | else | ||
441 | 8630 | list = ST_CURR_AFT; | |
442 | |||
443 | 33581 | ret = add_candidate_ref(s, l, &rps[list], poc, | |
444 | HEVC_FRAME_FLAG_SHORT_REF, 1); | ||
445 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 33581 times.
|
33581 | if (ret < 0) |
446 | ✗ | goto fail; | |
447 | } | ||
448 | |||
449 | /* add the long refs */ | ||
450 |
2/2✓ Branch 0 taken 1561 times.
✓ Branch 1 taken 9157 times.
|
10718 | for (i = 0; i < long_rps->nb_refs; i++) { |
451 | 1561 | int poc = long_rps->poc[i]; | |
452 |
2/2✓ Branch 0 taken 574 times.
✓ Branch 1 taken 987 times.
|
1561 | int list = long_rps->used[i] ? LT_CURR : LT_FOLL; |
453 | |||
454 | 1561 | ret = add_candidate_ref(s, l, &rps[list], poc, | |
455 | 1561 | HEVC_FRAME_FLAG_LONG_REF, long_rps->poc_msb_present[i]); | |
456 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 1561 times.
|
1561 | if (ret < 0) |
457 | ✗ | goto fail; | |
458 | } | ||
459 | |||
460 | 9157 | fail: | |
461 | /* release any frames that are now unused */ | ||
462 |
2/2✓ Branch 0 taken 293024 times.
✓ Branch 1 taken 9157 times.
|
302181 | for (i = 0; i < FF_ARRAY_ELEMS(l->DPB); i++) |
463 | 293024 | ff_hevc_unref_frame(&l->DPB[i], 0); | |
464 | |||
465 | 9157 | return ret; | |
466 | } | ||
467 | |||
468 | 18525 | int ff_hevc_frame_nb_refs(const SliceHeader *sh, const HEVCPPS *pps) | |
469 | { | ||
470 | 18525 | int ret = 0; | |
471 | int i; | ||
472 | 18525 | const ShortTermRPS *rps = sh->short_term_rps; | |
473 | 18525 | const LongTermRPS *long_rps = &sh->long_term_rps; | |
474 | |||
475 |
1/2✓ Branch 0 taken 18525 times.
✗ Branch 1 not taken.
|
18525 | if (rps) { |
476 |
2/2✓ Branch 0 taken 45435 times.
✓ Branch 1 taken 18525 times.
|
63960 | for (i = 0; i < rps->num_negative_pics; i++) |
477 | 45435 | ret += !!(rps->used & (1 << i)); | |
478 |
2/2✓ Branch 0 taken 20428 times.
✓ Branch 1 taken 18525 times.
|
38953 | for (; i < rps->num_delta_pocs; i++) |
479 | 20428 | ret += !!(rps->used & (1 << i)); | |
480 | } | ||
481 | |||
482 |
1/2✓ Branch 0 taken 18525 times.
✗ Branch 1 not taken.
|
18525 | if (long_rps) { |
483 |
2/2✓ Branch 0 taken 1421 times.
✓ Branch 1 taken 18525 times.
|
19946 | for (i = 0; i < long_rps->nb_refs; i++) |
484 | 1421 | ret += !!long_rps->used[i]; | |
485 | } | ||
486 | |||
487 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 18525 times.
|
18525 | if (pps->pps_curr_pic_ref_enabled_flag) |
488 | ✗ | ret++; | |
489 | |||
490 | 18525 | return ret; | |
491 | } | ||
492 |