filters/merge.cpp
| Line | Branch | Exec | Source |
|---|---|---|---|
| 1 | // Avisynth v2.5. Copyright 2002 Ben Rudiak-Gould et al. | ||
| 2 | // http://avisynth.nl | ||
| 3 | |||
| 4 | // This program is free software; you can redistribute it and/or modify | ||
| 5 | // it under the terms of the GNU General Public License as published by | ||
| 6 | // the Free Software Foundation; either version 2 of the License, or | ||
| 7 | // (at your option) any later version. | ||
| 8 | // | ||
| 9 | // This program is distributed in the hope that it will be useful, | ||
| 10 | // but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 11 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 12 | // GNU General Public License for more details. | ||
| 13 | // | ||
| 14 | // You should have received a copy of the GNU General Public License | ||
| 15 | // along with this program; if not, write to the Free Software | ||
| 16 | // Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA, or visit | ||
| 17 | // http://www.gnu.org/copyleft/gpl.html . | ||
| 18 | // | ||
| 19 | // Linking Avisynth statically or dynamically with other modules is making a | ||
| 20 | // combined work based on Avisynth. Thus, the terms and conditions of the GNU | ||
| 21 | // General Public License cover the whole combination. | ||
| 22 | // | ||
| 23 | // As a special exception, the copyright holders of Avisynth give you | ||
| 24 | // permission to link Avisynth with independent modules that communicate with | ||
| 25 | // Avisynth solely through the interfaces defined in avisynth.h, regardless of the license | ||
| 26 | // terms of these independent modules, and to copy and distribute the | ||
| 27 | // resulting combined work under terms of your choice, provided that | ||
| 28 | // every copy of the combined work is accompanied by a complete copy of | ||
| 29 | // the source code of Avisynth (the version of Avisynth used to produce the | ||
| 30 | // combined work), being distributed under the terms of the GNU General | ||
| 31 | // Public License plus this exception. An independent module is a module | ||
| 32 | // which is not derived from or based on Avisynth, such as 3rd-party filters, | ||
| 33 | // import and export plugins, or graphical user interfaces. | ||
| 34 | |||
| 35 | |||
| 36 | // Avisynth filter: YUV merge / Swap planes | ||
| 37 | // by Klaus Post (kp@interact.dk) | ||
| 38 | // adapted by Richard Berg (avisynth-dev@richardberg.net) | ||
| 39 | // iSSE code by Ian Brabham | ||
| 40 | |||
| 41 | #include <avisynth.h> | ||
| 42 | #include "merge.h" | ||
| 43 | #ifdef INTEL_INTRINSICS | ||
| 44 | #include "intel/merge_sse.h" | ||
| 45 | #include "intel/merge_avx2.h" | ||
| 46 | #endif | ||
| 47 | #include "../core/internal.h" | ||
| 48 | #include "avs/alignment.h" | ||
| 49 | #include <cstdint> | ||
| 50 | |||
| 51 | |||
| 52 | /* ----------------------------------- | ||
| 53 | * weighted_merge_chroma_yuy2 | ||
| 54 | * ----------------------------------- | ||
| 55 | */ | ||
| 56 | ✗ | static void weighted_merge_chroma_yuy2_c(BYTE *src, const BYTE *chroma, int pitch, int chroma_pitch,int width, int height, int weight, int invweight) { | |
| 57 | ✗ | for (int y = 0; y < height; ++y) { | |
| 58 | ✗ | for (int x = 0; x < width; x+=2) { | |
| 59 | ✗ | src[x+1] = (chroma[x+1] * weight + src[x+1] * invweight + 16384) >> 15; | |
| 60 | } | ||
| 61 | ✗ | src+=pitch; | |
| 62 | ✗ | chroma+=chroma_pitch; | |
| 63 | } | ||
| 64 | ✗ | } | |
| 65 | |||
| 66 | |||
| 67 | /* ----------------------------------- | ||
| 68 | * weighted_merge_luma_yuy2 | ||
| 69 | * ----------------------------------- | ||
| 70 | */ | ||
| 71 | ✗ | static void weighted_merge_luma_yuy2_c(BYTE *src, const BYTE *luma, int pitch, int luma_pitch,int width, int height, int weight, int invweight) { | |
| 72 | ✗ | for (int y = 0; y < height; ++y) { | |
| 73 | ✗ | for (int x = 0; x < width; x+=2) { | |
| 74 | ✗ | src[x] = (luma[x] * weight + src[x] * invweight + 16384) >> 15; | |
| 75 | } | ||
| 76 | ✗ | src+=pitch; | |
| 77 | ✗ | luma+=luma_pitch; | |
| 78 | } | ||
| 79 | ✗ | } | |
| 80 | |||
| 81 | |||
| 82 | /* ----------------------------------- | ||
| 83 | * replace_luma_yuy2 | ||
| 84 | * ----------------------------------- | ||
| 85 | */ | ||
| 86 | ✗ | static void replace_luma_yuy2_c(BYTE *src, const BYTE *luma, int pitch, int luma_pitch,int width, int height ) { | |
| 87 | ✗ | for (int y = 0; y < height; ++y) { | |
| 88 | ✗ | for (int x = 0; x < width; x+=2) { | |
| 89 | ✗ | src[x] = luma[x]; | |
| 90 | } | ||
| 91 | ✗ | src+=pitch; | |
| 92 | ✗ | luma+=luma_pitch; | |
| 93 | } | ||
| 94 | ✗ | } | |
| 95 | |||
| 96 | |||
| 97 | /* ----------------------------------- | ||
| 98 | * average_plane | ||
| 99 | * ----------------------------------- | ||
| 100 | */ | ||
| 101 | // for uint8_t and uint16_t | ||
| 102 | template<typename pixel_t> | ||
| 103 | ✗ | static void average_plane_c(BYTE *p1, const BYTE *p2, int p1_pitch, int p2_pitch, int rowsize, int height) { | |
| 104 | ✗ | for (int y = 0; y < height; ++y) { | |
| 105 | ✗ | for (size_t x = 0; x < rowsize / sizeof(pixel_t); ++x) { | |
| 106 | ✗ | reinterpret_cast<pixel_t *>(p1)[x] = (int(reinterpret_cast<pixel_t *>(p1)[x]) + reinterpret_cast<const pixel_t *>(p2)[x] + 1) >> 1; | |
| 107 | } | ||
| 108 | ✗ | p1 += p1_pitch; | |
| 109 | ✗ | p2 += p2_pitch; | |
| 110 | } | ||
| 111 | ✗ | } | |
| 112 | // for float | ||
| 113 | ✗ | static void average_plane_c_float(BYTE *p1, const BYTE *p2, int p1_pitch, int p2_pitch, int rowsize, int height) { | |
| 114 | |||
| 115 | ✗ | size_t rs = rowsize / sizeof(float); | |
| 116 | |||
| 117 | ✗ | for (int y = 0; y < height; ++y) { | |
| 118 | ✗ | for (size_t x = 0; x < rs; ++x) { | |
| 119 | ✗ | reinterpret_cast<float *>(p1)[x] = (reinterpret_cast<float *>(p1)[x] + reinterpret_cast<const float *>(p2)[x]) / 2.0f; | |
| 120 | } | ||
| 121 | ✗ | p1 += p1_pitch; | |
| 122 | ✗ | p2 += p2_pitch; | |
| 123 | } | ||
| 124 | ✗ | } | |
| 125 | |||
| 126 | // weighted_merge_planar C reference and SIMD are now in overlay/blend_common*. | ||
| 127 | // merge_plane uses get_weighted_merge_fn / get_weighted_merge_float_fn from merge.h. | ||
| 128 | |||
| 129 | |||
| 130 | /******************************************************************** | ||
| 131 | ***** Declare index of new filters for Avisynth's filter engine ***** | ||
| 132 | ********************************************************************/ | ||
| 133 | extern const AVSFunction Merge_filters[] = { | ||
| 134 | { "Merge", BUILTIN_FUNC_PREFIX, "cc[weight]f", MergeAll::Create }, // src, src2, weight | ||
| 135 | { "MergeChroma", BUILTIN_FUNC_PREFIX, "cc[weight]f", MergeChroma::Create }, // src, chroma src, weight | ||
| 136 | { "MergeChroma", BUILTIN_FUNC_PREFIX, "cc[chromaweight]f", MergeChroma::Create }, // Legacy! | ||
| 137 | { "MergeLuma", BUILTIN_FUNC_PREFIX, "cc[weight]f", MergeLuma::Create }, // src, luma src, weight | ||
| 138 | { "MergeLuma", BUILTIN_FUNC_PREFIX, "cc[lumaweight]f", MergeLuma::Create }, // Legacy! | ||
| 139 | { 0 } | ||
| 140 | }; | ||
| 141 | |||
| 142 | 35 | void merge_plane(BYTE* srcp, const BYTE* otherp, int src_pitch, int other_pitch, int src_rowsize, int src_height, float weight, int bits_per_pixel, bool use_padded_width, IScriptEnvironment* env) { | |
| 143 | |||
| 144 |
2/2✓ Branch 2 → 3 taken 26 times.
✓ Branch 2 → 4 taken 9 times.
|
35 | if (use_padded_width) { |
| 145 | // Align the width to the next multiple of FRAME_ALIGN (64) bytes, which is the alignment used for AviSynth+ frame buffers. | ||
| 146 | // This allows SIMD kernels to process the entire row without a scalar tail, improving performance for full-frame merges. | ||
| 147 | 26 | src_rowsize = AlignNumber(src_rowsize, FRAME_ALIGN); | |
| 148 | } | ||
| 149 | |||
| 150 | // 15 bit arithmetic for integer weighted merge: weight is in [0..32768], invweight = 32768 - weight. | ||
| 151 | 35 | const int weight_i = (int)(weight * 32768.0f + 0.5f); | |
| 152 | 35 | const int invweight_i = 32768 - weight_i; | |
| 153 | |||
| 154 |
1/4✗ Branch 4 → 5 not taken.
✓ Branch 4 → 8 taken 35 times.
✗ Branch 5 → 6 not taken.
✗ Branch 5 → 7 not taken.
|
35 | const int pixelsize = bits_per_pixel == 8 ? 1 : (bits_per_pixel <= 16 ? 2 : 4); |
| 155 | |||
| 156 |
1/2✗ Branch 9 → 10 not taken.
✓ Branch 9 → 11 taken 35 times.
|
35 | const bool use_average = (bits_per_pixel == 32) ? (weight == 0.5f) : (weight_i == 16384); |
| 157 |
2/2✓ Branch 12 → 13 taken 9 times.
✓ Branch 12 → 34 taken 26 times.
|
35 | if (use_average) |
| 158 | { | ||
| 159 | //average of two planes | ||
| 160 |
1/2✓ Branch 13 → 14 taken 9 times.
✗ Branch 13 → 27 not taken.
|
9 | if (pixelsize != 4) // 1 or 2 |
| 161 | { | ||
| 162 | #ifdef INTEL_INTRINSICS | ||
| 163 |
1/2✓ Branch 15 → 16 taken 9 times.
✗ Branch 15 → 19 not taken.
|
9 | if (env->GetCPUFlags() & CPUF_AVX2) { |
| 164 |
1/2✓ Branch 16 → 17 taken 9 times.
✗ Branch 16 → 18 not taken.
|
9 | if (pixelsize == 1) |
| 165 | 9 | average_plane_avx2<uint8_t>(srcp, otherp, src_pitch, other_pitch, src_rowsize, src_height); | |
| 166 | else // pixel_size==2 | ||
| 167 | ✗ | average_plane_avx2<uint16_t>(srcp, otherp, src_pitch, other_pitch, src_rowsize, src_height); | |
| 168 | } | ||
| 169 | ✗ | else if (env->GetCPUFlags() & CPUF_SSE2) { | |
| 170 | ✗ | if (pixelsize == 1) | |
| 171 | ✗ | average_plane_sse2<uint8_t>(srcp, otherp, src_pitch, other_pitch, src_rowsize, src_height); | |
| 172 | else // pixel_size==2 | ||
| 173 | ✗ | average_plane_sse2<uint16_t>(srcp, otherp, src_pitch, other_pitch, src_rowsize, src_height); | |
| 174 | } | ||
| 175 | else | ||
| 176 | #endif | ||
| 177 | { | ||
| 178 | ✗ | if (pixelsize == 1) | |
| 179 | ✗ | average_plane_c<uint8_t>(srcp, otherp, src_pitch, other_pitch, src_rowsize, src_height); | |
| 180 | else // pixel_size==2 | ||
| 181 | ✗ | average_plane_c<uint16_t>(srcp, otherp, src_pitch, other_pitch, src_rowsize, src_height); | |
| 182 | } | ||
| 183 | } | ||
| 184 | else { // if (pixelsize == 4) | ||
| 185 | #ifdef INTEL_INTRINSICS | ||
| 186 | ✗ | if (env->GetCPUFlags() & CPUF_AVX2) | |
| 187 | ✗ | average_plane_avx2_float(srcp, otherp, src_pitch, other_pitch, src_rowsize, src_height); | |
| 188 | ✗ | else if (env->GetCPUFlags() & CPUF_SSE2) | |
| 189 | ✗ | average_plane_sse2_float(srcp, otherp, src_pitch, other_pitch, src_rowsize, src_height); | |
| 190 | else | ||
| 191 | #endif | ||
| 192 | ✗ | average_plane_c_float(srcp, otherp, src_pitch, other_pitch, src_rowsize, src_height); | |
| 193 | } | ||
| 194 | } | ||
| 195 | else | ||
| 196 | { | ||
| 197 | // Frame scanlines are always padded to FRAME_ALIGN (64) bytes in AviSynth+. | ||
| 198 | // When called from the "Merge" filter, we are passing the aligned width, since it eliminates the | ||
| 199 | // scalar tail in all weighted_merge SIMD kernels. | ||
| 200 | // When called from other filters, like Overlay and Layer, the width must be exact. | ||
| 201 | // Overreading/writing into the alignment padding is safe for full-frame merges. | ||
| 202 | // See use_padded_width parameter. | ||
| 203 | 26 | const int width_pixels = src_rowsize / pixelsize; | |
| 204 | 26 | const int cpuFlags = env->GetCPUFlags(); | |
| 205 |
1/2✗ Branch 35 → 36 not taken.
✓ Branch 35 → 38 taken 26 times.
|
26 | if (bits_per_pixel == 32) { |
| 206 | ✗ | get_weighted_merge_float_fn(cpuFlags)(srcp, otherp, src_pitch, other_pitch, width_pixels, src_height, weight); | |
| 207 | } else { | ||
| 208 | 26 | get_weighted_merge_fn(cpuFlags, weight_i)(srcp, otherp, src_pitch, other_pitch, width_pixels, src_height, weight_i, invweight_i, bits_per_pixel); | |
| 209 | } | ||
| 210 | } | ||
| 211 | 35 | } | |
| 212 | |||
| 213 | /**************************** | ||
| 214 | ****** Merge Chroma ***** | ||
| 215 | ****************************/ | ||
| 216 | |||
| 217 | 6 | MergeChroma::MergeChroma(PClip _child, PClip _clip, float _weight, IScriptEnvironment* env) | |
| 218 |
3/6✓ Branch 2 → 3 taken 6 times.
✗ Branch 2 → 35 not taken.
✓ Branch 3 → 4 taken 6 times.
✗ Branch 3 → 33 not taken.
✓ Branch 5 → 6 taken 6 times.
✗ Branch 5 → 38 not taken.
|
6 | : GenericVideoFilter(_child), clip(_clip), weight(_weight) |
| 219 | { | ||
| 220 |
1/2✓ Branch 7 → 8 taken 6 times.
✗ Branch 7 → 36 not taken.
|
6 | const VideoInfo& vi2 = clip->GetVideoInfo(); |
| 221 | |||
| 222 |
11/18✓ Branch 8 → 9 taken 6 times.
✗ Branch 8 → 36 not taken.
✓ Branch 9 → 10 taken 1 time.
✓ Branch 9 → 12 taken 5 times.
✓ Branch 10 → 11 taken 1 time.
✗ Branch 10 → 36 not taken.
✓ Branch 11 → 12 taken 1 time.
✗ Branch 11 → 16 not taken.
✓ Branch 12 → 13 taken 6 times.
✗ Branch 12 → 36 not taken.
✓ Branch 13 → 14 taken 1 time.
✓ Branch 13 → 17 taken 5 times.
✓ Branch 14 → 15 taken 1 time.
✗ Branch 14 → 36 not taken.
✗ Branch 15 → 16 not taken.
✓ Branch 15 → 17 taken 1 time.
✗ Branch 18 → 19 not taken.
✓ Branch 18 → 20 taken 6 times.
|
6 | if (!(vi.IsYUV() || vi.IsYUVA()) || !(vi2.IsYUV() || vi2.IsYUVA())) |
| 223 | ✗ | env->ThrowError("MergeChroma: YUV data only (no RGB); use ConvertToYUY2, ConvertToYV12/16/24 or ConvertToYUVxxx"); | |
| 224 | |||
| 225 |
2/4✓ Branch 20 → 21 taken 6 times.
✗ Branch 20 → 36 not taken.
✗ Branch 21 → 22 not taken.
✓ Branch 21 → 23 taken 6 times.
|
6 | if (!(vi.IsSameColorspace(vi2))) |
| 226 | ✗ | env->ThrowError("MergeChroma: YUV images must have same data type."); | |
| 227 | |||
| 228 |
2/4✓ Branch 23 → 24 taken 6 times.
✗ Branch 23 → 25 not taken.
✗ Branch 24 → 25 not taken.
✓ Branch 24 → 26 taken 6 times.
|
6 | if (vi.width!=vi2.width || vi.height!=vi2.height) |
| 229 | ✗ | env->ThrowError("MergeChroma: Images must have same width and height!"); | |
| 230 | |||
| 231 |
1/2✗ Branch 26 → 27 not taken.
✓ Branch 26 → 28 taken 6 times.
|
6 | if (weight<0.0f) weight=0.0f; |
| 232 |
1/2✗ Branch 28 → 29 not taken.
✓ Branch 28 → 30 taken 6 times.
|
6 | if (weight>1.0f) weight=1.0f; |
| 233 | |||
| 234 |
1/2✓ Branch 30 → 31 taken 6 times.
✗ Branch 30 → 36 not taken.
|
6 | pixelsize = vi.ComponentSize(); |
| 235 |
1/2✓ Branch 31 → 32 taken 6 times.
✗ Branch 31 → 36 not taken.
|
6 | bits_per_pixel = vi.BitsPerComponent(); |
| 236 | 6 | } | |
| 237 | |||
| 238 | |||
| 239 | 5 | PVideoFrame __stdcall MergeChroma::GetFrame(int n, IScriptEnvironment* env) | |
| 240 | { | ||
| 241 |
1/2✓ Branch 3 → 4 taken 5 times.
✗ Branch 3 → 211 not taken.
|
5 | PVideoFrame src = child->GetFrame(n, env); |
| 242 | |||
| 243 | // Threshold: for integer clips snap based on the SIMD integer scale (0..32768); | ||
| 244 | // for float clips use exact float comparison. | ||
| 245 |
1/2✓ Branch 4 → 5 taken 5 times.
✗ Branch 4 → 6 not taken.
|
5 | const int weight_i_simd = (bits_per_pixel != 32) ? (int)(weight * 32768.0f + 0.5f) : 0; |
| 246 | 5 | const int inv_weight_i_simd = 32768 - weight_i_simd; | |
| 247 |
1/2✗ Branch 7 → 8 not taken.
✓ Branch 7 → 9 taken 5 times.
|
5 | const bool weight_is_zero = (bits_per_pixel == 32) ? (weight == 0.0f) : (weight_i_simd == 0); |
| 248 |
1/2✗ Branch 10 → 11 not taken.
✓ Branch 10 → 12 taken 5 times.
|
5 | const bool weight_is_one = (bits_per_pixel == 32) ? (weight == 1.0f) : (weight_i_simd >= 32768); |
| 249 | |||
| 250 |
1/4✗ Branch 13 → 14 not taken.
✓ Branch 13 → 16 taken 5 times.
✗ Branch 14 → 15 not taken.
✗ Branch 14 → 209 not taken.
|
5 | if (weight_is_zero) return src; |
| 251 | |||
| 252 |
1/2✓ Branch 17 → 18 taken 5 times.
✗ Branch 17 → 209 not taken.
|
5 | PVideoFrame chroma = clip->GetFrame(n, env); |
| 253 | |||
| 254 |
1/2✓ Branch 19 → 20 taken 5 times.
✗ Branch 19 → 207 not taken.
|
5 | int h = src->GetHeight(); |
| 255 |
1/2✓ Branch 21 → 22 taken 5 times.
✗ Branch 21 → 207 not taken.
|
5 | int w = src->GetRowSize(); // width in pixels |
| 256 | |||
| 257 |
2/2✓ Branch 22 → 23 taken 4 times.
✓ Branch 22 → 76 taken 1 time.
|
5 | if (!weight_is_one) { |
| 258 |
2/4✓ Branch 23 → 24 taken 4 times.
✗ Branch 23 → 207 not taken.
✗ Branch 24 → 25 not taken.
✓ Branch 24 → 38 taken 4 times.
|
4 | if (vi.IsYUY2()) { |
| 259 | ✗ | env->MakeWritable(&src); | |
| 260 | ✗ | BYTE* srcp = src->GetWritePtr(); | |
| 261 | ✗ | const BYTE* chromap = chroma->GetReadPtr(); | |
| 262 | |||
| 263 | ✗ | int src_pitch = src->GetPitch(); | |
| 264 | ✗ | int chroma_pitch = chroma->GetPitch(); | |
| 265 | #ifdef INTEL_INTRINSICS | ||
| 266 | ✗ | if (env->GetCPUFlags() & CPUF_SSE2) | |
| 267 | { | ||
| 268 | ✗ | weighted_merge_chroma_yuy2_sse2(srcp, chromap, src_pitch, chroma_pitch, w, h, weight_i_simd, inv_weight_i_simd); | |
| 269 | } | ||
| 270 | else | ||
| 271 | #ifdef X86_32 | ||
| 272 | if (env->GetCPUFlags() & CPUF_MMX) | ||
| 273 | { | ||
| 274 | weighted_merge_chroma_yuy2_mmx(srcp, chromap, src_pitch, chroma_pitch, w, h, weight_i_simd, inv_weight_i_simd); | ||
| 275 | } | ||
| 276 | else | ||
| 277 | #endif | ||
| 278 | #endif | ||
| 279 | { | ||
| 280 | ✗ | weighted_merge_chroma_yuy2_c(srcp, chromap, src_pitch, chroma_pitch, w, h, weight_i_simd, inv_weight_i_simd); | |
| 281 | } | ||
| 282 | } | ||
| 283 | else { // Planar YUV | ||
| 284 |
1/2✓ Branch 38 → 39 taken 4 times.
✗ Branch 38 → 207 not taken.
|
4 | env->MakeWritable(&src); |
| 285 |
1/2✓ Branch 40 → 41 taken 4 times.
✗ Branch 40 → 207 not taken.
|
4 | src->GetWritePtr(PLANAR_Y); //Must be requested |
| 286 | |||
| 287 |
1/2✓ Branch 42 → 43 taken 4 times.
✗ Branch 42 → 207 not taken.
|
4 | BYTE* srcpU = (BYTE*)src->GetWritePtr(PLANAR_U); |
| 288 |
1/2✓ Branch 44 → 45 taken 4 times.
✗ Branch 44 → 207 not taken.
|
4 | BYTE* chromapU = (BYTE*)chroma->GetReadPtr(PLANAR_U); |
| 289 |
1/2✓ Branch 46 → 47 taken 4 times.
✗ Branch 46 → 207 not taken.
|
4 | BYTE* srcpV = (BYTE*)src->GetWritePtr(PLANAR_V); |
| 290 |
1/2✓ Branch 48 → 49 taken 4 times.
✗ Branch 48 → 207 not taken.
|
4 | BYTE* chromapV = (BYTE*)chroma->GetReadPtr(PLANAR_V); |
| 291 |
1/2✓ Branch 50 → 51 taken 4 times.
✗ Branch 50 → 207 not taken.
|
4 | int src_pitch_uv = src->GetPitch(PLANAR_U); |
| 292 |
1/2✓ Branch 52 → 53 taken 4 times.
✗ Branch 52 → 207 not taken.
|
4 | int chroma_pitch_uv = chroma->GetPitch(PLANAR_U); |
| 293 |
1/2✓ Branch 54 → 55 taken 4 times.
✗ Branch 54 → 207 not taken.
|
4 | int src_rowsize_u = src->GetRowSize(PLANAR_U_ALIGNED); |
| 294 |
1/2✓ Branch 56 → 57 taken 4 times.
✗ Branch 56 → 207 not taken.
|
4 | int src_rowsize_v = src->GetRowSize(PLANAR_V_ALIGNED); |
| 295 |
1/2✓ Branch 58 → 59 taken 4 times.
✗ Branch 58 → 207 not taken.
|
4 | int src_height_uv = src->GetHeight(PLANAR_U); |
| 296 | |||
| 297 |
1/2✓ Branch 59 → 60 taken 4 times.
✗ Branch 59 → 207 not taken.
|
4 | merge_plane(srcpU, chromapU, src_pitch_uv, chroma_pitch_uv, src_rowsize_u, src_height_uv, weight, bits_per_pixel, true, env); |
| 298 |
1/2✓ Branch 60 → 61 taken 4 times.
✗ Branch 60 → 207 not taken.
|
4 | merge_plane(srcpV, chromapV, src_pitch_uv, chroma_pitch_uv, src_rowsize_v, src_height_uv, weight, bits_per_pixel, true, env); |
| 299 | |||
| 300 | // FIXME: MergeChroma should not be modifying the alpha plane | ||
| 301 |
3/4✓ Branch 61 → 62 taken 4 times.
✗ Branch 61 → 207 not taken.
✓ Branch 62 → 63 taken 1 time.
✓ Branch 62 → 198 taken 3 times.
|
4 | if (vi.IsYUVA()) |
| 302 |
7/14✓ Branch 64 → 65 taken 1 time.
✗ Branch 64 → 207 not taken.
✓ Branch 66 → 67 taken 1 time.
✗ Branch 66 → 207 not taken.
✓ Branch 68 → 69 taken 1 time.
✗ Branch 68 → 207 not taken.
✓ Branch 70 → 71 taken 1 time.
✗ Branch 70 → 207 not taken.
✓ Branch 72 → 73 taken 1 time.
✗ Branch 72 → 207 not taken.
✓ Branch 74 → 75 taken 1 time.
✗ Branch 74 → 207 not taken.
✓ Branch 75 → 198 taken 1 time.
✗ Branch 75 → 207 not taken.
|
1 | merge_plane(src->GetWritePtr(PLANAR_A), chroma->GetReadPtr(PLANAR_A), src->GetPitch(PLANAR_A), chroma->GetPitch(PLANAR_A), |
| 303 | src->GetRowSize(PLANAR_A_ALIGNED), src->GetHeight(PLANAR_A), weight, bits_per_pixel, true, env); | ||
| 304 | } | ||
| 305 | } | ||
| 306 | else { // weight == 1.0 | ||
| 307 |
2/4✓ Branch 76 → 77 taken 1 time.
✗ Branch 76 → 207 not taken.
✗ Branch 77 → 78 not taken.
✓ Branch 77 → 93 taken 1 time.
|
1 | if (vi.IsYUY2()) { |
| 308 | ✗ | const BYTE* srcp = src->GetReadPtr(); | |
| 309 | ✗ | env->MakeWritable(&chroma); | |
| 310 | ✗ | BYTE* chromap = chroma->GetWritePtr(); | |
| 311 | |||
| 312 | ✗ | int src_pitch = src->GetPitch(); | |
| 313 | ✗ | int chroma_pitch = chroma->GetPitch(); | |
| 314 | #ifdef INTEL_INTRINSICS | ||
| 315 | ✗ | if (env->GetCPUFlags() & CPUF_SSE2) | |
| 316 | { | ||
| 317 | ✗ | replace_luma_yuy2_sse2(chromap, srcp, chroma_pitch, src_pitch, w, h); // Just swap luma/chroma | |
| 318 | } | ||
| 319 | else | ||
| 320 | #ifdef X86_32 | ||
| 321 | if (env->GetCPUFlags() & CPUF_MMX) | ||
| 322 | { | ||
| 323 | replace_luma_yuy2_mmx(chromap, srcp, chroma_pitch, src_pitch, w, h); // Just swap luma/chroma | ||
| 324 | } | ||
| 325 | else | ||
| 326 | #endif | ||
| 327 | #endif | ||
| 328 | { | ||
| 329 | ✗ | replace_luma_yuy2_c(chromap, srcp, chroma_pitch, src_pitch, w, h); // Just swap luma/chroma | |
| 330 | } | ||
| 331 | |||
| 332 | ✗ | return chroma; | |
| 333 | } | ||
| 334 | else { | ||
| 335 |
2/4✓ Branch 94 → 95 taken 1 time.
✗ Branch 94 → 207 not taken.
✗ Branch 95 → 96 not taken.
✓ Branch 95 → 139 taken 1 time.
|
1 | if (src->IsWritable()) { |
| 336 | ✗ | src->GetWritePtr(PLANAR_Y); //Must be requested | |
| 337 | ✗ | env->BitBlt(src->GetWritePtr(PLANAR_U), src->GetPitch(PLANAR_U), chroma->GetReadPtr(PLANAR_U), chroma->GetPitch(PLANAR_U), chroma->GetRowSize(PLANAR_U), chroma->GetHeight(PLANAR_U)); | |
| 338 | ✗ | env->BitBlt(src->GetWritePtr(PLANAR_V), src->GetPitch(PLANAR_V), chroma->GetReadPtr(PLANAR_V), chroma->GetPitch(PLANAR_V), chroma->GetRowSize(PLANAR_V), chroma->GetHeight(PLANAR_V)); | |
| 339 | ✗ | if (vi.IsYUVA()) | |
| 340 | ✗ | env->BitBlt(src->GetWritePtr(PLANAR_A), src->GetPitch(PLANAR_A), chroma->GetReadPtr(PLANAR_A), chroma->GetPitch(PLANAR_A), chroma->GetRowSize(PLANAR_A), chroma->GetHeight(PLANAR_A)); | |
| 341 | } | ||
| 342 | else { // avoid the cost of 2 chroma blits | ||
| 343 |
1/2✓ Branch 139 → 140 taken 1 time.
✗ Branch 139 → 206 not taken.
|
1 | PVideoFrame dst = env->NewVideoFrameP(vi, &src); |
| 344 | |||
| 345 |
7/14✓ Branch 141 → 142 taken 1 time.
✗ Branch 141 → 204 not taken.
✓ Branch 143 → 144 taken 1 time.
✗ Branch 143 → 204 not taken.
✓ Branch 145 → 146 taken 1 time.
✗ Branch 145 → 204 not taken.
✓ Branch 147 → 148 taken 1 time.
✗ Branch 147 → 204 not taken.
✓ Branch 149 → 150 taken 1 time.
✗ Branch 149 → 204 not taken.
✓ Branch 151 → 152 taken 1 time.
✗ Branch 151 → 204 not taken.
✓ Branch 152 → 153 taken 1 time.
✗ Branch 152 → 204 not taken.
|
1 | env->BitBlt(dst->GetWritePtr(PLANAR_Y), dst->GetPitch(PLANAR_Y), src->GetReadPtr(PLANAR_Y), src->GetPitch(PLANAR_Y), src->GetRowSize(PLANAR_Y), src->GetHeight(PLANAR_Y)); |
| 346 |
7/14✓ Branch 154 → 155 taken 1 time.
✗ Branch 154 → 204 not taken.
✓ Branch 156 → 157 taken 1 time.
✗ Branch 156 → 204 not taken.
✓ Branch 158 → 159 taken 1 time.
✗ Branch 158 → 204 not taken.
✓ Branch 160 → 161 taken 1 time.
✗ Branch 160 → 204 not taken.
✓ Branch 162 → 163 taken 1 time.
✗ Branch 162 → 204 not taken.
✓ Branch 164 → 165 taken 1 time.
✗ Branch 164 → 204 not taken.
✓ Branch 165 → 166 taken 1 time.
✗ Branch 165 → 204 not taken.
|
1 | env->BitBlt(dst->GetWritePtr(PLANAR_U), dst->GetPitch(PLANAR_U), chroma->GetReadPtr(PLANAR_U), chroma->GetPitch(PLANAR_U), chroma->GetRowSize(PLANAR_U), chroma->GetHeight(PLANAR_U)); |
| 347 |
7/14✓ Branch 167 → 168 taken 1 time.
✗ Branch 167 → 204 not taken.
✓ Branch 169 → 170 taken 1 time.
✗ Branch 169 → 204 not taken.
✓ Branch 171 → 172 taken 1 time.
✗ Branch 171 → 204 not taken.
✓ Branch 173 → 174 taken 1 time.
✗ Branch 173 → 204 not taken.
✓ Branch 175 → 176 taken 1 time.
✗ Branch 175 → 204 not taken.
✓ Branch 177 → 178 taken 1 time.
✗ Branch 177 → 204 not taken.
✓ Branch 178 → 179 taken 1 time.
✗ Branch 178 → 204 not taken.
|
1 | env->BitBlt(dst->GetWritePtr(PLANAR_V), dst->GetPitch(PLANAR_V), chroma->GetReadPtr(PLANAR_V), chroma->GetPitch(PLANAR_V), chroma->GetRowSize(PLANAR_V), chroma->GetHeight(PLANAR_V)); |
| 348 |
2/4✓ Branch 179 → 180 taken 1 time.
✗ Branch 179 → 204 not taken.
✗ Branch 180 → 181 not taken.
✓ Branch 180 → 194 taken 1 time.
|
1 | if (vi.IsYUVA()) |
| 349 | ✗ | env->BitBlt(dst->GetWritePtr(PLANAR_A), dst->GetPitch(PLANAR_A), chroma->GetReadPtr(PLANAR_A), chroma->GetPitch(PLANAR_A), chroma->GetRowSize(PLANAR_A), chroma->GetHeight(PLANAR_A)); | |
| 350 | |||
| 351 |
1/2✓ Branch 194 → 195 taken 1 time.
✗ Branch 194 → 204 not taken.
|
1 | return dst; |
| 352 | 1 | } | |
| 353 | } | ||
| 354 | } | ||
| 355 |
1/2✓ Branch 198 → 199 taken 4 times.
✗ Branch 198 → 207 not taken.
|
4 | return src; |
| 356 | 5 | } | |
| 357 | |||
| 358 | |||
| 359 | ✗ | AVSValue __cdecl MergeChroma::Create(AVSValue args, void* , IScriptEnvironment* env) | |
| 360 | { | ||
| 361 | ✗ | return new MergeChroma(args[0].AsClip(), args[1].AsClip(), (float)args[2].AsFloat(1.0f), env); | |
| 362 | } | ||
| 363 | |||
| 364 | |||
| 365 | /************************** | ||
| 366 | ****** Merge Luma ***** | ||
| 367 | **************************/ | ||
| 368 | |||
| 369 | |||
| 370 | 6 | MergeLuma::MergeLuma(PClip _child, PClip _clip, float _weight, IScriptEnvironment* env) | |
| 371 |
3/6✓ Branch 2 → 3 taken 6 times.
✗ Branch 2 → 45 not taken.
✓ Branch 3 → 4 taken 6 times.
✗ Branch 3 → 43 not taken.
✓ Branch 5 → 6 taken 6 times.
✗ Branch 5 → 48 not taken.
|
6 | : GenericVideoFilter(_child), clip(_clip), weight(_weight) |
| 372 | { | ||
| 373 |
1/2✓ Branch 7 → 8 taken 6 times.
✗ Branch 7 → 46 not taken.
|
6 | const VideoInfo& vi2 = clip->GetVideoInfo(); |
| 374 | |||
| 375 |
11/18✓ Branch 8 → 9 taken 6 times.
✗ Branch 8 → 46 not taken.
✓ Branch 9 → 10 taken 1 time.
✓ Branch 9 → 12 taken 5 times.
✓ Branch 10 → 11 taken 1 time.
✗ Branch 10 → 46 not taken.
✓ Branch 11 → 12 taken 1 time.
✗ Branch 11 → 16 not taken.
✓ Branch 12 → 13 taken 6 times.
✗ Branch 12 → 46 not taken.
✓ Branch 13 → 14 taken 1 time.
✓ Branch 13 → 17 taken 5 times.
✓ Branch 14 → 15 taken 1 time.
✗ Branch 14 → 46 not taken.
✗ Branch 15 → 16 not taken.
✓ Branch 15 → 17 taken 1 time.
✗ Branch 18 → 19 not taken.
✓ Branch 18 → 20 taken 6 times.
|
6 | if (!(vi.IsYUV() || vi.IsYUVA()) || !(vi2.IsYUV() || vi2.IsYUVA())) |
| 376 | ✗ | env->ThrowError("MergeLuma: YUV data only (no RGB); use ConvertToYUY2, ConvertToYV12/16/24 or ConvertToYUVxxx"); | |
| 377 | |||
| 378 |
1/2✓ Branch 20 → 21 taken 6 times.
✗ Branch 20 → 46 not taken.
|
6 | pixelsize = vi.ComponentSize(); |
| 379 |
1/2✓ Branch 21 → 22 taken 6 times.
✗ Branch 21 → 46 not taken.
|
6 | bits_per_pixel = vi.BitsPerComponent(); |
| 380 | |||
| 381 |
2/4✓ Branch 22 → 23 taken 6 times.
✗ Branch 22 → 46 not taken.
✗ Branch 23 → 24 not taken.
✓ Branch 23 → 35 taken 6 times.
|
6 | if (!vi.IsSameColorspace(vi2)) { // Since this is luma we allow all planar formats to be merged. |
| 382 | ✗ | if (!(vi.IsPlanar() && vi2.IsPlanar())) { | |
| 383 | ✗ | env->ThrowError("MergeLuma: YUV data is not same type. YUY2 and planar images doesn't mix."); | |
| 384 | } | ||
| 385 | ✗ | if (pixelsize != vi2.ComponentSize()) { | |
| 386 | ✗ | env->ThrowError("MergeLuma: YUV data bit depth is not same."); | |
| 387 | } | ||
| 388 | } | ||
| 389 | |||
| 390 |
2/4✓ Branch 35 → 36 taken 6 times.
✗ Branch 35 → 37 not taken.
✗ Branch 36 → 37 not taken.
✓ Branch 36 → 38 taken 6 times.
|
6 | if (vi.width!=vi2.width || vi.height!=vi2.height) |
| 391 | ✗ | env->ThrowError("MergeLuma: Images must have same width and height!"); | |
| 392 | |||
| 393 |
1/2✗ Branch 38 → 39 not taken.
✓ Branch 38 → 40 taken 6 times.
|
6 | if (weight<0.0f) weight=0.0f; |
| 394 |
1/2✗ Branch 40 → 41 not taken.
✓ Branch 40 → 42 taken 6 times.
|
6 | if (weight>1.0f) weight=1.0f; |
| 395 | |||
| 396 | 6 | } | |
| 397 | |||
| 398 | |||
| 399 | 5 | PVideoFrame __stdcall MergeLuma::GetFrame(int n, IScriptEnvironment* env) | |
| 400 | { | ||
| 401 |
1/2✓ Branch 3 → 4 taken 5 times.
✗ Branch 3 → 206 not taken.
|
5 | PVideoFrame src = child->GetFrame(n, env); |
| 402 | |||
| 403 | // Threshold: for integer clips snap based on the SIMD integer scale (0..32767); | ||
| 404 | // for float clips use exact float comparison. | ||
| 405 |
1/2✓ Branch 4 → 5 taken 5 times.
✗ Branch 4 → 6 not taken.
|
5 | const int weight_i_simd = (bits_per_pixel != 32) ? (int)(weight * 32767.0f + 0.5f) : 0; |
| 406 |
1/2✗ Branch 7 → 8 not taken.
✓ Branch 7 → 9 taken 5 times.
|
5 | const bool weight_is_zero = (bits_per_pixel == 32) ? (weight == 0.0f) : (weight_i_simd == 0); |
| 407 |
1/2✗ Branch 10 → 11 not taken.
✓ Branch 10 → 12 taken 5 times.
|
5 | const bool weight_is_one = (bits_per_pixel == 32) ? (weight == 1.0f) : (weight_i_simd >= 32767); |
| 408 | |||
| 409 |
1/4✗ Branch 13 → 14 not taken.
✓ Branch 13 → 16 taken 5 times.
✗ Branch 14 → 15 not taken.
✗ Branch 14 → 204 not taken.
|
5 | if (weight_is_zero) return src; |
| 410 | |||
| 411 |
1/2✓ Branch 17 → 18 taken 5 times.
✗ Branch 17 → 204 not taken.
|
5 | PVideoFrame luma = clip->GetFrame(n, env); |
| 412 | |||
| 413 |
2/4✓ Branch 18 → 19 taken 5 times.
✗ Branch 18 → 202 not taken.
✗ Branch 19 → 20 not taken.
✓ Branch 19 → 44 taken 5 times.
|
5 | if (vi.IsYUY2()) { |
| 414 | ✗ | env->MakeWritable(&src); | |
| 415 | ✗ | BYTE* srcp = src->GetWritePtr(); | |
| 416 | ✗ | const BYTE* lumap = luma->GetReadPtr(); | |
| 417 | |||
| 418 | ✗ | int isrc_pitch = src->GetPitch(); | |
| 419 | ✗ | int iluma_pitch = luma->GetPitch(); | |
| 420 | |||
| 421 | ✗ | int h = src->GetHeight(); | |
| 422 | ✗ | int w = src->GetRowSize(); | |
| 423 | |||
| 424 | ✗ | if (!weight_is_one) { | |
| 425 | #ifdef INTEL_INTRINSICS | ||
| 426 | ✗ | if (env->GetCPUFlags() & CPUF_SSE2) | |
| 427 | { | ||
| 428 | ✗ | weighted_merge_luma_yuy2_sse2(srcp, lumap, isrc_pitch, iluma_pitch, w, h, (int)(weight * 32768.0f), 32768 - (int)(weight * 32768.0f)); | |
| 429 | } | ||
| 430 | else | ||
| 431 | #ifdef X86_32 | ||
| 432 | if (env->GetCPUFlags() & CPUF_MMX) | ||
| 433 | { | ||
| 434 | weighted_merge_luma_yuy2_mmx(srcp, lumap, isrc_pitch, iluma_pitch, w, h, (int)(weight * 32768.0f), 32768 - (int)(weight * 32768.0f)); | ||
| 435 | } | ||
| 436 | else | ||
| 437 | #endif | ||
| 438 | #endif | ||
| 439 | { | ||
| 440 | ✗ | weighted_merge_luma_yuy2_c(srcp, lumap, isrc_pitch, iluma_pitch, w, h, (int)(weight * 32768.0f), 32768 - (int)(weight * 32768.0f)); | |
| 441 | } | ||
| 442 | } | ||
| 443 | else { | ||
| 444 | #ifdef INTEL_INTRINSICS | ||
| 445 | ✗ | if (env->GetCPUFlags() & CPUF_SSE2) | |
| 446 | { | ||
| 447 | ✗ | replace_luma_yuy2_sse2(srcp, lumap, isrc_pitch, iluma_pitch, w, h); | |
| 448 | } | ||
| 449 | else | ||
| 450 | #ifdef X86_32 | ||
| 451 | if (env->GetCPUFlags() & CPUF_MMX) | ||
| 452 | { | ||
| 453 | replace_luma_yuy2_mmx(srcp, lumap, isrc_pitch, iluma_pitch, w, h); | ||
| 454 | } | ||
| 455 | else | ||
| 456 | #endif | ||
| 457 | #endif | ||
| 458 | { | ||
| 459 | ✗ | replace_luma_yuy2_c(srcp, lumap, isrc_pitch, iluma_pitch, w, h); | |
| 460 | } | ||
| 461 | } | ||
| 462 | ✗ | return src; | |
| 463 | } // Planar | ||
| 464 |
2/2✓ Branch 44 → 45 taken 1 time.
✓ Branch 44 → 179 taken 4 times.
|
5 | if (weight_is_one) { |
| 465 | // 2nd clip weight is 100%: no merge, just copy | ||
| 466 |
1/2✓ Branch 46 → 47 taken 1 time.
✗ Branch 46 → 202 not taken.
|
1 | const VideoInfo& vi2 = clip->GetVideoInfo(); |
| 467 |
3/10✓ Branch 48 → 49 taken 1 time.
✗ Branch 48 → 202 not taken.
✗ Branch 49 → 50 not taken.
✓ Branch 49 → 53 taken 1 time.
✗ Branch 50 → 51 not taken.
✗ Branch 50 → 202 not taken.
✗ Branch 51 → 52 not taken.
✗ Branch 51 → 53 not taken.
✗ Branch 54 → 55 not taken.
✓ Branch 54 → 104 taken 1 time.
|
1 | if (luma->IsWritable() && vi.IsSameColorspace(vi2)) { |
| 468 | ✗ | if (luma->GetRowSize(PLANAR_U)) { | |
| 469 | ✗ | luma->GetWritePtr(PLANAR_Y); //Must be requested BUT only if we actually do something | |
| 470 | ✗ | env->BitBlt(luma->GetWritePtr(PLANAR_U), luma->GetPitch(PLANAR_U), src->GetReadPtr(PLANAR_U), src->GetPitch(PLANAR_U), src->GetRowSize(PLANAR_U), src->GetHeight(PLANAR_U)); | |
| 471 | ✗ | env->BitBlt(luma->GetWritePtr(PLANAR_V), luma->GetPitch(PLANAR_V), src->GetReadPtr(PLANAR_V), src->GetPitch(PLANAR_V), src->GetRowSize(PLANAR_V), src->GetHeight(PLANAR_V)); | |
| 472 | } | ||
| 473 | ✗ | if (luma->GetPitch(PLANAR_A)) // copy Alpha if exists | |
| 474 | ✗ | env->BitBlt(luma->GetWritePtr(PLANAR_A), luma->GetPitch(PLANAR_A), src->GetReadPtr(PLANAR_A), src->GetPitch(PLANAR_A), src->GetRowSize(PLANAR_A), src->GetHeight(PLANAR_A)); | |
| 475 | |||
| 476 | ✗ | return luma; | |
| 477 | } | ||
| 478 | else { // avoid the cost of 2 chroma blits | ||
| 479 |
1/2✓ Branch 104 → 105 taken 1 time.
✗ Branch 104 → 201 not taken.
|
1 | PVideoFrame dst = env->NewVideoFrameP(vi, &luma); |
| 480 | |||
| 481 |
7/14✓ Branch 106 → 107 taken 1 time.
✗ Branch 106 → 199 not taken.
✓ Branch 108 → 109 taken 1 time.
✗ Branch 108 → 199 not taken.
✓ Branch 110 → 111 taken 1 time.
✗ Branch 110 → 199 not taken.
✓ Branch 112 → 113 taken 1 time.
✗ Branch 112 → 199 not taken.
✓ Branch 114 → 115 taken 1 time.
✗ Branch 114 → 199 not taken.
✓ Branch 116 → 117 taken 1 time.
✗ Branch 116 → 199 not taken.
✓ Branch 117 → 118 taken 1 time.
✗ Branch 117 → 199 not taken.
|
1 | env->BitBlt(dst->GetWritePtr(PLANAR_Y), dst->GetPitch(PLANAR_Y), luma->GetReadPtr(PLANAR_Y), luma->GetPitch(PLANAR_Y), luma->GetRowSize(PLANAR_Y), luma->GetHeight(PLANAR_Y)); |
| 482 |
5/10✓ Branch 119 → 120 taken 1 time.
✗ Branch 119 → 199 not taken.
✓ Branch 120 → 121 taken 1 time.
✗ Branch 120 → 125 not taken.
✓ Branch 122 → 123 taken 1 time.
✗ Branch 122 → 199 not taken.
✓ Branch 123 → 124 taken 1 time.
✗ Branch 123 → 125 not taken.
✓ Branch 126 → 127 taken 1 time.
✗ Branch 126 → 153 not taken.
|
1 | if (src->GetRowSize(PLANAR_U) && dst->GetRowSize(PLANAR_U)) { |
| 483 |
7/14✓ Branch 128 → 129 taken 1 time.
✗ Branch 128 → 199 not taken.
✓ Branch 130 → 131 taken 1 time.
✗ Branch 130 → 199 not taken.
✓ Branch 132 → 133 taken 1 time.
✗ Branch 132 → 199 not taken.
✓ Branch 134 → 135 taken 1 time.
✗ Branch 134 → 199 not taken.
✓ Branch 136 → 137 taken 1 time.
✗ Branch 136 → 199 not taken.
✓ Branch 138 → 139 taken 1 time.
✗ Branch 138 → 199 not taken.
✓ Branch 139 → 140 taken 1 time.
✗ Branch 139 → 199 not taken.
|
1 | env->BitBlt(dst->GetWritePtr(PLANAR_U), dst->GetPitch(PLANAR_U), src->GetReadPtr(PLANAR_U), src->GetPitch(PLANAR_U), src->GetRowSize(PLANAR_U), src->GetHeight(PLANAR_U)); |
| 484 |
7/14✓ Branch 141 → 142 taken 1 time.
✗ Branch 141 → 199 not taken.
✓ Branch 143 → 144 taken 1 time.
✗ Branch 143 → 199 not taken.
✓ Branch 145 → 146 taken 1 time.
✗ Branch 145 → 199 not taken.
✓ Branch 147 → 148 taken 1 time.
✗ Branch 147 → 199 not taken.
✓ Branch 149 → 150 taken 1 time.
✗ Branch 149 → 199 not taken.
✓ Branch 151 → 152 taken 1 time.
✗ Branch 151 → 199 not taken.
✓ Branch 152 → 153 taken 1 time.
✗ Branch 152 → 199 not taken.
|
1 | env->BitBlt(dst->GetWritePtr(PLANAR_V), dst->GetPitch(PLANAR_V), src->GetReadPtr(PLANAR_V), src->GetPitch(PLANAR_V), src->GetRowSize(PLANAR_V), src->GetHeight(PLANAR_V)); |
| 485 | } | ||
| 486 |
3/10✓ Branch 154 → 155 taken 1 time.
✗ Branch 154 → 199 not taken.
✗ Branch 155 → 156 not taken.
✓ Branch 155 → 160 taken 1 time.
✗ Branch 157 → 158 not taken.
✗ Branch 157 → 199 not taken.
✗ Branch 158 → 159 not taken.
✗ Branch 158 → 160 not taken.
✗ Branch 161 → 162 not taken.
✓ Branch 161 → 175 taken 1 time.
|
1 | if (dst->GetPitch(PLANAR_A) && src->GetPitch(PLANAR_A)) // copy Alpha if in both clip exists |
| 487 | ✗ | env->BitBlt(dst->GetWritePtr(PLANAR_A), dst->GetPitch(PLANAR_A), src->GetReadPtr(PLANAR_A), src->GetPitch(PLANAR_A), src->GetRowSize(PLANAR_A), src->GetHeight(PLANAR_A)); | |
| 488 | |||
| 489 |
1/2✓ Branch 175 → 176 taken 1 time.
✗ Branch 175 → 199 not taken.
|
1 | return dst; |
| 490 | 1 | } | |
| 491 | } | ||
| 492 | else { // weight < 1.0 (integer scale) | ||
| 493 |
1/2✓ Branch 179 → 180 taken 4 times.
✗ Branch 179 → 202 not taken.
|
4 | env->MakeWritable(&src); |
| 494 |
1/2✓ Branch 181 → 182 taken 4 times.
✗ Branch 181 → 202 not taken.
|
4 | BYTE* srcpY = (BYTE*)src->GetWritePtr(PLANAR_Y); |
| 495 |
1/2✓ Branch 183 → 184 taken 4 times.
✗ Branch 183 → 202 not taken.
|
4 | BYTE* lumapY = (BYTE*)luma->GetReadPtr(PLANAR_Y); |
| 496 |
1/2✓ Branch 185 → 186 taken 4 times.
✗ Branch 185 → 202 not taken.
|
4 | int src_pitch = src->GetPitch(PLANAR_Y); |
| 497 |
1/2✓ Branch 187 → 188 taken 4 times.
✗ Branch 187 → 202 not taken.
|
4 | int luma_pitch = luma->GetPitch(PLANAR_Y); |
| 498 |
1/2✓ Branch 189 → 190 taken 4 times.
✗ Branch 189 → 202 not taken.
|
4 | int src_rowsize = src->GetRowSize(PLANAR_Y); |
| 499 |
1/2✓ Branch 191 → 192 taken 4 times.
✗ Branch 191 → 202 not taken.
|
4 | int src_height = src->GetHeight(PLANAR_Y); |
| 500 | |||
| 501 |
1/2✓ Branch 192 → 193 taken 4 times.
✗ Branch 192 → 202 not taken.
|
4 | merge_plane(srcpY, lumapY, src_pitch, luma_pitch, src_rowsize, src_height, weight, bits_per_pixel, true, env); |
| 502 | } | ||
| 503 | |||
| 504 |
1/2✓ Branch 193 → 194 taken 4 times.
✗ Branch 193 → 202 not taken.
|
4 | return src; |
| 505 | 5 | } | |
| 506 | |||
| 507 | |||
| 508 | ✗ | AVSValue __cdecl MergeLuma::Create(AVSValue args, void* , IScriptEnvironment* env) | |
| 509 | { | ||
| 510 | ✗ | return new MergeLuma(args[0].AsClip(), args[1].AsClip(), (float)args[2].AsFloat(1.0f), env); | |
| 511 | } | ||
| 512 | |||
| 513 | |||
| 514 | /************************* | ||
| 515 | ****** Merge All ***** | ||
| 516 | *************************/ | ||
| 517 | |||
| 518 | |||
| 519 | 7 | MergeAll::MergeAll(PClip _child, PClip _clip, float _weight, IScriptEnvironment* env) | |
| 520 |
3/6✓ Branch 2 → 3 taken 7 times.
✗ Branch 2 → 23 not taken.
✓ Branch 3 → 4 taken 7 times.
✗ Branch 3 → 21 not taken.
✓ Branch 5 → 6 taken 7 times.
✗ Branch 5 → 26 not taken.
|
7 | : GenericVideoFilter(_child), clip(_clip), weight(_weight) |
| 521 | { | ||
| 522 |
1/2✓ Branch 7 → 8 taken 7 times.
✗ Branch 7 → 24 not taken.
|
7 | const VideoInfo& vi2 = clip->GetVideoInfo(); |
| 523 | |||
| 524 |
2/4✓ Branch 8 → 9 taken 7 times.
✗ Branch 8 → 24 not taken.
✗ Branch 9 → 10 not taken.
✓ Branch 9 → 11 taken 7 times.
|
7 | if (!vi.IsSameColorspace(vi2)) |
| 525 | ✗ | env->ThrowError("Merge: Pixel types are not the same. Both must be the same."); | |
| 526 | |||
| 527 |
2/4✓ Branch 11 → 12 taken 7 times.
✗ Branch 11 → 13 not taken.
✗ Branch 12 → 13 not taken.
✓ Branch 12 → 14 taken 7 times.
|
7 | if (vi.width!=vi2.width || vi.height!=vi2.height) |
| 528 | ✗ | env->ThrowError("Merge: Images must have same width and height!"); | |
| 529 | |||
| 530 |
1/2✓ Branch 14 → 15 taken 7 times.
✗ Branch 14 → 24 not taken.
|
7 | pixelsize = vi.ComponentSize(); |
| 531 |
1/2✓ Branch 15 → 16 taken 7 times.
✗ Branch 15 → 24 not taken.
|
7 | bits_per_pixel = vi.BitsPerComponent(); |
| 532 | |||
| 533 |
1/2✗ Branch 16 → 17 not taken.
✓ Branch 16 → 18 taken 7 times.
|
7 | if (weight<0.0f) weight=0.0f; |
| 534 |
1/2✗ Branch 18 → 19 not taken.
✓ Branch 18 → 20 taken 7 times.
|
7 | if (weight>1.0f) weight=1.0f; |
| 535 | 7 | } | |
| 536 | |||
| 537 | |||
| 538 | 6 | PVideoFrame __stdcall MergeAll::GetFrame(int n, IScriptEnvironment* env) | |
| 539 | { | ||
| 540 | // Threshold: for integer clips snap based on the SIMD integer scale (0..32768); | ||
| 541 | // for float clips use exact float comparison. | ||
| 542 |
1/2✓ Branch 2 → 3 taken 6 times.
✗ Branch 2 → 4 not taken.
|
6 | const int weight_i_simd = (bits_per_pixel != 32) ? (int)(weight * 32768.0f + 0.5f) : 0; |
| 543 |
4/6✗ Branch 5 → 6 not taken.
✓ Branch 5 → 7 taken 6 times.
✓ Branch 8 → 9 taken 1 time.
✓ Branch 8 → 12 taken 5 times.
✓ Branch 10 → 11 taken 1 time.
✗ Branch 10 → 74 not taken.
|
6 | if ((bits_per_pixel == 32) ? (weight == 0.0f) : (weight_i_simd == 0)) return child->GetFrame(n, env); |
| 544 |
4/6✗ Branch 12 → 13 not taken.
✓ Branch 12 → 14 taken 5 times.
✓ Branch 15 → 16 taken 1 time.
✓ Branch 15 → 19 taken 4 times.
✓ Branch 17 → 18 taken 1 time.
✗ Branch 17 → 74 not taken.
|
5 | if ((bits_per_pixel == 32) ? (weight == 1.0f) : (weight_i_simd >= 32768)) return clip->GetFrame(n, env); |
| 545 | |||
| 546 |
1/2✓ Branch 20 → 21 taken 4 times.
✗ Branch 20 → 74 not taken.
|
4 | PVideoFrame src = child->GetFrame(n, env); |
| 547 |
1/2✓ Branch 22 → 23 taken 4 times.
✗ Branch 22 → 72 not taken.
|
4 | PVideoFrame src2 = clip->GetFrame(n, env); |
| 548 | |||
| 549 |
1/2✓ Branch 23 → 24 taken 4 times.
✗ Branch 23 → 70 not taken.
|
4 | env->MakeWritable(&src); |
| 550 |
1/2✓ Branch 25 → 26 taken 4 times.
✗ Branch 25 → 70 not taken.
|
4 | BYTE* srcp = src->GetWritePtr(); |
| 551 |
1/2✓ Branch 27 → 28 taken 4 times.
✗ Branch 27 → 70 not taken.
|
4 | const BYTE* srcp2 = src2->GetReadPtr(); |
| 552 | |||
| 553 |
1/2✓ Branch 29 → 30 taken 4 times.
✗ Branch 29 → 70 not taken.
|
4 | const int src_pitch = src->GetPitch(); |
| 554 |
1/2✓ Branch 31 → 32 taken 4 times.
✗ Branch 31 → 70 not taken.
|
4 | const int src_rowsize = src->GetRowSize(); |
| 555 | |||
| 556 |
3/6✓ Branch 33 → 34 taken 4 times.
✗ Branch 33 → 70 not taken.
✓ Branch 35 → 36 taken 4 times.
✗ Branch 35 → 70 not taken.
✓ Branch 36 → 37 taken 4 times.
✗ Branch 36 → 70 not taken.
|
4 | merge_plane(srcp, srcp2, src_pitch, src2->GetPitch(), src_rowsize, src->GetHeight(), weight, bits_per_pixel, true, env); |
| 557 | |||
| 558 |
2/4✓ Branch 37 → 38 taken 4 times.
✗ Branch 37 → 70 not taken.
✓ Branch 38 → 39 taken 4 times.
✗ Branch 38 → 63 not taken.
|
4 | if (vi.IsPlanar()) { |
| 559 | 4 | const int planesYUV[4] = { PLANAR_Y, PLANAR_U, PLANAR_V, PLANAR_A}; | |
| 560 | 4 | const int planesRGB[4] = { PLANAR_G, PLANAR_B, PLANAR_R, PLANAR_A}; | |
| 561 |
5/8✓ Branch 39 → 40 taken 4 times.
✗ Branch 39 → 69 not taken.
✓ Branch 40 → 41 taken 1 time.
✓ Branch 40 → 43 taken 3 times.
✓ Branch 41 → 42 taken 1 time.
✗ Branch 41 → 69 not taken.
✓ Branch 42 → 43 taken 1 time.
✗ Branch 42 → 44 not taken.
|
4 | const int *planes = (vi.IsYUV() || vi.IsYUVA()) ? planesYUV : planesRGB; |
| 562 | // first plane is already processed | ||
| 563 |
3/4✓ Branch 60 → 61 taken 13 times.
✗ Branch 60 → 69 not taken.
✓ Branch 61 → 46 taken 9 times.
✓ Branch 61 → 62 taken 4 times.
|
13 | for (int p = 1; p < vi.NumComponents(); p++) { |
| 564 | 9 | const int plane = planes[p]; | |
| 565 |
7/14✓ Branch 47 → 48 taken 9 times.
✗ Branch 47 → 69 not taken.
✓ Branch 49 → 50 taken 9 times.
✗ Branch 49 → 69 not taken.
✓ Branch 51 → 52 taken 9 times.
✗ Branch 51 → 69 not taken.
✓ Branch 53 → 54 taken 9 times.
✗ Branch 53 → 69 not taken.
✓ Branch 55 → 56 taken 9 times.
✗ Branch 55 → 69 not taken.
✓ Branch 57 → 58 taken 9 times.
✗ Branch 57 → 69 not taken.
✓ Branch 58 → 59 taken 9 times.
✗ Branch 58 → 69 not taken.
|
9 | merge_plane(src->GetWritePtr(plane), src2->GetReadPtr(plane), src->GetPitch(plane), src2->GetPitch(plane), src->GetRowSize(plane), src->GetHeight(plane), weight, bits_per_pixel, true, env); |
| 566 | } | ||
| 567 | } | ||
| 568 | |||
| 569 |
1/2✓ Branch 63 → 64 taken 4 times.
✗ Branch 63 → 70 not taken.
|
4 | return src; |
| 570 | 4 | } | |
| 571 | |||
| 572 | |||
| 573 | ✗ | AVSValue __cdecl MergeAll::Create(AVSValue args, void* , IScriptEnvironment* env) | |
| 574 | { | ||
| 575 | ✗ | return new MergeAll(args[0].AsClip(), args[1].AsClip(), (float)args[2].AsFloat(0.5f), env); | |
| 576 | } | ||
| 577 |