X-Git-Url: http://git.cinelerra-gg.org/git/?a=blobdiff_plain;f=cinelerra-5.1%2Fplugins%2Fmotion-hv%2Fmotioncache-hv.C;fp=cinelerra-5.1%2Fplugins%2Fmotion-hv%2Fmotioncache-hv.C;h=98722ded06ca58f072a0ec1966b736bf5793249b;hb=9d832a1fff11b11aaa1108c460690ed05e2bdc05;hp=0000000000000000000000000000000000000000;hpb=4fedf98530b3a6ff1ada6d2b9fbbc470e3df300c;p=goodguy%2Fhistory.git diff --git a/cinelerra-5.1/plugins/motion-hv/motioncache-hv.C b/cinelerra-5.1/plugins/motion-hv/motioncache-hv.C new file mode 100644 index 00000000..98722ded --- /dev/null +++ b/cinelerra-5.1/plugins/motion-hv/motioncache-hv.C @@ -0,0 +1,233 @@ +/* + * CINELERRA + * Copyright (C) 2016 Adam Williams + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + + + +// store previously scaled images here for operations +// with multiple motion scans on the same frame. + + +#include "bcsignals.h" +#include "clip.h" +#include "motioncache-hv.h" +#include "mutex.h" +#include +#include "vframe.h" + + +MotionHVCacheItem::MotionHVCacheItem() +{ +} + +MotionHVCacheItem::~MotionHVCacheItem() +{ +//printf("MotionHVCacheItem::~MotionHVCacheItem %d image=%p\n", __LINE__, image); + if(image) + { + delete image; + } +} + + + +MotionHVCache::MotionHVCache() +{ + lock = new Mutex("MotionHVCache::lock"); +} + +MotionHVCache::~MotionHVCache() +{ +//printf("MotionHVCache::~MotionHVCache %d this=%p\n", __LINE__, this); + + delete lock; + clear(); +} + +void MotionHVCache::clear() +{ + images.remove_all_objects(); +} + + + +#define DOWNSAMPLE(type, temp_type, components, max) \ +{ \ + temp_type r; \ + temp_type g; \ + temp_type b; \ + temp_type a; \ + type **in_rows = (type**)src->get_rows(); \ + type **out_rows = (type**)dst->get_rows(); \ + \ + for(int i = 0; i < h; i += downsample) \ + { \ + int y1 = MAX(i, 0); \ + int y2 = MIN(i + downsample, h); \ + \ + \ + for(int j = 0; \ + j < w; \ + j += downsample) \ + { \ + int x1 = MAX(j, 0); \ + int x2 = MIN(j + downsample, w); \ + \ + temp_type scale = (x2 - x1) * (y2 - y1); \ + if(x2 > x1 && y2 > y1) \ + { \ + \ +/* Read in values */ \ + r = 0; \ + g = 0; \ + b = 0; \ + if(components == 4) a = 0; \ + \ + for(int k = y1; k < y2; k++) \ + { \ + type *row = in_rows[k] + x1 * components; \ + for(int l = x1; l < x2; l++) \ + { \ + r += *row++; \ + g += *row++; \ + b += *row++; \ + if(components == 4) a += *row++; \ + } \ + } \ + \ +/* Write average */ \ + r /= scale; \ + g /= scale; \ + b /= scale; \ + if(components == 4) a /= scale; \ + \ + type *row = out_rows[y1 / downsample] + \ + x1 / downsample * components; \ + *row++ = r; \ + *row++ = g; \ + *row++ = b; \ + if(components == 4) *row++ = a; \ + } \ + } \ +/*printf("DOWNSAMPLE 3 %d\n", i);*/ \ + } \ +} + + + + +void MotionHVCache::downsample_frame(VFrame *dst, + VFrame *src, + int downsample) +{ + int h = src->get_h(); + int w = src->get_w(); + +//PRINT_TRACE +//printf("downsample=%d w=%d h=%d dst=%d %d\n", downsample, w, h, dst->get_w(), dst->get_h()); + switch(src->get_color_model()) + { + case BC_RGB888: + DOWNSAMPLE(uint8_t, int64_t, 3, 0xff) + break; + case BC_RGB_FLOAT: + DOWNSAMPLE(float, float, 3, 1.0) + break; + case BC_RGBA8888: + DOWNSAMPLE(uint8_t, int64_t, 4, 0xff) + break; + case BC_RGBA_FLOAT: + DOWNSAMPLE(float, float, 4, 1.0) + break; + case BC_YUV888: + DOWNSAMPLE(uint8_t, int64_t, 3, 0xff) + break; + case BC_YUVA8888: + DOWNSAMPLE(uint8_t, int64_t, 4, 0xff) + break; + } +//PRINT_TRACE +} + +VFrame* MotionHVCache::get_image(int ratio, + int is_previous, + int downsampled_w, + int downsampled_h, + VFrame *src) +{ + lock->lock("MotionHVCache::get_image 1"); + + for(int i = 0; i < images.size(); i++) + { + if(images.get(i)->ratio == ratio && + images.get(i)->is_previous == is_previous) + { + VFrame *result = images.get(i)->image; + lock->unlock(); + return result; + } + } + + +//PRINT_TRACE + VFrame *result = new VFrame(); + result->set_use_shm(0); + result->reallocate(0, + -1, + 0, + 0, + 0, + downsampled_w + 1, + downsampled_h + 1, + src->get_color_model(), + -1); + downsample_frame(result, + src, + ratio); + + + MotionHVCacheItem *item = new MotionHVCacheItem(); + item->image = result; + item->is_previous = is_previous; + item->ratio = ratio; + images.append(item); + + lock->unlock(); + + return result; +} + + + + + + + + + + + + + + + + + + +