mf-common.cpp 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383
  1. #include "mf-common.hpp"
  2. #include <util/platform.h>
  3. #include <Mferror.h>
  4. #include <strsafe.h>
  5. #include <wrl/client.h>
  6. #include <string>
  7. using namespace std;
  8. static void DBGMSG(PCWSTR format, ...)
  9. {
  10. va_list args;
  11. va_start(args, format);
  12. WCHAR msg[MAX_PATH];
  13. if (SUCCEEDED(StringCbVPrintf(msg, sizeof(msg), format, args)))
  14. {
  15. char *cmsg;
  16. os_wcs_to_utf8_ptr(msg, 0, &cmsg);
  17. MF_LOG(LOG_INFO, "%s", cmsg);
  18. bfree(cmsg);
  19. }
  20. }
  21. #ifndef IF_EQUAL_RETURN
  22. #define IF_EQUAL_RETURN(param, val) if(val == param) return L#val
  23. #endif
  24. static LPCWSTR GetGUIDNameConst(const GUID& guid)
  25. {
  26. IF_EQUAL_RETURN(guid, MF_MT_MAJOR_TYPE);
  27. IF_EQUAL_RETURN(guid, MF_MT_MAJOR_TYPE);
  28. IF_EQUAL_RETURN(guid, MF_MT_SUBTYPE);
  29. IF_EQUAL_RETURN(guid, MF_MT_ALL_SAMPLES_INDEPENDENT);
  30. IF_EQUAL_RETURN(guid, MF_MT_FIXED_SIZE_SAMPLES);
  31. IF_EQUAL_RETURN(guid, MF_MT_COMPRESSED);
  32. IF_EQUAL_RETURN(guid, MF_MT_SAMPLE_SIZE);
  33. IF_EQUAL_RETURN(guid, MF_MT_WRAPPED_TYPE);
  34. IF_EQUAL_RETURN(guid, MF_MT_AUDIO_NUM_CHANNELS);
  35. IF_EQUAL_RETURN(guid, MF_MT_AUDIO_SAMPLES_PER_SECOND);
  36. IF_EQUAL_RETURN(guid, MF_MT_AUDIO_FLOAT_SAMPLES_PER_SECOND);
  37. IF_EQUAL_RETURN(guid, MF_MT_AUDIO_AVG_BYTES_PER_SECOND);
  38. IF_EQUAL_RETURN(guid, MF_MT_AUDIO_BLOCK_ALIGNMENT);
  39. IF_EQUAL_RETURN(guid, MF_MT_AUDIO_BITS_PER_SAMPLE);
  40. IF_EQUAL_RETURN(guid, MF_MT_AUDIO_VALID_BITS_PER_SAMPLE);
  41. IF_EQUAL_RETURN(guid, MF_MT_AUDIO_SAMPLES_PER_BLOCK);
  42. IF_EQUAL_RETURN(guid, MF_MT_AUDIO_CHANNEL_MASK);
  43. IF_EQUAL_RETURN(guid, MF_MT_AUDIO_FOLDDOWN_MATRIX);
  44. IF_EQUAL_RETURN(guid, MF_MT_AUDIO_WMADRC_PEAKREF);
  45. IF_EQUAL_RETURN(guid, MF_MT_AUDIO_WMADRC_PEAKTARGET);
  46. IF_EQUAL_RETURN(guid, MF_MT_AUDIO_WMADRC_AVGREF);
  47. IF_EQUAL_RETURN(guid, MF_MT_AUDIO_WMADRC_AVGTARGET);
  48. IF_EQUAL_RETURN(guid, MF_MT_AUDIO_PREFER_WAVEFORMATEX);
  49. IF_EQUAL_RETURN(guid, MF_MT_AAC_PAYLOAD_TYPE);
  50. IF_EQUAL_RETURN(guid, MF_MT_AAC_AUDIO_PROFILE_LEVEL_INDICATION);
  51. IF_EQUAL_RETURN(guid, MF_MT_FRAME_SIZE);
  52. IF_EQUAL_RETURN(guid, MF_MT_FRAME_RATE);
  53. IF_EQUAL_RETURN(guid, MF_MT_FRAME_RATE_RANGE_MAX);
  54. IF_EQUAL_RETURN(guid, MF_MT_FRAME_RATE_RANGE_MIN);
  55. IF_EQUAL_RETURN(guid, MF_MT_PIXEL_ASPECT_RATIO);
  56. IF_EQUAL_RETURN(guid, MF_MT_DRM_FLAGS);
  57. IF_EQUAL_RETURN(guid, MF_MT_PAD_CONTROL_FLAGS);
  58. IF_EQUAL_RETURN(guid, MF_MT_SOURCE_CONTENT_HINT);
  59. IF_EQUAL_RETURN(guid, MF_MT_VIDEO_CHROMA_SITING);
  60. IF_EQUAL_RETURN(guid, MF_MT_INTERLACE_MODE);
  61. IF_EQUAL_RETURN(guid, MF_MT_TRANSFER_FUNCTION);
  62. IF_EQUAL_RETURN(guid, MF_MT_VIDEO_PRIMARIES);
  63. IF_EQUAL_RETURN(guid, MF_MT_CUSTOM_VIDEO_PRIMARIES);
  64. IF_EQUAL_RETURN(guid, MF_MT_YUV_MATRIX);
  65. IF_EQUAL_RETURN(guid, MF_MT_VIDEO_LIGHTING);
  66. IF_EQUAL_RETURN(guid, MF_MT_VIDEO_NOMINAL_RANGE);
  67. IF_EQUAL_RETURN(guid, MF_MT_GEOMETRIC_APERTURE);
  68. IF_EQUAL_RETURN(guid, MF_MT_MINIMUM_DISPLAY_APERTURE);
  69. IF_EQUAL_RETURN(guid, MF_MT_PAN_SCAN_APERTURE);
  70. IF_EQUAL_RETURN(guid, MF_MT_PAN_SCAN_ENABLED);
  71. IF_EQUAL_RETURN(guid, MF_MT_AVG_BITRATE);
  72. IF_EQUAL_RETURN(guid, MF_MT_AVG_BIT_ERROR_RATE);
  73. IF_EQUAL_RETURN(guid, MF_MT_MAX_KEYFRAME_SPACING);
  74. IF_EQUAL_RETURN(guid, MF_MT_DEFAULT_STRIDE);
  75. IF_EQUAL_RETURN(guid, MF_MT_PALETTE);
  76. IF_EQUAL_RETURN(guid, MF_MT_USER_DATA);
  77. IF_EQUAL_RETURN(guid, MF_MT_AM_FORMAT_TYPE);
  78. IF_EQUAL_RETURN(guid, MF_MT_MPEG_START_TIME_CODE);
  79. IF_EQUAL_RETURN(guid, MF_MT_MPEG2_PROFILE);
  80. IF_EQUAL_RETURN(guid, MF_MT_MPEG2_LEVEL);
  81. IF_EQUAL_RETURN(guid, MF_MT_MPEG2_FLAGS);
  82. IF_EQUAL_RETURN(guid, MF_MT_MPEG_SEQUENCE_HEADER);
  83. IF_EQUAL_RETURN(guid, MF_MT_DV_AAUX_SRC_PACK_0);
  84. IF_EQUAL_RETURN(guid, MF_MT_DV_AAUX_CTRL_PACK_0);
  85. IF_EQUAL_RETURN(guid, MF_MT_DV_AAUX_SRC_PACK_1);
  86. IF_EQUAL_RETURN(guid, MF_MT_DV_AAUX_CTRL_PACK_1);
  87. IF_EQUAL_RETURN(guid, MF_MT_DV_VAUX_SRC_PACK);
  88. IF_EQUAL_RETURN(guid, MF_MT_DV_VAUX_CTRL_PACK);
  89. IF_EQUAL_RETURN(guid, MF_MT_ARBITRARY_HEADER);
  90. IF_EQUAL_RETURN(guid, MF_MT_ARBITRARY_FORMAT);
  91. IF_EQUAL_RETURN(guid, MF_MT_IMAGE_LOSS_TOLERANT);
  92. IF_EQUAL_RETURN(guid, MF_MT_MPEG4_SAMPLE_DESCRIPTION);
  93. IF_EQUAL_RETURN(guid, MF_MT_MPEG4_CURRENT_SAMPLE_ENTRY);
  94. IF_EQUAL_RETURN(guid, MF_MT_ORIGINAL_4CC);
  95. IF_EQUAL_RETURN(guid, MF_MT_ORIGINAL_WAVE_FORMAT_TAG);
  96. // Media types
  97. IF_EQUAL_RETURN(guid, MFMediaType_Audio);
  98. IF_EQUAL_RETURN(guid, MFMediaType_Video);
  99. IF_EQUAL_RETURN(guid, MFMediaType_Protected);
  100. IF_EQUAL_RETURN(guid, MFMediaType_SAMI);
  101. IF_EQUAL_RETURN(guid, MFMediaType_Script);
  102. IF_EQUAL_RETURN(guid, MFMediaType_Image);
  103. IF_EQUAL_RETURN(guid, MFMediaType_HTML);
  104. IF_EQUAL_RETURN(guid, MFMediaType_Binary);
  105. IF_EQUAL_RETURN(guid, MFMediaType_FileTransfer);
  106. IF_EQUAL_RETURN(guid, MFVideoFormat_AI44); // FCC('AI44')
  107. IF_EQUAL_RETURN(guid, MFVideoFormat_ARGB32); // D3DFMT_A8R8G8B8
  108. IF_EQUAL_RETURN(guid, MFVideoFormat_AYUV); // FCC('AYUV')
  109. IF_EQUAL_RETURN(guid, MFVideoFormat_DV25); // FCC('dv25')
  110. IF_EQUAL_RETURN(guid, MFVideoFormat_DV50); // FCC('dv50')
  111. IF_EQUAL_RETURN(guid, MFVideoFormat_DVH1); // FCC('dvh1')
  112. IF_EQUAL_RETURN(guid, MFVideoFormat_DVSD); // FCC('dvsd')
  113. IF_EQUAL_RETURN(guid, MFVideoFormat_DVSL); // FCC('dvsl')
  114. IF_EQUAL_RETURN(guid, MFVideoFormat_H264); // FCC('H264')
  115. IF_EQUAL_RETURN(guid, MFVideoFormat_I420); // FCC('I420')
  116. IF_EQUAL_RETURN(guid, MFVideoFormat_IYUV); // FCC('IYUV')
  117. IF_EQUAL_RETURN(guid, MFVideoFormat_M4S2); // FCC('M4S2')
  118. IF_EQUAL_RETURN(guid, MFVideoFormat_MJPG);
  119. IF_EQUAL_RETURN(guid, MFVideoFormat_MP43); // FCC('MP43')
  120. IF_EQUAL_RETURN(guid, MFVideoFormat_MP4S); // FCC('MP4S')
  121. IF_EQUAL_RETURN(guid, MFVideoFormat_MP4V); // FCC('MP4V')
  122. IF_EQUAL_RETURN(guid, MFVideoFormat_MPG1); // FCC('MPG1')
  123. IF_EQUAL_RETURN(guid, MFVideoFormat_MSS1); // FCC('MSS1')
  124. IF_EQUAL_RETURN(guid, MFVideoFormat_MSS2); // FCC('MSS2')
  125. IF_EQUAL_RETURN(guid, MFVideoFormat_NV11); // FCC('NV11')
  126. IF_EQUAL_RETURN(guid, MFVideoFormat_NV12); // FCC('NV12')
  127. IF_EQUAL_RETURN(guid, MFVideoFormat_P010); // FCC('P010')
  128. IF_EQUAL_RETURN(guid, MFVideoFormat_P016); // FCC('P016')
  129. IF_EQUAL_RETURN(guid, MFVideoFormat_P210); // FCC('P210')
  130. IF_EQUAL_RETURN(guid, MFVideoFormat_P216); // FCC('P216')
  131. IF_EQUAL_RETURN(guid, MFVideoFormat_RGB24); // D3DFMT_R8G8B8
  132. IF_EQUAL_RETURN(guid, MFVideoFormat_RGB32); // D3DFMT_X8R8G8B8
  133. IF_EQUAL_RETURN(guid, MFVideoFormat_RGB555); // D3DFMT_X1R5G5B5
  134. IF_EQUAL_RETURN(guid, MFVideoFormat_RGB565); // D3DFMT_R5G6B5
  135. IF_EQUAL_RETURN(guid, MFVideoFormat_RGB8);
  136. IF_EQUAL_RETURN(guid, MFVideoFormat_UYVY); // FCC('UYVY')
  137. IF_EQUAL_RETURN(guid, MFVideoFormat_v210); // FCC('v210')
  138. IF_EQUAL_RETURN(guid, MFVideoFormat_v410); // FCC('v410')
  139. IF_EQUAL_RETURN(guid, MFVideoFormat_WMV1); // FCC('WMV1')
  140. IF_EQUAL_RETURN(guid, MFVideoFormat_WMV2); // FCC('WMV2')
  141. IF_EQUAL_RETURN(guid, MFVideoFormat_WMV3); // FCC('WMV3')
  142. IF_EQUAL_RETURN(guid, MFVideoFormat_WVC1); // FCC('WVC1')
  143. IF_EQUAL_RETURN(guid, MFVideoFormat_Y210); // FCC('Y210')
  144. IF_EQUAL_RETURN(guid, MFVideoFormat_Y216); // FCC('Y216')
  145. IF_EQUAL_RETURN(guid, MFVideoFormat_Y410); // FCC('Y410')
  146. IF_EQUAL_RETURN(guid, MFVideoFormat_Y416); // FCC('Y416')
  147. IF_EQUAL_RETURN(guid, MFVideoFormat_Y41P);
  148. IF_EQUAL_RETURN(guid, MFVideoFormat_Y41T);
  149. IF_EQUAL_RETURN(guid, MFVideoFormat_YUY2); // FCC('YUY2')
  150. IF_EQUAL_RETURN(guid, MFVideoFormat_YV12); // FCC('YV12')
  151. IF_EQUAL_RETURN(guid, MFVideoFormat_YVYU);
  152. IF_EQUAL_RETURN(guid, MFAudioFormat_PCM); // WAVE_FORMAT_PCM
  153. IF_EQUAL_RETURN(guid, MFAudioFormat_Float); // WAVE_FORMAT_IEEE_FLOAT
  154. IF_EQUAL_RETURN(guid, MFAudioFormat_DTS); // WAVE_FORMAT_DTS
  155. IF_EQUAL_RETURN(guid, MFAudioFormat_Dolby_AC3_SPDIF); // WAVE_FORMAT_DOLBY_AC3_SPDIF
  156. IF_EQUAL_RETURN(guid, MFAudioFormat_DRM); // WAVE_FORMAT_DRM
  157. IF_EQUAL_RETURN(guid, MFAudioFormat_WMAudioV8); // WAVE_FORMAT_WMAUDIO2
  158. IF_EQUAL_RETURN(guid, MFAudioFormat_WMAudioV9); // WAVE_FORMAT_WMAUDIO3
  159. IF_EQUAL_RETURN(guid, MFAudioFormat_WMAudio_Lossless); // WAVE_FORMAT_WMAUDIO_LOSSLESS
  160. IF_EQUAL_RETURN(guid, MFAudioFormat_WMASPDIF); // WAVE_FORMAT_WMASPDIF
  161. IF_EQUAL_RETURN(guid, MFAudioFormat_MSP1); // WAVE_FORMAT_WMAVOICE9
  162. IF_EQUAL_RETURN(guid, MFAudioFormat_MP3); // WAVE_FORMAT_MPEGLAYER3
  163. IF_EQUAL_RETURN(guid, MFAudioFormat_MPEG); // WAVE_FORMAT_MPEG
  164. IF_EQUAL_RETURN(guid, MFAudioFormat_AAC); // WAVE_FORMAT_MPEG_HEAAC
  165. IF_EQUAL_RETURN(guid, MFAudioFormat_ADTS); // WAVE_FORMAT_MPEG_ADTS_AAC
  166. return NULL;
  167. }
  168. static float OffsetToFloat(const MFOffset& offset)
  169. {
  170. return offset.value + (static_cast<float>(offset.fract) / 65536.0f);
  171. }
  172. static HRESULT LogVideoArea(wstring &str, const PROPVARIANT& var)
  173. {
  174. if (var.caub.cElems < sizeof(MFVideoArea)) {
  175. return MF_E_BUFFERTOOSMALL;
  176. }
  177. MFVideoArea *pArea = (MFVideoArea*)var.caub.pElems;
  178. str += L"(";
  179. str += to_wstring(OffsetToFloat(pArea->OffsetX));
  180. str += L",";
  181. str += to_wstring(OffsetToFloat(pArea->OffsetY));
  182. str += L") (";
  183. str += to_wstring(pArea->Area.cx);
  184. str += L",";
  185. str += to_wstring(pArea->Area.cy);
  186. str += L")";
  187. return S_OK;
  188. }
  189. static HRESULT GetGUIDName(const GUID& guid, WCHAR **ppwsz)
  190. {
  191. HRESULT hr = S_OK;
  192. WCHAR *pName = NULL;
  193. LPCWSTR pcwsz = GetGUIDNameConst(guid);
  194. if (pcwsz) {
  195. size_t cchLength = 0;
  196. hr = StringCchLength(pcwsz, STRSAFE_MAX_CCH, &cchLength);
  197. if (FAILED(hr)) {
  198. goto done;
  199. }
  200. pName = (WCHAR*)CoTaskMemAlloc((cchLength + 1) * sizeof(WCHAR));
  201. if (pName == NULL) {
  202. hr = E_OUTOFMEMORY;
  203. goto done;
  204. }
  205. hr = StringCchCopy(pName, cchLength + 1, pcwsz);
  206. if (FAILED(hr)) {
  207. goto done;
  208. }
  209. } else {
  210. hr = StringFromCLSID(guid, &pName);
  211. }
  212. done:
  213. if (FAILED(hr)) {
  214. *ppwsz = NULL;
  215. CoTaskMemFree(pName);
  216. } else {
  217. *ppwsz = pName;
  218. }
  219. return hr;
  220. }
  221. static void LogUINT32AsUINT64(wstring &str, const PROPVARIANT& var)
  222. {
  223. UINT32 uHigh = 0, uLow = 0;
  224. Unpack2UINT32AsUINT64(var.uhVal.QuadPart, &uHigh, &uLow);
  225. str += to_wstring(uHigh);
  226. str += L" x ";
  227. str += to_wstring(uLow);
  228. }
  229. // Handle certain known special cases.
  230. static HRESULT SpecialCaseAttributeValue(wstring &str, GUID guid,
  231. const PROPVARIANT& var)
  232. {
  233. if ((guid == MF_MT_FRAME_RATE) || (guid == MF_MT_FRAME_RATE_RANGE_MAX) ||
  234. (guid == MF_MT_FRAME_RATE_RANGE_MIN) || (guid == MF_MT_FRAME_SIZE) ||
  235. (guid == MF_MT_PIXEL_ASPECT_RATIO)) {
  236. // Attributes that contain two packed 32-bit values.
  237. LogUINT32AsUINT64(str, var);
  238. } else if ((guid == MF_MT_GEOMETRIC_APERTURE) ||
  239. (guid == MF_MT_MINIMUM_DISPLAY_APERTURE) ||
  240. (guid == MF_MT_PAN_SCAN_APERTURE)) {
  241. // Attributes that an MFVideoArea structure.
  242. return LogVideoArea(str, var);
  243. } else {
  244. return S_FALSE;
  245. }
  246. return S_OK;
  247. }
  248. static HRESULT LogAttributeValueByIndex(IMFAttributes *pAttr, DWORD index)
  249. {
  250. wstring str;
  251. WCHAR *pGuidName = NULL;
  252. WCHAR *pGuidValName = NULL;
  253. GUID guid = { 0 };
  254. PROPVARIANT var;
  255. PropVariantInit(&var);
  256. HRESULT hr = pAttr->GetItemByIndex(index, &guid, &var);
  257. if (FAILED(hr)) {
  258. goto done;
  259. }
  260. hr = GetGUIDName(guid, &pGuidName);
  261. if (FAILED(hr)) {
  262. goto done;
  263. }
  264. str += L" ";
  265. str += pGuidName;
  266. str += L": ";
  267. hr = SpecialCaseAttributeValue(str, guid, var);
  268. if (FAILED(hr)) {
  269. goto done;
  270. }
  271. if (hr == S_FALSE) {
  272. switch (var.vt) {
  273. case VT_UI4:
  274. str += to_wstring(var.ulVal);
  275. break;
  276. case VT_UI8:
  277. str += to_wstring(var.uhVal.QuadPart);
  278. break;
  279. case VT_R8:
  280. str += to_wstring(var.dblVal);
  281. break;
  282. case VT_CLSID:
  283. hr = GetGUIDName(*var.puuid, &pGuidValName);
  284. if (SUCCEEDED(hr))
  285. {
  286. str += pGuidValName;
  287. }
  288. break;
  289. case VT_LPWSTR:
  290. str += var.pwszVal;
  291. break;
  292. case VT_VECTOR | VT_UI1:
  293. str += L"<<byte array>>";
  294. break;
  295. case VT_UNKNOWN:
  296. str += L"IUnknown";
  297. break;
  298. default:
  299. str += L"Unexpected attribute type (vt = ";
  300. str += to_wstring(var.vt);
  301. str += L")";
  302. break;
  303. }
  304. }
  305. DBGMSG(L"%s", str.c_str());
  306. done:
  307. CoTaskMemFree(pGuidName);
  308. CoTaskMemFree(pGuidValName);
  309. PropVariantClear(&var);
  310. return hr;
  311. }
  312. bool MF::LogMediaType(IMFMediaType *pType)
  313. {
  314. UINT32 count = 0;
  315. HRESULT hr = pType->GetCount(&count);
  316. if (FAILED(hr)) {
  317. return false;
  318. }
  319. if (count == 0) {
  320. DBGMSG(L"Empty media type.");
  321. }
  322. for (UINT32 i = 0; i < count; i++) {
  323. hr = LogAttributeValueByIndex(pType, i);
  324. if (FAILED(hr)) {
  325. return false;
  326. }
  327. }
  328. return true;
  329. }