一、解决方案

抓图就是保存视频帧,对于有硬编解码的视频,我们需要在编码前,或者解码后,获得视频帧。考虑到准确定位到要抓取的画面的帧,在接收流上做,是一个不错的选择。因为硬编解码的存在,好多事情都变得不那么简单了,比如GetCurrentImageFilter方法肯定不行了,在解码filter后连接一个抓图filter也不能达到预期效果,测试发现这个filter虽然连接上了,但是却工作不了,因为硬编码最后数据放到了显存中,硬解码filter跟最终的EVR(Enhanced Video Renderer)是经过了特定协商的,才成功把视频帧传下去了。如果中间插入一个filter,硬解码数据就不能成功传过来,所以就工作不了了。那么解决方案是什么了?一个比较好的也是较简单的就是在解码filter上添加一个接口,再解码完成后,保存视频帧,这完全不影响它正常传给EVR。那么我们面对的问题,就主要有以下几个:获得到显存中数据;将帧格式转为rgb格式;将rgb数据生成一个bmp图片。

二、获取数据

对于STDMETHODIMP GetPointer(BYTE ** ppBuffer);方法,大家是不是格外亲切熟悉了,是的,一般通过这个方法就能获得sample内存里的数据。但是硬解码后,再用这个方法会发现得不到任何数据,它确实得不到,也不可能得到,因为此时数据没有在内存中,所以我们要自己想办法得到数据,通过看硬解码filter的allocator发现EVR是通过MR_BUFFER_SERVICE获得surface的,注意这个surface是IDirect3DSurface9,然后调用它的LockRect方法,就获得数据了。

1.IMFGetService

<strong>HRESULT CDXVA2Sample::QueryInterface(REFIID riid, void **ppv)
{CheckPointer(ppv, E_POINTER);if (riid == __uuidof(IMFGetService)){return GetInterface((IUnknown*)static_cast<IMFGetService*>(this), ppv);}return CMFXSample::QueryInterface(riid, ppv);
}</strong>

2.从sample上获得获得service

IMFGetService    *pGetService;
hr = pOutSample->QueryInterface(__uuidof(IMFGetService), (void**)&pGetService);  //这个pOutSample就是要最后要往下deliver的

3.获得IDirect3DSurface9

 hr = pGetService->GetService(MR_BUFFER_SERVICE, __uuidof(IDirect3DSurface9), (void**)&pD3DSurface);

4.现在需要从pD3DSurface中获得数据,用到IDirect3DSurface的LockRect方法。

mfxStatus LockFrame(IDirect3DSurface9 *surface, mfxFrameData *ptr)
{IDirect3DSurface9 *pSurface = surface;if (pSurface == 0)return MFX_ERR_INVALID_HANDLE;if (ptr == 0)return MFX_ERR_LOCK_MEMORY;D3DSURFACE_DESC desc;HRESULT hr = pSurface->GetDesc(&desc);if (FAILED(hr))return MFX_ERR_LOCK_MEMORY;if (desc.Format != D3DFMT_NV12 &&desc.Format != D3DFMT_YV12 &&desc.Format != D3DFMT_YUY2 &&desc.Format != D3DFMT_R8G8B8 &&desc.Format != D3DFMT_A8R8G8B8 &&desc.Format != D3DFMT_P8)return MFX_ERR_LOCK_MEMORY;D3DLOCKED_RECT locked;hr = pSurface->LockRect(&locked, 0, D3DLOCK_NOSYSLOCK);if (FAILED(hr))return MFX_ERR_LOCK_MEMORY;switch ((DWORD)desc.Format){case D3DFMT_NV12:ptr->Pitch = (mfxU16)locked.Pitch;ptr->Y = (mfxU8 *)locked.pBits;ptr->U = (mfxU8 *)locked.pBits + desc.Height * locked.Pitch;ptr->V = ptr->U + 1;break;case D3DFMT_YV12:ptr->Pitch = (mfxU16)locked.Pitch;ptr->Y = (mfxU8 *)locked.pBits;ptr->V = ptr->Y + desc.Height * locked.Pitch;ptr->U = ptr->V + (desc.Height * locked.Pitch) / 4;break;case D3DFMT_YUY2:ptr->Pitch = (mfxU16)locked.Pitch;ptr->Y = (mfxU8 *)locked.pBits;ptr->U = ptr->Y + 1;ptr->V = ptr->Y + 3;break;case D3DFMT_R8G8B8:ptr->Pitch = (mfxU16)locked.Pitch;ptr->B = (mfxU8 *)locked.pBits;ptr->G = ptr->B + 1;ptr->R = ptr->B + 2;break;case D3DFMT_A8R8G8B8:ptr->Pitch = (mfxU16)locked.Pitch;ptr->B = (mfxU8 *)locked.pBits;ptr->G = ptr->B + 1;ptr->R = ptr->B + 2;ptr->A = ptr->B + 3;break;case D3DFMT_P8:ptr->Pitch = (mfxU16)locked.Pitch;ptr->Y = (mfxU8 *)locked.pBits;ptr->U = 0;ptr->V = 0;break;}return MFX_ERR_NONE;
}

<pre class="cpp" name="code" style="font-size: 14.039999961853px; font-weight: bold;">//数据就放到ptr中去了,然后对数据进行处理,最后unlock掉
mfxStatus CDecVideoFilter::UnlockFrame(IDirect3DSurface9 *surface, mfxFrameData *ptr)
{IDirect3DSurface9 *pSurface =surface;if (pSurface == 0)return MFX_ERR_INVALID_HANDLE;pSurface->UnlockRect();if (NULL != ptr){ptr->Pitch = 0;ptr->Y     = 0;ptr->U     = 0;ptr->V     = 0;}return MFX_ERR_NONE;
}

