Added GPU based deinterlacing and refactored interlacing code

Added deinterlacing modes:
- Blend (GPU)
- Linear (GPU)
- Yadif (GPU)
each with source framerate and double source framerate mode.
Also added GPU based Retro deinterlacing
master
palana 2013-07-09 01:20:26 +02:00
parent 796a5b43c2
commit 7c29a61324
16 changed files with 801 additions and 134 deletions

View File

@ -30,6 +30,19 @@ extern "C" __declspec(dllexport) CTSTR GetPluginDescription();
LocaleStringLookup *pluginLocale = NULL;
HINSTANCE hinstMain = NULL;
extern DeinterlacerConfig deinterlacerConfigs[DEINTERLACING_TYPE_LAST];
CTSTR deinterlacerLocalizations[DEINTERLACING_TYPE_LAST] = {
TEXT("DeinterlacingType.None"),
TEXT("DeinterlacingType.Discard"),
TEXT("DeinterlacingType.Retro"),
TEXT("DeinterlacingType.Blend"),
TEXT("DeinterlacingType.Blend2x"),
TEXT("DeinterlacingType.Linear"),
TEXT("DeinterlacingType.Linear2x"),
TEXT("DeinterlacingType.Yadif"),
TEXT("DeinterlacingType.Yadif2x"),
TEXT("DeinterlacingType.Debug")
};
#define DSHOW_CLASSNAME TEXT("DeviceCapture")
@ -987,7 +1000,7 @@ INT_PTR CALLBACK ConfigureDialogProc(HWND hwnd, UINT message, WPARAM wParam, LPA
static bool bSelectingColor = false;
static bool bMouseDown = false, bAudioDevicesPresent = true;
static ColorSelectionData colorData;
static BYTE deinterlacingType;
static DeinterlacerConfig deinterlacingConfig;
switch(message)
{
@ -1021,13 +1034,13 @@ INT_PTR CALLBACK ConfigureDialogProc(HWND hwnd, UINT message, WPARAM wParam, LPA
int gammaVal = configData->data->GetInt(TEXT("gamma"), 100);
HWND hwndTemp = GetDlgItem(hwnd, IDC_GAMMA2);
HWND hwndTemp = GetDlgItem(hwnd, IDC_GAMMA);
SendMessage(hwndTemp, TBM_CLEARTICS, FALSE, 0);
SendMessage(hwndTemp, TBM_SETRANGE, FALSE, MAKELPARAM(50, 175));
SendMessage(hwndTemp, TBM_SETTIC, 0, 100);
SendMessage(hwndTemp, TBM_SETPOS, TRUE, gammaVal);
SetSliderText(hwnd, IDC_GAMMA2, IDC_GAMMAVAL);
SetSliderText(hwnd, IDC_GAMMA, IDC_GAMMAVAL);
//------------------------------------------
@ -1037,17 +1050,58 @@ INT_PTR CALLBACK ConfigureDialogProc(HWND hwnd, UINT message, WPARAM wParam, LPA
UINT cy = configData->data->GetInt(TEXT("resolutionHeight"));
UINT64 frameInterval = configData->data->GetInt(TEXT("frameInterval"));
//------------------------------------------
deinterlacingConfig.type = configData->data->GetInt(TEXT("deinterlacingType"));
deinterlacingConfig.fieldOrder = configData->data->GetInt(TEXT("deinterlacingFieldOrder"));
deinterlacingConfig.processor = configData->data->GetInt(TEXT("deinterlacingProcessor"));
if(deinterlacingConfig.type >= DEINTERLACING_TYPE_LAST)
deinterlacingConfig.type = DEINTERLACING_NONE;
hwndTemp = GetDlgItem(hwnd, IDC_DEINTERLACELIST);
// Populate deinterlacing type list like this, since there's only one for now.
// Actually, there's more than one, but uhh...
SendMessage(hwndTemp, CB_ADDSTRING, 0, (LPARAM)pluginLocale->LookupString(L"DeinterlacingType.None"));
SendMessage(hwndTemp, CB_ADDSTRING, 0, (LPARAM)pluginLocale->LookupString(L"DeinterlacingType.Discard"));
SendMessage(hwndTemp, CB_ADDSTRING, 0, (LPARAM)pluginLocale->LookupString(L"DeinterlacingType.RetroTFF"));
SendMessage(hwndTemp, CB_ADDSTRING, 0, (LPARAM)pluginLocale->LookupString(L"DeinterlacingType.RetroBFF"));
// Populate deinterlacing type list
for(size_t i = 0; i < DEINTERLACING_TYPE_LAST; i++)
{
#ifndef _DEBUG
if(i == DEINTERLACING__DEBUG)
continue;
#endif
SendMessage(hwndTemp, CB_ADDSTRING, 0, (LPARAM)pluginLocale->LookupString(deinterlacerLocalizations[i]));
deinterlacingType = configData->data->GetInt(TEXT("deinterlacingType"));
SendMessage(hwndTemp, CB_SETCURSEL, deinterlacingType, 0);
DeinterlacerConfig& config = deinterlacerConfigs[i];
if(deinterlacingConfig.type != config.type)
continue;
const int deintProcBoth = (DEINTERLACING_PROCESSOR_CPU | DEINTERLACING_PROCESSOR_GPU);
HWND checkbox = GetDlgItem(hwnd, IDC_GPUDEINT);
EnableWindow(checkbox, config.processor == deintProcBoth);
if(config.processor != deintProcBoth && deinterlacingConfig.processor != config.processor)
{
configData->data->SetInt(TEXT("deinterlacingGPU"), config.processor);
deinterlacingConfig.processor = config.processor;
}
Button_SetCheck(checkbox, deinterlacingConfig.processor == DEINTERLACING_PROCESSOR_GPU);
const int deintFieldsBoth = (FIELD_ORDER_TFF | FIELD_ORDER_BFF);
HWND tff = GetDlgItem(hwnd, IDC_TFF),
bff = GetDlgItem(hwnd, IDC_BFF);
if(config.fieldOrder != deintFieldsBoth && deinterlacingConfig.fieldOrder != config.fieldOrder)
{
configData->data->SetInt(TEXT("deinterlacingFieldOrder"), config.fieldOrder);
deinterlacingConfig.fieldOrder = config.fieldOrder;
}
Button_SetCheck(tff, deinterlacingConfig.fieldOrder == FIELD_ORDER_TFF);
Button_SetCheck(bff, deinterlacingConfig.fieldOrder == FIELD_ORDER_BFF);
EnableWindow(tff, config.fieldOrder & FIELD_ORDER_TFF);
EnableWindow(bff, config.fieldOrder & FIELD_ORDER_BFF);
}
SendMessage(hwndTemp, CB_SETCURSEL, deinterlacingConfig.type, 0);
//------------------------------------------
BOOL bCustomResolution = configData->data->GetInt(TEXT("customResolution"));
SendMessage(GetDlgItem(hwnd, IDC_CUSTOMRESOLUTION), BM_SETCHECK, bCustomResolution ? BST_CHECKED : BST_UNCHECKED, 0);
@ -1246,9 +1300,9 @@ INT_PTR CALLBACK ConfigureDialogProc(HWND hwnd, UINT message, WPARAM wParam, LPA
case WM_HSCROLL:
{
if(GetDlgCtrlID((HWND)lParam) == IDC_GAMMA2)
if(GetDlgCtrlID((HWND)lParam) == IDC_GAMMA)
{
int gamma = SetSliderText(hwnd, IDC_GAMMA2, IDC_GAMMAVAL);
int gamma = SetSliderText(hwnd, IDC_GAMMA, IDC_GAMMAVAL);
ConfigDialogData *info = (ConfigDialogData*)GetWindowLongPtr(hwnd, DWLP_USER);
ImageSource *source = API->GetSceneImageSource(info->lpName);
@ -1448,7 +1502,37 @@ INT_PTR CALLBACK ConfigureDialogProc(HWND hwnd, UINT message, WPARAM wParam, LPA
case IDC_DEINTERLACELIST:
if(HIWORD(wParam) == CBN_SELCHANGE)
{
deinterlacingType = (BYTE)SendMessage(GetDlgItem(hwnd, IDC_DEINTERLACELIST), CB_GETCURSEL, 0, 0);
ConfigDialogData *configData = (ConfigDialogData*)GetWindowLongPtr(hwnd, DWLP_USER);;
int confId = (int)SendMessage(GetDlgItem(hwnd, IDC_DEINTERLACELIST), CB_GETCURSEL, 0, 0);
deinterlacingConfig.type = configData->data->GetInt(TEXT("deinterlacingType"));
deinterlacingConfig.fieldOrder = configData->data->GetInt(TEXT("deinterlacingFieldOrder"));
deinterlacingConfig.processor = configData->data->GetInt(TEXT("deinterlacingGPU"));
if(deinterlacingConfig.type >= DEINTERLACING_TYPE_LAST)
deinterlacingConfig.type = DEINTERLACING_NONE;
DeinterlacerConfig& config = deinterlacerConfigs[confId];
const int deintProcBoth = (DEINTERLACING_PROCESSOR_CPU | DEINTERLACING_PROCESSOR_GPU);
HWND checkbox = GetDlgItem(hwnd, IDC_GPUDEINT);
EnableWindow(checkbox, config.processor == deintProcBoth);
if(config.processor != deintProcBoth && deinterlacingConfig.processor != config.processor)
deinterlacingConfig.processor = config.processor;
Button_SetCheck(checkbox, deinterlacingConfig.processor == DEINTERLACING_PROCESSOR_GPU);
const int deintFieldsBoth = (FIELD_ORDER_TFF | FIELD_ORDER_BFF);
HWND tff = GetDlgItem(hwnd, IDC_TFF),
bff = GetDlgItem(hwnd, IDC_BFF);
if(config.fieldOrder != deintFieldsBoth && deinterlacingConfig.fieldOrder != config.fieldOrder)
deinterlacingConfig.fieldOrder = config.fieldOrder;
else if(deinterlacingConfig.fieldOrder != config.fieldOrder && (config.fieldOrder & deinterlacingConfig.fieldOrder) == 0)
deinterlacingConfig.fieldOrder = config.fieldOrder & FIELD_ORDER_TFF ? FIELD_ORDER_TFF : FIELD_ORDER_BFF;
Button_SetCheck(tff, deinterlacingConfig.fieldOrder == FIELD_ORDER_TFF);
Button_SetCheck(bff, deinterlacingConfig.fieldOrder == FIELD_ORDER_BFF);
EnableWindow(tff, config.fieldOrder & FIELD_ORDER_TFF);
EnableWindow(bff, config.fieldOrder & FIELD_ORDER_BFF);
}
break;
@ -1878,7 +1962,12 @@ INT_PTR CALLBACK ConfigureDialogProc(HWND hwnd, UINT message, WPARAM wParam, LPA
BOOL bCustomResolution = SendMessage(GetDlgItem(hwnd, IDC_CUSTOMRESOLUTION), BM_GETCHECK, 0, 0) == BST_CHECKED;
BOOL bUsePointFiltering = SendMessage(GetDlgItem(hwnd, IDC_POINTFILTERING), BM_GETCHECK, 0, 0) == BST_CHECKED;
deinterlacingType = (BYTE)SendMessage(GetDlgItem(hwnd, IDC_DEINTERLACELIST), CB_GETCURSEL, 0, 0);
int deintId = (int)SendMessage(GetDlgItem(hwnd, IDC_DEINTERLACELIST), CB_GETCURSEL, 0, 0);
deinterlacingConfig = deinterlacerConfigs[deintId];
bool tff = SendMessage(GetDlgItem(hwnd, IDC_TFF), BM_GETCHECK, 0, 0) == BST_CHECKED,
bff = SendMessage(GetDlgItem(hwnd, IDC_BFF), BM_GETCHECK, 0, 0) == BST_CHECKED;
deinterlacingConfig.fieldOrder = tff ? FIELD_ORDER_TFF : (bff ? FIELD_ORDER_BFF : FIELD_ORDER_NONE);
deinterlacingConfig.processor = SendMessage(GetDlgItem(hwnd, IDC_GPUDEINT), BM_GETCHECK, 0, 0) == BST_CHECKED ? DEINTERLACING_PROCESSOR_GPU : DEINTERLACING_PROCESSOR_CPU;
configData->data->SetString(TEXT("device"), strDevice);
configData->data->SetString(TEXT("deviceName"), configData->deviceNameList[deviceID]);
@ -1887,12 +1976,16 @@ INT_PTR CALLBACK ConfigureDialogProc(HWND hwnd, UINT message, WPARAM wParam, LPA
configData->data->SetInt(TEXT("customResolution"), bCustomResolution);
configData->data->SetInt(TEXT("resolutionWidth"), resolution.cx);
configData->data->SetInt(TEXT("resolutionHeight"), resolution.cy);
configData->data->SetInt(TEXT("deinterlacingType"), deinterlacingType);
configData->data->SetInt(TEXT("frameInterval"), UINT(frameInterval));
configData->data->SetInt(TEXT("flipImage"), bFlip);
configData->data->SetInt(TEXT("flipImageHorizontal"), bFlipHorizontal);
configData->data->SetInt(TEXT("usePointFiltering"), bUsePointFiltering);
configData->data->SetInt(TEXT("gamma"), (int)SendMessage(GetDlgItem(hwnd, IDC_GAMMA2), TBM_GETPOS, 0, 0));
configData->data->SetInt(TEXT("gamma"), (int)SendMessage(GetDlgItem(hwnd, IDC_GAMMA), TBM_GETPOS, 0, 0));
configData->data->SetInt(TEXT("deinterlacingType"), deinterlacingConfig.type);
configData->data->SetInt(TEXT("deinterlacingFieldOrder"), deinterlacingConfig.fieldOrder);
configData->data->SetInt(TEXT("deinterlacingProcessor"), deinterlacingConfig.processor);
configData->data->SetInt(TEXT("deinterlacingDoublesFramerate"), deinterlacingConfig.doublesFramerate);
//------------------------------------------
@ -1977,23 +2070,26 @@ INT_PTR CALLBACK ConfigureDialogProc(HWND hwnd, UINT message, WPARAM wParam, LPA
if(source)
{
source->SetInt(TEXT("bufferTime"), configData->data->GetInt(TEXT("bufferTime"), 0));
source->SetInt(TEXT("bufferTime"), configData->data->GetInt(TEXT("bufferTime"), 0));
source->SetInt(TEXT("timeOffset"), configData->data->GetInt(TEXT("soundTimeOffset"), 0));
source->SetFloat(TEXT("volume"), configData->data->GetFloat(TEXT("volume"), 1.0f));
source->SetInt(TEXT("timeOffset"), configData->data->GetInt(TEXT("soundTimeOffset"), 0));
source->SetFloat(TEXT("volume"), configData->data->GetFloat(TEXT("volume"), 1.0f));
source->SetInt(TEXT("flipImage"), configData->data->GetInt(TEXT("flipImage"), 0));
source->SetInt(TEXT("flipImageHorizontal"), configData->data->GetInt(TEXT("flipImageHorizontal"), 0));
source->SetInt(TEXT("usePointFiltering"), configData->data->GetInt(TEXT("usePointFiltering"), 0));
source->SetInt(TEXT("opacity"), configData->data->GetInt(TEXT("opacity"), 100));
source->SetInt(TEXT("flipImage"), configData->data->GetInt(TEXT("flipImage"), 0));
source->SetInt(TEXT("flipImageHorizontal"), configData->data->GetInt(TEXT("flipImageHorizontal"), 0));
source->SetInt(TEXT("usePointFiltering"), configData->data->GetInt(TEXT("usePointFiltering"), 0));
source->SetInt(TEXT("opacity"), configData->data->GetInt(TEXT("opacity"), 100));
source->SetInt(TEXT("useChromaKey"), configData->data->GetInt(TEXT("useChromaKey"), 0));
source->SetInt(TEXT("keyColor"), configData->data->GetInt(TEXT("keyColor"), 0xFFFFFFFF));
source->SetInt(TEXT("keySimilarity"), configData->data->GetInt(TEXT("keySimilarity"), 0));
source->SetInt(TEXT("keyBlend"), configData->data->GetInt(TEXT("keyBlend"), 80));
source->SetInt(TEXT("keySpillReduction"), configData->data->GetInt(TEXT("keySpillReduction"), 50));
source->SetInt(TEXT("gamma"), configData->data->GetInt(TEXT("gamma"), 100));
source->SetInt(TEXT("deinterlacingType"), configData->data->GetInt(TEXT("deinterlacingType"), 0));
source->SetInt(TEXT("useChromaKey"), configData->data->GetInt(TEXT("useChromaKey"), 0));
source->SetInt(TEXT("keyColor"), configData->data->GetInt(TEXT("keyColor"), 0xFFFFFFFF));
source->SetInt(TEXT("keySimilarity"), configData->data->GetInt(TEXT("keySimilarity"), 0));
source->SetInt(TEXT("keyBlend"), configData->data->GetInt(TEXT("keyBlend"), 80));
source->SetInt(TEXT("keySpillReduction"), configData->data->GetInt(TEXT("keySpillReduction"), 50));
source->SetInt(TEXT("gamma"), configData->data->GetInt(TEXT("gamma"), 100));
source->SetInt(TEXT("deinterlacingType"), configData->data->GetInt(TEXT("deinterlacingType"), 0));
source->SetInt(TEXT("deinterlacingFieldOrder"), configData->data->GetInt(TEXT("deinterlacingFieldOrder"), 0));
source->SetInt(TEXT("deinterlacingProcessor"), configData->data->GetInt(TEXT("deinterlacingProcessor"), 0));
source->SetInt(TEXT("deinterlacingDoublesFramerate"), configData->data->GetInt(TEXT("deinterlacingDoublesFramerate"), 0));
}
}

View File

@ -42,9 +42,32 @@ bool GetClosestResolutionFPS(List<MediaOutputInfo> &outputList, SIZE &resolution
extern LocaleStringLookup *pluginLocale;
#define PluginStr(text) pluginLocale->LookupString(TEXT2(text))
enum deinterLacingTypes {
deinterlacing_None,
deinterlacing_Discard,
deinterlacing_Retro_TFF,
deinterlacing_Retro_BFF,
enum DeinterlacingType {
DEINTERLACING_NONE,
DEINTERLACING_DISCARD,
DEINTERLACING_RETRO,
DEINTERLACING_BLEND,
DEINTERLACING_BLEND2x,
DEINTERLACING_LINEAR,
DEINTERLACING_LINEAR2x,
DEINTERLACING_YADIF,
DEINTERLACING_YADIF2x,
DEINTERLACING__DEBUG,
DEINTERLACING_TYPE_LAST
};
enum DeinterlacingFieldOrder {
FIELD_ORDER_NONE,
FIELD_ORDER_TFF = 1,
FIELD_ORDER_BFF,
};
enum DeinterlacingProcessor {
DEINTERLACING_PROCESSOR_CPU = 1,
DEINTERLACING_PROCESSOR_GPU,
};
struct DeinterlacerConfig {
int type, fieldOrder, processor;
bool doublesFramerate;
};

View File

@ -45,12 +45,29 @@ END
#endif // APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// Cursor
//
IDC_COLORPICKER CURSOR "cursor1.cur"
#endif // Japanese (Japan) resources
/////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////
// English resources
#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
LANGUAGE LANG_ENGLISH, SUBLANG_NEUTRAL
#pragma code_page(1252)
/////////////////////////////////////////////////////////////////////////////
//
// Dialog
//
IDD_CONFIG DIALOGEX 0, 0, 428, 281
IDD_CONFIG DIALOGEX 0, 0, 429, 295
STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION "DeviceSelection"
FONT 8, "MS Shell Dlg", 400, 0, 0x1
@ -68,51 +85,54 @@ BEGIN
RTEXT "DeviceSelection.Opacity",IDC_STATIC,144,38,117,8
EDITTEXT IDC_OPACITY_EDIT,264,35,40,14,ES_AUTOHSCROLL | ES_NUMBER
CONTROL "",IDC_OPACITY,"msctls_updown32",UDS_SETBUDDYINT | UDS_ALIGNRIGHT | UDS_AUTOBUDDY | UDS_ARROWKEYS | UDS_NOTHOUSANDS,304,35,11,14
GROUPBOX "DeviceSelection.Video",IDC_STATIC,7,67,216,101
GROUPBOX "DeviceSelection.Video",IDC_STATIC,6,79,216,101
CONTROL "DeviceSelection.CustomResolution",IDC_CUSTOMRESOLUTION,
"Button",BS_AUTOCHECKBOX | WS_TABSTOP,17,79,130,10,WS_EX_RIGHT
RTEXT "DeviceSelection.Resolution",IDC_STATIC,18,96,117,8
COMBOBOX IDC_RESOLUTION,138,93,76,72,CBS_DROPDOWN | WS_VSCROLL | WS_TABSTOP
RTEXT "DeviceSelection.FPS",IDC_STATIC,18,113,117,8
COMBOBOX IDC_FPS,138,111,76,56,CBS_DROPDOWN | CBS_SORT | WS_VSCROLL | WS_TABSTOP
"Button",BS_AUTOCHECKBOX | WS_TABSTOP,16,91,130,10,WS_EX_RIGHT
RTEXT "DeviceSelection.Resolution",IDC_STATIC,17,108,117,8
COMBOBOX IDC_RESOLUTION,137,105,76,72,CBS_DROPDOWN | WS_VSCROLL | WS_TABSTOP
RTEXT "DeviceSelection.FPS",IDC_STATIC,17,125,117,8
COMBOBOX IDC_FPS,137,123,76,56,CBS_DROPDOWN | CBS_SORT | WS_VSCROLL | WS_TABSTOP
CONTROL "DeviceSelection.PreferredType",IDC_USEPREFERREDOUTPUT,
"Button",BS_AUTOCHECKBOX | WS_TABSTOP,18,132,117,10,WS_EX_RIGHT
COMBOBOX IDC_PREFERREDOUTPUT,138,130,76,30,CBS_DROPDOWNLIST | CBS_SORT | WS_VSCROLL | WS_TABSTOP
CONTROL "DeviceSelection.UseBuffering",IDC_USEBUFFERING,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,18,151,117,10,WS_EX_RIGHT
EDITTEXT IDC_DELAY_EDIT,138,148,40,14,ES_AUTOHSCROLL
CONTROL "",IDC_DELAY,"msctls_updown32",UDS_SETBUDDYINT | UDS_ALIGNRIGHT | UDS_AUTOBUDDY | UDS_ARROWKEYS | UDS_NOTHOUSANDS,178,148,10,14
GROUPBOX "DeviceSelection.Sound",IDC_STATIC,234,67,187,136,WS_GROUP
LTEXT "DeviceSelection.AudioDevice",IDC_STATIC,243,84,117,8
COMBOBOX IDC_AUDIOLIST,243,96,169,12,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
PUSHBUTTON "DeviceSelection.Config",IDC_CONFIGAUDIO,335,112,78,13
CONTROL "ƒJƒXƒ^ƒ€1",IDC_VOLUME,"OBSVolumeControl",WS_TABSTOP,243,131,118,19
CONTROL "DeviceSelection.OutputSound",IDC_OUTPUTSOUND,"Button",BS_AUTORADIOBUTTON,243,156,163,10
LTEXT "DeviceSelection.SoundOffset",IDC_STATIC,239,171,117,8,NOT WS_GROUP,WS_EX_RIGHT
EDITTEXT IDC_TIMEOFFSET_EDIT,361,168,40,14,ES_AUTOHSCROLL
CONTROL "",IDC_TIMEOFFSET,"msctls_updown32",UDS_SETBUDDYINT | UDS_ALIGNRIGHT | UDS_AUTOBUDDY | UDS_ARROWKEYS | UDS_NOTHOUSANDS,401,168,11,14
"Button",BS_AUTOCHECKBOX | WS_TABSTOP,17,144,117,10,WS_EX_RIGHT
COMBOBOX IDC_PREFERREDOUTPUT,137,142,76,30,CBS_DROPDOWNLIST | CBS_SORT | WS_VSCROLL | WS_TABSTOP
CONTROL "DeviceSelection.UseBuffering",IDC_USEBUFFERING,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,17,163,117,10,WS_EX_RIGHT
EDITTEXT IDC_DELAY_EDIT,137,160,40,14,ES_AUTOHSCROLL
CONTROL "",IDC_DELAY,"msctls_updown32",UDS_SETBUDDYINT | UDS_ALIGNRIGHT | UDS_AUTOBUDDY | UDS_ARROWKEYS | UDS_NOTHOUSANDS,177,160,11,14
GROUPBOX "DeviceSelection.Sound",IDC_STATIC,233,79,187,136,WS_GROUP
LTEXT "DeviceSelection.AudioDevice",IDC_STATIC,242,96,117,8
COMBOBOX IDC_AUDIOLIST,242,108,169,12,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
PUSHBUTTON "DeviceSelection.Config",IDC_CONFIGAUDIO,334,124,78,13
CONTROL "OBSVolumeControl",IDC_VOLUME,"OBSVolumeControl",WS_TABSTOP,242,143,118,19
CONTROL "DeviceSelection.OutputSound",IDC_OUTPUTSOUND,"Button",BS_AUTORADIOBUTTON,242,168,163,10
LTEXT "DeviceSelection.SoundOffset",IDC_STATIC,238,183,117,8,NOT WS_GROUP,WS_EX_RIGHT
EDITTEXT IDC_TIMEOFFSET_EDIT,360,180,40,14,ES_AUTOHSCROLL
CONTROL "",IDC_TIMEOFFSET,"msctls_updown32",UDS_SETBUDDYINT | UDS_ALIGNRIGHT | UDS_AUTOBUDDY | UDS_ARROWKEYS | UDS_NOTHOUSANDS,400,180,11,14
CONTROL "DeviceSelection.PlayToDesktop",IDC_PLAYDESKTOPSOUND,
"Button",BS_AUTORADIOBUTTON,243,186,163,10
GROUPBOX "DeviceSelection.ChromaKey",IDC_STATIC,7,174,216,99
CONTROL "DeviceSelection.UseChromaKey",IDC_USECHROMAKEY,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,13,186,130,10,WS_EX_RIGHT
RTEXT "DeviceSelection.Color",IDC_STATIC,14,202,117,8
CONTROL "",IDC_COLOR,"OBSColorControl",WS_TABSTOP,133,199,28,14
PUSHBUTTON "DeviceSelection.Select",IDC_SELECTCOLOR,166,199,50,14
RTEXT "DeviceSelection.Similarity",IDC_STATIC,14,220,117,8
EDITTEXT IDC_BASETHRESHOLD_EDIT,132,218,40,14,ES_AUTOHSCROLL | ES_NUMBER
CONTROL "",IDC_BASETHRESHOLD,"msctls_updown32",UDS_SETBUDDYINT | UDS_ALIGNRIGHT | UDS_AUTOBUDDY | UDS_ARROWKEYS | UDS_NOTHOUSANDS,173,218,10,14
RTEXT "DeviceSelection.Blend",IDC_STATIC,12,236,117,8
EDITTEXT IDC_BLEND_EDIT,132,235,40,14,ES_AUTOHSCROLL | ES_NUMBER
CONTROL "",IDC_BLEND,"msctls_updown32",UDS_SETBUDDYINT | UDS_ALIGNRIGHT | UDS_AUTOBUDDY | UDS_ARROWKEYS | UDS_NOTHOUSANDS,172,235,11,14
RTEXT "DeviceSelection.SpillReduction",IDC_STATIC,12,252,117,8
EDITTEXT IDC_SPILLREDUCTION_EDIT,132,251,40,14,ES_AUTOHSCROLL
CONTROL "",IDC_SPILLREDUCTION,"msctls_updown32",UDS_SETBUDDYINT | UDS_ALIGNRIGHT | UDS_AUTOBUDDY | UDS_ARROWKEYS | UDS_NOTHOUSANDS,172,251,11,14
DEFPUSHBUTTON "OK",IDOK,313,260,50,14
PUSHBUTTON "Cancel",IDCANCEL,371,260,50,14
RTEXT "DeviceSelection.Gamma",IDC_STATIC,235,208,95,8
CONTROL "",IDC_GAMMA2,"msctls_trackbar32",TBS_BOTH | WS_TABSTOP,230,220,191,26
LTEXT ".numbers!",IDC_GAMMAVAL,336,208,54,8
"Button",BS_AUTORADIOBUTTON,242,198,163,10
GROUPBOX "DeviceSelection.ChromaKey",IDC_STATIC,6,186,216,99
CONTROL "DeviceSelection.UseChromaKey",IDC_USECHROMAKEY,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,12,198,130,10,WS_EX_RIGHT
RTEXT "DeviceSelection.Color",IDC_STATIC,13,214,117,8
CONTROL "",IDC_COLOR,"OBSColorControl",WS_TABSTOP,132,211,28,14
PUSHBUTTON "DeviceSelection.Select",IDC_SELECTCOLOR,165,211,50,14
RTEXT "DeviceSelection.Similarity",IDC_STATIC,13,232,117,8
EDITTEXT IDC_BASETHRESHOLD_EDIT,131,230,40,14,ES_AUTOHSCROLL | ES_NUMBER
CONTROL "",IDC_BASETHRESHOLD,"msctls_updown32",UDS_SETBUDDYINT | UDS_ALIGNRIGHT | UDS_AUTOBUDDY | UDS_ARROWKEYS | UDS_NOTHOUSANDS,172,230,11,14
RTEXT "DeviceSelection.Blend",IDC_STATIC,11,248,117,8
EDITTEXT IDC_BLEND_EDIT,131,247,40,14,ES_AUTOHSCROLL | ES_NUMBER
CONTROL "",IDC_BLEND,"msctls_updown32",UDS_SETBUDDYINT | UDS_ALIGNRIGHT | UDS_AUTOBUDDY | UDS_ARROWKEYS | UDS_NOTHOUSANDS,171,247,11,14
RTEXT "DeviceSelection.SpillReduction",IDC_STATIC,11,264,117,8
EDITTEXT IDC_SPILLREDUCTION_EDIT,131,263,40,14,ES_AUTOHSCROLL
CONTROL "",IDC_SPILLREDUCTION,"msctls_updown32",UDS_SETBUDDYINT | UDS_ALIGNRIGHT | UDS_AUTOBUDDY | UDS_ARROWKEYS | UDS_NOTHOUSANDS,171,263,11,14
DEFPUSHBUTTON "OK",IDOK,312,272,50,14
PUSHBUTTON "Cancel",IDCANCEL,370,272,50,14
RTEXT "DeviceSelection.Gamma",IDC_STATIC,234,220,95,8
CONTROL "",IDC_GAMMA,"msctls_trackbar32",TBS_BOTH | WS_TABSTOP,229,232,191,26
LTEXT ".numbers!",IDC_GAMMAVAL,335,220,54,8
RTEXT "DeviceSelection.Deinterlacing",IDC_STATIC,3,54,117,8
COMBOBOX IDC_DEINTERLACELIST,125,51,133,12,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
CONTROL "DeviceSelection.TopFieldFirst",IDC_TFF,"Button",BS_AUTORADIOBUTTON | BS_RIGHT | WS_TABSTOP,14,68,119,10,WS_EX_RIGHT
CONTROL "DeviceSelection.BottomFieldFirst",IDC_BFF,"Button",BS_AUTORADIOBUTTON | BS_RIGHT | WS_TABSTOP,154,68,119,10,WS_EX_RIGHT
CONTROL "DeviceSelection.GPUDeinterlacing",IDC_GPUDEINT,"Button",BS_AUTOCHECKBOX | BS_RIGHT | WS_TABSTOP,294,68,119,10,WS_EX_RIGHT
END
@ -127,21 +147,14 @@ BEGIN
IDD_CONFIG, DIALOG
BEGIN
LEFTMARGIN, 7
RIGHTMARGIN, 421
RIGHTMARGIN, 422
TOPMARGIN, 7
BOTTOMMARGIN, 274
BOTTOMMARGIN, 288
END
END
#endif // APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// Cursor
//
IDC_COLORPICKER CURSOR "cursor1.cur"
#endif // Japanese (Japan) resources
#endif // English resources
/////////////////////////////////////////////////////////////////////////////

View File

@ -24,6 +24,18 @@ DWORD STDCALL PackPlanarThread(ConvertData *data);
#define NEAR_SILENT 3000
#define NEAR_SILENTf 3000.0
DeinterlacerConfig deinterlacerConfigs[DEINTERLACING_TYPE_LAST] = {
{DEINTERLACING_NONE, FIELD_ORDER_NONE, DEINTERLACING_PROCESSOR_CPU},
{DEINTERLACING_DISCARD, FIELD_ORDER_TFF | FIELD_ORDER_BFF, DEINTERLACING_PROCESSOR_CPU},
{DEINTERLACING_RETRO, FIELD_ORDER_TFF | FIELD_ORDER_BFF, DEINTERLACING_PROCESSOR_CPU | DEINTERLACING_PROCESSOR_GPU, true},
{DEINTERLACING_BLEND, FIELD_ORDER_NONE, DEINTERLACING_PROCESSOR_GPU},
{DEINTERLACING_BLEND2x, FIELD_ORDER_TFF | FIELD_ORDER_BFF, DEINTERLACING_PROCESSOR_GPU, true},
{DEINTERLACING_LINEAR, FIELD_ORDER_TFF | FIELD_ORDER_BFF, DEINTERLACING_PROCESSOR_GPU},
{DEINTERLACING_LINEAR2x, FIELD_ORDER_TFF | FIELD_ORDER_BFF, DEINTERLACING_PROCESSOR_GPU, true},
{DEINTERLACING_YADIF, FIELD_ORDER_TFF | FIELD_ORDER_BFF, DEINTERLACING_PROCESSOR_GPU},
{DEINTERLACING_YADIF2x, FIELD_ORDER_TFF | FIELD_ORDER_BFF, DEINTERLACING_PROCESSOR_GPU, true},
{DEINTERLACING__DEBUG, FIELD_ORDER_TFF | FIELD_ORDER_BFF, DEINTERLACING_PROCESSOR_GPU},
};
bool DeviceSource::Init(XElement *data)
{
@ -89,13 +101,15 @@ DeviceSource::~DeviceSource()
OSCloseMutex(hSampleMutex);
}
#define SHADER_PATH TEXT("plugins/DShowPlugin/shaders/")
String DeviceSource::ChooseShader()
{
if(colorType == DeviceOutputType_RGB && !bUseChromaKey)
return String();
String strShader;
strShader << TEXT("plugins/DShowPlugin/shaders/");
strShader << SHADER_PATH;
if(bUseChromaKey)
strShader << TEXT("ChromaKey_");
@ -118,6 +132,35 @@ String DeviceSource::ChooseShader()
return strShader;
}
String DeviceSource::ChooseDeinterlacingShader()
{
String shader;
shader << SHADER_PATH << TEXT("Deinterlace_");
#ifdef _DEBUG
#define DEBUG__ _DEBUG
#undef _DEBUG
#endif
#define SELECT(x) case DEINTERLACING_##x: shader << String(TEXT(#x)).MakeLower(); break;
switch(deinterlacer.type)
{
SELECT(RETRO)
SELECT(BLEND)
SELECT(BLEND2x)
SELECT(LINEAR)
SELECT(LINEAR2x)
SELECT(YADIF)
SELECT(YADIF2x)
SELECT(_DEBUG)
}
return shader << TEXT(".pShader");
#undef SELECT
#ifdef DEBUG__
#define _DEBUG DEBUG__
#undef DEBUG__
#endif
}
const float yuv709Mat[16] = { 0.2126f, 0.7152f, 0.0722f, 0.0625f,
-0.1150f, -0.3850f, 0.5000f, 0.50f,
0.5000f, -0.4540f, -0.0460f, 0.50f,
@ -209,8 +252,11 @@ bool DeviceSource::LoadFilters()
keySimilarity = data->GetInt(TEXT("keySimilarity"));
keyBlend = data->GetInt(TEXT("keyBlend"), 80);
keySpillReduction = data->GetInt(TEXT("keySpillReduction"), 50);
deinterlacingType =data->GetInt(TEXT("deinterlacingType"), 0);
deinterlacer.type = data->GetInt(TEXT("deinterlacingType"), 0);
deinterlacer.fieldOrder = data->GetInt(TEXT("deinterlacingFieldOrder"), 0);
deinterlacer.processor = data->GetInt(TEXT("deinterlacingProcessor"), 0);
deinterlacer.doublesFramerate = data->GetInt(TEXT("deinterlacingDoublesFramerate"), 0) != 0;
if(keyBaseColor.x < keyBaseColor.y && keyBaseColor.x < keyBaseColor.z)
keyBaseColor -= keyBaseColor.x;
@ -637,19 +683,42 @@ bool DeviceSource::LoadFilters()
imageCX = renderCX;
imageCY = renderCY;
curField = false;
switch(deinterlacingType) {
case deinterlacing_Discard:
deinterlacer.imageCX = renderCX;
deinterlacer.imageCY = renderCY;
if(deinterlacer.doublesFramerate)
deinterlacer.imageCX *= 2;
switch(deinterlacer.type) {
case DEINTERLACING_DISCARD:
deinterlacer.imageCY = renderCY/2;
linePitch = lineSize * 2;
renderCY /= 2;
break;
case deinterlacing_Retro_BFF:
curField = true;
case deinterlacing_Retro_TFF:
lineSize *= 2;
linePitch = lineSize;
renderCY /= 2;
renderCX *= 2;
case DEINTERLACING_RETRO:
deinterlacer.imageCY = renderCY/2;
if(deinterlacer.processor != DEINTERLACING_PROCESSOR_GPU)
{
lineSize *= 2;
linePitch = lineSize;
renderCY /= 2;
renderCX *= 2;
}
case DEINTERLACING__DEBUG:
deinterlacer.imageCX *= 2;
deinterlacer.imageCY *= 2;
case DEINTERLACING_BLEND2x:
//case DEINTERLACING_MEAN2x:
case DEINTERLACING_YADIF:
case DEINTERLACING_YADIF2x:
deinterlacer.needsPreviousFrame = true;
break;
}
if(deinterlacer.type != DEINTERLACING_NONE && deinterlacer.processor == DEINTERLACING_PROCESSOR_GPU)
{
deinterlacer.vertexShader = CreateVertexShaderFromFile(TEXT("shaders/DrawTexture.vShader"));
deinterlacer.pixelShader = CreatePixelShaderFromFile(ChooseDeinterlacingShader());
}
int numThreads = MAX(OSGetTotalCores()-2, 1);
@ -759,11 +828,19 @@ cleanFinish:
{
msetd(textureData, 0xFFFF0000, renderCX*renderCY*4);
texture = CreateTexture(renderCX, renderCY, GS_BGR, textureData, FALSE, FALSE);
if(deinterlacer.needsPreviousFrame)
previousTexture = CreateTexture(renderCX, renderCY, GS_BGR, textureData, FALSE, FALSE);
if(deinterlacer.processor == DEINTERLACING_PROCESSOR_GPU)
deinterlacer.texture = CreateRenderTarget(deinterlacer.imageCX, deinterlacer.imageCY, GS_BGRA, FALSE);
}
else //if we're working with planar YUV, we can just use regular RGB textures instead
{
msetd(textureData, 0xFF0000FF, renderCX*renderCY*4);
texture = CreateTexture(renderCX, renderCY, GS_RGB, textureData, FALSE, FALSE);
if(deinterlacer.needsPreviousFrame)
previousTexture = CreateTexture(renderCX, renderCY, GS_RGB, textureData, FALSE, FALSE);
if(deinterlacer.processor == DEINTERLACING_PROCESSOR_GPU)
deinterlacer.texture = CreateRenderTarget(deinterlacer.imageCX, deinterlacer.imageCY, GS_BGRA, FALSE);
}
if(bSucceeded && bUseThreadedConversion)
@ -802,6 +879,8 @@ void DeviceSource::UnloadFilters()
{
delete texture;
texture = NULL;
delete previousTexture;
previousTexture = NULL;
}
int numThreads = MAX(OSGetTotalCores()-2, 1);
@ -1135,13 +1214,14 @@ void DeviceSource::Preprocess()
Log(TEXT("refTimeStart: %llu, refTimeFinish: %llu, offset = %llu"), refTimeStart, refTimeFinish, refTimeStart-lastRefTime);
lastRefTime = refTimeStart;*/
switch(deinterlacingType)
if(previousTexture)
{
case deinterlacing_Retro_BFF:
case deinterlacing_Retro_TFF:
curField = (deinterlacingType == deinterlacing_Retro_BFF); //select first field
bNewFrame = true;
Texture *tmp = texture;
texture = previousTexture;
previousTexture = tmp;
}
deinterlacer.curField = deinterlacer.processor == DEINTERLACING_PROCESSOR_GPU ? false : (deinterlacer.fieldOrder == FIELD_ORDER_BFF);
deinterlacer.bNewFrame = true;
if(colorType == DeviceOutputType_RGB)
{
@ -1225,6 +1305,35 @@ void DeviceSource::Preprocess()
}
lastSample->Release();
if(bReadyToDraw && deinterlacer.type != DEINTERLACING_NONE && deinterlacer.processor == DEINTERLACING_PROCESSOR_GPU)
{
SetRenderTarget(deinterlacer.texture);
Shader *oldVertShader = GetCurrentVertexShader();
LoadVertexShader(deinterlacer.vertexShader);
Shader *oldShader = GetCurrentPixelShader();
LoadPixelShader(deinterlacer.pixelShader);
HANDLE hField = deinterlacer.pixelShader->GetParameterByName(TEXT("field_order"));
if(hField)
deinterlacer.pixelShader->SetBool(hField, deinterlacer.fieldOrder == FIELD_ORDER_BFF);
Ortho(0.0f, float(deinterlacer.imageCX), float(deinterlacer.imageCY), 0.0f, -100.0f, 100.0f);
SetViewport(0.0f, 0.0f, float(deinterlacer.imageCX), float(deinterlacer.imageCY));
if(previousTexture)
LoadTexture(previousTexture, 1);
DrawSpriteEx(texture, 0xFFFFFFFF, 0.0f, 0.0f, float(deinterlacer.imageCX), float(deinterlacer.imageCY), 0.0f, 0.0f, 1.0f, 1.0f);
if(previousTexture)
LoadTexture(nullptr, 1);
LoadPixelShader(oldShader);
LoadVertexShader(oldVertShader);
}
}
}
@ -1304,25 +1413,19 @@ void DeviceSource::Render(const Vect2 &pos, const Vect2 &size)
switch(deinterlacingType) {
case deinterlacing_Retro_BFF:
case deinterlacing_Retro_TFF:
if(texture)
{
if(!curField)
DrawSpriteEx(texture, (opacity255<<24) | 0xFFFFFF, x, y, x2, y2, 0.f, 0.0f, .5f, 1.f);
else
DrawSpriteEx(texture, (opacity255<<24) | 0xFFFFFF, x, y, x2, y2, .5f, 0.0f, 1.f, 1.f);
}
if(bNewFrame)
{
curField = !curField;
bNewFrame = false; //prevent switching from the second field to the first field
}
break;
default:
DrawSprite(texture, (opacity255<<24) | 0xFFFFFF, x, y, x2, y2);
break;
if(deinterlacer.doublesFramerate)
{
if(!deinterlacer.curField)
DrawSpriteEx(deinterlacer.processor == DEINTERLACING_PROCESSOR_GPU ? deinterlacer.texture : texture, (opacity255<<24) | 0xFFFFFF, x, y, x2, y2, 0.f, 0.0f, .5f, 1.f);
else
DrawSpriteEx(deinterlacer.processor == DEINTERLACING_PROCESSOR_GPU ? deinterlacer.texture : texture, (opacity255<<24) | 0xFFFFFF, x, y, x2, y2, .5f, 0.0f, 1.f, 1.f);
}
else
DrawSprite(deinterlacer.processor == DEINTERLACING_PROCESSOR_GPU ? deinterlacer.texture : texture, (opacity255<<24) | 0xFFFFFF, x, y, x2, y2);
if(deinterlacer.bNewFrame)
{
deinterlacer.curField = !deinterlacer.curField;
deinterlacer.bNewFrame = false; //prevent switching from the second field to the first field
}
if(bUsePointFiltering) delete(sampler);
@ -1340,17 +1443,21 @@ void DeviceSource::UpdateSettings()
UINT newCX = data->GetInt(TEXT("resolutionWidth"));
UINT newCY = data->GetInt(TEXT("resolutionHeight"));
BOOL bNewCustom = data->GetInt(TEXT("customResolution"));
UINT newDeinterlacingType = data->GetInt(TEXT("deinterlacingType"));
UINT newPreferredType = data->GetInt(TEXT("usePreferredType")) != 0 ? data->GetInt(TEXT("preferredType")) : -1;
UINT newSoundOutputType = data->GetInt(TEXT("soundOutputType"));
bool bNewUseBuffering = data->GetInt(TEXT("useBuffering")) != 0;
UINT newGamma = data->GetInt(TEXT("gamma"), 100);
int newDeintType = data->GetInt(TEXT("deinterlacingType"));
int newDeintFieldOrder = data->GetInt(TEXT("deinterlacingFieldOrder"));
int newDeintProcessor = data->GetInt(TEXT("deinterlacingProcessor"));
if(newSoundOutputType != soundOutputType || imageCX != newCX || imageCY != newCY ||
frameInterval != newFrameInterval || newPreferredType != preferredOutputType ||
!strDevice.CompareI(strNewDevice) || !strAudioDevice.CompareI(strNewAudioDevice) ||
bNewCustom != bUseCustomResolution || bNewUseBuffering != bUseBuffering ||
newGamma != gamma || newDeinterlacingType != deinterlacingType)
newGamma != gamma || newDeintType != deinterlacer.type ||
newDeintFieldOrder != deinterlacer.fieldOrder || newDeintProcessor != deinterlacer.processor)
{
API->EnterSceneMutex();

View File

@ -135,8 +135,17 @@ class DeviceSource : public ImageSource
BOOL bUseCustomResolution;
UINT preferredOutputType;
BYTE deinterlacingType;
bool curField, bNewFrame;
struct {
int type; //DeinterlacingType
char fieldOrder; //DeinterlacingFieldOrder
char processor; //DeinterlacingProcessor
bool curField, bNewFrame;
bool doublesFramerate;
bool needsPreviousFrame;
Texture *texture;
UINT imageCX, imageCY;
Shader *vertexShader, *pixelShader;
} deinterlacer;
bool bFirstFrame;
bool bUseThreadedConversion;
@ -145,7 +154,7 @@ class DeviceSource : public ImageSource
int soundOutputType;
bool bOutputAudioToDesktop;
Texture *texture;
Texture *texture, *previousTexture;
XElement *data;
UINT texturePitch;
bool bCapturing, bFiltersLoaded;
@ -183,6 +192,7 @@ class DeviceSource : public ImageSource
//---------------------------------
String ChooseShader();
String ChooseDeinterlacingShader();
void Convert422To444(LPBYTE convertBuffer, LPBYTE lp422, UINT pitch, bool bLeadingY);

View File

@ -35,7 +35,6 @@
#define IDC_BLEND 1022
#define IDC_GAMMA_EDIT 1023
#define IDC_SPILLREDUCTION_EDIT 1023
#define IDC_GAMMA 1024
#define IDC_SPILLREDUCTION 1024
#define IDC_FLIPIMAGEH 1025
#define IDC_PREFERREDOUTPUT 1026
@ -47,14 +46,16 @@
#define IDC_TIMEOFFSET_EDIT 1032
#define IDC_TIMEOFFSET 1033
#define IDC_CHECK1 1034
#define IDC_CUSTOM1 1035
#define IDC_TFF 1034
#define IDC_VOLUME 1035
#define IDC_VOLMETER 1036
#define IDC_POINTFILTERING 1036
#define IDC_DELAY_EDIT 1037
#define IDC_VIDEODELAY 1038
#define IDC_DELAY 1038
#define IDC_GAMMA2 1039
#define IDC_GAMMA 1039
#define IDC_BFF 1040
#define IDC_GPUDEINT 1041
#define IDC_GAMMAVAL 1151
// Next default values for new objects

View File

@ -5,8 +5,17 @@ OK "OK"
DeinterlacingType.None "None"
DeinterlacingType.Discard "Field Discard"
DeinterlacingType.RetroTFF "Retro/scandoubling (TFF)"
DeinterlacingType.RetroBFF "Retro/scandoubling (BFF)"
DeinterlacingType.Retro "Retro/scandoubling"
DeinterlacingType.Blend "Blend"
DeinterlacingType.Blend2x "Blend2x"
DeinterlacingType.Linear "Linear"
DeinterlacingType.Linear2x "Linear2x"
DeinterlacingType.Yadif "Yadif"
DeinterlacingType.Yadif2x "Yadif2x"
DeinterlacingType.Debug "Debug"
DeviceSelection.TopFieldFirst "Top Field First"
DeviceSelection.BottomFieldFirst "Bottom Field First"
DeviceSelection.GPUDeinterlacing "Use GPU"
CrossbarSelection.Open "Open Crossbar"

View File

@ -0,0 +1,44 @@
/********************************************************************************
Copyright (C) 2012 Hugh Bailey <obs.jim@gmail.com>
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
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
********************************************************************************/
#include "Deinterlace_base.pShader"
float4 main(VertData input) : SV_Target
{
//input.texCoord.x *= 2;
//return sample_pixel(fmod(input.texCoord, 1), 1*(input.texCoord<1), YADIF);
//return sample_pixel(input.texCoord, 1, YADIF);
//return sample_pixel(input.texCoord, 0, WEAVE);
float2 texCoord = input.texCoord;// * 2;
if(texCoord.y < .5)
{
input.texCoord.y *= 2;
return sample_pixel_2x(input.texCoord, field_order, BLEND2x);
/*if(texCoord.x < .5)
return sample_pixel(texCoord*2, 1*(texCoord.y < 1), YADIF*(texCoord.x<1));
else
return sample_pixel(float2(texCoord.x*2-1, texCoord.y*2), 0, YADIF);*/
}
else
{
if(texCoord.x < .5)
return sample_pixel(input.texCoord*2-float2(0, 1), 1, WEAVE);
else
return sample_pixel(input.texCoord*2-1, 0, WEAVE);
}
}

View File

@ -0,0 +1,196 @@
/********************************************************************************
Copyright (C) 2012 Hugh Bailey <obs.jim@gmail.com>
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
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
********************************************************************************/
uniform Texture2D diffuseTexture;
uniform Texture2D prevTex;
uniform bool field_order;
#define WEAVE 0
#define YADIF 1
#define BLEND 2
#define BLEND2x 3
#define LINEAR 4
#define LINEAR2x 5
#define DISCARD 6
#define DISCARD2x 7
int3 select(int2 texel, int x, int y)
{
return int3(texel+int2(x, y), 0);
}
float4 load_at(int2 texel, int x, int y, int field)
{
if(field == 0)
return diffuseTexture.Load(int3(texel+int2(x, y), 0));
else
return prevTex.Load(int3(texel+int2(x, y), 0));
}
#define YADIF_UPDATE(c, level)\
if(score.c < spatial_score.c)\
{\
spatial_score.c = score.c;\
spatial_pred.c = (load_at(texel, level, -1, field) + load_at(texel, -level, 1, field)).c/2;\
#define YADIF_CHECK_ONE(level, c)\
{\
float4 score = abs(load_at(texel, -1+level, 1, field) - load_at(texel, -1-level, -1, field))+\
abs(load_at(texel, level, 1, field) - load_at(texel, -level, -1, field))+\
abs(load_at(texel, 1+level, 1, field) - load_at(texel, 1-level, -1, field));\
YADIF_UPDATE(c, level) }\
}
#define YADIF_CHECK(level)\
{\
float4 score = abs(load_at(texel, -1+level, 1, field) - load_at(texel, -1-level, -1, field))+\
abs(load_at(texel, level, 1, field) - load_at(texel, -level, -1, field))+\
abs(load_at(texel, 1+level, 1, field) - load_at(texel, 1-level, -1, field));\
YADIF_UPDATE(r, level) YADIF_CHECK_ONE(level*2, r) }\
YADIF_UPDATE(g, level) YADIF_CHECK_ONE(level*2, g) }\
YADIF_UPDATE(b, level) YADIF_CHECK_ONE(level*2, b) }\
YADIF_UPDATE(a, level) YADIF_CHECK_ONE(level*2, a) }\
}
float4 texel_at_yadif(int2 texel, int field)
{
Texture2D tex = diffuseTexture;
if((texel.y%2) == field)
return load_at(texel, 0, 0, field);
float4 b = (prevTex.Load(select(texel, 0, 2)) + tex.Load(select(texel, 0, 2)))/2,
c = load_at(texel, 0, 1, field),
d = (prevTex.Load(select(texel, 0, 0)) + tex.Load(select(texel, 0, 0)))/2,
e = load_at(texel, 0, -1, field),
f = (prevTex.Load(select(texel, 0, -2)) + tex.Load(select(texel, 0, -2)))/2;
float4 temporal_diff0 = (abs(prevTex.Load(select(texel, 0, 0)) - tex.Load(select(texel, 0, 0))))/2,
temporal_diff1 = (abs(prevTex.Load(select(texel, 0, 1))-c) + abs(prevTex.Load(select(texel, 0, -1))-e))/2,
temporal_diff2 = (abs(tex.Load(select(texel, 0, 1))-c) + abs(tex.Load(select(texel, 0, -1))-e))/2,
diff = max(temporal_diff0, max(temporal_diff1, temporal_diff2));
float4 spatial_pred = (c+e)/2,
spatial_score = abs(load_at(texel, -1, 1, field)-load_at(texel, -1, -1, field))+
abs(c-e)+
abs(load_at(texel, 1, 1, field)-load_at(texel, 1, -1, field))-1;
YADIF_CHECK(-1)
YADIF_CHECK(1)
float4 max_ = max(d-e, max(d-c, min(b-c, f-e))),
min_ = min(d-e, min(d-c, max(b-c, f-e)));
diff = max(diff, max(min_, -max_));
#define YADIF_SPATIAL(c)\
{\
if(spatial_pred.c > d.c + diff.c)\
spatial_pred.c = d.c + diff.c;\
else if(spatial_pred.c < d.c - diff.c)\
spatial_pred.c = d.c - diff.c;\
}
YADIF_SPATIAL(r)
YADIF_SPATIAL(g)
YADIF_SPATIAL(b)
YADIF_SPATIAL(a)
return spatial_pred;
}
float4 texel_at_blend(int2 texel, int field)
{
return (diffuseTexture.Load(int3(texel, 0)) + diffuseTexture.Load(int3(texel.x, texel.y+1, 0)))/2;
}
float4 texel_at_blend_2x(int2 texel, int field)
{
if(field_order != field)
return (diffuseTexture.Load(int3(texel.x, texel.y, 0)) + prevTex.Load(int3(texel.x, texel.y+1, 0)))/2;
return (diffuseTexture.Load(int3(texel.x, texel.y, 0)) + diffuseTexture.Load(int3(texel.x, texel.y+1, 0)))/2;
}
float4 texel_at_linear(int2 texel, int field)
{
if(field == texel.y%2)
return diffuseTexture.Load(int3(texel, 0));
return (diffuseTexture.Load(int3(texel+int2(0, -1), 0))+diffuseTexture.Load(int3(texel+int2(0, 1), 0)))/2;
}
float4 texel_at_linear2x(int2 texel, int field)
{
return texel_at_linear(texel, 1-field);
}
float4 texel_at_discard(int2 texel, int field)
{
Texture2D tex = diffuseTexture;
return tex.Load(int3(texel.x, texel.y/2*2+field, 0));
}
float4 texel_at_discard2x(int2 texel, int field)
{
return texel_at_discard(texel, 1-field);
}
float4 texel_at_weave(int2 texel, int field)
{
if(field != 0)
return prevTex.Load(int3(texel, 0));
return diffuseTexture.Load(int3(texel, 0));
}
#define DISPATCH(name, func)\
case name: return func(coord, field); break;
float4 sample_texel(float2 coord, int field, int name)
{
switch(name)
{
DISPATCH(YADIF, texel_at_yadif)
DISPATCH(BLEND, texel_at_blend)
DISPATCH(BLEND2x, texel_at_blend_2x)
DISPATCH(LINEAR, texel_at_linear)
DISPATCH(LINEAR2x, texel_at_linear2x)
DISPATCH(DISCARD, texel_at_discard)
DISPATCH(DISCARD2x, texel_at_discard2x)
default: return texel_at_weave(coord, field); break;
}
}
#undef DISPATCH
float4 sample_pixel(float2 coord, bool field, int func)
{
Texture2D tex = diffuseTexture;
float2 size = 0;
float miplevels;
tex.GetDimensions(0, size.x, size.y, miplevels);
float2 uv = coord*size;
return sample_texel(uv, field, func);
}
float4 sample_pixel_2x(float2 coord, bool field, int func)
{
coord.x *= 2;
return sample_pixel(coord-floor(coord), field*(coord.x>1)+(1-field)*(coord.x<1), func);
}
struct VertData
{
float4 pos : SV_Position;
float2 texCoord : TexCoord0;
};

View File

@ -0,0 +1,24 @@
/********************************************************************************
Copyright (C) 2012 Hugh Bailey <obs.jim@gmail.com>
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
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
********************************************************************************/
#include "Deinterlace_base.pShader"
float4 main(VertData input) : SV_Target
{
return sample_pixel(input.texCoord, field_order, BLEND);
}

View File

@ -0,0 +1,24 @@
/********************************************************************************
Copyright (C) 2012 Hugh Bailey <obs.jim@gmail.com>
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
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
********************************************************************************/
#include "Deinterlace_base.pShader"
float4 main(VertData input) : SV_Target
{
return sample_pixel_2x(input.texCoord, field_order, BLEND2x);
}

View File

@ -0,0 +1,24 @@
/********************************************************************************
Copyright (C) 2012 Hugh Bailey <obs.jim@gmail.com>
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
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
********************************************************************************/
#include "Deinterlace_base.pShader"
float4 main(VertData input) : SV_Target
{
return sample_pixel(input.texCoord, field_order, LINEAR);
}

View File

@ -0,0 +1,24 @@
/********************************************************************************
Copyright (C) 2012 Hugh Bailey <obs.jim@gmail.com>
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
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
********************************************************************************/
#include "Deinterlace_base.pShader"
float4 main(VertData input) : SV_Target
{
return sample_pixel_2x(input.texCoord, field_order, LINEAR2x);
}

View File

@ -0,0 +1,24 @@
/********************************************************************************
Copyright (C) 2012 Hugh Bailey <obs.jim@gmail.com>
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
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
********************************************************************************/
#include "Deinterlace_base.pShader"
float4 main(VertData input) : SV_Target
{
return sample_pixel_2x(input.texCoord, field_order, DISCARD2x);
}

View File

@ -0,0 +1,24 @@
/********************************************************************************
Copyright (C) 2012 Hugh Bailey <obs.jim@gmail.com>
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
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
********************************************************************************/
#include "Deinterlace_base.pShader"
float4 main(VertData input) : SV_Target
{
return sample_pixel(input.texCoord, field_order, YADIF);
}

View File

@ -0,0 +1,24 @@
/********************************************************************************
Copyright (C) 2012 Hugh Bailey <obs.jim@gmail.com>
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
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
********************************************************************************/
#include "Deinterlace_base.pShader"
float4 main(VertData input) : SV_Target
{
return sample_pixel_2x(input.texCoord, field_order, YADIF);
}