PR #23481 opened by Marton Balint (cus) URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/23481 Patch URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/23481.patch
- Minor cleanups - Fix a regression in `asf_o` demxer which made it report an error when opening most files - Factorize FILETIME and AVTIME conversion functions - Use the factorized functions all over wtv and asf muxers/demuxers - Enhance precision of timestamps, and use proper ISO 8601 formatting - Add support for presenting creation_time metadata for the asf demuxer. >From 23603abcf17704ae60bf93f1eaf908d4214a13f6 Mon Sep 17 00:00:00 2001 From: Marton Balint <[email protected]> Date: Sat, 13 Jun 2026 22:29:18 +0200 Subject: [PATCH 1/7] avformat/asfdec_o: remove constants already defined in asf.h Signed-off-by: Marton Balint <[email protected]> --- libavformat/asfdec_o.c | 7 ------- 1 file changed, 7 deletions(-) diff --git a/libavformat/asfdec_o.c b/libavformat/asfdec_o.c index cc9c5ec396..9338d4ee63 100644 --- a/libavformat/asfdec_o.c +++ b/libavformat/asfdec_o.c @@ -37,14 +37,7 @@ #include "asf.h" #include "asfcrypt.h" -#define ASF_BOOL 0x2 -#define ASF_WORD 0x5 -#define ASF_GUID 0x6 -#define ASF_DWORD 0x3 -#define ASF_QWORD 0x4 -#define ASF_UNICODE 0x0 #define ASF_FLAG_BROADCAST 0x1 -#define ASF_BYTE_ARRAY 0x1 #define ASF_TYPE_AUDIO 0x2 #define ASF_TYPE_VIDEO 0x1 #define ASF_STREAM_NUM 0x7F -- 2.52.0 >From 2d6f060dd0f81c922384b41500366ff1012b368e Mon Sep 17 00:00:00 2001 From: Marton Balint <[email protected]> Date: Sun, 14 Jun 2026 00:05:44 +0200 Subject: [PATCH 2/7] avformat/asfdec_o: fix EOF check in read_header Since d1ac6456369fecdc99044e69bb22130bbedc0558 ff_read_guid() never returns EOF. This change completely broke the asfdec_o demuxer returning failure on every file. Signed-off-by: Marton Balint <[email protected]> --- libavformat/asfdec_o.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libavformat/asfdec_o.c b/libavformat/asfdec_o.c index 9338d4ee63..dd022cb404 100644 --- a/libavformat/asfdec_o.c +++ b/libavformat/asfdec_o.c @@ -1616,7 +1616,7 @@ static int asf_read_header(AVFormatContext *s) break; asf->offset = avio_tell(pb); if ((ret = ff_get_guid(pb, &guid)) < 0) { - if (ret == AVERROR_EOF && asf->data_reached) + if (avio_feof(pb) && asf->data_reached) break; else goto failed; -- 2.52.0 >From 97138ba0e49351c56c060d3e75d1c3f1e7acf403 Mon Sep 17 00:00:00 2001 From: Marton Balint <[email protected]> Date: Sun, 14 Jun 2026 01:16:18 +0200 Subject: [PATCH 3/7] avformat/asf: add helper functions to convert between filetime and avtime Signed-off-by: Marton Balint <[email protected]> --- libavformat/asf.c | 16 ++++++++++++++++ libavformat/asf.h | 5 +++++ 2 files changed, 21 insertions(+) diff --git a/libavformat/asf.c b/libavformat/asf.c index 5224a5d88d..117c9fff4c 100644 --- a/libavformat/asf.c +++ b/libavformat/asf.c @@ -152,3 +152,19 @@ int ff_asf_handle_byte_array(AVFormatContext *s, const char *name, return 1; } + +int64_t ff_asf_avtime_to_filetime(int64_t avtime) +{ + int64_t t; + t = avtime * INT64_C(10); + t += INT64_C(116444736000000000); + return t; +} + +int64_t ff_asf_filetime_to_avtime(int64_t filetime) +{ + int64_t t; + t = filetime / INT64_C(10); + t -= INT64_C(11644473600000000); + return t; +} diff --git a/libavformat/asf.h b/libavformat/asf.h index b77dabe1ff..6379908700 100644 --- a/libavformat/asf.h +++ b/libavformat/asf.h @@ -113,6 +113,11 @@ extern const AVMetadataConv ff_asf_metadata_conv[]; int ff_asf_handle_byte_array(AVFormatContext *s, const char *name, int val_len); +/* convert from av time to windows filetime */ +int64_t ff_asf_avtime_to_filetime(int64_t avtime); + +/* convert from windows filetime to av time */ +int64_t ff_asf_filetime_to_avtime(int64_t filetime); #define ASF_PACKET_FLAG_ERROR_CORRECTION_PRESENT 0x80 //1000 0000 -- 2.52.0 >From ce666990bfb5cb3ecb9e7bf86d74b38e070e5b59 Mon Sep 17 00:00:00 2001 From: Marton Balint <[email protected]> Date: Sun, 14 Jun 2026 01:20:08 +0200 Subject: [PATCH 4/7] avformat/wtvdec: use ISO timestamps with timezone and higher precision Signed-off-by: Marton Balint <[email protected]> --- libavformat/wtvdec.c | 58 +++++++++----------------------------------- 1 file changed, 12 insertions(+), 46 deletions(-) diff --git a/libavformat/wtvdec.c b/libavformat/wtvdec.c index 088f15f87e..873ba72243 100644 --- a/libavformat/wtvdec.c +++ b/libavformat/wtvdec.c @@ -26,13 +26,11 @@ */ #include <inttypes.h> -#include <time.h> #include "libavutil/channel_layout.h" #include "libavutil/intreadwrite.h" #include "libavutil/intfloat.h" #include "libavutil/mem.h" -#include "libavutil/time_internal.h" #include "avformat.h" #include "avio_internal.h" #include "demux.h" @@ -385,51 +383,19 @@ static int read_probe(const AVProbeData *p) } /** - * Convert win32 FILETIME to ISO-8601 string - * @return <0 on error + * Convert crazy time (100ns since 1 Jan 0001) to av time (unix timestamp in microseconds) */ -static int filetime_to_iso8601(char *buf, int buf_size, int64_t value) +static int64_t crazytime_to_avtime(int64_t value) { - time_t t = (value / 10000000LL) - 11644473600LL; - struct tm tmbuf; - struct tm *tm = gmtime_r(&t, &tmbuf); - if (!tm) - return -1; - if (!strftime(buf, buf_size, "%Y-%m-%d %H:%M:%S", tm)) - return -1; - return 0; + return (value / 10LL) - 719162LL*86400000000LL; } /** - * Convert crazy time (100ns since 1 Jan 0001) to ISO-8601 string - * @return <0 on error + * Convert OLE DATE to av time (unix timestamp in microseconds) */ -static int crazytime_to_iso8601(char *buf, int buf_size, int64_t value) +static int64_t oledate_to_avtime(int64_t value) { - time_t t = (value / 10000000LL) - 719162LL*86400LL; - struct tm tmbuf; - struct tm *tm = gmtime_r(&t, &tmbuf); - if (!tm) - return -1; - if (!strftime(buf, buf_size, "%Y-%m-%d %H:%M:%S", tm)) - return -1; - return 0; -} - -/** - * Convert OLE DATE to ISO-8601 string - * @return <0 on error - */ -static int oledate_to_iso8601(char *buf, int buf_size, int64_t value) -{ - time_t t = (av_int2double(value) - 25569.0) * 86400; - struct tm tmbuf; - struct tm *tm= gmtime_r(&t, &tmbuf); - if (!tm) - return -1; - if (!strftime(buf, buf_size, "%Y-%m-%d %H:%M:%S", tm)) - return -1; - return 0; + return (av_int2double(value) - 25569.0) * 86400000000; } static void get_attachment(AVFormatContext *s, AVIOContext *pb, int length) @@ -489,15 +455,15 @@ static void get_tag(AVFormatContext *s, AVIOContext *pb, const char *key, int ty int64_t num = avio_rl64(pb); if (!strcmp(key, "WM/EncodingTime") || !strcmp(key, "WM/MediaOriginalBroadcastDateTime")) { - if (filetime_to_iso8601(buf, sizeof(buf), num) < 0) - return; + ff_dict_set_timestamp(&s->metadata, key, ff_asf_filetime_to_avtime(num)); + return; } else if (!strcmp(key, "WM/WMRVEncodeTime") || !strcmp(key, "WM/WMRVEndTime")) { - if (crazytime_to_iso8601(buf, sizeof(buf), num) < 0) - return; + ff_dict_set_timestamp(&s->metadata, key, crazytime_to_avtime(num)); + return; } else if (!strcmp(key, "WM/WMRVExpirationDate")) { - if (oledate_to_iso8601(buf, sizeof(buf), num) < 0) - return; + ff_dict_set_timestamp(&s->metadata, key, oledate_to_avtime(num)); + return; } else if (!strcmp(key, "WM/WMRVBitrate")) snprintf(buf, sizeof(buf), "%f", av_int2double(num)); else -- 2.52.0 >From 98b082517d8b524ac2892ba8eb51e0decbaedaac Mon Sep 17 00:00:00 2001 From: Marton Balint <[email protected]> Date: Sun, 14 Jun 2026 01:21:22 +0200 Subject: [PATCH 5/7] avformat/asfenc: use common function for timestamp conversion Signed-off-by: Marton Balint <[email protected]> --- libavformat/asfenc.c | 12 +----------- 1 file changed, 1 insertion(+), 11 deletions(-) diff --git a/libavformat/asfenc.c b/libavformat/asfenc.c index 75285b065c..59638e7b22 100644 --- a/libavformat/asfenc.c +++ b/libavformat/asfenc.c @@ -294,16 +294,6 @@ static void put_chunk(AVFormatContext *s, int type, asf->seqno++; } -/* convert from av time to windows time */ -static int64_t unix_to_file_time(int64_t ti) -{ - int64_t t; - - t = ti * INT64_C(10); - t += INT64_C(116444736000000000); - return t; -} - static int32_t get_send_time(ASFContext *asf, int64_t pres_time, uint64_t *offset) { int32_t send_time = 0; @@ -442,7 +432,7 @@ static int asf_write_header1(AVFormatContext *s, int64_t file_size, hpos = put_header(pb, &ff_asf_file_header); ff_put_guid(pb, &ff_asf_my_guid); avio_wl64(pb, file_size); - avio_wl64(pb, unix_to_file_time(asf->creation_time)); + avio_wl64(pb, ff_asf_avtime_to_filetime(asf->creation_time)); avio_wl64(pb, asf->nb_packets); /* number of packets */ avio_wl64(pb, duration); /* end time stamp (in 100ns units) */ avio_wl64(pb, asf->duration); /* duration (in 100ns units) */ -- 2.52.0 >From bc28c3b0d80caef4f277ee6608563b55645f8439 Mon Sep 17 00:00:00 2001 From: Marton Balint <[email protected]> Date: Sun, 14 Jun 2026 01:34:09 +0200 Subject: [PATCH 6/7] avformat/asfdec_o: use common function for setting creation time This also increases precision. Signed-off-by: Marton Balint <[email protected]> --- libavformat/asfdec_o.c | 25 +++---------------------- 1 file changed, 3 insertions(+), 22 deletions(-) diff --git a/libavformat/asfdec_o.c b/libavformat/asfdec_o.c index dd022cb404..f3d3d06891 100644 --- a/libavformat/asfdec_o.c +++ b/libavformat/asfdec_o.c @@ -19,15 +19,12 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ -#include <time.h> - #include "libavutil/attributes.h" #include "libavutil/common.h" #include "libavutil/dict.h" #include "libavutil/internal.h" #include "libavutil/mathematics.h" #include "libavutil/mem.h" -#include "libavutil/time_internal.h" #include "avformat.h" #include "avlanguage.h" @@ -534,31 +531,15 @@ static int asf_read_properties(AVFormatContext *s, const GUIDParseTable *g) { ASFContext *asf = s->priv_data; AVIOContext *pb = s->pb; - time_t creation_time; + int64_t creation_time; avio_rl64(pb); // read object size avio_skip(pb, 16); // skip File ID avio_skip(pb, 8); // skip File size creation_time = avio_rl64(pb); if (!(asf->b_flags & ASF_FLAG_BROADCAST)) { - struct tm tmbuf; - struct tm *tm; - char buf[64]; - - // creation date is in 100 ns units from 1 Jan 1601, conversion to s - creation_time /= 10000000; - // there are 11644473600 seconds between 1 Jan 1601 and 1 Jan 1970 - creation_time -= 11644473600; - tm = gmtime_r(&creation_time, &tmbuf); - if (tm) { - if (!strftime(buf, sizeof(buf), "%Y-%m-%d %H:%M:%S", tm)) - buf[0] = '\0'; - } else - buf[0] = '\0'; - if (buf[0]) { - if (av_dict_set(&s->metadata, "creation_time", buf, 0) < 0) - av_log(s, AV_LOG_WARNING, "av_dict_set failed.\n"); - } + if (ff_dict_set_timestamp(&s->metadata, "creation_time", ff_asf_filetime_to_avtime(creation_time)) < 0) + av_log(s, AV_LOG_WARNING, "av_dict_set failed.\n"); } asf->nb_packets = avio_rl64(pb); asf->duration = avio_rl64(pb) / 10000; // stream duration -- 2.52.0 >From b9bbb262e59f99f61f484b5ff48773dbc29d4252 Mon Sep 17 00:00:00 2001 From: Marton Balint <[email protected]> Date: Sun, 14 Jun 2026 01:34:54 +0200 Subject: [PATCH 7/7] avformat/asfdec_f: set creation time as metadata Signed-off-by: Marton Balint <[email protected]> --- libavformat/asfdec_f.c | 1 + tests/ref/fate/generic-tags-remux-asf | 1 + tests/ref/fate/id3v2-wma-comm | 1 + 3 files changed, 3 insertions(+) diff --git a/libavformat/asfdec_f.c b/libavformat/asfdec_f.c index 1e9ecfe91f..2948461ab1 100644 --- a/libavformat/asfdec_f.c +++ b/libavformat/asfdec_f.c @@ -295,6 +295,7 @@ static int asf_read_file_properties(AVFormatContext *s) asf->hdr.max_bitrate = avio_rl32(pb); s->packet_size = asf->hdr.max_pktsize; + ff_dict_set_timestamp(&s->metadata, "creation_time", ff_asf_filetime_to_avtime(asf->hdr.create_time)); return 0; } diff --git a/tests/ref/fate/generic-tags-remux-asf b/tests/ref/fate/generic-tags-remux-asf index 982ac7cf1c..3f8f0ee0cd 100644 --- a/tests/ref/fate/generic-tags-remux-asf +++ b/tests/ref/fate/generic-tags-remux-asf @@ -29,6 +29,7 @@ 0, 928, 928, 46, 743, 0xdf740eee 0, 975, 975, 46, 743, 0x41c84afe [FORMAT] +TAG:creation_time=1970-01-01T00:00:00.000000Z TAG:publisher=M83 Recording Inc TAG:album_artist=M83 TAG:composer=Anthony Gonzalez diff --git a/tests/ref/fate/id3v2-wma-comm b/tests/ref/fate/id3v2-wma-comm index 5a615d6d93..58130ed733 100644 --- a/tests/ref/fate/id3v2-wma-comm +++ b/tests/ref/fate/id3v2-wma-comm @@ -21,4 +21,5 @@ TAG:composer=Jacques Higelin TAG:WM/EncodingTime=1120324736 TAG:album_artist=Jacques Higelin TAG:WM/Provider=User Feedback +TAG:creation_time=2003-03-23T11:52:22.967000Z [/FORMAT] -- 2.52.0 _______________________________________________ ffmpeg-devel mailing list -- [email protected] To unsubscribe send an email to [email protected]
