--- branches/dev-api-4/xvidcore/dshow/src/CXvidDecoder.cpp 2004/01/02 13:18:28 1301 +++ branches/dev-api-4/xvidcore/dshow/src/CXvidDecoder.cpp 2004/02/28 07:24:34 1367 @@ -3,7 +3,7 @@ * XVID MPEG-4 VIDEO CODEC * - XviD Decoder part of the DShow Filter - * - * Copyright(C) 2002-2003 Peter Ross + * Copyright(C) 2002-2004 Peter Ross * * This program is free software ; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -19,7 +19,7 @@ * along with this program ; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * - * $Id: CXvidDecoder.cpp,v 1.1.2.8 2004-01-02 13:18:28 syskin Exp $ + * $Id: CXvidDecoder.cpp,v 1.1.2.19 2004-02-28 07:24:34 syskin Exp $ * ****************************************************************************/ @@ -60,21 +60,18 @@ #include "IXvidDecoder.h" #include "CXvidDecoder.h" #include "CAbout.h" +#include "config.h" +#include "debug.h" -// Externs defined here -PostProcessing_Settings PPSettings; - -int rgb_flip; - -bool USE_IYUV; -bool USE_YV12; -bool USE_YUY2; -bool USE_YVYU; -bool USE_UYVY; -bool USE_RGB32; -bool USE_RGB24; -bool USE_RG555; -bool USE_RG565; +static bool USE_IYUV; +static bool USE_YV12; +static bool USE_YUY2; +static bool USE_YVYU; +static bool USE_UYVY; +static bool USE_RGB32; +static bool USE_RGB24; +static bool USE_RG555; +static bool USE_RG565; const AMOVIESETUP_MEDIATYPE sudInputPinTypes[] = { @@ -84,6 +81,7 @@ { &MEDIATYPE_Video, &CLSID_DIVX_UC }, { &MEDIATYPE_Video, &CLSID_DX50 }, { &MEDIATYPE_Video, &CLSID_DX50_UC }, + { &MEDIATYPE_Video, &CLSID_MP4V }, }; const AMOVIESETUP_MEDIATYPE sudOutputPinTypes[] = @@ -150,6 +148,8 @@ }; + +/* note: g_cTemplates must be global; used by strmbase.lib(dllentry.cpp,dllsetup.cpp) */ int g_cTemplates = sizeof(g_Templates) / sizeof(CFactoryTemplate); @@ -212,6 +212,8 @@ memset(&init, 0, sizeof(init)); init.version = XVID_VERSION; + ar_x = ar_y = 0; + m_hdll = LoadLibrary(XVID_DLL_NAME); if (m_hdll == NULL) { DPRINTF("dll load failed"); @@ -244,19 +246,7 @@ memset(&m_frame, 0, sizeof(m_frame)); m_frame.version = XVID_VERSION; - HKEY hKey; - DWORD size; - RegOpenKeyEx(XVID_REG_KEY, XVID_REG_SUBKEY, 0, KEY_READ, &hKey); - - // Set the default post-processing settings - REG_GET_N("Brightness", PPSettings.nBrightness, 25) - REG_GET_N("Deblock_Y", PPSettings.bDeblock_Y, 1) - REG_GET_N("Deblock_UV", PPSettings.bDeblock_UV, 1) - REG_GET_N("Dering", PPSettings.bDering, 1) - REG_GET_N("FilmEffect", PPSettings.bFilmEffect, 1) - REG_GET_N("ForceColorspace", PPSettings.nForceColorspace, 0) - - RegCloseKey(hKey); + LoadRegistryInfo(); USE_IYUV = false; USE_YV12 = false; @@ -268,7 +258,7 @@ USE_RG555 = false; USE_RG565 = false; - switch ( PPSettings.nForceColorspace ) + switch ( g_config.nForceColorspace ) { case FORCE_NONE: USE_IYUV = true; @@ -337,11 +327,20 @@ { VIDEOINFOHEADER * vih = (VIDEOINFOHEADER *) mtIn->Format(); hdr = &vih->bmiHeader; + /* PAR (x:y) is (1/ppm_X):(1/ppm_Y) where ppm is pixels-per-meter + which is equal to ppm_Y:ppm_X */ + ar_x = vih->bmiHeader.biYPelsPerMeter * abs(hdr->biWidth); + ar_y = vih->bmiHeader.biXPelsPerMeter * abs(hdr->biHeight); + DPRINTF("VIDEOINFOHEADER PAR: %d:%d -> AR %d:%d", + vih->bmiHeader.biYPelsPerMeter,vih->bmiHeader.biXPelsPerMeter, ar_x, ar_y); } else if (*mtIn->FormatType() == FORMAT_VideoInfo2) { VIDEOINFOHEADER2 * vih2 = (VIDEOINFOHEADER2 *) mtIn->Format(); hdr = &vih2->bmiHeader; + ar_x = vih2->dwPictAspectRatioX; + ar_y = vih2->dwPictAspectRatioY; + DPRINTF("VIDEOINFOHEADER2 AR: %d:%d", ar_x, ar_y); } else { @@ -359,10 +358,18 @@ switch(hdr->biCompression) { + + case FOURCC_MP4V: + if (!(g_config.supported_4cc & SUPPORT_MP4V)) return VFW_E_TYPE_NOT_ACCEPTED; + break; + case FOURCC_DIVX : + if (!(g_config.supported_4cc & SUPPORT_DIVX)) return VFW_E_TYPE_NOT_ACCEPTED; + break; + case FOURCC_DX50 : + if (!(g_config.supported_4cc & SUPPORT_DX50)) return VFW_E_TYPE_NOT_ACCEPTED; case FOURCC_XVID : -// case FOURCC_DIVX : -// case FOURCC_DX50 : break; + default : DPRINTF("Unknown fourcc: 0x%08x (%c%c%c%c)", @@ -373,7 +380,6 @@ (hdr->biCompression>>24)&0xff); return VFW_E_TYPE_NOT_ACCEPTED; } - return S_OK; } @@ -383,6 +389,7 @@ HRESULT CXvidDecoder::GetMediaType(int iPosition, CMediaType *mtOut) { + BITMAPINFOHEADER * bmih; DPRINTF("GetMediaType"); if (m_pInput->IsConnected() == FALSE) @@ -390,94 +397,111 @@ return E_UNEXPECTED; } - VIDEOINFOHEADER * vih = (VIDEOINFOHEADER *) mtOut->ReallocFormatBuffer(sizeof(VIDEOINFOHEADER)); - if (vih == NULL) - { - return E_OUTOFMEMORY; - } + if (!g_config.videoinfo_compat) { + VIDEOINFOHEADER2 * vih = (VIDEOINFOHEADER2 *) mtOut->ReallocFormatBuffer(sizeof(VIDEOINFOHEADER2)); + if (vih == NULL) return E_OUTOFMEMORY; + + ZeroMemory(vih, sizeof (VIDEOINFOHEADER2)); + bmih = &(vih->bmiHeader); + mtOut->SetFormatType(&FORMAT_VideoInfo2); + + if (ar_x != 0 && ar_y != 0) { + vih->dwPictAspectRatioX = ar_x; + vih->dwPictAspectRatioY = ar_y; + } else { // just to be safe + vih->dwPictAspectRatioX = m_create.width; + vih->dwPictAspectRatioY = abs(m_create.height); + } - ZeroMemory(vih, sizeof (VIDEOINFOHEADER)); - vih->bmiHeader.biSize = sizeof(BITMAPINFOHEADER); - vih->bmiHeader.biWidth = m_create.width; - vih->bmiHeader.biHeight = m_create.height; - vih->bmiHeader.biPlanes = 1; + } else { - if (iPosition < 0) - { - return E_INVALIDARG; + VIDEOINFOHEADER * vih = (VIDEOINFOHEADER *) mtOut->ReallocFormatBuffer(sizeof(VIDEOINFOHEADER)); + if (vih == NULL) return E_OUTOFMEMORY; + + ZeroMemory(vih, sizeof (VIDEOINFOHEADER2)); + bmih = &(vih->bmiHeader); + mtOut->SetFormatType(&FORMAT_VideoInfo); } + bmih->biSize = sizeof(BITMAPINFOHEADER); + bmih->biWidth = m_create.width; + bmih->biHeight = m_create.height; + bmih->biPlanes = 1; + + if (iPosition < 0) return E_INVALIDARG; + switch(iPosition) { - case 0 : -if ( USE_IYUV ) -{ - vih->bmiHeader.biCompression = CLSID_MEDIASUBTYPE_IYUV.Data1; - vih->bmiHeader.biBitCount = 12; - mtOut->SetSubtype(&CLSID_MEDIASUBTYPE_IYUV); - break; -} - case 1 : -if ( USE_YV12 ) -{ - vih->bmiHeader.biCompression = MEDIASUBTYPE_YV12.Data1; - vih->bmiHeader.biBitCount = 12; - mtOut->SetSubtype(&MEDIASUBTYPE_YV12); - break; -} - case 2: + + case 0: if ( USE_YUY2 ) { - vih->bmiHeader.biCompression = MEDIASUBTYPE_YUY2.Data1; - vih->bmiHeader.biBitCount = 16; + bmih->biCompression = MEDIASUBTYPE_YUY2.Data1; + bmih->biBitCount = 16; mtOut->SetSubtype(&MEDIASUBTYPE_YUY2); break; } - case 3 : + case 1 : if ( USE_YVYU ) { - vih->bmiHeader.biCompression = MEDIASUBTYPE_YVYU.Data1; - vih->bmiHeader.biBitCount = 16; + bmih->biCompression = MEDIASUBTYPE_YVYU.Data1; + bmih->biBitCount = 16; mtOut->SetSubtype(&MEDIASUBTYPE_YVYU); break; } - case 4 : + case 2 : if ( USE_UYVY ) { - vih->bmiHeader.biCompression = MEDIASUBTYPE_UYVY.Data1; - vih->bmiHeader.biBitCount = 16; + bmih->biCompression = MEDIASUBTYPE_UYVY.Data1; + bmih->biBitCount = 16; mtOut->SetSubtype(&MEDIASUBTYPE_UYVY); break; } + case 3 : + if ( USE_IYUV ) +{ + bmih->biCompression = CLSID_MEDIASUBTYPE_IYUV.Data1; + bmih->biBitCount = 12; + mtOut->SetSubtype(&CLSID_MEDIASUBTYPE_IYUV); + break; +} + case 4 : +if ( USE_YV12 ) +{ + bmih->biCompression = MEDIASUBTYPE_YV12.Data1; + bmih->biBitCount = 12; + mtOut->SetSubtype(&MEDIASUBTYPE_YV12); + break; +} case 5 : if ( USE_RGB32 ) { - vih->bmiHeader.biCompression = BI_RGB; - vih->bmiHeader.biBitCount = 32; + bmih->biCompression = BI_RGB; + bmih->biBitCount = 32; mtOut->SetSubtype(&MEDIASUBTYPE_RGB32); break; } case 6 : if ( USE_RGB24 ) { - vih->bmiHeader.biCompression = BI_RGB; - vih->bmiHeader.biBitCount = 24; + bmih->biCompression = BI_RGB; + bmih->biBitCount = 24; mtOut->SetSubtype(&MEDIASUBTYPE_RGB24); break; } case 7 : if ( USE_RG555 ) { - vih->bmiHeader.biCompression = BI_RGB; - vih->bmiHeader.biBitCount = 16; + bmih->biCompression = BI_RGB; + bmih->biBitCount = 16; mtOut->SetSubtype(&MEDIASUBTYPE_RGB555); break; } case 8 : if ( USE_RG565 ) { - vih->bmiHeader.biCompression = BI_RGB; - vih->bmiHeader.biBitCount = 16; + bmih->biCompression = BI_RGB; + bmih->biBitCount = 16; mtOut->SetSubtype(&MEDIASUBTYPE_RGB565); break; } @@ -485,12 +509,11 @@ return VFW_S_NO_MORE_ITEMS; } - vih->bmiHeader.biSizeImage = GetBitmapSize(&vih->bmiHeader); + bmih->biSizeImage = GetBitmapSize(bmih); mtOut->SetType(&MEDIATYPE_Video); - mtOut->SetFormatType(&FORMAT_VideoInfo); mtOut->SetTemporalCompression(FALSE); - mtOut->SetSampleSize(vih->bmiHeader.biSizeImage); + mtOut->SetSampleSize(bmih->biSizeImage); return S_OK; } @@ -520,28 +543,33 @@ if (subtype == CLSID_MEDIASUBTYPE_IYUV) { DPRINTF("IYUV"); + rgb_flip = 0; m_frame.output.csp = XVID_CSP_I420; m_frame.output.stride[0] = (m_frame.output.stride[0] * 2) / 3; /* planar format fix */ } else if (subtype == MEDIASUBTYPE_YV12) { DPRINTF("YV12"); + rgb_flip = 0; m_frame.output.csp = XVID_CSP_YV12; m_frame.output.stride[0] = (m_frame.output.stride[0] * 2) / 3; /* planar format fix */ } else if (subtype == MEDIASUBTYPE_YUY2) { DPRINTF("YUY2"); + rgb_flip = 0; m_frame.output.csp = XVID_CSP_YUY2; } else if (subtype == MEDIASUBTYPE_YVYU) { DPRINTF("YVYU"); + rgb_flip = 0; m_frame.output.csp = XVID_CSP_YVYU; } else if (subtype == MEDIASUBTYPE_UYVY) { DPRINTF("UYVY"); + rgb_flip = 0; m_frame.output.csp = XVID_CSP_UYVY; } else if (subtype == MEDIASUBTYPE_RGB32) @@ -687,30 +715,20 @@ if (pIn->IsDiscontinuity() == S_OK) m_frame.general = XVID_DISCONTINUITY; - if (PPSettings.bDeblock_Y) + if (g_config.nDeblock_Y) m_frame.general |= XVID_DEBLOCKY; - if (PPSettings.bDeblock_UV) + if (g_config.nDeblock_UV) m_frame.general |= XVID_DEBLOCKUV; /* - if (PPSettings.bDering) + if (g_config.nDering) m_frame.general |= XVID_DERING; */ - if (PPSettings.bFilmEffect) + if (g_config.nFilmEffect) m_frame.general |= XVID_FILMEFFECT; - if (PPSettings.bFlipVideo) { - if (rgb_flip) - m_frame.output.csp &= ~XVID_CSP_VFLIP; - else - m_frame.output.csp |= XVID_CSP_VFLIP; - } - else { - if (rgb_flip) - m_frame.output.csp |= XVID_CSP_VFLIP; - else - m_frame.output.csp &= ~XVID_CSP_VFLIP; - } + m_frame.output.csp &= ~XVID_CSP_VFLIP; + m_frame.output.csp |= rgb_flip^(g_config.nFlipVideo ? XVID_CSP_VFLIP : 0); repeat : @@ -748,7 +766,7 @@ m_frame.general = tmp_gen; } - if (stats.type == XVID_TYPE_NOTHING) { + if (stats.type == XVID_TYPE_NOTHING && length > 0) { DPRINTF("B-Frame decoder lag"); return S_FALSE; } @@ -763,7 +781,7 @@ return S_FALSE; } - pOut->SetDiscontinuity(TRUE); +// pOut->SetDiscontinuity(TRUE); pOut->SetSyncPoint(TRUE); m_frame.bitstream = (BYTE*)m_frame.bitstream + length; @@ -774,7 +792,7 @@ if (pIn->IsPreroll() == S_OK) { return S_FALSE; } - + return S_OK; }