summaryrefslogtreecommitdiff
path: root/libavutil
diff options
context:
space:
mode:
authorAnton Khirnov <anton@khirnov.net>2013-08-26 08:13:49 +0200
committerJames Almer <jamrial@gmail.com>2022-03-15 09:42:29 -0300
commitf423497b455da06c1337846902c770028760e094 (patch)
tree716dfd0924b8031a2f8044399481e30decce235e /libavutil
parentf51e169d2b20d731a7b338e1381e438a5abe586f (diff)
lavu: support AVChannelLayout AVOptions
Signed-off-by: Vittorio Giovara <vittorio.giovara@gmail.com> Signed-off-by: James Almer <jamrial@gmail.com>
Diffstat (limited to 'libavutil')
-rw-r--r--libavutil/opt.c126
-rw-r--r--libavutil/opt.h12
-rw-r--r--libavutil/tests/opt.c8
3 files changed, 141 insertions, 5 deletions
diff --git a/libavutil/opt.c b/libavutil/opt.c
index d951edca9d..445537fbad 100644
--- a/libavutil/opt.c
+++ b/libavutil/opt.c
@@ -39,6 +39,7 @@
#include "opt.h"
#include "samplefmt.h"
#include "bprint.h"
+#include "version.h"
#include <float.h>
@@ -71,7 +72,11 @@ static int read_number(const AVOption *o, const void *dst, double *num, int *den
case AV_OPT_TYPE_INT:
*intnum = *(int *)dst;
return 0;
+#if FF_API_OLD_CHANNEL_LAYOUT
+FF_DISABLE_DEPRECATION_WARNINGS
case AV_OPT_TYPE_CHANNEL_LAYOUT:
+FF_ENABLE_DEPRECATION_WARNINGS
+#endif
case AV_OPT_TYPE_DURATION:
case AV_OPT_TYPE_INT64:
case AV_OPT_TYPE_UINT64:
@@ -126,7 +131,11 @@ static int write_number(void *obj, const AVOption *o, void *dst, double num, int
*(int *)dst = llrint(num / den) * intnum;
break;
case AV_OPT_TYPE_DURATION:
+#if FF_API_OLD_CHANNEL_LAYOUT
+FF_DISABLE_DEPRECATION_WARNINGS
case AV_OPT_TYPE_CHANNEL_LAYOUT:
+FF_ENABLE_DEPRECATION_WARNINGS
+#endif
case AV_OPT_TYPE_INT64:{
double d = num / den;
if (intnum == 1 && d == (double)INT64_MAX) {
@@ -465,6 +474,16 @@ static int set_string_dict(void *obj, const AVOption *o, const char *val, uint8_
return 0;
}
+static int set_string_channel_layout(void *obj, const AVOption *o,
+ const char *val, void *dst)
+{
+ AVChannelLayout *channel_layout = dst;
+ av_channel_layout_uninit(channel_layout);
+ if (!val)
+ return 0;
+ return av_channel_layout_from_string(channel_layout, val);
+}
+
int av_opt_set(void *obj, const char *name, const char *val, int search_flags)
{
int ret = 0;
@@ -472,12 +491,17 @@ int av_opt_set(void *obj, const char *name, const char *val, int search_flags)
const AVOption *o = av_opt_find2(obj, name, NULL, 0, search_flags, &target_obj);
if (!o || !target_obj)
return AVERROR_OPTION_NOT_FOUND;
+FF_DISABLE_DEPRECATION_WARNINGS
if (!val && (o->type != AV_OPT_TYPE_STRING &&
o->type != AV_OPT_TYPE_PIXEL_FMT && o->type != AV_OPT_TYPE_SAMPLE_FMT &&
o->type != AV_OPT_TYPE_IMAGE_SIZE &&
o->type != AV_OPT_TYPE_DURATION && o->type != AV_OPT_TYPE_COLOR &&
- o->type != AV_OPT_TYPE_CHANNEL_LAYOUT && o->type != AV_OPT_TYPE_BOOL))
+#if FF_API_OLD_CHANNEL_LAYOUT
+ o->type != AV_OPT_TYPE_CHANNEL_LAYOUT &&
+#endif
+ o->type != AV_OPT_TYPE_BOOL))
return AVERROR(EINVAL);
+FF_ENABLE_DEPRECATION_WARNINGS
if (o->flags & AV_OPT_FLAG_READONLY)
return AVERROR(EINVAL);
@@ -533,6 +557,8 @@ int av_opt_set(void *obj, const char *name, const char *val, int search_flags)
}
case AV_OPT_TYPE_COLOR:
return set_string_color(obj, o, val, dst);
+#if FF_API_OLD_CHANNEL_LAYOUT
+FF_DISABLE_DEPRECATION_WARNINGS
case AV_OPT_TYPE_CHANNEL_LAYOUT:
if (!val || !strcmp(val, "none")) {
*(int64_t *)dst = 0;
@@ -546,6 +572,15 @@ int av_opt_set(void *obj, const char *name, const char *val, int search_flags)
return ret;
}
break;
+FF_ENABLE_DEPRECATION_WARNINGS
+#endif
+ case AV_OPT_TYPE_CHLAYOUT:
+ ret = set_string_channel_layout(obj, o, val, dst);
+ if (ret < 0) {
+ av_log(obj, AV_LOG_ERROR, "Unable to parse option value \"%s\" as channel layout\n", val);
+ ret = AVERROR(EINVAL);
+ }
+ return ret;
case AV_OPT_TYPE_DICT:
return set_string_dict(obj, o, val, dst);
}
@@ -709,6 +744,8 @@ int av_opt_set_sample_fmt(void *obj, const char *name, enum AVSampleFormat fmt,
return set_format(obj, name, fmt, search_flags, AV_OPT_TYPE_SAMPLE_FMT, "sample", AV_SAMPLE_FMT_NB);
}
+#if FF_API_OLD_CHANNEL_LAYOUT
+FF_DISABLE_DEPRECATION_WARNINGS
int av_opt_set_channel_layout(void *obj, const char *name, int64_t cl, int search_flags)
{
void *target_obj;
@@ -724,6 +761,8 @@ int av_opt_set_channel_layout(void *obj, const char *name, int64_t cl, int searc
*(int64_t *)(((uint8_t *)target_obj) + o->offset) = cl;
return 0;
}
+FF_ENABLE_DEPRECATION_WARNINGS
+#endif
int av_opt_set_dict_val(void *obj, const char *name, const AVDictionary *val,
int search_flags)
@@ -744,6 +783,22 @@ int av_opt_set_dict_val(void *obj, const char *name, const AVDictionary *val,
return 0;
}
+int av_opt_set_chlayout(void *obj, const char *name,
+ const AVChannelLayout *channel_layout,
+ int search_flags)
+{
+ void *target_obj;
+ const AVOption *o = av_opt_find2(obj, name, NULL, 0, search_flags, &target_obj);
+ AVChannelLayout *dst;
+
+ if (!o || !target_obj)
+ return AVERROR_OPTION_NOT_FOUND;
+
+ dst = (AVChannelLayout*)((uint8_t*)target_obj + o->offset);
+
+ return av_channel_layout_copy(dst, channel_layout);
+}
+
static void format_duration(char *buf, size_t size, int64_t d)
{
char *e;
@@ -872,10 +927,18 @@ int av_opt_get(void *obj, const char *name, int search_flags, uint8_t **out_val)
(int)((uint8_t *)dst)[0], (int)((uint8_t *)dst)[1],
(int)((uint8_t *)dst)[2], (int)((uint8_t *)dst)[3]);
break;
+#if FF_API_OLD_CHANNEL_LAYOUT
+FF_DISABLE_DEPRECATION_WARNINGS
case AV_OPT_TYPE_CHANNEL_LAYOUT:
+
i64 = *(int64_t *)dst;
ret = snprintf(buf, sizeof(buf), "0x%"PRIx64, i64);
break;
+FF_ENABLE_DEPRECATION_WARNINGS
+#endif
+ case AV_OPT_TYPE_CHLAYOUT:
+ ret = av_channel_layout_describe(dst, buf, sizeof(buf));
+ break;
case AV_OPT_TYPE_DICT:
if (!*(AVDictionary **)dst && (search_flags & AV_OPT_ALLOW_NULL)) {
*out_val = NULL;
@@ -1017,6 +1080,8 @@ int av_opt_get_sample_fmt(void *obj, const char *name, int search_flags, enum AV
return get_format(obj, name, search_flags, out_fmt, AV_OPT_TYPE_SAMPLE_FMT, "sample");
}
+#if FF_API_OLD_CHANNEL_LAYOUT
+FF_DISABLE_DEPRECATION_WARNINGS
int av_opt_get_channel_layout(void *obj, const char *name, int search_flags, int64_t *cl)
{
void *dst, *target_obj;
@@ -1033,6 +1098,24 @@ int av_opt_get_channel_layout(void *obj, const char *name, int search_flags, int
*cl = *(int64_t *)dst;
return 0;
}
+FF_ENABLE_DEPRECATION_WARNINGS
+#endif
+
+int av_opt_get_chlayout(void *obj, const char *name, int search_flags, AVChannelLayout *cl)
+{
+ void *dst, *target_obj;
+ const AVOption *o = av_opt_find2(obj, name, NULL, 0, search_flags, &target_obj);
+ if (!o || !target_obj)
+ return AVERROR_OPTION_NOT_FOUND;
+ if (o->type != AV_OPT_TYPE_CHLAYOUT) {
+ av_log(obj, AV_LOG_ERROR,
+ "The value for option '%s' is not a channel layout.\n", name);
+ return AVERROR(EINVAL);
+ }
+
+ dst = ((uint8_t*)target_obj) + o->offset;
+ return av_channel_layout_copy(cl, dst);
+}
int av_opt_get_dict_val(void *obj, const char *name, int search_flags, AVDictionary **out_val)
{
@@ -1225,7 +1308,12 @@ static void opt_list(void *obj, void *av_log_obj, const char *unit,
case AV_OPT_TYPE_COLOR:
av_log(av_log_obj, AV_LOG_INFO, "%-12s ", "<color>");
break;
+ case AV_OPT_TYPE_CHLAYOUT:
+#if FF_API_OLD_CHANNEL_LAYOUT
+FF_DISABLE_DEPRECATION_WARNINGS
case AV_OPT_TYPE_CHANNEL_LAYOUT:
+FF_ENABLE_DEPRECATION_WARNINGS
+#endif
av_log(av_log_obj, AV_LOG_INFO, "%-12s ", "<channel_layout>");
break;
case AV_OPT_TYPE_BOOL:
@@ -1282,6 +1370,7 @@ static void opt_list(void *obj, void *av_log_obj, const char *unit,
opt->type == AV_OPT_TYPE_IMAGE_SIZE ||
opt->type == AV_OPT_TYPE_STRING ||
opt->type == AV_OPT_TYPE_DICT ||
+ opt->type == AV_OPT_TYPE_CHLAYOUT ||
opt->type == AV_OPT_TYPE_VIDEO_RATE) &&
!opt->default_val.str)) {
av_log(av_log_obj, AV_LOG_INFO, " (default ");
@@ -1334,11 +1423,16 @@ static void opt_list(void *obj, void *av_log_obj, const char *unit,
case AV_OPT_TYPE_STRING:
case AV_OPT_TYPE_DICT:
case AV_OPT_TYPE_VIDEO_RATE:
+ case AV_OPT_TYPE_CHLAYOUT:
av_log(av_log_obj, AV_LOG_INFO, "\"%s\"", opt->default_val.str);
break;
+#if FF_API_OLD_CHANNEL_LAYOUT
+FF_DISABLE_DEPRECATION_WARNINGS
case AV_OPT_TYPE_CHANNEL_LAYOUT:
av_log(av_log_obj, AV_LOG_INFO, "0x%"PRIx64, opt->default_val.i64);
break;
+FF_ENABLE_DEPRECATION_WARNINGS
+#endif
}
av_log(av_log_obj, AV_LOG_INFO, ")");
}
@@ -1388,7 +1482,11 @@ void av_opt_set_defaults2(void *s, int mask, int flags)
case AV_OPT_TYPE_INT64:
case AV_OPT_TYPE_UINT64:
case AV_OPT_TYPE_DURATION:
+#if FF_API_OLD_CHANNEL_LAYOUT
+FF_DISABLE_DEPRECATION_WARNINGS
case AV_OPT_TYPE_CHANNEL_LAYOUT:
+FF_ENABLE_DEPRECATION_WARNINGS
+#endif
case AV_OPT_TYPE_PIXEL_FMT:
case AV_OPT_TYPE_SAMPLE_FMT:
write_number(s, opt, dst, 1, 1, opt->default_val.i64);
@@ -1421,6 +1519,9 @@ void av_opt_set_defaults2(void *s, int mask, int flags)
case AV_OPT_TYPE_BINARY:
set_string_binary(s, opt, opt->default_val.str, dst);
break;
+ case AV_OPT_TYPE_CHLAYOUT:
+ set_string_channel_layout(s, opt, opt->default_val.str, dst);
+ break;
case AV_OPT_TYPE_DICT:
set_string_dict(s, opt, opt->default_val.str, dst);
break;
@@ -1745,7 +1846,11 @@ static int opt_size(enum AVOptionType type)
case AV_OPT_TYPE_FLAGS:
return sizeof(int);
case AV_OPT_TYPE_DURATION:
+#if FF_API_OLD_CHANNEL_LAYOUT
+FF_DISABLE_DEPRECATION_WARNINGS
case AV_OPT_TYPE_CHANNEL_LAYOUT:
+FF_ENABLE_DEPRECATION_WARNINGS
+#endif
case AV_OPT_TYPE_INT64:
case AV_OPT_TYPE_UINT64:
return sizeof(int64_t);
@@ -1819,6 +1924,9 @@ int av_opt_copy(void *dst, const void *src)
ret2 = av_dict_copy(ddict, *sdict, 0);
if (ret2 < 0)
ret = ret2;
+ } else if (o->type == AV_OPT_TYPE_CHLAYOUT) {
+ if (field_dst != field_src)
+ ret = av_channel_layout_copy(field_dst, field_src);
} else {
int size = opt_size(o->type);
if (size < 0)
@@ -1882,7 +1990,11 @@ int av_opt_query_ranges_default(AVOptionRanges **ranges_arg, void *obj, const ch
case AV_OPT_TYPE_DOUBLE:
case AV_OPT_TYPE_DURATION:
case AV_OPT_TYPE_COLOR:
+#if FF_API_OLD_CHANNEL_LAYOUT
+FF_DISABLE_DEPRECATION_WARNINGS
case AV_OPT_TYPE_CHANNEL_LAYOUT:
+FF_ENABLE_DEPRECATION_WARNINGS
+#endif
break;
case AV_OPT_TYPE_STRING:
range->component_min = 0;
@@ -1962,12 +2074,24 @@ int av_opt_is_set_to_default(void *obj, const AVOption *o)
case AV_OPT_TYPE_PIXEL_FMT:
case AV_OPT_TYPE_SAMPLE_FMT:
case AV_OPT_TYPE_INT:
+#if FF_API_OLD_CHANNEL_LAYOUT
+FF_DISABLE_DEPRECATION_WARNINGS
case AV_OPT_TYPE_CHANNEL_LAYOUT:
+FF_ENABLE_DEPRECATION_WARNINGS
+#endif
case AV_OPT_TYPE_DURATION:
case AV_OPT_TYPE_INT64:
case AV_OPT_TYPE_UINT64:
read_number(o, dst, NULL, NULL, &i64);
return o->default_val.i64 == i64;
+ case AV_OPT_TYPE_CHLAYOUT: {
+ AVChannelLayout ch_layout = { 0 };
+ if (o->default_val.str) {
+ if ((ret = av_channel_layout_from_string(&ch_layout, o->default_val.str)) < 0)
+ return ret;
+ }
+ return !av_channel_layout_compare((AVChannelLayout *)dst, &ch_layout);
+ }
case AV_OPT_TYPE_STRING:
str = *(char **)dst;
if (str == o->default_val.str) //2 NULLs
diff --git a/libavutil/opt.h b/libavutil/opt.h
index 2820435eec..461b5d3b6b 100644
--- a/libavutil/opt.h
+++ b/libavutil/opt.h
@@ -29,6 +29,7 @@
#include "rational.h"
#include "avutil.h"
+#include "channel_layout.h"
#include "dict.h"
#include "log.h"
#include "pixfmt.h"
@@ -237,8 +238,11 @@ enum AVOptionType{
AV_OPT_TYPE_VIDEO_RATE, ///< offset must point to AVRational
AV_OPT_TYPE_DURATION,
AV_OPT_TYPE_COLOR,
+#if FF_API_OLD_CHANNEL_LAYOUT
AV_OPT_TYPE_CHANNEL_LAYOUT,
+#endif
AV_OPT_TYPE_BOOL,
+ AV_OPT_TYPE_CHLAYOUT,
};
/**
@@ -693,7 +697,11 @@ int av_opt_set_image_size(void *obj, const char *name, int w, int h, int search_
int av_opt_set_pixel_fmt (void *obj, const char *name, enum AVPixelFormat fmt, int search_flags);
int av_opt_set_sample_fmt(void *obj, const char *name, enum AVSampleFormat fmt, int search_flags);
int av_opt_set_video_rate(void *obj, const char *name, AVRational val, int search_flags);
+#if FF_API_OLD_CHANNEL_LAYOUT
+attribute_deprecated
int av_opt_set_channel_layout(void *obj, const char *name, int64_t ch_layout, int search_flags);
+#endif
+int av_opt_set_chlayout(void *obj, const char *name, const AVChannelLayout *layout, int search_flags);
/**
* @note Any old dictionary present is discarded and replaced with a copy of the new one. The
* caller still owns val is and responsible for freeing it.
@@ -748,7 +756,11 @@ int av_opt_get_image_size(void *obj, const char *name, int search_flags, int *w_
int av_opt_get_pixel_fmt (void *obj, const char *name, int search_flags, enum AVPixelFormat *out_fmt);
int av_opt_get_sample_fmt(void *obj, const char *name, int search_flags, enum AVSampleFormat *out_fmt);
int av_opt_get_video_rate(void *obj, const char *name, int search_flags, AVRational *out_val);
+#if FF_API_OLD_CHANNEL_LAYOUT
+attribute_deprecated
int av_opt_get_channel_layout(void *obj, const char *name, int search_flags, int64_t *ch_layout);
+#endif
+int av_opt_get_chlayout(void *obj, const char *name, int search_flags, AVChannelLayout *layout);
/**
* @param[out] out_val The returned dictionary is a copy of the actual value and must
* be freed with av_dict_free() by the caller
diff --git a/libavutil/tests/opt.c b/libavutil/tests/opt.c
index e6ea892373..5799e45c6a 100644
--- a/libavutil/tests/opt.c
+++ b/libavutil/tests/opt.c
@@ -41,7 +41,7 @@ typedef struct TestContext {
enum AVSampleFormat sample_fmt;
int64_t duration;
uint8_t color[4];
- int64_t channel_layout;
+ AVChannelLayout channel_layout;
void *binary;
int binary_size;
void *binary1;
@@ -81,7 +81,7 @@ static const AVOption test_options[]= {
{"video_rate", "set videorate", OFFSET(video_rate), AV_OPT_TYPE_VIDEO_RATE, { .str = "25" }, 0, INT_MAX, 1 },
{"duration", "set duration", OFFSET(duration), AV_OPT_TYPE_DURATION, { .i64 = 1000 }, 0, INT64_MAX, 1 },
{"color", "set color", OFFSET(color), AV_OPT_TYPE_COLOR, { .str = "pink" }, 0, 0, 1 },
- {"cl", "set channel layout", OFFSET(channel_layout), AV_OPT_TYPE_CHANNEL_LAYOUT, { .i64 = AV_CH_LAYOUT_HEXAGONAL }, 0, INT64_MAX, 1 },
+ {"cl", "set channel layout", OFFSET(channel_layout), AV_OPT_TYPE_CHLAYOUT, { .str = "hexagonal" }, 0, 0, 1 },
{"bin", "set binary value", OFFSET(binary), AV_OPT_TYPE_BINARY, { .str="62696e00" }, 0, 0, 1 },
{"bin1", "set binary value", OFFSET(binary1), AV_OPT_TYPE_BINARY, { .str=NULL }, 0, 0, 1 },
{"bin2", "set binary value", OFFSET(binary2), AV_OPT_TYPE_BINARY, { .str="" }, 0, 0, 1 },
@@ -138,7 +138,7 @@ int main(void)
printf("sample_fmt=%s\n", av_get_sample_fmt_name(test_ctx.sample_fmt));
printf("duration=%"PRId64"\n", test_ctx.duration);
printf("color=%d %d %d %d\n", test_ctx.color[0], test_ctx.color[1], test_ctx.color[2], test_ctx.color[3]);
- printf("channel_layout=%"PRId64"=%"PRId64"\n", test_ctx.channel_layout, (int64_t)AV_CH_LAYOUT_HEXAGONAL);
+ printf("channel_layout=%"PRId64"=%"PRId64"\n", test_ctx.channel_layout.u.mask, (int64_t)AV_CH_LAYOUT_HEXAGONAL);
if (test_ctx.binary)
printf("binary=%x %x %x %x\n", ((uint8_t*)test_ctx.binary)[0], ((uint8_t*)test_ctx.binary)[1], ((uint8_t*)test_ctx.binary)[2], ((uint8_t*)test_ctx.binary)[3]);
printf("binary_size=%d\n", test_ctx.binary_size);
@@ -280,7 +280,7 @@ int main(void)
"color=blue",
"color=0x223300",
"color=0x42FF07AA",
- "cl=stereo+downmix",
+ "cl=FL+FR",
"cl=foo",
"bin=boguss",
"bin=111",