Sequencer: Expose read-only FPS property for movie-type strips
authorSergey Sharybin <sergey.vfx@gmail.com>
Mon, 5 Mar 2018 14:00:04 +0000 (15:00 +0100)
committerSergey Sharybin <sergey.vfx@gmail.com>
Mon, 5 Mar 2018 14:01:23 +0000 (15:01 +0100)
Main purpose is to make it possible to cover FPS detection with regression test.
But it might also be handy for some other scripters.

Thanks Campbell for review!

source/blender/blenkernel/BKE_movieclip.h
source/blender/blenkernel/BKE_sequencer.h
source/blender/blenkernel/intern/movieclip.c
source/blender/blenkernel/intern/sequencer.c
source/blender/makesrna/intern/rna_sequencer.c

index bd193b8..818f79a 100644 (file)
@@ -60,6 +60,7 @@ struct ImBuf *BKE_movieclip_get_ibuf_flag(struct MovieClip *clip, struct MovieCl
 void BKE_movieclip_get_size(struct MovieClip *clip, struct MovieClipUser *user, int *width, int *height);
 void BKE_movieclip_get_size_fl(struct MovieClip *clip, struct MovieClipUser *user, float size[2]);
 int  BKE_movieclip_get_duration(struct MovieClip *clip);
+float BKE_movieclip_get_fps(struct MovieClip *clip);
 void BKE_movieclip_get_aspect(struct MovieClip *clip, float *aspx, float *aspy);
 bool BKE_movieclip_has_frame(struct MovieClip *clip, struct MovieClipUser *user);
 void BKE_movieclip_user_set_frame(struct MovieClipUser *user, int framenr);
index 6c9dc12..3c2cebc 100644 (file)
@@ -405,6 +405,8 @@ struct Sequence *BKE_sequence_alloc(ListBase *lb, int cfra, int machine);
 void BKE_sequence_alpha_mode_from_extension(struct Sequence *seq);
 void BKE_sequence_init_colorspace(struct Sequence *seq);
 
+float BKE_sequence_get_fps(struct Scene *scene, struct Sequence *seq);
+
 /* RNA enums, just to be more readable */
 enum {
        SEQ_SIDE_NONE = 0,
index f67560f..6073075 100644 (file)
@@ -1202,6 +1202,23 @@ int BKE_movieclip_get_duration(MovieClip *clip)
        return clip->len;
 }
 
+float BKE_movieclip_get_fps(MovieClip *clip)
+{
+       if (clip->source != MCLIP_SRC_MOVIE) {
+               return 0.0f;
+       }
+       movieclip_open_anim_file(clip);
+       if (clip->anim == NULL) {
+               return 0.0f;
+       }
+       short frs_sec;
+       float frs_sec_base;
+       if (IMB_anim_get_fps(clip->anim, &frs_sec, &frs_sec_base, true)) {
+               return (float)frs_sec / frs_sec_base;
+       }
+       return 0.0f;
+}
+
 void BKE_movieclip_get_aspect(MovieClip *clip, float *aspx, float *aspy)
 {
        *aspx = 1.0;
index ea45c1b..67a64ab 100644 (file)
@@ -5155,6 +5155,40 @@ void BKE_sequence_init_colorspace(Sequence *seq)
        }
 }
 
+float BKE_sequence_get_fps(Scene *scene, Sequence *seq)
+{
+       switch (seq->type) {
+               case SEQ_TYPE_MOVIE:
+               {
+                       seq_open_anim_file(scene, seq, true);
+                       if (BLI_listbase_is_empty(&seq->anims)) {
+                               return 0.0f;
+                       }
+                       StripAnim *strip_anim = seq->anims.first;
+                       if (strip_anim->anim == NULL) {
+                               return 0.0f;
+                       }
+                       short frs_sec;
+                       float frs_sec_base;
+                       if (IMB_anim_get_fps(strip_anim->anim, &frs_sec, &frs_sec_base, true)) {
+                               return (float)frs_sec / frs_sec_base;
+                       }
+                       break;
+               }
+               case SEQ_TYPE_MOVIECLIP:
+                       if (seq->clip != NULL) {
+                               return BKE_movieclip_get_fps(seq->clip);
+                       }
+                       break;
+               case SEQ_TYPE_SCENE:
+                       if (seq->scene != NULL) {
+                               return (float)seq->scene->r.frs_sec / seq->scene->r.frs_sec_base;
+                       }
+                       break;
+       }
+       return 0.0f;
+}
+
 /* NOTE: this function doesn't fill in image names */
 Sequence *BKE_sequencer_add_image_strip(bContext *C, ListBase *seqbasep, SeqLoadInfo *seq_load)
 {
index 1d0fa7a..cfd6d0c 100644 (file)
@@ -75,6 +75,7 @@ const EnumPropertyItem rna_enum_sequence_modifier_type_items[] = {
 
 #include "BKE_report.h"
 #include "BKE_idprop.h"
+#include "BKE_movieclip.h"
 
 #include "WM_api.h"
 
@@ -1085,6 +1086,13 @@ static void rna_Sequence_modifier_clear(Sequence *seq, bContext *C)
        WM_main_add_notifier(NC_SCENE | ND_SEQUENCER, NULL);
 }
 
+static float rna_Sequence_fps_get(PointerRNA *ptr)
+{
+       Scene *scene = (Scene *)ptr->id.data;
+       Sequence *seq = (Sequence *)(ptr->data);
+       return BKE_sequence_get_fps(scene, seq);
+}
+
 #else
 
 static void rna_def_strip_element(BlenderRNA *brna)
@@ -1840,6 +1848,16 @@ static void rna_def_color_management(StructRNA *srna)
        RNA_def_property_ui_text(prop, "Color Space Settings", "Input color space settings");
 }
 
+static void rna_def_movie_types(StructRNA *srna)
+{
+       PropertyRNA *prop;
+
+       prop = RNA_def_property(srna, "fps", PROP_FLOAT, PROP_NONE);
+       RNA_def_property_ui_text(prop, "FPS", "Frames per second");
+       RNA_def_property_clear_flag(prop, PROP_EDITABLE);
+       RNA_def_property_float_funcs(prop, "rna_Sequence_fps_get", NULL, NULL);
+}
+
 static void rna_def_image(BlenderRNA *brna)
 {
        StructRNA *srna;
@@ -1939,6 +1957,7 @@ static void rna_def_scene(BlenderRNA *brna)
        rna_def_filter_video(srna);
        rna_def_proxy(srna);
        rna_def_input(srna);
+       rna_def_movie_types(srna);
 }
 
 static void rna_def_movie(BlenderRNA *brna)
@@ -1999,6 +2018,7 @@ static void rna_def_movie(BlenderRNA *brna)
        rna_def_proxy(srna);
        rna_def_input(srna);
        rna_def_color_management(srna);
+       rna_def_movie_types(srna);
 }
 
 static void rna_def_movieclip(BlenderRNA *brna)
@@ -2024,6 +2044,7 @@ static void rna_def_movieclip(BlenderRNA *brna)
 
        rna_def_filter_video(srna);
        rna_def_input(srna);
+       rna_def_movie_types(srna);
 }
 
 static void rna_def_mask(BlenderRNA *brna)