Function allows to create string containing object's serialized options.
Such string may be passed back to av_set_options_string() in order to restore options.
Signed-off-by: Lukasz Marek <lukasz.m.luki2@gmail.com>
... | ... |
@@ -37,6 +37,7 @@ |
37 | 37 |
#include "pixdesc.h" |
38 | 38 |
#include "mathematics.h" |
39 | 39 |
#include "samplefmt.h" |
40 |
+#include "bprint.h" |
|
40 | 41 |
|
41 | 42 |
#include <float.h> |
42 | 43 |
|
... | ... |
@@ -1835,6 +1836,44 @@ int av_opt_is_set_to_default_by_name(void *obj, const char *name, int search_fla |
1835 | 1835 |
return av_opt_is_set_to_default(target, o); |
1836 | 1836 |
} |
1837 | 1837 |
|
1838 |
+int av_opt_serialize(void *obj, int opt_flags, int flags, char **buffer, |
|
1839 |
+ const char key_val_sep, const char pairs_sep) |
|
1840 |
+{ |
|
1841 |
+ const AVOption *o = NULL; |
|
1842 |
+ uint8_t *buf; |
|
1843 |
+ AVBPrint bprint; |
|
1844 |
+ int ret, cnt = 0; |
|
1845 |
+ |
|
1846 |
+ if (!obj || !buffer) |
|
1847 |
+ return AVERROR(EINVAL); |
|
1848 |
+ |
|
1849 |
+ *buffer = NULL; |
|
1850 |
+ av_bprint_init(&bprint, 64, AV_BPRINT_SIZE_UNLIMITED); |
|
1851 |
+ |
|
1852 |
+ while (o = av_opt_next(obj, o)) { |
|
1853 |
+ if (o->type == AV_OPT_TYPE_CONST) |
|
1854 |
+ continue; |
|
1855 |
+ if ((flags & AV_OPT_SERIALIZE_OPT_FLAGS_EXACT) && o->flags != opt_flags) |
|
1856 |
+ continue; |
|
1857 |
+ else if (((o->flags & opt_flags) != opt_flags)) |
|
1858 |
+ continue; |
|
1859 |
+ if (flags & AV_OPT_SERIALIZE_SKIP_DEFAULTS && av_opt_is_set_to_default(obj, o) > 0) |
|
1860 |
+ continue; |
|
1861 |
+ if ((ret = av_opt_get(obj, o->name, 0, &buf)) < 0) { |
|
1862 |
+ av_bprint_finalize(&bprint, NULL); |
|
1863 |
+ return ret; |
|
1864 |
+ } |
|
1865 |
+ if (buf) { |
|
1866 |
+ if (cnt++) |
|
1867 |
+ av_bprint_append_data(&bprint, &pairs_sep, 1); |
|
1868 |
+ av_bprintf(&bprint, "%s%c%s", o->name, key_val_sep, buf); |
|
1869 |
+ av_freep(&buf); |
|
1870 |
+ } |
|
1871 |
+ } |
|
1872 |
+ av_bprint_finalize(&bprint, buffer); |
|
1873 |
+ return 0; |
|
1874 |
+} |
|
1875 |
+ |
|
1838 | 1876 |
#ifdef TEST |
1839 | 1877 |
|
1840 | 1878 |
typedef struct TestContext |
... | ... |
@@ -1854,6 +1893,10 @@ typedef struct TestContext |
1854 | 1854 |
int64_t channel_layout; |
1855 | 1855 |
void *binary; |
1856 | 1856 |
int binary_size; |
1857 |
+ void *binary1; |
|
1858 |
+ int binary_size1; |
|
1859 |
+ void *binary2; |
|
1860 |
+ int binary_size2; |
|
1857 | 1861 |
int64_t num64; |
1858 | 1862 |
float flt; |
1859 | 1863 |
double dbl; |
... | ... |
@@ -1882,6 +1925,8 @@ static const AVOption test_options[]= { |
1882 | 1882 |
{"color", "set color", OFFSET(color), AV_OPT_TYPE_COLOR, {.str = "pink"}, 0, 0}, |
1883 | 1883 |
{"cl", "set channel layout", OFFSET(channel_layout), AV_OPT_TYPE_CHANNEL_LAYOUT, {.i64 = AV_CH_LAYOUT_HEXAGONAL}, 0, INT64_MAX}, |
1884 | 1884 |
{"bin", "set binary value", OFFSET(binary), AV_OPT_TYPE_BINARY, {.str="62696e00"}, 0, 0 }, |
1885 |
+{"bin1", "set binary value", OFFSET(binary1), AV_OPT_TYPE_BINARY, {.str=NULL}, 0, 0 }, |
|
1886 |
+{"bin2", "set binary value", OFFSET(binary2), AV_OPT_TYPE_BINARY, {.str=""}, 0, 0 }, |
|
1885 | 1887 |
{"num64", "set num 64bit", OFFSET(num64), AV_OPT_TYPE_INT64, {.i64 = 1}, 0, 100 }, |
1886 | 1888 |
{"flt", "set float", OFFSET(flt), AV_OPT_TYPE_FLOAT, {.dbl = 1.0/3}, 0, 100 }, |
1887 | 1889 |
{"dbl", "set double", OFFSET(dbl), AV_OPT_TYPE_DOUBLE, {.dbl = 1.0/3}, 0, 100 }, |
... | ... |
@@ -1951,6 +1996,30 @@ int main(void) |
1951 | 1951 |
av_opt_free(&test_ctx); |
1952 | 1952 |
} |
1953 | 1953 |
|
1954 |
+ printf("\nTest av_opt_serialize()\n"); |
|
1955 |
+ { |
|
1956 |
+ TestContext test_ctx = { 0 }; |
|
1957 |
+ char *buf; |
|
1958 |
+ test_ctx.class = &test_class; |
|
1959 |
+ |
|
1960 |
+ av_log_set_level(AV_LOG_QUIET); |
|
1961 |
+ |
|
1962 |
+ av_opt_set_defaults(&test_ctx); |
|
1963 |
+ if (av_opt_serialize(&test_ctx, 0, 0, &buf, '=', ',') >= 0) { |
|
1964 |
+ printf("%s\n", buf); |
|
1965 |
+ av_opt_free(&test_ctx); |
|
1966 |
+ memset(&test_ctx, 0, sizeof(test_ctx)); |
|
1967 |
+ test_ctx.class = &test_class; |
|
1968 |
+ av_set_options_string(&test_ctx, buf, "=", ","); |
|
1969 |
+ av_free(buf); |
|
1970 |
+ if (av_opt_serialize(&test_ctx, 0, 0, &buf, '=', ',') >= 0) { |
|
1971 |
+ printf("%s\n", buf); |
|
1972 |
+ av_free(buf); |
|
1973 |
+ } |
|
1974 |
+ } |
|
1975 |
+ av_opt_free(&test_ctx); |
|
1976 |
+ } |
|
1977 |
+ |
|
1954 | 1978 |
printf("\nTesting av_set_options_string()\n"); |
1955 | 1979 |
{ |
1956 | 1980 |
TestContext test_ctx = { 0 }; |
... | ... |
@@ -869,6 +869,27 @@ int av_opt_is_set_to_default(void *obj, const AVOption *o); |
869 | 869 |
*/ |
870 | 870 |
int av_opt_is_set_to_default_by_name(void *obj, const char *name, int search_flags); |
871 | 871 |
|
872 |
+ |
|
873 |
+#define AV_OPT_SERIALIZE_SKIP_DEFAULTS 0x00000001 ///< Serialize options that are not set to default values only. |
|
874 |
+#define AV_OPT_SERIALIZE_OPT_FLAGS_EXACT 0x00000002 ///< Serialize options that exactly match opt_flags only. |
|
875 |
+ |
|
876 |
+/** |
|
877 |
+ * Serialize object's options. |
|
878 |
+ * |
|
879 |
+ * Create a string containing object's serialized options. |
|
880 |
+ * Such string may be passed back to av_opt_set_from_string() in order to restore option values. |
|
881 |
+ * |
|
882 |
+ * @param[in] obj AVClass object to serialize |
|
883 |
+ * @param[in] opt_flags serialize options with all the specified flags set (AV_OPT_FLAG) |
|
884 |
+ * @param[in] flags combination of AV_OPT_SERIALIZE_* flags |
|
885 |
+ * @param[out] buffer Pointer to buffer that will be allocated with string containg serialized options. |
|
886 |
+ * Buffer must be freed by the caller when is no longer needed. |
|
887 |
+ * @param[in] key_val_sep character used to separate key from value |
|
888 |
+ * @param[in] pairs_sep character used to separate two pairs from each other |
|
889 |
+ * @return >= 0 on success, negative on error |
|
890 |
+ */ |
|
891 |
+int av_opt_serialize(void *obj, int opt_flags, int flags, char **buffer, |
|
892 |
+ const char key_val_sep, const char pairs_sep); |
|
872 | 893 |
/** |
873 | 894 |
* @} |
874 | 895 |
*/ |
... | ... |
@@ -34,6 +34,8 @@ name: duration default:0 error: |
34 | 34 |
name: color default:0 error: |
35 | 35 |
name: cl default:0 error: |
36 | 36 |
name: bin default:0 error: |
37 |
+name: bin1 default:1 error: |
|
38 |
+name: bin2 default:1 error: |
|
37 | 39 |
name: num64 default:0 error: |
38 | 40 |
name: flt default:0 error: |
39 | 41 |
name: dbl default:0 error: |
... | ... |
@@ -53,10 +55,16 @@ name: duration default:1 error: |
53 | 53 |
name: color default:1 error: |
54 | 54 |
name: cl default:1 error: |
55 | 55 |
name: bin default:1 error: |
56 |
+name: bin1 default:1 error: |
|
57 |
+name: bin2 default:1 error: |
|
56 | 58 |
name: num64 default:1 error: |
57 | 59 |
name: flt default:1 error: |
58 | 60 |
name: dbl default:1 error: |
59 | 61 |
|
62 |
+Test av_opt_serialize() |
|
63 |
+num=0,toggle=1,rational=1/1,string=default,flags=0x00000001,size=200x300,pix_fmt=0bgr,sample_fmt=s16,video_rate=25/1,duration=0:00:00.001000,color=0xffc0cbff,cl=0x137,bin=62696E00,bin1=,bin2=,num64=1,flt=0.333333,dbl=0.333333 |
|
64 |
+num=0,toggle=1,rational=1/1,string=default,flags=0x00000001,size=200x300,pix_fmt=0bgr,sample_fmt=s16,video_rate=25/1,duration=0:00:00.001000,color=0xffc0cbff,cl=0x137,bin=62696E00,bin1=,bin2=,num64=1,flt=0.333333,dbl=0.333333 |
|
65 |
+ |
|
60 | 66 |
Testing av_set_options_string() |
61 | 67 |
OK '' |
62 | 68 |
Error ':' |