

    fW^fvO

                                            fW^ZpJ@\


 Tv

  fW^fvÓAp[\iRs[^̔ėp
  OS ɂāAfW^̉fsvO̎ړIŔЕz
  錤łB

  ̎ MPEG-2 f𕜍邽߂̊{Iȋ@\ĂB
  CAS ͎ĂȂ߁Aʂ̃er̎ɗp邱Ƃ͂łȂB


 ӎ

  C^[tF[X GUID ύXꂽ߁A0.3.0 Õo[WCXg[
  Ă 0.3.0 ̃o[WɍXVۂɂ́AxOo[W
  ACXg[sAt@C̍XVɉ߂ăCXg[KvB

  ̃fR[_͂܂Jrɂ̂ŁAC^[tF[XpɂɕύX\
  B̂߃CXg[sȂŗpꍇ́ATVTest 
  ITVTestVideoDecoder.h ̐ƂȂΐɓ삵ȂB


 

  EOS
      Windows Vista/7/8/10/11

  ECPU
      SSE2 Ή CPU
      SSE2 Ή CPU ł삷͂ASIMD g߂؎gȂ


 \z

  Visual Studio 2019 ̃vWFNgt@CYtĂB

  src tH_̃\[Vt@C(.sln) Visual Studio ŊJărh
  邱ƂłBȉ̃\[Vt@CYtĂB

  ETVTestVideoDecoder.sln  Visual C++ 2019


 @

  TVTestVideoDecoder.ax  TVTest.exe ƓtH_ɔzuƁAMPEG-2 fR[
  _ƂđIł悤ɂȂB

  ʏ DirectShow tB^ƓlɁAregsvr32 ŃCXg[邱Ƃ\ł
  BCXg[/ACXg[͊ǗҌōsKvB

  CXg[
    regsvr32 TVTestVideoDecoder.ax

  ACXg[
    regsvr32 /u TVTestVideoDecoder.ax

  CXg[ĎgpƃWXg̈ȉ̃L[ɐݒ肪ۑB
    HKEY_CURRENT_USER\Software\DBCTRADO\TVTest DTV Video Decoder
  ȉ̃R}hŐݒ폜邱ƂłB
    rundll32 TVTestVideoDecoder.ax,Uninstall

  CXg[sꍇɂĂATVTest ̃tH_ TVTestVideoDecoder.ax
  zuĂ΂炪D悵ėpB

  TVTest ̃j[́utB^̃voeBvuffR[_vIƁA
  ݒsƂłB


 ݒ荀

  tB^̃vpeBł̐ݒsƂłB

  EfR[_
    gpfR[_IB
    ̐ݒ𔽉fɂ́AvO̍ċNtB^OtďsB
    IłfR[_͈ȉ̂ꂩłB

    E\tgEFA
      \tgEFAfR[_gpBfR[h CPU ɂčsB

    EDXVA2 (EVR p̂)
      DXVA2 (DirectX Video Acceleration 2) ɂfR[hsB
      _ EVR IĂāAGPU  MPEG-2  VLD (Variable-Length
      Decoding) [hɑΉĂKvB

    ED3D11 (Windows 8 ȍ~)
      Direct3D 11 ɂfR[hsB
      GPU  MPEG-2  VLD (Variable-Length Decoding) [hɑΉĂKv
      B

  EC^[[Xs
  EC^[[XsȂ
    C^[[X̃fR[_tB^ɂčsǂw肷B

  EC^[[X@
    C^[[XɗpASYIB

  EvObVuK
  EeVlK
    t[vObVułꍇeVlsĂ鎞AC^[[
    X@̐ݒ𖳎 Weave  Blend pB

  EC^[[XtOݒ肷
    _Ƀt[C^[[Xł邱Ƃm点BC^[[X
    s邩Aǂ̂悤ȕ@ɂs邩̓_ɈˑB

  EF␳
    F␳sB

  EXbh
    fR[hsXbhw肷B
    uvIƁACPU ̃RAɉăXbh肳B
    ̐ݒ̓\tgEFAɂfR[ĥݗLłB

  ED3D11 xt[
    D3D11 ł̃fR[hɁAfR[ht[_ɑM܂łɉt
    [x邩w肷B
    ̐ȉ߂ƁAGPU ̏ptH[}XቺB
    ̐ݒ𔽉fɂ́AvO̍ċNtB^OtďsB


 fR[_EC^[tF[X̗p

  TVTestVideoDecoder.ax ł͈ȉ2ނ̃fR[_EC^[tF[X񋟂B

  EITVTestVideoDecoder
      DirectShow tB^EfR[_

  EITVTestVideoFrameDecoder
      PƃfR[_

  ̃C^[tF[X́AITVTestVideoDecoder.h Œ`ĂB
  ̃fR[_ATVTestVideoDecoder_CreateInstance ֐ĂяoCX^
  X쐬ėpB

  ITVTestVideoDecoder ́AQueryInterface ɂ IBaseFilter 擾
  DirectShow tB^ƂėpB

  ITVTestVideoFrameDecoder ́AITVTestVideoDecoderFrameCapture 邱
  ƂɂAfR[hꂽ摜擾łB
  ITVTestVideoFrameDecoder ̗p̗ȉɎB
  ȂAG[͏ȗĂB

    // fR[hꂽt[擾NX
    class CMyFrameCapture : public ITVTestVideoDecoderFrameCapture
    {
      LONG m_RefCount = 0;

    public:
      // IUnknown 
      STDMETHODIMP_(ULONG) AddRef() override
      {
        return InterlockedIncrement(&m_RefCount);
      }
      STDMETHODIMP_(ULONG) Release() override
      {
        LONG Count = InterlockedDecrement(&m_RefCount);
        if (Count == 0) delete this;
        return Count;
      }
      STDMETHODIMP QueryInterface(REFIID riid, void **ppvObject) override
      {
        if (riid == __uuidof(ITVTestVideoDecoderFrameCapture)) {
          *ppvObject = static_cast<ITVTestVideoDecoderFrameCapture*>(this);
        } else if (riid == IID_IUnknown) {
          *ppvObject = static_cast<IUnknown*>(this);
        } else {
          *ppvObject = nullptr;
          return E_NOINTERFACE;
        }
        AddRef();
        return S_OK;
      }

      // t[擾֐
      STDMETHODIMP OnFrame(const TVTVIDEODEC_FrameInfo *pFrameInfo) override
      {
        if (pFrameInfo->Subtype == MEDIASUBTYPE_RGB32) {
          // RGB 32-bit
          // pFrameInfo->Buffer[0][(y * pFrameInfo->Pitch[0]) + (x * 4) + 0] == B
          // pFrameInfo->Buffer[0][(y * pFrameInfo->Pitch[0]) + (x * 4) + 1] == G
          // pFrameInfo->Buffer[0][(y * pFrameInfo->Pitch[0]) + (x * 4) + 2] == R
        } else if (pFrameInfo->Subtype == MEDIASUBTYPE_IYUV) {
          // YUV 4:2:0
          // pFrameInfo->Buffer[0][(y * pFrameInfo->Pitch[0]) + x]             == Y
          // pFrameInfo->Buffer[1][((y / 2) * pFrameInfo->Pitch[1]) + (x / 2)] == U
          // pFrameInfo->Buffer[2][((y / 2) * pFrameInfo->Pitch[2]) + (x / 2)] == V
        }
        // t[擾֐G[ԂƁAŃfR[h~
        return S_OK;
      }
    };

    // Cu[hACX^X쐬֐擾
    HMODULE hLib = LoadLibraryW(L"TVTestVideoDecoder.ax");
    auto pCreateInstance =
      reinterpret_cast<decltype(TVTestVideoDecoder_CreateInstance) *>(
        GetProcAddress(hLib, "TVTestVideoDecoder_CreateInstance"));

    // fR[_̃CX^X쐬
    ITVTestVideoFrameDecoder *pDecoder;
    pCreateInstance(IID_PPV_ARGS(&pDecoder));

    // Lv`EC^[tF[Xݒ肷
    // 擾摜̃tH[}bgƂāAȉ̂ꂩwł
    // MEDIASUBTYPE_RGB24 / MEDIASUBTYPE_RGB32 / MEDIASUBTYPE_IYUV / MEDIASUBTYPE_I420
    CMyFrameCapture *pFrameCapture = new CMyFrameCapture;
    pDecoder->SetFrameCapture(pFrameCapture, MEDIASUBTYPE_RGB32);

    // fR[_J
    pDecoder->Open(MEDIASUBTYPE_MPEG2_VIDEO);

    while ( ... ) {
      ...
      // fR[_ɃXg[͂
      // t[fR[hxɁAOnFrame Ăяo
      pDecoder->InputStream(PointerToData, SizeOfData);
    }

    // fR[_AC^[tF[X
    pDecoder->Close();
    pDecoder->Release();

    // Cu
    FreeLibrary(hLib);


 ݂̐

  EDXVA2 ̃fR[h́AsN`\t[łȂꍇɑΉĂȂB


 gpCu

  ͈̎ȉ̃Cu𗘗pĂB

    DirectShow BaseClasses
      Copyright (c) Microsoft Corporation
      https://github.com/Microsoft/Windows-classic-samples/tree/master/Samples/Win7Samples/multimedia/directshow/baseclasses

    libmpeg2 0.5.1
      Copyright (C) 2000-2004 Michel Lespinasse
      Copyright (C) 1999-2000 Aaron Holtzman

  libmpeg2 ɂ͎Ɉȉ̉ςsĂB

  EXCX̃fR[h}`Xbhōs悤ɂB
  ESSE2  IDCT yѓ⏞CgVbN֐ŎB
  ELɔ IDCT xύXꂽ߂ɁAIWi IDCT AZuR[h
    ͖ɂȂĂB
  Eobt@I[o[t[h~邽߂̋E`FbNǉB
  EDXVA ŗp邽߂ɕKvȃoǉAXCX̃R[obN֐o^
    悤ɂB


 L

  E̎ GPLv3 ɏ]ĔЕzB
  E̎̎gpyюgps\ɂĐȂ鑹Q⏞ȂB


 Еz

  https://github.com/DBCTRADO/TVTestVideoDecoder

