| 257 | } |
| 258 | |
| 259 | static int commit_bitstream_and_slice_buffer(AVCodecContext *avctx, |
| 260 | DXVA2_DecodeBufferDesc *bs, |
| 261 | DXVA2_DecodeBufferDesc *sc) |
| 262 | { |
| 263 | const H264Context *h = avctx->priv_data; |
| 264 | const MpegEncContext *s = &h->s; |
| 265 | const unsigned mb_count = s->mb_width * s->mb_height; |
| 266 | struct dxva_context *ctx = avctx->hwaccel_context; |
| 267 | const Picture *current_picture = h->s.current_picture_ptr; |
| 268 | struct dxva2_picture_context *ctx_pic = current_picture->hwaccel_picture_private; |
| 269 | DXVA_Slice_H264_Short *slice = NULL; |
| 270 | uint8_t *dxva_data, *current, *end; |
| 271 | unsigned dxva_size; |
| 272 | void *slice_data; |
| 273 | unsigned slice_size; |
| 274 | unsigned padding; |
| 275 | unsigned i; |
| 276 | |
| 277 | /* Create an annex B bitstream buffer with only slice NAL and finalize slice */ |
| 278 | if (FAILED(IDirectXVideoDecoder_GetBuffer(ctx->decoder, |
| 279 | DXVA2_BitStreamDateBufferType, |
| 280 | &dxva_data, &dxva_size))) |
| 281 | return -1; |
| 282 | current = dxva_data; |
| 283 | end = dxva_data + dxva_size; |
| 284 | |
| 285 | for (i = 0; i < ctx_pic->slice_count; i++) { |
| 286 | static const uint8_t start_code[] = { 0, 0, 1 }; |
| 287 | static const unsigned start_code_size = sizeof(start_code); |
| 288 | unsigned position, size; |
| 289 | |
| 290 | assert(offsetof(DXVA_Slice_H264_Short, BSNALunitDataLocation) == |
| 291 | offsetof(DXVA_Slice_H264_Long, BSNALunitDataLocation)); |
| 292 | assert(offsetof(DXVA_Slice_H264_Short, SliceBytesInBuffer) == |
| 293 | offsetof(DXVA_Slice_H264_Long, SliceBytesInBuffer)); |
| 294 | |
| 295 | if (is_slice_short(ctx)) |
| 296 | slice = &ctx_pic->slice_short[i]; |
| 297 | else |
| 298 | slice = (DXVA_Slice_H264_Short*)&ctx_pic->slice_long[i]; |
| 299 | |
| 300 | position = slice->BSNALunitDataLocation; |
| 301 | size = slice->SliceBytesInBuffer; |
| 302 | if (start_code_size + size > end - current) { |
| 303 | av_log(avctx, AV_LOG_ERROR, "Failed to build bitstream"); |
| 304 | break; |
| 305 | } |
| 306 | |
| 307 | slice->BSNALunitDataLocation = current - dxva_data; |
| 308 | slice->SliceBytesInBuffer = start_code_size + size; |
| 309 | |
| 310 | if (!is_slice_short(ctx)) { |
| 311 | DXVA_Slice_H264_Long *slice_long = (DXVA_Slice_H264_Long*)slice; |
| 312 | if (i < ctx_pic->slice_count - 1) |
| 313 | slice_long->NumMbsForSlice = |
| 314 | slice_long[1].first_mb_in_slice - slice_long[0].first_mb_in_slice; |
| 315 | else |
| 316 | slice_long->NumMbsForSlice = mb_count - slice_long->first_mb_in_slice; |
nothing calls this directly
no test coverage detected