解码及显示

解码

  1. 循环读取视频帧

    AVPacket packet = { 0 };
    while (av_read_frame(m_pFmtCtx, &packet) >= 0)
    {
    if (m_videoIndex == packet.stream_index)
    {
    Decode(m_pDecoderCtx, &packet);
    av_packet_unref(&packet);
    }
    } // 缓冲中的可能还有数据,所以需要将剩下的数据一并解码
    packet.data = NULL;
    packet.size = 0; Decode(m_pDecoderCtx, &packet);
    av_packet_unref(&packet);
  2. 解码

    两个重要的FFmpeg接口:

    avcodec_send_packet,发送一个包给解码器;

    avcodec_receive_frame,从解码器取回解码后的数据。

    void Decode(AVCodecContext * pDecodeCtx, AVPacket * pPacket)
    {
    if (avcodec_send_packet(pDecodeCtx, pPacket) < 0)
    {
    return;
    } while (TRUE)
    {
    if (avcodec_receive_frame(pDecodeCtx, m_pFrame) != 0)
    {
    break;
    } DisplayVideo(m_pFrame);
    }
    }

显示

关于D3D显示的大概步骤是解码数据放在缓冲区,也就是这里离屏的概念,然后将离屏数据拷贝到后台缓冲表面,后台表面和前台表面不停的交替实现显示。

// 离屏
LPDIRECT3DSURFACE9 surface = (LPDIRECT3DSURFACE9)pFrame->data[3]; // D3DCLEAR_TARGET 清除要渲染目标(帧缓存)的颜色为D3DCOLOR_XRGB(0, 0, 0)的值
// D3DCLEAR_ZBUFFER 清除深度缓冲(确定像素遮挡关系)的值为1.0f
// D3DCLEAR_STENCIL 清除模板缓冲区(用于特效)为0
// 此时1.0f和0均会被忽略
m_pD3d9Dev->Clear(0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB(0, 0, 0), 1.0f, 0);
m_pD3d9Dev->BeginScene(); IDirect3DSurface9 * pBackBuffer = nullptr;
if (pBackBuffer)
{
pBackBuffer->Release();
pBackBuffer = NULL;
} // 获取第1个交换链上的第一个后台缓冲区的地址
m_pD3d9Dev->GetBackBuffer(0, 0, D3DBACKBUFFER_TYPE_MONO, &pBackBuffer); GetClientRect(m_hWnd, &m_renderRect); // 将待显示的数据拷贝到后台缓冲区,通过线性插值的方式显示到指定窗口区域
m_pD3d9Dev->StretchRect(surface, NULL, pBackBuffer, &m_renderRect, D3DTEXF_LINEAR);
m_pD3d9Dev->EndScene();
m_pD3d9Dev->Present(NULL, NULL, NULL, NULL); #if !CAMERA
Sleep(1000 / m_frameRate);
#endif

资源清理

if (m_hD3dDll)
{
FreeLibrary(m_hD3dDll);
m_hD3dDll = nullptr;
} if (m_hDxva2Dll)
{
FreeLibrary(m_hDxva2Dll);
m_hDxva2Dll = nullptr;
} if (m_pD3d9Dev)
{
m_pD3d9Dev->Release();
} if (m_pD3d9DevMgr && m_hDev != INVALID_HANDLE_VALUE)
{
m_pD3d9DevMgr->CloseDeviceHandle(m_hDev);
} if (m_pDecoderService)
{
m_pDecoderService->Release();
} if (m_pD3d9DevMgr)
{
m_pD3d9DevMgr->Release();
} // 释放缓冲区
if (m_pSurface)
{
for (uint32_t i = 0; i < m_surfaceNums; i++)
{
if (m_pSurface[i])
m_pSurface[i]->Release();
}
} // 释放DirectX解码器
if (m_pDecoder)
{
m_pDecoder->Release();
m_pDecoder = nullptr;
} av_freep(&pCodecCtx->hwaccel_context);

