4 * Copyright (C) 2008 Adam Williams <broadcast at earthling dot net>
5 * Copyright (C) 2003-2016 Cinelerra CV contributors
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
28 #include "seltempavg.h"
29 #include "seltempavgwindow.h"
35 REGISTER_PLUGIN(SelTempAvgMain)
38 //////////////////////////////////////////////////////////////////////
39 SelTempAvgConfig::SelTempAvgConfig()
42 method = SelTempAvgConfig::METHOD_SELTEMPAVG;
43 offsetmode = SelTempAvgConfig::OFFSETMODE_RESTARTMARKERSYS;
46 offset_restartmarker_keyframe = 0;
47 offset_fixed_value = -15;
50 avg_threshold_RY = 0; avg_threshold_GU = 0; avg_threshold_BV = 0;
51 std_threshold_RY = 0; std_threshold_GU = 0; std_threshold_BV = 0;
52 mask_RY = 0; mask_GU = 0; mask_BV = 0;
55 void SelTempAvgConfig::copy_from(SelTempAvgConfig *src)
57 this->frames = src->frames;
58 this->method = src->method;
59 this->offsetmode = src->offsetmode;
60 this->paranoid = src->paranoid;
61 this->nosubtract = src->nosubtract;
62 this->offset_restartmarker_keyframe = src->offset_restartmarker_keyframe;
63 this->offset_fixed_value = src->offset_fixed_value;
64 this->gain = src->gain;
65 this->avg_threshold_RY = src->avg_threshold_RY; this->avg_threshold_GU = src->avg_threshold_GU;
66 this->avg_threshold_BV = src->avg_threshold_BV; this->std_threshold_RY = src->std_threshold_RY;
67 this->std_threshold_GU = src->std_threshold_GU; this->std_threshold_BV = src->std_threshold_BV;
69 this->mask_BV = src->mask_BV; this->mask_RY = src->mask_RY; this->mask_GU = src->mask_GU;
72 int SelTempAvgConfig::equivalent(SelTempAvgConfig *src)
74 return frames == src->frames &&
75 method == src->method &&
76 offsetmode == src->offsetmode &&
77 paranoid == src->paranoid &&
78 offset_restartmarker_keyframe == src->offset_restartmarker_keyframe &&
79 offset_fixed_value == src->offset_fixed_value &&
81 this->avg_threshold_RY == src->avg_threshold_RY && this->avg_threshold_GU == src->avg_threshold_GU &&
82 this->avg_threshold_BV == src->avg_threshold_BV && this->std_threshold_RY == src->std_threshold_RY &&
83 this->std_threshold_GU == src->std_threshold_GU && this->std_threshold_BV == src->std_threshold_BV &&
84 this->mask_RY == src->mask_RY && this->mask_GU == src->mask_GU && this->mask_BV == src->mask_BV;
88 //////////////////////////////////////////////////////////////////////
89 SelTempAvgMain::SelTempAvgMain(PluginServer *server)
90 : PluginVClient(server)
96 history_start = -0x7fffffff;
102 SelTempAvgMain::~SelTempAvgMain()
108 delete [] accumulation;
109 delete [] accumulation_sq;
113 for(int i = 0; i < config.frames; i++)
117 if(history_frame) delete [] history_frame;
118 if(history_valid) delete [] history_valid;
121 const char* SelTempAvgMain::plugin_title() { return N_("Selective Temporal Averaging"); }
122 int SelTempAvgMain::is_realtime() { return 1; }
125 NEW_WINDOW_MACRO(SelTempAvgMain, SelTempAvgWindow);
127 int SelTempAvgMain::process_buffer(VFrame *frame,
128 int64_t start_position,
131 int h = frame->get_h();
132 int w = frame->get_w();
133 int color_model = frame->get_color_model();
134 load_configuration();
136 // Allocate accumulation
139 accumulation = new unsigned char[w *
141 BC_CModels::components(color_model) *
144 accumulation_sq = new unsigned char[w *
148 clear_accum(w, h, color_model);
151 if(!config.nosubtract)
153 // Reallocate history
156 if(config.frames != history_size)
159 int64_t *history_frame2;
161 history2 = new VFrame*[config.frames];
162 history_frame2 = new int64_t[config.frames];
163 history_valid2 = new int[config.frames];
165 // Copy existing frames over
167 for(i = 0, j = 0; i < config.frames && j < history_size; i++, j++)
169 history2[i] = history[j];
170 history_frame2[i] = history_frame[i];
171 history_valid2[i] = history_valid[i];
174 // Delete extra previous frames and subtract from accumulation
175 for( ; j < history_size; j++)
177 subtract_accum(history[j]);
181 delete [] history_frame;
182 delete [] history_valid;
186 for( ; i < config.frames; i++)
188 history2[i] = new VFrame(w, h, color_model, 0);
189 history_frame2[i] = -0x7fffffff;
190 history_valid2[i] = 0;
194 history_frame = history_frame2;
195 history_valid = history_valid2;
197 history_size = config.frames;
203 history = new VFrame*[config.frames];
204 for(int i = 0; i < config.frames; i++)
205 history[i] = new VFrame(w, h, color_model, 0);
206 history_size = config.frames;
207 history_frame = new int64_t[config.frames];
208 bzero(history_frame, sizeof(int64_t) * config.frames);
209 history_valid = new int[config.frames];
210 bzero(history_valid, sizeof(int) * config.frames);
218 // Create new history frames based on current frame
219 int64_t *new_history_frames = new int64_t[history_size];
221 int64_t theoffset = (int64_t) config.offset_fixed_value;
222 if (config.offsetmode == SelTempAvgConfig::OFFSETMODE_RESTARTMARKERSYS)
223 theoffset = (int64_t) restartoffset;
225 for(int i = 0; i < history_size; i++)
227 new_history_frames[history_size - i - 1] = start_position + theoffset + i;
230 // Subtract old history frames which are not in the new vector
232 for(int i = 0; i < history_size; i++)
234 // Old frame is valid
238 for(int j = 0; j < history_size; j++)
240 // Old frame is equal to a new frame
241 if(history_frame[i] == new_history_frames[j])
248 // Didn't find old frame in new frames
251 subtract_accum(history[i]);
252 history_valid[i] = 0;
257 // If all frames are still valid, assume tweek occurred upstream and reload.
258 if(config.paranoid && no_change)
260 for(int i = 0; i < history_size; i++)
262 history_valid[i] = 0;
264 clear_accum(w, h, color_model);
267 // Add new history frames which are not in the old vector
268 for(int i = 0; i < history_size; i++)
270 // Find new frame in old vector
272 for(int j = 0; j < history_size; j++)
274 if(history_valid[j] && history_frame[j] == new_history_frames[i])
281 // Didn't find new frame in old vector
284 // Get first unused entry
285 for(int j = 0; j < history_size; j++)
287 if(!history_valid[j])
289 // Load new frame into it
290 history_frame[j] = new_history_frames[i];
291 history_valid[j] = 1;
292 read_frame(history[j],
297 add_accum(history[j]);
303 delete [] new_history_frames;
308 // Force reload if not repositioned or just started
309 if( (config.paranoid && prev_frame == start_position) ||
312 prev_frame = start_position - config.frames + 1;
313 prev_frame = MAX(0, prev_frame);
314 clear_accum(w, h, color_model);
317 for(int64_t i = prev_frame; i <= start_position; i++)
325 //printf("SelTempAvgMain::process_buffer 1 %lld %lld %lld\n", prev_frame, start_position, i);
328 prev_frame = start_position;
333 // Read current frame into buffer (needed for the std-deviation tool)
341 // Transfer accumulation to output with division if average is desired.
342 transfer_accum(frame);
344 //printf("SelTempAvgMain::process_buffer 2\n");
359 // Reset accumulation
360 #define CLEAR_ACCUM(type, components, chroma) \
362 float *row = (float*)accumulation; \
363 float *row_sq = (float*)accumulation_sq; \
366 for(int i = 0; i < w * h; i++) \
371 if(components == 4) *row++ = 0x0; \
379 bzero(row, w * h * sizeof(type) * components); \
380 bzero(row_sq, w * h * 3 * sizeof(float)); \
385 void SelTempAvgMain::clear_accum(int w, int h, int color_model)
390 CLEAR_ACCUM(int, 3, 0x0)
393 CLEAR_ACCUM(float, 3, 0x0)
396 CLEAR_ACCUM(int, 4, 0x0)
399 CLEAR_ACCUM(float, 4, 0x0)
402 CLEAR_ACCUM(int, 3, 0x80)
405 CLEAR_ACCUM(int, 4, 0x80)
408 CLEAR_ACCUM(int, 3, 0x8000)
410 case BC_YUVA16161616:
411 CLEAR_ACCUM(int, 4, 0x8000)
415 #define C2_IS(frame_row,chroma,max) (float)(frame_row)/max
418 #define SUBTRACT_ACCUM(type, \
425 for(int i = 0; i < h; i++) \
427 float *accum_row = (float*)accumulation + \
428 i * w * components; \
429 float *accum_row_sq = (float*)accumulation_sq + \
431 type *frame_row = (type*)frame->get_rows()[i]; \
433 for(int j = 0; j < w; j++) \
435 c1 = ( (float)*frame_row )/max; \
437 c2 = ( (float)*frame_row )/max; \
439 c3 = ( (float)(*frame_row -0) )/max; \
448 if(components == 4) { *accum_row -= ((float)*frame_row++)/max; accum_row++; } \
450 *accum_row_sq++ -= c1*c1; \
451 *accum_row_sq++ -= c2*c2; \
452 *accum_row_sq++ -= c3*c3; \
459 void SelTempAvgMain::subtract_accum(VFrame *frame)
462 if(config.nosubtract) return;
463 int w = frame->get_w();
464 int h = frame->get_h();
466 switch(frame->get_color_model())
469 SUBTRACT_ACCUM(unsigned char, 3, 0x0, 0xff)
472 SUBTRACT_ACCUM(float, 3, 0x0, 1.0)
475 SUBTRACT_ACCUM(unsigned char, 4, 0x0, 0xff)
478 SUBTRACT_ACCUM(float, 4, 0x0, 1.0)
481 SUBTRACT_ACCUM(unsigned char, 3, 0x80, 0xff)
484 SUBTRACT_ACCUM(unsigned char, 4, 0x80, 0xff)
487 SUBTRACT_ACCUM(uint16_t, 3, 0x8000, 0xffff)
489 case BC_YUVA16161616:
490 SUBTRACT_ACCUM(uint16_t, 4, 0x8000, 0xffff)
496 // The behavior has to be very specific to the color model because we rely on
497 // the value of full black to determine what pixel to show.
498 #define ADD_ACCUM(type, components, chroma, max) \
503 for(int i = 0; i < h; i++) \
505 float *accum_row = (float*)accumulation + \
506 i * w * components; \
507 float *accum_row_sq = (float*)accumulation_sq + \
509 type *frame_row = (type*)frame->get_rows()[i]; \
510 for(int j = 0; j < w; j++) \
512 c1 = ( (float)*frame_row )/max; \
514 c2 = ( (float)*frame_row )/max; \
516 c3 = ( (float)*frame_row )/max; \
525 if(components == 4) { *accum_row += ((float)*frame_row++)/max; accum_row++; } \
527 *accum_row_sq++ += c1*c1; \
528 *accum_row_sq++ += c2*c2; \
529 *accum_row_sq++ += c3*c3; \
536 void SelTempAvgMain::add_accum(VFrame *frame)
538 int w = frame->get_w();
539 int h = frame->get_h();
541 switch(frame->get_color_model())
544 ADD_ACCUM(unsigned char, 3, 0x0, 0xff)
547 ADD_ACCUM(float, 3, 0x0, 1.0)
550 ADD_ACCUM(unsigned char, 4, 0x0, 0xff)
553 ADD_ACCUM(float, 4, 0x0, 1.0)
556 ADD_ACCUM(unsigned char, 3, 0x80, 0xff)
559 ADD_ACCUM(unsigned char, 4, 0x80, 0xff)
562 ADD_ACCUM(uint16_t, 3, 0x8000, 0xffff)
564 case BC_YUVA16161616:
565 ADD_ACCUM(uint16_t, 4, 0x8000, 0xffff)
570 #define MASKER(type, avg_thresh, std_thresh, c_now, c_mean, c_stddev, mask, gain, frame_rowp, max) \
572 if ( (avg_thresh > fabs(c_now - c_mean)) && (std_thresh > c_stddev) ) \
576 frame_rowp = (type)(c_mean*max*gain); \
581 frame_rowp = (type)(c_now*max*gain); \
584 #define TRANSFER_ACCUM(type, components, chroma, max, c1_gain, c2_gain, c3_gain) \
586 if(config.method == SelTempAvgConfig::METHOD_SELTEMPAVG) \
588 float denominator = config.frames; \
589 float c1_now, c2_now, c3_now; \
590 float c1_mean, c2_mean, c3_mean; \
591 float c1_stddev, c2_stddev, c3_stddev; \
592 for(int i = 0; i < h; i++) \
594 float *accum_row = (float*)accumulation + i * w * components; \
595 float *accum_row_sq = (float*)accumulation_sq + i * w * 3; \
597 type *frame_row = (type*)frame->get_rows()[i]; \
598 for(int j = 0; j < w; j++) \
600 c1_now = (float)(*frame_row)/max; \
602 c2_now = (float)(*frame_row)/max; \
604 c3_now = (float)(*frame_row)/max; \
607 c1_mean = *accum_row/denominator; \
609 c2_mean = *accum_row/denominator; \
611 c3_mean = *accum_row/denominator; \
613 if(components == 4) { accum_row++; } \
615 c1_stddev = (*accum_row_sq++)/denominator - c1_mean*c1_mean; \
616 c2_stddev = (*accum_row_sq++)/denominator - c2_mean*c2_mean; \
617 c3_stddev = (*accum_row_sq++)/denominator - c3_mean*c3_mean; \
620 config.avg_threshold_RY, \
621 config.std_threshold_RY, \
622 c1_now, c1_mean, c1_stddev, config.mask_RY, c1_gain,\
625 config.avg_threshold_GU, \
626 config.std_threshold_GU, \
627 c2_now, c2_mean, c2_stddev, config.mask_GU, c2_gain,\
630 config.avg_threshold_BV, \
631 config.std_threshold_BV, \
632 c3_now, c3_mean, c3_stddev, config.mask_BV, c3_gain,\
634 if(components == 4) *frame_row++ = max; \
639 if(config.method == SelTempAvgConfig::METHOD_AVERAGE) \
641 float denominator = config.frames; \
642 for(int i = 0; i < h; i++) \
644 float *accum_row = (float*)accumulation + i * w * components; \
645 type *frame_row = (type*)frame->get_rows()[i]; \
646 for(int j = 0; j < w; j++) \
649 *frame_row++ = (type)( (*accum_row++ / denominator)*c1_gain*max ); \
650 *frame_row++ = (type)( (*accum_row++ / denominator)*c2_gain*max ); \
651 *frame_row++ = (type)( (*accum_row++ / denominator)*c3_gain*max ); \
652 if(components == 4) *frame_row++ = (type)((*accum_row++/denominator)*max ); \
657 if(config.method == SelTempAvgConfig::METHOD_STDDEV) \
659 float c1_mean, c2_mean, c3_mean; \
660 float c1_stddev, c2_stddev, c3_stddev; \
661 float denominator = config.frames; \
662 for(int i = 0; i < h; i++) \
664 float *accum_row = (float*)accumulation + i * w * components; \
665 float *accum_row_sq = (float*)accumulation_sq + i * w * 3; \
666 type *frame_row = (type*)frame->get_rows()[i]; \
667 for(int j = 0; j < w; j++) \
670 c1_mean = *accum_row/denominator; \
672 c2_mean = *accum_row/denominator; \
674 c3_mean = *accum_row/denominator; \
676 if(components == 4) { accum_row++; } \
678 c1_stddev = (*accum_row_sq++)/denominator - c1_mean*c1_mean; \
679 c2_stddev = (*accum_row_sq++)/denominator - c2_mean*c2_mean; \
680 c3_stddev = (*accum_row_sq++)/denominator - c3_mean*c3_mean; \
682 *frame_row++ = (type)( c1_stddev*c1_gain*max ); \
683 *frame_row++ = (type)( c2_stddev*c2_gain*max ); \
684 *frame_row++ = (type)( c3_stddev*c3_gain*max ); \
685 if(components == 4) *frame_row++ = max; \
692 void SelTempAvgMain::transfer_accum(VFrame *frame)
694 int w = frame->get_w();
695 int h = frame->get_h();
697 switch(frame->get_color_model())
700 TRANSFER_ACCUM(unsigned char, 3 , 0x0 , 0xff , config.gain, config.gain, config.gain)
703 TRANSFER_ACCUM(float , 3 , 0x0 , 1 , config.gain, config.gain, config.gain)
706 TRANSFER_ACCUM(unsigned char, 4 , 0x0 , 0xff , config.gain, config.gain, config.gain)
709 TRANSFER_ACCUM(float , 4 , 0x0 , 1 , config.gain, config.gain, config.gain)
712 TRANSFER_ACCUM(unsigned char, 3 , 0x80 , 0xff , config.gain, 1.0 , 1.0)
715 TRANSFER_ACCUM(unsigned char, 4 , 0x80 , 0xff , config.gain, 1.0 , 1.0)
718 TRANSFER_ACCUM(uint16_t , 3 , 0x8000, 0xffff, config.gain, 1.0 , 1.0)
720 case BC_YUVA16161616:
721 TRANSFER_ACCUM(uint16_t , 4 , 0x8000, 0xffff, config.gain, 1.0 , 1.0)
728 int SelTempAvgMain::load_configuration()
730 KeyFrame *prev_keyframe;
731 KeyFrame *temp_keyframe;
733 SelTempAvgConfig old_config;
734 old_config.copy_from(&config);
736 int64_t curpos = get_source_position();
737 prev_keyframe = get_prev_keyframe(curpos);
738 read_data(prev_keyframe);
740 if (curpos == prev_keyframe->position)
745 int64_t next_restart_keyframe = curpos + config.frames;
746 int64_t prev_restart_keyframe = curpos - config.frames;
748 for (int i = curpos; i < curpos + config.frames; i++)
750 temp_keyframe = get_next_keyframe(i);
752 (temp_keyframe->position < curpos + config.frames/2) &&
753 (temp_keyframe->position > curpos) &&
754 nextkeyframeisoffsetrestart(temp_keyframe)
757 next_restart_keyframe = temp_keyframe->position;
758 i = curpos + config.frames;
759 } else if (temp_keyframe->position > i)
760 i = temp_keyframe->position;
763 for (int i = curpos; i > curpos - config.frames; i--)
765 temp_keyframe = get_prev_keyframe(i);
767 (temp_keyframe->position > curpos - config.frames/2) &&
768 (temp_keyframe->position < curpos) &&
769 nextkeyframeisoffsetrestart(temp_keyframe)
772 prev_restart_keyframe = temp_keyframe->position;
773 i = curpos - config.frames;
774 } else if (temp_keyframe->position < i)
775 i = temp_keyframe->position;
778 restartoffset = -config.frames/2;
780 if (onakeyframe && config.offset_restartmarker_keyframe)
782 else if ((curpos - prev_restart_keyframe) < config.frames/2)
783 restartoffset = prev_restart_keyframe - curpos;
784 else if ((next_restart_keyframe - curpos) < config.frames/2) {
785 restartoffset = (next_restart_keyframe - curpos) - config.frames;
786 // Probably should put another if in here, (when two "restart" keyframes are close together
789 return !old_config.equivalent(&config);
792 void SelTempAvgMain::save_data(KeyFrame *keyframe)
796 // cause data to be stored directly in text
797 output.set_shared_output(keyframe->xbuf);
798 output.tag.set_title("SELECTIVE_TEMPORAL_AVERAGE");
799 output.tag.set_property("FRAMES", config.frames);
800 output.tag.set_property("METHOD", config.method);
801 output.tag.set_property("OFFSETMODE", config.offsetmode);
802 output.tag.set_property("PARANOID", config.paranoid);
803 output.tag.set_property("NOSUBTRACT", config.nosubtract);
804 output.tag.set_property("OFFSETMODE_RESTARTMODE_KEYFRAME", config.offset_restartmarker_keyframe);
805 output.tag.set_property("OFFSETMODE_FIXED_VALUE", config.offset_fixed_value);
806 output.tag.set_property("GAIN", config.gain);
809 output.tag.set_property("AVG_THRESHOLD_RY", config.avg_threshold_RY);
810 output.tag.set_property("AVG_THRESHOLD_GU", config.avg_threshold_GU);
811 output.tag.set_property("AVG_THRESHOLD_BV", config.avg_threshold_BV);
812 output.tag.set_property("STD_THRESHOLD_RY", config.std_threshold_RY);
813 output.tag.set_property("STD_THRESHOLD_GU", config.std_threshold_GU);
814 output.tag.set_property("STD_THRESHOLD_BV", config.std_threshold_BV);
816 output.tag.set_property("MASK_RY", config.mask_RY);
817 output.tag.set_property("MASK_GU", config.mask_GU);
818 output.tag.set_property("MASK_BV", config.mask_BV);
821 output.tag.set_title("/SELECTIVE_TEMPORAL_AVERAGE");
823 output.append_newline();
824 output.terminate_string();
827 void SelTempAvgMain::read_data(KeyFrame *keyframe)
831 input.set_shared_input(keyframe->xbuf);
833 while(!input.read_tag())
835 if(input.tag.title_is("SELECTIVE_TEMPORAL_AVERAGE"))
837 config.frames = input.tag.get_property("FRAMES", config.frames);
838 config.method = input.tag.get_property("METHOD", config.method);
839 config.offsetmode = input.tag.get_property("OFFSETMODE", config.offsetmode);
840 config.paranoid = input.tag.get_property("PARANOID", config.paranoid);
841 config.nosubtract = input.tag.get_property("NOSUBTRACT", config.nosubtract);
842 config.offset_restartmarker_keyframe = input.tag.get_property("OFFSETMODE_RESTARTMODE_KEYFRAME", config.offset_restartmarker_keyframe);
843 config.offset_fixed_value = input.tag.get_property("OFFSETMODE_FIXED_VALUE", config.offset_fixed_value);
844 config.gain = input.tag.get_property("gain", config.gain);
846 config.avg_threshold_RY = input.tag.get_property("AVG_THRESHOLD_RY", config.avg_threshold_RY);
847 config.avg_threshold_GU = input.tag.get_property("AVG_THRESHOLD_GU", config.avg_threshold_GU);
848 config.avg_threshold_BV = input.tag.get_property("AVG_THRESHOLD_BV", config.avg_threshold_BV);
849 config.std_threshold_RY = input.tag.get_property("STD_THRESHOLD_RY", config.std_threshold_RY);
850 config.std_threshold_GU = input.tag.get_property("STD_THRESHOLD_GU", config.std_threshold_GU);
851 config.std_threshold_BV = input.tag.get_property("STD_THRESHOLD_BV", config.std_threshold_BV);
853 config.mask_RY = input.tag.get_property("MASK_RY", config.mask_RY);
854 config.mask_GU = input.tag.get_property("MASK_GU", config.mask_GU);
855 config.mask_BV = input.tag.get_property("MASK_BV", config.mask_BV);
863 int SelTempAvgMain::nextkeyframeisoffsetrestart(KeyFrame *keyframe)
867 input.set_shared_input(keyframe->xbuf);
869 while(!input.read_tag())
871 if(input.tag.title_is("SELECTIVE_TEMPORAL_AVERAGE"))
873 return(input.tag.get_property("OFFSETMODE_RESTARTMODE_KEYFRAME", config.offset_restartmarker_keyframe));
881 void SelTempAvgMain::update_gui()
885 ((SelTempAvgWindow*)thread->window)->lock_window("SelTempAvgMain::update_gui");
886 if(load_configuration())
888 ((SelTempAvgWindow*)thread->window)->total_frames->update(config.frames);
890 ((SelTempAvgWindow*)thread->window)->method_none->update( config.method == SelTempAvgConfig::METHOD_NONE);
891 ((SelTempAvgWindow*)thread->window)->method_seltempavg->update( config.method == SelTempAvgConfig::METHOD_SELTEMPAVG);
892 ((SelTempAvgWindow*)thread->window)->method_average->update( config.method == SelTempAvgConfig::METHOD_AVERAGE);
893 ((SelTempAvgWindow*)thread->window)->method_stddev->update( config.method == SelTempAvgConfig::METHOD_STDDEV);
895 ((SelTempAvgWindow*)thread->window)->offset_fixed->update( config.offsetmode == SelTempAvgConfig::OFFSETMODE_FIXED);
896 ((SelTempAvgWindow*)thread->window)->offset_restartmarker->update(config.offsetmode == SelTempAvgConfig::OFFSETMODE_RESTARTMARKERSYS);
899 ((SelTempAvgWindow*)thread->window)->paranoid->update(config.paranoid);
900 ((SelTempAvgWindow*)thread->window)->no_subtract->update(config.nosubtract);
902 ((SelTempAvgWindow*)thread->window)->offset_fixed_value->update((int64_t)config.offset_fixed_value);
903 ((SelTempAvgWindow*)thread->window)->gain->update(config.gain);
905 ((SelTempAvgWindow*)thread->window)->avg_threshold_RY->update((float)config.avg_threshold_RY);
906 ((SelTempAvgWindow*)thread->window)->avg_threshold_GU->update((float)config.avg_threshold_GU);
907 ((SelTempAvgWindow*)thread->window)->avg_threshold_BV->update((float)config.avg_threshold_BV);
908 ((SelTempAvgWindow*)thread->window)->std_threshold_RY->update((float)config.std_threshold_RY);
909 ((SelTempAvgWindow*)thread->window)->std_threshold_GU->update((float)config.std_threshold_GU);
910 ((SelTempAvgWindow*)thread->window)->std_threshold_BV->update((float)config.std_threshold_BV);
912 ((SelTempAvgWindow*)thread->window)->mask_RY->update(config.mask_RY);
913 ((SelTempAvgWindow*)thread->window)->mask_GU->update(config.mask_GU);
914 ((SelTempAvgWindow*)thread->window)->mask_BV->update(config.mask_BV);
916 ((SelTempAvgWindow*)thread->window)->offset_restartmarker_pos->update((int64_t)restartoffset);
917 ((SelTempAvgWindow*)thread->window)->offset_restartmarker_keyframe->update((config.offset_restartmarker_keyframe) && (onakeyframe));
918 ((SelTempAvgWindow*)thread->window)->unlock_window();