fmpeg 硬解vp8 AVCodec的成员函数decode是怎么写的
时间: 2024-05-10 17:21:39 浏览: 130
FFmpeg中VP8的硬解码是通过VAAPI实现的。下面是AVCodec的成员函数decode的部分实现代码:
```
static int vp8_vaapi_decode_frame(AVCodecContext *avctx, void *data, int *got_frame, AVPacket *avpkt)
{
VAAPIContext *const vactx = avctx->hwaccel_context;
VASurfaceID surface;
VAStatus vas;
int ret;
if (!vactx || !vactx->va_context) {
av_log(avctx, AV_LOG_ERROR, "VAAPI not initialized.\n");
return AVERROR(EINVAL);
}
if ((ret = ff_vaapi_get_surface(avctx, data, got_frame, avpkt, &surface)) < 0)
return ret;
vas = vaBeginPicture(vactx->display, vactx->context, surface);
if (vas != VA_STATUS_SUCCESS) {
av_log(avctx, AV_LOG_ERROR, "Error calling vaBeginPicture: %d (%s).\n",
vas, vaErrorStr(vas));
return AVERROR_EXTERNAL;
}
// 调用VAAPI硬解码函数
ret = ff_vaapi_common_decode_slice(avctx, avpkt->data, avpkt->size);
if (ret < 0) {
vaEndPicture(vactx->display, vactx->context);
ff_vaapi_unmap_buffer(vactx->display, &vactx->slice_params_buf_id);
ff_vaapi_unmap_buffer(vactx->display, &vactx->iq_matrix_buf_id);
av_log(avctx, AV_LOG_ERROR, "Error decoding slice: %d.\n", ret);
return ret;
}
vas = vaEndPicture(vactx->display, vactx->context);
if (vas != VA_STATUS_SUCCESS) {
av_log(avctx, AV_LOG_ERROR, "Error calling vaEndPicture: %d (%s).\n",
vas, vaErrorStr(vas));
return AVERROR_EXTERNAL;
}
ff_vaapi_unmap_buffer(vactx->display, &vactx->slice_params_buf_id);
ff_vaapi_unmap_buffer(vactx->display, &vactx->iq_matrix_buf_id);
*got_frame = 1;
return avpkt->size;
}
```
该函数首先通过调用ff_vaapi_get_surface函数获取VAAPI表面,然后调用VAAPI硬解码函数ff_vaapi_common_decode_slice进行硬解码,最后调用VAAPI函数vaEndPicture结束VAAPI图像。
阅读全文