Permalink
Browse files

Merge pull request #213 from elupus/avfilter

Changed libpostproc based software deinterlacer to yadif based using libavfilter
  • Loading branch information...
2 parents 15e04f8 + 1db605e commit ad392e9fbf169611b22630065fa078a3db055cf6 @elupus elupus committed Jun 21, 2011
View
@@ -371,6 +371,7 @@ project/Win32BuildSetup/dependencies/libcdio-10.dll
/system/players/dvdplayer/avcore-0.dll
/system/players/dvdplayer/avformat-52.dll
/system/players/dvdplayer/avutil-50.dll
+/system/players/dvdplayer/avfilter-1.dll
/system/players/dvdplayer/freetype6.dll
/system/players/dvdplayer/libass.dll
/system/players/dvdplayer/libdvdcss-2.dll
@@ -379,7 +380,7 @@ project/Win32BuildSetup/dependencies/libcdio-10.dll
/system/players/dvdplayer/libfontconfig-1.dll
/system/players/dvdplayer/librtmp.dll
/system/players/dvdplayer/postproc-51.dll
-/system/players/dvdplayer/swscale-0.6.1.dll
+/system/players/dvdplayer/swscale-0.dll
/system/players/dvdplayer/libbluray.dll
/system/players/dvdplayer/libmpeg2-0.dll
/system/players/dvdplayer/libmad.dll
View
@@ -0,0 +1,200 @@
+#pragma once
+/*
+ * Copyright (C) 2005-2011 Team XBMC
+ * http://www.xbmc.org
+ *
+ * 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, 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 XBMC; see the file COPYING. If not, write to
+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ */
+
+#if (defined HAVE_CONFIG_H) && (!defined WIN32)
+ #include "config.h"
+#endif
+#include "DynamicDll.h"
+#include "DllAvCore.h"
+#include "DllAvCodec.h"
+#include "utils/log.h"
+
+extern "C" {
+#ifndef HAVE_MMX
+#define HAVE_MMX
+#endif
+#ifndef __STDC_CONSTANT_MACROS
+#define __STDC_CONSTANT_MACROS
+#endif
+
+#ifndef __GNUC__
+#pragma warning(disable:4244)
+#endif
+
+#if (defined USE_EXTERNAL_FFMPEG)
+ #if (defined HAVE_LIBAVFILTER_AVFILTER_H)
+ #include <libavfilter/avfiltergraph.h>
+ #include <libavfilter/vsrc_buffer.h>
+ #elif (defined HAVE_FFMPEG_AVFILTER_H)
+ #include <ffmpeg/avfiltergraph.h>
+ #include <ffmpeg/vsrc_buffer.h>
+ #endif
+#else
+ #include "libavfilter/avfiltergraph.h"
+ #include "libavfilter/vsrc_buffer.h"
+#endif
+}
+
+#include "threads/SingleLock.h"
+
+class DllAvFilterInterface
+{
+public:
+ virtual ~DllAvFilterInterface() {}
+ virtual int avfilter_open_dont_call(AVFilterContext **filter_ctx, AVFilter *filter, const char *inst_name)=0;
+ virtual void avfilter_free_dont_call(AVFilterContext *filter)=0;
+ virtual void avfilter_graph_free_dont_call(AVFilterGraph *graph)=0;
+ virtual int avfilter_graph_create_filter(AVFilterContext **filt_ctx, AVFilter *filt, const char *name, const char *args, void *opaque, AVFilterGraph *graph_ctx)=0;
+ virtual AVFilter *avfilter_get_by_name(const char *name)=0;
+ virtual AVFilterGraph *avfilter_graph_alloc(void)=0;
+ virtual int avfilter_graph_parse(AVFilterGraph *graph, const char *filters, AVFilterInOut *inputs, AVFilterInOut *outputs, AVClass *log_ctx)=0;
+ virtual int avfilter_graph_config(AVFilterGraph *graphctx, AVClass *log_ctx)=0;
+ virtual int avfilter_poll_frame(AVFilterLink *link)=0;
+ virtual int avfilter_request_frame(AVFilterLink *link)=0;
+ virtual int av_vsrc_buffer_add_frame(AVFilterContext *buffer_filter, AVFrame *frame, int64_t pts, AVRational pixel_aspect)=0;
+ virtual AVFilterBufferRef *avfilter_get_video_buffer(AVFilterLink *link, int perms, int w, int h)=0;
+ virtual void avfilter_unref_buffer(AVFilterBufferRef *ref)=0;
+ virtual int avfilter_link(AVFilterContext *src, unsigned srcpad, AVFilterContext *dst, unsigned dstpad)=0;
+};
+
+#if (defined USE_EXTERNAL_FFMPEG)
+// Use direct mapping
+class DllAvFilter : public DllDynamic, DllAvFilterInterface
+{
+public:
+ virtual ~DllAvFilter();
+ virtual int avfilter_open(AVFilterContext **filter_ctx, AVFilter *filter, const char *inst_name)
+ {
+ CSingleLock lock(DllAvCodec::m_critSection);
+ return ::avfilter_open(filter_ctx, filter, inst_name);
+ }
+ virtual int avfilter_free(AVFilterContext *filter)
+ {
+ CSingleLock lock(DllAvCodec::m_critSection);
+ return ::avfilter_free(filter);
+ }
+ virtual int avfilter_graph_free(AVFilterGraph *graph)
+ {
+ CSingleLock lock(DllAvCodec::m_critSection);
+ return ::avfilter_graph_free(graph);
+ }
+ virtual int avfilter_open_dont_call(AVFilterContext **filter_ctx, AVFilter *filter, const char *inst_name) { *(int *)0x0 = 0; return 0; }
+ virtual void avfilter_free_dont_call(AVFilterContext *filter) { *(int *)0x0 = 0; }
+ virtual void avfilter_graph_free_dont_call(AVFilterGraph *graph) { *(int *)0x0 = 0; }
+ virtual int avfilter_graph_create_filter(AVFilterContext **filt_ctx, AVFilter *filt, const char *name, const char *args, void *opaque, AVFilterGraph *graph_ctx) { return ::avfilter_graph_create_filter(filt_ctx, filt, name, args, opaque, graph_ctx); }
+ virtual AVFilter *avfilter_get_by_name(const char *name) { return ::avfilter_get_by_name(name); }
+ virtual AVFilterGraph *avfilter_graph_alloc() { return ::avfilter_graph_alloc(); }
+ virtual int avfilter_graph_parse(AVFilterGraph *graph, const char *filters, AVFilterInOut *inputs, AVFilterInOut *outputs, AVClass *log_ctx) { return ::avfilter_graph_parse(graph, filters, inputs, outputs, log_ctx); }
+ virtual int avfilter_graph_config(AVFilterGraph *graphctx, AVClass *log_ctx) { return ::avfilter_graph_config(graphctx, log_ctx); }
+ virtual int avfilter_poll_frame(AVFilterLink *link) { return ::avfilter_poll_frame(link); }
+ virtual int avfilter_request_frame(AVFilterLink *link) { return ::avfilter_request_frame(link); }
+ virtual int av_vsrc_buffer_add_frame(AVFilterContext *buffer_filter, AVFrame *frame, int64_t pts, AVRational pixel_aspect) { return ::av_vsrc_buffer_add_frame(buffer_filter, frame, pts, pixel_aspect); }
+ virtual AVFilterBufferRef *avfilter_get_video_buffer(AVFilterLink *link, int perms, int w, int h) { return ::avfilter_get_video_buffer(link, perms, w, h); }
+ virtual void avfilter_unref_buffer(AVFilterBufferRef *ref) { ::avfilter_unref_buffer(ref); }
+ virtual int avfilter_link(AVFilterContext *src, unsigned srcpad, AVFilterContext *dst, unsigned dstpad) { return ::avfilter_link(src, srcpad, dst, dstpad); }
+ // DLL faking.
+ virtual bool ResolveExports() { return true; }
+ virtual bool Load() {
+ CLog::Log(LOGDEBUG, "DllAvFilter: Using libavfilter system library");
+ return true;
+ }
+ virtual void Unload() {}
+};
+#else
+class DllAvFilter : public DllDynamic, DllAvFilterInterface
+{
+ DECLARE_DLL_WRAPPER(DllAvFilter, DLL_PATH_LIBAVFILTER)
+
+ LOAD_SYMBOLS()
+
+ DEFINE_METHOD3(int, avfilter_open_dont_call, (AVFilterContext **p1, AVFilter *p2, const char *p3))
+ DEFINE_METHOD1(void, avfilter_free_dont_call, (AVFilterContext *p1))
+ DEFINE_METHOD1(void, avfilter_graph_free_dont_call, (AVFilterGraph *p1))
+ DEFINE_METHOD0(void, avfilter_register_all_dont_call)
+ DEFINE_METHOD6(int, avfilter_graph_create_filter, (AVFilterContext **p1, AVFilter *p2, const char *p3, const char *p4, void *p5, AVFilterGraph *p6))
+ DEFINE_METHOD1(AVFilter*, avfilter_get_by_name, (const char *p1))
+ DEFINE_METHOD0(AVFilterGraph*, avfilter_graph_alloc)
+ DEFINE_METHOD5(int, avfilter_graph_parse, (AVFilterGraph *p1, const char *p2, AVFilterInOut *p3, AVFilterInOut *p4, AVClass *p5))
+ DEFINE_METHOD2(int, avfilter_graph_config, (AVFilterGraph *p1, AVClass *p2))
+#ifdef _LINUX
+ DEFINE_METHOD1(int, avfilter_poll_frame, (AVFilterLink *p1))
+ DEFINE_METHOD1(int, avfilter_request_frame, (AVFilterLink* p1))
+#else
+ DEFINE_FUNC_ALIGNED1(int, __cdecl, avfilter_poll_frame, AVFilterLink *)
+ DEFINE_FUNC_ALIGNED1(int, __cdecl, avfilter_request_frame, AVFilterLink*)
+#endif
+ DEFINE_METHOD4(int, av_vsrc_buffer_add_frame, (AVFilterContext *p1, AVFrame *p2, int64_t p3, AVRational p4))
+ DEFINE_METHOD4(AVFilterBufferRef*, avfilter_get_video_buffer, (AVFilterLink *p1, int p2, int p3, int p4))
+ DEFINE_METHOD1(void, avfilter_unref_buffer, (AVFilterBufferRef *p1))
+ DEFINE_METHOD4(int, avfilter_link, (AVFilterContext *p1, unsigned p2, AVFilterContext *p3, unsigned p4))
+
+ BEGIN_METHOD_RESOLVE()
+ RESOLVE_METHOD_RENAME(avfilter_open, avfilter_open_dont_call)
+ RESOLVE_METHOD_RENAME(avfilter_free, avfilter_free_dont_call)
+ RESOLVE_METHOD_RENAME(avfilter_graph_free ,avfilter_graph_free_dont_call)
+ RESOLVE_METHOD_RENAME(avfilter_register_all, avfilter_register_all_dont_call)
+ RESOLVE_METHOD(avfilter_graph_create_filter)
+ RESOLVE_METHOD(avfilter_get_by_name)
+ RESOLVE_METHOD(avfilter_graph_alloc)
+ RESOLVE_METHOD(avfilter_graph_parse)
+ RESOLVE_METHOD(avfilter_graph_config)
+ RESOLVE_METHOD(avfilter_poll_frame)
+ RESOLVE_METHOD(avfilter_request_frame)
+ RESOLVE_METHOD(av_vsrc_buffer_add_frame)
+ RESOLVE_METHOD(avfilter_get_video_buffer)
+ RESOLVE_METHOD(avfilter_unref_buffer)
+ RESOLVE_METHOD(avfilter_link)
+ END_METHOD_RESOLVE()
+
+ /* dependencies of libavfilter */
+ DllAvCore m_dllAvCore;
+ // DllAvUtil loaded implicitely by m_dllAvCore
+
+public:
+ int avfilter_open(AVFilterContext **filter_ctx, AVFilter *filter, const char *inst_name)
+ {
+ CSingleLock lock(DllAvCodec::m_critSection);
+ return avfilter_open_dont_call(filter_ctx, filter, inst_name);
+ }
+ void avfilter_free(AVFilterContext *filter)
+ {
+ CSingleLock lock(DllAvCodec::m_critSection);
+ avfilter_free_dont_call(filter);
+ }
+ void avfilter_graph_free(AVFilterGraph *graph)
+ {
+ CSingleLock lock(DllAvCodec::m_critSection);
+ avfilter_graph_free_dont_call(graph);
+ }
+ void avfilter_register_all()
+ {
+ CSingleLock lock(DllAvCodec::m_critSection);
+ avfilter_register_all_dont_call();
+ }
+ virtual bool Load()
+ {
+ if (!m_dllAvCore.Load())
+ return false;
+ return DllDynamic::Load();
+ }
+};
+#endif
View
@@ -54,10 +54,16 @@ extern "C" {
#else
#include <ffmpeg/opt.h>
#endif
+ #if defined(HAVE_LIBAVUTIL_MEM_H)
+ #include <libavutil/mem.h>
+ #else
+ #include <ffmpeg/mem.h>
+ #endif
#else
#include "libavutil/avutil.h"
#include "libavutil/crc.h"
#include "libavutil/opt.h"
+ #include "libavutil/mem.h"
#include "libavutil/fifo.h"
#endif
}
@@ -90,6 +96,7 @@ class DllAvUtilInterface
virtual int av_fifo_size(AVFifoBuffer *f) = 0;
virtual int av_fifo_generic_read(AVFifoBuffer *f, void *dest, int buf_size, void (*func)(void*, void*, int)) = 0;
virtual int av_fifo_generic_write(AVFifoBuffer *f, void *src, int size, int (*func)(void*, void*, int)) = 0;
+ virtual char *av_strdup(const char *s)=0;
};
#if (defined USE_EXTERNAL_FFMPEG)
@@ -124,6 +131,7 @@ class DllAvUtilBase : public DllDynamic, DllAvUtilInterface
{ return ::av_fifo_generic_read(f, dest, buf_size, func); }
virtual int av_fifo_generic_write(AVFifoBuffer *f, void *src, int size, int (*func)(void*, void*, int))
{ return ::av_fifo_generic_write(f, src, size, func); }
+ virtual char *av_strdup(const char *s) { return ::av_strdup(s); }
// DLL faking.
virtual bool ResolveExports() { return true; }
@@ -159,6 +167,7 @@ class DllAvUtilBase : public DllDynamic, DllAvUtilInterface
DEFINE_METHOD1(int, av_fifo_size, (AVFifoBuffer *p1))
DEFINE_METHOD4(int, av_fifo_generic_read, (AVFifoBuffer *p1, void *p2, int p3, void (*p4)(void*, void*, int)))
DEFINE_METHOD4(int, av_fifo_generic_write, (AVFifoBuffer *p1, void *p2, int p3, int (*p4)(void*, void*, int)))
+ DEFINE_METHOD1(char*, av_strdup, (const char *p1))
public:
BEGIN_METHOD_RESOLVE()
@@ -179,6 +188,7 @@ class DllAvUtilBase : public DllDynamic, DllAvUtilInterface
RESOLVE_METHOD(av_fifo_size)
RESOLVE_METHOD(av_fifo_generic_read)
RESOLVE_METHOD(av_fifo_generic_write)
+ RESOLVE_METHOD(av_strdup)
END_METHOD_RESOLVE()
};
View
@@ -30,6 +30,7 @@ ifneq (@USE_EXTERNAL_FFMPEG@,1)
avcore-0-$(ARCH).so \
avformat-52-$(ARCH).so \
postproc-51-$(ARCH).so \
+ avfilter-1-$(ARCH).so \
swscale-0-$(ARCH).so
endif
@@ -72,6 +73,10 @@ $(SYSDIR)/avformat-52-$(ARCH).so: $(WRAPPER) ffmpeg/libavformat/libavformat.dyli
$(LD) $(LDFLAGS) -alias_list $(WRAPPER_MACH_ALIAS) -o $@ \
$(WRAPPER) ffmpeg/libavformat/*.o $(BUNDLE1_O)
+$(SYSDIR)/avfilter-1-$(ARCH).so: $(WRAPPER) ffmpeg/libavfilter/libavfilter.dylib
+ $(LD) $(LDFLAGS) -alias_list $(WRAPPER_MACH_ALIAS) -o $@ \
+ $(WRAPPER) ffmpeg/libavfilter/*.o $(BUNDLE1_O)
+
ifneq ($(findstring arm,$(ARCH)), arm)
$(SYSDIR)/swscale-0-$(ARCH).so: $(WRAPPER) ffmpeg/libswscale/libswscale.dylib
$(LD) $(LDFLAGS) -alias_list $(WRAPPER_MACH_ALIAS) -o $@ \
@@ -91,6 +96,7 @@ ffmpeg/libavutil/libavutil.dylib : ffmpeg;
ffmpeg/libavcodec/libavcodec.dylib : ffmpeg;
ffmpeg/libavcore/libavcore.dylib : ffmpeg;
ffmpeg/libavformat/libavformat.dylib : ffmpeg;
+ffmpeg/libavformat/libavfilter.dylib : ffmpeg;
ffmpeg/libswscale/libswscale.dylib : ffmpeg;
ffmpeg/libpostproc/libpostproc.dylib : ffmpeg;
ffmpeg:
@@ -110,6 +116,9 @@ $(SYSDIR)/avcore-0-$(ARCH).so: $(WRAPPER) ffmpeg/libavcore/libavcore.so
$(SYSDIR)/avformat-52-$(ARCH).so: $(WRAPPER) ffmpeg/libavformat/libavformat.so
cp ffmpeg/libavformat/libavformat.so $@
+$(SYSDIR)/avfilter-1-$(ARCH).so: $(WRAPPER) ffmpeg/libavfilter/libavfilter.so
+ cp ffmpeg/libavfilter/libavfilter.so $@
+
ifneq ($(ARCH), arm)
$(SYSDIR)/swscale-0-$(ARCH).so: $(WRAPPER) ffmpeg/libswscale/libswscale.so
cp ffmpeg/libswscale/libswscale.so $@
@@ -127,6 +136,7 @@ ffmpeg/libavutil/libavutil.so : ffmpeg;
ffmpeg/libavcodec/libavcodec.so : ffmpeg;
ffmpeg/libavcore/libavcore.so : ffmpeg;
ffmpeg/libavformat/libavformat.so : ffmpeg;
+ffmpeg/libavfilter/libavfilter.so : ffmpeg;
ffmpeg/libswscale/libswscale.so : ffmpeg;
ffmpeg/libpostproc/libpostproc.so : ffmpeg;
ffmpeg:
@@ -35,17 +35,18 @@ OPTIONS="
--enable-encoder=ac3 \
--enable-encoder=aac \
--enable-runtime-cpudetect \
+--enable-avfilter \
--disable-debug \
--disable-doc"
./configure --extra-cflags="-fno-common -Iinclude-xbmc-win32/dxva2" --extra-ldflags="-L/xbmc/system/players/dvdplayer" ${OPTIONS} &&
make &&
cp lib*/*.dll .libs/ &&
-mv .libs/swscale-0.dll .libs/swscale-0.6.1.dll &&
cp .libs/avcodec-52.dll /xbmc/system/players/dvdplayer/ &&
cp .libs/avcore-0.dll /xbmc/system/players/dvdplayer/ &&
cp .libs/avformat-52.dll /xbmc/system/players/dvdplayer/ &&
cp .libs/avutil-50.dll /xbmc/system/players/dvdplayer/ &&
+cp .libs/avfilter-1.dll /xbmc/system/players/dvdplayer/ &&
cp .libs/postproc-51.dll /xbmc/system/players/dvdplayer/ &&
-cp .libs/swscale-0.6.1.dll /xbmc/system/players/dvdplayer/
+cp .libs/swscale-0.dll /xbmc/system/players/dvdplayer/
@@ -1163,6 +1163,7 @@
<ClCompile Include="..\..\xbmc\xbmc.cpp" />
</ItemGroup>
<ItemGroup>
+ <ClInclude Include="..\..\lib\DllAvFilter.h" />
<ClInclude Include="..\..\lib\ffmpeg\include-xbmc-win32\libavutil\avconfig.h" />
<ClInclude Include="..\..\lib\SlingboxLib\SlingboxLib.h" />
<ClInclude Include="..\..\lib\tinyXML\tinystr.h" />
@@ -4940,6 +4940,9 @@
<ClInclude Include="..\..\xbmc\addons\AddonVersion.h">
<Filter>addons</Filter>
</ClInclude>
+ <ClInclude Include="..\..\lib\DllAvFilter.h">
+ <Filter>cores\dvdplayer\DVDHeaders</Filter>
+ </ClInclude>
<ClInclude Include="..\..\xbmc\guilib\DirtyRegionTracker.h">
<Filter>guilib</Filter>
</ClInclude>
@@ -4965,4 +4968,4 @@
<Filter>win32</Filter>
</CustomBuild>
</ItemGroup>
-</Project>
+</Project>
@@ -59,7 +59,7 @@ echo "##### building ffmpeg dlls #####"
cd /xbmc/lib/ffmpeg/
sh ./build_xbmc_win32.sh $MAKECLEAN
setfilepath /xbmc/system/players/dvdplayer
-checkfiles avcodec-52.dll avcore-0.dll avformat-52.dll avutil-50.dll postproc-51.dll swscale-0.6.1.dll
+checkfiles avcodec-52.dll avcore-0.dll avformat-52.dll avutil-50.dll postproc-51.dll swscale-0.dll avfilter-1.dll
echo "##### building of ffmpeg dlls done #####"
echo "##### building libdvd dlls #####"
@@ -76,6 +76,7 @@
#define DLL_PATH_LIBAVUTIL "special://xbmcbin/system/players/dvdplayer/avutil-50-@ARCH@.so"
#define DLL_PATH_LIBPOSTPROC "special://xbmcbin/system/players/dvdplayer/postproc-51-@ARCH@.so"
#define DLL_PATH_LIBSWSCALE "special://xbmcbin/system/players/dvdplayer/swscale-0-@ARCH@.so"
+#define DLL_PATH_LIBAVFILTER "special://xbmcbin/system/players/dvdplayer/avfilter-1-@ARCH@.so"
/* cdrip */
#if defined(_LINUX) && !defined(__APPLE__)
View
@@ -63,8 +63,9 @@
#define DLL_PATH_LIBAVCORE "special://xbmcbin/system/players/dvdplayer/avcore-0.dll"
#define DLL_PATH_LIBAVFORMAT "special://xbmcbin/system/players/dvdplayer/avformat-52.dll"
#define DLL_PATH_LIBAVUTIL "special://xbmcbin/system/players/dvdplayer/avutil-50.dll"
+#define DLL_PATH_LIBAVFILTER "special://xbmcbin/system/players/dvdplayer/avfilter-1.dll"
#define DLL_PATH_LIBPOSTPROC "special://xbmcbin/system/players/dvdplayer/postproc-51.dll"
-#define DLL_PATH_LIBSWSCALE "special://xbmcbin/system/players/dvdplayer/swscale-0.6.1.dll"
+#define DLL_PATH_LIBSWSCALE "special://xbmcbin/system/players/dvdplayer/swscale-0.dll"
/* cdrip */
#define DLL_PATH_LAME_ENC "special://xbmcbin/system/cdrip/lame_enc.dll"
Oops, something went wrong.

