00001
00034 #include "YUV420ToRGBFilter.h"
00035
00036
00037 #include <DirectShow/CustomMediaTypes.h>
00038
00039
00040 #include <Image/RealYUV420toRGB24Converter.h>
00041
00042 YUV420toRGBFilter::YUV420toRGBFilter()
00043 : CCustomBaseFilter(NAME("Meraka RTVC YUV420P 2 RGB Converter"), 0, CLSID_YUV420toRGBColorConverter),
00044 m_pConverter(NULL),
00045 m_nSizeUV(0)
00046 {
00047
00048 InitialiseInputTypes();
00049 m_pConverter = new RealYUV420toRGB24Converter(m_nInWidth, m_nInHeight);
00050 }
00051
00052 YUV420toRGBFilter::~YUV420toRGBFilter()
00053 {
00054 if (m_pConverter)
00055 {
00056 delete m_pConverter;
00057 m_pConverter = NULL;
00058 }
00059 }
00060
00061 CUnknown * WINAPI YUV420toRGBFilter::CreateInstance( LPUNKNOWN pUnk, HRESULT *pHr )
00062 {
00063 YUV420toRGBFilter *pFilter = new YUV420toRGBFilter();
00064 if (pFilter== NULL)
00065 {
00066 *pHr = E_OUTOFMEMORY;
00067 }
00068 return pFilter;
00069 }
00070
00071
00072 void YUV420toRGBFilter::InitialiseInputTypes()
00073 {
00074 AddInputType(&MEDIATYPE_Video, &MEDIASUBTYPE_YUV420P, &FORMAT_VideoInfo);
00075 }
00076
00077
00078 HRESULT YUV420toRGBFilter::SetMediaType( PIN_DIRECTION direction, const CMediaType *pmt )
00079 {
00080 HRESULT hr = CCustomBaseFilter::SetMediaType(direction, pmt);
00081 if (direction == PINDIR_INPUT)
00082 {
00083 m_nSizeUV = m_nInPixels >> 2;
00084 m_pConverter->SetDimensions(m_nInWidth, m_nInHeight);
00085 }
00086 return hr;
00087 }
00088
00089 HRESULT YUV420toRGBFilter::GetMediaType( int iPosition, CMediaType *pMediaType )
00090 {
00091 if (iPosition < 0)
00092 {
00093 return E_INVALIDARG;
00094 }
00095 else if (iPosition == 0)
00096 {
00097
00098
00099 HRESULT hr = m_pInput->ConnectionMediaType(pMediaType);
00100 if (FAILED(hr))
00101 {
00102 return hr;
00103 }
00104
00105
00106 BITMAPINFOHEADER *pbmi = HEADER(pMediaType->pbFormat);
00107 if (pbmi->biBitCount == 32)
00108 {
00109
00110
00111 pbmi->biBitCount = 24;
00112 pbmi->biSizeImage = m_nInPixels * BYTES_PER_PIXEL_RGB24;
00113 }
00114 else if (pbmi->biBitCount == 24)
00115 {
00116
00117
00118 pbmi->biSizeImage = m_nInPixels * BYTES_PER_PIXEL_RGB24;
00119 }
00120
00121
00122 pMediaType->SetSubtype(&MEDIASUBTYPE_RGB24);
00123 return S_OK;
00124 }
00125 return VFW_S_NO_MORE_ITEMS;
00126 }
00127
00128 HRESULT YUV420toRGBFilter::DecideBufferSize( IMemAllocator *pAlloc, ALLOCATOR_PROPERTIES *pProp )
00129 {
00130 AM_MEDIA_TYPE mt;
00131 HRESULT hr = m_pOutput->ConnectionMediaType(&mt);
00132 if (FAILED(hr))
00133 {
00134 return hr;
00135 }
00136
00137 ASSERT(mt.formattype == FORMAT_VideoInfo);
00138 BITMAPINFOHEADER *pbmi = HEADER(mt.pbFormat);
00139 pProp->cbBuffer = DIBSIZE(*pbmi);
00140
00141 if (pProp->cbAlign == 0)
00142 {
00143 pProp->cbAlign = 1;
00144 }
00145 if (pProp->cBuffers == 0)
00146 {
00147 pProp->cBuffers = 1;
00148 }
00149
00150 FreeMediaType(mt);
00151
00152
00153 ALLOCATOR_PROPERTIES Actual;
00154 hr = pAlloc->SetProperties(pProp, &Actual);
00155 if (FAILED(hr))
00156 {
00157 return hr;
00158 }
00159
00160 if (pProp->cbBuffer > Actual.cbBuffer)
00161 {
00162 return E_FAIL;
00163 }
00164 return S_OK;
00165 }
00166
00167 DWORD YUV420toRGBFilter::ApplyTransform( BYTE* pBufferIn, BYTE* pBufferOut )
00168 {
00169 int nRet = 0;
00170 if (m_pConverter)
00171 {
00172 yuvType* pYUV = NULL;
00173 pYUV = (yuvType*)pBufferIn;
00174 if (pYUV)
00175 {
00176
00177 yuvType* pY = pYUV;
00178 yuvType* pU = pYUV + m_nInPixels;
00179 yuvType* pV = pYUV + m_nInPixels + m_nSizeUV;
00180
00181 m_pConverter->Convert((void*)pY, (void*)pU, (void*)pV, (void*)pBufferOut);
00182 DbgLog((LOG_TRACE, 0, TEXT("Converted from YUV420 to RGB Directly")));
00183
00184 nRet = m_nInPixels * BYTES_PER_PIXEL_RGB24;
00185 }
00186 }
00187 return nRet;
00188 }
00189
00190 HRESULT YUV420toRGBFilter::CheckTransform( const CMediaType *mtIn, const CMediaType *mtOut )
00191 {
00192
00193 long lSize = mtOut->GetSampleSize();
00194
00195
00196 if (mtOut->majortype != MEDIATYPE_Video)
00197 {
00198 return VFW_E_TYPE_NOT_ACCEPTED;
00199 }
00200 if (mtOut->subtype != MEDIASUBTYPE_RGB24)
00201 {
00202 return VFW_E_TYPE_NOT_ACCEPTED;
00203 }
00204 if (mtOut->formattype != FORMAT_VideoInfo)
00205 {
00206 return VFW_E_TYPE_NOT_ACCEPTED;
00207 }
00208
00209 return S_OK;
00210 }