00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032 #include "stdafx.h"
00033 #include "abstractVideodecodeoutputpin.h"
00034
00035 AbstractVideoDecodeOutputPin::AbstractVideoDecodeOutputPin(AbstractVideoDecodeFilter* inParentFilter, CCritSec* inFilterLock, CHAR* inObjectName, LPCWSTR inPinDisplayName)
00036 : CBaseOutputPin(inObjectName, inParentFilter, inFilterLock, &mHR, inPinDisplayName),
00037 mParentFilter(inParentFilter)
00038 , mDataQueue(NULL)
00039 {
00040
00041 }
00042 AbstractVideoDecodeOutputPin::~AbstractVideoDecodeOutputPin(void)
00043 {
00044
00045
00046 delete mDataQueue;
00047 mDataQueue = NULL;
00048 }
00049
00050 STDMETHODIMP AbstractVideoDecodeOutputPin::NonDelegatingQueryInterface(REFIID riid, void **ppv) {
00051
00052 if (riid == IID_IMediaSeeking) {
00053 *ppv = (IMediaSeeking*)this;
00054 ((IUnknown*)*ppv)->AddRef();
00055 return NOERROR;
00056 }
00057
00058 return CBaseOutputPin::NonDelegatingQueryInterface(riid, ppv);
00059 }
00060 HRESULT AbstractVideoDecodeOutputPin::DecideBufferSize(IMemAllocator* inAllocator, ALLOCATOR_PROPERTIES* inPropertyRequest) {
00061
00062
00063
00064
00065
00066
00067
00068
00069 HRESULT locHR = S_OK;
00070
00071
00072 ALLOCATOR_PROPERTIES locReqAlloc;
00073 ALLOCATOR_PROPERTIES locActualAlloc;
00074
00075
00076
00077
00078
00079
00080
00081
00082 const unsigned long MIN_BUFFER_SIZE = 16*16;
00083 const unsigned long DEFAULT_BUFFER_SIZE = 1024*1024;
00084 const unsigned long MIN_NUM_BUFFERS = 1;
00085 const unsigned long DEFAULT_NUM_BUFFERS = 1;
00086
00087
00088
00089
00090 if (inPropertyRequest->cbAlign <= 0) {
00091 locReqAlloc.cbAlign = 1;
00092 } else {
00093 locReqAlloc.cbAlign = inPropertyRequest->cbAlign;
00094 }
00095
00096
00097 if (inPropertyRequest->cbBuffer < MIN_BUFFER_SIZE) {
00098 locReqAlloc.cbBuffer = DEFAULT_BUFFER_SIZE;
00099 } else {
00100 locReqAlloc.cbBuffer = inPropertyRequest->cbBuffer;
00101 }
00102
00103
00104 if (inPropertyRequest->cbPrefix < 0) {
00105 locReqAlloc.cbPrefix = 0;
00106 } else {
00107 locReqAlloc.cbPrefix = inPropertyRequest->cbPrefix;
00108 }
00109
00110
00111 if (inPropertyRequest->cBuffers < MIN_NUM_BUFFERS) {
00112 locReqAlloc.cBuffers = DEFAULT_NUM_BUFFERS;
00113 } else {
00114
00115 locReqAlloc.cBuffers = inPropertyRequest->cBuffers;
00116 }
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126 locHR = inAllocator->SetProperties(&locReqAlloc, &locActualAlloc);
00127
00128
00129
00130
00131
00132
00133
00134
00135
00136 switch (locHR) {
00137 case E_POINTER:
00138
00139 return locHR;
00140
00141
00142 case VFW_E_ALREADY_COMMITTED:
00143
00144 return locHR;
00145
00146 case VFW_E_BADALIGN:
00147
00148 return locHR;
00149
00150 case VFW_E_BUFFERS_OUTSTANDING:
00151
00152 return locHR;
00153
00154
00155 case S_OK:
00156
00157 break;
00158 default:
00159
00160 break;
00161
00162 }
00163
00164
00165
00166
00167
00168 locHR = inAllocator->Commit();
00169
00170
00171
00172 switch (locHR) {
00173 case E_FAIL:
00174
00175 return locHR;
00176 case E_POINTER:
00177
00178 return locHR;
00179 case E_INVALIDARG:
00180
00181 return locHR;
00182 case E_NOTIMPL:
00183
00184 return locHR;
00185 case S_OK:
00186
00187 break;
00188 default:
00189
00190 return locHR;
00191 }
00192
00193
00194 return S_OK;
00195 }
00196 HRESULT AbstractVideoDecodeOutputPin::CheckMediaType(const CMediaType *inMediaType) {
00197
00198 if ((inMediaType->majortype == MEDIATYPE_Video) && (inMediaType->subtype == MEDIASUBTYPE_YV12) && (inMediaType->formattype == FORMAT_VideoInfo)) {
00199
00200
00201
00202
00203
00204 VIDEOINFOHEADER* locVideoHeader = (VIDEOINFOHEADER*)inMediaType->Format();
00205
00206
00207
00208
00209
00210
00211 mParentFilter->mInputPin->mHeight = (unsigned long)abs(locVideoHeader->bmiHeader.biHeight);
00212 mParentFilter->mInputPin->mWidth = (unsigned long)abs(locVideoHeader->bmiHeader.biWidth);
00213 mParentFilter->mInputPin->mFrameSize = (unsigned long)locVideoHeader->bmiHeader.biSizeImage;
00214
00215
00216 return S_OK;
00217 } else {
00218
00219 return S_FALSE;
00220 }
00221
00222 }
00223
00224 void AbstractVideoDecodeOutputPin::FillMediaType(CMediaType* outMediaType) {
00225 outMediaType->SetType(&MEDIATYPE_Video);
00226 outMediaType->SetSubtype(&MEDIASUBTYPE_YV12);
00227 outMediaType->SetFormatType(&FORMAT_VideoInfo);
00228 outMediaType->SetTemporalCompression(FALSE);
00229 outMediaType->SetSampleSize(0);
00230
00231 }
00232 HRESULT AbstractVideoDecodeOutputPin::GetMediaType(int inPosition, CMediaType *outMediaType) {
00233
00234 if (inPosition < 0) {
00235 return E_INVALIDARG;
00236 }
00237
00238 if (inPosition == 0) {
00239 FillMediaType(outMediaType);
00240 VIDEOINFOHEADER* locVideoFormat = (VIDEOINFOHEADER*)outMediaType->AllocFormatBuffer(sizeof(VIDEOINFOHEADER));
00241 FillVideoInfoHeader(locVideoFormat);
00242
00243
00244 outMediaType->SetSampleSize(locVideoFormat->bmiHeader.biSizeImage);
00245
00246 return S_OK;
00247 } else {
00248 return VFW_S_NO_MORE_ITEMS;
00249 }
00250 }
00251
00252
00253
00254 HRESULT AbstractVideoDecodeOutputPin::DeliverNewSegment(REFERENCE_TIME tStart, REFERENCE_TIME tStop, double dRate)
00255 {
00256
00257
00258 CBasePin::NewSegment(tStart, tStop, dRate);
00259 mDataQueue->NewSegment(tStart, tStop, dRate);
00260
00261
00262 return S_OK;
00263 }
00264 HRESULT AbstractVideoDecodeOutputPin::DeliverEndOfStream(void)
00265 {
00266
00267
00268 mDataQueue->EOS();
00269 return S_OK;
00270 }
00271
00272 HRESULT AbstractVideoDecodeOutputPin::DeliverEndFlush(void)
00273 {
00274
00275 mDataQueue->EndFlush();
00276 return S_OK;
00277 }
00278
00279 HRESULT AbstractVideoDecodeOutputPin::DeliverBeginFlush(void)
00280 {
00281
00282
00283 mDataQueue->BeginFlush();
00284 return S_OK;
00285 }
00286
00287 HRESULT AbstractVideoDecodeOutputPin::CompleteConnect (IPin *inReceivePin)
00288 {
00289
00290 HRESULT locHR = S_OK;
00291
00292
00293
00294
00295 IMediaSeeking* locSeeker = NULL;
00296 mParentFilter->mInputPin->NonDelegatingQueryInterface(IID_IMediaSeeking, (void**)&locSeeker);
00297 SetDelegate(locSeeker);
00298
00299
00300
00301 mDataQueue = new COutputQueue (inReceivePin, &locHR, FALSE, TRUE, 1, TRUE, 15);
00302 if (FAILED(locHR)) {
00303
00304 locHR = locHR;
00305 }
00306
00307 return CBaseOutputPin::CompleteConnect(inReceivePin);
00308 }
00309
00310 HRESULT AbstractVideoDecodeOutputPin::BreakConnect(void) {
00311
00312
00313 HRESULT locHR = CBaseOutputPin::BreakConnect();
00314
00315 ReleaseDelegate();
00316 delete mDataQueue;
00317 mDataQueue = NULL;
00318 return locHR;
00319 }
00320
00321
00322 HRESULT AbstractVideoDecodeOutputPin::InitAllocator(IMemAllocator **ppAlloc) {
00323
00324 HRESULT locHR = CBaseOutputPin::InitAllocator(ppAlloc);
00325
00326 return locHR;
00327 }
00328
00329 HRESULT AbstractVideoDecodeOutputPin::SetMediaType(const CMediaType *pmt) {
00330
00331 HRESULT locHR = CBaseOutputPin::SetMediaType(pmt);
00332
00333 return locHR;
00334 }