17 comments on commit ad392e9

Member

hi elupus - First of all, thanks this is a great addition to MPEG2 DVD decoding (especially for old interlaced material). I have just built this on Win32, and works great on powerful CPUs. Unfortunately, the Atom 330 CPU I have doesn't seem to be powerful enough to do YADIF as I'm getting lots of frame drops (about 1-3 frames per second). Is there a way to offload the filter processing to the (ION) GPU?

Member

@bob1on1 wrote (part of ?) yadif with shaders i think. Also i think we could enable hardware decoding of dvd's outside menus. That way we'd get the vdpau deinterlacers for the normal movie parts. But needs alot of testing. If you look at c3e5b2b you can change the hints.software flag to be identical to how the hints.stills flag, that should give that effect.

Member

I never finished that, but it wasn't terribly difficult to port yadif to a glsl shader.

Member

Does it mean that if hints.software flag = false for dvd video outside menus works ok, we don't need new yadif+shader code? Or do we somehow still need this?

Member

on ion that would mean we don't need yadif yes since vdpau have good deinterlacers already.

Member

does that also apply to windows? or would we need dxva deinterlacing then, like the patch that is currently under development by a11559 / isidrogar?

Member

build broken with external ffmpeg version > 2011-02-06
see 97b65d8 commit log

