summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAnton Khirnov <anton@khirnov.net>2023-03-12 17:01:12 +0100
committerAnton Khirnov <anton@khirnov.net>2023-03-14 15:12:13 +0100
commitf76ce9133ddaee988549e9ae0a0df8723392acaa (patch)
treea949d491d699f6334fc7c65c946b533406ec0905
parent74e292a3556b7f06e52c2a898726bb3d927fc8cc (diff)
lavfi/framesync: switch ts maps to use pts+timebaseframe_map_sort
Also, sort the entries.
-rw-r--r--doc/filters.texi6
-rw-r--r--libavfilter/framesync.c44
-rw-r--r--libavfilter/framesync.h7
3 files changed, 44 insertions, 13 deletions
diff --git a/doc/filters.texi b/doc/filters.texi
index afc6fd3ebf..bd964d4094 100644
--- a/doc/filters.texi
+++ b/doc/filters.texi
@@ -377,9 +377,9 @@ input frame.
@item ts_map
Specify an explicit timestamp map. The string should be composed of lines, one
-per each output frame. The line should contain whitespace-separated times in
-microseconds, one for every input. Frames with these timestamps will be matched
-together to produces output events.
+per each output frame. The line should contain whitespace-separated pairs of
+"pts tb_num/tb_den", one for every input. Frames with these timestamps will be
+matched together to produces output events.
@end table
@c man end OPTIONS FOR FILTERS WITH SEVERAL INPUTS
diff --git a/libavfilter/framesync.c b/libavfilter/framesync.c
index 6e628af647..2042c83a0b 100644
--- a/libavfilter/framesync.c
+++ b/libavfilter/framesync.c
@@ -130,10 +130,17 @@ static void framesync_sync_level_update(FFFrameSync *fs)
framesync_eof(fs);
}
+static int map_sort(const void *m1, const void *m2)
+{
+ const TSMapEntry *e1 = m1;
+ const TSMapEntry *e2 = m2;
+ return av_compare_ts(e1->pts, e1->tb, e2->pts, e2->tb);
+}
+
static int ts_map_parse(FFFrameSync *fs, const char *ts_map_str)
{
while (*ts_map_str) {
- int64_t *dst;
+ TSMapEntry *dst;
ts_map_str += strspn(ts_map_str, " \t\r\n");
@@ -153,7 +160,7 @@ static int ts_map_parse(FFFrameSync *fs, const char *ts_map_str)
// read a timestamp for each input
for (int i = 0; i < fs->nb_in; i++) {
char *p;
- dst[i] = strtol(ts_map_str, &p, 0);
+ dst[i].pts = strtol(ts_map_str, &p, 0);
if (p == ts_map_str) {
av_log(fs, AV_LOG_ERROR,
"Invalid number in timestamp map on line %zu: %s\n",
@@ -162,14 +169,29 @@ static int ts_map_parse(FFFrameSync *fs, const char *ts_map_str)
}
ts_map_str = p;
- if (fs->nb_ts_map > 1 && dst[i - (int)fs->nb_in] > dst[i]) {
- av_log(fs, AV_LOG_ERROR,
- "Timestamp map for input %d, frame %zu goes backwards\n",
- i, fs->nb_ts_map - 1);
+ ts_map_str += strspn(ts_map_str, " \t");
+
+ dst[i].tb.num = strtol(ts_map_str, &p, 0);
+ if (p == ts_map_str) {
+ av_log(fs, AV_LOG_ERROR, "Expected timebase numerator, got %s\n", p);
+ return AVERROR_INVALIDDATA;
+ };
+ ts_map_str = p;
+
+ ts_map_str += strspn(ts_map_str, " \t");
+ if (*ts_map_str != '/') {
+ av_log(fs, AV_LOG_ERROR, "Expected '/' as the timebase separator, got %s\n", ts_map_str);
return AVERROR_INVALIDDATA;
}
+ ts_map_str++;
+ dst[i].tb.den = strtol(ts_map_str, &p, 0);
+ if (p == ts_map_str) {
+ av_log(fs, AV_LOG_ERROR, "Expected timebase denominator, got %s\n", p);
+ return AVERROR_INVALIDDATA;
+ }
+ ts_map_str = p;
- ts_map_str += strspn(p, " \t");
+ ts_map_str += strspn(ts_map_str, " \t");
}
// skip everything after the needed timestamp
@@ -179,6 +201,9 @@ skip_line:
break;
}
+ if (fs->ts_map)
+ qsort(fs->ts_map, fs->nb_ts_map, sizeof(*fs->ts_map) * fs->nb_in, map_sort);
+
return 0;
}
@@ -349,8 +374,9 @@ static int framesync_advance(FFFrameSync *fs)
fs->frame_ready = 1;
for (i = 0; i < fs->nb_in; i++) {
FFFrameSyncIn * const in = &fs->in[i];
- int64_t next_ts = av_rescale_q(fs->ts_map[fs->nb_events * fs->nb_in + i],
- AV_TIME_BASE_Q, fs->time_base);
+ int64_t next_ts = av_rescale_q(fs->ts_map[fs->nb_events * fs->nb_in + i].pts,
+ fs->ts_map[fs->nb_events * fs->nb_in + i].tb,
+ fs->time_base);
uint64_t delta_cur = in->frame ? FFABS(in->pts - next_ts) : UINT64_MAX;
uint64_t delta_next = in->frame_next ? FFABS(in->pts_next - next_ts) : UINT64_MAX;
diff --git a/libavfilter/framesync.h b/libavfilter/framesync.h
index 979f54e16e..10b116c925 100644
--- a/libavfilter/framesync.h
+++ b/libavfilter/framesync.h
@@ -162,6 +162,11 @@ typedef struct FFFrameSyncIn {
enum FFFrameTSSyncMode ts_mode;
} FFFrameSyncIn;
+typedef struct TSMapEntry {
+ int64_t pts;
+ AVRational tb;
+} TSMapEntry;
+
/**
* Frame sync structure.
*/
@@ -237,7 +242,7 @@ typedef struct FFFrameSync {
char *ts_map_str;
// explicit frame map
- int64_t *ts_map;
+ TSMapEntry *ts_map;
size_t nb_ts_map;
unsigned int ts_map_allocated;
} FFFrameSync;