[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