| 294 | } |
| 295 | |
| 296 | int ff_vk_decode_add_slice(AVCodecContext *avctx, FFVulkanDecodePicture *vp, |
| 297 | const uint8_t *data, size_t size, int add_startcode, |
| 298 | uint32_t *nb_slices, const uint32_t **offsets) |
| 299 | { |
| 300 | FFVulkanDecodeContext *dec = avctx->internal->hwaccel_priv_data; |
| 301 | FFVulkanDecodeShared *ctx = dec->shared_ctx; |
| 302 | |
| 303 | static const uint8_t startcode_prefix[3] = { 0x0, 0x0, 0x1 }; |
| 304 | const size_t startcode_len = add_startcode ? sizeof(startcode_prefix) : 0; |
| 305 | const int nb = nb_slices ? *nb_slices : 0; |
| 306 | uint8_t *slices; |
| 307 | uint32_t *slice_off; |
| 308 | FFVkBuffer *vkbuf; |
| 309 | |
| 310 | size_t new_size = vp->slices_size + startcode_len + size + |
| 311 | ctx->caps.minBitstreamBufferSizeAlignment; |
| 312 | new_size = FFALIGN(new_size, ctx->caps.minBitstreamBufferSizeAlignment); |
| 313 | |
| 314 | if (offsets) { |
| 315 | slice_off = av_fast_realloc(dec->slice_off, &dec->slice_off_max, |
| 316 | (nb + 1)*sizeof(slice_off)); |
| 317 | if (!slice_off) |
| 318 | return AVERROR(ENOMEM); |
| 319 | |
| 320 | *offsets = dec->slice_off = slice_off; |
| 321 | |
| 322 | slice_off[nb] = vp->slices_size; |
| 323 | } |
| 324 | |
| 325 | vkbuf = vp->slices_buf ? (FFVkBuffer *)vp->slices_buf->data : NULL; |
| 326 | if (!vkbuf || vkbuf->size < new_size) { |
| 327 | int err; |
| 328 | AVBufferRef *new_ref; |
| 329 | FFVkBuffer *new_buf; |
| 330 | |
| 331 | /* No point in requesting anything smaller. */ |
| 332 | size_t buf_size = FFMAX(new_size, 1024*1024); |
| 333 | |
| 334 | /* Align buffer to nearest power of two. Makes fragmentation management |
| 335 | * easier, and gives us ample headroom. */ |
| 336 | buf_size = 2 << av_log2(buf_size); |
| 337 | |
| 338 | err = ff_vk_get_pooled_buffer(&ctx->s, &ctx->buf_pool, &new_ref, |
| 339 | DECODER_IS_SDR(avctx->codec_id) ? |
| 340 | (VK_BUFFER_USAGE_STORAGE_BUFFER_BIT | |
| 341 | VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT) : |
| 342 | VK_BUFFER_USAGE_VIDEO_DECODE_SRC_BIT_KHR, |
| 343 | ctx->s.hwfc->create_pnext, buf_size, |
| 344 | VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | |
| 345 | (DECODER_IS_SDR(avctx->codec_id) ? |
| 346 | VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT : 0x0)); |
| 347 | if (err < 0) |
| 348 | return err; |
| 349 | |
| 350 | new_buf = (FFVkBuffer *)new_ref->data; |
| 351 | |
| 352 | /* Copy data from the old buffer */ |
| 353 | if (vkbuf) { |
no test coverage detected