[FFmpeg-devel] [PATCH 3/3] lavfi/formats: document the negotiation process
Nicolas George
george at nsup.org
Fri Aug 20 14:30:47 EEST 2021
Nicolas George (12021-08-19):
> + * FIXME: the similarity logic (the ref argument to
> + * pick_format()) added in FFmpeg duplicates and
> + * overrides the swapping logic added in libav. Better
> + * merge them into a score system.
For sample formats, here are the scoring matrices used by each logic:
Sample formats matrix for pick_formats(), small is best:
in\o u8 s16 s32 flt dbl u8p s16p s32p fltp dblp s64 s64p
u8 0 10 30 30 70 1 11 31 31 71 70 71
s16 100 0 20 20 60 101 1 21 21 61 60 61
s32 300 200 0 2 40 301 201 1 3 41 40 41
flt 300 200 20 0 40 301 201 21 1 41 40 41
dbl 700 600 400 400 0 701 601 401 401 1 0 1
u8p 1 11 31 31 71 0 10 30 30 70 71 70
s16p 101 1 21 21 61 100 0 20 20 60 61 60
s32p 301 201 1 3 41 300 200 0 2 40 41 40
fltp 301 201 21 1 41 300 200 20 0 40 41 40
dblp 701 601 401 401 1 700 600 400 400 0 1 0
s64 700 600 400 400 0 701 601 401 401 1 0 1
s64p 701 601 401 401 1 700 600 400 400 0 1 0
Sample formats matrix for swap_sample_fmts() with INT_MAX/2=100000, large is best:
in\o u8 s16 s32 flt dbl u8p s16p s32p fltp dblp s64 s64p
u8 inf 99999 99997 99997 99993 inf 99999 99997 99997 99993 99993 99993
s16 -1 inf 99998 99998 99994 -1 inf 99998 99998 99994 99994 99994
s32 -3 -2 inf 100000 inf -3 -2 inf 100000 inf inf inf
flt -3 -2 100000 inf inf -3 -2 100000 inf inf inf inf
dbl -7 -6 -4 -4 inf -7 -6 -4 -4 inf 100000 100000
u8p inf 99999 99997 99997 99993 inf 99999 99997 99997 99993 99993 99993
s16p -1 inf 99998 99998 99994 -1 inf 99998 99998 99994 99994 99994
s32p -3 -2 inf 100000 inf -3 -2 inf 100000 inf inf inf
fltp -3 -2 100000 inf inf -3 -2 100000 inf inf inf inf
dblp -7 -6 -4 -4 inf -7 -6 -4 -4 inf 100000 100000
s64 -7 -6 -4 -4 100000 -7 -6 -4 -4 100000 inf inf
s64p -7 -6 -4 -4 100000 -7 -6 -4 -4 100000 inf inf
In the second case, inf is a special case that breaks the loop looking
for the best format. That means that for s16, it can pick s16p if it is
present before s16p. The logic in pick_formats() explicitly favors the
same planarity.
Apart from that, the logic seem to yield the same kind of results.
For a system where scores will be combined between several possible
conversions, I think I will not just add the scores but use a bucket
system, where the bucket "precision loss" at weight 1 is always worse
than any amount in the bucket "precision waste".
For reference, this is the code I used:
static void
print_score_matrices(void)
{
int i, j;
printf("\nSample formats matrix for pick_formats(), small is best:\n");
printf("in\\o");
for (j = 0; j < AV_SAMPLE_FMT_NB; j++)
printf(" %6s", av_get_sample_fmt_name(j));
printf("\n");
for (i = 0; i < AV_SAMPLE_FMT_NB; i++) {
printf("%-4s", av_get_sample_fmt_name(i));
for (j = 0; j < AV_SAMPLE_FMT_NB; j++)
printf(" %6d", get_fmt_score(j, i));
printf("\n");
}
printf("\nSample formats matrix for swap_sample_fmts() with INT_MAX/2=100000, large is best:\n");
printf("in\\o");
for (j = 0; j < AV_SAMPLE_FMT_NB; j++)
printf(" %6s", av_get_sample_fmt_name(j));
printf("\n");
for (i = 0; i < AV_SAMPLE_FMT_NB; i++) {
printf("%-4s", av_get_sample_fmt_name(i));
for (j = 0; j < AV_SAMPLE_FMT_NB; j++) {
int bps = av_get_bytes_per_sample(i);
int out_bps = av_get_bytes_per_sample(j);
int score;
if (av_get_packed_sample_fmt(j) == i ||
av_get_planar_sample_fmt(j) == i) {
printf(" %6s", "inf");
} else if (bps == 4 && out_bps == 8) {
printf(" %6s", "inf");
} else {
score = -abs(out_bps - bps);
if (out_bps >= bps)
score += 100000;
printf(" %6d", score);
}
}
printf("\n");
}
printf("\n");
}
Regards,
--
Nicolas George
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 833 bytes
Desc: not available
URL: <https://ffmpeg.org/pipermail/ffmpeg-devel/attachments/20210820/85387b4f/attachment.sig>
More information about the ffmpeg-devel
mailing list