- android - RelativeLayout 背景可绘制重叠内容
- android - 如何链接 cpufeatures lib 以获取 native android 库?
- java - OnItemClickListener 不起作用,但 OnLongItemClickListener 在自定义 ListView 中起作用
- java - Android 文件转字符串
我正在尝试编写一个使用 Media Foundation 的 Win32 c++ 程序, 用于捕获 mp4桌面视频。我发现在屏幕分辨率超过 1920x1080 的 PC 上,捕获失败。失败是在调用 SetInputMediaType 之后() 返回错误 0xc00d36b4(为媒体类型指定的数据无效、不一致或不受此对象支持)
有什么解决办法吗?
HRESULT InitializeDirect3D9(IDirect3DDevice9** ppDevice, IDirect3DSurface9** ppSurface, UINT32& uiWidth, UINT32& uiHeight)
{
IDirect3D9* d3d = NULL;
d3d = Direct3DCreate9(D3D_SDK_VERSION);
if (d3d == NULL)
return E_POINTER;
D3DDISPLAYMODE mode;
HRESULT hr = d3d->GetAdapterDisplayMode(D3DADAPTER_DEFAULT, &mode);
if (FAILED(hr))
{
SafeRelease(&d3d);
return hr;
}
D3DPRESENT_PARAMETERS parameters = { 0 };
parameters.Windowed = TRUE;
parameters.BackBufferCount = 1;
uiHeight = parameters.BackBufferHeight = mode.Height;
uiWidth = parameters.BackBufferWidth = mode.Width;
parameters.SwapEffect = D3DSWAPEFFECT_DISCARD;
parameters.hDeviceWindow = NULL;
hr = d3d->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, NULL, D3DCREATE_SOFTWARE_VERTEXPROCESSING, ¶meters, ppDevice);
if (FAILED(hr))
{
SafeRelease(&d3d);
return hr;
}
hr = (*ppDevice)->CreateOffscreenPlainSurface(mode.Width, mode.Height, D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, ppSurface, nullptr);
SafeRelease(&d3d);
return hr;
}
HRESULT SGCaptureDecktopVideo::InitializeSinkWriter(std::wstring VideoPath, IMFSinkWriter **ppWriter, DWORD *pStreamIndex, const UINT32 uiWidth, const UINT32 uiHeight)
{
*ppWriter = NULL;
*pStreamIndex = NULL;
IMFSinkWriter *pSinkWriter = NULL;
IMFMediaType *pMediaTypeOut = NULL;
IMFMediaType *pMediaTypeIn = NULL;
DWORD streamIndex;
HRESULT hr = MFCreateSinkWriterFromURL(VideoPath.c_str(), NULL, NULL, &pSinkWriter);
// Set the output media type.
if (SUCCEEDED(hr))
{
hr = MFCreateMediaType(&pMediaTypeOut);
}
if (SUCCEEDED(hr))
{
hr = pMediaTypeOut->SetGUID(MF_MT_MAJOR_TYPE, MFMediaType_Video);
}
if (SUCCEEDED(hr))
{
hr = pMediaTypeOut->SetGUID(MF_MT_SUBTYPE, myVideoRecorder.CaptureParams.VIDEO_ENCODING_FORMAT);
}
�
void vidThread(vidThreadArgs *args)
{
WriteLogFile(L"Thread started");
HRESULT hr = CoInitializeEx(NULL, COINIT_APARTMENTTHREADED);
if (SUCCEEDED(hr))
{
WriteLogFile(L"CoInitializeEx - success");
hr = MFStartup(MF_VERSION);
if (SUCCEEDED(hr))
{
WriteLogFile(L"MFStartup - success");
UINT32 uiWidth = 0;
UINT32 uiHeight = 0;
IDirect3DDevice9* pDevice = NULL;
IDirect3DSurface9* pSurface = NULL;
hr = myVideoRecorder.InitializeDirect3D9(&pDevice, &pSurface, uiWidth, uiHeight);
if (SUCCEEDED(hr))
{
WriteLogFile(L"InitializeDirect3D9 - success");
IMFSinkWriter *pSinkWriter = NULL;
DWORD stream;
hr = myVideoRecorder.InitializeSinkWriter(myVideoRecorder.CaptureParams.VideoPath, &pSinkWriter, &stream, uiWidth, uiHeight);
if (SUCCEEDED(hr))
{
WriteLogFile(L"InitializeSinkWriter - success");
LONGLONG rtStart = 0;
unsigned long long int frameCounter = 0;
while (true)
{
hr = myVideoRecorder.WriteFrame(pDevice, pSurface, pSinkWriter, stream, rtStart, uiWidth, uiHeight);
frameCounter++;
if (FAILED(hr))
{
WriteLogFile(L"Internal error %d Frame %d\n",
GetLastError(), frameCounter);
break;
}
rtStart += myVideoRecorder.CaptureParams.VIDEO_FRAME_DURATION;
if (bStopRecording)
{
WriteLogFile(L"Finalizing recording of file %s. Frame %llu",
myVideoRecorder.CaptureParams.VideoPath.c_str(),
frameCounter);
break;
}
}
}
else
{
DWORD error = GetLastError();
WriteLogFile(L"failed here. Error %d\n", error);
}
if (SUCCEEDED(hr))
{
hr = pSinkWriter->Finalize();
}
SafeRelease(&pSinkWriter);
}
else
{
WriteLogFile(L"InitializeDirect3D9 - failed Error %d",GetLastError());
result = STATUS_ERROR_INIT_DIRECT3D9;
}
SafeRelease(&pDevice);
SafeRelease(&pSurface);
MFShutdown();
WriteLogFile(L"MFShutDown");
}
else
{
result = STATUS_ERROR_MFSSTARTUP;
WriteLogFile(L"MFStartup failed");
}
CoUninitialize();
}
else
{
result = STATUS_ERROR_COINITILIZE;
WriteLogFile(L"CoInitilize - failed Error %d", GetLastError());
}
HRESULT WriteFrame(IDirect3DDevice9* pDevice, IDirect3DSurface9*
pSurface, IMFSinkWriter* pWriter, DWORD streamIndex, const
LONGLONG& rtStart, const UINT32 uiWidth, const UINT32 uiHeight){
HRESULT hr = pDevice->GetFrontBufferData(0, pSurface);
if(FAILED(hr)){
return hr;
}
D3DLOCKED_RECT rc;
hr = pSurface->LockRect(&rc, NULL, 0);
if(FAILED(hr)){
return hr;
}
IMFSample *pSample = NULL;
IMFMediaBuffer *pBuffer = NULL;
const LONG cbWidth = 4 * uiWidth;
const DWORD cbBuffer = cbWidth * uiHeight;
BYTE *pData = NULL;
// Create a new memory buffer.
hr = MFCreateMemoryBuffer(cbBuffer, &pBuffer);
// Lock the buffer and copy the video frame to the buffer.
if(SUCCEEDED(hr)){
hr = pBuffer->Lock(&pData, NULL, NULL);
}
if(SUCCEEDED(hr)){
#ifdef REVERSE_IMAGE
for(int i = 0, j = uiHeight - 1; i < uiHeight; i++, j--)
for(int k = 0; k < cbWidth; k++)
pData[(i * cbWidth) + k] = ((BYTE*)rc.pBits)[(j *
cbWidth) + k];
#else
hr = MFCopyImage(pData, cbWidth, (BYTE*)rc.pBits, rc.Pitch,
cbWidth, uiHeight);
#endif
}
if(pBuffer){
pBuffer->Unlock();
}
// Set the data length of the buffer.
if(SUCCEEDED(hr)){
hr = pBuffer->SetCurrentLength(cbBuffer);
}
// Create a media sample and add the buffer to the sample.
if(SUCCEEDED(hr)){
hr = MFCreateSample(&pSample);
}
if(SUCCEEDED(hr)){
hr = pSample->AddBuffer(pBuffer);
}
// Set the time stamp and the duration.
if(SUCCEEDED(hr)){
hr = pSample->SetSampleTime(rtStart);
}
if(SUCCEEDED(hr)){
hr = pSample->SetSampleDuration(VIDEO_FRAME_DURATION);
}
// Send the sample to the Sink Writer.
if(SUCCEEDED(hr)){
hr = pWriter->WriteSample(streamIndex, pSample);
}
hr = pSurface->UnlockRect();
SafeRelease(&pSample);
SafeRelease(&pBuffer);
return hr;
}
代码在 5 台不同的机器上进行了测试,全部使用 Windows 10 x64,发现如果我将 uiWidth 和 uiHeight 的值存储在日志文件中,只需在以下行之前:
hr = MFSetAttributeSize(pMediaTypeOut, MF_MT_FRAME_SIZE, uiWidth, uiHeight);
当它们的值低于 1220 和 1080 时,代码可以完美运行,并且当这些值中的一个(或两个)超过 1220x1080 时,它们将获得大小为 0 的视频文件。
更新:我还发布了 InitializeSinkWriter()。在第 17 步,SetInputMediaType() 失败并出现错误 c00d36b4。
HRESULT SGCaptureDecktopVideo::InitializeSinkWriter(std::wstring VideoPath, IMFSinkWriter **ppWriter, DWORD *pStreamIndex, const UINT32 uiWidth, const UINT32 uiHeight)
{
*ppWriter = NULL;
*pStreamIndex = NULL;
IMFSinkWriter *pSinkWriter = NULL;
IMFMediaType *pMediaTypeOut = NULL;
IMFMediaType *pMediaTypeIn = NULL;
DWORD streamIndex;
// Step 1 - MFCreateSinkWriterFromURL
HRESULT hr = MFCreateSinkWriterFromURL(VideoPath.c_str(), NULL, NULL, &pSinkWriter);
if (SUCCEEDED(hr) == 0)
{
WriteLogFile(L"Step 1 - MFCreateSinkWriterFromURL() failed. %x", hr);
goto cleanup;
}
// Step 2 - MFCreateMediaType
hr = MFCreateMediaType(&pMediaTypeOut);
if(SUCCEEDED(hr)==0)
{
WriteLogFile(L"Step 2 - MFCreateMediaType() failed. %x", hr);
goto cleanup;
}
// Step 3 - SetGUID (MF_MT_MAJOR_TYPE)
hr = pMediaTypeOut->SetGUID(MF_MT_MAJOR_TYPE, MFMediaType_Video);
if(SUCCEEDED(hr)==0)
{
WriteLogFile(L"Step 3 - SetGUID (MF_MT_MAJOR_TYPE) failed. %x", hr);
goto cleanup;
}
// Step 4 - SetGUID (MF_MT_SUBTYPE)
hr = pMediaTypeOut->SetGUID(MF_MT_SUBTYPE, myVideoRecorder.CaptureParams.VIDEO_ENCODING_FORMAT);
if (SUCCEEDED(hr) == 0)
{
WriteLogFile(L"Step 4 - SetGUID (MF_MT_SUBTYPE) failed. %x", hr);
goto cleanup;
}
// Step 5 - SetUINT32 (MF_MT_AVG_BITRATE)
hr = pMediaTypeOut->SetUINT32(MF_MT_AVG_BITRATE, myVideoRecorder.CaptureParams.VIDEO_BIT_RATE);
if (SUCCEEDED(hr) == 0)
{
WriteLogFile(L"Step 5 - SetUINT32 (MF_MT_AVG_BITRATE) failed. %x", hr);
goto cleanup;
}
// Step 6 - SetUINT32(MF_MT_INTERLACE_MODE)
hr = pMediaTypeOut->SetUINT32(MF_MT_INTERLACE_MODE, MFVideoInterlace_Progressive);
if (SUCCEEDED(hr) == 0)
{
WriteLogFile(L"Step 6 - SetUINT32(MF_MT_INTERLACE_MODE) failed. %x", hr);
goto cleanup;
}
// Step 7 - MFSetAttributeSize
WriteLogFile(L"w %d h %d",uiWidth, uiHeight);
hr = MFSetAttributeSize(pMediaTypeOut, MF_MT_FRAME_SIZE, uiWidth, uiHeight);
if (SUCCEEDED(hr) == 0)
{
WriteLogFile(L"Step 7 - MFSetAttributeSize() failed. %x", hr);
goto cleanup;
}
// Step 8 - MFSetAttributeRatio - MF_MT_FRAME_RATE
hr = MFSetAttributeRatio(pMediaTypeOut, MF_MT_FRAME_RATE, myVideoRecorder.CaptureParams.VIDEO_FPS, 1);
if (SUCCEEDED(hr) == 0)
{
WriteLogFile(L"Step 8 - MFSetAttributeRatio(MF_MT_FRAME_RATE) failed. %x", hr);
goto cleanup;
}
// Step 9 - MFSetAttributeRatio - MF_MT_PIXEL_ASPECT_RATIO
hr = MFSetAttributeRatio(pMediaTypeOut, MF_MT_PIXEL_ASPECT_RATIO, 1, 1);
if (SUCCEEDED(hr) == 0)
{
WriteLogFile(L"Step 9 - MFSetAttributeRatio(MF_MT_PIXEL_ASPECT_RATIO) failed. %x", hr);
goto cleanup;
}
// Step 10 - AddStream
hr = pSinkWriter->AddStream(pMediaTypeOut, &streamIndex);
if (SUCCEEDED(hr) == 0)
{
WriteLogFile(L"Step 10 - AddStream() failed. %x", hr);
goto cleanup;
}
// Step 11 - MFCreateMediaType
hr = MFCreateMediaType(&pMediaTypeIn);
if (SUCCEEDED(hr) == 0 || pMediaTypeIn==NULL)
{
WriteLogFile(L"Step 11 - MFCreateMediaType() failed. %x", hr);
goto cleanup;
}
// Step 12 - SetGUID (MF_MT_MAJOR_TYPE)
hr = pMediaTypeIn->SetGUID(MF_MT_MAJOR_TYPE, MFMediaType_Video);
if (SUCCEEDED(hr) == 0)
{
WriteLogFile(L"Step 12 - SetGUID (MF_MT_MAJOR_TYPE) failed. %x", hr);
goto cleanup;
}
// Step 13 - SetGUID (MF_MT_SUBTYPE)
hr = pMediaTypeIn->SetGUID(MF_MT_SUBTYPE, myVideoRecorder.CaptureParams.VIDEO_INPUT_FORMAT);
if (SUCCEEDED(hr) == 0)
{
WriteLogFile(L"Step 13 - SetGUID (MF_MT_SUBTYPE) failed. %x", hr);
goto cleanup;
}
// Step 13 - SetUINT32 (MF_MT_INTERLACE_MODE)
hr = pMediaTypeIn->SetUINT32(MF_MT_INTERLACE_MODE, MFVideoInterlace_Progressive);
if (SUCCEEDED(hr) == 0)
{
WriteLogFile(L"SetUINT32 (MF_MT_INTERLACE_MODE). %x", hr);
goto cleanup;
}
// Step 14 - SMFSetAttributeSize
hr = MFSetAttributeSize(pMediaTypeIn, MF_MT_FRAME_SIZE, uiWidth, uiHeight);
if (SUCCEEDED(hr) == 0)
{
WriteLogFile(L"Step 14 - MFSetAttributeSize() failed. %x", hr);
goto cleanup;
}
// Step 15 - MFSetAttributeRatio(MF_MT_FRAME_RATE)
hr = MFSetAttributeRatio(pMediaTypeIn, MF_MT_FRAME_RATE, myVideoRecorder.CaptureParams.VIDEO_FPS, 1);
if (SUCCEEDED(hr) == 0)
{
WriteLogFile(L"Step 15 - MFSetAttributeRatio(MF_MT_FRAME_RATE) failed. %x", hr);
goto cleanup;
}
// Step 16 - MFSetAttributeRatio(MF_MT_PIXEL_ASPECT_RATIO)
hr = MFSetAttributeRatio(pMediaTypeIn, MF_MT_PIXEL_ASPECT_RATIO, 1, 1);
if (SUCCEEDED(hr) == 0)
{
WriteLogFile(L"Step 16 - MFSetAttributeRatio(MF_MT_PIXEL_ASPECT_RATIO) failed. %x", hr);
goto cleanup;
}
// Step 17 - SetInputMediaType
hr = pSinkWriter->SetInputMediaType(streamIndex, pMediaTypeIn, NULL);
if (SUCCEEDED(hr) == 0)
{
WriteLogFile(L"Step 17 - SetInputMediaType() failed. %x", hr);
goto cleanup;
}
// Step 18 - BeginWriting() Tell the sink writer to start accepting data.
hr = pSinkWriter->BeginWriting();
if (SUCCEEDED(hr) == 0)
{
WriteLogFile(L"Step 18 - BeginWriting() failed. %x", hr);
goto cleanup;
}
// Return the pointer to the caller.
WriteLogFile(L"Success");
*ppWriter = pSinkWriter;
(*ppWriter)->AddRef();
*pStreamIndex = streamIndex;
cleanup:;
SafeRelease(&pSinkWriter);
SafeRelease(&pMediaTypeOut);
SafeRelease(&pMediaTypeIn);
return hr;
}
在分辨率更高的机器上,我仍然在这部分遇到错误。 CreateDevice() 失败,错误为 0x7E。
D3DDISPLAYMODE mode;
HRESULT hr = d3d->GetAdapterDisplayMode(D3DADAPTER_DEFAULT, &mode);
if (FAILED(hr))
{
WriteLogFile(L"GetAdapterDisplayMode() failed. Error =%x", GetLastError());
SafeRelease(&d3d);
return hr;
}
WriteLogFile(L"Fetched mode. Width=%d Height=%d", mode.Width, mode.Height);
D3DPRESENT_PARAMETERS parameters = { 0 };
parameters.Windowed = TRUE;
parameters.BackBufferCount = 1;
uiHeight = parameters.BackBufferHeight = mode.Height;
uiWidth = parameters.BackBufferWidth = mode.Width;
parameters.SwapEffect = D3DSWAPEFFECT_DISCARD;
parameters.hDeviceWindow = NULL;
hr = d3d->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, NULL, D3DCREATE_SOFTWARE_VERTEXPROCESSING, ¶meters, ppDevice);
if (FAILED(hr))
{
WriteLogFile(L"CreateDevice failed. Error =%x",GetLastError());
SafeRelease(&d3d);
return hr;
}
最佳答案
您的瓶颈是视频编码器的分辨率支持。
视频编码器通常对分辨率有限制,但限制各不相同。广泛支持的最大安全分辨率为 1920x1088。在您的情况下,您可能正在使用 Microsoft 的软件编码器。我想过去的一段时间MSDN documetnation直接提到了最大分辨率,但是该信息目前不存在。
无法可靠地确定支持的最大分辨率,它看起来像是一个 API 设计缺陷。
根据记录,Windows 10 版本 1903(2019 年 5 月更新)附带软件 H.264 视频编码器,能够编码至少 3840x2160 视频。
另见:
关于c++ - 当屏幕分辨率高于 1920x1080 时捕获视频,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57633885/
我正在使用 JavaFX 开发视频播放器。我正在将视频从本地文件系统加载到 JavaFX 类媒体中。然后我想获取宽度和高度,以便我可以将场景的尺寸设置为该大小: Media media = new M
我是OpenCV的新手,正在尝试解决这个问题。我有一个.mp4文件保存在从网络摄像头流式传输的磁盘上。现在,我需要制作视频的低分辨率版本,以上传到Web服务器(这个想法是,低分辨率预览实时或多或少地上
我在我的应用程序中使用 jfree 图表(折线图)...创建时我的图表看起来很模糊...我怎样才能获得高清晰度图像。 我使用过:ChartUtilities.writeScaledChartAsPNG
我正在用 Java 编写一个工具来处理我网站上上传的文件。我想以特定的方式管理图像:如果尺寸大于限制,我想首先调整图像的尺寸,然后再次检查尺寸。当然,我不想做无用的工作,所以我想在调整图像大小之前估计
是否有一种纯 WPF 方法来获取有关所有可用显示器大小(分辨率)的信息。我知道我可以使用 Screen.AllScreens 来获取它们,但在我的遗留项目中我无法添加新的引用(内置 WPF 程序集除外
看了Developer文档,部分理解了LDPI,HDPI,MDPI,XHDPI类比,网上到处找也没有找到具体答案。 我有两部手机,一部是小屏幕,一部是平板电脑。我希望我的小屏幕手机上的按钮看起来很小,
对于下面给定的网页, xyz {% load staticfiles %} html, body {
我在 Mac 上使用多个 JFrames 制作了一个程序,分辨率还可以,一切都适合屏幕。但是,当我在我的 PC 上运行该程序时,JFrames 太大并且会立即离开屏幕。 我的问题是:是否可以在 JFr
我需要有关如何检索屏幕分辨率的帮助,如下图所示。 我找到了 this documentation这真的很有帮助。这是我根据这些文档尝试的代码: int numberOfScreens = GetSys
有什么方法可以更改分辨率或为亚马逊 Kindle 键盘上的屏幕设置不同的边界?我的屏幕有一部分出现裂纹,我想解决这个问题。 我试过在文件系统中乱搞(通过 WiFi 连接),但我的所有属性更改都没有任何
快速提问, 我正在开发 libgdx 中的游戏,但遇到了问题。我正在尝试扩展我的 Assets ,我正在使用 Gdx.graphics.getDensity() 来获取密度,然后使用它作为乘数来设置我
我有一些关于屏幕分辨率的问题,我不清楚。这些问题假设我的应用程序将在 iOS 4.0 及更高版本以及 iPhone 3GS 或 iPhone 4 上运行。 启动图像 (default.png) 的大小
我们有一个应用程序在审核过程中被 Apple 应用程序审核人员拒绝。拒绝的原因是应用程序在 Ipad 上运行时无法正确缩放。 该应用程序本来就不是要在 Ipad 上运行的,但与他们争论这一点似乎没有意
我试图在不解码文件的情况下获取 JPEG 图像的分辨率。我从互联网上获得了几个样本,但没有一个可以正常工作。似乎是这样,因为许多 JPEG 文件不是标准的,尽管任何图形应用程序(Irfan、PSP、F
我尝试了很多事情,但是所有尝试都失败了。 我需要将灰度图像(2560x1440)调整为更低或更高的分辨率,然后我需要将边界设置为原始大小(2560x1440),但将调整后的图像保持在中心。 我使用的是
我正在使用 GLSulfaceView 开发一个静音相机应用程序,该应用程序从预览中捕获图片。 为了捕捉图片,我使用 GLES20.glReadPixels(0, 0, surfaceWidth, s
是否有相当于 yarn resolutions 的 npm功能? npm package.json docs 中没有提及它. 例如,我想在 3.3.2 上安装 lerna@3.3.2 及其依赖项之一
我制作了一个在 Arduino 上运行的 24x15 LED 显示屏,去年我在内存中放入了 32KB 的图形例程,这很酷。 但现在我已经升级到 Arduino Mega,具有 256KB 内存,并且有
我的场景是,我正在收集网络数据包,如果数据包与网络过滤器匹配,我想记录连续数据包之间的时间差,最后一部分是不起作用的部分。我的问题是,无论我使用什么 C 定时器函数,我都无法获得准确的亚秒级测量。我尝
我们一直在学校布置一项任务,需要更改图像(反转颜色、切换颜色、旋转 90 度、双倍大小、放大图像),现在我正在尝试通过将分辨率加倍来使其大小加倍,但无法弄清楚如何访问该地址并更改它。我们得到了两个函数
我是一名优秀的程序员,十分优秀!