Fix (unreported) broken export of timecodes in SubRip VSE exporter.
authorBastien Montagne <montagne29@wanadoo.fr>
Sun, 4 Oct 2015 13:53:56 +0000 (15:53 +0200)
committerBastien Montagne <montagne29@wanadoo.fr>
Sun, 4 Oct 2015 14:43:24 +0000 (16:43 +0200)
Would write 1.04 seconds as `00:00:01,40` instead of `00:00:01,040`...

Anyway, we already have BLI API for timecodes, much better to add
SubRip timecode format there, heavily simplifies code.

To be backported to final 2.76.

source/blender/blenlib/intern/timecode.c
source/blender/editors/space_sequencer/sequencer_edit.c
source/blender/makesdna/DNA_userdef_types.h

index 4ae9249ec0d89dd4d47c5e8f26c1cab74db065ed..e755a7ae52ca98dc76399f9f39831abf24915937 100644 (file)
@@ -72,20 +72,20 @@ size_t BLI_timecode_string_from_time(
                time = -time;
        }
 
-       if (time >= 3600) {
+       if (time >= 3600.0f) {
                /* hours */
                /* XXX should we only display a single digit for hours since clips are
                 *     VERY UNLIKELY to be more than 1-2 hours max? However, that would
                 *     go against conventions...
                 */
                hours = (int)time / 3600;
-               time = (float)fmod(time, 3600);
+               time = fmodf(time, 3600);
        }
 
-       if (time >= 60) {
+       if (time >= 60.0f) {
                /* minutes */
                minutes = (int)time / 60;
-               time = (float)fmod(time, 60);
+               time = fmodf(time, 60);
        }
 
        if (power <= 0) {
@@ -163,6 +163,18 @@ size_t BLI_timecode_string_from_time(
                        }
                        break;
                }
+               case USER_TIMECODE_SUBRIP:
+               {
+                       /* SubRip, like SMPTE milliseconds but seconds and milliseconds are separated by a comma, not a dot... */
+
+                       /* precision of decimal part */
+                       const int ms_dp = (power <= 0) ? (1 - power) : 1;
+                       const int ms = iroundf((time - (float)seconds) * 1000.0f);
+
+                       rlen = BLI_snprintf_rlen(
+                                  str, maxncpy, "%s%02d:%02d:%02d,%0*d", neg, hours, minutes, seconds, ms_dp, ms);
+                       break;
+               }
                case USER_TIMECODE_SECONDS_ONLY:
                {
                        /* only show the original seconds display */
index 3cc0276104eefa4cf26a725cb8320d9858d20302..88a2f386b9b83915057df7a650fe64788e5a6502 100644 (file)
@@ -3892,24 +3892,15 @@ static int sequencer_export_subtitles_exec(bContext *C, wmOperator *op)
        {
                if (seq->type == SEQ_TYPE_TEXT) {
                        TextVars *data = seq->effectdata;
-                       char timecode_str[32];
-                       double sec;
-                       int frac;
-                       int len;
-                       fprintf(file, "%d\n", iter++);
-                       sec = FRA2TIME(seq->startdisp);
-                       frac = 1000 * (sec - floor(sec));
-                       sec = floor(sec);
-                       BLI_timecode_string_from_time(timecode_str, sizeof(timecode_str), 1, sec, FPS, USER_TIMECODE_SMPTE_FULL);
-                       len = strlen(timecode_str);
-                       timecode_str[len - 3] = 0;
-                       fprintf(file, "%s,%d", timecode_str, frac);
-                       sec = FRA2TIME(seq->enddisp);
-                       BLI_timecode_string_from_time(timecode_str, sizeof(timecode_str), 1, sec, FPS, USER_TIMECODE_SMPTE_FULL);
-                       len = strlen(timecode_str);
-                       timecode_str[len - 3] = 0;
-                       fprintf(file, " --> %s,%d\n", timecode_str, frac);
-                       fprintf(file, "%s\n\n", data->text);
+                       char timecode_str_start[32];
+                       char timecode_str_end[32];
+
+                       BLI_timecode_string_from_time(timecode_str_start, sizeof(timecode_str_start),
+                                                     -2, FRA2TIME(seq->startdisp), FPS, USER_TIMECODE_SUBRIP);
+                       BLI_timecode_string_from_time(timecode_str_end, sizeof(timecode_str_end),
+                                                     -2, FRA2TIME(seq->enddisp), FPS, USER_TIMECODE_SUBRIP);
+
+                       fprintf(file, "%d\n%s --> %s\n%s\n\n", iter++, timecode_str_start, timecode_str_end, data->text);
                }
        }
        SEQ_END
index 00dc1c1205e4510468dad73923a84de7ed37ceb6..5b540e654cf1dfa1c8e0fad66350febaec23c821 100644 (file)
@@ -802,19 +802,23 @@ typedef enum eTimecodeStyles {
         * with '+' to denote the frames 
         * i.e. HH:MM:SS+FF, MM:SS+FF, SS+FF, or MM:SS
         */
-       USER_TIMECODE_MINIMAL           = 0,
-       
+       USER_TIMECODE_MINIMAL       = 0,
+
        /* reduced SMPTE - (HH:)MM:SS:FF */
-       USER_TIMECODE_SMPTE_MSF         = 1,
-       
+       USER_TIMECODE_SMPTE_MSF     = 1,
+
        /* full SMPTE - HH:MM:SS:FF */
-       USER_TIMECODE_SMPTE_FULL        = 2,
-       
+       USER_TIMECODE_SMPTE_FULL    = 2,
+
        /* milliseconds for sub-frames - HH:MM:SS.sss */
-       USER_TIMECODE_MILLISECONDS      = 3,
-       
+       USER_TIMECODE_MILLISECONDS  = 3,
+
        /* seconds only */
-       USER_TIMECODE_SECONDS_ONLY      = 4,
+       USER_TIMECODE_SECONDS_ONLY  = 4,
+
+       /* Private (not exposed as generic choices) options. */
+       /* milliseconds for sub-frames , SubRip format- HH:MM:SS,sss */
+       USER_TIMECODE_SUBRIP        = 100,
 } eTimecodeStyles;
 
 /* theme drawtypes */