gpt4 book ai didi

c++ - 什么是 AVHWAccel,我该如何使用它?

转载 作者:行者123 更新时间:2023-11-30 01:08:26 25 4
gpt4 key购买 nike

我想利用硬件加速来解码 h264 编码的 MP4 文件。

我的计算环境:

Hardware: MacPro (2015 model)
Software: FFmpeg (installed by brew)

这是 FFmpeg 命令的输出:

$ffmpeg -hwaccels
Hardware acceleration methods:
vda
videotoolbox

根据 this document ,我的环境有两个选项,即VDAVideoToolBox。我在 C++ 中尝试了 VDA:

Codec = avcodec_find_decoder_by_name("h264_vda");

它有点工作,但像素格式的输出是 UYVY422 我很难处理(关于如何在 中呈现 UYVY422 的任何建议C++?理想的格式是yuv420p)

所以我想试试VideotoolBox,但是没有这么简单的东西(虽然它可能在编码的情况下有效)

Codec = avcodec_find_decoder_by_name("h264_videotoolbox");

看来我应该使用AVHWAccel,但是什么是AVHWAccel以及如何使用它?

我的部分 C++ 代码:

for( unsigned int i = 0; i < pFormatCtx->nb_streams; i++ ){
if(pFormatCtx->streams[i]->codec->codec_type == AVMEDIA_TYPE_VIDEO){
pCodecCtx = pFormatCtx->streams[i]->codec;
video_stream = pFormatCtx->streams[i];
if( pCodecCtx->codec_id == AV_CODEC_ID_H264 ){
//pCodec = avcodec_find_decoder(pCodecCtx->codec_id);
pCodec = avcodec_find_decoder_by_name("h264_vda");
break;
}
}
}
// open codec
if( pCodec ){
if((ret=avcodec_open2(pCodecCtx, pCodec, NULL)) < 0) {
....

最佳答案

选择哪种像素格式与解码器无关。

你的视频像素格式是UYVY422,所以你解码帧后得到这个格式。

就像@halfelf 提到的答案,你可以在解码帧后执行 swscale,将 pix 格式转换为你理想的格式 yuv420p,然后渲染它。

同时,如果您确定它是 UYVY422 格式,SDL2 可以直接为您处理渲染。

在下面的例子中,我的格式是yuv420p,我使用swscale转换成UYVY422渲染成SDL2

// prepare swscale context, AV_PIX_FMT_UYVY422 is my destination pix format
SwsContext *swsCtx = sws_getContext(codecCtx->width, codecCtx->height, codecCtx->pix_fmt,
codecCtx->width, codecCtx->height, AV_PIX_FMT_UYVY422,
SWS_FAST_BILINEAR, NULL, NULL, NULL);

SDL_Init(SDL_INIT_EVERYTHING);

SDL_Window *window;
SDL_Renderer *render;
SDL_Texture *texture;

SDL_CreateWindowAndRenderer(codecCtx->width,
codecCtx->height, SDL_WINDOW_OPENGL, &window, &render);

texture = SDL_CreateTexture(render, SDL_PIXELFORMAT_UYVY, SDL_TEXTUREACCESS_STREAMING,
codecCtx->width, codecCtx->height);

// ......
// decode the frame
// ......
AVFrame *frameUYVY = av_frame_alloc();
av_image_alloc(frameUYVY->data, frameUYVY->linesize, codecCtx->width, codecCtx->height, AV_PIX_FMT_UYVY422, 32);

SDL_LockTexture(texture, NULL, (void **)frameUYVY->data, frameUYVY->linesize);

// convert the decoded frame to destination frameUYVY (yuv420p -> uyvy422)
sws_scale(swsCtx, frame->data, frame->linesize, 0, frame->height,
frameUYVY->data, frameUYVY->linesize);

SDL_UnlockTexture(texture);

// performa render
SDL_RenderClear(render);
SDL_RenderCopy(render, texture, NULL, NULL);
SDL_RenderPresent(render);

在您的示例中,如果您的 pix 格式是 uyvy422,您可以跳过 swscale 部分,并在从 ffmpeg 解码后直接执行渲染。

关于c++ - 什么是 AVHWAccel,我该如何使用它?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42776530/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com