MFTDecoder.cpp 9.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465
  1. #include "MFTDecoder.h"
  2. #include <Mfapi.h>
  3. #include <wmcodecdsp.h>
  4. #include <Mferror.h>
  5. //-----------------------------------------------------------------------------
  6. // GetDefaultStride
  7. //
  8. // Gets the default stride for a video frame, assuming no extra padding bytes.
  9. //
  10. //-----------------------------------------------------------------------------
  11. static HRESULT GetDefaultStride(IMFMediaType *pType, LONG *plStride)
  12. {
  13. LONG lStride = 0;
  14. // Try to get the default stride from the media type.
  15. HRESULT hr = pType->GetUINT32(MF_MT_DEFAULT_STRIDE, (UINT32*)&lStride);
  16. if (FAILED(hr))
  17. {
  18. // Attribute not set. Try to calculate the default stride.
  19. GUID subtype = GUID_NULL;
  20. UINT32 width = 0;
  21. UINT32 height = 0;
  22. // Get the subtype and the image size.
  23. hr = pType->GetGUID(MF_MT_SUBTYPE, &subtype);
  24. if (SUCCEEDED(hr))
  25. {
  26. hr = MFGetAttributeSize(pType, MF_MT_FRAME_SIZE, &width, &height);
  27. }
  28. if (SUCCEEDED(hr))
  29. {
  30. hr = MFGetStrideForBitmapInfoHeader(subtype.Data1, width, &lStride);
  31. }
  32. // Set the attribute for later reference.
  33. if (SUCCEEDED(hr))
  34. {
  35. (void)pType->SetUINT32(MF_MT_DEFAULT_STRIDE, UINT32(lStride));
  36. }
  37. }
  38. if (SUCCEEDED(hr))
  39. {
  40. *plStride = lStride;
  41. }
  42. return hr;
  43. }
  44. static HRESULT ConfigureOutput(IMFTransform *decoder, LONG *stride)
  45. {
  46. HRESULT hr = S_OK;
  47. IMFMediaType *media_type = 0;
  48. AM_MEDIA_TYPE *format = NULL;
  49. int index=0;
  50. while(SUCCEEDED(hr)) {
  51. hr = decoder->GetOutputAvailableType(0, index++, &media_type);
  52. if (FAILED(hr)) {
  53. break;
  54. }
  55. media_type->GetRepresentation(FORMAT_MFVideoFormat, (LPVOID*)&format);
  56. MFVIDEOFORMAT* z = (MFVIDEOFORMAT*)format->pbFormat;
  57. unsigned int surface_format = z->surfaceInfo.Format;
  58. media_type->FreeRepresentation(FORMAT_MFVideoFormat, (LPVOID)format);
  59. if (surface_format == '21VY') { // MFVideoFormat_YV12
  60. hr = GetDefaultStride(media_type, stride);
  61. hr = decoder->SetOutputType(0, media_type, 0);
  62. break;
  63. }
  64. }
  65. if(media_type) {
  66. media_type->Release();
  67. }
  68. return hr;
  69. }
  70. MFTDecoder::MFTDecoder()
  71. {
  72. decoder = 0;
  73. stride = 0;
  74. width = 0;
  75. height = 0;
  76. }
  77. MFTDecoder::~MFTDecoder()
  78. {
  79. if (decoder) {
  80. decoder->Release();
  81. }
  82. }
  83. static HRESULT CreateInputMediaType(IMFMediaType **_media_type, VIDEOINFOHEADER *header)
  84. {
  85. HRESULT hr=E_FAIL;
  86. IMFMediaType *media_type=0;
  87. do {
  88. hr = MFCreateMediaType(&media_type);
  89. if (FAILED(hr)) {
  90. break;
  91. }
  92. hr = MFInitMediaTypeFromVideoInfoHeader(media_type, header, 88);
  93. if (FAILED(hr)) {
  94. break;
  95. }
  96. if (FAILED(hr)) {
  97. break;
  98. }
  99. *_media_type = media_type;
  100. return S_OK;
  101. } while(0);
  102. if (media_type) {
  103. media_type->Release();
  104. }
  105. return hr;
  106. }
  107. HRESULT MFTDecoder::Open(VIDEOINFOHEADER *header)
  108. {
  109. HRESULT hr=E_FAIL;
  110. hr = CoCreateInstance(CLSID_CMpeg4sDecMFT, NULL, CLSCTX_INPROC_SERVER, __uuidof(IMFTransform), (void**)&decoder);
  111. if (FAILED(hr)) {
  112. return hr;
  113. }
  114. /* set input */
  115. IMFMediaType *media_type=0;
  116. hr = CreateInputMediaType(&media_type, header);
  117. if (FAILED(hr)) {
  118. return hr;
  119. }
  120. hr = decoder->SetInputType(0, media_type, 0);
  121. media_type->Release();
  122. if (FAILED(hr)) {
  123. return hr;
  124. }
  125. /* set output */
  126. ConfigureOutput(decoder, &stride);
  127. width=0;
  128. height=0;
  129. decoder->ProcessMessage(MFT_MESSAGE_NOTIFY_BEGIN_STREAMING, 0);
  130. decoder->ProcessMessage(MFT_MESSAGE_NOTIFY_START_OF_STREAM, 0);
  131. return S_OK;
  132. }
  133. HRESULT MFTDecoder::GetOutputFormat(UINT *width, UINT *height, bool *flip, double *aspect)
  134. {
  135. HRESULT hr=E_FAIL;
  136. IMFMediaType *media_type = 0;
  137. do {
  138. hr = decoder->GetOutputCurrentType(0, &media_type);
  139. if (FAILED(hr)) {
  140. break;
  141. }
  142. if (width && height) {
  143. hr = MFGetAttributeSize(media_type, MF_MT_FRAME_SIZE, width, height);
  144. if (FAILED(hr)) {
  145. break;
  146. }
  147. }
  148. if (flip) {
  149. LONG stride;
  150. hr = GetDefaultStride(media_type, &stride);
  151. if (FAILED(hr)) {
  152. break;
  153. }
  154. *flip = stride<0;
  155. }
  156. if (aspect) {
  157. MFRatio PAR = {0};
  158. hr = MFGetAttributeRatio(media_type, MF_MT_PIXEL_ASPECT_RATIO,
  159. (UINT32*)&PAR.Numerator,
  160. (UINT32*)&PAR.Denominator);
  161. if (FAILED(hr)) {
  162. *aspect = 1.0;
  163. } else {
  164. *aspect = (double)PAR.Numerator / (double)PAR.Denominator;
  165. }
  166. }
  167. } while(0);
  168. if (media_type) {
  169. media_type->Release();
  170. }
  171. return hr;
  172. }
  173. HRESULT MFTDecoder::Feed(const void *data, size_t data_size, uint64_t timestamp_hundred_nanos)
  174. {
  175. HRESULT hr=E_FAIL;
  176. IMFMediaBuffer *buffer = 0;
  177. BYTE *buffer_pointer = 0;
  178. IMFSample *sample = 0;
  179. do {
  180. hr = MFCreateMemoryBuffer((DWORD)data_size, &buffer);
  181. if (FAILED(hr)) {
  182. break;
  183. }
  184. hr = buffer->Lock(&buffer_pointer, NULL, NULL);
  185. if (FAILED(hr)) {
  186. break;
  187. }
  188. memcpy(buffer_pointer, data, data_size);
  189. hr = buffer->Unlock();
  190. if (FAILED(hr)) {
  191. break;
  192. }
  193. hr = buffer->SetCurrentLength((DWORD)data_size);
  194. if (FAILED(hr)) {
  195. break;
  196. }
  197. hr = MFCreateSample(&sample);
  198. if (FAILED(hr)) {
  199. break;
  200. }
  201. hr = sample->AddBuffer(buffer);
  202. if (FAILED(hr)) {
  203. break;
  204. }
  205. hr = sample->SetSampleTime(timestamp_hundred_nanos);
  206. if (FAILED(hr)) {
  207. break;
  208. }
  209. hr = decoder->ProcessInput(0, sample, 0);
  210. if (FAILED(hr)) {
  211. break;
  212. }
  213. } while(0);
  214. if (buffer) {
  215. buffer->Release();
  216. }
  217. if (sample) {
  218. sample->Release();
  219. }
  220. return hr;
  221. }
  222. static HRESULT CreateOutputSample(IMFTransform *decoder, IMFSample **_output_sample)
  223. {
  224. HRESULT hr=E_FAIL;
  225. MFT_OUTPUT_STREAM_INFO stream_info;
  226. IMFMediaBuffer *media_buffer = 0;
  227. IMFSample *sample = 0;
  228. do {
  229. hr = MFCreateSample(&sample);
  230. if (FAILED(hr)) {
  231. break;
  232. }
  233. hr = decoder->GetOutputStreamInfo(0, &stream_info);
  234. if (FAILED(hr)) {
  235. break;
  236. }
  237. hr = MFCreateAlignedMemoryBuffer(stream_info.cbSize, MF_16_BYTE_ALIGNMENT, &media_buffer);
  238. if (FAILED(hr)) {
  239. break;
  240. }
  241. hr = sample->AddBuffer(media_buffer);
  242. if (FAILED(hr)) {
  243. break;
  244. }
  245. if (media_buffer) {
  246. media_buffer->Release();
  247. }
  248. *_output_sample = sample;
  249. return S_OK;
  250. } while(0);
  251. if (sample) {
  252. sample->Release();
  253. }
  254. if (media_buffer) {
  255. media_buffer->Release();
  256. }
  257. return hr;
  258. }
  259. // Release the events that an MFT might allocate in IMFTransform::ProcessOutput().
  260. static void ReleaseEventCollection(MFT_OUTPUT_DATA_BUFFER &pBuffers)
  261. {
  262. if (pBuffers.pEvents) {
  263. pBuffers.pEvents->Release();
  264. pBuffers.pEvents = NULL;
  265. }
  266. }
  267. HRESULT MFTDecoder::GetFrame(IMFMediaBuffer **out_buffer, uint64_t *hundrednanos)
  268. {
  269. HRESULT hr=E_FAIL;
  270. IMFSample *output_sample=0;
  271. DWORD mftStatus;
  272. do {
  273. hr = CreateOutputSample(decoder, &output_sample);
  274. if (FAILED(hr)) {
  275. break;
  276. }
  277. MFT_OUTPUT_DATA_BUFFER mftDataBuffer = {0, };
  278. mftDataBuffer.pSample = output_sample;
  279. mftStatus = 0;
  280. hr = decoder->ProcessOutput(0, 1, &mftDataBuffer, &mftStatus);
  281. if (hr == MF_E_TRANSFORM_NEED_MORE_INPUT) {
  282. break;
  283. }
  284. if (hr == MF_E_TRANSFORM_STREAM_CHANGE) {
  285. ConfigureOutput(decoder, &stride);
  286. width=0;
  287. height=0;
  288. } else if (FAILED(hr)) {
  289. break;
  290. } else {
  291. if (mftDataBuffer.pSample) {
  292. IMFMediaBuffer *mediaBuffer;
  293. hr = mftDataBuffer.pSample->GetBufferByIndex(0, &mediaBuffer);
  294. if (FAILED(hr)) {
  295. break;
  296. }
  297. LONGLONG sample_time;
  298. output_sample->GetSampleTime(&sample_time);
  299. if (hundrednanos) {
  300. *hundrednanos = sample_time;
  301. }
  302. *out_buffer = mediaBuffer;
  303. }
  304. ReleaseEventCollection(mftDataBuffer);
  305. }
  306. } while (0);
  307. if (output_sample) {
  308. output_sample->Release();
  309. }
  310. return hr;
  311. }
  312. HRESULT MFTDecoder::Flush()
  313. {
  314. return decoder->ProcessMessage(MFT_MESSAGE_COMMAND_FLUSH, 0);
  315. }
  316. HRESULT MFTDecoder::Drain()
  317. {
  318. return decoder->ProcessMessage(MFT_MESSAGE_COMMAND_DRAIN, 0);
  319. }
  320. HRESULT MFTDecoder::GetFrame(YV12_PLANES **data, void **decoder_data, uint64_t *mft_timestamp)
  321. {
  322. HRESULT hr=E_FAIL;
  323. IMFMediaBuffer *media_buffer = 0;
  324. IMFMediaType *media_type = 0;
  325. do {
  326. if (!height || !stride) {
  327. hr = decoder->GetOutputCurrentType(0, &media_type);
  328. if (FAILED(hr)) {
  329. break;
  330. }
  331. hr = MFGetAttributeSize(media_type, MF_MT_FRAME_SIZE, &width, &height);
  332. if (FAILED(hr)) {
  333. break;
  334. }
  335. hr = GetDefaultStride(media_type, &stride);
  336. if (FAILED(hr)) {
  337. break;
  338. }
  339. }
  340. hr = this->GetFrame(&media_buffer, mft_timestamp);
  341. if (FAILED(hr)) {
  342. break;
  343. }
  344. YV12_PLANES *planes = (YV12_PLANES *)malloc(sizeof(YV12_PLANES));
  345. IMF2DBuffer *buffer2d=0;
  346. if (SUCCEEDED(media_buffer->QueryInterface(&buffer2d))) {
  347. BYTE *pbScanline0;
  348. LONG pitch;
  349. buffer2d->Lock2D(&pbScanline0, &pitch);
  350. planes->y.baseAddr = pbScanline0;
  351. planes->y.rowBytes = pitch;
  352. pbScanline0 += pitch * height;
  353. planes->v.baseAddr = pbScanline0;
  354. planes->v.rowBytes = pitch/2;
  355. pbScanline0 += pitch * height/4;
  356. planes->u.baseAddr = pbScanline0;
  357. planes->u.rowBytes = pitch/2;
  358. buffer2d->Release();
  359. } else {
  360. DWORD length, max_length;
  361. BYTE *video_data;
  362. media_buffer->Lock(&video_data, &length, &max_length);
  363. planes->y.baseAddr = video_data;
  364. planes->y.rowBytes = stride;
  365. video_data += stride * height;
  366. planes->v.baseAddr = video_data;
  367. planes->v.rowBytes = stride/2;
  368. video_data += (stride/2) * (height/2);
  369. planes->u.baseAddr = video_data;
  370. planes->u.rowBytes = stride/2;
  371. }
  372. *data = planes;
  373. *decoder_data = media_buffer;
  374. } while(0);
  375. if (media_type) {
  376. media_type->Release();
  377. }
  378. return hr;
  379. }
  380. HRESULT MFTDecoder::FreeFrame(YV12_PLANES *data, void *decoder_data)
  381. {
  382. IMFMediaBuffer *buffer= (IMFMediaBuffer *)decoder_data;
  383. if (buffer) {
  384. IMF2DBuffer *buffer2d=0;
  385. if (SUCCEEDED(buffer->QueryInterface(&buffer2d))) {
  386. buffer2d->Unlock2D();
  387. buffer2d->Release();
  388. } else {
  389. buffer->Unlock();
  390. }
  391. buffer->Release();
  392. }
  393. free(data);
  394. return S_OK;
  395. }