Skip to content

Commit a739b3b

Browse files
committed
Add code
1 parent 536855f commit a739b3b

19 files changed

Lines changed: 3297 additions & 1 deletion

CMakeLists.txt

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
cmake_minimum_required (VERSION 3.1)
2+
project (MiniDeen)
3+
add_library(MiniDeen SHARED avs_interface.cpp vs_interface.cpp version.rc)
4+
set (VERSION "r1")
5+
configure_file (
6+
"${PROJECT_SOURCE_DIR}/version.hpp.in"
7+
"${PROJECT_SOURCE_DIR}/version.hpp"
8+
)
9+
configure_file (
10+
"${PROJECT_SOURCE_DIR}/version.rc.in"
11+
"${PROJECT_SOURCE_DIR}/version.rc"
12+
)
13+
add_definitions(-DMINIDEEN_X86)
14+
include_directories(include)
15+
add_custom_command(
16+
TARGET MiniDeen POST_BUILD
17+
COMMAND ${CMAKE_COMMAND} -E copy $<TARGET_FILE:MiniDeen> "../Release_${VERSION}/${_DIR}/$<TARGET_FILE_NAME:MiniDeen>"
18+
)

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ Parameters:
2424

2525
Size of the neighbourhood. Must be between 1 (3x3) and 7 (15x15).
2626

27-
Default: 1 for the first plane, and the previous plane's radius for the other planes.
27+
Default: 1.
2828

2929
- *thrY*, *thrUV*
3030

avs_interface.cpp

Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
#include <inttypes.h>
2+
#include "wrapper/avs_filter.hpp"
3+
#include "version.hpp"
4+
#include "minideen_engine.hpp"
5+
6+
class MiniDeenFilter: public AVSFilter {
7+
8+
protected:
9+
int radius;
10+
int thrY, thrUV;
11+
int y, u, v;
12+
int bit_per_channel;
13+
uint16_t magic[MAX_PIXEL_COUNT];
14+
decltype (MiniDeenEngine::process_plane_scalar<uint8_t>) *process_plane;
15+
16+
public:
17+
virtual const char* name() const { return "MiniDeen"; }
18+
virtual void initialize() {
19+
radius = ArgAsInt( 1, "radius", 1);
20+
thrY = ArgAsInt( 2, "thrY", 10);
21+
thrUV = ArgAsInt( 3, "thrUV", 12);
22+
y = ArgAsInt( 4, "y", 3);
23+
u = ArgAsInt( 5, "u", 3);
24+
v = ArgAsInt( 6, "v", 3);
25+
bit_per_channel = vi.BitsPerComponent();
26+
byte_per_channel = bit_per_channel > 8 ? 2 : 1;
27+
28+
// Check input
29+
if (!vi.HasVideo())
30+
throw("where's the video?");
31+
if (thrY < 2 || thrY > 255)
32+
throw("threshold (Y) must be between 2 and 255 (inclusive).");
33+
if (thrUV < 2 || thrUV > 255)
34+
throw("threshold (UV) must be between 2 and 255 (inclusive).");
35+
if (!supported_pixel())
36+
throw("only 8..16 bit integer clips with constant format are supported.");
37+
38+
int pixel_max = (1 << bit_per_channel) - 1;
39+
40+
thrY = thrY * pixel_max / 255;
41+
thrUV = thrUV * pixel_max / 255;
42+
memset(&magic, 0, sizeof(magic));
43+
44+
process_plane = (bit_per_channel == 8) ? MiniDeenEngine::process_plane_scalar<uint8_t>
45+
: MiniDeenEngine::process_plane_scalar<uint16_t>;
46+
#if defined (MINIDEEN_X86)
47+
process_plane = (bit_per_channel == 8) ? MiniDeenEngine::process_plane_sse2_8bit
48+
: MiniDeenEngine::process_plane_sse2_16bit;
49+
50+
for (int i = 2; i < MAX_PIXEL_COUNT; i++)
51+
magic[i] = (unsigned)(65536.0 / i + 0.5);
52+
#endif
53+
54+
}
55+
56+
virtual AVSFilter::AFrame get(int n) {
57+
auto src = GetFrame(child, n);
58+
auto dst = NewFrame();
59+
auto widthY = width(src, PLANAR_Y);
60+
auto widthUV = width(src, PLANAR_U);
61+
auto heightY = height(src, PLANAR_Y);
62+
auto heightUV = height(src, PLANAR_U);
63+
auto strideY = stride(src, PLANAR_Y);
64+
auto strideUV = stride(src, PLANAR_U);
65+
if (y == 3)
66+
process_plane(src->GetReadPtr(PLANAR_Y), dst->GetWritePtr(PLANAR_Y), 0, widthY, widthY, heightY, strideY, thrY, radius, magic);
67+
else if (y == 2)
68+
_env->BitBlt(dst->GetWritePtr(PLANAR_Y), strideY, src->GetReadPtr(PLANAR_Y), strideY, widthY * byte_per_channel, heightY);
69+
if (u == 3)
70+
process_plane(src->GetReadPtr(PLANAR_U), dst->GetWritePtr(PLANAR_U), 0, widthUV, widthUV, heightUV, strideUV, thrUV, radius, magic);
71+
else if (u == 2)
72+
_env->BitBlt(dst->GetWritePtr(PLANAR_U), strideUV, src->GetReadPtr(PLANAR_U), strideUV, widthUV * byte_per_channel, heightUV);
73+
if (v == 3)
74+
process_plane(src->GetReadPtr(PLANAR_V), dst->GetWritePtr(PLANAR_V), 0, widthUV, widthUV, heightUV, strideUV, thrUV, radius, magic);
75+
else if (v == 2)
76+
_env->BitBlt(dst->GetWritePtr(PLANAR_V), strideUV, src->GetReadPtr(PLANAR_V), strideUV, widthUV * byte_per_channel, heightUV);
77+
78+
return dst;
79+
}
80+
public:
81+
using AVSFilter::AVSFilter;
82+
};
83+
84+
85+
const AVS_Linkage *AVS_linkage = NULL;
86+
87+
AVSValue __cdecl CreateAVSFilter(AVSValue args, void* user_data, IScriptEnvironment* env)
88+
{
89+
auto filter = new MiniDeenFilter(args, env);
90+
try {
91+
filter->initialize();
92+
}
93+
catch (const char *err) {
94+
env->ThrowError("%s %s: %s", filter->name(), PLUGIN_VERSION, err);
95+
}
96+
return filter;
97+
}
98+
99+
extern "C" __declspec(dllexport) const char* __stdcall AvisynthPluginInit3(IScriptEnvironment* env, AVS_Linkage* vectors)
100+
{
101+
AVS_linkage = vectors;
102+
env->AddFunction("MiniDeen", "c[radius]i[thrY]i[thrUV]i[y]i[u]i[v]i", CreateAVSFilter, 0);
103+
return "MiniDeen";
104+
}

