Advertisement
Guest User

Untitled

a guest
Jan 25th, 2016
68
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 5.27 KB | None | 0 0
  1. #include <iostream>
  2. #include <string>
  3. #include <vector>
  4. #include <atlbase.h>
  5. #include <mfapi.h>
  6. #include <mfidl.h>
  7. #include <wmcodecdsp.h>
  8. #include <wmcontainer.h>
  9. #include <comdef.h>
  10. #include <dmo.h>
  11. #include <dshow.h>
  12.  
  13. #pragma comment(lib, "mf.lib")
  14. #pragma comment(lib, "mfplat.lib")
  15. #pragma comment(lib, "mfuuid.lib")
  16. #pragma comment(lib, "strmiids.lib")
  17. #pragma comment(lib, "winmm.lib")
  18. #pragma comment(lib, "msdmo.lib")
  19.  
  20. class ComException : public std::exception
  21. {
  22. public:
  23. ComException(HRESULT errorCode, const std::string& message) :
  24. errorCode(errorCode),
  25. message(message)
  26. {}
  27. friend std::ostream& operator<<(std::ostream& s, const ComException& e)
  28. {
  29. _com_error comError(e.errorCode);
  30. return s << "Error in '" << e.message << "': 0x" << std::hex << e.errorCode << " - " << comError.ErrorMessage();
  31. }
  32. private:
  33. HRESULT errorCode;
  34. std::string message;
  35. };
  36.  
  37.  
  38. #define THROW_ON_FAIL(expr) { \
  39. HRESULT _errorCode = expr; \
  40. if(FAILED(_errorCode)) throw ComException(_errorCode, #expr); \
  41. }
  42.  
  43.  
  44. static const GUID Codec = MFVideoFormat_MSS2;
  45. static const int FrameWidth = 1280;
  46. static const int FrameHeight = 720;
  47. static const int FrameRate = 25;
  48. static const int Bitrate = 1000000;
  49.  
  50. static CComPtr<IMFMediaType> createInputMediaType()
  51. {
  52. CComPtr<IMFMediaType> mediaType;
  53. THROW_ON_FAIL(MFCreateMediaType(&mediaType));
  54. THROW_ON_FAIL(mediaType->SetGUID(MF_MT_MAJOR_TYPE, MFMediaType_Video));
  55. THROW_ON_FAIL(mediaType->SetGUID(MF_MT_SUBTYPE, MFVideoFormat_RGB32));
  56. THROW_ON_FAIL(mediaType->SetUINT32(MF_MT_INTERLACE_MODE, MFVideoInterlace_Progressive));
  57. THROW_ON_FAIL(MFSetAttributeSize(mediaType, MF_MT_FRAME_SIZE, FrameWidth, FrameHeight));
  58. THROW_ON_FAIL(MFSetAttributeRatio(mediaType, MF_MT_FRAME_RATE, FrameRate, 1));
  59. return mediaType;
  60. }
  61.  
  62. static CComPtr<IMFMediaType> createOutputMediaType()
  63. {
  64. CComPtr<IMFMediaType> mediaType;
  65. THROW_ON_FAIL(MFCreateMediaType(&mediaType));
  66. THROW_ON_FAIL(mediaType->SetGUID(MF_MT_MAJOR_TYPE, MFMediaType_Video));
  67. THROW_ON_FAIL(mediaType->SetGUID(MF_MT_SUBTYPE, Codec));
  68. THROW_ON_FAIL(mediaType->SetUINT32(MF_MT_AVG_BITRATE, Bitrate));
  69. THROW_ON_FAIL(mediaType->SetUINT32(MF_MT_INTERLACE_MODE, MFVideoInterlace_Progressive));
  70. THROW_ON_FAIL(MFSetAttributeSize(mediaType, MF_MT_FRAME_SIZE, FrameWidth, FrameHeight));
  71. THROW_ON_FAIL(MFSetAttributeRatio(mediaType, MF_MT_FRAME_RATE, FrameRate, 1));
  72. return mediaType;
  73. }
  74.  
  75. static CComPtr<IMFTransform> findRegisteredEncoderTransform(IMFMediaType* outputType)
  76. {
  77. MFT_REGISTER_TYPE_INFO outputTypeInfo = {};
  78. THROW_ON_FAIL(outputType->GetGUID(MF_MT_MAJOR_TYPE, &outputTypeInfo.guidMajorType));
  79. THROW_ON_FAIL(outputType->GetGUID(MF_MT_SUBTYPE, &outputTypeInfo.guidSubtype));
  80.  
  81. IMFActivate** activates = nullptr;
  82. UINT32 activateCount = 0;
  83.  
  84. THROW_ON_FAIL(MFTEnumEx(MFT_CATEGORY_VIDEO_ENCODER, MFT_ENUM_FLAG_ALL, nullptr, &outputTypeInfo, &activates, &activateCount));
  85. if(activateCount == 0) throw ComException(E_FAIL, "Can't find encoder");
  86.  
  87. CComPtr<IMFActivate> activate = activates[0];
  88.  
  89. for (UINT32 i = 0; i < activateCount; i++)
  90. {
  91. activates[i]->Release();
  92. }
  93. CoTaskMemFree(activates);
  94.  
  95. CComPtr<IMFTransform> transform;
  96. THROW_ON_FAIL(activate->ActivateObject(IID_PPV_ARGS(&transform)));
  97. return transform;
  98. }
  99.  
  100. static void addPrivateData(IMFTransform* transform, IMFMediaType* mediaType)
  101. {
  102. CComQIPtr<IWMCodecPrivateData> privateData = transform;
  103. if(!privateData) throw ComException(E_FAIL, "Can't get codec private data");
  104. DMO_MEDIA_TYPE dmoType = {};
  105. try
  106. {
  107. THROW_ON_FAIL(MFInitAMMediaTypeFromMFMediaType(mediaType, FORMAT_VideoInfo, (AM_MEDIA_TYPE*)&dmoType));
  108. THROW_ON_FAIL(privateData->SetPartialOutputType(&dmoType));
  109.  
  110. ULONG dataSize = 0;
  111. THROW_ON_FAIL(privateData->GetPrivateData(nullptr, &dataSize));
  112. std::vector<BYTE> data;
  113. data.resize(dataSize);
  114. THROW_ON_FAIL(privateData->GetPrivateData(&data[0], &dataSize)); // FIXME: E_NOTIMPL error here
  115. THROW_ON_FAIL(mediaType->SetBlob(MF_MT_USER_DATA, &data[0], dataSize));
  116. }
  117. catch(...)
  118. {
  119. MoFreeMediaType(&dmoType);
  120. throw;
  121. }
  122. MoFreeMediaType(&dmoType);
  123. }
  124.  
  125. CComPtr<IMFTransform> createEncoderTransform()
  126. {
  127. CComPtr<IMFMediaType> inputType = createInputMediaType();
  128. CComPtr<IMFMediaType> outputType = createOutputMediaType();
  129.  
  130. CComPtr<IMFTransform> transform = findRegisteredEncoderTransform(outputType);
  131.  
  132. THROW_ON_FAIL(transform->SetInputType(0, inputType, 0));
  133. addPrivateData(transform, outputType);
  134. THROW_ON_FAIL(transform->SetOutputType(0, outputType, 0));
  135. return transform;
  136. }
  137.  
  138. EXTERN_GUID(CLSID_CMSSCEncMediaObject2, 0xf7ffe0a0, 0xa4f5, 0x44b5, 0x94, 0x9e, 0x15, 0xed, 0x2b, 0xc6, 0x6f, 0x9d);
  139.  
  140. static void registerScreenEncoder()
  141. {
  142. MFT_REGISTER_TYPE_INFO outputTypeInfo;
  143. outputTypeInfo.guidMajorType = MFMediaType_Video;
  144. outputTypeInfo.guidSubtype = MFVideoFormat_MSS2;
  145. THROW_ON_FAIL(MFTRegisterLocalByCLSID(CLSID_CMSSCEncMediaObject2, MFT_CATEGORY_VIDEO_ENCODER, L"Windows Media Video 9 Screen Encoder", MFT_ENUM_FLAG_ALL, 0, nullptr, 1, &outputTypeInfo));
  146. }
  147.  
  148. int main()
  149. {
  150. try
  151. {
  152. THROW_ON_FAIL(CoInitialize(nullptr));
  153. THROW_ON_FAIL(MFStartup(MF_VERSION));
  154. registerScreenEncoder();
  155. CComPtr<IMFTransform> transform = createEncoderTransform();
  156. std::cout << "Transform created " << transform << std::endl;
  157. THROW_ON_FAIL(MFShutdown());
  158. }
  159. catch(const ComException& e)
  160. {
  161. std::cout << e << std::endl;
  162. }
  163. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement