OpenShot Library | libopenshot  0.5.0
AnalogTape.h
Go to the documentation of this file.
1 
12 // Copyright (c) 2008-2025 OpenShot Studios, LLC
13 //
14 // SPDX-License-Identifier: LGPL-3.0-or-later
15 
16 #ifndef OPENSHOT_ANALOGTAPE_EFFECT_H
17 #define OPENSHOT_ANALOGTAPE_EFFECT_H
18 
19 #include "../EffectBase.h"
20 #include "../Frame.h"
21 #include "../Json.h"
22 #include "../KeyFrame.h"
23 
24 #include <algorithm>
25 #include <cmath>
26 #include <cstring>
27 #include <cstdint>
28 #include <memory>
29 #include <string>
30 #include <vector>
31 
32 #if defined(__GNUC__) || defined(__clang__)
33 #define OS_RESTRICT __restrict__
34 #else
35 #define OS_RESTRICT
36 #endif
37 
38 namespace openshot {
39 
41 class AnalogTape : public EffectBase {
42 private:
43  void init_effect_details();
44  static inline uint32_t fnv1a_32(const std::string &s) {
45  uint32_t h = 2166136261u;
46  for (unsigned char c : s) {
47  h ^= c;
48  h *= 16777619u;
49  }
50  return h;
51  }
52  static inline uint32_t fnv1a_32(uint32_t h, uint32_t d) {
53  unsigned char bytes[4];
54  bytes[0] = d & 0xFF;
55  bytes[1] = (d >> 8) & 0xFF;
56  bytes[2] = (d >> 16) & 0xFF;
57  bytes[3] = (d >> 24) & 0xFF;
58  for (int i = 0; i < 4; ++i) {
59  h ^= bytes[i];
60  h *= 16777619u;
61  }
62  return h;
63  }
64  static inline float hash01(uint32_t seed, uint32_t a, uint32_t b, uint32_t c) {
65  uint32_t h = fnv1a_32(seed, a);
66  h = fnv1a_32(h, b);
67  h = fnv1a_32(h, c);
68  return h / 4294967295.0f;
69  }
70  static inline float row_density(uint32_t seed, int frame, int y) {
71  int tc = (frame >> 3);
72  int y0 = (y >> 3);
73  float a = (y & 7) / 8.0f;
74  float h0 = hash01(seed, tc, y0, 31);
75  float h1 = hash01(seed, tc, y0 + 1, 31);
76  float m = (1 - a) * h0 + a * h1;
77  return m * m;
78  }
79  static inline void box_blur_row(const float *OS_RESTRICT src,
80  float *OS_RESTRICT dst, int w, int r) {
81  if (r == 0) {
82  std::memcpy(dst, src, w * sizeof(float));
83  return;
84  }
85  const int win = 2 * r + 1;
86  float sum = 0.0f;
87  for (int k = -r; k <= r; ++k)
88  sum += src[std::clamp(k, 0, w - 1)];
89  dst[0] = sum / win;
90  for (int x = 1; x < w; ++x) {
91  int add = std::min(w - 1, x + r);
92  int sub = std::max(0, x - r - 1);
93  sum += src[add] - src[sub];
94  dst[x] = sum / win;
95  }
96  }
97 
98  int last_w = 0, last_h = 0;
99  std::vector<float> Y, U, V, tmpY, tmpU, tmpV, dx;
100 
101 public:
109 
110  AnalogTape();
113  int seed_offset = 0);
114 
115  std::shared_ptr<openshot::Frame>
116  GetFrame(std::shared_ptr<openshot::Frame> frame,
117  int64_t frame_number) override;
118 
119  std::shared_ptr<openshot::Frame> GetFrame(int64_t frame_number) override {
120  return GetFrame(std::make_shared<openshot::Frame>(), frame_number);
121  }
122 
123  // JSON
124  std::string Json() const override;
125  void SetJson(const std::string value) override;
126  Json::Value JsonValue() const override;
127  void SetJsonValue(const Json::Value root) override;
128 
129 std::string PropertiesJSON(int64_t requested_frame) const override;
130 };
131 
132 } // namespace openshot
133 
134 #undef OS_RESTRICT
135 
136 #endif
openshot::EffectBase
This abstract class is the base class, used by all effects in libopenshot.
Definition: EffectBase.h:53
openshot::AnalogTape::PropertiesJSON
std::string PropertiesJSON(int64_t requested_frame) const override
Definition: AnalogTape.cpp:426
openshot::AnalogTape::AnalogTape
AnalogTape()
Definition: AnalogTape.cpp:24
openshot
This namespace is the default namespace for all code in the openshot library.
Definition: Compressor.h:28
openshot::AnalogTape::seed_offset
int seed_offset
seed offset for deterministic randomness
Definition: AnalogTape.h:108
openshot::AnalogTape::GetFrame
std::shared_ptr< openshot::Frame > GetFrame(std::shared_ptr< openshot::Frame > frame, int64_t frame_number) override
This method is required for all derived classes of ClipBase, and returns a modified openshot::Frame o...
openshot::AnalogTape::GetFrame
std::shared_ptr< openshot::Frame > GetFrame(int64_t frame_number) override
This method is required for all derived classes of ClipBase, and returns a new openshot::Frame object...
Definition: AnalogTape.h:119
openshot::AnalogTape::noise
Keyframe noise
grain/dropouts amount
Definition: AnalogTape.h:105
openshot::Keyframe
A Keyframe is a collection of Point instances, which is used to vary a number or property over time.
Definition: KeyFrame.h:53
openshot::AnalogTape::JsonValue
Json::Value JsonValue() const override
Generate Json::Value for this object.
Definition: AnalogTape.cpp:386
openshot::AnalogTape::bleed
Keyframe bleed
color bleed amount
Definition: AnalogTape.h:103
OS_RESTRICT
#define OS_RESTRICT
Definition: AnalogTape.h:35
openshot::AnalogTape::SetJsonValue
void SetJsonValue(const Json::Value root) override
Load Json::Value into this object.
Definition: AnalogTape.cpp:408
openshot::AnalogTape::tracking
Keyframe tracking
tracking wobble amount
Definition: AnalogTape.h:102
openshot::AnalogTape
Analog video tape simulation effect.
Definition: AnalogTape.h:41
openshot::AnalogTape::stripe
Keyframe stripe
bottom tracking stripe strength
Definition: AnalogTape.h:106
openshot::AnalogTape::SetJson
void SetJson(const std::string value) override
Load JSON string into this object.
Definition: AnalogTape.cpp:399
openshot::AnalogTape::staticBands
Keyframe staticBands
burst static band strength
Definition: AnalogTape.h:107
openshot::AnalogTape::Json
std::string Json() const override
Generate JSON string of this object.
Definition: AnalogTape.cpp:384
openshot::AnalogTape::softness
Keyframe softness
luma blur radius
Definition: AnalogTape.h:104