On 31/07/16 23:22, Mark Thompson wrote:
> +void *ff_vaapi_decode_alloc_slice_buffer(AVCodecContext *avctx,
> +                                         VAAPIDecodePicture *pic,
> +                                         size_t params_size,
> +                                         const void *slice_data,
> +                                         size_t data_size)
> +{
> +    VAAPIDecodeContext *ctx = avctx->internal->hwaccel_priv_data;
> +    VAAPIDecodeSlice *slice = NULL;
> +    VAStatus vas;
> +    void *addr = NULL;
> +    VASliceParameterBufferBase *slice_param;
> +
> +    if (pic->nb_slices == pic->slices_allocated) {
> +        if (pic->slices_allocated > 0)
> +            pic->slices_allocated *= 2;
> +        else
> +            pic->slices_allocated = 64;
> +
> +        pic->slices = av_realloc_array(pic->slices,
> +                                       pic->slices_allocated,
> +                                       sizeof(*pic->slices));
> +        if (!pic->slices)
> +            return NULL;
> +    }
> +
> +    av_assert0(pic->nb_slices < pic->slices_allocated);
> +    slice = &pic->slices[pic->nb_slices];
> +    slice->param_buffer = VA_INVALID_ID;
> +    slice->data_buffer  = VA_INVALID_ID;
> +
> +    vas = vaCreateBuffer(ctx->hwctx->display, ctx->va_context,
> +                         VASliceParameterBufferType, params_size,
> +                         1, NULL, &slice->param_buffer);
> +    if (vas != VA_STATUS_SUCCESS) {
> +        av_log(avctx, AV_LOG_ERROR, "Failed to create slice "
> +               "parameter buffer: %d (%s).\n", vas, vaErrorStr(vas));
> +        goto fail;
> +    }
> +
> +    av_log(avctx, AV_LOG_DEBUG, "Slice %d param buffer (%zu bytes) "
> +           "is %#x.\n", pic->nb_slices, params_size,
> +           slice->param_buffer);
> +
> +    vas = vaCreateBuffer(ctx->hwctx->display, ctx->va_context,
> +                         VASliceDataBufferType, data_size,
> +                         1, (void*)slice_data, &slice->data_buffer);
> +    if (vas != VA_STATUS_SUCCESS) {
> +        av_log(avctx, AV_LOG_ERROR, "Failed to create slice "
> +               "data buffer (size %zu): %d (%s).\n",
> +               data_size, vas, vaErrorStr(vas));
> +        goto fail;
> +    }
> +
> +    av_log(avctx, AV_LOG_DEBUG, "Slice %d data buffer (%zu bytes) "
> +           "is %#x.\n", pic->nb_slices, data_size,
> +           slice->data_buffer);
> +
> +    vas = vaMapBuffer(ctx->hwctx->display,
> +                      slice->param_buffer, &addr);
> +    if (vas != VA_STATUS_SUCCESS) {
> +        av_log(avctx, AV_LOG_ERROR, "Failed to map slice parameter "
> +               "buffer: %d (%s).\n", vas, vaErrorStr(vas));
> +        goto fail;
> +    }
> +
> +    slice_param = addr;
> +    slice_param->slice_data_size   = data_size;
> +    slice_param->slice_data_offset = 0;
> +    slice_param->slice_data_flag   = VA_SLICE_DATA_FLAG_ALL;
> +
> +    ++pic->nb_slices;
> +
> +    return addr;
> +
> +fail:
> +    if (slice) {
> +        if (addr)
> +            vaUnmapBuffer(ctx->hwctx->display,
> +                          slice->param_buffer);
> +        if (slice->param_buffer != VA_INVALID_ID)
> +            vaDestroyBuffer(ctx->hwctx->display,
> +                            slice->param_buffer);
> +        if (slice->data_buffer != VA_INVALID_ID)
> +            vaDestroyBuffer(ctx->hwctx->display,
> +                            slice->data_buffer);
> +    }
> +    return NULL;
> +}

This gets caught out somewhat by interlacing in H.264.  The two fields of a
frame get the same VAAPIDecodePicture (hwaccel_picture_private), and then the
slices have to be rendered separately to the same surface.  This currently
crashes because of the slice allocation - resetting slices_allocated in the
decode issue fixes it, but I don't really like how the picture structure is
being reused.

I'll see if I can come up with a nicer way of dealing with it (though I do
mostly want to ignore the problem on "interlacing is an abomination" grounds).

- Mark

_______________________________________________
libav-devel mailing list
[email protected]
https://lists.libav.org/mailman/listinfo/libav-devel

Reply via email to