[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [58565] trunk/blender: fix [#36262] Paste strip with video or sound content from another file crashes Blender

Campbell Barton ideasman42 at gmail.com
Wed Jul 24 08:51:04 CEST 2013


Revision: 58565
          http://projects.blender.org/scm/viewvc.php?view=rev&root=bf-blender&revision=58565
Author:   campbellbarton
Date:     2013-07-24 06:51:04 +0000 (Wed, 24 Jul 2013)
Log Message:
-----------
fix [#36262] Paste strip with video or sound content from another file crashes Blender

existing code was very stupid.

- all ID pointers for clipboard strips are handled uniformly.
- clipboard stores a duplicate ID pointer which are restored on paste.
- restoring pointers...
-- use ID's that are still in the database (copy&paste within the same file).
-- fallback to name lookup.
-- fallback to loading them from the original filepath (movie-clip and sound only).

also fix bug pasting where initialing the sound wasn't done if there was no frame-offset.

Modified Paths:
--------------
    trunk/blender/release/scripts/startup/bl_ui/space_sequencer.py
    trunk/blender/source/blender/blenkernel/BKE_sequencer.h
    trunk/blender/source/blender/blenkernel/intern/mask.c
    trunk/blender/source/blender/blenkernel/intern/movieclip.c
    trunk/blender/source/blender/blenkernel/intern/sequencer.c
    trunk/blender/source/blender/blenloader/intern/readfile.c
    trunk/blender/source/blender/editors/space_sequencer/sequencer_edit.c

Modified: trunk/blender/release/scripts/startup/bl_ui/space_sequencer.py
===================================================================
--- trunk/blender/release/scripts/startup/bl_ui/space_sequencer.py	2013-07-24 05:39:38 UTC (rev 58564)
+++ trunk/blender/release/scripts/startup/bl_ui/space_sequencer.py	2013-07-24 06:51:04 UTC (rev 58565)
@@ -671,13 +671,14 @@
         layout.separator()
         layout.prop(strip, "filepath", text="")
 
-        row = layout.row()
-        if sound.packed_file:
-            row.operator("sound.unpack", icon='PACKAGE', text="Unpack")
-        else:
-            row.operator("sound.pack", icon='UGLYPACKAGE', text="Pack")
+        if sound is not None:
+            row = layout.row()
+            if sound.packed_file:
+                row.operator("sound.unpack", icon='PACKAGE', text="Unpack")
+            else:
+                row.operator("sound.pack", icon='UGLYPACKAGE', text="Pack")
 
-        row.prop(sound, "use_memory_cache")
+            row.prop(sound, "use_memory_cache")
 
         layout.prop(strip, "show_waveform")
         layout.prop(strip, "volume")

Modified: trunk/blender/source/blender/blenkernel/BKE_sequencer.h
===================================================================
--- trunk/blender/source/blender/blenkernel/BKE_sequencer.h	2013-07-24 05:39:38 UTC (rev 58564)
+++ trunk/blender/source/blender/blenkernel/BKE_sequencer.h	2013-07-24 06:51:04 UTC (rev 58565)
@@ -208,6 +208,10 @@
 
 void BKE_sequencer_free_clipboard(void);
 
+void BKE_sequence_clipboard_pointers_free(struct Sequence *seq);
+void BKE_sequence_clipboard_pointers_store(struct Sequence *seq);
+void BKE_sequence_clipboard_pointers_restore(struct Sequence *seq, struct Main *bmain);
+
 void BKE_sequence_free(struct Scene *scene, struct Sequence *seq);
 const char *BKE_sequence_give_name(struct Sequence *seq);
 void BKE_sequence_calc(struct Scene *scene, struct Sequence *seq);
@@ -319,8 +323,6 @@
 bool BKE_sequence_is_valid_check(struct Sequence *seq);
 
 void BKE_sequencer_clear_scene_in_allseqs(struct Main *bmain, struct Scene *sce);
-void BKE_sequencer_clear_movieclip_in_clipboard(struct MovieClip *clip);
-void BKE_sequencer_clear_mask_in_clipboard(struct Mask *mask);
 
 struct Sequence *BKE_sequence_get_by_name(struct ListBase *seqbase, const char *name, int recursive);
 

Modified: trunk/blender/source/blender/blenkernel/intern/mask.c
===================================================================
--- trunk/blender/source/blender/blenkernel/intern/mask.c	2013-07-24 05:39:38 UTC (rev 58564)
+++ trunk/blender/source/blender/blenkernel/intern/mask.c	2013-07-24 06:51:04 UTC (rev 58565)
@@ -939,8 +939,6 @@
 	SpaceLink *sl;
 	Scene *scene;
 
-	BKE_sequencer_clear_mask_in_clipboard(mask);
-
 	for (scr = bmain->screen.first; scr; scr = scr->id.next) {
 		for (area = scr->areabase.first; area; area = area->next) {
 			for (sl = area->spacedata.first; sl; sl = sl->next) {

Modified: trunk/blender/source/blender/blenkernel/intern/movieclip.c
===================================================================
--- trunk/blender/source/blender/blenkernel/intern/movieclip.c	2013-07-24 05:39:38 UTC (rev 58564)
+++ trunk/blender/source/blender/blenkernel/intern/movieclip.c	2013-07-24 06:51:04 UTC (rev 58565)
@@ -1395,8 +1395,6 @@
 
 void BKE_movieclip_free(MovieClip *clip)
 {
-	BKE_sequencer_clear_movieclip_in_clipboard(clip);
-
 	free_buffers(clip);
 
 	BKE_tracking_free(&clip->tracking);

Modified: trunk/blender/source/blender/blenkernel/intern/sequencer.c
===================================================================
--- trunk/blender/source/blender/blenkernel/intern/sequencer.c	2013-07-24 05:39:38 UTC (rev 58564)
+++ trunk/blender/source/blender/blenkernel/intern/sequencer.c	2013-07-24 06:51:04 UTC (rev 58565)
@@ -65,6 +65,7 @@
 #include "BKE_fcurve.h"
 #include "BKE_scene.h"
 #include "BKE_mask.h"
+#include "BKE_library.h"
 
 #include "RNA_access.h"
 
@@ -265,6 +266,7 @@
 		seq_free_clipboard_recursive(seq);
 	}
 
+	BKE_sequence_clipboard_pointers_free(seq_parent);
 	BKE_sequence_free_ex(NULL, seq_parent, FALSE);
 }
 
@@ -279,6 +281,101 @@
 	seqbase_clipboard.first = seqbase_clipboard.last = NULL;
 }
 
+/* -------------------------------------------------------------------- */
+/* Manage pointers in the clipboard.
+ * note that these pointers should _never_ be access in the sequencer,
+ * they are only for storage while in the clipboard
+ * notice 'newid' is used for temp pointer storage here, validate on access.
+ */
+#define ID_PT (*id_pt)
+static void seqclipboard_ptr_free(ID **id_pt)
+{
+	if (ID_PT) {
+		BLI_assert(ID_PT->newid != NULL);
+		MEM_freeN(ID_PT);
+		ID_PT = NULL;
+	}
+}
+static void seqclipboard_ptr_store(ID **id_pt)
+{
+	if (ID_PT) {
+		ID *id_prev = ID_PT;
+		ID_PT = MEM_dupallocN(ID_PT);
+		ID_PT->newid = id_prev;
+	}
+}
+static void seqclipboard_ptr_restore(Main *bmain, ID **id_pt)
+{
+	if (ID_PT) {
+		const ListBase *lb = which_libbase(bmain, GS(ID_PT->name));
+		void *id_restore;
+
+		BLI_assert(ID_PT->newid != NULL);
+		if (BLI_findindex(lb, (ID_PT)->newid) != -1) {
+			/* the pointer is still valid */
+			id_restore = (ID_PT)->newid;
+		}
+		else {
+			/* the pointer of the same name still exists  */
+			id_restore = BLI_findstring(lb, (ID_PT)->name + 2, offsetof(ID, name) + 2);
+		}
+
+		if (id_restore == NULL) {
+			/* check for a data with the same filename */
+			switch (GS(ID_PT->name)) {
+				case ID_SO:
+				{
+					id_restore = BLI_findstring(lb, ((bSound *)ID_PT)->name, offsetof(bSound, name));
+					if (id_restore == NULL) {
+						id_restore = sound_new_file(bmain, ((bSound *)ID_PT)->name);
+						(ID_PT)->newid = id_restore;  /* reuse next time */
+					}
+					break;
+				}
+				case ID_MC:
+				{
+					id_restore = BLI_findstring(lb, ((MovieClip *)ID_PT)->name, offsetof(MovieClip, name));
+					if (id_restore == NULL) {
+						id_restore = BKE_movieclip_file_add(bmain, ((MovieClip *)ID_PT)->name);
+						(ID_PT)->newid = id_restore;  /* reuse next time */
+					}
+					break;
+				}
+			}
+		}
+
+		ID_PT = id_restore;
+	}
+}
+#undef ID_PT
+
+void BKE_sequence_clipboard_pointers_free(Sequence *seq)
+{
+	seqclipboard_ptr_free((ID **)&seq->scene);
+	seqclipboard_ptr_free((ID **)&seq->scene_camera);
+	seqclipboard_ptr_free((ID **)&seq->clip);
+	seqclipboard_ptr_free((ID **)&seq->mask);
+	seqclipboard_ptr_free((ID **)&seq->sound);
+}
+void BKE_sequence_clipboard_pointers_store(Sequence *seq)
+{
+	seqclipboard_ptr_store((ID **)&seq->scene);
+	seqclipboard_ptr_store((ID **)&seq->scene_camera);
+	seqclipboard_ptr_store((ID **)&seq->clip);
+	seqclipboard_ptr_store((ID **)&seq->mask);
+	seqclipboard_ptr_store((ID **)&seq->sound);
+}
+void BKE_sequence_clipboard_pointers_restore(Sequence *seq, Main *bmain)
+{
+	seqclipboard_ptr_restore(bmain, (ID **)&seq->scene);
+	seqclipboard_ptr_restore(bmain, (ID **)&seq->scene_camera);
+	seqclipboard_ptr_restore(bmain, (ID **)&seq->clip);
+	seqclipboard_ptr_restore(bmain, (ID **)&seq->mask);
+	seqclipboard_ptr_restore(bmain, (ID **)&seq->sound);
+}
+/* end clipboard pointer mess */
+
+
 Editing *BKE_sequencer_editing_ensure(Scene *scene)
 {
 	if (scene->ed == NULL) {
@@ -818,35 +915,8 @@
 			BKE_sequencer_base_recursive_apply(&scene_iter->ed->seqbase, clear_scene_in_allseqs_cb, scene);
 		}
 	}
-
-	/* also clear clipboard */
-	BKE_sequencer_base_recursive_apply(&seqbase_clipboard, clear_scene_in_allseqs_cb, scene);
 }
 
-static int clear_movieclip_in_clipboard_cb(Sequence *seq, void *arg_pt)
-{
-	if (seq->clip == (MovieClip *)arg_pt)
-		seq->clip = NULL;
-	return 1;
-}
-
-void BKE_sequencer_clear_movieclip_in_clipboard(MovieClip *clip)
-{
-	BKE_sequencer_base_recursive_apply(&seqbase_clipboard, clear_movieclip_in_clipboard_cb, clip);
-}
-
-static int clear_mask_in_clipboard_cb(Sequence *seq, void *arg_pt)
-{
-	if (seq->mask == (Mask *)arg_pt)
-		seq->mask = NULL;
-	return 1;
-}
-
-void BKE_sequencer_clear_mask_in_clipboard(Mask *mask)
-{
-	BKE_sequencer_base_recursive_apply(&seqbase_clipboard, clear_mask_in_clipboard_cb, mask);
-}
-
 typedef struct SeqUniqueInfo {
 	Sequence *seq;
 	char name_src[SEQ_NAME_MAXSTR];

Modified: trunk/blender/source/blender/blenloader/intern/readfile.c
===================================================================
--- trunk/blender/source/blender/blenloader/intern/readfile.c	2013-07-24 05:39:38 UTC (rev 58564)
+++ trunk/blender/source/blender/blenloader/intern/readfile.c	2013-07-24 06:51:04 UTC (rev 58565)
@@ -5803,21 +5803,23 @@
 	return NULL;
 }
 
+static void lib_link_seq_clipboard_pt_restore(ID *id, Main *newmain)
+{
+	if (id) {
+		/* clipboard must ensure this */
+		BLI_assert(id->newid != NULL);
+		id->newid = restore_pointer_by_name(newmain, (ID *)id->newid, 1);
+	}
+}
 static int lib_link_seq_clipboard_cb(Sequence *seq, void *arg_pt)
 {
 	Main *newmain = (Main *)arg_pt;
-	
-	if (seq->sound) {
-		seq->sound = restore_pointer_by_name(newmain, (ID *)seq->sound, 0);
-		seq->sound->id.us++;
-	}
-	
-	if (seq->scene)
-		seq->scene = restore_pointer_by_name(newmain, (ID *)seq->scene, 1);
-	
-	if (seq->scene_camera)
-		seq->scene_camera = restore_pointer_by_name(newmain, (ID *)seq->scene_camera, 1);
-	
+
+	lib_link_seq_clipboard_pt_restore((ID *)seq->scene, newmain);
+	lib_link_seq_clipboard_pt_restore((ID *)seq->scene_camera, newmain);
+	lib_link_seq_clipboard_pt_restore((ID *)seq->clip, newmain);
+	lib_link_seq_clipboard_pt_restore((ID *)seq->mask, newmain);
+	lib_link_seq_clipboard_pt_restore((ID *)seq->sound, newmain);
 	return 1;
 }
 

Modified: trunk/blender/source/blender/editors/space_sequencer/sequencer_edit.c
===================================================================
--- trunk/blender/source/blender/editors/space_sequencer/sequencer_edit.c	2013-07-24 05:39:38 UTC (rev 58564)
+++ trunk/blender/source/blender/editors/space_sequencer/sequencer_edit.c	2013-07-24 06:51:04 UTC (rev 58565)
@@ -2721,7 +2721,6 @@
 	}
 }
 
-/* TODO, validate scenes */
 static int sequencer_copy_exec(bContext *C, wmOperator *op)
 {
 	Scene *scene = CTX_data_scene(C);
@@ -2766,6 +2765,11 @@
 		for (seq = seqbase_clipboard.first; seq; seq = seq->next) {
 			seq_copy_del_sound(scene, seq);
 		}
+
+		/* duplicate pointers */
+		for (seq = seqbase_clipboard.first; seq; seq = seq->next) {
+			BKE_sequence_clipboard_pointers_store(seq);
+		}
 	}
 
 	return OPERATOR_FINISHED;
@@ -2790,6 +2794,7 @@
 
 static int sequencer_paste_exec(bContext *C, wmOperator *UNUSED(op))
 {
+	Main *bmain = CTX_data_main(C);
 	Scene *scene = CTX_data_scene(C);

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list