fixes https://trac.ffmpeg.org/ticket/11406
Unified · Split
| @@ -21,6 +21,7 @@ · 20 unmodified lines | ||
| 21 | 21 | */ |
| 22 | 22 | |
| 23 | 23 | #include <stdatomic.h> |
| 24 | +#include <stdbool.h> | |
| 24 | 25 | |
| 25 | 26 | #include "libavutil/mem.h" |
| 26 | 27 | #include "libavutil/thread.h" |
| @@ -168,6 +169,36 @@ fail: · 141 unmodified lines | ||
| 168 | 169 | return NULL; |
| 169 | 170 | } |
| 170 | 171 | |
| 172 | +static void set_pict_type(AVFrame *frame, const VVCContext *s, const VVCFrameContext *fc) | |
| 173 | +{ | |
| 174 | + bool has_b = false, has_inter = false; | |
| 175 | + | |
| 176 | + if (IS_IRAP(s)) { | |
| 177 | + frame->pict_type = AV_PICTURE_TYPE_I; | |
| 178 | + frame->flags |= AV_FRAME_FLAG_KEY; | |
| 179 | + return; | |
| 180 | + } | |
| 181 | + | |
| 182 | + if (fc->ps.ph.r->ph_inter_slice_allowed_flag) { | |
| 183 | + // At this point, fc->slices is not fully initialized; we need to inspect the CBS directly. | |
| 184 | + const CodedBitstreamFragment *current = &s->current_frame; | |
| 185 | + for (int i = 0; i < current->nb_units && !has_b; i++) { | |
| 186 | + const CodedBitstreamUnit *unit = current->units + i; | |
| 187 | + if (unit->type <= VVC_RSV_IRAP_11) { | |
| 188 | + const H266RawSliceHeader *rsh = unit->content_ref; | |
| 189 | + has_inter |= !IS_I(rsh); | |
| 190 | + has_b |= IS_B(rsh); | |
| 191 | + } | |
| 192 | + } | |
| 193 | + } | |
| 194 | + if (!has_inter) | |
| 195 | + frame->pict_type = AV_PICTURE_TYPE_I; | |
| 196 | + else if (has_b) | |
| 197 | + frame->pict_type = AV_PICTURE_TYPE_B; | |
| 198 | + else | |
| 199 | + frame->pict_type = AV_PICTURE_TYPE_P; | |
| 200 | +} | |
| 201 | + | |
| 171 | 202 | int ff_vvc_set_new_ref(VVCContext *s, VVCFrameContext *fc, AVFrame **frame) |
| 172 | 203 | { |
| 173 | 204 | const VVCPH *ph= &fc->ps.ph; |
| @@ -189,6 +220,7 @@ int ff_vvc_set_new_ref(VVCContext *s, VVCFrameContext *fc, AVFrame **frame) · 15 unmodified lines | ||
| 189 | 220 | if (!ref) |
| 190 | 221 | return AVERROR(ENOMEM); |
| 191 | 222 | |
| 223 | + set_pict_type(ref->frame, s, fc); | |
| 192 | 224 | *frame = ref->frame; |
| 193 | 225 | fc->ref = ref; |
| 194 | 226 | |