菜鸟学ffmpeg音视频技术之4 使用d3d 抓屏幕图像

这篇博客介绍了如何利用Direct3D 9捕获屏幕图像并将其转换为RGB数据,以便与FFmpeg进行编解码。详细步骤包括创建D3D对象、获取显示配置、创建设备对象、创建CreateOffscreenPlainSurface对象以及将数据转换为RGB格式。适用于需要使用D3D抓图和FFmpeg录制的场景。
摘要由CSDN通过智能技术生成

本篇介绍如何使用d3d 9抓取屏幕图像,并将图像转化为RGB数据,转化后的数据可直接传递给FFmpeg进行编解码。

获取桌面数据容易,转为RGB网上的例子就少了,大多只会使用D3D api保存为一个图片,本文解决了这个难题,如果你想使用D3D抓图然后使用FFMPEG进行录制会对你有所帮助。

1.创建D3D对象

_d3d = Direct3DCreate9(D3D_SDK_VERSION);

2.获取display配置

            memset(&_d3d_displaymodel, 0, sizeof(_d3d_displaymodel));
            HRESULT hr = _d3d->GetAdapterDisplayMode(D3DADAPTER_DEFAULT, &_d3d_displaymodel);
            if (FAILED(hr))
            {
                SafeRelease(_d3d);
                return error;
            }

3.创建设备对象

            D3DPRESENT_PARAMETERS d3dParam;
            memset(&d3dParam, 0, sizeof(d3dParam));
            d3dParam.Flags = D3DPRESENTFLAG_LOCKABLE_BACKBUFFER;
            d3dParam.MultiSampleType = D3DMULTISAMPLE_NONE;
            d3dParam.SwapEffect = D3DSWAPEFFECT_DISCARD;
            d3dParam.PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE;
            d3dParam.Windowed = TRUE;
            d3dParam.BackBufferWidth = 0;
            d3dParam.BackBufferHeight = 0;
            d3dParam.BackBufferFormat = D3DFMT_UNKNOWN;
            d3dParam.FullScreen_RefreshRateInHz = D3DPRESENT_RATE_DEFAULT;
            d3dParam.hDeviceWindow = hWnd;


            // create d3ddevice
            hr = _d3d->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hWnd,
                D3DCREATE_SOFTWARE_VERTEXPROCESSING, &d3dParam, &_d3d_device);
            if (FAILED(hr))
            {
                SafeRelease(_d3d_device);
                return error;
            }
4. 创建CreateOffscreenPlainSurface对象

 hr = _d3d_device->CreateOffscreenPlainSurface(_d3d_displaymodel.Width, _d3d_displaymodel.Height,
                D3DFMT_A8R8G8B8, D3DPOOL_SCRATCH, &_d3d_surface, NULL);
            if (FAILED(hr))
            {
                SafeRelease(_d3d_device);
                SafeRelease(_d3d_surface);
                return error;
            }

5.获取数据

            _d3d_device->GetFrontBufferData(0, _d3d_surface);
            D3DLOCKED_RECT lr;
            _d3d_surface->LockRect(&lr,NULL,
                               D3DLOCK_NO_DIRTY_UPDATE|
                               D3DLOCK_NOSYSLOCK|D3DLOCK_READONLY);
6.转为为RGB数据

            int BITSPERPIXEL = 32;
            DWORD* pBuf = (DWORD*)lr.pBits;
            int nPitch = lr.Pitch;
            for( int i=0 ; i < winheight ; i++)
            {
                memcpy((BYTE*) _buffer + i *
                    winwidth * BITSPERPIXEL/8 ,
                    (BYTE*) pBuf+ i* nPitch ,
                    winwidth* BITSPERPIXEL/8);
            }
 

注意桌面缓存不使用BackBuffer,所以这里一定要用GetFrontBufferData,GetBackBuffer是拿不到数据的。

 

完整代码:

#ifndef RECORD_WINDOW_D3D
#define RECORD_WINDOW_D3D

#include "record_desktop.h"

#include <Windows.h>
#include <d3d9.h>
#pragma comment(lib,"d3d9.lib")

namespace RecorderSP {


template <typename T>

inline void SafeRelease(T* &p)

{
    if (NULL != p)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值