三、至此已经获取到数据了,注意对数据进行处理后,要调用unlockframe方法。



视频抓图(有硬编码解码)一获得解码后数据相关推荐

  1. 如何使用ffmpeg为Mac进行视频硬解码/硬编码(在Qt环境)

    如何使用ffmpeg为Mac进行视频硬解码/硬编码(在Qt环境) 科普 前期准备 安装ffmpeg 将ffmpeg的库文件添加到Qt项目的.pro文件中 在源文件用引入头文件 第一步:先查看本机支持哪 ...

  2. 香橙派Pi5基于Qt5视频硬编码编译

    香橙派Pi5视频通过Qt5硬编码编译 文章目录 香橙派Pi5视频通过Qt5硬编码编译 前言 一.RKMpp和RKMpi是什么? 二.编译RKMPP 1.下载地址 2.文件结构 3.开始编译 4.编译M ...

  3. 1小时学会:最简单的iOS直播推流(七)h264/aac 硬编码

    最简单的iOS 推流代码,视频捕获,软编码(faac,x264),硬编码(aac,h264),美颜,flv编码,rtmp协议,陆续更新代码解析,你想学的知识这里都有,愿意懂直播技术的同学快来看!! 源 ...

  4. android硬编码封装mp4,【Android 音视频开发打怪升级:音视频硬解码篇】四、音视频解封和封装:生成一个MP4...

    [声 明] 首先,这一系列文章均基于自己的理解和实践,可能有不对的地方,欢迎大家指正. 其次,这是一个入门系列,涉及的知识也仅限于够用,深入的知识网上也有许许多多的博文供大家学习了. 最后,写文章过程 ...

  5. iOS视频硬编码技术

    iOS视频硬编码技术 一.iOS视频采集硬编码 基本原理 硬编码 & 软编码 硬编码:通过系统自带的Camera录制视频,实际上调用的是底层的高清编码硬件模块,即显卡,不使用CPU,速度快 软 ...

  6. 视频直播推流技术(MediaCodec硬编码+libRTMP,编码器),Demo - Android

    - aac audio_codec; h264,video_codec;25 framerate 25帧; - Camera-YUV帧序列-YUV帧预处理(镜像 缩放 旋转)-编码器-H264数据 从 ...

  7. Android视频滤镜添加硬解码方案

    由于工作的需求,研究过了一段时间的Android 的音视频播放渲染以及编辑方面的知识,这里就自己一些浅薄的了解对所了解做一个简单的介绍和记录,如有不对的地方请指正!同时也会记录下硬件解码的情况下完成滤 ...

  8. 手机视频硬解码和软解码的区别

    在手机评测视频播放能力的时候经常会提到"硬解码"和"软解码",但是很多人不太明白是什么意思,其实问题很简单.大家都知道PC都有CPU和GPU(显卡),在手机上也 ...

  9. 音频编解码(软/硬编码),音频转码

    > 音频编解码(软编码) FFMpeg视频软件编解码的.B站的ijkplayer等. 音频数据的编解码- http://blog.51cto.com/ticktick/1760191 1.And ...

最新文章

  1. NVIDIA DRIVE AGX开发工具包
  2. .NET Framework 4.7 安装
  3. 《众妙之门——Web用户体验设计与可用性测试》一第2章 在网页设计中通过测量数据优化情感投入2.1 情感应答和行为应答的关系...
  4. 下列符合c语言语法的字符常量是,C语言程序设计(周经亚)选择题练习-chapter 5.doc...
  5. leetcode-187-重复的DNA序列
  6. 福利 | 闷骚的程序员是如何讲冷笑话的?
  7. spring boot 配置网关时404错误_Kong中使用grpcweb插件代理grpc服务时遇到的坑
  8. 基于OpenCv的人脸识别系统设计
  9. java毕业设计幼儿园管理系统Mybatis+系统+数据库+调试部署
  10. 辞职信 求助编辑百科名片
  11. 解析云产品SLA的价值
  12. 信号处理--傅里叶变换的性质及常用信号的傅里叶变换
  13. lambda 表达式forEach中获取元素下标
  14. 数字战疫|央视聚焦闵行,有信云助力上海数千家企业复工复产
  15. Android OTA在线升级一(架构分析)
  16. 一些汇编指令和寄存器。
  17. 不少专车司机考虑退出
  18. 纳米金;AuNPs;直 径 1~100nm
  19. aarch64安装numba
  20. 【大数据】计算引擎之三:Hadoop处理框架

热门文章

  1. 网络性能优化的几个思路
  2. 谷歌125亿美元收购摩托罗拉
  3. jt808终端鉴权_驾培协议和jt808协议的区别 | 车载GPS和视频平台产品经理
  4. 一文读透GO语言的通道
  5. 口碑问答营销推广如何做?广告联盟同样需要
  6. VnlnHub Momentum
  7. 【linux基础】18、进程管理工具
  8. JAva中的自然排序是什么意思_Java中的自然排序顺序字符串比较 – 是内置的吗?...
  9. SqlPersistenceService持久化数据库
  10. Elasticsearch:验证 Elasticsearch Docker 镜像并安装 Elasticsearch