Member

Voyager-xbmc technically yes, but currently no dxva deinterlacing is supported i think. Same would go for vaapi.

Member

also libavfilter/vsrc_buffer.h header is not copied by ffmpeg install script
so the file is not present with external ffmpeg.
AND av_vsrc_buffer_add is not present on all ffmpeg version so you can't use it :(

Member

It should be available on all that libavfilter have compiled no?.. it has changed prototype a few times.

Contributor

I found a few issues with this patch.

The first issue is that display framerate gets doubled after changing deinterlace method from none to anything else (even automatic for progressive video). Once the framerate is doubled, it never goes back to the movie framerate even if changing deinterlace option to none. The framerate should only be doubled if yadif is doing any processing. That is, if interlace method is automatic and source is progressive, or the user explicitly forces deinterlace. This will also cause trouble with auto refresh rate (if someone sets deinterlace to auto for all videos -> 2x output framerate -> display will switch to 60 Hz for 24p content as many displays do not support 48 Hz).

Second, the automatic scaling option checks video dimensions and fps before selecting the actual scaling algorithm. By default if video is SD and fps is below a certain threshold (30 IIRC) the Lanczos3 optimized option is selected. But when the framerate is doubled for yadif, the scaler algorithm is not refreshed so if the video was SD and now the display framerate is doubled it will still be scaled using Lanczos3 optimized which tops out at ~30 fps for low-end graphics like the ION -> heavy stutter.

Contributor

I'm investigating the problem and seems like I already have a fix to the first part of the issue. Working on second part, will report soon.
EDIT: hm, seems fixing the automatic deinterlacer is somewhat more difficult... :(

Member

Changing mode to none should make it go back to normal fps. But yes. auto mode is somewhat broken now. It should be fixed inside the yadif filter thou so we don't disable the whole filter graph just cause something is marked as progressive.

Contributor

Yep, I cannot fix auto from XBMC as the picture flags will (obviously) report the video as progressive after decode stage, so I give up on that. The fix on the other part of the problem works however fine. Will now check how to handle the automatic scaler algorithm selection issue.

EDIT: Found a fix to all issues, including automatic deinterlace method. Sent as a pull req.

Member

Just hold off on this a few days until I've looked at the current issues. I suspect you'll just do double work with me.

Contributor

Ok, feel free to use any part of the pull req. I submitted.

Member

As long as hardware decoding isn't working for dvd's we need a possibility to turn off the filter. It's too CPU intensive on Atoms. Perhaps "advancedsettings?"

Please sign in to comment.