Welcome to Doom9's Forum, THE in-place to be for everyone interested in DVD conversion. Before you start posting please read the forum rules. By posting to this forum you agree to abide by the rules. |
30th July 2016, 11:44 | #385 | Link |
I'm Siri
Join Date: Oct 2012
Location: void
Posts: 2,633
|
|
30th July 2016, 11:59 | #387 | Link | |
I'm Siri
Join Date: Oct 2012
Location: void
Posts: 2,633
|
Quote:
I would have discontinued my branch if the answer was yeah |
|
2nd August 2016, 17:41 | #391 | Link |
I'm Siri
Join Date: Oct 2012
Location: void
Posts: 2,633
|
good news and bad news here
bad news: the SATD deduction I made last year was totally wrong (forgive me, my major is not signal processing...) and you merged that incorrect stuff into your branch as well... good news: I made the double checked correct SATD implementation this time with a recursive Hadamard Ordered Walsh-Hadamard Transform References: https://en.wikipedia.org/wiki/Hadamard_transform http://fourier.eng.hmc.edu/e161/lectures/wht/node2.html Code:
static auto uninitialized = true; static constexpr auto init_val = 1.; static decltype(init_val + 0) hadamard_matrix_2x2[2][2]; static decltype(init_val + 0) hadamard_matrix_4x4[4][4]; static decltype(init_val + 0) hadamard_matrix_8x8[8][8]; static decltype(init_val + 0) hadamard_matrix_16x16[16][16]; static decltype(init_val + 0) hadamard_matrix_32x32[32][32]; template<int length = 2, typename T = double> auto create_Hadamard_matrix(void *dst, const void *src) { constexpr auto src_length = length >> 1; const auto coeff = std::sqrt(2.); auto actual_dst = reinterpret_cast<T(*)[length]>(dst); auto actual_src = reinterpret_cast<const T(*)[src_length]>(src); for (auto i = 0; i < src_length; ++i) std::memcpy(actual_dst[i], actual_src[i], sizeof(actual_src[0])); for (auto i = 0; i < src_length; ++i) std::memcpy(actual_dst[src_length + i], actual_src[i], sizeof(actual_src[0])); auto ptr = reinterpret_cast<T(*)[2][src_length]>(dst); for (auto i = 0; i <length; ++i) std::memcpy(ptr[i][1], ptr[i][0], sizeof(actual_src[0])); ptr += src_length; for (auto i = 0; i < src_length; ++i) for (auto &x : ptr[i][1]) x = -x; for (auto i = 0; i < length; ++i) for (auto &x : actual_dst[i]) x /= coeff; } static auto SATD_init() { create_Hadamard_matrix(hadamard_matrix_2x2, &init_val); create_Hadamard_matrix<4>(hadamard_matrix_4x4, hadamard_matrix_2x2); create_Hadamard_matrix<8>(hadamard_matrix_8x8, hadamard_matrix_4x4); create_Hadamard_matrix<16>(hadamard_matrix_16x16, hadamard_matrix_8x8); create_Hadamard_matrix<32>(hadamard_matrix_32x32, hadamard_matrix_16x16); uninitialized = false; } template<int length = 2, typename T = double> auto product_calc(const void *src, const void *hadamard, void *dst) { auto actual_hadamard = reinterpret_cast<const T(*)[length]>(hadamard); auto actual_src = reinterpret_cast<const T(*)[length]>(src); auto actual_dst = reinterpret_cast<T(*)[length]>(dst); auto dot_p = [&](auto row, auto column) { T sum = 0; for (auto i = 0; i < length; ++i) sum += actual_hadamard[row][i] * actual_src[i][column]; return sum; }; for (auto i = 0; i < length; ++i) for (auto j = 0; j < length; ++j) actual_dst[i][j] = dot_p(i, j); } template<int nBlkWidth, int nBlkHeight, typename PixelType> auto Satd_C(const uint8_t *pSrc8, intptr_t nSrcPitch, const uint8_t *pRef8, intptr_t nRefPitch) { if (uninitialized) SATD_init(); void *hadamard; if (nBlkWidth == 32 && nBlkHeight == 32) hadamard = hadamard_matrix_32x32; else if (nBlkWidth == 16 && nBlkHeight == 16) hadamard = hadamard_matrix_16x16; else if (nBlkWidth == 8 && nBlkHeight == 8) hadamard = hadamard_matrix_8x8; else if (nBlkWidth == 4 && nBlkHeight == 4) hadamard = hadamard_matrix_4x4; else hadamard = nullptr; auto sum = 0.; decltype(sum) _dif_block[nBlkHeight][nBlkWidth]; decltype(sum) _transformed_block[nBlkHeight][nBlkWidth]; for (auto y = 0; y < nBlkHeight; ++y) { for (auto x = 0; x < nBlkWidth; ++x) { auto pSrc = reinterpret_cast<const PixelType *>(pSrc8); auto pRef = reinterpret_cast<const PixelType *>(pRef8); _dif_block[y][x] = static_cast<decltype(sum)>(pSrc[x]) - pRef[x]; } pSrc8 += nSrcPitch; pRef8 += nRefPitch; } product_calc<nBlkWidth>(_dif_block, hadamard, _transformed_block); for (auto &x : _transformed_block) for (auto y : x) sum += std::abs(y); return sum; } my implementation is C++14 inside out, not sure if I could translate it to C properly so didn't make any PR this time edit:typo Last edited by feisty2; 2nd August 2016 at 19:10. |
3rd August 2016, 08:32 | #392 | Link |
Registered User
Join Date: Oct 2009
Location: crow-land
Posts: 540
|
vapoursynth newbie seeking clarification :- I want a script to mimic my old avisynth script and process all planes but now using the vapoursynth mvtools ... is the below correct ? If not, what is it doing, and what should it be instead ?
vsource = icore.mv.Degrain1(vsource, super, backward_vec1, forward_vec1, thsad=400, plane=4) avisynth: MDegrain1(super, backward_vec1,forward_vec1,thSAD=400,plane=4) Last edited by hydra3333; 3rd August 2016 at 08:35. |
3rd August 2016, 10:24 | #393 | Link | |
unsigned int
Join Date: Oct 2012
Location: 🇪🇺
Posts: 760
|
Quote:
__________________
Buy me a "coffee" and/or hire me to write code! |
|
21st August 2016, 15:27 | #394 | Link | |
unsigned int
Join Date: Oct 2012
Location: 🇪🇺
Posts: 760
|
Quote:
__________________
Buy me a "coffee" and/or hire me to write code! |
|
21st August 2016, 15:41 | #395 | Link | |
I'm Siri
Join Date: Oct 2012
Location: void
Posts: 2,633
|
Quote:
well, SATD transforms the difference to frequency domain(Hadamard Transform = Discrete Fourier Transform mathematically on a 2^n * 2^n square block) and it helps with shimmering and fading sometimes like dct=1, but much faster than that |
|
21st August 2016, 15:48 | #396 | Link |
Professional Code Monkey
Join Date: Jun 2003
Location: Kinnarps Chair
Posts: 2,548
|
I have a simple question. Has anyone ever tried SAD but with the average value of the input blocks adjusted? I mean the main point of this exercise is to reduce the whole block average into a single coefficient to reduce its influence a lot. There should be some faster but still good for 90% of the times trick.
And saying it's in avisynth is a bad excuse. Temporalsoften is in avisynth and that's nothing to be proud of.
__________________
VapourSynth - proving that scripting languages and video processing isn't dead yet |
23rd August 2016, 11:54 | #398 | Link |
Registered User
Join Date: Jan 2016
Posts: 98
|
I was trying to remember what's the purpose of using SATD in mvtools, so I googled a little, and found:
And then I thought: if people at VideoLAN / MulltiCoreWare implemented the asm functions for SATD for x265? Could they be used? As I’m not a developer, I can't answer that question. Is this a possibility? In the search I saw things like: [x265] [PATCH] primitives: asm: update: implementation of satd(sse2) [x265] [PATCH] primitives: asm: satd: fix for 32 bit issue Could those be used for mvtools-VapourSynth ??? |
23rd August 2016, 14:16 | #400 | Link |
I'm Siri
Join Date: Oct 2012
Location: void
Posts: 2,633
|
Code:
I was trying to remember what's the purpose of using SATD in mvtools 1. SAD, sum of the absolute difference between each pair of samples 2. dct=1, transform both current block and the reference block to frequency domain, and calculate the sum of the absolute difference between each pair of transformed samples 3. SATD, get the difference block between 2 macroblocks, and transform that difference block to frequency domain and calculate the sum of the absolute value of each sample in that transformed difference block basically, dct=5(SATD) is the compromise between dct=0(SAD) and dct=1(frequency domain SAD) |
Thread Tools | Search this Thread |
Display Modes | |
|
|