- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我想使用 Frame Rate convertor DSP在我的媒体基金会应用程序中。我正在使用“SourceReader”来读取视频文件。谁能告诉我在何处以及如何将 DMO 与 MF 集成以获得帧速率转换。我似乎不明白向 DMO 提供什么样的样本(压缩/未压缩)以获得新的帧速率。 DMO 如何改变帧率?它是否为新样本提供了新的时间戳?没有代码示例演示其用法。请帮忙,我被卡住了。
谢谢,
莫茨
最佳答案
这是一个老问题。
使用SourceReader 进行帧率转换,需要手动集成DMO。
这个想法是从 SourceReader 获取兼容的样本,比如说由 DMO 处理的视频子类型。
How does the DMO change the frame rate?
This DSP changes the frame rate by repeating or dropping frames.
Does it give a new time-stamp to the new samples?
#pragma once
#define WIN32_LEAN_AND_MEAN
#define STRICT
#pragma comment(lib, "mfplat")
#pragma comment(lib, "mfreadwrite")
#pragma comment(lib, "mfuuid")
#pragma comment(lib, "wmcodecdspuuid")
#include <WinSDKVer.h>
#include <new>
#include <windows.h>
#include <mfapi.h>
#include <mfidl.h>
#include <mfreadwrite.h>
#include <mferror.h>
#include <Wmcodecdsp.h>
template <class T> inline void SAFE_RELEASE(T*& p){
if(p){
p->Release();
p = NULL;
}
}
HRESULT ProcessConverter();
HRESULT InitDMO(IMFTransform**, IMFMediaType*);
HRESULT ProcessSample(IMFSourceReader*, IMFTransform*);
HRESULT ProcessDMO(IMFTransform*, IMFSample*, DWORD&, const UINT32);
HRESULT InitOutputDataBuffer(IMFTransform*, MFT_OUTPUT_DATA_BUFFER*, const UINT32);
void main(){
HRESULT hr = CoInitializeEx(NULL, COINIT_APARTMENTTHREADED | COINIT_DISABLE_OLE1DDE);
if(SUCCEEDED(hr)){
hr = MFStartup(MF_VERSION, MFSTARTUP_LITE);
if(SUCCEEDED(hr)){
hr = ProcessConverter();
hr = MFShutdown();
}
CoUninitialize();
}
}
HRESULT ProcessConverter(){
HRESULT hr;
IMFSourceReader* pReader = NULL;
// Change the URL
if(FAILED(hr = MFCreateSourceReaderFromURL(L"Wildlife.wmv", NULL, &pReader))){
return hr;
}
DWORD dwMediaTypeIndex = 0;
IMFMediaType* pType = NULL;
hr = pReader->GetNativeMediaType((DWORD)MF_SOURCE_READER_FIRST_VIDEO_STREAM, dwMediaTypeIndex, &pType);
if(SUCCEEDED(hr)){
// We must ask for a subtype compatible with DMO :
// ARGB32 RGB24 RGB32 RGB555 RGB565 AYUV IYUV UYVY Y211 Y411 Y41P YUY2 YUYV YV12 YVYU
hr = pType->SetGUID(MF_MT_SUBTYPE, MFVideoFormat_YV12);
if(SUCCEEDED(hr)){
hr = pReader->SetCurrentMediaType((DWORD)MF_SOURCE_READER_FIRST_VIDEO_STREAM, NULL, pType);
}
// We need this because we use the MediaType to initialize the Transform
if(SUCCEEDED(hr)){
SAFE_RELEASE(pType);
hr = pReader->GetCurrentMediaType((DWORD)MF_SOURCE_READER_FIRST_VIDEO_STREAM, &pType);
}
if(SUCCEEDED(hr)){
IMFTransform* pTransform = NULL;
hr = InitDMO(&pTransform, pType);
if(SUCCEEDED(hr)){
hr = ProcessSample(pReader, pTransform);
// Seems not really needed with the DMO
/*hr = */ pTransform->ProcessMessage(MFT_MESSAGE_COMMAND_FLUSH, NULL);
/*hr = */ pTransform->ProcessMessage(MFT_MESSAGE_NOTIFY_END_OF_STREAM, NULL);
/*hr = */ pTransform->ProcessMessage(MFT_MESSAGE_NOTIFY_END_STREAMING, NULL);
}
SAFE_RELEASE(pTransform);
}
}
SAFE_RELEASE(pType);
SAFE_RELEASE(pReader);
return hr;
}
HRESULT InitDMO(IMFTransform** ppTransform, IMFMediaType* pType){
HRESULT hr = CoCreateInstance(CLSID_CFrameRateConvertDmo, NULL, CLSCTX_INPROC_SERVER, IID_IMFTransform, reinterpret_cast<void**>(ppTransform));
if(SUCCEEDED(hr)){
hr = (*ppTransform)->SetInputType(0, pType, 0);
}
if(SUCCEEDED(hr)){
// Change the frame rate as needed, here num = 60000 and den = 1001
hr = MFSetAttributeRatio(pType, MF_MT_FRAME_RATE, 60000, 1001);
}
if(SUCCEEDED(hr)){
hr = (*ppTransform)->SetOutputType(0, pType, 0);
}
if(SUCCEEDED(hr)){
hr = (*ppTransform)->ProcessMessage(MFT_MESSAGE_NOTIFY_BEGIN_STREAMING, NULL);
}
if(SUCCEEDED(hr)){
hr = (*ppTransform)->ProcessMessage(MFT_MESSAGE_NOTIFY_START_OF_STREAM, NULL);
}
return hr;
}
HRESULT ProcessSample(IMFSourceReader* pReader, IMFTransform* pTransform){
HRESULT hr;
IMFMediaType* pType = NULL;
if(FAILED(hr = pTransform->GetOutputCurrentType(0, &pType))){
return hr;
}
// We need the frame size to create the sample buffer.
UINT32 uiFrameSize = 0;
hr = pType->GetUINT32(MF_MT_SAMPLE_SIZE, &uiFrameSize);
SAFE_RELEASE(pType);
if(FAILED(hr) || uiFrameSize == 0){
return hr;
}
BOOL bProcess = TRUE;
DWORD streamIndex;
DWORD flags;
LONGLONG llTimeStamp;
IMFSample* pSample = NULL;
DWORD dwReaderCount = 0;
DWORD dwDMOCount = 0;
while(bProcess){
hr = pReader->ReadSample((DWORD)MF_SOURCE_READER_FIRST_VIDEO_STREAM, 0, &streamIndex, &flags, &llTimeStamp, &pSample);
if(FAILED(hr) || flags != 0){
bProcess = FALSE;
}
else{
hr = ProcessDMO(pTransform, pSample, dwDMOCount, uiFrameSize);
// You can check timestamp from the SourceReader
//hr = pSample->GetSampleDuration(&llTimeStamp);
//hr = pSample->GetSampleTime(&llTimeStamp);
SAFE_RELEASE(pSample);
dwReaderCount++;
}
}
// Todo : check dwReaderCount and dwDMOCount here.
// For example with native frame rate = 30000/1001 and dwReaderCount = 900
// DMO frame rate = 30000/1001 -> dwReaderCount = 900
// DMO frame rate = 60000/1001 -> dwReaderCount = 1800
// DMO frame rate = 25/1 -> dwReaderCount = 750
SAFE_RELEASE(pSample);
return hr;
}
HRESULT ProcessDMO(IMFTransform* pTransform, IMFSample* pSample, DWORD& dwDMOCount, const UINT32 uiFrameSize){
HRESULT hr = S_OK;
MFT_OUTPUT_DATA_BUFFER outputDataBuffer;
DWORD processOutputStatus = 0;
// Todo : we should avoid recreating the buffer...
hr = InitOutputDataBuffer(pTransform, &outputDataBuffer, uiFrameSize);
while(hr == S_OK){
hr = pTransform->ProcessOutput(0, 1, &outputDataBuffer, &processOutputStatus);
if(hr == MF_E_TRANSFORM_NEED_MORE_INPUT){
break;
}
// You can check new timestamp from the DMO
/*if(outputDataBuffer.pSample != NULL){
LONGLONG llTimeStamp = 0;
hr = outputDataBuffer.pSample->GetSampleTime(&llTimeStamp);
hr = outputDataBuffer.pSample->GetSampleDuration(&llTimeStamp);
}*/
dwDMOCount++;
}
if(hr == MF_E_TRANSFORM_NEED_MORE_INPUT){
hr = pTransform->ProcessInput(0, pSample, 0);
}
if(outputDataBuffer.pSample != NULL){
SAFE_RELEASE(outputDataBuffer.pSample);
}
return hr;
}
HRESULT InitOutputDataBuffer(IMFTransform* pMFTransform, MFT_OUTPUT_DATA_BUFFER* pOutputBuffer, const UINT32 uiFrameSize){
MFT_OUTPUT_STREAM_INFO outputStreamInfo;
DWORD outputStreamId = 0;
ZeroMemory(&outputStreamInfo, sizeof(outputStreamInfo));
ZeroMemory(pOutputBuffer, sizeof(*pOutputBuffer));
HRESULT hr = pMFTransform->GetOutputStreamInfo(outputStreamId, &outputStreamInfo);
if(SUCCEEDED(hr)){
if((outputStreamInfo.dwFlags & MFT_OUTPUT_STREAM_PROVIDES_SAMPLES) == 0 &&
(outputStreamInfo.dwFlags & MFT_OUTPUT_STREAM_CAN_PROVIDE_SAMPLES) == 0){
IMFSample* pOutputSample = NULL;
IMFMediaBuffer* pMediaBuffer = NULL;
hr = MFCreateSample(&pOutputSample);
if(SUCCEEDED(hr)){
hr = MFCreateMemoryBuffer(uiFrameSize, &pMediaBuffer);
}
if(SUCCEEDED(hr)){
hr = pOutputSample->AddBuffer(pMediaBuffer);
}
if(SUCCEEDED(hr)){
pOutputBuffer->pSample = pOutputSample;
pOutputBuffer->pSample->AddRef();
}
SAFE_RELEASE(pMediaBuffer);
SAFE_RELEASE(pOutputSample);
}
}
return hr;
}
关于directshow - 如何在 MF 应用程序中使用帧速率转换器 DMO,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8412343/
我需要一次发送至少 200 条消息。程序启动后,给15或17发邮件成功,然后报错: 消息错误: com.sun.mail.smtp.SMTPSendFailedException: 421 4.4.2
我目前正在开发一个使用 AVSynthesizer 将文本转换为语音的 iOS 应用程序。 我想要做的是,当合成器在说话时,可以通过 slider 改变发声率,并且说话的速度会发生变化。 我在 sli
假设我们有以下场景: 包含 10,000 条消息的服务总线队列 Azure Functions(使用计划),其中函数设置为 SB 队列的触发器 外部(不受我们控制)系统无法超过特定请求率 如果我尽快对
TextToSpeech有设置语速的方法:setSpeechRate() .但它没有查询当前速度的相反方法。 有没有办法向系统查询该值? 最佳答案 您可能会得到默认的 TTS 语速 Settings.
我有一个关于 NGINX 速率限制的问题。 是否可以根据 JWT token 的解码值进行速率限制?我在文档中找不到任何这样的信息。 或者即使有一种通过创建纯自定义变量(使用 LuaJIT)来进行速率
我有一个带有方向键和 2 个按钮的游戏 handle 。所有这些都是数字的(不是模拟的)。 我有一个处理他们的事件的程序: -(void)gamepadTick:(float)delta {
所以我需要在 OpenCV 中获取网络摄像头的 fps 速率。哪个功能可以做这样的事情? 最佳答案 int cvGetCaptureProperty( CvCapture* capture, int
我四处寻找 CURL 设置文件,但没有在/etc/中找到它,也没有在 curl 站点 ether 上找到太多... 所以基本上我想做的是设置 curl 可以上传的最大速度限制(无论它正在运行多少个实例
我有一个在 Atom 上运行的嵌入式 Linux 系统,这是一个足够新的 CPU,可以有一个不变的 TSC(时间戳计数器),内核在启动时测量其频率。我在自己的代码中使用 TSC 来保持时间(避免内核调
我正在寻找一种以高粒度单独限制 RPC 速率的方法,令我沮丧的是,针对此问题可用的选项并不多。我正在尝试用 gRPC 替换 REST API,对我来说最重要的功能之一是能够为每个路由添加中间件。不幸的
我正在使用 PHP、MySQL 和 Redis 开发 API,并希望对特定调用进行速率限制。 API 位于 CloudFlare 后面。为实现这一点,我将增加每个 IP 地址每小时在 Redis 中进
我正在寻找一种以编程方式(无论是调用库还是独立程序)监视 linux 中实时 ip 流量的方法。我不想要总数,我想要当前正在使用的带宽。我正在寻找与 OS X 的 istat 菜单的网络流量监视器类似
所以我注意到 Apple 更改了 SKStoreProductViewController,禁用了“写评论”按钮。此问题是否有任何解决方法或修复方法? 最佳答案 SKStoreProductViewC
我今天浏览了 Amazon RDS 定价网站,现在确实想知道他们实际上如何计算 I/O 速率? “每 100 万个请求 0.10 美元”到底是什么意思? 谁能举出一些简单的例子,从 EC2 到 RDS
关闭。这个问题需要details or clarity .它目前不接受答案。 想改进这个问题吗? 通过 editing this post 添加细节并澄清问题. 关闭 5 年前。 Improve
在旧的 API 中,剩余的允许容量显然作为 X-Ratelimit-Remaining 返回HTTP header 。 然而,current version's documentation对此一无所获
在我的 Android 应用程序中,我观察到前置摄像头录制的视频以 7-10 fps 的速度录制,而后置摄像头的工作正常, native 摄像头应用程序确实以 29fps 的速度录制前置摄像头的视频。
我正在编码一个里面有 dvb_teletext 的视频。打开输出流 #1:2 的编码器时出现错误提示。我使用以下命令对我的视频进行编码。 ffmpeg -threads 8 -i input.ts -
我正在使用以下命令为我的视频添加淡入淡出效果 {"-y", "-ss", "" + startMs / 1000, "-t", "" + (endMs - startMs) / 1000, "-i",
我正在尝试使用以下命令通过 FFMPEG 将 avi 视频文件转换为 flv 格式: -i C:\files\input\test.avi -y -ab 448k -ar 48000 -vcodec
我是一名优秀的程序员,十分优秀!