cuda解码 opengl 显示_实现FFMPEG 使用CUDA解码播放

播放器使用ffmpeg读取视频文件,packet发给cuda解码,解码后OpenGL直接映射给pbo,pbo绑定texture,然后显示出来

流程读取文件,判断packet,丢到CUDA那

if (av_read_frame(m_pFormatContext, &packet) >= 0)

{if (packet.stream_index ==m_VideoStreamIndex)

{if(m_UseGPUDecode)

{//MiniConsole::getInstance().Output("ThreadDecodeVideoGPU begin \n");

ThreadDecodeVideoGPU(packet);//MiniConsole::getInstance().Output("ThreadDecodeVideoGPU end \n");

}else{

ThreadDecodeVideoCPU(packet);

}

}else if (packet.stream_index ==m_AudioStreamIndex)

{

ThreadDecodeAudio(packet);

}else{

av_free_packet(&packet);

}

}

数据丢给cuvidParseVideoData

CUVIDSOURCEDATAPACKET cudaPkt;

CUresult oResult;if (pData ==NULL)

{

cudaPkt.flags=

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
ffmpeg可以使用CUDA进行硬件加速的解码[^1]。下面是两种使用CUDA进行解码的方法: 1. 使用ffmpeg官方文档提供的示例代码: ```c #include <stdio.h> #include <stdlib.h> #include <string.h> #include <math.h> #include <libavutil/opt.h> #include <libavcodec/avcodec.h> #include <libavformat/avformat.h> #include <libswscale/swscale.h> #include <libavutil/imgutils.h> #include <libavutil/hwcontext.h> #include <libavutil/hwcontext_cuda.h> int main(int argc, char *argv[]) { AVCodec *codec; AVCodecContext *codec_ctx = NULL; AVFrame *frame = NULL; AVPacket pkt; AVBufferRef *hw_device_ctx = NULL; AVBufferRef *hw_frames_ctx = NULL; int ret; av_register_all(); avcodec_register_all(); // 初始化CUDA设备上下文 ret = av_hwdevice_ctx_create(&hw_device_ctx, AV_HWDEVICE_TYPE_CUDA, NULL, NULL, 0); if (ret < 0) { fprintf(stderr, "Failed to create CUDA device context: %s\n", av_err2str(ret)); return ret; } // 打开输入文件 AVFormatContext *fmt_ctx = NULL; ret = avformat_open_input(&fmt_ctx, argv[1], NULL, NULL); if (ret < 0) { fprintf(stderr, "Failed to open input file: %s\n", av_err2str(ret)); return ret; } // 查找视频流 ret = avformat_find_stream_info(fmt_ctx, NULL); if (ret < 0) { fprintf(stderr, "Failed to find stream info: %s\n", av_err2str(ret)); return ret; } int video_stream_index = -1; for (int i = 0; i < fmt_ctx->nb_streams; i++) { if (fmt_ctx->streams[i]->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) { video_stream_index = i; break; } } if (video_stream_index == -1) { fprintf(stderr, "Failed to find video stream\n"); return AVERROR_STREAM_NOT_FOUND; } // 创建解码器上下文 codec = avcodec_find_decoder_by_name("h264_cuvid"); if (!codec) { fprintf(stderr, "Failed to find CUDA decoder\n"); return AVERROR_DECODER_NOT_FOUND; } codec_ctx = avcodec_alloc_context3(codec); if (!codec_ctx) { fprintf(stderr, "Failed to allocate codec context\n"); return AVERROR(ENOMEM); } // 设置解码器上下文参数 codec_ctx->hw_device_ctx = av_buffer_ref(hw_device_ctx); codec_ctx->get_format = av_hwdevice_get_hwframe_constraints; codec_ctx->flags |= AV_CODEC_FLAG_TRUNCATED; // 打开解码器 ret = avcodec_open2(codec_ctx, codec, NULL); if (ret < 0) { fprintf(stderr, "Failed to open codec: %s\n", av_err2str(ret)); return ret; } // 创建帧对象 frame = av_frame_alloc(); if (!frame) { fprintf(stderr, "Failed to allocate frame\n"); return AVERROR(ENOMEM); } // 解码循环 while (av_read_frame(fmt_ctx, &pkt) >= 0) { if (pkt.stream_index == video_stream_index) { // 发送数据到解码器 ret = avcodec_send_packet(codec_ctx, &pkt); if (ret < 0) { fprintf(stderr, "Error sending packet to decoder: %s\n", av_err2str(ret)); break; } // 接收解码后的帧数据 while (ret >= 0) { ret = avcodec_receive_frame(codec_ctx, frame); if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF) { break; } else if (ret < 0) { fprintf(stderr, "Error receiving frame from decoder: %s\n", av_err2str(ret)); break; } // 处理解码后的帧数据 // ... av_frame_unref(frame); } } av_packet_unref(&pkt); } // 清理资源 av_frame_free(&frame); avcodec_free_context(&codec_ctx); avformat_close_input(&fmt_ctx); av_buffer_unref(&hw_device_ctx); return 0; } ``` 2. 使用git上的一个示例代码库: ```shell git clone https://github.com/chinahbcq/ffmpeg_hw_decode.git cd ffmpeg_hw_decode make ./ffmpeg_hw_decode -i input.mp4 ```

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值