| 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 "thread.h" | ||
| 33 | #include "libavutil/refstruct.h" | ||
| 34 | |||
| 35 | 407887 | void ff_hevc_unref_frame(HEVCFrame *frame, int flags) | |
| 36 | { | ||
| 37 | 407887 | frame->flags &= ~flags; | |
| 38 |
2/2✓ Branch 0 taken 348855 times.
✓ Branch 1 taken 59032 times.
|
407887 | if (!(frame->flags & ~HEVC_FRAME_FLAG_CORRUPT)) |
| 39 | 348855 | frame->flags = 0; | |
| 40 |
2/2✓ Branch 0 taken 348855 times.
✓ Branch 1 taken 59032 times.
|
407887 | if (!frame->flags) { |
| 41 | 348855 | ff_progress_frame_unref(&frame->tf); | |
| 42 | 348855 | av_frame_unref(frame->frame_grain); | |
| 43 | 348855 | frame->needs_fg = 0; | |
| 44 | |||
| 45 | 348855 | av_refstruct_unref(&frame->pps); | |
| 46 | 348855 | av_refstruct_unref(&frame->tab_mvf); | |
| 47 | |||
| 48 | 348855 | av_refstruct_unref(&frame->rpl); | |
| 49 | 348855 | frame->nb_rpl_elems = 0; | |
| 50 | 348855 | av_refstruct_unref(&frame->rpl_tab); | |
| 51 | 348855 | frame->refPicList = NULL; | |
| 52 | |||
| 53 | 348855 | av_refstruct_unref(&frame->hwaccel_picture_private); | |
| 54 | } | ||
| 55 | 407887 | } | |
| 56 | |||
| 57 | 5145864 | const RefPicList *ff_hevc_get_ref_list(const HEVCFrame *ref, int x0, int y0) | |
| 58 | { | ||
| 59 | 5145864 | const HEVCSPS *sps = ref->pps->sps; | |
| 60 | 5145864 | int x_cb = x0 >> sps->log2_ctb_size; | |
| 61 | 5145864 | int y_cb = y0 >> sps->log2_ctb_size; | |
| 62 | 5145864 | int pic_width_cb = sps->ctb_width; | |
| 63 | 5145864 | int ctb_addr_ts = ref->pps->ctb_addr_rs_to_ts[y_cb * pic_width_cb + x_cb]; | |
| 64 | 5145864 | return &ref->rpl_tab[ctb_addr_ts]->refPicList[0]; | |
| 65 | } | ||
| 66 | |||
| 67 | 881 | void ff_hevc_clear_refs(HEVCLayerContext *l) | |
| 68 | { | ||
| 69 | int i; | ||
| 70 |
2/2✓ Branch 0 taken 28192 times.
✓ Branch 1 taken 881 times.
|
29073 | for (i = 0; i < FF_ARRAY_ELEMS(l->DPB); i++) |
| 71 | 28192 | ff_hevc_unref_frame(&l->DPB[i], | |
| 72 | HEVC_FRAME_FLAG_SHORT_REF | | ||
| 73 | HEVC_FRAME_FLAG_LONG_REF); | ||
| 74 | 881 | } | |
| 75 | |||
| 76 | 10 | void ff_hevc_flush_dpb(HEVCContext *s) | |
| 77 | { | ||
| 78 |
2/2✓ Branch 0 taken 20 times.
✓ Branch 1 taken 10 times.
|
30 | for (int layer = 0; layer < FF_ARRAY_ELEMS(s->layers); layer++) { |
| 79 | 20 | HEVCLayerContext *l = &s->layers[layer]; | |
| 80 |
2/2✓ Branch 0 taken 640 times.
✓ Branch 1 taken 20 times.
|
660 | for (int i = 0; i < FF_ARRAY_ELEMS(l->DPB); i++) |
| 81 | 640 | ff_hevc_unref_frame(&l->DPB[i], ~0); | |
| 82 | } | ||
| 83 | 10 | } | |
| 84 | |||
| 85 | 50 | static int replace_alpha_plane(AVFrame *alpha, AVFrame *base) | |
| 86 | { | ||
| 87 | 50 | AVBufferRef *base_a = av_frame_get_plane_buffer(base, 3); | |
| 88 | 50 | uintptr_t data = (uintptr_t)alpha->data[0]; | |
| 89 | int ret; | ||
| 90 | |||
| 91 |
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++) { |
| 92 | 50 | AVBufferRef *buf = alpha->buf[i]; | |
| 93 | 50 | uintptr_t buf_begin = (uintptr_t)buf->data; | |
| 94 | |||
| 95 |
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) { |
| 96 | 50 | ret = av_buffer_replace(&alpha->buf[i], base_a); | |
| 97 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 50 times.
|
50 | if (ret < 0) |
| 98 | ✗ | return ret; | |
| 99 | |||
| 100 | 50 | alpha->linesize[0] = base->linesize[3]; | |
| 101 | 50 | alpha->data[0] = base->data[3]; | |
| 102 | |||
| 103 | 50 | return 0; | |
| 104 | } | ||
| 105 | } | ||
| 106 | |||
| 107 | ✗ | return AVERROR_BUG; | |
| 108 | } | ||
| 109 | |||
| 110 | 10489 | static HEVCFrame *alloc_frame(HEVCContext *s, HEVCLayerContext *l) | |
| 111 | { | ||
| 112 | 10489 | const HEVCVPS *vps = l->sps->vps; | |
| 113 | 10489 | const int view_id = vps->view_id[s->cur_layer]; | |
| 114 | int i, j, ret; | ||
| 115 |
1/2✓ Branch 0 taken 36536 times.
✗ Branch 1 not taken.
|
36536 | for (i = 0; i < FF_ARRAY_ELEMS(l->DPB); i++) { |
| 116 | 36536 | HEVCFrame *frame = &l->DPB[i]; | |
| 117 |
2/2✓ Branch 0 taken 26047 times.
✓ Branch 1 taken 10489 times.
|
36536 | if (frame->f) |
| 118 | 26047 | continue; | |
| 119 | |||
| 120 | 10489 | ret = ff_progress_frame_alloc(s->avctx, &frame->tf); | |
| 121 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 10489 times.
|
10489 | if (ret < 0) |
| 122 | ✗ | return NULL; | |
| 123 | |||
| 124 | // Add LCEVC SEI metadata here, as it's needed in get_buffer() | ||
| 125 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 10489 times.
|
10489 | if (s->sei.common.lcevc.info) { |
| 126 | ✗ | HEVCSEILCEVC *lcevc = &s->sei.common.lcevc; | |
| 127 | ✗ | ret = ff_frame_new_side_data_from_buf(s->avctx, frame->tf.f, | |
| 128 | AV_FRAME_DATA_LCEVC, &lcevc->info); | ||
| 129 | ✗ | if (ret < 0) | |
| 130 | ✗ | goto fail; | |
| 131 | } | ||
| 132 | |||
| 133 | // add view ID side data if it's nontrivial | ||
| 134 |
5/6✓ Branch 1 taken 10389 times.
✓ Branch 2 taken 100 times.
✓ Branch 3 taken 9704 times.
✓ Branch 4 taken 685 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 9704 times.
|
10489 | if (!ff_hevc_is_alpha_video(s) && (vps->nb_layers > 1 || view_id)) { |
| 135 | 685 | HEVCSEITDRDI *tdrdi = &s->sei.tdrdi; | |
| 136 | 685 | AVFrameSideData *sd = av_frame_side_data_new(&frame->f->side_data, | |
| 137 | 685 | &frame->f->nb_side_data, | |
| 138 | AV_FRAME_DATA_VIEW_ID, | ||
| 139 | sizeof(int), 0); | ||
| 140 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 685 times.
|
685 | if (!sd) |
| 141 | ✗ | goto fail; | |
| 142 | 685 | *(int*)sd->data = view_id; | |
| 143 | |||
| 144 |
2/2✓ Branch 0 taken 22 times.
✓ Branch 1 taken 663 times.
|
685 | if (tdrdi->num_ref_displays) { |
| 145 | AVStereo3D *stereo_3d; | ||
| 146 | |||
| 147 | 22 | stereo_3d = av_stereo3d_create_side_data(frame->f); | |
| 148 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 22 times.
|
22 | if (!stereo_3d) |
| 149 | ✗ | goto fail; | |
| 150 | |||
| 151 | 22 | stereo_3d->type = AV_STEREO3D_FRAMESEQUENCE; | |
| 152 |
2/2✓ Branch 0 taken 11 times.
✓ Branch 1 taken 11 times.
|
22 | if (tdrdi->left_view_id[0] == view_id) |
| 153 | 11 | stereo_3d->view = AV_STEREO3D_VIEW_LEFT; | |
| 154 |
1/2✓ Branch 0 taken 11 times.
✗ Branch 1 not taken.
|
11 | else if (tdrdi->right_view_id[0] == view_id) |
| 155 | 11 | stereo_3d->view = AV_STEREO3D_VIEW_RIGHT; | |
| 156 | else | ||
| 157 | ✗ | stereo_3d->view = AV_STEREO3D_VIEW_UNSPEC; | |
| 158 | } | ||
| 159 | } | ||
| 160 | |||
| 161 | 10489 | ret = ff_thread_get_buffer(s->avctx, frame->f, AV_GET_BUFFER_FLAG_REF); | |
| 162 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 10489 times.
|
10489 | if (ret < 0) |
| 163 | ✗ | goto fail; | |
| 164 | |||
| 165 | 10489 | frame->rpl = av_refstruct_allocz(s->pkt.nb_nals * sizeof(*frame->rpl)); | |
| 166 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 10489 times.
|
10489 | if (!frame->rpl) |
| 167 | ✗ | goto fail; | |
| 168 | 10489 | frame->nb_rpl_elems = s->pkt.nb_nals; | |
| 169 | |||
| 170 | 10489 | frame->tab_mvf = av_refstruct_pool_get(l->tab_mvf_pool); | |
| 171 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 10489 times.
|
10489 | if (!frame->tab_mvf) |
| 172 | ✗ | goto fail; | |
| 173 | |||
| 174 | 10489 | frame->rpl_tab = av_refstruct_pool_get(l->rpl_tab_pool); | |
| 175 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 10489 times.
|
10489 | if (!frame->rpl_tab) |
| 176 | ✗ | goto fail; | |
| 177 | 10489 | frame->ctb_count = l->sps->ctb_width * l->sps->ctb_height; | |
| 178 |
2/2✓ Branch 0 taken 2077757 times.
✓ Branch 1 taken 10489 times.
|
2088246 | for (j = 0; j < frame->ctb_count; j++) |
| 179 | 2077757 | frame->rpl_tab[j] = frame->rpl; | |
| 180 | |||
| 181 |
2/2✓ Branch 0 taken 15 times.
✓ Branch 1 taken 10474 times.
|
10489 | 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 10474 times.
✓ Branch 1 taken 15 times.
|
10489 | if ((s->sei.picture_timing.picture_struct == AV_PICTURE_STRUCTURE_TOP_FIELD) || |
| 184 |
2/2✓ Branch 0 taken 2 times.
✓ Branch 1 taken 10472 times.
|
10474 | (s->sei.picture_timing.picture_struct == AV_PICTURE_STRUCTURE_BOTTOM_FIELD)) |
| 185 | 17 | frame->f->flags |= AV_FRAME_FLAG_INTERLACED; | |
| 186 | |||
| 187 | 10489 | ret = ff_hwaccel_frame_priv_alloc(s->avctx, &frame->hwaccel_picture_private); | |
| 188 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 10489 times.
|
10489 | if (ret < 0) |
| 189 | ✗ | goto fail; | |
| 190 | |||
| 191 | 10489 | frame->pps = av_refstruct_ref_c(s->pps); | |
| 192 |
4/4✓ Branch 0 taken 390 times.
✓ Branch 1 taken 10099 times.
✓ Branch 3 taken 50 times.
✓ Branch 4 taken 340 times.
|
10489 | 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 | 10489 | 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 | 10427 | 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 333664 times.
✓ Branch 1 taken 10427 times.
|
344091 | for (i = 0; i < FF_ARRAY_ELEMS(l->DPB); i++) { |
| 217 | 333664 | HEVCFrame *frame = &l->DPB[i]; | |
| 218 | |||
| 219 |
3/4✓ Branch 0 taken 47697 times.
✓ Branch 1 taken 285967 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 47697 times.
|
333664 | 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 | 10427 | ref = alloc_frame(s, l); | |
| 227 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 10427 times.
|
10427 | if (!ref) |
| 228 | ✗ | return AVERROR(ENOMEM); | |
| 229 | |||
| 230 | 10427 | s->cur_frame = ref; | |
| 231 | 10427 | l->cur_frame = ref; | |
| 232 | 10427 | s->collocated_ref = NULL; | |
| 233 | |||
| 234 |
3/4✓ Branch 0 taken 390 times.
✓ Branch 1 taken 10037 times.
✓ Branch 2 taken 390 times.
✗ Branch 3 not taken.
|
10427 | ref->base_layer_frame = (l != &s->layers[0] && s->layers[0].cur_frame) ? |
| 235 | 390 | s->layers[0].cur_frame - s->layers[0].DPB : -1; | |
| 236 | |||
| 237 |
3/4✗ Branch 0 not taken.
✓ Branch 1 taken 742 times.
✓ Branch 2 taken 20 times.
✓ Branch 3 taken 9665 times.
|
10427 | no_output = !IS_IRAP(s) && (s->poc < s->recovery_poc) && |
| 238 |
1/4✗ Branch 0 not taken.
✓ Branch 1 taken 20 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
|
20 | HEVC_IS_RECOVERING(s) && |
| 239 |
2/4✓ Branch 0 taken 742 times.
✓ Branch 1 taken 9685 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
|
20854 | !(s->avctx->flags & AV_CODEC_FLAG_OUTPUT_CORRUPT) && |
| 240 | ✗ | !(s->avctx->flags2 & AV_CODEC_FLAG2_SHOW_ALL); | |
| 241 |
3/4✓ Branch 0 taken 10421 times.
✓ Branch 1 taken 6 times.
✓ Branch 2 taken 10421 times.
✗ Branch 3 not taken.
|
10427 | if (s->sh.pic_output_flag && !no_output) |
| 242 | 10421 | ref->flags = HEVC_FRAME_FLAG_OUTPUT | HEVC_FRAME_FLAG_SHORT_REF; | |
| 243 | else | ||
| 244 | 6 | ref->flags = HEVC_FRAME_FLAG_SHORT_REF; | |
| 245 | |||
| 246 | 10427 | ref->poc = poc; | |
| 247 | 10427 | ref->f->crop_left = l->sps->output_window.left_offset; | |
| 248 | 10427 | ref->f->crop_right = l->sps->output_window.right_offset; | |
| 249 | 10427 | ref->f->crop_top = l->sps->output_window.top_offset; | |
| 250 | 10427 | ref->f->crop_bottom = l->sps->output_window.bottom_offset; | |
| 251 | |||
| 252 | 10427 | return 0; | |
| 253 | } | ||
| 254 | |||
| 255 | 10427 | static void unref_missing_refs(HEVCLayerContext *l) | |
| 256 | { | ||
| 257 |
2/2✓ Branch 0 taken 333664 times.
✓ Branch 1 taken 10427 times.
|
344091 | for (int i = 0; i < FF_ARRAY_ELEMS(l->DPB); i++) { |
| 258 | 333664 | HEVCFrame *frame = &l->DPB[i]; | |
| 259 |
2/2✓ Branch 0 taken 37 times.
✓ Branch 1 taken 333627 times.
|
333664 | if (frame->flags & HEVC_FRAME_FLAG_UNAVAILABLE) { |
| 260 | 37 | ff_hevc_unref_frame(frame, ~0); | |
| 261 | } | ||
| 262 | } | ||
| 263 | 10427 | } | |
| 264 | |||
| 265 | 11206 | int ff_hevc_output_frames(HEVCContext *s, | |
| 266 | unsigned layers_active_decode, unsigned layers_active_output, | ||
| 267 | unsigned max_output, unsigned max_dpb, int discard) | ||
| 268 | { | ||
| 269 | 10282 | while (1) { | |
| 270 | 21488 | int nb_dpb[HEVC_VPS_MAX_LAYERS] = { 0 }; | |
| 271 | 21488 | int nb_output = 0; | |
| 272 | 21488 | int min_poc = INT_MAX; | |
| 273 | 21488 | int min_layer = -1; | |
| 274 | 21488 | int min_idx, ret = 0; | |
| 275 | |||
| 276 |
2/2✓ Branch 0 taken 42976 times.
✓ Branch 1 taken 21488 times.
|
64464 | for (int layer = 0; layer < FF_ARRAY_ELEMS(s->layers); layer++) { |
| 277 | 42976 | HEVCLayerContext *l = &s->layers[layer]; | |
| 278 | |||
| 279 |
2/2✓ Branch 0 taken 20328 times.
✓ Branch 1 taken 22648 times.
|
42976 | if (!(layers_active_decode & (1 << layer))) |
| 280 | 20328 | continue; | |
| 281 | |||
| 282 |
2/2✓ Branch 0 taken 724736 times.
✓ Branch 1 taken 22648 times.
|
747384 | for (int i = 0; i < FF_ARRAY_ELEMS(l->DPB); i++) { |
| 283 | 724736 | HEVCFrame *frame = &l->DPB[i]; | |
| 284 |
2/2✓ Branch 0 taken 56865 times.
✓ Branch 1 taken 667871 times.
|
724736 | if (frame->flags & HEVC_FRAME_FLAG_OUTPUT) { |
| 285 | // nb_output counts AUs with an output-pending frame | ||
| 286 | // in at least one layer | ||
| 287 |
2/2✓ Branch 0 taken 2420 times.
✓ Branch 1 taken 54445 times.
|
56865 | if (!(frame->base_layer_frame >= 0 && |
| 288 |
2/2✓ Branch 0 taken 402 times.
✓ Branch 1 taken 2018 times.
|
2420 | (s->layers[0].DPB[frame->base_layer_frame].flags & HEVC_FRAME_FLAG_OUTPUT))) |
| 289 | 54847 | nb_output++; | |
| 290 |
4/4✓ Branch 0 taken 39085 times.
✓ Branch 1 taken 17780 times.
✓ Branch 2 taken 12831 times.
✓ Branch 3 taken 26254 times.
|
56865 | if (min_layer < 0 || frame->poc < min_poc) { |
| 291 | 30611 | min_poc = frame->poc; | |
| 292 | 30611 | min_idx = i; | |
| 293 | 30611 | min_layer = layer; | |
| 294 | } | ||
| 295 | } | ||
| 296 | 724736 | nb_dpb[layer] += !!frame->flags; | |
| 297 | } | ||
| 298 | } | ||
| 299 | |||
| 300 |
4/4✓ Branch 0 taken 11655 times.
✓ Branch 1 taken 9833 times.
✓ Branch 2 taken 7947 times.
✓ Branch 3 taken 3708 times.
|
21488 | if (nb_output > max_output || |
| 301 | 7947 | (nb_output && | |
| 302 |
4/4✓ Branch 0 taken 7510 times.
✓ Branch 1 taken 437 times.
✓ Branch 2 taken 12 times.
✓ Branch 3 taken 7498 times.
|
7947 | (nb_dpb[0] > max_dpb || nb_dpb[1] > max_dpb))) { |
| 303 | 10282 | HEVCFrame *frame = &s->layers[min_layer].DPB[min_idx]; | |
| 304 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 10282 times.
|
10282 | AVFrame *f = frame->needs_fg ? frame->frame_grain : frame->f; |
| 305 |
4/4✓ Branch 0 taken 10253 times.
✓ Branch 1 taken 29 times.
✓ Branch 2 taken 10140 times.
✓ Branch 3 taken 113 times.
|
10282 | int output = !discard && (layers_active_output & (1 << min_layer)); |
| 306 | |||
| 307 |
2/2✓ Branch 0 taken 10140 times.
✓ Branch 1 taken 142 times.
|
10282 | if (output) { |
| 308 |
2/2✓ Branch 0 taken 51 times.
✓ Branch 1 taken 10089 times.
|
10140 | if (frame->flags & HEVC_FRAME_FLAG_CORRUPT) |
| 309 | 51 | f->flags |= AV_FRAME_FLAG_CORRUPT; | |
| 310 | 10140 | f->pkt_dts = s->pkt_dts; | |
| 311 | 10140 | ret = av_container_fifo_write(s->output_fifo, f, AV_CONTAINER_FIFO_FLAG_REF); | |
| 312 | } | ||
| 313 | 10282 | ff_hevc_unref_frame(frame, HEVC_FRAME_FLAG_OUTPUT); | |
| 314 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 10282 times.
|
10282 | if (ret < 0) |
| 315 | 11206 | return ret; | |
| 316 | |||
| 317 |
2/2✓ Branch 0 taken 10140 times.
✓ Branch 1 taken 142 times.
|
10282 | av_log(s->avctx, AV_LOG_DEBUG, "%s frame with POC %d/%d.\n", |
| 318 | output ? "Output" : "Discarded", min_layer, frame->poc); | ||
| 319 | 10282 | continue; | |
| 320 | } | ||
| 321 | 11206 | return 0; | |
| 322 | } | ||
| 323 | } | ||
| 324 | |||
| 325 | 19450 | static int init_slice_rpl(HEVCContext *s) | |
| 326 | { | ||
| 327 | 19450 | HEVCFrame *frame = s->cur_frame; | |
| 328 | 19450 | int ctb_count = frame->ctb_count; | |
| 329 | 19450 | int ctb_addr_ts = s->pps->ctb_addr_rs_to_ts[s->sh.slice_segment_addr]; | |
| 330 | int i; | ||
| 331 | |||
| 332 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 19450 times.
|
19450 | if (s->slice_idx >= frame->nb_rpl_elems) |
| 333 | ✗ | return AVERROR_INVALIDDATA; | |
| 334 | |||
| 335 |
2/2✓ Branch 0 taken 2836512 times.
✓ Branch 1 taken 19450 times.
|
2855962 | for (i = ctb_addr_ts; i < ctb_count; i++) |
| 336 | 2836512 | frame->rpl_tab[i] = frame->rpl + s->slice_idx; | |
| 337 | |||
| 338 | 19450 | frame->refPicList = (RefPicList *)frame->rpl_tab[ctb_addr_ts]; | |
| 339 | |||
| 340 | 19450 | return 0; | |
| 341 | } | ||
| 342 | |||
| 343 | 19450 | int ff_hevc_slice_rpl(HEVCContext *s) | |
| 344 | { | ||
| 345 | 19450 | SliceHeader *sh = &s->sh; | |
| 346 | |||
| 347 |
2/2✓ Branch 0 taken 15151 times.
✓ Branch 1 taken 4299 times.
|
19450 | uint8_t nb_list = sh->slice_type == HEVC_SLICE_B ? 2 : 1; |
| 348 | uint8_t list_idx; | ||
| 349 | int i, j, ret; | ||
| 350 | |||
| 351 | 19450 | ret = init_slice_rpl(s); | |
| 352 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 19450 times.
|
19450 | if (ret < 0) |
| 353 | ✗ | return ret; | |
| 354 | |||
| 355 | 19450 | if (!(s->rps[ST_CURR_BEF].nb_refs + s->rps[ST_CURR_AFT].nb_refs + | |
| 356 | 19450 | s->rps[LT_CURR].nb_refs + | |
| 357 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 19450 times.
|
19450 | s->rps[INTER_LAYER0].nb_refs + s->rps[INTER_LAYER1].nb_refs) && |
| 358 | ✗ | !s->pps->pps_curr_pic_ref_enabled_flag) { | |
| 359 | ✗ | av_log(s->avctx, AV_LOG_ERROR, "Zero refs in the frame RPS.\n"); | |
| 360 | ✗ | return AVERROR_INVALIDDATA; | |
| 361 | } | ||
| 362 | |||
| 363 |
2/2✓ Branch 0 taken 34601 times.
✓ Branch 1 taken 19450 times.
|
54051 | for (list_idx = 0; list_idx < nb_list; list_idx++) { |
| 364 | 34601 | RefPicList rpl_tmp = { { 0 } }; | |
| 365 | 34601 | RefPicList *rpl = &s->cur_frame->refPicList[list_idx]; | |
| 366 | |||
| 367 | /* The order of the elements is | ||
| 368 | * ST_CURR_BEF - INTER_LAYER0 - ST_CURR_AFT - LT_CURR - INTER_LAYER1 for the L0 and | ||
| 369 | * ST_CURR_AFT - INTER_LAYER1 - ST_CURR_BEF - LT_CURR - INTER_LAYER0 for the L1 */ | ||
| 370 | 103803 | int cand_lists[] = { list_idx ? ST_CURR_AFT : ST_CURR_BEF, | |
| 371 |
2/2✓ Branch 0 taken 15151 times.
✓ Branch 1 taken 19450 times.
|
34601 | list_idx ? INTER_LAYER1 : INTER_LAYER0, |
| 372 | 34601 | list_idx ? ST_CURR_BEF : ST_CURR_AFT, | |
| 373 | LT_CURR, | ||
| 374 |
2/2✓ Branch 0 taken 15151 times.
✓ Branch 1 taken 19450 times.
|
34601 | list_idx ? INTER_LAYER0 : INTER_LAYER1 |
| 375 | }; | ||
| 376 | |||
| 377 | /* concatenate the candidate lists for the current frame */ | ||
| 378 |
2/2✓ Branch 0 taken 34619 times.
✓ Branch 1 taken 34601 times.
|
69220 | while (rpl_tmp.nb_refs < sh->nb_refs[list_idx]) { |
| 379 |
2/2✓ Branch 0 taken 173095 times.
✓ Branch 1 taken 34619 times.
|
207714 | for (i = 0; i < FF_ARRAY_ELEMS(cand_lists); i++) { |
| 380 | 173095 | RefPicList *rps = &s->rps[cand_lists[i]]; | |
| 381 |
3/4✓ Branch 0 taken 124188 times.
✓ Branch 1 taken 173095 times.
✓ Branch 2 taken 124188 times.
✗ Branch 3 not taken.
|
297283 | for (j = 0; j < rps->nb_refs && rpl_tmp.nb_refs < HEVC_MAX_REFS; j++) { |
| 382 | 124188 | rpl_tmp.list[rpl_tmp.nb_refs] = rps->list[j]; | |
| 383 | 124188 | rpl_tmp.ref[rpl_tmp.nb_refs] = rps->ref[j]; | |
| 384 | // multiview inter-layer refs are treated as long-term here, | ||
| 385 | // cf. G.8.1.3 | ||
| 386 | 371158 | rpl_tmp.isLongTerm[rpl_tmp.nb_refs] = cand_lists[i] == LT_CURR || | |
| 387 |
4/4✓ Branch 0 taken 122782 times.
✓ Branch 1 taken 1406 times.
✓ Branch 2 taken 122204 times.
✓ Branch 3 taken 578 times.
|
246392 | cand_lists[i] == INTER_LAYER0 || |
| 388 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 122204 times.
|
122204 | cand_lists[i] == INTER_LAYER1; |
| 389 | 124188 | rpl_tmp.nb_refs++; | |
| 390 | } | ||
| 391 | } | ||
| 392 | // Construct RefPicList0, RefPicList1 (8-8, 8-10) | ||
| 393 |
1/4✗ Branch 0 not taken.
✓ Branch 1 taken 34619 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
|
34619 | if (s->pps->pps_curr_pic_ref_enabled_flag && rpl_tmp.nb_refs < HEVC_MAX_REFS) { |
| 394 | ✗ | rpl_tmp.list[rpl_tmp.nb_refs] = s->cur_frame->poc; | |
| 395 | ✗ | rpl_tmp.ref[rpl_tmp.nb_refs] = s->cur_frame; | |
| 396 | ✗ | rpl_tmp.isLongTerm[rpl_tmp.nb_refs] = 1; | |
| 397 | ✗ | rpl_tmp.nb_refs++; | |
| 398 | } | ||
| 399 | } | ||
| 400 | |||
| 401 | /* reorder the references if necessary */ | ||
| 402 |
2/2✓ Branch 0 taken 2083 times.
✓ Branch 1 taken 32518 times.
|
34601 | if (sh->rpl_modification_flag[list_idx]) { |
| 403 |
2/2✓ Branch 0 taken 4920 times.
✓ Branch 1 taken 2083 times.
|
7003 | for (i = 0; i < sh->nb_refs[list_idx]; i++) { |
| 404 | 4920 | int idx = sh->list_entry_lx[list_idx][i]; | |
| 405 | |||
| 406 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 4920 times.
|
4920 | if (idx >= rpl_tmp.nb_refs) { |
| 407 | ✗ | av_log(s->avctx, AV_LOG_ERROR, "Invalid reference index.\n"); | |
| 408 | ✗ | return AVERROR_INVALIDDATA; | |
| 409 | } | ||
| 410 | |||
| 411 | 4920 | rpl->list[i] = rpl_tmp.list[idx]; | |
| 412 | 4920 | rpl->ref[i] = rpl_tmp.ref[idx]; | |
| 413 | 4920 | rpl->isLongTerm[i] = rpl_tmp.isLongTerm[idx]; | |
| 414 | 4920 | rpl->nb_refs++; | |
| 415 | } | ||
| 416 | } else { | ||
| 417 | 32518 | memcpy(rpl, &rpl_tmp, sizeof(*rpl)); | |
| 418 | 32518 | rpl->nb_refs = FFMIN(rpl->nb_refs, sh->nb_refs[list_idx]); | |
| 419 | } | ||
| 420 | |||
| 421 | // 8-9 | ||
| 422 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 34601 times.
|
34601 | if (s->pps->pps_curr_pic_ref_enabled_flag && |
| 423 | ✗ | !sh->rpl_modification_flag[list_idx] && | |
| 424 | ✗ | rpl_tmp.nb_refs > sh->nb_refs[L0]) { | |
| 425 | ✗ | rpl->list[sh->nb_refs[L0] - 1] = s->cur_frame->poc; | |
| 426 | ✗ | rpl->ref[sh->nb_refs[L0] - 1] = s->cur_frame; | |
| 427 | } | ||
| 428 | |||
| 429 |
2/2✓ Branch 0 taken 19449 times.
✓ Branch 1 taken 15152 times.
|
34601 | if (sh->collocated_list == list_idx && |
| 430 |
1/2✓ Branch 0 taken 19449 times.
✗ Branch 1 not taken.
|
19449 | sh->collocated_ref_idx < rpl->nb_refs) |
| 431 | 19449 | s->collocated_ref = rpl->ref[sh->collocated_ref_idx]; | |
| 432 | } | ||
| 433 | |||
| 434 | 19450 | return 0; | |
| 435 | } | ||
| 436 | |||
| 437 | 37482 | static HEVCFrame *find_ref_idx(HEVCContext *s, HEVCLayerContext *l, | |
| 438 | int poc, uint8_t use_msb) | ||
| 439 | { | ||
| 440 |
2/2✓ Branch 0 taken 1635 times.
✓ Branch 1 taken 35847 times.
|
37482 | int mask = use_msb ? ~0 : (1 << l->sps->log2_max_poc_lsb) - 1; |
| 441 | int i; | ||
| 442 | |||
| 443 |
2/2✓ Branch 0 taken 152813 times.
✓ Branch 1 taken 62 times.
|
152875 | for (i = 0; i < FF_ARRAY_ELEMS(l->DPB); i++) { |
| 444 | 152813 | HEVCFrame *ref = &l->DPB[i]; | |
| 445 |
2/2✓ Branch 0 taken 147884 times.
✓ Branch 1 taken 4929 times.
|
152813 | if (ref->f) { |
| 446 |
5/6✓ Branch 0 taken 37420 times.
✓ Branch 1 taken 110464 times.
✓ Branch 2 taken 1634 times.
✓ Branch 3 taken 35786 times.
✓ Branch 4 taken 1634 times.
✗ Branch 5 not taken.
|
147884 | if ((ref->poc & mask) == poc && (use_msb || ref->poc != s->poc)) |
| 447 | 37420 | return ref; | |
| 448 | } | ||
| 449 | } | ||
| 450 | |||
| 451 |
7/8✓ Branch 0 taken 23 times.
✓ Branch 1 taken 39 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.
|
62 | if (s->nal_unit_type != HEVC_NAL_CRA_NUT && !IS_BLA(s)) |
| 452 | 20 | av_log(s->avctx, AV_LOG_ERROR, | |
| 453 | "Could not find ref with POC %d\n", poc); | ||
| 454 | 62 | return NULL; | |
| 455 | } | ||
| 456 | |||
| 457 | 360719 | static void mark_ref(HEVCFrame *frame, int flag) | |
| 458 | { | ||
| 459 | 360719 | frame->flags &= ~(HEVC_FRAME_FLAG_LONG_REF | HEVC_FRAME_FLAG_SHORT_REF); | |
| 460 | 360719 | frame->flags |= flag; | |
| 461 | 360719 | } | |
| 462 | |||
| 463 | 62 | static HEVCFrame *generate_missing_ref(HEVCContext *s, HEVCLayerContext *l, int poc) | |
| 464 | { | ||
| 465 | HEVCFrame *frame; | ||
| 466 | int i, y; | ||
| 467 | |||
| 468 | 62 | frame = alloc_frame(s, l); | |
| 469 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 62 times.
|
62 | if (!frame) |
| 470 | ✗ | return NULL; | |
| 471 | |||
| 472 |
1/2✓ Branch 0 taken 62 times.
✗ Branch 1 not taken.
|
62 | if (!s->avctx->hwaccel) { |
| 473 |
2/2✓ Branch 0 taken 42 times.
✓ Branch 1 taken 20 times.
|
62 | if (!l->sps->pixel_shift) { |
| 474 |
2/2✓ Branch 0 taken 126 times.
✓ Branch 1 taken 42 times.
|
168 | for (i = 0; frame->f->data[i]; i++) |
| 475 | 126 | memset(frame->f->data[i], 1 << (l->sps->bit_depth - 1), | |
| 476 | 126 | frame->f->linesize[i] * AV_CEIL_RSHIFT(l->sps->height, l->sps->vshift[i])); | |
| 477 | } else { | ||
| 478 |
2/2✓ Branch 0 taken 60 times.
✓ Branch 1 taken 20 times.
|
80 | for (i = 0; frame->f->data[i]; i++) |
| 479 |
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++) { |
| 480 | 71424 | uint8_t *dst = frame->f->data[i] + y * frame->f->linesize[i]; | |
| 481 | 71424 | AV_WN16(dst, 1 << (l->sps->bit_depth - 1)); | |
| 482 | 71424 | av_memcpy_backptr(dst + 2, 2, 2*(l->sps->width >> l->sps->hshift[i]) - 2); | |
| 483 | } | ||
| 484 | } | ||
| 485 | } | ||
| 486 | |||
| 487 | 62 | frame->poc = poc; | |
| 488 | 62 | frame->flags = HEVC_FRAME_FLAG_UNAVAILABLE; | |
| 489 | |||
| 490 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 62 times.
|
62 | if (s->avctx->active_thread_type == FF_THREAD_FRAME) |
| 491 | ✗ | ff_progress_frame_report(&frame->tf, INT_MAX); | |
| 492 | |||
| 493 | 62 | return frame; | |
| 494 | } | ||
| 495 | |||
| 496 | /* add a reference with the given poc to the list and mark it as used in DPB */ | ||
| 497 | 37482 | static int add_candidate_ref(HEVCContext *s, HEVCLayerContext *l, | |
| 498 | RefPicList *list, | ||
| 499 | int poc, int ref_flag, uint8_t use_msb) | ||
| 500 | { | ||
| 501 | 37482 | HEVCFrame *ref = find_ref_idx(s, l, poc, use_msb); | |
| 502 | |||
| 503 |
2/4✓ Branch 0 taken 37482 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 37482 times.
|
37482 | if (ref == s->cur_frame || list->nb_refs >= HEVC_MAX_REFS) |
| 504 | ✗ | return AVERROR_INVALIDDATA; | |
| 505 | |||
| 506 |
3/4✓ Branch 0 taken 729 times.
✓ Branch 1 taken 36753 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 729 times.
|
37482 | if (!IS_IRAP(s)) { |
| 507 |
4/4✓ Branch 0 taken 36733 times.
✓ Branch 1 taken 20 times.
✓ Branch 2 taken 117 times.
✓ Branch 3 taken 36616 times.
|
36753 | int ref_corrupt = !ref || ref->flags & (HEVC_FRAME_FLAG_CORRUPT | |
| 508 | HEVC_FRAME_FLAG_UNAVAILABLE); | ||
| 509 |
3/4✓ Branch 0 taken 36730 times.
✓ Branch 1 taken 23 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 36730 times.
|
36753 | int recovering = HEVC_IS_RECOVERING(s); |
| 510 | |||
| 511 |
3/4✓ Branch 0 taken 137 times.
✓ Branch 1 taken 36616 times.
✓ Branch 2 taken 137 times.
✗ Branch 3 not taken.
|
36753 | if (ref_corrupt && !recovering) { |
| 512 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 137 times.
|
137 | if (!(s->avctx->flags & AV_CODEC_FLAG_OUTPUT_CORRUPT) && |
| 513 | ✗ | !(s->avctx->flags2 & AV_CODEC_FLAG2_SHOW_ALL)) | |
| 514 | ✗ | return AVERROR_INVALIDDATA; | |
| 515 | |||
| 516 | 137 | s->cur_frame->flags |= HEVC_FRAME_FLAG_CORRUPT; | |
| 517 | } | ||
| 518 | } | ||
| 519 | |||
| 520 |
2/2✓ Branch 0 taken 62 times.
✓ Branch 1 taken 37420 times.
|
37482 | if (!ref) { |
| 521 | 62 | ref = generate_missing_ref(s, l, poc); | |
| 522 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 62 times.
|
62 | if (!ref) |
| 523 | ✗ | return AVERROR(ENOMEM); | |
| 524 | } | ||
| 525 | |||
| 526 | 37482 | list->list[list->nb_refs] = ref->poc; | |
| 527 | 37482 | list->ref[list->nb_refs] = ref; | |
| 528 | 37482 | list->nb_refs++; | |
| 529 | |||
| 530 | 37482 | mark_ref(ref, ref_flag); | |
| 531 | 37482 | return 0; | |
| 532 | } | ||
| 533 | |||
| 534 | 10427 | int ff_hevc_frame_rps(HEVCContext *s, HEVCLayerContext *l) | |
| 535 | { | ||
| 536 | 10427 | const ShortTermRPS *short_rps = s->sh.short_term_rps; | |
| 537 | 10427 | const LongTermRPS *long_rps = &s->sh.long_term_rps; | |
| 538 | 10427 | RefPicList *rps = s->rps; | |
| 539 | 10427 | int i, ret = 0; | |
| 540 | |||
| 541 | 10427 | unref_missing_refs(l); | |
| 542 | |||
| 543 | /* clear the reference flags on all frames except the current one */ | ||
| 544 |
2/2✓ Branch 0 taken 333664 times.
✓ Branch 1 taken 10427 times.
|
344091 | for (i = 0; i < FF_ARRAY_ELEMS(l->DPB); i++) { |
| 545 | 333664 | HEVCFrame *frame = &l->DPB[i]; | |
| 546 | |||
| 547 |
2/2✓ Branch 0 taken 10427 times.
✓ Branch 1 taken 323237 times.
|
333664 | if (frame == s->cur_frame) |
| 548 | 10427 | continue; | |
| 549 | |||
| 550 | 323237 | mark_ref(frame, 0); | |
| 551 | } | ||
| 552 | |||
| 553 |
2/2✓ Branch 0 taken 72989 times.
✓ Branch 1 taken 10427 times.
|
83416 | for (i = 0; i < NB_RPS_TYPE; i++) |
| 554 | 72989 | rps[i].nb_refs = 0; | |
| 555 | |||
| 556 |
2/2✓ Branch 0 taken 439 times.
✓ Branch 1 taken 9988 times.
|
10427 | if (!short_rps) |
| 557 | 439 | goto inter_layer; | |
| 558 | |||
| 559 | /* add the short refs */ | ||
| 560 |
2/2✓ Branch 0 taken 35504 times.
✓ Branch 1 taken 9988 times.
|
45492 | for (i = 0; i < short_rps->num_delta_pocs; i++) { |
| 561 | 35504 | int poc = s->poc + short_rps->delta_poc[i]; | |
| 562 | int list; | ||
| 563 | |||
| 564 |
2/2✓ Branch 0 taken 1770 times.
✓ Branch 1 taken 33734 times.
|
35504 | if (!(short_rps->used & (1 << i))) |
| 565 | 1770 | list = ST_FOLL; | |
| 566 |
2/2✓ Branch 0 taken 24462 times.
✓ Branch 1 taken 9272 times.
|
33734 | else if (i < short_rps->num_negative_pics) |
| 567 | 24462 | list = ST_CURR_BEF; | |
| 568 | else | ||
| 569 | 9272 | list = ST_CURR_AFT; | |
| 570 | |||
| 571 | 35504 | ret = add_candidate_ref(s, l, &rps[list], poc, | |
| 572 | HEVC_FRAME_FLAG_SHORT_REF, 1); | ||
| 573 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 35504 times.
|
35504 | if (ret < 0) |
| 574 | ✗ | goto fail; | |
| 575 | } | ||
| 576 | |||
| 577 | /* add the long refs */ | ||
| 578 |
2/2✓ Branch 0 taken 1683 times.
✓ Branch 1 taken 9988 times.
|
11671 | for (i = 0; i < long_rps->nb_refs; i++) { |
| 579 | 1683 | int poc = long_rps->poc[i]; | |
| 580 |
2/2✓ Branch 0 taken 696 times.
✓ Branch 1 taken 987 times.
|
1683 | int list = long_rps->used[i] ? LT_CURR : LT_FOLL; |
| 581 | |||
| 582 | 1683 | ret = add_candidate_ref(s, l, &rps[list], poc, | |
| 583 | 1683 | HEVC_FRAME_FLAG_LONG_REF, long_rps->poc_msb_present[i]); | |
| 584 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 1683 times.
|
1683 | if (ret < 0) |
| 585 | ✗ | goto fail; | |
| 586 | } | ||
| 587 | |||
| 588 | 9988 | inter_layer: | |
| 589 | /* add inter-layer refs */ | ||
| 590 |
2/2✓ Branch 0 taken 10132 times.
✓ Branch 1 taken 295 times.
|
10427 | if (s->sh.inter_layer_pred) { |
| 591 | 295 | HEVCLayerContext *l0 = &s->layers[0]; | |
| 592 | |||
| 593 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 295 times.
|
295 | av_assert0(l != l0); |
| 594 | |||
| 595 | /* Given the assumption of at most two layers, refPicSet0Flag is | ||
| 596 | * always 1, so only RefPicSetInterLayer0 can ever contain a frame. */ | ||
| 597 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 295 times.
|
295 | if (l0->cur_frame) { |
| 598 | // inter-layer refs are treated as short-term here, cf. F.8.1.6 | ||
| 599 | 295 | ret = add_candidate_ref(s, l0, &rps[INTER_LAYER0], l0->cur_frame->poc, | |
| 600 | HEVC_FRAME_FLAG_SHORT_REF, 1); | ||
| 601 |
1/2✓ Branch 0 taken 295 times.
✗ Branch 1 not taken.
|
295 | if (ret < 0) |
| 602 | ✗ | goto fail; | |
| 603 | } | ||
| 604 | } | ||
| 605 | |||
| 606 | 10427 | fail: | |
| 607 | /* release any frames that are now unused */ | ||
| 608 |
2/2✓ Branch 0 taken 333664 times.
✓ Branch 1 taken 10427 times.
|
344091 | for (i = 0; i < FF_ARRAY_ELEMS(l->DPB); i++) |
| 609 | 333664 | ff_hevc_unref_frame(&l->DPB[i], 0); | |
| 610 | |||
| 611 | 10427 | return ret; | |
| 612 | } | ||
| 613 | |||
| 614 | 19536 | int ff_hevc_frame_nb_refs(const SliceHeader *sh, const HEVCPPS *pps, | |
| 615 | unsigned layer_idx) | ||
| 616 | { | ||
| 617 | 19536 | int ret = 0; | |
| 618 | int i; | ||
| 619 | 19536 | const ShortTermRPS *rps = sh->short_term_rps; | |
| 620 | 19536 | const LongTermRPS *long_rps = &sh->long_term_rps; | |
| 621 | |||
| 622 |
2/2✓ Branch 0 taken 19523 times.
✓ Branch 1 taken 13 times.
|
19536 | if (rps) { |
| 623 |
2/2✓ Branch 0 taken 46692 times.
✓ Branch 1 taken 19523 times.
|
66215 | for (i = 0; i < rps->num_negative_pics; i++) |
| 624 | 46692 | ret += !!(rps->used & (1 << i)); | |
| 625 |
2/2✓ Branch 0 taken 21074 times.
✓ Branch 1 taken 19523 times.
|
40597 | for (; i < rps->num_delta_pocs; i++) |
| 626 | 21074 | ret += !!(rps->used & (1 << i)); | |
| 627 | } | ||
| 628 | |||
| 629 |
2/2✓ Branch 0 taken 1787 times.
✓ Branch 1 taken 19536 times.
|
21323 | for (i = 0; i < long_rps->nb_refs; i++) |
| 630 | 1787 | ret += !!long_rps->used[i]; | |
| 631 | |||
| 632 |
2/2✓ Branch 0 taken 421 times.
✓ Branch 1 taken 19115 times.
|
19536 | if (sh->inter_layer_pred) { |
| 633 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 421 times.
|
421 | av_assert0(pps->sps->vps->num_direct_ref_layers[layer_idx] < 2); |
| 634 | 421 | ret++; | |
| 635 | } | ||
| 636 | |||
| 637 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 19536 times.
|
19536 | if (pps->pps_curr_pic_ref_enabled_flag) |
| 638 | ✗ | ret++; | |
| 639 | |||
| 640 | 19536 | return ret; | |
| 641 | } | ||
| 642 |