gmtime isn't thread safe in general. In msvcrt (which lacks gmtime_r), the buffer used by gmtime is thread specific though. One call to localtime is left in avconv_opt.c, where thread safety shouldn't matter (instead of making avconv depend on the libavutil internal header). Signed-off-by: Martin Storsjö <martin@martin.st>tags/n2.5
| @@ -34,6 +34,7 @@ | |||||
| #include "libavutil/intreadwrite.h" | #include "libavutil/intreadwrite.h" | ||||
| #include "libavutil/intfloat.h" | #include "libavutil/intfloat.h" | ||||
| #include "libavutil/mathematics.h" | #include "libavutil/mathematics.h" | ||||
| #include "libavutil/time_internal.h" | |||||
| #include "libavutil/avstring.h" | #include "libavutil/avstring.h" | ||||
| #include "libavutil/dict.h" | #include "libavutil/dict.h" | ||||
| #include "libavcodec/ac3tab.h" | #include "libavcodec/ac3tab.h" | ||||
| @@ -739,9 +740,9 @@ static void mov_metadata_creation_time(AVDictionary **metadata, time_t time) | |||||
| { | { | ||||
| char buffer[32]; | char buffer[32]; | ||||
| if (time) { | if (time) { | ||||
| struct tm *ptm; | |||||
| struct tm *ptm, tmbuf; | |||||
| time -= 2082844800; /* seconds between 1904-01-01 and Epoch */ | time -= 2082844800; /* seconds between 1904-01-01 and Epoch */ | ||||
| ptm = gmtime(&time); | |||||
| ptm = gmtime_r(&time, &tmbuf); | |||||
| if (!ptm) return; | if (!ptm) return; | ||||
| if (strftime(buffer, sizeof(buffer), "%Y-%m-%d %H:%M:%S", ptm)) | if (strftime(buffer, sizeof(buffer), "%Y-%m-%d %H:%M:%S", ptm)) | ||||
| av_dict_set(metadata, "creation_time", buffer, 0); | av_dict_set(metadata, "creation_time", buffer, 0); | ||||
| @@ -35,6 +35,7 @@ | |||||
| #include <time.h> | #include <time.h> | ||||
| #include "libavutil/random_seed.h" | #include "libavutil/random_seed.h" | ||||
| #include "libavutil/time_internal.h" | |||||
| #include "libavcodec/bytestream.h" | #include "libavcodec/bytestream.h" | ||||
| #include "audiointerleave.h" | #include "audiointerleave.h" | ||||
| #include "avformat.h" | #include "avformat.h" | ||||
| @@ -1386,7 +1387,8 @@ static int mxf_parse_mpeg2_frame(AVFormatContext *s, AVStream *st, | |||||
| static uint64_t mxf_parse_timestamp(time_t timestamp) | static uint64_t mxf_parse_timestamp(time_t timestamp) | ||||
| { | { | ||||
| struct tm *time = gmtime(×tamp); | |||||
| struct tm tmbuf; | |||||
| struct tm *time = gmtime_r(×tamp, &tmbuf); | |||||
| if (!time) | if (!time) | ||||
| return 0; | return 0; | ||||
| return (uint64_t)(time->tm_year+1900) << 48 | | return (uint64_t)(time->tm_year+1900) << 48 | | ||||
| @@ -31,6 +31,7 @@ | |||||
| #include "libavutil/intreadwrite.h" | #include "libavutil/intreadwrite.h" | ||||
| #include "libavutil/intfloat.h" | #include "libavutil/intfloat.h" | ||||
| #include "libavutil/dict.h" | #include "libavutil/dict.h" | ||||
| #include "libavutil/time_internal.h" | |||||
| #include "avformat.h" | #include "avformat.h" | ||||
| #include "internal.h" | #include "internal.h" | ||||
| #include "riff.h" | #include "riff.h" | ||||
| @@ -428,7 +429,8 @@ static int read_probe(AVProbeData *p) | |||||
| static void filetime_to_iso8601(char *buf, int buf_size, int64_t value) | static void filetime_to_iso8601(char *buf, int buf_size, int64_t value) | ||||
| { | { | ||||
| time_t t = (value / 10000000LL) - 11644473600LL; | time_t t = (value / 10000000LL) - 11644473600LL; | ||||
| struct tm *tm = gmtime(&t); | |||||
| struct tm tmbuf; | |||||
| struct tm *tm = gmtime_r(&t, &tmbuf); | |||||
| if (tm) { | if (tm) { | ||||
| if (!strftime(buf, buf_size, "%Y-%m-%d %H:%M:%S", tm)) | if (!strftime(buf, buf_size, "%Y-%m-%d %H:%M:%S", tm)) | ||||
| buf[0] = '\0'; | buf[0] = '\0'; | ||||
| @@ -442,7 +444,8 @@ static void filetime_to_iso8601(char *buf, int buf_size, int64_t value) | |||||
| static void crazytime_to_iso8601(char *buf, int buf_size, int64_t value) | static void crazytime_to_iso8601(char *buf, int buf_size, int64_t value) | ||||
| { | { | ||||
| time_t t = (value / 10000000LL) - 719162LL*86400LL; | time_t t = (value / 10000000LL) - 719162LL*86400LL; | ||||
| struct tm *tm = gmtime(&t); | |||||
| struct tm tmbuf; | |||||
| struct tm *tm = gmtime_r(&t, &tmbuf); | |||||
| if (tm) { | if (tm) { | ||||
| if (!strftime(buf, buf_size, "%Y-%m-%d %H:%M:%S", tm)) | if (!strftime(buf, buf_size, "%Y-%m-%d %H:%M:%S", tm)) | ||||
| buf[0] = '\0'; | buf[0] = '\0'; | ||||
| @@ -456,7 +459,8 @@ static void crazytime_to_iso8601(char *buf, int buf_size, int64_t value) | |||||
| static void oledate_to_iso8601(char *buf, int buf_size, int64_t value) | static void oledate_to_iso8601(char *buf, int buf_size, int64_t value) | ||||
| { | { | ||||
| time_t t = 631112400LL + 86400*av_int2double(value); | time_t t = 631112400LL + 86400*av_int2double(value); | ||||
| struct tm *tm = gmtime(&t); | |||||
| struct tm tmbuf; | |||||
| struct tm *tm = gmtime_r(&t, &tmbuf); | |||||
| if (tm) { | if (tm) { | ||||
| if (!strftime(buf, buf_size, "%Y-%m-%d %H:%M:%S", tm)) | if (!strftime(buf, buf_size, "%Y-%m-%d %H:%M:%S", tm)) | ||||
| buf[0] = '\0'; | buf[0] = '\0'; | ||||
| @@ -29,6 +29,7 @@ | |||||
| #include "eval.h" | #include "eval.h" | ||||
| #include "log.h" | #include "log.h" | ||||
| #include "random_seed.h" | #include "random_seed.h" | ||||
| #include "time_internal.h" | |||||
| #include "parseutils.h" | #include "parseutils.h" | ||||
| typedef struct { | typedef struct { | ||||
| @@ -483,7 +484,7 @@ int av_parse_time(int64_t *timeval, const char *timestr, int duration) | |||||
| { | { | ||||
| const char *p; | const char *p; | ||||
| int64_t t; | int64_t t; | ||||
| struct tm dt = { 0 }; | |||||
| struct tm dt = { 0 }, tmbuf; | |||||
| int i; | int i; | ||||
| static const char * const date_fmt[] = { | static const char * const date_fmt[] = { | ||||
| "%Y-%m-%d", | "%Y-%m-%d", | ||||
| @@ -527,9 +528,9 @@ int av_parse_time(int64_t *timeval, const char *timestr, int duration) | |||||
| * current year-month-day time */ | * current year-month-day time */ | ||||
| if (!q) { | if (!q) { | ||||
| if (is_utc) { | if (is_utc) { | ||||
| dt = *gmtime(&now); | |||||
| dt = *gmtime_r(&now, &tmbuf); | |||||
| } else { | } else { | ||||
| dt = *localtime(&now); | |||||
| dt = *localtime_r(&now, &tmbuf); | |||||
| } | } | ||||
| dt.tm_hour = dt.tm_min = dt.tm_sec = 0; | dt.tm_hour = dt.tm_min = dt.tm_sec = 0; | ||||
| } else { | } else { | ||||