DiracSplitter.cpp

00001 /* 
00002  *      Copyright (C) 2003-2005 Gabest
00003  *      http://www.gabest.org
00004  *
00005  *  This Program is free software; you can redistribute it and/or modify
00006  *  it under the terms of the GNU General Public License as published by
00007  *  the Free Software Foundation; either version 2, or (at your option)
00008  *  any later version.
00009  *   
00010  *  This Program is distributed in the hope that it will be useful,
00011  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00012  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
00013  *  GNU General Public License for more details.
00014  *   
00015  *  You should have received a copy of the GNU General Public License
00016  *  along with GNU Make; see the file COPYING.  If not, write to
00017  *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. 
00018  *  http://www.gnu.org/copyleft/gpl.html
00019  *
00020  */
00021 
00022 #include "StdAfx.h"
00023 #include <mmreg.h>
00024 #include <initguid.h>
00025 #include "DiracSplitter.h"
00026 #include "..\..\..\..\include\moreuuids.h"
00027 
00028 #ifdef REGISTER_FILTER
00029 
00030 const AMOVIESETUP_MEDIATYPE sudPinTypesIn[] =
00031 {       
00032         {&MEDIATYPE_Stream, &MEDIASUBTYPE_Dirac},
00033         {&MEDIATYPE_Stream, &MEDIASUBTYPE_NULL}
00034 };
00035 
00036 const AMOVIESETUP_PIN sudpPins[] =
00037 {
00038         {L"Input", FALSE, FALSE, FALSE, FALSE, &CLSID_NULL, NULL, countof(sudPinTypesIn), sudPinTypesIn},
00039         {L"Output", FALSE, TRUE, FALSE, FALSE, &CLSID_NULL, NULL, 0, NULL}
00040 };
00041 
00042 const AMOVIESETUP_MEDIATYPE sudPinTypesIn2[] =
00043 {
00044         {&MEDIATYPE_Video, &MEDIASUBTYPE_DiracVideo},
00045 };
00046 
00047 const AMOVIESETUP_MEDIATYPE sudPinTypesOut2[] =
00048 {
00049         {&MEDIATYPE_Video, &MEDIASUBTYPE_NULL},
00050 };
00051 
00052 const AMOVIESETUP_PIN sudpPins2[] =
00053 {
00054     {L"Input", FALSE, FALSE, FALSE, FALSE, &CLSID_NULL, NULL, countof(sudPinTypesIn2), sudPinTypesIn2},
00055     {L"Output", FALSE, TRUE, FALSE, FALSE, &CLSID_NULL, NULL, countof(sudPinTypesOut2), sudPinTypesOut2}
00056 };
00057 
00058 const AMOVIESETUP_FILTER sudFilter[] =
00059 {
00060         {&__uuidof(CDiracSplitterFilter), L"Dirac Splitter", MERIT_NORMAL, countof(sudpPins), sudpPins},
00061         {&__uuidof(CDiracSourceFilter), L"Dirac Source", MERIT_NORMAL, 0, NULL},
00062         {&__uuidof(CDiracVideoDecoder), L"Dirac Video Decoder", MERIT_UNLIKELY, countof(sudpPins2), sudpPins2},
00063 };
00064 
00065 CFactoryTemplate g_Templates[] =
00066 {
00067         {sudFilter[0].strName, sudFilter[0].clsID, CreateInstance<CDiracSplitterFilter>, NULL, &sudFilter[0]},
00068         {sudFilter[1].strName, sudFilter[1].clsID, CreateInstance<CDiracSourceFilter>, NULL, &sudFilter[1]},
00069     {sudFilter[2].strName, sudFilter[2].clsID, CreateInstance<CDiracVideoDecoder>, NULL, &sudFilter[2]},
00070 };
00071 
00072 int g_cTemplates = countof(g_Templates);
00073 
00074 STDAPI DllRegisterServer()
00075 {
00076         RegisterSourceFilter(
00077                 CLSID_AsyncReader, 
00078                 MEDIASUBTYPE_Dirac, 
00079                 _T("0,8,,4B572D4449524143"), // KW-DIRAC
00080                 _T(".drc"), NULL);
00081 
00082         return AMovieDllRegisterServer2(TRUE);
00083 }
00084 
00085 STDAPI DllUnregisterServer()
00086 {
00087         UnRegisterSourceFilter(MEDIASUBTYPE_Dirac);
00088 
00089         return AMovieDllRegisterServer2(FALSE);
00090 }
00091 
00092 extern "C" BOOL WINAPI DllEntryPoint(HINSTANCE, ULONG, LPVOID);
00093 
00094 BOOL APIENTRY DllMain(HANDLE hModule, DWORD dwReason, LPVOID lpReserved)
00095 {
00096         return DllEntryPoint((HINSTANCE)hModule, dwReason, 0); // "DllMain" of the dshow baseclasses;
00097 }
00098 
00099 #endif
00100 
00101 //
00102 // CDiracSplitterFilter
00103 //
00104 
00105 CDiracSplitterFilter::CDiracSplitterFilter(LPUNKNOWN pUnk, HRESULT* phr)
00106         : CBaseSplitterFilter(NAME("CDiracSplitterFilter"), pUnk, phr, __uuidof(this))
00107 {
00108 }
00109 
00110 STDMETHODIMP CDiracSplitterFilter::NonDelegatingQueryInterface(REFIID riid, void** ppv)
00111 {
00112     CheckPointer(ppv, E_POINTER);
00113 
00114     return 
00115                 __super::NonDelegatingQueryInterface(riid, ppv);
00116 }
00117 
00118 HRESULT CDiracSplitterFilter::CreateOutputs(IAsyncReader* pAsyncReader)
00119 {
00120         CheckPointer(pAsyncReader, E_POINTER);
00121 
00122         HRESULT hr = E_FAIL;
00123 
00124         m_pFile.Free();
00125 
00126         m_pFile.Attach(new CDiracSplitterFile(pAsyncReader, hr));
00127         if(!m_pFile) return E_OUTOFMEMORY;
00128         if(FAILED(hr)) {m_pFile.Free(); return hr;}
00129 
00130         CArray<CMediaType> mts;
00131         mts.Add(m_pFile->GetMediaType());
00132 
00133         CAutoPtr<CBaseSplitterOutputPin> pPinOut(new CBaseSplitterOutputPin(mts, L"Video", this, this, &hr));
00134         AddOutputPin(0, pPinOut);
00135 
00136         m_rtNewStart = m_rtCurrent = 0;
00137         m_rtNewStop = m_rtStop = m_rtDuration = m_pFile->GetDuration();
00138 
00139         return m_pOutputs.GetCount() > 0 ? S_OK : E_FAIL;
00140 }
00141 
00142 bool CDiracSplitterFilter::DemuxInit()
00143 {
00144         if(!m_pFile) return(false);
00145 
00146         // TODO
00147 
00148         return(true);
00149 }
00150 
00151 void CDiracSplitterFilter::DemuxSeek(REFERENCE_TIME rt)
00152 {
00153         REFERENCE_TIME rtPreroll = 0; //10000000;
00154 
00155         if(rt <= rtPreroll || m_rtDuration <= 0)
00156         {
00157                 m_pFile->Seek(8);
00158         }
00159         else
00160         {
00161                 // TODO
00162 
00163                 __int64 len = m_pFile->GetLength();
00164                 __int64 seekpos = (__int64)(1.0*rt/m_rtDuration*len);
00165 
00166                 m_pFile->Seek(seekpos);
00167                 seekpos = 8;
00168 
00169                 REFERENCE_TIME rtmax = rt - rtPreroll;
00170                 REFERENCE_TIME rtmin = rtmax - 5000000;
00171 
00172                 REFERENCE_TIME pdt = _I64_MIN;
00173 
00174                 for(int j = 0; j < 10; j++)
00175                 {
00176                         BYTE code = NOT_START_CODE;
00177                         while(m_pFile->Next(code) && code != IFRAME_START_CODE);
00178                         if(code != IFRAME_START_CODE) {m_pFile->Seek(seekpos >>= 1); continue;}
00179 
00180                         __int64 pos = m_pFile->GetPos() - 5;
00181 
00182                         REFERENCE_TIME rt = ((DIRACINFOHEADER*)m_pFile->GetMediaType().Format())->hdr.AvgTimePerFrame * m_pFile->UnsignedGolombDecode();
00183                         REFERENCE_TIME dt = rt - rtmax;
00184                         if(dt > 0 && dt == pdt) dt = 10000000i64;
00185 
00186                         if(rtmin <= rt && rt <= rtmax || pdt > 0 && dt < 0)
00187                         {
00188                                 seekpos = pos;
00189                                 break;
00190                         }
00191 
00192                         m_pFile->Seek(pos - (__int64)(1.0*dt/m_rtDuration*len));
00193 
00194                         pdt = dt;
00195                 }
00196 
00197                 m_pFile->Seek(seekpos);
00198         }
00199 }
00200 
00201 bool CDiracSplitterFilter::DemuxLoop()
00202 {
00203         HRESULT hr = S_OK;
00204         REFERENCE_TIME rtAvgTimePerFrame = ((DIRACINFOHEADER*)m_pFile->GetMediaType().Format())->hdr.AvgTimePerFrame;
00205 
00206         while(SUCCEEDED(hr) && !CheckRequest(NULL))
00207         {
00208                 BYTE code = NOT_START_CODE;
00209                 int size = 0, fnum = 0;
00210                 const BYTE* pBuff = m_pFile->NextBlock(code, size, fnum);
00211                 if(!pBuff || size < 5) break;
00212 
00213                 if(isFrameStartCode(code))
00214                 {
00215                         CAutoPtr<Packet> p(new Packet());
00216                         p->pData.SetSize(size);
00217                         memcpy(p->pData.GetData(), pBuff, size);
00218 
00219                         p->TrackNumber = 0;
00220                         p->rtStart = rtAvgTimePerFrame*fnum;
00221                         p->rtStop = p->rtStart + rtAvgTimePerFrame;
00222                         p->bSyncPoint = code == IFRAME_START_CODE;
00223 
00224                         hr = DeliverPacket(p);
00225                 }
00226 
00227                 if(code == SEQ_END_CODE)
00228                         break;
00229         }
00230 
00231         return(true);
00232 }
00233 
00234 //
00235 // CDiracSourceFilter
00236 //
00237 
00238 CDiracSourceFilter::CDiracSourceFilter(LPUNKNOWN pUnk, HRESULT* phr)
00239         : CDiracSplitterFilter(pUnk, phr)
00240 {
00241         m_clsid = __uuidof(this);
00242         m_pInput.Free();
00243 }
00244 
00245 //
00246 // CDiracVideoDecoder
00247 //
00248 
00249 CDiracVideoDecoder::CDiracVideoDecoder(LPUNKNOWN lpunk, HRESULT* phr)
00250         : CTransformFilter(NAME("CDiracVideoDecoder"), lpunk, __uuidof(this))
00251 {
00252         if(phr) *phr = S_OK;
00253 
00254         m_decoder = NULL;
00255         m_pYUV[0] = NULL;
00256 }
00257 
00258 CDiracVideoDecoder::~CDiracVideoDecoder()
00259 {
00260         delete [] m_pYUV[0];
00261 }
00262 
00263 void CDiracVideoDecoder::InitDecoder()
00264 {
00265         FreeDecoder();
00266 
00267         dirac_decoder_t* decoder = dirac_decoder_init(0);
00268 
00269         DIRACINFOHEADER* dvih = (DIRACINFOHEADER*)m_pInput->CurrentMediaType().Format();
00270         dirac_buffer(decoder, (BYTE*)&dvih->dwSequenceHeader[0], (BYTE*)&dvih->dwSequenceHeader[0] + dvih->cbSequenceHeader);
00271 
00272         m_decoder = decoder;
00273 }
00274 
00275 void CDiracVideoDecoder::FreeDecoder()
00276 {
00277         if(m_decoder)
00278         {
00279                 dirac_decoder_close((dirac_decoder_t*)m_decoder);
00280                 m_decoder = NULL;
00281                 delete [] m_pYUV[0]; m_pYUV[0] = NULL;
00282         }
00283 }
00284 
00285 HRESULT CDiracVideoDecoder::Receive(IMediaSample* pIn)
00286 {
00287         CAutoLock cAutoLock(&m_csReceive);
00288 
00289         HRESULT hr;
00290 
00291     AM_SAMPLE2_PROPERTIES* const pProps = m_pInput->SampleProps();
00292     if(pProps->dwStreamId != AM_STREAM_MEDIA)
00293                 return m_pOutput->Deliver(pIn);
00294 
00295         BYTE* pDataIn = NULL;
00296         if(FAILED(hr = pIn->GetPointer(&pDataIn))) return hr;
00297 
00298         long len = pIn->GetActualDataLength();
00299         if(len <= 0) return S_OK; // nothing to do
00300 
00301         if(pIn->IsDiscontinuity() == S_OK) 
00302                 InitDecoder();
00303 
00304         dirac_decoder_t* decoder = (dirac_decoder_t*)m_decoder;
00305 
00306         hr = S_OK;
00307         while(SUCCEEDED(hr))
00308         {
00309         switch(dirac_parse(decoder))
00310         {
00311         case STATE_BUFFER:
00312                         if(len == 0) return S_OK;
00313                         dirac_buffer(decoder, pDataIn, pDataIn + len);
00314                         len = 0;
00315                         break;
00316 
00317         case STATE_SEQUENCE:
00318                         TRACE(_T("STATE_SEQUENCE\n"));
00319 
00320                         {
00321                                 DIRACINFOHEADER* dvih = (DIRACINFOHEADER*)m_pInput->CurrentMediaType().Format();
00322                                 if(dvih->hdr.bmiHeader.biWidth != decoder->seq_params.width
00323                                 || dvih->hdr.bmiHeader.biHeight != decoder->seq_params.height)
00324                                         return E_FAIL; // hmm
00325                         }
00326 
00327                         if(!m_pYUV[0])
00328                         {
00329                                 int w = decoder->seq_params.width;
00330                                 int h = decoder->seq_params.height;
00331                                 int wc = decoder->seq_params.chroma_width;
00332                                 int hc = decoder->seq_params.chroma_height; 
00333                                 delete [] m_pYUV[0]; m_pYUV[0] = NULL;
00334                                 m_pYUV[0] = new BYTE[w*h + wc*hc*2 + w/2*h/2];
00335                                 m_pYUV[1] = m_pYUV[0] + w*h;
00336                                 m_pYUV[2] = m_pYUV[1] + wc*hc;
00337                                 m_pYUV[3] = m_pYUV[2] + wc*hc;
00338                                 memset(m_pYUV[3], 0x80, w/2*h/2);
00339                                 m_rtAvgTimePerFrame = 10000000i64 * decoder->seq_params.frame_rate.denominator / decoder->seq_params.frame_rate.numerator;
00340                                 dirac_set_buf(decoder, m_pYUV, NULL);
00341                         }
00342 
00343                         break;
00344 
00345         case STATE_SEQUENCE_END:
00346                         TRACE(_T("STATE_SEQUENCE_END\n"));
00347             break;
00348 
00349         case STATE_PICTURE_START:
00350                         TRACE(_T("STATE_PICTURE_START, frame_type=%d frame_num=%d\n"), decoder->frame_params.ftype, decoder->frame_params.fnum);
00351                         dirac_skip(decoder, (m_fDropFrames || decoder->frame_params.fnum * m_rtAvgTimePerFrame < m_tStart) && decoder->frame_params.ftype == L2_frame ? 1 : 0);
00352                         if(m_fDropFrames && decoder->frame_params.ftype == L2_frame) return S_OK;
00353             break;
00354 
00355         case STATE_PICTURE_AVAIL:
00356                         TRACE(_T("STATE_PICTURE_AVAIL, frame_type=%d frame_num=%d\n"), decoder->frame_params.ftype, decoder->frame_params.fnum);
00357                         hr = Deliver(pIn, decoder->frame_params.fnum * m_rtAvgTimePerFrame - m_tStart, (decoder->frame_params.fnum + 1) * m_rtAvgTimePerFrame - m_tStart);
00358                         break;
00359 
00360         case STATE_INVALID:
00361                         TRACE(_T("STATE_INVALID\n"));
00362                         return E_FAIL; // TODO: can we recover from this state?
00363                         // break;
00364 
00365         default:
00366                         TRACE(_T("unknown state\n"));
00367             continue;
00368         }
00369     }
00370 
00371         return hr;
00372 }
00373 
00374 HRESULT CDiracVideoDecoder::Deliver(IMediaSample* pIn, REFERENCE_TIME rtStart, REFERENCE_TIME rtStop)
00375 {
00376         CheckPointer(pIn, E_POINTER);
00377 
00378         HRESULT hr;
00379 
00380         if(pIn->IsPreroll() == S_OK || rtStart < 0)
00381                 return S_OK;
00382 
00383     CComPtr<IMediaSample> pOut;
00384         BYTE* pDataOut = NULL;
00385         if(FAILED(hr = m_pOutput->GetDeliveryBuffer(&pOut, NULL, NULL, 0))
00386         || FAILED(hr = pOut->GetPointer(&pDataOut)))
00387                 return hr;
00388 
00389         AM_MEDIA_TYPE* pmt;
00390         if(SUCCEEDED(pOut->GetMediaType(&pmt)) && pmt)
00391         {
00392                 CMediaType mt(*pmt);
00393                 m_pOutput->SetMediaType(&mt);
00394                 DeleteMediaType(pmt);
00395         }
00396 
00397         TRACE(_T("CDiracVideoDecoder::Deliver(%I64d, %I64d)\n"), rtStart, rtStop);
00398 
00399         pOut->SetTime(&rtStart, &rtStop);
00400         pOut->SetMediaTime(NULL, NULL);
00401 
00402         pOut->SetDiscontinuity(pIn->IsDiscontinuity() == S_OK);
00403         pOut->SetSyncPoint(TRUE);
00404 
00405         if(GetCLSID(m_pOutput->GetConnected()) == CLSID_OverlayMixer)
00406                 pOut->SetDiscontinuity(TRUE);
00407 
00408         Copy(pDataOut);
00409 
00410         return m_pOutput->Deliver(pOut);
00411 }
00412 
00413 void CDiracVideoDecoder::Copy(BYTE* pOut)
00414 {
00415         // FIXME: modes other than I420 and Y-only
00416 
00417         BITMAPINFOHEADER bihOut;
00418         ExtractBIH(&m_pOutput->CurrentMediaType(), &bihOut);
00419 
00420         dirac_decoder_t* decoder = (dirac_decoder_t*)m_decoder;
00421 
00422         int w = decoder->seq_params.width;
00423         int h = decoder->seq_params.height;
00424         int wc = decoder->seq_params.chroma_width;
00425         int hc = decoder->seq_params.chroma_height;
00426 
00427         int pitchIn = w;
00428 
00429         BYTE* pY = m_pYUV[0];
00430         BYTE* pU = w/2 == wc && h/2 == hc ? m_pYUV[1] : m_pYUV[3]; // FIXME
00431         BYTE* pV = w/2 == wc && h/2 == hc ? m_pYUV[2] : m_pYUV[3]; // FIXME
00432 
00433         if(bihOut.biCompression == '2YUY')
00434         {
00435                 BitBltFromI420ToYUY2(w, h, pOut, bihOut.biWidth*2, pY, pU, pV, pitchIn);
00436         }
00437         else if(bihOut.biCompression == 'I420' || bihOut.biCompression == 'VUYI')
00438         {
00439                 BitBltFromI420ToI420(w, h, pOut, pOut + bihOut.biWidth*h, pOut + bihOut.biWidth*h*5/4, bihOut.biWidth, pY, pU, pV, pitchIn);
00440         }
00441         else if(bihOut.biCompression == '21VY')
00442         {
00443                 BitBltFromI420ToI420(w, h, pOut, pOut + bihOut.biWidth*h*5/4, pOut + bihOut.biWidth*h, bihOut.biWidth, pY, pU, pV, pitchIn);
00444         }
00445         else if(bihOut.biCompression == BI_RGB || bihOut.biCompression == BI_BITFIELDS)
00446         {
00447                 int pitchOut = bihOut.biWidth*bihOut.biBitCount>>3;
00448 
00449                 if(bihOut.biHeight > 0)
00450                 {
00451                         pOut += pitchOut*(h-1);
00452                         pitchOut = -pitchOut;
00453                 }
00454 
00455                 if(!BitBltFromI420ToRGB(w, h, pOut, pitchOut, bihOut.biBitCount, pY, pU, pV, pitchIn))
00456                 {
00457                         for(DWORD y = 0; y < h; y++, pOut += pitchOut)
00458                                 memset(pOut, 0, pitchOut);
00459                 }
00460         }
00461 }
00462 
00463 HRESULT CDiracVideoDecoder::CheckInputType(const CMediaType* mtIn)
00464 {
00465         DIRACINFOHEADER* dvih = (DIRACINFOHEADER*)mtIn->Format();
00466 
00467         if(mtIn->majortype != MEDIATYPE_Video 
00468         || mtIn->subtype != MEDIASUBTYPE_DiracVideo
00469         || mtIn->formattype != FORMAT_DiracVideoInfo
00470         || (dvih->hdr.bmiHeader.biWidth&1) || (dvih->hdr.bmiHeader.biHeight&1))
00471                 return VFW_E_TYPE_NOT_ACCEPTED;
00472 
00473         return S_OK;
00474 }
00475 
00476 HRESULT CDiracVideoDecoder::CheckTransform(const CMediaType* mtIn, const CMediaType* mtOut)
00477 {
00478         if(m_pOutput && m_pOutput->IsConnected())
00479         {
00480                 BITMAPINFOHEADER bih1, bih2;
00481                 if(ExtractBIH(mtOut, &bih1) && ExtractBIH(&m_pOutput->CurrentMediaType(), &bih2)
00482                 && abs(bih1.biHeight) != abs(bih2.biHeight))
00483                         return VFW_E_TYPE_NOT_ACCEPTED;
00484         }
00485 
00486         return mtIn->majortype == MEDIATYPE_Video && mtIn->subtype == MEDIASUBTYPE_DiracVideo
00487                 && mtOut->majortype == MEDIATYPE_Video && (mtOut->subtype == MEDIASUBTYPE_YUY2
00488                                                                                                 || mtOut->subtype == MEDIASUBTYPE_YV12
00489                                                                                                 || mtOut->subtype == MEDIASUBTYPE_I420
00490                                                                                                 || mtOut->subtype == MEDIASUBTYPE_IYUV
00491                                                                                                 || mtOut->subtype == MEDIASUBTYPE_ARGB32
00492                                                                                                 || mtOut->subtype == MEDIASUBTYPE_RGB32
00493                                                                                                 || mtOut->subtype == MEDIASUBTYPE_RGB24
00494                                                                                                 || mtOut->subtype == MEDIASUBTYPE_RGB565
00495                                                                                                 || mtOut->subtype == MEDIASUBTYPE_RGB555)
00496                 ? S_OK
00497                 : VFW_E_TYPE_NOT_ACCEPTED;
00498 }
00499 
00500 HRESULT CDiracVideoDecoder::DecideBufferSize(IMemAllocator* pAllocator, ALLOCATOR_PROPERTIES* pProperties)
00501 {
00502         if(m_pInput->IsConnected() == FALSE) return E_UNEXPECTED;
00503 
00504         BITMAPINFOHEADER bih;
00505         ExtractBIH(&m_pOutput->CurrentMediaType(), &bih);
00506 
00507         pProperties->cBuffers = 1;
00508         pProperties->cbBuffer = bih.biSizeImage;
00509         pProperties->cbAlign = 1;
00510         pProperties->cbPrefix = 0;
00511 
00512         HRESULT hr;
00513         ALLOCATOR_PROPERTIES Actual;
00514     if(FAILED(hr = pAllocator->SetProperties(pProperties, &Actual))) 
00515                 return hr;
00516 
00517     return(pProperties->cBuffers > Actual.cBuffers || pProperties->cbBuffer > Actual.cbBuffer
00518                 ? E_FAIL
00519                 : NOERROR);
00520 }
00521 
00522 HRESULT CDiracVideoDecoder::GetMediaType(int iPosition, CMediaType* pmt)
00523 {
00524     if(m_pInput->IsConnected() == FALSE) return E_UNEXPECTED;
00525 
00526         struct {const GUID* subtype; WORD biPlanes, biBitCount; DWORD biCompression;} fmts[] =
00527         {
00528                 {&MEDIASUBTYPE_YV12, 3, 12, '21VY'},
00529                 {&MEDIASUBTYPE_I420, 3, 12, '024I'},
00530                 {&MEDIASUBTYPE_IYUV, 3, 12, 'VUYI'},
00531                 {&MEDIASUBTYPE_YUY2, 1, 16, '2YUY'},
00532                 {&MEDIASUBTYPE_ARGB32, 1, 32, BI_RGB},
00533                 {&MEDIASUBTYPE_RGB32, 1, 32, BI_RGB},
00534                 {&MEDIASUBTYPE_RGB24, 1, 24, BI_RGB},
00535                 {&MEDIASUBTYPE_RGB565, 1, 16, BI_RGB},
00536                 {&MEDIASUBTYPE_RGB555, 1, 16, BI_RGB},
00537                 {&MEDIASUBTYPE_ARGB32, 1, 32, BI_BITFIELDS},
00538                 {&MEDIASUBTYPE_RGB32, 1, 32, BI_BITFIELDS},
00539                 {&MEDIASUBTYPE_RGB24, 1, 24, BI_BITFIELDS},
00540                 {&MEDIASUBTYPE_RGB565, 1, 16, BI_BITFIELDS},
00541                 {&MEDIASUBTYPE_RGB555, 1, 16, BI_BITFIELDS},
00542         };
00543 
00544         if(m_pInput->CurrentMediaType().formattype == FORMAT_VideoInfo)
00545                 iPosition = iPosition*2 + 1;
00546 
00547         if(iPosition < 0) return E_INVALIDARG;
00548         if(iPosition >= 2*countof(fmts)) return VFW_S_NO_MORE_ITEMS;
00549 
00550         BITMAPINFOHEADER bih;
00551         ExtractBIH(&m_pInput->CurrentMediaType(), &bih);
00552 
00553         pmt->majortype = MEDIATYPE_Video;
00554         pmt->subtype = *fmts[iPosition/2].subtype;
00555 
00556         BITMAPINFOHEADER bihOut;
00557         memset(&bihOut, 0, sizeof(bihOut));
00558         bihOut.biSize = sizeof(bihOut);
00559         bihOut.biWidth = bih.biWidth;
00560         bihOut.biHeight = bih.biHeight;
00561         bihOut.biPlanes = fmts[iPosition/2].biPlanes;
00562         bihOut.biBitCount = fmts[iPosition/2].biBitCount;
00563         bihOut.biCompression = fmts[iPosition/2].biCompression;
00564         bihOut.biSizeImage = bih.biWidth*bih.biHeight*bihOut.biBitCount>>3;
00565 
00566         if(iPosition&1)
00567         {
00568                 pmt->formattype = FORMAT_VideoInfo;
00569                 VIDEOINFOHEADER* vih = (VIDEOINFOHEADER*)pmt->AllocFormatBuffer(sizeof(VIDEOINFOHEADER));
00570                 memset(vih, 0, sizeof(VIDEOINFOHEADER));
00571                 vih->bmiHeader = bihOut;
00572 
00573                 if(m_pInput->CurrentMediaType().formattype == FORMAT_VideoInfo2)
00574                 {
00575                         vih->bmiHeader.biWidth = ((VIDEOINFOHEADER2*)m_pInput->CurrentMediaType().Format())->dwPictAspectRatioX;
00576                         vih->bmiHeader.biHeight = ((VIDEOINFOHEADER2*)m_pInput->CurrentMediaType().Format())->dwPictAspectRatioY;
00577                         vih->bmiHeader.biSizeImage = vih->bmiHeader.biWidth*vih->bmiHeader.biHeight*vih->bmiHeader.biBitCount>>3;
00578                 }
00579         }
00580         else
00581         {
00582                 pmt->formattype = FORMAT_VideoInfo2;
00583                 VIDEOINFOHEADER2* vih2 = (VIDEOINFOHEADER2*)pmt->AllocFormatBuffer(sizeof(VIDEOINFOHEADER2));
00584                 memset(vih2, 0, sizeof(VIDEOINFOHEADER2));
00585                 vih2->bmiHeader = bihOut;
00586                 vih2->dwPictAspectRatioX = ((VIDEOINFOHEADER2*)m_pInput->CurrentMediaType().Format())->dwPictAspectRatioX;
00587                 vih2->dwPictAspectRatioY = ((VIDEOINFOHEADER2*)m_pInput->CurrentMediaType().Format())->dwPictAspectRatioY;
00588         }
00589 
00590         CorrectMediaType(pmt);
00591 
00592         return S_OK;
00593 }
00594 
00595 HRESULT CDiracVideoDecoder::StartStreaming()
00596 {
00597         InitDecoder();
00598         return __super::StartStreaming();
00599 }
00600 
00601 HRESULT CDiracVideoDecoder::StopStreaming()
00602 {
00603         FreeDecoder();
00604         return __super::StopStreaming();
00605 }
00606 
00607 HRESULT CDiracVideoDecoder::NewSegment(REFERENCE_TIME tStart, REFERENCE_TIME tStop, double dRate)
00608 {
00609         CAutoLock cAutoLock(&m_csReceive);
00610 
00611         m_fDropFrames = false;
00612         m_tStart = tStart;
00613 
00614         return __super::NewSegment(tStart, tStop, dRate);
00615 }
00616 
00617 HRESULT CDiracVideoDecoder::AlterQuality(Quality q)
00618 {
00619         if(q.Late > 500*10000i64) m_fDropFrames = true;
00620         if(q.Late <= 0) m_fDropFrames = false;
00621         return E_NOTIMPL;
00622 }

Generated on Tue Dec 13 14:47:11 2005 for guliverkli by  doxygen 1.4.5