Changeset View
Changeset View
Standalone View
Standalone View
source/blender/blenlib/intern/timecode.c
| Show All 35 Lines | |||||
| #include "BLI_strict_flags.h" | #include "BLI_strict_flags.h" | ||||
| /** | /** | ||||
| * Generate timecode/frame number string and store in \a str | * Generate timecode/frame number string and store in \a str | ||||
| * | * | ||||
| * \param str: destination string | * \param str: destination string | ||||
| * \param maxncpy: maximum number of characters to copy ``sizeof(str)`` | * \param maxncpy: maximum number of characters to copy ``sizeof(str)`` | ||||
| * \param power: special setting for #View2D grid drawing, | * \param brevity_level: special setting for #View2D grid drawing, | ||||
| * used to specify how detailed we need to be | * used to specify how detailed we need to be | ||||
| * \param time_seconds: time total time in seconds | * \param time_seconds: time total time in seconds | ||||
| * \param fps: frames per second, typically from the #FPS macro | * \param fps: frames per second, typically from the #FPS macro | ||||
| * \param timecode_style: enum from eTimecodeStyles | * \param timecode_style: enum from eTimecodeStyles | ||||
| * \return length of \a str | * \return length of \a str | ||||
| */ | */ | ||||
| size_t BLI_timecode_string_from_time( | size_t BLI_timecode_string_from_time( | ||||
| char *str, const size_t maxncpy, const int power, const float time_seconds, | char *str, const size_t maxncpy, const int brevity_level, const float time_seconds, | ||||
| const double fps, const short timecode_style) | const double fps, const short timecode_style) | ||||
| { | { | ||||
| int hours = 0, minutes = 0, seconds = 0, frames = 0; | int hours = 0, minutes = 0, seconds = 0, frames = 0; | ||||
| float time = time_seconds; | float time = time_seconds; | ||||
| char neg[2] = {'\0'}; | char neg[2] = {'\0'}; | ||||
| size_t rlen; | size_t rlen; | ||||
| /* get cframes */ | /* get cframes */ | ||||
| Show All 14 Lines | size_t BLI_timecode_string_from_time( | ||||
| } | } | ||||
| if (time >= 60.0f) { | if (time >= 60.0f) { | ||||
| /* minutes */ | /* minutes */ | ||||
| minutes = (int)time / 60; | minutes = (int)time / 60; | ||||
| time = fmodf(time, 60); | time = fmodf(time, 60); | ||||
| } | } | ||||
| if (power <= 0) { | if (brevity_level <= 0) { | ||||
| /* seconds + frames | /* seconds + frames | ||||
| * Frames are derived from 'fraction' of second. We need to perform some additional rounding | * Frames are derived from 'fraction' of second. We need to perform some additional rounding | ||||
| * to cope with 'half' frames, etc., which should be fine in most cases | * to cope with 'half' frames, etc., which should be fine in most cases | ||||
| */ | */ | ||||
| seconds = (int)time; | seconds = (int)time; | ||||
| frames = round_fl_to_int((float)(((double)time - (double)seconds) * fps)); | frames = round_fl_to_int((float)(((double)time - (double)seconds) * fps)); | ||||
| } | } | ||||
| else { | else { | ||||
| /* seconds (with pixel offset rounding) */ | /* seconds (with pixel offset rounding) */ | ||||
| seconds = round_fl_to_int(time); | seconds = round_fl_to_int(time); | ||||
| } | } | ||||
| switch (timecode_style) { | switch (timecode_style) { | ||||
| case USER_TIMECODE_MINIMAL: | case USER_TIMECODE_MINIMAL: | ||||
| { | { | ||||
| /* - In general, minutes and seconds should be shown, as most clips will be | /* - In general, minutes and seconds should be shown, as most clips will be | ||||
| * within this length. Hours will only be included if relevant. | * within this length. Hours will only be included if relevant. | ||||
| * - Only show frames when zoomed in enough for them to be relevant | * - Only show frames when zoomed in enough for them to be relevant | ||||
| * (using separator of '+' for frames). | * (using separator of '+' for frames). | ||||
| * When showing frames, use slightly different display to avoid confusion with mm:ss format | * When showing frames, use slightly different display to avoid confusion with mm:ss format | ||||
| */ | */ | ||||
| if (power <= 0) { | if (brevity_level <= 0) { | ||||
| /* include "frames" in display */ | /* include "frames" in display */ | ||||
| if (hours) { | if (hours) { | ||||
| rlen = BLI_snprintf_rlen(str, maxncpy, "%s%02d:%02d:%02d+%02d", neg, hours, minutes, seconds, frames); | rlen = BLI_snprintf_rlen(str, maxncpy, "%s%02d:%02d:%02d+%02d", neg, hours, minutes, seconds, frames); | ||||
| } | } | ||||
| else if (minutes) { | else if (minutes) { | ||||
| rlen = BLI_snprintf_rlen(str, maxncpy, "%s%02d:%02d+%02d", neg, minutes, seconds, frames); | rlen = BLI_snprintf_rlen(str, maxncpy, "%s%02d:%02d+%02d", neg, minutes, seconds, frames); | ||||
| } | } | ||||
| else { | else { | ||||
| Show All 23 Lines | case USER_TIMECODE_SMPTE_MSF: | ||||
| } | } | ||||
| break; | break; | ||||
| } | } | ||||
| case USER_TIMECODE_MILLISECONDS: | case USER_TIMECODE_MILLISECONDS: | ||||
| { | { | ||||
| /* reduced SMPTE. Instead of frames, milliseconds are shown */ | /* reduced SMPTE. Instead of frames, milliseconds are shown */ | ||||
| /* precision of decimal part */ | /* precision of decimal part */ | ||||
| const int ms_dp = (power <= 0) ? (1 - power) : 1; | const int ms_dp = (brevity_level <= 0) ? (1 - brevity_level) : 1; | ||||
| /* to get 2 digit whole-number part for seconds display | /* to get 2 digit whole-number part for seconds display | ||||
| * (i.e. 3 is for 2 digits + radix, on top of full length) */ | * (i.e. 3 is for 2 digits + radix, on top of full length) */ | ||||
| const int s_pad = ms_dp + 3; | const int s_pad = ms_dp + 3; | ||||
| if (hours) { | if (hours) { | ||||
| rlen = BLI_snprintf_rlen(str, maxncpy, "%s%02d:%02d:%0*.*f", neg, hours, minutes, s_pad, ms_dp, time); | rlen = BLI_snprintf_rlen(str, maxncpy, "%s%02d:%02d:%0*.*f", neg, hours, minutes, s_pad, ms_dp, time); | ||||
| } | } | ||||
| else { | else { | ||||
| rlen = BLI_snprintf_rlen(str, maxncpy, "%s%02d:%0*.*f", neg, minutes, s_pad, ms_dp, time); | rlen = BLI_snprintf_rlen(str, maxncpy, "%s%02d:%0*.*f", neg, minutes, s_pad, ms_dp, time); | ||||
| } | } | ||||
| break; | break; | ||||
| } | } | ||||
| case USER_TIMECODE_SUBRIP: | case USER_TIMECODE_SUBRIP: | ||||
| { | { | ||||
| /* SubRip, like SMPTE milliseconds but seconds and milliseconds | /* SubRip, like SMPTE milliseconds but seconds and milliseconds | ||||
| * are separated by a comma, not a dot... */ | * are separated by a comma, not a dot... */ | ||||
| /* precision of decimal part */ | /* precision of decimal part */ | ||||
| const int ms_dp = (power <= 0) ? (1 - power) : 1; | const int ms_dp = (brevity_level <= 0) ? (1 - brevity_level) : 1; | ||||
| const int ms = round_fl_to_int((time - (float)seconds) * 1000.0f); | const int ms = round_fl_to_int((time - (float)seconds) * 1000.0f); | ||||
| rlen = BLI_snprintf_rlen( | rlen = BLI_snprintf_rlen( | ||||
| str, maxncpy, "%s%02d:%02d:%02d,%0*d", neg, hours, minutes, seconds, ms_dp, ms); | str, maxncpy, "%s%02d:%02d:%02d,%0*d", neg, hours, minutes, seconds, ms_dp, ms); | ||||
| break; | break; | ||||
| } | } | ||||
| case USER_TIMECODE_SECONDS_ONLY: | case USER_TIMECODE_SECONDS_ONLY: | ||||
| { | { | ||||
| /* only show the original seconds display */ | /* only show the original seconds display */ | ||||
| /* round to whole numbers if power is >= 1 (i.e. scale is coarse) */ | /* round to whole numbers if brevity_level is >= 1 (i.e. scale is coarse) */ | ||||
| if (power <= 0) { | if (brevity_level <= 0) { | ||||
| rlen = BLI_snprintf_rlen(str, maxncpy, "%.*f", 1 - power, time_seconds); | rlen = BLI_snprintf_rlen(str, maxncpy, "%.*f", 1 - brevity_level, time_seconds); | ||||
| } | } | ||||
| else { | else { | ||||
| rlen = BLI_snprintf_rlen(str, maxncpy, "%d", round_fl_to_int(time_seconds)); | rlen = BLI_snprintf_rlen(str, maxncpy, "%d", round_fl_to_int(time_seconds)); | ||||
| } | } | ||||
| break; | break; | ||||
| } | } | ||||
| case USER_TIMECODE_SMPTE_FULL: | case USER_TIMECODE_SMPTE_FULL: | ||||
| default: | default: | ||||
| Show All 36 Lines | size_t BLI_timecode_string_from_time_simple( | ||||
| return rlen; | return rlen; | ||||
| } | } | ||||
| /** | /** | ||||
| * Generate time string and store in \a str | * Generate time string and store in \a str | ||||
| * | * | ||||
| * \param str: destination string | * \param str: destination string | ||||
| * \param maxncpy: maximum number of characters to copy ``sizeof(str)`` | * \param maxncpy: maximum number of characters to copy ``sizeof(str)`` | ||||
| * \param power: special setting for #View2D grid drawing, | * \param brevity_level: special setting for #View2D grid drawing, | ||||
| * used to specify how detailed we need to be | * used to specify how detailed we need to be | ||||
| * \param time_seconds: time total time in seconds | * \param time_seconds: time total time in seconds | ||||
| * \return length of \a str | * \return length of \a str | ||||
| * | * | ||||
| * \note in some cases this is used to print non-seconds values. | * \note in some cases this is used to print non-seconds values. | ||||
| */ | */ | ||||
| size_t BLI_timecode_string_from_time_seconds( | size_t BLI_timecode_string_from_time_seconds( | ||||
| char *str, const size_t maxncpy, const int power, const float time_seconds) | char *str, const size_t maxncpy, const int brevity_level, const float time_seconds) | ||||
| { | { | ||||
| size_t rlen; | size_t rlen; | ||||
| /* round to whole numbers if power is >= 1 (i.e. scale is coarse) */ | /* round to whole numbers if brevity_level is >= 1 (i.e. scale is coarse) */ | ||||
| if (power <= 0) { | if (brevity_level <= 0) { | ||||
| rlen = BLI_snprintf_rlen(str, maxncpy, "%.*f", 1 - power, time_seconds); | rlen = BLI_snprintf_rlen(str, maxncpy, "%.*f", 1 - brevity_level, time_seconds); | ||||
| } | } | ||||
| else { | else { | ||||
| rlen = BLI_snprintf_rlen(str, maxncpy, "%d", round_fl_to_int(time_seconds)); | rlen = BLI_snprintf_rlen(str, maxncpy, "%d", round_fl_to_int(time_seconds)); | ||||
| } | } | ||||
| return rlen; | return rlen; | ||||
| } | } | ||||