OutputStream.h 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169
  1. #ifndef NULLSOFT_OUTPUTSTREAMH
  2. #define NULLSOFT_OUTPUTSTREAMH
  3. #include <wmsdk.h>
  4. #define NULLSOFT_INTERFACE_BEGIN(RIID, OBJ) void **&NULLSOFT_interfaceHolder = OBJ; REFIID NULLSOFT_IID = RIID;
  5. #define NULLSOFT_VALID_INTERFACE(a) if (NULLSOFT_IID == IID_ ## a) { *NULLSOFT_interfaceHolder = static_cast<a *>(this); return S_OK; }
  6. #define NULLSOFT_INTERFACE_END() *NULLSOFT_interfaceHolder = 0; return E_NOINTERFACE;
  7. class OutputStream : public IWMOutputMediaProps
  8. {
  9. public:
  10. OutputStream(IWMMediaProps *props) : mediaType(0)
  11. {
  12. DWORD mediaTypeSize;
  13. props->GetMediaType(0, &mediaTypeSize);
  14. if (mediaTypeSize)
  15. {
  16. mediaType = (WM_MEDIA_TYPE *)new unsigned char[mediaTypeSize];
  17. props->GetMediaType(mediaType, &mediaTypeSize);
  18. }
  19. }
  20. ~OutputStream()
  21. {
  22. if (mediaType)
  23. {
  24. delete mediaType;
  25. mediaType = 0;
  26. }
  27. }
  28. GUID &GetSubType() const
  29. {
  30. return mediaType->subtype;
  31. }
  32. WM_MEDIA_TYPE *mediaType;
  33. HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void **ppvObject)
  34. {
  35. NULLSOFT_INTERFACE_BEGIN(riid, ppvObject)
  36. NULLSOFT_VALID_INTERFACE(IWMOutputMediaProps);
  37. NULLSOFT_VALID_INTERFACE(IWMMediaProps);
  38. NULLSOFT_INTERFACE_END()
  39. }
  40. ULONG STDMETHODCALLTYPE AddRef()
  41. {
  42. return 0;
  43. }
  44. ULONG STDMETHODCALLTYPE Release()
  45. {
  46. return 0;
  47. }
  48. HRESULT STDMETHODCALLTYPE GetType(GUID *pguidType)
  49. {
  50. if (!mediaType) return E_FAIL;
  51. *pguidType = mediaType->majortype;
  52. return S_OK;
  53. }
  54. HRESULT STDMETHODCALLTYPE GetMediaType(WM_MEDIA_TYPE *pType, DWORD *pcbType)
  55. {
  56. if (!mediaType) return E_FAIL;
  57. if (!pType)
  58. {
  59. if (!pcbType) return E_INVALIDARG;
  60. *pcbType = sizeof(WM_MEDIA_TYPE);
  61. }
  62. else
  63. {
  64. if (*pcbType < sizeof(WM_MEDIA_TYPE)) ASF_E_BUFFERTOOSMALL;
  65. memcpy(pType, mediaType, sizeof(WM_MEDIA_TYPE));
  66. }
  67. return S_OK;
  68. }
  69. HRESULT STDMETHODCALLTYPE SetMediaType(WM_MEDIA_TYPE *pType)
  70. {
  71. return E_NOTIMPL;
  72. }
  73. HRESULT STDMETHODCALLTYPE GetStreamGroupName(WCHAR *pwszName, WORD *pcchName)
  74. {
  75. return E_NOTIMPL;
  76. }
  77. HRESULT STDMETHODCALLTYPE GetConnectionName(WCHAR *pwszName, WORD *pcchName)
  78. {
  79. return E_NOTIMPL;
  80. }
  81. };
  82. #include <uuids.h>
  83. class VideoOutputStream : public OutputStream
  84. {
  85. public:
  86. VideoOutputStream(IWMMediaProps *props) : OutputStream(props)
  87. {}
  88. WMVIDEOINFOHEADER *VideoInfo() const
  89. {
  90. return (WMVIDEOINFOHEADER *)mediaType->pbFormat;
  91. }
  92. int SourceWidth() const
  93. {
  94. return VideoInfo()->rcSource.right - VideoInfo()->rcSource.left;
  95. }
  96. int DestinationWidth() const
  97. {
  98. return VideoInfo()->rcTarget.right - VideoInfo()->rcTarget.left;
  99. }
  100. int DestinationHeight() const
  101. {
  102. return VideoInfo()->rcTarget.bottom - VideoInfo()->rcTarget.top;
  103. }
  104. bool Flipped() const
  105. {
  106. BITMAPINFOHEADER &info = VideoInfo()->bmiHeader;
  107. if (info.biHeight < 0 || info.biCompression == 0)
  108. return true;
  109. else
  110. return false;
  111. }
  112. int bmiHeight()
  113. {
  114. return VideoInfo()->bmiHeader.biYPelsPerMeter;
  115. }
  116. int bmiWidth()
  117. {
  118. return VideoInfo()->bmiHeader.biXPelsPerMeter;
  119. }
  120. RGBQUAD *CreatePalette()
  121. {
  122. RGBQUAD *palette = (RGBQUAD *)calloc(1, 1024);
  123. BITMAPINFOHEADER &info = VideoInfo()->bmiHeader;
  124. memcpy(palette, (char *)(&info) + 40, info.biClrUsed * 4);
  125. return palette;
  126. }
  127. int FourCC() const
  128. {
  129. BITMAPINFOHEADER &info = VideoInfo()->bmiHeader;
  130. int fourcc = info.biCompression;
  131. if (fourcc == BI_RGB)
  132. {
  133. switch(info.biBitCount)
  134. {
  135. case 32:
  136. fourcc='23GR'; // RG32
  137. break;
  138. case 24:
  139. fourcc='42GR'; // RG24
  140. break;
  141. case 8:
  142. fourcc='8BGR'; // RGB8
  143. break;
  144. }
  145. } else if (fourcc == BI_BITFIELDS)
  146. fourcc = 0; // TODO: calc a CC that winamp likes
  147. return fourcc;
  148. }
  149. bool IsVideo() const
  150. {
  151. return !!(mediaType->formattype == WMFORMAT_VideoInfo);
  152. }
  153. };
  154. #endif