Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSergey Sharybin <sergey.vfx@gmail.com>2013-03-15 15:59:46 +0400
committerSergey Sharybin <sergey.vfx@gmail.com>2013-03-15 15:59:46 +0400
commit6dc4ea34e44ae77125918ab9eda0fcfe7d9f0b3c (patch)
tree20c04bcd39de1a63b515154789e1a8551e77f082 /source/blender/imbuf/intern/scaling.c
parent0807c976f45f81bc289aa87e1c8cedd07f8245c1 (diff)
Multi-threaded frame calculation for movie clip proxies
This commit implements multi-threaded calculation of frames when building proxies. Both scaling and undistortion steps are now threaded. Frames and proxy resolution are still handled one-by-one, saving files after every single step. So if HDD is not so fast, this commit could have not so much benefit. Internal changes: - Added IMB_scaleImBuf_threaded which scales given image buffer in multiple threads and uses bilinear filtering. - libmv's camera intrinsics now have SetThreads() method which is used to specify how many OpenMP threads to use for buffer distortion/undistortion. And yeah, this code is using OpenMP for threading. - Reshuffled a bit libmv-capi calls and added function BKE_tracking_distortion_set_threads to specify number of threads used by intrinscis.
Diffstat (limited to 'source/blender/imbuf/intern/scaling.c')
-rw-r--r--source/blender/imbuf/intern/scaling.c111
1 files changed, 111 insertions, 0 deletions
diff --git a/source/blender/imbuf/intern/scaling.c b/source/blender/imbuf/intern/scaling.c
index 1050d3f8715..51619e18980 100644
--- a/source/blender/imbuf/intern/scaling.c
+++ b/source/blender/imbuf/intern/scaling.c
@@ -34,6 +34,7 @@
#include "BLI_utildefines.h"
#include "BLI_math_color.h"
+#include "BLI_math_interp.h"
#include "MEM_guardedalloc.h"
#include "imbuf.h"
@@ -1604,3 +1605,113 @@ struct ImBuf *IMB_scalefastImBuf(struct ImBuf *ibuf, unsigned int newx, unsigned
return(ibuf);
}
+/* ******** threaded scaling ******** */
+
+typedef struct ScaleTreadInitData {
+ ImBuf *ibuf;
+
+ unsigned int newx;
+ unsigned int newy;
+
+ unsigned char *byte_buffer;
+ float *float_buffer;
+} ScaleTreadInitData;
+
+typedef struct ScaleThreadData {
+ ImBuf *ibuf;
+
+ unsigned int newx;
+ unsigned int newy;
+
+ int start_line;
+ int tot_line;
+
+ unsigned char *byte_buffer;
+ float *float_buffer;
+} ScaleThreadData;
+
+static void scale_thread_init(void *data_v, int start_line, int tot_line, void *init_data_v)
+{
+ ScaleThreadData *data = (ScaleThreadData *) data_v;
+ ScaleTreadInitData *init_data = (ScaleTreadInitData *) init_data_v;
+
+ data->ibuf = init_data->ibuf;
+
+ data->newx = init_data->newx;
+ data->newy = init_data->newy;
+
+ data->start_line = start_line;
+ data->tot_line = tot_line;
+
+ data->byte_buffer = init_data->byte_buffer;
+ data->float_buffer = init_data->float_buffer;
+}
+
+static void *do_scale_thread(void *data_v)
+{
+ ScaleThreadData *data = (ScaleThreadData *) data_v;
+ ImBuf *ibuf = data->ibuf;
+ int i;
+ float factor_x = (float) ibuf->x / data->newx;
+ float factor_y = (float) ibuf->y / data->newy;
+
+ for (i = 0; i < data->tot_line; i++) {
+ int y = data->start_line + i;
+ int x;
+
+ for (x = 0; x < data->newx; x++) {
+ float u = (float) x * factor_x;
+ float v = (float) y * factor_y;
+ int offset = y * data->newx + x;
+
+ if (data->byte_buffer) {
+ unsigned char *pixel = data->byte_buffer + 4 * offset;
+ BLI_bilinear_interpolation_char((unsigned char *) ibuf->rect, pixel, ibuf->x, ibuf->y, 4, u, v);
+ }
+
+ if (data->float_buffer) {
+ float *pixel = data->float_buffer + ibuf->channels * offset;
+ BLI_bilinear_interpolation_fl(ibuf->rect_float, pixel, ibuf->x, ibuf->y, ibuf->channels, u, v);
+ }
+ }
+ }
+
+ return NULL;
+}
+
+void IMB_scaleImBuf_threaded(ImBuf *ibuf, unsigned int newx, unsigned int newy)
+{
+ ScaleTreadInitData init_data = {0};
+
+ /* prepare initialization data */
+ init_data.ibuf = ibuf;
+
+ init_data.newx = newx;
+ init_data.newy = newy;
+
+ if (ibuf->rect)
+ init_data.byte_buffer = MEM_mallocN(4 * newx * newy * sizeof(char), "threaded scale byte buffer");
+
+ if (ibuf->rect_float)
+ init_data.float_buffer = MEM_mallocN(ibuf->channels * newx * newy * sizeof(float), "threaded scale float buffer");
+
+ /* actual scaling threads */
+ IMB_processor_apply_threaded(newy, sizeof(ScaleThreadData), &init_data,
+ scale_thread_init, do_scale_thread);
+
+ /* alter image buffer */
+ ibuf->x = newx;
+ ibuf->y = newy;
+
+ if (ibuf->rect) {
+ imb_freerectImBuf(ibuf);
+ ibuf->mall |= IB_rect;
+ ibuf->rect = (unsigned int *) init_data.byte_buffer;
+ }
+
+ if (ibuf->rect_float) {
+ imb_freerectfloatImBuf(ibuf);
+ ibuf->mall |= IB_rectfloat;
+ ibuf->rect_float = init_data.float_buffer;
+ }
+}