音视频软硬解码流程详解
音视频解码流程详解
软解码基础流程
- 打开输入文件
- 读取媒体文件信息
- 查询视频流
- 获取解码器
- 获取解码器上下文
- 使用视频流的codecpar为解码器上下文赋值
- 打开解码器
- 获取原始数据帧
- 将数据发送给解码器
- 从解码器读取解码后的数据
- 获取图像转换上下文
- 将解码的图像格式转换成QImage
硬解码流程
基础步骤
- 打开输入文件
avformat_open_input
- 读取媒体文件信息
avformat_find_stream_info
- 查询视频流
av_find_best_stream
- 获取解码器
avcodec_find_decoder
- 获取解码器上下文
avcodec_alloc_context3
- 使用视频流的codecpar赋值
avcodec_parameters_to_context
硬件加速相关步骤
- 检索编解码器支持的硬件配置
avcodec_get_hw_config
- 遍历支持的编解码器设备类型
av_hwdevice_iterate_types
- 在构造函数中记录支持的类型到数组
- 打开指定类型的编解码器设备
av_hwdevice_ctx_create
- 注册硬件像素格式回调
m_codecContext->get_format = get_hw_format
解码步骤
- 打开解码器
avcodec_open2
- 读取原始数据帧
av_read_frame
- 发送数据到解码器
avcodec_send_packet
- 读取解码后的数据
avcodec_receive_frame
- GPU数据拷贝到CPU
av_hwframe_transfer_data
av_hwframe_map(m_frameHW, m_frame, 0)
- 获取图像转换上下文
sws_getCachedContext
- 转换为QImage格式
sws_scale
软解码显示实现(PlayImage类)
基于QWidget
- 接收图像信号并响应updateImage槽函数
- 转换为QPixmap
- 调用update触发重绘
- paintEvent中绘制
YUV转RGB
- FFmpeg默认解码为YUV格式
- 使用
sws_getCachedContext
转换为RGB(AV_PIX_FMT_RGBA)
OpenGL渲染优化
软解码+OpenGL(YUV->RGB)
- 继承QOpenGLWidget和QOpenGLFunctions
- initializeGL中设置VAO/VBO/IBO
- updateImage中处理纹理
- paintGL中执行绘制
软解码+OpenGL(直接YUV)
- 使用AVFrame直接传递
- 使用三个纹理处理YUV数据
- 在GPU中完成格式转换
硬解码+OpenGL(NV12)
- 使用
av_hwframe_map
替代transfer_data - 根据格式选择初始化方式
- 直接在GPU中完成NV12到RGB的转换
摄像头采集
- 注册设备
avdevice_register_all
- 查询输入设备
av_find_input_format
- 执行标准解码流程
- OpenGL中完成YUV转RGB
视频录制流程
- 创建输出上下文
avformat_alloc_output_context2
- 初始化IO上下文
avio_open
- 配置编码器
- 创建视频流
- 写入头信息
- 编码循环
- 写入尾信息
评论