[FFmpeg-devel] [PATCH 3/3] avfilter/formats: do not allow unknown layouts in ff_parse_channel_layout if nret is not set
Nicolas George
george at nsup.org
Sat Dec 31 13:34:55 EET 2016
Le sextidi 6 nivôse, an CCXXV, Marton Balint a écrit :
> Current code returned the number of channels as channel layout in that case,
> and if nret is not set then unknown layouts are typically not supported.
Good catch.
Let me see if I got this correctly:
av_get_channel_layout("2c") = stereo
av_get_channel_layout("2C") = 0
av_get_channel_layout("13c") = 0
av_get_channel_layout("13C") = 0
av_get_extended_channel_layout("2c") = stereo / 2
av_get_extended_channel_layout("2C") = 0 / 2
av_get_extended_channel_layout("13c") = EINVAL
av_get_extended_channel_layout("13C") = 0 / 13
ff_parse_channel_layout():
before after
nret == NULL 2c stereo stereo
nret == NULL 2C EINVAL EINVAL
nret == NULL 13c (int64)13 = FL+FC+LF EINVAL
nret == NULL 13C EINVAL EINVAL
nret != NULL 2c stereo / 2 stereo / 2
nret != NULL 2C EINVAL 0 / 2
nret != NULL 13c 0 / 13 EINVAL
nret != NULL 13C EINVAL 0 / 13
Do we agree?
> Also use the common parsing code. This breaks a very specific case, using
> af_pan with an unknown channel layout such as '13c', from now on, only '13C'
> will work.
I think you could easily add a temporary workaround and a warning.
(I suggest, from now on, we flag temporary workarounds and warnings with
a standardized comment: "/* [TEMPORARY 2016-12 -> 2017-12]*/"; that way,
we can find them using git grep.)
> Signed-off-by: Marton Balint <cus at passwd.hu>
> ---
> libavfilter/formats.c | 20 ++++++--------------
> libavfilter/tests/formats.c | 3 +++
> tests/ref/fate/filter-formats | 5 ++++-
> 3 files changed, 13 insertions(+), 15 deletions(-)
>
> diff --git a/libavfilter/formats.c b/libavfilter/formats.c
> index 840780d..8be606f 100644
> --- a/libavfilter/formats.c
> +++ b/libavfilter/formats.c
> @@ -662,24 +662,16 @@ int ff_parse_sample_rate(int *ret, const char *arg, void *log_ctx)
> int ff_parse_channel_layout(int64_t *ret, int *nret, const char *arg,
> void *log_ctx)
> {
> - char *tail;
> int64_t chlayout;
> + int nb_channels;
>
> - chlayout = av_get_channel_layout(arg);
> - if (chlayout == 0) {
> - chlayout = strtol(arg, &tail, 10);
> - if (!(*tail == '\0' || *tail == 'c' && *(tail + 1) == '\0') || chlayout <= 0 || chlayout > 63) {
This is losing the >63 test since av_get_extended_channel_layout() tests
for >64. lavfi can not deal with channel layouts with channel #63 set,
because the bit serves to mark channel counts disguised as layouts;
channel #63 is not defined in lavu anyway. Unknown channel layouts
should work with even more than 64 channels, but that would require
testing.
> - av_log(log_ctx, AV_LOG_ERROR, "Invalid channel layout '%s'\n", arg);
> - return AVERROR(EINVAL);
> - }
> - if (nret) {
> - *nret = chlayout;
> - *ret = 0;
> - return 0;
> - }
> + if (av_get_extended_channel_layout(arg, &chlayout, &nb_channels) < 0 || (!chlayout && !nret)) {
> + av_log(log_ctx, AV_LOG_ERROR, "Invalid channel layout '%s'\n", arg);
Could you split the test to distinguish the warning?
av_get_extended_channel_layout < 0 -> "Invalid channel layout"
(!chlayout && !nret) -> "channel count without layout unsupported"
(it also makes it easier to add the temporary workaround)
> + return AVERROR(EINVAL);
> }
> *ret = chlayout;
> if (nret)
> - *nret = av_get_channel_layout_nb_channels(chlayout);
> + *nret = nb_channels;
> +
> return 0;
> }
> diff --git a/libavfilter/tests/formats.c b/libavfilter/tests/formats.c
> index 0e8ba4a..5450742 100644
> --- a/libavfilter/tests/formats.c
> +++ b/libavfilter/tests/formats.c
> @@ -39,6 +39,9 @@ int main(void)
> "-1c",
> "60c",
> "65c",
> + "2C",
> + "60C",
> + "65C",
> "5.1",
> "stereo",
> "1+1+1+1",
> diff --git a/tests/ref/fate/filter-formats b/tests/ref/fate/filter-formats
> index 4c303d8..17ff5b2 100644
> --- a/tests/ref/fate/filter-formats
> +++ b/tests/ref/fate/filter-formats
> @@ -75,8 +75,11 @@ quad(side)
> 0 = ff_parse_channel_layout(0000000000000004, 1, 1c);
> 0 = ff_parse_channel_layout(0000000000000003, 2, 2c);
> -1 = ff_parse_channel_layout(FFFFFFFFFFFFFFFF, -1, -1c);
> -0 = ff_parse_channel_layout(0000000000000000, 60, 60c);
> +-1 = ff_parse_channel_layout(FFFFFFFFFFFFFFFF, -1, 60c);
> -1 = ff_parse_channel_layout(FFFFFFFFFFFFFFFF, -1, 65c);
> +0 = ff_parse_channel_layout(0000000000000000, 2, 2C);
> +0 = ff_parse_channel_layout(0000000000000000, 60, 60C);
> +-1 = ff_parse_channel_layout(FFFFFFFFFFFFFFFF, -1, 65C);
> 0 = ff_parse_channel_layout(000000000000003F, 6, 5.1);
> 0 = ff_parse_channel_layout(0000000000000003, 2, stereo);
> 0 = ff_parse_channel_layout(0000000000000001, 1, 1+1+1+1);
Regards,
--
Nicolas George
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 833 bytes
Desc: Digital signature
URL: <http://ffmpeg.org/pipermail/ffmpeg-devel/attachments/20161231/5e641776/attachment.sig>
More information about the ffmpeg-devel
mailing list