Patch #34204: [Render Animation] Fails with "Error: Specified sample_fmt is not suppo...
[blender.git] / source / blender / blenkernel / intern / seqmodifier.c
1 /*
2  * ***** BEGIN GPL LICENSE BLOCK *****
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License
6  * as published by the Free Software Foundation; either version 2
7  * of the License, or (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software Foundation,
16  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17  *
18  * The Original Code is Copyright (C) 2012 Blender Foundation.
19  * All rights reserved.
20  *
21  * Contributor(s): Blender Foundation,
22  *                 Sergey Sharybin
23  *
24  * ***** END GPL LICENSE BLOCK *****
25  */
26
27 /** \file blender/blenkernel/intern/seqmodifier.c
28  *  \ingroup bke
29  */
30
31 #include <stddef.h>
32 #include <string.h>
33
34 #include "MEM_guardedalloc.h"
35
36 #include "BLI_listbase.h"
37 #include "BLI_path_util.h"
38 #include "BLI_string.h"
39 #include "BLI_utildefines.h"
40 #include "BLI_math.h"
41
42 #include "DNA_sequence_types.h"
43
44 #include "BKE_colortools.h"
45 #include "BKE_sequencer.h"
46
47 #include "IMB_imbuf.h"
48 #include "IMB_imbuf_types.h"
49
50 static SequenceModifierTypeInfo *modifiersTypes[NUM_SEQUENCE_MODIFIER_TYPES];
51 static int modifierTypesInit = FALSE;
52
53 /*********************** Modifiers *************************/
54
55 typedef void (*modifier_apply_threaded_cb) (int width, int height, unsigned char *rect, float *rect_float,
56                                             unsigned char *mask_rect, float *mask_rect_float, void *data_v);
57
58 typedef struct ModifierInitData {
59         ImBuf *ibuf;
60         ImBuf *mask;
61         void *user_data;
62
63         modifier_apply_threaded_cb apply_callback;
64 } ModifierInitData;
65
66 typedef struct ModifierThread {
67         int width, height;
68
69         unsigned char *rect, *mask_rect;
70         float *rect_float, *mask_rect_float;
71
72         void *user_data;
73
74         modifier_apply_threaded_cb apply_callback;
75 } ModifierThread;
76
77
78 static ImBuf *modifier_mask_get(SequenceModifierData *smd, SeqRenderData context, int cfra, int make_float)
79 {
80         return BKE_sequencer_render_mask_input(context, smd->mask_input_type, smd->mask_sequence, smd->mask_id, cfra, make_float);
81 }
82
83 static void modifier_init_handle(void *handle_v, int start_line, int tot_line, void *init_data_v)
84 {
85         ModifierThread *handle = (ModifierThread *) handle_v;
86         ModifierInitData *init_data = (ModifierInitData *) init_data_v;
87         ImBuf *ibuf = init_data->ibuf;
88         ImBuf *mask = init_data->mask;
89
90         int offset = 4 * start_line * ibuf->x;
91
92         memset(handle, 0, sizeof(ModifierThread));
93
94         handle->width = ibuf->x;
95         handle->height = tot_line;
96         handle->apply_callback = init_data->apply_callback;
97         handle->user_data = init_data->user_data;
98
99         if (ibuf->rect)
100                 handle->rect = (unsigned char *) ibuf->rect + offset;
101
102         if (ibuf->rect_float)
103                 handle->rect_float = ibuf->rect_float + offset;
104
105         if (mask) {
106                 if (mask->rect)
107                         handle->mask_rect = (unsigned char *) mask->rect + offset;
108
109                 if (mask->rect_float)
110                         handle->mask_rect_float = mask->rect_float + offset;
111         }
112         else {
113                 handle->mask_rect = NULL;
114                 handle->mask_rect_float = NULL;
115         }
116 }
117
118 static void *modifier_do_thread(void *thread_data_v)
119 {
120         ModifierThread *td = (ModifierThread *) thread_data_v;
121
122         td->apply_callback(td->width, td->height, td->rect, td->rect_float, td->mask_rect, td->mask_rect_float, td->user_data);
123
124         return NULL;
125 }
126
127 static void modifier_apply_threaded(ImBuf *ibuf, ImBuf *mask, modifier_apply_threaded_cb apply_callback, void *user_data)
128 {
129         ModifierInitData init_data;
130
131         init_data.ibuf = ibuf;
132         init_data.mask = mask;
133         init_data.user_data = user_data;
134
135         init_data.apply_callback = apply_callback;
136
137         IMB_processor_apply_threaded(ibuf->y, sizeof(ModifierThread), &init_data,
138                                      modifier_init_handle, modifier_do_thread);
139 }
140
141 /* **** Color Balance Modifier **** */
142
143 static void colorBalance_init_data(SequenceModifierData *smd)
144 {
145         ColorBalanceModifierData *cbmd = (ColorBalanceModifierData *) smd;
146         int c;
147
148         cbmd->color_multiply = 1.0f;
149
150         for (c = 0; c < 3; c++) {
151                 cbmd->color_balance.lift[c] = 1.0f;
152                 cbmd->color_balance.gamma[c] = 1.0f;
153                 cbmd->color_balance.gain[c] = 1.0f;
154         }
155 }
156
157 static void colorBalance_apply(SequenceModifierData *smd, ImBuf *ibuf, ImBuf *mask)
158 {
159         ColorBalanceModifierData *cbmd = (ColorBalanceModifierData *) smd;
160
161         BKE_sequencer_color_balance_apply(&cbmd->color_balance, ibuf, cbmd->color_multiply, FALSE, mask);
162 }
163
164 static SequenceModifierTypeInfo seqModifier_ColorBalance = {
165         "Color Balance",                   /* name */
166         "ColorBalanceModifierData",        /* struct_name */
167         sizeof(ColorBalanceModifierData),  /* struct_size */
168         colorBalance_init_data,            /* init_data */
169         NULL,                              /* free_data */
170         NULL,                              /* copy_data */
171         colorBalance_apply                 /* apply */
172 };
173
174 /* **** Curves Modifier **** */
175
176 static void curves_init_data(SequenceModifierData *smd)
177 {
178         CurvesModifierData *cmd = (CurvesModifierData *) smd;
179
180         curvemapping_set_defaults(&cmd->curve_mapping, 4, 0.0f, 0.0f, 1.0f, 1.0f);
181 }
182
183 static void curves_free_data(SequenceModifierData *smd)
184 {
185         CurvesModifierData *cmd = (CurvesModifierData *) smd;
186
187         curvemapping_free_data(&cmd->curve_mapping);
188 }
189
190 static void curves_copy_data(SequenceModifierData *target, SequenceModifierData *smd)
191 {
192         CurvesModifierData *cmd = (CurvesModifierData *) smd;
193         CurvesModifierData *cmd_target = (CurvesModifierData *) target;
194
195         curvemapping_copy_data(&cmd_target->curve_mapping, &cmd->curve_mapping);
196 }
197
198 static void curves_apply_threaded(int width, int height, unsigned char *rect, float *rect_float,
199                                   unsigned char *mask_rect, float *mask_rect_float, void *data_v)
200 {
201         CurveMapping *curve_mapping = (CurveMapping *) data_v;
202         int x, y;
203
204         for (y = 0; y < height; y++) {
205                 for (x = 0; x < width; x++) {
206                         int pixel_index = (y * width + x) * 4;
207
208                         if (rect_float) {
209                                 float *pixel = rect_float + pixel_index;
210                                 float result[3];
211
212                                 curvemapping_evaluate_premulRGBF(curve_mapping, result, pixel);
213
214                                 if (mask_rect_float) {
215                                         float *m = mask_rect_float + pixel_index;
216
217                                         pixel[0] = pixel[0] * (1.0f - m[0]) + result[0] * m[0];
218                                         pixel[1] = pixel[1] * (1.0f - m[1]) + result[1] * m[1];
219                                         pixel[2] = pixel[2] * (1.0f - m[2]) + result[2] * m[2];
220                                 }
221                                 else {
222                                         pixel[0] = result[0];
223                                         pixel[1] = result[1];
224                                         pixel[2] = result[2];
225                                 }
226                         }
227                         if (rect) {
228                                 unsigned char *pixel = rect + pixel_index;
229                                 float result[3], tempc[4];
230
231                                 straight_uchar_to_premul_float(tempc, pixel);
232
233                                 curvemapping_evaluate_premulRGBF(curve_mapping, result, tempc);
234
235                                 if (mask_rect) {
236                                         float t[3];
237
238                                         rgb_uchar_to_float(t, mask_rect + pixel_index);
239
240                                         tempc[0] = tempc[0] * (1.0f - t[0]) + result[0] * t[0];
241                                         tempc[1] = tempc[1] * (1.0f - t[1]) + result[1] * t[1];
242                                         tempc[2] = tempc[2] * (1.0f - t[2]) + result[2] * t[2];
243                                 }
244                                 else {
245                                         tempc[0] = result[0];
246                                         tempc[1] = result[1];
247                                         tempc[2] = result[2];
248                                 }
249
250                                 premul_float_to_straight_uchar(pixel, tempc);
251                         }
252                 }
253         }
254 }
255
256 static void curves_apply(struct SequenceModifierData *smd, ImBuf *ibuf, ImBuf *mask)
257 {
258         CurvesModifierData *cmd = (CurvesModifierData *) smd;
259
260         float black[3] = {0.0f, 0.0f, 0.0f};
261         float white[3] = {1.0f, 1.0f, 1.0f};
262
263         curvemapping_initialize(&cmd->curve_mapping);
264
265         curvemapping_premultiply(&cmd->curve_mapping, 0);
266         curvemapping_set_black_white(&cmd->curve_mapping, black, white);
267
268         modifier_apply_threaded(ibuf, mask, curves_apply_threaded, &cmd->curve_mapping);
269
270         curvemapping_premultiply(&cmd->curve_mapping, 1);
271 }
272
273 static SequenceModifierTypeInfo seqModifier_Curves = {
274         "Curves",                    /* name */
275         "CurvesModifierData",        /* struct_name */
276         sizeof(CurvesModifierData),  /* struct_size */
277         curves_init_data,            /* init_data */
278         curves_free_data,            /* free_data */
279         curves_copy_data,            /* copy_data */
280         curves_apply                 /* apply */
281 };
282
283 /* **** Hue Correct Modifier **** */
284
285 static void hue_correct_init_data(SequenceModifierData *smd)
286 {
287         HueCorrectModifierData *hcmd = (HueCorrectModifierData *) smd;
288         int c;
289
290         curvemapping_set_defaults(&hcmd->curve_mapping, 1, 0.0f, 0.0f, 1.0f, 1.0f);
291         hcmd->curve_mapping.preset = CURVE_PRESET_MID9;
292
293         for (c = 0; c < 3; c++) {
294                 CurveMap *cuma = &hcmd->curve_mapping.cm[c];
295
296                 curvemap_reset(cuma, &hcmd->curve_mapping.clipr, hcmd->curve_mapping.preset, CURVEMAP_SLOPE_POSITIVE);
297         }
298
299         /* default to showing Saturation */
300         hcmd->curve_mapping.cur = 1;
301 }
302
303 static void hue_correct_free_data(SequenceModifierData *smd)
304 {
305         HueCorrectModifierData *hcmd = (HueCorrectModifierData *) smd;
306
307         curvemapping_free_data(&hcmd->curve_mapping);
308 }
309
310 static void hue_correct_copy_data(SequenceModifierData *target, SequenceModifierData *smd)
311 {
312         HueCorrectModifierData *hcmd = (HueCorrectModifierData *) smd;
313         HueCorrectModifierData *hcmd_target = (HueCorrectModifierData *) target;
314
315         curvemapping_copy_data(&hcmd_target->curve_mapping, &hcmd->curve_mapping);
316 }
317
318 static void hue_correct_apply_threaded(int width, int height, unsigned char *rect, float *rect_float,
319                                 unsigned char *mask_rect, float *mask_rect_float, void *data_v)
320 {
321         CurveMapping *curve_mapping = (CurveMapping *) data_v;
322         int x, y;
323
324         for (y = 0; y < height; y++) {
325                 for (x = 0; x < width; x++) {
326                         int pixel_index = (y * width + x) * 4;
327                         float pixel[3], result[3], mask[3] = {1.0f, 1.0f, 1.0f};
328                         float hsv[3], f;
329
330                         if (rect_float)
331                                 copy_v3_v3(pixel, rect_float + pixel_index);
332                         else
333                                 rgb_uchar_to_float(pixel, rect + pixel_index);
334
335                         rgb_to_hsv(pixel[0], pixel[1], pixel[2], hsv, hsv + 1, hsv + 2);
336
337                         /* adjust hue, scaling returned default 0.5 up to 1 */
338                         f = curvemapping_evaluateF(curve_mapping, 0, hsv[0]);
339                         hsv[0] += f - 0.5f;
340
341                         /* adjust saturation, scaling returned default 0.5 up to 1 */
342                         f = curvemapping_evaluateF(curve_mapping, 1, hsv[0]);
343                         hsv[1] *= (f * 2.0f);
344
345                         /* adjust value, scaling returned default 0.5 up to 1 */
346                         f = curvemapping_evaluateF(curve_mapping, 2, hsv[0]);
347                         hsv[2] *= (f * 2.f);
348
349                         hsv[0] = hsv[0] - floorf(hsv[0]); /* mod 1.0 */
350                         CLAMP(hsv[1], 0.0f, 1.0f);
351
352                         /* convert back to rgb */
353                         hsv_to_rgb(hsv[0], hsv[1], hsv[2], result, result + 1, result + 2);
354
355                         if (mask_rect_float)
356                                 copy_v3_v3(mask, mask_rect_float + pixel_index);
357                         else if (mask_rect)
358                                 rgb_uchar_to_float(mask, mask_rect + pixel_index);
359
360                         result[0] = pixel[0] * (1.0f - mask[0]) + result[0] * mask[0];
361                         result[1] = pixel[1] * (1.0f - mask[1]) + result[1] * mask[1];
362                         result[2] = pixel[2] * (1.0f - mask[2]) + result[2] * mask[2];
363
364                         if (rect_float)
365                                 copy_v3_v3(rect_float + pixel_index, result);
366                         else
367                                 rgb_float_to_uchar(rect + pixel_index, result);
368                 }
369         }
370 }
371
372 static void hue_correct_apply(struct SequenceModifierData *smd, ImBuf *ibuf, ImBuf *mask)
373 {
374         HueCorrectModifierData *hcmd = (HueCorrectModifierData *) smd;
375
376         curvemapping_initialize(&hcmd->curve_mapping);
377
378         modifier_apply_threaded(ibuf, mask, hue_correct_apply_threaded, &hcmd->curve_mapping);
379 }
380
381 static SequenceModifierTypeInfo seqModifier_HueCorrect = {
382         "Hue Correct",                    /* name */
383         "HueCorrectModifierData",         /* struct_name */
384         sizeof(HueCorrectModifierData),   /* struct_size */
385         hue_correct_init_data,            /* init_data */
386         hue_correct_free_data,            /* free_data */
387         hue_correct_copy_data,            /* copy_data */
388         hue_correct_apply                 /* apply */
389 };
390
391 /* **** Bright/Contrast Modifier **** */
392
393 typedef struct BrightContrastThreadData {
394         float bright;
395         float contrast;
396 } BrightContrastThreadData;
397
398 static void brightcontrast_apply_threaded(int width, int height, unsigned char *rect, float *rect_float,
399                                           unsigned char *mask_rect, float *mask_rect_float, void *data_v)
400 {
401         BrightContrastThreadData *data = (BrightContrastThreadData *) data_v;
402         int x, y;
403
404         float i;
405         int c;
406         float a, b, v;
407         float brightness = data->bright / 100.0f;
408         float contrast = data->contrast;
409         float delta = contrast / 200.0f;
410
411         a = 1.0f - delta * 2.0f;
412         /*
413          * The algorithm is by Werner D. Streidt
414          * (http://visca.com/ffactory/archives/5-99/msg00021.html)
415          * Extracted of OpenCV demhist.c
416          */
417         if (contrast > 0) {
418                 a = 1.0f / a;
419                 b = a * (brightness - delta);
420         }
421         else {
422                 delta *= -1;
423                 b = a * (brightness + delta);
424         }
425
426         for (y = 0; y < height; y++) {
427                 for (x = 0; x < width; x++) {
428                         int pixel_index = (y * width + x) * 4;
429
430                         if (rect) {
431                                 unsigned char *pixel = rect + pixel_index;
432
433                                 for (c = 0; c < 3; c++) {
434                                         i = (float) pixel[c] / 255.0f;
435                                         v = a * i + b;
436
437                                         if (mask_rect) {
438                                                 unsigned char *m = mask_rect + pixel_index;
439                                                 float t = (float) m[c] / 255.0f;
440
441                                                 v = (float) pixel[c] / 255.0f * (1.0f - t) + v * t;
442                                         }
443
444                                         pixel[c] = FTOCHAR(v);
445                                 }
446                         }
447                         else if (rect_float) {
448                                 float *pixel = rect_float + pixel_index;
449
450                                 for (c = 0; c < 3; c++) {
451                                         i = pixel[c];
452                                         v = a * i + b;
453
454                                         if (mask_rect_float) {
455                                                 float *m = mask_rect_float + pixel_index;
456
457                                                 pixel[c] = pixel[c] * (1.0f - m[c]) + v * m[c];
458                                         }
459                                         else
460                                                 pixel[c] = v;
461                                 }
462                         }
463                 }
464         }
465 }
466
467 static void brightcontrast_apply(struct SequenceModifierData *smd, ImBuf *ibuf, ImBuf *mask)
468 {
469         BrightContrastModifierData *bcmd = (BrightContrastModifierData *) smd;
470         BrightContrastThreadData data;
471
472         data.bright = bcmd->bright;
473         data.contrast = bcmd->contrast;
474
475         modifier_apply_threaded(ibuf, mask, brightcontrast_apply_threaded, &data);
476 }
477
478 static SequenceModifierTypeInfo seqModifier_BrightContrast = {
479         "Bright/Contrast",                   /* name */
480         "BrightContrastModifierData",        /* struct_name */
481         sizeof(BrightContrastModifierData),  /* struct_size */
482         NULL,                                /* init_data */
483         NULL,                                /* free_data */
484         NULL,                                /* copy_data */
485         brightcontrast_apply                 /* apply */
486 };
487
488 /*********************** Modifier functions *************************/
489
490 static void sequence_modifier_type_info_init(void)
491 {
492 #define INIT_TYPE(typeName) (modifiersTypes[seqModifierType_##typeName] = &seqModifier_##typeName)
493
494         INIT_TYPE(ColorBalance);
495         INIT_TYPE(Curves);
496         INIT_TYPE(HueCorrect);
497         INIT_TYPE(BrightContrast);
498
499 #undef INIT_TYPE
500 }
501
502 SequenceModifierTypeInfo *BKE_sequence_modifier_type_info_get(int type)
503 {
504         if (!modifierTypesInit) {
505                 sequence_modifier_type_info_init();
506                 modifierTypesInit = TRUE;
507         }
508
509         return modifiersTypes[type];
510 }
511
512 SequenceModifierData *BKE_sequence_modifier_new(Sequence *seq, const char *name, int type)
513 {
514         SequenceModifierData *smd;
515         SequenceModifierTypeInfo *smti = BKE_sequence_modifier_type_info_get(type);
516
517         smd = MEM_callocN(smti->struct_size, "sequence modifier");
518
519         smd->type = type;
520         smd->flag |= SEQUENCE_MODIFIER_EXPANDED;
521
522         if (!name || !name[0])
523                 BLI_strncpy(smd->name, smti->name, sizeof(smd->name));
524         else
525                 BLI_strncpy(smd->name, name, sizeof(smd->name));
526
527         BLI_addtail(&seq->modifiers, smd);
528
529         BKE_sequence_modifier_unique_name(seq, smd);
530
531         if (smti->init_data)
532                 smti->init_data(smd);
533
534         return smd;
535 }
536
537 int BKE_sequence_modifier_remove(Sequence *seq, SequenceModifierData *smd)
538 {
539         if (BLI_findindex(&seq->modifiers, smd) == -1)
540                 return FALSE;
541
542         BLI_remlink(&seq->modifiers, smd);
543         BKE_sequence_modifier_free(smd);
544
545         return TRUE;
546 }
547
548 void BKE_sequence_modifier_clear(Sequence *seq)
549 {
550         SequenceModifierData *smd, *smd_next;
551
552         for (smd = seq->modifiers.first; smd; smd = smd_next) {
553                 smd_next = smd->next;
554                 BKE_sequence_modifier_free(smd);
555         }
556
557         seq->modifiers.first = seq->modifiers.last = NULL;
558 }
559
560 void BKE_sequence_modifier_free(SequenceModifierData *smd)
561 {
562         SequenceModifierTypeInfo *smti = BKE_sequence_modifier_type_info_get(smd->type);
563
564         if (smti && smti->free_data) {
565                 smti->free_data(smd);
566         }
567
568         MEM_freeN(smd);
569 }
570
571 void BKE_sequence_modifier_unique_name(Sequence *seq, SequenceModifierData *smd)
572 {
573         SequenceModifierTypeInfo *smti = BKE_sequence_modifier_type_info_get(smd->type);
574
575         BLI_uniquename(&seq->modifiers, smd, smti->name, '.', offsetof(SequenceModifierData, name), sizeof(smd->name));
576 }
577
578 SequenceModifierData *BKE_sequence_modifier_find_by_name(Sequence *seq, char *name)
579 {
580         return BLI_findstring(&(seq->modifiers), name, offsetof(SequenceModifierData, name));
581 }
582
583 ImBuf *BKE_sequence_modifier_apply_stack(SeqRenderData context, Sequence *seq, ImBuf *ibuf, int cfra)
584 {
585         SequenceModifierData *smd;
586         ImBuf *processed_ibuf = ibuf;
587
588         if (seq->modifiers.first && (seq->flag & SEQ_USE_LINEAR_MODIFIERS)) {
589                 processed_ibuf = IMB_dupImBuf(ibuf);
590                 BKE_sequencer_imbuf_from_sequencer_space(context.scene, processed_ibuf);
591         }
592
593         for (smd = seq->modifiers.first; smd; smd = smd->next) {
594                 SequenceModifierTypeInfo *smti = BKE_sequence_modifier_type_info_get(smd->type);
595
596                 /* could happen if modifier is being removed or not exists in current version of blender */
597                 if (!smti)
598                         continue;
599
600                 /* modifier is muted, do nothing */
601                 if (smd->flag & SEQUENCE_MODIFIER_MUTE)
602                         continue;
603
604                 if (smti->apply) {
605                         ImBuf *mask = modifier_mask_get(smd, context, cfra, ibuf->rect_float != NULL);
606
607                         if (processed_ibuf == ibuf)
608                                 processed_ibuf = IMB_dupImBuf(ibuf);
609
610                         smti->apply(smd, processed_ibuf, mask);
611
612                         if (mask)
613                                 IMB_freeImBuf(mask);
614                 }
615         }
616
617         if (seq->modifiers.first && (seq->flag & SEQ_USE_LINEAR_MODIFIERS)) {
618                 BKE_sequencer_imbuf_to_sequencer_space(context.scene, processed_ibuf, FALSE);
619         }
620
621         return processed_ibuf;
622 }
623
624 void BKE_sequence_modifier_list_copy(Sequence *seqn, Sequence *seq)
625 {
626         SequenceModifierData *smd;
627
628         for (smd = seq->modifiers.first; smd; smd = smd->next) {
629                 SequenceModifierData *smdn;
630                 SequenceModifierTypeInfo *smti = BKE_sequence_modifier_type_info_get(smd->type);
631
632                 smdn = MEM_dupallocN(smd);
633
634                 if (smti && smti->copy_data)
635                         smti->copy_data(smdn, smd);
636
637                 smdn->next = smdn->prev = NULL;
638                 BLI_addtail(&seqn->modifiers, smdn);
639         }
640 }
641
642 int BKE_sequence_supports_modifiers(Sequence *seq)
643 {
644         return !ELEM(seq->type, SEQ_TYPE_SOUND_RAM, SEQ_TYPE_SOUND_HD);
645 }