1 #include "temporal-antialias.hpp"
5 framerate_reducer_temporalantialias::framerate_reducer_temporalantialias(double alpha
, uint32_t n
, uint32_t d
)
9 factor
= log(1-exp((1 - alpha
) * lh
))/lh
;
14 tdiv
= 1000000000.0 * d
/ n
;
17 framerate_reducer_temporalantialias::~framerate_reducer_temporalantialias()
19 while(!queue
.empty()) {
20 delete queue
.front().second
;
25 void framerate_reducer_temporalantialias::push(uint64_t ts
, image_frame_rgbx
& f
)
27 if(queue
.empty() && newest
) {
32 queue
.push_back(std::make_pair(ts
, newest
));
35 image_frame_rgbx
& framerate_reducer_temporalantialias::pull(uint64_t ts
)
37 image_frame_rgbx
* result
;
39 return *new image_frame_rgbx(0, 0); //No frame.
41 result
= new image_frame_rgbx(newest
->get_width(), newest
->get_height());
42 size_t frames
= queue
.size();
43 float* weights
= new float[frames
];
44 float* tempframe
= new float[4 * newest
->get_width() * newest
->get_height() + 1];
46 compute_frame_weights(ts
, weights
);
48 //Initialize the temporary frame.
49 for(size_t i
= 0; i
< 4 * newest
->get_width() * newest
->get_height(); i
++)
54 for(std::list
<std::pair
<uint64_t, image_frame_rgbx
*> >::iterator j
= queue
.begin(); j
!= queue
.end();
56 uint8_t* fpx
= j
->second
->get_pixels();
57 for(size_t i
= 0; i
< 4 * newest
->get_width() * newest
->get_height(); i
++)
58 tempframe
[i
] += weights
[k
] * fpx
[i
];
61 //Translate pixels back.
62 uint8_t* px
= result
->get_pixels();
63 for(size_t i
= 0; i
< 4 * newest
->get_width() * newest
->get_height(); i
++) {
66 else if(tempframe
[i
] > 255)
69 px
[i
] = (uint8_t)tempframe
[i
];
72 //Delete all frames from queue except newest (and other temporaries).
76 if(queue
.front().second
== newest
)
78 delete queue
.front().second
;
85 static double integrate_sensitivity(double fraction
, double factor
)
88 return 0.5 * pow(2 * fraction
, factor
);
90 return 1 - 0.5 * pow(2 - 2 * fraction
, factor
);
93 void framerate_reducer_temporalantialias::compute_frame_weights(uint64_t ts
, float* weights
)
96 for(std::list
<std::pair
<uint64_t, image_frame_rgbx
*> >::iterator j
= queue
.begin(); j
!= queue
.end();
98 uint64_t start_ts
= j
->first
;
99 //Note: The first frame needs to be processed as if its timestamp was last_ts.
100 if(j
== queue
.begin())
102 //The end timestamp is timestamp of next frame or ts if there's no next frame yet.
103 std::list
<std::pair
<uint64_t, image_frame_rgbx
*> >::iterator jn
= j
;
105 uint64_t end_ts
= ts
;
106 if(jn
!= queue
.end())
108 double start_fraction
= 1 - (start_ts
- last_ts
) / tdiv
;
109 double end_fraction
= 1 - (end_ts
- last_ts
) / tdiv
;
110 start_fraction
= (start_fraction
< 0) ? 0 : (start_fraction
> 1) ? 1 : start_fraction
;
111 end_fraction
= (end_fraction
< 0) ? 0 : (end_fraction
> 1) ? 1 : end_fraction
;
113 weights
[k
] = integrate_sensitivity(start_fraction
, factor
) - integrate_sensitivity(end_fraction
,
115 //std::cerr << "Weight for subframe #" << k << ": " << weights[k] << "." << std::endl;