Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mpc-hc/mpc-hc.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorXhmikosR <xhmikosr@users.sourceforge.net>2011-08-11 02:02:49 +0400
committerXhmikosR <xhmikosr@users.sourceforge.net>2011-08-11 02:02:49 +0400
commit5120ff34ceb2baee049582abded29ea597f3372b (patch)
tree3811dcdd8693f44517fb2e7fa6f1db9f92b99e65 /src/thirdparty/VirtualDub
parent24fc79bfb297d24b091e6950f9277edfe9e88c84 (diff)
update VirtualDub to v1.10.1-test11
git-svn-id: https://mpc-hc.svn.sourceforge.net/svnroot/mpc-hc/trunk@3643 10f7b99b-c216-0410-bff0-8a66a9350fd8
Diffstat (limited to 'src/thirdparty/VirtualDub')
-rw-r--r--src/thirdparty/VirtualDub/Kasumi/Kasumi.vcxproj4
-rw-r--r--src/thirdparty/VirtualDub/Kasumi/Kasumi.vcxproj.filters12
-rw-r--r--src/thirdparty/VirtualDub/Kasumi/h/blt_spanutils_x86.h2
-rw-r--r--src/thirdparty/VirtualDub/Kasumi/h/stdafx.h21
-rw-r--r--src/thirdparty/VirtualDub/Kasumi/h/uberblit.h40
-rw-r--r--src/thirdparty/VirtualDub/Kasumi/h/uberblit_base.h2
-rw-r--r--src/thirdparty/VirtualDub/Kasumi/h/uberblit_gen.h10
-rw-r--r--src/thirdparty/VirtualDub/Kasumi/h/uberblit_interlace.h123
-rw-r--r--src/thirdparty/VirtualDub/Kasumi/h/uberblit_ycbcr.h154
-rw-r--r--src/thirdparty/VirtualDub/Kasumi/h/uberblit_ycbcr_generic.h154
-rw-r--r--src/thirdparty/VirtualDub/Kasumi/source/alphablt.cpp19
-rw-r--r--src/thirdparty/VirtualDub/Kasumi/source/blitter.cpp52
-rw-r--r--src/thirdparty/VirtualDub/Kasumi/source/blt.cpp24
-rw-r--r--src/thirdparty/VirtualDub/Kasumi/source/blt_reference.cpp89
-rw-r--r--src/thirdparty/VirtualDub/Kasumi/source/blt_reference_pal.cpp19
-rw-r--r--src/thirdparty/VirtualDub/Kasumi/source/blt_reference_rgb.cpp19
-rw-r--r--src/thirdparty/VirtualDub/Kasumi/source/blt_reference_yuv.cpp19
-rw-r--r--src/thirdparty/VirtualDub/Kasumi/source/blt_reference_yuv2yuv.cpp19
-rw-r--r--src/thirdparty/VirtualDub/Kasumi/source/blt_reference_yuvrev.cpp19
-rw-r--r--src/thirdparty/VirtualDub/Kasumi/source/blt_setup.cpp19
-rw-r--r--src/thirdparty/VirtualDub/Kasumi/source/blt_spanutils.cpp19
-rw-r--r--src/thirdparty/VirtualDub/Kasumi/source/blt_spanutils_x86.cpp3
-rw-r--r--src/thirdparty/VirtualDub/Kasumi/source/blt_uberblit.cpp19
-rw-r--r--src/thirdparty/VirtualDub/Kasumi/source/blt_x86.cpp19
-rw-r--r--src/thirdparty/VirtualDub/Kasumi/source/pixel.cpp371
-rw-r--r--src/thirdparty/VirtualDub/Kasumi/source/pixmaputils.cpp100
-rw-r--r--src/thirdparty/VirtualDub/Kasumi/source/region.cpp152
-rw-r--r--src/thirdparty/VirtualDub/Kasumi/source/resample.cpp3
-rw-r--r--src/thirdparty/VirtualDub/Kasumi/source/resample_kernels.cpp37
-rw-r--r--src/thirdparty/VirtualDub/Kasumi/source/resample_stages.cpp19
-rw-r--r--src/thirdparty/VirtualDub/Kasumi/source/resample_stages_reference.cpp19
-rw-r--r--src/thirdparty/VirtualDub/Kasumi/source/resample_stages_x86.cpp27
-rw-r--r--src/thirdparty/VirtualDub/Kasumi/source/stdafx.cpp19
-rw-r--r--src/thirdparty/VirtualDub/Kasumi/source/stretchblt_reference.cpp19
-rw-r--r--src/thirdparty/VirtualDub/Kasumi/source/tables.cpp1
-rw-r--r--src/thirdparty/VirtualDub/Kasumi/source/triblt.cpp75
-rw-r--r--src/thirdparty/VirtualDub/Kasumi/source/uberblit.cpp703
-rw-r--r--src/thirdparty/VirtualDub/Kasumi/source/uberblit_16f.cpp19
-rw-r--r--src/thirdparty/VirtualDub/Kasumi/source/uberblit_gen.cpp136
-rw-r--r--src/thirdparty/VirtualDub/Kasumi/source/uberblit_resample.cpp19
-rw-r--r--src/thirdparty/VirtualDub/Kasumi/source/uberblit_resample_special.cpp19
-rw-r--r--src/thirdparty/VirtualDub/Kasumi/source/uberblit_resample_special_x86.cpp19
-rw-r--r--src/thirdparty/VirtualDub/Kasumi/source/uberblit_swizzle.cpp19
-rw-r--r--src/thirdparty/VirtualDub/Kasumi/source/uberblit_swizzle_x86.cpp19
-rw-r--r--src/thirdparty/VirtualDub/Kasumi/source/uberblit_v210.cpp19
-rw-r--r--src/thirdparty/VirtualDub/Kasumi/source/uberblit_ycbcr_generic.cpp545
-rw-r--r--src/thirdparty/VirtualDub/Kasumi/source/uberblit_ycbcr_x86.cpp19
-rw-r--r--src/thirdparty/VirtualDub/h/vd2/Kasumi/blitter.h20
-rw-r--r--src/thirdparty/VirtualDub/h/vd2/Kasumi/pixel.h6
-rw-r--r--src/thirdparty/VirtualDub/h/vd2/Kasumi/pixmap.h33
-rw-r--r--src/thirdparty/VirtualDub/h/vd2/Kasumi/region.h2
-rw-r--r--src/thirdparty/VirtualDub/h/vd2/Kasumi/text.h16
-rw-r--r--src/thirdparty/VirtualDub/h/vd2/Kasumi/triblt.h3
-rw-r--r--src/thirdparty/VirtualDub/h/vd2/system/Error.h5
-rw-r--r--src/thirdparty/VirtualDub/h/vd2/system/VDScheduler.h27
-rw-r--r--src/thirdparty/VirtualDub/h/vd2/system/VDString.h149
-rw-r--r--src/thirdparty/VirtualDub/h/vd2/system/atomic.h36
-rw-r--r--src/thirdparty/VirtualDub/h/vd2/system/binary.h4
-rw-r--r--src/thirdparty/VirtualDub/h/vd2/system/bitmath.h20
-rw-r--r--src/thirdparty/VirtualDub/h/vd2/system/cache.h38
-rw-r--r--src/thirdparty/VirtualDub/h/vd2/system/cmdline.h5
-rw-r--r--src/thirdparty/VirtualDub/h/vd2/system/date.h60
-rw-r--r--src/thirdparty/VirtualDub/h/vd2/system/event.h6
-rw-r--r--src/thirdparty/VirtualDub/h/vd2/system/file.h8
-rw-r--r--src/thirdparty/VirtualDub/h/vd2/system/fileasync.h2
-rw-r--r--src/thirdparty/VirtualDub/h/vd2/system/filesys.h96
-rw-r--r--src/thirdparty/VirtualDub/h/vd2/system/hash.h4
-rw-r--r--src/thirdparty/VirtualDub/h/vd2/system/linearalloc.h84
-rw-r--r--src/thirdparty/VirtualDub/h/vd2/system/log.h7
-rw-r--r--src/thirdparty/VirtualDub/h/vd2/system/math.h8
-rw-r--r--src/thirdparty/VirtualDub/h/vd2/system/process.h33
-rw-r--r--src/thirdparty/VirtualDub/h/vd2/system/profile.h32
-rw-r--r--src/thirdparty/VirtualDub/h/vd2/system/refcount.h29
-rw-r--r--src/thirdparty/VirtualDub/h/vd2/system/registry.h111
-rw-r--r--src/thirdparty/VirtualDub/h/vd2/system/registrymemory.h81
-rw-r--r--src/thirdparty/VirtualDub/h/vd2/system/source/registrymemory.cpp657
-rw-r--r--src/thirdparty/VirtualDub/h/vd2/system/strutil.h16
-rw-r--r--src/thirdparty/VirtualDub/h/vd2/system/thread.h4
-rw-r--r--src/thirdparty/VirtualDub/h/vd2/system/vdalloc.h22
-rw-r--r--src/thirdparty/VirtualDub/h/vd2/system/vdstl.h68
-rw-r--r--src/thirdparty/VirtualDub/h/vd2/system/vdstl_hash.h124
-rw-r--r--src/thirdparty/VirtualDub/h/vd2/system/vdstl_hashmap.h548
-rw-r--r--src/thirdparty/VirtualDub/h/vd2/system/vdstl_hashset.h513
-rw-r--r--src/thirdparty/VirtualDub/h/vd2/system/vdstl_hashtable.h361
-rw-r--r--src/thirdparty/VirtualDub/h/vd2/system/vdstl_vector.h606
-rw-r--r--src/thirdparty/VirtualDub/h/vd2/system/vdtypes.h2
-rw-r--r--src/thirdparty/VirtualDub/h/vd2/system/vectors.h37
-rw-r--r--src/thirdparty/VirtualDub/h/vd2/system/w32assist.h10
-rw-r--r--src/thirdparty/VirtualDub/h/vd2/system/win32/miniwindows.h1
-rw-r--r--src/thirdparty/VirtualDub/system/linearalloc.cpp55
-rw-r--r--src/thirdparty/VirtualDub/system/source/Error.cpp4
-rw-r--r--src/thirdparty/VirtualDub/system/source/VDScheduler.cpp48
-rw-r--r--src/thirdparty/VirtualDub/system/source/VDString.cpp74
-rw-r--r--src/thirdparty/VirtualDub/system/source/a64_thunk.asm4
-rw-r--r--src/thirdparty/VirtualDub/system/source/cmdline.cpp32
-rw-r--r--src/thirdparty/VirtualDub/system/source/date.cpp131
-rw-r--r--src/thirdparty/VirtualDub/system/source/event.cpp9
-rw-r--r--src/thirdparty/VirtualDub/system/source/file.cpp34
-rw-r--r--src/thirdparty/VirtualDub/system/source/fileasync.cpp98
-rw-r--r--src/thirdparty/VirtualDub/system/source/filesys.cpp506
-rw-r--r--src/thirdparty/VirtualDub/system/source/hash.cpp25
-rw-r--r--src/thirdparty/VirtualDub/system/source/log.cpp14
-rw-r--r--src/thirdparty/VirtualDub/system/source/process.cpp47
-rw-r--r--src/thirdparty/VirtualDub/system/source/profile.cpp4
-rw-r--r--src/thirdparty/VirtualDub/system/source/registry.cpp435
-rw-r--r--src/thirdparty/VirtualDub/system/source/thread.cpp20
-rw-r--r--src/thirdparty/VirtualDub/system/source/thunk.cpp7
-rw-r--r--src/thirdparty/VirtualDub/system/source/time.cpp4
-rw-r--r--src/thirdparty/VirtualDub/system/source/vdstl_hash.cpp69
-rw-r--r--src/thirdparty/VirtualDub/system/source/vdstl_hashtable.cpp82
-rw-r--r--src/thirdparty/VirtualDub/system/source/vectors.cpp6
-rw-r--r--src/thirdparty/VirtualDub/system/source/w32assist.cpp94
-rw-r--r--src/thirdparty/VirtualDub/system/source/zip.cpp47
-rw-r--r--src/thirdparty/VirtualDub/system/system.vcxproj15
-rw-r--r--src/thirdparty/VirtualDub/system/system.vcxproj.filters45
115 files changed, 8448 insertions, 613 deletions
diff --git a/src/thirdparty/VirtualDub/Kasumi/Kasumi.vcxproj b/src/thirdparty/VirtualDub/Kasumi/Kasumi.vcxproj
index 8ca5eefac..69aac6598 100644
--- a/src/thirdparty/VirtualDub/Kasumi/Kasumi.vcxproj
+++ b/src/thirdparty/VirtualDub/Kasumi/Kasumi.vcxproj
@@ -110,6 +110,7 @@
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="source\alphablt.cpp" />
+ <ClCompile Include="source\blitter.cpp" />
<ClCompile Include="source\blt.cpp" />
<ClCompile Include="source\blt_reference.cpp" />
<ClCompile Include="source\blt_reference_pal.cpp" />
@@ -141,6 +142,7 @@
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="source\uberblit_v210.cpp" />
+ <ClCompile Include="source\uberblit_ycbcr_generic.cpp" />
<ClCompile Include="source\uberblit_ycbcr_x86.cpp">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
@@ -190,6 +192,7 @@
<ClInclude Include="h\uberblit_fill.h" />
<ClInclude Include="h\uberblit_gen.h" />
<ClInclude Include="h\uberblit_input.h" />
+ <ClInclude Include="h\uberblit_interlace.h" />
<ClInclude Include="h\uberblit_pal.h" />
<ClInclude Include="h\uberblit_resample.h" />
<ClInclude Include="h\uberblit_resample_special.h" />
@@ -200,6 +203,7 @@
<ClInclude Include="h\uberblit_swizzle_x86.h" />
<ClInclude Include="h\uberblit_v210.h" />
<ClInclude Include="h\uberblit_ycbcr.h" />
+ <ClInclude Include="h\uberblit_ycbcr_generic.h" />
<ClInclude Include="h\uberblit_ycbcr_x86.h" />
<ClInclude Include="..\h\vd2\Kasumi\blitter.h" />
<ClInclude Include="..\h\vd2\Kasumi\resample_kernels.h" />
diff --git a/src/thirdparty/VirtualDub/Kasumi/Kasumi.vcxproj.filters b/src/thirdparty/VirtualDub/Kasumi/Kasumi.vcxproj.filters
index 728a2eb51..e8840b9c5 100644
--- a/src/thirdparty/VirtualDub/Kasumi/Kasumi.vcxproj.filters
+++ b/src/thirdparty/VirtualDub/Kasumi/Kasumi.vcxproj.filters
@@ -133,6 +133,12 @@
<ClCompile Include="source\resample_stages_x64.cpp">
<Filter>Source Files %28x64%29</Filter>
</ClCompile>
+ <ClCompile Include="source\blitter.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="source\uberblit_ycbcr_generic.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="h\bitutils.h">
@@ -243,6 +249,12 @@
<ClInclude Include="..\h\vd2\Kasumi\resample_kernels.h">
<Filter>Interface Header Files</Filter>
</ClInclude>
+ <ClInclude Include="h\uberblit_interlace.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="h\uberblit_ycbcr_generic.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
</ItemGroup>
<ItemGroup>
<YASM Include="source\a_bltrgb.asm">
diff --git a/src/thirdparty/VirtualDub/Kasumi/h/blt_spanutils_x86.h b/src/thirdparty/VirtualDub/Kasumi/h/blt_spanutils_x86.h
index c697485a2..d0893558a 100644
--- a/src/thirdparty/VirtualDub/Kasumi/h/blt_spanutils_x86.h
+++ b/src/thirdparty/VirtualDub/Kasumi/h/blt_spanutils_x86.h
@@ -1,6 +1,6 @@
// VirtualDub - Video processing and capture application
// Graphics support library
-// Copyright (C) 1998-2007 Avery Lee
+// Copyright (C) 1998-2009 Avery Lee
//
// 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
diff --git a/src/thirdparty/VirtualDub/Kasumi/h/stdafx.h b/src/thirdparty/VirtualDub/Kasumi/h/stdafx.h
new file mode 100644
index 000000000..28ae68d6c
--- /dev/null
+++ b/src/thirdparty/VirtualDub/Kasumi/h/stdafx.h
@@ -0,0 +1,21 @@
+// VirtualDub - Video processing and capture application
+// Graphics support library
+// Copyright (C) 1998-2009 Avery Lee
+//
+// 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+#include <vd2/system/vdtypes.h>
+#include <vd2/Kasumi/pixmap.h>
+#include <uberblit.h>
diff --git a/src/thirdparty/VirtualDub/Kasumi/h/uberblit.h b/src/thirdparty/VirtualDub/Kasumi/h/uberblit.h
index 72f8ee060..161166096 100644
--- a/src/thirdparty/VirtualDub/Kasumi/h/uberblit.h
+++ b/src/thirdparty/VirtualDub/Kasumi/h/uberblit.h
@@ -37,31 +37,43 @@ enum VDPixmapFormatToken {
kVDPixSamp_422_JPEG = 0x000000C0,
kVDPixSamp_420_MPEG2 = 0x00000100,
kVDPixSamp_420_MPEG2INT = 0x00000140,
- kVDPixSamp_420_MPEG1 = 0x00000180,
- kVDPixSamp_420_DVPAL = 0x000001C0,
- kVDPixSamp_411 = 0x00000200,
- kVDPixSamp_410 = 0x00000240,
+ kVDPixSamp_420_MPEG2INT1= 0x00000180, // MPEG-2 interlaced, top field
+ kVDPixSamp_420_MPEG2INT2= 0x000001C0, // MPEG-2 interlaced, bottom field
+ kVDPixSamp_420_MPEG1 = 0x00000200,
+ kVDPixSamp_420_DVPAL = 0x00000240,
+ kVDPixSamp_411 = 0x00000280,
+ kVDPixSamp_410 = 0x000002C0,
kVDPixSamp_Mask = 0x00000FC0,
kVDPixSamp_Bits = 6,
kVDPixSpace_Pal = 0x00001000,
- kVDPixSpace_RGB = 0x00002000,
+// kVDPixSpace_RGB = 0x00002000,
kVDPixSpace_BGR = 0x00003000,
- kVDPixSpace_BGRA = 0x00004000,
+ kVDPixSpace_BGR_Studio = 0x00004000,
kVDPixSpace_Y_601 = 0x00005000,
kVDPixSpace_Y_709 = 0x00006000,
- kVDPixSpace_YCC_601 = 0x00007000,
- kVDPixSpace_YCC_709 = 0x00008000,
- kVDPixSpace_YCC_JPEG = 0x00009000,
+ kVDPixSpace_Y_601_FR = 0x00007000,
+ kVDPixSpace_Y_709_FR = 0x00008000,
+ kVDPixSpace_YCC_601 = 0x0000B000,
+ kVDPixSpace_YCC_709 = 0x0000C000,
+ kVDPixSpace_YCC_601_FR = 0x0000D000,
+ kVDPixSpace_YCC_709_FR = 0x0000E000,
kVDPixSpace_Mask = 0x0003F000,
};
+struct VDPixmapPlaneSamplingInfo {
+ int mX; ///< X offset of sample from center location, in 16ths of plane pixels.
+ int mY; ///< Y offset of sample from center location, in 16ths of plane pixels.
+ int mXBits; ///< Horizontal subsampling factor in bits.
+ int mYBits; ///< Vertical subsampling factor in bits.
+};
+
struct VDPixmapSamplingInfo {
- int mCXOffset16;
- int mCrYOffset16;
- int mCbYOffset16;
- int mCXBits;
- int mCYBits;
+ bool mbInterlaced;
+ VDPixmapPlaneSamplingInfo mPlane1Cr;
+ VDPixmapPlaneSamplingInfo mPlane1Cb;
+ VDPixmapPlaneSamplingInfo mPlane2Cr;
+ VDPixmapPlaneSamplingInfo mPlane2Cb;
};
uint32 VDPixmapGetFormatTokenFromFormat(int format);
diff --git a/src/thirdparty/VirtualDub/Kasumi/h/uberblit_base.h b/src/thirdparty/VirtualDub/Kasumi/h/uberblit_base.h
index 675619a7b..e01ef73fe 100644
--- a/src/thirdparty/VirtualDub/Kasumi/h/uberblit_base.h
+++ b/src/thirdparty/VirtualDub/Kasumi/h/uberblit_base.h
@@ -31,7 +31,7 @@ public:
mWindow.resize(mWindowSize * 2);
for(sint32 i=0; i<mWindowSize; ++i)
- mWindow[i] = mWindow[i + mWindowSize] = &mWindowBuffer[mWindowPitch * outputCount * i];
+ mWindow[i] = mWindow[i + mWindowSize] = mWindowBuffer.data() + (mWindowPitch * outputCount * i);
mWindowIndex = 0;
mWindowLastY = -0x3FFFFFFF;
diff --git a/src/thirdparty/VirtualDub/Kasumi/h/uberblit_gen.h b/src/thirdparty/VirtualDub/Kasumi/h/uberblit_gen.h
index 3937fbba7..205430161 100644
--- a/src/thirdparty/VirtualDub/Kasumi/h/uberblit_gen.h
+++ b/src/thirdparty/VirtualDub/Kasumi/h/uberblit_gen.h
@@ -5,6 +5,7 @@
#include "uberblit.h"
class IVDPixmapGenSrc;
+struct VDPixmapGenYCbCrBasis;
class VDPixmapUberBlitterDirectCopy : public IVDPixmapBlitter {
public:
@@ -106,6 +107,9 @@ public:
void interleave_X8R8G8B8();
void interleave_B8R8();
+ void merge_fields(uint32 w, uint32 h, uint32 bpr);
+ void split_fields(uint32 bpr);
+
void ycbcr601_to_rgb32();
void ycbcr709_to_rgb32();
void rgb32_to_ycbcr601();
@@ -119,6 +123,12 @@ public:
void ycbcr601_to_ycbcr709();
void ycbcr709_to_ycbcr601();
+ void ycbcr_to_rgb32_generic(const VDPixmapGenYCbCrBasis& basis, bool studioRGB);
+ void ycbcr_to_rgb32f_generic(const VDPixmapGenYCbCrBasis& basis);
+ void rgb32_to_ycbcr_generic(const VDPixmapGenYCbCrBasis& basis, bool studioRGB, uint32 colorSpace);
+ void rgb32f_to_ycbcr_generic(const VDPixmapGenYCbCrBasis& basis, uint32 colorSpace);
+ void ycbcr_to_ycbcr_generic(const VDPixmapGenYCbCrBasis& basisDst, bool dstLimitedRange, const VDPixmapGenYCbCrBasis& basisSrc, bool srcLimitedRange, uint32 colorSpace);
+
void pointh(float xoffset, float xfactor, uint32 w);
void pointv(float yoffset, float yfactor, uint32 h);
void linearh(float xoffset, float xfactor, uint32 w, bool interpOnly);
diff --git a/src/thirdparty/VirtualDub/Kasumi/h/uberblit_interlace.h b/src/thirdparty/VirtualDub/Kasumi/h/uberblit_interlace.h
new file mode 100644
index 000000000..23adaa76b
--- /dev/null
+++ b/src/thirdparty/VirtualDub/Kasumi/h/uberblit_interlace.h
@@ -0,0 +1,123 @@
+// VirtualDub - Video processing and capture application
+// Graphics support library
+// Copyright (C) 1998-2009 Avery Lee
+//
+// 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+#ifndef f_VD2_KASUMI_UBERBLIT_INTERLACE_H
+#define f_VD2_KASUMI_UBERBLIT_INTERLACE_H
+
+#include "uberblit_base.h"
+
+class VDPixmapGen_SplitFields : public IVDPixmapGen {
+public:
+ void AddWindowRequest(int minDY, int maxDY) {
+ mpSrc->AddWindowRequest(minDY*2, maxDY*2+1);
+ }
+
+ void Start() {
+ mpSrc->Start();
+ }
+
+ sint32 GetWidth(int) const { return mWidth; }
+ sint32 GetHeight(int idx) const { return mHeight[idx]; }
+
+ bool IsStateful() const {
+ return false;
+ }
+
+ uint32 GetType(uint32 output) const {
+ return mpSrc->GetType(mSrcIndex);
+ }
+
+ const void *GetRow(sint32 y, uint32 index) {
+ return mpSrc->GetRow(y+y+index, mSrcIndex);
+ }
+
+ void ProcessRow(void *dst, sint32 y) {
+ memcpy(dst, GetRow(y, 0), mBpr);
+ }
+
+ void Init(IVDPixmapGen *src, uint32 srcindex, uint32 bpr) {
+ mpSrc = src;
+ mSrcIndex = srcindex;
+ mBpr = bpr;
+ mWidth = src->GetWidth(srcindex);
+
+ uint32 h = src->GetHeight(srcindex);
+ mHeight[0] = (h + 1) >> 1;
+ mHeight[1] = h >> 1;
+ }
+
+protected:
+ IVDPixmapGen *mpSrc;
+ uint32 mSrcIndex;
+ sint32 mWidth;
+ sint32 mHeight[2];
+ uint32 mBpr;
+};
+
+class VDPixmapGen_MergeFields : public IVDPixmapGen {
+public:
+ void AddWindowRequest(int minDY, int maxDY) {
+ mpSrc[0]->AddWindowRequest(minDY >> 1, maxDY >> 1);
+ mpSrc[1]->AddWindowRequest(minDY >> 1, maxDY >> 1);
+ }
+
+ void Start() {
+ mpSrc[0]->Start();
+ mpSrc[1]->Start();
+ }
+
+ sint32 GetWidth(int) const { return mWidth; }
+ sint32 GetHeight(int) const { return mHeight; }
+
+ bool IsStateful() const {
+ return false;
+ }
+
+ uint32 GetType(uint32 output) const {
+ return mpSrc[0]->GetType(mSrcIndex[0]);
+ }
+
+ const void *GetRow(sint32 y, uint32 index) {
+ int srcIndex = y & 1;
+ return mpSrc[srcIndex]->GetRow(y >> 1, mSrcIndex[srcIndex]);
+ }
+
+ void ProcessRow(void *dst, sint32 y) {
+ memcpy(dst, GetRow(y, 0), mBpr);
+ }
+
+ void Init(IVDPixmapGen *src1, uint32 srcindex1, IVDPixmapGen *src2, uint32 srcindex2, uint32 w, uint32 h, uint32 bpr) {
+ mpSrc[0] = src1;
+ mpSrc[1] = src2;
+ mSrcIndex[0] = srcindex1;
+ mSrcIndex[1] = srcindex2;
+
+ mWidth = w;
+ mHeight = h;
+ mBpr = bpr;
+ }
+
+protected:
+ IVDPixmapGen *mpSrc[2];
+ uint32 mSrcIndex[2];
+ sint32 mWidth;
+ sint32 mHeight;
+ uint32 mBpr;
+};
+
+#endif
diff --git a/src/thirdparty/VirtualDub/Kasumi/h/uberblit_ycbcr.h b/src/thirdparty/VirtualDub/Kasumi/h/uberblit_ycbcr.h
index 2eb62da01..d6ad5a6a7 100644
--- a/src/thirdparty/VirtualDub/Kasumi/h/uberblit_ycbcr.h
+++ b/src/thirdparty/VirtualDub/Kasumi/h/uberblit_ycbcr.h
@@ -34,6 +34,60 @@ protected:
uint32 mSrcIndexCr;
};
+class VDPixmapGenYCbCrToRGB32Base : public VDPixmapGenYCbCrToRGBBase {
+public:
+ void Start() {
+ mpSrcY->Start();
+ mpSrcCb->Start();
+ mpSrcCr->Start();
+
+ StartWindow(mWidth * 4);
+ }
+};
+
+
+class VDPixmapGenYCbCrToRGB32FBase : public VDPixmapGenYCbCrToRGBBase {
+public:
+ void Start() {
+ mpSrcY->Start();
+ mpSrcCb->Start();
+ mpSrcCr->Start();
+
+ StartWindow(mWidth * 16);
+ }
+};
+
+
+class VDPixmapGenRGB32ToYCbCrBase : public VDPixmapGenWindowBasedOneSource {
+public:
+ void Init(IVDPixmapGen *src, uint32 srcindex) {
+ InitSource(src, srcindex);
+ }
+
+ void Start() {
+ StartWindow(mWidth, 3);
+ }
+
+ const void *GetRow(sint32 y, uint32 index) {
+ return (const uint8 *)VDPixmapGenWindowBasedOneSource::GetRow(y, index) + mWindowPitch * index;
+ }
+};
+
+class VDPixmapGenRGB32FToYCbCrBase : public VDPixmapGenWindowBasedOneSource {
+public:
+ void Init(IVDPixmapGen *src, uint32 srcindex) {
+ InitSource(src, srcindex);
+ }
+
+ void Start() {
+ StartWindow(mWidth * sizeof(float), 3);
+ }
+
+ const void *GetRow(sint32 y, uint32 index) {
+ return (const uint8 *)VDPixmapGenWindowBasedOneSource::GetRow(y, index) + mWindowPitch * index;
+ }
+};
+
///////////////////////////////////////////////////////////////////////////////////////////////////
//
// Rec.601 converters
@@ -53,16 +107,8 @@ protected:
//
///////////////////////////////////////////////////////////////////////////////////////////////////
-class VDPixmapGenYCbCr601ToRGB32 : public VDPixmapGenYCbCrToRGBBase {
+class VDPixmapGenYCbCr601ToRGB32 : public VDPixmapGenYCbCrToRGB32Base {
public:
- void Start() {
- mpSrcY->Start();
- mpSrcCb->Start();
- mpSrcCr->Start();
-
- StartWindow(mWidth * 4);
- }
-
uint32 GetType(uint32 output) const {
return (mpSrcY->GetType(mSrcIndexY) & ~(kVDPixType_Mask | kVDPixSpace_Mask)) | kVDPixType_8888 | kVDPixSpace_BGR;
}
@@ -93,16 +139,8 @@ protected:
}
};
-class VDPixmapGenYCbCr601ToRGB32F : public VDPixmapGenYCbCrToRGBBase {
+class VDPixmapGenYCbCr601ToRGB32F : public VDPixmapGenYCbCrToRGB32FBase {
public:
- void Start() {
- mpSrcY->Start();
- mpSrcCb->Start();
- mpSrcCr->Start();
-
- StartWindow(mWidth * 16);
- }
-
uint32 GetType(uint32 output) const {
return (mpSrcY->GetType(mSrcIndexY) & ~(kVDPixType_Mask | kVDPixSpace_Mask)) | kVDPixType_32Fx4_LE | kVDPixSpace_BGR;
}
@@ -132,29 +170,17 @@ protected:
}
};
-class VDPixmapGenRGB32ToYCbCr601 : public VDPixmapGenWindowBasedOneSource {
+class VDPixmapGenRGB32ToYCbCr601 : public VDPixmapGenRGB32ToYCbCrBase {
public:
- void Init(IVDPixmapGen *src, uint32 srcindex) {
- InitSource(src, srcindex);
- }
-
- void Start() {
- StartWindow(mWidth, 3);
- }
-
- const void *GetRow(sint32 y, uint32 index) {
- return (const uint8 *)VDPixmapGenWindowBasedOneSource::GetRow(y, index) + mWindowPitch * index;
- }
-
uint32 GetType(uint32 output) const {
return (mpSrc->GetType(mSrcIndex) & ~(kVDPixType_Mask | kVDPixSpace_Mask)) | kVDPixType_8 | kVDPixSpace_YCC_601;
}
protected:
void Compute(void *dst0, sint32 y) {
- uint8 *dstCb = (uint8 *)dst0;
- uint8 *dstY = dstCb + mWindowPitch;
- uint8 *dstCr = dstY + mWindowPitch;
+ uint8 *dstCr = (uint8 *)dst0;
+ uint8 *dstY = dstCr + mWindowPitch;
+ uint8 *dstCb = dstY + mWindowPitch;
const uint8 *srcRGB = (const uint8 *)mpSrc->GetRow(y, mSrcIndex);
@@ -174,29 +200,17 @@ protected:
// ! 6416. - 4681. 28784. 0. !
// ! 1048576. 8388608. 8388608. 65536. !
- *dstCb++ = (28784*r - 24103*g - 4681*b + 8388608 + 32768) >> 16;
+ *dstCr++ = (28784*r - 24103*g - 4681*b + 8388608 + 32768) >> 16;
*dstY ++ = (16829*r + 33039*g + 6416*b + 1048576 + 32768) >> 16;
- *dstCr++ = (-9714*r - 19071*g + 28784*b + 8388608 + 32768) >> 16;
+ *dstCb++ = (-9714*r - 19071*g + 28784*b + 8388608 + 32768) >> 16;
}
}
};
-class VDPixmapGenRGB32FToYCbCr601 : public VDPixmapGenWindowBasedOneSource {
+class VDPixmapGenRGB32FToYCbCr601 : public VDPixmapGenRGB32FToYCbCrBase {
public:
- void Init(IVDPixmapGen *src, uint32 srcindex) {
- InitSource(src, srcindex);
- }
-
- void Start() {
- StartWindow(mWidth * sizeof(float), 3);
- }
-
- const void *GetRow(sint32 y, uint32 index) {
- return (const uint8 *)VDPixmapGenWindowBasedOneSource::GetRow(y, index) + mWindowPitch * index;
- }
-
uint32 GetType(uint32 output) const {
- return (mpSrc->GetType(mSrcIndex) & ~(kVDPixType_Mask | kVDPixSpace_Mask)) | kVDPixType_32F_LE | kVDPixSpace_YCC_709;
+ return (mpSrc->GetType(mSrcIndex) & ~(kVDPixType_Mask | kVDPixSpace_Mask)) | kVDPixType_32F_LE | kVDPixSpace_YCC_601;
}
protected:
@@ -207,6 +221,8 @@ protected:
const float *srcRGB = (const float *)mpSrc->GetRow(y, mSrcIndex);
+ VDCPUCleanupExtensions();
+
for(sint32 i=0; i<mWidth; ++i) {
float r = srcRGB[2];
float g = srcRGB[1];
@@ -339,9 +355,9 @@ public:
protected:
void Compute(void *dst0, sint32 y) {
- uint8 *dstCb = (uint8 *)dst0;
- uint8 *dstY = dstCb + mWindowPitch;
- uint8 *dstCr = dstY + mWindowPitch;
+ uint8 *dstCr = (uint8 *)dst0;
+ uint8 *dstY = dstCr + mWindowPitch;
+ uint8 *dstCb = dstY + mWindowPitch;
const uint8 *srcRGB = (const uint8 *)mpSrc->GetRow(y, mSrcIndex);
@@ -351,9 +367,9 @@ protected:
int b = (int)srcRGB[0];
srcRGB += 4;
- *dstCb++ = (28784*r - 26145*g - 2639*b + 8388608 + 32768) >> 16;
+ *dstCr++ = (28784*r - 26145*g - 2639*b + 8388608 + 32768) >> 16;
*dstY ++ = (11966*r + 40254*g + 4064*b + 1048576 + 32768) >> 16;
- *dstCr++ = (-6596*r - 22189*g + 28784*b + 8388608 + 32768) >> 16;
+ *dstCb++ = (-6596*r - 22189*g + 28784*b + 8388608 + 32768) >> 16;
}
}
};
@@ -378,9 +394,9 @@ public:
protected:
void Compute(void *dst0, sint32 y) {
- float *dstCb = (float *)dst0;
- float *dstY = dstCb + mWindowPitch;
- float *dstCr = dstY + mWindowPitch;
+ float *dstCr = (float *)dst0;
+ float *dstY = dstCr + mWindowPitch;
+ float *dstCb = dstY + mWindowPitch;
const float *srcRGB = (const float *)mpSrc->GetRow(y, mSrcIndex);
@@ -392,9 +408,9 @@ protected:
float b = srcRGB[0];
srcRGB += 4;
- *dstCb++ = -0.1006437f*r - 0.3385720f*g + 0.4392157f*b + (128.0f / 255.0f);
+ *dstCr++ = -0.1006437f*r - 0.3385720f*g + 0.4392157f*b + (128.0f / 255.0f);
*dstY++ = 0.1825859f*r + 0.6142306f*g + 0.0620071f*b + ( 16.0f / 255.0f);
- *dstCr++ = 0.4392157f*r - 0.3989422f*g - 0.0402735f*b + (128.0f / 255.0f);
+ *dstCb++ = 0.4392157f*r - 0.3989422f*g - 0.0402735f*b + (128.0f / 255.0f);
}
}
};
@@ -529,12 +545,12 @@ protected:
for(sint32 i=0; i<mWidth; ++i) {
float y = srcY[i];
- float cb = srcCb[i] - (128.0f / 255.0f);
- float cr = srcCr[i] - (128.0f / 255.0f);
+ float cb = srcCb[i];
+ float cr = srcCr[i];
- *dstY++ = y - 0.1155497f*cb - 0.2079376f*cr;
- *dstCb++ = 1.0186397f*cb + 0.1146180f*cr + (128.0f / 255.0f);
- *dstCr++ = 0.0750494f*cb + 1.0253271f*cr + (128.0f / 255.0f);
+ *dstY++ = y - 0.1155497f*cb - 0.2079376f*cr;
+ *dstCb++ = 1.0186397f*cb + 0.1146180f*cr;
+ *dstCr++ = 0.0750494f*cb + 1.0253271f*cr;
}
}
};
@@ -571,12 +587,12 @@ protected:
for(sint32 i=0; i<mWidth; ++i) {
float y = srcY[i];
- float cb = srcCb[i] - (128.0f / 255.0f);
- float cr = srcCr[i] - (128.0f / 255.0f);
+ float cb = srcCb[i];
+ float cr = srcCr[i];
*dstY++ = y - 0.1155497f*cb - 0.2079376f*cr;
- *dstCb++ = 0.9898538f*cb - 0.1106525f*cr + (128.0f / 255.0f);
- *dstCr++ = - 0.0724530f*cb + 0.9833978f*cr + (128.0f / 255.0f);
+ *dstCb++ = 0.9898538f*cb - 0.1106525f*cr;
+ *dstCr++ = - 0.0724530f*cb + 0.9833978f*cr;
}
}
};
diff --git a/src/thirdparty/VirtualDub/Kasumi/h/uberblit_ycbcr_generic.h b/src/thirdparty/VirtualDub/Kasumi/h/uberblit_ycbcr_generic.h
new file mode 100644
index 000000000..3b8af02e8
--- /dev/null
+++ b/src/thirdparty/VirtualDub/Kasumi/h/uberblit_ycbcr_generic.h
@@ -0,0 +1,154 @@
+#ifndef f_VD2_KASUMI_UBERBLIT_YCBCR_GENERIC_H
+#define f_VD2_KASUMI_UBERBLIT_YCBCR_GENERIC_H
+
+#include "uberblit_ycbcr.h"
+
+struct VDPixmapGenYCbCrBasis {
+ float mKr;
+ float mKb;
+ float mToRGB[2][3];
+};
+
+extern const VDPixmapGenYCbCrBasis g_VDPixmapGenYCbCrBasis_601;
+extern const VDPixmapGenYCbCrBasis g_VDPixmapGenYCbCrBasis_709;
+
+////////////////////////////////////////////////////////////////////////////
+
+class VDPixmapGenYCbCrToRGB32Generic : public VDPixmapGenYCbCrToRGB32Base {
+public:
+ VDPixmapGenYCbCrToRGB32Generic(const VDPixmapGenYCbCrBasis& basis, bool studioRGB);
+
+ uint32 GetType(uint32 output) const;
+
+protected:
+ virtual void Compute(void *dst0, sint32 y);
+
+ sint32 mCoY;
+ sint32 mCoRCr;
+ sint32 mCoGCr;
+ sint32 mCoGCb;
+ sint32 mCoBCb;
+ sint32 mBiasR;
+ sint32 mBiasG;
+ sint32 mBiasB;
+};
+
+////////////////////////////////////////////////////////////////////////////
+
+class VDPixmapGenYCbCrToRGB32FGeneric : public VDPixmapGenYCbCrToRGB32FBase {
+public:
+ VDPixmapGenYCbCrToRGB32FGeneric(const VDPixmapGenYCbCrBasis& basis);
+
+ uint32 GetType(uint32 output) const;
+
+protected:
+ void Compute(void *dst0, sint32 y);
+
+ float mCoRCr;
+ float mCoGCr;
+ float mCoGCb;
+ float mCoBCb;
+};
+
+////////////////////////////////////////////////////////////////////////////
+
+class VDPixmapGenRGB32ToYCbCrGeneric : public VDPixmapGenRGB32ToYCbCrBase {
+public:
+ VDPixmapGenRGB32ToYCbCrGeneric(const VDPixmapGenYCbCrBasis& basis, bool studioRGB, uint32 colorSpace);
+
+ uint32 GetType(uint32 output) const;
+
+protected:
+ void Compute(void *dst0, sint32 y);
+
+ sint32 mCoYR;
+ sint32 mCoYG;
+ sint32 mCoYB;
+ sint32 mCoCbR;
+ sint32 mCoCbG;
+ sint32 mCoCbB;
+ sint32 mCoCrR;
+ sint32 mCoCrG;
+ sint32 mCoCrB;
+ sint32 mCoYA;
+ sint32 mCoCbA;
+ sint32 mCoCrA;
+
+ const uint32 mColorSpace;
+};
+
+////////////////////////////////////////////////////////////////////////////
+
+class VDPixmapGenRGB32FToYCbCrGeneric : public VDPixmapGenRGB32FToYCbCrBase {
+public:
+ VDPixmapGenRGB32FToYCbCrGeneric(const VDPixmapGenYCbCrBasis& basis, uint32 colorSpace);
+
+ uint32 GetType(uint32 output) const;
+
+protected:
+ void Compute(void *dst0, sint32 y);
+
+ float mCoYR;
+ float mCoYG;
+ float mCoYB;
+ float mCoCb;
+ float mCoCr;
+
+ const uint32 mColorSpace;
+};
+
+////////////////////////////////////////////////////////////////////////////
+
+class VDPixmapGenYCbCrToYCbCrGeneric : public VDPixmapGenYCbCrToRGBBase {
+public:
+ VDPixmapGenYCbCrToYCbCrGeneric(const VDPixmapGenYCbCrBasis& dstBasis, bool dstLimitedRange, const VDPixmapGenYCbCrBasis& srcBasis, bool srcLimitedRange, uint32 colorSpace);
+
+ void Start();
+ const void *GetRow(sint32 y, uint32 index);
+ uint32 GetType(uint32 output) const;
+
+protected:
+ void Compute(void *dst0, sint32 ypos);
+
+ sint32 mCoYY;
+ sint32 mCoYCb;
+ sint32 mCoYCr;
+ sint32 mCoYA;
+ sint32 mCoCbCb;
+ sint32 mCoCbCr;
+ sint32 mCoCbA;
+ sint32 mCoCrCb;
+ sint32 mCoCrCr;
+ sint32 mCoCrA;
+
+ const uint32 mColorSpace;
+};
+
+////////////////////////////////////////////////////////////////////////////
+
+class VDPixmapGenYCbCrToYCbCrGeneric_32F : public VDPixmapGenYCbCrToRGBBase {
+public:
+ VDPixmapGenYCbCrToYCbCrGeneric_32F(const VDPixmapGenYCbCrBasis& dstBasis, bool dstLimitedRange, const VDPixmapGenYCbCrBasis& srcBasis, bool srcLimitedRange, uint32 colorSpace);
+
+ void Start();
+ const void *GetRow(sint32 y, uint32 index);
+ uint32 GetType(uint32 output) const;
+
+protected:
+ void Compute(void *dst0, sint32 ypos);
+
+ float mCoYY;
+ float mCoYCb;
+ float mCoYCr;
+ float mCoYA;
+ float mCoCbCb;
+ float mCoCbCr;
+ float mCoCbA;
+ float mCoCrCb;
+ float mCoCrCr;
+ float mCoCrA;
+
+ const uint32 mColorSpace;
+};
+
+#endif
diff --git a/src/thirdparty/VirtualDub/Kasumi/source/alphablt.cpp b/src/thirdparty/VirtualDub/Kasumi/source/alphablt.cpp
index a292ca2bd..93501ede4 100644
--- a/src/thirdparty/VirtualDub/Kasumi/source/alphablt.cpp
+++ b/src/thirdparty/VirtualDub/Kasumi/source/alphablt.cpp
@@ -1,3 +1,22 @@
+// VirtualDub - Video processing and capture application
+// Graphics support library
+// Copyright (C) 1998-2009 Avery Lee
+//
+// 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+#include <stdafx.h>
#include <vd2/system/math.h>
#include <vd2/system/cpuaccel.h>
#include <vd2/Kasumi/pixmap.h>
diff --git a/src/thirdparty/VirtualDub/Kasumi/source/blitter.cpp b/src/thirdparty/VirtualDub/Kasumi/source/blitter.cpp
new file mode 100644
index 000000000..0879424d2
--- /dev/null
+++ b/src/thirdparty/VirtualDub/Kasumi/source/blitter.cpp
@@ -0,0 +1,52 @@
+#include <stdafx.h>
+#include <vd2/Kasumi/blitter.h>
+
+VDPixmapCachedBlitter::VDPixmapCachedBlitter()
+ : mSrcWidth(0)
+ , mSrcHeight(0)
+ , mSrcFormat(0)
+ , mDstWidth(0)
+ , mDstHeight(0)
+ , mDstFormat(0)
+ , mpCachedBlitter(NULL)
+{
+}
+
+VDPixmapCachedBlitter::~VDPixmapCachedBlitter() {
+ Invalidate();
+}
+
+void VDPixmapCachedBlitter::Blit(const VDPixmap& dst, const VDPixmap& src) {
+ VDASSERT(src.w == dst.w && src.h == dst.h);
+
+ if (!mpCachedBlitter ||
+ dst.w != mDstWidth ||
+ dst.h != mDstHeight ||
+ dst.format != mDstFormat ||
+ src.w != mSrcWidth ||
+ src.h != mSrcHeight ||
+ src.format != mSrcFormat)
+ {
+ if (mpCachedBlitter)
+ delete mpCachedBlitter;
+ mpCachedBlitter = VDPixmapCreateBlitter(dst, src);
+ if (!mpCachedBlitter)
+ return;
+
+ mDstWidth = dst.w;
+ mDstHeight = dst.h;
+ mDstFormat = dst.format;
+ mSrcWidth = src.w;
+ mSrcHeight = src.h;
+ mSrcFormat = src.format;
+ }
+
+ mpCachedBlitter->Blit(dst, src);
+}
+
+void VDPixmapCachedBlitter::Invalidate() {
+ if (mpCachedBlitter) {
+ delete mpCachedBlitter;
+ mpCachedBlitter = NULL;
+ }
+}
diff --git a/src/thirdparty/VirtualDub/Kasumi/source/blt.cpp b/src/thirdparty/VirtualDub/Kasumi/source/blt.cpp
index 75e5542a9..7a5d1c7c1 100644
--- a/src/thirdparty/VirtualDub/Kasumi/source/blt.cpp
+++ b/src/thirdparty/VirtualDub/Kasumi/source/blt.cpp
@@ -1,3 +1,22 @@
+// VirtualDub - Video processing and capture application
+// Graphics support library
+// Copyright (C) 1998-2009 Avery Lee
+//
+// 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+#include <stdafx.h>
#include <vector>
#include <vd2/system/memory.h>
#include <vd2/system/cpuaccel.h>
@@ -189,6 +208,11 @@ bool VDNOINLINE VDPixmapBltTwoStage(const VDPixmap& dst, const VDPixmap& src, vd
}
bool VDPixmapBltFast(const VDPixmap& dst, const VDPixmap& src, vdpixsize w, vdpixsize h) {
+ if (w <= 0 || h <= 0) {
+ VDASSERT((w|h) >= 0);
+ return true;
+ }
+
if (VDPixmapBltDirect(dst, src, w, h))
return true;
diff --git a/src/thirdparty/VirtualDub/Kasumi/source/blt_reference.cpp b/src/thirdparty/VirtualDub/Kasumi/source/blt_reference.cpp
index c4dccce9f..4ee033bde 100644
--- a/src/thirdparty/VirtualDub/Kasumi/source/blt_reference.cpp
+++ b/src/thirdparty/VirtualDub/Kasumi/source/blt_reference.cpp
@@ -1,3 +1,22 @@
+// VirtualDub - Video processing and capture application
+// Graphics support library
+// Copyright (C) 1998-2009 Avery Lee
+//
+// 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+#include <stdafx.h>
#include <vd2/system/vdtypes.h>
#include <vd2/Kasumi/pixmap.h>
#include <vd2/Kasumi/pixmaputils.h>
@@ -116,7 +135,40 @@ void VDPixmapInitBlittersReference(VDPixmapBlitterTable& table) {
kPixFormat_YUV420_Planar_Centered,
kPixFormat_YUV422_V210,
kPixFormat_YUV422_UYVY_709,
- kPixFormat_YUV420_NV12;
+ kPixFormat_YUV420_NV12,
+ kPixFormat_Y8_FR,
+ kPixFormat_YUV422_YUYV_709,
+ kPixFormat_YUV444_Planar_709,
+ kPixFormat_YUV422_Planar_709,
+ kPixFormat_YUV420_Planar_709,
+ kPixFormat_YUV411_Planar_709,
+ kPixFormat_YUV410_Planar_709,
+ kPixFormat_YUV422_UYVY_FR,
+ kPixFormat_YUV422_YUYV_FR,
+ kPixFormat_YUV444_Planar_FR,
+ kPixFormat_YUV422_Planar_FR,
+ kPixFormat_YUV420_Planar_FR,
+ kPixFormat_YUV411_Planar_FR,
+ kPixFormat_YUV410_Planar_FR,
+ kPixFormat_YUV422_UYVY_709_FR,
+ kPixFormat_YUV422_YUYV_709_FR,
+ kPixFormat_YUV444_Planar_709_FR,
+ kPixFormat_YUV422_Planar_709_FR,
+ kPixFormat_YUV420_Planar_709_FR,
+ kPixFormat_YUV411_Planar_709_FR,
+ kPixFormat_YUV410_Planar_709_FR,
+ kPixFormat_YUV420i_Planar,
+ kPixFormat_YUV420i_Planar_FR,
+ kPixFormat_YUV420i_Planar_709,
+ kPixFormat_YUV420i_Planar_709_FR,
+ kPixFormat_YUV420it_Planar,
+ kPixFormat_YUV420it_Planar_FR,
+ kPixFormat_YUV420it_Planar_709,
+ kPixFormat_YUV420it_Planar_709_FR,
+ kPixFormat_YUV420ib_Planar,
+ kPixFormat_YUV420ib_Planar_FR,
+ kPixFormat_YUV420ib_Planar_709,
+ kPixFormat_YUV420ib_Planar_709_FR;
uberblitDstFormats =
kPixFormat_XRGB1555,
@@ -137,7 +189,40 @@ void VDPixmapInitBlittersReference(VDPixmapBlitterTable& table) {
kPixFormat_YUV420_Planar_Centered,
kPixFormat_YUV422_V210,
kPixFormat_YUV422_UYVY_709,
- kPixFormat_YUV420_NV12;
+ kPixFormat_YUV420_NV12,
+ kPixFormat_Y8_FR,
+ kPixFormat_YUV422_YUYV_709,
+ kPixFormat_YUV444_Planar_709,
+ kPixFormat_YUV422_Planar_709,
+ kPixFormat_YUV420_Planar_709,
+ kPixFormat_YUV411_Planar_709,
+ kPixFormat_YUV410_Planar_709,
+ kPixFormat_YUV422_UYVY_FR,
+ kPixFormat_YUV422_YUYV_FR,
+ kPixFormat_YUV444_Planar_FR,
+ kPixFormat_YUV422_Planar_FR,
+ kPixFormat_YUV420_Planar_FR,
+ kPixFormat_YUV411_Planar_FR,
+ kPixFormat_YUV410_Planar_FR,
+ kPixFormat_YUV422_UYVY_709_FR,
+ kPixFormat_YUV422_YUYV_709_FR,
+ kPixFormat_YUV444_Planar_709_FR,
+ kPixFormat_YUV422_Planar_709_FR,
+ kPixFormat_YUV420_Planar_709_FR,
+ kPixFormat_YUV411_Planar_709_FR,
+ kPixFormat_YUV410_Planar_709_FR,
+ kPixFormat_YUV420i_Planar,
+ kPixFormat_YUV420i_Planar_FR,
+ kPixFormat_YUV420i_Planar_709,
+ kPixFormat_YUV420i_Planar_709_FR,
+ kPixFormat_YUV420it_Planar,
+ kPixFormat_YUV420it_Planar_FR,
+ kPixFormat_YUV420it_Planar_709,
+ kPixFormat_YUV420it_Planar_709_FR,
+ kPixFormat_YUV420ib_Planar,
+ kPixFormat_YUV420ib_Planar_FR,
+ kPixFormat_YUV420ib_Planar_709,
+ kPixFormat_YUV420ib_Planar_709_FR;
table.AddBlitter(uberblitSrcFormats, uberblitDstFormats, VDPixmapBlt_UberblitAdapter);
diff --git a/src/thirdparty/VirtualDub/Kasumi/source/blt_reference_pal.cpp b/src/thirdparty/VirtualDub/Kasumi/source/blt_reference_pal.cpp
index 4a103de3b..4bf5a5f71 100644
--- a/src/thirdparty/VirtualDub/Kasumi/source/blt_reference_pal.cpp
+++ b/src/thirdparty/VirtualDub/Kasumi/source/blt_reference_pal.cpp
@@ -1,3 +1,22 @@
+// VirtualDub - Video processing and capture application
+// Graphics support library
+// Copyright (C) 1998-2009 Avery Lee
+//
+// 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+#include <stdafx.h>
#include <vd2/system/vdtypes.h>
#include <vd2/Kasumi/pixmap.h>
#include <vd2/Kasumi/pixmaputils.h>
diff --git a/src/thirdparty/VirtualDub/Kasumi/source/blt_reference_rgb.cpp b/src/thirdparty/VirtualDub/Kasumi/source/blt_reference_rgb.cpp
index ea49f260d..8f7c2df6a 100644
--- a/src/thirdparty/VirtualDub/Kasumi/source/blt_reference_rgb.cpp
+++ b/src/thirdparty/VirtualDub/Kasumi/source/blt_reference_rgb.cpp
@@ -1,3 +1,22 @@
+// VirtualDub - Video processing and capture application
+// Graphics support library
+// Copyright (C) 1998-2009 Avery Lee
+//
+// 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+#include <stdafx.h>
#include <vd2/system/vdtypes.h>
#include <vd2/Kasumi/pixmap.h>
#include <vd2/Kasumi/pixmaputils.h>
diff --git a/src/thirdparty/VirtualDub/Kasumi/source/blt_reference_yuv.cpp b/src/thirdparty/VirtualDub/Kasumi/source/blt_reference_yuv.cpp
index 6f40eeaa0..ffd96052f 100644
--- a/src/thirdparty/VirtualDub/Kasumi/source/blt_reference_yuv.cpp
+++ b/src/thirdparty/VirtualDub/Kasumi/source/blt_reference_yuv.cpp
@@ -1,3 +1,22 @@
+// VirtualDub - Video processing and capture application
+// Graphics support library
+// Copyright (C) 1998-2009 Avery Lee
+//
+// 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+#include <stdafx.h>
#include <vd2/system/vdtypes.h>
#include <vd2/system/vdstl.h>
#include <vd2/system/cpuaccel.h>
diff --git a/src/thirdparty/VirtualDub/Kasumi/source/blt_reference_yuv2yuv.cpp b/src/thirdparty/VirtualDub/Kasumi/source/blt_reference_yuv2yuv.cpp
index b581e9bf7..093ac5360 100644
--- a/src/thirdparty/VirtualDub/Kasumi/source/blt_reference_yuv2yuv.cpp
+++ b/src/thirdparty/VirtualDub/Kasumi/source/blt_reference_yuv2yuv.cpp
@@ -1,3 +1,22 @@
+// VirtualDub - Video processing and capture application
+// Graphics support library
+// Copyright (C) 1998-2009 Avery Lee
+//
+// 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+#include <stdafx.h>
#include <vd2/system/vdtypes.h>
#include <vd2/system/memory.h>
#include <vd2/system/vdstl.h>
diff --git a/src/thirdparty/VirtualDub/Kasumi/source/blt_reference_yuvrev.cpp b/src/thirdparty/VirtualDub/Kasumi/source/blt_reference_yuvrev.cpp
index d6f38bf65..d6f6ce75d 100644
--- a/src/thirdparty/VirtualDub/Kasumi/source/blt_reference_yuvrev.cpp
+++ b/src/thirdparty/VirtualDub/Kasumi/source/blt_reference_yuvrev.cpp
@@ -1,3 +1,22 @@
+// VirtualDub - Video processing and capture application
+// Graphics support library
+// Copyright (C) 1998-2009 Avery Lee
+//
+// 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+#include <stdafx.h>
#include <vd2/system/cpuaccel.h>
#include <vd2/system/vdtypes.h>
#include <vd2/system/vdstl.h>
diff --git a/src/thirdparty/VirtualDub/Kasumi/source/blt_setup.cpp b/src/thirdparty/VirtualDub/Kasumi/source/blt_setup.cpp
index ce999221a..c4b3746a6 100644
--- a/src/thirdparty/VirtualDub/Kasumi/source/blt_setup.cpp
+++ b/src/thirdparty/VirtualDub/Kasumi/source/blt_setup.cpp
@@ -1,3 +1,22 @@
+// VirtualDub - Video processing and capture application
+// Graphics support library
+// Copyright (C) 1998-2009 Avery Lee
+//
+// 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+#include <stdafx.h>
#include "blt_setup.h"
void VDPixmapBlitterTable::Clear() {
diff --git a/src/thirdparty/VirtualDub/Kasumi/source/blt_spanutils.cpp b/src/thirdparty/VirtualDub/Kasumi/source/blt_spanutils.cpp
index 6baeeca36..07885b929 100644
--- a/src/thirdparty/VirtualDub/Kasumi/source/blt_spanutils.cpp
+++ b/src/thirdparty/VirtualDub/Kasumi/source/blt_spanutils.cpp
@@ -1,3 +1,22 @@
+// VirtualDub - Video processing and capture application
+// Graphics support library
+// Copyright (C) 1998-2009 Avery Lee
+//
+// 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+#include <stdafx.h>
#include "blt_spanutils.h"
#include "bitutils.h"
diff --git a/src/thirdparty/VirtualDub/Kasumi/source/blt_spanutils_x86.cpp b/src/thirdparty/VirtualDub/Kasumi/source/blt_spanutils_x86.cpp
index ea9e0599a..f529444ca 100644
--- a/src/thirdparty/VirtualDub/Kasumi/source/blt_spanutils_x86.cpp
+++ b/src/thirdparty/VirtualDub/Kasumi/source/blt_spanutils_x86.cpp
@@ -1,6 +1,6 @@
// VirtualDub - Video processing and capture application
// Graphics support library
-// Copyright (C) 1998-2007 Avery Lee
+// Copyright (C) 1998-2009 Avery Lee
//
// 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
@@ -16,6 +16,7 @@
// along with this program; if not, write to the Free Software
// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+#include <stdafx.h>
#include "blt_spanutils_x86.h"
#ifdef _MSC_VER
diff --git a/src/thirdparty/VirtualDub/Kasumi/source/blt_uberblit.cpp b/src/thirdparty/VirtualDub/Kasumi/source/blt_uberblit.cpp
index dcaa20907..73eb269e8 100644
--- a/src/thirdparty/VirtualDub/Kasumi/source/blt_uberblit.cpp
+++ b/src/thirdparty/VirtualDub/Kasumi/source/blt_uberblit.cpp
@@ -1,3 +1,22 @@
+// VirtualDub - Video processing and capture application
+// Graphics support library
+// Copyright (C) 1998-2009 Avery Lee
+//
+// 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+#include <stdafx.h>
#include <vd2/system/vdalloc.h>
#include <vd2/Kasumi/pixmap.h>
#include "uberblit.h"
diff --git a/src/thirdparty/VirtualDub/Kasumi/source/blt_x86.cpp b/src/thirdparty/VirtualDub/Kasumi/source/blt_x86.cpp
index af1519c5b..29cce407f 100644
--- a/src/thirdparty/VirtualDub/Kasumi/source/blt_x86.cpp
+++ b/src/thirdparty/VirtualDub/Kasumi/source/blt_x86.cpp
@@ -1,3 +1,22 @@
+// VirtualDub - Video processing and capture application
+// Graphics support library
+// Copyright (C) 1998-2009 Avery Lee
+//
+// 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+#include <stdafx.h>
#include <vd2/system/vdtypes.h>
#include <vd2/Kasumi/pixmap.h>
#include <vd2/Kasumi/pixmaputils.h>
diff --git a/src/thirdparty/VirtualDub/Kasumi/source/pixel.cpp b/src/thirdparty/VirtualDub/Kasumi/source/pixel.cpp
index 4e7c7f4d6..e6eaada3f 100644
--- a/src/thirdparty/VirtualDub/Kasumi/source/pixel.cpp
+++ b/src/thirdparty/VirtualDub/Kasumi/source/pixel.cpp
@@ -1,6 +1,6 @@
// VirtualDub - Video processing and capture application
// Graphics support library
-// Copyright (C) 1998-2007 Avery Lee
+// Copyright (C) 1998-2009 Avery Lee
//
// 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
@@ -16,6 +16,7 @@
// along with this program; if not, write to the Free Software
// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+#include <stdafx.h>
#include <vd2/system/math.h>
#include <vd2/system/halffloat.h>
#include <vd2/Kasumi/pixmap.h>
@@ -109,8 +110,16 @@ uint32 VDPixmapSample(const VDPixmap& px, sint32 x, sint32 y) {
}
break;
+ case nsVDPixmap::kPixFormat_Y8_FR:
+ {
+ uint8 luma = ((const uint8 *)px.data + px.pitch*y)[x];
+
+ return (uint32)luma * 0x010101;
+ }
+ break;
+
case nsVDPixmap::kPixFormat_YUV444_Planar:
- return VDConvertYCbCrToRGB(VDPixmapSample8(px.data, px.pitch, x, y), VDPixmapSample8(px.data2, px.pitch2, x, y), VDPixmapSample8(px.data3, px.pitch3, x, y));
+ return VDConvertYCbCrToRGB(VDPixmapSample8(px.data, px.pitch, x, y), VDPixmapSample8(px.data2, px.pitch2, x, y), VDPixmapSample8(px.data3, px.pitch3, x, y), false, false);
case nsVDPixmap::kPixFormat_YUV422_Planar:
{
@@ -122,7 +131,8 @@ uint32 VDPixmapSample(const VDPixmap& px, sint32 x, sint32 y) {
return VDConvertYCbCrToRGB(
VDPixmapSample8(px.data, px.pitch, x, y),
VDPixmapInterpolateSample8(px.data2, px.pitch2, w2, h2, u, v),
- VDPixmapInterpolateSample8(px.data3, px.pitch3, w2, h2, u, v));
+ VDPixmapInterpolateSample8(px.data3, px.pitch3, w2, h2, u, v),
+ false, false);
}
case nsVDPixmap::kPixFormat_YUV420_Planar:
@@ -135,7 +145,8 @@ uint32 VDPixmapSample(const VDPixmap& px, sint32 x, sint32 y) {
return VDConvertYCbCrToRGB(
VDPixmapSample8(px.data, px.pitch, x, y),
VDPixmapInterpolateSample8(px.data2, px.pitch2, w2, h2, u, v),
- VDPixmapInterpolateSample8(px.data3, px.pitch3, w2, h2, u, v));
+ VDPixmapInterpolateSample8(px.data3, px.pitch3, w2, h2, u, v),
+ false, false);
}
case nsVDPixmap::kPixFormat_YUV411_Planar:
@@ -148,7 +159,8 @@ uint32 VDPixmapSample(const VDPixmap& px, sint32 x, sint32 y) {
return VDConvertYCbCrToRGB(
VDPixmapSample8(px.data, px.pitch, x, y),
VDPixmapInterpolateSample8(px.data2, px.pitch2, w2, h2, u, v),
- VDPixmapInterpolateSample8(px.data3, px.pitch3, w2, h2, u, v));
+ VDPixmapInterpolateSample8(px.data3, px.pitch3, w2, h2, u, v),
+ false, false);
}
case nsVDPixmap::kPixFormat_YUV410_Planar:
@@ -161,7 +173,8 @@ uint32 VDPixmapSample(const VDPixmap& px, sint32 x, sint32 y) {
return VDConvertYCbCrToRGB(
VDPixmapSample8(px.data, px.pitch, x, y),
VDPixmapInterpolateSample8(px.data2, px.pitch2, w2, h2, u, v),
- VDPixmapInterpolateSample8(px.data3, px.pitch3, w2, h2, u, v));
+ VDPixmapInterpolateSample8(px.data3, px.pitch3, w2, h2, u, v),
+ false, false);
}
default:
@@ -212,18 +225,18 @@ uint32 VDPixmapInterpolateSample8To24(const void *data, ptrdiff_t pitch, uint32
x_256 &= ~(x_256 >> 31);
y_256 &= ~(y_256 >> 31);
- uint32 w_256 = (w - 1) << 8;
- uint32 h_256 = (h - 1) << 8;
- x_256 ^= (x_256 ^ w_256) & ((x_256 - w_256) >> 31);
- y_256 ^= (y_256 ^ h_256) & ((y_256 - h_256) >> 31);
+ sint32 w_256 = (w - 1) << 8;
+ sint32 h_256 = (h - 1) << 8;
+ x_256 += (w_256 - x_256) & ((w_256 - x_256) >> 31);
+ y_256 += (h_256 - y_256) & ((h_256 - y_256) >> 31);
const uint8 *row0 = (const uint8 *)data + pitch * (y_256 >> 8) + (x_256 >> 8);
const uint8 *row1 = row0;
- if ((uint32)y_256 < h_256)
+ if (y_256 < h_256)
row1 += pitch;
- ptrdiff_t xstep = (uint32)x_256 < w_256 ? 1 : 0;
+ ptrdiff_t xstep = x_256 < w_256 ? 1 : 0;
sint32 xoffset = x_256 & 255;
sint32 yoffset = y_256 & 255;
sint32 p00 = row0[0];
@@ -371,10 +384,10 @@ namespace {
return VDClampedRoundFixedToUint8Fast((float)(y-0x100000) * (1.1643836f/65536.0f/255.0f))*0x010101;
}
- uint32 InterpPlanarYCC888(const VDPixmap& px, sint32 x1, sint32 y1, sint32 x23, sint32 y23, uint32 w23, uint32 h23) {
- float y = (float)(sint32)VDPixmapInterpolateSample8To24(px.data, px.pitch, px.w, px.h, x1, y1);
- float cb = (float)(sint32)VDPixmapInterpolateSample8To24(px.data2, px.pitch2, w23, h23, x23, y23);
- float cr = (float)(sint32)VDPixmapInterpolateSample8To24(px.data3, px.pitch3, w23, h23, x23, y23);
+ uint32 ConvertYCC72ToRGB24(sint32 iy, sint32 icb, sint32 icr) {
+ float y = (float)iy;
+ float cb = (float)icb;
+ float cr = (float)icr;
// ! 1.1643836 - 5.599D-17 1.5960268 - 222.92157 !
// ! 1.1643836 - 0.3917623 - 0.8129676 135.57529 !
@@ -386,17 +399,17 @@ namespace {
return (ir << 16) + (ig << 8) + ib;
}
- uint32 ConvertYCC72ToRGB24(sint32 iy, sint32 icb, sint32 icr) {
+ uint32 ConvertYCC72ToRGB24_FR(sint32 iy, sint32 icb, sint32 icr) {
float y = (float)iy;
float cb = (float)icb;
float cr = (float)icr;
- // ! 1.1643836 - 5.599D-17 1.5960268 - 222.92157 !
- // ! 1.1643836 - 0.3917623 - 0.8129676 135.57529 !
- // ! 1.1643836 2.0172321 - 1.110D-16 - 276.83585 !
- uint32 ir = VDClampedRoundFixedToUint8Fast((1.1643836f/65536.0f/255.0f)*y + (1.5960268f/65536.0f/255.0f)*cr - (222.92157f / 255.0f));
- uint32 ig = VDClampedRoundFixedToUint8Fast((1.1643836f/65536.0f/255.0f)*y - (0.3917623f/65536.0f/255.0f)*cb - (0.8129676f/65536.0f/255.0f)*cr + (135.57529f / 255.0f));
- uint32 ib = VDClampedRoundFixedToUint8Fast((1.1643836f/65536.0f/255.0f)*y + (2.0172321f/65536.0f/255.0f)*cb - (276.83585f / 255.0f));
+ // 1. 0. 1.402 - 179.456
+ // 1. - 0.3441363 - 0.7141363 135.45889
+ // 1. 1.772 - 2.220D-16 - 226.816
+ uint32 ir = VDClampedRoundFixedToUint8Fast((1.0f/65536.0f/255.0f)*y + (1.4020000f/65536.0f/255.0f)*cr - (179.456f / 255.0f));
+ uint32 ig = VDClampedRoundFixedToUint8Fast((1.0f/65536.0f/255.0f)*y - (0.3441363f/65536.0f/255.0f)*cb - (0.7141363f/65536.0f/255.0f)*cr + (135.45889f / 255.0f));
+ uint32 ib = VDClampedRoundFixedToUint8Fast((1.0f/65536.0f/255.0f)*y + (1.7720000f/65536.0f/255.0f)*cb - (226.816f / 255.0f));
return (ir << 16) + (ig << 8) + ib;
}
@@ -416,7 +429,90 @@ namespace {
return (ir << 16) + (ig << 8) + ib;
}
+ uint32 ConvertYCC72ToRGB24_709_FR(sint32 iy, sint32 icb, sint32 icr) {
+ float y = (float)iy;
+ float cb = (float)icb;
+ float cr = (float)icr;
+
+ // 1. 0. 1.5748 - 201.5744
+ // 1. - 0.1873243 - 0.4681243 83.897414
+ // 1. 1.8556 0. - 237.5168
+ uint32 ir = VDClampedRoundFixedToUint8Fast((1.0f/65536.0f/255.0f)*y + (1.5748f/65536.0f/255.0f)*cr - (201.5744f / 255.0f));
+ uint32 ig = VDClampedRoundFixedToUint8Fast((1.0f/65536.0f/255.0f)*y - (0.1873243f/65536.0f/255.0f)*cb - (0.4681243f/65536.0f/255.0f)*cr + (83.897414f / 255.0f));
+ uint32 ib = VDClampedRoundFixedToUint8Fast((1.0f/65536.0f/255.0f)*y + (1.8556f/65536.0f/255.0f)*cb - (237.5168f / 255.0f));
+
+ return (ir << 16) + (ig << 8) + ib;
+ }
+
+ uint32 InterpPlanarYCC888(const VDPixmap& px, sint32 x1, sint32 y1, sint32 x23, sint32 y23, uint32 w23, uint32 h23) {
+ sint32 y = VDPixmapInterpolateSample8To24(px.data, px.pitch, px.w, px.h, x1, y1);
+ sint32 cb = VDPixmapInterpolateSample8To24(px.data2, px.pitch2, w23, h23, x23, y23);
+ sint32 cr = VDPixmapInterpolateSample8To24(px.data3, px.pitch3, w23, h23, x23, y23);
+
+ return ConvertYCC72ToRGB24(y, cb, cr);
+ }
+
+ uint32 InterpPlanarYCC888_709(const VDPixmap& px, sint32 x1, sint32 y1, sint32 x23, sint32 y23, uint32 w23, uint32 h23) {
+ sint32 y = VDPixmapInterpolateSample8To24(px.data, px.pitch, px.w, px.h, x1, y1);
+ sint32 cb = VDPixmapInterpolateSample8To24(px.data2, px.pitch2, w23, h23, x23, y23);
+ sint32 cr = VDPixmapInterpolateSample8To24(px.data3, px.pitch3, w23, h23, x23, y23);
+
+ return ConvertYCC72ToRGB24_709(y, cb, cr);
+ }
+
+ uint32 InterpPlanarYCC888_FR(const VDPixmap& px, sint32 x1, sint32 y1, sint32 x23, sint32 y23, uint32 w23, uint32 h23) {
+ sint32 y = VDPixmapInterpolateSample8To24(px.data, px.pitch, px.w, px.h, x1, y1);
+ sint32 cb = VDPixmapInterpolateSample8To24(px.data2, px.pitch2, w23, h23, x23, y23);
+ sint32 cr = VDPixmapInterpolateSample8To24(px.data3, px.pitch3, w23, h23, x23, y23);
+
+ return ConvertYCC72ToRGB24_FR(y, cb, cr);
+ }
+
+ uint32 InterpPlanarYCC888_709_FR(const VDPixmap& px, sint32 x1, sint32 y1, sint32 x23, sint32 y23, uint32 w23, uint32 h23) {
+ sint32 y = VDPixmapInterpolateSample8To24(px.data, px.pitch, px.w, px.h, x1, y1);
+ sint32 cb = VDPixmapInterpolateSample8To24(px.data2, px.pitch2, w23, h23, x23, y23);
+ sint32 cr = VDPixmapInterpolateSample8To24(px.data3, px.pitch3, w23, h23, x23, y23);
+
+ return ConvertYCC72ToRGB24_709_FR(y, cb, cr);
+ }
+
+ template<uint32 (*ConvFn)(sint32, sint32, sint32)>
+ uint32 InterpPlanarYCC888_420i(const VDPixmap& px, sint32 x1, sint32 y1) {
+ sint32 y = VDPixmapInterpolateSample8To24(px.data, px.pitch, px.w, px.h, x1, y1);
+ sint32 cb;
+ sint32 cr;
+
+ const uint8 *src2 = (const uint8 *)px.data2;
+ const uint8 *src3 = (const uint8 *)px.data3;
+ const ptrdiff_t pitch2 = px.pitch2 + px.pitch2;
+ const ptrdiff_t pitch3 = px.pitch3 + px.pitch3;
+ const uint32 w23 = (px.w + 1) >> 1;
+ const uint32 h23 = (px.h + 1) >> 1;
+ const sint32 xc = (x1 >> 1) + 64;
+ sint32 yc = (y1 >> 1) + 64;
+
+ if (y1 & 1) {
+ yc -= 256;
+ cb = VDPixmapInterpolateSample8To24(src2, pitch2, w23, h23 >> 1, xc, yc);
+ cr = VDPixmapInterpolateSample8To24(src3, pitch3, w23, h23 >> 1, xc, yc);
+ } else {
+ cb = VDPixmapInterpolateSample8To24(src2 + px.pitch2, pitch2, w23, (h23 + 1) >> 1, xc, yc);
+ cr = VDPixmapInterpolateSample8To24(src3 + px.pitch3, pitch3, w23, (h23 + 1) >> 1, xc, yc);
+ }
+
+ return ConvFn(y, cb, cr);
+ }
+
uint32 SampleV210_Y(const void *src, ptrdiff_t srcpitch, sint32 x, sint32 y, uint32 w, uint32 h) {
+ if (x < 0)
+ x = 0;
+ if ((uint32)x >= w)
+ x = w - 1;
+ if (y < 0)
+ y = 0;
+ if ((uint32)y >= h)
+ y = h - 1;
+
const uint32 *p = (const uint32 *)((const char *)src + srcpitch*y) + (x / 6)*4;
switch((uint32)x % 6) {
@@ -431,6 +527,15 @@ namespace {
}
uint32 SampleV210_Cb(const void *src, ptrdiff_t srcpitch, sint32 x, sint32 y, uint32 w, uint32 h) {
+ if (x < 0)
+ x = 0;
+ if ((uint32)x >= w)
+ x = w - 1;
+ if (y < 0)
+ y = 0;
+ if ((uint32)y >= h)
+ y = h - 1;
+
const uint32 *p = (const uint32 *)((const char *)src + srcpitch*y) + (x / 3)*4;
switch((uint32)x % 3) {
@@ -442,6 +547,15 @@ namespace {
}
uint32 SampleV210_Cr(const void *src, ptrdiff_t srcpitch, sint32 x, sint32 y, uint32 w, uint32 h) {
+ if (x < 0)
+ x = 0;
+ if ((uint32)x >= w)
+ x = w - 1;
+ if (y < 0)
+ y = 0;
+ if ((uint32)y >= h)
+ y = h - 1;
+
const uint32 *p = (const uint32 *)((const char *)src + srcpitch*y) + (x / 3)*4;
switch((uint32)x % 3) {
@@ -494,6 +608,20 @@ uint32 VDPixmapInterpolateSampleRGB24(const VDPixmap& px, sint32 x_256, sint32 y
VDPixmapInterpolateSample8x4To24((const char *)px.data + 3, px.pitch, (px.w + 1) >> 1, px.h, (x_256 >> 1) + 128, y_256)
);
+ case nsVDPixmap::kPixFormat_YUV422_UYVY_FR:
+ return ConvertYCC72ToRGB24_FR(
+ VDPixmapInterpolateSample8x2To24((const char *)px.data + 1, px.pitch, px.w, px.h, x_256, y_256),
+ VDPixmapInterpolateSample8x4To24((const char *)px.data + 0, px.pitch, (px.w + 1) >> 1, px.h, (x_256 >> 1) + 128, y_256),
+ VDPixmapInterpolateSample8x4To24((const char *)px.data + 2, px.pitch, (px.w + 1) >> 1, px.h, (x_256 >> 1) + 128, y_256)
+ );
+
+ case nsVDPixmap::kPixFormat_YUV422_YUYV_FR:
+ return ConvertYCC72ToRGB24_FR(
+ VDPixmapInterpolateSample8x2To24((const char *)px.data + 0, px.pitch, px.w, px.h, x_256, y_256),
+ VDPixmapInterpolateSample8x4To24((const char *)px.data + 1, px.pitch, (px.w + 1) >> 1, px.h, (x_256 >> 1) + 128, y_256),
+ VDPixmapInterpolateSample8x4To24((const char *)px.data + 3, px.pitch, (px.w + 1) >> 1, px.h, (x_256 >> 1) + 128, y_256)
+ );
+
case nsVDPixmap::kPixFormat_YUV444_XVYU:
return ConvertYCC72ToRGB24(
VDPixmapInterpolateSample8x4To24((const char *)px.data + 1, px.pitch, px.w, px.h, x_256, y_256),
@@ -508,6 +636,27 @@ uint32 VDPixmapInterpolateSampleRGB24(const VDPixmap& px, sint32 x_256, sint32 y
VDPixmapInterpolateSample8x4To24((const char *)px.data + 2, px.pitch, (px.w + 1) >> 1, px.h, (x_256 >> 1) + 128, y_256)
);
+ case nsVDPixmap::kPixFormat_YUV422_YUYV_709:
+ return ConvertYCC72ToRGB24_709(
+ VDPixmapInterpolateSample8x2To24((const char *)px.data + 0, px.pitch, px.w, px.h, x_256, y_256),
+ VDPixmapInterpolateSample8x4To24((const char *)px.data + 1, px.pitch, (px.w + 1) >> 1, px.h, (x_256 >> 1) + 128, y_256),
+ VDPixmapInterpolateSample8x4To24((const char *)px.data + 3, px.pitch, (px.w + 1) >> 1, px.h, (x_256 >> 1) + 128, y_256)
+ );
+
+ case nsVDPixmap::kPixFormat_YUV422_UYVY_709_FR:
+ return ConvertYCC72ToRGB24_709_FR(
+ VDPixmapInterpolateSample8x2To24((const char *)px.data + 1, px.pitch, px.w, px.h, x_256, y_256),
+ VDPixmapInterpolateSample8x4To24((const char *)px.data + 0, px.pitch, (px.w + 1) >> 1, px.h, (x_256 >> 1) + 128, y_256),
+ VDPixmapInterpolateSample8x4To24((const char *)px.data + 2, px.pitch, (px.w + 1) >> 1, px.h, (x_256 >> 1) + 128, y_256)
+ );
+
+ case nsVDPixmap::kPixFormat_YUV422_YUYV_709_FR:
+ return ConvertYCC72ToRGB24_709_FR(
+ VDPixmapInterpolateSample8x2To24((const char *)px.data + 0, px.pitch, px.w, px.h, x_256, y_256),
+ VDPixmapInterpolateSample8x4To24((const char *)px.data + 1, px.pitch, (px.w + 1) >> 1, px.h, (x_256 >> 1) + 128, y_256),
+ VDPixmapInterpolateSample8x4To24((const char *)px.data + 3, px.pitch, (px.w + 1) >> 1, px.h, (x_256 >> 1) + 128, y_256)
+ );
+
case nsVDPixmap::kPixFormat_YUV420_NV12:
return ConvertYCC72ToRGB24(
VDPixmapInterpolateSample8To24(px.data, px.pitch, px.w, px.h, x_256, y_256),
@@ -519,16 +668,22 @@ uint32 VDPixmapInterpolateSampleRGB24(const VDPixmap& px, sint32 x_256, sint32 y
return InterpPlanarYCC888(px, x_256, y_256, x_256, y_256, px.w, px.h);
case nsVDPixmap::kPixFormat_YUV422_Planar:
- return InterpPlanarYCC888(px, x_256, y_256, (x_256 >> 1) + 128, y_256, (px.w + 1) >> 1, px.h);
+ return InterpPlanarYCC888(px, x_256, y_256, (x_256 >> 1) + 64, y_256, (px.w + 1) >> 1, px.h);
case nsVDPixmap::kPixFormat_YUV411_Planar:
- return InterpPlanarYCC888(px, x_256, y_256, (x_256 >> 2) + 128, y_256, (px.w + 3) >> 2, px.h);
+ return InterpPlanarYCC888(px, x_256, y_256, (x_256 >> 2) + 96, y_256, (px.w + 3) >> 2, px.h);
case nsVDPixmap::kPixFormat_YUV420_Planar:
- return InterpPlanarYCC888(px, x_256, y_256, (x_256 >> 1) + 128, y_256 >> 1, (px.w + 1) >> 1, (px.h + 1) >> 1);
+ return InterpPlanarYCC888(px, x_256, y_256, (x_256 >> 1) + 64, y_256 >> 1, (px.w + 1) >> 1, (px.h + 1) >> 1);
+
+ case nsVDPixmap::kPixFormat_YUV420it_Planar:
+ return InterpPlanarYCC888(px, x_256, y_256, (x_256 >> 1) + 64, (y_256 >> 1) + 32, (px.w + 1) >> 1, (px.h + 1) >> 1);
+
+ case nsVDPixmap::kPixFormat_YUV420ib_Planar:
+ return InterpPlanarYCC888(px, x_256, y_256, (x_256 >> 1) + 64, (y_256 >> 1) - 32, (px.w + 1) >> 1, (px.h + 1) >> 1);
case nsVDPixmap::kPixFormat_YUV410_Planar:
- return InterpPlanarYCC888(px, x_256, y_256, (x_256 >> 2) + 128, y_256 >> 2, (px.w + 3) >> 2, (px.h + 3) >> 2);
+ return InterpPlanarYCC888(px, x_256, y_256, (x_256 >> 2) + 96, y_256 >> 2, (px.w + 3) >> 2, (px.h + 3) >> 2);
case nsVDPixmap::kPixFormat_YUV420_Planar_Centered:
return InterpPlanarYCC888(px, x_256, y_256, x_256 >> 1, y_256 >> 1, (px.w + 1) >> 1, (px.h + 1) >> 1);
@@ -536,6 +691,81 @@ uint32 VDPixmapInterpolateSampleRGB24(const VDPixmap& px, sint32 x_256, sint32 y
case nsVDPixmap::kPixFormat_YUV422_Planar_Centered:
return InterpPlanarYCC888(px, x_256, y_256, x_256 >> 1, y_256, (px.w + 1) >> 1, px.h);
+ case nsVDPixmap::kPixFormat_YUV444_Planar_709:
+ return InterpPlanarYCC888_709(px, x_256, y_256, x_256, y_256, px.w, px.h);
+
+ case nsVDPixmap::kPixFormat_YUV422_Planar_709:
+ return InterpPlanarYCC888_709(px, x_256, y_256, (x_256 >> 1) + 64, y_256, (px.w + 1) >> 1, px.h);
+
+ case nsVDPixmap::kPixFormat_YUV411_Planar_709:
+ return InterpPlanarYCC888_709(px, x_256, y_256, (x_256 >> 2) + 96, y_256, (px.w + 3) >> 2, px.h);
+
+ case nsVDPixmap::kPixFormat_YUV420_Planar_709:
+ return InterpPlanarYCC888_709(px, x_256, y_256, (x_256 >> 1) + 64, y_256 >> 1, (px.w + 1) >> 1, (px.h + 1) >> 1);
+
+ case nsVDPixmap::kPixFormat_YUV420it_Planar_709:
+ return InterpPlanarYCC888_709(px, x_256, y_256, (x_256 >> 1) + 64, (y_256 >> 1) + 32, (px.w + 1) >> 1, (px.h + 1) >> 1);
+
+ case nsVDPixmap::kPixFormat_YUV420ib_Planar_709:
+ return InterpPlanarYCC888_709(px, x_256, y_256, (x_256 >> 1) + 64, (y_256 >> 1) - 32, (px.w + 1) >> 1, (px.h + 1) >> 1);
+
+ case nsVDPixmap::kPixFormat_YUV410_Planar_709:
+ return InterpPlanarYCC888_709(px, x_256, y_256, (x_256 >> 2) + 96, y_256 >> 2, (px.w + 3) >> 2, (px.h + 3) >> 2);
+
+ case nsVDPixmap::kPixFormat_YUV444_Planar_FR:
+ return InterpPlanarYCC888_FR(px, x_256, y_256, x_256, y_256, px.w, px.h);
+
+ case nsVDPixmap::kPixFormat_YUV422_Planar_FR:
+ return InterpPlanarYCC888_FR(px, x_256, y_256, (x_256 >> 1) + 64, y_256, (px.w + 1) >> 1, px.h);
+
+ case nsVDPixmap::kPixFormat_YUV411_Planar_FR:
+ return InterpPlanarYCC888_FR(px, x_256, y_256, (x_256 >> 2) + 96, y_256, (px.w + 3) >> 2, px.h);
+
+ case nsVDPixmap::kPixFormat_YUV420_Planar_FR:
+ return InterpPlanarYCC888_FR(px, x_256, y_256, (x_256 >> 1) + 64, y_256 >> 1, (px.w + 1) >> 1, (px.h + 1) >> 1);
+
+ case nsVDPixmap::kPixFormat_YUV420it_Planar_FR:
+ return InterpPlanarYCC888_FR(px, x_256, y_256, (x_256 >> 1) + 64, (y_256 >> 1) + 32, (px.w + 1) >> 1, (px.h + 1) >> 1);
+
+ case nsVDPixmap::kPixFormat_YUV420ib_Planar_FR:
+ return InterpPlanarYCC888_FR(px, x_256, y_256, (x_256 >> 1) + 64, (y_256 >> 1) - 32, (px.w + 1) >> 1, (px.h + 1) >> 1);
+
+ case nsVDPixmap::kPixFormat_YUV410_Planar_FR:
+ return InterpPlanarYCC888_FR(px, x_256, y_256, (x_256 >> 2) + 96, y_256 >> 2, (px.w + 3) >> 2, (px.h + 3) >> 2);
+
+ case nsVDPixmap::kPixFormat_YUV444_Planar_709_FR:
+ return InterpPlanarYCC888_709_FR(px, x_256, y_256, x_256, y_256, px.w, px.h);
+
+ case nsVDPixmap::kPixFormat_YUV422_Planar_709_FR:
+ return InterpPlanarYCC888_709_FR(px, x_256, y_256, (x_256 >> 1) + 64, y_256, (px.w + 1) >> 1, px.h);
+
+ case nsVDPixmap::kPixFormat_YUV411_Planar_709_FR:
+ return InterpPlanarYCC888_709_FR(px, x_256, y_256, (x_256 >> 2) + 96, y_256, (px.w + 3) >> 2, px.h);
+
+ case nsVDPixmap::kPixFormat_YUV420_Planar_709_FR:
+ return InterpPlanarYCC888_709_FR(px, x_256, y_256, (x_256 >> 1) + 64, y_256 >> 1, (px.w + 1) >> 1, (px.h + 1) >> 1);
+
+ case nsVDPixmap::kPixFormat_YUV420it_Planar_709_FR:
+ return InterpPlanarYCC888_709_FR(px, x_256, y_256, (x_256 >> 1) + 64, (y_256 >> 1) + 32, (px.w + 1) >> 1, (px.h + 1) >> 1);
+
+ case nsVDPixmap::kPixFormat_YUV420ib_Planar_709_FR:
+ return InterpPlanarYCC888_709_FR(px, x_256, y_256, (x_256 >> 1) + 64, (y_256 >> 1) - 32, (px.w + 1) >> 1, (px.h + 1) >> 1);
+
+ case nsVDPixmap::kPixFormat_YUV410_Planar_709_FR:
+ return InterpPlanarYCC888_709_FR(px, x_256, y_256, (x_256 >> 2) + 96, y_256 >> 2, (px.w + 3) >> 2, (px.h + 3) >> 2);
+
+ case nsVDPixmap::kPixFormat_YUV420i_Planar:
+ return InterpPlanarYCC888_420i<ConvertYCC72ToRGB24 >(px, x_256, y_256);
+
+ case nsVDPixmap::kPixFormat_YUV420i_Planar_FR:
+ return InterpPlanarYCC888_420i<ConvertYCC72ToRGB24_FR >(px, x_256, y_256);
+
+ case nsVDPixmap::kPixFormat_YUV420i_Planar_709:
+ return InterpPlanarYCC888_420i<ConvertYCC72ToRGB24_709 >(px, x_256, y_256);
+
+ case nsVDPixmap::kPixFormat_YUV420i_Planar_709_FR:
+ return InterpPlanarYCC888_420i<ConvertYCC72ToRGB24_709_FR>(px, x_256, y_256);
+
case nsVDPixmap::kPixFormat_YUV422_Planar_16F:
{
float y = VDPixmapInterpolateSample16F(px.data, px.pitch, px.w, px.h, x_256, y_256);
@@ -601,18 +831,18 @@ uint32 VDPixmapInterpolateSampleRGB24(const VDPixmap& px, sint32 x_256, sint32 y
float chroma_fx = (float)(chroma_x & 255) * (1.0f / 255.0f);
float chroma_fy = (float)(chroma_y & 255) * (1.0f / 255.0f);
- float cb0 = SampleV210_Cb(px.data, px.pitch, chroma_ix+0, chroma_iy+0, px.w, px.h) * (1.0f / 1023.0f);
- float cb1 = SampleV210_Cb(px.data, px.pitch, chroma_ix+1, chroma_iy+0, px.w, px.h) * (1.0f / 1023.0f);
- float cb2 = SampleV210_Cb(px.data, px.pitch, chroma_ix+0, chroma_iy+1, px.w, px.h) * (1.0f / 1023.0f);
- float cb3 = SampleV210_Cb(px.data, px.pitch, chroma_ix+1, chroma_iy+1, px.w, px.h) * (1.0f / 1023.0f);
+ float cb0 = SampleV210_Cb(px.data, px.pitch, chroma_ix+0, chroma_iy+0, chroma_w, chroma_h) * (1.0f / 1023.0f);
+ float cb1 = SampleV210_Cb(px.data, px.pitch, chroma_ix+1, chroma_iy+0, chroma_w, chroma_h) * (1.0f / 1023.0f);
+ float cb2 = SampleV210_Cb(px.data, px.pitch, chroma_ix+0, chroma_iy+1, chroma_w, chroma_h) * (1.0f / 1023.0f);
+ float cb3 = SampleV210_Cb(px.data, px.pitch, chroma_ix+1, chroma_iy+1, chroma_w, chroma_h) * (1.0f / 1023.0f);
float cbt = cb0 + (cb1 - cb0)*chroma_fx;
float cbb = cb2 + (cb3 - cb2)*chroma_fx;
float cbr = cbt + (cbb - cbt)*chroma_fy;
- float cr0 = SampleV210_Cr(px.data, px.pitch, chroma_ix+0, chroma_iy+0, px.w, px.h) * (1.0f / 1023.0f);
- float cr1 = SampleV210_Cr(px.data, px.pitch, chroma_ix+1, chroma_iy+0, px.w, px.h) * (1.0f / 1023.0f);
- float cr2 = SampleV210_Cr(px.data, px.pitch, chroma_ix+0, chroma_iy+1, px.w, px.h) * (1.0f / 1023.0f);
- float cr3 = SampleV210_Cr(px.data, px.pitch, chroma_ix+1, chroma_iy+1, px.w, px.h) * (1.0f / 1023.0f);
+ float cr0 = SampleV210_Cr(px.data, px.pitch, chroma_ix+0, chroma_iy+0, chroma_w, chroma_h) * (1.0f / 1023.0f);
+ float cr1 = SampleV210_Cr(px.data, px.pitch, chroma_ix+1, chroma_iy+0, chroma_w, chroma_h) * (1.0f / 1023.0f);
+ float cr2 = SampleV210_Cr(px.data, px.pitch, chroma_ix+0, chroma_iy+1, chroma_w, chroma_h) * (1.0f / 1023.0f);
+ float cr3 = SampleV210_Cr(px.data, px.pitch, chroma_ix+1, chroma_iy+1, chroma_w, chroma_h) * (1.0f / 1023.0f);
float crt = cr0 + (cr1 - cr0)*chroma_fx;
float crb = cr2 + (cr3 - cr2)*chroma_fx;
float crr = crt + (crb - crt)*chroma_fy;
@@ -630,15 +860,39 @@ uint32 VDPixmapInterpolateSampleRGB24(const VDPixmap& px, sint32 x_256, sint32 y
}
}
-uint32 VDConvertYCbCrToRGB(uint8 y0, uint8 cb0, uint8 cr0) {
- sint32 y = y0 - 16;
+uint32 VDConvertYCbCrToRGB(uint8 y0, uint8 cb0, uint8 cr0, bool use709, bool useFullRange) {
+ sint32 y = y0;
sint32 cb = cb0 - 128;
sint32 cr = cr0 - 128;
-
- sint32 y2 = y * 76309 + 0x8000;
- sint32 r = y2 + cr * 104597;
- sint32 g = y2 + cr * -53279 + cb * -25674;
- sint32 b = y2 + cb * 132201;
+ sint32 r;
+ sint32 g;
+ sint32 b;
+
+ if (use709) {
+ if (useFullRange) {
+ sint32 y2 = (y << 16) + 0x8000;
+ r = y2 + cr * 103206;
+ g = y2 + cr * -30679 + cb * -12276;
+ b = y2 + cb * 121609;
+ } else {
+ sint32 y2 = (y - 16) * 76309 + 0x8000;
+ r = y2 + cr * 117489;
+ g = y2 + cr * -34925 + cb * -13975;
+ b = y2 + cb * 138438;
+ }
+ } else {
+ if (useFullRange) {
+ sint32 y2 = (y << 16) + 0x8000;
+ r = y2 + cr * 91181;
+ g = y2 + cr * -46802 + cb * -22554;
+ b = y2 + cb * 166130;
+ } else {
+ sint32 y2 = (y - 16) * 76309 + 0x8000;
+ r = y2 + cr * 104597;
+ g = y2 + cr * -53279 + cb * -25674;
+ b = y2 + cb * 132201;
+ }
+ }
r &= ~(r >> 31);
g &= ~(g >> 31);
@@ -651,17 +905,38 @@ uint32 VDConvertYCbCrToRGB(uint8 y0, uint8 cb0, uint8 cr0) {
}
uint32 VDConvertRGBToYCbCr(uint32 c) {
- return VDConvertRGBToYCbCr((uint8)(c >> 16), (uint8)(c >> 8), (uint8)c);
+ return VDConvertRGBToYCbCr((uint8)(c >> 16), (uint8)(c >> 8), (uint8)c, false, false);
}
-uint32 VDConvertRGBToYCbCr(uint8 r8, uint8 g8, uint8 b8) {
+uint32 VDConvertRGBToYCbCr(uint8 r8, uint8 g8, uint8 b8, bool use709, bool useFullRange) {
sint32 r = r8;
sint32 g = g8;
sint32 b = b8;
- sint32 yt = 1052*r + 2065*g + 401*b;
- sint32 y = (yt + 0x10800) >> 4;
- sint32 cr = (10507932*r - yt*2987 + 0x80800000U) >> 8;
- sint32 cb = ( 8312025*b - yt*2363 + 0x80800000U) >> 24;
+ sint32 y;
+ sint32 cb;
+ sint32 cr;
+
+ if (use709) {
+ if (useFullRange) {
+ y = ( 13933*r + 46871*g + 4732*b + 0x8000) >> 8;
+ cb = ( -7509*r - 25259*g + 32768*b + 0x808000) >> 16;
+ cr = ( 32768*r - 29763*g - 3005*b + 0x808000);
+ } else {
+ y = ( 11966*r + 40254*g + 4064*b + 0x8000) >> 8;
+ cb = ( -6596*r - 22189*g + 28784*b + 0x808000) >> 16;
+ cr = ( 28784*r - 26145*g + 2639*b + 0x808000);
+ }
+ } else {
+ if (useFullRange) {
+ y = ( 19595*r + 38470*g + 7471*b + 0x8000) >> 8;
+ cb = (-11058*r - 21710*g + 32768*b + 0x808000) >> 16;
+ cr = ( 32768*r - 27439*g + 5329*b + 0x808000);
+ } else {
+ y = ( 16829*r + 33039*g + 6416*b + 0x108000) >> 8;
+ cb = ( -9714*r - 19071*g + 28784*b + 0x808000) >> 16;
+ cr = ( 28784*r - 24103*g - 4681*b + 0x808000);
+ }
+ }
return (uint8)cb + (y & 0xff00) + (cr&0xff0000);
}
diff --git a/src/thirdparty/VirtualDub/Kasumi/source/pixmaputils.cpp b/src/thirdparty/VirtualDub/Kasumi/source/pixmaputils.cpp
index 1134a1e69..d43335a1b 100644
--- a/src/thirdparty/VirtualDub/Kasumi/source/pixmaputils.cpp
+++ b/src/thirdparty/VirtualDub/Kasumi/source/pixmaputils.cpp
@@ -1,3 +1,23 @@
+// VirtualDub - Video processing and capture application
+// Graphics support library
+// Copyright (C) 1998-2009 Avery Lee
+//
+// 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+#include <stdafx.h>
+#include <vd2/system/vdtypes.h>
#include <vd2/Kasumi/pixmaputils.h>
#include <vd2/system/memory.h>
@@ -27,8 +47,47 @@ extern VDPixmapFormatInfo g_vdPixmapFormats[] = {
/* V210 */ { "v210", true,24, 1, 2, 0, 64, 0, 0, 0, 1, 0 },
/* YUV422_UYVY_709 */ { "UYVY-709", true, 2, 1, 1, 0, 4, 0, 0, 0, 0, 0 },
/* NV12 */ { "NV12", false, 1, 1, 0, 0, 1, 1, 1, 1, 2, 0 },
+ /* Y8-FR */ { "I8", false, 1, 1, 1, 0, 1, 0, 0, 0, 0, 0 },
+ /* YUV422_YUYV_709 */ { "YUYV-709", true, 2, 1, 1, 0, 4, 0, 0, 0, 0, 0 },
+ /* YUV444_Planar_709 */ { "YUV444-709", false, 1, 1, 0, 0, 1, 2, 0, 0, 1, 0 },
+ /* YUV422_Planar_709 */ { "YUV422-709", false, 1, 1, 0, 0, 1, 2, 1, 0, 1, 0 },
+ /* YUV420_Planar_709 */ { "YUV420-709", false, 1, 1, 0, 0, 1, 2, 1, 1, 1, 0 },
+ /* YUV411_Planar_709 */ { "YUV411-709", false, 1, 1, 0, 0, 1, 2, 2, 0, 1, 0 },
+ /* YUV410_Planar_709 */ { "YUV410-709", false, 1, 1, 0, 0, 1, 2, 2, 2, 1, 0 },
+ /* YUV422_UYVY_FR */ { "UYVY-FR", true, 2, 1, 1, 0, 4, 0, 0, 0, 0, 0 },
+ /* YUV422_YUYV_FR */ { "YUYV-FR", true, 2, 1, 1, 0, 4, 0, 0, 0, 0, 0 },
+ /* YUV444_Planar_FR */ { "YUV444-FR", false, 1, 1, 0, 0, 1, 2, 0, 0, 1, 0 },
+ /* YUV422_Planar_FR */ { "YUV422-FR", false, 1, 1, 0, 0, 1, 2, 1, 0, 1, 0 },
+ /* YUV420_Planar_FR */ { "YUV420-FR", false, 1, 1, 0, 0, 1, 2, 1, 1, 1, 0 },
+ /* YUV411_Planar_FR */ { "YUV411-FR", false, 1, 1, 0, 0, 1, 2, 2, 0, 1, 0 },
+ /* YUV410_Planar_FR */ { "YUV410-FR", false, 1, 1, 0, 0, 1, 2, 2, 2, 1, 0 },
+ /* YUV422_UYVY_FR_709 */ { "UYVY-709-FR", true, 2, 1, 1, 0, 4, 0, 0, 0, 0, 0 },
+ /* YUV422_YUYV_FR_709 */ { "YUYV-709-FR", true, 2, 1, 1, 0, 4, 0, 0, 0, 0, 0 },
+ /* YUV444_Planar_FR_709 */ { "YUV444-709-FR", false, 1, 1, 0, 0, 1, 2, 0, 0, 1, 0 },
+ /* YUV422_Planar_FR_709 */ { "YUV422-709-FR", false, 1, 1, 0, 0, 1, 2, 1, 0, 1, 0 },
+ /* YUV420_Planar_FR_709 */ { "YUV420-709-FR", false, 1, 1, 0, 0, 1, 2, 1, 1, 1, 0 },
+ /* YUV411_Planar_FR_709 */ { "YUV411-709-FR", false, 1, 1, 0, 0, 1, 2, 2, 0, 1, 0 },
+ /* YUV410_Planar_FR_709 */ { "YUV410-709-FR", false, 1, 1, 0, 0, 1, 2, 2, 2, 1, 0 },
+ /* YUV420i_Planar */ { "YUV420i", false, 1, 1, 0, 0, 1, 2, 1, 1, 1, 0 },
+ /* YUV420i_Planar_FR */ { "YUV420i-FR", false, 1, 1, 0, 0, 1, 2, 1, 1, 1, 0 },
+ /* YUV420i_Planar_709 */ { "YUV420i-709", false, 1, 1, 0, 0, 1, 2, 1, 1, 1, 0 },
+ /* YUV420i_Planar_709_FR */ { "YUV420i-709-FR", false, 1, 1, 0, 0, 1, 2, 1, 1, 1, 0 },
+ /* YUV420it_Planar */ { "YUV420it", false, 1, 1, 0, 0, 1, 2, 1, 1, 1, 0 },
+ /* YUV420it_Planar_FR */ { "YUV420it-FR", false, 1, 1, 0, 0, 1, 2, 1, 1, 1, 0 },
+ /* YUV420it_Planar_709 */ { "YUV420it-709", false, 1, 1, 0, 0, 1, 2, 1, 1, 1, 0 },
+ /* YUV420it_Planar_709_FR */ { "YUV420it-709-FR",false, 1, 1, 0, 0, 1, 2, 1, 1, 1, 0 },
+ /* YUV420ib_Planar */ { "YUV420ib", false, 1, 1, 0, 0, 1, 2, 1, 1, 1, 0 },
+ /* YUV420ib_Planar_FR */ { "YUV420ib-FR", false, 1, 1, 0, 0, 1, 2, 1, 1, 1, 0 },
+ /* YUV420ib_Planar_709 */ { "YUV420ib-709", false, 1, 1, 0, 0, 1, 2, 1, 1, 1, 0 },
+ /* YUV420ib_Planar_709_FR */ { "YUV420ib-709-FR",false, 1, 1, 0, 0, 1, 2, 1, 1, 1, 0 },
};
+namespace {
+ void check() {
+ VDASSERTCT(sizeof(g_vdPixmapFormats)/sizeof(g_vdPixmapFormats[0]) == nsVDPixmap::kPixFormat_Max_Standard);
+ }
+}
+
#ifdef _DEBUG
bool VDIsValidPixmapPlane(const void *p, ptrdiff_t pitch, vdpixsize w, vdpixsize h) {
bool isvalid;
@@ -270,13 +329,48 @@ VDPixmap VDPixmapExtractField(const VDPixmap& src, bool field2) {
if (info.qh == 1)
vdptrstep(px.data, px.pitch);
- if (!info.auxhbits) {
+ if (!info.auxhbits ||
+ src.format == nsVDPixmap::kPixFormat_YUV420i_Planar ||
+ src.format == nsVDPixmap::kPixFormat_YUV420i_Planar_FR ||
+ src.format == nsVDPixmap::kPixFormat_YUV420i_Planar_709 ||
+ src.format == nsVDPixmap::kPixFormat_YUV420i_Planar_709_FR) {
+
vdptrstep(px.data2, px.pitch2);
vdptrstep(px.data3, px.pitch3);
}
}
}
+ switch(src.format) {
+ case nsVDPixmap::kPixFormat_YUV420i_Planar:
+ if (field2)
+ px.format = nsVDPixmap::kPixFormat_YUV420ib_Planar;
+ else
+ px.format = nsVDPixmap::kPixFormat_YUV420it_Planar;
+ break;
+
+ case nsVDPixmap::kPixFormat_YUV420i_Planar_FR:
+ if (field2)
+ px.format = nsVDPixmap::kPixFormat_YUV420ib_Planar_FR;
+ else
+ px.format = nsVDPixmap::kPixFormat_YUV420it_Planar_FR;
+ break;
+
+ case nsVDPixmap::kPixFormat_YUV420i_Planar_709:
+ if (field2)
+ px.format = nsVDPixmap::kPixFormat_YUV420ib_Planar_709;
+ else
+ px.format = nsVDPixmap::kPixFormat_YUV420it_Planar_709;
+ break;
+
+ case nsVDPixmap::kPixFormat_YUV420i_Planar_709_FR:
+ if (field2)
+ px.format = nsVDPixmap::kPixFormat_YUV420ib_Planar_709_FR;
+ else
+ px.format = nsVDPixmap::kPixFormat_YUV420it_Planar_709_FR;
+ break;
+ }
+
px.h >>= 1;
px.pitch += px.pitch;
px.pitch2 += px.pitch2;
@@ -454,7 +548,9 @@ void VDPixmapBuffer::init(const VDPixmapLayout& layout) {
if (srcinfo.palsize) {
palette = (const uint32 *)(p + linsize);
- memcpy((void *)palette, layout.palette, 4*srcinfo.palsize);
+
+ if (layout.palette)
+ memcpy((void *)palette, layout.palette, 4*srcinfo.palsize);
}
#ifdef _DEBUG
diff --git a/src/thirdparty/VirtualDub/Kasumi/source/region.cpp b/src/thirdparty/VirtualDub/Kasumi/source/region.cpp
index 283f43cf8..de605abc0 100644
--- a/src/thirdparty/VirtualDub/Kasumi/source/region.cpp
+++ b/src/thirdparty/VirtualDub/Kasumi/source/region.cpp
@@ -1,6 +1,6 @@
// VirtualDub - Video processing and capture application
// Graphics support library
-// Copyright (C) 1998-2007 Avery Lee
+// Copyright (C) 1998-2009 Avery Lee
//
// 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
@@ -16,6 +16,7 @@
// along with this program; if not, write to the Free Software
// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+#include <stdafx.h>
#include <vd2/Kasumi/pixmap.h>
#include <vd2/Kasumi/pixmaputils.h>
#include <vd2/Kasumi/region.h>
@@ -1005,67 +1006,94 @@ bool VDPixmapFillRegionAntialiased_16x_8x(const VDPixmap& dst, const VDPixmapReg
}
bool VDPixmapFillRegionAntialiased8x(const VDPixmap& dst, const VDPixmapRegion& region, int x, int y, uint32 color) {
- if (dst.format == nsVDPixmap::kPixFormat_YUV444_Planar ||
- dst.format == nsVDPixmap::kPixFormat_YUV422_Planar ||
- dst.format == nsVDPixmap::kPixFormat_YUV420_Planar ||
- dst.format == nsVDPixmap::kPixFormat_YUV410_Planar) {
- VDPixmap pxY;
- VDPixmap pxCb;
- VDPixmap pxCr;
-
- pxY.format = nsVDPixmap::kPixFormat_Y8;
- pxY.data = dst.data;
- pxY.pitch = dst.pitch;
- pxY.w = dst.w;
- pxY.h = dst.h;
-
- pxCb.format = nsVDPixmap::kPixFormat_Y8;
- pxCb.data = dst.data2;
- pxCb.pitch = dst.pitch2;
- pxCb.w = dst.w;
- pxCb.h = dst.h;
-
- pxCr.format = nsVDPixmap::kPixFormat_Y8;
- pxCr.data = dst.data3;
- pxCr.pitch = dst.pitch3;
- pxCr.w = dst.w;
- pxCr.h = dst.h;
-
- uint32 colorY = (color >> 8) & 0xff;
- uint32 colorCb = (color >> 0) & 0xff;
- uint32 colorCr = (color >> 16) & 0xff;
-
- VDPixmapFillRegionAntialiased8x(pxY, region, x, y, colorY);
-
- switch(dst.format) {
- case nsVDPixmap::kPixFormat_YUV410_Planar:
- pxCr.w = pxCb.w = dst.w >> 2;
- pxCr.h = pxCb.h = dst.h >> 2;
- x >>= 2;
- y >>= 2;
- VDPixmapFillRegionAntialiased_32x_32x(pxCb, region, x, y, colorCb);
- VDPixmapFillRegionAntialiased_32x_32x(pxCr, region, x, y, colorCr);
- return true;
- case nsVDPixmap::kPixFormat_YUV420_Planar:
- pxCr.w = pxCb.w = dst.w >> 1;
- pxCr.h = pxCb.h = dst.h >> 1;
- x >>= 1;
- y >>= 1;
- x += 2;
- VDPixmapFillRegionAntialiased_16x_16x(pxCb, region, x, y, colorCb);
- VDPixmapFillRegionAntialiased_16x_16x(pxCr, region, x, y, colorCr);
- return true;
- case nsVDPixmap::kPixFormat_YUV422_Planar:
- pxCr.w = pxCb.w = dst.w >> 1;
- x >>= 1;
- x += 2;
- VDPixmapFillRegionAntialiased_16x_8x(pxCb, region, x, y, colorCb);
- VDPixmapFillRegionAntialiased_16x_8x(pxCr, region, x, y, colorCr);
- return true;
- case nsVDPixmap::kPixFormat_YUV444_Planar:
- VDPixmapFillRegionAntialiased8x(pxCb, region, x, y, colorCb);
- VDPixmapFillRegionAntialiased8x(pxCr, region, x, y, colorCr);
- return true;
+ switch(dst.format) {
+ case nsVDPixmap::kPixFormat_YUV444_Planar:
+ case nsVDPixmap::kPixFormat_YUV444_Planar_FR:
+ case nsVDPixmap::kPixFormat_YUV444_Planar_709:
+ case nsVDPixmap::kPixFormat_YUV444_Planar_709_FR:
+ case nsVDPixmap::kPixFormat_YUV422_Planar:
+ case nsVDPixmap::kPixFormat_YUV422_Planar_FR:
+ case nsVDPixmap::kPixFormat_YUV422_Planar_709:
+ case nsVDPixmap::kPixFormat_YUV422_Planar_709_FR:
+ case nsVDPixmap::kPixFormat_YUV420_Planar:
+ case nsVDPixmap::kPixFormat_YUV420_Planar_FR:
+ case nsVDPixmap::kPixFormat_YUV420_Planar_709:
+ case nsVDPixmap::kPixFormat_YUV420_Planar_709_FR:
+ case nsVDPixmap::kPixFormat_YUV410_Planar:
+ case nsVDPixmap::kPixFormat_YUV410_Planar_FR:
+ case nsVDPixmap::kPixFormat_YUV410_Planar_709:
+ case nsVDPixmap::kPixFormat_YUV410_Planar_709_FR:
+ {
+ VDPixmap pxY;
+ VDPixmap pxCb;
+ VDPixmap pxCr;
+
+ pxY.format = nsVDPixmap::kPixFormat_Y8;
+ pxY.data = dst.data;
+ pxY.pitch = dst.pitch;
+ pxY.w = dst.w;
+ pxY.h = dst.h;
+
+ pxCb.format = nsVDPixmap::kPixFormat_Y8;
+ pxCb.data = dst.data2;
+ pxCb.pitch = dst.pitch2;
+ pxCb.w = dst.w;
+ pxCb.h = dst.h;
+
+ pxCr.format = nsVDPixmap::kPixFormat_Y8;
+ pxCr.data = dst.data3;
+ pxCr.pitch = dst.pitch3;
+ pxCr.w = dst.w;
+ pxCr.h = dst.h;
+
+ uint32 colorY = (color >> 8) & 0xff;
+ uint32 colorCb = (color >> 0) & 0xff;
+ uint32 colorCr = (color >> 16) & 0xff;
+
+ VDPixmapFillRegionAntialiased8x(pxY, region, x, y, colorY);
+
+ switch(dst.format) {
+ case nsVDPixmap::kPixFormat_YUV410_Planar:
+ case nsVDPixmap::kPixFormat_YUV410_Planar_FR:
+ case nsVDPixmap::kPixFormat_YUV410_Planar_709:
+ case nsVDPixmap::kPixFormat_YUV410_Planar_709_FR:
+ pxCr.w = pxCb.w = dst.w >> 2;
+ pxCr.h = pxCb.h = dst.h >> 2;
+ x >>= 2;
+ y >>= 2;
+ VDPixmapFillRegionAntialiased_32x_32x(pxCb, region, x, y, colorCb);
+ VDPixmapFillRegionAntialiased_32x_32x(pxCr, region, x, y, colorCr);
+ return true;
+ case nsVDPixmap::kPixFormat_YUV420_Planar:
+ case nsVDPixmap::kPixFormat_YUV420_Planar_FR:
+ case nsVDPixmap::kPixFormat_YUV420_Planar_709:
+ case nsVDPixmap::kPixFormat_YUV420_Planar_709_FR:
+ pxCr.w = pxCb.w = dst.w >> 1;
+ pxCr.h = pxCb.h = dst.h >> 1;
+ x >>= 1;
+ y >>= 1;
+ x += 2;
+ VDPixmapFillRegionAntialiased_16x_16x(pxCb, region, x, y, colorCb);
+ VDPixmapFillRegionAntialiased_16x_16x(pxCr, region, x, y, colorCr);
+ return true;
+ case nsVDPixmap::kPixFormat_YUV422_Planar:
+ case nsVDPixmap::kPixFormat_YUV422_Planar_FR:
+ case nsVDPixmap::kPixFormat_YUV422_Planar_709:
+ case nsVDPixmap::kPixFormat_YUV422_Planar_709_FR:
+ pxCr.w = pxCb.w = dst.w >> 1;
+ x >>= 1;
+ x += 2;
+ VDPixmapFillRegionAntialiased_16x_8x(pxCb, region, x, y, colorCb);
+ VDPixmapFillRegionAntialiased_16x_8x(pxCr, region, x, y, colorCr);
+ return true;
+ case nsVDPixmap::kPixFormat_YUV444_Planar:
+ case nsVDPixmap::kPixFormat_YUV444_Planar_FR:
+ case nsVDPixmap::kPixFormat_YUV444_Planar_709:
+ case nsVDPixmap::kPixFormat_YUV444_Planar_709_FR:
+ VDPixmapFillRegionAntialiased8x(pxCb, region, x, y, colorCb);
+ VDPixmapFillRegionAntialiased8x(pxCr, region, x, y, colorCr);
+ return true;
+ }
}
}
diff --git a/src/thirdparty/VirtualDub/Kasumi/source/resample.cpp b/src/thirdparty/VirtualDub/Kasumi/source/resample.cpp
index 4d1aef5f5..d52fece16 100644
--- a/src/thirdparty/VirtualDub/Kasumi/source/resample.cpp
+++ b/src/thirdparty/VirtualDub/Kasumi/source/resample.cpp
@@ -1,6 +1,6 @@
// VirtualDub - Video processing and capture application
// Graphics support library
-// Copyright (C) 1998-2004 Avery Lee
+// Copyright (C) 1998-2009 Avery Lee
//
// 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
@@ -16,6 +16,7 @@
// along with this program; if not, write to the Free Software
// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+#include <stdafx.h>
#include <float.h>
#include <math.h>
#include <vd2/system/vdalloc.h>
diff --git a/src/thirdparty/VirtualDub/Kasumi/source/resample_kernels.cpp b/src/thirdparty/VirtualDub/Kasumi/source/resample_kernels.cpp
index 010364e1a..86911b325 100644
--- a/src/thirdparty/VirtualDub/Kasumi/source/resample_kernels.cpp
+++ b/src/thirdparty/VirtualDub/Kasumi/source/resample_kernels.cpp
@@ -1,3 +1,22 @@
+// VirtualDub - Video processing and capture application
+// Graphics support library
+// Copyright (C) 1998-2009 Avery Lee
+//
+// 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+#include <stdafx.h>
#include <math.h>
#include <vd2/Kasumi/resample_kernels.h>
@@ -42,6 +61,24 @@ void VDResamplerAxis::Compute(sint32 count, sint32 u0, sint32 w, sint32 kernel_w
dx_postcopy = 0;
dx_dualclip = 0;
+ if (dudx == 0) {
+ if (u < -du_kern)
+ dx_precopy = w;
+ else if (u >= u_limit)
+ dx_postcopy = w;
+ else if (u < 0) {
+ if (u + du_kern < u_limit)
+ dx_preclip = w;
+ else
+ dx_dualclip = w;
+ } else if (u + du_kern >= u_limit)
+ dx_postclip = w;
+ else
+ dx_active = w;
+
+ return;
+ }
+
sint32 dx_temp = dx;
sint32 u_start = u;
diff --git a/src/thirdparty/VirtualDub/Kasumi/source/resample_stages.cpp b/src/thirdparty/VirtualDub/Kasumi/source/resample_stages.cpp
index fcea6c669..15b44273d 100644
--- a/src/thirdparty/VirtualDub/Kasumi/source/resample_stages.cpp
+++ b/src/thirdparty/VirtualDub/Kasumi/source/resample_stages.cpp
@@ -1,3 +1,22 @@
+// VirtualDub - Video processing and capture application
+// Graphics support library
+// Copyright (C) 1998-2009 Avery Lee
+//
+// 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+#include <stdafx.h>
#include <vd2/system/math.h>
#include <vd2/system/vdstl.h>
#include <vd2/Kasumi/resample_kernels.h>
diff --git a/src/thirdparty/VirtualDub/Kasumi/source/resample_stages_reference.cpp b/src/thirdparty/VirtualDub/Kasumi/source/resample_stages_reference.cpp
index 94bee7c9e..72d4e9b79 100644
--- a/src/thirdparty/VirtualDub/Kasumi/source/resample_stages_reference.cpp
+++ b/src/thirdparty/VirtualDub/Kasumi/source/resample_stages_reference.cpp
@@ -1,3 +1,22 @@
+// VirtualDub - Video processing and capture application
+// Graphics support library
+// Copyright (C) 1998-2009 Avery Lee
+//
+// 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+#include <stdafx.h>
#include <vd2/system/memory.h>
#include <vd2/system/cpuaccel.h>
#include <vd2/Kasumi/pixmaputils.h>
diff --git a/src/thirdparty/VirtualDub/Kasumi/source/resample_stages_x86.cpp b/src/thirdparty/VirtualDub/Kasumi/source/resample_stages_x86.cpp
index bc4db574f..123fa17c4 100644
--- a/src/thirdparty/VirtualDub/Kasumi/source/resample_stages_x86.cpp
+++ b/src/thirdparty/VirtualDub/Kasumi/source/resample_stages_x86.cpp
@@ -1,3 +1,22 @@
+// VirtualDub - Video processing and capture application
+// Graphics support library
+// Copyright (C) 1998-2009 Avery Lee
+//
+// 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+#include <stdafx.h>
#include <numeric>
#include "blt_spanutils_x86.h"
#include "resample_stages_x86.h"
@@ -564,7 +583,7 @@ xloop:
void VDResamplerSeparableTableRowStage8MMX::Process(void *dst, const void *src, uint32 w) {
int byteOffset = (int)(ptrdiff_t)src & 3;
- const sint16 *ksrc = &mRowKernels[mRowKernelSize * byteOffset];
+ const sint16 *ksrc = mRowKernels.data() + (mRowKernelSize * byteOffset);
#if 0
int kwidth = mAlignedKernelWidth;
uint8 *dst2 = (uint8 *)dst;
@@ -694,7 +713,7 @@ void VDResamplerSeparableTableRowStage8MMX::Process(void *dst, const void *src,
if (w & 3)
vdasm_resize_table_row_8_MMX((char *)dst + (w & ~3), src, w & 3, ksrc + mTailOffset[byteOffset], ksize);
- } else {
+ } else if (w) {
vdasm_resize_table_row_8_MMX(dst, src, w, ksrc, ksize);
}
#endif
@@ -1197,7 +1216,7 @@ void VDResamplerSeparableTableRowStage8SSE41::RedoRowFilters(const VDResamplerAx
void VDResamplerSeparableTableRowStage8SSE41::Process(void *dst, const void *src, uint32 w) {
int byteOffset = (int)(ptrdiff_t)src & 7;
- const sint16 *ksrc = &mRowKernels[mRowKernelSize * byteOffset];
+ const sint16 *ksrc = mRowKernels.data() + (mRowKernelSize * byteOffset);
int ksize = mKernelSizeByOffset[byteOffset];
if (mbQuadOptimizationEnabled[byteOffset]) {
@@ -1210,7 +1229,7 @@ void VDResamplerSeparableTableRowStage8SSE41::Process(void *dst, const void *src
if (w & 3)
vdasm_resize_table_row_8_SSE41((char *)dst + (w & ~3), src, w & 3, ksrc + mTailOffset[byteOffset], ksize);
- } else {
+ } else if (w) {
vdasm_resize_table_row_8_SSE41(dst, src, w, ksrc, ksize);
}
}
diff --git a/src/thirdparty/VirtualDub/Kasumi/source/stdafx.cpp b/src/thirdparty/VirtualDub/Kasumi/source/stdafx.cpp
new file mode 100644
index 000000000..8eed47b75
--- /dev/null
+++ b/src/thirdparty/VirtualDub/Kasumi/source/stdafx.cpp
@@ -0,0 +1,19 @@
+// VirtualDub - Video processing and capture application
+// Graphics support library
+// Copyright (C) 1998-2009 Avery Lee
+//
+// 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+#include "stdafx.h"
diff --git a/src/thirdparty/VirtualDub/Kasumi/source/stretchblt_reference.cpp b/src/thirdparty/VirtualDub/Kasumi/source/stretchblt_reference.cpp
index 8a57ada41..19d140ee6 100644
--- a/src/thirdparty/VirtualDub/Kasumi/source/stretchblt_reference.cpp
+++ b/src/thirdparty/VirtualDub/Kasumi/source/stretchblt_reference.cpp
@@ -1,3 +1,22 @@
+// VirtualDub - Video processing and capture application
+// Graphics support library
+// Copyright (C) 1998-2009 Avery Lee
+//
+// 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+#include <stdafx.h>
#include <vd2/system/memory.h>
#include <vd2/system/cpuaccel.h>
#include <vd2/Kasumi/pixmap.h>
diff --git a/src/thirdparty/VirtualDub/Kasumi/source/tables.cpp b/src/thirdparty/VirtualDub/Kasumi/source/tables.cpp
index bf1987500..4107ded95 100644
--- a/src/thirdparty/VirtualDub/Kasumi/source/tables.cpp
+++ b/src/thirdparty/VirtualDub/Kasumi/source/tables.cpp
@@ -1,5 +1,6 @@
// Automatically generated by Asuka 'maketables.'" DO NOT EDIT!
+#include <stdafx.h>
#include <vd2/system/vdtypes.h>
extern "C" const sint32 kVDCubicInterpTableFX14_075[256][4]={
diff --git a/src/thirdparty/VirtualDub/Kasumi/source/triblt.cpp b/src/thirdparty/VirtualDub/Kasumi/source/triblt.cpp
index 8fe16138a..bf0752353 100644
--- a/src/thirdparty/VirtualDub/Kasumi/source/triblt.cpp
+++ b/src/thirdparty/VirtualDub/Kasumi/source/triblt.cpp
@@ -1,6 +1,6 @@
// VirtualDub - Video processing and capture application
// Graphics support library
-// Copyright (C) 1998-2008 Avery Lee
+// Copyright (C) 1998-2009 Avery Lee
//
// 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
@@ -16,6 +16,7 @@
// along with this program; if not, write to the Free Software
// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+#include <stdafx.h>
#include <math.h>
#include <vector>
#include <vd2/system/math.h>
@@ -1429,7 +1430,7 @@ bool VDPixmapTriFill(VDPixmap& dst, const uint32 c, const VDTriBltVertex *pVerti
return true;
}
-bool VDPixmapTriFill(VDPixmap& dst, const VDTriColorVertex *pVertices, int nVertices, const int *pIndices, int nIndices, const float pTransform[16]) {
+bool VDPixmapTriFill(VDPixmap& dst, const VDTriColorVertex *pVertices, int nVertices, const int *pIndices, int nIndices, const float pTransform[16], const float *chroma_yoffset) {
VDPixmap pxY;
VDPixmap pxCb;
VDPixmap pxCr;
@@ -1441,9 +1442,21 @@ bool VDPixmapTriFill(VDPixmap& dst, const VDTriColorVertex *pVertices, int nVert
case nsVDPixmap::kPixFormat_Y8:
break;
case nsVDPixmap::kPixFormat_YUV444_Planar:
+ case nsVDPixmap::kPixFormat_YUV444_Planar_FR:
+ case nsVDPixmap::kPixFormat_YUV444_Planar_709:
+ case nsVDPixmap::kPixFormat_YUV444_Planar_709_FR:
case nsVDPixmap::kPixFormat_YUV422_Planar:
+ case nsVDPixmap::kPixFormat_YUV422_Planar_FR:
+ case nsVDPixmap::kPixFormat_YUV422_Planar_709:
+ case nsVDPixmap::kPixFormat_YUV422_Planar_709_FR:
case nsVDPixmap::kPixFormat_YUV420_Planar:
+ case nsVDPixmap::kPixFormat_YUV420_Planar_FR:
+ case nsVDPixmap::kPixFormat_YUV420_Planar_709:
+ case nsVDPixmap::kPixFormat_YUV420_Planar_709_FR:
case nsVDPixmap::kPixFormat_YUV410_Planar:
+ case nsVDPixmap::kPixFormat_YUV410_Planar_FR:
+ case nsVDPixmap::kPixFormat_YUV410_Planar_709:
+ case nsVDPixmap::kPixFormat_YUV410_Planar_709_FR:
pxY.format = nsVDPixmap::kPixFormat_Y8;
pxY.data = dst.data;
pxY.pitch = dst.pitch;
@@ -1453,27 +1466,49 @@ bool VDPixmapTriFill(VDPixmap& dst, const VDTriColorVertex *pVertices, int nVert
pxCb.format = nsVDPixmap::kPixFormat_Y8;
pxCb.data = dst.data2;
pxCb.pitch = dst.pitch2;
+ pxCb.w = dst.w;
pxCb.h = dst.h;
pxCr.format = nsVDPixmap::kPixFormat_Y8;
pxCr.data = dst.data3;
pxCr.pitch = dst.pitch3;
+ pxCr.w = dst.w;
pxCr.h = dst.h;
- if (dst.format == nsVDPixmap::kPixFormat_YUV410_Planar) {
- pxCr.w = pxCb.w = dst.w >> 2;
- pxCr.h = pxCb.h = dst.h >> 2;
- ycbcr_xoffset = 0.75f / (float)pxCr.w;
- } else if (dst.format == nsVDPixmap::kPixFormat_YUV420_Planar) {
- pxCr.w = pxCb.w = dst.w >> 1;
- pxCr.h = pxCb.h = dst.h >> 1;
- ycbcr_xoffset = 0.5f / (float)pxCr.w;
- } else if (dst.format == nsVDPixmap::kPixFormat_YUV422_Planar) {
- pxCr.w = pxCb.w = dst.w >> 1;
- ycbcr_xoffset = 0.5f / (float)pxCr.w;
- } else if (dst.format == nsVDPixmap::kPixFormat_YUV444_Planar) {
- pxCr.w = pxCb.w = dst.w;
- ycbcr_xoffset = 0.0f;
+ switch(dst.format) {
+ case nsVDPixmap::kPixFormat_YUV410_Planar:
+ case nsVDPixmap::kPixFormat_YUV410_Planar_FR:
+ case nsVDPixmap::kPixFormat_YUV410_Planar_709:
+ case nsVDPixmap::kPixFormat_YUV410_Planar_709_FR:
+ pxCr.w = pxCb.w = dst.w >> 2;
+ pxCr.h = pxCb.h = dst.h >> 2;
+ ycbcr_xoffset = 0.75f / (float)pxCr.w;
+ break;
+
+ case nsVDPixmap::kPixFormat_YUV420_Planar:
+ case nsVDPixmap::kPixFormat_YUV420_Planar_FR:
+ case nsVDPixmap::kPixFormat_YUV420_Planar_709:
+ case nsVDPixmap::kPixFormat_YUV420_Planar_709_FR:
+ pxCr.w = pxCb.w = dst.w >> 1;
+ pxCr.h = pxCb.h = dst.h >> 1;
+ ycbcr_xoffset = 0.5f / (float)pxCr.w;
+ break;
+
+ case nsVDPixmap::kPixFormat_YUV422_Planar:
+ case nsVDPixmap::kPixFormat_YUV422_Planar_FR:
+ case nsVDPixmap::kPixFormat_YUV422_Planar_709:
+ case nsVDPixmap::kPixFormat_YUV422_Planar_709_FR:
+ pxCr.w = pxCb.w = dst.w >> 1;
+ ycbcr_xoffset = 0.5f / (float)pxCr.w;
+ break;
+
+ case nsVDPixmap::kPixFormat_YUV444_Planar:
+ case nsVDPixmap::kPixFormat_YUV444_Planar_FR:
+ case nsVDPixmap::kPixFormat_YUV444_Planar_709:
+ case nsVDPixmap::kPixFormat_YUV444_Planar_709_FR:
+ pxCr.w = pxCb.w = dst.w;
+ ycbcr_xoffset = 0.0f;
+ break;
}
ycbcr = true;
@@ -1511,6 +1546,14 @@ bool VDPixmapTriFill(VDPixmap& dst, const VDTriColorVertex *pVertices, int nVert
xf_ycbcr[2] += xf_ycbcr[14]*ycbcr_xoffset;
xf_ycbcr[3] += xf_ycbcr[15]*ycbcr_xoffset;
+ // translate in y by chroma_yoffset
+ if (chroma_yoffset) {
+ xf_ycbcr[4] += xf_ycbcr[12]*(*chroma_yoffset);
+ xf_ycbcr[5] += xf_ycbcr[13]*(*chroma_yoffset);
+ xf_ycbcr[6] += xf_ycbcr[14]*(*chroma_yoffset);
+ xf_ycbcr[7] += xf_ycbcr[15]*(*chroma_yoffset);
+ }
+
TransformVerts(xsrc, pVertices, nVertices, xf_ycbcr);
switch(plane) {
diff --git a/src/thirdparty/VirtualDub/Kasumi/source/uberblit.cpp b/src/thirdparty/VirtualDub/Kasumi/source/uberblit.cpp
index 6dc1b4334..d6caf3707 100644
--- a/src/thirdparty/VirtualDub/Kasumi/source/uberblit.cpp
+++ b/src/thirdparty/VirtualDub/Kasumi/source/uberblit.cpp
@@ -1,7 +1,27 @@
+// VirtualDub - Video processing and capture application
+// Graphics support library
+// Copyright (C) 1998-2009 Avery Lee
+//
+// 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+#include <stdafx.h>
#include <vd2/Kasumi/pixmap.h>
#include <vd2/Kasumi/pixmaputils.h>
#include "uberblit.h"
#include "uberblit_gen.h"
+#include "uberblit_ycbcr_generic.h"
uint32 VDPixmapGetFormatTokenFromFormat(int format) {
using namespace nsVDPixmap;
@@ -29,6 +49,39 @@ uint32 VDPixmapGetFormatTokenFromFormat(int format) {
case kPixFormat_YUV422_V210: return kVDPixType_V210 | kVDPixSamp_422 | kVDPixSpace_YCC_601;
case kPixFormat_YUV422_UYVY_709: return kVDPixType_B8G8_R8G8 | kVDPixSamp_422 | kVDPixSpace_YCC_709;
case kPixFormat_YUV420_NV12: return kVDPixType_8_B8R8 | kVDPixSamp_420_MPEG2 | kVDPixSpace_YCC_601;
+ case kPixFormat_Y8_FR: return kVDPixType_8 | kVDPixSamp_444 | kVDPixSpace_Y_601_FR;
+ case kPixFormat_YUV422_YUYV_709: return kVDPixType_G8B8_G8R8 | kVDPixSamp_422 | kVDPixSpace_YCC_709;
+ case kPixFormat_YUV444_Planar_709: return kVDPixType_8_8_8 | kVDPixSamp_444 | kVDPixSpace_YCC_709;
+ case kPixFormat_YUV422_Planar_709: return kVDPixType_8_8_8 | kVDPixSamp_422 | kVDPixSpace_YCC_709;
+ case kPixFormat_YUV420_Planar_709: return kVDPixType_8_8_8 | kVDPixSamp_420_MPEG2 | kVDPixSpace_YCC_709;
+ case kPixFormat_YUV411_Planar_709: return kVDPixType_8_8_8 | kVDPixSamp_411 | kVDPixSpace_YCC_709;
+ case kPixFormat_YUV410_Planar_709: return kVDPixType_8_8_8 | kVDPixSamp_410 | kVDPixSpace_YCC_709;
+ case kPixFormat_YUV422_UYVY_FR: return kVDPixType_B8G8_R8G8 | kVDPixSamp_422 | kVDPixSpace_YCC_601_FR;
+ case kPixFormat_YUV422_YUYV_FR: return kVDPixType_G8B8_G8R8 | kVDPixSamp_422 | kVDPixSpace_YCC_601_FR;
+ case kPixFormat_YUV444_Planar_FR: return kVDPixType_8_8_8 | kVDPixSamp_444 | kVDPixSpace_YCC_601_FR;
+ case kPixFormat_YUV422_Planar_FR: return kVDPixType_8_8_8 | kVDPixSamp_422 | kVDPixSpace_YCC_601_FR;
+ case kPixFormat_YUV420_Planar_FR: return kVDPixType_8_8_8 | kVDPixSamp_420_MPEG2 | kVDPixSpace_YCC_601_FR;
+ case kPixFormat_YUV411_Planar_FR: return kVDPixType_8_8_8 | kVDPixSamp_411 | kVDPixSpace_YCC_601_FR;
+ case kPixFormat_YUV410_Planar_FR: return kVDPixType_8_8_8 | kVDPixSamp_410 | kVDPixSpace_YCC_601_FR;
+ case kPixFormat_YUV422_UYVY_709_FR: return kVDPixType_B8G8_R8G8 | kVDPixSamp_422 | kVDPixSpace_YCC_709_FR;
+ case kPixFormat_YUV422_YUYV_709_FR: return kVDPixType_G8B8_G8R8 | kVDPixSamp_422 | kVDPixSpace_YCC_709_FR;
+ case kPixFormat_YUV444_Planar_709_FR: return kVDPixType_8_8_8 | kVDPixSamp_444 | kVDPixSpace_YCC_709_FR;
+ case kPixFormat_YUV422_Planar_709_FR: return kVDPixType_8_8_8 | kVDPixSamp_422 | kVDPixSpace_YCC_709_FR;
+ case kPixFormat_YUV420_Planar_709_FR: return kVDPixType_8_8_8 | kVDPixSamp_420_MPEG2 | kVDPixSpace_YCC_709_FR;
+ case kPixFormat_YUV411_Planar_709_FR: return kVDPixType_8_8_8 | kVDPixSamp_411 | kVDPixSpace_YCC_709_FR;
+ case kPixFormat_YUV410_Planar_709_FR: return kVDPixType_8_8_8 | kVDPixSamp_410 | kVDPixSpace_YCC_709_FR;
+ case kPixFormat_YUV420i_Planar: return kVDPixType_8_8_8 | kVDPixSamp_420_MPEG2INT | kVDPixSpace_YCC_601;
+ case kPixFormat_YUV420i_Planar_FR: return kVDPixType_8_8_8 | kVDPixSamp_420_MPEG2INT | kVDPixSpace_YCC_601_FR;
+ case kPixFormat_YUV420i_Planar_709: return kVDPixType_8_8_8 | kVDPixSamp_420_MPEG2INT | kVDPixSpace_YCC_709;
+ case kPixFormat_YUV420i_Planar_709_FR: return kVDPixType_8_8_8 | kVDPixSamp_420_MPEG2INT | kVDPixSpace_YCC_709_FR;
+ case kPixFormat_YUV420it_Planar: return kVDPixType_8_8_8 | kVDPixSamp_420_MPEG2INT1 | kVDPixSpace_YCC_601;
+ case kPixFormat_YUV420it_Planar_FR: return kVDPixType_8_8_8 | kVDPixSamp_420_MPEG2INT1 | kVDPixSpace_YCC_601_FR;
+ case kPixFormat_YUV420it_Planar_709: return kVDPixType_8_8_8 | kVDPixSamp_420_MPEG2INT1 | kVDPixSpace_YCC_709;
+ case kPixFormat_YUV420it_Planar_709_FR: return kVDPixType_8_8_8 | kVDPixSamp_420_MPEG2INT1 | kVDPixSpace_YCC_709_FR;
+ case kPixFormat_YUV420ib_Planar: return kVDPixType_8_8_8 | kVDPixSamp_420_MPEG2INT2 | kVDPixSpace_YCC_601;
+ case kPixFormat_YUV420ib_Planar_FR: return kVDPixType_8_8_8 | kVDPixSamp_420_MPEG2INT2 | kVDPixSpace_YCC_601_FR;
+ case kPixFormat_YUV420ib_Planar_709: return kVDPixType_8_8_8 | kVDPixSamp_420_MPEG2INT2 | kVDPixSpace_YCC_709;
+ case kPixFormat_YUV420ib_Planar_709_FR: return kVDPixType_8_8_8 | kVDPixSamp_420_MPEG2INT2 | kVDPixSpace_YCC_709_FR;
default:
VDASSERT(false);
return 0;
@@ -37,16 +90,18 @@ uint32 VDPixmapGetFormatTokenFromFormat(int format) {
const VDPixmapSamplingInfo& VDPixmapGetSamplingInfo(uint32 samplingToken) {
static const VDPixmapSamplingInfo kPixmapSamplingInfo[]={
- /* Null */ { 0, 0, 0, 0, 0 },
- /* 444 */ { 0, 0, 0, 0, 0 },
- /* 422 */ { -4, 0, 0, 1, 0 },
- /* 422_JPEG */ { 0, 0, 0, 1, 0 },
- /* 420_MPEG2 */ { -4, 0, 0, 1, 1 },
- /* 420_MPEG2INT */ { -4, 0, 0, 1, 1 },
- /* 420_MPEG1 */ { 0, 0, 0, 1, 1 },
- /* 420_DVPAL */ { -4, 0, 0, 1, 1 },
- /* 411 */ { -6, 0, 0, 2, 0 },
- /* 410 */ { -6, 0, 0, 2, 2 }
+ /* Null */ { false, { 0, 0, 0, 0 }, { 0, 0, 0, 0 } },
+ /* 444 */ { false, { 0, 0, 0, 0 }, { 0, 0, 0, 0 } },
+ /* 422 */ { false, { -4, 0, 1, 0 }, { -4, 0, 1, 0 } },
+ /* 422_JPEG */ { false, { 0, 0, 1, 0 }, { 0, 0, 1, 0 } },
+ /* 420_MPEG2 */ { false, { -4, 0, 1, 1 }, { -4, 0, 1, 1 } },
+ /* 420_MPEG2INT */ { true , { -4, -2, 1, 1 }, { -4, -2, 1, 1 }, { -4, +2, 1, 1 }, { -4, +2, 1, 1 } },
+ /* 420_MPEG2INT1*/ { false, { -4, -2, 1, 1 }, { -4, -2, 1, 1 } },
+ /* 420_MPEG2INT2*/ { false, { -4, +2, 1, 1 }, { -4, +2, 1, 1 } },
+ /* 420_MPEG1 */ { false, { 0, 0, 1, 1 }, { 0, 0, 1, 1 } },
+ /* 420_DVPAL */ { true , { -4, 0, 1, 1 }, { -4, 0, 1, 1 } },
+ /* 411 */ { false, { -6, 0, 2, 0 }, { -6, 0, 2, 0 } },
+ /* 410 */ { false, { -6, 0, 2, 2 }, { -6, 0, 2, 2 } },
};
uint32 index = (samplingToken & kVDPixSamp_Mask) >> kVDPixSamp_Bits;
@@ -55,6 +110,43 @@ const VDPixmapSamplingInfo& VDPixmapGetSamplingInfo(uint32 samplingToken) {
}
namespace {
+ uint32 GetChromaPlaneBpr(uint32 w, uint32 srcToken) {
+ switch(srcToken & kVDPixType_Mask) {
+ case kVDPixType_1:
+ case kVDPixType_2:
+ case kVDPixType_4:
+ case kVDPixType_8:
+ case kVDPixType_555_LE:
+ case kVDPixType_565_LE:
+ case kVDPixType_1555_LE:
+ case kVDPixType_16F_LE:
+ case kVDPixType_888:
+ case kVDPixType_8888:
+ case kVDPixType_16Fx4_LE:
+ case kVDPixType_32F_LE:
+ case kVDPixType_32Fx4_LE:
+ case kVDPixType_B8G8_R8G8:
+ case kVDPixType_G8B8_G8R8:
+ case kVDPixType_V210:
+ case kVDPixType_8_B8R8:
+ case kVDPixType_B8R8:
+ default:
+ return 0;
+
+ case kVDPixType_8_8_8:
+ return w;
+
+ case kVDPixType_16F_16F_16F_LE:
+ return w*2;
+
+ case kVDPixType_32F_32F_32F_LE:
+ return w*4;
+ }
+ }
+
+ void BlitterConvertSampling(VDPixmapUberBlitterGenerator& gen, const VDPixmapSamplingInfo& dstInfo, const VDPixmapSamplingInfo& srcInfo, sint32 cw, sint32 ch);
+ void BlitterConvertPlaneSampling(VDPixmapUberBlitterGenerator& gen, const VDPixmapPlaneSamplingInfo& dstInfo, const VDPixmapPlaneSamplingInfo& srcInfo, sint32 cw, sint32 ch);
+
uint32 BlitterConvertSampling(VDPixmapUberBlitterGenerator& gen, uint32 srcToken, uint32 dstSamplingToken, sint32 w, sint32 h) {
// if the source type is 16F, we have to convert to 32F
if ((srcToken & kVDPixType_Mask) == kVDPixType_16F_16F_16F_LE) {
@@ -75,28 +167,176 @@ namespace {
const VDPixmapSamplingInfo& srcInfo = VDPixmapGetSamplingInfo(srcToken);
const VDPixmapSamplingInfo& dstInfo = VDPixmapGetSamplingInfo(dstSamplingToken);
+ // Check if we have an interlacing mismatch. If so, then we have to convert up to
+ // full resolution vertically in order to split or merge fields.
+ const sint32 cw = -(-w >> dstInfo.mPlane1Cr.mXBits);
+ const sint32 ch = -(-h >> dstInfo.mPlane1Cr.mYBits);
+ const uint32 cbpr = GetChromaPlaneBpr(cw, srcToken);
+
+ if (dstInfo.mbInterlaced || srcInfo.mbInterlaced) {
+ const sint32 src_cw = -(-w >> srcInfo.mPlane1Cr.mXBits);
+
+ const sint32 ch1 = (ch + 1) >> 1;
+ const sint32 ch2 = ch >> 1;
+
+ if (dstInfo.mbInterlaced) {
+ if (srcInfo.mbInterlaced) {
+ // interlaced -> interlaced: split fields, resample, merge fields
+ //
+ // cr y cb
+ gen.split_fields(cbpr);
+
+ // cr-odd cr-even y cb
+ BlitterConvertPlaneSampling(gen, dstInfo.mPlane2Cr, srcInfo.mPlane2Cr, cw, ch2);
+
+ // cr-odd' cr-even y cb
+ gen.swap(1);
+
+ // cr-even cr-odd' y cb
+ BlitterConvertPlaneSampling(gen, dstInfo.mPlane1Cr, srcInfo.mPlane1Cr, cw, ch1);
+
+ // cr-even' cr-odd' y cb
+ gen.swap(1);
+
+ // cr-odd' cr-even' y cb
+ gen.merge_fields(cw, ch, cbpr);
+
+ // cr' y cb
+ gen.swap(2);
+
+ // cb' y cr'
+ gen.split_fields(cbpr);
+
+ // cb-odd cb-even y cr'
+ BlitterConvertPlaneSampling(gen, dstInfo.mPlane2Cb, srcInfo.mPlane2Cb, cw, ch2);
+
+ // cb-odd' cb-even y cr'
+ gen.swap(1);
+
+ // cb-even cb-odd' y cr'
+ BlitterConvertPlaneSampling(gen, dstInfo.mPlane1Cb, srcInfo.mPlane1Cb, cw, ch1);
+
+ // cb-even' cb-odd' y cr'
+ gen.swap(1);
+
+ // cb-odd' cb-even' y cr'
+ gen.merge_fields(cw, ch, cbpr);
+
+ // cb' y cr'
+ gen.swap(2);
+
+ // cr' y cb'
+ } else {
+ // non-interlaced -> interlaced
+ VDPixmapPlaneSamplingInfo crPlaneInt(srcInfo.mPlane1Cr);
+ VDPixmapPlaneSamplingInfo crPlaneFieldInt(srcInfo.mPlane1Cr);
+ VDPixmapPlaneSamplingInfo cbPlaneInt(srcInfo.mPlane1Cb);
+ VDPixmapPlaneSamplingInfo cbPlaneFieldInt(srcInfo.mPlane1Cb);
+
+ crPlaneInt.mX = dstInfo.mPlane1Cr.mX;
+ crPlaneInt.mXBits = dstInfo.mPlane1Cr.mXBits;
+ crPlaneInt.mY = 0;
+ crPlaneInt.mYBits = 0;
+ crPlaneFieldInt.mX = dstInfo.mPlane1Cr.mX;
+ crPlaneFieldInt.mXBits = dstInfo.mPlane1Cr.mXBits;
+ crPlaneFieldInt.mY = 0;
+ crPlaneFieldInt.mYBits = 0;
+
+ cbPlaneInt.mX = dstInfo.mPlane1Cb.mX;
+ cbPlaneInt.mXBits = dstInfo.mPlane1Cb.mXBits;
+ cbPlaneFieldInt.mX = dstInfo.mPlane1Cb.mX;
+ cbPlaneFieldInt.mXBits = dstInfo.mPlane1Cb.mXBits;
+ cbPlaneFieldInt.mY = 0;
+ cbPlaneFieldInt.mYBits = 0;
+
+ // cr y cb
+ BlitterConvertPlaneSampling(gen, crPlaneInt, srcInfo.mPlane1Cr, cw, h);
+
+ // cr' y cb
+ gen.split_fields(cbpr);
+ BlitterConvertPlaneSampling(gen, dstInfo.mPlane1Cr, crPlaneFieldInt, cw, ch1);
+ gen.swap(1);
+ BlitterConvertPlaneSampling(gen, dstInfo.mPlane2Cr, crPlaneFieldInt, cw, ch2);
+ gen.swap(1);
+ gen.merge_fields(cw, ch, cbpr);
+
+ gen.swap(2);
+ BlitterConvertPlaneSampling(gen, cbPlaneInt, srcInfo.mPlane1Cb, cw, h);
+ gen.split_fields(cbpr);
+ gen.swap(1);
+ BlitterConvertPlaneSampling(gen, dstInfo.mPlane1Cb, cbPlaneFieldInt, cw, ch1);
+ gen.swap(1);
+ BlitterConvertPlaneSampling(gen, dstInfo.mPlane1Cb, cbPlaneFieldInt, cw, ch2);
+ gen.merge_fields(cw, ch, cbpr);
+ gen.swap(2);
+ }
+ } else {
+ sint32 src_cbpr = src_cw;
+
+ // interlaced -> non-interlaced
+ VDPixmapPlaneSamplingInfo crPlaneFieldInt(srcInfo.mPlane1Cr);
+ VDPixmapPlaneSamplingInfo crPlaneInt(srcInfo.mPlane1Cr);
+ VDPixmapPlaneSamplingInfo cbPlaneFieldInt(srcInfo.mPlane1Cb);
+ VDPixmapPlaneSamplingInfo cbPlaneInt(srcInfo.mPlane1Cb);
+
+ crPlaneFieldInt.mY = 0;
+ crPlaneFieldInt.mYBits = 0;
+ crPlaneInt.mY = 0;
+ crPlaneInt.mYBits = 0;
+ cbPlaneFieldInt.mY = 0;
+ cbPlaneFieldInt.mYBits = 0;
+ cbPlaneInt.mY = 0;
+ cbPlaneInt.mYBits = 0;
+
+ // cr y cb
+ gen.split_fields(src_cbpr);
+ BlitterConvertPlaneSampling(gen, crPlaneFieldInt, srcInfo.mPlane1Cr, src_cw, (h + 1) >> 1);
+ gen.swap(1);
+ BlitterConvertPlaneSampling(gen, crPlaneFieldInt, srcInfo.mPlane2Cr, src_cw, h >> 1);
+ gen.swap(1);
+ gen.merge_fields(src_cw, h, src_cbpr);
+ BlitterConvertPlaneSampling(gen, dstInfo.mPlane1Cr, crPlaneInt, cw, ch);
+ gen.swap(2);
+
+ // cr' y cb
+ gen.split_fields(src_cbpr);
+ BlitterConvertPlaneSampling(gen, cbPlaneFieldInt, srcInfo.mPlane1Cb, src_cw, (h + 1) >> 1);
+ gen.swap(1);
+ BlitterConvertPlaneSampling(gen, cbPlaneFieldInt, srcInfo.mPlane2Cb, src_cw, h >> 1);
+ gen.swap(1);
+ gen.merge_fields(src_cw, h, src_cbpr);
+ BlitterConvertPlaneSampling(gen, dstInfo.mPlane1Cb, cbPlaneInt, cw, ch);
+ gen.swap(2);
+ }
+ } else {
+ // non-interlaced -> non-interlaced
+ BlitterConvertSampling(gen, dstInfo, srcInfo, cw, ch);
+ }
+
+ return (srcToken & ~kVDPixSamp_Mask) | (dstSamplingToken & kVDPixSamp_Mask);
+ }
+
+ void BlitterConvertSampling(VDPixmapUberBlitterGenerator& gen, const VDPixmapSamplingInfo& dstInfo, const VDPixmapSamplingInfo& srcInfo, sint32 cw, sint32 ch) {
+ gen.swap(2);
+ BlitterConvertPlaneSampling(gen, dstInfo.mPlane1Cb, srcInfo.mPlane1Cb, cw, ch);
+ gen.swap(2);
+ BlitterConvertPlaneSampling(gen, dstInfo.mPlane1Cr, srcInfo.mPlane1Cr, cw, ch);
+ }
+
+ void BlitterConvertPlaneSampling(VDPixmapUberBlitterGenerator& gen, const VDPixmapPlaneSamplingInfo& dstInfo, const VDPixmapPlaneSamplingInfo& srcInfo, sint32 cw, sint32 ch) {
// convert destination chroma origin to luma space
- int c_x = ((8 + dstInfo.mCXOffset16) << dstInfo.mCXBits) - 8;
- int cr_y = ((8 + dstInfo.mCrYOffset16) << dstInfo.mCYBits) - 8;
- int cb_y = ((8 + dstInfo.mCbYOffset16) << dstInfo.mCYBits) - 8;
+ int c_x = ((8 + dstInfo.mX) << dstInfo.mXBits) - 8;
+ int c_y = ((8 + dstInfo.mY) << dstInfo.mYBits) - 8;
// convert luma chroma location to source chroma space
- c_x = ((8 + c_x) >> srcInfo.mCXBits) - 8 - srcInfo.mCXOffset16;
- cr_y = ((8 + cr_y) >> srcInfo.mCYBits) - 8 - srcInfo.mCrYOffset16;
- cb_y = ((8 + cb_y) >> srcInfo.mCYBits) - 8 - srcInfo.mCbYOffset16;
+ c_x = ((8 + c_x) >> srcInfo.mXBits) - 8 - srcInfo.mX;
+ c_y = ((8 + c_y) >> srcInfo.mYBits) - 8 - srcInfo.mY;
float cxo = c_x / 16.0f + 0.5f;
- float cxf = ((16 << dstInfo.mCXBits) >> srcInfo.mCXBits) / 16.0f;
- float cyf = ((16 << dstInfo.mCYBits) >> srcInfo.mCYBits) / 16.0f;
- sint32 cw = -(-w >> dstInfo.mCXBits);
- sint32 ch = -(-h >> dstInfo.mCYBits);
-
- gen.swap(2);
- gen.linear(cxo, cxf, cw, cb_y / 16.0f + 0.5f, cyf, ch);
- gen.swap(2);
- gen.linear(cxo, cxf, cw, cr_y / 16.0f + 0.5f, cyf, ch);
+ float cxf = ((16 << dstInfo.mXBits) >> srcInfo.mXBits) / 16.0f;
+ float cyf = ((16 << dstInfo.mYBits) >> srcInfo.mYBits) / 16.0f;
- return (srcToken & ~kVDPixSamp_Mask) | (dstSamplingToken & kVDPixSamp_Mask);
+ gen.linear(cxo, cxf, cw, c_y / 16.0f + 0.5f, cyf, ch);
}
uint32 BlitterConvertType(VDPixmapUberBlitterGenerator& gen, uint32 srcToken, uint32 dstToken, sint32 w, sint32 h) {
@@ -257,8 +497,8 @@ namespace {
case kVDPixType_8_B8R8:
{
const VDPixmapSamplingInfo& sampInfo = VDPixmapGetSamplingInfo(srcToken);
- int cw = -(-w >> sampInfo.mCXBits);
- int ch = -(-h >> sampInfo.mCYBits);
+ int cw = -(-w >> sampInfo.mPlane1Cr.mXBits);
+ int ch = -(-h >> sampInfo.mPlane1Cr.mYBits);
gen.dup();
gen.extract_8in16(1, cw, ch);
@@ -284,7 +524,7 @@ namespace {
srcToken = (srcToken & ~(kVDPixType_Mask | kVDPixSamp_Mask)) | kVDPixType_B8G8_R8G8;
break;
case kVDPixType_G8B8_G8R8:
- gen.swap_8in16(w, h, w*2);
+ gen.swap_8in16(w, h, ((w + 1) & ~1)*2);
srcToken = (srcToken & ~(kVDPixType_Mask | kVDPixSamp_Mask)) | kVDPixType_B8G8_R8G8;
break;
default:
@@ -303,7 +543,7 @@ namespace {
srcToken = (srcToken & ~(kVDPixType_Mask | kVDPixSamp_Mask)) | kVDPixType_G8B8_G8R8;
break;
case kVDPixType_B8G8_R8G8:
- gen.swap_8in16(w, h, w*2);
+ gen.swap_8in16(w, h, ((w + 1) & ~1)*2);
srcToken = (srcToken & ~(kVDPixType_Mask | kVDPixSamp_Mask)) | kVDPixType_G8B8_G8R8;
break;
default:
@@ -521,12 +761,12 @@ IVDPixmapBlitter *VDPixmapCreateBlitter(const VDPixmapLayout& dst, const VDPixma
const VDPixmapSamplingInfo& sampInfo = VDPixmapGetSamplingInfo(srcToken);
- int cxbits = sampInfo.mCXBits;
- int cybits = sampInfo.mCYBits;
+ int cxbits = sampInfo.mPlane1Cb.mXBits;
+ int cybits = sampInfo.mPlane1Cb.mYBits;
int w2 = -(-w >> cxbits);
int h2 = -(-h >> cybits);
gen.ldsrc(0, 2, 0, 0, w2, h2, cbtoken, w2);
- gen.ldsrc(0, 0, 0, 0, w, h, srcToken, w);
+ gen.ldsrc(0, 0, 0, 0, w, h, ytoken, w);
gen.ldsrc(0, 1, 0, 0, w2, h2, crtoken, w2);
}
break;
@@ -539,12 +779,12 @@ IVDPixmapBlitter *VDPixmapCreateBlitter(const VDPixmapLayout& dst, const VDPixma
const VDPixmapSamplingInfo& sampInfo = VDPixmapGetSamplingInfo(srcToken);
- int cxbits = sampInfo.mCXBits;
- int cybits = sampInfo.mCYBits;
+ int cxbits = sampInfo.mPlane1Cb.mXBits;
+ int cybits = sampInfo.mPlane1Cb.mYBits;
int w2 = -(-w >> cxbits);
int h2 = -(-h >> cybits);
gen.ldsrc(0, 2, 0, 0, w2, h2, cbtoken, w2 * 2);
- gen.ldsrc(0, 0, 0, 0, w, h, srcToken, w*2);
+ gen.ldsrc(0, 0, 0, 0, w, h, ytoken, w*2);
gen.ldsrc(0, 1, 0, 0, w2, h2, crtoken, w2 * 2);
}
break;
@@ -557,12 +797,12 @@ IVDPixmapBlitter *VDPixmapCreateBlitter(const VDPixmapLayout& dst, const VDPixma
const VDPixmapSamplingInfo& sampInfo = VDPixmapGetSamplingInfo(srcToken);
- int cxbits = sampInfo.mCXBits;
- int cybits = sampInfo.mCYBits;
+ int cxbits = sampInfo.mPlane1Cb.mXBits;
+ int cybits = sampInfo.mPlane1Cb.mYBits;
int w2 = -(-w >> cxbits);
int h2 = -(-h >> cybits);
gen.ldsrc(0, 2, 0, 0, w2, h2, cbtoken, w2 * 4);
- gen.ldsrc(0, 0, 0, 0, w, h, srcToken, w*4);
+ gen.ldsrc(0, 0, 0, 0, w, h, ytoken, w*4);
gen.ldsrc(0, 1, 0, 0, w2, h2, crtoken, w2 * 4);
}
break;
@@ -578,11 +818,11 @@ IVDPixmapBlitter *VDPixmapCreateBlitter(const VDPixmapLayout& dst, const VDPixma
const VDPixmapSamplingInfo& sampInfo = VDPixmapGetSamplingInfo(srcToken);
- int cxbits = sampInfo.mCXBits;
- int cybits = sampInfo.mCYBits;
+ int cxbits = sampInfo.mPlane1Cb.mXBits;
+ int cybits = sampInfo.mPlane1Cb.mYBits;
int w2 = -(-w >> cxbits);
int h2 = -(-h >> cybits);
- gen.ldsrc(0, 0, 0, 0, w, h, srcToken, w);
+ gen.ldsrc(0, 0, 0, 0, w, h, ytoken, w);
gen.ldsrc(0, 1, 0, 0, w2, h2, ctoken, w2*2);
}
break;
@@ -636,10 +876,29 @@ IVDPixmapBlitter *VDPixmapCreateBlitter(const VDPixmapLayout& dst, const VDPixma
// the auxiliary channels
const VDPixmapSamplingInfo& sampInfo = VDPixmapGetSamplingInfo(srcToken);
- if ((dstToken & kVDPixSpace_Mask) != kVDPixSpace_Y_601 && (dstToken & kVDPixSpace_Mask) != kVDPixSpace_Y_709) {
- if (sampInfo.mCXBits | sampInfo.mCYBits | sampInfo.mCXOffset16 | sampInfo.mCbYOffset16 | sampInfo.mCrYOffset16)
- srcToken = BlitterConvertSampling(gen, srcToken, kVDPixSamp_444, w, h);
+#if 0
+ // This check is currently disabled because we currently do need the chroma planes
+ // if we're doing a color space conversion, even if we are going to Y-only.
+ switch(dstToken & kVDPixSpace_Mask) {
+// case kVDPixSpace_Y_601:
+// case kVDPixSpace_Y_709:
+// case kVDPixSpace_Y_601_FR:
+// case kVDPixSpace_Y_709_FR:
+// break;
+
+ default:
+#endif
+ if (sampInfo.mPlane1Cb.mXBits |
+ sampInfo.mPlane1Cb.mYBits |
+ sampInfo.mPlane1Cb.mX |
+ sampInfo.mPlane1Cb.mY |
+ sampInfo.mPlane1Cr.mX |
+ sampInfo.mPlane1Cr.mY)
+ srcToken = BlitterConvertSampling(gen, srcToken, kVDPixSamp_444, w, h);
+#if 0
+ break;
}
+#endif
// change color spaces
uint32 dstSpace = dstToken & kVDPixSpace_Mask;
@@ -699,10 +958,48 @@ space_reconvert:
}
break;
+ case kVDPixSpace_YCC_709_FR:
+ switch(srcToken & kVDPixType_Mask) {
+ case kVDPixType_8_8_8:
+ gen.ycbcr_to_rgb32_generic(g_VDPixmapGenYCbCrBasis_709, false);
+ srcToken = (srcToken & ~(kVDPixType_Mask | kVDPixSpace_Mask)) | kVDPixSpace_BGR | kVDPixType_8888;
+ break;
+
+ default:
+ VDASSERT(false);
+ break;
+ }
+ break;
+
+ case kVDPixSpace_YCC_601_FR:
+ switch(srcToken & kVDPixType_Mask) {
+ case kVDPixType_8_8_8:
+ gen.ycbcr_to_rgb32_generic(g_VDPixmapGenYCbCrBasis_601, false);
+ srcToken = (srcToken & ~(kVDPixType_Mask | kVDPixSpace_Mask)) | kVDPixSpace_BGR | kVDPixType_8888;
+ break;
+
+ default:
+ VDASSERT(false);
+ break;
+ }
+ break;
+
case kVDPixSpace_Y_601:
targetSpace = kVDPixSpace_YCC_601;
goto space_reconvert;
+ case kVDPixSpace_Y_709:
+ targetSpace = kVDPixSpace_YCC_709;
+ goto space_reconvert;
+
+ case kVDPixSpace_Y_601_FR:
+ targetSpace = kVDPixSpace_YCC_601_FR;
+ goto space_reconvert;
+
+ case kVDPixSpace_Y_709_FR:
+ targetSpace = kVDPixSpace_YCC_709_FR;
+ goto space_reconvert;
+
case kVDPixSpace_Pal:
switch(srcToken & kVDPixType_Mask) {
case kVDPixType_1:
@@ -736,49 +1033,123 @@ space_reconvert:
break;
}
break;
+
case kVDPixSpace_Y_601:
- if (srcSpace == kVDPixSpace_YCC_601) {
- gen.pop();
- gen.swap(1);
- gen.pop();
- switch(srcToken & kVDPixType_Mask) {
- case kVDPixType_32F_32F_32F_LE:
- srcToken = (srcToken & ~(kVDPixType_Mask | kVDPixSpace_Mask)) | kVDPixSpace_Y_601 | kVDPixType_32F_LE;
- break;
- case kVDPixType_16F_16F_16F_LE:
- srcToken = (srcToken & ~(kVDPixType_Mask | kVDPixSpace_Mask)) | kVDPixSpace_Y_601 | kVDPixType_16F_LE;
- break;
- case kVDPixType_8_8_8:
- srcToken = (srcToken & ~(kVDPixType_Mask | kVDPixSpace_Mask)) | kVDPixSpace_Y_601 | kVDPixType_8;
- break;
+ switch(srcSpace) {
+ case kVDPixSpace_YCC_601:
+ gen.pop();
+ gen.swap(1);
+ gen.pop();
+ switch(srcToken & kVDPixType_Mask) {
+ case kVDPixType_32F_32F_32F_LE:
+ srcToken = (srcToken & ~(kVDPixType_Mask | kVDPixSpace_Mask)) | targetSpace | kVDPixType_32F_LE;
+ break;
+ case kVDPixType_16F_16F_16F_LE:
+ srcToken = (srcToken & ~(kVDPixType_Mask | kVDPixSpace_Mask)) | targetSpace | kVDPixType_16F_LE;
+ break;
+ case kVDPixType_8_8_8:
+ srcToken = (srcToken & ~(kVDPixType_Mask | kVDPixSpace_Mask)) | targetSpace | kVDPixType_8;
+ break;
+
+ default:
+ VDASSERT(false);
+ }
+ srcToken = BlitterConvertType(gen, srcToken, kVDPixType_8, w, h);
+ break;
- default:
- VDASSERT(false);
- }
- srcToken = BlitterConvertType(gen, srcToken, kVDPixType_8, w, h);
- break;
- } else if (srcSpace == kVDPixSpace_YCC_709) {
- gen.pop();
- gen.swap(1);
- gen.pop();
- switch(srcToken & kVDPixType_Mask) {
- case kVDPixType_32F_32F_32F_LE:
- srcToken = (srcToken & ~(kVDPixType_Mask | kVDPixSpace_Mask)) | kVDPixSpace_Y_709 | kVDPixType_32F_LE;
- break;
- case kVDPixType_16F_16F_16F_LE:
- srcToken = (srcToken & ~(kVDPixType_Mask | kVDPixSpace_Mask)) | kVDPixSpace_Y_709 | kVDPixType_16F_LE;
- break;
- case kVDPixType_8_8_8:
- srcToken = (srcToken & ~(kVDPixType_Mask | kVDPixSpace_Mask)) | kVDPixSpace_Y_709 | kVDPixType_8;
- break;
+ default:
+ targetSpace = kVDPixSpace_YCC_601;
+ goto space_reconvert;
+ }
+ break;
- default:
- VDASSERT(false);
- }
- srcToken = BlitterConvertType(gen, srcToken, kVDPixType_8, w, h);
- break;
+ case kVDPixSpace_Y_601_FR:
+ switch(srcSpace) {
+ case kVDPixSpace_YCC_601_FR:
+ gen.pop();
+ gen.swap(1);
+ gen.pop();
+ switch(srcToken & kVDPixType_Mask) {
+ case kVDPixType_32F_32F_32F_LE:
+ srcToken = (srcToken & ~(kVDPixType_Mask | kVDPixSpace_Mask)) | targetSpace | kVDPixType_32F_LE;
+ break;
+ case kVDPixType_16F_16F_16F_LE:
+ srcToken = (srcToken & ~(kVDPixType_Mask | kVDPixSpace_Mask)) | targetSpace | kVDPixType_16F_LE;
+ break;
+ case kVDPixType_8_8_8:
+ srcToken = (srcToken & ~(kVDPixType_Mask | kVDPixSpace_Mask)) | targetSpace | kVDPixType_8;
+ break;
+
+ default:
+ VDASSERT(false);
+ }
+ srcToken = BlitterConvertType(gen, srcToken, kVDPixType_8, w, h);
+ break;
+
+ default:
+ targetSpace = kVDPixSpace_YCC_601_FR;
+ goto space_reconvert;
+ }
+ break;
+
+ case kVDPixSpace_Y_709:
+ switch(srcSpace) {
+ case kVDPixSpace_YCC_709:
+ gen.pop();
+ gen.swap(1);
+ gen.pop();
+ switch(srcToken & kVDPixType_Mask) {
+ case kVDPixType_32F_32F_32F_LE:
+ srcToken = (srcToken & ~(kVDPixType_Mask | kVDPixSpace_Mask)) | targetSpace | kVDPixType_32F_LE;
+ break;
+ case kVDPixType_16F_16F_16F_LE:
+ srcToken = (srcToken & ~(kVDPixType_Mask | kVDPixSpace_Mask)) | targetSpace | kVDPixType_16F_LE;
+ break;
+ case kVDPixType_8_8_8:
+ srcToken = (srcToken & ~(kVDPixType_Mask | kVDPixSpace_Mask)) | targetSpace | kVDPixType_8;
+ break;
+
+ default:
+ VDASSERT(false);
+ }
+ srcToken = BlitterConvertType(gen, srcToken, kVDPixType_8, w, h);
+ break;
+
+ default:
+ targetSpace = kVDPixSpace_YCC_709;
+ goto space_reconvert;
}
- // fall through
+ break;
+
+ case kVDPixSpace_Y_709_FR:
+ switch(srcSpace) {
+ case kVDPixSpace_YCC_709_FR:
+ gen.pop();
+ gen.swap(1);
+ gen.pop();
+ switch(srcToken & kVDPixType_Mask) {
+ case kVDPixType_32F_32F_32F_LE:
+ srcToken = (srcToken & ~(kVDPixType_Mask | kVDPixSpace_Mask)) | targetSpace | kVDPixType_32F_LE;
+ break;
+ case kVDPixType_16F_16F_16F_LE:
+ srcToken = (srcToken & ~(kVDPixType_Mask | kVDPixSpace_Mask)) | targetSpace | kVDPixType_16F_LE;
+ break;
+ case kVDPixType_8_8_8:
+ srcToken = (srcToken & ~(kVDPixType_Mask | kVDPixSpace_Mask)) | targetSpace | kVDPixType_8;
+ break;
+
+ default:
+ VDASSERT(false);
+ }
+ srcToken = BlitterConvertType(gen, srcToken, kVDPixType_8, w, h);
+ break;
+
+ default:
+ targetSpace = kVDPixSpace_YCC_709_FR;
+ goto space_reconvert;
+ }
+ break;
+
case kVDPixSpace_YCC_601:
switch(srcSpace) {
case kVDPixSpace_BGR:
@@ -791,9 +1162,9 @@ space_reconvert:
srcToken = (srcToken & ~(kVDPixType_Mask | kVDPixSpace_Mask)) | kVDPixSpace_YCC_601 | kVDPixType_8;
{
- const VDPixmapSamplingInfo& sinfo = VDPixmapGetSamplingInfo(dstToken);
- int cw = ((w - 1) >> sinfo.mCXBits) + 1;
- int ch = ((h - 1) >> sinfo.mCYBits) + 1;
+ const VDPixmapSamplingInfo& sinfo = VDPixmapGetSamplingInfo(srcToken);
+ int cw = ((w - 1) >> sinfo.mPlane1Cb.mXBits) + 1;
+ int ch = ((h - 1) >> sinfo.mPlane1Cb.mYBits) + 1;
gen.ldconst(0x80, cw, cw, ch, srcToken);
}
@@ -801,14 +1172,51 @@ space_reconvert:
gen.dup();
gen.swap(2);
gen.swap(1);
- srcToken = kVDPixSpace_YCC_601 | kVDPixType_8_8_8 | (dstToken & kVDPixSamp_Mask);
+ srcToken = kVDPixSpace_YCC_601 | kVDPixType_8_8_8 | (srcToken & kVDPixSamp_Mask);
break;
+
+ case kVDPixSpace_Y_601_FR:
+ targetSpace = kVDPixSpace_YCC_601_FR;
+ goto space_reconvert;
+
+ case kVDPixSpace_Y_709_FR:
+ targetSpace = kVDPixSpace_YCC_709_FR;
+ goto space_reconvert;
+
case kVDPixSpace_YCC_709:
VDASSERT((srcToken & kVDPixType_Mask) == kVDPixType_8_8_8);
gen.ycbcr709_to_ycbcr601();
srcToken = (srcToken & ~kVDPixSpace_Mask) | kVDPixSpace_YCC_601;
break;
+ case kVDPixSpace_YCC_601_FR:
+ switch(srcToken & kVDPixType_Mask) {
+ case kVDPixType_8_8_8:
+ case kVDPixType_32F_32F_32F_LE:
+ gen.ycbcr_to_ycbcr_generic(g_VDPixmapGenYCbCrBasis_601, true, g_VDPixmapGenYCbCrBasis_601, false, kVDPixSpace_YCC_601);
+ srcToken = (srcToken & ~kVDPixSpace_Mask) | kVDPixSpace_YCC_601;
+ break;
+
+ default:
+ VDASSERT(false);
+ break;
+ }
+ break;
+
+ case kVDPixSpace_YCC_709_FR:
+ switch(srcToken & kVDPixType_Mask) {
+ case kVDPixType_8_8_8:
+ case kVDPixType_32F_32F_32F_LE:
+ gen.ycbcr_to_ycbcr_generic(g_VDPixmapGenYCbCrBasis_601, true, g_VDPixmapGenYCbCrBasis_709, false, kVDPixSpace_YCC_601);
+ srcToken = (srcToken & ~kVDPixSpace_Mask) | kVDPixSpace_YCC_601;
+ break;
+
+ default:
+ VDASSERT(false);
+ break;
+ }
+ break;
+
case kVDPixSpace_Pal:
targetSpace = kVDPixSpace_BGR;
goto space_reconvert;
@@ -818,6 +1226,7 @@ space_reconvert:
break;
}
break;
+
case kVDPixSpace_YCC_709:
switch(srcSpace) {
case kVDPixSpace_BGR:
@@ -825,14 +1234,14 @@ space_reconvert:
gen.rgb32_to_ycbcr709();
srcToken = (srcToken & ~(kVDPixType_Mask | kVDPixSpace_Mask)) | kVDPixSpace_YCC_709 | kVDPixType_8_8_8;
break;
- case kVDPixSpace_Y_709:
case kVDPixSpace_Y_601:
+ case kVDPixSpace_Y_709:
srcToken = (srcToken & ~(kVDPixType_Mask | kVDPixSpace_Mask)) | kVDPixSpace_YCC_709 | kVDPixType_8;
{
- const VDPixmapSamplingInfo& sinfo = VDPixmapGetSamplingInfo(dstToken);
- int cw = ((w - 1) >> sinfo.mCXBits) + 1;
- int ch = ((h - 1) >> sinfo.mCYBits) + 1;
+ const VDPixmapSamplingInfo& sinfo = VDPixmapGetSamplingInfo(srcToken);
+ int cw = ((w - 1) >> sinfo.mPlane1Cb.mXBits) + 1;
+ int ch = ((h - 1) >> sinfo.mPlane1Cb.mYBits) + 1;
gen.ldconst(0x80, cw, cw, ch, srcToken);
}
@@ -840,22 +1249,126 @@ space_reconvert:
gen.dup();
gen.swap(2);
gen.swap(1);
- srcToken = kVDPixSpace_YCC_709 | kVDPixType_8_8_8 | (dstToken & kVDPixSamp_Mask);
+ srcToken = kVDPixSpace_YCC_709 | kVDPixType_8_8_8 | (srcToken & kVDPixSamp_Mask);
break;
case kVDPixSpace_YCC_601:
- VDASSERT((srcToken & kVDPixType_Mask) == kVDPixType_8_8_8 || (srcToken & kVDPixType_Mask) == kVDPixType_32F_32F_32F_LE);
- gen.ycbcr601_to_ycbcr709();
+ if ((srcToken & kVDPixType_Mask) == kVDPixType_8_8_8)
+ gen.ycbcr601_to_ycbcr709();
+ else
+ gen.ycbcr_to_ycbcr_generic(g_VDPixmapGenYCbCrBasis_709, true, g_VDPixmapGenYCbCrBasis_601, true, kVDPixSpace_YCC_709);
+
srcToken = (srcToken & ~kVDPixSpace_Mask) | kVDPixSpace_YCC_709;
break;
+
+ case kVDPixSpace_YCC_601_FR:
+ switch(srcToken & kVDPixType_Mask) {
+ case kVDPixType_8_8_8:
+ case kVDPixType_32F_32F_32F_LE:
+ gen.ycbcr_to_ycbcr_generic(g_VDPixmapGenYCbCrBasis_709, true, g_VDPixmapGenYCbCrBasis_601, false, kVDPixSpace_YCC_709);
+ srcToken = (srcToken & ~kVDPixSpace_Mask) | kVDPixSpace_YCC_709;
+ break;
+
+ default:
+ VDASSERT(false);
+ break;
+ }
+ break;
+
+ case kVDPixSpace_YCC_709_FR:
+ switch(srcToken & kVDPixType_Mask) {
+ case kVDPixType_8_8_8:
+ case kVDPixType_32F_32F_32F_LE:
+ gen.ycbcr_to_ycbcr_generic(g_VDPixmapGenYCbCrBasis_709, true, g_VDPixmapGenYCbCrBasis_709, false, kVDPixSpace_YCC_709);
+ srcToken = (srcToken & ~kVDPixSpace_Mask) | kVDPixSpace_YCC_709;
+ break;
+
+ default:
+ VDASSERT(false);
+ break;
+ }
+ break;
+
+ case kVDPixSpace_Y_601_FR:
+ targetSpace = kVDPixSpace_YCC_601_FR;
+ goto space_reconvert;
+
+ case kVDPixSpace_Y_709_FR:
+ targetSpace = kVDPixSpace_YCC_709_FR;
+ goto space_reconvert;
+
case kVDPixSpace_Pal:
targetSpace = kVDPixSpace_BGR;
goto space_reconvert;
+
default:
VDASSERT(false);
break;
}
break;
+ case kVDPixSpace_YCC_601_FR:
+ case kVDPixSpace_YCC_709_FR:
+ {
+ const VDPixmapGenYCbCrBasis& dstBasis = *(targetSpace == kVDPixSpace_YCC_601_FR ? &g_VDPixmapGenYCbCrBasis_601 : &g_VDPixmapGenYCbCrBasis_709);
+
+ switch(srcSpace) {
+ case kVDPixSpace_BGR:
+ srcToken = BlitterConvertType(gen, srcToken, kVDPixType_8888, w, h);
+ gen.rgb32_to_ycbcr_generic(dstBasis, false, targetSpace);
+ srcToken = (srcToken & ~(kVDPixType_Mask | kVDPixSpace_Mask)) | targetSpace | kVDPixType_8_8_8;
+ break;
+ case kVDPixSpace_Y_601_FR:
+ case kVDPixSpace_Y_709_FR:
+ srcToken = (srcToken & ~(kVDPixType_Mask | kVDPixSpace_Mask)) | targetSpace | kVDPixType_8;
+
+ {
+ const VDPixmapSamplingInfo& sinfo = VDPixmapGetSamplingInfo(srcToken);
+ int cw = ((w - 1) >> sinfo.mPlane1Cb.mXBits) + 1;
+ int ch = ((h - 1) >> sinfo.mPlane1Cb.mYBits) + 1;
+
+ gen.ldconst(0x80, cw, cw, ch, srcToken);
+ }
+
+ gen.dup();
+ gen.swap(2);
+ gen.swap(1);
+ srcToken = (srcToken & ~kVDPixType_Mask) | kVDPixType_8_8_8;
+ break;
+ case kVDPixSpace_YCC_601:
+ gen.ycbcr_to_ycbcr_generic(dstBasis, false, g_VDPixmapGenYCbCrBasis_601, true, targetSpace);
+ srcToken = (srcToken & ~kVDPixSpace_Mask) | targetSpace;
+ break;
+ case kVDPixSpace_YCC_709:
+ gen.ycbcr_to_ycbcr_generic(dstBasis, false, g_VDPixmapGenYCbCrBasis_709, true, targetSpace);
+ srcToken = (srcToken & ~kVDPixSpace_Mask) | targetSpace;
+ break;
+ case kVDPixSpace_YCC_601_FR:
+ gen.ycbcr_to_ycbcr_generic(dstBasis, false, g_VDPixmapGenYCbCrBasis_601, false, targetSpace);
+ srcToken = (srcToken & ~kVDPixSpace_Mask) | targetSpace;
+ break;
+ case kVDPixSpace_YCC_709_FR:
+ gen.ycbcr_to_ycbcr_generic(dstBasis, false, g_VDPixmapGenYCbCrBasis_709, false, targetSpace);
+ srcToken = (srcToken & ~kVDPixSpace_Mask) | targetSpace;
+ break;
+ case kVDPixSpace_Pal:
+ targetSpace = kVDPixSpace_BGR;
+ goto space_reconvert;
+
+ case kVDPixSpace_Y_601:
+ targetSpace = kVDPixSpace_YCC_601;
+ goto space_reconvert;
+
+ case kVDPixSpace_Y_709:
+ targetSpace = kVDPixSpace_YCC_709;
+ goto space_reconvert;
+
+ default:
+ VDASSERT(false);
+ break;
+ }
+ }
+ break;
+
default:
VDASSERT(false);
break;
diff --git a/src/thirdparty/VirtualDub/Kasumi/source/uberblit_16f.cpp b/src/thirdparty/VirtualDub/Kasumi/source/uberblit_16f.cpp
index 3e9af1a1b..34422884b 100644
--- a/src/thirdparty/VirtualDub/Kasumi/source/uberblit_16f.cpp
+++ b/src/thirdparty/VirtualDub/Kasumi/source/uberblit_16f.cpp
@@ -1,3 +1,22 @@
+// VirtualDub - Video processing and capture application
+// Graphics support library
+// Copyright (C) 1998-2009 Avery Lee
+//
+// 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+#include <stdafx.h>
#include <vd2/system/halffloat.h>
#include "uberblit_16f.h"
diff --git a/src/thirdparty/VirtualDub/Kasumi/source/uberblit_gen.cpp b/src/thirdparty/VirtualDub/Kasumi/source/uberblit_gen.cpp
index f93ca322e..3f652863a 100644
--- a/src/thirdparty/VirtualDub/Kasumi/source/uberblit_gen.cpp
+++ b/src/thirdparty/VirtualDub/Kasumi/source/uberblit_gen.cpp
@@ -1,3 +1,22 @@
+// VirtualDub - Video processing and capture application
+// Graphics support library
+// Copyright (C) 1998-2009 Avery Lee
+//
+// 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+#include <stdafx.h>
#include <vd2/system/vdalloc.h>
#include <vd2/Kasumi/pixmaputils.h>
#include "uberblit.h"
@@ -7,11 +26,13 @@
#include "uberblit_resample.h"
#include "uberblit_resample_special.h"
#include "uberblit_ycbcr.h"
+#include "uberblit_ycbcr_generic.h"
#include "uberblit_rgb.h"
#include "uberblit_swizzle.h"
#include "uberblit_pal.h"
#include "uberblit_16f.h"
#include "uberblit_v210.h"
+#include "uberblit_interlace.h"
#ifdef VD_CPU_X86
#include "uberblit_swizzle_x86.h"
@@ -64,8 +85,8 @@ void VDPixmapUberBlitterDirectCopy::Blit(const VDPixmap& dst, const vdrect32 *rD
void *p = dst.data;
void *p2 = dst.data2;
void *p3 = dst.data3;
- int w = dst.w;
- int h = dst.h;
+ int w = std::min<int>(dst.w, src.w);
+ int h = std::min<int>(dst.h, src.h);
if (formatInfo.qchunky) {
w = (w + formatInfo.qw - 1) / formatInfo.qw;
@@ -1284,6 +1305,34 @@ void VDPixmapUberBlitterGenerator::interleave_B8R8() {
mStack.pop_back();
}
+void VDPixmapUberBlitterGenerator::merge_fields(uint32 w, uint32 h, uint32 bpr) {
+ StackEntry *args = &mStack.back() - 1;
+
+ VDPixmapGen_MergeFields *src = new VDPixmapGen_MergeFields;
+
+ src->Init(args[0].mpSrc, args[0].mSrcIndex, args[1].mpSrc, args[1].mSrcIndex, w, h, bpr);
+
+ mGenerators.push_back(src);
+ MarkDependency(src, args[0].mpSrc);
+ MarkDependency(src, args[1].mpSrc);
+ args[0] = StackEntry(src, 0);
+ mStack.pop_back();
+}
+
+void VDPixmapUberBlitterGenerator::split_fields(uint32 bpr) {
+ StackEntry *args = &mStack.back();
+
+ VDPixmapGen_SplitFields *src = new VDPixmapGen_SplitFields;
+
+ src->Init(args[0].mpSrc, args[0].mSrcIndex, bpr);
+
+ mGenerators.push_back(src);
+ MarkDependency(src, args[0].mpSrc);
+
+ args[0] = StackEntry(src, 0);
+ mStack.push_back(StackEntry(src, 1));
+}
+
void VDPixmapUberBlitterGenerator::ycbcr601_to_rgb32() {
StackEntry *args = &mStack.back() - 2;
@@ -1458,6 +1507,89 @@ void VDPixmapUberBlitterGenerator::ycbcr709_to_ycbcr601() {
args[2] = StackEntry(src, 2);
}
+void VDPixmapUberBlitterGenerator::ycbcr_to_rgb32_generic(const VDPixmapGenYCbCrBasis& basis, bool studioRGB) {
+ StackEntry *args = &mStack.back() - 2;
+
+ VDPixmapGenYCbCrToRGB32Generic *src = new VDPixmapGenYCbCrToRGB32Generic(basis, studioRGB);
+
+ src->Init(args[0].mpSrc, args[0].mSrcIndex, args[1].mpSrc, args[1].mSrcIndex, args[2].mpSrc, args[2].mSrcIndex);
+
+ mGenerators.push_back(src);
+ MarkDependency(src, args[0].mpSrc);
+ MarkDependency(src, args[1].mpSrc);
+ MarkDependency(src, args[2].mpSrc);
+ args[0] = StackEntry(src, 0);
+ mStack.pop_back();
+ mStack.pop_back();
+}
+
+void VDPixmapUberBlitterGenerator::ycbcr_to_rgb32f_generic(const VDPixmapGenYCbCrBasis& basis) {
+ StackEntry *args = &mStack.back() - 2;
+
+ VDPixmapGenYCbCrToRGB32FGeneric *src = new VDPixmapGenYCbCrToRGB32FGeneric(basis);
+
+ src->Init(args[0].mpSrc, args[0].mSrcIndex, args[1].mpSrc, args[1].mSrcIndex, args[2].mpSrc, args[2].mSrcIndex);
+
+ mGenerators.push_back(src);
+ MarkDependency(src, args[0].mpSrc);
+ MarkDependency(src, args[1].mpSrc);
+ MarkDependency(src, args[2].mpSrc);
+ args[0] = StackEntry(src, 0);
+ mStack.pop_back();
+ mStack.pop_back();
+}
+
+void VDPixmapUberBlitterGenerator::rgb32_to_ycbcr_generic(const VDPixmapGenYCbCrBasis& basis, bool studioRGB, uint32 colorSpace) {
+ StackEntry *args = &mStack.back();
+
+ VDPixmapGenRGB32ToYCbCrGeneric *src = new VDPixmapGenRGB32ToYCbCrGeneric(basis, studioRGB, colorSpace);
+ src->Init(args[0].mpSrc, args[0].mSrcIndex);
+
+ mGenerators.push_back(src);
+ MarkDependency(src, args[0].mpSrc);
+ args[0] = StackEntry(src, 0);
+ mStack.push_back(StackEntry(src, 1));
+ mStack.push_back(StackEntry(src, 2));
+}
+
+void VDPixmapUberBlitterGenerator::rgb32f_to_ycbcr_generic(const VDPixmapGenYCbCrBasis& basis, uint32 colorSpace) {
+ StackEntry *args = &mStack.back();
+
+ VDPixmapGenRGB32FToYCbCrGeneric *src = new VDPixmapGenRGB32FToYCbCrGeneric(basis, colorSpace);
+ src->Init(args[0].mpSrc, args[0].mSrcIndex);
+
+ mGenerators.push_back(src);
+ MarkDependency(src, args[0].mpSrc);
+ args[0] = StackEntry(src, 0);
+ mStack.push_back(StackEntry(src, 1));
+ mStack.push_back(StackEntry(src, 2));
+}
+
+void VDPixmapUberBlitterGenerator::ycbcr_to_ycbcr_generic(const VDPixmapGenYCbCrBasis& basisDst, bool dstLimitedRange, const VDPixmapGenYCbCrBasis& basisSrc, bool srcLimitedRange, uint32 colorSpace) {
+ StackEntry *args = &mStack.back() - 2;
+
+ IVDPixmapGen *src;
+ if ((args[0].mpSrc->GetType(args[0].mSrcIndex) & kVDPixType_Mask) == kVDPixType_32F_LE) {
+ VDPixmapGenYCbCrToYCbCrGeneric_32F *src2 = new VDPixmapGenYCbCrToYCbCrGeneric_32F(basisDst, dstLimitedRange, basisSrc, srcLimitedRange, colorSpace);
+
+ src2->Init(args[0].mpSrc, args[0].mSrcIndex, args[1].mpSrc, args[1].mSrcIndex, args[2].mpSrc, args[2].mSrcIndex);
+ src = src2;
+ } else {
+ VDPixmapGenYCbCrToYCbCrGeneric *src2 = new VDPixmapGenYCbCrToYCbCrGeneric(basisDst, dstLimitedRange, basisSrc, srcLimitedRange, colorSpace);
+
+ src2->Init(args[0].mpSrc, args[0].mSrcIndex, args[1].mpSrc, args[1].mSrcIndex, args[2].mpSrc, args[2].mSrcIndex);
+ src = src2;
+ }
+
+ mGenerators.push_back(src);
+ MarkDependency(src, args[0].mpSrc);
+ MarkDependency(src, args[1].mpSrc);
+ MarkDependency(src, args[2].mpSrc);
+ args[0] = StackEntry(src, 0);
+ args[1] = StackEntry(src, 1);
+ args[2] = StackEntry(src, 2);
+}
+
IVDPixmapBlitter *VDPixmapUberBlitterGenerator::create() {
vdautoptr<VDPixmapUberBlitter> blitter(new VDPixmapUberBlitter);
diff --git a/src/thirdparty/VirtualDub/Kasumi/source/uberblit_resample.cpp b/src/thirdparty/VirtualDub/Kasumi/source/uberblit_resample.cpp
index 1363fb730..8174d6721 100644
--- a/src/thirdparty/VirtualDub/Kasumi/source/uberblit_resample.cpp
+++ b/src/thirdparty/VirtualDub/Kasumi/source/uberblit_resample.cpp
@@ -1,3 +1,22 @@
+// VirtualDub - Video processing and capture application
+// Graphics support library
+// Copyright (C) 1998-2009 Avery Lee
+//
+// 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+#include <stdafx.h>
#include <float.h>
#include <math.h>
#include <vd2/system/vdstl.h>
diff --git a/src/thirdparty/VirtualDub/Kasumi/source/uberblit_resample_special.cpp b/src/thirdparty/VirtualDub/Kasumi/source/uberblit_resample_special.cpp
index 0c649dd5c..b162dbcc0 100644
--- a/src/thirdparty/VirtualDub/Kasumi/source/uberblit_resample_special.cpp
+++ b/src/thirdparty/VirtualDub/Kasumi/source/uberblit_resample_special.cpp
@@ -1,3 +1,22 @@
+// VirtualDub - Video processing and capture application
+// Graphics support library
+// Copyright (C) 1998-2009 Avery Lee
+//
+// 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+#include <stdafx.h>
#include "uberblit_resample_special.h"
#include "blt_spanutils.h"
diff --git a/src/thirdparty/VirtualDub/Kasumi/source/uberblit_resample_special_x86.cpp b/src/thirdparty/VirtualDub/Kasumi/source/uberblit_resample_special_x86.cpp
index b1828fcca..990e0520e 100644
--- a/src/thirdparty/VirtualDub/Kasumi/source/uberblit_resample_special_x86.cpp
+++ b/src/thirdparty/VirtualDub/Kasumi/source/uberblit_resample_special_x86.cpp
@@ -1,3 +1,22 @@
+// VirtualDub - Video processing and capture application
+// Graphics support library
+// Copyright (C) 1998-2009 Avery Lee
+//
+// 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+#include <stdafx.h>
#include "uberblit_resample_special_x86.h"
#include "blt_spanutils.h"
#include "blt_spanutils_x86.h"
diff --git a/src/thirdparty/VirtualDub/Kasumi/source/uberblit_swizzle.cpp b/src/thirdparty/VirtualDub/Kasumi/source/uberblit_swizzle.cpp
index 4cb5e4409..d65c317a2 100644
--- a/src/thirdparty/VirtualDub/Kasumi/source/uberblit_swizzle.cpp
+++ b/src/thirdparty/VirtualDub/Kasumi/source/uberblit_swizzle.cpp
@@ -1,3 +1,22 @@
+// VirtualDub - Video processing and capture application
+// Graphics support library
+// Copyright (C) 1998-2009 Avery Lee
+//
+// 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+#include <stdafx.h>
#include "uberblit_swizzle.h"
void VDPixmapGen_Swap8In16::Init(IVDPixmapGen *gen, int srcIndex, uint32 w, uint32 h, uint32 bpr) {
diff --git a/src/thirdparty/VirtualDub/Kasumi/source/uberblit_swizzle_x86.cpp b/src/thirdparty/VirtualDub/Kasumi/source/uberblit_swizzle_x86.cpp
index 3a87d5a68..311ecde84 100644
--- a/src/thirdparty/VirtualDub/Kasumi/source/uberblit_swizzle_x86.cpp
+++ b/src/thirdparty/VirtualDub/Kasumi/source/uberblit_swizzle_x86.cpp
@@ -1,3 +1,22 @@
+// VirtualDub - Video processing and capture application
+// Graphics support library
+// Copyright (C) 1998-2009 Avery Lee
+//
+// 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+#include <stdafx.h>
#include "uberblit_swizzle_x86.h"
#ifdef VD_COMPILER_MSVC
diff --git a/src/thirdparty/VirtualDub/Kasumi/source/uberblit_v210.cpp b/src/thirdparty/VirtualDub/Kasumi/source/uberblit_v210.cpp
index 78793f477..1e558aabd 100644
--- a/src/thirdparty/VirtualDub/Kasumi/source/uberblit_v210.cpp
+++ b/src/thirdparty/VirtualDub/Kasumi/source/uberblit_v210.cpp
@@ -1,3 +1,22 @@
+// VirtualDub - Video processing and capture application
+// Graphics support library
+// Copyright (C) 1998-2009 Avery Lee
+//
+// 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+#include <stdafx.h>
#include <vd2/system/halffloat.h>
#include <vd2/system/math.h>
#include "uberblit_v210.h"
diff --git a/src/thirdparty/VirtualDub/Kasumi/source/uberblit_ycbcr_generic.cpp b/src/thirdparty/VirtualDub/Kasumi/source/uberblit_ycbcr_generic.cpp
new file mode 100644
index 000000000..3820c7254
--- /dev/null
+++ b/src/thirdparty/VirtualDub/Kasumi/source/uberblit_ycbcr_generic.cpp
@@ -0,0 +1,545 @@
+// VirtualDub - Video processing and capture application
+// Graphics support library
+// Copyright (C) 1998-2009 Avery Lee
+//
+// 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+#include <stdafx.h>
+#include <vd2/system/vectors.h>
+#include "uberblit_ycbcr_generic.h"
+
+extern const VDPixmapGenYCbCrBasis g_VDPixmapGenYCbCrBasis_601 = {
+ 0.299f,
+ 0.114f,
+ {
+ 0.0f, -0.3441363f, 1.772f,
+ 1.402f, -0.7141363f, 0.0f,
+ }
+};
+
+extern const VDPixmapGenYCbCrBasis g_VDPixmapGenYCbCrBasis_709 = {
+ 0.2126f,
+ 0.0722f,
+ {
+ 0.0f, -0.1873243f, 1.8556f,
+ 1.5748f, -0.4681243f, 0.0f,
+ }
+};
+
+////////////////////////////////////////////////////////////////////////////
+
+VDPixmapGenYCbCrToRGB32Generic::VDPixmapGenYCbCrToRGB32Generic(const VDPixmapGenYCbCrBasis& basis, bool studioRGB) {
+ float scale;
+ float bias;
+
+ if (studioRGB) {
+ scale = 65536.0f * (219.0f / 255.0f);
+ bias = 65536.0f * (16.0f / 255.0f + 0.5f);
+ } else {
+ scale = 65536.0f;
+ bias = 32768.0f;
+ }
+
+ float scale255 = scale * 255.0f;
+
+ mCoY = VDRoundToInt32(scale);
+ mCoRCr = VDRoundToInt32(basis.mToRGB[1][0] * scale);
+ mCoGCr = VDRoundToInt32(basis.mToRGB[1][1] * scale);
+ mCoGCb = VDRoundToInt32(basis.mToRGB[0][1] * scale);
+ mCoBCb = VDRoundToInt32(basis.mToRGB[0][2] * scale);
+ mBiasR = VDRoundToInt32(bias) - 128*mCoRCr;
+ mBiasG = VDRoundToInt32(bias) - 128*(mCoGCr + mCoGCb);
+ mBiasB = VDRoundToInt32(bias) - 128*mCoBCb;
+}
+
+uint32 VDPixmapGenYCbCrToRGB32Generic::GetType(uint32 output) const {
+ return (mpSrcY->GetType(mSrcIndexY) & ~(kVDPixType_Mask | kVDPixSpace_Mask)) | kVDPixType_8888 | kVDPixSpace_BGR;
+}
+
+void VDPixmapGenYCbCrToRGB32Generic::Compute(void *dst0, sint32 y) {
+ uint8 *dst = (uint8 *)dst0;
+ const uint8 *srcY = (const uint8 *)mpSrcY->GetRow(y, mSrcIndexY);
+ const uint8 *srcCb = (const uint8 *)mpSrcCb->GetRow(y, mSrcIndexCb);
+ const uint8 *srcCr = (const uint8 *)mpSrcCr->GetRow(y, mSrcIndexCr);
+
+ const sint32 coY = mCoY;
+ const sint32 coRCr = mCoRCr;
+ const sint32 coGCr = mCoGCr;
+ const sint32 coGCb = mCoGCb;
+ const sint32 coBCb = mCoBCb;
+ const sint32 biasR = mBiasR;
+ const sint32 biasG = mBiasG;
+ const sint32 biasB = mBiasB;
+
+ const sint32 w = mWidth;
+ for(sint32 i=0; i<w; ++i) {
+ sint32 y = srcY[i];
+ sint32 cb = srcCb[i];
+ sint32 cr = srcCr[i];
+
+ y *= coY;
+
+ sint32 r = biasR + y + coRCr * cr;
+ sint32 g = biasG + y + coGCr * cr + coGCb * cb;
+ sint32 b = biasB + y + coBCb * cb;
+
+ // clip low
+ r &= ~r >> 31;
+ g &= ~g >> 31;
+ b &= ~b >> 31;
+
+ // clip high
+ sint32 clipR = 0xffffff - r;
+ sint32 clipG = 0xffffff - g;
+ sint32 clipB = 0xffffff - b;
+ r |= clipR >> 31;
+ g |= clipG >> 31;
+ b |= clipB >> 31;
+
+ dst[0] = (uint8)(b >> 16);
+ dst[1] = (uint8)(g >> 16);
+ dst[2] = (uint8)(r >> 16);
+ dst[3] = 0xff;
+
+ dst += 4;
+ }
+}
+
+////////////////////////////////////////////////////////////////////////////
+
+VDPixmapGenYCbCrToRGB32FGeneric::VDPixmapGenYCbCrToRGB32FGeneric(const VDPixmapGenYCbCrBasis& basis) {
+ mCoRCr = basis.mToRGB[1][0];
+ mCoGCr = basis.mToRGB[1][1];
+ mCoGCb = basis.mToRGB[0][1];
+ mCoBCb = basis.mToRGB[0][2];
+}
+
+uint32 VDPixmapGenYCbCrToRGB32FGeneric::GetType(uint32 output) const {
+ return (mpSrcY->GetType(mSrcIndexY) & ~(kVDPixType_Mask | kVDPixSpace_Mask)) | kVDPixType_32Fx4_LE | kVDPixSpace_BGR;
+}
+
+void VDPixmapGenYCbCrToRGB32FGeneric::Compute(void *dst0, sint32 y) {
+ float *dst = (float *)dst0;
+ const float *srcY = (const float *)mpSrcY->GetRow(y, mSrcIndexY);
+ const float *srcCb = (const float *)mpSrcCb->GetRow(y, mSrcIndexCb);
+ const float *srcCr = (const float *)mpSrcCr->GetRow(y, mSrcIndexCr);
+
+ VDCPUCleanupExtensions();
+
+ const float coRCr = mCoRCr;
+ const float coGCr = mCoGCr;
+ const float coGCb = mCoGCb;
+ const float coBCb = mCoBCb;
+
+ for(sint32 i=0; i<mWidth; ++i) {
+ float y = srcY[i];
+ float cb = srcCb[i] - (128.0f / 255.0f);
+ float cr = srcCr[i] - (128.0f / 255.0f);
+
+ dst[0] = y + coRCr * cr;
+ dst[1] = y + coGCr * cr + coGCb * cb;
+ dst[2] = y + coBCb * cb;
+ dst[3] = 1.0f;
+ dst += 4;
+ }
+}
+
+////////////////////////////////////////////////////////////////////////////
+
+VDPixmapGenRGB32ToYCbCrGeneric::VDPixmapGenRGB32ToYCbCrGeneric(const VDPixmapGenYCbCrBasis& basis, bool studioRGB, uint32 colorSpace)
+ : mColorSpace(colorSpace)
+{
+ float scale;
+ float bias;
+
+ if (studioRGB) {
+ scale = 255.0f / 219.0f;
+ bias = -16.0f;
+ } else {
+ scale = 1.0f;
+ bias = 0.0f;
+ }
+
+
+ // compute Y coefficients
+ float coYR = basis.mKr;
+ float coYG = (1.0f - basis.mKr - basis.mKb);
+ float coYB = basis.mKb;
+
+ mCoYR = VDRoundToInt32(scale * coYR * 65536.0f);
+ mCoYG = VDRoundToInt32(scale * coYG * 65536.0f);
+ mCoYB = VDRoundToInt32(scale * coYB * 65536.0f);
+ mCoYA = 0x8000;
+
+ // Cb = 0.5 * (B-Y) / (1-Kb)
+ const float coCb = 0.5f / (1.0f - basis.mKb);
+ float coCbR = (0.0f - coYR) * coCb;
+ float coCbG = (0.0f - coYG) * coCb;
+ float coCbB = (1.0f - coYB) * coCb;
+ float coCbA = (coCbR + coCbG + coCbB) * bias;
+
+ // Cr = 0.5 * (R-Y) / (1-Kr)
+ const float coCr = 0.5f / (1.0f - basis.mKr);
+ float coCrR = (1.0f - coYR) * coCr;
+ float coCrG = (0.0f - coYG) * coCr;
+ float coCrB = (0.0f - coYB) * coCr;
+ float coCrA = (coCrR + coCrG + coCrB) * bias;
+
+ mCoCbR = VDRoundToInt32(coCbR * 65536.0f);
+ mCoCbG = VDRoundToInt32(coCbG * 65536.0f);
+ mCoCbB = VDRoundToInt32(coCbB * 65536.0f);
+ mCoCbA = VDRoundToInt32(coCbA * 65536.0f) + 0x808000;
+
+ mCoCrR = VDRoundToInt32(coCrR * 65536.0f);
+ mCoCrG = VDRoundToInt32(coCrG * 65536.0f);
+ mCoCrB = VDRoundToInt32(coCrB * 65536.0f);
+ mCoCrA = VDRoundToInt32(coCrA * 65536.0f) + 0x808000;
+}
+
+uint32 VDPixmapGenRGB32ToYCbCrGeneric::GetType(uint32 output) const {
+ return (mpSrc->GetType(mSrcIndex) & ~(kVDPixType_Mask | kVDPixSpace_Mask)) | kVDPixType_8 | mColorSpace;
+}
+
+void VDPixmapGenRGB32ToYCbCrGeneric::Compute(void *dst0, sint32 y) {
+ uint8 *dstCr = (uint8 *)dst0;
+ uint8 *dstY = dstCr + mWindowPitch;
+ uint8 *dstCb = dstY + mWindowPitch;
+
+ const uint8 *srcRGB = (const uint8 *)mpSrc->GetRow(y, mSrcIndex);
+
+ const sint32 coYR = mCoYR;
+ const sint32 coYG = mCoYG;
+ const sint32 coYB = mCoYB;
+ const sint32 coCbR = mCoCbR;
+ const sint32 coCbG = mCoCbG;
+ const sint32 coCbB = mCoCbB;
+ const sint32 coCrR = mCoCrR;
+ const sint32 coCrG = mCoCrG;
+ const sint32 coCrB = mCoCrB;
+ const sint32 coYA = mCoYA;
+ const sint32 coCbA = mCoCbA;
+ const sint32 coCrA = mCoCrA;
+
+ const sint32 w = mWidth;
+ for(sint32 i=0; i<w; ++i) {
+ int r = (int)srcRGB[2];
+ int g = (int)srcRGB[1];
+ int b = (int)srcRGB[0];
+ srcRGB += 4;
+
+ // Normally, this can be optimized by encoding the chroma channels as
+ // (R-Y) and (B-Y) differences. However, us working in fixed point complicates
+ // things here, so for now we do a full 4x3 matrix.
+
+ sint32 y16 = coYR * r + coYG * g + coYB * b + coYA;
+ sint32 cb16 = coCbR * r + coCbG * g + coCbB * b + coCbA;
+ sint32 cr16 = coCrR * r + coCrG * g + coCrB * b + coCrA;
+
+ // Quite annoyingly, we have to clip chroma on the high end since the transformation
+ // targets [0,1] instead of [0,1). This occurs due to the bias by +0.5 to make
+ // reference black for chroma fall on 128 instead of 127.5. The resulting
+ // transformation is the one used for JFIF and also for TIFF with the full
+ // range ReferenceBlack/ReferenceWhite values.
+
+ cb16 |= (0xffffff - cb16) >> 31;
+ cr16 |= (0xffffff - cr16) >> 31;
+
+ *dstCb++ = (uint8)(cb16 >> 16);
+ *dstY ++ = (uint8)( y16 >> 16);
+ *dstCr++ = (uint8)(cr16 >> 16);
+ }
+}
+
+////////////////////////////////////////////////////////////////////////////
+
+VDPixmapGenRGB32FToYCbCrGeneric::VDPixmapGenRGB32FToYCbCrGeneric(const VDPixmapGenYCbCrBasis& basis, uint32 colorSpace)
+ : mColorSpace(colorSpace)
+{
+ mCoYR = basis.mKr;
+ mCoYG = 1.0f - basis.mKr - basis.mKb;
+ mCoYB = basis.mKb;
+
+ // Cb = 0.5 * (B-Y) / (1-Kb)
+ mCoCb = 0.5f / (1.0f - basis.mKb);
+
+ // Cr = 0.5 * (R-Y) / (1-Kr)
+ mCoCr = 0.5f / (1.0f - basis.mKr);
+}
+
+uint32 VDPixmapGenRGB32FToYCbCrGeneric::GetType(uint32 output) const {
+ return (mpSrc->GetType(mSrcIndex) & ~(kVDPixType_Mask | kVDPixSpace_Mask)) | kVDPixType_32F_LE | mColorSpace;
+}
+
+void VDPixmapGenRGB32FToYCbCrGeneric::Compute(void *dst0, sint32 y) {
+ float *dstCr = (float *)dst0;
+ float *dstY = dstCr + mWindowPitch;
+ float *dstCb = dstY + mWindowPitch;
+
+ const float *srcRGB = (const float *)mpSrc->GetRow(y, mSrcIndex);
+
+ VDCPUCleanupExtensions();
+
+ const float coYR = mCoYR;
+ const float coYG = mCoYG;
+ const float coYB = mCoYB;
+ const float coCb = mCoCb;
+ const float coCr = mCoCr;
+
+ const sint32 w = mWidth;
+ for(sint32 i=0; i<w; ++i) {
+ float r = srcRGB[2];
+ float g = srcRGB[1];
+ float b = srcRGB[0];
+ srcRGB += 4;
+
+ float y = coYR * r + coYG * g + coYB * b;
+
+ *dstY++ = y;
+ *dstCb++ = coCb * (b - y) + (128.0f / 255.0f);
+ *dstCr++ = coCr * (r - y) + (128.0f / 255.0f);
+ }
+}
+
+////////////////////////////////////////////////////////////////////////////
+
+VDPixmapGenYCbCrToYCbCrGeneric::VDPixmapGenYCbCrToYCbCrGeneric(const VDPixmapGenYCbCrBasis& dstBasis, bool dstLimitedRange, const VDPixmapGenYCbCrBasis& srcBasis, bool srcLimitedRange, uint32 colorSpace)
+ : mColorSpace(colorSpace)
+{
+ vdfloat3x3 dstToRGB;
+ dstToRGB.m[0] = vdfloat3c(1, 1, 1);
+ dstToRGB.m[1] = vdfloat3c(dstBasis.mToRGB[0]);
+ dstToRGB.m[2] = vdfloat3c(dstBasis.mToRGB[1]);
+
+ if (dstLimitedRange) {
+ dstToRGB.m[0] *= (255.0f / 219.0f);
+ dstToRGB.m[1] *= (128.0f / 112.0f);
+ dstToRGB.m[2] *= (128.0f / 112.0f);
+ }
+
+ vdfloat3x3 srcToRGB;
+ srcToRGB.m[0] = vdfloat3c(1, 1, 1);
+ srcToRGB.m[1] = vdfloat3c(srcBasis.mToRGB[0]);
+ srcToRGB.m[2] = vdfloat3c(srcBasis.mToRGB[1]);
+
+ if (srcLimitedRange) {
+ srcToRGB.m[0] *= (255.0f / 219.0f);
+ srcToRGB.m[1] *= (128.0f / 112.0f);
+ srcToRGB.m[2] *= (128.0f / 112.0f);
+ }
+
+ vdfloat3x3 xf(srcToRGB * ~dstToRGB);
+
+ // We should get a transform that looks like this:
+ //
+ // |k 0 0|
+ // [y cb cr 1] |a c e| = [y' cb' cr]
+ // |b d f|
+ // |x y z|
+
+ VDASSERT(fabsf(xf.m[0].v[1]) < 1e-5f);
+ VDASSERT(fabsf(xf.m[0].v[2]) < 1e-5f);
+
+ mCoYY = VDRoundToInt32(xf.m[0].v[0] * 65536.0f);
+ mCoYCb = VDRoundToInt32(xf.m[1].v[0] * 65536.0f);
+ mCoYCr = VDRoundToInt32(xf.m[2].v[0] * 65536.0f);
+ mCoCbCb = VDRoundToInt32(xf.m[1].v[1] * 65536.0f);
+ mCoCbCr = VDRoundToInt32(xf.m[2].v[1] * 65536.0f);
+ mCoCrCb = VDRoundToInt32(xf.m[1].v[2] * 65536.0f);
+ mCoCrCr = VDRoundToInt32(xf.m[2].v[2] * 65536.0f);
+
+ vdfloat3c srcBias(0, 128.0f/255.0f, 128.0f/255.0f);
+ if (srcLimitedRange)
+ srcBias.set(16.0f / 255.0f, 128.0f / 255.0f, 128.0f / 255.0f);
+
+ vdfloat3c dstBias(0, 128.0f/255.0f, 128.0f/255.0f);
+ if (dstLimitedRange)
+ dstBias.set(16.0f / 255.0f, 128.0f / 255.0f, 128.0f / 255.0f);
+
+ vdfloat3 bias = -srcBias * xf + dstBias;
+
+ mCoYA = VDRoundToInt32(bias.x * 255.0f * 65536.0f) + 0x8000;
+ mCoCbA = VDRoundToInt32(bias.y * 255.0f * 65536.0f) + 0x8000;
+ mCoCrA = VDRoundToInt32(bias.z * 255.0f * 65536.0f) + 0x8000;
+}
+
+void VDPixmapGenYCbCrToYCbCrGeneric::Start() {
+ mpSrcY->Start();
+ mpSrcCb->Start();
+ mpSrcCr->Start();
+
+ StartWindow(mWidth, 3);
+}
+
+const void *VDPixmapGenYCbCrToYCbCrGeneric::GetRow(sint32 y, uint32 index) {
+ return (const uint8 *)VDPixmapGenYCbCrToRGBBase::GetRow(y, index) + mWindowPitch * index;
+}
+
+uint32 VDPixmapGenYCbCrToYCbCrGeneric::GetType(uint32 output) const {
+ return (mpSrcY->GetType(mSrcIndexY) & ~kVDPixSpace_Mask) | mColorSpace;
+}
+
+void VDPixmapGenYCbCrToYCbCrGeneric::Compute(void *dst0, sint32 ypos) {
+ uint8 *dstCr = (uint8 *)dst0;
+ uint8 *dstY = dstCr + mWindowPitch;
+ uint8 *dstCb = dstY + mWindowPitch;
+
+ const uint8 *srcY = (const uint8 *)mpSrcY ->GetRow(ypos, mSrcIndexY );
+ const uint8 *srcCb = (const uint8 *)mpSrcCb->GetRow(ypos, mSrcIndexCb);
+ const uint8 *srcCr = (const uint8 *)mpSrcCr->GetRow(ypos, mSrcIndexCr);
+
+ const sint32 coYY = mCoYY;
+ const sint32 coYCb = mCoYCb;
+ const sint32 coYCr = mCoYCr;
+ const sint32 coYA = mCoYA;
+ const sint32 coCbCb = mCoCbCb;
+ const sint32 coCbCr = mCoCbCr;
+ const sint32 coCbA = mCoCbA;
+ const sint32 coCrCb = mCoCrCb;
+ const sint32 coCrCr = mCoCrCr;
+ const sint32 coCrA = mCoCrA;
+
+ for(sint32 i=0; i<mWidth; ++i) {
+ sint32 y = srcY[i];
+ sint32 cb = srcCb[i];
+ sint32 cr = srcCr[i];
+
+ sint32 y2 = y*coYY + cb*coYCb + cr*coYCr + coYA;
+ sint32 cb2 = cb*coCbCb + cr*coCbCr + coCbA;
+ sint32 cr2 = cb*coCrCb + cr*coCrCr + coCrA;
+
+ y2 &= ~y2 >> 31;
+ cb2 &= ~cb2 >> 31;
+ cr2 &= ~cr2 >> 31;
+
+ y2 |= (0xffffff - y2) >> 31;
+ cb2 |= (0xffffff - cb2) >> 31;
+ cr2 |= (0xffffff - cr2) >> 31;
+
+ *dstY++ = (uint8)(y2 >> 16);
+ *dstCb++ = (uint8)(cb2 >> 16);
+ *dstCr++ = (uint8)(cr2 >> 16);
+ }
+}
+
+////////////////////////////////////////////////////////////////////////////
+
+VDPixmapGenYCbCrToYCbCrGeneric_32F::VDPixmapGenYCbCrToYCbCrGeneric_32F(const VDPixmapGenYCbCrBasis& dstBasis, bool dstLimitedRange, const VDPixmapGenYCbCrBasis& srcBasis, bool srcLimitedRange, uint32 colorSpace)
+ : mColorSpace(colorSpace)
+{
+ vdfloat3x3 dstToRGB;
+ dstToRGB.m[0] = vdfloat3c(1, 1, 1);
+ dstToRGB.m[1] = vdfloat3c(dstBasis.mToRGB[0]);
+ dstToRGB.m[2] = vdfloat3c(dstBasis.mToRGB[1]);
+
+ if (dstLimitedRange) {
+ dstToRGB.m[0] *= (255.0f / 219.0f);
+ dstToRGB.m[1] *= (255.0f / 224.0f);
+ dstToRGB.m[2] *= (255.0f / 224.0f);
+ }
+
+ vdfloat3x3 srcToRGB;
+ srcToRGB.m[0] = vdfloat3c(1, 1, 1);
+ srcToRGB.m[1] = vdfloat3c(srcBasis.mToRGB[0]);
+ srcToRGB.m[2] = vdfloat3c(srcBasis.mToRGB[1]);
+
+ if (srcLimitedRange) {
+ srcToRGB.m[0] *= (255.0f / 219.0f);
+ srcToRGB.m[1] *= (255.0f / 224.0f);
+ srcToRGB.m[2] *= (255.0f / 224.0f);
+ }
+
+ vdfloat3x3 xf(srcToRGB * ~dstToRGB);
+
+ // We should get a transform that looks like this:
+ //
+ // |k 0 0|
+ // [y cb cr 1] |a c e| = [y' cb' cr]
+ // |b d f|
+ // |x y z|
+
+ VDASSERT(fabsf(xf.m[0].v[1]) < 1e-5f);
+ VDASSERT(fabsf(xf.m[0].v[2]) < 1e-5f);
+
+ mCoYY = xf.m[0].v[0];
+ mCoYCb = xf.m[1].v[0];
+ mCoYCr = xf.m[2].v[0];
+ mCoCbCb = xf.m[1].v[1];
+ mCoCbCr = xf.m[2].v[1];
+ mCoCrCb = xf.m[1].v[2];
+ mCoCrCr = xf.m[2].v[2];
+
+ vdfloat3c srcBias(0, 128.0f/255.0f, 128.0f/255.0f);
+ if (srcLimitedRange)
+ srcBias.set(16.0f / 255.0f, 128.0f / 255.0f, 128.0f / 255.0f);
+
+ vdfloat3c dstBias(0, 128.0f/255.0f, 128.0f/255.0f);
+ if (dstLimitedRange)
+ dstBias.set(16.0f / 255.0f, 128.0f / 255.0f, 128.0f / 255.0f);
+
+ vdfloat3 bias = -srcBias * xf + dstBias;
+
+ mCoYA = bias.x;
+ mCoCbA = bias.y;
+ mCoCrA = bias.z;
+}
+
+void VDPixmapGenYCbCrToYCbCrGeneric_32F::Start() {
+ mpSrcY->Start();
+ mpSrcCb->Start();
+ mpSrcCr->Start();
+
+ StartWindow(mWidth * sizeof(float), 3);
+}
+
+const void *VDPixmapGenYCbCrToYCbCrGeneric_32F::GetRow(sint32 y, uint32 index) {
+ return (const uint8 *)VDPixmapGenYCbCrToRGBBase::GetRow(y, index) + mWindowPitch * index;
+}
+
+uint32 VDPixmapGenYCbCrToYCbCrGeneric_32F::GetType(uint32 output) const {
+ return (mpSrcY->GetType(mSrcIndexY) & ~kVDPixSpace_Mask) | mColorSpace;
+}
+
+void VDPixmapGenYCbCrToYCbCrGeneric_32F::Compute(void *dst0, sint32 ypos) {
+ float *dstCr = (float *)dst0;
+ float *dstY = vdptroffset(dstCr, mWindowPitch);
+ float *dstCb = vdptroffset(dstY, mWindowPitch);
+
+ const float *srcY = (const float *)mpSrcY ->GetRow(ypos, mSrcIndexY );
+ const float *srcCb = (const float *)mpSrcCb->GetRow(ypos, mSrcIndexCb);
+ const float *srcCr = (const float *)mpSrcCr->GetRow(ypos, mSrcIndexCr);
+
+ VDCPUCleanupExtensions();
+
+ const float coYY = mCoYY;
+ const float coYCb = mCoYCb;
+ const float coYCr = mCoYCr;
+ const float coYA = mCoYA;
+ const float coCbCb = mCoCbCb;
+ const float coCbCr = mCoCbCr;
+ const float coCbA = mCoCbA;
+ const float coCrCb = mCoCrCb;
+ const float coCrCr = mCoCrCr;
+ const float coCrA = mCoCrA;
+
+ for(sint32 i=0; i<mWidth; ++i) {
+ float y = srcY [i];
+ float cb = srcCb[i];
+ float cr = srcCr[i];
+
+ *dstY++ = y*coYY + cb*coYCb + cr*coYCr + coYA;
+ *dstCb++ = cb*coCbCb + cr*coCbCr + coCbA;
+ *dstCr++ = cb*coCrCb + cr*coCrCr + coCrA;
+ }
+}
diff --git a/src/thirdparty/VirtualDub/Kasumi/source/uberblit_ycbcr_x86.cpp b/src/thirdparty/VirtualDub/Kasumi/source/uberblit_ycbcr_x86.cpp
index d34f731f1..4a2b10563 100644
--- a/src/thirdparty/VirtualDub/Kasumi/source/uberblit_ycbcr_x86.cpp
+++ b/src/thirdparty/VirtualDub/Kasumi/source/uberblit_ycbcr_x86.cpp
@@ -1,3 +1,22 @@
+// VirtualDub - Video processing and capture application
+// Graphics support library
+// Copyright (C) 1998-2009 Avery Lee
+//
+// 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+#include <stdafx.h>
#include "uberblit_ycbcr_x86.h"
extern "C" void vdasm_pixblt_XRGB8888_to_YUV444Planar_scan_SSE2(void *dstY, void *dstCb, void *dstCr, const void *srcRGB, uint32 count, const void *coeffs);
diff --git a/src/thirdparty/VirtualDub/h/vd2/Kasumi/blitter.h b/src/thirdparty/VirtualDub/h/vd2/Kasumi/blitter.h
index 536bc0e7a..d930f0d64 100644
--- a/src/thirdparty/VirtualDub/h/vd2/Kasumi/blitter.h
+++ b/src/thirdparty/VirtualDub/h/vd2/Kasumi/blitter.h
@@ -16,4 +16,24 @@ public:
IVDPixmapBlitter *VDPixmapCreateBlitter(const VDPixmap& dst, const VDPixmap& src);
IVDPixmapBlitter *VDPixmapCreateBlitter(const VDPixmapLayout& dst, const VDPixmapLayout& src);
+class VDPixmapCachedBlitter {
+ VDPixmapCachedBlitter(const VDPixmapCachedBlitter&);
+ VDPixmapCachedBlitter& operator=(const VDPixmapCachedBlitter&);
+public:
+ VDPixmapCachedBlitter();
+ ~VDPixmapCachedBlitter();
+
+ void Blit(const VDPixmap& dst, const VDPixmap& src);
+ void Invalidate();
+
+protected:
+ sint32 mSrcWidth;
+ sint32 mSrcHeight;
+ int mSrcFormat;
+ sint32 mDstWidth;
+ sint32 mDstHeight;
+ int mDstFormat;
+ IVDPixmapBlitter *mpCachedBlitter;
+};
+
#endif
diff --git a/src/thirdparty/VirtualDub/h/vd2/Kasumi/pixel.h b/src/thirdparty/VirtualDub/h/vd2/Kasumi/pixel.h
index a2f2e2ead..3c65ac1cc 100644
--- a/src/thirdparty/VirtualDub/h/vd2/Kasumi/pixel.h
+++ b/src/thirdparty/VirtualDub/h/vd2/Kasumi/pixel.h
@@ -1,6 +1,6 @@
// VirtualDub - Video processing and capture application
// Graphics support library
-// Copyright (C) 1998-2007 Avery Lee
+// Copyright (C) 1998-2009 Avery Lee
//
// 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
@@ -33,8 +33,8 @@ inline uint8 VDPixmapSample8(const void *data, ptrdiff_t pitch, sint32 x, sint32
}
uint8 VDPixmapInterpolateSample8(const void *data, ptrdiff_t pitch, uint32 w, uint32 h, sint32 x_256, sint32 y_256);
-uint32 VDConvertYCbCrToRGB(uint8 y, uint8 cb, uint8 cr);
+uint32 VDConvertYCbCrToRGB(uint8 y, uint8 cb, uint8 cr, bool use709, bool useFullRange);
uint32 VDConvertRGBToYCbCr(uint32 c);
-uint32 VDConvertRGBToYCbCr(uint8 r, uint8 g, uint8 b);
+uint32 VDConvertRGBToYCbCr(uint8 r, uint8 g, uint8 b, bool use709, bool useFullRange);
#endif
diff --git a/src/thirdparty/VirtualDub/h/vd2/Kasumi/pixmap.h b/src/thirdparty/VirtualDub/h/vd2/Kasumi/pixmap.h
index a0125b6e3..33e36f67b 100644
--- a/src/thirdparty/VirtualDub/h/vd2/Kasumi/pixmap.h
+++ b/src/thirdparty/VirtualDub/h/vd2/Kasumi/pixmap.h
@@ -33,6 +33,39 @@ namespace nsVDPixmap {
kPixFormat_YUV422_V210,
kPixFormat_YUV422_UYVY_709, // Also known as HDYC.
kPixFormat_YUV420_NV12,
+ kPixFormat_Y8_FR,
+ kPixFormat_YUV422_YUYV_709,
+ kPixFormat_YUV444_Planar_709,
+ kPixFormat_YUV422_Planar_709,
+ kPixFormat_YUV420_Planar_709,
+ kPixFormat_YUV411_Planar_709,
+ kPixFormat_YUV410_Planar_709,
+ kPixFormat_YUV422_UYVY_FR,
+ kPixFormat_YUV422_YUYV_FR,
+ kPixFormat_YUV444_Planar_FR,
+ kPixFormat_YUV422_Planar_FR,
+ kPixFormat_YUV420_Planar_FR,
+ kPixFormat_YUV411_Planar_FR,
+ kPixFormat_YUV410_Planar_FR,
+ kPixFormat_YUV422_UYVY_709_FR,
+ kPixFormat_YUV422_YUYV_709_FR,
+ kPixFormat_YUV444_Planar_709_FR,
+ kPixFormat_YUV422_Planar_709_FR,
+ kPixFormat_YUV420_Planar_709_FR,
+ kPixFormat_YUV411_Planar_709_FR,
+ kPixFormat_YUV410_Planar_709_FR,
+ kPixFormat_YUV420i_Planar,
+ kPixFormat_YUV420i_Planar_FR,
+ kPixFormat_YUV420i_Planar_709,
+ kPixFormat_YUV420i_Planar_709_FR,
+ kPixFormat_YUV420it_Planar,
+ kPixFormat_YUV420it_Planar_FR,
+ kPixFormat_YUV420it_Planar_709,
+ kPixFormat_YUV420it_Planar_709_FR,
+ kPixFormat_YUV420ib_Planar,
+ kPixFormat_YUV420ib_Planar_FR,
+ kPixFormat_YUV420ib_Planar_709,
+ kPixFormat_YUV420ib_Planar_709_FR,
kPixFormat_Max_Standard
};
}
diff --git a/src/thirdparty/VirtualDub/h/vd2/Kasumi/region.h b/src/thirdparty/VirtualDub/h/vd2/Kasumi/region.h
index aa2963c90..c87610d99 100644
--- a/src/thirdparty/VirtualDub/h/vd2/Kasumi/region.h
+++ b/src/thirdparty/VirtualDub/h/vd2/Kasumi/region.h
@@ -1,6 +1,6 @@
// VirtualDub - Video processing and capture application
// Graphics support library
-// Copyright (C) 1998-2007 Avery Lee
+// Copyright (C) 1998-2009 Avery Lee
//
// 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
diff --git a/src/thirdparty/VirtualDub/h/vd2/Kasumi/text.h b/src/thirdparty/VirtualDub/h/vd2/Kasumi/text.h
index 245d38f12..f4dba2796 100644
--- a/src/thirdparty/VirtualDub/h/vd2/Kasumi/text.h
+++ b/src/thirdparty/VirtualDub/h/vd2/Kasumi/text.h
@@ -1,6 +1,6 @@
// VirtualDub - Video processing and capture application
// Graphics support library
-// Copyright (C) 1998-2007 Avery Lee
+// Copyright (C) 1998-2009 Avery Lee
//
// 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
@@ -59,4 +59,18 @@ struct VDTextLayoutMetrics {
void VDPixmapGetTextExtents(const VDOutlineFontInfo *font, float size, const char *pText, VDTextLayoutMetrics& out_Metrics);
void VDPixmapConvertTextToPath(VDPixmapPathRasterizer& rast, const VDOutlineFontInfo *font, float size, float x, float y, const char *pText, const float transform[2][2] = NULL);
+struct VDBitmapFontInfo {
+ const uint8 *mpBitsArray;
+ const uint16 *mpPosArray;
+ uint8 mStartChar;
+ uint8 mEndChar;
+ int mCellWidth;
+ int mCellHeight;
+ int mCellAscent;
+ int mCellAdvance;
+ int mLineGap;
+};
+
+void VDPixmapDrawText(const VDPixmap& pxdst, const VDBitmapFontInfo *font, int x, int y, uint32 fore, uint32 back, const char *pText);
+
#endif
diff --git a/src/thirdparty/VirtualDub/h/vd2/Kasumi/triblt.h b/src/thirdparty/VirtualDub/h/vd2/Kasumi/triblt.h
index 4602cd883..9765f8e41 100644
--- a/src/thirdparty/VirtualDub/h/vd2/Kasumi/triblt.h
+++ b/src/thirdparty/VirtualDub/h/vd2/Kasumi/triblt.h
@@ -47,7 +47,8 @@ bool VDPixmapTriFill(VDPixmap& dst, uint32 c,
bool VDPixmapTriFill(VDPixmap& dst,
const VDTriColorVertex *pVertices, int nVertices,
const int *pIndices, const int nIndices,
- const float pTransform[16] = NULL);
+ const float pTransform[16] = NULL,
+ const float *chroma_yoffset = NULL);
bool VDPixmapTriBlt(VDPixmap& dst, const VDPixmap *const *pSources, int nMipmaps,
const VDTriBltVertex *pVertices, int nVertices,
diff --git a/src/thirdparty/VirtualDub/h/vd2/system/Error.h b/src/thirdparty/VirtualDub/h/vd2/system/Error.h
index 22f15ede3..ca11527f9 100644
--- a/src/thirdparty/VirtualDub/h/vd2/system/Error.h
+++ b/src/thirdparty/VirtualDub/h/vd2/system/Error.h
@@ -99,6 +99,11 @@ public:
class MyWin32Error : public MyError {
public:
MyWin32Error(const char *format, uint32 err, ...);
+
+ uint32 GetWin32Error() const { return mWin32Error; }
+
+protected:
+ const uint32 mWin32Error;
};
class MyCrashError : public MyError {
diff --git a/src/thirdparty/VirtualDub/h/vd2/system/VDScheduler.h b/src/thirdparty/VirtualDub/h/vd2/system/VDScheduler.h
index e88fb6c6f..37c2e921e 100644
--- a/src/thirdparty/VirtualDub/h/vd2/system/VDScheduler.h
+++ b/src/thirdparty/VirtualDub/h/vd2/system/VDScheduler.h
@@ -83,17 +83,17 @@ friend class VDScheduler;
public:
int nPriority;
- VDSchedulerNode() : nPriority(0) {}
+ VDSchedulerNode() : nPriority(0), mpScheduler(NULL) {}
virtual bool Service()=0;
virtual void DumpStatus();
- void Reschedule() { pScheduler->Reschedule(this); }
- void RemoveFromScheduler() { pScheduler->Remove(this); }
+ void Reschedule() { mpScheduler->Reschedule(this); }
+ void RemoveFromScheduler() { mpScheduler->Remove(this); }
protected:
- VDScheduler *pScheduler;
+ VDScheduler *mpScheduler;
volatile bool bRunning;
volatile bool bReschedule;
volatile bool bReady;
@@ -109,6 +109,8 @@ public:
};
class VDSchedulerThread : public VDThread {
+ VDSchedulerThread(const VDSchedulerThread&);
+ VDSchedulerThread& operator=(const VDSchedulerThread&);
public:
VDSchedulerThread();
~VDSchedulerThread();
@@ -122,4 +124,21 @@ protected:
uint32 mAffinity;
};
+class VDSchedulerThreadPool {
+ VDSchedulerThreadPool(const VDSchedulerThreadPool&);
+ VDSchedulerThreadPool& operator=(const VDSchedulerThreadPool&);
+public:
+ VDSchedulerThreadPool();
+ ~VDSchedulerThreadPool();
+
+ uint32 GetThreadCount() const { return mThreadCount; }
+
+ bool Start(VDScheduler *pScheduler);
+ bool Start(VDScheduler *pScheduler, uint32 threadCount);
+
+protected:
+ VDSchedulerThread *mpThreads;
+ uint32 mThreadCount;
+};
+
#endif
diff --git a/src/thirdparty/VirtualDub/h/vd2/system/VDString.h b/src/thirdparty/VirtualDub/h/vd2/system/VDString.h
index 58955384e..7fd2a7a1a 100644
--- a/src/thirdparty/VirtualDub/h/vd2/system/VDString.h
+++ b/src/thirdparty/VirtualDub/h/vd2/system/VDString.h
@@ -38,6 +38,7 @@
#include <vd2/system/vdtypes.h>
#include <vd2/system/text.h>
+#include <vd2/system/vdstl.h>
///////////////////////////////////////////////////////////////////////////
@@ -78,8 +79,8 @@ public:
const_iterator end() const { return mpEnd; }
// 21.3.3 capacity
- size_type size() const { return mpEnd - mpBegin; }
- size_type length() const { return mpEnd - mpBegin; }
+ size_type size() const { return (size_type)(mpEnd - mpBegin); }
+ size_type length() const { return (size_type)(mpEnd - mpBegin); }
bool empty() const { return mpBegin == mpEnd; }
// 21.3.4 element access
@@ -108,22 +109,58 @@ public:
VDASSERT(pos <= (size_type)(mpEnd - mpBegin));
const void *p = memchr(mpBegin + pos, c, mpEnd - (mpBegin + pos));
- return p ? (const value_type *)p - mpBegin : npos;
+ return p ? (size_type)((const value_type *)p - mpBegin) : npos;
+ }
+
+ size_type find_last_of(value_type c) const {
+ const value_type *s = mpEnd;
+
+ while(s != mpBegin) {
+ --s;
+
+ if (*s == c)
+ return (size_type)(s - mpBegin);
+ }
+
+ return npos;
}
int compare(const VDStringSpanA& s) const {
- size_type l1 = mpEnd - mpBegin;
- size_type l2 = s.mpEnd - s.mpBegin;
+ size_type l1 = (size_type)(mpEnd - mpBegin);
+ size_type l2 = (size_type)(s.mpEnd - s.mpBegin);
size_type lm = l1 < l2 ? l1 : l2;
int r = memcmp(mpBegin, s.mpBegin, lm);
- if (!r)
+ if (!r && l1 != l2)
r = (int)mpBegin[lm] - (int)s.mpBegin[lm];
return r;
}
+ int comparei(const char *s) const {
+ return comparei(VDStringSpanA(s));
+ }
+
+ int comparei(const VDStringSpanA& s) const {
+ size_type l1 = (size_type)(mpEnd - mpBegin);
+ size_type l2 = (size_type)(s.mpEnd - s.mpBegin);
+ size_type lm = l1 < l2 ? l1 : l2;
+
+ const char *p = mpBegin;
+ const char *q = s.mpBegin;
+
+ while(lm--) {
+ const unsigned char c = tolower((unsigned char)*p++);
+ const unsigned char d = tolower((unsigned char)*q++);
+
+ if (c != d)
+ return (int)c - (int)d;
+ }
+
+ return (int)l1 - (int)l2;
+ }
+
const VDStringSpanA trim(const value_type *s) const {
bool flags[256]={false};
@@ -233,6 +270,10 @@ public:
static_cast<VDStringSpanA&>(*this) = s;
}
+ void clear() {
+ mpBegin = mpEnd = NULL;
+ }
+
bool split(value_type c, VDStringRefA& token) {
size_type pos = find(c);
@@ -340,9 +381,9 @@ public:
resize_slow(n, current, v);
}
- size_type capacity() const { return mpEOS - mpBegin; }
+ size_type capacity() const { return (size_type)(mpEOS - mpBegin); }
- void reserve(size_t n) {
+ void reserve(size_type n) {
size_type current = (size_type)(mpEOS - mpBegin);
if (n > current)
@@ -432,6 +473,11 @@ public:
*mpEnd = 0;
}
+ void pop_back() {
+ --mpEnd;
+ *mpEnd = 0;
+ }
+
this_type& assign(const VDStringSpanA& str) {
return assign(str.begin(), str.end());
}
@@ -571,6 +617,8 @@ public:
this_type& append_sprintf(const value_type *format, ...);
this_type& append_vsprintf(const value_type *format, va_list val);
+ void move_from(VDStringA& src);
+
protected:
void push_back_extend();
void resize_slow(size_type n, size_type current_size);
@@ -585,7 +633,7 @@ protected:
inline VDStringA operator+(const VDStringA& str, const VDStringA& s) {
VDStringA result;
- result.reserve(str.size() + s.size());
+ result.reserve((VDStringA::size_type)(str.size() + s.size()));
result.assign(str);
result.append(s);
return result;
@@ -593,7 +641,7 @@ inline VDStringA operator+(const VDStringA& str, const VDStringA& s) {
inline VDStringA operator+(const VDStringA& str, const char *s) {
VDStringA result;
- result.reserve(str.size() + strlen(s));
+ result.reserve((VDStringA::size_type)(str.size() + strlen(s)));
result.assign(str);
result.append(s);
return result;
@@ -655,8 +703,8 @@ public:
const_iterator end() const { return mpEnd; }
// 21.3.3 capacity
- size_type size() const { return mpEnd - mpBegin; }
- size_type length() const { return mpEnd - mpBegin; }
+ size_type size() const { return (size_type)(mpEnd - mpBegin); }
+ size_type length() const { return (size_type)(mpEnd - mpBegin); }
bool empty() const { return mpBegin == mpEnd; }
// 21.3.4 element access
@@ -685,7 +733,42 @@ public:
VDASSERT(pos <= (size_type)(mpEnd - mpBegin));
const void *p = wmemchr(mpBegin + pos, c, mpEnd - (mpBegin + pos));
- return p ? (const value_type *)p - mpBegin : npos;
+ return p ? (size_type)((const value_type *)p - mpBegin) : npos;
+ }
+
+ int compare(const VDStringSpanW& s) const {
+ size_type l1 = (size_type)(mpEnd - mpBegin);
+ size_type l2 = (size_type)(s.mpEnd - s.mpBegin);
+ size_type lm = l1 < l2 ? l1 : l2;
+
+ for(size_type i = 0; i < lm; ++i) {
+ if (mpBegin[i] != s.mpBegin[i])
+ return mpBegin[i] < s.mpBegin[i] ? -1 : +1;
+ }
+
+ if (l1 == l2)
+ return 0;
+
+ return l1 < l2 ? -1 : +1;
+ }
+
+ int comparei(const VDStringSpanW& s) const {
+ size_type l1 = (size_type)(mpEnd - mpBegin);
+ size_type l2 = (size_type)(s.mpEnd - s.mpBegin);
+ size_type lm = l1 < l2 ? l1 : l2;
+
+ for(size_type i = 0; i < lm; ++i) {
+ wint_t c = towlower(mpBegin[i]);
+ wint_t d = towlower(s.mpBegin[i]);
+
+ if (c != d)
+ return c < d ? -1 : +1;
+ }
+
+ if (l1 == l2)
+ return 0;
+
+ return l1 < l2 ? -1 : +1;
}
// extensions
@@ -719,6 +802,22 @@ inline bool operator!=(const VDStringSpanW& x, const VDStringSpanW& y) { return
inline bool operator!=(const VDStringSpanW& x, const wchar_t *y) { return !(x == y); }
inline bool operator!=(const wchar_t *x, const VDStringSpanW& y) { return !(y == x); }
+inline bool operator<(const VDStringSpanW& x, const VDStringSpanW& y) {
+ return x.compare(y) < 0;
+}
+
+inline bool operator>(const VDStringSpanW& x, const VDStringSpanW& y) {
+ return x.compare(y) > 0;
+}
+
+inline bool operator<=(const VDStringSpanW& x, const VDStringSpanW& y) {
+ return x.compare(y) <= 0;
+}
+
+inline bool operator>=(const VDStringSpanW& x, const VDStringSpanW& y) {
+ return x.compare(y) >= 0;
+}
+
class VDStringRefW : public VDStringSpanW {
public:
typedef VDStringRefW this_type;
@@ -763,6 +862,10 @@ public:
static_cast<VDStringSpanW&>(*this) = s;
}
+ void clear() {
+ mpBegin = mpEnd = NULL;
+ }
+
bool split(value_type c, VDStringRefW& token) {
size_type pos = find(c);
@@ -865,9 +968,9 @@ public:
wmemset(mpBegin, v, n);
}
- size_type capacity() const { return mpEOS - mpBegin; }
+ size_type capacity() const { return (size_type)(mpEOS - mpBegin); }
- void reserve(size_t n) {
+ void reserve(size_type n) {
size_type current = (size_type)(mpEOS - mpBegin);
if (n > current)
@@ -956,6 +1059,11 @@ public:
*mpEnd = 0;
}
+ void pop_back() {
+ --mpEnd;
+ *mpEnd = 0;
+ }
+
this_type& assign(const this_type& str) {
return assign(str.mpBegin, str.mpEnd);
}
@@ -1091,6 +1199,8 @@ public:
this_type& append_sprintf(const value_type *format, ...);
this_type& append_vsprintf(const value_type *format, va_list val);
+ void move_from(VDStringW& src);
+
protected:
void push_back_extend();
void resize_slow(size_type n, size_type current_size);
@@ -1104,7 +1214,7 @@ protected:
inline VDStringW operator+(const VDStringW& str, const VDStringW& s) {
VDStringW result;
- result.reserve(str.size() + s.size());
+ result.reserve((VDStringA::size_type)(str.size() + s.size()));
result.assign(str);
result.append(s);
return result;
@@ -1112,7 +1222,7 @@ inline VDStringW operator+(const VDStringW& str, const VDStringW& s) {
inline VDStringW operator+(const VDStringW& str, const wchar_t *s) {
VDStringW result;
- result.reserve(str.size() + wcslen(s));
+ result.reserve((VDStringA::size_type)(str.size() + wcslen(s)));
result.assign(str);
result.append(s);
return result;
@@ -1130,5 +1240,10 @@ inline VDStringW operator+(const VDStringW& str, wchar_t c) {
typedef VDStringA VDString;
+template<> VDStringA *vdmove_forward(VDStringA *src1, VDStringA *src2, VDStringA *dst);
+template<> VDStringW *vdmove_forward(VDStringW *src1, VDStringW *src2, VDStringW *dst);
+template<> VDStringA *vdmove_backward(VDStringA *src1, VDStringA *src2, VDStringA *dst);
+template<> VDStringW *vdmove_backward(VDStringW *src1, VDStringW *src2, VDStringW *dst);
+
#endif
diff --git a/src/thirdparty/VirtualDub/h/vd2/system/atomic.h b/src/thirdparty/VirtualDub/h/vd2/system/atomic.h
index a7c2eb532..11c91dd0d 100644
--- a/src/thirdparty/VirtualDub/h/vd2/system/atomic.h
+++ b/src/thirdparty/VirtualDub/h/vd2/system/atomic.h
@@ -236,6 +236,42 @@ public:
};
///////////////////////////////////////////////////////////////////////////
+
+class VDAtomicBool {
+protected:
+ volatile char n;
+
+public:
+ VDAtomicBool() {}
+ VDAtomicBool(bool v) : n(v) {}
+
+ bool operator!=(bool v) const { return (n != 0) != v; }
+ bool operator==(bool v) const { return (n != 0) == v; }
+
+ bool operator=(bool v) { return n = v; }
+
+ operator bool() const {
+ return n != 0;
+ }
+
+ /// Atomic exchange.
+ bool xchg(bool v) {
+ const uint32 mask = ((uint32)0xFF << (int)((size_t)&n & 3));
+ const int andval = (int)~mask;
+ const int orval = (int)(mask & 0x01010101);
+ volatile int *p = (volatile int *)((uintptr)&n & ~(uintptr)3);
+
+ for(;;) {
+ const uint32 prevval = *p;
+ const uint32 newval = (prevval & andval) + orval;
+
+ if (prevval == VDAtomicInt::staticCompareExchange(p, newval, prevval))
+ return (prevval & mask) != 0;
+ }
+ }
+};
+
+///////////////////////////////////////////////////////////////////////////
/// \class VDAtomicPtr
/// \brief Wrapped pointer supporting thread-safe atomic operations.
///
diff --git a/src/thirdparty/VirtualDub/h/vd2/system/binary.h b/src/thirdparty/VirtualDub/h/vd2/system/binary.h
index 66542a516..fe3a5afa8 100644
--- a/src/thirdparty/VirtualDub/h/vd2/system/binary.h
+++ b/src/thirdparty/VirtualDub/h/vd2/system/binary.h
@@ -51,11 +51,11 @@
inline sint64 VDSwizzleS64(sint64 value) { return (sint32)_byteswap_uint64((unsigned __int64)value); }
#else
inline uint16 VDSwizzleU16(uint16 value) {
- return (value >> 8) + (value >> 8);
+ return (value >> 8) + (value << 8);
}
inline sint16 VDSwizzleS16(sint16 value) {
- return (sint16)(((uint16)value >> 8) + ((uint16)value >> 8));
+ return (sint16)(((uint16)value >> 8) + ((uint16)value << 8));
}
inline uint32 VDSwizzleU32(uint32 value) {
diff --git a/src/thirdparty/VirtualDub/h/vd2/system/bitmath.h b/src/thirdparty/VirtualDub/h/vd2/system/bitmath.h
index fc1c185a7..ebc3fa23b 100644
--- a/src/thirdparty/VirtualDub/h/vd2/system/bitmath.h
+++ b/src/thirdparty/VirtualDub/h/vd2/system/bitmath.h
@@ -39,6 +39,26 @@ int VDFindLowestSetBit(uint32 v);
int VDFindHighestSetBit(uint32 v);
uint32 VDCeilToPow2(uint32 v);
+union VDFloatAsInt {
+ float f;
+ sint32 i;
+};
+
+union VDIntAsFloat {
+ sint32 i;
+ float f;
+};
+
+inline sint32 VDGetFloatAsInt(float f) {
+ const VDFloatAsInt conv = { f };
+ return conv.i;
+}
+
+inline float VDGetIntAsFloat(sint32 i) {
+ const VDIntAsFloat conv = { i };
+ return conv.f;
+}
+
///////////////////////////////////////////////////////////////////////////////
#ifdef VD_COMPILER_MSVC_VC8
diff --git a/src/thirdparty/VirtualDub/h/vd2/system/cache.h b/src/thirdparty/VirtualDub/h/vd2/system/cache.h
index 8fbdea7c2..e4d45eb15 100644
--- a/src/thirdparty/VirtualDub/h/vd2/system/cache.h
+++ b/src/thirdparty/VirtualDub/h/vd2/system/cache.h
@@ -31,9 +31,9 @@
///////////////////////////////////////////////////////////////////////////
-struct vdhashmap_node {
- vdhashmap_node *mpHashPrev;
- vdhashmap_node *mpHashNext;
+struct vdfixedhashmap_node {
+ vdfixedhashmap_node *mpHashPrev;
+ vdfixedhashmap_node *mpHashNext;
};
template<class K>
@@ -44,17 +44,17 @@ struct vdhash {
};
template<class K, class V, class Hash = vdhash<K>, int N = 256>
-class vdhashmap_iterator {
+class vdfixedhashmap_iterator {
public:
- typedef vdhashmap_node node;
+ typedef vdfixedhashmap_node node;
- bool operator==(vdhashmap_iterator& x) const { return mpNode == x.mpNode; }
- bool operator!=(vdhashmap_iterator& x) const { return mpNode != x.mpNode; }
+ bool operator==(vdfixedhashmap_iterator& x) const { return mpNode == x.mpNode; }
+ bool operator!=(vdfixedhashmap_iterator& x) const { return mpNode != x.mpNode; }
V& operator*() const { return *static_cast<V *>((node *)mpNode); }
V *operator->() const { return static_cast<V *>((node *)mpNode); }
- vdhashmap_iterator& operator++() {
+ vdfixedhashmap_iterator& operator++() {
do {
mpNode = ((node *)mpNode)->mpHashNext;
if (mpNode != mpTableNode)
@@ -67,27 +67,27 @@ public:
return *this;
}
- vdhashmap_iterator operator++(int) {
- vdhashmap_iterator it(*this);
+ vdfixedhashmap_iterator operator++(int) {
+ vdfixedhashmap_iterator it(*this);
++*this;
return it;
}
public:
- vdhashmap_node *mpNode;
- vdhashmap_node *mpTableNode;
+ vdfixedhashmap_node *mpNode;
+ vdfixedhashmap_node *mpTableNode;
};
template<class K, class V, class Hash = vdhash<K>, int N = 256>
-class vdhashmap {
+class vdfixedhashmap {
public:
typedef K key_type;
typedef V value_type;
typedef Hash hash_type;
- typedef vdhashmap_node node;
- typedef vdhashmap_iterator<K, V> iterator;
+ typedef vdfixedhashmap_node node;
+ typedef vdfixedhashmap_iterator<K, V> iterator;
- vdhashmap() {
+ vdfixedhashmap() {
for(int i=0; i<N; ++i)
m.mpTable[i].mpHashPrev = m.mpTable[i].mpHashNext = &m.mpTable[i];
}
@@ -159,7 +159,7 @@ public:
protected:
struct Data : public Hash {
- vdhashmap_node mpTable[N];
+ vdfixedhashmap_node mpTable[N];
} m;
};
@@ -185,7 +185,7 @@ enum VDCacheState {
kVDCacheStateCount
};
-struct VDCachedObjectNodes : public vdlist_node, public vdhashmap_node {
+struct VDCachedObjectNodes : public vdlist_node, public vdfixedhashmap_node {
sint64 mHashKey;
};
@@ -223,7 +223,7 @@ protected:
typedef vdlist<VDCachedObjectNodes> ObjectList;
ObjectList mLists[kVDCacheStateCount];
- vdhashmap<sint64, VDCachedObjectNodes> mHash;
+ vdfixedhashmap<sint64, VDCachedObjectNodes> mHash;
};
///////////////////////////////////////////////////////////////////////////
diff --git a/src/thirdparty/VirtualDub/h/vd2/system/cmdline.h b/src/thirdparty/VirtualDub/h/vd2/system/cmdline.h
index eb1d94480..0eb461308 100644
--- a/src/thirdparty/VirtualDub/h/vd2/system/cmdline.h
+++ b/src/thirdparty/VirtualDub/h/vd2/system/cmdline.h
@@ -28,6 +28,8 @@
#include <vd2/system/vdstl.h>
+class VDStringSpanW;
+
class VDCommandLineIterator {
friend class VDCommandLine;
public:
@@ -47,6 +49,7 @@ public:
uint32 GetCount() const;
const wchar_t *operator[](int index) const;
+ const VDStringSpanW operator()(int index) const;
bool GetNextArgument(VDCommandLineIterator& index, const wchar_t *& token, bool& isSwitch) const;
bool GetNextNonSwitchArgument(VDCommandLineIterator& index, const wchar_t *& token) const;
@@ -55,6 +58,8 @@ public:
bool FindAndRemoveSwitch(const wchar_t *name, const wchar_t *& token);
protected:
+ void RemoveArgument(int index);
+
vdfastvector<wchar_t> mLine;
struct Token {
diff --git a/src/thirdparty/VirtualDub/h/vd2/system/date.h b/src/thirdparty/VirtualDub/h/vd2/system/date.h
new file mode 100644
index 000000000..ce9dd5cd3
--- /dev/null
+++ b/src/thirdparty/VirtualDub/h/vd2/system/date.h
@@ -0,0 +1,60 @@
+// VirtualDub - Video processing and capture application
+// System library component
+// Copyright (C) 1998-2011 Avery Lee, All Rights Reserved.
+//
+// Beginning with 1.6.0, the VirtualDub system library is licensed
+// differently than the remainder of VirtualDub. This particular file is
+// thus licensed as follows (the "zlib" license):
+//
+// This software is provided 'as-is', without any express or implied
+// warranty. In no event will the authors be held liable for any
+// damages arising from the use of this software.
+//
+// Permission is granted to anyone to use this software for any purpose,
+// including commercial applications, and to alter it and redistribute it
+// freely, subject to the following restrictions:
+//
+// 1. The origin of this software must not be misrepresented; you must
+// not claim that you wrote the original software. If you use this
+// software in a product, an acknowledgment in the product
+// documentation would be appreciated but is not required.
+// 2. Altered source versions must be plainly marked as such, and must
+// not be misrepresented as being the original software.
+// 3. This notice may not be removed or altered from any source
+// distribution.
+
+#ifndef f_VD2_SYSTEM_DATE_H
+#define f_VD2_SYSTEM_DATE_H
+
+#include <vd2/system/vdtypes.h>
+
+class VDStringW;
+
+struct VDDate {
+ uint64 mTicks;
+
+ bool operator==(const VDDate& x) const { return mTicks == x.mTicks; }
+ bool operator!=(const VDDate& x) const { return mTicks != x.mTicks; }
+ bool operator< (const VDDate& x) const { return mTicks < x.mTicks; }
+ bool operator> (const VDDate& x) const { return mTicks > x.mTicks; }
+ bool operator<=(const VDDate& x) const { return mTicks <= x.mTicks; }
+ bool operator>=(const VDDate& x) const { return mTicks >= x.mTicks; }
+};
+
+struct VDExpandedDate {
+ uint32 mYear;
+ uint8 mMonth;
+ uint8 mDayOfWeek;
+ uint8 mDay;
+ uint8 mHour;
+ uint8 mMinute;
+ uint8 mSecond;
+ uint16 mMilliseconds;
+};
+
+VDDate VDGetCurrentDate();
+VDExpandedDate VDGetLocalDate(const VDDate& date);
+void VDAppendLocalDateString(VDStringW& dst, const VDExpandedDate& date);
+void VDAppendLocalTimeString(VDStringW& dst, const VDExpandedDate& date);
+
+#endif // f_VD2_SYSTEM_DATE_H
diff --git a/src/thirdparty/VirtualDub/h/vd2/system/event.h b/src/thirdparty/VirtualDub/h/vd2/system/event.h
index a725f8d43..b43824507 100644
--- a/src/thirdparty/VirtualDub/h/vd2/system/event.h
+++ b/src/thirdparty/VirtualDub/h/vd2/system/event.h
@@ -118,7 +118,7 @@ struct VDDelegateAdapterM {
static void Init(VDDelegate& dst, T_Fn2 fn) {
dst.mpCallback = Fn2;
- dst.mpFnM = reinterpret_cast<void(VDDelegateHolderM::*)()>(fn2);
+ dst.mpFnM = reinterpret_cast<void(VDDelegateHolderM::*)()>(fn);
}
static void Fn(void *src, const void *info, VDDelegate& del) {
@@ -189,8 +189,8 @@ public:
Add(*binding.mpBoundDelegate);
}
- void operator-=(const VDDelegateBinding<Source, ArgType>& binding) {
- Remove(*binding.mpBoundDelegate);
+ void operator-=(VDDelegate& del) {
+ Remove(del);
}
void Raise(Source *src, const ArgType& args) {
diff --git a/src/thirdparty/VirtualDub/h/vd2/system/file.h b/src/thirdparty/VirtualDub/h/vd2/system/file.h
index bfdfab44e..166b0d416 100644
--- a/src/thirdparty/VirtualDub/h/vd2/system/file.h
+++ b/src/thirdparty/VirtualDub/h/vd2/system/file.h
@@ -35,7 +35,6 @@
#include <vd2/system/vdtypes.h>
#include <vd2/system/vdalloc.h>
#include <vd2/system/vdstl.h>
-#include <vector>
#ifdef WIN32
typedef void *VDFileHandle; // this needs to match wtypes.h definition for HANDLE
@@ -133,6 +132,9 @@ public:
void skip(sint64 delta);
sint64 tell();
+ bool flushNT();
+ void flush();
+
bool isOpen();
VDFileHandle getRawHandle();
@@ -304,13 +306,15 @@ public:
void Flush();
+ void Write(const char *s);
void Write(const char *s, int len);
void PutLine();
void PutLine(const char *s);
+ void Format(const char *format, ...);
void FormatLine(const char *format, ...);
protected:
- void FormatLine2(const char *format, va_list val);
+ void Format2(const char *format, va_list val);
void PutData(const char *s, int len);
enum { kBufSize = 4096 };
diff --git a/src/thirdparty/VirtualDub/h/vd2/system/fileasync.h b/src/thirdparty/VirtualDub/h/vd2/system/fileasync.h
index 7693aa30f..cb46036f1 100644
--- a/src/thirdparty/VirtualDub/h/vd2/system/fileasync.h
+++ b/src/thirdparty/VirtualDub/h/vd2/system/fileasync.h
@@ -31,6 +31,7 @@
#endif
#include <vd2/system/vdtypes.h>
+#include <vd2/system/file.h>
class VDRTProfileChannel;
@@ -48,6 +49,7 @@ public:
virtual bool IsPreemptiveExtendActive() = 0;
virtual bool IsOpen() = 0;
virtual void Open(const wchar_t *pszFilename, uint32 count, uint32 bufferSize) = 0;
+ virtual void Open(VDFileHandle h, uint32 count, uint32 bufferSize) = 0;
virtual void Close() = 0;
virtual void FastWrite(const void *pData, uint32 bytes) = 0;
virtual void FastWriteEnd() = 0;
diff --git a/src/thirdparty/VirtualDub/h/vd2/system/filesys.h b/src/thirdparty/VirtualDub/h/vd2/system/filesys.h
index 4aa830833..10e529501 100644
--- a/src/thirdparty/VirtualDub/h/vd2/system/filesys.h
+++ b/src/thirdparty/VirtualDub/h/vd2/system/filesys.h
@@ -29,6 +29,8 @@
#include <ctype.h>
#include <vector>
+#include <vd2/system/date.h>
+#include <vd2/system/vdstl.h>
#include <vd2/system/vdtypes.h>
#include <vd2/system/VDString.h>
@@ -112,11 +114,74 @@ bool VDFileWildMatch(const wchar_t *pattern, const wchar_t *path);
/////////////////////////////////////////////////////////////////////////////
+inline bool VDIsPathSeparator(const char c) {
+ return c == ':' || c == '/' || c == '\\';
+}
+
+inline bool VDIsPathSeparator(const wchar_t c) {
+ return c == L':' || c == L'/' || c == L'\\';
+}
+
+class VDParsedPath {
+public:
+ VDParsedPath();
+ VDParsedPath(const wchar_t *path);
+
+ bool IsRelative() const { return mbIsRelative; }
+ VDStringW ToString() const;
+
+ const wchar_t *GetRoot() const { return mRoot.c_str(); }
+ size_t GetComponentCount() const { return mComponents.size(); }
+ const wchar_t *GetComponent(size_t i) const { return mComponents[i].c_str(); }
+ const wchar_t *GetStream() const { return mStream.c_str(); }
+
+ void SetRoot() { mbIsRelative = true; }
+ void SetRoot(const wchar_t *s) { mRoot = s; mbIsRelative = mRoot.empty() || mRoot.back() == L':'; }
+ void SetStream(const wchar_t *s) { mStream = s; }
+
+ void RemoveLastComponent() { if (!mComponents.empty()) mComponents.pop_back(); }
+ void AddComponent(const wchar_t *s) { mComponents.push_back_as(s); }
+
+protected:
+ bool mbIsRelative;
+ VDStringW mRoot;
+ VDStringW mStream;
+
+ typedef vdvector<VDStringW> Components;
+ Components mComponents;
+};
+
+/// Given a valid path, return the same path in canonical form. This
+/// collapses redundant backslashes, removes any on the end, and evaluates
+/// any ..\ and .\ sections. It is useful for comparing paths.
+VDStringW VDFileGetCanonicalPath(const wchar_t *path);
+
+/// Given a base path, attempt to convert a path to a relative path. The
+/// empty string is returned if the conversion fails. Both paths must be
+/// absolute paths; conversion fails if either is relative.
+///
+/// Note that this conversion will work even if the path to convert is above
+/// the base path; ..\ sections will be added as needed as long as the
+/// allowAscent flag is set.
+VDStringW VDFileGetRelativePath(const wchar_t *basePath, const wchar_t *pathToConvert, bool allowAscent);
+
+/// Returns true if the given path is a relative path.
+bool VDFileIsRelativePath(const wchar_t *path);
+
+/// Resolves a possibly relatively path with a given base path. If the path
+/// is absolute, the base path is ignored.
+VDStringW VDFileResolvePath(const wchar_t *basePath, const wchar_t *pathToResolve);
+
+/////////////////////////////////////////////////////////////////////////////
+
sint64 VDGetDiskFreeSpace(const wchar_t *path);
void VDCreateDirectory(const wchar_t *path);
+void VDRemoveDirectory(const wchar_t *path);
extern bool (*VDRemoveFile)(const wchar_t *path);
+void VDMoveFile(const wchar_t *srcPath, const wchar_t *dstPath);
+
bool VDDoesPathExist(const wchar_t *fileName);
uint64 VDFileGetLastWriteTime(const wchar_t *path);
@@ -124,9 +189,26 @@ VDStringW VDFileGetRootPath(const wchar_t *partialPath);
VDStringW VDGetFullPath(const wchar_t *partialPath);
VDStringW VDMakePath(const wchar_t *base, const wchar_t *file);
+bool VDFileIsPathEqual(const wchar_t *path1, const wchar_t *path2);
void VDFileFixDirPath(VDStringW& path);
VDStringW VDGetLocalModulePath();
VDStringW VDGetProgramPath();
+VDStringW VDGetProgramFilePath();
+VDStringW VDGetSystemPath();
+
+/////////////////////////////////////////////////////////////////////////////
+
+enum VDFileAttributes {
+ kVDFileAttr_ReadOnly = 0x01,
+ kVDFileAttr_System = 0x02,
+ kVDFileAttr_Hidden = 0x04,
+ kVDFileAttr_Archive = 0x08,
+ kVDFileAttr_Directory = 0x10,
+ kVDFileAttr_Invalid = 0xFFFFFFFFU
+};
+
+uint32 VDFileGetAttributes(const wchar_t *path);
+void VDFileSetAttributes(const wchar_t *path, uint32 attrsToChange, uint32 newAttrs);
/////////////////////////////////////////////////////////////////////////////
@@ -139,6 +221,9 @@ public:
bool Next();
+ // checks for . and .. directories
+ bool IsDotDirectory() const;
+
bool IsDirectory() const {
return mbDirectory;
}
@@ -155,6 +240,14 @@ public:
return mFileSize;
}
+ VDDate GetLastWriteDate() const {
+ return mLastWriteDate;
+ }
+
+ uint32 GetAttributes() const {
+ return mAttributes;
+ }
+
protected:
void *mpHandle;
bool mbSearchComplete;
@@ -165,6 +258,9 @@ protected:
VDStringW mFilename;
sint64 mFileSize;
bool mbDirectory;
+ uint32 mAttributes;
+
+ VDDate mLastWriteDate;
};
#endif
diff --git a/src/thirdparty/VirtualDub/h/vd2/system/hash.h b/src/thirdparty/VirtualDub/h/vd2/system/hash.h
index d5f3612e1..9b93f3e2c 100644
--- a/src/thirdparty/VirtualDub/h/vd2/system/hash.h
+++ b/src/thirdparty/VirtualDub/h/vd2/system/hash.h
@@ -38,9 +38,13 @@
uint32 VDHashString32(const char *s);
uint32 VDHashString32(const char *s, uint32 len);
+uint32 VDHashString32(const wchar_t *s);
+uint32 VDHashString32(const wchar_t *s, uint32 len);
// Case-insensitive, culture-invariant string hashes
+uint32 VDHashString32I(const char *s);
+uint32 VDHashString32I(const char *s, uint32 len);
uint32 VDHashString32I(const wchar_t *s);
uint32 VDHashString32I(const wchar_t *s, uint32 len);
diff --git a/src/thirdparty/VirtualDub/h/vd2/system/linearalloc.h b/src/thirdparty/VirtualDub/h/vd2/system/linearalloc.h
new file mode 100644
index 000000000..8d2570c8e
--- /dev/null
+++ b/src/thirdparty/VirtualDub/h/vd2/system/linearalloc.h
@@ -0,0 +1,84 @@
+#ifndef f_VD2_SYSTEM_LINEARALLOC_H
+#define f_VD2_SYSTEM_LINEARALLOC_H
+
+#include <new>
+
+class VDLinearAllocator {
+public:
+ explicit VDLinearAllocator(uint32 blockSize = 4096);
+ ~VDLinearAllocator();
+
+ void *Allocate(size_t bytes) {
+ void *p = mpAllocPtr;
+
+ if (mAllocLeft < bytes)
+ p = AllocateSlow(bytes);
+ else {
+ mAllocLeft -= bytes;
+ mpAllocPtr += bytes;
+ }
+
+ return p;
+ }
+
+ template<class T>
+ T *Allocate() {
+ return new(Allocate(sizeof(T))) T;
+ }
+
+ template<class T, class A1>
+ T *Allocate(const A1& a1) {
+ return new(Allocate(sizeof(T))) T(a1);
+ }
+
+ template<class T, class A1, class A2>
+ T *Allocate(const A1& a1, const A2& a2) {
+ return new(Allocate(sizeof(T))) T(a1, a2);
+ }
+
+ template<class T, class A1, class A2, class A3>
+ T *Allocate(const A1& a1, const A2& a2, const A3& a3) {
+ return new(Allocate(sizeof(T))) T(a1, a2, a3);
+ }
+
+protected:
+ void *AllocateSlow(size_t bytes);
+
+ union Block {
+ Block *mpNext;
+ double mAlign;
+ };
+
+ Block *mpBlocks;
+ char *mpAllocPtr;
+ size_t mAllocLeft;
+ size_t mBlockSize;
+};
+
+class VDFixedLinearAllocator {
+public:
+ VDFixedLinearAllocator(void *mem, size_t size)
+ : mpAllocPtr((char *)mem)
+ , mAllocLeft(size)
+ {
+ }
+
+ void *Allocate(size_t bytes) {
+ void *p = mpAllocPtr;
+
+ if (mAllocLeft < bytes)
+ ThrowException();
+
+ mAllocLeft -= bytes;
+ mpAllocPtr += bytes;
+ return p;
+ }
+
+protected:
+ void ThrowException();
+
+ char *mpAllocPtr;
+ size_t mAllocLeft;
+};
+
+#endif
diff --git a/src/thirdparty/VirtualDub/h/vd2/system/log.h b/src/thirdparty/VirtualDub/h/vd2/system/log.h
index b36e36e7e..ebe021ede 100644
--- a/src/thirdparty/VirtualDub/h/vd2/system/log.h
+++ b/src/thirdparty/VirtualDub/h/vd2/system/log.h
@@ -31,13 +31,14 @@
class IVDLogger {
public:
- virtual void AddLogEntry(int severity, const VDStringW& s) = 0;
+ virtual void AddLogEntry(int severity, const wchar_t *s) = 0;
};
enum {
kVDLogInfo, kVDLogMarker, kVDLogWarning, kVDLogError
};
+void VDLog(int severity, const wchar_t *format);
void VDLog(int severity, const VDStringW& s);
void VDLogF(int severity, const wchar_t *format, ...);
void VDAttachLogger(IVDLogger *pLogger, bool bThisThreadOnly, bool bReplayLog);
@@ -49,7 +50,7 @@ public:
int severity;
VDStringW text;
- Entry(int sev, const VDStringW& s) : severity(sev), text(s) {}
+ Entry(int sev, const wchar_t *s) : severity(sev), text(s) {}
};
typedef std::list<Entry> tEntries;
@@ -57,7 +58,7 @@ public:
VDAutoLogger(int min_severity);
~VDAutoLogger();
- void AddLogEntry(int severity, const VDStringW& s);
+ void AddLogEntry(int severity, const wchar_t *s);
const tEntries& GetEntries();
diff --git a/src/thirdparty/VirtualDub/h/vd2/system/math.h b/src/thirdparty/VirtualDub/h/vd2/system/math.h
index aa4d03f77..c395bcbc7 100644
--- a/src/thirdparty/VirtualDub/h/vd2/system/math.h
+++ b/src/thirdparty/VirtualDub/h/vd2/system/math.h
@@ -212,13 +212,14 @@ inline sint32 VDRoundToIntFastFullRange(double x) {
#endif
///////////////////////////////////////////////////////////////////////////
+/// Convert a value from [-~1..1] to [-32768, 32767] with clamping.
inline sint16 VDClampedRoundFixedToInt16Fast(float x) {
union {
float f;
sint32 i;
- } u = {x + 384.0f}; // 2^7+2^8
+ } u = {x * 65535.0f + 12582912.0f}; // 2^22+2^23
- sint32 v = (sint32)u.i - 0x43BF8000;
+ sint32 v = (sint32)u.i - 0x4B3F8000;
if ((uint32)v >= 0x10000)
v = ~v >> 31;
@@ -226,6 +227,7 @@ inline sint16 VDClampedRoundFixedToInt16Fast(float x) {
return (sint16)(v - 0x8000);
}
+/// Convert a value from [0..1] to [0..255] with clamping.
inline uint8 VDClampedRoundFixedToUint8Fast(float x) {
union {
float f;
@@ -234,7 +236,7 @@ inline uint8 VDClampedRoundFixedToUint8Fast(float x) {
sint32 v = (sint32)u.i - 0x4B400000;
- if ((uint32)v >= 0xFF)
+ if ((uint32)v >= 0x100)
v = ~v >> 31;
return (uint8)v;
diff --git a/src/thirdparty/VirtualDub/h/vd2/system/process.h b/src/thirdparty/VirtualDub/h/vd2/system/process.h
new file mode 100644
index 000000000..cfc7d514d
--- /dev/null
+++ b/src/thirdparty/VirtualDub/h/vd2/system/process.h
@@ -0,0 +1,33 @@
+// VirtualDub - Video processing and capture application
+// System library component
+// Copyright (C) 1998-2011 Avery Lee, All Rights Reserved.
+//
+// Beginning with 1.6.0, the VirtualDub system library is licensed
+// differently than the remainder of VirtualDub. This particular file is
+// thus licensed as follows (the "zlib" license):
+//
+// This software is provided 'as-is', without any express or implied
+// warranty. In no event will the authors be held liable for any
+// damages arising from the use of this software.
+//
+// Permission is granted to anyone to use this software for any purpose,
+// including commercial applications, and to alter it and redistribute it
+// freely, subject to the following restrictions:
+//
+// 1. The origin of this software must not be misrepresented; you must
+// not claim that you wrote the original software. If you use this
+// software in a product, an acknowledgment in the product
+// documentation would be appreciated but is not required.
+// 2. Altered source versions must be plainly marked as such, and must
+// not be misrepresented as being the original software.
+// 3. This notice may not be removed or altered from any source
+// distribution.
+
+#ifndef f_VD2_SYSTEM_PROCESS_H
+#define f_VD2_SYSTEM_PROCESS_H
+
+/// Simple asynchronous program launch -- no arguments. The current directory
+/// defaults to the windows directory to prevent inadvernent locking.
+void VDLaunchProgram(const wchar_t *path);
+
+#endif // f_VD2_SYSTEM_PROCESS_H
diff --git a/src/thirdparty/VirtualDub/h/vd2/system/profile.h b/src/thirdparty/VirtualDub/h/vd2/system/profile.h
index ff4f1b3d7..b5c2cfca9 100644
--- a/src/thirdparty/VirtualDub/h/vd2/system/profile.h
+++ b/src/thirdparty/VirtualDub/h/vd2/system/profile.h
@@ -163,5 +163,37 @@ protected:
int mProfileChannel;
};
+///////////////////////////////////////////////////////////////////////////
+
+class IVDEventProfiler {
+public:
+ virtual void BeginScope(const char *name, uintptr *cache, uint32 data) = 0;
+ virtual void BeginDynamicScope(const char *name, uintptr *cache, uint32 data) = 0;
+ virtual void EndScope() = 0;
+ virtual void ExitThread() = 0;
+};
+
+extern IVDEventProfiler *g_pVDEventProfiler;
+
+class VDProfileEventAutoEndScope {
+public:
+ ~VDProfileEventAutoEndScope() {
+ if (g_pVDEventProfiler)
+ g_pVDEventProfiler->EndScope();
+ }
+};
+
+struct VDProfileCachedEvent;
+
+typedef uintptr VDProfileEventCache;
+
+#define VDPROFILEBEGINDYNAMIC(cache, dynLabel) if (true) { if (g_pVDEventProfiler) g_pVDEventProfiler->BeginDynamicScope((dynLabel), &(cache), 0); } else ((void)0)
+#define VDPROFILEBEGINDYNAMICEX(cache, dynLabel, data) if (true) { if (g_pVDEventProfiler) g_pVDEventProfiler->BeginDynamicScope((dynLabel), &(cache), data); } else ((void)0)
+#define VDPROFILEBEGIN(label) if (true) { static uintptr sCache = NULL; if (g_pVDEventProfiler) g_pVDEventProfiler->BeginScope((label), &sCache, 0); } else ((void)0)
+#define VDPROFILEBEGINEX(label, data) if (true) { static uintptr sCache = NULL; if (g_pVDEventProfiler) g_pVDEventProfiler->BeginScope((label), &sCache, data); } else ((void)0)
+#define VDPROFILEEND() if (g_pVDEventProfiler) g_pVDEventProfiler->EndScope(); else ((void)0)
+#define VDPROFILEAUTOEND() VDProfileEventAutoEndScope _autoEndScope
+#define VDPROFILESCOPE(label) VDPROFILEBEGIN(label); VDPROFILEAUTOEND()
+
#endif
diff --git a/src/thirdparty/VirtualDub/h/vd2/system/refcount.h b/src/thirdparty/VirtualDub/h/vd2/system/refcount.h
index 654cbe24c..e2bd70f57 100644
--- a/src/thirdparty/VirtualDub/h/vd2/system/refcount.h
+++ b/src/thirdparty/VirtualDub/h/vd2/system/refcount.h
@@ -87,6 +87,35 @@ public:
};
///////////////////////////////////////////////////////////////////////////
+class vdrefcount {
+public:
+ vdrefcount() : mRefCount(0) {}
+ vdrefcount(const vdrefcount& src) : mRefCount(0) {} // do not copy the refcount
+ virtual ~vdrefcount() {}
+
+ vdrefcount& operator=(const vdrefcount&) {} // do not copy the refcount
+
+ int AddRef() {
+ return mRefCount.inc();
+ }
+
+ int Release() {
+ int rc = --mRefCount;
+
+ if (!rc) {
+ delete this;
+ return 0;
+ }
+
+ VDASSERT(rc > 0);
+ return rc;
+ }
+
+protected:
+ VDAtomicInt mRefCount;
+};
+
+///////////////////////////////////////////////////////////////////////////
// vdrefcounted<T>
/// Implements thread-safe reference counting on top of a base class.
///
diff --git a/src/thirdparty/VirtualDub/h/vd2/system/registry.h b/src/thirdparty/VirtualDub/h/vd2/system/registry.h
index c9ee119da..2a8ebec3d 100644
--- a/src/thirdparty/VirtualDub/h/vd2/system/registry.h
+++ b/src/thirdparty/VirtualDub/h/vd2/system/registry.h
@@ -28,46 +28,117 @@
#include <vd2/system/VDString.h>
-class VDRegistryKey {
-private:
- void *pHandle;
+class IVDRegistryProvider {
+public:
+ enum Type {
+ kTypeUnknown,
+ kTypeInt,
+ kTypeString,
+ kTypeBinary
+ };
+
+ virtual void *GetMachineKey() = 0;
+ virtual void *GetUserKey() = 0;
+ virtual void *CreateKey(void *key, const char *path, bool write) = 0;
+ virtual void CloseKey(void *key) = 0;
+
+ virtual bool SetBool(void *key, const char *name, bool) = 0;
+ virtual bool SetInt(void *key, const char *name, int) = 0;
+ virtual bool SetString(void *key, const char *name, const char *pszString) = 0;
+ virtual bool SetString(void *key, const char *name, const wchar_t *pszString) = 0;
+ virtual bool SetBinary(void *key, const char *name, const char *data, int len) = 0;
+
+ virtual Type GetType(void *key, const char *name) = 0;
+ virtual bool GetBool(void *key, const char *name, bool& val) = 0;
+ virtual bool GetInt(void *key, const char *name, int& val) = 0;
+ virtual bool GetString(void *key, const char *name, VDStringA& s) = 0;
+ virtual bool GetString(void *key, const char *name, VDStringW& s) = 0;
+
+ virtual int GetBinaryLength(void *key, const char *name) = 0;
+ virtual bool GetBinary(void *key, const char *name, char *buf, int maxlen) = 0;
+
+ virtual bool RemoveValue(void *key, const char *name) = 0;
+ virtual bool RemoveKey(void *key, const char *name) = 0;
+
+ virtual void *EnumKeysBegin(void *key) = 0;
+ virtual const char *EnumKeysNext(void *enumerator) = 0;
+ virtual void EnumKeysClose(void *enumerator) = 0;
+
+ virtual void *EnumValuesBegin(void *key) = 0;
+ virtual const char *EnumValuesNext(void *enumerator) = 0;
+ virtual void EnumValuesClose(void *enumerator) = 0;
+};
+
+IVDRegistryProvider *VDGetRegistryProvider();
+void VDSetRegistryProvider(IVDRegistryProvider *provider);
+///////////////////////////////////////////////////////////////////////////
+
+class VDRegistryKey {
public:
+ enum Type {
+ kTypeUnknown,
+ kTypeInt,
+ kTypeString,
+ kTypeBinary
+ };
+
VDRegistryKey(const char *pszKey, bool global = false, bool write = true);
+ VDRegistryKey(VDRegistryKey& baseKey, const char *name, bool write = true);
~VDRegistryKey();
- void *getRawHandle() const { return pHandle; }
+ void *getRawHandle() const { return mKey; }
+
+ bool isReady() const { return mKey != 0; }
- bool isReady() const { return pHandle != 0; }
+ bool setBool(const char *name, bool) const;
+ bool setInt(const char *name, int) const;
+ bool setString(const char *name, const char *pszString) const;
+ bool setString(const char *name, const wchar_t *pszString) const;
+ bool setBinary(const char *name, const char *data, int len) const;
- bool setBool(const char *pszName, bool) const;
- bool setInt(const char *pszName, int) const;
- bool setString(const char *pszName, const char *pszString) const;
- bool setString(const char *pszName, const wchar_t *pszString) const;
- bool setBinary(const char *pszName, const char *data, int len) const;
+ Type getValueType(const char *name) const;
- bool getBool(const char *pszName, bool def=false) const;
- int getInt(const char *pszName, int def=0) const;
- int getEnumInt(const char *pszName, int maxVal, int def=0) const;
- bool getString(const char *pszName, VDStringA& s) const;
- bool getString(const char *pszName, VDStringW& s) const;
+ bool getBool(const char *name, bool def=false) const;
+ int getInt(const char *name, int def=0) const;
+ int getEnumInt(const char *name, int maxVal, int def=0) const;
+ bool getString(const char *name, VDStringA& s) const;
+ bool getString(const char *name, VDStringW& s) const;
- int getBinaryLength(const char *pszName) const;
- bool getBinary(const char *pszName, char *buf, int maxlen) const;
+ int getBinaryLength(const char *name) const;
+ bool getBinary(const char *name, char *buf, int maxlen) const;
bool removeValue(const char *);
+ bool removeKey(const char *);
+
+private:
+ void *mKey;
};
class VDRegistryValueIterator {
+ VDRegistryValueIterator(const VDRegistryValueIterator&);
+ VDRegistryValueIterator& operator=(const VDRegistryValueIterator&);
public:
VDRegistryValueIterator(const VDRegistryKey& key);
+ ~VDRegistryValueIterator();
+
+ const char *Next();
+
+protected:
+ void *mEnumerator;
+};
+
+class VDRegistryKeyIterator {
+ VDRegistryKeyIterator(const VDRegistryKeyIterator& key);
+ VDRegistryKeyIterator& operator=(const VDRegistryKeyIterator& key);
+public:
+ VDRegistryKeyIterator(const VDRegistryKey& key);
+ ~VDRegistryKeyIterator();
const char *Next();
protected:
- void *mpHandle;
- uint32 mIndex;
- char mName[256];
+ void *mEnumerator;
};
class VDRegistryAppKey : public VDRegistryKey {
diff --git a/src/thirdparty/VirtualDub/h/vd2/system/registrymemory.h b/src/thirdparty/VirtualDub/h/vd2/system/registrymemory.h
new file mode 100644
index 000000000..38e2a9c45
--- /dev/null
+++ b/src/thirdparty/VirtualDub/h/vd2/system/registrymemory.h
@@ -0,0 +1,81 @@
+// VirtualDub - Video processing and capture application
+// System library component
+// Copyright (C) 1998-2010 Avery Lee, All Rights Reserved.
+//
+// Beginning with 1.6.0, the VirtualDub system library is licensed
+// differently than the remainder of VirtualDub. This particular file is
+// thus licensed as follows (the "zlib" license):
+//
+// This software is provided 'as-is', without any express or implied
+// warranty. In no event will the authors be held liable for any
+// damages arising from the use of this software.
+//
+// Permission is granted to anyone to use this software for any purpose,
+// including commercial applications, and to alter it and redistribute it
+// freely, subject to the following restrictions:
+//
+// 1. The origin of this software must not be misrepresented; you must
+// not claim that you wrote the original software. If you use this
+// software in a product, an acknowledgment in the product
+// documentation would be appreciated but is not required.
+// 2. Altered source versions must be plainly marked as such, and must
+// not be misrepresented as being the original software.
+// 3. This notice may not be removed or altered from any source
+// distribution.
+
+#ifndef f_VD2_SYSTEM_REGISTRYMEMORY_H
+#define f_VD2_SYSTEM_REGISTRYMEMORY_H
+
+#include <vd2/system/registry.h>
+#include <vd2/system/thread.h>
+#include <vd2/system/VDString.h>
+#include <vd2/system/vdstl.h>
+
+class VDRegistryProviderMemory : public IVDRegistryProvider {
+public:
+ VDRegistryProviderMemory();
+ ~VDRegistryProviderMemory();
+
+ void *GetMachineKey();
+ void *GetUserKey();
+ void *CreateKey(void *key, const char *path, bool write);
+ void CloseKey(void *key);
+
+ bool SetBool(void *key, const char *name, bool);
+ bool SetInt(void *key, const char *name, int);
+ bool SetString(void *key, const char *name, const char *str);
+ bool SetString(void *key, const char *name, const wchar_t *str);
+ bool SetBinary(void *key, const char *name, const char *data, int len);
+
+ Type GetType(void *key, const char *name);
+ bool GetBool(void *key, const char *name, bool& val);
+ bool GetInt(void *key, const char *name, int& val);
+ bool GetString(void *key, const char *name, VDStringA& s);
+ bool GetString(void *key, const char *name, VDStringW& s);
+
+ int GetBinaryLength(void *key, const char *name);
+ bool GetBinary(void *key, const char *name, char *buf, int maxlen);
+
+ bool RemoveValue(void *key, const char *name);
+ bool RemoveKey(void *key, const char *name);
+
+ void *EnumKeysBegin(void *key);
+ const char *EnumKeysNext(void *enumerator);
+ void EnumKeysClose(void *enumerator);
+
+ void *EnumValuesBegin(void *key);
+ const char *EnumValuesNext(void *enumerator);
+ void EnumValuesClose(void *enumerator);
+
+protected:
+ class Key;
+ class Value;
+ struct Enumerator;
+
+ Key *mpUserKey;
+ Key *mpMachineKey;
+
+ VDCriticalSection mMutex;
+};
+
+#endif
diff --git a/src/thirdparty/VirtualDub/h/vd2/system/source/registrymemory.cpp b/src/thirdparty/VirtualDub/h/vd2/system/source/registrymemory.cpp
new file mode 100644
index 000000000..ba850ab17
--- /dev/null
+++ b/src/thirdparty/VirtualDub/h/vd2/system/source/registrymemory.cpp
@@ -0,0 +1,657 @@
+// VirtualDub - Video processing and capture application
+// System library component
+// Copyright (C) 1998-2010 Avery Lee, All Rights Reserved.
+//
+// Beginning with 1.6.0, the VirtualDub system library is licensed
+// differently than the remainder of VirtualDub. This particular file is
+// thus licensed as follows (the "zlib" license):
+//
+// This software is provided 'as-is', without any express or implied
+// warranty. In no event will the authors be held liable for any
+// damages arising from the use of this software.
+//
+// Permission is granted to anyone to use this software for any purpose,
+// including commercial applications, and to alter it and redistribute it
+// freely, subject to the following restrictions:
+//
+// 1. The origin of this software must not be misrepresented; you must
+// not claim that you wrote the original software. If you use this
+// software in a product, an acknowledgment in the product
+// documentation would be appreciated but is not required.
+// 2. Altered source versions must be plainly marked as such, and must
+// not be misrepresented as being the original software.
+// 3. This notice may not be removed or altered from any source
+// distribution.
+
+#include "stdafx.h"
+#include <vd2/system/vdalloc.h>
+#include <vd2/system/registrymemory.h>
+#include <vd2/system/hash.h>
+
+class VDRegistryProviderMemory::Value : public vdhashtable_base_node {
+public:
+ enum Type {
+ kTypeInt,
+ kTypeString,
+ kTypeBinary
+ };
+
+ Value();
+
+ void SetInt(sint32 v);
+ void SetString(const wchar_t *str);
+ void SetBinary(const void *p, size_t len);
+
+ Type GetType() const { return mType; }
+
+ bool GetInt(sint32& v) const;
+ bool GetString(const wchar_t *&s) const;
+ bool GetBinary(const void *&p, size_t& len) const;
+
+protected:
+ Type mType;
+
+ // we're being lazy for now
+ sint32 mInt;
+ VDStringW mString;
+ vdfastvector<char> mRawData;
+};
+
+VDRegistryProviderMemory::Value::Value()
+ : mType(kTypeInt)
+ , mInt(0)
+{
+}
+
+void VDRegistryProviderMemory::Value::SetInt(sint32 v) {
+ if (mType != kTypeInt) {
+ mString.swap(VDStringW());
+ mRawData.swap(vdfastvector<char>());
+ mType = kTypeInt;
+ }
+
+ mInt = v;
+}
+
+void VDRegistryProviderMemory::Value::SetString(const wchar_t *str) {
+ if (mType != kTypeString) {
+ mRawData.swap(vdfastvector<char>());
+ mType = kTypeString;
+ }
+
+ mString = str;
+}
+
+void VDRegistryProviderMemory::Value::SetBinary(const void *p, size_t len) {
+ if (mType != kTypeBinary) {
+ mString.swap(VDStringW());
+ mType = kTypeBinary;
+ }
+
+ mRawData.assign((char *)p, (char *)p + len);
+}
+
+bool VDRegistryProviderMemory::Value::GetInt(sint32& v) const {
+ if (mType != kTypeInt)
+ return false;
+
+ v = mInt;
+ return true;
+}
+
+bool VDRegistryProviderMemory::Value::GetString(const wchar_t *&s) const {
+ if (mType != kTypeString)
+ return false;
+
+ s = mString.c_str();
+ return true;
+}
+
+bool VDRegistryProviderMemory::Value::GetBinary(const void *&p, size_t& len) const {
+ if (mType != kTypeBinary)
+ return false;
+
+ p = mRawData.data();
+ len = mRawData.size();
+ return true;
+}
+
+class VDRegistryProviderMemory::Key {
+public:
+ Key();
+ ~Key();
+
+ void AddRef();
+ void Release();
+
+ bool Add(const VDStringA& name, VDRegistryProviderMemory::Value *value);
+ void Remove(VDRegistryProviderMemory::Key *key);
+ bool RemoveKey(const char *name);
+ bool RemoveValue(const char *name);
+
+ const char *GetKeyName(size_t index) const {
+ if (index >= mKeyList.size())
+ return NULL;
+
+ return mKeyList[index]->first.c_str();
+ }
+
+ const char *GetValueName(size_t index) const {
+ if (index >= mValueList.size())
+ return NULL;
+
+ return mValueList[index]->first.c_str();
+ }
+
+ Value *OpenValue(const char *name, bool create);
+ Key *OpenKey(const VDStringSpanA& name, bool create);
+
+ int mRefCount;
+ bool mbCondemned;
+
+ Key *mpParent;
+
+ struct KeyHash {
+ size_t operator()(const VDStringA& s) const;
+ size_t operator()(const char *s) const;
+ };
+
+ struct KeyPred {
+ bool operator()(const VDStringA& s, const VDStringA& t) const;
+ bool operator()(const VDStringA& s, const VDStringSpanA& t) const;
+ bool operator()(const VDStringA& s, const char *t) const;
+ };
+
+ typedef vdhashmap<VDStringA, Key, KeyHash, KeyPred> KeyMap;
+ KeyMap mKeyMap;
+
+ typedef vdfastvector<const KeyMap::value_type *> KeyList;
+ KeyList mKeyList;
+
+ typedef vdhashmap<VDStringA, Value, KeyHash, KeyPred> ValueMap;
+ ValueMap mValueMap;
+
+ typedef vdfastvector<const ValueMap::value_type *> ValueList;
+ ValueList mValueList;
+};
+
+size_t VDRegistryProviderMemory::Key::KeyHash::operator()(const VDStringA& s) const {
+ return VDHashString32I(s.data(), s.size());
+}
+
+size_t VDRegistryProviderMemory::Key::KeyHash::operator()(const char *s) const {
+ return VDHashString32I(s);
+}
+
+bool VDRegistryProviderMemory::Key::KeyPred::operator()(const VDStringA& s, const VDStringA& t) const {
+ return s.comparei(t) == 0;
+}
+
+bool VDRegistryProviderMemory::Key::KeyPred::operator()(const VDStringA& s, const VDStringSpanA& t) const {
+ return s.comparei(t) == 0;
+}
+
+bool VDRegistryProviderMemory::Key::KeyPred::operator()(const VDStringA& s, const char *t) const {
+ return s.comparei(t) == 0;
+}
+
+VDRegistryProviderMemory::Key::Key()
+ : mRefCount(0)
+ , mbCondemned(false)
+ , mpParent(NULL)
+{
+}
+
+VDRegistryProviderMemory::Key::~Key() {
+ VDASSERT(!mRefCount);
+}
+
+void VDRegistryProviderMemory::Key::AddRef() {
+ ++mRefCount;
+}
+
+void VDRegistryProviderMemory::Key::Release() {
+ if (!--mRefCount && mbCondemned)
+ mpParent->Remove(this);
+}
+
+bool VDRegistryProviderMemory::Key::Add(const VDStringA& name, VDRegistryProviderMemory::Value *value) {
+ ValueMap::insert_return_type r(mValueMap.insert(name));
+ if (!r.second)
+ return false;
+
+ mValueList.push_back(&*r.first);
+ return true;
+}
+
+void VDRegistryProviderMemory::Key::Remove(VDRegistryProviderMemory::Key *key) {
+ VDASSERT(key->mRefCount == 0);
+
+ for(KeyList::iterator it(mKeyList.begin()), itEnd(mKeyList.end()); it != itEnd; ++it) {
+ const KeyMap::value_type *e = *it;
+
+ if (&e->second == key) {
+ mKeyMap.erase(e->first);
+ mKeyList.erase(it);
+ break;
+ }
+ }
+}
+
+bool VDRegistryProviderMemory::Key::RemoveKey(const char *name) {
+ // look up the subkey
+ KeyMap::iterator it(mKeyMap.find_as(name));
+
+ // fail if not found
+ if (it != mKeyMap.end())
+ return false;
+
+ // can't delete key if it has subkeys
+ Key& key = it->second;
+ if (!key.mKeyList.empty())
+ return false;
+
+ // if the key is open, we have to condemn it and delete it later
+ if (key.mRefCount) {
+ key.mbCondemned = true;
+ return true;
+ }
+
+ // delete the key
+ mKeyMap.erase(it);
+
+ KeyList::iterator it2(std::find(mKeyList.begin(), mKeyList.end(), &*it));
+ VDASSERT(it2 != mKeyList.end());
+
+ mKeyList.erase(it2);
+ return true;
+}
+
+bool VDRegistryProviderMemory::Key::RemoveValue(const char *name) {
+ ValueMap::iterator it(mValueMap.find_as(name));
+
+ if (it == mValueMap.end())
+ return false;
+
+ ValueList::iterator it2(std::find(mValueList.begin(), mValueList.end(), &*it));
+ VDASSERT(it2 != mValueList.end());
+
+ mValueList.erase(it2);
+ mValueMap.erase(it);
+ return true;
+}
+
+VDRegistryProviderMemory::Value *VDRegistryProviderMemory::Key::OpenValue(const char *name, bool create) {
+ ValueMap::iterator it(mValueMap.find_as(name));
+
+ if (it != mValueMap.end())
+ return &it->second;
+
+ if (!create)
+ return NULL;
+
+ ValueMap::insert_return_type r(mValueMap.insert(VDStringA(name)));
+ mValueList.push_back(&*r.first);
+
+ return &r.first->second;
+}
+
+VDRegistryProviderMemory::Key *VDRegistryProviderMemory::Key::OpenKey(const VDStringSpanA& name, bool create) {
+ KeyMap::iterator it(mKeyMap.find_as(name));
+
+ if (it != mKeyMap.end())
+ return &it->second;
+
+ if (!create)
+ return NULL;
+
+ KeyMap::insert_return_type r(mKeyMap.insert(VDStringA(name)));
+ mKeyList.push_back(&*r.first);
+
+ Key *key = &r.first->second;
+
+ key->mpParent = this;
+
+ return key;
+}
+
+///////////////////////////////////////////////////////////////////////
+
+VDRegistryProviderMemory::VDRegistryProviderMemory() {
+ vdautoptr<Key> machineKey(new Key);
+ vdautoptr<Key> userKey(new Key);
+
+ mpMachineKey = machineKey.release();
+ mpUserKey = userKey.release();
+}
+
+VDRegistryProviderMemory::~VDRegistryProviderMemory() {
+ delete mpMachineKey;
+ delete mpUserKey;
+}
+
+void *VDRegistryProviderMemory::GetMachineKey() {
+ return mpMachineKey;
+}
+
+void *VDRegistryProviderMemory::GetUserKey() {
+ return mpUserKey;
+}
+
+void *VDRegistryProviderMemory::CreateKey(void *key0, const char *path, bool write) {
+ Key *key = (Key *)key0;
+
+ vdsynchronized(mMutex) {
+ // check for root specifier
+ if (*path == '\\') {
+ do {
+ ++path;
+ } while(*path == '\\');
+
+ while(key->mpParent)
+ key = key->mpParent;
+ }
+
+ // parse out a component at a time
+ for(;;) {
+ const char *split = strchr(path, '\\');
+ if (!split)
+ split = path + strlen(path);
+
+ if (path == split)
+ break;
+
+ VDStringSpanA component(path, split);
+
+ // lookup component
+ key = key->OpenKey(component, write);
+ if (!key)
+ return NULL;
+
+ // skip path specifier
+ if (!*split)
+ break;
+
+ path = split;
+ do {
+ ++path;
+ } while(*path == L'\\');
+ }
+
+ key->AddRef();
+ }
+
+ return key;
+}
+
+void VDRegistryProviderMemory::CloseKey(void *key0) {
+ Key *key = (Key *)key0;
+
+ vdsynchronized(mMutex) {
+ key->Release();
+ }
+}
+
+bool VDRegistryProviderMemory::SetBool(void *key0, const char *name, bool v) {
+ vdsynchronized(mMutex) {
+ Key *key = (Key *)key0;
+ Value *value = key->OpenValue(name, true);
+
+ if (!value)
+ return false;
+
+ value->SetInt(v);
+ }
+ return true;
+}
+
+bool VDRegistryProviderMemory::SetInt(void *key0, const char *name, int v) {
+ vdsynchronized(mMutex) {
+ Key *key = (Key *)key0;
+ Value *value = key->OpenValue(name, true);
+
+ if (!value)
+ return false;
+
+ value->SetInt(v);
+ }
+ return true;
+}
+
+bool VDRegistryProviderMemory::SetString(void *key0, const char *name, const char *str) {
+ vdsynchronized(mMutex) {
+ Key *key = (Key *)key0;
+ Value *value = key->OpenValue(name, true);
+
+ if (!value)
+ return false;
+
+ value->SetString(VDTextAToW(str).c_str());
+ }
+ return true;
+}
+
+bool VDRegistryProviderMemory::SetString(void *key0, const char *name, const wchar_t *str) {
+ vdsynchronized(mMutex) {
+ Key *key = (Key *)key0;
+ Value *value = key->OpenValue(name, true);
+
+ if (!value)
+ return false;
+
+ value->SetString(str);
+ }
+ return true;
+}
+
+bool VDRegistryProviderMemory::SetBinary(void *key0, const char *name, const char *data, int len) {
+ vdsynchronized(mMutex) {
+ Key *key = (Key *)key0;
+ Value *value = key->OpenValue(name, true);
+
+ if (!value)
+ return false;
+
+ value->SetBinary(data, len);
+ }
+ return true;
+}
+
+IVDRegistryProvider::Type VDRegistryProviderMemory::GetType(void *key0, const char *name) {
+ Type type = kTypeUnknown;
+
+ vdsynchronized(mMutex) {
+ Key *key = (Key *)key0;
+ Value *value = key->OpenValue(name, true);
+
+ if (value) {
+ switch(value->GetType()) {
+ case Value::kTypeInt:
+ type = kTypeInt;
+ break;
+
+ case Value::kTypeString:
+ type = kTypeString;
+ break;
+
+ case Value::kTypeBinary:
+ type = kTypeBinary;
+ break;
+ }
+ }
+ }
+
+ return type;
+}
+
+bool VDRegistryProviderMemory::GetBool(void *key0, const char *name, bool& val) {
+ vdsynchronized(mMutex) {
+ Key *key = (Key *)key0;
+ Value *value = key->OpenValue(name, false);
+
+ sint32 v32;
+ if (!value || !value->GetInt(v32))
+ return false;
+
+ val = v32 != 0;
+ }
+ return true;
+}
+
+bool VDRegistryProviderMemory::GetInt(void *key0, const char *name, int& val) {
+ vdsynchronized(mMutex) {
+ Key *key = (Key *)key0;
+ Value *value = key->OpenValue(name, false);
+
+ sint32 v32;
+ if (!value || !value->GetInt(v32))
+ return false;
+
+ val = v32;
+ }
+ return true;
+}
+
+bool VDRegistryProviderMemory::GetString(void *key0, const char *name, VDStringA& s) {
+ vdsynchronized(mMutex) {
+ Key *key = (Key *)key0;
+ Value *value = key->OpenValue(name, false);
+
+ const wchar_t *raws;
+ if (!value || !value->GetString(raws))
+ return false;
+
+ s = VDTextWToA(raws);
+ }
+ return true;
+}
+
+bool VDRegistryProviderMemory::GetString(void *key0, const char *name, VDStringW& s) {
+ vdsynchronized(mMutex) {
+ Key *key = (Key *)key0;
+ Value *value = key->OpenValue(name, false);
+
+ const wchar_t *raws;
+ if (!value || !value->GetString(raws))
+ return false;
+
+ s = raws;
+ }
+ return true;
+}
+
+int VDRegistryProviderMemory::GetBinaryLength(void *key0, const char *name) {
+ size_t len;
+
+ vdsynchronized(mMutex) {
+ Key *key = (Key *)key0;
+ Value *value = key->OpenValue(name, false);
+
+ const void *p;
+ if (!value || !value->GetBinary(p, len))
+ return -1;
+ }
+ return len;
+}
+
+bool VDRegistryProviderMemory::GetBinary(void *key0, const char *name, char *buf, int maxlen) {
+ vdsynchronized(mMutex) {
+ Key *key = (Key *)key0;
+ Value *value = key->OpenValue(name, false);
+
+ const void *p;
+ size_t len;
+ if (!value || !value->GetBinary(p, len) || (int)len > maxlen)
+ return false;
+
+ memcpy(buf, p, len);
+ }
+
+ return true;
+}
+
+bool VDRegistryProviderMemory::RemoveValue(void *key0, const char *name) {
+ bool success;
+
+ vdsynchronized(mMutex) {
+ Key *key = (Key *)key0;
+
+ success = key->RemoveValue(name);
+ }
+
+ return true;
+}
+
+bool VDRegistryProviderMemory::RemoveKey(void *key0, const char *name) {
+ bool success;
+
+ vdsynchronized(mMutex) {
+ Key *key = (Key *)key0;
+
+ // if the key is a root key, silently ignore the request
+ if (!key->mpParent)
+ return true;
+
+ success = key->RemoveKey(name);
+ }
+
+ return true;
+}
+
+struct VDRegistryProviderMemory::Enumerator {
+ Enumerator(Key *key) : mKey(key), mIndex(0) {}
+
+ Key *mKey;
+ size_t mIndex;
+ VDStringA mName;
+};
+
+void *VDRegistryProviderMemory::EnumKeysBegin(void *key) {
+ return new Enumerator((Key *)key);
+}
+
+const char *VDRegistryProviderMemory::EnumKeysNext(void *enumerator) {
+ Enumerator *en = (Enumerator *)enumerator;
+
+ vdsynchronized(mMutex) {
+ const char *s = en->mKey->GetKeyName(en->mIndex);
+ if (!s)
+ return NULL;
+
+ ++en->mIndex;
+ en->mName = s;
+ }
+
+ return en->mName.c_str();
+}
+
+void VDRegistryProviderMemory::EnumKeysClose(void *enumerator) {
+ Enumerator *en = (Enumerator *)enumerator;
+
+ delete en;
+}
+
+void *VDRegistryProviderMemory::EnumValuesBegin(void *key) {
+ return new Enumerator((Key *)key);
+}
+
+const char *VDRegistryProviderMemory::EnumValuesNext(void *enumerator) {
+ Enumerator *en = (Enumerator *)enumerator;
+
+ vdsynchronized(mMutex) {
+ const char *s = en->mKey->GetValueName(en->mIndex);
+ if (!s)
+ return NULL;
+
+ ++en->mIndex;
+ en->mName = s;
+ }
+
+ return en->mName.c_str();
+}
+
+void VDRegistryProviderMemory::EnumValuesClose(void *enumerator) {
+ Enumerator *en = (Enumerator *)enumerator;
+
+ delete en;
+}
diff --git a/src/thirdparty/VirtualDub/h/vd2/system/strutil.h b/src/thirdparty/VirtualDub/h/vd2/system/strutil.h
index 2f1fdf84f..07b22bccc 100644
--- a/src/thirdparty/VirtualDub/h/vd2/system/strutil.h
+++ b/src/thirdparty/VirtualDub/h/vd2/system/strutil.h
@@ -41,4 +41,20 @@ size_t vdwcslcpy(wchar_t *dst, const wchar_t *src, size_t sizeChars);
size_t vdstrlcat(char *dst, const char *src, size_t sizeChars);
+inline int vdstricmp(const char *s, const char *t) {
+ return _stricmp(s, t);
+}
+
+inline int vdstricmp(const char *s, const char *t, size_t maxlen) {
+ return _strnicmp(s, t, maxlen);
+}
+
+inline int vdwcsicmp(const wchar_t *s, const wchar_t *t) {
+ return _wcsicmp(s, t);
+}
+
+inline int vdwcsnicmp(const wchar_t *s, const wchar_t *t, size_t maxlen) {
+ return _wcsnicmp(s, t, maxlen);
+}
+
#endif
diff --git a/src/thirdparty/VirtualDub/h/vd2/system/thread.h b/src/thirdparty/VirtualDub/h/vd2/system/thread.h
index 6cf1fc7a0..5fa7d6e0f 100644
--- a/src/thirdparty/VirtualDub/h/vd2/system/thread.h
+++ b/src/thirdparty/VirtualDub/h/vd2/system/thread.h
@@ -49,6 +49,7 @@ extern "C" int __declspec(dllimport) __stdcall ReleaseSemaphore(void *hSemaphore
VDThreadID VDGetCurrentThreadID();
VDProcessId VDGetCurrentProcessId();
+uint32 VDGetLogicalProcessorCount();
void VDSetThreadDebugName(VDThreadID tid, const char *name);
void VDThreadSleep(int milliseconds);
@@ -212,6 +213,9 @@ public:
int wait(VDSignalBase *second);
int wait(VDSignalBase *second, VDSignalBase *third);
static int waitMultiple(const VDSignalBase **signals, int count);
+
+ bool tryWait(uint32 timeoutMillisec);
+
void *getHandle() { return hEvent; }
void operator()() { signal(); }
diff --git a/src/thirdparty/VirtualDub/h/vd2/system/vdalloc.h b/src/thirdparty/VirtualDub/h/vd2/system/vdalloc.h
index 2c9fa2efd..96039754a 100644
--- a/src/thirdparty/VirtualDub/h/vd2/system/vdalloc.h
+++ b/src/thirdparty/VirtualDub/h/vd2/system/vdalloc.h
@@ -52,7 +52,7 @@ public:
operator void*() const { return ptr; }
- vdautoblockptr& from(vdautoblockptr& src) { free(ptr); ptr=src.ptr; src.ptr=0; }
+ void from(vdautoblockptr& src) { free(ptr); ptr=src.ptr; src.ptr=0; }
void *get() const { return ptr; }
void *release() { void *v = ptr; ptr = NULL; return v; }
};
@@ -90,10 +90,26 @@ public:
T& operator*() const { return *ptr; }
T *operator->() const { return ptr; }
- vdautoptr<T>& from(vdautoptr<T>& src) { delete ptr; ptr=src.ptr; src.ptr=0; }
+ T** operator~() {
+ if (ptr) {
+ delete ptr;
+ ptr = NULL;
+ }
+
+ return &ptr;
+ }
+
+ void from(vdautoptr<T>& src) { delete ptr; ptr=src.ptr; src.ptr=0; }
T *get() const { return ptr; }
T *release() { T *v = ptr; ptr = NULL; return v; }
+ void reset() {
+ if (ptr) {
+ delete ptr;
+ ptr = NULL;
+ }
+ }
+
void swap(vdautoptr<T>& other) {
T *p = other.ptr;
other.ptr = ptr;
@@ -113,7 +129,7 @@ public:
T& operator[](int offset) const { return ptr[offset]; }
- vdautoarrayptr<T>& from(vdautoarrayptr<T>& src) { delete[] ptr; ptr=src.ptr; src.ptr=0; }
+ void from(vdautoarrayptr<T>& src) { delete[] ptr; ptr=src.ptr; src.ptr=0; }
T *get() const { return ptr; }
T *release() { T *v = ptr; ptr = NULL; return v; }
};
diff --git a/src/thirdparty/VirtualDub/h/vd2/system/vdstl.h b/src/thirdparty/VirtualDub/h/vd2/system/vdstl.h
index aeaaf15d6..693c7e28d 100644
--- a/src/thirdparty/VirtualDub/h/vd2/system/vdstl.h
+++ b/src/thirdparty/VirtualDub/h/vd2/system/vdstl.h
@@ -40,15 +40,6 @@
//
///////////////////////////////////////////////////////////////////////////
-template<class Category, class T, class Distance = ptrdiff_t, class Pointer = T*, class Reference = T&>
-struct vditerator {
-#if defined(VD_COMPILER_MSVC) && (VD_COMPILER_MSVC < 1310 || (defined(VD_COMPILER_MSVC_VC8_PSDK) || defined(VD_COMPILER_MSVC_VC8_DDK)))
- typedef std::iterator<Category, T, Distance> type;
-#else
- typedef std::iterator<Category, T, Distance, Pointer, Reference> type;
-#endif
-};
-
template<class Iterator, class T>
struct vdreverse_iterator {
#if defined(VD_COMPILER_MSVC) && (VD_COMPILER_MSVC < 1310 || (defined(VD_COMPILER_MSVC_VC8_PSDK) || defined(VD_COMPILER_MSVC_VC8_DDK)))
@@ -59,6 +50,32 @@ struct vdreverse_iterator {
};
///////////////////////////////////////////////////////////////////////////
+
+template<class T>
+T *vdmove_forward(T *src1, T *src2, T *dst) {
+ T *p = src1;
+ while(p != src2) {
+ *dst = *p;
+ ++dst;
+ ++p;
+ }
+
+ return dst;
+}
+
+template<class T>
+T *vdmove_backward(T *src1, T *src2, T *dst) {
+ T *p = src2;
+ while(p != src1) {
+ --dst;
+ --p;
+ *dst = *p;
+ }
+
+ return dst;
+}
+
+///////////////////////////////////////////////////////////////////////////
class vdallocator_base {
protected:
void VDNORETURN throw_oom();
@@ -394,8 +411,14 @@ struct vdlist_node {
};
template<class T, class T_Nonconst>
-class vdlist_iterator : public vditerator<std::bidirectional_iterator_tag, T, ptrdiff_t>::type {
+class vdlist_iterator {
public:
+ typedef ptrdiff_t difference_type;
+ typedef T value_type;
+ typedef T *pointer_type;
+ typedef T& reference_type;
+ typedef std::bidirectional_iterator_tag iterator_category;
+
vdlist_iterator() {}
vdlist_iterator(T *p) : mp(p) {}
vdlist_iterator(const vdlist_iterator<T_Nonconst, T_Nonconst>& src) : mp(src.mp) {}
@@ -711,6 +734,10 @@ public:
typedef typename vdreverse_iterator<const_iterator, const T>::type const_reverse_iterator;
VDTINLINE vdspan();
+
+ template<size_t N>
+ VDTINLINE vdspan(T (&arr)[N]);
+
VDTINLINE vdspan(T *p1, T *p2);
VDTINLINE vdspan(T *p1, size_type len);
@@ -763,6 +790,7 @@ protected:
#endif
template<class T> VDTINLINE vdspan<T>::vdspan() : mpBegin(NULL), mpEnd(NULL) {}
+template<class T> template<size_t N> VDTINLINE vdspan<T>::vdspan(T (&arr)[N]) : mpBegin(&arr[0]), mpEnd(&arr[N]) {}
template<class T> VDTINLINE vdspan<T>::vdspan(T *p1, T *p2) : mpBegin(p1), mpEnd(p2) {}
template<class T> VDTINLINE vdspan<T>::vdspan(T *p, size_type len) : mpBegin(p), mpEnd(p+len) {}
template<class T> VDTINLINE bool vdspan<T>::empty() const { return mpBegin == mpEnd; }
@@ -773,10 +801,10 @@ template<class T> VDTINLINE typename vdspan<T>::iterator vdspan<T>::begin() {
template<class T> VDTINLINE typename vdspan<T>::const_iterator vdspan<T>::begin() const { return mpBegin; }
template<class T> VDTINLINE typename vdspan<T>::iterator vdspan<T>::end() { return mpEnd; }
template<class T> VDTINLINE typename vdspan<T>::const_iterator vdspan<T>::end() const { return mpEnd; }
-template<class T> VDTINLINE typename vdspan<T>::reverse_iterator vdspan<T>::rbegin() { return reverse_iterator(mpBegin); }
-template<class T> VDTINLINE typename vdspan<T>::const_reverse_iterator vdspan<T>::rbegin() const { return const_reverse_iterator(mpBegin); }
-template<class T> VDTINLINE typename vdspan<T>::reverse_iterator vdspan<T>::rend() { return reverse_iterator(mpEnd); }
-template<class T> VDTINLINE typename vdspan<T>::const_reverse_iterator vdspan<T>::rend() const { return const_reverse_iterator(mpEnd); }
+template<class T> VDTINLINE typename vdspan<T>::reverse_iterator vdspan<T>::rbegin() { return reverse_iterator(mpEnd); }
+template<class T> VDTINLINE typename vdspan<T>::const_reverse_iterator vdspan<T>::rbegin() const { return const_reverse_iterator(mpEnd); }
+template<class T> VDTINLINE typename vdspan<T>::reverse_iterator vdspan<T>::rend() { return reverse_iterator(mpBegin); }
+template<class T> VDTINLINE typename vdspan<T>::const_reverse_iterator vdspan<T>::rend() const { return const_reverse_iterator(mpBegin); }
template<class T> VDTINLINE typename vdspan<T>::reference vdspan<T>::front() { return *mpBegin; }
template<class T> VDTINLINE typename vdspan<T>::const_reference vdspan<T>::front() const { return *mpBegin; }
template<class T> VDTINLINE typename vdspan<T>::reference vdspan<T>::back() { VDASSERT(mpBegin != mpEnd); return mpEnd[-1]; }
@@ -1201,6 +1229,12 @@ struct vdfastdeque_block {
template<class T, class T_Base>
class vdfastdeque_iterator {
public:
+ typedef T value_type;
+ typedef T* pointer;
+ typedef T& reference;
+ typedef ptrdiff_t difference_type;
+ typedef std::bidirectional_iterator_tag iterator_category;
+
vdfastdeque_iterator(const vdfastdeque_iterator<T_Base, T_Base>&);
vdfastdeque_iterator(vdfastdeque_block<T_Base> **pMapEntry, uint32 index);
@@ -1262,7 +1296,7 @@ vdfastdeque_iterator<T, T_Base> vdfastdeque_iterator<T, T_Base>::operator++(int)
template<class T, class T_Base>
vdfastdeque_iterator<T, T_Base>& vdfastdeque_iterator<T, T_Base>::operator--() {
if (mIndex-- == 0) {
- mIndex = vdfastdeque_block<T, T_Base>::kBlockSize - 1;
+ mIndex = vdfastdeque_block<T>::kBlockSize - 1;
mpBlock = *--mpMap;
}
return *this;
@@ -1607,4 +1641,8 @@ void vdfastdeque<T,A>::validate() {
VDASSERT(m.mapEndCommit == m.mapEndAlloc || !m.mapEndCommit[0]);
}
+#include <vd2/system/vdstl_vector.h>
+#include <vd2/system/vdstl_hash.h>
+#include <vd2/system/vdstl_hashmap.h>
+
#endif
diff --git a/src/thirdparty/VirtualDub/h/vd2/system/vdstl_hash.h b/src/thirdparty/VirtualDub/h/vd2/system/vdstl_hash.h
new file mode 100644
index 000000000..a7957e8c2
--- /dev/null
+++ b/src/thirdparty/VirtualDub/h/vd2/system/vdstl_hash.h
@@ -0,0 +1,124 @@
+// VirtualDub - Video processing and capture application
+// System library component
+// Copyright (C) 1998-2010 Avery Lee, All Rights Reserved.
+//
+// Beginning with 1.6.0, the VirtualDub system library is licensed
+// differently than the remainder of VirtualDub. This particular file is
+// thus licensed as follows (the "zlib" license):
+//
+// This software is provided 'as-is', without any express or implied
+// warranty. In no event will the authors be held liable for any
+// damages arising from the use of this software.
+//
+// Permission is granted to anyone to use this software for any purpose,
+// including commercial applications, and to alter it and redistribute it
+// freely, subject to the following restrictions:
+//
+// 1. The origin of this software must not be misrepresented; you must
+// not claim that you wrote the original software. If you use this
+// software in a product, an acknowledgment in the product
+// documentation would be appreciated but is not required.
+// 2. Altered source versions must be plainly marked as such, and must
+// not be misrepresented as being the original software.
+// 3. This notice may not be removed or altered from any source
+// distribution.
+
+#ifndef f_VD2_SYSTEM_VDSTL_HASH_H
+#define f_VD2_SYSTEM_VDSTL_HASH_H
+
+#include <vd2/system/vdtypes.h>
+
+///////////////////////////////////////////////////////////////////////////////
+// vdhash
+//
+// Differences from TR1:
+//
+// - We omit the hash for long double, as that's not really useful, esp. on
+// Windows.
+
+template<class T> struct vdhash;
+
+#define VDSTL_DECLARE_STANDARD_HASH(T) \
+ template<> struct vdhash<T> { \
+ size_t operator()(T val) const { return (size_t)val; } \
+ };
+
+VDSTL_DECLARE_STANDARD_HASH(char);
+VDSTL_DECLARE_STANDARD_HASH(signed char);
+VDSTL_DECLARE_STANDARD_HASH(unsigned char);
+VDSTL_DECLARE_STANDARD_HASH(wchar_t);
+VDSTL_DECLARE_STANDARD_HASH(short);
+VDSTL_DECLARE_STANDARD_HASH(unsigned short);
+VDSTL_DECLARE_STANDARD_HASH(int);
+VDSTL_DECLARE_STANDARD_HASH(unsigned int);
+VDSTL_DECLARE_STANDARD_HASH(long);
+VDSTL_DECLARE_STANDARD_HASH(unsigned long);
+VDSTL_DECLARE_STANDARD_HASH(long long);
+VDSTL_DECLARE_STANDARD_HASH(unsigned long long);
+
+template<> struct vdhash<float> {
+ size_t operator()(float v) const {
+ const union { float f; sint32 i; } conv = {v};
+
+ uint32 i = conv.i;
+
+ // Denormals and infinities are unique encodings and work as-is. NaNs work
+ // because they never compare equal to anything else, so their hash value
+ // can be arbitrary. Zero and negative zero, however, compare equal.
+ if (i == 0x80000000)
+ i = 0;
+
+ return i;
+ }
+};
+
+template<> struct vdhash<double> {
+ size_t operator()(double v) const {
+ const union conv { double f; sint64 i; } conv = {v};
+
+ uint64 i = conv.i;
+
+ // Denormals and infinities are unique encodings and work as-is. NaNs work
+ // because they never compare equal to anything else, so their hash value
+ // can be arbitrary. Zero and negative zero, however, compare equal.
+ if (i == 0x8000000000000000ULL)
+ i = 0;
+
+ if (sizeof(size_t) < 8)
+ return (size_t)((i >> 32) ^ i);
+ else
+ return (size_t)i;
+ }
+};
+
+#undef VDSTL_DECLARE_STANDARD_HASH
+
+class VDStringA;
+class VDStringSpanA;
+class VDStringW;
+class VDStringSpanW;
+
+template<> struct vdhash<VDStringA> {
+ size_t operator()(const VDStringA& s) const;
+ size_t operator()(const char *s) const;
+};
+
+template<> struct vdhash<VDStringW> {
+ size_t operator()(const VDStringW& s) const;
+ size_t operator()(const wchar_t *s) const;
+};
+
+template<class T> struct vdhash<T *> {
+ size_t operator()(T *val) const { return (size_t)val; }
+};
+
+struct vdstringpred {
+ bool operator()(const VDStringA& s, const VDStringA& t) const;
+ bool operator()(const VDStringA& s, const VDStringSpanA& t) const;
+ bool operator()(const VDStringA& s, const char *t) const;
+ bool operator()(const VDStringW& s, const VDStringW& t) const;
+ bool operator()(const VDStringW& s, const VDStringSpanW& t) const;
+ bool operator()(const VDStringW& s, const wchar_t *t) const;
+};
+
+#endif // f_VD2_SYSTEM_VDSTL_HASH_H
diff --git a/src/thirdparty/VirtualDub/h/vd2/system/vdstl_hashmap.h b/src/thirdparty/VirtualDub/h/vd2/system/vdstl_hashmap.h
new file mode 100644
index 000000000..8715cbf34
--- /dev/null
+++ b/src/thirdparty/VirtualDub/h/vd2/system/vdstl_hashmap.h
@@ -0,0 +1,548 @@
+// VirtualDub - Video processing and capture application
+// System library component
+// Copyright (C) 1998-2010 Avery Lee, All Rights Reserved.
+//
+// Beginning with 1.6.0, the VirtualDub system library is licensed
+// differently than the remainder of VirtualDub. This particular file is
+// thus licensed as follows (the "zlib" license):
+//
+// This software is provided 'as-is', without any express or implied
+// warranty. In no event will the authors be held liable for any
+// damages arising from the use of this software.
+//
+// Permission is granted to anyone to use this software for any purpose,
+// including commercial applications, and to alter it and redistribute it
+// freely, subject to the following restrictions:
+//
+// 1. The origin of this software must not be misrepresented; you must
+// not claim that you wrote the original software. If you use this
+// software in a product, an acknowledgment in the product
+// documentation would be appreciated but is not required.
+// 2. Altered source versions must be plainly marked as such, and must
+// not be misrepresented as being the original software.
+// 3. This notice may not be removed or altered from any source
+// distribution.
+
+#ifndef f_VD2_SYSTEM_VDSTL_HASHMAP_H
+#define f_VD2_SYSTEM_VDSTL_HASHMAP_H
+
+#include <vd2/system/vdstl_hash.h>
+#include <vd2/system/vdstl_hashtable.h>
+#include <functional>
+
+template<class K, class V, class Hash = vdhash<K>, class Pred = std::equal_to<K>, class A = std::allocator<vdhashtable_node<std::pair<K, V> > > >
+class vdhashmap : public vdhashtable<std::pair<K, V> > {
+public:
+ typedef K key_type;
+ typedef V mapped_type;
+ typedef Hash hasher;
+ typedef Pred key_equal;
+ typedef A allocator_type;
+ typedef std::pair<iterator, bool> insert_return_type;
+
+ vdhashmap();
+ vdhashmap(const vdhashmap&);
+ ~vdhashmap();
+
+ vdhashmap& operator=(const vdhashmap&);
+
+ mapped_type& operator[](const K& key);
+
+ allocator_type get_allocator() const;
+
+ // iterators
+ using vdhashtable<value_type>::begin;
+ using vdhashtable<value_type>::end;
+// iterator begin(); Inherited.
+// const_iterator begin() const; Inherited.
+// iterator end(); Inherited.
+// const_iterator end() const; Inherited.
+
+ // modifiers
+ insert_return_type insert(const key_type& key);
+ insert_return_type insert(const std::pair<K, V>& obj);
+// iterator insert(iterator hint, const value_type& obj); // TODO
+// const_iterator insert(const_iterator hint, const value_type& obj); // TODO
+
+ iterator erase(iterator position);
+ const_iterator erase(const_iterator position);
+ size_type erase(const key_type& k);
+// iterator erase(iterator first, iterator last); // TODO
+// const_iterator erase(const_iterator first, const_iterator last); // TODO
+ void clear();
+
+ // observers
+ hasher hash_function() const;
+ key_equal key_eq() const;
+
+ // lookup
+ iterator find(const key_type& k);
+ const_iterator find(const key_type& k) const;
+ size_type count(const key_type& k) const;
+ std::pair<iterator, iterator> equal_range(const key_type& k);
+ std::pair<const_iterator, const_iterator> equal_range(const key_type& k) const;
+
+ // lookup (extensions)
+ template<class U>
+ iterator find_as(const U& k);
+
+ template<class U>
+ const_iterator find_as(const U& k) const;
+
+ // bucket interface
+// size_type bucket_count() const; Inherited.
+// size_type max_bucket_count() const; Inherited.
+// size_type bucket_size(size_type n) const; Inherited.
+ size_type bucket(const key_type& k) const;
+ local_iterator begin(size_type n);
+ const_local_iterator begin(size_type n) const;
+ local_iterator end(size_type n);
+ const_local_iterator end(size_type n) const;
+
+ // hash policy
+// float load_factor() const; // TODO
+// float max_load_factor() const; // TODO
+// void max_load_factor(float z); // TODO
+ void rehash(size_type n);
+
+protected:
+ void rehash_to_size(size_type n);
+ void reset();
+
+ A mAllocator;
+ typename A::rebind<vdhashtable_base_node *>::other mBucketAllocator;
+ Hash mHasher;
+ Pred mPred;
+};
+
+template<class K, class V, class Hash, class Pred, class A>
+vdhashmap<K, V, Hash, Pred, A>::vdhashmap() {
+}
+
+template<class K, class V, class Hash, class Pred, class A>
+vdhashmap<K, V, Hash, Pred, A>::vdhashmap(const vdhashmap& src)
+ : mHasher(src.mHasher)
+ , mPred(src.mPred)
+{
+ rehash_to_size(src.mElementCount);
+
+ try {
+ for(vdhashtable_base_node **bucket = mpBucketStart; bucket != mpBucketEnd; ++bucket) {
+ vdhashtable_base_node *p = *bucket;
+
+ while(p) {
+ vdhashtable_base_node *next = p->mpHashNext;
+ node_type *node = static_cast<node_type *>(p);
+
+ insert(node->mData);
+
+ p = next;
+ }
+
+ *bucket = NULL;
+ }
+ } catch(...) {
+ reset();
+ throw;
+ }
+}
+
+template<class K, class V, class Hash, class Pred, class A>
+vdhashmap<K, V, Hash, Pred, A>::~vdhashmap() {
+ reset();
+}
+
+template<class K, class V, class Hash, class Pred, class A>
+vdhashmap<K, V, Hash, Pred, A>& vdhashmap<K, V, Hash, Pred, A>::operator=(const vdhashmap& src) {
+ if (&src != this) {
+ clear();
+
+ mHasher = src.mHasher;
+ mPred = src.mPred;
+
+ for(vdhashtable_base_node **bucket = src.mpBucketStart; bucket != src.mpBucketEnd; ++bucket) {
+ vdhashtable_base_node *p = *bucket;
+
+ while(p) {
+ vdhashtable_base_node *next = p->mpHashNext;
+ node_type *node = static_cast<node_type *>(p);
+
+ insert(node->mData);
+
+ p = next;
+ }
+
+ *bucket = NULL;
+ }
+ }
+
+ return *this;
+}
+
+template<class K, class V, class Hash, class Pred, class A>
+typename vdhashmap<K, V, Hash, Pred, A>::mapped_type& vdhashmap<K, V, Hash, Pred, A>::operator[](const K& key) {
+ return insert(key).first->second;
+}
+
+template<class K, class V, class Hash, class Pred, class A>
+typename vdhashmap<K, V, Hash, Pred, A>::allocator_type vdhashmap<K, V, Hash, Pred, A>::get_allocator() const {
+ return A();
+}
+
+// modifiers
+template<class K, class V, class Hash, class Pred, class A>
+typename vdhashmap<K, V, Hash, Pred, A>::insert_return_type vdhashmap<K, V, Hash, Pred, A>::insert(const key_type& key) {
+ if (mElementCount >= mBucketCount)
+ rehash_to_size(mElementCount + 1);
+
+ size_type bucket = mHasher(key) % mBucketCount;
+
+ for(node_type *p = static_cast<node_type *>(mpBucketStart[bucket]); p; p = static_cast<node_type *>(p->mpHashNext)) {
+ if (mPred(p->mData.first, key))
+ return std::pair<iterator, bool>(iterator(p, &mpBucketStart[bucket], mpBucketEnd), false);
+ }
+
+ node_type *node = mAllocator.allocate(1);
+ try {
+ new(node) node_type(static_cast<node_type *>(mpBucketStart[bucket]), value_type(key, V()));
+ } catch(...) {
+ mAllocator.deallocate(node, 1);
+ throw;
+ }
+
+ mpBucketStart[bucket] = node;
+ ++mElementCount;
+
+ return std::pair<iterator, bool>(iterator(node, &mpBucketStart[bucket], mpBucketEnd), true);
+}
+
+template<class K, class V, class Hash, class Pred, class A>
+typename vdhashmap<K, V, Hash, Pred, A>::insert_return_type vdhashmap<K, V, Hash, Pred, A>::insert(const std::pair<K, V>& obj) {
+ if (mElementCount >= mBucketCount)
+ rehash_to_size(mElementCount + 1);
+
+ size_type bucket = mHasher(obj.first) % mBucketCount;
+
+ for(node_type *p = static_cast<node_type *>(mpBucketStart[bucket]); p; p = static_cast<node_type *>(p->mpHashNext)) {
+ if (mPred(p->mData.first, obj.first))
+ return std::pair<iterator, bool>(iterator(p, &mpBucketStart[bucket], mpBucketEnd), false);
+ }
+
+ node_type *node = mAllocator.allocate(1);
+ try {
+ new(node) node_type(static_cast<node_type *>(mpBucketStart[bucket]), obj);
+ } catch(...) {
+ mAllocator.deallocate(node, 1);
+ throw;
+ }
+
+ mpBucketStart[bucket] = node;
+ ++mElementCount;
+
+ return std::pair<iterator, bool>(iterator(node, &mpBucketStart[bucket], mpBucketEnd), true);
+}
+
+template<class K, class V, class Hash, class Pred, class A>
+typename vdhashmap<K, V, Hash, Pred, A>::iterator vdhashmap<K, V, Hash, Pred, A>::erase(iterator position) {
+ size_type bucket = mHasher(position->first) % mBucketCount;
+ vdhashtable_base_node *prev = NULL;
+ vdhashtable_base_node *p = mpBucketStart[bucket];
+
+ while(&static_cast<node_type *>(p)->mData != &*position) {
+ prev = p;
+ p = p->mpHashNext;
+ }
+
+ vdhashtable_base_node *next = p->mpHashNext;
+ if (prev)
+ prev->mpHashNext = next;
+ else
+ mpBucketStart[bucket] = next;
+
+ node_type *node = static_cast<node_type *>(p);
+ node->~node_type();
+ mAllocator.deallocate(node, 1);
+ --mElementCount;
+
+ return iterator(next, &mpBucketStart[bucket], mpBucketEnd);
+}
+
+template<class K, class V, class Hash, class Pred, class A>
+typename vdhashmap<K, V, Hash, Pred, A>::const_iterator vdhashmap<K, V, Hash, Pred, A>::erase(const_iterator position) {
+ size_type bucket = mHasher(position->first) % mBucketCount;
+ const vdhashtable_base_node *prev = NULL;
+ const vdhashtable_base_node *p = mpBucketStart[bucket];
+
+ while(&static_cast<const node_type *>(p)->mData != &*position) {
+ prev = p;
+ p = p->mpHashNext;
+ }
+
+ const vdhashtable_base_node *next = p->mpHashNext;
+ if (prev)
+ prev->mpHashNext = next;
+ else
+ mpBucketStart[bucket] = next;
+
+ node_type *node = static_cast<node_type *>(p);
+ node->~node_type();
+ mAllocator.deallocate(node, 1);
+ --mElementCount;
+
+ return const_iterator(next, &mpBucketStart[bucket], mpBucketEnd);
+}
+
+template<class K, class V, class Hash, class Pred, class A>
+typename vdhashmap<K, V, Hash, Pred, A>::size_type vdhashmap<K, V, Hash, Pred, A>::erase(const key_type& k) {
+ if (!mBucketCount)
+ return 0;
+
+ size_type bucket = mHasher(k) % mBucketCount;
+ vdhashtable_base_node *prev = NULL;
+ vdhashtable_base_node *p = mpBucketStart[bucket];
+
+ while(p) {
+ node_type *node = static_cast<node_type *>(p);
+
+ if (mPred(node->mData.first, k)) {
+ vdhashtable_base_node *next = p->mpHashNext;
+
+ if (prev)
+ prev->mpHashNext = next;
+ else
+ mpBucketStart[bucket] = next;
+
+ node->~node_type();
+ mAllocator.deallocate(node, 1);
+ --mElementCount;
+ return 1;
+ }
+
+ prev = p;
+ p = p->mpHashNext;
+ }
+
+ return 0;
+}
+
+template<class K, class V, class Hash, class Pred, class A>
+void vdhashmap<K, V, Hash, Pred, A>::clear() {
+ for(vdhashtable_base_node **bucket = mpBucketStart; bucket != mpBucketEnd; ++bucket) {
+ vdhashtable_base_node *p = *bucket;
+
+ while(p) {
+ vdhashtable_base_node *next = p->mpHashNext;
+ node_type *node = static_cast<node_type *>(p);
+
+ node->~node_type();
+
+ mAllocator.deallocate(node, 1);
+
+ p = next;
+ }
+
+ *bucket = NULL;
+ }
+
+ mElementCount = 0;
+}
+
+// observers
+template<class K, class V, class Hash, class Pred, class A>
+typename vdhashmap<K, V, Hash, Pred, A>::hasher vdhashmap<K, V, Hash, Pred, A>::hash_function() const {
+ return mHasher;
+}
+
+template<class K, class V, class Hash, class Pred, class A>
+typename vdhashmap<K, V, Hash, Pred, A>::key_equal vdhashmap<K, V, Hash, Pred, A>::key_eq() const {
+ return mPred;
+}
+
+// lookup
+template<class K, class V, class Hash, class Pred, class A>
+typename vdhashmap<K, V, Hash, Pred, A>::iterator vdhashmap<K, V, Hash, Pred, A>::find(const key_type& k) {
+ if (!mBucketCount)
+ return iterator();
+
+ size_type bucket = mHasher(k) % mBucketCount;
+
+ for(vdhashtable_base_node *p = mpBucketStart[bucket]; p; p = p->mpHashNext) {
+ node_type *node = static_cast<node_type *>(p);
+
+ if (mPred(node->mData.first, k))
+ return iterator(node, &mpBucketStart[bucket], mpBucketEnd);
+ }
+
+ return iterator();
+}
+
+template<class K, class V, class Hash, class Pred, class A>
+typename vdhashmap<K, V, Hash, Pred, A>::const_iterator vdhashmap<K, V, Hash, Pred, A>::find(const key_type& k) const {
+ if (!mBucketCount)
+ return iterator();
+
+ size_type bucket = mHasher(k) % mBucketCount;
+
+ for(const vdhashtable_base_node *p = mpBucketStart[bucket]; p; p = p->mpHashNext) {
+ const node_type *node = static_cast<const node_type *>(p);
+
+ if (mPred(node->mData.first, k))
+ return const_iterator(const_cast<vdhashtable_base_node *>(static_cast<const vdhashtable_base_node *>(node)), &mpBucketStart[bucket], mpBucketEnd);
+ }
+
+ return iterator();
+}
+
+template<class K, class V, class Hash, class Pred, class A>
+typename vdhashmap<K, V, Hash, Pred, A>::size_type vdhashmap<K, V, Hash, Pred, A>::count(const key_type& k) const {
+ return find(k) != end() ? 1 : 0;
+}
+
+template<class K, class V, class Hash, class Pred, class A>
+std::pair<typename vdhashmap<K, V, Hash, Pred, A>::iterator, typename vdhashmap<K, V, Hash, Pred, A>::iterator> vdhashmap<K, V, Hash, Pred, A>::equal_range(const key_type& k) {
+ iterator it = find(k);
+ iterator itEnd;
+
+ if (it == itEnd)
+ return std::pair<itEnd, itEnd>();
+
+ itEnd = it;
+ ++itEnd;
+
+ return std::pair<it, itEnd>();
+}
+
+template<class K, class V, class Hash, class Pred, class A>
+std::pair<typename vdhashmap<K, V, Hash, Pred, A>::const_iterator, typename vdhashmap<K, V, Hash, Pred, A>::const_iterator> vdhashmap<K, V, Hash, Pred, A>::equal_range(const key_type& k) const {
+ const_iterator it = find(k);
+ const_iterator itEnd;
+
+ if (it == itEnd)
+ return std::pair<itEnd, itEnd>();
+
+ itEnd = it;
+ ++itEnd;
+
+ return std::pair<it, itEnd>();
+}
+
+template<class K, class V, class Hash, class Pred, class A>
+template<class U>
+typename vdhashmap<K, V, Hash, Pred, A>::iterator vdhashmap<K, V, Hash, Pred, A>::find_as(const U& k) {
+ if (!mBucketCount)
+ return iterator();
+
+ size_type bucket = mHasher(k) % mBucketCount;
+
+ for(vdhashtable_base_node *p = mpBucketStart[bucket]; p; p = p->mpHashNext) {
+ node_type *node = static_cast<node_type *>(p);
+
+ if (mPred(node->mData.first, k))
+ return iterator(node, &mpBucketStart[bucket], mpBucketEnd);
+ }
+
+ return iterator();
+}
+
+template<class K, class V, class Hash, class Pred, class A>
+template<class U>
+typename vdhashmap<K, V, Hash, Pred, A>::const_iterator vdhashmap<K, V, Hash, Pred, A>::find_as(const U& k) const {
+ if (!mBucketCount)
+ return iterator();
+
+ size_type bucket = mHasher(k) % mBucketCount;
+
+ for(const vdhashtable_base_node *p = mpBucketStart[bucket]; p; p = p->mpHashNext) {
+ const node_type *node = static_cast<const node_type *>(p);
+
+ if (mPred(node->mData.first, k))
+ return const_iterator(const_cast<vdhashtable_base_node *>(static_cast<const vdhashtable_base_node *>(node)), &mpBucketStart[bucket], mpBucketEnd);
+ }
+
+ return iterator();
+}
+
+// bucket interface
+template<class K, class V, class Hash, class Pred, class A>
+typename vdhashmap<K, V, Hash, Pred, A>::size_type vdhashmap<K, V, Hash, Pred, A>::bucket(const key_type& k) const {
+ size_type bucket = 0;
+
+ if (mBucketCount)
+ bucket = mHasher(k) % mBucketCount;
+
+ return bucket;
+}
+
+template<class K, class V, class Hash, class Pred, class A>
+typename vdhashmap<K, V, Hash, Pred, A>::local_iterator vdhashmap<K, V, Hash, Pred, A>::begin(size_type n) {
+ return local_iterator(mpBucketStart[n]);
+}
+
+template<class K, class V, class Hash, class Pred, class A>
+typename vdhashmap<K, V, Hash, Pred, A>::const_local_iterator vdhashmap<K, V, Hash, Pred, A>::begin(size_type n) const {
+ return const_local_iterator(mpBucketStart[n]);
+}
+
+template<class K, class V, class Hash, class Pred, class A>
+typename vdhashmap<K, V, Hash, Pred, A>::local_iterator vdhashmap<K, V, Hash, Pred, A>::end(size_type n) {
+ return local_iterator(NULL);
+}
+
+template<class K, class V, class Hash, class Pred, class A>
+typename vdhashmap<K, V, Hash, Pred, A>::const_local_iterator vdhashmap<K, V, Hash, Pred, A>::end(size_type n) const {
+ return const_local_iterator(NULL);
+}
+
+// hash policy
+template<class K, class V, class Hash, class Pred, class A>
+void vdhashmap<K, V, Hash, Pred, A>::rehash(size_type n) {
+ if (!n)
+ n = 1;
+
+ if (mBucketCount == n)
+ return;
+
+ vdhashtable_base_node **newBuckets = mBucketAllocator.allocate(n + 1);
+
+ for(size_type i=0; i<=n; ++i)
+ newBuckets[i] = NULL;
+
+ const size_type m = mBucketCount;
+ for(size_type i=0; i<m; ++i) {
+ for(vdhashtable_base_node *p = mpBucketStart[i]; p;) {
+ vdhashtable_base_node *next = p->mpHashNext;
+ const value_type& vt = static_cast<vdhashtable_node<value_type> *>(p)->mData;
+ size_t bucket = mHasher(vt.first) % n;
+
+ vdhashtable_base_node *head = newBuckets[bucket];
+
+ p->mpHashNext = head;
+ newBuckets[bucket] = p;
+
+ p = next;
+ }
+ }
+
+ if (mpBucketStart != &sEmptyBucket)
+ mBucketAllocator.deallocate(mpBucketStart, (mpBucketEnd - mpBucketStart) + 1);
+
+ mpBucketStart = newBuckets;
+ mpBucketEnd = newBuckets + n;
+ mBucketCount = n;
+}
+
+template<class K, class V, class Hash, class Pred, class A>
+void vdhashmap<K, V, Hash, Pred, A>::rehash_to_size(size_type n) {
+ size_type buckets = compute_bucket_count(n);
+ rehash(buckets);
+}
+
+template<class K, class V, class Hash, class Pred, class A>
+void vdhashmap<K, V, Hash, Pred, A>::reset() {
+ clear();
+
+ if (mpBucketStart != &sEmptyBucket)
+ mBucketAllocator.deallocate(mpBucketStart, (mpBucketEnd - mpBucketStart) + 1);
+}
+
+#endif // f_VD2_SYSTEM_VDSTL_HASHMAP_H
diff --git a/src/thirdparty/VirtualDub/h/vd2/system/vdstl_hashset.h b/src/thirdparty/VirtualDub/h/vd2/system/vdstl_hashset.h
new file mode 100644
index 000000000..f514b26e6
--- /dev/null
+++ b/src/thirdparty/VirtualDub/h/vd2/system/vdstl_hashset.h
@@ -0,0 +1,513 @@
+// VirtualDub - Video processing and capture application
+// System library component
+// Copyright (C) 1998-2010 Avery Lee, All Rights Reserved.
+//
+// Beginning with 1.6.0, the VirtualDub system library is licensed
+// differently than the remainder of VirtualDub. This particular file is
+// thus licensed as follows (the "zlib" license):
+//
+// This software is provided 'as-is', without any express or implied
+// warranty. In no event will the authors be held liable for any
+// damages arising from the use of this software.
+//
+// Permission is granted to anyone to use this software for any purpose,
+// including commercial applications, and to alter it and redistribute it
+// freely, subject to the following restrictions:
+//
+// 1. The origin of this software must not be misrepresented; you must
+// not claim that you wrote the original software. If you use this
+// software in a product, an acknowledgment in the product
+// documentation would be appreciated but is not required.
+// 2. Altered source versions must be plainly marked as such, and must
+// not be misrepresented as being the original software.
+// 3. This notice may not be removed or altered from any source
+// distribution.
+
+#ifndef f_VD2_SYSTEM_VDSTL_HASHSET_H
+#define f_VD2_SYSTEM_VDSTL_HASHSET_H
+
+#include <vd2/system/vdstl_hash.h>
+#include <vd2/system/vdstl_hashtable.h>
+#include <functional>
+
+template<class K, class Hash = vdhash<K>, class Pred = std::equal_to<K>, class A = std::allocator<vdhashtable_node<K> > >
+class vdhashset : public vdhashtable<K> {
+public:
+ typedef K key_type;
+ typedef Hash hasher;
+ typedef Pred key_equal;
+ typedef A allocator_type;
+ typedef std::pair<iterator, bool> insert_return_type;
+
+ vdhashset();
+ vdhashset(const vdhashset&);
+ ~vdhashset();
+
+ vdhashset& operator=(const vdhashset&);
+
+ allocator_type get_allocator() const;
+
+ // iterators
+ using vdhashtable<value_type>::begin;
+ using vdhashtable<value_type>::end;
+// iterator begin(); Inherited.
+// const_iterator begin() const; Inherited.
+// iterator end(); Inherited.
+// const_iterator end() const; Inherited.
+
+ // modifiers
+ insert_return_type insert(const key_type& key);
+// iterator insert(iterator hint, const value_type& obj); // TODO
+// const_iterator insert(const_iterator hint, const value_type& obj); // TODO
+
+ iterator erase(iterator position);
+ const_iterator erase(const_iterator position);
+ size_type erase(const key_type& k);
+// iterator erase(iterator first, iterator last); // TODO
+// const_iterator erase(const_iterator first, const_iterator last); // TODO
+ void clear();
+
+ // observers
+ hasher hash_function() const;
+ key_equal key_eq() const;
+
+ // lookup
+ iterator find(const key_type& k);
+ const_iterator find(const key_type& k) const;
+ size_type count(const key_type& k) const;
+ std::pair<iterator, iterator> equal_range(const key_type& k);
+ std::pair<const_iterator, const_iterator> equal_range(const key_type& k) const;
+
+ // lookup (extensions)
+ template<class U>
+ iterator find_as(const U& k);
+
+ template<class U>
+ const_iterator find_as(const U& k) const;
+
+ // bucket interface
+// size_type bucket_count() const; Inherited.
+// size_type max_bucket_count() const; Inherited.
+// size_type bucket_size(size_type n) const; Inherited.
+ size_type bucket(const key_type& k) const;
+ local_iterator begin(size_type n);
+ const_local_iterator begin(size_type n) const;
+ local_iterator end(size_type n);
+ const_local_iterator end(size_type n) const;
+
+ // hash policy
+// float load_factor() const; // TODO
+// float max_load_factor() const; // TODO
+// void max_load_factor(float z); // TODO
+ void rehash(size_type n);
+
+protected:
+ void rehash_to_size(size_type n);
+ void reset();
+
+ A mAllocator;
+ typename A::rebind<vdhashtable_base_node *>::other mBucketAllocator;
+ Hash mHasher;
+ Pred mPred;
+};
+
+template<class K, class Hash, class Pred, class A>
+vdhashset<K, Hash, Pred, A>::vdhashset() {
+}
+
+template<class K, class Hash, class Pred, class A>
+vdhashset<K, Hash, Pred, A>::vdhashset(const vdhashset& src)
+ : mHasher(src.mHasher)
+ , mPred(src.mPred)
+{
+ rehash_to_size(src.mElementCount);
+
+ try {
+ for(vdhashtable_base_node **bucket = mpBucketStart; bucket != mpBucketEnd; ++bucket) {
+ vdhashtable_base_node *p = *bucket;
+
+ while(p) {
+ vdhashtable_base_node *next = p->mpHashNext;
+ node_type *node = static_cast<node_type *>(p);
+
+ insert(node->mData);
+
+ p = next;
+ }
+
+ *bucket = NULL;
+ }
+ } catch(...) {
+ reset();
+ throw;
+ }
+}
+
+template<class K, class Hash, class Pred, class A>
+vdhashset<K, Hash, Pred, A>::~vdhashset() {
+ reset();
+}
+
+template<class K, class Hash, class Pred, class A>
+vdhashset<K, Hash, Pred, A>& vdhashset<K, Hash, Pred, A>::operator=(const vdhashset& src) {
+ if (&src != this) {
+ clear();
+
+ mHasher = src.mHasher;
+ mPred = src.mPred;
+
+ for(vdhashtable_base_node **bucket = src.mpBucketStart; bucket != src.mpBucketEnd; ++bucket) {
+ vdhashtable_base_node *p = *bucket;
+
+ while(p) {
+ vdhashtable_base_node *next = p->mpHashNext;
+ node_type *node = static_cast<node_type *>(p);
+
+ insert(node->mData);
+
+ p = next;
+ }
+
+ *bucket = NULL;
+ }
+ }
+
+ return *this;
+}
+
+template<class K, class Hash, class Pred, class A>
+typename vdhashset<K, Hash, Pred, A>::allocator_type vdhashset<K, Hash, Pred, A>::get_allocator() const {
+ return A();
+}
+
+// modifiers
+template<class K, class Hash, class Pred, class A>
+typename vdhashset<K, Hash, Pred, A>::insert_return_type vdhashset<K, Hash, Pred, A>::insert(const key_type& key) {
+ if (mElementCount >= mBucketCount)
+ rehash_to_size(mElementCount + 1);
+
+ size_type bucket = mHasher(key) % mBucketCount;
+
+ for(node_type *p = static_cast<node_type *>(mpBucketStart[bucket]); p; p = static_cast<node_type *>(p->mpHashNext)) {
+ if (mPred(p->mData, key))
+ return std::pair<iterator, bool>(iterator(p, &mpBucketStart[bucket], mpBucketEnd), false);
+ }
+
+ node_type *node = mAllocator.allocate(1);
+ try {
+ new(node) node_type(static_cast<node_type *>(mpBucketStart[bucket]), key);
+ } catch(...) {
+ mAllocator.deallocate(node, 1);
+ throw;
+ }
+
+ mpBucketStart[bucket] = node;
+ ++mElementCount;
+
+ return std::pair<iterator, bool>(iterator(node, &mpBucketStart[bucket], mpBucketEnd), true);
+}
+
+template<class K, class Hash, class Pred, class A>
+typename vdhashset<K, Hash, Pred, A>::iterator vdhashset<K, Hash, Pred, A>::erase(iterator position) {
+ size_type bucket = mHasher(position->first) % mBucketCount;
+ vdhashtable_base_node *prev = NULL;
+ vdhashtable_base_node *p = mpBucketStart[bucket];
+
+ while(&static_cast<node_type *>(p)->mData != &*position) {
+ prev = p;
+ p = p->mpHashNext;
+ }
+
+ vdhashtable_base_node *next = p->mpHashNext;
+ if (prev)
+ prev->mpHashNext = next;
+ else
+ mpBucketStart[bucket] = next;
+
+ node_type *node = static_cast<node_type *>(p);
+ node->~node_type();
+ mAllocator.deallocate(node, 1);
+ --mElementCount;
+
+ return iterator(next, &mpBucketStart[bucket], mpBucketEnd);
+}
+
+template<class K, class Hash, class Pred, class A>
+typename vdhashset<K, Hash, Pred, A>::const_iterator vdhashset<K, Hash, Pred, A>::erase(const_iterator position) {
+ size_type bucket = mHasher(position->first) % mBucketCount;
+ const vdhashtable_base_node *prev = NULL;
+ const vdhashtable_base_node *p = mpBucketStart[bucket];
+
+ while(&static_cast<const node_type *>(p)->mData != &*position) {
+ prev = p;
+ p = p->mpHashNext;
+ }
+
+ const vdhashtable_base_node *next = p->mpHashNext;
+ if (prev)
+ prev->mpHashNext = next;
+ else
+ mpBucketStart[bucket] = next;
+
+ node_type *node = static_cast<node_type *>(p);
+ node->~node_type();
+ mAllocator.deallocate(node, 1);
+ --mElementCount;
+
+ return const_iterator(next, &mpBucketStart[bucket], mpBucketEnd);
+}
+
+template<class K, class Hash, class Pred, class A>
+typename vdhashset<K, Hash, Pred, A>::size_type vdhashset<K, Hash, Pred, A>::erase(const key_type& k) {
+ if (!mBucketCount)
+ return 0;
+
+ size_type bucket = mHasher(k) % mBucketCount;
+ vdhashtable_base_node *prev = NULL;
+ vdhashtable_base_node *p = mpBucketStart[bucket];
+
+ while(p) {
+ node_type *node = static_cast<node_type *>(p);
+
+ if (mPred(node->mData.first, k)) {
+ vdhashtable_base_node *next = p->mpHashNext;
+
+ if (prev)
+ prev->mpHashNext = next;
+ else
+ mpBucketStart[bucket] = next;
+
+ node->~node_type();
+ mAllocator.deallocate(node, 1);
+ --mElementCount;
+ return 1;
+ }
+
+ prev = p;
+ p = p->mpHashNext;
+ }
+
+ return 0;
+}
+
+template<class K, class Hash, class Pred, class A>
+void vdhashset<K, Hash, Pred, A>::clear() {
+ for(vdhashtable_base_node **bucket = mpBucketStart; bucket != mpBucketEnd; ++bucket) {
+ vdhashtable_base_node *p = *bucket;
+
+ while(p) {
+ vdhashtable_base_node *next = p->mpHashNext;
+ node_type *node = static_cast<node_type *>(p);
+
+ node->~node_type();
+
+ mAllocator.deallocate(node, 1);
+
+ p = next;
+ }
+
+ *bucket = NULL;
+ }
+
+ mElementCount = 0;
+}
+
+// observers
+template<class K, class Hash, class Pred, class A>
+typename vdhashset<K, Hash, Pred, A>::hasher vdhashset<K, Hash, Pred, A>::hash_function() const {
+ return mHasher;
+}
+
+template<class K, class Hash, class Pred, class A>
+typename vdhashset<K, Hash, Pred, A>::key_equal vdhashset<K, Hash, Pred, A>::key_eq() const {
+ return mPred;
+}
+
+// lookup
+template<class K, class Hash, class Pred, class A>
+typename vdhashset<K, Hash, Pred, A>::iterator vdhashset<K, Hash, Pred, A>::find(const key_type& k) {
+ if (!mBucketCount)
+ return iterator();
+
+ size_type bucket = mHasher(k) % mBucketCount;
+
+ for(vdhashtable_base_node *p = mpBucketStart[bucket]; p; p = p->mpHashNext) {
+ node_type *node = static_cast<node_type *>(p);
+
+ if (mPred(node->mData.first, k))
+ return iterator(node, &mpBucketStart[bucket], mpBucketEnd);
+ }
+
+ return iterator();
+}
+
+template<class K, class Hash, class Pred, class A>
+typename vdhashset<K, Hash, Pred, A>::const_iterator vdhashset<K, Hash, Pred, A>::find(const key_type& k) const {
+ if (!mBucketCount)
+ return iterator();
+
+ size_type bucket = mHasher(k) % mBucketCount;
+
+ for(const vdhashtable_base_node *p = mpBucketStart[bucket]; p; p = p->mpHashNext) {
+ const node_type *node = static_cast<const node_type *>(p);
+
+ if (mPred(node->mData.first, k))
+ return const_iterator(const_cast<vdhashtable_base_node *>(static_cast<const vdhashtable_base_node *>(node)), &mpBucketStart[bucket], mpBucketEnd);
+ }
+
+ return iterator();
+}
+
+template<class K, class Hash, class Pred, class A>
+typename vdhashset<K, Hash, Pred, A>::size_type vdhashset<K, Hash, Pred, A>::count(const key_type& k) const {
+ return find(k) != end() ? 1 : 0;
+}
+
+template<class K, class Hash, class Pred, class A>
+std::pair<typename vdhashset<K, Hash, Pred, A>::iterator, typename vdhashset<K, Hash, Pred, A>::iterator> vdhashset<K, Hash, Pred, A>::equal_range(const key_type& k) {
+ iterator it = find(k);
+ iterator itEnd;
+
+ if (it == itEnd)
+ return std::pair<itEnd, itEnd>();
+
+ itEnd = it;
+ ++itEnd;
+
+ return std::pair<it, itEnd>();
+}
+
+template<class K, class Hash, class Pred, class A>
+std::pair<typename vdhashset<K, Hash, Pred, A>::const_iterator, typename vdhashset<K, Hash, Pred, A>::const_iterator> vdhashset<K, Hash, Pred, A>::equal_range(const key_type& k) const {
+ const_iterator it = find(k);
+ const_iterator itEnd;
+
+ if (it == itEnd)
+ return std::pair<itEnd, itEnd>();
+
+ itEnd = it;
+ ++itEnd;
+
+ return std::pair<it, itEnd>();
+}
+
+template<class K, class Hash, class Pred, class A>
+template<class U>
+typename vdhashset<K, Hash, Pred, A>::iterator vdhashset<K, Hash, Pred, A>::find_as(const U& k) {
+ if (!mBucketCount)
+ return iterator();
+
+ size_type bucket = mHasher(k) % mBucketCount;
+
+ for(vdhashtable_base_node *p = mpBucketStart[bucket]; p; p = p->mpHashNext) {
+ node_type *node = static_cast<node_type *>(p);
+
+ if (mPred(node->mData.first, k))
+ return iterator(node, &mpBucketStart[bucket], mpBucketEnd);
+ }
+
+ return iterator();
+}
+
+template<class K, class Hash, class Pred, class A>
+template<class U>
+typename vdhashset<K, Hash, Pred, A>::const_iterator vdhashset<K, Hash, Pred, A>::find_as(const U& k) const {
+ if (!mBucketCount)
+ return iterator();
+
+ size_type bucket = mHasher(k) % mBucketCount;
+
+ for(const vdhashtable_base_node *p = mpBucketStart[bucket]; p; p = p->mpHashNext) {
+ const node_type *node = static_cast<const node_type *>(p);
+
+ if (mPred(node->mData.first, k))
+ return const_iterator(const_cast<vdhashtable_base_node *>(static_cast<const vdhashtable_base_node *>(node)), &mpBucketStart[bucket], mpBucketEnd);
+ }
+
+ return iterator();
+}
+
+// bucket interface
+template<class K, class Hash, class Pred, class A>
+typename vdhashset<K, Hash, Pred, A>::size_type vdhashset<K, Hash, Pred, A>::bucket(const key_type& k) const {
+ size_type bucket = 0;
+
+ if (mBucketCount)
+ bucket = mHasher(k) % mBucketCount;
+
+ return bucket;
+}
+
+template<class K, class Hash, class Pred, class A>
+typename vdhashset<K, Hash, Pred, A>::local_iterator vdhashset<K, Hash, Pred, A>::begin(size_type n) {
+ return local_iterator(mpBucketStart[n]);
+}
+
+template<class K, class Hash, class Pred, class A>
+typename vdhashset<K, Hash, Pred, A>::const_local_iterator vdhashset<K, Hash, Pred, A>::begin(size_type n) const {
+ return const_local_iterator(mpBucketStart[n]);
+}
+
+template<class K, class Hash, class Pred, class A>
+typename vdhashset<K, Hash, Pred, A>::local_iterator vdhashset<K, Hash, Pred, A>::end(size_type n) {
+ return local_iterator(NULL);
+}
+
+template<class K, class Hash, class Pred, class A>
+typename vdhashset<K, Hash, Pred, A>::const_local_iterator vdhashset<K, Hash, Pred, A>::end(size_type n) const {
+ return const_local_iterator(NULL);
+}
+
+// hash policy
+template<class K, class Hash, class Pred, class A>
+void vdhashset<K, Hash, Pred, A>::rehash(size_type n) {
+ if (!n)
+ n = 1;
+
+ if (mBucketCount == n)
+ return;
+
+ vdhashtable_base_node **newBuckets = mBucketAllocator.allocate(n + 1);
+
+ for(size_type i=0; i<=n; ++i)
+ newBuckets[i] = NULL;
+
+ const size_type m = mBucketCount;
+ for(size_type i=0; i<m; ++i) {
+ for(vdhashtable_base_node *p = mpBucketStart[i]; p;) {
+ vdhashtable_base_node *next = p->mpHashNext;
+ const value_type& vt = static_cast<vdhashtable_node<value_type> *>(p)->mData;
+ size_t bucket = mHasher(vt) % n;
+
+ vdhashtable_base_node *head = newBuckets[bucket];
+
+ p->mpHashNext = head;
+ newBuckets[bucket] = p;
+
+ p = next;
+ }
+ }
+
+ if (mpBucketStart != &sEmptyBucket)
+ mBucketAllocator.deallocate(mpBucketStart, (mpBucketEnd - mpBucketStart) + 1);
+
+ mpBucketStart = newBuckets;
+ mpBucketEnd = newBuckets + n;
+ mBucketCount = n;
+}
+
+template<class K, class Hash, class Pred, class A>
+void vdhashset<K, Hash, Pred, A>::rehash_to_size(size_type n) {
+ size_type buckets = compute_bucket_count(n);
+ rehash(buckets);
+}
+
+template<class K, class Hash, class Pred, class A>
+void vdhashset<K, Hash, Pred, A>::reset() {
+ clear();
+
+ if (mpBucketStart != &sEmptyBucket)
+ mBucketAllocator.deallocate(mpBucketStart, (mpBucketEnd - mpBucketStart) + 1);
+}
+
+#endif // f_VD2_SYSTEM_VDSTL_HASHSET_H
diff --git a/src/thirdparty/VirtualDub/h/vd2/system/vdstl_hashtable.h b/src/thirdparty/VirtualDub/h/vd2/system/vdstl_hashtable.h
new file mode 100644
index 000000000..83b365bd8
--- /dev/null
+++ b/src/thirdparty/VirtualDub/h/vd2/system/vdstl_hashtable.h
@@ -0,0 +1,361 @@
+// VirtualDub - Video processing and capture application
+// System library component
+// Copyright (C) 1998-2010 Avery Lee, All Rights Reserved.
+//
+// Beginning with 1.6.0, the VirtualDub system library is licensed
+// differently than the remainder of VirtualDub. This particular file is
+// thus licensed as follows (the "zlib" license):
+//
+// This software is provided 'as-is', without any express or implied
+// warranty. In no event will the authors be held liable for any
+// damages arising from the use of this software.
+//
+// Permission is granted to anyone to use this software for any purpose,
+// including commercial applications, and to alter it and redistribute it
+// freely, subject to the following restrictions:
+//
+// 1. The origin of this software must not be misrepresented; you must
+// not claim that you wrote the original software. If you use this
+// software in a product, an acknowledgment in the product
+// documentation would be appreciated but is not required.
+// 2. Altered source versions must be plainly marked as such, and must
+// not be misrepresented as being the original software.
+// 3. This notice may not be removed or altered from any source
+// distribution.
+
+#ifndef f_VD2_SYSTEM_VDSTL_HASHTABLE_H
+#define f_VD2_SYSTEM_VDSTL_HASHTABLE_H
+
+///////////////////////////////////////////////////////////////////////////////
+// vdhashtable_base_node
+//
+struct vdhashtable_base_node {
+ vdhashtable_base_node *mpHashNext;
+};
+
+///////////////////////////////////////////////////////////////////////////////
+// vdhashtable_base
+//
+class vdhashtable_base {
+public:
+ typedef size_t size_type;
+ typedef ptrdiff_t difference_type;
+
+ vdhashtable_base();
+
+ // size and capacity
+ bool empty() const { return mElementCount == 0; }
+ size_type size() const { return mElementCount; }
+ size_type max_size() const { return (size_type)-1 >> 1; }
+
+ // bucket interface
+ size_type bucket_count() const;
+ size_type max_bucket_count() const;
+ size_type bucket_size(size_type n) const;
+
+protected:
+ static size_type compute_bucket_count(size_type n);
+
+ size_type mBucketCount;
+ size_type mElementCount;
+ vdhashtable_base_node **mpBucketStart;
+ vdhashtable_base_node **mpBucketEnd;
+
+ static vdhashtable_base_node *const sEmptyBucket;
+};
+
+///////////////////////////////////////////////////////////////////////////
+
+template<class T>
+struct vdhashtable_node : public vdhashtable_base_node {
+ T mData;
+
+ vdhashtable_node() {}
+ vdhashtable_node(vdhashtable_node<T> *next, const T& val) : mData(val) {
+ mpHashNext = next;
+ }
+};
+
+///////////////////////////////////////////////////////////////////////////
+
+template<class T>
+class vdhashtable_local_iterator {
+public:
+ typedef std::forward_iterator_tag iterator_category;
+ typedef T value_type;
+ typedef T* pointer;
+ typedef T& reference;
+ typedef size_t size_type;
+ typedef ptrdiff_t difference_type;
+
+ vdhashtable_local_iterator(vdhashtable_base_node *node);
+
+ vdhashtable_local_iterator& operator++();
+ vdhashtable_local_iterator operator++(int);
+
+ T& operator*() const;
+ T* operator->() const;
+
+private:
+ template<class T> friend bool operator==(const vdhashtable_local_iterator<T>& x, const vdhashtable_local_iterator<T>& y);
+ template<class T> friend bool operator==(const vdhashtable_local_iterator<const T>& x, const vdhashtable_local_iterator<T>& y);
+ template<class T> friend bool operator==(const vdhashtable_local_iterator<T>& x, const vdhashtable_local_iterator<const T>& y);
+ template<class T> friend bool operator!=(const vdhashtable_local_iterator<T>& x, const vdhashtable_local_iterator<T>& y);
+ template<class T> friend bool operator!=(const vdhashtable_local_iterator<const T>& x, const vdhashtable_local_iterator<T>& y);
+ template<class T> friend bool operator!=(const vdhashtable_local_iterator<T>& x, const vdhashtable_local_iterator<const T>& y);
+
+ vdhashtable_base_node *mpNode;
+};
+
+template<class T>
+vdhashtable_local_iterator<T>::vdhashtable_local_iterator(vdhashtable_base_node *node)
+ : mpNode(node)
+{
+}
+
+template<class T>
+vdhashtable_local_iterator<T>& vdhashtable_local_iterator<T>::operator++() {
+ mpNode = mpNode->mpHashNext;
+ return *this;
+}
+
+template<class T>
+vdhashtable_local_iterator<T> vdhashtable_local_iterator<T>::operator++(int) {
+ vdhashtable_local_iterator prev(*this);
+ mpNode = mpNode->mpHashNext;
+ return prev;
+}
+
+template<class T>
+T& vdhashtable_local_iterator<T>::operator*() const {
+ return static_cast<vdhashtable_node<T> *>(mpNode)->mData;
+}
+
+template<class T>
+T* vdhashtable_local_iterator<T>::operator->() const {
+ return &static_cast<vdhashtable_node<T> *>(mpNode)->mData;
+}
+
+template<class T>
+bool operator==(const vdhashtable_local_iterator<T>& x, const vdhashtable_local_iterator<T>& y) {
+ return x.mpNode == y.mpNode;
+}
+
+template<class T>
+bool operator==(const vdhashtable_local_iterator<const T>& x, const vdhashtable_local_iterator<T>& y) {
+ return x.mpNode == y.mpNode;
+}
+
+template<class T>
+bool operator==(const vdhashtable_local_iterator<T>& x, const vdhashtable_local_iterator<const T>& y) {
+ return x.mpNode == y.mpNode;
+}
+
+template<class T>
+bool operator!=(const vdhashtable_local_iterator<T>& x, const vdhashtable_local_iterator<T>& y) {
+ return x.mpNode != y.mpNode;
+}
+
+template<class T>
+bool operator!=(const vdhashtable_local_iterator<const T>& x, const vdhashtable_local_iterator<T>& y) {
+ return x.mpNode != y.mpNode;
+}
+
+template<class T>
+bool operator!=(const vdhashtable_local_iterator<T>& x, const vdhashtable_local_iterator<const T>& y) {
+ return x.mpNode != y.mpNode;
+}
+
+///////////////////////////////////////////////////////////////////////////
+
+template<class T> struct vdhashtable_iterator_nonconst {
+ typedef T result;
+};
+
+template<class T> struct vdhashtable_iterator_nonconst<const T> {
+ typedef T result;
+};
+
+template<class T>
+class vdhashtable_iterator {
+ typedef typename vdhashtable_iterator_nonconst<T>::result T_NonConst;
+public:
+ typedef std::forward_iterator_tag iterator_category;
+ typedef T value_type;
+ typedef T* pointer;
+ typedef T& reference;
+ typedef size_t size_type;
+ typedef ptrdiff_t difference_type;
+
+ vdhashtable_iterator();
+ vdhashtable_iterator(vdhashtable_base_node *node, vdhashtable_base_node **bucket, vdhashtable_base_node **bucketEnd);
+ vdhashtable_iterator(const vdhashtable_iterator<T_NonConst>& src);
+
+ vdhashtable_iterator& operator++();
+ vdhashtable_iterator operator++(int);
+
+ T& operator*() const;
+ T* operator->() const;
+
+private:
+ friend class vdhashtable_iterator<const T>;
+ template<class T> friend bool operator==(const vdhashtable_iterator<T>& x, const vdhashtable_iterator<T>& y);
+ template<class T> friend bool operator==(const vdhashtable_iterator<const T>& x, const vdhashtable_iterator<T>& y);
+ template<class T> friend bool operator==(const vdhashtable_iterator<T>& x, const vdhashtable_iterator<const T>& y);
+ template<class T> friend bool operator!=(const vdhashtable_iterator<T>& x, const vdhashtable_iterator<T>& y);
+ template<class T> friend bool operator!=(const vdhashtable_iterator<const T>& x, const vdhashtable_iterator<T>& y);
+ template<class T> friend bool operator!=(const vdhashtable_iterator<T>& x, const vdhashtable_iterator<const T>& y);
+
+ vdhashtable_base_node *mpNode;
+ vdhashtable_base_node **mpBucket;
+ vdhashtable_base_node **mpBucketEnd;
+};
+
+template<class T>
+vdhashtable_iterator<T>::vdhashtable_iterator()
+ : mpNode(NULL)
+ , mpBucket(NULL)
+ , mpBucketEnd(NULL)
+{
+}
+
+template<class T>
+vdhashtable_iterator<T>::vdhashtable_iterator(vdhashtable_base_node *node, vdhashtable_base_node **bucket, vdhashtable_base_node **bucketEnd)
+ : mpNode(node)
+ , mpBucket(bucket)
+ , mpBucketEnd(bucketEnd)
+{
+}
+
+template<class T>
+vdhashtable_iterator<T>::vdhashtable_iterator(const vdhashtable_iterator<T_NonConst>& src)
+ : mpNode(src.mpNode)
+ , mpBucket(src.mpBucket)
+ , mpBucketEnd(src.mpBucketEnd)
+{
+}
+
+template<class T>
+vdhashtable_iterator<T>& vdhashtable_iterator<T>::operator++() {
+ mpNode = mpNode->mpHashNext;
+
+ while(!mpNode && ++mpBucket != mpBucketEnd)
+ mpNode = static_cast<vdhashtable_node<T> *>(*mpBucket);
+
+ return *this;
+}
+
+template<class T>
+vdhashtable_iterator<T> vdhashtable_iterator<T>::operator++(int) {
+ vdhashtable_iterator prev(*this);
+ mpNode = mpNode->mpHashNext;
+ return prev;
+}
+
+template<class T>
+T& vdhashtable_iterator<T>::operator*() const {
+ return static_cast<vdhashtable_node<T> *>(mpNode)->mData;
+}
+
+template<class T>
+T* vdhashtable_iterator<T>::operator->() const {
+ return &static_cast<vdhashtable_node<T> *>(mpNode)->mData;
+}
+
+template<class T>
+bool operator==(const vdhashtable_iterator<T>& x, const vdhashtable_iterator<T>& y) {
+ return x.mpNode == y.mpNode;
+}
+
+template<class T>
+bool operator==(const vdhashtable_iterator<const T>& x, const vdhashtable_iterator<T>& y) {
+ return x.mpNode == y.mpNode;
+}
+
+template<class T>
+bool operator==(const vdhashtable_iterator<T>& x, const vdhashtable_iterator<const T>& y) {
+ return x.mpNode == y.mpNode;
+}
+
+template<class T>
+bool operator!=(const vdhashtable_iterator<T>& x, const vdhashtable_iterator<T>& y) {
+ return x.mpNode != y.mpNode;
+}
+
+template<class T>
+bool operator!=(const vdhashtable_iterator<const T>& x, const vdhashtable_iterator<T>& y) {
+ return x.mpNode != y.mpNode;
+}
+
+template<class T>
+bool operator!=(const vdhashtable_iterator<T>& x, const vdhashtable_iterator<const T>& y) {
+ return x.mpNode != y.mpNode;
+}
+
+///////////////////////////////////////////////////////////////////////////
+
+template<class T>
+class vdhashtable : public vdhashtable_base {
+public:
+ typedef T value_type;
+ typedef vdhashtable_node<value_type> node_type;
+ typedef value_type *pointer;
+ typedef const value_type *const_pointer;
+ typedef value_type& reference;
+ typedef const value_type& const_reference;
+ typedef vdhashtable_iterator<value_type> iterator;
+ typedef vdhashtable_iterator<const value_type> const_iterator;
+ typedef vdhashtable_local_iterator<value_type> local_iterator;
+ typedef vdhashtable_local_iterator<const value_type> const_local_iterator;
+
+ // iterators
+ iterator begin();
+ const_iterator begin() const;
+ iterator end();
+ const_iterator end() const;
+};
+
+// iterators
+template<class T>
+typename vdhashtable<T>::iterator vdhashtable<T>::begin() {
+ vdhashtable_base_node **bucket = mpBucketStart;
+ vdhashtable_base_node *p = NULL;
+
+ while(bucket != mpBucketEnd) {
+ p = *bucket;
+ if (p)
+ break;
+
+ ++bucket;
+ }
+
+ return iterator(static_cast<node_type *>(p), bucket, mpBucketEnd);
+}
+
+template<class T>
+typename vdhashtable<T>::const_iterator vdhashtable<T>::begin() const {
+ vdhashtable_base_node **bucket = mpBucketStart;
+ vdhashtable_base_node *p = NULL;
+
+ while(bucket != mpBucketEnd) {
+ p = *bucket;
+ if (p)
+ break;
+
+ ++bucket;
+ }
+
+ return const_iterator(static_cast<node_type *>(p), bucket, mpBucketEnd);
+}
+
+template<class T>
+typename vdhashtable<T>::iterator vdhashtable<T>::end() {
+ return iterator(NULL, NULL, NULL);
+}
+
+template<class T>
+typename vdhashtable<T>::const_iterator vdhashtable<T>::end() const {
+ return const_iterator(NULL, NULL, NULL);
+}
+
+#endif // f_VD2_SYSTEM_VDSTL_HASHTABLE_H
diff --git a/src/thirdparty/VirtualDub/h/vd2/system/vdstl_vector.h b/src/thirdparty/VirtualDub/h/vd2/system/vdstl_vector.h
new file mode 100644
index 000000000..43e062df1
--- /dev/null
+++ b/src/thirdparty/VirtualDub/h/vd2/system/vdstl_vector.h
@@ -0,0 +1,606 @@
+// VirtualDub - Video processing and capture application
+// System library component
+// Copyright (C) 1998-2009 Avery Lee, All Rights Reserved.
+//
+// Beginning with 1.6.0, the VirtualDub system library is licensed
+// differently than the remainder of VirtualDub. This particular file is
+// thus licensed as follows (the "zlib" license):
+//
+// This software is provided 'as-is', without any express or implied
+// warranty. In no event will the authors be held liable for any
+// damages arising from the use of this software.
+//
+// Permission is granted to anyone to use this software for any purpose,
+// including commercial applications, and to alter it and redistribute it
+// freely, subject to the following restrictions:
+//
+// 1. The origin of this software must not be misrepresented; you must
+// not claim that you wrote the original software. If you use this
+// software in a product, an acknowledgment in the product
+// documentation would be appreciated but is not required.
+// 2. Altered source versions must be plainly marked as such, and must
+// not be misrepresented as being the original software.
+// 3. This notice may not be removed or altered from any source
+// distribution.
+
+#ifndef f_VD2_SYSTEM_VDSTL_VECTOR_H
+#define f_VD2_SYSTEM_VDSTL_VECTOR_H
+
+#ifdef _MSC_VER
+#pragma once
+#endif
+
+template <class T, class A = vdallocator<T> >
+class vdvector {
+public:
+ typedef typename A::reference reference;
+ typedef typename A::const_reference const_reference;
+ typedef T *iterator;
+ typedef const T *const_iterator;
+ typedef size_t size_type;
+ typedef ptrdiff_t difference_type;
+ typedef T value_type;
+ typedef A allocator_type;
+ typedef typename A::pointer pointer;
+ typedef typename A::const_pointer const_pointer;
+ typedef typename vdreverse_iterator<iterator, T>::type reverse_iterator;
+ typedef typename vdreverse_iterator<const_iterator, T>::type const_reverse_iterator;
+
+ // 23.2.4.1 construct/copy/destroy:
+ explicit vdvector();
+ explicit vdvector(const A&);
+ explicit vdvector(size_type n);
+ explicit vdvector(size_type n, const T& value, const A& = A());
+ template <class InputIterator>
+ vdvector(InputIterator first, InputIterator last, const A& = A());
+ vdvector(const vdvector<T,A>& x);
+ ~vdvector();
+ vdvector<T,A>& operator=(const vdvector<T,A>& x);
+ template <class InputIterator>
+ void assign(InputIterator first, InputIterator last);
+ void assign(size_type n, const T& u);
+ allocator_type get_allocator() const;
+
+ // iterators:
+ iterator begin();
+ const_iterator begin() const;
+ iterator end();
+ const_iterator end() const;
+ reverse_iterator rbegin();
+ const_reverse_iterator rbegin() const;
+ reverse_iterator rend();
+ const_reverse_iterator rend() const;
+ pointer data();
+ const_pointer data() const;
+
+ // 23.2.4.2 capacity:
+ size_type size() const;
+ size_type max_size() const;
+ size_type capacity() const;
+ bool empty() const;
+
+ // element access:
+ reference operator[](size_type n);
+ const_reference operator[](size_type n) const;
+ const_reference at(size_type n) const;
+ reference at(size_type n);
+ reference front();
+ const_reference front() const;
+ reference back();
+ const_reference back() const;
+
+ void resize(size_type sz, T c = T());
+ void reserve(size_type n);
+
+ template<class U>
+ void push_back_as(const U& x);
+
+ reference push_back();
+ void push_back(const T& x);
+ void pop_back();
+ iterator insert(iterator position, const T& x);
+
+ template<class U>
+ iterator insert_as(iterator position, const U& x);
+
+ void insert(iterator position, size_type n, const T& x);
+ template <class InputIterator>
+ void insert(iterator position, InputIterator first, InputIterator last);
+ iterator erase(iterator position);
+ iterator erase(iterator first, iterator last);
+ void swap(vdvector<T,A>&);
+ void clear();
+
+private:
+ void free_storage();
+
+ struct Data : public A {
+ pointer mpBegin;
+ pointer mpEnd;
+ pointer mpEOS;
+
+ Data() : A(), mpBegin(NULL), mpEnd(NULL), mpEOS(NULL) {}
+ Data(const A& alloc) : A(alloc), mpBegin(NULL), mpEnd(NULL), mpEOS(NULL) {}
+ } m;
+};
+
+template <class T, class A>
+vdvector<T,A>::vdvector() {
+}
+
+template <class T, class A>
+vdvector<T,A>::vdvector(const A& a)
+ : m(a)
+{
+}
+
+template <class T, class A>
+vdvector<T,A>::vdvector(size_type n) {
+ resize(n);
+}
+
+template <class T, class A>
+vdvector<T,A>::vdvector(size_type n, const T& value, const A& a = A())
+ : m(a)
+{
+ resize(n, value);
+}
+
+template <class T, class A>
+template <class InputIterator>
+vdvector<T,A>::vdvector(InputIterator first, InputIterator last, const A& a = A())
+ : m(a)
+{
+ assign(first, last);
+}
+
+template <class T, class A>
+vdvector<T,A>::vdvector(const vdvector<T,A>& x)
+ : m(static_cast<const A&>(x.m))
+{
+ assign(x.m.mpBegin, x.m.mpEnd);
+}
+
+template <class T, class A>
+vdvector<T,A>::~vdvector() {
+ clear();
+
+ if (m.mpBegin)
+ m.deallocate(m.mpBegin, m.mpEOS - m.mpBegin);
+}
+
+template <class T, class A>
+vdvector<T,A>& vdvector<T,A>::operator=(const vdvector<T,A>& x) {
+ if (&x != this) {
+ vdvector tmp(x);
+
+ swap(tmp);
+ }
+
+ return *this;
+}
+
+template <class T, class A>
+template <class InputIterator>
+void vdvector<T,A>::assign(InputIterator first, InputIterator last) {
+ clear();
+ insert(m.mpBegin, first, last);
+}
+
+template <class T, class A>
+void vdvector<T,A>::assign(size_type n, const T& u) {
+ clear();
+ insert(m.mpBegin, n, u);
+}
+
+template <class T, class A> typename vdvector<T,A>::allocator_type vdvector<T,A>::get_allocator() const { return m; }
+template <class T, class A> typename vdvector<T,A>::iterator vdvector<T,A>::begin() { return m.mpBegin; }
+template <class T, class A> typename vdvector<T,A>::const_iterator vdvector<T,A>::begin() const { return m.mpBegin; }
+template <class T, class A> typename vdvector<T,A>::iterator vdvector<T,A>::end() { return m.mpEnd; }
+template <class T, class A> typename vdvector<T,A>::const_iterator vdvector<T,A>::end() const { return m.mpEnd; }
+template <class T, class A> typename vdvector<T,A>::reverse_iterator vdvector<T,A>::rbegin() { return reverse_iterator(m.mpEnd); }
+template <class T, class A> typename vdvector<T,A>::const_reverse_iterator vdvector<T,A>::rbegin() const { return const_reverse_iterator(m.mpEnd); }
+template <class T, class A> typename vdvector<T,A>::reverse_iterator vdvector<T,A>::rend() { return reverse_iterator(m.mpBegin); }
+template <class T, class A> typename vdvector<T,A>::const_reverse_iterator vdvector<T,A>::rend() const { return const_reverse_iterator(m.mpBegin); }
+template <class T, class A> typename vdvector<T,A>::pointer vdvector<T,A>::data() { return m.mpBegin; }
+template <class T, class A> typename vdvector<T,A>::const_pointer vdvector<T,A>::data() const { return m.mpBegin; }
+
+template <class T, class A> typename vdvector<T,A>::size_type vdvector<T,A>::size() const { return m.mpEnd - m.mpBegin; }
+template <class T, class A> typename vdvector<T,A>::size_type vdvector<T,A>::max_size() const { return m.max_size(); }
+template <class T, class A> typename vdvector<T,A>::size_type vdvector<T,A>::capacity() const { return m.mpEOS - m.mpBegin; }
+template <class T, class A> typename bool vdvector<T,A>::empty() const { return m.mpBegin == m.mpEnd; }
+
+template <class T, class A> typename vdvector<T,A>::reference vdvector<T,A>::operator[](size_type n) { return m.mpBegin[n]; }
+template <class T, class A> typename vdvector<T,A>::const_reference vdvector<T,A>::operator[](size_type n) const { return m.mpBegin[n]; }
+template <class T, class A> typename vdvector<T,A>::const_reference vdvector<T,A>::at(size_type n) const { if (n >= (size_type)(m.mpEnd - m.mpBegin)) throw std::out_of_range("The index is out of range."); return m.mpBegin[n]; }
+template <class T, class A> typename vdvector<T,A>::reference vdvector<T,A>::at(size_type n) { if (n >= (size_type)(m.mpEnd - m.mpBegin)) throw std::out_of_range("The index is out of range."); return m.mpBegin[n]; }
+template <class T, class A> typename vdvector<T,A>::reference vdvector<T,A>::front() { return *m.mpBegin; }
+template <class T, class A> typename vdvector<T,A>::const_reference vdvector<T,A>::front() const { return *m.mpBegin; }
+template <class T, class A> typename vdvector<T,A>::reference vdvector<T,A>::back() { return m.mpEnd[-1]; }
+template <class T, class A> typename vdvector<T,A>::const_reference vdvector<T,A>::back() const { return m.mpEnd[-1]; }
+
+template <class T, class A>
+void vdvector<T,A>::resize(size_type sz, T c = T()) {
+ const size_type currSize = m.mpEnd - m.mpBegin;
+
+ if (sz < currSize) {
+ T *p = m.mpBegin + sz;
+ while(m.mpEnd != p) {
+ --m.mpEnd;
+ m.mpEnd->~T();
+ }
+ } else if (sz > currSize) {
+ const size_type currCapacity = m.mpEOS - m.mpBegin;
+
+ if (sz > currCapacity) {
+ pointer p0 = m.allocate(sz);
+
+ try {
+ pointer p1 = std::uninitialized_copy(m.mpBegin, m.mpEnd, p0);
+ pointer p2 = p0 + sz;
+
+ T *prev0 = m.mpBegin;
+ T *prev1 = m.mpEnd;
+ T *prev2 = m.mpEOS;
+ try {
+ std::uninitialized_fill(p1, p2, c);
+
+ // destroy old range
+ while(prev1 != prev0) {
+ --prev1;
+ prev0->~T();
+ }
+
+ m.mpBegin = p0;
+ m.mpEnd = p2;
+ m.mpEOS = p2;
+ } catch(...) {
+ while(p2 != p1) {
+ --p2;
+ p2->~T();
+ }
+ m.deallocate(p0, sz);
+ throw;
+ }
+
+ m.deallocate(prev0, prev2 - prev0);
+ } catch(...) {
+ m.deallocate(p0, sz);
+ throw;
+ }
+ } else {
+ pointer newEnd = m.mpBegin + sz;
+ std::uninitialized_fill(m.mpEnd, newEnd, c);
+ m.mpEnd = newEnd;
+ }
+ }
+}
+
+template <class T, class A>
+void vdvector<T,A>::reserve(size_type n) {
+ const size_type currCapacity = m.mpEOS - m.mpBegin;
+
+ if (n <= currCapacity)
+ return;
+
+ pointer p0 = m.allocate(n);
+
+ try {
+ pointer p1 = std::uninitialized_copy(m.mpBegin, m.mpEnd, p0);
+
+ free_storage();
+
+ m.mpBegin = p0;
+ m.mpEnd = p1;
+ m.mpEOS = p0 + n;
+ } catch(...) {
+ m.deallocate(p0, n);
+ throw;
+ }
+}
+
+template<class T, class A>
+template<class U>
+void vdvector<T,A>::push_back_as(const U& x) {
+ if (m.mpEnd != m.mpEOS) {
+ new(m.mpEnd) T(x);
+ ++m.mpEnd;
+ } else {
+ insert_as(m.mpEnd, x);
+ }
+}
+
+template <class T, class A>
+typename vdvector<T,A>::reference vdvector<T,A>::push_back() {
+ if (m.mpEnd != m.mpEOS) {
+ new(m.mpEnd) T();
+ return *m.mpEnd++;
+ } else {
+ return *insert(m.mpEnd, T());
+ }
+}
+
+template <class T, class A>
+void vdvector<T,A>::push_back(const T& x) {
+ VDASSERT(m.mpEnd >= m.mpBegin && m.mpEnd <= m.mpEOS);
+ if (m.mpEnd != m.mpEOS) {
+ new(m.mpEnd) T(x);
+ ++m.mpEnd;
+ } else {
+ insert(m.mpEnd, x);
+ }
+}
+
+template <class T, class A>
+void vdvector<T,A>::pop_back() {
+ --m.mpEnd;
+ m.mpEnd->~T();
+}
+
+template <class T, class A>
+template<class U>
+typename vdvector<T,A>::iterator vdvector<T,A>::insert_as(iterator position, const U& x) {
+ if (m.mpEnd == m.mpEOS) {
+ const size_type currSize = m.mpEnd - m.mpBegin;
+ const size_type newCapacity = currSize + 1;
+
+ const pointer p0 = m.allocate(newCapacity);
+ pointer pe = p0;
+ try {
+ const pointer p1 = std::uninitialized_copy(m.mpBegin, position, p0);
+ pe = p1;
+
+ new(pe) T(x);
+ ++pe;
+
+ const pointer p3 = std::uninitialized_copy(position, m.mpEnd, pe);
+ pe = p3;
+
+ free_storage();
+
+ m.mpBegin = p0;
+ m.mpEnd = pe;
+ m.mpEOS = p0 + newCapacity;
+
+ return p1;
+ } catch(...) {
+ while(pe != p0) {
+ --pe;
+ pe->~T();
+ }
+
+ m.deallocate(p0, newCapacity);
+ throw;
+ }
+ } else if (position != m.mpEnd) {
+ T tmp(*position);
+
+ *position = x;
+
+ new(m.mpEnd) T();
+
+ try {
+ vdmove_backward(position + 1, m.mpEnd, m.mpEnd + 1);
+ position[1] = tmp;
+ ++m.mpEnd;
+ } catch(...) {
+ m.mpEnd->~T();
+ throw;
+ }
+
+ return position;
+ } else {
+ new(m.mpEnd) T(x);
+ ++m.mpEnd;
+
+ return position;
+ }
+}
+
+template <class T, class A>
+typename vdvector<T,A>::iterator vdvector<T,A>::insert(iterator position, const T& x) {
+ if (m.mpEnd == m.mpEOS) {
+ const size_type currSize = m.mpEnd - m.mpBegin;
+ const size_type newCapacity = currSize + 1;
+
+ const pointer p0 = m.allocate(newCapacity);
+ pointer pe = p0;
+ try {
+ const pointer p1 = std::uninitialized_copy(m.mpBegin, position, p0);
+ pe = p1;
+
+ new(pe) T(x);
+ ++pe;
+
+ const pointer p3 = std::uninitialized_copy(position, m.mpEnd, pe);
+ pe = p3;
+
+ free_storage();
+
+ m.mpBegin = p0;
+ m.mpEnd = pe;
+ m.mpEOS = p0 + newCapacity;
+
+ return p1;
+ } catch(...) {
+ while(pe != p0) {
+ --pe;
+ pe->~T();
+ }
+
+ m.deallocate(p0, newCapacity);
+ throw;
+ }
+ } else if (position != m.mpEnd) {
+ T tmp(*position);
+
+ *position = x;
+
+ new(m.mpEnd) T();
+
+ try {
+ vdmove_backward(position + 1, m.mpEnd, m.mpEnd + 1);
+ position[1] = tmp;
+ ++m.mpEnd;
+ } catch(...) {
+ m.mpEnd->~T();
+ throw;
+ }
+
+ return position;
+ } else {
+ new(m.mpEnd) T(x);
+ ++m.mpEnd;
+
+ return position;
+ }
+}
+
+template <class T, class A>
+void vdvector<T,A>::insert(iterator position, size_type n, const T& x) {
+ if ((size_type)(m.mpEOS - m.mpEnd) < n) {
+ const size_type currSize = m.mpEnd - m.mpBegin;
+ const size_type newCapacity = currSize + n;
+
+ const pointer p0 = m.allocate(newCapacity);
+ pointer pe = p0;
+ try {
+ const pointer p1 = std::uninitialized_copy(m.mpBegin, position, p0);
+ pe = p1;
+
+ const pointer p2 = p1 + n;
+ std::uninitialized_fill(p1, p2, x);
+ pe = p2;
+
+ const pointer p3 = std::uninitialized_copy(position, m.mpEnd, p2);
+ pe = p3;
+
+ free_storage();
+
+ m.mpBegin = p0;
+ m.mpEnd = pe;
+ m.mpEOS = p0 + newCapacity;
+ } catch(...) {
+ while(pe != p0) {
+ --pe;
+ pe->~T();
+ }
+
+ m.deallocate(p0, newCapacity);
+ throw;
+ }
+ } else if (n) {
+ pointer newEnd = m.mpEnd + n;
+ pointer insEnd = std::copy_backward(position, m.mpEnd, newEnd);
+
+ try {
+ std::uninitialized_fill(position, m.mpEnd, x);
+ m.mpEnd = newEnd;
+ } catch(...) {
+ std::copy(insEnd, newEnd, position);
+ throw;
+ }
+ }
+}
+
+template <class T, class A>
+template <class InputIterator>
+void vdvector<T,A>::insert(iterator position, InputIterator first, InputIterator last) {
+ const size_type n = last - first;
+
+ if ((size_type)(m.mpEOS - m.mpEnd) < n) {
+ const size_type currSize = m.mpEnd - m.mpBegin;
+ const size_type newCapacity = currSize + n;
+
+ const pointer p0 = m.allocate(newCapacity);
+ pointer pe = p0;
+ try {
+ const pointer p1 = std::uninitialized_copy(m.mpBegin, position, p0);
+ pe = p1;
+
+ const pointer p2 = p1 + n;
+ std::uninitialized_copy(first, last, p1);
+ pe = p2;
+
+ const pointer p3 = std::uninitialized_copy(position, m.mpEnd, p2);
+ pe = p3;
+
+ free_storage();
+
+ m.mpBegin = p0;
+ m.mpEnd = pe;
+ m.mpEOS = p0 + newCapacity;
+ } catch(...) {
+ while(pe != p0) {
+ --pe;
+ pe->~T();
+ }
+
+ m.deallocate(p0, newCapacity);
+ throw;
+ }
+ } else if (n) {
+ pointer newEnd = m.mpEnd + n;
+ pointer insEnd = std::copy_backward(position, m.mpEnd, newEnd);
+
+ try {
+ std::uninitialized_copy(first, last, position);
+ m.mpEnd = newEnd;
+ } catch(...) {
+ std::copy(insEnd, newEnd, position);
+ throw;
+ }
+ }
+}
+
+template <class T, class A>
+typename vdvector<T,A>::iterator vdvector<T,A>::erase(iterator position) {
+ m.mpEnd = vdmove_forward(position + 1, m.mpEnd, position);
+ m.mpEnd->~T();
+
+ return position;
+}
+
+template <class T, class A>
+typename vdvector<T,A>::iterator vdvector<T,A>::erase(iterator first, iterator last) {
+ if (first != last) {
+ pointer p = vdmove_forward(last, m.mpEnd, first);
+
+ for(pointer q = p; q != m.mpEnd; ++q)
+ q->~T();
+
+ m.mpEnd = p;
+ }
+
+ return first;
+}
+
+template <class T, class A>
+void vdvector<T,A>::swap(vdvector<T,A>& x) {
+ std::swap(m.mpBegin, x.m.mpBegin);
+ std::swap(m.mpEnd, x.m.mpEnd);
+ std::swap(m.mpEOS, x.m.mpEOS);
+}
+
+template <class T, class A>
+void vdvector<T,A>::clear() {
+ while(m.mpEnd != m.mpBegin) {
+ --m.mpEnd;
+ m.mpEnd->~T();
+ }
+}
+
+template <class T, class A>
+void vdvector<T,A>::free_storage() {
+ pointer b = m.mpBegin;
+ pointer p = m.mpEnd;
+
+ while(p != b) {
+ --p;
+ p->~T();
+ }
+
+ m.deallocate(b, m.mpEOS - b);
+}
+
+#endif // f_VD2_SYSTEM_VDSTL_VECTOR_H
diff --git a/src/thirdparty/VirtualDub/h/vd2/system/vdtypes.h b/src/thirdparty/VirtualDub/h/vd2/system/vdtypes.h
index 5e5bdc898..0a5a63e50 100644
--- a/src/thirdparty/VirtualDub/h/vd2/system/vdtypes.h
+++ b/src/thirdparty/VirtualDub/h/vd2/system/vdtypes.h
@@ -272,7 +272,7 @@ extern void VDDebugPrint(const char *format, ...);
#endif
-#if defined(_DEBUG) && !defined(__INTEL_COMPILER) /* MPC specific - Cannot use these macros with ICL */
+#ifdef _DEBUG
namespace {
template<int line>
diff --git a/src/thirdparty/VirtualDub/h/vd2/system/vectors.h b/src/thirdparty/VirtualDub/h/vd2/system/vectors.h
index 6dcbe65fa..ea42546b5 100644
--- a/src/thirdparty/VirtualDub/h/vd2/system/vectors.h
+++ b/src/thirdparty/VirtualDub/h/vd2/system/vectors.h
@@ -276,6 +276,10 @@ public:
vector_type m[3];
};
+inline vdfloat3 operator*(const vdfloat3& v, const vdfloat3x3& m) {
+ return v.x * m.m[0] + v.y * m.m[1] + v.z * m.m[2];
+}
+
class vdfloat4x4 {
public:
enum zero_type { zero };
@@ -419,6 +423,26 @@ struct VDSize {
};
template<class T>
+class VDPoint {
+public:
+ VDPoint();
+ VDPoint(T x_, T y_);
+
+ T x;
+ T y;
+};
+
+template<class T>
+VDPoint<T>::VDPoint() {
+}
+
+template<class T>
+VDPoint<T>::VDPoint(T x_, T y_)
+ : x(x_), y(y_)
+{
+}
+
+template<class T>
class VDRect {
public:
typedef T value_type;
@@ -447,6 +471,8 @@ public:
T area() const;
VDSize<T> size() const;
+ bool contains(const VDPoint<T>& pt) const;
+
public:
T left, top, right, bottom;
};
@@ -559,10 +585,21 @@ T VDRect<T>::area() const { return (right-left)*(bottom-top); }
template<class T>
VDSize<T> VDRect<T>::size() const { return VDSize<T>(right-left, bottom-top); }
+template<class T>
+bool VDRect<T>::contains(const VDPoint<T>& pt) const {
+ return pt.x >= left
+ && pt.x < right
+ && pt.y >= top
+ && pt.y < bottom;
+}
+
///////////////////////////////////////////////////////////////////////////////
+typedef VDPoint<sint32> vdpoint32;
typedef VDSize<sint32> vdsize32;
typedef VDSize<float> vdsize32f;
typedef VDRect<sint32> vdrect32;
typedef VDRect<float> vdrect32f;
+template<> bool vdrect32::contains(const vdpoint32& pt) const;
+
#endif
diff --git a/src/thirdparty/VirtualDub/h/vd2/system/w32assist.h b/src/thirdparty/VirtualDub/h/vd2/system/w32assist.h
index e47e20f52..e7c13629b 100644
--- a/src/thirdparty/VirtualDub/h/vd2/system/w32assist.h
+++ b/src/thirdparty/VirtualDub/h/vd2/system/w32assist.h
@@ -40,6 +40,10 @@ inline bool VDIsWindowsNT() {
#endif
}
+inline bool VDIsAtLeastVistaW32() {
+ return (sint32)(::GetVersion() & 0x800000FF) >= 6;
+}
+
// useful constants missing from the Platform SDK
enum {
@@ -62,9 +66,12 @@ void VDSwitchToFiberW32(LPVOID fiber);
int VDGetSizeOfBitmapHeaderW32(const BITMAPINFOHEADER *pHdr);
void VDSetWindowTextW32(HWND hwnd, const wchar_t *s);
void VDSetWindowTextFW32(HWND hwnd, const wchar_t *format, ...);
+VDStringA VDGetWindowTextAW32(HWND hwnd);
VDStringW VDGetWindowTextW32(HWND hwnd);
void VDAppendMenuW32(HMENU hmenu, UINT flags, UINT id, const wchar_t *text);
+void VDCheckMenuItemByPositionW32(HMENU hmenu, uint32 pos, bool checked);
void VDCheckMenuItemByCommandW32(HMENU hmenu, UINT cmd, bool checked);
+void VDCheckRadioMenuItemByPositionW32(HMENU hmenu, uint32 pos, bool checked);
void VDCheckRadioMenuItemByCommandW32(HMENU hmenu, UINT cmd, bool checked);
void VDEnableMenuItemByCommandW32(HMENU hmenu, UINT cmd, bool checked);
VDStringW VDGetMenuItemTextByCommandW32(HMENU hmenu, UINT cmd);
@@ -92,4 +99,7 @@ bool VDDrawTextW32(HDC hdc, const wchar_t *s, int nCount, LPRECT lpRect, UINT u
bool VDPatchModuleImportTableW32(HMODULE hmod, const char *srcModule, const char *name, void *pCompareValue, void *pNewValue, void *volatile *ppOldValue);
bool VDPatchModuleExportTableW32(HMODULE hmod, const char *name, void *pCompareValue, void *pNewValue, void *volatile *ppOldValue);
+/// Load a library from the Windows system directory.
+HMODULE VDLoadSystemLibraryW32(const char *name);
+
#endif
diff --git a/src/thirdparty/VirtualDub/h/vd2/system/win32/miniwindows.h b/src/thirdparty/VirtualDub/h/vd2/system/win32/miniwindows.h
index be4ee5695..48c0612bf 100644
--- a/src/thirdparty/VirtualDub/h/vd2/system/win32/miniwindows.h
+++ b/src/thirdparty/VirtualDub/h/vd2/system/win32/miniwindows.h
@@ -39,6 +39,7 @@
#endif
typedef struct HWND__ *VDZHWND;
+typedef struct HDC__ *VDZHDC;
typedef unsigned VDZUINT;
typedef unsigned short VDZWORD;
typedef unsigned long VDZDWORD;
diff --git a/src/thirdparty/VirtualDub/system/linearalloc.cpp b/src/thirdparty/VirtualDub/system/linearalloc.cpp
new file mode 100644
index 000000000..c6b8dabc2
--- /dev/null
+++ b/src/thirdparty/VirtualDub/system/linearalloc.cpp
@@ -0,0 +1,55 @@
+#include "stdafx.h"
+#include <vd2/system/error.h>
+#include <vd2/system/linearalloc.h>
+
+VDLinearAllocator::VDLinearAllocator(uint32 blockSize)
+ : mpBlocks(NULL)
+ , mpAllocPtr(NULL)
+ , mAllocLeft(0)
+ , mBlockSize(blockSize)
+{
+}
+
+VDLinearAllocator::~VDLinearAllocator() {
+ Block *p = mpBlocks;
+
+ while(p) {
+ Block *next = p->mpNext;
+
+ free(p);
+
+ p = next;
+ }
+}
+
+void *VDLinearAllocator::AllocateSlow(size_t bytes) {
+ Block *block;
+ void *p;
+
+ if ((bytes + bytes) >= mBlockSize) {
+ block = (Block *)malloc(sizeof(Block) + bytes);
+ if (!block)
+ throw MyMemoryError();
+
+ p = block + 1;
+
+ } else {
+ block = (Block *)malloc(sizeof(Block) + mBlockSize);
+ if (!block)
+ throw MyMemoryError();
+
+ p = block + 1;
+ mpAllocPtr = (char *)p + bytes;
+ mAllocLeft = mBlockSize - bytes;
+ }
+
+ block->mpNext = mpBlocks;
+ mpBlocks = block;
+
+ return p;
+}
+
+void VDFixedLinearAllocator::ThrowException() {
+ throw MyMemoryError();
+}
+
diff --git a/src/thirdparty/VirtualDub/system/source/Error.cpp b/src/thirdparty/VirtualDub/system/source/Error.cpp
index 727354c96..c8e9848ef 100644
--- a/src/thirdparty/VirtualDub/system/source/Error.cpp
+++ b/src/thirdparty/VirtualDub/system/source/Error.cpp
@@ -231,7 +231,9 @@ MyMemoryError::MyMemoryError() {
setf("Out of memory");
}
-MyWin32Error::MyWin32Error(const char *format, uint32 err, ...) {
+MyWin32Error::MyWin32Error(const char *format, uint32 err, ...)
+ : mWin32Error(err)
+{
char szError[1024];
char szTemp[1024];
va_list val;
diff --git a/src/thirdparty/VirtualDub/system/source/VDScheduler.cpp b/src/thirdparty/VirtualDub/system/source/VDScheduler.cpp
index cdfc97269..ed0d5af11 100644
--- a/src/thirdparty/VirtualDub/system/source/VDScheduler.cpp
+++ b/src/thirdparty/VirtualDub/system/source/VDScheduler.cpp
@@ -176,7 +176,7 @@ void VDScheduler::RescheduleFast(VDSchedulerNode *pNode) {
void VDScheduler::Add(VDSchedulerNode *pNode) {
VDASSERT(pNode);
- pNode->pScheduler = this;
+ pNode->mpScheduler = this;
pNode->bRunning = false;
pNode->bReschedule = false;
pNode->bReady = true;
@@ -237,7 +237,8 @@ void VDSchedulerNode::DumpStatus() {
///////////////////////////////////////////////////////////////////////////
VDSchedulerThread::VDSchedulerThread()
- : mpScheduler(NULL)
+ : VDThread("Scheduler thread")
+ , mpScheduler(NULL)
{
}
@@ -259,3 +260,46 @@ void VDSchedulerThread::ThreadRun() {
scheduler.Ping();
}
+
+///////////////////////////////////////////////////////////////////////////
+
+VDSchedulerThreadPool::VDSchedulerThreadPool()
+ : mpThreads(NULL)
+ , mThreadCount(0)
+{
+}
+
+VDSchedulerThreadPool::~VDSchedulerThreadPool() {
+ if (mpThreads) {
+ for(uint32 i=0; i<mThreadCount; ++i) {
+ mpThreads[i].ThreadWait();
+ }
+
+ delete[] mpThreads;
+ }
+}
+
+bool VDSchedulerThreadPool::Start(VDScheduler *pScheduler) {
+ return Start(pScheduler, VDGetLogicalProcessorCount());
+}
+
+bool VDSchedulerThreadPool::Start(VDScheduler *pScheduler, uint32 threadCount) {
+ VDASSERT(!mpThreads);
+
+ mpThreads = new VDSchedulerThread[threadCount];
+ mThreadCount = threadCount;
+
+ bool success = true;
+ for(uint32 i=0; i<mThreadCount; ++i) {
+ if (!mpThreads[i].Start(pScheduler)) {
+ // We don't attempt to tear down scheduling threads here. The reason is
+ // that those threads have already entered the scheduler, and it's very
+ // difficult to extract only a specific thread. Usually it'll suffice
+ // to shut down the entire scheduler instead.
+ success = false;
+ break;
+ }
+ }
+
+ return false;
+}
diff --git a/src/thirdparty/VirtualDub/system/source/VDString.cpp b/src/thirdparty/VirtualDub/system/source/VDString.cpp
index 5877fadb5..6f4848b5d 100644
--- a/src/thirdparty/VirtualDub/system/source/VDString.cpp
+++ b/src/thirdparty/VirtualDub/system/source/VDString.cpp
@@ -118,6 +118,19 @@ VDStringA& VDStringA::append_vsprintf(const value_type *format, va_list val) {
return *this;
}
+void VDStringA::move_from(VDStringA& src) {
+ if (mpBegin != sNull)
+ delete[] mpBegin;
+
+ mpBegin = src.mpBegin;
+ mpEnd = src.mpEnd;
+ mpEOS = src.mpEOS;
+
+ src.mpBegin = NULL;
+ src.mpEnd = NULL;
+ src.mpEOS = NULL;
+}
+
///////////////////////////////////////////////////////////////////////////////
const VDStringSpanW::value_type VDStringSpanW::sNull[1] = {0};
@@ -207,3 +220,64 @@ VDStringW& VDStringW::append_vsprintf(const value_type *format, va_list val) {
va_end(val);
return *this;
}
+
+void VDStringW::move_from(VDStringW& src) {
+ delete[] mpBegin;
+ mpBegin = src.mpBegin;
+ mpEnd = src.mpEnd;
+ mpEOS = src.mpEOS;
+
+ src.mpBegin = NULL;
+ src.mpEnd = NULL;
+ src.mpEOS = NULL;
+}
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+template<>
+VDStringA *vdmove_forward(VDStringA *src1, VDStringA *src2, VDStringA *dst) {
+ VDStringA *p = src1;
+ while(p != src2) {
+ dst->move_from(*p);
+ ++dst;
+ ++p;
+ }
+
+ return dst;
+}
+
+template<>
+VDStringW *vdmove_forward(VDStringW *src1, VDStringW *src2, VDStringW *dst) {
+ VDStringW *p = src1;
+ while(p != src2) {
+ dst->move_from(*p);
+ ++dst;
+ ++p;
+ }
+
+ return dst;
+}
+
+template<>
+VDStringA *vdmove_backward(VDStringA *src1, VDStringA *src2, VDStringA *dst) {
+ VDStringA *p = src2;
+ while(p != src1) {
+ --dst;
+ --p;
+ dst->move_from(*p);
+ }
+
+ return dst;
+}
+
+template<>
+VDStringW *vdmove_backward(VDStringW *src1, VDStringW *src2, VDStringW *dst) {
+ VDStringW *p = src2;
+ while(p != src1) {
+ --dst;
+ --p;
+ dst->move_from(*p);
+ }
+
+ return dst;
+}
diff --git a/src/thirdparty/VirtualDub/system/source/a64_thunk.asm b/src/thirdparty/VirtualDub/system/source/a64_thunk.asm
index b9e09e1e8..72745606d 100644
--- a/src/thirdparty/VirtualDub/system/source/a64_thunk.asm
+++ b/src/thirdparty/VirtualDub/system/source/a64_thunk.asm
@@ -22,13 +22,13 @@ proc_frame VDMethodToFunctionThunk64
mov [rbp+40], r9 ;save arg4
[savereg rcx, 24]
-end_prolog
+ [endprolog]
;re-copy arguments 4 and up
mov ecx, [rax+24]
or ecx, ecx
jz .argsdone
- lea rdx, [rcx+48-8]
+ lea rdx, [rcx+32]
.argsloop:
push qword [rsp+rdx]
sub ecx, 8
diff --git a/src/thirdparty/VirtualDub/system/source/cmdline.cpp b/src/thirdparty/VirtualDub/system/source/cmdline.cpp
index 2bd1cbe42..96876cedd 100644
--- a/src/thirdparty/VirtualDub/system/source/cmdline.cpp
+++ b/src/thirdparty/VirtualDub/system/source/cmdline.cpp
@@ -25,6 +25,7 @@
#include "stdafx.h"
#include <vd2/system/cmdline.h>
+#include <vd2/system/VDString.h>
VDCommandLine::VDCommandLine() {
}
@@ -61,8 +62,11 @@ void VDCommandLine::Init(const wchar_t *s) {
while(*s && *s != L' ' && *s != L'/') {
if (te.mbIsSwitch) {
- if (!isalnum((unsigned char)*s))
+ if (!isalnum((unsigned char)*s)) {
+ if (*s == L':')
+ ++s;
break;
+ }
mLine.push_back(*s++);
} else if (*s == L'"') {
@@ -94,6 +98,15 @@ const wchar_t *VDCommandLine::operator[](int index) const {
return (uint32)index < mTokens.size() ? mLine.data() + mTokens[index].mTokenIndex : NULL;
}
+const VDStringSpanW VDCommandLine::operator()(int index) const {
+ if ((uint32)index >= mTokens.size())
+ return VDStringSpanW();
+
+ const wchar_t *s = mLine.data() + mTokens[index].mTokenIndex;
+
+ return VDStringSpanW(s);
+}
+
bool VDCommandLine::GetNextArgument(VDCommandLineIterator& it, const wchar_t *& token, bool& isSwitch) const {
int count = (int)mTokens.size();
@@ -157,19 +170,14 @@ bool VDCommandLine::FindAndRemoveSwitch(const wchar_t *name, const wchar_t *& to
const wchar_t *s = mLine.data() + mTokens[i].mTokenIndex + 1;
if (!_wcsnicmp(name, s, namelen)) {
- token = s+namelen;
-
- switch(*token) {
- case L':':
- ++token;
- break;
- case 0:
- break;
- default:
- continue;
- }
+ token = s+namelen; // null term
mTokens.erase(mTokens.begin() + i);
+
+ if (i < count-1 && !mTokens[i].mbIsSwitch) {
+ token = mLine.data() + mTokens[i].mTokenIndex;
+ mTokens.erase(mTokens.begin() + i);
+ }
return true;
}
}
diff --git a/src/thirdparty/VirtualDub/system/source/date.cpp b/src/thirdparty/VirtualDub/system/source/date.cpp
new file mode 100644
index 000000000..ab23a8633
--- /dev/null
+++ b/src/thirdparty/VirtualDub/system/source/date.cpp
@@ -0,0 +1,131 @@
+// VirtualDub - Video processing and capture application
+// System library component
+// Copyright (C) 1998-2011 Avery Lee, All Rights Reserved.
+//
+// Beginning with 1.6.0, the VirtualDub system library is licensed
+// differently than the remainder of VirtualDub. This particular file is
+// thus licensed as follows (the "zlib" license):
+//
+// This software is provided 'as-is', without any express or implied
+// warranty. In no event will the authors be held liable for any
+// damages arising from the use of this software.
+//
+// Permission is granted to anyone to use this software for any purpose,
+// including commercial applications, and to alter it and redistribute it
+// freely, subject to the following restrictions:
+//
+// 1. The origin of this software must not be misrepresented; you must
+// not claim that you wrote the original software. If you use this
+// software in a product, an acknowledgment in the product
+// documentation would be appreciated but is not required.
+// 2. Altered source versions must be plainly marked as such, and must
+// not be misrepresented as being the original software.
+// 3. This notice may not be removed or altered from any source
+// distribution.
+
+#include "stdafx.h"
+#include <vd2/system/date.h>
+#include <vd2/system/w32assist.h>
+#include <windows.h>
+
+VDDate VDGetCurrentDate() {
+ FILETIME ft;
+ ::GetSystemTimeAsFileTime(&ft);
+
+ VDDate r;
+ r.mTicks = ft.dwLowDateTime + ((uint64)ft.dwHighDateTime << 32);
+
+ return r;
+}
+
+VDExpandedDate VDGetLocalDate(const VDDate& date) {
+ VDExpandedDate r = {0};
+
+ FILETIME ft;
+ ft.dwLowDateTime = (uint32)date.mTicks;
+ ft.dwHighDateTime = (uint32)(date.mTicks >> 32);
+
+ SYSTEMTIME st;
+ SYSTEMTIME lt;
+ if (::FileTimeToSystemTime(&ft, &st) &&
+ ::SystemTimeToTzSpecificLocalTime(NULL, &st, &lt))
+ {
+ r.mYear = lt.wYear;
+ r.mMonth = (uint8)lt.wMonth;
+ r.mDayOfWeek = (uint8)lt.wDayOfWeek;
+ r.mDay = (uint8)lt.wDay;
+ r.mHour = (uint8)lt.wHour;
+ r.mMinute = (uint8)lt.wMinute;
+ r.mSecond = (uint8)lt.wSecond;
+ r.mMilliseconds = (uint16)lt.wMilliseconds;
+ }
+
+ return r;
+}
+
+void VDConvertExpandedDateToNativeW32(SYSTEMTIME& dst, const VDExpandedDate& src) {
+ dst.wYear = src.mYear;
+ dst.wMonth = src.mMonth;
+ dst.wDayOfWeek = src.mDayOfWeek;
+ dst.wDay = src.mDay;
+ dst.wHour = src.mHour;
+ dst.wMinute = src.mMinute;
+ dst.wSecond = src.mSecond;
+ dst.wMilliseconds = src.mMilliseconds;
+}
+
+void VDAppendLocalDateString(VDStringW& dst, const VDExpandedDate& ed) {
+ SYSTEMTIME st;
+
+ VDConvertExpandedDateToNativeW32(st, ed);
+
+ if (VDIsWindowsNT()) {
+ int len = ::GetDateFormatW(LOCALE_USER_DEFAULT, LOCALE_USE_CP_ACP, &st, NULL, NULL, 0);
+
+ if (len > 0) {
+ vdfastvector<WCHAR> buf;
+ buf.resize(len, 0);
+
+ if (::GetDateFormatW(LOCALE_USER_DEFAULT, LOCALE_USE_CP_ACP | DATE_SHORTDATE, &st, NULL, buf.data(), len))
+ dst += buf.data();
+ }
+ } else {
+ int len = ::GetDateFormatA(LOCALE_USER_DEFAULT, LOCALE_USE_CP_ACP | DATE_SHORTDATE, &st, NULL, NULL, 0);
+
+ if (len > 0) {
+ vdfastvector<CHAR> buf;
+ buf.resize(len, 0);
+
+ if (::GetDateFormatA(LOCALE_USER_DEFAULT, LOCALE_USE_CP_ACP | DATE_SHORTDATE, &st, NULL, buf.data(), len))
+ dst += VDTextAToW(buf.data());
+ }
+ }
+}
+
+void VDAppendLocalTimeString(VDStringW& dst, const VDExpandedDate& ed) {
+ SYSTEMTIME st;
+
+ VDConvertExpandedDateToNativeW32(st, ed);
+
+ if (VDIsWindowsNT()) {
+ int len = ::GetTimeFormatW(LOCALE_USER_DEFAULT, LOCALE_USE_CP_ACP | TIME_NOSECONDS, &st, NULL, NULL, 0);
+
+ if (len > 0) {
+ vdfastvector<WCHAR> buf;
+ buf.resize(len, 0);
+
+ if (::GetTimeFormatW(LOCALE_USER_DEFAULT, LOCALE_USE_CP_ACP | TIME_NOSECONDS, &st, NULL, buf.data(), len))
+ dst += buf.data();
+ }
+ } else {
+ int len = ::GetTimeFormatA(LOCALE_USER_DEFAULT, LOCALE_USE_CP_ACP | TIME_NOSECONDS, &st, NULL, NULL, 0);
+
+ if (len > 0) {
+ vdfastvector<CHAR> buf;
+ buf.resize(len, 0);
+
+ if (::GetTimeFormatA(LOCALE_USER_DEFAULT, LOCALE_USE_CP_ACP | TIME_NOSECONDS, &st, NULL, buf.data(), len))
+ dst += VDTextAToW(buf.data());
+ }
+ }
+}
diff --git a/src/thirdparty/VirtualDub/system/source/event.cpp b/src/thirdparty/VirtualDub/system/source/event.cpp
index 368f03cb1..70e8e8534 100644
--- a/src/thirdparty/VirtualDub/system/source/event.cpp
+++ b/src/thirdparty/VirtualDub/system/source/event.cpp
@@ -73,9 +73,16 @@ void VDEventBase::Remove(VDDelegate& dbase) {
}
void VDEventBase::Raise(void *src, const void *info) {
- for(VDDelegateNode *node = mAnchor.mpNext; node != &mAnchor; node = node->mpNext) {
+ // We allow the specific case of removing the delegate that's being removed.
+ VDDelegateNode *node = mAnchor.mpNext;
+
+ while(node != &mAnchor) {
+ VDDelegateNode *next = node->mpNext;
+
VDDelegate& dbase = static_cast<VDDelegate&>(*node);
dbase.mpCallback(src, info, dbase);
+
+ node = next;
}
}
diff --git a/src/thirdparty/VirtualDub/system/source/file.cpp b/src/thirdparty/VirtualDub/system/source/file.cpp
index 11ab82eeb..dd2517362 100644
--- a/src/thirdparty/VirtualDub/system/source/file.cpp
+++ b/src/thirdparty/VirtualDub/system/source/file.cpp
@@ -404,6 +404,15 @@ sint64 VDFile::tell() {
return mFilePosition;
}
+bool VDFile::flushNT() {
+ return 0 != FlushFileBuffers(mhFile);
+}
+
+void VDFile::flush() {
+ if (!flushNT())
+ throw MyWin32Error("Cannot flush file \"%ls\": %%s", GetLastError(), mpFilename.get());
+}
+
bool VDFile::isOpen() {
return mhFile != 0;
}
@@ -733,6 +742,10 @@ void VDTextOutputStream::Flush() {
}
}
+void VDTextOutputStream::Write(const char *s) {
+ PutData(s, strlen(s));
+}
+
void VDTextOutputStream::Write(const char *s, int len) {
PutData(s, len);
}
@@ -746,6 +759,23 @@ void VDTextOutputStream::PutLine(const char *s) {
PutData("\r\n", 2);
}
+void VDTextOutputStream::Format(const char *format, ...) {
+ va_list val;
+
+ va_start(val, format);
+
+ int rv = -1;
+ if (mLevel < kBufSize-4)
+ rv = _vsnprintf(mBuf+mLevel, kBufSize-mLevel, format, val);
+
+ if (rv >= 0)
+ mLevel += rv;
+ else
+ Format2(format, val);
+
+ va_end(val);
+}
+
void VDTextOutputStream::FormatLine(const char *format, ...) {
va_list val;
@@ -758,13 +788,13 @@ void VDTextOutputStream::FormatLine(const char *format, ...) {
if (rv >= 0)
mLevel += rv;
else
- FormatLine2(format, val);
+ Format2(format, val);
PutData("\r\n", 2);
va_end(val);
}
-void VDTextOutputStream::FormatLine2(const char *format, va_list val) {
+void VDTextOutputStream::Format2(const char *format, va_list val) {
char buf[3072];
int rv = _vsnprintf(buf, 3072, format, val);
diff --git a/src/thirdparty/VirtualDub/system/source/fileasync.cpp b/src/thirdparty/VirtualDub/system/source/fileasync.cpp
index 18f97afc8..21457879a 100644
--- a/src/thirdparty/VirtualDub/system/source/fileasync.cpp
+++ b/src/thirdparty/VirtualDub/system/source/fileasync.cpp
@@ -52,6 +52,7 @@ public:
bool IsOpen() { return mhFileSlow != INVALID_HANDLE_VALUE; }
void Open(const wchar_t *pszFilename, uint32 count, uint32 bufferSize);
+ void Open(VDFileHandle h, uint32 count, uint32 bufferSize);
void Close();
void FastWrite(const void *pData, uint32 bytes);
void FastWriteEnd();
@@ -74,6 +75,7 @@ protected:
uint32 mBlockSize;
uint32 mBlockCount;
uint32 mSectorSize;
+ sint64 mClientSlowPointer;
sint64 mClientFastPointer;
const bool mbUseFastMode;
@@ -101,6 +103,7 @@ protected:
VDFileAsync9x::VDFileAsync9x(bool useFastMode)
: mhFileSlow(INVALID_HANDLE_VALUE)
, mhFileFast(INVALID_HANDLE_VALUE)
+ , mClientSlowPointer(0)
, mClientFastPointer(0)
, mbUseFastMode(useFastMode)
, mbPreemptiveExtend(false)
@@ -138,6 +141,29 @@ void VDFileAsync9x::Open(const wchar_t *pszFilename, uint32 count, uint32 buffer
ThreadStart();
}
+void VDFileAsync9x::Open(VDFileHandle h, uint32 count, uint32 bufferSize) {
+ try {
+ mFilename = "<anonymous pipe>";
+
+ HANDLE hProcess = GetCurrentProcess();
+ if (!DuplicateHandle(hProcess, h, hProcess, &mhFileSlow, 0, FALSE, DUPLICATE_SAME_ACCESS))
+ throw MyWin32Error("Unable to open file \"%s\" for write: %%s", GetLastError(), mFilename.c_str());
+
+ mSectorSize = 4096; // guess for now... proper way would be GetVolumeMountPoint() followed by GetDiskFreeSpace().
+
+ mBlockSize = bufferSize;
+ mBlockCount = count;
+ mBuffer.Init(count * bufferSize);
+
+ mState = kStateNormal;
+ } catch(const MyError&) {
+ Close();
+ throw;
+ }
+
+ ThreadStart();
+}
+
void VDFileAsync9x::Close() {
mState = kStateAbort;
mWriteOccurred.signal();
@@ -205,8 +231,12 @@ void VDFileAsync9x::Write(sint64 pos, const void *p, uint32 bytes) {
Seek(pos);
DWORD dwActual;
- if (!WriteFile(mhFileSlow, p, bytes, &dwActual, NULL) || dwActual != bytes)
+ if (!WriteFile(mhFileSlow, p, bytes, &dwActual, NULL) || dwActual != bytes) {
+ mClientSlowPointer = -1;
throw MyWin32Error("Write error occurred on file \"%s\": %%s\n", GetLastError(), mFilename.c_str());
+ }
+
+ mClientSlowPointer += bytes;
}
void VDFileAsync9x::WriteZero(sint64 pos, uint32 bytes) {
@@ -262,16 +292,23 @@ void VDFileAsync9x::Seek(sint64 pos) {
}
bool VDFileAsync9x::SeekNT(sint64 pos) {
+ if (mClientSlowPointer == pos)
+ return true;
+
LONG posHi = (LONG)(pos >> 32);
DWORD result = SetFilePointer(mhFileSlow, (LONG)pos, &posHi, FILE_BEGIN);
if (result == INVALID_SET_FILE_POINTER) {
DWORD dwError = GetLastError();
- if (dwError != NO_ERROR)
+ if (dwError != NO_ERROR) {
+ mClientSlowPointer = -1;
return false;
+ }
}
+ mClientSlowPointer = pos;
+
return true;
}
@@ -299,7 +336,7 @@ void VDFileAsync9x::ThreadRun() {
HANDLE hFile = mhFileFast != INVALID_HANDLE_VALUE ? mhFileFast : mhFileSlow;
try {
- if (!VDGetFileSizeW32(hFile, currentSize))
+ if (bPreemptiveExtend && !VDGetFileSizeW32(hFile, currentSize))
throw MyWin32Error("I/O error on file \"%s\": %%s", GetLastError(), mFilename.c_str());
for(;;) {
@@ -388,6 +425,7 @@ public:
bool IsOpen() { return mhFileSlow != INVALID_HANDLE_VALUE; }
void Open(const wchar_t *pszFilename, uint32 count, uint32 bufferSize);
+ void Open(VDFileHandle h, uint32 count, uint32 bufferSize);
void Close();
void FastWrite(const void *pData, uint32 bytes);
void FastWriteEnd();
@@ -485,6 +523,36 @@ void VDFileAsyncNT::Open(const wchar_t *pszFilename, uint32 count, uint32 buffer
}
}
+void VDFileAsyncNT::Open(VDFileHandle h, uint32 count, uint32 bufferSize) {
+ try {
+ mFilename = "<anonymous pipe>";
+
+ HANDLE hProcess = GetCurrentProcess();
+ if (!DuplicateHandle(hProcess, h, hProcess, &mhFileSlow, 0, FALSE, DUPLICATE_SAME_ACCESS))
+ throw MyWin32Error("Unable to open file \"%s\" for write: %%s", GetLastError(), mFilename.c_str());
+
+ mSectorSize = 4096; // guess for now... proper way would be GetVolumeMountPoint() followed by GetDiskFreeSpace().
+
+ mBlockSize = bufferSize;
+ mBlockCount = count;
+ mBufferSize = mBlockSize * mBlockCount;
+
+ mWriteOffset = 0;
+ mBufferLevel = 0;
+
+ mState = kStateNormal;
+
+ if (mhFileFast != INVALID_HANDLE_VALUE) {
+ mpBlocks = new VDFileAsyncNTBuffer[count];
+ mBuffer.resize(count * bufferSize);
+ ThreadStart();
+ }
+ } catch(const MyError&) {
+ Close();
+ throw;
+ }
+}
+
void VDFileAsyncNT::Close() {
mState = kStateAbort;
mWriteOccurred.signal();
@@ -562,10 +630,13 @@ void VDFileAsyncNT::FastWrite(const void *pData, uint32 bytes) {
}
void VDFileAsyncNT::FastWriteEnd() {
- FastWrite(NULL, mSectorSize - 1);
- mState = kStateFlush;
- mWriteOccurred.signal();
- ThreadWait();
+ if (mhFileFast != INVALID_HANDLE_VALUE) {
+ FastWrite(NULL, mSectorSize - 1);
+ mState = kStateFlush;
+ mWriteOccurred.signal();
+ ThreadWait();
+ }
+
if (mpError)
ThrowError();
}
@@ -685,6 +756,16 @@ void VDFileAsyncNT::ThreadRun() {
typedef BOOL (WINAPI *tpCancelIo)(HANDLE);
static const tpCancelIo pCancelIo = (tpCancelIo)GetProcAddress(GetModuleHandle("kernel32"), "CancelIo");
pCancelIo(mhFileFast);
+
+ // Wait for any pending blocks to complete.
+ for(int i=0; i<requestCount; ++i) {
+ VDFileAsyncNTBuffer& buf = mpBlocks[i];
+
+ if (buf.mbActive) {
+ WaitForSingleObject(buf.hEvent, INFINITE);
+ buf.mbActive = false;
+ }
+ }
break;
}
@@ -739,8 +820,7 @@ void VDFileAsyncNT::ThreadRun() {
}
- if (state == kStateNormal)
- continue;
+ continue;
}
VDASSERT(state == kStateFlush);
diff --git a/src/thirdparty/VirtualDub/system/source/filesys.cpp b/src/thirdparty/VirtualDub/system/source/filesys.cpp
index a85c0f5c7..d64180e28 100644
--- a/src/thirdparty/VirtualDub/system/source/filesys.cpp
+++ b/src/thirdparty/VirtualDub/system/source/filesys.cpp
@@ -32,6 +32,7 @@
#include <vd2/system/Error.h>
#include <vd2/system/vdstl.h>
#include <vd2/system/w32assist.h>
+#include <vd2/system/strutil.h>
///////////////////////////////////////////////////////////////////////////
@@ -108,34 +109,58 @@ const char *VDFileSplitRoot(const char *s) {
return s;
}
- const char *const t = s;
+ const char *t = s;
+
+ for(;;) {
+ const char c = *t;
+
+ if (c == ':') {
+ if (t[1] == '/' || t[1] == '\\')
+ return t+2;
- while(*s && *s != ':' && *s != '/' && *s != '\\')
- ++s;
+ return t+1;
+ }
+
+ // check if it was a valid drive identifier
+ if (!isalpha((unsigned char)c) && (s == t || !isdigit((unsigned char)c)))
+ return s;
- return *s ? *s == ':' && (s[1]=='/' || s[1]=='\\') ? s+2 : s+1 : t;
+ ++t;
+ }
}
const wchar_t *VDFileSplitRoot(const wchar_t *s) {
// Test for a UNC path.
- if (s[0] == '\\' && s[1] == '\\') {
+ if (s[0] == L'\\' && s[1] == L'\\') {
// For these, we scan for the fourth backslash.
s += 2;
for(int i=0; i<2; ++i) {
- while(*s && *s != '\\')
+ while(*s && *s != L'\\')
++s;
- if (*s == '\\')
+ if (*s == L'\\')
++s;
}
return s;
}
- const wchar_t *const t = s;
+ const wchar_t *t = s;
- while(*s && *s != L':' && *s != L'/' && *s != L'\\')
- ++s;
+ for(;;) {
+ const wchar_t c = *t;
+
+ if (c == L':') {
+ if (t[1] == L'/' || t[1] == L'\\')
+ return t+2;
+
+ return t+1;
+ }
+
+ // check if it was a valid drive identifier
+ if (!iswalpha(c) && (s == t || !iswdigit(c)))
+ return s;
- return *s ? *s == L':' && (s[1]==L'/' || s[1]==L'\\') ? s+2 : s+1 : t;
+ ++t;
+ }
}
VDString VDFileSplitRoot(const VDString& s) { return splitimpL(s, VDFileSplitRoot(s.c_str())); }
@@ -159,7 +184,7 @@ const char *VDFileSplitExt(const char *s) {
break;
}
- return NULL;
+ return end;
}
const wchar_t *VDFileSplitExt(const wchar_t *s) {
@@ -288,6 +313,183 @@ bool VDFileWildMatch(const wchar_t *pattern, const wchar_t *path) {
/////////////////////////////////////////////////////////////////////////////
+VDParsedPath::VDParsedPath()
+ : mbIsRelative(true)
+{
+}
+
+VDParsedPath::VDParsedPath(const wchar_t *path)
+ : mbIsRelative(true)
+{
+ // Check if the string contains a root, such as a drive or UNC specifier.
+ const wchar_t *rootSplit = VDFileSplitRoot(path);
+ if (rootSplit != path) {
+ mRoot.assign(path, rootSplit);
+
+ for(VDStringW::iterator it(mRoot.begin()), itEnd(mRoot.end()); it != itEnd; ++it) {
+ if (*it == L'/')
+ *it = L'\\';
+ }
+
+ mbIsRelative = (mRoot.back() == L':');
+
+ // If the path is UNC, strip a trailing backslash.
+ if (mRoot.size() >= 3 && mRoot[0] == L'\\' && mRoot[1] == L'\\' && mRoot.back() == L'\\')
+ mRoot.resize(mRoot.size() - 1);
+
+ path = rootSplit;
+ }
+
+ // Parse out additional components.
+ for(;;) {
+ // Skip any separators.
+ wchar_t c = *path++;
+
+ while(c == L'\\' || c == L'/')
+ c = *path++;
+
+ // If we've hit a null, we're done.
+ if (!c)
+ break;
+
+ // Have we hit a semicolon? If so, we've found an NTFS stream identifier and we're done.
+ if (c == L';') {
+ mStream = path;
+ break;
+ }
+
+ // Skip until we hit a separator or a null.
+ const wchar_t *compStart = path - 1;
+
+ while(c && c != L'\\' && c != L'/' && c != L';') {
+ c = *path++;
+ }
+
+ --path;
+
+ const wchar_t *compEnd = path;
+
+ // Check if we've got a component that starts with .
+ const size_t compLen = compEnd - compStart;
+ if (*compStart == L'.') {
+ // Is it . (current)?
+ if (compLen == 1) {
+ // Yes -- just ditch it.
+ continue;
+ }
+
+ // Is it .. (parent)?
+ if (compLen == 2 && compStart[1] == L'.') {
+ // Yes -- see if we have a previous component we can remove. If we don't have a component,
+ // then what we do depends on whether we have an absolute path or not.
+ if (!mComponents.empty() && (!mbIsRelative || mComponents.back() != L"..")) {
+ mComponents.pop_back();
+ } else if (mbIsRelative) {
+ // We've got a relative path. This means that we need to preserve this ..; we push
+ // it into the root section to prevent it from being backed up over by another ...
+ mComponents.push_back() = L"..";
+ }
+
+ // Otherwise, we have an absolute path, and we can just drop this.
+ continue;
+ }
+ }
+
+ // Copy the component.
+ mComponents.push_back().assign(compStart, compEnd);
+ }
+}
+
+VDStringW VDParsedPath::ToString() const {
+ VDStringW s(mRoot);
+
+ bool first = true;
+ for(Components::const_iterator it(mComponents.begin()), itEnd(mComponents.end()); it != itEnd; ++it) {
+ if (!first)
+ s += L'\\';
+ else
+ first = false;
+
+ s.append(*it);
+ }
+
+ // If the string is still empty, throw in a .
+ if (s.empty())
+ s = L".";
+
+ if (!mStream.empty()) {
+ s += L';';
+ s.append(mStream);
+ }
+
+ return s;
+}
+
+/////////////////////////////////////////////////////////////////////////////
+
+VDStringW VDFileGetCanonicalPath(const wchar_t *path) {
+ return VDParsedPath(path).ToString();
+}
+
+VDStringW VDFileGetRelativePath(const wchar_t *basePath, const wchar_t *pathToConvert, bool allowAscent) {
+ VDParsedPath base(basePath);
+ VDParsedPath path(pathToConvert);
+
+ // Fail if either path is relative.
+ if (base.IsRelative() || path.IsRelative())
+ return VDStringW();
+
+ // Fail if the roots don't match.
+ if (vdwcsicmp(base.GetRoot(), path.GetRoot()))
+ return VDStringW();
+
+ // Figure out how many components are in common.
+ size_t n1 = base.GetComponentCount();
+ size_t n2 = path.GetComponentCount();
+ size_t nc = 0;
+
+ while(nc < n1 && nc < n2 && !vdwcsicmp(base.GetComponent(nc), path.GetComponent(nc)))
+ ++nc;
+
+ // Check how many extra components are in the base; these need to become .. identifiers.
+ VDParsedPath relPath;
+
+ if (n1 > nc) {
+ if (!allowAscent)
+ return VDStringW();
+
+ while(n1 > nc) {
+ relPath.AddComponent(L"..");
+ --n1;
+ }
+ }
+
+ // Append extra components from path.
+ while(nc < n2) {
+ relPath.AddComponent(path.GetComponent(nc++));
+ }
+
+ // Copy stream.
+ relPath.SetStream(path.GetStream());
+
+ return relPath.ToString();
+}
+
+bool VDFileIsRelativePath(const wchar_t *path) {
+ VDParsedPath ppath(path);
+
+ return ppath.IsRelative();
+}
+
+VDStringW VDFileResolvePath(const wchar_t *basePath, const wchar_t *pathToResolve) {
+ if (VDFileIsRelativePath(pathToResolve))
+ return VDFileGetCanonicalPath(VDMakePath(basePath, pathToResolve).c_str());
+
+ return VDStringW(pathToResolve);
+}
+
+/////////////////////////////////////////////////////////////////////////////
+
#include <windows.h>
#include <vd2/system/w32assist.h>
@@ -377,6 +579,30 @@ void VDCreateDirectory(const wchar_t *path) {
throw MyWin32Error("Cannot create directory: %%s", GetLastError());
}
+void VDRemoveDirectory(const wchar_t *path) {
+ VDStringW::size_type l(wcslen(path));
+
+ if (l) {
+ const wchar_t c = path[l-1];
+
+ if (c == L'/' || c == L'\\') {
+ VDCreateDirectory(VDStringW(path, l-1).c_str());
+ return;
+ }
+ }
+
+ BOOL succeeded;
+
+ if (!(GetVersion() & 0x80000000)) {
+ succeeded = RemoveDirectoryW(path);
+ } else {
+ succeeded = RemoveDirectoryA(VDTextWToA(path).c_str());
+ }
+
+ if (!succeeded)
+ throw MyWin32Error("Cannot remove directory: %%s", GetLastError());
+}
+
///////////////////////////////////////////////////////////////////////////
bool VDDeletePathAutodetect(const wchar_t *path);
@@ -407,6 +633,20 @@ bool VDDeletePathAutodetect(const wchar_t *path) {
///////////////////////////////////////////////////////////////////////////
+void VDMoveFile(const wchar_t *srcPath, const wchar_t *dstPath) {
+ bool success;
+ if (VDIsWindowsNT()) {
+ success = MoveFileW(srcPath, dstPath) != 0;
+ } else {
+ success = MoveFileA(VDTextWToA(srcPath).c_str(), VDTextWToA(dstPath).c_str()) != 0;
+ }
+
+ if (!success)
+ throw MyWin32Error("Cannot rename \"%ls\" to \"%ls\": %%s", GetLastError(), srcPath, dstPath);
+}
+
+///////////////////////////////////////////////////////////////////////////
+
namespace {
typedef BOOL (WINAPI *tpGetVolumePathNameW)(LPCWSTR lpszPathName, LPWSTR lpszVolumePathName, DWORD cchBufferLength);
typedef BOOL (WINAPI *tpGetFullPathNameW)(LPCWSTR lpFileName, DWORD nBufferLength, LPWSTR lpBuffer, LPWSTR *lpFilePart);
@@ -515,6 +755,49 @@ VDStringW VDMakePath(const wchar_t *base, const wchar_t *file) {
return result;
}
+bool VDFileIsPathEqual(const wchar_t *path1, const wchar_t *path2) {
+ // check for UNC paths
+ if (path1[0] == '\\' && path1[1] == '\\' && path1[2] != '\\' &&
+ path2[0] == '\\' && path2[1] == '\\' && path2[2] != '\\')
+ {
+ path1 += 2;
+ path2 += 2;
+ }
+
+ for(;;) {
+ wchar_t c = *path1++;
+ wchar_t d = *path2++;
+
+ if (c == '\\' || c == '/') {
+ c = '/';
+
+ while(*path1 == '\\' || *path1 == '/')
+ ++path1;
+
+ if (!*path1)
+ c = 0;
+ } else
+ c = towupper(c);
+
+ if (d == '\\' || d == '/') {
+ d = '/';
+
+ while(*path2 == '\\' || *path2 == '/')
+ ++path2;
+
+ if (!*path2)
+ d = 0;
+ } else
+ d = towupper(d);
+
+ if (c != d)
+ return false;
+
+ if (!c)
+ return true;
+ }
+}
+
void VDFileFixDirPath(VDStringW& path) {
if (!path.empty()) {
wchar_t c = path[path.size()-1];
@@ -559,6 +842,141 @@ VDStringW VDGetProgramPath() {
return VDGetModulePathW32(NULL);
}
+VDStringW VDGetProgramFilePath() {
+ union {
+ wchar_t w[MAX_PATH];
+ char a[MAX_PATH];
+ } buf;
+
+ VDStringW wstr;
+
+ if (VDIsWindowsNT()) {
+ if (!GetModuleFileNameW(NULL, buf.w, MAX_PATH))
+ throw MyWin32Error("Unable to get program path: %%s", GetLastError());
+
+ wstr = buf.w;
+ } else {
+ if (GetModuleFileNameA(NULL, buf.a, MAX_PATH))
+ throw MyWin32Error("Unable to get program path: %%s", GetLastError());
+
+ wstr = VDTextAToW(buf.a, -1);
+ }
+
+ return wstr;
+}
+
+VDStringW VDGetSystemPath9x() {
+ char path[MAX_PATH];
+
+ if (!GetSystemDirectoryA(path, MAX_PATH))
+ throw MyWin32Error("Cannot locate system directory: %%s", GetLastError());
+
+ return VDTextAToW(path);
+}
+
+VDStringW VDGetSystemPathNT() {
+ wchar_t path[MAX_PATH];
+
+ if (!GetSystemDirectoryW(path, MAX_PATH))
+ throw MyWin32Error("Cannot locate system directory: %%s", GetLastError());
+
+ return VDStringW(path);
+}
+
+VDStringW VDGetSystemPath() {
+ if (VDIsWindowsNT())
+ return VDGetSystemPathNT();
+
+ return VDGetSystemPath9x();
+}
+
+uint32 VDFileGetAttributesFromNativeW32(uint32 nativeAttrs) {
+ if (nativeAttrs == INVALID_FILE_ATTRIBUTES)
+ return kVDFileAttr_Invalid;
+
+ uint32 attrs = 0;
+
+ if (nativeAttrs & FILE_ATTRIBUTE_READONLY)
+ attrs |= kVDFileAttr_ReadOnly;
+
+ if (nativeAttrs & FILE_ATTRIBUTE_SYSTEM)
+ attrs |= kVDFileAttr_System;
+
+ if (nativeAttrs & FILE_ATTRIBUTE_HIDDEN)
+ attrs |= kVDFileAttr_Hidden;
+
+ if (nativeAttrs & FILE_ATTRIBUTE_ARCHIVE)
+ attrs |= kVDFileAttr_Archive;
+
+ if (nativeAttrs & FILE_ATTRIBUTE_DIRECTORY)
+ attrs |= kVDFileAttr_Directory;
+
+ return attrs;
+}
+
+uint32 VDFileGetNativeAttributesFromAttrsW32(uint32 attrs) {
+ uint32 nativeAttrs = 0;
+
+ if (attrs == kVDFileAttr_Invalid)
+ return INVALID_FILE_ATTRIBUTES;
+
+ if (attrs & kVDFileAttr_ReadOnly)
+ nativeAttrs |= FILE_ATTRIBUTE_READONLY;
+
+ if (attrs & kVDFileAttr_System)
+ nativeAttrs |= FILE_ATTRIBUTE_SYSTEM;
+
+ if (attrs & kVDFileAttr_Hidden)
+ nativeAttrs |= FILE_ATTRIBUTE_HIDDEN;
+
+ if (attrs & kVDFileAttr_Archive)
+ nativeAttrs |= FILE_ATTRIBUTE_ARCHIVE;
+
+ if (attrs & kVDFileAttr_Directory)
+ nativeAttrs |= FILE_ATTRIBUTE_DIRECTORY;
+
+ return nativeAttrs;
+}
+
+uint32 VDFileGetAttributes(const wchar_t *path) {
+ uint32 nativeAttrs = 0;
+ if (VDIsWindowsNT())
+ nativeAttrs = ::GetFileAttributesW(path);
+ else
+ nativeAttrs = ::GetFileAttributesA(VDTextWToA(path).c_str());
+
+ return VDFileGetAttributesFromNativeW32(nativeAttrs);
+}
+
+void VDFileSetAttributes(const wchar_t *path, uint32 attrsToChange, uint32 newAttrs) {
+ const uint32 nativeAttrMask = VDFileGetNativeAttributesFromAttrsW32(attrsToChange);
+ const uint32 nativeAttrVals = VDFileGetNativeAttributesFromAttrsW32(newAttrs);
+
+ if (VDIsWindowsNT()) {
+ DWORD nativeAttrs = ::GetFileAttributesW(path);
+
+ if (nativeAttrs != INVALID_FILE_ATTRIBUTES) {
+ nativeAttrs ^= (nativeAttrs ^ nativeAttrVals) & nativeAttrMask;
+
+ if (::SetFileAttributesW(path, nativeAttrs))
+ return;
+ }
+ } else {
+ VDStringA pathA(VDTextWToA(path));
+
+ DWORD nativeAttrs = ::GetFileAttributesA(pathA.c_str());
+
+ if (nativeAttrs != INVALID_FILE_ATTRIBUTES) {
+ nativeAttrs ^= (nativeAttrs ^ nativeAttrVals) & nativeAttrMask;
+
+ if (::SetFileAttributesA(pathA.c_str(), nativeAttrs))
+ return;
+ }
+ }
+
+ throw MyWin32Error("Cannot change attributes on \"%ls\": %%s.", GetLastError(), path);
+}
+
///////////////////////////////////////////////////////////////////////////
VDDirectoryIterator::VDDirectoryIterator(const wchar_t *path)
@@ -584,6 +1002,8 @@ bool VDDirectoryIterator::Next() {
WIN32_FIND_DATAW w;
} wfd;
+ uint32 attribs;
+
if (GetVersion() & 0x80000000) {
if (mpHandle)
mbSearchComplete = !FindNextFileA((HANDLE)mpHandle, &wfd.a);
@@ -597,6 +1017,9 @@ bool VDDirectoryIterator::Next() {
mbDirectory = (wfd.a.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) != 0;
mFilename = VDTextAToW(wfd.a.cFileName);
mFileSize = wfd.a.nFileSizeLow + ((sint64)wfd.w.nFileSizeHigh << 32);
+ mLastWriteDate.mTicks = wfd.a.ftLastWriteTime.dwLowDateTime + ((uint64)wfd.a.ftLastWriteTime.dwHighDateTime << 32);
+
+ attribs = wfd.a.dwFileAttributes;
} else {
if (mpHandle)
mbSearchComplete = !FindNextFileW((HANDLE)mpHandle, &wfd.w);
@@ -610,54 +1033,23 @@ bool VDDirectoryIterator::Next() {
mbDirectory = (wfd.w.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) != 0;
mFilename = wfd.w.cFileName;
mFileSize = wfd.w.nFileSizeLow + ((sint64)wfd.w.nFileSizeHigh << 32);
+ mLastWriteDate.mTicks = wfd.w.ftLastWriteTime.dwLowDateTime + ((uint64)wfd.w.ftLastWriteTime.dwHighDateTime << 32);
+
+ attribs = wfd.w.dwFileAttributes;
}
+ mAttributes = VDFileGetAttributesFromNativeW32(attribs);
return true;
}
-///////////////////////////////////////////////////////////////////////////
+bool VDDirectoryIterator::IsDotDirectory() const {
+ if (!mbDirectory)
+ return false;
+
+ const wchar_t *s = mFilename.c_str();
-#ifdef _DEBUG
-
-struct VDSystemFilesysTestObject {
- VDSystemFilesysTestObject() {
-#define TEST(fn, x, y1, y2) VDASSERT(!strcmp(fn(x), y2)); VDASSERT(!wcscmp(fn(L##x), L##y2)); VDASSERT(fn##Left(VDStringA(x))==y1); VDASSERT(fn##Right(VDStringA(x))==y2); VDASSERT(fn##Left(VDStringW(L##x))==L##y1); VDASSERT(fn##Right(VDStringW(L##x))==L##y2)
- TEST(VDFileSplitPath, "", "", "");
- TEST(VDFileSplitPath, "x", "", "x");
- TEST(VDFileSplitPath, "x\\y", "x\\", "y");
- TEST(VDFileSplitPath, "x\\y\\z", "x\\y\\", "z");
- TEST(VDFileSplitPath, "x\\", "x\\", "");
- TEST(VDFileSplitPath, "x\\y\\z\\", "x\\y\\z\\", "");
- TEST(VDFileSplitPath, "c:", "c:", "");
- TEST(VDFileSplitPath, "c:x", "c:", "x");
- TEST(VDFileSplitPath, "c:\\", "c:\\", "");
- TEST(VDFileSplitPath, "c:\\x", "c:\\", "x");
- TEST(VDFileSplitPath, "c:\\x\\", "c:\\x\\", "");
- TEST(VDFileSplitPath, "c:\\x\\", "c:\\x\\", "");
- TEST(VDFileSplitPath, "c:x\\y", "c:x\\", "y");
- TEST(VDFileSplitPath, "\\\\server\\share\\", "\\\\server\\share\\", "");
- TEST(VDFileSplitPath, "\\\\server\\share\\x", "\\\\server\\share\\", "x");
-#undef TEST
-#define TEST(fn, x, y1, y2) VDASSERT(!strcmp(fn(x), y2)); VDASSERT(!wcscmp(fn(L##x), L##y2)); VDASSERT(fn(VDStringA(x))==y1); VDASSERT(fn(VDStringW(L##x))==L##y1)
- TEST(VDFileSplitRoot, "", "", "");
- TEST(VDFileSplitRoot, "c:", "c:", "");
- TEST(VDFileSplitRoot, "c:x", "c:", "x");
- TEST(VDFileSplitRoot, "c:x\\", "c:", "x\\");
- TEST(VDFileSplitRoot, "c:x\\y", "c:", "x\\y");
- TEST(VDFileSplitRoot, "c:\\", "c:\\", "");
- TEST(VDFileSplitRoot, "c:\\x", "c:\\", "x");
- TEST(VDFileSplitRoot, "c:\\x\\", "c:\\", "x\\");
- TEST(VDFileSplitRoot, "\\", "\\", "");
- TEST(VDFileSplitRoot, "\\x", "\\", "x");
- TEST(VDFileSplitRoot, "\\x\\", "\\", "x\\");
- TEST(VDFileSplitRoot, "\\x\\y", "\\", "x\\y");
- TEST(VDFileSplitRoot, "\\\\server\\share", "\\\\server\\share", "");
- TEST(VDFileSplitRoot, "\\\\server\\share\\", "\\\\server\\share\\", "");
- TEST(VDFileSplitRoot, "\\\\server\\share\\x", "\\\\server\\share\\", "x");
- TEST(VDFileSplitRoot, "\\\\server\\share\\x\\", "\\\\server\\share\\", "x\\");
- TEST(VDFileSplitRoot, "\\\\server\\share\\x\\y", "\\\\server\\share\\", "x\\y");
-#undef TEST
- }
-} g_VDSystemFilesysTestObject;
-
-#endif
+ if (s[0] != L'.')
+ return false;
+
+ return !s[1] || (s[1] == L'.' && !s[2]);
+}
diff --git a/src/thirdparty/VirtualDub/system/source/hash.cpp b/src/thirdparty/VirtualDub/system/source/hash.cpp
index 8962a511d..914f5980b 100644
--- a/src/thirdparty/VirtualDub/system/source/hash.cpp
+++ b/src/thirdparty/VirtualDub/system/source/hash.cpp
@@ -80,6 +80,31 @@ uint32 VDHashString32(const char *s, uint32 len) {
return hash;
}
+uint32 VDHashString32(const wchar_t *s) {
+ return VDHashString32((const char *)s, wcslen(s) * sizeof(wchar_t));
+}
+
+uint32 VDHashString32(const wchar_t *s, uint32 len) {
+ return VDHashString32((const char *)s, len * sizeof(wchar_t));
+}
+
+uint32 VDHashString32I(const char *s) {
+ uint32 len = (uint32)strlen(s);
+
+ return VDHashString32I(s, len);
+}
+
+uint32 VDHashString32I(const char *s, uint32 len) {
+ uint32 hash = 2166136261;
+
+ for(uint32 i=0; i<len; ++i) {
+ hash *= 16777619;
+ hash ^= (uint32)tolower((unsigned char)*s++);
+ }
+
+ return hash;
+}
+
uint32 VDHashString32I(const wchar_t *s) {
uint32 len = (uint32)wcslen(s);
diff --git a/src/thirdparty/VirtualDub/system/source/log.cpp b/src/thirdparty/VirtualDub/system/source/log.cpp
index fce3df920..d11aba081 100644
--- a/src/thirdparty/VirtualDub/system/source/log.cpp
+++ b/src/thirdparty/VirtualDub/system/source/log.cpp
@@ -41,7 +41,11 @@ namespace {
}
void VDLog(int severity, const VDStringW& s) {
- int strSize = s.size() + 1;
+ VDLog(severity, s.c_str());
+}
+
+void VDLog(int severity, const wchar_t *s) {
+ int strSize = wcslen(s) + 1;
if (strSize >= 16384) {
VDASSERT(false);
@@ -61,7 +65,7 @@ void VDLog(int severity, const VDStringW& s) {
g_logHead &= 16383;
}
- const wchar_t *ps = s.data();
+ const wchar_t *ps = s;
g_log[g_logTail++] = severity;
@@ -113,13 +117,13 @@ void VDAttachLogger(IVDLogger *pLogger, bool bThisThreadOnly, bool bReplayLog) {
}
if (idx > headidx) {
- pLogger->AddLogEntry(severity, VDStringW(g_log + headidx, idx-headidx-1));
+ pLogger->AddLogEntry(severity, VDStringW(g_log + headidx, idx-headidx-1).c_str());
} else {
VDStringW t(idx+16383-headidx);
std::copy(g_log + headidx, g_log + 16384, const_cast<wchar_t *>(t.data()));
std::copy(g_log, g_log + idx - 1, const_cast<wchar_t *>(t.data() + (16384 - headidx)));
- pLogger->AddLogEntry(severity, t);
+ pLogger->AddLogEntry(severity, t.c_str());
}
}
}
@@ -155,7 +159,7 @@ VDAutoLogger::~VDAutoLogger() {
VDDetachLogger(this);
}
-void VDAutoLogger::AddLogEntry(int severity, const VDStringW& s) {
+void VDAutoLogger::AddLogEntry(int severity, const wchar_t *s) {
if (severity >= mMinSeverity)
mEntries.push_back(Entry(severity, s));
}
diff --git a/src/thirdparty/VirtualDub/system/source/process.cpp b/src/thirdparty/VirtualDub/system/source/process.cpp
new file mode 100644
index 000000000..8e96da81c
--- /dev/null
+++ b/src/thirdparty/VirtualDub/system/source/process.cpp
@@ -0,0 +1,47 @@
+#include <stdafx.h>
+#include <vd2/system/process.h>
+#include <vd2/system/VDString.h>
+#include <vd2/system/w32assist.h>
+
+void VDLaunchProgram(const wchar_t *path) {
+ VDStringW cmdLine(L"\"");
+
+ cmdLine += path;
+
+ if (cmdLine.back() == L'\\')
+ cmdLine.push_back(L'\\');
+
+ cmdLine += L"\"";
+
+ PROCESS_INFORMATION processInfo;
+ const DWORD createFlags = CREATE_NEW_PROCESS_GROUP | CREATE_DEFAULT_ERROR_MODE;
+ BOOL success;
+
+ if (VDIsWindowsNT()) {
+ STARTUPINFOW startupInfoW = { sizeof(STARTUPINFOW) };
+ startupInfoW.dwFlags = STARTF_USESHOWWINDOW;
+ startupInfoW.wShowWindow = SW_SHOWNORMAL;
+
+ WCHAR winDir[MAX_PATH];
+ success = GetWindowsDirectoryW(winDir, MAX_PATH);
+
+ if (success)
+ success = CreateProcessW(path, (LPWSTR)cmdLine.c_str(), NULL, NULL, FALSE, createFlags, NULL, winDir, &startupInfoW, &processInfo);
+ } else {
+ STARTUPINFOA startupInfoA = { sizeof(STARTUPINFOA) };
+ startupInfoA.dwFlags = STARTF_USESHOWWINDOW;
+ startupInfoA.wShowWindow = SW_SHOWNORMAL;
+
+ const VDStringA& pathA = VDTextWToA(path);
+ const VDStringA& cmdLineA = VDTextWToA(cmdLine);
+ CHAR winDir[MAX_PATH];
+
+ success = GetWindowsDirectoryA(winDir, MAX_PATH);
+
+ if (success)
+ success = CreateProcessA(pathA.c_str(), (LPSTR)cmdLineA.c_str(), NULL, NULL, FALSE, createFlags, NULL, winDir, &startupInfoA, &processInfo);
+ }
+
+ if (!success)
+ throw MyWin32Error("Unable to launch process: %%s", GetLastError());
+}
diff --git a/src/thirdparty/VirtualDub/system/source/profile.cpp b/src/thirdparty/VirtualDub/system/source/profile.cpp
index 3c91adb07..5de4b1f5f 100644
--- a/src/thirdparty/VirtualDub/system/source/profile.cpp
+++ b/src/thirdparty/VirtualDub/system/source/profile.cpp
@@ -232,3 +232,7 @@ void VDRTProfiler::UnregisterCounter(void *p) {
}
}
}
+
+///////////////////////////////////////////////////////////////////////////
+
+IVDEventProfiler *g_pVDEventProfiler;
diff --git a/src/thirdparty/VirtualDub/system/source/registry.cpp b/src/thirdparty/VirtualDub/system/source/registry.cpp
index 18506e7f6..9007fe8ca 100644
--- a/src/thirdparty/VirtualDub/system/source/registry.cpp
+++ b/src/thirdparty/VirtualDub/system/source/registry.cpp
@@ -28,117 +28,171 @@
#include <vd2/system/VDString.h>
#include <vd2/system/registry.h>
+#include <vd2/system/w32assist.h>
+
+///////////////////////////////////////////////////////////////////////////
+
+class VDRegistryProviderW32 : public IVDRegistryProvider {
+public:
+ void *GetUserKey();
+ void *GetMachineKey();
+ void *CreateKey(void *key, const char *path, bool write);
+ void CloseKey(void *key);
+
+ bool SetBool(void *key, const char *pszName, bool);
+ bool SetInt(void *key, const char *pszName, int);
+ bool SetString(void *key, const char *pszName, const char *pszString);
+ bool SetString(void *key, const char *pszName, const wchar_t *pszString);
+ bool SetBinary(void *key, const char *pszName, const char *data, int len);
+
+ Type GetType(void *key, const char *name);
+ bool GetBool(void *key, const char *pszName, bool& val);
+ bool GetInt(void *key, const char *pszName, int& val);
+ bool GetString(void *key, const char *pszName, VDStringA& s);
+ bool GetString(void *key, const char *pszName, VDStringW& s);
+
+ int GetBinaryLength(void *key, const char *pszName);
+ bool GetBinary(void *key, const char *pszName, char *buf, int maxlen);
+
+ bool RemoveValue(void *key, const char *name);
+ bool RemoveKey(void *key, const char *name);
+
+ void *EnumKeysBegin(void *key);
+ const char *EnumKeysNext(void *enumerator);
+ void EnumKeysClose(void *enumerator);
+
+ void *EnumValuesBegin(void *key);
+ const char *EnumValuesNext(void *enumerator);
+ void EnumValuesClose(void *enumerator);
+
+protected:
+ struct KeyEnumerator {
+ void *mKey;
+ uint32 mIndex;
+ char mName[256];
+ };
+
+ struct ValueEnumerator {
+ void *mKey;
+ uint32 mIndex;
+ char mName[256];
+ };
+};
+
+void *VDRegistryProviderW32::GetUserKey() {
+ return HKEY_CURRENT_USER;
+}
-VDRegistryKey::VDRegistryKey(const char *keyName, bool global, bool write) {
- const HKEY rootKey = global ? HKEY_LOCAL_MACHINE : HKEY_CURRENT_USER;
+void *VDRegistryProviderW32::GetMachineKey() {
+ return HKEY_LOCAL_MACHINE;
+}
+
+void *VDRegistryProviderW32::CreateKey(void *key, const char *path, bool write) {
+ HKEY newKey;
if (write) {
- if (RegCreateKeyEx(rootKey, keyName, 0, NULL, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, (PHKEY)&pHandle, NULL))
- pHandle = NULL;
+ if (RegCreateKeyEx((HKEY)key, path, 0, NULL, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &newKey, NULL))
+ return NULL;
} else {
- if (RegOpenKeyEx(rootKey, keyName, 0, KEY_READ, (PHKEY)&pHandle))
- pHandle = NULL;
+ if (RegOpenKeyEx((HKEY)key, path, 0, KEY_READ, &newKey))
+ return NULL;
}
-}
-VDRegistryKey::~VDRegistryKey() {
- if (pHandle)
- RegCloseKey((HKEY)pHandle);
+ return newKey;
}
-bool VDRegistryKey::setBool(const char *pszName, bool v) const {
- if (pHandle) {
- DWORD dw = v;
-
- if (RegSetValueEx((HKEY)pHandle, pszName, 0, REG_DWORD, (const BYTE *)&dw, sizeof dw))
- return true;
- }
-
- return false;
+void VDRegistryProviderW32::CloseKey(void *key) {
+ RegCloseKey((HKEY)key);
}
-bool VDRegistryKey::setInt(const char *pszName, int i) const {
- if (pHandle) {
- DWORD dw = i;
+bool VDRegistryProviderW32::SetBool(void *key, const char *pszName, bool val) {
+ DWORD dw = val;
+
+ return !RegSetValueEx((HKEY)key, pszName, 0, REG_DWORD, (const BYTE *)&dw, sizeof dw);
+}
- if (RegSetValueEx((HKEY)pHandle, pszName, 0, REG_DWORD, (const BYTE *)&dw, sizeof dw))
- return true;
- }
+bool VDRegistryProviderW32::SetInt(void *key, const char *pszName, int val) {
+ DWORD dw = val;
- return false;
+ return !RegSetValueEx((HKEY)key, pszName, 0, REG_DWORD, (const BYTE *)&dw, sizeof dw);
}
-bool VDRegistryKey::setString(const char *pszName, const char *pszString) const {
- if (pHandle) {
- if (RegSetValueEx((HKEY)pHandle, pszName, 0, REG_SZ, (const BYTE *)pszString, strlen(pszString)))
- return true;
- }
-
- return false;
+bool VDRegistryProviderW32::SetString(void *key, const char *pszName, const char *pszString) {
+ return !RegSetValueEx((HKEY)key, pszName, 0, REG_SZ, (const BYTE *)pszString, strlen(pszString));
}
-bool VDRegistryKey::setString(const char *pszName, const wchar_t *pszString) const {
- if (pHandle) {
- if (GetVersion() & 0x80000000) {
- VDStringA s(VDTextWToA(pszString));
+bool VDRegistryProviderW32::SetString(void *key, const char *pszName, const wchar_t *pszString) {
+ if (!VDIsWindowsNT()) {
+ VDStringA s(VDTextWToA(pszString));
- if (RegSetValueEx((HKEY)pHandle, pszName, 0, REG_SZ, (const BYTE *)s.data(), s.size()))
- return true;
- } else {
- if (RegSetValueExW((HKEY)pHandle, VDTextAToW(pszName).c_str(), 0, REG_SZ, (const BYTE *)pszString, sizeof(wchar_t) * wcslen(pszString)))
- return true;
- }
+ if (RegSetValueEx((HKEY)key, pszName, 0, REG_SZ, (const BYTE *)s.data(), s.size()))
+ return false;
+ } else {
+ if (RegSetValueExW((HKEY)key, VDTextAToW(pszName).c_str(), 0, REG_SZ, (const BYTE *)pszString, sizeof(wchar_t) * wcslen(pszString)))
+ return false;
}
- return false;
+ return true;
}
-bool VDRegistryKey::setBinary(const char *pszName, const char *data, int len) const {
- if (pHandle) {
- if (RegSetValueEx((HKEY)pHandle, pszName, 0, REG_BINARY, (const BYTE *)data, len))
- return true;
- }
-
- return false;
+bool VDRegistryProviderW32::SetBinary(void *key, const char *pszName, const char *data, int len) {
+ return !RegSetValueEx((HKEY)key, pszName, 0, REG_BINARY, (const BYTE *)data, len);
}
-bool VDRegistryKey::getBool(const char *pszName, bool def) const {
- DWORD type, v, s=sizeof(DWORD);
+IVDRegistryProvider::Type VDRegistryProviderW32::GetType(void *key, const char *name) {
+ DWORD type;
+
+ if (RegQueryValueEx((HKEY)key, name, 0, &type, NULL, NULL))
+ return kTypeUnknown;
+
+ switch(type) {
+ case REG_SZ:
+ return kTypeString;
- if (!pHandle || RegQueryValueEx((HKEY)pHandle, pszName, 0, &type, (BYTE *)&v, &s)
- || type != REG_DWORD)
- return def;
+ case REG_BINARY:
+ return kTypeBinary;
- return v != 0;
+ case REG_DWORD:
+ return kTypeInt;
+
+ default:
+ return kTypeUnknown;
+ }
}
-int VDRegistryKey::getInt(const char *pszName, int def) const {
- DWORD type, v, s=sizeof(DWORD);
+bool VDRegistryProviderW32::GetBool(void *key, const char *pszName, bool& val) {
+ DWORD type;
+ DWORD v;
+ DWORD len = sizeof(DWORD);
- if (!pHandle || RegQueryValueEx((HKEY)pHandle, pszName, 0, &type, (BYTE *)&v, &s)
- || type != REG_DWORD)
- return def;
+ if (RegQueryValueEx((HKEY)key, pszName, 0, &type, (BYTE *)&v, &len) || type != REG_DWORD)
+ return false;
- return (int)v;
+ val = (v != 0);
+ return true;
}
-int VDRegistryKey::getEnumInt(const char *pszName, int maxVal, int def) const {
- int v = getInt(pszName, def);
+bool VDRegistryProviderW32::GetInt(void *key, const char *pszName, int& val) {
+ DWORD type;
+ DWORD v;
+ DWORD len = sizeof(DWORD);
- if (v<0 || v>=maxVal)
- v = def;
+ if (RegQueryValueEx((HKEY)key, pszName, 0, &type, (BYTE *)&v, &len) || type != REG_DWORD)
+ return false;
- return v;
+ val = v;
+ return true;
}
-bool VDRegistryKey::getString(const char *pszName, VDStringA& str) const {
- DWORD type, s = sizeof(DWORD);
+bool VDRegistryProviderW32::GetString(void *key, const char *pszName, VDStringA& str) {
+ DWORD type;
+ DWORD s = sizeof(DWORD);
- if (!pHandle || RegQueryValueEx((HKEY)pHandle, pszName, 0, &type, NULL, &s) || type != REG_SZ)
+ if (RegQueryValueEx((HKEY)key, pszName, 0, &type, NULL, &s) || type != REG_SZ)
return false;
str.resize(s);
- if (RegQueryValueEx((HKEY)pHandle, pszName, 0, NULL, (BYTE *)str.data(), &s))
+ if (RegQueryValueEx((HKEY)key, pszName, 0, NULL, (BYTE *)str.data(), &s))
return false;
if (!s)
@@ -149,22 +203,20 @@ bool VDRegistryKey::getString(const char *pszName, VDStringA& str) const {
return true;
}
-bool VDRegistryKey::getString(const char *pszName, VDStringW& str) const {
- if (!pHandle)
- return false;
-
- if (GetVersion() & 0x80000000) {
+bool VDRegistryProviderW32::GetString(void *key, const char *pszName, VDStringW& str) {
+ if (!VDIsWindowsNT()) {
VDStringA v;
- if (!getString(pszName, v))
+ if (!GetString(key, pszName, v))
return false;
str = VDTextAToW(v);
return true;
}
const VDStringW wsName(VDTextAToW(pszName));
- DWORD type, s = sizeof(DWORD);
+ DWORD type;
+ DWORD s = sizeof(DWORD);
- if (!pHandle || RegQueryValueExW((HKEY)pHandle, wsName.c_str(), 0, &type, NULL, &s) || type != REG_SZ)
+ if (RegQueryValueExW((HKEY)key, wsName.c_str(), 0, &type, NULL, &s) || type != REG_SZ)
return false;
if (s <= 0)
@@ -172,7 +224,7 @@ bool VDRegistryKey::getString(const char *pszName, VDStringW& str) const {
else {
str.resize((s + sizeof(wchar_t) - 1) / sizeof(wchar_t));
- if (RegQueryValueExW((HKEY)pHandle, wsName.c_str(), 0, NULL, (BYTE *)&str[0], &s))
+ if (RegQueryValueExW((HKEY)key, wsName.c_str(), 0, NULL, (BYTE *)&str[0], &s))
return false;
str.resize(wcslen(str.c_str())); // Trim off pesky terminating NULLs.
@@ -181,49 +233,234 @@ bool VDRegistryKey::getString(const char *pszName, VDStringW& str) const {
return true;
}
-int VDRegistryKey::getBinaryLength(const char *pszName) const {
- DWORD type, s = sizeof(DWORD);
+int VDRegistryProviderW32::GetBinaryLength(void *key, const char *pszName) {
+ DWORD type;
+ DWORD s = sizeof(DWORD);
- if (!pHandle || RegQueryValueEx((HKEY)pHandle, pszName, 0, &type, NULL, &s)
- || type != REG_BINARY)
+ if (RegQueryValueEx((HKEY)key, pszName, 0, &type, NULL, &s) || type != REG_BINARY)
return -1;
return s;
}
-bool VDRegistryKey::getBinary(const char *pszName, char *buf, int maxlen) const {
- DWORD type, s = maxlen;
+bool VDRegistryProviderW32::GetBinary(void *key, const char *pszName, char *buf, int maxlen) {
+ DWORD type;
+ DWORD s = maxlen;
- if (!pHandle || RegQueryValueEx((HKEY)pHandle, pszName, 0, &type, (BYTE *)buf, &s) || maxlen < (int)s || type != REG_BINARY)
+ if (RegQueryValueEx((HKEY)key, pszName, 0, &type, (BYTE *)buf, &s) || maxlen < (int)s || type != REG_BINARY)
return false;
return true;
}
+bool VDRegistryProviderW32::RemoveValue(void *key, const char *name) {
+ return 0 != RegDeleteValue((HKEY)key, name);
+}
+
+bool VDRegistryProviderW32::RemoveKey(void *key, const char *name) {
+ return 0 != RegDeleteKey((HKEY)key, name);
+}
+
+void *VDRegistryProviderW32::EnumKeysBegin(void *key) {
+ KeyEnumerator *ke = new KeyEnumerator;
+
+ ke->mKey = key;
+ ke->mIndex = 0;
+
+ return ke;
+}
+
+const char *VDRegistryProviderW32::EnumKeysNext(void *enumerator) {
+ KeyEnumerator *ke = (KeyEnumerator *)enumerator;
+
+ DWORD len = sizeof(ke->mName)/sizeof(ke->mName[0]);
+ FILETIME ft;
+ LONG error = RegEnumKeyExA((HKEY)ke->mKey, ke->mIndex, ke->mName, &len, NULL, NULL, NULL, &ft);
+
+ if (error)
+ return NULL;
+
+ ++ke->mIndex;
+ return ke->mName;
+}
+
+void VDRegistryProviderW32::EnumKeysClose(void *enumerator) {
+ delete (KeyEnumerator *)enumerator;
+}
+
+void *VDRegistryProviderW32::EnumValuesBegin(void *key) {
+ ValueEnumerator *ve = new ValueEnumerator;
+
+ ve->mKey = key;
+ ve->mIndex = 0;
+
+ return ve;
+}
+
+const char *VDRegistryProviderW32::EnumValuesNext(void *enumerator) {
+ ValueEnumerator *ve = (ValueEnumerator *)enumerator;
+
+ DWORD len = sizeof(ve->mName)/sizeof(ve->mName[0]);
+ LONG error = RegEnumValueA((HKEY)ve->mKey, ve->mIndex, ve->mName, &len, NULL, NULL, NULL, NULL);
+
+ if (error)
+ return NULL;
+
+ ++ve->mIndex;
+ return ve->mName;
+}
+
+void VDRegistryProviderW32::EnumValuesClose(void *enumerator) {
+ delete (ValueEnumerator *)enumerator;
+}
+
+///////////////////////////////////////////////////////////////////////////
+
+VDRegistryProviderW32 g_VDRegistryProviderW32;
+IVDRegistryProvider *g_pVDRegistryProvider = &g_VDRegistryProviderW32;
+
+IVDRegistryProvider *VDGetRegistryProvider() {
+ return g_pVDRegistryProvider;
+}
+
+void VDSetRegistryProvider(IVDRegistryProvider *provider) {
+ g_pVDRegistryProvider = provider;
+}
+
+///////////////////////////////////////////////////////////////////////////
+
+VDRegistryKey::VDRegistryKey(const char *keyName, bool global, bool write) {
+ IVDRegistryProvider *provider = VDGetRegistryProvider();
+ void *rootKey = global ? provider->GetMachineKey() : provider->GetUserKey();
+
+ mKey = provider->CreateKey(rootKey, keyName, write);
+}
+
+VDRegistryKey::VDRegistryKey(VDRegistryKey& baseKey, const char *name, bool write) {
+ IVDRegistryProvider *provider = VDGetRegistryProvider();
+ void *rootKey = baseKey.getRawHandle();
+
+ mKey = rootKey ? provider->CreateKey(rootKey, name, write) : NULL;
+}
+
+VDRegistryKey::~VDRegistryKey() {
+ if (mKey)
+ VDGetRegistryProvider()->CloseKey(mKey);
+}
+
+bool VDRegistryKey::setBool(const char *name, bool v) const {
+ return mKey && VDGetRegistryProvider()->SetBool(mKey, name, v);
+}
+
+bool VDRegistryKey::setInt(const char *name, int i) const {
+ return mKey && VDGetRegistryProvider()->SetInt(mKey, name, i);
+}
+
+bool VDRegistryKey::setString(const char *name, const char *s) const {
+ return mKey && VDGetRegistryProvider()->SetString(mKey, name, s);
+}
+
+bool VDRegistryKey::setString(const char *name, const wchar_t *s) const {
+ return mKey && VDGetRegistryProvider()->SetString(mKey, name, s);
+}
+
+bool VDRegistryKey::setBinary(const char *name, const char *data, int len) const {
+ return mKey && VDGetRegistryProvider()->SetBinary(mKey, name, data, len);
+}
+
+VDRegistryKey::Type VDRegistryKey::getValueType(const char *name) const {
+ Type type = kTypeUnknown;
+
+ if (mKey) {
+ switch(VDGetRegistryProvider()->GetType(mKey, name)) {
+ case IVDRegistryProvider::kTypeInt:
+ type = kTypeInt;
+ break;
+
+ case IVDRegistryProvider::kTypeString:
+ type = kTypeString;
+ break;
+
+ case IVDRegistryProvider::kTypeBinary:
+ type = kTypeBinary;
+ break;
+ }
+ }
+
+ return type;
+}
+
+bool VDRegistryKey::getBool(const char *name, bool def) const {
+ bool v;
+ return mKey && VDGetRegistryProvider()->GetBool(mKey, name, v) ? v : def;
+}
+
+int VDRegistryKey::getInt(const char *name, int def) const {
+ int v;
+ return mKey && VDGetRegistryProvider()->GetInt(mKey, name, v) ? v : def;
+}
+
+int VDRegistryKey::getEnumInt(const char *pszName, int maxVal, int def) const {
+ int v = getInt(pszName, def);
+
+ if (v<0 || v>=maxVal)
+ v = def;
+
+ return v;
+}
+
+bool VDRegistryKey::getString(const char *name, VDStringA& str) const {
+ return mKey && VDGetRegistryProvider()->GetString(mKey, name, str);
+}
+
+bool VDRegistryKey::getString(const char *name, VDStringW& str) const {
+ return mKey && VDGetRegistryProvider()->GetString(mKey, name, str);
+}
+
+int VDRegistryKey::getBinaryLength(const char *name) const {
+ return mKey ? VDGetRegistryProvider()->GetBinaryLength(mKey, name) : -1;
+}
+
+bool VDRegistryKey::getBinary(const char *name, char *buf, int maxlen) const {
+ return mKey && VDGetRegistryProvider()->GetBinary(mKey, name, buf, maxlen);
+}
+
bool VDRegistryKey::removeValue(const char *name) {
- if (!pHandle || RegDeleteValue((HKEY)pHandle, name))
- return false;
+ return mKey && VDGetRegistryProvider()->RemoveValue(mKey, name);
+}
- return true;
+bool VDRegistryKey::removeKey(const char *name) {
+ return mKey && VDGetRegistryProvider()->RemoveKey(mKey, name);
}
///////////////////////////////////////////////////////////////////////////////
VDRegistryValueIterator::VDRegistryValueIterator(const VDRegistryKey& key)
- : mpHandle(key.getRawHandle())
- , mIndex(0)
+ : mEnumerator(VDGetRegistryProvider()->EnumValuesBegin(key.getRawHandle()))
{
}
+VDRegistryValueIterator::~VDRegistryValueIterator() {
+ VDGetRegistryProvider()->EnumValuesClose(mEnumerator);
+}
+
const char *VDRegistryValueIterator::Next() {
- DWORD len = sizeof(mName)/sizeof(mName[0]);
- LONG error = RegEnumValueA((HKEY)mpHandle, mIndex, mName, &len, NULL, NULL, NULL, NULL);
+ return mEnumerator ? VDGetRegistryProvider()->EnumValuesNext(mEnumerator) : NULL;
+}
- if (error)
- return NULL;
+///////////////////////////////////////////////////////////////////////////////
+
+VDRegistryKeyIterator::VDRegistryKeyIterator(const VDRegistryKey& key)
+ : mEnumerator(VDGetRegistryProvider()->EnumKeysBegin(key.getRawHandle()))
+{
+}
+
+VDRegistryKeyIterator::~VDRegistryKeyIterator() {
+ VDGetRegistryProvider()->EnumKeysClose(mEnumerator);
+}
- ++mIndex;
- return mName;
+const char *VDRegistryKeyIterator::Next() {
+ return mEnumerator ? VDGetRegistryProvider()->EnumKeysNext(mEnumerator) : NULL;
}
///////////////////////////////////////////////////////////////////////////////
diff --git a/src/thirdparty/VirtualDub/system/source/thread.cpp b/src/thirdparty/VirtualDub/system/source/thread.cpp
index 910678bc4..cbdff60e6 100644
--- a/src/thirdparty/VirtualDub/system/source/thread.cpp
+++ b/src/thirdparty/VirtualDub/system/source/thread.cpp
@@ -32,6 +32,7 @@
#include <vd2/system/thread.h>
#include <vd2/system/tls.h>
#include <vd2/system/protscope.h>
+#include <vd2/system/bitmath.h>
namespace {
//
@@ -57,6 +58,21 @@ VDProcessId VDGetCurrentProcessId() {
return (VDProcessId)GetCurrentProcessId();
}
+uint32 VDGetLogicalProcessorCount() {
+ DWORD_PTR processAffinityMask;
+ DWORD_PTR systemAffinityMask;
+ if (!::GetProcessAffinityMask(::GetCurrentProcess(), &processAffinityMask, &systemAffinityMask))
+ return 1;
+
+ // avoid unnecessary WTFs
+ if (!processAffinityMask)
+ return 1;
+
+ // We use the process affinity mask as that's the number of logical processors we'll
+ // actually be working with.
+ return VDCountBits(processAffinityMask);
+}
+
void VDSetThreadDebugName(VDThreadID tid, const char *name) {
THREADNAME_INFO info;
info.dwType = 0x1000;
@@ -250,6 +266,10 @@ int VDSignalBase::waitMultiple(const VDSignalBase **signals, int count) {
return dwRet == WAIT_FAILED ? -1 : dwRet - WAIT_OBJECT_0;
}
+bool VDSignalBase::tryWait(uint32 timeoutMillisec) {
+ return WAIT_OBJECT_0 == WaitForSingleObject(hEvent, timeoutMillisec);
+}
+
void VDSignalPersistent::unsignal() {
ResetEvent(hEvent);
}
diff --git a/src/thirdparty/VirtualDub/system/source/thunk.cpp b/src/thirdparty/VirtualDub/system/source/thunk.cpp
index b39089116..59fbe7f9c 100644
--- a/src/thirdparty/VirtualDub/system/source/thunk.cpp
+++ b/src/thirdparty/VirtualDub/system/source/thunk.cpp
@@ -264,9 +264,10 @@ VDFunctionThunk *VDCreateFunctionThunkFromMethod(void *method, void *pThis, size
return NULL;
uint8 thunkbytes[44]={
- 0x48, 0x8D, 0x04, 0x25, 0x10, 0x00, 0x00, // lea rax, [eip+16]
- 0x00,
- 0xFF, 0x24, 0x25, 0x08, 0x00, 0x00, 0x00, // jmp qword ptr [rip+8]
+ 0x48, 0x8D, 0x05, 0x09, 0x00, 0x00, 0x00, // lea rax, [rip+9]
+ 0xFF, 0x25, 0x03, 0x00, 0x00, 0x00, // jmp qword ptr [rip+3]
+ 0x90, // nop
+ 0x90, // nop
0x90, // nop
0, 0, 0, 0, 0, 0, 0, 0, // dq VDFunctionThunk64
0, 0, 0, 0, 0, 0, 0, 0, // dq method
diff --git a/src/thirdparty/VirtualDub/system/source/time.cpp b/src/thirdparty/VirtualDub/system/source/time.cpp
index 51627c8e7..ae0c3e4bf 100644
--- a/src/thirdparty/VirtualDub/system/source/time.cpp
+++ b/src/thirdparty/VirtualDub/system/source/time.cpp
@@ -33,6 +33,10 @@
#include <vd2/system/thread.h>
#include <vd2/system/thunk.h>
+#ifdef _MSC_VER
+ #pragma comment(lib, "winmm")
+#endif
+
uint32 VDGetCurrentTick() {
return (uint32)GetTickCount();
}
diff --git a/src/thirdparty/VirtualDub/system/source/vdstl_hash.cpp b/src/thirdparty/VirtualDub/system/source/vdstl_hash.cpp
new file mode 100644
index 000000000..d68c6546f
--- /dev/null
+++ b/src/thirdparty/VirtualDub/system/source/vdstl_hash.cpp
@@ -0,0 +1,69 @@
+// VirtualDub - Video processing and capture application
+// System library component
+// Copyright (C) 1998-2010 Avery Lee, All Rights Reserved.
+//
+// Beginning with 1.6.0, the VirtualDub system library is licensed
+// differently than the remainder of VirtualDub. This particular file is
+// thus licensed as follows (the "zlib" license):
+//
+// This software is provided 'as-is', without any express or implied
+// warranty. In no event will the authors be held liable for any
+// damages arising from the use of this software.
+//
+// Permission is granted to anyone to use this software for any purpose,
+// including commercial applications, and to alter it and redistribute it
+// freely, subject to the following restrictions:
+//
+// 1. The origin of this software must not be misrepresented; you must
+// not claim that you wrote the original software. If you use this
+// software in a product, an acknowledgment in the product
+// documentation would be appreciated but is not required.
+// 2. Altered source versions must be plainly marked as such, and must
+// not be misrepresented as being the original software.
+// 3. This notice may not be removed or altered from any source
+// distribution.
+
+#include <stdafx.h>
+#include <vd2/system/hash.h>
+#include <vd2/system/VDString.h>
+#include <vd2/system/vdstl_hash.h>
+
+size_t vdhash<VDStringA>::operator()(const VDStringA& s) const {
+ return VDHashString32(s.data(), s.length());
+}
+
+size_t vdhash<VDStringA>::operator()(const char *s) const {
+ return VDHashString32(s, strlen(s));
+}
+
+size_t vdhash<VDStringW>::operator()(const VDStringW& s) const {
+ return VDHashString32(s.data(), s.length());
+}
+
+size_t vdhash<VDStringW>::operator()(const wchar_t *s) const {
+ return VDHashString32(s, wcslen(s));
+}
+
+bool vdstringpred::operator()(const VDStringA& s, const VDStringA& t) const {
+ return s == t;
+}
+
+bool vdstringpred::operator()(const VDStringA& s, const VDStringSpanA& t) const {
+ return s == t;
+}
+
+bool vdstringpred::operator()(const VDStringA& s, const char *t) const {
+ return s == t;
+}
+
+bool vdstringpred::operator()(const VDStringW& s, const VDStringW& t) const {
+ return s == t;
+}
+
+bool vdstringpred::operator()(const VDStringW& s, const VDStringSpanW& t) const {
+ return s == t;
+}
+
+bool vdstringpred::operator()(const VDStringW& s, const wchar_t *t) const {
+ return s == t;
+}
diff --git a/src/thirdparty/VirtualDub/system/source/vdstl_hashtable.cpp b/src/thirdparty/VirtualDub/system/source/vdstl_hashtable.cpp
new file mode 100644
index 000000000..9b1c277fe
--- /dev/null
+++ b/src/thirdparty/VirtualDub/system/source/vdstl_hashtable.cpp
@@ -0,0 +1,82 @@
+// VirtualDub - Video processing and capture application
+// System library component
+// Copyright (C) 1998-2010 Avery Lee, All Rights Reserved.
+//
+// Beginning with 1.6.0, the VirtualDub system library is licensed
+// differently than the remainder of VirtualDub. This particular file is
+// thus licensed as follows (the "zlib" license):
+//
+// This software is provided 'as-is', without any express or implied
+// warranty. In no event will the authors be held liable for any
+// damages arising from the use of this software.
+//
+// Permission is granted to anyone to use this software for any purpose,
+// including commercial applications, and to alter it and redistribute it
+// freely, subject to the following restrictions:
+//
+// 1. The origin of this software must not be misrepresented; you must
+// not claim that you wrote the original software. If you use this
+// software in a product, an acknowledgment in the product
+// documentation would be appreciated but is not required.
+// 2. Altered source versions must be plainly marked as such, and must
+// not be misrepresented as being the original software.
+// 3. This notice may not be removed or altered from any source
+// distribution.
+
+#include <stdafx.h>
+#include <vd2/system/vdstl_hashtable.h>
+
+vdhashtable_base_node *const vdhashtable_base::sEmptyBucket = {NULL};
+
+vdhashtable_base::vdhashtable_base()
+ : mBucketCount(0)
+ , mElementCount(0)
+ , mpBucketStart(const_cast<vdhashtable_base_node **>(&sEmptyBucket))
+ , mpBucketEnd(const_cast<vdhashtable_base_node **>(&sEmptyBucket))
+{
+}
+
+vdhashtable_base::size_type vdhashtable_base::bucket_count() const {
+ return mpBucketEnd - mpBucketStart;
+}
+
+vdhashtable_base::size_type vdhashtable_base::max_bucket_count() const {
+ return (size_type)-1 >> 1;
+}
+
+vdhashtable_base::size_type vdhashtable_base::bucket_size(size_type n) const {
+ VDASSERT(n < (size_type)(mpBucketEnd - mpBucketStart));
+
+ size_type len = 0;
+ for(vdhashtable_base_node *p = mpBucketStart[n]; p; p = p->mpHashNext)
+ ++len;
+
+ return len;
+}
+
+vdhashtable_base::size_type vdhashtable_base::compute_bucket_count(size_type n) {
+ static const size_t kBucketSizes[]={
+ 11,
+ 17, 37, 67, 131,
+ 257, 521, 1031, 2049,
+ 4099, 8209, 16411, 32771,
+ 65537, 131101, 262147, 524309,
+ 1048583, 2097169, 4194319, 8388617,
+ 16777259, 33554467, 67108879, 134217757,
+ 268435459, 536870923, 1073741827
+ };
+
+ int i = 0;
+ size_type buckets;
+
+ while(i < sizeof(kBucketSizes)/sizeof(kBucketSizes[0])) {
+ buckets = kBucketSizes[i];
+
+ if (n <= buckets)
+ break;
+
+ ++i;
+ }
+
+ return buckets;
+}
diff --git a/src/thirdparty/VirtualDub/system/source/vectors.cpp b/src/thirdparty/VirtualDub/system/source/vectors.cpp
index c54885c45..3a6b91c43 100644
--- a/src/thirdparty/VirtualDub/system/source/vectors.cpp
+++ b/src/thirdparty/VirtualDub/system/source/vectors.cpp
@@ -75,3 +75,9 @@ bool VDSolveLinearEquation(double *src, int n, ptrdiff_t stride_elements, double
return true;
}
+
+template<>
+bool vdrect32::contains(const vdpoint32& pt) const {
+ return ((uint32)pt.x - (uint32)left) < (uint32)right - (uint32)left
+ && ((uint32)pt.y - (uint32)top) < (uint32)bottom - (uint32)top;
+}
diff --git a/src/thirdparty/VirtualDub/system/source/w32assist.cpp b/src/thirdparty/VirtualDub/system/source/w32assist.cpp
index 1faf527ed..5d8285558 100644
--- a/src/thirdparty/VirtualDub/system/source/w32assist.cpp
+++ b/src/thirdparty/VirtualDub/system/source/w32assist.cpp
@@ -104,6 +104,27 @@ void VDSetWindowTextFW32(HWND hwnd, const wchar_t *format, ...) {
va_end(val);
}
+VDStringA VDGetWindowTextAW32(HWND hwnd) {
+ char buf[512];
+
+ int len = GetWindowTextLengthA(hwnd);
+
+ if (len > 511) {
+ vdblock<char> tmp(len + 1);
+ len = GetWindowTextA(hwnd, tmp.data(), tmp.size());
+
+ const char *s = tmp.data();
+ VDStringA text(s, s+len);
+ return text;
+ } else if (len > 0) {
+ len = GetWindowTextA(hwnd, buf, 512);
+
+ return VDStringA(buf, buf + len);
+ }
+
+ return VDStringA();
+}
+
VDStringW VDGetWindowTextW32(HWND hwnd) {
union {
wchar_t w[256];
@@ -153,10 +174,28 @@ void VDAppendMenuW32(HMENU hmenu, UINT flags, UINT id, const wchar_t *text){
}
}
+void VDCheckMenuItemByPositionW32(HMENU hmenu, uint32 pos, bool checked) {
+ CheckMenuItem(hmenu, pos, checked ? MF_BYPOSITION|MF_CHECKED : MF_BYPOSITION|MF_UNCHECKED);
+}
+
void VDCheckMenuItemByCommandW32(HMENU hmenu, UINT cmd, bool checked) {
CheckMenuItem(hmenu, cmd, checked ? MF_BYCOMMAND|MF_CHECKED : MF_BYCOMMAND|MF_UNCHECKED);
}
+void VDCheckRadioMenuItemByPositionW32(HMENU hmenu, uint32 pos, bool checked) {
+ MENUITEMINFOA mii;
+
+ mii.cbSize = sizeof(MENUITEMINFOA);
+ mii.fMask = MIIM_FTYPE | MIIM_STATE;
+ if (GetMenuItemInfo(hmenu, pos, TRUE, &mii)) {
+ mii.fType |= MFT_RADIOCHECK;
+ mii.fState &= ~MFS_CHECKED;
+ if (checked)
+ mii.fState |= MFS_CHECKED;
+ SetMenuItemInfo(hmenu, pos, TRUE, &mii);
+ }
+}
+
void VDCheckRadioMenuItemByCommandW32(HMENU hmenu, UINT cmd, bool checked) {
MENUITEMINFOA mii;
@@ -578,3 +617,58 @@ bool VDPatchModuleExportTableW32(HMODULE hmod, const char *name, void *pCompareV
return false;
}
+
+HMODULE VDLoadSystemLibraryW32(const char *name) {
+ if (VDIsWindowsNT()) {
+ vdfastvector<wchar_t> pathW(MAX_PATH, 0);
+
+ size_t len = GetSystemDirectoryW(pathW.data(), MAX_PATH);
+
+ if (!len)
+ return NULL;
+
+ if (len > MAX_PATH) {
+ pathW.resize(len + 1, 0);
+
+ len = GetSystemDirectoryW(pathW.data(), len);
+ if (!len || len >= pathW.size())
+ return NULL;
+ }
+
+ pathW.resize(len);
+
+ if (pathW.back() != '\\')
+ pathW.push_back('\\');
+
+ while(const char c = *name++)
+ pathW.push_back(c);
+
+ pathW.push_back(0);
+
+ return LoadLibraryW(pathW.data());
+ } else {
+ vdfastvector<char> pathA(MAX_PATH, 0);
+ size_t len = GetSystemDirectoryA(pathA.data(), MAX_PATH);
+
+ if (!len)
+ return NULL;
+
+ if (len > MAX_PATH) {
+ pathA.resize(len + 1, 0);
+
+ len = GetSystemDirectoryA(pathA.data(), len);
+ if (!len || len >= pathA.size())
+ return NULL;
+ }
+
+ pathA.resize(len);
+
+ if (pathA.back() != '\\')
+ pathA.push_back('\\');
+
+ pathA.insert(pathA.end(), name, name + strlen(name));
+ pathA.push_back(0);
+
+ return LoadLibraryA(pathA.data());
+ }
+}
diff --git a/src/thirdparty/VirtualDub/system/source/zip.cpp b/src/thirdparty/VirtualDub/system/source/zip.cpp
index 8ea2ce7bf..9b39ed30b 100644
--- a/src/thirdparty/VirtualDub/system/source/zip.cpp
+++ b/src/thirdparty/VirtualDub/system/source/zip.cpp
@@ -26,6 +26,7 @@
#include "stdafx.h"
#include <vd2/system/zip.h>
#include <vd2/system/error.h>
+#include <vd2/system/binary.h>
bool VDDeflateBitReader::refill() {
sint32 tc = mBytesLeft>kBufferSize?kBufferSize:(sint32)mBytesLeft;
@@ -539,16 +540,54 @@ VDZipArchive::~VDZipArchive() {
void VDZipArchive::Init(IVDRandomAccessStream *pSrc) {
mpStream = pSrc;
- // This seek is wrong for files with zip comments, but we aren't creating
- // a general purpose Unzip utility anyway.
- mpStream->Seek(mpStream->Length() - sizeof(ZipCentralDir));
+ // First, see if the central directory is at the end (common case).
+ const sint64 streamLen = mpStream->Length();
+ mpStream->Seek(streamLen - sizeof(ZipCentralDir));
ZipCentralDir cdirhdr;
mpStream->Read(&cdirhdr, sizeof cdirhdr);
- if (cdirhdr.signature != ZipCentralDir::kSignature)
+ if (cdirhdr.signature != ZipCentralDir::kSignature) {
+ // Okay, the central directory isn't at the end. Read the last 64K of the file
+ // and see if we can spot it.
+ uint32 buflen = 65536 + sizeof(ZipCentralDir);
+
+ if ((sint64)buflen > streamLen)
+ buflen = (uint32)streamLen;
+
+ vdfastvector<uint8> buf(buflen);
+ const uint8 *bufp = buf.data();
+
+ const sint64 bufOffset = streamLen - buflen;
+ mpStream->Seek(bufOffset);
+ mpStream->Read(buf.data(), buflen);
+
+ // Search for valid end-of-central-dir signature.
+ const uint32 kNativeEndSig = VDFromLE32(ZipCentralDir::kSignature);
+ const uint32 kNativeStartSig = VDFromLE32(ZipFileEntry::kSignature);
+
+ for(uint32 i=0; i<buflen-4; ++i) {
+ if (VDReadUnalignedU32(bufp + i) == kNativeEndSig) {
+ const uint32 diroffset = VDReadUnalignedLEU32(bufp + i + offsetof(ZipCentralDir, diroffset));
+ const uint32 dirsize = VDReadUnalignedLEU32(bufp + i + offsetof(ZipCentralDir, dirsize));
+
+ if (diroffset + dirsize == bufOffset + i) {
+ uint32 testsig;
+ mpStream->Seek(diroffset);
+ mpStream->Read(&testsig, 4);
+
+ if (testsig == kNativeStartSig) {
+ memcpy(&cdirhdr, bufp + i, sizeof(ZipCentralDir));
+ goto found_directory;
+ }
+ }
+ }
+ }
+
throw MyError("Zip file has missing or bad central directory");
+ }
+found_directory:
mDirectory.resize(cdirhdr.dirents_total);
mpStream->Seek(cdirhdr.diroffset);
diff --git a/src/thirdparty/VirtualDub/system/system.vcxproj b/src/thirdparty/VirtualDub/system/system.vcxproj
index c8ca21036..fb4b44a98 100644
--- a/src/thirdparty/VirtualDub/system/system.vcxproj
+++ b/src/thirdparty/VirtualDub/system/system.vcxproj
@@ -115,9 +115,12 @@
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="..\h\vd2\system\source\bitmath.cpp" />
+ <ClCompile Include="..\h\vd2\system\source\registrymemory.cpp" />
+ <ClCompile Include="linearalloc.cpp" />
<ClCompile Include="source\cache.cpp" />
<ClCompile Include="source\cmdline.cpp" />
<ClCompile Include="source\cpuaccel.cpp" />
+ <ClCompile Include="source\date.cpp" />
<ClCompile Include="source\debug.cpp" />
<ClCompile Include="source\debugx86.cpp" />
<ClCompile Include="source\Error.cpp" />
@@ -134,6 +137,7 @@
<ClCompile Include="source\log.cpp" />
<ClCompile Include="source\math.cpp" />
<ClCompile Include="source\memory.cpp" />
+ <ClCompile Include="source\process.cpp" />
<ClCompile Include="source\profile.cpp" />
<ClCompile Include="source\progress.cpp" />
<ClCompile Include="source\protscope.cpp" />
@@ -148,6 +152,8 @@
<ClCompile Include="source\VDNamespace.cpp" />
<ClCompile Include="source\VDScheduler.cpp" />
<ClCompile Include="source\vdstl.cpp" />
+ <ClCompile Include="source\vdstl_hash.cpp" />
+ <ClCompile Include="source\vdstl_hashtable.cpp" />
<ClCompile Include="source\VDString.cpp" />
<ClCompile Include="source\vectors.cpp" />
<ClCompile Include="source\w32assist.cpp" />
@@ -172,6 +178,7 @@
<ClInclude Include="..\h\vd2\system\cache.h" />
<ClInclude Include="..\h\vd2\system\cmdline.h" />
<ClInclude Include="..\h\vd2\system\cpuaccel.h" />
+ <ClInclude Include="..\h\vd2\system\date.h" />
<ClInclude Include="..\h\vd2\system\debug.h" />
<ClInclude Include="..\h\vd2\system\debugx86.h" />
<ClInclude Include="..\h\vd2\system\Error.h" />
@@ -184,15 +191,18 @@
<ClInclude Include="..\h\vd2\system\halffloat.h" />
<ClInclude Include="..\h\vd2\system\hash.h" />
<ClInclude Include="..\h\vd2\system\int128.h" />
+ <ClInclude Include="..\h\vd2\system\linearalloc.h" />
<ClInclude Include="..\h\vd2\system\list.h" />
<ClInclude Include="..\h\vd2\system\log.h" />
<ClInclude Include="..\h\vd2\system\math.h" />
<ClInclude Include="..\h\vd2\system\memory.h" />
+ <ClInclude Include="..\h\vd2\system\process.h" />
<ClInclude Include="..\h\vd2\system\profile.h" />
<ClInclude Include="..\h\vd2\system\progress.h" />
<ClInclude Include="..\h\vd2\system\protscope.h" />
<ClInclude Include="..\h\vd2\system\refcount.h" />
<ClInclude Include="..\h\vd2\system\registry.h" />
+ <ClInclude Include="..\h\vd2\system\registrymemory.h" />
<ClInclude Include="..\h\vd2\system\strutil.h" />
<ClInclude Include="..\h\vd2\system\text.h" />
<ClInclude Include="..\h\vd2\system\thread.h" />
@@ -206,6 +216,11 @@
<ClInclude Include="..\h\vd2\system\VDRingBuffer.h" />
<ClInclude Include="..\h\vd2\system\VDScheduler.h" />
<ClInclude Include="..\h\vd2\system\vdstl.h" />
+ <ClInclude Include="..\h\vd2\system\vdstl_hash.h" />
+ <ClInclude Include="..\h\vd2\system\vdstl_hashmap.h" />
+ <ClInclude Include="..\h\vd2\system\vdstl_hashset.h" />
+ <ClInclude Include="..\h\vd2\system\vdstl_hashtable.h" />
+ <ClInclude Include="..\h\vd2\system\vdstl_vector.h" />
<ClInclude Include="..\h\vd2\system\VDString.h" />
<ClInclude Include="..\h\vd2\system\vdtypes.h" />
<ClInclude Include="..\h\vd2\system\vectors.h" />
diff --git a/src/thirdparty/VirtualDub/system/system.vcxproj.filters b/src/thirdparty/VirtualDub/system/system.vcxproj.filters
index 3b70d3f4b..41673220c 100644
--- a/src/thirdparty/VirtualDub/system/system.vcxproj.filters
+++ b/src/thirdparty/VirtualDub/system/system.vcxproj.filters
@@ -36,6 +36,9 @@
<ClCompile Include="source\cpuaccel.cpp">
<Filter>Source Files</Filter>
</ClCompile>
+ <ClCompile Include="source\date.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
<ClCompile Include="source\debug.cpp">
<Filter>Source Files</Filter>
</ClCompile>
@@ -144,6 +147,21 @@
<ClCompile Include="source\stdafx.cpp">
<Filter>Precompiled Header Support</Filter>
</ClCompile>
+ <ClCompile Include="source\process.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="..\h\vd2\system\source\registrymemory.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="source\vdstl_hash.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="source\vdstl_hashtable.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="linearalloc.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\h\vd2\system\atomic.h">
@@ -164,6 +182,9 @@
<ClInclude Include="..\h\VD2\system\cpuaccel.h">
<Filter>Header Files</Filter>
</ClInclude>
+ <ClInclude Include="..\h\VD2\system\date.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
<ClInclude Include="..\h\vd2\system\debug.h">
<Filter>Header Files</Filter>
</ClInclude>
@@ -293,6 +314,30 @@
<ClInclude Include="h\stdafx.h">
<Filter>Precompiled Header Support</Filter>
</ClInclude>
+ <ClInclude Include="..\h\vd2\system\linearalloc.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="..\h\vd2\system\process.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="..\h\vd2\system\registrymemory.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="..\h\vd2\system\vdstl_hash.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="..\h\vd2\system\vdstl_hashmap.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="..\h\vd2\system\vdstl_hashset.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="..\h\vd2\system\vdstl_hashtable.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="..\h\vd2\system\vdstl_vector.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
</ItemGroup>
<ItemGroup>
<YASM Include="source\a_memory.asm">