|
Blender
V2.59
|
00001 /* 00002 * $Id: sequencer.c 38500 2011-07-19 01:36:59Z campbellbarton $ 00003 * 00004 * ***** BEGIN GPL LICENSE BLOCK ***** 00005 * 00006 * This program is free software; you can redistribute it and/or 00007 * modify it under the terms of the GNU General Public License 00008 * as published by the Free Software Foundation; either version 2 00009 * of the License, or (at your option) any later version. 00010 * 00011 * This program is distributed in the hope that it will be useful, 00012 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00014 * GNU General Public License for more details. 00015 * 00016 * You should have received a copy of the GNU General Public License 00017 * along with this program; if not, write to the Free Software Foundation, 00018 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 00019 * 00020 * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. 00021 * All rights reserved. 00022 * 00023 * Contributor(s): 00024 * - Blender Foundation, 2003-2009 00025 * - Peter Schlaile <peter [at] schlaile [dot] de> 2005/2006 00026 * 00027 * ***** END GPL LICENSE BLOCK ***** 00028 */ 00029 00035 #include <stddef.h> 00036 #include <stdlib.h> 00037 #include <string.h> 00038 #include <math.h> 00039 00040 #include "MEM_guardedalloc.h" 00041 #include "MEM_CacheLimiterC-Api.h" 00042 00043 #include "DNA_sequence_types.h" 00044 #include "DNA_scene_types.h" 00045 #include "DNA_anim_types.h" 00046 #include "DNA_object_types.h" 00047 #include "DNA_sound_types.h" 00048 00049 #include "BLI_math.h" 00050 #include "BLI_fileops.h" 00051 #include "BLI_listbase.h" 00052 #include "BLI_path_util.h" 00053 #include "BLI_string.h" 00054 #include "BLI_threads.h" 00055 #include "BLI_utildefines.h" 00056 00057 #include "BKE_animsys.h" 00058 #include "BKE_global.h" 00059 #include "BKE_image.h" 00060 #include "BKE_main.h" 00061 #include "BKE_sequencer.h" 00062 #include "BKE_fcurve.h" 00063 #include "BKE_scene.h" 00064 #include "RNA_access.h" 00065 #include "BKE_utildefines.h" 00066 00067 #include "RE_pipeline.h" 00068 00069 #include <pthread.h> 00070 00071 #include "IMB_imbuf.h" 00072 #include "IMB_imbuf_types.h" 00073 00074 #include "BKE_context.h" 00075 #include "BKE_sound.h" 00076 00077 #ifdef WITH_AUDASPACE 00078 # include "AUD_C-API.h" 00079 #endif 00080 00081 #ifdef WIN32 00082 #define snprintf _snprintf 00083 #endif 00084 00085 00086 static ImBuf* seq_render_strip_stack( 00087 SeqRenderData context, ListBase *seqbasep, float cfra, int chanshown); 00088 00089 static ImBuf * seq_render_strip( 00090 SeqRenderData context, Sequence * seq, float cfra); 00091 00092 static void seq_free_animdata(Scene *scene, Sequence *seq); 00093 00094 00095 /* **** XXX ******** */ 00096 #define SELECT 1 00097 ListBase seqbase_clipboard; 00098 int seqbase_clipboard_frame; 00099 SequencerDrawView sequencer_view3d_cb= NULL; /* NULL in background mode */ 00100 00101 00102 void printf_strip(Sequence *seq) 00103 { 00104 fprintf(stderr, "name: '%s', len:%d, start:%d, (startofs:%d, endofs:%d), (startstill:%d, endstill:%d), machine:%d, (startdisp:%d, enddisp:%d)\n", 00105 seq->name, seq->len, seq->start, seq->startofs, seq->endofs, seq->startstill, seq->endstill, seq->machine, seq->startdisp, seq->enddisp); 00106 fprintf(stderr, "\tseq_tx_set_final_left: %d %d\n\n", seq_tx_get_final_left(seq, 0), seq_tx_get_final_right(seq, 0)); 00107 } 00108 00109 int seqbase_recursive_apply(ListBase *seqbase, int (*apply_func)(Sequence *seq, void *), void *arg) 00110 { 00111 Sequence *iseq; 00112 for(iseq= seqbase->first; iseq; iseq= iseq->next) { 00113 if(seq_recursive_apply(iseq, apply_func, arg) == -1) 00114 return -1; /* bail out */ 00115 } 00116 return 1; 00117 } 00118 00119 int seq_recursive_apply(Sequence *seq, int (*apply_func)(Sequence *, void *), void *arg) 00120 { 00121 int ret= apply_func(seq, arg); 00122 00123 if(ret == -1) 00124 return -1; /* bail out */ 00125 00126 if(ret && seq->seqbase.first) 00127 ret = seqbase_recursive_apply(&seq->seqbase, apply_func, arg); 00128 00129 return ret; 00130 } 00131 00132 /* ********************************************************************** 00133 alloc / free functions 00134 ********************************************************************** */ 00135 00136 00137 00138 void new_tstripdata(Sequence *seq) 00139 { 00140 if(seq->strip) { 00141 seq->strip->len= seq->len; 00142 } 00143 } 00144 00145 00146 /* free */ 00147 00148 static void free_proxy_seq(Sequence *seq) 00149 { 00150 if (seq->strip && seq->strip->proxy && seq->strip->proxy->anim) { 00151 IMB_free_anim(seq->strip->proxy->anim); 00152 seq->strip->proxy->anim = NULL; 00153 } 00154 } 00155 00156 void seq_free_strip(Strip *strip) 00157 { 00158 strip->us--; 00159 if(strip->us>0) return; 00160 if(strip->us<0) { 00161 printf("error: negative users in strip\n"); 00162 return; 00163 } 00164 00165 if (strip->stripdata) { 00166 MEM_freeN(strip->stripdata); 00167 } 00168 00169 if (strip->proxy) { 00170 if (strip->proxy->anim) { 00171 IMB_free_anim(strip->proxy->anim); 00172 } 00173 00174 MEM_freeN(strip->proxy); 00175 } 00176 if (strip->crop) { 00177 MEM_freeN(strip->crop); 00178 } 00179 if (strip->transform) { 00180 MEM_freeN(strip->transform); 00181 } 00182 if (strip->color_balance) { 00183 MEM_freeN(strip->color_balance); 00184 } 00185 00186 MEM_freeN(strip); 00187 } 00188 00189 void seq_free_sequence(Scene *scene, Sequence *seq) 00190 { 00191 if(seq->strip) seq_free_strip(seq->strip); 00192 00193 if(seq->anim) IMB_free_anim(seq->anim); 00194 00195 if (seq->type & SEQ_EFFECT) { 00196 struct SeqEffectHandle sh = get_sequence_effect(seq); 00197 00198 sh.free(seq); 00199 } 00200 00201 if(seq->sound) { 00202 ((ID *)seq->sound)->us--; 00203 } 00204 00205 /* clipboard has no scene and will never have a sound handle or be active */ 00206 if(scene) { 00207 Editing *ed = scene->ed; 00208 00209 if (ed->act_seq==seq) 00210 ed->act_seq= NULL; 00211 00212 if(seq->scene_sound && ELEM(seq->type, SEQ_SOUND, SEQ_SCENE)) 00213 sound_remove_scene_sound(scene, seq->scene_sound); 00214 00215 seq_free_animdata(scene, seq); 00216 } 00217 00218 MEM_freeN(seq); 00219 } 00220 00221 Editing *seq_give_editing(Scene *scene, int alloc) 00222 { 00223 if (scene->ed == NULL && alloc) { 00224 Editing *ed; 00225 00226 ed= scene->ed= MEM_callocN( sizeof(Editing), "addseq"); 00227 ed->seqbasep= &ed->seqbase; 00228 } 00229 return scene->ed; 00230 } 00231 00232 static void seq_free_clipboard_recursive(Sequence *seq_parent) 00233 { 00234 Sequence *seq, *nseq; 00235 00236 for(seq= seq_parent->seqbase.first; seq; seq= nseq) { 00237 nseq= seq->next; 00238 seq_free_clipboard_recursive(seq); 00239 } 00240 00241 seq_free_sequence(NULL, seq_parent); 00242 } 00243 00244 void seq_free_clipboard(void) 00245 { 00246 Sequence *seq, *nseq; 00247 00248 for(seq= seqbase_clipboard.first; seq; seq= nseq) { 00249 nseq= seq->next; 00250 seq_free_clipboard_recursive(seq); 00251 } 00252 seqbase_clipboard.first= seqbase_clipboard.last= NULL; 00253 } 00254 00255 void seq_free_editing(Scene *scene) 00256 { 00257 Editing *ed = scene->ed; 00258 MetaStack *ms; 00259 Sequence *seq; 00260 00261 if(ed==NULL) 00262 return; 00263 00264 SEQ_BEGIN(ed, seq) { 00265 seq_free_sequence(scene, seq); 00266 } 00267 SEQ_END 00268 00269 while((ms= ed->metastack.first)) { 00270 BLI_remlink(&ed->metastack, ms); 00271 MEM_freeN(ms); 00272 } 00273 00274 MEM_freeN(ed); 00275 } 00276 00277 /* ********************************************************************** 00278 * sequencer pipeline functions 00279 ********************************************************************** */ 00280 00281 SeqRenderData seq_new_render_data( 00282 struct Main * bmain, struct Scene * scene, 00283 int rectx, int recty, int preview_render_size) 00284 { 00285 SeqRenderData rval; 00286 00287 rval.bmain = bmain; 00288 rval.scene = scene; 00289 rval.rectx = rectx; 00290 rval.recty = recty; 00291 rval.preview_render_size = preview_render_size; 00292 rval.motion_blur_samples = 0; 00293 rval.motion_blur_shutter = 0; 00294 00295 return rval; 00296 } 00297 00298 int seq_cmp_render_data(const SeqRenderData * a, const SeqRenderData * b) 00299 { 00300 if (a->preview_render_size < b->preview_render_size) { 00301 return -1; 00302 } 00303 if (a->preview_render_size > b->preview_render_size) { 00304 return 1; 00305 } 00306 00307 if (a->rectx < b->rectx) { 00308 return -1; 00309 } 00310 if (a->rectx > b->rectx) { 00311 return 1; 00312 } 00313 00314 if (a->recty < b->recty) { 00315 return -1; 00316 } 00317 if (a->recty > b->recty) { 00318 return 1; 00319 } 00320 00321 if (a->bmain < b->bmain) { 00322 return -1; 00323 } 00324 if (a->bmain > b->bmain) { 00325 return 1; 00326 } 00327 00328 if (a->scene < b->scene) { 00329 return -1; 00330 } 00331 if (a->scene > b->scene) { 00332 return 1; 00333 } 00334 00335 if (a->motion_blur_shutter < b->motion_blur_shutter) { 00336 return -1; 00337 } 00338 if (a->motion_blur_shutter > b->motion_blur_shutter) { 00339 return 1; 00340 } 00341 00342 if (a->motion_blur_samples < b->motion_blur_samples) { 00343 return -1; 00344 } 00345 if (a->motion_blur_samples > b->motion_blur_samples) { 00346 return 1; 00347 } 00348 00349 return 0; 00350 } 00351 00352 unsigned int seq_hash_render_data(const SeqRenderData * a) 00353 { 00354 unsigned int rval = a->rectx + a->recty; 00355 00356 rval ^= a->preview_render_size; 00357 rval ^= ((intptr_t) a->bmain) << 6; 00358 rval ^= ((intptr_t) a->scene) << 6; 00359 rval ^= (int) (a->motion_blur_shutter * 100.0f) << 10; 00360 rval ^= a->motion_blur_samples << 24; 00361 00362 return rval; 00363 } 00364 00365 /* ************************* iterator ************************** */ 00366 /* *************** (replaces old WHILE_SEQ) ********************* */ 00367 /* **************** use now SEQ_BEGIN() SEQ_END ***************** */ 00368 00369 /* sequence strip iterator: 00370 * - builds a full array, recursively into meta strips */ 00371 00372 static void seq_count(ListBase *seqbase, int *tot) 00373 { 00374 Sequence *seq; 00375 00376 for(seq=seqbase->first; seq; seq=seq->next) { 00377 (*tot)++; 00378 00379 if(seq->seqbase.first) 00380 seq_count(&seq->seqbase, tot); 00381 } 00382 } 00383 00384 static void seq_build_array(ListBase *seqbase, Sequence ***array, int depth) 00385 { 00386 Sequence *seq; 00387 00388 for(seq=seqbase->first; seq; seq=seq->next) { 00389 seq->depth= depth; 00390 00391 if(seq->seqbase.first) 00392 seq_build_array(&seq->seqbase, array, depth+1); 00393 00394 **array= seq; 00395 (*array)++; 00396 } 00397 } 00398 00399 void seq_array(Editing *ed, Sequence ***seqarray, int *tot, int use_pointer) 00400 { 00401 Sequence **array; 00402 00403 *seqarray= NULL; 00404 *tot= 0; 00405 00406 if(ed == NULL) 00407 return; 00408 00409 if(use_pointer) 00410 seq_count(ed->seqbasep, tot); 00411 else 00412 seq_count(&ed->seqbase, tot); 00413 00414 if(*tot == 0) 00415 return; 00416 00417 *seqarray= array= MEM_mallocN(sizeof(Sequence *)*(*tot), "SeqArray"); 00418 if(use_pointer) 00419 seq_build_array(ed->seqbasep, &array, 0); 00420 else 00421 seq_build_array(&ed->seqbase, &array, 0); 00422 } 00423 00424 void seq_begin(Editing *ed, SeqIterator *iter, int use_pointer) 00425 { 00426 memset(iter, 0, sizeof(*iter)); 00427 seq_array(ed, &iter->array, &iter->tot, use_pointer); 00428 00429 if(iter->tot) { 00430 iter->cur= 0; 00431 iter->seq= iter->array[iter->cur]; 00432 iter->valid= 1; 00433 } 00434 } 00435 00436 void seq_next(SeqIterator *iter) 00437 { 00438 if(++iter->cur < iter->tot) 00439 iter->seq= iter->array[iter->cur]; 00440 else 00441 iter->valid= 0; 00442 } 00443 00444 void seq_end(SeqIterator *iter) 00445 { 00446 if(iter->array) 00447 MEM_freeN(iter->array); 00448 00449 iter->valid= 0; 00450 } 00451 00452 /* 00453 ********************************************************************** 00454 * build_seqar 00455 ********************************************************************** 00456 * Build a complete array of _all_ sequencies (including those 00457 * in metastrips!) 00458 ********************************************************************** 00459 */ 00460 00461 static void do_seq_count_cb(ListBase *seqbase, int *totseq, 00462 int (*test_func)(Sequence * seq)) 00463 { 00464 Sequence *seq; 00465 00466 seq= seqbase->first; 00467 while(seq) { 00468 int test = test_func(seq); 00469 if (test & BUILD_SEQAR_COUNT_CURRENT) { 00470 (*totseq)++; 00471 } 00472 if(seq->seqbase.first && (test & BUILD_SEQAR_COUNT_CHILDREN)) { 00473 do_seq_count_cb(&seq->seqbase, totseq, test_func); 00474 } 00475 seq= seq->next; 00476 } 00477 } 00478 00479 static void do_build_seqar_cb(ListBase *seqbase, Sequence ***seqar, int depth, 00480 int (*test_func)(Sequence * seq)) 00481 { 00482 Sequence *seq; 00483 00484 seq= seqbase->first; 00485 while(seq) { 00486 int test = test_func(seq); 00487 seq->depth= depth; 00488 00489 if(seq->seqbase.first && (test & BUILD_SEQAR_COUNT_CHILDREN)) { 00490 do_build_seqar_cb(&seq->seqbase, seqar, depth+1, test_func); 00491 } 00492 if (test & BUILD_SEQAR_COUNT_CURRENT) { 00493 **seqar= seq; 00494 (*seqar)++; 00495 } 00496 seq= seq->next; 00497 } 00498 } 00499 00500 void build_seqar_cb(ListBase *seqbase, Sequence ***seqar, int *totseq, 00501 int (*test_func)(Sequence * seq)) 00502 { 00503 Sequence **tseqar; 00504 00505 *totseq= 0; 00506 do_seq_count_cb(seqbase, totseq, test_func); 00507 00508 if(*totseq==0) { 00509 *seqar= NULL; 00510 return; 00511 } 00512 *seqar= MEM_mallocN(sizeof(void *)* *totseq, "seqar"); 00513 tseqar= *seqar; 00514 00515 do_build_seqar_cb(seqbase, seqar, 0, test_func); 00516 *seqar= tseqar; 00517 } 00518 00519 00520 void calc_sequence_disp(Scene *scene, Sequence *seq) 00521 { 00522 if(seq->startofs && seq->startstill) seq->startstill= 0; 00523 if(seq->endofs && seq->endstill) seq->endstill= 0; 00524 00525 seq->startdisp= seq->start + seq->startofs - seq->startstill; 00526 seq->enddisp= seq->start+seq->len - seq->endofs + seq->endstill; 00527 00528 seq->handsize= 10.0; /* 10 frames */ 00529 if( seq->enddisp-seq->startdisp < 10 ) { 00530 seq->handsize= (float)(0.5*(seq->enddisp-seq->startdisp)); 00531 } 00532 else if(seq->enddisp-seq->startdisp > 250) { 00533 seq->handsize= (float)((seq->enddisp-seq->startdisp)/25); 00534 } 00535 00536 seq_update_sound(scene, seq); 00537 } 00538 00539 static void seq_update_sound_bounds_recursive(Scene *scene, Sequence *metaseq) 00540 { 00541 Sequence *seq; 00542 00543 /* for sound we go over full meta tree to update bounds of the sound strips, 00544 since sound is played outside of evaluating the imbufs, */ 00545 for(seq=metaseq->seqbase.first; seq; seq=seq->next) { 00546 if(seq->type == SEQ_META) { 00547 seq_update_sound_bounds_recursive(scene, seq); 00548 } 00549 else if(ELEM(seq->type, SEQ_SOUND, SEQ_SCENE)) { 00550 if(seq->scene_sound) { 00551 int startofs = seq->startofs; 00552 int endofs = seq->endofs; 00553 if(seq->startofs + seq->start < metaseq->start + metaseq->startofs) 00554 startofs = metaseq->start + metaseq->startofs - seq->start; 00555 00556 if(seq->start + seq->len - seq->endofs > metaseq->start + metaseq->len - metaseq->endofs) 00557 endofs = seq->start + seq->len - metaseq->start - metaseq->len + metaseq->endofs; 00558 sound_move_scene_sound(scene, seq->scene_sound, seq->start + startofs, seq->start+seq->len - endofs, startofs); 00559 } 00560 } 00561 } 00562 } 00563 00564 void calc_sequence(Scene *scene, Sequence *seq) 00565 { 00566 Sequence *seqm; 00567 int min, max; 00568 00569 /* check all metas recursively */ 00570 seqm= seq->seqbase.first; 00571 while(seqm) { 00572 if(seqm->seqbase.first) calc_sequence(scene, seqm); 00573 seqm= seqm->next; 00574 } 00575 00576 /* effects and meta: automatic start and end */ 00577 00578 if(seq->type & SEQ_EFFECT) { 00579 /* pointers */ 00580 if(seq->seq2==NULL) seq->seq2= seq->seq1; 00581 if(seq->seq3==NULL) seq->seq3= seq->seq1; 00582 00583 /* effecten go from seq1 -> seq2: test */ 00584 00585 /* we take the largest start and smallest end */ 00586 00587 // seq->start= seq->startdisp= MAX2(seq->seq1->startdisp, seq->seq2->startdisp); 00588 // seq->enddisp= MIN2(seq->seq1->enddisp, seq->seq2->enddisp); 00589 00590 if (seq->seq1) { 00591 seq->start= seq->startdisp= MAX3(seq->seq1->startdisp, seq->seq2->startdisp, seq->seq3->startdisp); 00592 seq->enddisp= MIN3(seq->seq1->enddisp, seq->seq2->enddisp, seq->seq3->enddisp); 00593 /* we cant help if strips don't overlap, it wont give useful results. 00594 * but at least ensure 'len' is never negative which causes bad bugs elsewhere. */ 00595 if(seq->enddisp < seq->startdisp) { 00596 /* simple start/end swap */ 00597 seq->start= seq->enddisp; 00598 seq->enddisp = seq->startdisp; 00599 seq->startdisp= seq->start; 00600 seq->flag |= SEQ_INVALID_EFFECT; 00601 } 00602 else { 00603 seq->flag &= ~SEQ_INVALID_EFFECT; 00604 } 00605 00606 seq->len= seq->enddisp - seq->startdisp; 00607 } 00608 else { 00609 calc_sequence_disp(scene, seq); 00610 } 00611 00612 if(seq->strip && seq->len!=seq->strip->len) { 00613 new_tstripdata(seq); 00614 } 00615 00616 } 00617 else { 00618 if(seq->type==SEQ_META) { 00619 seqm= seq->seqbase.first; 00620 if(seqm) { 00621 min= MAXFRAME * 2; 00622 max= -MAXFRAME * 2; 00623 while(seqm) { 00624 if(seqm->startdisp < min) min= seqm->startdisp; 00625 if(seqm->enddisp > max) max= seqm->enddisp; 00626 seqm= seqm->next; 00627 } 00628 seq->start= min + seq->anim_startofs; 00629 seq->len = max-min; 00630 seq->len -= seq->anim_startofs; 00631 seq->len -= seq->anim_endofs; 00632 00633 if(seq->strip && seq->len!=seq->strip->len) { 00634 new_tstripdata(seq); 00635 } 00636 } 00637 seq_update_sound_bounds_recursive(scene, seq); 00638 } 00639 calc_sequence_disp(scene, seq); 00640 } 00641 } 00642 00643 /* note: caller should run calc_sequence(scene, seq) after */ 00644 void reload_sequence_new_file(Scene *scene, Sequence * seq, int lock_range) 00645 { 00646 char str[FILE_MAXDIR+FILE_MAXFILE]; 00647 int prev_startdisp=0, prev_enddisp=0; 00648 /* note: dont rename the strip, will break animation curves */ 00649 00650 if (ELEM5(seq->type, SEQ_MOVIE, SEQ_IMAGE, SEQ_SOUND, SEQ_SCENE, SEQ_META)==0) { 00651 return; 00652 } 00653 00654 if(lock_range) { 00655 /* keep so we dont have to move the actual start and end points (only the data) */ 00656 calc_sequence_disp(scene, seq); 00657 prev_startdisp= seq->startdisp; 00658 prev_enddisp= seq->enddisp; 00659 } 00660 00661 00662 new_tstripdata(seq); 00663 00664 if (ELEM3(seq->type, SEQ_SCENE, SEQ_META, SEQ_IMAGE)==0) { 00665 BLI_join_dirfile(str, sizeof(str), seq->strip->dir, seq->strip->stripdata->name); 00666 BLI_path_abs(str, G.main->name); 00667 } 00668 00669 switch(seq->type) { 00670 case SEQ_IMAGE: 00671 { 00672 /* Hack? */ 00673 size_t olen = MEM_allocN_len(seq->strip->stripdata)/sizeof(struct StripElem); 00674 00675 seq->len = olen; 00676 seq->len -= seq->anim_startofs; 00677 seq->len -= seq->anim_endofs; 00678 if (seq->len < 0) { 00679 seq->len = 0; 00680 } 00681 seq->strip->len = seq->len; 00682 break; 00683 } 00684 case SEQ_MOVIE: 00685 if(seq->anim) IMB_free_anim(seq->anim); 00686 seq->anim = openanim(str, IB_rect | ((seq->flag & SEQ_FILTERY) ? IB_animdeinterlace : 0)); 00687 00688 if (!seq->anim) { 00689 return; 00690 } 00691 00692 seq->len = IMB_anim_get_duration(seq->anim); 00693 00694 seq->anim_preseek = IMB_anim_get_preseek(seq->anim); 00695 00696 seq->len -= seq->anim_startofs; 00697 seq->len -= seq->anim_endofs; 00698 if (seq->len < 0) { 00699 seq->len = 0; 00700 } 00701 seq->strip->len = seq->len; 00702 case SEQ_SOUND: 00703 #ifdef WITH_AUDASPACE 00704 if(!seq->sound) 00705 return; 00706 seq->len = ceil(AUD_getInfo(seq->sound->playback_handle).length * FPS); 00707 seq->len -= seq->anim_startofs; 00708 seq->len -= seq->anim_endofs; 00709 if (seq->len < 0) { 00710 seq->len = 0; 00711 } 00712 seq->strip->len = seq->len; 00713 #else 00714 return; 00715 #endif 00716 break; 00717 case SEQ_SCENE: 00718 { 00719 /* 'seq->scenenr' should be replaced with something more reliable */ 00720 Scene * sce = G.main->scene.first; 00721 int nr = 1; 00722 00723 while(sce) { 00724 if(nr == seq->scenenr) { 00725 break; 00726 } 00727 nr++; 00728 sce= sce->id.next; 00729 } 00730 00731 if (sce) { 00732 seq->scene = sce; 00733 } 00734 00735 seq->len= seq->scene->r.efra - seq->scene->r.sfra + 1; 00736 seq->len -= seq->anim_startofs; 00737 seq->len -= seq->anim_endofs; 00738 if (seq->len < 0) { 00739 seq->len = 0; 00740 } 00741 seq->strip->len = seq->len; 00742 break; 00743 } 00744 } 00745 00746 free_proxy_seq(seq); 00747 00748 if(lock_range) { 00749 seq_tx_set_final_left(seq, prev_startdisp); 00750 seq_tx_set_final_right(seq, prev_enddisp); 00751 seq_single_fix(seq); 00752 } 00753 00754 calc_sequence(scene, seq); 00755 } 00756 00757 void sort_seq(Scene *scene) 00758 { 00759 /* all strips together per kind, and in order of y location ("machine") */ 00760 ListBase seqbase, effbase; 00761 Editing *ed= seq_give_editing(scene, FALSE); 00762 Sequence *seq, *seqt; 00763 00764 00765 if(ed==NULL) return; 00766 00767 seqbase.first= seqbase.last= NULL; 00768 effbase.first= effbase.last= NULL; 00769 00770 while( (seq= ed->seqbasep->first) ) { 00771 BLI_remlink(ed->seqbasep, seq); 00772 00773 if(seq->type & SEQ_EFFECT) { 00774 seqt= effbase.first; 00775 while(seqt) { 00776 if(seqt->machine>=seq->machine) { 00777 BLI_insertlinkbefore(&effbase, seqt, seq); 00778 break; 00779 } 00780 seqt= seqt->next; 00781 } 00782 if(seqt==NULL) BLI_addtail(&effbase, seq); 00783 } 00784 else { 00785 seqt= seqbase.first; 00786 while(seqt) { 00787 if(seqt->machine>=seq->machine) { 00788 BLI_insertlinkbefore(&seqbase, seqt, seq); 00789 break; 00790 } 00791 seqt= seqt->next; 00792 } 00793 if(seqt==NULL) BLI_addtail(&seqbase, seq); 00794 } 00795 } 00796 00797 BLI_movelisttolist(&seqbase, &effbase); 00798 *(ed->seqbasep)= seqbase; 00799 } 00800 00801 00802 static int clear_scene_in_allseqs_cb(Sequence *seq, void *arg_pt) 00803 { 00804 if(seq->scene==(Scene *)arg_pt) 00805 seq->scene= NULL; 00806 return 1; 00807 } 00808 00809 void clear_scene_in_allseqs(Main *bmain, Scene *scene) 00810 { 00811 Scene *scene_iter; 00812 00813 /* when a scene is deleted: test all seqs */ 00814 for(scene_iter= bmain->scene.first; scene_iter; scene_iter= scene_iter->id.next) { 00815 if(scene_iter != scene && scene_iter->ed) { 00816 seqbase_recursive_apply(&scene_iter->ed->seqbase, clear_scene_in_allseqs_cb, scene); 00817 } 00818 } 00819 } 00820 00821 typedef struct SeqUniqueInfo { 00822 Sequence *seq; 00823 char name_src[32]; 00824 char name_dest[32]; 00825 int count; 00826 int match; 00827 } SeqUniqueInfo; 00828 00829 /* 00830 static void seqbase_unique_name(ListBase *seqbasep, Sequence *seq) 00831 { 00832 BLI_uniquename(seqbasep, seq, "Sequence", '.', offsetof(Sequence, name), SEQ_NAME_MAXSTR); 00833 }*/ 00834 00835 static void seqbase_unique_name(ListBase *seqbasep, SeqUniqueInfo *sui) 00836 { 00837 Sequence *seq; 00838 for(seq=seqbasep->first; seq; seq= seq->next) { 00839 if (sui->seq != seq && strcmp(sui->name_dest, seq->name+2)==0) { 00840 sprintf(sui->name_dest, "%.17s.%03d", sui->name_src, sui->count++); /*24 - 2 for prefix, -1 for \0 */ 00841 sui->match= 1; /* be sure to re-scan */ 00842 } 00843 } 00844 } 00845 00846 static int seqbase_unique_name_recursive_cb(Sequence *seq, void *arg_pt) 00847 { 00848 if(seq->seqbase.first) 00849 seqbase_unique_name(&seq->seqbase, (SeqUniqueInfo *)arg_pt); 00850 return 1; 00851 } 00852 00853 void seqbase_unique_name_recursive(ListBase *seqbasep, struct Sequence *seq) 00854 { 00855 SeqUniqueInfo sui; 00856 char *dot; 00857 sui.seq= seq; 00858 strcpy(sui.name_src, seq->name+2); 00859 strcpy(sui.name_dest, seq->name+2); 00860 00861 sui.count= 1; 00862 sui.match= 1; /* assume the worst to start the loop */ 00863 00864 /* Strip off the suffix */ 00865 if ((dot=strrchr(sui.name_src, '.'))) { 00866 *dot= '\0'; 00867 dot++; 00868 00869 if(*dot) 00870 sui.count= atoi(dot) + 1; 00871 } 00872 00873 while(sui.match) { 00874 sui.match= 0; 00875 seqbase_unique_name(seqbasep, &sui); 00876 seqbase_recursive_apply(seqbasep, seqbase_unique_name_recursive_cb, &sui); 00877 } 00878 00879 strcpy(seq->name+2, sui.name_dest); 00880 } 00881 00882 static const char *give_seqname_by_type(int type) 00883 { 00884 switch(type) { 00885 case SEQ_META: return "Meta"; 00886 case SEQ_IMAGE: return "Image"; 00887 case SEQ_SCENE: return "Scene"; 00888 case SEQ_MOVIE: return "Movie"; 00889 case SEQ_SOUND: return "Audio"; 00890 case SEQ_CROSS: return "Cross"; 00891 case SEQ_GAMCROSS: return "Gamma Cross"; 00892 case SEQ_ADD: return "Add"; 00893 case SEQ_SUB: return "Sub"; 00894 case SEQ_MUL: return "Mul"; 00895 case SEQ_ALPHAOVER: return "Alpha Over"; 00896 case SEQ_ALPHAUNDER: return "Alpha Under"; 00897 case SEQ_OVERDROP: return "Over Drop"; 00898 case SEQ_WIPE: return "Wipe"; 00899 case SEQ_GLOW: return "Glow"; 00900 case SEQ_TRANSFORM: return "Transform"; 00901 case SEQ_COLOR: return "Color"; 00902 case SEQ_MULTICAM: return "Multicam"; 00903 case SEQ_ADJUSTMENT: return "Adjustment"; 00904 case SEQ_SPEED: return "Speed"; 00905 default: 00906 return NULL; 00907 } 00908 } 00909 00910 const char *give_seqname(Sequence *seq) 00911 { 00912 const char *name = give_seqname_by_type(seq->type); 00913 00914 if (!name) { 00915 if(seq->type<SEQ_EFFECT) { 00916 return seq->strip->dir; 00917 } else if(seq->type==SEQ_PLUGIN) { 00918 if(!(seq->flag & SEQ_EFFECT_NOT_LOADED) && 00919 seq->plugin && seq->plugin->doit) { 00920 return seq->plugin->pname; 00921 } else { 00922 return "Plugin"; 00923 } 00924 } else { 00925 return "Effect"; 00926 } 00927 } 00928 return name; 00929 } 00930 00931 /* ***************** DO THE SEQUENCE ***************** */ 00932 00933 static void make_black_ibuf(ImBuf *ibuf) 00934 { 00935 unsigned int *rect; 00936 float *rect_float; 00937 int tot; 00938 00939 if(ibuf==NULL || (ibuf->rect==NULL && ibuf->rect_float==NULL)) return; 00940 00941 tot= ibuf->x*ibuf->y; 00942 00943 rect= ibuf->rect; 00944 rect_float = ibuf->rect_float; 00945 00946 if (rect) { 00947 memset(rect, 0, tot * sizeof(char) * 4); 00948 } 00949 00950 if (rect_float) { 00951 memset(rect_float, 0, tot * sizeof(float) * 4); 00952 } 00953 } 00954 00955 static void multibuf(ImBuf *ibuf, float fmul) 00956 { 00957 char *rt; 00958 float *rt_float; 00959 00960 int a, mul, icol; 00961 00962 mul= (int)(256.0f * fmul); 00963 rt= (char *)ibuf->rect; 00964 rt_float = ibuf->rect_float; 00965 00966 if (rt) { 00967 a= ibuf->x*ibuf->y; 00968 while(a--) { 00969 00970 icol= (mul*rt[0])>>8; 00971 if(icol>254) rt[0]= 255; else rt[0]= icol; 00972 icol= (mul*rt[1])>>8; 00973 if(icol>254) rt[1]= 255; else rt[1]= icol; 00974 icol= (mul*rt[2])>>8; 00975 if(icol>254) rt[2]= 255; else rt[2]= icol; 00976 icol= (mul*rt[3])>>8; 00977 if(icol>254) rt[3]= 255; else rt[3]= icol; 00978 00979 rt+= 4; 00980 } 00981 } 00982 if (rt_float) { 00983 a= ibuf->x*ibuf->y; 00984 while(a--) { 00985 rt_float[0] *= fmul; 00986 rt_float[1] *= fmul; 00987 rt_float[2] *= fmul; 00988 rt_float[3] *= fmul; 00989 00990 rt_float += 4; 00991 } 00992 } 00993 } 00994 00995 static float give_stripelem_index(Sequence *seq, float cfra) 00996 { 00997 float nr; 00998 int sta = seq->start; 00999 int end = seq->start+seq->len-1; 01000 01001 if (seq->type & SEQ_EFFECT) { 01002 end = seq->enddisp; 01003 } 01004 01005 if(end < sta) { 01006 return -1; 01007 } 01008 01009 if(seq->flag&SEQ_REVERSE_FRAMES) { 01010 /*reverse frame in this sequence */ 01011 if(cfra <= sta) nr= end - sta; 01012 else if(cfra >= end) nr= 0; 01013 else nr= end - cfra; 01014 } else { 01015 if(cfra <= sta) nr= 0; 01016 else if(cfra >= end) nr= end - sta; 01017 else nr= cfra - sta; 01018 } 01019 01020 if (seq->strobe < 1.0f) seq->strobe = 1.0f; 01021 01022 if (seq->strobe > 1.0f) { 01023 nr -= fmodf((double)nr, (double)seq->strobe); 01024 } 01025 01026 return nr; 01027 } 01028 01029 StripElem *give_stripelem(Sequence *seq, int cfra) 01030 { 01031 StripElem *se= seq->strip->stripdata; 01032 01033 if(seq->type == SEQ_IMAGE) { /* only 01034 IMAGE strips use the whole array, 01035 MOVIE strips use only 01036 the first element, all other strips 01037 don't use this... */ 01038 int nr = (int) give_stripelem_index(seq, cfra); 01039 01040 if (nr == -1 || se == NULL) return NULL; 01041 01042 se += nr + seq->anim_startofs; 01043 } 01044 return se; 01045 } 01046 01047 static int evaluate_seq_frame_gen(Sequence ** seq_arr, ListBase *seqbase, int cfra) 01048 { 01049 Sequence *seq; 01050 int totseq=0; 01051 01052 memset(seq_arr, 0, sizeof(Sequence*) * (MAXSEQ+1)); 01053 01054 seq= seqbase->first; 01055 while(seq) { 01056 if(seq->startdisp <=cfra && seq->enddisp > cfra) { 01057 seq_arr[seq->machine]= seq; 01058 totseq++; 01059 } 01060 seq= seq->next; 01061 } 01062 01063 return totseq; 01064 } 01065 01066 int evaluate_seq_frame(Scene *scene, int cfra) 01067 { 01068 Editing *ed= seq_give_editing(scene, FALSE); 01069 Sequence *seq_arr[MAXSEQ+1]; 01070 01071 if(ed==NULL) return 0; 01072 return evaluate_seq_frame_gen(seq_arr, ed->seqbasep, cfra); 01073 } 01074 01075 static int video_seq_is_rendered(Sequence * seq) 01076 { 01077 return (seq && !(seq->flag & SEQ_MUTE) && seq->type != SEQ_SOUND); 01078 } 01079 01080 static int get_shown_sequences( ListBase * seqbasep, int cfra, int chanshown, Sequence ** seq_arr_out) 01081 { 01082 Sequence *seq_arr[MAXSEQ+1]; 01083 int b = chanshown; 01084 int cnt = 0; 01085 01086 if (b > MAXSEQ) { 01087 return 0; 01088 } 01089 01090 if(evaluate_seq_frame_gen(seq_arr, seqbasep, cfra)) { 01091 if (b == 0) { 01092 b = MAXSEQ; 01093 } 01094 for (; b > 0; b--) { 01095 if (video_seq_is_rendered(seq_arr[b])) { 01096 break; 01097 } 01098 } 01099 } 01100 01101 chanshown = b; 01102 01103 for (;b > 0; b--) { 01104 if (video_seq_is_rendered(seq_arr[b])) { 01105 if (seq_arr[b]->blend_mode == SEQ_BLEND_REPLACE) { 01106 break; 01107 } 01108 } 01109 } 01110 01111 for (;b <= chanshown && b >= 0; b++) { 01112 if (video_seq_is_rendered(seq_arr[b])) { 01113 seq_arr_out[cnt++] = seq_arr[b]; 01114 } 01115 } 01116 01117 return cnt; 01118 } 01119 01120 01121 /* ********************************************************************** 01122 proxy management 01123 ********************************************************************** */ 01124 01125 #define PROXY_MAXFILE (2*FILE_MAXDIR+FILE_MAXFILE) 01126 01127 static int seq_proxy_get_fname(SeqRenderData context, Sequence * seq, int cfra, char * name) 01128 { 01129 int frameno; 01130 char dir[FILE_MAXDIR]; 01131 01132 if (!seq->strip->proxy) { 01133 return FALSE; 01134 } 01135 01136 if (seq->flag & (SEQ_USE_PROXY_CUSTOM_DIR|SEQ_USE_PROXY_CUSTOM_FILE)) { 01137 strcpy(dir, seq->strip->proxy->dir); 01138 } else { 01139 if (ELEM(seq->type, SEQ_IMAGE, SEQ_MOVIE)) { 01140 snprintf(dir, FILE_MAXDIR, "%s/BL_proxy", seq->strip->dir); 01141 } else { 01142 return FALSE; 01143 } 01144 } 01145 01146 if (seq->flag & SEQ_USE_PROXY_CUSTOM_FILE) { 01147 BLI_join_dirfile(name, FILE_MAX, dir, seq->strip->proxy->file); /* XXX, not real length */ 01148 BLI_path_abs(name, G.main->name); 01149 01150 return TRUE; 01151 } 01152 01153 /* generate a separate proxy directory for each preview size */ 01154 01155 switch(seq->type) { 01156 case SEQ_IMAGE: 01157 snprintf(name, PROXY_MAXFILE, "%s/images/%d/%s_proxy", dir, 01158 context.preview_render_size, 01159 give_stripelem(seq, cfra)->name); 01160 frameno = 1; 01161 break; 01162 case SEQ_MOVIE: 01163 frameno = (int) give_stripelem_index(seq, cfra) + seq->anim_startofs; 01164 snprintf(name, PROXY_MAXFILE, "%s/%s/%d/####", dir, 01165 seq->strip->stripdata->name, context.preview_render_size); 01166 break; 01167 default: 01168 frameno = (int) give_stripelem_index(seq, cfra) + seq->anim_startofs; 01169 snprintf(name, PROXY_MAXFILE, "%s/proxy_misc/%d/####", dir, 01170 context.preview_render_size); 01171 } 01172 01173 BLI_path_abs(name, G.main->name); 01174 BLI_path_frame(name, frameno, 0); 01175 01176 strcat(name, ".jpg"); 01177 01178 return TRUE; 01179 } 01180 01181 static struct ImBuf * seq_proxy_fetch(SeqRenderData context, Sequence * seq, int cfra) 01182 { 01183 char name[PROXY_MAXFILE]; 01184 01185 if (!(seq->flag & SEQ_USE_PROXY)) { 01186 return NULL; 01187 } 01188 01189 /* rendering at 100% ? No real sense in proxy-ing, right? */ 01190 if (context.preview_render_size == 100) { 01191 return NULL; 01192 } 01193 01194 if (seq->flag & SEQ_USE_PROXY_CUSTOM_FILE) { 01195 int frameno = (int) give_stripelem_index(seq, cfra) + seq->anim_startofs; 01196 if (seq->strip->proxy->anim == NULL) { 01197 if (seq_proxy_get_fname(context, seq, cfra, name)==0) { 01198 return NULL; 01199 } 01200 01201 seq->strip->proxy->anim = openanim(name, IB_rect); 01202 } 01203 if (seq->strip->proxy->anim==NULL) { 01204 return NULL; 01205 } 01206 01207 return IMB_anim_absolute(seq->strip->proxy->anim, frameno); 01208 } 01209 01210 if (seq_proxy_get_fname(context, seq, cfra, name) == 0) { 01211 return NULL; 01212 } 01213 01214 if (BLI_exists(name)) { 01215 return IMB_loadiffname(name, IB_rect); 01216 } else { 01217 return NULL; 01218 } 01219 } 01220 01221 #if 0 01222 static void do_build_seq_ibuf(Scene *scene, Sequence * seq, TStripElem *se, int cfra, 01223 int build_proxy_run, int preview_render_size); 01224 01225 static void seq_proxy_build_frame(Scene *scene, Sequence * seq, int cfra, int preview_render_size, int seqrectx, int seqrecty) 01226 { 01227 char name[PROXY_MAXFILE]; 01228 int quality; 01229 TStripElem * se; 01230 int ok; 01231 int rectx, recty; 01232 struct ImBuf * ibuf; 01233 01234 if (!(seq->flag & SEQ_USE_PROXY)) { 01235 return; 01236 } 01237 01238 /* rendering at 100% ? No real sense in proxy-ing, right? */ 01239 if (preview_render_size == 100) { 01240 return; 01241 } 01242 01243 /* that's why it is called custom... */ 01244 if (seq->flag & SEQ_USE_PROXY_CUSTOM_FILE) { 01245 return; 01246 } 01247 01248 if (!seq_proxy_get_fname(scene, seq, cfra, name, preview_render_size)) { 01249 return; 01250 } 01251 01252 se = give_tstripelem(seq, cfra); 01253 if (!se) { 01254 return; 01255 } 01256 01257 if(se->ibuf) { 01258 IMB_freeImBuf(se->ibuf); 01259 se->ibuf = 0; 01260 } 01261 01262 do_build_seq_ibuf(scene, seq, se, cfra, TRUE, preview_render_size, 01263 seqrectx, seqrecty); 01264 01265 if (!se->ibuf) { 01266 return; 01267 } 01268 01269 rectx= (preview_render_size*scene->r.xsch)/100; 01270 recty= (preview_render_size*scene->r.ysch)/100; 01271 01272 ibuf = se->ibuf; 01273 01274 if (ibuf->x != rectx || ibuf->y != recty) { 01275 IMB_scalefastImBuf(ibuf, (short)rectx, (short)recty); 01276 } 01277 01278 /* quality is fixed, otherwise one has to generate separate 01279 directories for every quality... 01280 01281 depth = 32 is intentionally left in, otherwise ALPHA channels 01282 won't work... */ 01283 quality = seq->strip->proxy->quality; 01284 ibuf->ftype= JPG | quality; 01285 01286 BLI_make_existing_file(name); 01287 01288 ok = IMB_saveiff(ibuf, name, IB_rect | IB_zbuf | IB_zbuffloat); 01289 if (ok == 0) { 01290 perror(name); 01291 } 01292 01293 IMB_freeImBuf(ibuf); 01294 se->ibuf = 0; 01295 } 01296 01297 static void seq_proxy_rebuild(Scene *scene, Sequence * seq, int seqrectx, 01298 int seqrecty) 01299 { 01300 int cfra; 01301 float rsize = seq->strip->proxy->size; 01302 01303 waitcursor(1); 01304 01305 G.afbreek = 0; 01306 01307 /* flag management tries to account for strobe and 01308 other "non-linearities", that might come in the future... 01309 better way would be to "touch" the files, so that _really_ 01310 no one is rebuild twice. 01311 */ 01312 01313 for (cfra = seq->startdisp; cfra < seq->enddisp; cfra++) { 01314 TStripElem * tse = give_tstripelem(seq, cfra); 01315 01316 tse->flag &= ~STRIPELEM_PREVIEW_DONE; 01317 } 01318 01319 01320 01321 /* a _lot_ faster for movie files, if we read frames in 01322 sequential order */ 01323 if (seq->flag & SEQ_REVERSE_FRAMES) { 01324 for (cfra = seq->enddisp-seq->endstill-1; 01325 cfra >= seq->startdisp + seq->startstill; cfra--) { 01326 TStripElem * tse = give_tstripelem(seq, cfra); 01327 01328 if (!(tse->flag & STRIPELEM_PREVIEW_DONE)) { 01329 //XXX set_timecursor(cfra); 01330 seq_proxy_build_frame(scene, seq, cfra, rsize, 01331 seqrectx, seqrecty); 01332 tse->flag |= STRIPELEM_PREVIEW_DONE; 01333 } 01334 if (blender_test_break()) { 01335 break; 01336 } 01337 } 01338 } else { 01339 for (cfra = seq->startdisp + seq->startstill; 01340 cfra < seq->enddisp - seq->endstill; cfra++) { 01341 TStripElem * tse = give_tstripelem(seq, cfra); 01342 01343 if (!(tse->flag & STRIPELEM_PREVIEW_DONE)) { 01344 //XXX set_timecursor(cfra); 01345 seq_proxy_build_frame(scene, seq, cfra, rsize, 01346 seqrectx, seqrecty); 01347 tse->flag |= STRIPELEM_PREVIEW_DONE; 01348 } 01349 if (blender_test_break()) { 01350 break; 01351 } 01352 } 01353 } 01354 waitcursor(0); 01355 } 01356 #endif 01357 01358 01359 /* ********************************************************************** 01360 color balance 01361 ********************************************************************** */ 01362 01363 static StripColorBalance calc_cb(StripColorBalance * cb_) 01364 { 01365 StripColorBalance cb = *cb_; 01366 int c; 01367 01368 for (c = 0; c < 3; c++) { 01369 cb.lift[c] = 2.0f - cb.lift[c]; 01370 } 01371 01372 if(cb.flag & SEQ_COLOR_BALANCE_INVERSE_LIFT) { 01373 for (c = 0; c < 3; c++) { 01374 /* tweak to give more subtle results 01375 * values above 1.0 are scaled */ 01376 if(cb.lift[c] > 1.0f) 01377 cb.lift[c] = pow(cb.lift[c] - 1.0f, 2.0) + 1.0; 01378 01379 cb.lift[c] = 2.0f - cb.lift[c]; 01380 } 01381 } 01382 01383 if (cb.flag & SEQ_COLOR_BALANCE_INVERSE_GAIN) { 01384 for (c = 0; c < 3; c++) { 01385 if (cb.gain[c] != 0.0f) { 01386 cb.gain[c] = 1.0f / cb.gain[c]; 01387 } else { 01388 cb.gain[c] = 1000000; /* should be enough :) */ 01389 } 01390 } 01391 } 01392 01393 if (!(cb.flag & SEQ_COLOR_BALANCE_INVERSE_GAMMA)) { 01394 for (c = 0; c < 3; c++) { 01395 if (cb.gamma[c] != 0.0f) { 01396 cb.gamma[c] = 1.0f/cb.gamma[c]; 01397 } else { 01398 cb.gamma[c] = 1000000; /* should be enough :) */ 01399 } 01400 } 01401 } 01402 01403 return cb; 01404 } 01405 01406 /* note: lift is actually 2-lift */ 01407 MINLINE float color_balance_fl(float in, const float lift, const float gain, const float gamma, const float mul) 01408 { 01409 float x= (((in - 1.0f) * lift) + 1.0f) * gain; 01410 01411 /* prevent NaN */ 01412 if (x < 0.f) x = 0.f; 01413 01414 return powf(x, gamma) * mul; 01415 } 01416 01417 static void make_cb_table_byte(float lift, float gain, float gamma, 01418 unsigned char * table, float mul) 01419 { 01420 int y; 01421 01422 for (y = 0; y < 256; y++) { 01423 float v= color_balance_fl((float)y * (1.0f / 255.0f), lift, gain, gamma, mul); 01424 CLAMP(v, 0.0f, 1.0f); 01425 table[y] = v * 255; 01426 } 01427 } 01428 01429 static void make_cb_table_float(float lift, float gain, float gamma, 01430 float * table, float mul) 01431 { 01432 int y; 01433 01434 for (y = 0; y < 256; y++) { 01435 float v= color_balance_fl((float)y * (1.0f / 255.0f), lift, gain, gamma, mul); 01436 table[y] = v; 01437 } 01438 } 01439 01440 static void color_balance_byte_byte(Sequence * seq, ImBuf* ibuf, float mul) 01441 { 01442 unsigned char cb_tab[3][256]; 01443 int c; 01444 unsigned char * p = (unsigned char*) ibuf->rect; 01445 unsigned char * e = p + ibuf->x * 4 * ibuf->y; 01446 01447 StripColorBalance cb = calc_cb(seq->strip->color_balance); 01448 01449 for (c = 0; c < 3; c++) { 01450 make_cb_table_byte(cb.lift[c], cb.gain[c], cb.gamma[c], 01451 cb_tab[c], mul); 01452 } 01453 01454 while (p < e) { 01455 p[0] = cb_tab[0][p[0]]; 01456 p[1] = cb_tab[1][p[1]]; 01457 p[2] = cb_tab[2][p[2]]; 01458 01459 p += 4; 01460 } 01461 } 01462 01463 static void color_balance_byte_float(Sequence * seq, ImBuf* ibuf, float mul) 01464 { 01465 float cb_tab[4][256]; 01466 int c,i; 01467 unsigned char * p = (unsigned char*) ibuf->rect; 01468 unsigned char * e = p + ibuf->x * 4 * ibuf->y; 01469 float * o; 01470 StripColorBalance cb; 01471 01472 imb_addrectfloatImBuf(ibuf); 01473 01474 o = ibuf->rect_float; 01475 01476 cb = calc_cb(seq->strip->color_balance); 01477 01478 for (c = 0; c < 3; c++) { 01479 make_cb_table_float(cb.lift[c], cb.gain[c], cb.gamma[c], cb_tab[c], mul); 01480 } 01481 01482 for (i = 0; i < 256; i++) { 01483 cb_tab[3][i] = ((float)i)*(1.0f/255.0f); 01484 } 01485 01486 while (p < e) { 01487 o[0] = cb_tab[0][p[0]]; 01488 o[1] = cb_tab[1][p[1]]; 01489 o[2] = cb_tab[2][p[2]]; 01490 o[3] = cb_tab[3][p[3]]; 01491 01492 p += 4; o += 4; 01493 } 01494 } 01495 01496 static void color_balance_float_float(Sequence * seq, ImBuf* ibuf, float mul) 01497 { 01498 float * p = ibuf->rect_float; 01499 float * e = ibuf->rect_float + ibuf->x * 4* ibuf->y; 01500 StripColorBalance cb = calc_cb(seq->strip->color_balance); 01501 01502 while (p < e) { 01503 int c; 01504 for (c = 0; c < 3; c++) { 01505 p[c]= color_balance_fl(p[c], cb.lift[c], cb.gain[c], cb.gamma[c], mul); 01506 } 01507 p += 4; 01508 } 01509 } 01510 01511 static void color_balance(Sequence * seq, ImBuf* ibuf, float mul) 01512 { 01513 if (ibuf->rect_float) { 01514 color_balance_float_float(seq, ibuf, mul); 01515 } else if(seq->flag & SEQ_MAKE_FLOAT) { 01516 color_balance_byte_float(seq, ibuf, mul); 01517 } else { 01518 color_balance_byte_byte(seq, ibuf, mul); 01519 } 01520 } 01521 01522 /* 01523 input preprocessing for SEQ_IMAGE, SEQ_MOVIE and SEQ_SCENE 01524 01525 Do all the things you can't really do afterwards using sequence effects 01526 (read: before rescaling to render resolution has been done) 01527 01528 Order is important! 01529 01530 - Deinterlace 01531 - Crop and transform in image source coordinate space 01532 - Flip X + Flip Y (could be done afterwards, backward compatibility) 01533 - Promote image to float data (affects pipeline operations afterwards) 01534 - Color balance (is most efficient in the byte -> float 01535 (future: half -> float should also work fine!) 01536 case, if done on load, since we can use lookup tables) 01537 - Premultiply 01538 01539 */ 01540 01541 int input_have_to_preprocess( 01542 SeqRenderData UNUSED(context), Sequence * seq, float UNUSED(cfra)) 01543 { 01544 float mul; 01545 01546 if (seq->flag & (SEQ_FILTERY|SEQ_USE_CROP|SEQ_USE_TRANSFORM|SEQ_FLIPX| 01547 SEQ_FLIPY|SEQ_USE_COLOR_BALANCE|SEQ_MAKE_PREMUL)) { 01548 return TRUE; 01549 } 01550 01551 mul = seq->mul; 01552 01553 if(seq->blend_mode == SEQ_BLEND_REPLACE) { 01554 mul *= seq->blend_opacity / 100.0f; 01555 } 01556 01557 if (mul != 1.0f) { 01558 return TRUE; 01559 } 01560 01561 if (seq->sat != 1.0f) { 01562 return TRUE; 01563 } 01564 01565 return FALSE; 01566 } 01567 01568 static ImBuf * input_preprocess( 01569 SeqRenderData context, Sequence *seq, float UNUSED(cfra), ImBuf * ibuf) 01570 { 01571 float mul; 01572 01573 if((seq->flag & SEQ_FILTERY) && seq->type != SEQ_MOVIE) { 01574 IMB_filtery(ibuf); 01575 } 01576 01577 if(seq->flag & (SEQ_USE_CROP|SEQ_USE_TRANSFORM)) { 01578 StripCrop c= {0}; 01579 StripTransform t= {0}; 01580 int sx,sy,dx,dy; 01581 01582 if(seq->flag & SEQ_USE_CROP && seq->strip->crop) { 01583 c = *seq->strip->crop; 01584 } 01585 if(seq->flag & SEQ_USE_TRANSFORM && seq->strip->transform) { 01586 t = *seq->strip->transform; 01587 } 01588 01589 sx = ibuf->x - c.left - c.right; 01590 sy = ibuf->y - c.top - c.bottom; 01591 dx = sx; 01592 dy = sy; 01593 01594 if (seq->flag & SEQ_USE_TRANSFORM) { 01595 dx = context.scene->r.xsch; 01596 dy = context.scene->r.ysch; 01597 } 01598 01599 if (c.top + c.bottom >= ibuf->y || c.left + c.right >= ibuf->x || 01600 t.xofs >= dx || t.yofs >= dy) { 01601 make_black_ibuf(ibuf); 01602 } else { 01603 ImBuf * i = IMB_allocImBuf(dx, dy,32, ibuf->rect_float ? IB_rectfloat : IB_rect); 01604 01605 IMB_rectcpy(i, ibuf, t.xofs, t.yofs, c.left, c.bottom, sx, sy); 01606 01607 IMB_freeImBuf(ibuf); 01608 01609 ibuf = i; 01610 } 01611 } 01612 01613 if(seq->flag & SEQ_FLIPX) { 01614 IMB_flipx(ibuf); 01615 } 01616 01617 if(seq->flag & SEQ_FLIPY) { 01618 IMB_flipy(ibuf); 01619 } 01620 01621 if(seq->sat != 1.0f) { 01622 /* inline for now, could become an imbuf function */ 01623 int i; 01624 unsigned char *rct= (unsigned char *)ibuf->rect; 01625 float *rctf= ibuf->rect_float; 01626 const float sat= seq->sat; 01627 float hsv[3]; 01628 01629 if(rct) { 01630 float rgb[3]; 01631 for (i = ibuf->x * ibuf->y; i > 0; i--, rct+=4) { 01632 rgb_byte_to_float(rct, rgb); 01633 rgb_to_hsv(rgb[0], rgb[1], rgb[2], hsv, hsv+1, hsv+2); 01634 hsv_to_rgb(hsv[0], hsv[1] * sat, hsv[2], rgb, rgb+1, rgb+2); 01635 rgb_float_to_byte(rgb, rct); 01636 } 01637 } 01638 01639 if(rctf) { 01640 for (i = ibuf->x * ibuf->y; i > 0; i--, rctf+=4) { 01641 rgb_to_hsv(rctf[0], rctf[1], rctf[2], hsv, hsv+1, hsv+2); 01642 hsv_to_rgb(hsv[0], hsv[1] * sat, hsv[2], rctf, rctf+1, rctf+2); 01643 } 01644 } 01645 } 01646 01647 mul = seq->mul; 01648 01649 if(seq->blend_mode == SEQ_BLEND_REPLACE) { 01650 mul *= seq->blend_opacity / 100.0f; 01651 } 01652 01653 if(seq->flag & SEQ_USE_COLOR_BALANCE && seq->strip->color_balance) { 01654 color_balance(seq, ibuf, mul); 01655 mul = 1.0; 01656 } 01657 01658 if(seq->flag & SEQ_MAKE_FLOAT) { 01659 if (!ibuf->rect_float) 01660 IMB_float_from_rect_simple(ibuf); 01661 01662 if (ibuf->rect) { 01663 imb_freerectImBuf(ibuf); 01664 } 01665 } 01666 01667 if(mul != 1.0f) { 01668 multibuf(ibuf, mul); 01669 } 01670 01671 if(seq->flag & SEQ_MAKE_PREMUL) { 01672 if(ibuf->depth == 32 && ibuf->zbuf == NULL) { 01673 IMB_premultiply_alpha(ibuf); 01674 } 01675 } 01676 01677 01678 if(ibuf->x != context.rectx || ibuf->y != context.recty ) { 01679 if(context.scene->r.mode & R_OSA) { 01680 IMB_scaleImBuf(ibuf, (short)context.rectx, (short)context.recty); 01681 } else { 01682 IMB_scalefastImBuf(ibuf, (short)context.rectx, (short)context.recty); 01683 } 01684 } 01685 return ibuf; 01686 } 01687 01688 static ImBuf * copy_from_ibuf_still(SeqRenderData context, Sequence * seq, 01689 float nr) 01690 { 01691 ImBuf * rval = NULL; 01692 ImBuf * ibuf = NULL; 01693 01694 if (nr == 0) { 01695 ibuf = seq_stripelem_cache_get( 01696 context, seq, seq->start, 01697 SEQ_STRIPELEM_IBUF_STARTSTILL); 01698 } else if (nr == seq->len - 1) { 01699 ibuf = seq_stripelem_cache_get( 01700 context, seq, seq->start, 01701 SEQ_STRIPELEM_IBUF_ENDSTILL); 01702 } 01703 01704 if (ibuf) { 01705 rval = IMB_dupImBuf(ibuf); 01706 IMB_freeImBuf(ibuf); 01707 } 01708 01709 return rval; 01710 } 01711 01712 static void copy_to_ibuf_still(SeqRenderData context, Sequence * seq, float nr, 01713 ImBuf * ibuf) 01714 { 01715 if (nr == 0 || nr == seq->len - 1) { 01716 /* we have to store a copy, since the passed ibuf 01717 could be preprocessed afterwards (thereby silently 01718 changing the cached image... */ 01719 ibuf = IMB_dupImBuf(ibuf); 01720 01721 if (nr == 0) { 01722 seq_stripelem_cache_put( 01723 context, seq, seq->start, 01724 SEQ_STRIPELEM_IBUF_STARTSTILL, ibuf); 01725 } 01726 01727 if (nr == seq->len - 1) { 01728 seq_stripelem_cache_put( 01729 context, seq, seq->start, 01730 SEQ_STRIPELEM_IBUF_ENDSTILL, ibuf); 01731 } 01732 01733 IMB_freeImBuf(ibuf); 01734 } 01735 } 01736 01737 /* ********************************************************************** 01738 strip rendering functions 01739 ********************************************************************** */ 01740 01741 static ImBuf* seq_render_strip_stack( 01742 SeqRenderData context, ListBase *seqbasep, float cfra, int chanshown); 01743 01744 static ImBuf * seq_render_strip( 01745 SeqRenderData context, Sequence * seq, float cfra); 01746 01747 01748 static ImBuf* seq_render_effect_strip_impl( 01749 SeqRenderData context, Sequence *seq, float cfra) 01750 { 01751 float fac, facf; 01752 int early_out; 01753 int i; 01754 struct SeqEffectHandle sh = get_sequence_effect(seq); 01755 FCurve *fcu= NULL; 01756 ImBuf * ibuf[3]; 01757 Sequence *input[3]; 01758 ImBuf * out = NULL; 01759 01760 ibuf[0] = ibuf[1] = ibuf[2] = NULL; 01761 01762 input[0] = seq->seq1; input[1] = seq->seq2; input[2] = seq->seq3; 01763 01764 if (!sh.execute) { /* effect not supported in this version... */ 01765 out = IMB_allocImBuf((short)context.rectx, 01766 (short)context.recty, 32, IB_rect); 01767 return out; 01768 } 01769 01770 if (seq->flag & SEQ_USE_EFFECT_DEFAULT_FADE) { 01771 sh.get_default_fac(seq, cfra, &fac, &facf); 01772 01773 if ((context.scene->r.mode & R_FIELDS)==0) 01774 facf= fac; 01775 } 01776 else { 01777 fcu = id_data_find_fcurve(&context.scene->id, seq, &RNA_Sequence, "effect_fader", 0); 01778 if (fcu) { 01779 fac = facf = evaluate_fcurve(fcu, cfra); 01780 if( context.scene->r.mode & R_FIELDS ) { 01781 facf = evaluate_fcurve(fcu, cfra + 0.5f); 01782 } 01783 } else { 01784 fac = facf = seq->effect_fader; 01785 } 01786 } 01787 01788 early_out = sh.early_out(seq, fac, facf); 01789 01790 switch (early_out) { 01791 case EARLY_NO_INPUT: 01792 out = sh.execute(context, seq, cfra, fac, facf, 01793 NULL, NULL, NULL); 01794 break; 01795 case EARLY_DO_EFFECT: 01796 for(i=0; i<3; i++) { 01797 if(input[i]) 01798 ibuf[i] = seq_render_strip( 01799 context, input[i], cfra); 01800 } 01801 01802 if (ibuf[0] && ibuf[1]) { 01803 out = sh.execute(context, seq, cfra, fac, facf, 01804 ibuf[0], ibuf[1], ibuf[2]); 01805 } 01806 break; 01807 case EARLY_USE_INPUT_1: 01808 if (input[0]) { 01809 ibuf[0] = seq_render_strip(context, input[0], cfra); 01810 } 01811 if (ibuf[0]) { 01812 if (input_have_to_preprocess(context, seq, cfra)) { 01813 out = IMB_dupImBuf(ibuf[0]); 01814 } else { 01815 out = ibuf[0]; 01816 IMB_refImBuf(out); 01817 } 01818 } 01819 break; 01820 case EARLY_USE_INPUT_2: 01821 if (input[1]) { 01822 ibuf[1] = seq_render_strip(context, input[1], cfra); 01823 } 01824 if (ibuf[1]) { 01825 if (input_have_to_preprocess(context, seq, cfra)) { 01826 out = IMB_dupImBuf(ibuf[1]); 01827 } else { 01828 out = ibuf[1]; 01829 IMB_refImBuf(out); 01830 } 01831 } 01832 break; 01833 } 01834 01835 for (i = 0; i < 3; i++) { 01836 IMB_freeImBuf(ibuf[i]); 01837 } 01838 01839 if (out == NULL) { 01840 out = IMB_allocImBuf((short)context.rectx, (short)context.recty, 32, IB_rect); 01841 } 01842 01843 return out; 01844 } 01845 01846 01847 static ImBuf * seq_render_scene_strip_impl( 01848 SeqRenderData context, Sequence * seq, float nr) 01849 { 01850 ImBuf * ibuf = NULL; 01851 float frame= seq->sfra + nr + seq->anim_startofs; 01852 float oldcfra; 01853 Object *camera; 01854 ListBase oldmarkers; 01855 01856 /* Old info: 01857 Hack! This function can be called from do_render_seq(), in that case 01858 the seq->scene can already have a Render initialized with same name, 01859 so we have to use a default name. (compositor uses scene name to 01860 find render). 01861 However, when called from within the UI (image preview in sequencer) 01862 we do want to use scene Render, that way the render result is defined 01863 for display in render/imagewindow 01864 01865 Hmm, don't see, why we can't do that all the time, 01866 and since G.rendering is uhm, gone... (Peter) 01867 */ 01868 01869 /* New info: 01870 Using the same name for the renders works just fine as the do_render_seq() 01871 render is not used while the scene strips are rendered. 01872 01873 However rendering from UI (through sequencer_preview_area_draw) can crash in 01874 very many cases since other renders (material preview, an actual render etc.) 01875 can be started while this sequence preview render is running. The only proper 01876 solution is to make the sequencer preview render a proper job, which can be 01877 stopped when needed. This would also give a nice progress bar for the preview 01878 space so that users know there's something happening. 01879 01880 As a result the active scene now only uses OpenGL rendering for the sequencer 01881 preview. This is far from nice, but is the only way to prevent crashes at this 01882 time. 01883 01884 -jahka 01885 */ 01886 01887 int rendering = G.rendering; 01888 int doseq; 01889 int doseq_gl= G.rendering ? /*(scene->r.seq_flag & R_SEQ_GL_REND)*/ 0 : /*(scene->r.seq_flag & R_SEQ_GL_PREV)*/ 1; 01890 int have_seq= FALSE; 01891 Scene *scene; 01892 01893 /* dont refer to seq->scene above this point!, it can be NULL */ 01894 if(seq->scene == NULL) { 01895 return NULL; 01896 } 01897 01898 scene= seq->scene; 01899 01900 have_seq= (scene->r.scemode & R_DOSEQ) && scene->ed && scene->ed->seqbase.first; 01901 01902 oldcfra= scene->r.cfra; 01903 scene->r.cfra= frame; 01904 01905 if(seq->scene_camera) 01906 camera= seq->scene_camera; 01907 else { 01908 scene_camera_switch_update(scene); 01909 camera= scene->camera; 01910 } 01911 01912 if(have_seq==FALSE && camera==NULL) { 01913 scene->r.cfra= oldcfra; 01914 return NULL; 01915 } 01916 01917 /* prevent eternal loop */ 01918 doseq= context.scene->r.scemode & R_DOSEQ; 01919 context.scene->r.scemode &= ~R_DOSEQ; 01920 01921 #ifdef DURIAN_CAMERA_SWITCH 01922 /* stooping to new low's in hackyness :( */ 01923 oldmarkers= scene->markers; 01924 scene->markers.first= scene->markers.last= NULL; 01925 #endif 01926 01927 if(sequencer_view3d_cb && BLI_thread_is_main() && doseq_gl && (scene == context.scene || have_seq==0) && camera) { 01928 char err_out[256]= "unknown"; 01929 /* for old scened this can be uninitialized, should probably be added to do_versions at some point if the functionality stays */ 01930 if(context.scene->r.seq_prev_type==0) 01931 context.scene->r.seq_prev_type = 3 /* ==OB_SOLID */; 01932 01933 /* opengl offscreen render */ 01934 scene_update_for_newframe(context.bmain, scene, scene->lay); 01935 ibuf= sequencer_view3d_cb(scene, camera, context.rectx, context.recty, IB_rect, context.scene->r.seq_prev_type, err_out); 01936 if(ibuf == NULL) { 01937 fprintf(stderr, "seq_render_scene_strip_impl failed to get opengl buffer: %s\n", err_out); 01938 } 01939 } 01940 else { 01941 Render *re = RE_GetRender(scene->id.name); 01942 RenderResult rres; 01943 01944 /* XXX: this if can be removed when sequence preview rendering uses the job system */ 01945 if(rendering || context.scene != scene) { 01946 if(re==NULL) 01947 re= RE_NewRender(scene->id.name); 01948 01949 RE_BlenderFrame(re, context.bmain, scene, NULL, camera, scene->lay, frame, FALSE); 01950 01951 /* restore previous state after it was toggled on & off by RE_BlenderFrame */ 01952 G.rendering = rendering; 01953 } 01954 01955 RE_AcquireResultImage(re, &rres); 01956 01957 if(rres.rectf) { 01958 ibuf= IMB_allocImBuf(rres.rectx, rres.recty, 32, IB_rectfloat); 01959 memcpy(ibuf->rect_float, rres.rectf, 4*sizeof(float)*rres.rectx*rres.recty); 01960 if(rres.rectz) { 01961 addzbuffloatImBuf(ibuf); 01962 memcpy(ibuf->zbuf_float, rres.rectz, sizeof(float)*rres.rectx*rres.recty); 01963 } 01964 01965 /* float buffers in the sequencer are not linear */ 01966 ibuf->profile= IB_PROFILE_LINEAR_RGB; 01967 IMB_convert_profile(ibuf, IB_PROFILE_SRGB); 01968 } 01969 else if (rres.rect32) { 01970 ibuf= IMB_allocImBuf(rres.rectx, rres.recty, 32, IB_rect); 01971 memcpy(ibuf->rect, rres.rect32, 4*rres.rectx*rres.recty); 01972 } 01973 01974 RE_ReleaseResultImage(re); 01975 01976 // BIF_end_render_callbacks(); 01977 } 01978 01979 /* restore */ 01980 context.scene->r.scemode |= doseq; 01981 01982 scene->r.cfra = oldcfra; 01983 01984 if(frame != oldcfra) 01985 scene_update_for_newframe(context.bmain, scene, scene->lay); 01986 01987 #ifdef DURIAN_CAMERA_SWITCH 01988 /* stooping to new low's in hackyness :( */ 01989 scene->markers= oldmarkers; 01990 #endif 01991 01992 return ibuf; 01993 } 01994 01995 static ImBuf * seq_render_strip(SeqRenderData context, Sequence * seq, float cfra) 01996 { 01997 ImBuf * ibuf = NULL; 01998 char name[FILE_MAXDIR+FILE_MAXFILE]; 01999 int use_preprocess = input_have_to_preprocess(context, seq, cfra); 02000 float nr = give_stripelem_index(seq, cfra); 02001 /* all effects are handled similarly with the exception of speed effect */ 02002 int type = (seq->type & SEQ_EFFECT && seq->type != SEQ_SPEED) ? SEQ_EFFECT : seq->type; 02003 02004 ibuf = seq_stripelem_cache_get(context, seq, cfra, SEQ_STRIPELEM_IBUF); 02005 02006 /* currently, we cache preprocessed images in SEQ_STRIPELEM_IBUF, 02007 but not(!) on SEQ_STRIPELEM_IBUF_ENDSTILL and ..._STARTSTILL */ 02008 if (ibuf) 02009 use_preprocess = FALSE; 02010 02011 if (ibuf == NULL) 02012 ibuf = copy_from_ibuf_still(context, seq, nr); 02013 02014 if (ibuf == NULL) 02015 ibuf = seq_proxy_fetch(context, seq, cfra); 02016 02017 if(ibuf == NULL) switch(type) { 02018 case SEQ_META: 02019 { 02020 ImBuf * meta_ibuf = NULL; 02021 02022 if(seq->seqbase.first) 02023 meta_ibuf = seq_render_strip_stack( 02024 context, &seq->seqbase, 02025 seq->start + nr, 0); 02026 02027 if(meta_ibuf) { 02028 ibuf = meta_ibuf; 02029 if(ibuf && use_preprocess) { 02030 struct ImBuf * i = IMB_dupImBuf(ibuf); 02031 02032 IMB_freeImBuf(ibuf); 02033 02034 ibuf = i; 02035 } 02036 } 02037 break; 02038 } 02039 case SEQ_SPEED: 02040 { 02041 ImBuf * child_ibuf = NULL; 02042 02043 float f_cfra; 02044 SpeedControlVars * s = (SpeedControlVars *)seq->effectdata; 02045 02046 sequence_effect_speed_rebuild_map(context.scene,seq, 0); 02047 02048 /* weeek! */ 02049 f_cfra = seq->start + s->frameMap[(int) nr]; 02050 02051 child_ibuf = seq_render_strip(context,seq->seq1,f_cfra); 02052 02053 if (child_ibuf) { 02054 ibuf = child_ibuf; 02055 if(ibuf && use_preprocess) { 02056 struct ImBuf * i = IMB_dupImBuf(ibuf); 02057 02058 IMB_freeImBuf(ibuf); 02059 02060 ibuf = i; 02061 } 02062 } 02063 break; 02064 } 02065 case SEQ_EFFECT: 02066 { 02067 ibuf = seq_render_effect_strip_impl( 02068 context, seq, seq->start + nr); 02069 break; 02070 } 02071 case SEQ_IMAGE: 02072 { 02073 StripElem * s_elem = give_stripelem(seq, cfra); 02074 02075 if (s_elem) { 02076 BLI_join_dirfile(name, sizeof(name), seq->strip->dir, s_elem->name); 02077 BLI_path_abs(name, G.main->name); 02078 } 02079 02080 if (s_elem && (ibuf = IMB_loadiffname(name, IB_rect))) { 02081 /* we don't need both (speed reasons)! */ 02082 if (ibuf->rect_float && ibuf->rect) 02083 imb_freerectImBuf(ibuf); 02084 02085 /* all sequencer color is done in SRGB space, linear gives odd crossfades */ 02086 if(ibuf->profile == IB_PROFILE_LINEAR_RGB) 02087 IMB_convert_profile(ibuf, IB_PROFILE_NONE); 02088 02089 copy_to_ibuf_still(context, seq, nr, ibuf); 02090 02091 s_elem->orig_width = ibuf->x; 02092 s_elem->orig_height = ibuf->y; 02093 } 02094 break; 02095 } 02096 case SEQ_MOVIE: 02097 { 02098 if(seq->anim==NULL) { 02099 BLI_join_dirfile(name, sizeof(name), seq->strip->dir, seq->strip->stripdata->name); 02100 BLI_path_abs(name, G.main->name); 02101 02102 seq->anim = openanim(name, IB_rect | 02103 ((seq->flag & SEQ_FILTERY) ? IB_animdeinterlace : 0)); 02104 } 02105 02106 if(seq->anim) { 02107 IMB_anim_set_preseek(seq->anim, seq->anim_preseek); 02108 ibuf = IMB_anim_absolute(seq->anim, nr + seq->anim_startofs); 02109 /* we don't need both (speed reasons)! */ 02110 if (ibuf && ibuf->rect_float && ibuf->rect) 02111 imb_freerectImBuf(ibuf); 02112 if (ibuf) { 02113 seq->strip->stripdata->orig_width = ibuf->x; 02114 seq->strip->stripdata->orig_height = ibuf->y; 02115 } 02116 } 02117 copy_to_ibuf_still(context, seq, nr, ibuf); 02118 break; 02119 } 02120 case SEQ_SCENE: 02121 { // scene can be NULL after deletions 02122 ibuf = seq_render_scene_strip_impl(context, seq, nr); 02123 02124 /* Scene strips update all animation, so we need to restore original state.*/ 02125 BKE_animsys_evaluate_all_animation(context.bmain, cfra); 02126 02127 copy_to_ibuf_still(context, seq, nr, ibuf); 02128 break; 02129 } 02130 } 02131 02132 if (ibuf == NULL) 02133 ibuf = IMB_allocImBuf((short)context.rectx, (short)context.recty, 32, IB_rect); 02134 02135 if (ibuf->x != context.rectx || ibuf->y != context.recty) 02136 use_preprocess = TRUE; 02137 02138 if (use_preprocess) 02139 ibuf = input_preprocess(context, seq, cfra, ibuf); 02140 02141 seq_stripelem_cache_put(context, seq, cfra, SEQ_STRIPELEM_IBUF, ibuf); 02142 02143 return ibuf; 02144 } 02145 02146 /* ********************************************************************** 02147 strip stack rendering functions 02148 ********************************************************************** */ 02149 02150 static int seq_must_swap_input_in_blend_mode(Sequence * seq) 02151 { 02152 int swap_input = FALSE; 02153 02154 /* bad hack, to fix crazy input ordering of 02155 those two effects */ 02156 02157 if (ELEM3(seq->blend_mode, SEQ_ALPHAOVER, SEQ_ALPHAUNDER, SEQ_OVERDROP)) { 02158 swap_input = TRUE; 02159 } 02160 02161 return swap_input; 02162 } 02163 02164 static int seq_get_early_out_for_blend_mode(Sequence * seq) 02165 { 02166 struct SeqEffectHandle sh = get_sequence_blend(seq); 02167 float facf = seq->blend_opacity / 100.0f; 02168 int early_out = sh.early_out(seq, facf, facf); 02169 02170 if (ELEM(early_out, EARLY_DO_EFFECT, EARLY_NO_INPUT)) { 02171 return early_out; 02172 } 02173 02174 if (seq_must_swap_input_in_blend_mode(seq)) { 02175 if (early_out == EARLY_USE_INPUT_2) { 02176 return EARLY_USE_INPUT_1; 02177 } else if (early_out == EARLY_USE_INPUT_1) { 02178 return EARLY_USE_INPUT_2; 02179 } 02180 } 02181 return early_out; 02182 } 02183 02184 static ImBuf* seq_render_strip_stack( 02185 SeqRenderData context, ListBase *seqbasep, float cfra, int chanshown) 02186 { 02187 Sequence* seq_arr[MAXSEQ+1]; 02188 int count; 02189 int i; 02190 ImBuf* out = NULL; 02191 02192 count = get_shown_sequences(seqbasep, cfra, chanshown, (Sequence **)&seq_arr); 02193 02194 if (count == 0) { 02195 return NULL; 02196 } 02197 02198 #if 0 /* commentind since this breaks keyframing, since it resets the value on draw */ 02199 if(scene->r.cfra != cfra) { 02200 // XXX for prefetch and overlay offset!..., very bad!!! 02201 AnimData *adt= BKE_animdata_from_id(&scene->id); 02202 BKE_animsys_evaluate_animdata(&scene->id, adt, cfra, ADT_RECALC_ANIM); 02203 } 02204 #endif 02205 02206 out = seq_stripelem_cache_get(context, seq_arr[count - 1], 02207 cfra, SEQ_STRIPELEM_IBUF_COMP); 02208 02209 if (out) { 02210 return out; 02211 } 02212 02213 if(count == 1) { 02214 out = seq_render_strip(context, seq_arr[0], cfra); 02215 seq_stripelem_cache_put(context, seq_arr[0], cfra, 02216 SEQ_STRIPELEM_IBUF_COMP, out); 02217 02218 return out; 02219 } 02220 02221 02222 for (i = count - 1; i >= 0; i--) { 02223 int early_out; 02224 Sequence *seq = seq_arr[i]; 02225 02226 out = seq_stripelem_cache_get( 02227 context, seq, cfra, SEQ_STRIPELEM_IBUF_COMP); 02228 02229 if (out) { 02230 break; 02231 } 02232 if (seq->blend_mode == SEQ_BLEND_REPLACE) { 02233 out = seq_render_strip(context, seq, cfra); 02234 break; 02235 } 02236 02237 early_out = seq_get_early_out_for_blend_mode(seq); 02238 02239 switch (early_out) { 02240 case EARLY_NO_INPUT: 02241 case EARLY_USE_INPUT_2: 02242 out = seq_render_strip(context, seq, cfra); 02243 break; 02244 case EARLY_USE_INPUT_1: 02245 if (i == 0) { 02246 out = IMB_allocImBuf((short)context.rectx, (short)context.recty, 32, IB_rect); 02247 } 02248 break; 02249 case EARLY_DO_EFFECT: 02250 if (i == 0) { 02251 out = seq_render_strip(context, seq, cfra); 02252 } 02253 02254 break; 02255 } 02256 if (out) { 02257 break; 02258 } 02259 } 02260 02261 seq_stripelem_cache_put(context, seq_arr[i], cfra, 02262 SEQ_STRIPELEM_IBUF_COMP, out); 02263 02264 02265 i++; 02266 02267 for (; i < count; i++) { 02268 Sequence * seq = seq_arr[i]; 02269 02270 if (seq_get_early_out_for_blend_mode(seq) == EARLY_DO_EFFECT) { 02271 struct SeqEffectHandle sh = get_sequence_blend(seq); 02272 ImBuf * ibuf1 = out; 02273 ImBuf * ibuf2 = seq_render_strip(context, seq, cfra); 02274 02275 float facf = seq->blend_opacity / 100.0f; 02276 int swap_input = seq_must_swap_input_in_blend_mode(seq); 02277 02278 if (swap_input) { 02279 out = sh.execute(context, seq, cfra, 02280 facf, facf, 02281 ibuf2, ibuf1, NULL); 02282 } else { 02283 out = sh.execute(context, seq, cfra, 02284 facf, facf, 02285 ibuf1, ibuf2, NULL); 02286 } 02287 02288 IMB_freeImBuf(ibuf1); 02289 IMB_freeImBuf(ibuf2); 02290 } 02291 02292 seq_stripelem_cache_put(context, seq_arr[i], cfra, 02293 SEQ_STRIPELEM_IBUF_COMP, out); 02294 } 02295 02296 return out; 02297 } 02298 02299 /* 02300 * returned ImBuf is refed! 02301 * you have to free after usage! 02302 */ 02303 02304 ImBuf *give_ibuf_seq(SeqRenderData context, float cfra, int chanshown) 02305 { 02306 Editing *ed= seq_give_editing(context.scene, FALSE); 02307 int count; 02308 ListBase *seqbasep; 02309 02310 if(ed==NULL) return NULL; 02311 02312 count = BLI_countlist(&ed->metastack); 02313 if((chanshown < 0) && (count > 0)) { 02314 count = MAX2(count + chanshown, 0); 02315 seqbasep= ((MetaStack*)BLI_findlink(&ed->metastack, count))->oldbasep; 02316 } else { 02317 seqbasep= ed->seqbasep; 02318 } 02319 02320 return seq_render_strip_stack(context, seqbasep, cfra, chanshown); 02321 } 02322 02323 ImBuf *give_ibuf_seqbase(SeqRenderData context, float cfra, int chanshown, ListBase *seqbasep) 02324 { 02325 return seq_render_strip_stack(context, seqbasep, cfra, chanshown); 02326 } 02327 02328 02329 ImBuf *give_ibuf_seq_direct(SeqRenderData context, float cfra, Sequence *seq) 02330 { 02331 return seq_render_strip(context, seq, cfra); 02332 } 02333 02334 #if 0 02335 /* check used when we need to change seq->blend_mode but not to effect or audio strips */ 02336 static int seq_can_blend(Sequence *seq) 02337 { 02338 if (ELEM4(seq->type, SEQ_IMAGE, SEQ_META, SEQ_SCENE, SEQ_MOVIE)) { 02339 return 1; 02340 } else { 02341 return 0; 02342 } 02343 } 02344 #endif 02345 02346 /* *********************** threading api ******************* */ 02347 02348 static ListBase running_threads; 02349 static ListBase prefetch_wait; 02350 static ListBase prefetch_done; 02351 02352 static pthread_mutex_t queue_lock = PTHREAD_MUTEX_INITIALIZER; 02353 static pthread_mutex_t wakeup_lock = PTHREAD_MUTEX_INITIALIZER; 02354 static pthread_cond_t wakeup_cond = PTHREAD_COND_INITIALIZER; 02355 02356 //static pthread_mutex_t prefetch_ready_lock = PTHREAD_MUTEX_INITIALIZER; 02357 //static pthread_cond_t prefetch_ready_cond = PTHREAD_COND_INITIALIZER; 02358 02359 static pthread_mutex_t frame_done_lock = PTHREAD_MUTEX_INITIALIZER; 02360 static pthread_cond_t frame_done_cond = PTHREAD_COND_INITIALIZER; 02361 02362 static volatile int seq_thread_shutdown = TRUE; 02363 static volatile int seq_last_given_monoton_cfra = 0; 02364 static int monoton_cfra = 0; 02365 02366 typedef struct PrefetchThread { 02367 struct PrefetchThread *next, *prev; 02368 02369 Scene *scene; 02370 struct PrefetchQueueElem *current; 02371 pthread_t pthread; 02372 int running; 02373 02374 } PrefetchThread; 02375 02376 typedef struct PrefetchQueueElem { 02377 struct PrefetchQueueElem *next, *prev; 02378 02379 int rectx; 02380 int recty; 02381 float cfra; 02382 int chanshown; 02383 int preview_render_size; 02384 02385 int monoton_cfra; 02386 02387 struct ImBuf * ibuf; 02388 } PrefetchQueueElem; 02389 02390 #if 0 02391 static void *seq_prefetch_thread(void * This_) 02392 { 02393 PrefetchThread * This = This_; 02394 02395 while (!seq_thread_shutdown) { 02396 PrefetchQueueElem *e; 02397 int s_last; 02398 02399 pthread_mutex_lock(&queue_lock); 02400 e = prefetch_wait.first; 02401 if (e) { 02402 BLI_remlink(&prefetch_wait, e); 02403 } 02404 s_last = seq_last_given_monoton_cfra; 02405 02406 This->current = e; 02407 02408 pthread_mutex_unlock(&queue_lock); 02409 02410 if (!e) { 02411 pthread_mutex_lock(&prefetch_ready_lock); 02412 02413 This->running = FALSE; 02414 02415 pthread_cond_signal(&prefetch_ready_cond); 02416 pthread_mutex_unlock(&prefetch_ready_lock); 02417 02418 pthread_mutex_lock(&wakeup_lock); 02419 if (!seq_thread_shutdown) { 02420 pthread_cond_wait(&wakeup_cond, &wakeup_lock); 02421 } 02422 pthread_mutex_unlock(&wakeup_lock); 02423 continue; 02424 } 02425 02426 This->running = TRUE; 02427 02428 if (e->cfra >= s_last) { 02429 e->ibuf = give_ibuf_seq_impl(This->scene, 02430 e->rectx, e->recty, e->cfra, e->chanshown, 02431 e->preview_render_size); 02432 } 02433 02434 pthread_mutex_lock(&queue_lock); 02435 02436 BLI_addtail(&prefetch_done, e); 02437 02438 for (e = prefetch_wait.first; e; e = e->next) { 02439 if (s_last > e->monoton_cfra) { 02440 BLI_remlink(&prefetch_wait, e); 02441 MEM_freeN(e); 02442 } 02443 } 02444 02445 for (e = prefetch_done.first; e; e = e->next) { 02446 if (s_last > e->monoton_cfra) { 02447 if (e->ibuf) { 02448 IMB_cache_limiter_unref(e->ibuf); 02449 } 02450 BLI_remlink(&prefetch_done, e); 02451 MEM_freeN(e); 02452 } 02453 } 02454 02455 pthread_mutex_unlock(&queue_lock); 02456 02457 pthread_mutex_lock(&frame_done_lock); 02458 pthread_cond_signal(&frame_done_cond); 02459 pthread_mutex_unlock(&frame_done_lock); 02460 } 02461 return 0; 02462 } 02463 02464 static void seq_start_threads(Scene *scene) 02465 { 02466 int i; 02467 02468 running_threads.first = running_threads.last = NULL; 02469 prefetch_wait.first = prefetch_wait.last = NULL; 02470 prefetch_done.first = prefetch_done.last = NULL; 02471 02472 seq_thread_shutdown = FALSE; 02473 seq_last_given_monoton_cfra = monoton_cfra = 0; 02474 02475 /* since global structures are modified during the processing 02476 of one frame, only one render thread is currently possible... 02477 02478 (but we code, in the hope, that we can remove this restriction 02479 soon...) 02480 */ 02481 02482 fprintf(stderr, "SEQ-THREAD: seq_start_threads\n"); 02483 02484 for (i = 0; i < 1; i++) { 02485 PrefetchThread *t = MEM_callocN(sizeof(PrefetchThread), "prefetch_thread"); 02486 t->scene= scene; 02487 t->running = TRUE; 02488 BLI_addtail(&running_threads, t); 02489 02490 pthread_create(&t->pthread, NULL, seq_prefetch_thread, t); 02491 } 02492 02493 /* init malloc mutex */ 02494 BLI_init_threads(0, 0, 0); 02495 } 02496 02497 static void seq_stop_threads() 02498 { 02499 PrefetchThread *tslot; 02500 PrefetchQueueElem *e; 02501 02502 fprintf(stderr, "SEQ-THREAD: seq_stop_threads()\n"); 02503 02504 if (seq_thread_shutdown) { 02505 fprintf(stderr, "SEQ-THREAD: ... already stopped\n"); 02506 return; 02507 } 02508 02509 pthread_mutex_lock(&wakeup_lock); 02510 02511 seq_thread_shutdown = TRUE; 02512 02513 pthread_cond_broadcast(&wakeup_cond); 02514 pthread_mutex_unlock(&wakeup_lock); 02515 02516 for(tslot = running_threads.first; tslot; tslot= tslot->next) { 02517 pthread_join(tslot->pthread, NULL); 02518 } 02519 02520 02521 for (e = prefetch_wait.first; e; e = e->next) { 02522 BLI_remlink(&prefetch_wait, e); 02523 MEM_freeN(e); 02524 } 02525 02526 for (e = prefetch_done.first; e; e = e->next) { 02527 if (e->ibuf) { 02528 IMB_cache_limiter_unref(e->ibuf); 02529 } 02530 BLI_remlink(&prefetch_done, e); 02531 MEM_freeN(e); 02532 } 02533 02534 BLI_freelistN(&running_threads); 02535 02536 /* deinit malloc mutex */ 02537 BLI_end_threads(0); 02538 } 02539 #endif 02540 02541 void give_ibuf_prefetch_request(SeqRenderData context, float cfra, int chanshown) 02542 { 02543 PrefetchQueueElem *e; 02544 if (seq_thread_shutdown) { 02545 return; 02546 } 02547 02548 e = MEM_callocN(sizeof(PrefetchQueueElem), "prefetch_queue_elem"); 02549 e->rectx = context.rectx; 02550 e->recty = context.recty; 02551 e->cfra = cfra; 02552 e->chanshown = chanshown; 02553 e->preview_render_size = context.preview_render_size; 02554 e->monoton_cfra = monoton_cfra++; 02555 02556 pthread_mutex_lock(&queue_lock); 02557 BLI_addtail(&prefetch_wait, e); 02558 pthread_mutex_unlock(&queue_lock); 02559 02560 pthread_mutex_lock(&wakeup_lock); 02561 pthread_cond_signal(&wakeup_cond); 02562 pthread_mutex_unlock(&wakeup_lock); 02563 } 02564 02565 #if 0 02566 static void seq_wait_for_prefetch_ready() 02567 { 02568 PrefetchThread *tslot; 02569 02570 if (seq_thread_shutdown) { 02571 return; 02572 } 02573 02574 fprintf(stderr, "SEQ-THREAD: rendering prefetch frames...\n"); 02575 02576 pthread_mutex_lock(&prefetch_ready_lock); 02577 02578 for(;;) { 02579 for(tslot = running_threads.first; tslot; tslot= tslot->next) { 02580 if (tslot->running) { 02581 break; 02582 } 02583 } 02584 if (!tslot) { 02585 break; 02586 } 02587 pthread_cond_wait(&prefetch_ready_cond, &prefetch_ready_lock); 02588 } 02589 02590 pthread_mutex_unlock(&prefetch_ready_lock); 02591 02592 fprintf(stderr, "SEQ-THREAD: prefetch done\n"); 02593 } 02594 #endif 02595 02596 ImBuf *give_ibuf_seq_threaded(SeqRenderData context, float cfra, int chanshown) 02597 { 02598 PrefetchQueueElem *e = NULL; 02599 int found_something = FALSE; 02600 02601 if (seq_thread_shutdown) { 02602 return give_ibuf_seq(context, cfra, chanshown); 02603 } 02604 02605 while (!e) { 02606 int success = FALSE; 02607 pthread_mutex_lock(&queue_lock); 02608 02609 for (e = prefetch_done.first; e; e = e->next) { 02610 if (cfra == e->cfra && 02611 chanshown == e->chanshown && 02612 context.rectx == e->rectx && 02613 context.recty == e->recty && 02614 context.preview_render_size == e->preview_render_size) { 02615 success = TRUE; 02616 found_something = TRUE; 02617 break; 02618 } 02619 } 02620 02621 if (!e) { 02622 for (e = prefetch_wait.first; e; e = e->next) { 02623 if (cfra == e->cfra && 02624 chanshown == e->chanshown && 02625 context.rectx == e->rectx && 02626 context.recty == e->recty && 02627 context.preview_render_size == e->preview_render_size) { 02628 found_something = TRUE; 02629 break; 02630 } 02631 } 02632 } 02633 02634 if (!e) { 02635 PrefetchThread *tslot; 02636 02637 for(tslot = running_threads.first; 02638 tslot; tslot= tslot->next) { 02639 if (tslot->current && 02640 cfra == tslot->current->cfra && 02641 chanshown == tslot->current->chanshown && 02642 context.rectx == tslot->current->rectx && 02643 context.recty == tslot->current->recty && 02644 context.preview_render_size== tslot->current->preview_render_size){ 02645 found_something = TRUE; 02646 break; 02647 } 02648 } 02649 } 02650 02651 /* e->ibuf is unrefed by render thread on next round. */ 02652 02653 if (e) { 02654 seq_last_given_monoton_cfra = e->monoton_cfra; 02655 } 02656 02657 pthread_mutex_unlock(&queue_lock); 02658 02659 if (!success) { 02660 e = NULL; 02661 02662 if (!found_something) { 02663 fprintf(stderr, 02664 "SEQ-THREAD: Requested frame " 02665 "not in queue ???\n"); 02666 break; 02667 } 02668 pthread_mutex_lock(&frame_done_lock); 02669 pthread_cond_wait(&frame_done_cond, &frame_done_lock); 02670 pthread_mutex_unlock(&frame_done_lock); 02671 } 02672 } 02673 02674 return e ? e->ibuf : NULL; 02675 } 02676 02677 /* Functions to free imbuf and anim data on changes */ 02678 02679 static void free_anim_seq(Sequence *seq) 02680 { 02681 if(seq->anim) { 02682 IMB_free_anim(seq->anim); 02683 seq->anim = NULL; 02684 } 02685 } 02686 02687 void free_imbuf_seq(Scene *scene, ListBase * seqbase, int check_mem_usage, 02688 int keep_file_handles) 02689 { 02690 Sequence *seq; 02691 02692 if (check_mem_usage) { 02693 /* Let the cache limitor take care of this (schlaile) */ 02694 /* While render let's keep all memory available for render 02695 (ton) 02696 At least if free memory is tight... 02697 This can make a big difference in encoding speed 02698 (it is around 4 times(!) faster, if we do not waste time 02699 on freeing _all_ buffers every time on long timelines...) 02700 (schlaile) 02701 */ 02702 02703 uintptr_t mem_in_use; 02704 uintptr_t mmap_in_use; 02705 uintptr_t max; 02706 02707 mem_in_use= MEM_get_memory_in_use(); 02708 mmap_in_use= MEM_get_mapped_memory_in_use(); 02709 max = MEM_CacheLimiter_get_maximum(); 02710 02711 if (max == 0 || mem_in_use + mmap_in_use <= max) { 02712 return; 02713 } 02714 } 02715 02716 seq_stripelem_cache_cleanup(); 02717 02718 for(seq= seqbase->first; seq; seq= seq->next) { 02719 if(seq->strip) { 02720 if(seq->type==SEQ_MOVIE && !keep_file_handles) 02721 free_anim_seq(seq); 02722 if(seq->type==SEQ_SPEED) { 02723 sequence_effect_speed_rebuild_map(scene, seq, 1); 02724 } 02725 } 02726 if(seq->type==SEQ_META) { 02727 free_imbuf_seq(scene, &seq->seqbase, FALSE, keep_file_handles); 02728 } 02729 if(seq->type==SEQ_SCENE) { 02730 /* FIXME: recurs downwards, 02731 but do recurs protection somehow! */ 02732 } 02733 } 02734 02735 } 02736 02737 static int update_changed_seq_recurs(Scene *scene, Sequence *seq, Sequence *changed_seq, int len_change, int ibuf_change) 02738 { 02739 Sequence *subseq; 02740 int free_imbuf = 0; 02741 02742 /* recurs downwards to see if this seq depends on the changed seq */ 02743 02744 if(seq == NULL) 02745 return 0; 02746 02747 if(seq == changed_seq) 02748 free_imbuf = 1; 02749 02750 for(subseq=seq->seqbase.first; subseq; subseq=subseq->next) 02751 if(update_changed_seq_recurs(scene, subseq, changed_seq, len_change, ibuf_change)) 02752 free_imbuf = TRUE; 02753 02754 if(seq->seq1) 02755 if(update_changed_seq_recurs(scene, seq->seq1, changed_seq, len_change, ibuf_change)) 02756 free_imbuf = TRUE; 02757 if(seq->seq2 && (seq->seq2 != seq->seq1)) 02758 if(update_changed_seq_recurs(scene, seq->seq2, changed_seq, len_change, ibuf_change)) 02759 free_imbuf = TRUE; 02760 if(seq->seq3 && (seq->seq3 != seq->seq1) && (seq->seq3 != seq->seq2)) 02761 if(update_changed_seq_recurs(scene, seq->seq3, changed_seq, len_change, ibuf_change)) 02762 free_imbuf = TRUE; 02763 02764 if(free_imbuf) { 02765 if(ibuf_change) { 02766 if(seq->type == SEQ_MOVIE) 02767 free_anim_seq(seq); 02768 if(seq->type == SEQ_SPEED) { 02769 sequence_effect_speed_rebuild_map(scene, seq, 1); 02770 } 02771 } 02772 02773 if(len_change) 02774 calc_sequence(scene, seq); 02775 } 02776 02777 return free_imbuf; 02778 } 02779 02780 void update_changed_seq_and_deps(Scene *scene, Sequence *changed_seq, int len_change, int ibuf_change) 02781 { 02782 Editing *ed= seq_give_editing(scene, FALSE); 02783 Sequence *seq; 02784 02785 if (ed==NULL) return; 02786 02787 for (seq=ed->seqbase.first; seq; seq=seq->next) 02788 update_changed_seq_recurs(scene, seq, changed_seq, len_change, ibuf_change); 02789 } 02790 02791 /* seq funcs's for transforming internally 02792 notice the difference between start/end and left/right. 02793 02794 left and right are the bounds at which the sequence is rendered, 02795 start and end are from the start and fixed length of the sequence. 02796 */ 02797 int seq_tx_get_start(Sequence *seq) { 02798 return seq->start; 02799 } 02800 int seq_tx_get_end(Sequence *seq) 02801 { 02802 return seq->start+seq->len; 02803 } 02804 02805 int seq_tx_get_final_left(Sequence *seq, int metaclip) 02806 { 02807 if (metaclip && seq->tmp) { 02808 /* return the range clipped by the parents range */ 02809 return MAX2( seq_tx_get_final_left(seq, 0), seq_tx_get_final_left((Sequence *)seq->tmp, 1) ); 02810 } else { 02811 return (seq->start - seq->startstill) + seq->startofs; 02812 } 02813 02814 } 02815 int seq_tx_get_final_right(Sequence *seq, int metaclip) 02816 { 02817 if (metaclip && seq->tmp) { 02818 /* return the range clipped by the parents range */ 02819 return MIN2( seq_tx_get_final_right(seq, 0), seq_tx_get_final_right((Sequence *)seq->tmp, 1) ); 02820 } else { 02821 return ((seq->start+seq->len) + seq->endstill) - seq->endofs; 02822 } 02823 } 02824 02825 void seq_tx_set_final_left(Sequence *seq, int val) 02826 { 02827 if (val < (seq)->start) { 02828 seq->startstill = abs(val - (seq)->start); 02829 seq->startofs = 0; 02830 } else { 02831 seq->startofs = abs(val - (seq)->start); 02832 seq->startstill = 0; 02833 } 02834 } 02835 02836 void seq_tx_set_final_right(Sequence *seq, int val) 02837 { 02838 if (val > (seq)->start + (seq)->len) { 02839 seq->endstill = abs(val - (seq->start + (seq)->len)); 02840 seq->endofs = 0; 02841 } else { 02842 seq->endofs = abs(val - ((seq)->start + (seq)->len)); 02843 seq->endstill = 0; 02844 } 02845 } 02846 02847 /* used so we can do a quick check for single image seq 02848 since they work a bit differently to normal image seq's (during transform) */ 02849 int seq_single_check(Sequence *seq) 02850 { 02851 return (seq->len==1 && ( 02852 seq->type == SEQ_IMAGE 02853 || ((seq->type & SEQ_EFFECT) && 02854 get_sequence_effect_num_inputs(seq->type) == 0))); 02855 } 02856 02857 /* check if the selected seq's reference unselected seq's */ 02858 int seqbase_isolated_sel_check(ListBase *seqbase) 02859 { 02860 Sequence *seq; 02861 /* is there more than 1 select */ 02862 int ok= FALSE; 02863 02864 for(seq= seqbase->first; seq; seq= seq->next) { 02865 if(seq->flag & SELECT) { 02866 ok= TRUE; 02867 break; 02868 } 02869 } 02870 02871 if(ok == FALSE) 02872 return FALSE; 02873 02874 /* test relationships */ 02875 for(seq= seqbase->first; seq; seq= seq->next) { 02876 if((seq->type & SEQ_EFFECT)==0) 02877 continue; 02878 02879 if(seq->flag & SELECT) { 02880 if( (seq->seq1 && (seq->seq1->flag & SELECT)==0) || 02881 (seq->seq2 && (seq->seq2->flag & SELECT)==0) || 02882 (seq->seq3 && (seq->seq3->flag & SELECT)==0) ) 02883 return FALSE; 02884 } 02885 else { 02886 if( (seq->seq1 && (seq->seq1->flag & SELECT)) || 02887 (seq->seq2 && (seq->seq2->flag & SELECT)) || 02888 (seq->seq3 && (seq->seq3->flag & SELECT)) ) 02889 return FALSE; 02890 } 02891 } 02892 02893 return TRUE; 02894 } 02895 02896 /* use to impose limits when dragging/extending - so impossible situations dont happen 02897 * Cant use the SEQ_LEFTSEL and SEQ_LEFTSEL directly because the strip may be in a metastrip */ 02898 void seq_tx_handle_xlimits(Sequence *seq, int leftflag, int rightflag) 02899 { 02900 if(leftflag) { 02901 if (seq_tx_get_final_left(seq, 0) >= seq_tx_get_final_right(seq, 0)) { 02902 seq_tx_set_final_left(seq, seq_tx_get_final_right(seq, 0)-1); 02903 } 02904 02905 if (seq_single_check(seq)==0) { 02906 if (seq_tx_get_final_left(seq, 0) >= seq_tx_get_end(seq)) { 02907 seq_tx_set_final_left(seq, seq_tx_get_end(seq)-1); 02908 } 02909 02910 /* dosnt work now - TODO */ 02911 /* 02912 if (seq_tx_get_start(seq) >= seq_tx_get_final_right(seq, 0)) { 02913 int ofs; 02914 ofs = seq_tx_get_start(seq) - seq_tx_get_final_right(seq, 0); 02915 seq->start -= ofs; 02916 seq_tx_set_final_left(seq, seq_tx_get_final_left(seq, 0) + ofs ); 02917 }*/ 02918 02919 } 02920 } 02921 02922 if(rightflag) { 02923 if (seq_tx_get_final_right(seq, 0) <= seq_tx_get_final_left(seq, 0)) { 02924 seq_tx_set_final_right(seq, seq_tx_get_final_left(seq, 0)+1); 02925 } 02926 02927 if (seq_single_check(seq)==0) { 02928 if (seq_tx_get_final_right(seq, 0) <= seq_tx_get_start(seq)) { 02929 seq_tx_set_final_right(seq, seq_tx_get_start(seq)+1); 02930 } 02931 } 02932 } 02933 02934 /* sounds cannot be extended past their endpoints */ 02935 if (seq->type == SEQ_SOUND) { 02936 seq->startstill= 0; 02937 seq->endstill= 0; 02938 } 02939 } 02940 02941 void seq_single_fix(Sequence *seq) 02942 { 02943 int left, start, offset; 02944 if (!seq_single_check(seq)) 02945 return; 02946 02947 /* make sure the image is always at the start since there is only one, 02948 adjusting its start should be ok */ 02949 left = seq_tx_get_final_left(seq, 0); 02950 start = seq->start; 02951 if (start != left) { 02952 offset = left - start; 02953 seq_tx_set_final_left( seq, seq_tx_get_final_left(seq, 0) - offset ); 02954 seq_tx_set_final_right( seq, seq_tx_get_final_right(seq, 0) - offset ); 02955 seq->start += offset; 02956 } 02957 } 02958 02959 int seq_tx_test(Sequence * seq) 02960 { 02961 return (seq->type < SEQ_EFFECT) || (get_sequence_effect_num_inputs(seq->type) == 0); 02962 } 02963 02964 static int seq_overlap(Sequence *seq1, Sequence *seq2) 02965 { 02966 return (seq1 != seq2 && seq1->machine == seq2->machine && 02967 ((seq1->enddisp <= seq2->startdisp) || (seq1->startdisp >= seq2->enddisp))==0); 02968 } 02969 02970 int seq_test_overlap(ListBase * seqbasep, Sequence *test) 02971 { 02972 Sequence *seq; 02973 02974 seq= seqbasep->first; 02975 while(seq) { 02976 if(seq_overlap(test, seq)) 02977 return 1; 02978 02979 seq= seq->next; 02980 } 02981 return 0; 02982 } 02983 02984 02985 void seq_translate(Scene *evil_scene, Sequence *seq, int delta) 02986 { 02987 seq_offset_animdata(evil_scene, seq, delta); 02988 seq->start += delta; 02989 02990 if(seq->type==SEQ_META) { 02991 Sequence *seq_child; 02992 for(seq_child= seq->seqbase.first; seq_child; seq_child= seq_child->next) { 02993 seq_translate(evil_scene, seq_child, delta); 02994 } 02995 } 02996 02997 calc_sequence_disp(evil_scene, seq); 02998 } 02999 03000 void seq_sound_init(Scene *scene, Sequence *seq) 03001 { 03002 if(seq->type==SEQ_META) { 03003 Sequence *seq_child; 03004 for(seq_child= seq->seqbase.first; seq_child; seq_child= seq_child->next) { 03005 seq_sound_init(scene, seq_child); 03006 } 03007 } 03008 else { 03009 if(seq->sound) { 03010 seq->scene_sound = sound_add_scene_sound(scene, seq, seq->startdisp, seq->enddisp, seq->startofs + seq->anim_startofs); 03011 } 03012 if(seq->scene) { 03013 sound_scene_add_scene_sound(scene, seq, seq->startdisp, seq->enddisp, seq->startofs + seq->anim_startofs); 03014 } 03015 } 03016 } 03017 03018 Sequence *seq_foreground_frame_get(Scene *scene, int frame) 03019 { 03020 Editing *ed= seq_give_editing(scene, FALSE); 03021 Sequence *seq, *best_seq=NULL; 03022 int best_machine = -1; 03023 03024 if(!ed) return NULL; 03025 03026 for (seq=ed->seqbasep->first; seq; seq= seq->next) { 03027 if(seq->flag & SEQ_MUTE || seq->startdisp > frame || seq->enddisp <= frame) 03028 continue; 03029 /* only use elements you can see - not */ 03030 if (ELEM5(seq->type, SEQ_IMAGE, SEQ_META, SEQ_SCENE, SEQ_MOVIE, SEQ_COLOR)) { 03031 if (seq->machine > best_machine) { 03032 best_seq = seq; 03033 best_machine = seq->machine; 03034 } 03035 } 03036 } 03037 return best_seq; 03038 } 03039 03040 /* return 0 if there werent enough space */ 03041 int shuffle_seq(ListBase * seqbasep, Sequence *test, Scene *evil_scene) 03042 { 03043 int orig_machine= test->machine; 03044 test->machine++; 03045 calc_sequence(evil_scene, test); 03046 while( seq_test_overlap(seqbasep, test) ) { 03047 if(test->machine >= MAXSEQ) { 03048 break; 03049 } 03050 test->machine++; 03051 calc_sequence(evil_scene, test); // XXX - I dont think this is needed since were only moving vertically, Campbell. 03052 } 03053 03054 03055 if(test->machine >= MAXSEQ) { 03056 /* Blender 2.4x would remove the strip. 03057 * nicer to move it to the end */ 03058 03059 Sequence *seq; 03060 int new_frame= test->enddisp; 03061 03062 for(seq= seqbasep->first; seq; seq= seq->next) { 03063 if (seq->machine == orig_machine) 03064 new_frame = MAX2(new_frame, seq->enddisp); 03065 } 03066 03067 test->machine= orig_machine; 03068 new_frame = new_frame + (test->start-test->startdisp); /* adjust by the startdisp */ 03069 seq_translate(evil_scene, test, new_frame - test->start); 03070 03071 calc_sequence(evil_scene, test); 03072 return 0; 03073 } else { 03074 return 1; 03075 } 03076 } 03077 03078 static int shuffle_seq_time_offset_test(ListBase * seqbasep, char dir) 03079 { 03080 int offset= 0; 03081 Sequence *seq, *seq_other; 03082 03083 for(seq= seqbasep->first; seq; seq= seq->next) { 03084 if(seq->tmp) { 03085 for(seq_other= seqbasep->first; seq_other; seq_other= seq_other->next) { 03086 if(!seq_other->tmp && seq_overlap(seq, seq_other)) { 03087 if(dir=='L') { 03088 offset= MIN2(offset, seq_other->startdisp - seq->enddisp); 03089 } 03090 else { 03091 offset= MAX2(offset, seq_other->enddisp - seq->startdisp); 03092 } 03093 } 03094 } 03095 } 03096 } 03097 return offset; 03098 } 03099 03100 static int shuffle_seq_time_offset(Scene* scene, ListBase * seqbasep, char dir) 03101 { 03102 int ofs= 0; 03103 int tot_ofs= 0; 03104 Sequence *seq; 03105 while( (ofs= shuffle_seq_time_offset_test(seqbasep, dir)) ) { 03106 for(seq= seqbasep->first; seq; seq= seq->next) { 03107 if(seq->tmp) { 03108 /* seq_test_overlap only tests display values */ 03109 seq->startdisp += ofs; 03110 seq->enddisp += ofs; 03111 } 03112 } 03113 03114 tot_ofs+= ofs; 03115 } 03116 03117 for(seq= seqbasep->first; seq; seq= seq->next) { 03118 if(seq->tmp) 03119 calc_sequence_disp(scene, seq); /* corrects dummy startdisp/enddisp values */ 03120 } 03121 03122 return tot_ofs; 03123 } 03124 03125 int shuffle_seq_time(ListBase * seqbasep, Scene *evil_scene) 03126 { 03127 /* note: seq->tmp is used to tag strips to move */ 03128 03129 Sequence *seq; 03130 03131 int offset_l = shuffle_seq_time_offset(evil_scene, seqbasep, 'L'); 03132 int offset_r = shuffle_seq_time_offset(evil_scene, seqbasep, 'R'); 03133 int offset = (-offset_l < offset_r) ? offset_l:offset_r; 03134 03135 if(offset) { 03136 for(seq= seqbasep->first; seq; seq= seq->next) { 03137 if(seq->tmp) { 03138 seq_translate(evil_scene, seq, offset); 03139 seq->flag &= ~SEQ_OVERLAP; 03140 } 03141 } 03142 } 03143 03144 return offset? 0:1; 03145 } 03146 03147 void seq_update_sound(Scene* scene, Sequence *seq) 03148 { 03149 if(seq->scene_sound) 03150 { 03151 sound_move_scene_sound(scene, seq->scene_sound, seq->startdisp, seq->enddisp, seq->startofs + seq->anim_startofs); 03152 /* mute is set in seq_update_muting_recursive */ 03153 } 03154 } 03155 03156 static void seq_update_muting_recursive(Scene *scene, ListBase *seqbasep, Sequence *metaseq, int mute) 03157 { 03158 Sequence *seq; 03159 int seqmute; 03160 03161 /* for sound we go over full meta tree to update muted state, 03162 since sound is played outside of evaluating the imbufs, */ 03163 for(seq=seqbasep->first; seq; seq=seq->next) { 03164 seqmute= (mute || (seq->flag & SEQ_MUTE)); 03165 03166 if(seq->type == SEQ_META) { 03167 /* if this is the current meta sequence, unmute because 03168 all sequences above this were set to mute */ 03169 if(seq == metaseq) 03170 seqmute= 0; 03171 03172 seq_update_muting_recursive(scene, &seq->seqbase, metaseq, seqmute); 03173 } 03174 else if(ELEM(seq->type, SEQ_SOUND, SEQ_SCENE)) { 03175 if(seq->scene_sound) { 03176 sound_mute_scene_sound(scene, seq->scene_sound, seqmute); 03177 } 03178 } 03179 } 03180 } 03181 03182 void seq_update_muting(Scene *scene, Editing *ed) 03183 { 03184 if(ed) { 03185 /* mute all sounds up to current metastack list */ 03186 MetaStack *ms= ed->metastack.last; 03187 03188 if(ms) 03189 seq_update_muting_recursive(scene, &ed->seqbase, ms->parseq, 1); 03190 else 03191 seq_update_muting_recursive(scene, &ed->seqbase, NULL, 0); 03192 } 03193 } 03194 03195 /* in cases where we done know the sequence's listbase */ 03196 ListBase *seq_seqbase(ListBase *seqbase, Sequence *seq) 03197 { 03198 Sequence *iseq; 03199 ListBase *lb= NULL; 03200 03201 for(iseq= seqbase->first; iseq; iseq= iseq->next) { 03202 if(seq==iseq) { 03203 return seqbase; 03204 } 03205 else if(iseq->seqbase.first && (lb= seq_seqbase(&iseq->seqbase, seq))) { 03206 return lb; 03207 } 03208 } 03209 03210 return NULL; 03211 } 03212 03213 Sequence *seq_metastrip(ListBase * seqbase, Sequence * meta, Sequence *seq) 03214 { 03215 Sequence * iseq; 03216 03217 for(iseq = seqbase->first; iseq; iseq = iseq->next) { 03218 Sequence * rval; 03219 03220 if (seq == iseq) { 03221 return meta; 03222 } else if(iseq->seqbase.first && 03223 (rval = seq_metastrip(&iseq->seqbase, iseq, seq))) { 03224 return rval; 03225 } 03226 } 03227 03228 return NULL; 03229 } 03230 03231 int seq_swap(Sequence *seq_a, Sequence *seq_b, const char **error_str) 03232 { 03233 char name[sizeof(seq_a->name)]; 03234 03235 if(seq_a->len != seq_b->len) { 03236 *error_str= "Strips must be the same length"; 03237 return 0; 03238 } 03239 03240 /* type checking, could be more advanced but disalow sound vs non-sound copy */ 03241 if(seq_a->type != seq_b->type) { 03242 if(seq_a->type == SEQ_SOUND || seq_b->type == SEQ_SOUND) { 03243 *error_str= "Strips were not compatible"; 03244 return 0; 03245 } 03246 03247 /* disallow effects to swap with non-effects strips */ 03248 if((seq_a->type & SEQ_EFFECT) != (seq_b->type & SEQ_EFFECT)) { 03249 *error_str= "Strips were not compatible"; 03250 return 0; 03251 } 03252 03253 if((seq_a->type & SEQ_EFFECT) && (seq_b->type & SEQ_EFFECT)) { 03254 if(get_sequence_effect_num_inputs(seq_a->type) != get_sequence_effect_num_inputs(seq_b->type)) { 03255 *error_str= "Strips must have the same number of inputs"; 03256 return 0; 03257 } 03258 } 03259 } 03260 03261 SWAP(Sequence, *seq_a, *seq_b); 03262 03263 /* swap back names so animation fcurves dont get swapped */ 03264 strcpy(name, seq_a->name+2); 03265 strcpy(seq_a->name+2, seq_b->name+2); 03266 strcpy(seq_b->name+2, name); 03267 03268 /* swap back opacity, and overlay mode */ 03269 SWAP(int, seq_a->blend_mode, seq_b->blend_mode); 03270 SWAP(float, seq_a->blend_opacity, seq_b->blend_opacity); 03271 03272 03273 SWAP(void *, seq_a->prev, seq_b->prev); 03274 SWAP(void *, seq_a->next, seq_b->next); 03275 SWAP(int, seq_a->start, seq_b->start); 03276 SWAP(int, seq_a->startofs, seq_b->startofs); 03277 SWAP(int, seq_a->endofs, seq_b->endofs); 03278 SWAP(int, seq_a->startstill, seq_b->startstill); 03279 SWAP(int, seq_a->endstill, seq_b->endstill); 03280 SWAP(int, seq_a->machine, seq_b->machine); 03281 SWAP(int, seq_a->startdisp, seq_b->startdisp); 03282 SWAP(int, seq_a->enddisp, seq_b->enddisp); 03283 03284 return 1; 03285 } 03286 03287 /* XXX - hackish function needed for transforming strips! TODO - have some better solution */ 03288 void seq_offset_animdata(Scene *scene, Sequence *seq, int ofs) 03289 { 03290 char str[32]; 03291 FCurve *fcu; 03292 03293 if(scene->adt==NULL || ofs==0 || scene->adt->action==NULL) 03294 return; 03295 03296 sprintf(str, "[\"%s\"]", seq->name+2); 03297 03298 for (fcu= scene->adt->action->curves.first; fcu; fcu= fcu->next) { 03299 if(strstr(fcu->rna_path, "sequence_editor.sequences_all[") && strstr(fcu->rna_path, str)) { 03300 unsigned int i; 03301 for (i = 0; i < fcu->totvert; i++) { 03302 BezTriple *bezt= &fcu->bezt[i]; 03303 bezt->vec[0][0] += ofs; 03304 bezt->vec[1][0] += ofs; 03305 bezt->vec[2][0] += ofs; 03306 } 03307 } 03308 } 03309 } 03310 03311 void seq_dupe_animdata(Scene *scene, char *name_from, char *name_to) 03312 { 03313 char str_from[32]; 03314 FCurve *fcu; 03315 FCurve *fcu_last; 03316 FCurve *fcu_cpy; 03317 ListBase lb= {NULL, NULL}; 03318 03319 if(scene->adt==NULL || scene->adt->action==NULL) 03320 return; 03321 03322 sprintf(str_from, "[\"%s\"]", name_from); 03323 03324 fcu_last= scene->adt->action->curves.last; 03325 03326 for (fcu= scene->adt->action->curves.first; fcu && fcu->prev != fcu_last; fcu= fcu->next) { 03327 if(strstr(fcu->rna_path, "sequence_editor.sequences_all[") && strstr(fcu->rna_path, str_from)) { 03328 fcu_cpy= copy_fcurve(fcu); 03329 BLI_addtail(&lb, fcu_cpy); 03330 } 03331 } 03332 03333 /* notice validate is 0, keep this because the seq may not be added to the scene yet */ 03334 BKE_animdata_fix_paths_rename(&scene->id, scene->adt, "sequence_editor.sequences_all", name_from, name_to, 0, 0, 0); 03335 03336 /* add the original fcurves back */ 03337 BLI_movelisttolist(&scene->adt->action->curves, &lb); 03338 } 03339 03340 /* XXX - hackish function needed to remove all fcurves belonging to a sequencer strip */ 03341 static void seq_free_animdata(Scene *scene, Sequence *seq) 03342 { 03343 char str[32]; 03344 FCurve *fcu; 03345 03346 if(scene->adt==NULL || scene->adt->action==NULL) 03347 return; 03348 03349 sprintf(str, "[\"%s\"]", seq->name+2); 03350 03351 fcu= scene->adt->action->curves.first; 03352 03353 while (fcu) { 03354 if(strstr(fcu->rna_path, "sequence_editor.sequences_all[") && strstr(fcu->rna_path, str)) { 03355 FCurve *next_fcu = fcu->next; 03356 03357 BLI_remlink(&scene->adt->action->curves, fcu); 03358 free_fcurve(fcu); 03359 03360 fcu = next_fcu; 03361 } else { 03362 fcu = fcu->next; 03363 } 03364 } 03365 } 03366 03367 03368 Sequence *get_seq_by_name(ListBase *seqbase, const char *name, int recursive) 03369 { 03370 Sequence *iseq=NULL; 03371 Sequence *rseq=NULL; 03372 03373 for (iseq=seqbase->first; iseq; iseq=iseq->next) { 03374 if (strcmp(name, iseq->name+2) == 0) 03375 return iseq; 03376 else if(recursive && (iseq->seqbase.first) && (rseq=get_seq_by_name(&iseq->seqbase, name, 1))) { 03377 return rseq; 03378 } 03379 } 03380 03381 return NULL; 03382 } 03383 03384 03385 Sequence *seq_active_get(Scene *scene) 03386 { 03387 Editing *ed= seq_give_editing(scene, FALSE); 03388 if(ed==NULL) return NULL; 03389 return ed->act_seq; 03390 } 03391 03392 void seq_active_set(Scene *scene, Sequence *seq) 03393 { 03394 Editing *ed= seq_give_editing(scene, FALSE); 03395 if(ed==NULL) return; 03396 03397 ed->act_seq= seq; 03398 } 03399 03400 int seq_active_pair_get(Scene *scene, Sequence **seq_act, Sequence **seq_other) 03401 { 03402 Editing *ed= seq_give_editing(scene, FALSE); 03403 03404 *seq_act= seq_active_get(scene); 03405 03406 if(*seq_act == NULL) { 03407 return 0; 03408 } 03409 else { 03410 Sequence *seq; 03411 03412 *seq_other= NULL; 03413 03414 for(seq= ed->seqbasep->first; seq; seq= seq->next) { 03415 if(seq->flag & SELECT && (seq != (*seq_act))) { 03416 if(*seq_other) { 03417 return 0; 03418 } 03419 else { 03420 *seq_other= seq; 03421 } 03422 } 03423 } 03424 03425 return (*seq_other != NULL); 03426 } 03427 } 03428 03429 /* api like funcs for adding */ 03430 03431 void seq_load_apply(Scene *scene, Sequence *seq, SeqLoadInfo *seq_load) 03432 { 03433 if(seq) { 03434 BLI_strncpy(seq->name+2, seq_load->name, sizeof(seq->name)-2); 03435 seqbase_unique_name_recursive(&scene->ed->seqbase, seq); 03436 03437 if(seq_load->flag & SEQ_LOAD_FRAME_ADVANCE) { 03438 seq_load->start_frame += (seq->enddisp - seq->startdisp); 03439 } 03440 03441 if(seq_load->flag & SEQ_LOAD_REPLACE_SEL) { 03442 seq_load->flag |= SELECT; 03443 seq_active_set(scene, seq); 03444 } 03445 03446 if(seq_load->flag & SEQ_LOAD_SOUND_CACHE) { 03447 if(seq->sound) 03448 sound_cache(seq->sound, 0); 03449 } 03450 03451 seq_load->tot_success++; 03452 } 03453 else { 03454 seq_load->tot_error++; 03455 } 03456 } 03457 03458 Sequence *alloc_sequence(ListBase *lb, int cfra, int machine) 03459 { 03460 Sequence *seq; 03461 03462 seq= MEM_callocN( sizeof(Sequence), "addseq"); 03463 BLI_addtail(lb, seq); 03464 03465 *( (short *)seq->name )= ID_SEQ; 03466 seq->name[2]= 0; 03467 03468 seq->flag= SELECT; 03469 seq->start= cfra; 03470 seq->machine= machine; 03471 seq->sat= 1.0; 03472 seq->mul= 1.0; 03473 seq->blend_opacity = 100.0; 03474 seq->volume = 1.0f; 03475 seq->scene_sound = NULL; 03476 03477 return seq; 03478 } 03479 03480 /* NOTE: this function doesn't fill in image names */ 03481 Sequence *sequencer_add_image_strip(bContext *C, ListBase *seqbasep, SeqLoadInfo *seq_load) 03482 { 03483 Scene *scene= CTX_data_scene(C); /* only for active seq */ 03484 Sequence *seq; 03485 Strip *strip; 03486 03487 seq = alloc_sequence(seqbasep, seq_load->start_frame, seq_load->channel); 03488 seq->type= SEQ_IMAGE; 03489 seq->blend_mode= SEQ_CROSS; /* so alpha adjustment fade to the strip below */ 03490 03491 /* basic defaults */ 03492 seq->strip= strip= MEM_callocN(sizeof(Strip), "strip"); 03493 03494 strip->len = seq->len = seq_load->len ? seq_load->len : 1; 03495 strip->us= 1; 03496 strip->stripdata= MEM_callocN(seq->len*sizeof(StripElem), "stripelem"); 03497 BLI_strncpy(strip->dir, seq_load->path, sizeof(strip->dir)); 03498 03499 seq_load_apply(scene, seq, seq_load); 03500 03501 return seq; 03502 } 03503 03504 #ifdef WITH_AUDASPACE 03505 Sequence *sequencer_add_sound_strip(bContext *C, ListBase *seqbasep, SeqLoadInfo *seq_load) 03506 { 03507 Scene *scene= CTX_data_scene(C); /* only for sound */ 03508 Editing *ed= seq_give_editing(scene, TRUE); 03509 bSound *sound; 03510 03511 Sequence *seq; /* generic strip vars */ 03512 Strip *strip; 03513 StripElem *se; 03514 03515 AUD_SoundInfo info; 03516 03517 sound = sound_new_file(CTX_data_main(C), seq_load->path); /* handles relative paths */ 03518 03519 if (sound==NULL || sound->playback_handle == NULL) { 03520 //if(op) 03521 // BKE_report(op->reports, RPT_ERROR, "Unsupported audio format"); 03522 return NULL; 03523 } 03524 03525 info = AUD_getInfo(sound->playback_handle); 03526 03527 if (info.specs.channels == AUD_CHANNELS_INVALID) { 03528 sound_delete(C, sound); 03529 //if(op) 03530 // BKE_report(op->reports, RPT_ERROR, "Unsupported audio format"); 03531 return NULL; 03532 } 03533 03534 seq = alloc_sequence(seqbasep, seq_load->start_frame, seq_load->channel); 03535 03536 seq->type= SEQ_SOUND; 03537 seq->sound= sound; 03538 BLI_strncpy(seq->name+2, "Sound", SEQ_NAME_MAXSTR-2); 03539 seqbase_unique_name_recursive(&scene->ed->seqbase, seq); 03540 03541 /* basic defaults */ 03542 seq->strip= strip= MEM_callocN(sizeof(Strip), "strip"); 03543 strip->len = seq->len = ceil(info.length * FPS); 03544 strip->us= 1; 03545 03546 /* we only need 1 element to store the filename */ 03547 strip->stripdata= se= MEM_callocN(sizeof(StripElem), "stripelem"); 03548 03549 BLI_split_dirfile(seq_load->path, strip->dir, se->name); 03550 03551 seq->scene_sound = sound_add_scene_sound(scene, seq, seq_load->start_frame, seq_load->start_frame + strip->len, 0); 03552 03553 calc_sequence_disp(scene, seq); 03554 03555 /* last active name */ 03556 strncpy(ed->act_sounddir, strip->dir, FILE_MAXDIR-1); 03557 03558 seq_load_apply(scene, seq, seq_load); 03559 03560 return seq; 03561 } 03562 #else // WITH_AUDASPACE 03563 Sequence *sequencer_add_sound_strip(bContext *C, ListBase *seqbasep, SeqLoadInfo *seq_load) 03564 { 03565 (void)C; 03566 (void)seqbasep; 03567 (void)seq_load; 03568 return NULL; 03569 } 03570 #endif // WITH_AUDASPACE 03571 03572 Sequence *sequencer_add_movie_strip(bContext *C, ListBase *seqbasep, SeqLoadInfo *seq_load) 03573 { 03574 Scene *scene= CTX_data_scene(C); /* only for sound */ 03575 char path[sizeof(seq_load->path)]; 03576 03577 Sequence *seq; /* generic strip vars */ 03578 Strip *strip; 03579 StripElem *se; 03580 03581 struct anim *an; 03582 03583 BLI_strncpy(path, seq_load->path, sizeof(path)); 03584 BLI_path_abs(path, G.main->name); 03585 03586 an = openanim(path, IB_rect); 03587 03588 if(an==NULL) 03589 return NULL; 03590 03591 seq = alloc_sequence(seqbasep, seq_load->start_frame, seq_load->channel); 03592 seq->type= SEQ_MOVIE; 03593 seq->blend_mode= SEQ_CROSS; /* so alpha adjustment fade to the strip below */ 03594 03595 seq->anim= an; 03596 seq->anim_preseek = IMB_anim_get_preseek(an); 03597 BLI_strncpy(seq->name+2, "Movie", SEQ_NAME_MAXSTR-2); 03598 seqbase_unique_name_recursive(&scene->ed->seqbase, seq); 03599 03600 /* basic defaults */ 03601 seq->strip= strip= MEM_callocN(sizeof(Strip), "strip"); 03602 strip->len = seq->len = IMB_anim_get_duration( an ); 03603 strip->us= 1; 03604 03605 /* we only need 1 element for MOVIE strips */ 03606 strip->stripdata= se= MEM_callocN(sizeof(StripElem), "stripelem"); 03607 03608 BLI_split_dirfile(seq_load->path, strip->dir, se->name); 03609 03610 calc_sequence_disp(scene, seq); 03611 03612 03613 if(seq_load->flag & SEQ_LOAD_MOVIE_SOUND) { 03614 int start_frame_back= seq_load->start_frame; 03615 seq_load->channel++; 03616 03617 sequencer_add_sound_strip(C, seqbasep, seq_load); 03618 03619 seq_load->start_frame= start_frame_back; 03620 seq_load->channel--; 03621 } 03622 03623 if(seq_load->name[0] == '\0') 03624 BLI_strncpy(seq_load->name, se->name, sizeof(seq_load->name)); 03625 03626 /* can be NULL */ 03627 seq_load_apply(scene, seq, seq_load); 03628 03629 return seq; 03630 } 03631 03632 03633 static Sequence *seq_dupli(struct Scene *scene, struct Scene *scene_to, Sequence *seq, int dupe_flag) 03634 { 03635 Scene *sce_audio= scene_to ? scene_to : scene; 03636 Sequence *seqn = MEM_dupallocN(seq); 03637 03638 seq->tmp = seqn; 03639 seqn->strip= MEM_dupallocN(seq->strip); 03640 03641 // XXX: add F-Curve duplication stuff? 03642 03643 if (seq->strip->crop) { 03644 seqn->strip->crop = MEM_dupallocN(seq->strip->crop); 03645 } 03646 03647 if (seq->strip->transform) { 03648 seqn->strip->transform = MEM_dupallocN(seq->strip->transform); 03649 } 03650 03651 if (seq->strip->proxy) { 03652 seqn->strip->proxy = MEM_dupallocN(seq->strip->proxy); 03653 seqn->strip->proxy->anim = NULL; 03654 } 03655 03656 if (seq->strip->color_balance) { 03657 seqn->strip->color_balance 03658 = MEM_dupallocN(seq->strip->color_balance); 03659 } 03660 03661 if(seq->type==SEQ_META) { 03662 seqn->strip->stripdata = NULL; 03663 03664 seqn->seqbase.first= seqn->seqbase.last= NULL; 03665 /* WATCH OUT!!! - This metastrip is not recursively duplicated here - do this after!!! */ 03666 /* - seq_dupli_recursive(&seq->seqbase,&seqn->seqbase);*/ 03667 } else if(seq->type == SEQ_SCENE) { 03668 seqn->strip->stripdata = NULL; 03669 if(seq->scene_sound) 03670 seqn->scene_sound = sound_scene_add_scene_sound(sce_audio, seqn, seq->startdisp, seq->enddisp, seq->startofs + seq->anim_startofs); 03671 } else if(seq->type == SEQ_MOVIE) { 03672 seqn->strip->stripdata = 03673 MEM_dupallocN(seq->strip->stripdata); 03674 seqn->anim= NULL; 03675 } else if(seq->type == SEQ_SOUND) { 03676 seqn->strip->stripdata = 03677 MEM_dupallocN(seq->strip->stripdata); 03678 if(seq->scene_sound) 03679 seqn->scene_sound = sound_add_scene_sound(sce_audio, seqn, seq->startdisp, seq->enddisp, seq->startofs + seq->anim_startofs); 03680 03681 seqn->sound->id.us++; 03682 } else if(seq->type == SEQ_IMAGE) { 03683 seqn->strip->stripdata = 03684 MEM_dupallocN(seq->strip->stripdata); 03685 } else if(seq->type >= SEQ_EFFECT) { 03686 if(seq->seq1 && seq->seq1->tmp) seqn->seq1= seq->seq1->tmp; 03687 if(seq->seq2 && seq->seq2->tmp) seqn->seq2= seq->seq2->tmp; 03688 if(seq->seq3 && seq->seq3->tmp) seqn->seq3= seq->seq3->tmp; 03689 03690 if (seq->type & SEQ_EFFECT) { 03691 struct SeqEffectHandle sh; 03692 sh = get_sequence_effect(seq); 03693 if(sh.copy) 03694 sh.copy(seq, seqn); 03695 } 03696 03697 seqn->strip->stripdata = NULL; 03698 03699 } else { 03700 fprintf(stderr, "Aiiiiekkk! sequence type not " 03701 "handled in duplicate!\nExpect a crash" 03702 " now...\n"); 03703 } 03704 03705 if(dupe_flag & SEQ_DUPE_UNIQUE_NAME) 03706 seqbase_unique_name_recursive(&scene->ed->seqbase, seqn); 03707 03708 if(dupe_flag & SEQ_DUPE_ANIM) 03709 seq_dupe_animdata(scene, seq->name+2, seqn->name+2); 03710 03711 return seqn; 03712 } 03713 03714 Sequence * seq_dupli_recursive(struct Scene *scene, struct Scene *scene_to, Sequence * seq, int dupe_flag) 03715 { 03716 Sequence * seqn = seq_dupli(scene, scene_to, seq, dupe_flag); 03717 if (seq->type == SEQ_META) { 03718 Sequence *s; 03719 for(s= seq->seqbase.first; s; s = s->next) { 03720 Sequence *n = seq_dupli_recursive(scene, scene_to, s, dupe_flag); 03721 if (n) { 03722 BLI_addtail(&seqn->seqbase, n); 03723 } 03724 } 03725 } 03726 return seqn; 03727 } 03728 03729 void seqbase_dupli_recursive(Scene *scene, Scene *scene_to, ListBase *nseqbase, ListBase *seqbase, int dupe_flag) 03730 { 03731 Sequence *seq; 03732 Sequence *seqn = NULL; 03733 Sequence *last_seq = seq_active_get(scene); 03734 03735 for(seq= seqbase->first; seq; seq= seq->next) { 03736 seq->tmp= NULL; 03737 if((seq->flag & SELECT) || (dupe_flag & SEQ_DUPE_ALL)) { 03738 seqn = seq_dupli(scene, scene_to, seq, dupe_flag); 03739 if (seqn) { /*should never fail */ 03740 if(dupe_flag & SEQ_DUPE_CONTEXT) { 03741 seq->flag &= ~SEQ_ALLSEL; 03742 seqn->flag &= ~(SEQ_LEFTSEL+SEQ_RIGHTSEL+SEQ_LOCK); 03743 } 03744 03745 BLI_addtail(nseqbase, seqn); 03746 if(seq->type==SEQ_META) 03747 seqbase_dupli_recursive(scene, scene_to, &seqn->seqbase, &seq->seqbase, dupe_flag); 03748 03749 if(dupe_flag & SEQ_DUPE_CONTEXT) { 03750 if (seq == last_seq) { 03751 seq_active_set(scene, seqn); 03752 } 03753 } 03754 } 03755 } 03756 } 03757 }