include/VSHelper.h

Lines changed: 169 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,169 @@
1+
/*****************************************************************************
2+
* Copyright (c) 2012-2015 Fredrik Mellbin
3+
* --- Legal stuff ---
4+
* This program is free software. It comes without any warranty, to
5+
* the extent permitted by applicable law. You can redistribute it
6+
* and/or modify it under the terms of the Do What The Fuck You Want
7+
* To Public License, Version 2, as published by Sam Hocevar. See
8+
* http://sam.zoy.org/wtfpl/COPYING for more details.
9+
*****************************************************************************/
10+
11+
#ifndef VSHELPER_H
12+
#define VSHELPER_H
13+
14+
#include <limits.h>
15+
#include <stdint.h>
16+
#include <stdlib.h>
17+
#include <string.h>
18+
#include <assert.h>
19+
#include <math.h>
20+
#ifdef _WIN32
21+
#include <malloc.h>
22+
#endif
23+
#include "VapourSynth.h"
24+
25+
/* Visual Studio doesn't recognize inline in c mode */
26+
#if defined(_MSC_VER) && !defined(__cplusplus)
27+
#define inline _inline
28+
#endif
29+
30+
/* A kinda portable definition of the C99 restrict keyword (or its inofficial C++ equivalent) */
31+
#if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L /* Available in C99 */
32+
#define VS_RESTRICT restrict
33+
#elif defined(__cplusplus) || defined(_MSC_VER) /* Almost all relevant C++ compilers support it so just assume it works */
34+
#define VS_RESTRICT __restrict
35+
#else /* Not supported */
36+
#define VS_RESTRICT
37+
#endif
38+
39+
#ifdef _WIN32
40+
#define VS_ALIGNED_MALLOC(pptr, size, alignment) do { *(pptr) = _aligned_malloc((size), (alignment)); } while (0)
41+
#define VS_ALIGNED_FREE(ptr) do { _aligned_free((ptr)); } while (0)
42+
#else
43+
#define VS_ALIGNED_MALLOC(pptr, size, alignment) do { if(posix_memalign((void**)(pptr), (alignment), (size))) *((void**)pptr) = NULL; } while (0)
44+
#define VS_ALIGNED_FREE(ptr) do { free((ptr)); } while (0)
45+
#endif
46+
47+
#define VSMAX(a,b) ((a) > (b) ? (a) : (b))
48+
#define VSMIN(a,b) ((a) > (b) ? (b) : (a))
49+
50+
#ifdef __cplusplus
51+
/* A nicer templated malloc for all the C++ users out there */
52+
#if __cplusplus >= 201103L || (defined(_MSC_VER) && _MSC_VER >= 1900)
53+
template<typename T=void>
54+
#else
55+
template<typename T>
56+
#endif
57+
static inline T* vs_aligned_malloc(size_t size, size_t alignment) {
58+
#ifdef _WIN32
59+
return (T*)_aligned_malloc(size, alignment);
60+
#else
61+
void *tmp = NULL;
62+
if (posix_memalign(&tmp, alignment, size))
63+
tmp = 0;
64+
return (T*)tmp;
65+
#endif
66+
}
67+
68+
static inline void vs_aligned_free(void *ptr) {
69+
VS_ALIGNED_FREE(ptr);
70+
}
71+
#endif /* __cplusplus */
72+
73+
/* convenience function for checking if the format never changes between frames */
74+
static inline int isConstantFormat(const VSVideoInfo *vi) {
75+
return vi->height > 0 && vi->width > 0 && vi->format;
76+
}
77+
78+
/* convenience function to check for if two clips have the same format (unknown/changeable will be considered the same too) */
79+
static inline int isSameFormat(const VSVideoInfo *v1, const VSVideoInfo *v2) {
80+
return v1->height == v2->height && v1->width == v2->width && v1->format == v2->format;
81+
}
82+
83+
/* multiplies and divides a rational number, such as a frame duration, in place and reduces the result */
84+
static inline void muldivRational(int64_t *num, int64_t *den, int64_t mul, int64_t div) {
85+
/* do nothing if the rational number is invalid */
86+
if (!*den)
87+
return;
88+
89+
/* nobody wants to accidentally divide by zero */
90+
assert(div);
91+
92+
int64_t a, b;
93+
*num *= mul;
94+
*den *= div;
95+
a = *num;
96+
b = *den;
97+
while (b != 0) {
98+
int64_t t = a;
99+
a = b;
100+
b = t % b;
101+
}
102+
if (a < 0)
103+
a = -a;
104+
*num /= a;
105+
*den /= a;
106+
}
107+
108+
/* reduces a rational number */
109+
static inline void vs_normalizeRational(int64_t *num, int64_t *den) {
110+
muldivRational(num, den, 1, 1);
111+
}
112+
113+
/* add two rational numbers and reduces the result */
114+
static inline void vs_addRational(int64_t *num, int64_t *den, int64_t addnum, int64_t addden) {
115+
/* do nothing if the rational number is invalid */
116+
if (!*den)
117+
return;
118+
119+
/* nobody wants to accidentally add an invalid rational number */
120+
assert(addden);
121+
122+
if (*den == addden) {
123+
*num += addnum;
124+
} else {
125+
int64_t temp = addden;
126+
addnum *= *den;
127+
addden *= *den;
128+
*num *= temp;
129+
*den *= temp;
130+
131+
*num += addnum;
132+
133+
vs_normalizeRational(num, den);
134+
}
135+
}
136+
137+
/* converts an int64 to int with saturation, useful to silence warnings when reading int properties among other things */
138+
static inline int int64ToIntS(int64_t i) {
139+
if (i > INT_MAX)
140+
return INT_MAX;
141+
else if (i < INT_MIN)
142+
return INT_MIN;
143+
else return (int)i;
144+
}
145+
146+
static inline void vs_bitblt(void *dstp, int dst_stride, const void *srcp, int src_stride, size_t row_size, size_t height) {
147+
if (height) {
148+
if (src_stride == dst_stride && src_stride == (int)row_size) {
149+
memcpy(dstp, srcp, row_size * height);
150+
} else {
151+
const uint8_t *srcp8 = (const uint8_t *)srcp;
152+
uint8_t *dstp8 = (uint8_t *)dstp;
153+
size_t i;
154+
for (i = 0; i < height; i++) {
155+
memcpy(dstp8, srcp8, row_size);
156+
srcp8 += src_stride;
157+
dstp8 += dst_stride;
158+
}
159+
}
160+
}
161+
}
162+
163+
/* check if the frame dimensions are valid for a given format */
164+
/* returns non-zero for valid width and height */
165+
static inline int areValidDimensions(const VSFormat *fi, int width, int height) {
166+
return !(width % (1 << fi->subSamplingW) || height % (1 << fi->subSamplingH));
167+
}
168+
169+
#endif

0 commit comments

Comments
 (0)