基于FFmpeg的Dxva2硬解码及Direct3D显示(五)的更多相关文章

  1. 基于FFmpeg的Dxva2硬解码及Direct3D显示(四)

    初始化硬解码上下文 目录 初始化硬解码上下文 创建解码数据缓冲区 创建IDirectXVideoDecoder视频解码器 设置硬解码上下文 解码回调函数 创建解码数据缓冲区 这一步为了得到 LPDIR ...

  2. 基于FFmpeg的Dxva2硬解码及Direct3D显示(一)

    目录 前言 名词解释 代码实现逻辑 前言 关于视频软解码的资料网上比较多了,但是关于硬解可供参考的资料非常之有限,虽然总得来说软解和硬解的基本逻辑一样,但是实现细节上的差别还是比较多的.虽然目前功能已 ...

  3. 基于FFmpeg的Dxva2硬解码及Direct3D显示(三)

    初始化Direct3D 目录 初始化Direct3D 创建Direct3D物理设备对象实例 创建Direct3D渲染设备实例 创建Direct3D视频解码服务 Direct3D渲染可以通过Surfac ...

  4. 基于FFmpeg的Dxva2硬解码及Direct3D显示(二)

    解析视频源 目录 解析视频源 获取视频流 解析视频流 说明:这篇博文分为"获取视频流"和"解析视频流"两个部分,使用的是FFmpeg4.1的版本,与网上流传的低 ...

  5. 使用C#+FFmpeg+DirectX+dxva2硬件解码播放h264流

    本文门槛较高,因此行文看起来会乱一些,如果你看到某处能会心一笑请马上联系我开始摆龙门阵 如果你跟随这篇文章实现了播放器,那你会得到一个高效率,低cpu占用(单路720p视频解码播放占用1%左右cpu) ...

  6. 【视频开发】 ffmpeg支持的硬解码接口

    To enable DXVA2, use the --enable-dxva2 ffmpeg configure switch. To test decoding, use the following ...

  7. [原]ffmpeg编译android 硬解码支持库 libstagefright

    最近花了一天时间将ffmpeg/tools/build_stagefright执行成功,主要是交叉编译所需要的各种动态库的支持没链接上,导致各种报错,基本上网络上问到的问题我都碰到了,特此记录下来. ...

  8. 【并行计算与CUDA开发】基于NVIDIA显卡的硬编解码的一点心得 (完结)

    原文:基于NVIDIA显卡的硬编解码的一点心得 (完结) 1.硬解码软编码方法:大体流程,先用ffmpeg来读取视频文件的包,接着开启两个线程,一个用于硬解码,一个用于软编码,然后将读取的包传给解码器 ...

  9. 最简单的基于FFMPEG的封装格式转换器(无编解码)

    本文介绍一个基于FFMPEG的封装格式转换器.所谓的封装格式转换,就是在AVI,FLV,MKV,MP4这些格式之间转换(相应.avi,.flv,.mkv,.mp4文件).须要注意的是,本程序并不进行视 ...

随机推荐

  1. 多测师讲解jmeter _图片详解_(全)高级讲师肖sir

  2. jquery的实时触发事件(textarea实时获取中文个数)

    jquery的实时触发事件(textarea实时获取中文个数) (2014-09-16 11:49:50) 转载▼ 标签: 实时触发事件 中文个数 onpropertychange oninput o ...

  3. 【状态压缩DP】SCOI2009 围豆豆

    题目大意 洛谷链接 在一个\(N×M\)的矩阵方格内分布着\(D\)颗豆子,每颗豆有不同的分值\(V_i\).游戏者可以选择任意一个方格作为起始格,每次移动可以随意的走到相邻的四个格子,直到最终又回到 ...

  4. buuctf-misc-刷新过的图片

    知识点:F5隐写 kali中安装F5-steganography 工具 git clone https://github.com/matthewgao/F5-steganography 解密的时候输入 ...

  5. 作图直观理解Parzen窗估计(附Python代码)

    1.简介 Parzen窗估计属于非参数估计.所谓非参数估计是指,已知样本所属的类别,但未知总体概率密度函数的形式,要求我们直接推断概率密度函数本身. 对于不了解的可以看一下https://zhuanl ...

  6. Jmeter入门(5)- jmeter取样器的HTTP请求

    一.HTTP管理器 位置:线程组右键 ==> 添加 ==> 配置元件 1.HTTP信息头管理器 添加测试计划 添加线程组 添加HTTP请求 添加请求头(HTTP信息头管理器) 设置请求参数 ...

  7. 为iOS编译FFmpeg静态库

    为iOS编译FFmpeg静态库 
 环境:OS X Yosemite (版本10.10.5) Xcode (Version 7.1.1 (7B1005)) 
 
 一.资料准备: (1)ffmpeg源 ...

  8. springmvc maven 入门及页面拿不到controller的值 显示${message} el表达式不起作用

    1:参考https://www.cnblogs.com/zhuawang/p/5651896.html 操作完,运行,结果不是后端控制器controller返回的,是index.jsp中的. 因为执行 ...

  9. NB-IoT的HARQ过程是怎么样的

    NB-IoT的HARQ是一种将前向纠错(Forward Error Correction,FEC)编码和ARQ相结合而形成的技术.HARQ的基本原理是缓存没有正确接收到的数据,并且将重传数据和原始数据 ...

  10. 4g数据无线传输终端dtu

    将串口数据转换为IP数据或将IP数据转换为串口数据并且进行传输的过程被称为数据透明传输,利用4G网络进行数据透明传输的设备被称为4G网络无线数据双向透明传输终端,也可以称为4G DTU,现在市面上大多 ...