| @@ -1732,6 +1732,109 @@ void av_opt_freep_ranges(AVOptionRanges **rangesp) · 1731 unmodified lines |
| 1732 | 1732 | av_freep(rangesp); |
| 1733 | 1733 | } |
| 1734 | 1734 | |
| 1735 | +int av_opt_is_set_to_default(void *obj, const AVOption *o) |
| 1736 | +{ |
| 1737 | + int64_t i64; |
| 1738 | + double d, d2; |
| 1739 | + float f; |
| 1740 | + AVRational q; |
| 1741 | + int ret, w, h; |
| 1742 | + char *str; |
| 1743 | + void *dst; |
| 1744 | + |
| 1745 | + if (!o || !obj) |
| 1746 | + return AVERROR(EINVAL); |
| 1747 | + |
| 1748 | + dst = ((uint8_t*)obj) + o->offset; |
| 1749 | + |
| 1750 | + switch (o->type) { |
| 1751 | + case AV_OPT_TYPE_CONST: |
| 1752 | + return 1; |
| 1753 | + case AV_OPT_TYPE_FLAGS: |
| 1754 | + case AV_OPT_TYPE_PIXEL_FMT: |
| 1755 | + case AV_OPT_TYPE_SAMPLE_FMT: |
| 1756 | + case AV_OPT_TYPE_INT: |
| 1757 | + case AV_OPT_TYPE_CHANNEL_LAYOUT: |
| 1758 | + case AV_OPT_TYPE_DURATION: |
| 1759 | + case AV_OPT_TYPE_INT64: |
| 1760 | + read_number(o, dst, NULL, NULL, &i64); |
| 1761 | + return o->default_val.i64 == i64; |
| 1762 | + case AV_OPT_TYPE_STRING: |
| 1763 | + str = *(char **)dst; |
| 1764 | + if (str == o->default_val.str) //2 NULLs |
| 1765 | + return 1; |
| 1766 | + if (!str || !o->default_val.str) //1 NULL |
| 1767 | + return 0; |
| 1768 | + return !strcmp(str, o->default_val.str); |
| 1769 | + case AV_OPT_TYPE_DOUBLE: |
| 1770 | + read_number(o, dst, &d, NULL, NULL); |
| 1771 | + return o->default_val.dbl == d; |
| 1772 | + case AV_OPT_TYPE_FLOAT: |
| 1773 | + read_number(o, dst, &d, NULL, NULL); |
| 1774 | + f = o->default_val.dbl; |
| 1775 | + d2 = f; |
| 1776 | + return d2 == d; |
| 1777 | + case AV_OPT_TYPE_RATIONAL: |
| 1778 | + q = av_d2q(o->default_val.dbl, INT_MAX); |
| 1779 | + return !av_cmp_q(*(AVRational*)dst, q); |
| 1780 | + case AV_OPT_TYPE_BINARY: { |
| 1781 | + struct { |
| 1782 | + uint8_t *data; |
| 1783 | + int size; |
| 1784 | + } tmp = {0}; |
| 1785 | + int opt_size = *(int *)((void **)dst + 1); |
| 1786 | + void *opt_ptr = *(void **)dst; |
| 1787 | + if (!opt_ptr && (!o->default_val.str || !strlen(o->default_val.str))) |
| 1788 | + return 1; |
| 1789 | + if (opt_ptr && o->default_val.str && !strlen(o->default_val.str)) |
| 1790 | + return 0; |
| 1791 | + if (opt_size != strlen(o->default_val.str) / 2) |
| 1792 | + return 0; |
| 1793 | + ret = set_string_binary(NULL, NULL, o->default_val.str, &tmp.data); |
| 1794 | + if (!ret) |
| 1795 | + ret = !memcmp(opt_ptr, tmp.data, tmp.size); |
| 1796 | + av_free(tmp.data); |
| 1797 | + return ret; |
| 1798 | + } |
| 1799 | + case AV_OPT_TYPE_DICT: |
| 1800 | + /* Binary and dict have not default support yet. Any pointer is not default. */ |
| 1801 | + return !!(*(void **)dst); |
| 1802 | + case AV_OPT_TYPE_IMAGE_SIZE: |
| 1803 | + if (!o->default_val.str || !strcmp(o->default_val.str, "none")) |
| 1804 | + w = h = 0; |
| 1805 | + else if ((ret = av_parse_video_size(&w, &h, o->default_val.str)) < 0) |
| 1806 | + return ret; |
| 1807 | + return (w == *(int *)dst) && (h == *((int *)dst+1)); |
| 1808 | + case AV_OPT_TYPE_VIDEO_RATE: |
| 1809 | + q = (AVRational){0, 0}; |
| 1810 | + if (o->default_val.str) |
| 1811 | + av_parse_video_rate(&q, o->default_val.str); |
| 1812 | + return !av_cmp_q(*(AVRational*)dst, q); |
| 1813 | + case AV_OPT_TYPE_COLOR: { |
| 1814 | + uint8_t color[4] = {0, 0, 0, 0}; |
| 1815 | + if (o->default_val.str) |
| 1816 | + av_parse_color(color, o->default_val.str, -1, NULL); |
| 1817 | + return !memcmp(color, dst, sizeof(color)); |
| 1818 | + } |
| 1819 | + default: |
| 1820 | + av_log(obj, AV_LOG_WARNING, "Not supported option type: %d, option name: %s\n", o->type, o->name); |
| 1821 | + break; |
| 1822 | + } |
| 1823 | + return AVERROR_PATCHWELCOME; |
| 1824 | +} |
| 1825 | + |
| 1826 | +int av_opt_is_set_to_default_by_name(void *obj, const char *name, int search_flags) |
| 1827 | +{ |
| 1828 | + const AVOption *o; |
| 1829 | + void *target; |
| 1830 | + if (!obj) |
| 1831 | + return AVERROR(EINVAL); |
| 1832 | + o = av_opt_find2(obj, name, NULL, 0, search_flags, &target); |
| 1833 | + if (!o) |
| 1834 | + return AVERROR_OPTION_NOT_FOUND; |
| 1835 | + return av_opt_is_set_to_default(target, o); |
| 1836 | +} |
| 1837 | + |
| 1735 | 1838 | #ifdef TEST |
| 1736 | 1839 | |
| 1737 | 1840 | typedef struct TestContext |
| @@ -1827,6 +1930,27 @@ int main(void) · 89 unmodified lines |
| 1827 | 1930 | av_opt_free(&test_ctx); |
| 1828 | 1931 | } |
| 1829 | 1932 | |
| 1933 | + printf("\nTesting av_opt_is_set_to_default()\n"); |
| 1934 | + { |
| 1935 | + int ret; |
| 1936 | + TestContext test_ctx = { 0 }; |
| 1937 | + const AVOption *o = NULL; |
| 1938 | + test_ctx.class = &test_class; |
| 1939 | + |
| 1940 | + av_log_set_level(AV_LOG_QUIET); |
| 1941 | + |
| 1942 | + while (o = av_opt_next(&test_ctx, o)) { |
| 1943 | + ret = av_opt_is_set_to_default_by_name(&test_ctx, o->name, 0); |
| 1944 | + printf("name:%10s default:%d error:%s\n", o->name, !!ret, ret < 0 ? av_err2str(ret) : ""); |
| 1945 | + } |
| 1946 | + av_opt_set_defaults(&test_ctx); |
| 1947 | + while (o = av_opt_next(&test_ctx, o)) { |
| 1948 | + ret = av_opt_is_set_to_default_by_name(&test_ctx, o->name, 0); |
| 1949 | + printf("name:%10s default:%d error:%s\n", o->name, !!ret, ret < 0 ? av_err2str(ret) : ""); |
| 1950 | + } |
| 1951 | + av_opt_free(&test_ctx); |
| 1952 | + } |
| 1953 | + |
| 1830 | 1954 | printf("\nTesting av_set_options_string()\n"); |
| 1831 | 1955 | { |
| 1832 | 1956 | TestContext test_ctx = { 0 }; |