如何解决如何获得Microsoft MPEG4源来以高于4Gbps的比特率打开MOV
似乎当MOV的比特率太高并且无法容纳32位时,Microsoft MPEG 4 Source不会对其进行解析。有人知道解决此问题的方法吗?
我非常确定它与比特率有关,因为我已经生成了测试文件,并且通过仅调整帧速率,我生成了两个文件-比特率超过4.2Gbps(32位)的文件不会打开,但是另一个比特率小于4.2Gps的文件会打开文件。
我尝试使用IMFSourceReader打开文件:
IMFSourceReader* reader = nullptr;
hr = MFCreateSourceReaderFromURL(L"input.mov",nullptr,&reader);
SAFE_RELEASE(reader);
但这只会返回E_FAIL。
我尝试通过IMFSourceResolver打开它:
IMFMediaSource* source = nullptr;
IMFSourceResolver* resolver = nullptr;
MFCreateSourceResolver(&resolver);
MF_OBJECT_TYPE objectType;
IUnknown* result = nullptr;
hr = resolver->CreateObjectFromURL(L"input.mov",MF_RESOLUTION_MEDIASOURCE | MF_RESOLUTION_CONTENT_DOES_NOT_HAVE_TO_MATCH_EXTENSION_OR_MIME_TYPE | MF_RESOLUTION_READ,&objectType,&result);
这也失败了。
为重现此内容,我上传了一个小的400KB ZIP,其中包含:
- 3000x3000源图像
- .bat ffmpeg命令生成视频
- 3000x3000 @ 59fps的HapQ MOV文件-MPEG4源可以解决此问题,比特率仅低于4.2Gbps
- 3000x3000 @ 60fps的HapQ MOV文件-MPEG4源无法解决此问题,比特率仅为推动者4.2Gbps
生成视频供参考:
ffmpeg -y -loop 1 -i black3000.png -t 0.2 -r 59 -s 3000x3000 -c:v hap -format hap_q -compressor none output-good.mov
ffmpeg -y -loop 1 -i black3000.png -t 0.2 -r 60 -s 3000x3000 -c:v hap -format hap_q -compressor none output-bad.mov
pause
有没有其他人以前见过这种行为,并且知道解决方法?
谢谢
解决方法
就像@Simon Mourier所建议的那样,解决此问题的唯一方法是实现自定义ByteStreamHandler并向MFRegisterLocalByteStreamHandler注册它,但是您还必须创建一个自定义IMFMediaSource,因为我找不到任何方法似乎只能实例化MPEG4源,所以只能通过其ByteStreamHandler创建它。.
作为参考,这是我用来创建手动创建MPEG4源而不使用Source Resolver的伪测试代码:
#include <initguid.h>
DEFINE_GUID(CLSID_MPEG4ByteStreamPlugin,0x271c3902,0x6095,0x4c45,0xa2,0x2f,0x20,0x09,0x18,0x16,0xee,0x9e);
class CallbackTest : public IMFAsyncCallback
{
public:
CallbackTest(IMFByteStreamHandler* handler)
{
_handler = handler;
}
IMFByteStreamHandler* _handler;
virtual HRESULT QueryInterface(REFIID riid,void ** ppvObject) override
{
return HRESULT();
}
virtual ULONG AddRef(void) override
{
return 1;
}
virtual ULONG Release(void) override
{
return 1;
}
virtual HRESULT GetParameters(DWORD * pdwFlags,DWORD * pdwQueue) override
{
return E_NOTIMPL;
}
virtual HRESULT __stdcall Invoke(IMFAsyncResult * pAsyncResult) override
{
// At this point HR = E_FAIL for > 4.2Gbps MOV
HRESULT hr = pAsyncResult->GetStatus();
MF_OBJECT_TYPE objectType;
IUnknown* unknownObject = nullptr;
hr = _handler->EndCreateObject(pAsyncResult,&objectType,&unknownObject);
// NOTE: I also tried to just force creating the MPEG 4 Source by calling
// EndCreateObject with a dummy IMFAsyncResult but that always failed..
IMFMediaSource* mediaSource = nullptr;
hr = unknownObject->QueryInterface(&mediaSource);
return S_OK;
}
};
void Test()
{
HRESULT hr;
// Create a bytestream from the file
IMFByteStream* byteStream = nullptr;
hr = MFCreateFile(MF_ACCESSMODE_READ,MF_OPENMODE_FAIL_IF_NOT_EXIST,MF_FILEFLAGS_NOBUFFERING,fileUrl,&byteStream);
// Create the MPEG4 ByteStreamHandler
IMFByteStreamHandler* handler = nullptr;
hr = CoCreateInstance(CLSID_MPEG4ByteStreamPlugin,nullptr,CLSCTX_ALL,IID_IMFByteStreamHandler,(void**)&handler);
IMFAsyncCallback* callback = new CallbackTest(handler);
hr = handler->BeginCreateObject(byteStream,MF_RESOLUTION_MEDIASOURCE | MF_RESOLUTION_READ | MF_RESOLUTION_CONTENT_DOES_NOT_HAVE_TO_MATCH_EXTENSION_OR_MIME_TYPE,callback,handler);
}
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。