1 /*
2  * This program is free software; you can redistribute it and/or
3  * modify it under the terms of the GNU General Public License
4  * as published by the Free Software Foundation; either version 2
5  * of the License, or (at your option) any later version.
6  *
7  * This program is distributed in the hope that it will be useful,
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
10  * GNU General Public License for more details.
11  *
12  * You should have received a copy of the GNU General Public License
13  * along with this program; if not, write to the Free Software Foundation,
14  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
15  */
16 
17 /** \file
18  * \ingroup RNA
19  */
20 
21 #include <limits.h>
22 #include <stdlib.h>
23 
24 #include "MEM_guardedalloc.h"
25 
26 #include "DNA_movieclip_types.h"
27 #include "DNA_scene_types.h"
28 
29 #include "RNA_access.h"
30 #include "RNA_define.h"
31 
32 #include "rna_internal.h"
33 
34 #include "BKE_movieclip.h"
35 #include "BKE_tracking.h"
36 
37 #include "WM_types.h"
38 
39 #include "IMB_imbuf.h"
40 #include "IMB_imbuf_types.h"
41 #include "IMB_metadata.h"
42 
43 #ifdef RNA_RUNTIME
44 
45 #  include "DEG_depsgraph.h"
46 
47 #  include "ED_clip.h"
48 
49 #  include "BKE_sequencer.h"
50 
51 #  include "DNA_screen_types.h"
52 #  include "DNA_space_types.h"
53 
rna_MovieClip_reload_update(Main * UNUSED (bmain),Scene * UNUSED (scene),PointerRNA * ptr)54 static void rna_MovieClip_reload_update(Main *UNUSED(bmain), Scene *UNUSED(scene), PointerRNA *ptr)
55 {
56   MovieClip *clip = (MovieClip *)ptr->owner_id;
57 
58   DEG_id_tag_update(&clip->id, ID_RECALC_SOURCE);
59 }
60 
rna_MovieClip_size_get(PointerRNA * ptr,int * values)61 static void rna_MovieClip_size_get(PointerRNA *ptr, int *values)
62 {
63   MovieClip *clip = (MovieClip *)ptr->owner_id;
64 
65   values[0] = clip->lastsize[0];
66   values[1] = clip->lastsize[1];
67 }
68 
rna_MovieClip_fps_get(PointerRNA * ptr)69 static float rna_MovieClip_fps_get(PointerRNA *ptr)
70 {
71   MovieClip *clip = (MovieClip *)ptr->owner_id;
72   return BKE_movieclip_get_fps(clip);
73 }
74 
rna_MovieClip_use_proxy_update(Main * bmain,Scene * UNUSED (scene),PointerRNA * ptr)75 static void rna_MovieClip_use_proxy_update(Main *bmain, Scene *UNUSED(scene), PointerRNA *ptr)
76 {
77   MovieClip *clip = (MovieClip *)ptr->owner_id;
78   BKE_movieclip_clear_cache(clip);
79   BKE_sequence_invalidate_movieclip_strips(bmain, clip);
80 }
81 
rna_MovieClipUser_proxy_render_settings_update(Main * bmain,Scene * UNUSED (scene),PointerRNA * ptr)82 static void rna_MovieClipUser_proxy_render_settings_update(Main *bmain,
83                                                            Scene *UNUSED(scene),
84                                                            PointerRNA *ptr)
85 {
86   ID *id = ptr->owner_id;
87   MovieClipUser *user = (MovieClipUser *)ptr->data;
88 
89   /* when changing render settings of space clip user
90    * clear cache for clip, so all the memory is available
91    * for new render settings
92    */
93   if (GS(id->name) == ID_SCR) {
94     bScreen *screen = (bScreen *)id;
95     ScrArea *area;
96     SpaceLink *sl;
97 
98     for (area = screen->areabase.first; area; area = area->next) {
99       for (sl = area->spacedata.first; sl; sl = sl->next) {
100         if (sl->spacetype == SPACE_CLIP) {
101           SpaceClip *sc = (SpaceClip *)sl;
102 
103           if (&sc->user == user) {
104             MovieClip *clip = ED_space_clip_get_clip(sc);
105 
106             if (clip && (clip->flag & MCLIP_USE_PROXY)) {
107               BKE_movieclip_clear_cache(clip);
108               BKE_sequence_invalidate_movieclip_strips(bmain, clip);
109             }
110 
111             break;
112           }
113         }
114       }
115     }
116   }
117 }
118 
rna_MovieClip_metadata_get(MovieClip * clip)119 static PointerRNA rna_MovieClip_metadata_get(MovieClip *clip)
120 {
121   if (clip == NULL || clip->anim == NULL) {
122     return PointerRNA_NULL;
123   }
124 
125   IDProperty *metadata = IMB_anim_load_metadata(clip->anim);
126   if (metadata == NULL) {
127     return PointerRNA_NULL;
128   }
129 
130   PointerRNA ptr;
131   RNA_pointer_create(NULL, &RNA_IDPropertyWrapPtr, metadata, &ptr);
132   return ptr;
133 }
134 
135 #else
136 
rna_def_movieclip_proxy(BlenderRNA * brna)137 static void rna_def_movieclip_proxy(BlenderRNA *brna)
138 {
139   StructRNA *srna;
140   PropertyRNA *prop;
141 
142   static const EnumPropertyItem clip_tc_items[] = {
143       {IMB_TC_NONE, "NONE", 0, "No TC in use", ""},
144       {IMB_TC_RECORD_RUN,
145        "RECORD_RUN",
146        0,
147        "Record Run",
148        "Use images in the order they are recorded"},
149       {IMB_TC_FREE_RUN,
150        "FREE_RUN",
151        0,
152        "Free Run",
153        "Use global timestamp written by recording device"},
154       {IMB_TC_INTERPOLATED_REC_DATE_FREE_RUN,
155        "FREE_RUN_REC_DATE",
156        0,
157        "Free Run (rec date)",
158        "Interpolate a global timestamp using the record date and time "
159        "written by recording device"},
160       {IMB_TC_RECORD_RUN_NO_GAPS,
161        "FREE_RUN_NO_GAPS",
162        0,
163        "Free Run No Gaps",
164        "Record run, but ignore timecode, changes in framerate or dropouts"},
165       {0, NULL, 0, NULL, NULL},
166   };
167 
168   srna = RNA_def_struct(brna, "MovieClipProxy", NULL);
169   RNA_def_struct_ui_text(srna, "Movie Clip Proxy", "Proxy parameters for a movie clip");
170   RNA_def_struct_sdna(srna, "MovieClipProxy");
171 
172   /* build proxy sized */
173   prop = RNA_def_property(srna, "build_25", PROP_BOOLEAN, PROP_NONE);
174   RNA_def_property_boolean_sdna(prop, NULL, "build_size_flag", MCLIP_PROXY_SIZE_25);
175   RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
176   RNA_def_property_ui_text(
177       prop, "25%", "Build proxy resolution 25% of the original footage dimension");
178 
179   prop = RNA_def_property(srna, "build_50", PROP_BOOLEAN, PROP_NONE);
180   RNA_def_property_boolean_sdna(prop, NULL, "build_size_flag", MCLIP_PROXY_SIZE_50);
181   RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
182   RNA_def_property_ui_text(
183       prop, "50%", "Build proxy resolution 50% of the original footage dimension");
184 
185   prop = RNA_def_property(srna, "build_75", PROP_BOOLEAN, PROP_NONE);
186   RNA_def_property_boolean_sdna(prop, NULL, "build_size_flag", MCLIP_PROXY_SIZE_75);
187   RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
188   RNA_def_property_ui_text(
189       prop, "75%", "Build proxy resolution 75% of the original footage dimension");
190 
191   prop = RNA_def_property(srna, "build_100", PROP_BOOLEAN, PROP_NONE);
192   RNA_def_property_boolean_sdna(prop, NULL, "build_size_flag", MCLIP_PROXY_SIZE_100);
193   RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
194   RNA_def_property_ui_text(
195       prop, "100%", "Build proxy resolution 100% of the original footage dimension");
196 
197   prop = RNA_def_property(srna, "build_undistorted_25", PROP_BOOLEAN, PROP_NONE);
198   RNA_def_property_boolean_sdna(prop, NULL, "build_size_flag", MCLIP_PROXY_UNDISTORTED_SIZE_25);
199   RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
200   RNA_def_property_ui_text(
201       prop, "25%", "Build proxy resolution 25% of the original undistorted footage dimension");
202 
203   prop = RNA_def_property(srna, "build_undistorted_50", PROP_BOOLEAN, PROP_NONE);
204   RNA_def_property_boolean_sdna(prop, NULL, "build_size_flag", MCLIP_PROXY_UNDISTORTED_SIZE_50);
205   RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
206   RNA_def_property_ui_text(
207       prop, "50%", "Build proxy resolution 50% of the original undistorted footage dimension");
208 
209   prop = RNA_def_property(srna, "build_undistorted_75", PROP_BOOLEAN, PROP_NONE);
210   RNA_def_property_boolean_sdna(prop, NULL, "build_size_flag", MCLIP_PROXY_UNDISTORTED_SIZE_75);
211   RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
212   RNA_def_property_ui_text(
213       prop, "75%", "Build proxy resolution 75% of the original undistorted footage dimension");
214 
215   prop = RNA_def_property(srna, "build_undistorted_100", PROP_BOOLEAN, PROP_NONE);
216   RNA_def_property_boolean_sdna(prop, NULL, "build_size_flag", MCLIP_PROXY_UNDISTORTED_SIZE_100);
217   RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
218   RNA_def_property_ui_text(
219       prop, "100%", "Build proxy resolution 100% of the original undistorted footage dimension");
220 
221   /* Build time-codes. */
222   prop = RNA_def_property(srna, "build_record_run", PROP_BOOLEAN, PROP_NONE);
223   RNA_def_property_boolean_sdna(prop, NULL, "build_tc_flag", IMB_TC_RECORD_RUN);
224   RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
225   RNA_def_property_ui_text(prop, "Rec Run", "Build record run time code index");
226 
227   prop = RNA_def_property(srna, "build_free_run", PROP_BOOLEAN, PROP_NONE);
228   RNA_def_property_boolean_sdna(prop, NULL, "build_tc_flag", IMB_TC_FREE_RUN);
229   RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
230   RNA_def_property_ui_text(prop, "Free Run", "Build free run time code index");
231 
232   prop = RNA_def_property(srna, "build_free_run_rec_date", PROP_BOOLEAN, PROP_NONE);
233   RNA_def_property_boolean_sdna(
234       prop, NULL, "build_tc_flag", IMB_TC_INTERPOLATED_REC_DATE_FREE_RUN);
235   RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
236   RNA_def_property_ui_text(
237       prop, "Free Run (Rec Date)", "Build free run time code index using Record Date/Time");
238 
239   /* quality of proxied image */
240   prop = RNA_def_property(srna, "quality", PROP_INT, PROP_UNSIGNED);
241   RNA_def_property_int_sdna(prop, NULL, "quality");
242   RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
243   RNA_def_property_ui_text(prop, "Quality", "JPEG quality of proxy images");
244   RNA_def_property_ui_range(prop, 1, 100, 1, -1);
245 
246   prop = RNA_def_property(srna, "timecode", PROP_ENUM, PROP_NONE);
247   RNA_def_property_enum_sdna(prop, NULL, "tc");
248   RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
249   RNA_def_property_enum_items(prop, clip_tc_items);
250   RNA_def_property_ui_text(prop, "Timecode", "");
251   RNA_def_property_update(prop, NC_MOVIECLIP | ND_DISPLAY, "rna_MovieClip_reload_update");
252 
253   /* directory */
254   prop = RNA_def_property(srna, "directory", PROP_STRING, PROP_DIRPATH);
255   RNA_def_property_string_sdna(prop, NULL, "dir");
256   RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
257   RNA_def_property_ui_text(prop, "Directory", "Location to store the proxy files");
258   RNA_def_property_update(prop, NC_MOVIECLIP | ND_DISPLAY, "rna_MovieClip_reload_update");
259 }
260 
rna_def_moviecliUser(BlenderRNA * brna)261 static void rna_def_moviecliUser(BlenderRNA *brna)
262 {
263   StructRNA *srna;
264   PropertyRNA *prop;
265 
266   static const EnumPropertyItem clip_render_size_items[] = {
267       {MCLIP_PROXY_RENDER_SIZE_25, "PROXY_25", 0, "25%", ""},
268       {MCLIP_PROXY_RENDER_SIZE_50, "PROXY_50", 0, "50%", ""},
269       {MCLIP_PROXY_RENDER_SIZE_75, "PROXY_75", 0, "75%", ""},
270       {MCLIP_PROXY_RENDER_SIZE_100, "PROXY_100", 0, "100%", ""},
271       {MCLIP_PROXY_RENDER_SIZE_FULL, "FULL", 0, "None, full render", ""},
272       {0, NULL, 0, NULL, NULL},
273   };
274 
275   srna = RNA_def_struct(brna, "MovieClipUser", NULL);
276   RNA_def_struct_ui_text(
277       srna,
278       "Movie Clip User",
279       "Parameters defining how a MovieClip data-block is used by another data-block");
280 
281   prop = RNA_def_property(srna, "frame_current", PROP_INT, PROP_TIME);
282   RNA_def_property_int_sdna(prop, NULL, "framenr");
283   RNA_def_property_range(prop, MINAFRAME, MAXFRAME);
284   RNA_def_property_ui_text(
285       prop, "Current Frame", "Current frame number in movie or image sequence");
286 
287   /* render size */
288   prop = RNA_def_property(srna, "proxy_render_size", PROP_ENUM, PROP_NONE);
289   RNA_def_property_enum_sdna(prop, NULL, "render_size");
290   RNA_def_property_enum_items(prop, clip_render_size_items);
291   RNA_def_property_ui_text(prop,
292                            "Proxy Render Size",
293                            "Draw preview using full resolution or different proxy resolutions");
294   RNA_def_property_update(
295       prop, NC_MOVIECLIP | ND_DISPLAY, "rna_MovieClipUser_proxy_render_settings_update");
296 
297   /* render undistorted */
298   prop = RNA_def_property(srna, "use_render_undistorted", PROP_BOOLEAN, PROP_NONE);
299   RNA_def_property_boolean_sdna(prop, NULL, "render_flag", MCLIP_PROXY_RENDER_UNDISTORT);
300   RNA_def_property_ui_text(prop, "Render Undistorted", "Render preview using undistorted proxy");
301   RNA_def_property_update(
302       prop, NC_MOVIECLIP | ND_DISPLAY, "rna_MovieClipUser_proxy_render_settings_update");
303 }
304 
rna_def_movieClipScopes(BlenderRNA * brna)305 static void rna_def_movieClipScopes(BlenderRNA *brna)
306 {
307   StructRNA *srna;
308 
309   srna = RNA_def_struct(brna, "MovieClipScopes", NULL);
310   RNA_def_struct_ui_text(srna, "MovieClipScopes", "Scopes for statistical view of a movie clip");
311 }
312 
rna_def_movieclip(BlenderRNA * brna)313 static void rna_def_movieclip(BlenderRNA *brna)
314 {
315   StructRNA *srna;
316   PropertyRNA *prop;
317   FunctionRNA *func;
318   PropertyRNA *parm;
319 
320   static const EnumPropertyItem clip_source_items[] = {
321       {MCLIP_SRC_SEQUENCE, "SEQUENCE", 0, "Image Sequence", "Multiple image files, as a sequence"},
322       {MCLIP_SRC_MOVIE, "MOVIE", 0, "Movie File", "Movie file"},
323       {0, NULL, 0, NULL, NULL},
324   };
325 
326   srna = RNA_def_struct(brna, "MovieClip", "ID");
327   RNA_def_struct_ui_text(
328       srna, "MovieClip", "MovieClip data-block referencing an external movie file");
329   RNA_def_struct_ui_icon(srna, ICON_SEQUENCE);
330 
331   prop = RNA_def_property(srna, "filepath", PROP_STRING, PROP_FILEPATH);
332   RNA_def_property_string_sdna(prop, NULL, "filepath");
333   RNA_def_property_ui_text(prop, "File Path", "Filename of the movie or sequence file");
334   RNA_def_property_update(prop, NC_MOVIECLIP | ND_DISPLAY, "rna_MovieClip_reload_update");
335 
336   prop = RNA_def_property(srna, "tracking", PROP_POINTER, PROP_NONE);
337   RNA_def_property_struct_type(prop, "MovieTracking");
338 
339   prop = RNA_def_property(srna, "proxy", PROP_POINTER, PROP_NONE);
340   RNA_def_property_struct_type(prop, "MovieClipProxy");
341 
342   /* use proxy */
343   prop = RNA_def_property(srna, "use_proxy", PROP_BOOLEAN, PROP_NONE);
344   RNA_def_property_boolean_sdna(prop, NULL, "flag", MCLIP_USE_PROXY);
345   RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
346   RNA_def_property_ui_text(
347       prop, "Use Proxy / Timecode", "Use a preview proxy and/or timecode index for this clip");
348   RNA_def_property_update(prop, NC_MOVIECLIP | ND_DISPLAY, "rna_MovieClip_use_proxy_update");
349 
350   prop = RNA_def_int_vector(srna,
351                             "size",
352                             2,
353                             NULL,
354                             0,
355                             0,
356                             "Size",
357                             "Width and height in pixels, zero when image data cant be loaded",
358                             0,
359                             0);
360   RNA_def_property_int_funcs(prop, "rna_MovieClip_size_get", NULL, NULL);
361   RNA_def_property_clear_flag(prop, PROP_EDITABLE);
362 
363   prop = RNA_def_property(srna, "display_aspect", PROP_FLOAT, PROP_XYZ);
364   RNA_def_property_float_sdna(prop, NULL, "aspx");
365   RNA_def_property_array(prop, 2);
366   RNA_def_property_range(prop, 0.1f, FLT_MAX);
367   RNA_def_property_ui_range(prop, 0.1f, 5000.0f, 1, 2);
368   RNA_def_property_ui_text(
369       prop, "Display Aspect", "Display Aspect for this clip, does not affect rendering");
370   RNA_def_property_update(prop, NC_MOVIECLIP | ND_DISPLAY, NULL);
371 
372   /* source */
373   prop = RNA_def_property(srna, "source", PROP_ENUM, PROP_NONE);
374   RNA_def_property_enum_items(prop, clip_source_items);
375   RNA_def_property_ui_text(prop, "Source", "Where the clip comes from");
376   RNA_def_property_clear_flag(prop, PROP_EDITABLE);
377 
378   /* custom proxy directory */
379   prop = RNA_def_property(srna, "use_proxy_custom_directory", PROP_BOOLEAN, PROP_NONE);
380   RNA_def_property_boolean_sdna(prop, NULL, "flag", MCLIP_USE_PROXY_CUSTOM_DIR);
381   RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
382   RNA_def_property_ui_text(
383       prop,
384       "Proxy Custom Directory",
385       "Create proxy images in a custom directory (default is movie location)");
386   RNA_def_property_update(prop, NC_MOVIECLIP | ND_DISPLAY, "rna_MovieClip_reload_update");
387 
388   /* grease pencil */
389   prop = RNA_def_property(srna, "grease_pencil", PROP_POINTER, PROP_NONE);
390   RNA_def_property_pointer_sdna(prop, NULL, "gpd");
391   RNA_def_property_struct_type(prop, "GreasePencil");
392   RNA_def_property_pointer_funcs(
393       prop, NULL, NULL, NULL, "rna_GPencil_datablocks_annotations_poll");
394   RNA_def_property_flag(prop, PROP_EDITABLE | PROP_ID_REFCOUNT);
395   RNA_def_property_ui_text(prop, "Grease Pencil", "Grease pencil data for this movie clip");
396   RNA_def_property_update(prop, NC_MOVIECLIP | ND_DISPLAY, NULL);
397 
398   /* start_frame */
399   prop = RNA_def_property(srna, "frame_start", PROP_INT, PROP_NONE);
400   RNA_def_property_int_sdna(prop, NULL, "start_frame");
401   RNA_def_property_ui_text(prop,
402                            "Start Frame",
403                            "Global scene frame number at which this movie starts playing "
404                            "(affects all data associated with a clip)");
405   RNA_def_property_update(prop, NC_MOVIECLIP | ND_DISPLAY, "rna_MovieClip_reload_update");
406 
407   /* frame_offset */
408   prop = RNA_def_property(srna, "frame_offset", PROP_INT, PROP_NONE);
409   RNA_def_property_int_sdna(prop, NULL, "frame_offset");
410   RNA_def_property_ui_text(
411       prop,
412       "Frame Offset",
413       "Offset of footage first frame relative to its file name "
414       "(affects only how footage is loading, does not change data associated with a clip)");
415   RNA_def_property_update(prop, NC_MOVIECLIP | ND_DISPLAY, "rna_MovieClip_reload_update");
416 
417   /* length */
418   prop = RNA_def_property(srna, "frame_duration", PROP_INT, PROP_NONE);
419   RNA_def_property_clear_flag(prop, PROP_EDITABLE);
420   RNA_def_property_int_sdna(prop, NULL, "len");
421   RNA_def_property_ui_text(prop, "Duration", "Detected duration of movie clip in frames");
422 
423   /* FPS */
424   prop = RNA_def_property(srna, "fps", PROP_FLOAT, PROP_NONE);
425   RNA_def_property_clear_flag(prop, PROP_EDITABLE);
426   RNA_def_property_float_funcs(prop, "rna_MovieClip_fps_get", NULL, NULL);
427   RNA_def_property_ui_text(
428       prop, "Frame Rate", "Detected frame rate of the movie clip in frames per second");
429 
430   /* color management */
431   prop = RNA_def_property(srna, "colorspace_settings", PROP_POINTER, PROP_NONE);
432   RNA_def_property_pointer_sdna(prop, NULL, "colorspace_settings");
433   RNA_def_property_struct_type(prop, "ColorManagedInputColorspaceSettings");
434   RNA_def_property_ui_text(prop, "Color Space Settings", "Input color space settings");
435 
436   /* metadata */
437   func = RNA_def_function(srna, "metadata", "rna_MovieClip_metadata_get");
438   RNA_def_function_ui_description(func, "Retrieve metadata of the movie file");
439   /* return type */
440   parm = RNA_def_pointer(
441       func, "metadata", "IDPropertyWrapPtr", "", "Dict-like object containing the metadata");
442   RNA_def_parameter_flags(parm, 0, PARM_RNAPTR);
443   RNA_def_function_return(func, parm);
444 
445   rna_def_animdata_common(srna);
446 }
447 
RNA_def_movieclip(BlenderRNA * brna)448 void RNA_def_movieclip(BlenderRNA *brna)
449 {
450   rna_def_movieclip(brna);
451   rna_def_movieclip_proxy(brna);
452   rna_def_moviecliUser(brna);
453   rna_def_movieClipScopes(brna);
454 }
455 
456 #endif
457