You've already forked FFmpeg
							
							
				mirror of
				https://github.com/FFmpeg/FFmpeg.git
				synced 2025-10-30 23:18:11 +02:00 
			
		
		
		
	lavfi/drawtext: Add %N for drawing fractions of a second
Suggested-By: ffmpeg@fb.com
This commit is contained in:
		| @@ -11431,10 +11431,14 @@ It can be used to add padding with zeros from the left. | ||||
| @item gmtime | ||||
| The time at which the filter is running, expressed in UTC. | ||||
| It can accept an argument: a strftime() format string. | ||||
| The format string is extended to support the variable @var{%[1-6]N} | ||||
| which prints fractions of the second with optionally specified number of digits. | ||||
|  | ||||
| @item localtime | ||||
| The time at which the filter is running, expressed in the local time zone. | ||||
| It can accept an argument: a strftime() format string. | ||||
| The format string is extended to support the variable @var{%[1-6]N} | ||||
| which prints fractions of the second with optionally specified number of digits. | ||||
|  | ||||
| @item metadata | ||||
| Frame metadata. Takes one or two arguments. | ||||
|   | ||||
| @@ -51,6 +51,7 @@ | ||||
| #include "libavutil/opt.h" | ||||
| #include "libavutil/random_seed.h" | ||||
| #include "libavutil/parseutils.h" | ||||
| #include "libavutil/time.h" | ||||
| #include "libavutil/timecode.h" | ||||
| #include "libavutil/time_internal.h" | ||||
| #include "libavutil/tree.h" | ||||
| @@ -1045,15 +1046,78 @@ static int func_strftime(AVFilterContext *ctx, AVBPrint *bp, | ||||
|                          char *fct, unsigned argc, char **argv, int tag) | ||||
| { | ||||
|     const char *fmt = argc ? argv[0] : "%Y-%m-%d %H:%M:%S"; | ||||
|     const char *fmt_begin = fmt; | ||||
|     int64_t unow; | ||||
|     time_t now; | ||||
|     struct tm tm; | ||||
|     const char *begin; | ||||
|     const char *tmp; | ||||
|     int len; | ||||
|     int div; | ||||
|     AVBPrint fmt_bp; | ||||
|  | ||||
|     time(&now); | ||||
|     if (tag == 'L') | ||||
|     av_bprint_init(&fmt_bp, 0, AV_BPRINT_SIZE_UNLIMITED); | ||||
|  | ||||
|     unow = av_gettime(); | ||||
|     now  = unow / 1000000; | ||||
|     if (tag == 'L' || tag == 'm') | ||||
|         localtime_r(&now, &tm); | ||||
|     else | ||||
|         tm = *gmtime_r(&now, &tm); | ||||
|     av_bprint_strftime(bp, fmt, &tm); | ||||
|  | ||||
|     // manually parse format for %N (fractional seconds) | ||||
|     begin = fmt; | ||||
|     while ((begin = strchr(begin, '%'))) { | ||||
|         tmp = begin + 1; | ||||
|         len = 0; | ||||
|  | ||||
|         // skip escaped "%%" | ||||
|         if (*tmp == '%') { | ||||
|             begin = tmp + 1; | ||||
|             continue; | ||||
|         } | ||||
|  | ||||
|         // count digits between % and possible N | ||||
|         while (*tmp != '\0' && av_isdigit((int)*tmp)) { | ||||
|             len++; | ||||
|             tmp++; | ||||
|         } | ||||
|  | ||||
|         // N encountered, insert time | ||||
|         if (*tmp == 'N') { | ||||
|             int num_digits = 3; // default show millisecond [1,6] | ||||
|  | ||||
|             // if digit given, expect [1,6], warn & clamp otherwise | ||||
|             if (len == 1) { | ||||
|                 num_digits = av_clip(*(begin + 1) - '0', 1, 6); | ||||
|             } else if (len > 1) { | ||||
|                 av_log(ctx, AV_LOG_WARNING, "Invalid number of decimals for %%N, using default of %i\n", num_digits); | ||||
|             } | ||||
|  | ||||
|             len += 2; // add % and N to get length of string part | ||||
|  | ||||
|             div = pow(10, 6 - num_digits); | ||||
|  | ||||
|             av_bprintf(&fmt_bp, "%.*s%0*d", (int)(begin - fmt_begin), fmt_begin, num_digits, (int)(unow % 1000000) / div); | ||||
|  | ||||
|             begin += len; | ||||
|             fmt_begin = begin; | ||||
|  | ||||
|             continue; | ||||
|         } | ||||
|  | ||||
|         begin = tmp; | ||||
|     } | ||||
|  | ||||
|     av_bprintf(&fmt_bp, "%s", fmt_begin); | ||||
|     if (!av_bprint_is_complete(&fmt_bp)) { | ||||
|         av_log(ctx, AV_LOG_WARNING, "Format string truncated at %u/%u.", fmt_bp.size, fmt_bp.len); | ||||
|     } | ||||
|  | ||||
|     av_bprint_strftime(bp, fmt_bp.str, &tm); | ||||
|  | ||||
|     av_bprint_finalize(&fmt_bp, NULL); | ||||
|  | ||||
|     return 0; | ||||
| } | ||||
|  | ||||
|   | ||||
		Reference in New Issue
	
	Block a user