T264Enc.cpp
上传用户:sunbaby
上传日期:2013-05-31
资源大小:242k
文件大小:38k
源码类别:

mpeg/mp3

开发平台:

Visual C++

  1. #include "stdafx.h"
  2. #include <initguid.h>    // declares DEFINE_GUID to declare an EXTERN_C const.
  3. #if (_MSC_VER < 1100)
  4. #include <olectlid.h>
  5. #else
  6. #include <olectl.h>
  7. #endif
  8. #include "T264Enc.h"
  9. #include "malloc.h"
  10. #include "T264EncProp.h"
  11. #include "dvdmedia.h"
  12. static const WCHAR g_wszEncName[] = L"T264 Encoder";
  13. static const WCHAR g_wszEncPropName[] = L"T264 Properties";
  14. static const WCHAR g_wszDecName[] = L"T264 Decoder";
  15. static const WCHAR g_wszDecPropName[] = L"T264 decoder properties";
  16. static const WCHAR g_wszSplitterName[] = L"T264 splitter";
  17. // dshow needs this
  18. STDAPI
  19. DllRegisterServer()
  20. {
  21.     return AMovieDllRegisterServer2( TRUE );
  22. }
  23. STDAPI
  24. DllUnregisterServer()
  25. {
  26.     return AMovieDllRegisterServer2( FALSE );
  27. }
  28. //
  29. // DllEntryPoint
  30. //
  31. extern "C" BOOL WINAPI DllEntryPoint(HINSTANCE, ULONG, LPVOID);
  32. BOOL APIENTRY DllMain(HANDLE hModule, 
  33.                       DWORD  dwReason, 
  34.                       LPVOID lpReserved)
  35. {
  36.     return DllEntryPoint((HINSTANCE)(hModule), dwReason, lpReserved);
  37. }
  38. // {6D2616AA-3C89-4703-9CEB-693C051C9E5F}
  39. DEFINE_GUID(CLSID_T264ENC, 
  40.             0x6d2616aa, 0x3c89, 0x4703, 0x9c, 0xeb, 0x69, 0x3c, 0x5, 0x1c, 0x9e, 0x5f);
  41. // {EAB4831B-121B-4568-86A7-E8058BABA62E}
  42. DEFINE_GUID(CLSID_T264DEC, 
  43.             0xeab4831b, 0x121b, 0x4568, 0x86, 0xa7, 0xe8, 0x5, 0x8b, 0xab, 0xa6, 0x2e);
  44. // {0CA6ED63-793D-4a4e-BF64-6E37F6F4D44E}
  45. DEFINE_GUID(CLSID_T264SUBTYPE, 
  46.             0xca6ed63, 0x793d, 0x4a4e, 0xbf, 0x64, 0x6e, 0x37, 0xf6, 0xf4, 0xd4, 0x4e);
  47. // {E795D14A-879D-4ea9-95EE-B6884276AEEF}
  48. DEFINE_GUID(CLSID_T264PropPage, 
  49.             0xe795d14a, 0x879d, 0x4ea9, 0x95, 0xee, 0xb6, 0x88, 0x42, 0x76, 0xae, 0xef);
  50. // {F3957FA3-98EE-4568-942D-953BBF79136F}
  51. DEFINE_GUID(CLSID_T264Splitter, 
  52.             0xf3957fa3, 0x98ee, 0x4568, 0x94, 0x2d, 0x95, 0x3b, 0xbf, 0x79, 0x13, 0x6f);
  53. // setup data - allows the self-registration to work.
  54. const AMOVIESETUP_MEDIATYPE sudInPinTypes[] =
  55. {
  56.     { 
  57.         &MEDIATYPE_Video,
  58.         &MEDIASUBTYPE_NULL 
  59.     }
  60. };
  61. const AMOVIESETUP_MEDIATYPE sudOutPinTypes[] =
  62. {
  63.     { 
  64.         &MEDIATYPE_Stream,
  65.         &MEDIASUBTYPE_NULL 
  66.     }
  67. };
  68. const AMOVIESETUP_MEDIATYPE sudInPinTypes1[] = 
  69. {
  70.     {
  71.         &MEDIATYPE_Stream,
  72.         &MEDIASUBTYPE_NULL
  73.     }
  74. };
  75. // encoder
  76. const AMOVIESETUP_PIN psudPins[] =
  77.     { 
  78.         L"Input",            // strName
  79.         FALSE,               // bRendered
  80.         FALSE,               // bOutput
  81.         FALSE,               // bZero
  82.         FALSE,               // bMany
  83.         &CLSID_NULL,         // clsConnectsToFilter
  84.         L"",                 // strConnectsToPin
  85.         1,                   // nTypes
  86.         sudInPinTypes,       // lpTypes
  87.     },
  88.     { 
  89.         L"Output",           // strName
  90.         FALSE,               // bRendered
  91.         TRUE,                // bOutput
  92.         FALSE,               // bZero
  93.         FALSE,               // bMany
  94.         &CLSID_NULL,         // clsConnectsToFilter
  95.         L"",                 // strConnectsToPin
  96.         1,                   // nTypes
  97.         sudOutPinTypes,      // lpTypes
  98.     }
  99. };
  100. // decoder
  101. const AMOVIESETUP_PIN psudPinsdec[] =
  102.     { 
  103.         L"Input",            // strName
  104.         FALSE,               // bRendered
  105.         FALSE,               // bOutput
  106.         FALSE,               // bZero
  107.         FALSE,               // bMany
  108.         &CLSID_NULL,         // clsConnectsToFilter
  109.         L"",                 // strConnectsToPin
  110.         1,                   // nTypes
  111.         sudInPinTypes,       // lpTypes
  112.     },
  113.     { 
  114.         L"Output",           // strName
  115.         FALSE,               // bRendered
  116.         TRUE,                // bOutput
  117.         FALSE,               // bZero
  118.         FALSE,               // bMany
  119.         &CLSID_NULL,         // clsConnectsToFilter
  120.         L"",                 // strConnectsToPin
  121.         1,                   // nTypes
  122.         sudInPinTypes,      // lpTypes
  123.     }
  124. };
  125. // splitter
  126. const AMOVIESETUP_PIN psudPinssplitter[] =
  127. {
  128.     { 
  129.         L"Input",            // strName
  130.         FALSE,               // bRendered
  131.         FALSE,               // bOutput
  132.         FALSE,               // bZero
  133.         FALSE,               // bMany
  134.         &CLSID_NULL,         // clsConnectsToFilter
  135.         L"",                 // strConnectsToPin
  136.         1,                   // nTypes
  137.         sudInPinTypes1,       // lpTypes
  138.     },
  139.     { 
  140.         L"Output",           // strName
  141.         FALSE,               // bRendered
  142.         TRUE,                // bOutput
  143.         FALSE,               // bZero
  144.         FALSE,               // bMany
  145.         &CLSID_NULL,         // clsConnectsToFilter
  146.         L"",                 // strConnectsToPin
  147.         1,                   // nTypes
  148.         sudInPinTypes,      // lpTypes
  149.     }
  150. };
  151. const AMOVIESETUP_FILTER sudDST264ENC =
  152.     &CLSID_T264ENC,                  // clsID
  153.     g_wszEncName,                    // strName
  154.     MERIT_DO_NOT_USE,                // dwMerit
  155.     2,                               // nPins
  156.     psudPins, 
  157. };
  158. const AMOVIESETUP_FILTER sudDST264DEC =
  159.     &CLSID_T264DEC,                  // clsID
  160.     g_wszDecName,                    // strName
  161.     MERIT_NORMAL,                    // dwMerit
  162.     2,                               // nPins
  163.     psudPinsdec, 
  164. };
  165. const AMOVIESETUP_FILTER subDST264Splitter = 
  166. {
  167.     &CLSID_T264Splitter,             // clsID
  168.     g_wszSplitterName,               // strName
  169.     MERIT_NORMAL + 3,                // dwMerit
  170.     2,                               // nPins
  171.     psudPinssplitter, 
  172. };
  173. CFactoryTemplate g_Templates[]=
  174. {   
  175.     { 
  176.         g_wszEncName,          
  177.         &CLSID_T264ENC,
  178.         CT264Enc::CreateInstance,  // function called by class factory
  179.         NULL,
  180.         &sudDST264ENC 
  181.     },
  182.     { 
  183.         g_wszEncPropName,
  184.         &CLSID_T264PropPage,
  185.         CT264EncProp::CreateInstance 
  186.     },
  187.     { 
  188.         g_wszDecName,          
  189.         &CLSID_T264DEC,
  190.         CT264Dec::CreateInstance,  // function called by class factory
  191.         NULL,
  192.         &sudDST264DEC 
  193.     },
  194.     {
  195.         g_wszSplitterName,
  196.         &CLSID_T264Splitter,
  197.         CT264Splitter::CreateInstance,
  198.         NULL,
  199.         &subDST264Splitter
  200.     }
  201. };
  202. int g_cTemplates = sizeof(g_Templates)/sizeof(g_Templates[0]);  
  203. //////////////////////////////////////////////////////////////////////////
  204. // CT264Enc
  205. CT264Enc::CT264Enc(TCHAR *tszName,LPUNKNOWN punk,HRESULT *phr) :
  206.     CTransformFilter(tszName, punk, CLSID_T264ENC)
  207. {
  208.     m_t264 = 0;
  209.     memset(&m_param, 0, sizeof(m_param));
  210.     put_Default();
  211.     m_hWnd = 0;
  212. }
  213. CT264Enc::~CT264Enc()
  214. {
  215.     if (m_t264 != 0)
  216.     {
  217.         T264_close(m_t264);
  218.         _aligned_free(m_pBuffer);
  219.     }
  220. }
  221. //
  222. // CreateInstance
  223. //
  224. // Provide the way for COM to create a CT264Enc object
  225. //
  226. CUnknown * WINAPI CT264Enc::CreateInstance(LPUNKNOWN punk, HRESULT *phr) 
  227. {
  228.     ASSERT(phr);
  229.     CT264Enc *pNewObject = new CT264Enc(NAME("T264Enc"), punk, phr);
  230.     if (pNewObject == NULL) {
  231.         if (phr)
  232.             *phr = E_OUTOFMEMORY;
  233.     }
  234.     return pNewObject;
  235. } // CreateInstance
  236. //
  237. // NonDelegatingQueryInterface
  238. //
  239. // Reveals IContrast and ISpecifyPropertyPages
  240. //
  241. STDMETHODIMP CT264Enc::NonDelegatingQueryInterface(REFIID riid, void **ppv)
  242. {
  243.     CheckPointer(ppv, E_POINTER);
  244.     if (riid == IID_IProp)
  245.     {
  246.         return GetInterface((IProp*) this, ppv);
  247.     } 
  248.     else if (riid == IID_ISpecifyPropertyPages) 
  249.     {
  250.         return GetInterface((ISpecifyPropertyPages*) this, ppv);
  251.     } 
  252.     else 
  253.     {
  254.         return CTransformFilter::NonDelegatingQueryInterface(riid, ppv);
  255.     }
  256. } // NonDelegatingQueryInterface
  257. HRESULT CT264Enc::Transform(IMediaSample *pIn, IMediaSample *pOut)
  258. {
  259.     INT plane = m_param.width * m_param.height;
  260.     HRESULT hr;
  261.     // some decoder does not reset emms(such as mainconcept mpeg2 decoder), and we need compute floating ...
  262.     __asm emms
  263.     BYTE* pSrc, *pDst;
  264.     LONG lDstSize, lActualSize;
  265.     hr = pIn->GetPointer(&pSrc);
  266.     ASSERT(hr == S_OK);
  267.     hr = pOut->GetPointer(&pDst);
  268.     ASSERT(hr == S_OK);
  269.     lDstSize = pOut->GetSize();
  270.     // convert yv12 ==> iyuv
  271.     CopyMemory(m_pBuffer, pSrc, plane);
  272.     CopyMemory(m_pBuffer + plane, pSrc + plane + (plane >> 2), plane >> 2);
  273.     CopyMemory(m_pBuffer + plane + (plane >> 2), pSrc + plane, plane >> 2);
  274.     lActualSize = T264_encode(m_t264, m_pBuffer, pDst, lDstSize);
  275.     ASSERT(lActualSize <= lDstSize);
  276.     pOut->SetActualDataLength(lActualSize);
  277.     if (m_hWnd && lActualSize)
  278.     {
  279.         wsprintf(m_szInfo, "Frame = %d, Qp = %d, Length = %d.", m_t264->frame_id, m_t264->qp_y, lActualSize);
  280.         SendMessage(m_hWnd, WM_SETTEXT, 0, (LPARAM)m_szInfo);
  281.     }
  282.     return hr;
  283. } // Transform
  284. HRESULT CT264Enc::Copy(IMediaSample *pSource, IMediaSample *pDest) const
  285. {
  286.     CheckPointer(pSource,E_POINTER);
  287.     CheckPointer(pDest,E_POINTER);
  288.     // Copy the sample data
  289.     BYTE *pSourceBuffer, *pDestBuffer;
  290.     long lSourceSize = pSource->GetActualDataLength();
  291. #ifdef DEBUG
  292.     long lDestSize = pDest->GetSize();
  293.     ASSERT(lDestSize >= lSourceSize);
  294. #endif
  295.     pSource->GetPointer(&pSourceBuffer);
  296.     pDest->GetPointer(&pDestBuffer);
  297.     CopyMemory((PVOID) pDestBuffer,(PVOID) pSourceBuffer,lSourceSize);
  298.     // Copy the sample times
  299.     REFERENCE_TIME TimeStart, TimeEnd;
  300.     if(NOERROR == pSource->GetTime(&TimeStart, &TimeEnd))
  301.     {
  302.         pDest->SetTime(&TimeStart, &TimeEnd);
  303.     }
  304.     LONGLONG MediaStart, MediaEnd;
  305.     if(pSource->GetMediaTime(&MediaStart,&MediaEnd) == NOERROR)
  306.     {
  307.         pDest->SetMediaTime(&MediaStart,&MediaEnd);
  308.     }
  309.     // Copy the Sync point property
  310.     HRESULT hr = pSource->IsSyncPoint();
  311.     if(hr == S_OK)
  312.     {
  313.         pDest->SetSyncPoint(TRUE);
  314.     }
  315.     else if(hr == S_FALSE)
  316.     {
  317.         pDest->SetSyncPoint(FALSE);
  318.     }
  319.     else
  320.     {  // an unexpected error has occured...
  321.         return E_UNEXPECTED;
  322.     }
  323.     // Copy the media type
  324.     AM_MEDIA_TYPE *pMediaType;
  325.     pSource->GetMediaType(&pMediaType);
  326.     pDest->SetMediaType(pMediaType);
  327.     DeleteMediaType(pMediaType);
  328.     // Copy the preroll property
  329.     hr = pSource->IsPreroll();
  330.     if(hr == S_OK)
  331.     {
  332.         pDest->SetPreroll(TRUE);
  333.     }
  334.     else if(hr == S_FALSE)
  335.     {
  336.         pDest->SetPreroll(FALSE);
  337.     }
  338.     else
  339.     {  // an unexpected error has occured...
  340.         return E_UNEXPECTED;
  341.     }
  342.     // Copy the discontinuity property
  343.     hr = pSource->IsDiscontinuity();
  344.     if(hr == S_OK)
  345.     {
  346.         pDest->SetDiscontinuity(TRUE);
  347.     }
  348.     else if(hr == S_FALSE)
  349.     {
  350.         pDest->SetDiscontinuity(FALSE);
  351.     }
  352.     else
  353.     {  // an unexpected error has occured...
  354.         return E_UNEXPECTED;
  355.     }
  356.     // Copy the actual data length
  357.     long lDataLength = pSource->GetActualDataLength();
  358.     pDest->SetActualDataLength(lDataLength);
  359.     return NOERROR;
  360. } // Copy
  361. HRESULT CT264Enc::CheckInputType(const CMediaType *mtIn)
  362. {
  363.     CheckPointer(mtIn,E_POINTER);
  364.     if(*mtIn->FormatType() == FORMAT_VideoInfo)
  365.     {
  366.         if(IsEqualGUID(*mtIn->Subtype(), MEDIASUBTYPE_YV12))
  367.         {
  368.             if(mtIn->FormatLength() < sizeof(VIDEOINFOHEADER))
  369.                 return E_INVALIDARG;
  370.             VIDEOINFO *pInput  = (VIDEOINFO *) mtIn->Format();
  371.             m_param.width = pInput->bmiHeader.biWidth;
  372.             m_param.height = pInput->bmiHeader.biHeight;
  373.             m_param.framerate = (float)(INT)((float)10000000 / pInput->AvgTimePerFrame + 0.5);
  374.             m_avgFrameTime = pInput->AvgTimePerFrame;
  375.             return NOERROR;
  376.         }
  377.     }
  378.     else if (*mtIn->FormatType() == FORMAT_VideoInfo2)
  379.     {
  380.         if(IsEqualGUID(*mtIn->Subtype(), MEDIASUBTYPE_YV12))
  381.         {
  382.             if(mtIn->FormatLength() < sizeof(VIDEOINFOHEADER2))
  383.                 return E_INVALIDARG;
  384.             VIDEOINFOHEADER2 *pInput  = (VIDEOINFOHEADER2*) mtIn->Format();
  385.             m_param.width = pInput->bmiHeader.biWidth;
  386.             m_param.height = pInput->bmiHeader.biHeight;
  387.             m_avgFrameTime = (LONGLONG)((float)10000000 / m_param.framerate);//pInput->AvgTimePerFrame;
  388.             m_param.framerate = (float)(INT)(m_param.framerate + 0.5f);
  389.             return NOERROR;
  390.         }
  391.     }
  392.     return E_INVALIDARG;
  393. } // CheckInputType
  394. HRESULT CT264Enc::CheckTransform(const CMediaType *mtIn,const CMediaType *mtOut)
  395. {
  396.     CheckPointer(mtIn,E_POINTER);
  397.     CheckPointer(mtOut,E_POINTER);
  398.     HRESULT hr;
  399.     if(FAILED(hr = CheckInputType(mtIn)))
  400.     {
  401.         return hr;
  402.     }
  403.     if(*mtOut->FormatType() != FORMAT_VideoInfo)
  404.     {
  405.         return E_INVALIDARG;
  406.     }
  407.     // formats must be big enough 
  408.     if(mtIn->FormatLength() < sizeof(VIDEOINFOHEADER) ||
  409.         mtOut->FormatLength() < sizeof(VIDEOINFOHEADER))
  410.         return E_INVALIDARG;
  411.     return NOERROR;
  412. } // CheckTransform
  413. HRESULT CT264Enc::InitOutMediaType(CMediaType* pmt)
  414. {
  415.     pmt->InitMediaType();
  416.     pmt->SetType(&MEDIATYPE_Video);
  417.     pmt->SetSubtype(&CLSID_T264SUBTYPE);
  418.     VIDEOINFOHEADER *pvi = (VIDEOINFOHEADER*)pmt->AllocFormatBuffer(sizeof(VIDEOINFOHEADER));
  419.     ZeroMemory(pvi, sizeof(VIDEOINFOHEADER));
  420.     DWORD fcc = '462T';
  421.     pvi->dwBitRate = m_param.bitrate;
  422.     pvi->AvgTimePerFrame = m_avgFrameTime;
  423.     pvi->bmiHeader.biCompression = fcc;
  424.     pvi->bmiHeader.biBitCount    = 12;
  425.     pvi->bmiHeader.biPlanes = 1;
  426.     pvi->bmiHeader.biSize       = sizeof(BITMAPINFOHEADER);
  427.     pvi->bmiHeader.biWidth      = m_param.width;
  428.     pvi->bmiHeader.biHeight     = m_param.height;
  429.     pvi->bmiHeader.biSizeImage  = GetBitmapSize(&pvi->bmiHeader);
  430.     SetRectEmpty(&(pvi->rcSource));
  431.     SetRectEmpty(&(pvi->rcTarget));
  432.     pmt->SetFormatType(&FORMAT_VideoInfo);
  433.     pmt->SetVariableSize();
  434.     pmt->SetTemporalCompression(true);
  435.     return S_OK;
  436. }
  437. //
  438. // DecideBufferSize
  439. //
  440. // Tell the output pin's allocator what size buffers we
  441. // require. Can only do this when the input is connected
  442. //
  443. HRESULT CT264Enc::DecideBufferSize(IMemAllocator *pAlloc,ALLOCATOR_PROPERTIES *pProperties)
  444. {
  445.     CheckPointer(pAlloc,E_POINTER);
  446.     CheckPointer(pProperties,E_POINTER);
  447.     // Is the input pin connected
  448.     if(m_pInput->IsConnected() == FALSE)
  449.     {
  450.         return E_UNEXPECTED;
  451.     }
  452.     HRESULT hr = NOERROR;
  453.     pProperties->cBuffers = 1;
  454.     pProperties->cbBuffer = m_pInput->CurrentMediaType().GetSampleSize();
  455.     ASSERT(pProperties->cbBuffer);
  456.     // If we don't have fixed sized samples we must guess some size
  457.     if(!m_pInput->CurrentMediaType().bFixedSizeSamples)
  458.     {
  459.         if(pProperties->cbBuffer < OUTPIN_BUFFER_SIZE)
  460.         {
  461.             // nothing more than a guess!!
  462.             pProperties->cbBuffer = OUTPIN_BUFFER_SIZE;
  463.         }
  464.     }
  465.     // Ask the allocator to reserve us some sample memory, NOTE the function
  466.     // can succeed (that is return NOERROR) but still not have allocated the
  467.     // memory that we requested, so we must check we got whatever we wanted
  468.     ALLOCATOR_PROPERTIES Actual;
  469.     hr = pAlloc->SetProperties(pProperties,&Actual);
  470.     if(FAILED(hr))
  471.     {
  472.         return hr;
  473.     }
  474.     ASSERT(Actual.cBuffers == 1);
  475.     if(pProperties->cBuffers > Actual.cBuffers ||
  476.         pProperties->cbBuffer > Actual.cbBuffer)
  477.     {
  478.         return E_FAIL;
  479.     }
  480.     return NOERROR;
  481. } // DecideBufferSize
  482. //
  483. // GetMediaType
  484. //
  485. // I support one type, namely the type of the input pin
  486. // We must be connected to support the single output type
  487. //
  488. HRESULT CT264Enc::GetMediaType(int iPosition, CMediaType *pMediaType)
  489. {
  490.     // Is the input pin connected
  491.     if(m_pInput->IsConnected() == FALSE)
  492.     {
  493.         return E_UNEXPECTED;
  494.     }
  495.     // This should never happen
  496.     if(iPosition < 0)
  497.     {
  498.         return E_INVALIDARG;
  499.     }
  500.     // Do we have more items to offer
  501.     if(iPosition > 0)
  502.     {
  503.         return VFW_S_NO_MORE_ITEMS;
  504.     }
  505.     CheckPointer(pMediaType,E_POINTER);
  506.     InitOutMediaType(pMediaType);
  507.     return NOERROR;
  508. } // GetMediaType
  509. HRESULT CT264Enc::StartStreaming()
  510. {
  511.     _asm emms
  512.     if (m_t264 == NULL)
  513.     {
  514.         INT plane = m_param.width * m_param.height;
  515.         m_t264 = T264_open(&m_param);
  516.         m_pBuffer = (BYTE*)_aligned_malloc(plane + (plane >> 1), 16);
  517.         ASSERT(m_t264);
  518.     }
  519.     return CTransformFilter::StartStreaming();
  520. }
  521. HRESULT CT264Enc::StopStreaming()
  522. {
  523.     if (m_t264 != NULL)
  524.     {
  525.         T264_close(m_t264);
  526.         m_t264 = 0;
  527.         _aligned_free(m_pBuffer);
  528.         m_pBuffer = 0;
  529.     }
  530.     return CTransformFilter::StopStreaming();
  531. }
  532. //
  533. // GetPages
  534. //
  535. // This is the sole member of ISpecifyPropertyPages
  536. // Returns the clsid's of the property pages we support
  537. //
  538. STDMETHODIMP CT264Enc::GetPages(CAUUID *pPages)
  539. {
  540.     CheckPointer(pPages,E_POINTER);
  541.     pPages->cElems = 1;
  542.     pPages->pElems = (GUID *) CoTaskMemAlloc(sizeof(GUID));
  543.     if(pPages->pElems == NULL)
  544.     {
  545.         return E_OUTOFMEMORY;
  546.     }
  547.     *(pPages->pElems) = CLSID_T264PropPage;
  548.     return NOERROR;
  549. } // GetPages
  550. HRESULT CT264Enc::get_Para(INT** pPara)
  551. {
  552.     *pPara = (INT*)&m_param;
  553.     return S_OK;
  554. }
  555. HRESULT CT264Enc::put_Default()
  556. {
  557.     m_param.flags  = //USE_INTRA16x16|
  558.         USE_INTRA4x4| 
  559.         USE_HALFPEL|
  560.         USE_QUARTPEL|
  561.         USE_SUBBLOCK|
  562.         //    USE_FULLSEARCH|
  563.         USE_DIAMONDSEACH|
  564.         USE_FORCEBLOCKSIZE|
  565.         USE_FASTINTERPOLATE|
  566.         USE_SAD|
  567.         USE_EXTRASUBPELSEARCH|
  568.         USE_INTRAININTER|
  569.         USE_SCENEDETECT;
  570.     m_param.iframe = 300;
  571.     m_param.idrframe = 3000 * 300;
  572.     m_param.qp       = 28;
  573.     m_param.min_qp   = 8;
  574.     m_param.max_qp   = 34;
  575.     m_param.bitrate  = 600 * 1024;
  576.     m_param.framerate= 30;
  577.     m_param.search_x = 16;
  578.     m_param.search_y = 16;
  579.     m_param.block_size = SEARCH_16x16P
  580.         |SEARCH_16x8P
  581.         |SEARCH_8x16P
  582. //        |SEARCH_8x8P
  583. //        |SEARCH_8x4P
  584. //        |SEARCH_4x8P
  585. //        |SEARCH_4x4P;
  586.         |SEARCH_16x16B
  587.         |SEARCH_16x8B
  588.         |SEARCH_8x16B;
  589.     m_param.disable_filter = 0;
  590.     m_param.aspect_ratio = 2;
  591.     m_param.video_format = 1;
  592.     m_param.ref_num  = 3;
  593.     m_param.luma_coeff_cost = 4;    // default 4, min qp please decrease this value
  594.     m_param.cpu      = 0;
  595.     m_param.cabac = 1;
  596.     m_param.b_num = 1;
  597.     if (m_param.bitrate != 0)
  598.         m_param.enable_rc = 1;
  599.     else
  600.         m_param.enable_rc = 0;
  601.     return S_OK;
  602. }
  603. HRESULT CT264Enc::put_InfoWnd(INT hWnd)
  604. {
  605.     m_hWnd = (HWND)hWnd;
  606.     return S_OK;
  607. }
  608. //////////////////////////////////////////////////////////////////////////
  609. // CT264Dec
  610. CT264Dec::CT264Dec(TCHAR *tszName,LPUNKNOWN punk,HRESULT *phr) :
  611. CTransformFilter(tszName, punk, CLSID_T264ENC)
  612. {
  613.     m_t264 = 0;
  614.     m_hWnd = 0;
  615. }
  616. CT264Dec::~CT264Dec()
  617. {
  618.     if (m_t264 != 0)
  619.     {
  620.         T264dec_close(m_t264);
  621.     }
  622. }
  623. //
  624. // CreateInstance
  625. //
  626. // Provide the way for COM to create a CT264Dec object
  627. //
  628. CUnknown * WINAPI CT264Dec::CreateInstance(LPUNKNOWN punk, HRESULT *phr) 
  629. {
  630.     ASSERT(phr);
  631.     CT264Dec *pNewObject = new CT264Dec(NAME("T264Dec"), punk, phr);
  632.     if (pNewObject == NULL) {
  633.         if (phr)
  634.             *phr = E_OUTOFMEMORY;
  635.     }
  636.     return pNewObject;
  637. } // CreateInstance
  638. //
  639. // NonDelegatingQueryInterface
  640. //
  641. // Reveals IContrast and ISpecifyPropertyPages
  642. //
  643. STDMETHODIMP CT264Dec::NonDelegatingQueryInterface(REFIID riid, void **ppv)
  644. {
  645.     CheckPointer(ppv, E_POINTER);
  646.     //if (riid == IID_IProp)
  647.     //{
  648.     //    return GetInterface((IProp*) this, ppv);
  649.     //} 
  650.     //else if (riid == IID_ISpecifyPropertyPages) 
  651.     //{
  652.     //    return GetInterface((ISpecifyPropertyPages*) this, ppv);
  653.     //} 
  654.     //else 
  655.     {
  656.         return CTransformFilter::NonDelegatingQueryInterface(riid, ppv);
  657.     }
  658. } // NonDelegatingQueryInterface
  659. HRESULT CT264Dec::Transform(IMediaSample *pIn, IMediaSample *pOut)
  660. {
  661.     return S_OK;
  662. } // Transform
  663. HRESULT CT264Dec::SendSample(T264_t* t, T264_frame_t *frame, IMediaSample* pSample)
  664. {
  665.     INT i;
  666.     BYTE* p, *pDst;
  667.     HRESULT hr;
  668.     IMediaSample* pOutSample;
  669.     // Set up the output sample
  670.     hr = InitializeOutputSample(pSample, &pOutSample);
  671.     if (FAILED(hr)) 
  672.     {
  673.         return hr;
  674.     }
  675.     hr = pOutSample->GetPointer(&pDst);
  676.     ASSERT(hr == S_OK);
  677.     p = frame->Y[0];
  678.     for(i = 0 ; i < t->height ; i ++)
  679.     {
  680.         memcpy(pDst, p, t->width);
  681.         pDst += m_nStride;
  682.         p += t->edged_stride;
  683.     }
  684.     p = frame->V;
  685.     for(i = 0 ; i < t->height >> 1 ; i ++)
  686.     {
  687.         memcpy(pDst, p, t->width);
  688.         pDst += m_nStride >> 1;
  689.         p += t->edged_stride_uv;
  690.     }
  691.     p = frame->U;
  692.     for(i = 0 ; i < t->height >> 1 ; i ++)
  693.     {
  694.         memcpy(pDst, p, t->width);
  695.         pDst += m_nStride >> 1;
  696.         p += t->edged_stride_uv;
  697.     }
  698.     pOutSample->SetActualDataLength(t->width * t->height + (t->width * t->height >> 1));
  699.     pOutSample->SetSyncPoint(TRUE);
  700.     CRefTime rtEnd = m_time + m_avgFrameTime;
  701.     pOutSample->SetTime(&m_time.m_time, &rtEnd.m_time);
  702.     m_time = rtEnd;
  703.     hr = m_pNextFilterInputpin->Receive(pOutSample);
  704.     m_bSampleSkipped = FALSE; // last thing no longer dropped
  705.     // release the output buffer. If the connected pin still needs it,
  706.     // it will have addrefed it itself.
  707.     pOutSample->Release();
  708.     return hr;
  709. }
  710. HRESULT CT264Dec::CompleteConnect(PIN_DIRECTION direction, IPin *pReceivePin)
  711. {
  712.     HRESULT hr = CTransformFilter::CompleteConnect(direction, pReceivePin);
  713.     if (direction == PINDIR_OUTPUT)
  714.     {
  715.         hr = pReceivePin->QueryInterface(__uuidof(m_pNextFilterInputpin), (VOID**)&m_pNextFilterInputpin);
  716.         ASSERT(hr == S_OK);
  717.         // we do not want to hold the reference of the input pin
  718.         m_pNextFilterInputpin->Release();
  719.     }
  720.     return hr;
  721. }
  722. HRESULT CT264Dec::Receive(IMediaSample* pSample)
  723. {
  724.     /*  Check for other streams and pass them on */
  725.     AM_SAMPLE2_PROPERTIES * const pProps = m_pInput->SampleProps();
  726.     if (pProps->dwStreamId != AM_STREAM_MEDIA) {
  727.         return m_pNextFilterInputpin->Receive(pSample);
  728.     }
  729.     HRESULT hr;
  730.     ASSERT(pSample);
  731.     ASSERT (m_pOutput != NULL) ;
  732.     {
  733.         // some decoder does not reset emms(such as mainconcept mpeg2 decoder), and we need compute floating ...
  734.         BYTE* pSrc;
  735.         LONG lSrcSize;
  736.         INT run = 1;
  737.         hr = pSample->GetPointer(&pSrc);
  738.         ASSERT(hr == S_OK);
  739.         lSrcSize = pSample->GetSize();
  740.         T264dec_buffer(m_t264, pSrc, lSrcSize);
  741.         while (run)
  742.         {
  743.             decoder_state_t state = T264dec_parse(m_t264);
  744.             switch(state) 
  745.             {
  746.             case DEC_STATE_SLICE:
  747.                 {
  748.                     if (m_t264->output.poc >= 0)
  749.                     {
  750.                         SendSample(m_t264, &m_t264->output, pSample);
  751.                     }
  752.                 }
  753.                 break;
  754.             case DEC_STATE_BUFFER:
  755.                 /* read more data */
  756.                 return S_OK;
  757.             case DEC_STATE_SEQ:
  758.                 if (m_t264->frame_id > 0)
  759.                 {
  760.                     SendSample(m_t264, T264dec_flush_frame(m_t264), pSample);
  761.                 }
  762.                 break;
  763.             /*case DEC_STATE_PIC:*/
  764.             default:
  765.                 /* do not care */
  766.                 break;
  767.             }
  768.         }
  769.     }
  770.     return hr;
  771. }
  772. HRESULT CT264Dec::Copy(IMediaSample *pSource, IMediaSample *pDest) const
  773. {
  774.     CheckPointer(pSource,E_POINTER);
  775.     CheckPointer(pDest,E_POINTER);
  776.     // Copy the sample data
  777.     BYTE *pSourceBuffer, *pDestBuffer;
  778.     long lSourceSize = pSource->GetActualDataLength();
  779. #ifdef DEBUG
  780.     long lDestSize = pDest->GetSize();
  781.     ASSERT(lDestSize >= lSourceSize);
  782. #endif
  783.     pSource->GetPointer(&pSourceBuffer);
  784.     pDest->GetPointer(&pDestBuffer);
  785.     CopyMemory((PVOID) pDestBuffer,(PVOID) pSourceBuffer,lSourceSize);
  786.     // Copy the sample times
  787.     REFERENCE_TIME TimeStart, TimeEnd;
  788.     if(NOERROR == pSource->GetTime(&TimeStart, &TimeEnd))
  789.     {
  790.         pDest->SetTime(&TimeStart, &TimeEnd);
  791.     }
  792.     LONGLONG MediaStart, MediaEnd;
  793.     if(pSource->GetMediaTime(&MediaStart,&MediaEnd) == NOERROR)
  794.     {
  795.         pDest->SetMediaTime(&MediaStart,&MediaEnd);
  796.     }
  797.     // Copy the Sync point property
  798.     HRESULT hr = pSource->IsSyncPoint();
  799.     if(hr == S_OK)
  800.     {
  801.         pDest->SetSyncPoint(TRUE);
  802.     }
  803.     else if(hr == S_FALSE)
  804.     {
  805.         pDest->SetSyncPoint(FALSE);
  806.     }
  807.     else
  808.     {  // an unexpected error has occured...
  809.         return E_UNEXPECTED;
  810.     }
  811.     // Copy the media type
  812.     AM_MEDIA_TYPE *pMediaType;
  813.     pSource->GetMediaType(&pMediaType);
  814.     pDest->SetMediaType(pMediaType);
  815.     DeleteMediaType(pMediaType);
  816.     // Copy the preroll property
  817.     hr = pSource->IsPreroll();
  818.     if(hr == S_OK)
  819.     {
  820.         pDest->SetPreroll(TRUE);
  821.     }
  822.     else if(hr == S_FALSE)
  823.     {
  824.         pDest->SetPreroll(FALSE);
  825.     }
  826.     else
  827.     {  // an unexpected error has occured...
  828.         return E_UNEXPECTED;
  829.     }
  830.     // Copy the discontinuity property
  831.     hr = pSource->IsDiscontinuity();
  832.     if(hr == S_OK)
  833.     {
  834.         pDest->SetDiscontinuity(TRUE);
  835.     }
  836.     else if(hr == S_FALSE)
  837.     {
  838.         pDest->SetDiscontinuity(FALSE);
  839.     }
  840.     else
  841.     {  // an unexpected error has occured...
  842.         return E_UNEXPECTED;
  843.     }
  844.     // Copy the actual data length
  845.     long lDataLength = pSource->GetActualDataLength();
  846.     pDest->SetActualDataLength(lDataLength);
  847.     return NOERROR;
  848. } // Copy
  849. HRESULT CT264Dec::CheckInputType(const CMediaType *mtIn)
  850. {
  851.     CheckPointer(mtIn,E_POINTER);
  852.     if(*mtIn->FormatType() == FORMAT_VideoInfo)
  853.     {
  854. //        if (*mtIn->Subtype() == CLSID_T264SUBTYPE)
  855.         {
  856.             if(mtIn->FormatLength() < sizeof(VIDEOINFOHEADER))
  857.                 return E_INVALIDARG;
  858.             VIDEOINFO *pInput  = (VIDEOINFO *) mtIn->Format();
  859.             if (pInput->bmiHeader.biCompression == 'HSSV' || pInput->bmiHeader.biCompression == '462T')
  860.             {
  861.                 m_nWidth = pInput->bmiHeader.biWidth;
  862.                 m_nHeight = pInput->bmiHeader.biHeight;
  863.                 m_framerate = (float)(INT)((float)10000000 / pInput->AvgTimePerFrame + 0.5);
  864.                 m_avgFrameTime = pInput->AvgTimePerFrame;
  865.                 return NOERROR;
  866.             }
  867.         }
  868.     }
  869.     else if (*mtIn->FormatType() == FORMAT_VideoInfo2)
  870.     {
  871. //        if (*mtIn->Subtype() == CLSID_T264SUBTYPE)
  872.         {
  873.             if(mtIn->FormatLength() < sizeof(VIDEOINFOHEADER2))
  874.                 return E_INVALIDARG;
  875.             VIDEOINFOHEADER2 *pInput  = (VIDEOINFOHEADER2*) mtIn->Format();
  876.             if (pInput->bmiHeader.biCompression == 'HSSV' || pInput->bmiHeader.biCompression == '462T')
  877.             {
  878.                 m_nWidth = pInput->bmiHeader.biWidth;
  879.                 m_nHeight = pInput->bmiHeader.biHeight;
  880.                 m_avgFrameTime = pInput->AvgTimePerFrame;
  881.                 m_framerate = (float)(INT)((float)10000000 / pInput->AvgTimePerFrame + 0.5);
  882.                 return NOERROR;
  883.             }
  884.         }
  885.     }
  886.     return E_INVALIDARG;
  887. } // CheckInputType
  888. HRESULT CT264Dec::CheckTransform(const CMediaType *mtIn,const CMediaType *mtOut)
  889. {
  890.     CheckPointer(mtIn,E_POINTER);
  891.     CheckPointer(mtOut,E_POINTER);
  892.     HRESULT hr;
  893.     if(FAILED(hr = CheckInputType(mtIn)))
  894.     {
  895.         return hr;
  896.     }
  897.     if(*mtOut->FormatType() != FORMAT_VideoInfo)
  898.     {
  899.         return E_INVALIDARG;
  900.     }
  901.     // formats must be big enough 
  902.     if(mtIn->FormatLength() < sizeof(VIDEOINFOHEADER) ||
  903.         mtOut->FormatLength() < sizeof(VIDEOINFOHEADER))
  904.         return E_INVALIDARG;
  905.     VIDEOINFO* pInfo = (VIDEOINFO*)mtOut->Format();
  906.     m_nStride = pInfo->bmiHeader.biWidth;
  907.     return NOERROR;
  908. } // CheckTransform
  909. HRESULT CT264Dec::InitOutMediaType(CMediaType* pmt)
  910. {
  911.     pmt->InitMediaType();
  912.     pmt->SetType(&MEDIATYPE_Video);
  913.     pmt->SetSubtype(&MEDIASUBTYPE_YV12);
  914.     VIDEOINFOHEADER *pvi = (VIDEOINFOHEADER*)pmt->AllocFormatBuffer(sizeof(VIDEOINFOHEADER));
  915.     ZeroMemory(pvi, sizeof(VIDEOINFOHEADER));
  916.     pvi->AvgTimePerFrame = m_avgFrameTime;
  917.     pvi->bmiHeader.biCompression = '21VY';
  918.     pvi->bmiHeader.biBitCount    = 12;
  919.     pvi->bmiHeader.biPlanes = 1;
  920.     pvi->bmiHeader.biSize       = sizeof(BITMAPINFOHEADER);
  921.     pvi->bmiHeader.biWidth      = m_nWidth;
  922.     pvi->bmiHeader.biHeight     = m_nHeight;
  923.     pvi->bmiHeader.biSizeImage  = GetBitmapSize(&pvi->bmiHeader);
  924.     SetRectEmpty(&(pvi->rcSource));
  925.     SetRectEmpty(&(pvi->rcTarget));
  926.     pmt->SetFormatType(&FORMAT_VideoInfo);
  927.     pmt->SetVariableSize();
  928.     pmt->SetTemporalCompression(true);
  929.     return S_OK;
  930. }
  931. //
  932. // DecideBufferSize
  933. //
  934. // Tell the output pin's allocator what size buffers we
  935. // require. Can only do this when the input is connected
  936. //
  937. HRESULT CT264Dec::DecideBufferSize(IMemAllocator *pAlloc,ALLOCATOR_PROPERTIES *pProperties)
  938. {
  939.     CheckPointer(pAlloc,E_POINTER);
  940.     CheckPointer(pProperties,E_POINTER);
  941.     // Is the input pin connected
  942.     if(m_pInput->IsConnected() == FALSE)
  943.     {
  944.         return E_UNEXPECTED;
  945.     }
  946.     HRESULT hr = NOERROR;
  947.     pProperties->cBuffers = 1;
  948.     pProperties->cbBuffer = (m_nWidth * m_nHeight >> 1) + m_nWidth * m_nHeight;
  949.     ASSERT(pProperties->cbBuffer);
  950.     // If we don't have fixed sized samples we must guess some size
  951.     if(!m_pOutput->CurrentMediaType().bFixedSizeSamples)
  952.     {
  953.         if(pProperties->cbBuffer < OUTPIN_BUFFER_SIZE)
  954.         {
  955.             // nothing more than a guess!!
  956.             pProperties->cbBuffer = OUTPIN_BUFFER_SIZE;
  957.         }
  958.     }
  959.     // Ask the allocator to reserve us some sample memory, NOTE the function
  960.     // can succeed (that is return NOERROR) but still not have allocated the
  961.     // memory that we requested, so we must check we got whatever we wanted
  962.     ALLOCATOR_PROPERTIES Actual;
  963.     hr = pAlloc->SetProperties(pProperties,&Actual);
  964.     if(FAILED(hr))
  965.     {
  966.         return hr;
  967.     }
  968.     ASSERT(Actual.cBuffers == 1);
  969.     if(pProperties->cBuffers > Actual.cBuffers ||
  970.         pProperties->cbBuffer > Actual.cbBuffer)
  971.     {
  972.         return E_FAIL;
  973.     }
  974.     return NOERROR;
  975. } // DecideBufferSize
  976. //
  977. // GetMediaType
  978. //
  979. // I support one type, namely the type of the input pin
  980. // We must be connected to support the single output type
  981. //
  982. HRESULT CT264Dec::GetMediaType(int iPosition, CMediaType *pMediaType)
  983. {
  984.     // Is the input pin connected
  985.     if(m_pInput->IsConnected() == FALSE)
  986.     {
  987.         return E_UNEXPECTED;
  988.     }
  989.     // This should never happen
  990.     if(iPosition < 0)
  991.     {
  992.         return E_INVALIDARG;
  993.     }
  994.     // Do we have more items to offer
  995.     if(iPosition > 0)
  996.     {
  997.         return VFW_S_NO_MORE_ITEMS;
  998.     }
  999.     CheckPointer(pMediaType,E_POINTER);
  1000.     InitOutMediaType(pMediaType);
  1001.     return NOERROR;
  1002. } // GetMediaType
  1003. HRESULT CT264Dec::StartStreaming()
  1004. {
  1005.     _asm emms
  1006.     if (m_t264 == NULL)
  1007.     {
  1008.         m_t264 = T264dec_open();
  1009.         ASSERT(m_t264);
  1010.     }
  1011.     m_time = 0;
  1012.     return CTransformFilter::StartStreaming();
  1013. }
  1014. HRESULT CT264Dec::StopStreaming()
  1015. {
  1016.     if (m_t264 != NULL)
  1017.     {
  1018.         T264dec_close(m_t264);
  1019.         m_t264 = 0;
  1020.     }
  1021.     return CTransformFilter::StopStreaming();
  1022. }
  1023. //////////////////////////////////////////////////////////////////////////
  1024. // CT264Splitter
  1025. CT264Splitter::CT264Splitter(
  1026.     LPUNKNOWN pUnk,
  1027.     HRESULT *phr) :
  1028.     CBaseSplitterFilter(
  1029.                     TEXT("CT264Splitter"),
  1030.                     pUnk,
  1031.                     CLSID_T264Splitter,
  1032.                     phr)
  1033. {
  1034.     //  Create our input pin
  1035.     m_pInput = new CSplitterInputPin(this, phr);
  1036. }
  1037. CUnknown *CT264Splitter::CreateInstance(LPUNKNOWN pUnk, HRESULT *phr)
  1038. {
  1039.     CUnknown *pUnkRet = new CT264Splitter(pUnk, phr);
  1040.     return pUnkRet;
  1041. }
  1042. //  Override type checking
  1043. HRESULT CT264Splitter::CheckInputType(const CMediaType *pmt)
  1044. {
  1045.     /*  We'll accept our preferred type or a wild card for the subtype */
  1046.     /*if (pmt->majortype != MEDIATYPE_Stream ||
  1047.         pmt->subtype != MEDIASUBTYPE_NULL) {
  1048.             return S_FALSE;
  1049.         } else {
  1050.             return S_OK;
  1051.         }*/
  1052.     // Async. source filter just send majortype equal null
  1053.     return S_OK;
  1054. }
  1055. LPAMOVIESETUP_FILTER CT264Splitter::GetSetupData()
  1056. {
  1057.     return (LPAMOVIESETUP_FILTER)&subDST264Splitter;
  1058. }
  1059. /*  Complete connection and instantiate parser
  1060. This involves:
  1061. Instatiate the parser with for the type and have it check the format
  1062. */
  1063. CBaseParser *CT264Splitter::CreateParser(
  1064.     CParserNotify *pNotify,
  1065.     CMediaType *pType
  1066.     )
  1067. {
  1068.     HRESULT hr = S_OK;
  1069.     return new CT264Parser(pNotify, &hr);
  1070. }
  1071. /*  Cheap'n nasty parser - DON'T do yours like this! */
  1072. /*  Initialize a parser
  1073. pmt     - type of stream if known - can be NULL
  1074. pRdr    - way to read the source medium - can be NULL
  1075. */
  1076. HRESULT CT264Parser::Init(CParseReader *pRdr)
  1077. {
  1078.     const DWORD dwLen = 128;
  1079.     /*  Just read 32K and look for interesting stuff */
  1080.     PBYTE pbData = new BYTE[dwLen];
  1081.     if (pbData == NULL) {
  1082.         return E_OUTOFMEMORY;
  1083.     }
  1084.     HRESULT hr = pRdr->Read(pbData, dwLen);
  1085.     if (S_OK != hr) {
  1086.         delete [] pbData;
  1087.         return hr;
  1088.     }
  1089.     /*  Now just loop looking for start codes */
  1090.     DWORD dwLeft = dwLen;
  1091.     int is_t264 = 0;
  1092.     PBYTE pbCurrent = pbData;
  1093.     {
  1094.         DWORD dwCode = *(UNALIGNED DWORD *)pbCurrent;
  1095.         /*  Check if it's a valid start code */
  1096.         if (dwCode == 0x01000000) 
  1097.         {
  1098.             int run = 1;
  1099.             /*  Create the media type from the stream
  1100.             only support Payload streams for now
  1101.             */
  1102.             VIDEOINFO* pInfo;
  1103.             CMediaType cmt;
  1104.             cmt.InitMediaType();
  1105.             T264_t* t = T264dec_open();
  1106.             T264dec_buffer(t, pbData, dwLen);
  1107.             while (run)
  1108.             {
  1109.                 decoder_state_t state = T264dec_parse(t);
  1110.                 switch(state) 
  1111.                 {
  1112.                 case DEC_STATE_CUSTOM_SET:
  1113.                     is_t264 = true;
  1114.                     break;
  1115.                 case DEC_STATE_SEQ:
  1116.                     run = 0;
  1117.                     cmt.SetType(&MEDIATYPE_Video);
  1118.                     cmt.SetSubtype(&CLSID_T264SUBTYPE);
  1119.                     cmt.SetFormatType(&FORMAT_VideoInfo);
  1120.                     cmt.AllocFormatBuffer(sizeof(VIDEOINFO));
  1121.                     ZeroMemory(cmt.pbFormat, sizeof(VIDEOINFO));
  1122.                     pInfo = (VIDEOINFO*)cmt.Format();
  1123.                     pInfo->bmiHeader.biWidth = t->width;
  1124.                     pInfo->bmiHeader.biHeight = t->height;
  1125.                     pInfo->bmiHeader.biBitCount = 12;
  1126.                     pInfo->bmiHeader.biCompression = '462T';
  1127.                     pInfo->bmiHeader.biPlanes = 1;
  1128.                     pInfo->bmiHeader.biSizeImage  = GetBitmapSize(&pInfo->bmiHeader);
  1129.                     SetRectEmpty(&(pInfo->rcSource));
  1130.                     SetRectEmpty(&(pInfo->rcTarget));
  1131.                     cmt.SetVariableSize();
  1132.                     cmt.SetTemporalCompression(true);
  1133.                     if (t->aspect_ratio == 2)
  1134.                         pInfo->AvgTimePerFrame = 400000;
  1135.                     else
  1136.                         pInfo->AvgTimePerFrame = 333333;
  1137.                     break;
  1138.                 case DEC_STATE_SLICE:
  1139.                 case DEC_STATE_BUFFER:
  1140.                     ASSERT(false);
  1141.                     break;
  1142.                 case DEC_STATE_PIC:
  1143.                     break;
  1144.                 default:
  1145.                     /* do not care */
  1146.                     break;
  1147.                 }
  1148.             };
  1149.             T264dec_close(t);
  1150.             /*  Create our video stream */
  1151.             m_pNotify->CreateStream(L"Video", &m_Video.m_pNotify);
  1152.             m_Video.m_pNotify->AddMediaType(&cmt);
  1153.         }
  1154.     }
  1155.     delete [] pbData;
  1156.     if (!is_t264 || !m_Video.Initialized()) 
  1157.     {
  1158.         return VFW_E_TYPE_NOT_ACCEPTED;
  1159.     } 
  1160.     else 
  1161.     {
  1162.         return S_OK;
  1163.     }
  1164. }
  1165. /*  Get the size and count of buffers preferred based on the
  1166. actual content
  1167. */
  1168. void CT264Parser::GetSizeAndCount(LONG *plSize, LONG *plCount)
  1169. {
  1170.     *plSize = 32768;
  1171.     *plCount = 4;
  1172. }
  1173. /*  Call this to reinitialize for a new stream */
  1174. void CT264Parser::StreamReset()
  1175. {
  1176. }
  1177. /*  Call this to pass new stream data :
  1178. pbData        - pointer to data
  1179. lData         - length of data
  1180. plProcessed   - Amount of data consumed
  1181. */
  1182. HRESULT CT264Parser::Process(
  1183.                               const BYTE * pbData,
  1184.                               LONG lData,
  1185.                               LONG *plProcessed
  1186.                               )
  1187. {
  1188.     /*  Just loop processing packets until we run out of data
  1189.     We should do a lot more to sync up than just eat a start
  1190.     code !
  1191.     */
  1192.     // we do not to parse anything, the decoder do itself!
  1193.     m_Video.m_pNotify->SendSample(
  1194.         pbData,
  1195.         lData,
  1196.         0,
  1197.         false);
  1198.     *plProcessed = lData;
  1199. /*
  1200.     DWORD dwLeft = lData;
  1201.     const BYTE * pbCurrent = pbData;
  1202.     pbCurrent += 4;
  1203.     DWORD dwCode = 0xffffff00;
  1204.     BOOL bSend = false;
  1205.     DWORD dwSend = 0;
  1206.     while (dwLeft > 4) 
  1207.     {
  1208.         //  Find a start code 
  1209.         dwCode = (dwCode << 8) | (*pbCurrent ++);
  1210.         if (dwCode == 0x00000001)
  1211.         {
  1212.             m_Video.m_pNotify->SendSample(
  1213.                 pbData,
  1214.                 pbCurrent - pbData - 4,
  1215.                 0,
  1216.                 false);
  1217.             bSend = true;
  1218.             dwSend += pbCurrent - pbData - 4;
  1219.             pbData = pbCurrent - 4;
  1220.         }
  1221.         dwLeft --;
  1222.     }
  1223.     if (bSend)
  1224.     {
  1225.         *plProcessed = dwSend;
  1226.     }
  1227.     else
  1228.     {
  1229.         m_Video.m_pNotify->SendSample(
  1230.             pbData,
  1231.             lData,
  1232.             0,
  1233.             false);
  1234.         *plProcessed = lData;
  1235.     }
  1236.     */
  1237.     return S_OK;
  1238. }