diff options
-rw-r--r-- | build_ffmpeg.sh | 3 | ||||
-rw-r--r-- | build_ffmpeg_msvc.sh | 3 | ||||
-rw-r--r-- | decoder/LAVVideo/Filtering.cpp | 25 | ||||
-rw-r--r-- | decoder/LAVVideo/LAVVideo.cpp | 6 | ||||
-rw-r--r-- | decoder/LAVVideo/LAVVideo.rc | 6 | ||||
-rw-r--r-- | decoder/LAVVideo/LAVVideoSettings.h | 4 | ||||
-rw-r--r-- | decoder/LAVVideo/VideoSettingsProp.cpp | 32 | ||||
-rw-r--r-- | decoder/LAVVideo/VideoSettingsProp.h | 2 | ||||
-rw-r--r-- | decoder/LAVVideo/resource.h | 2 |
9 files changed, 53 insertions, 30 deletions
diff --git a/build_ffmpeg.sh b/build_ffmpeg.sh index 0d3dd285..4bc75459 100644 --- a/build_ffmpeg.sh +++ b/build_ffmpeg.sh @@ -56,8 +56,7 @@ configure() ( --enable-w32threads \ --disable-demuxer=matroska \ --disable-filters \ - --enable-filter=yadif \ - --enable-filter=scale \ + --enable-filter=scale,yadif,w3fdif \ --disable-protocol=async,cache,concat,httpproxy,icecast,md5,subfile \ --disable-muxers \ --enable-muxer=spdif \ diff --git a/build_ffmpeg_msvc.sh b/build_ffmpeg_msvc.sh index 4cd84adb..58eb70b6 100644 --- a/build_ffmpeg_msvc.sh +++ b/build_ffmpeg_msvc.sh @@ -55,8 +55,7 @@ configure() ( --enable-w32threads \ --disable-demuxer=matroska \ --disable-filters \ - --enable-filter=yadif \ - --enable-filter=scale \ + --enable-filter=scale,yadif,w3fdif \ --disable-protocol=async,cache,concat,httpproxy,icecast,md5,subfile \ --disable-muxers \ --enable-muxer=spdif \ diff --git a/decoder/LAVVideo/Filtering.cpp b/decoder/LAVVideo/Filtering.cpp index a39713a2..94708e02 100644 --- a/decoder/LAVVideo/Filtering.cpp +++ b/decoder/LAVVideo/Filtering.cpp @@ -42,7 +42,9 @@ HRESULT CLAVVideo::Filter(LAVFrame *pFrame) { int ret = 0; BOOL bFlush = pFrame->flags & LAV_FRAME_FLAG_FLUSH; - if (m_Decoder.IsInterlaced() && m_settings.DeintMode != DeintMode_Disable && m_settings.SWDeintMode == SWDeintMode_YADIF && ((bFlush && m_pFilterGraph) || pFrame->format == LAVPixFmt_YUV420 || pFrame->format == LAVPixFmt_YUV422 || pFrame->format == LAVPixFmt_NV12)) { + if (m_Decoder.IsInterlaced() && m_settings.DeintMode != DeintMode_Disable + && (m_settings.SWDeintMode == SWDeintMode_YADIF || m_settings.SWDeintMode == SWDeintMode_W3FDIF_Simple || m_settings.SWDeintMode == SWDeintMode_W3FDIF_Complex) + && ((bFlush && m_pFilterGraph) || pFrame->format == LAVPixFmt_YUV420 || pFrame->format == LAVPixFmt_YUV422 || pFrame->format == LAVPixFmt_NV12)) { AVPixelFormat ff_pixfmt = (pFrame->format == LAVPixFmt_YUV420) ? AV_PIX_FMT_YUV420P : (pFrame->format == LAVPixFmt_YUV422) ? AV_PIX_FMT_YUV422P : AV_PIX_FMT_NV12; if (!bFlush && (!m_pFilterGraph || pFrame->format != m_filterPixFmt || pFrame->width != m_filterWidth || pFrame->height != m_filterHeight)) { @@ -79,7 +81,7 @@ HRESULT CLAVVideo::Filter(LAVFrame *pFrame) av_opt_set(m_pFilterGraph, "thread_type", "slice", AV_OPT_SEARCH_CHILDREN); av_opt_set_int(m_pFilterGraph, "threads", FFMAX(1, av_cpu_count() / 2), AV_OPT_SEARCH_CHILDREN); - _snprintf_s(args, sizeof(args), "video_size=%dx%d:pix_fmt=%s:time_base=1/10000000:pixel_aspect=1/1", pFrame->width, pFrame->height, av_get_pix_fmt_name(ff_pixfmt)); + _snprintf_s(args, sizeof(args), "video_size=%dx%d:pix_fmt=%s:time_base=1/10000000:pixel_aspect=%d/%d", pFrame->width, pFrame->height, av_get_pix_fmt_name(ff_pixfmt), pFrame->aspect_ratio.num, pFrame->aspect_ratio.den); ret = avfilter_graph_create_filter(&m_pFilterBufferSrc, buffersrc, "in", args, nullptr, m_pFilterGraph); if (ret < 0) { DbgLog((LOG_TRACE, 10, L"::Filter()(init) Creating the input buffer filter failed with code %d", ret)); @@ -109,7 +111,15 @@ HRESULT CLAVVideo::Filter(LAVFrame *pFrame) inputs->pad_idx = 0; inputs->next = nullptr; - _snprintf_s(args, sizeof(args), "yadif=mode=%s:parity=auto:deint=interlaced", (m_settings.SWDeintOutput == DeintOutput_FramePerField) ? "send_field" : "send_frame"); + if (m_settings.SWDeintMode == SWDeintMode_YADIF) + _snprintf_s(args, sizeof(args), "yadif=mode=%s:parity=auto:deint=interlaced", (m_settings.SWDeintOutput == DeintOutput_FramePerField) ? "send_field" : "send_frame"); + else if (m_settings.SWDeintMode == SWDeintMode_W3FDIF_Simple) + _snprintf_s(args, sizeof(args), "w3fdif=filter=simple:deint=interlaced"); + else if (m_settings.SWDeintMode == SWDeintMode_W3FDIF_Complex) + _snprintf_s(args, sizeof(args), "w3fdif=filter=complex:deint=interlaced"); + else + ASSERT(0); + if ((ret = avfilter_graph_parse_ptr(m_pFilterGraph, args, &inputs, &outputs, nullptr)) < 0) { DbgLog((LOG_TRACE, 10, L"::Filter()(init) Parsing the graph failed with code %d", ret)); avfilter_graph_free(&m_pFilterGraph); @@ -122,7 +132,7 @@ HRESULT CLAVVideo::Filter(LAVFrame *pFrame) goto deliver; } - DbgLog((LOG_TRACE, 10, L":Filter()(init) YADIF Initialization complete")); + DbgLog((LOG_TRACE, 10, L":Filter()(init) avfilter Initialization complete")); } if (!m_pFilterGraph) @@ -179,6 +189,9 @@ HRESULT CLAVVideo::Filter(LAVFrame *pFrame) goto deliver; } + BOOL bFramePerField = (m_settings.SWDeintMode == SWDeintMode_YADIF && m_settings.SWDeintOutput == DeintOutput_FramePerField) + || m_settings.SWDeintMode == SWDeintMode_W3FDIF_Simple || m_settings.SWDeintMode == SWDeintMode_W3FDIF_Complex; + AVFrame *out_frame = av_frame_alloc(); HRESULT hrDeliver = S_OK; while (SUCCEEDED(hrDeliver) && (av_buffersink_get_frame(m_pFilterBufferSink, out_frame) >= 0)) { @@ -186,7 +199,7 @@ HRESULT CLAVVideo::Filter(LAVFrame *pFrame) AllocateFrame(&outFrame); REFERENCE_TIME rtDuration = pFrame->rtStop - pFrame->rtStart; - if (m_settings.SWDeintOutput == DeintOutput_FramePerField) + if (bFramePerField) rtDuration >>= 1; // Copy most settings over @@ -205,7 +218,7 @@ HRESULT CLAVVideo::Filter(LAVFrame *pFrame) outFrame->rtStart = pts; outFrame->rtStop = pts + rtDuration; - if (m_settings.SWDeintOutput == DeintOutput_FramePerField) { + if (bFramePerField) { if (outFrame->avgFrameDuration != AV_NOPTS_VALUE) outFrame->avgFrameDuration /= 2; } diff --git a/decoder/LAVVideo/LAVVideo.cpp b/decoder/LAVVideo/LAVVideo.cpp index 9ce03457..f273b511 100644 --- a/decoder/LAVVideo/LAVVideo.cpp +++ b/decoder/LAVVideo/LAVVideo.cpp @@ -681,7 +681,7 @@ HRESULT CLAVVideo::CheckDirectMode() m_Decoder.GetPixelFormat(&pix, &bpp); BOOL bDirect = (pix == LAVPixFmt_NV12 || pix == LAVPixFmt_P010); - if (pix == LAVPixFmt_NV12 && m_Decoder.IsInterlaced() && m_settings.SWDeintMode == SWDeintMode_YADIF) + if (pix == LAVPixFmt_NV12 && m_Decoder.IsInterlaced() && m_settings.SWDeintMode != SWDeintMode_None) bDirect = FALSE; else if (pix == LAVPixFmt_NV12 && m_pOutput->CurrentMediaType().subtype != MEDIASUBTYPE_NV12 && m_pOutput->CurrentMediaType().subtype != MEDIASUBTYPE_YV12) bDirect = FALSE; @@ -1486,9 +1486,9 @@ STDMETHODIMP CLAVVideo::Deliver(LAVFrame *pFrame) } // Only perform filtering if we have to. - // DXVA Native generally can't be filtered, and the only filtering we currently support is YADIF deint + // DXVA Native generally can't be filtered, and the only filtering we currently support is software deinterlacing if ( pFrame->format == LAVPixFmt_DXVA2 - || !(m_Decoder.IsInterlaced() && m_settings.SWDeintMode == SWDeintMode_YADIF) + || !(m_Decoder.IsInterlaced() && m_settings.SWDeintMode != SWDeintMode_None) || pFrame->flags & LAV_FRAME_FLAG_REDRAW) { return DeliverToRenderer(pFrame); } else { diff --git a/decoder/LAVVideo/LAVVideo.rc b/decoder/LAVVideo/LAVVideo.rc index 865e489d..0fcd0b05 100644 --- a/decoder/LAVVideo/LAVVideo.rc +++ b/decoder/LAVVideo/LAVVideo.rc @@ -132,9 +132,9 @@ BEGIN LTEXT "Output Mode",IDC_LBL_HWDEINT_MODE,243,154,62,8 CONTROL "25p/30p (Film)",IDC_HWDEINT_OUT_FILM,"Button",BS_AUTORADIOBUTTON | WS_GROUP,247,167,58,10 CONTROL "50p/60p (Video)",IDC_HWDEINT_OUT_VIDEO,"Button",BS_AUTORADIOBUTTON,315,167,62,10 - GROUPBOX "Software Deinterlacing (YADIF)",IDC_SWDEINT,238,184,156,50 - CONTROL "Enable YADIF Deinterlacing",IDC_SWDEINT_ENABLE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,244,195,116,10 - LTEXT "Output Mode",IDC_LBL_SWDEINT_MODE,243,207,61,11 + GROUPBOX "Software Deinterlacing",IDC_SWDEINT,238,184,156,50 + COMBOBOX IDC_SWDEINT_MODE,246,193,140,100, CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP + LTEXT "Output Mode (YADIF only)",IDC_LBL_SWDEINT_MODE,243,208,100,11 CONTROL "25p/30p (Film)",IDC_SWDEINT_OUT_FILM,"Button",BS_AUTORADIOBUTTON | WS_GROUP,247,219,58,10 CONTROL "50p/60p (Video)",IDC_SWDEINT_OUT_VIDEO,"Button",BS_AUTORADIOBUTTON,315,219,62,10 CONTROL "Enable System Tray Icon",IDC_TRAYICON,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,7,237,192,10 diff --git a/decoder/LAVVideo/LAVVideoSettings.h b/decoder/LAVVideo/LAVVideoSettings.h index 25306c9e..68daa5a4 100644 --- a/decoder/LAVVideo/LAVVideoSettings.h +++ b/decoder/LAVVideo/LAVVideoSettings.h @@ -129,7 +129,9 @@ typedef enum LAVHWDeintModes { // Software deinterlacing algorithms typedef enum LAVSWDeintModes { SWDeintMode_None, - SWDeintMode_YADIF + SWDeintMode_YADIF, + SWDeintMode_W3FDIF_Simple, + SWDeintMode_W3FDIF_Complex, } LAVSWDeintModes; // Deinterlacing processing mode diff --git a/decoder/LAVVideo/VideoSettingsProp.cpp b/decoder/LAVVideo/VideoSettingsProp.cpp index d2f3695a..3024ca22 100644 --- a/decoder/LAVVideo/VideoSettingsProp.cpp +++ b/decoder/LAVVideo/VideoSettingsProp.cpp @@ -148,8 +148,8 @@ HRESULT CLAVVideoSettingsProp::OnApplyChanges() //BOOL bVideo = (BOOL)SendDlgItemMessage(m_Dlg, IDC_HWDEINT_OUT_VIDEO, BM_GETCHECK, 0, 0); m_pVideoSettings->SetHWAccelDeintOutput(bFilm ? DeintOutput_FramePer2Field : DeintOutput_FramePerField); - bFlag = (BOOL)SendDlgItemMessage(m_Dlg, IDC_SWDEINT_ENABLE, BM_GETCHECK, 0, 0); - m_pVideoSettings->SetSWDeintMode(bFlag ? SWDeintMode_YADIF : SWDeintMode_None); + dwVal = (DWORD)SendDlgItemMessage(m_Dlg, IDC_SWDEINT_MODE, CB_GETCURSEL, 0, 0); + m_pVideoSettings->SetSWDeintMode((LAVSWDeintModes)dwVal); bFlag = (BOOL)SendDlgItemMessage(m_Dlg, IDC_SWDEINT_OUT_FILM, BM_GETCHECK, 0, 0); //BOOL bVideo = (BOOL)SendDlgItemMessage(m_Dlg, IDC_SWDEINT_OUT_VIDEO, BM_GETCHECK, 0, 0); @@ -228,6 +228,16 @@ HRESULT CLAVVideoSettingsProp::OnActivate() WideStringFromResource(stringBuffer, IDS_DEINTMODE_DISABLE); SendDlgItemMessage(m_Dlg, IDC_DEINT_MODE, CB_ADDSTRING, 0, (LPARAM)stringBuffer); + // SW Deint Mode + WCHAR swdeintNone[] = L"No Software Deinterlacing"; + WCHAR swdeintYADIF[] = L"YADIF"; + WCHAR swdeintW3FDIFS[] = L"Weston Three Field (Simple)"; + WCHAR swdeintW3FDIFC[] = L"Weston Three Field (Complex)"; + SendDlgItemMessage(m_Dlg, IDC_SWDEINT_MODE, CB_ADDSTRING, 0, (LPARAM)swdeintNone); + SendDlgItemMessage(m_Dlg, IDC_SWDEINT_MODE, CB_ADDSTRING, 0, (LPARAM)swdeintYADIF); + SendDlgItemMessage(m_Dlg, IDC_SWDEINT_MODE, CB_ADDSTRING, 0, (LPARAM)swdeintW3FDIFS); + SendDlgItemMessage(m_Dlg, IDC_SWDEINT_MODE, CB_ADDSTRING, 0, (LPARAM)swdeintW3FDIFC); + addHint(IDC_HWACCEL_MPEG4, L"EXPERIMENTAL! The MPEG4-ASP decoder is known to be unstable! Use at your own peril!"); addHint(IDC_HWACCEL_VP9, L"EXPERIMENTAL! The VP9 HW decoder is still under development and may be unstable!"); @@ -292,7 +302,7 @@ HRESULT CLAVVideoSettingsProp::OnActivate() SendDlgItemMessage(m_Dlg, IDC_HWDEINT_OUT_FILM, BM_SETCHECK, (m_HWDeintOutMode == DeintOutput_FramePer2Field), 0); SendDlgItemMessage(m_Dlg, IDC_HWDEINT_OUT_VIDEO, BM_SETCHECK, (m_HWDeintOutMode == DeintOutput_FramePerField), 0); - SendDlgItemMessage(m_Dlg, IDC_SWDEINT_ENABLE, BM_SETCHECK, m_SWDeint, 0); + SendDlgItemMessage(m_Dlg, IDC_SWDEINT_MODE, CB_SETCURSEL, m_SWDeint, 0); SendDlgItemMessage(m_Dlg, IDC_SWDEINT_OUT_FILM, BM_SETCHECK, (m_SWDeintOutMode == DeintOutput_FramePer2Field), 0); SendDlgItemMessage(m_Dlg, IDC_SWDEINT_OUT_VIDEO, BM_SETCHECK, (m_SWDeintOutMode == DeintOutput_FramePerField), 0); @@ -354,11 +364,11 @@ HRESULT CLAVVideoSettingsProp::UpdateHWOptions() HRESULT CLAVVideoSettingsProp::UpdateYADIFOptions() { - BOOL bYadifEnabled = (BOOL)SendDlgItemMessage(m_Dlg, IDC_SWDEINT_ENABLE, BM_GETCHECK, 0, 0); + DWORD dwVal = (DWORD)SendDlgItemMessage(m_Dlg, IDC_SWDEINT_MODE, CB_GETCURSEL, 0, 0); - EnableWindow(GetDlgItem(m_Dlg, IDC_LBL_SWDEINT_MODE), bYadifEnabled); - EnableWindow(GetDlgItem(m_Dlg, IDC_SWDEINT_OUT_FILM), bYadifEnabled); - EnableWindow(GetDlgItem(m_Dlg, IDC_SWDEINT_OUT_VIDEO), bYadifEnabled); + EnableWindow(GetDlgItem(m_Dlg, IDC_LBL_SWDEINT_MODE), (dwVal == SWDeintMode_YADIF)); + EnableWindow(GetDlgItem(m_Dlg, IDC_SWDEINT_OUT_FILM), (dwVal == SWDeintMode_YADIF)); + EnableWindow(GetDlgItem(m_Dlg, IDC_SWDEINT_OUT_VIDEO), (dwVal == SWDeintMode_YADIF)); return S_OK; } @@ -387,7 +397,7 @@ HRESULT CLAVVideoSettingsProp::LoadData() m_HWDeintAlgo = m_pVideoSettings->GetHWAccelDeintMode(); m_HWDeintOutMode = m_pVideoSettings->GetHWAccelDeintOutput(); - m_SWDeint = m_pVideoSettings->GetSWDeintMode() == SWDeintMode_YADIF; + m_SWDeint = m_pVideoSettings->GetSWDeintMode(); m_SWDeintOutMode = m_pVideoSettings->GetSWDeintOutput(); m_DitherMode = m_pVideoSettings->GetDitherMode(); @@ -593,9 +603,9 @@ INT_PTR CLAVVideoSettingsProp::OnReceiveMessage(HWND hwnd, UINT uMsg, WPARAM wPa if (bValue != (m_SWDeintOutMode == DeintOutput_FramePerField)) { SetDirty(); } - } else if (LOWORD(wParam) == IDC_SWDEINT_ENABLE && HIWORD(wParam) == BN_CLICKED) { - bValue = (BOOL)SendDlgItemMessage(m_Dlg, LOWORD(wParam), BM_GETCHECK, 0, 0); - if (bValue != m_SWDeint) { + } else if (HIWORD(wParam) == CBN_SELCHANGE && LOWORD(wParam) == IDC_SWDEINT_MODE) { + lValue = SendDlgItemMessage(m_Dlg, LOWORD(wParam), CB_GETCURSEL, 0, 0); + if (lValue != m_SWDeint) { SetDirty(); } UpdateYADIFOptions(); diff --git a/decoder/LAVVideo/VideoSettingsProp.h b/decoder/LAVVideo/VideoSettingsProp.h index fafbb119..dbec6f01 100644 --- a/decoder/LAVVideo/VideoSettingsProp.h +++ b/decoder/LAVVideo/VideoSettingsProp.h @@ -75,7 +75,7 @@ private: DWORD m_HWDeintAlgo; DWORD m_HWDeintOutMode; - BOOL m_SWDeint; + LAVSWDeintModes m_SWDeint; DWORD m_SWDeintOutMode; DWORD m_DitherMode; diff --git a/decoder/LAVVideo/resource.h b/decoder/LAVVideo/resource.h index b45fad24..3a5cc0d2 100644 --- a/decoder/LAVVideo/resource.h +++ b/decoder/LAVVideo/resource.h @@ -63,7 +63,7 @@ #define IDC_HWACCEL_AVAIL 1053 #define IDC_DEINT_SETTINGS 1054 #define IDC_DEINT_MODE 1055 -#define IDC_SWDEINT_ENABLE 1056 +#define IDC_SWDEINT_MODE 1056 #define IDC_SWDEINT 1057 #define IDC_LBL_SWDEINT_MODE 1058 #define IDC_SWDEINT_OUT_FILM 1059 |