mf-common.cpp 12 KB

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