| 2071 | #endif |
| 2072 | |
| 2073 | static int opt_copy_elem(void *logctx, enum AVOptionType type, |
| 2074 | void *dst, const void *src) |
| 2075 | { |
| 2076 | if (type == AV_OPT_TYPE_STRING) { |
| 2077 | const char *src_str = *(const char *const *)src; |
| 2078 | char **dstp = (char **)dst; |
| 2079 | if (*dstp != src_str) |
| 2080 | av_freep(dstp); |
| 2081 | if (src_str) { |
| 2082 | *dstp = av_strdup(src_str); |
| 2083 | if (!*dstp) |
| 2084 | return AVERROR(ENOMEM); |
| 2085 | } |
| 2086 | } else if (type == AV_OPT_TYPE_BINARY) { |
| 2087 | const uint8_t *const *src8 = (const uint8_t *const *)src; |
| 2088 | uint8_t **dst8 = (uint8_t **)dst; |
| 2089 | int len = *(const int *)(src8 + 1); |
| 2090 | if (*dst8 != *src8) |
| 2091 | av_freep(dst8); |
| 2092 | *dst8 = av_memdup(*src8, len); |
| 2093 | if (len && !*dst8) { |
| 2094 | *(int *)(dst8 + 1) = 0; |
| 2095 | return AVERROR(ENOMEM); |
| 2096 | } |
| 2097 | *(int *)(dst8 + 1) = len; |
| 2098 | } else if (type == AV_OPT_TYPE_CONST) { |
| 2099 | // do nothing |
| 2100 | } else if (type == AV_OPT_TYPE_DICT) { |
| 2101 | const AVDictionary *sdict = *(const AVDictionary * const *)src; |
| 2102 | AVDictionary **ddictp = (AVDictionary **)dst; |
| 2103 | if (sdict != *ddictp) |
| 2104 | av_dict_free(ddictp); |
| 2105 | *ddictp = NULL; |
| 2106 | return av_dict_copy(ddictp, sdict, 0); |
| 2107 | } else if (type == AV_OPT_TYPE_CHLAYOUT) { |
| 2108 | if (dst != src) |
| 2109 | return av_channel_layout_copy(dst, src); |
| 2110 | } else if (opt_is_pod(type)) { |
| 2111 | size_t size = opt_type_desc[type].size; |
| 2112 | memcpy(dst, src, size); |
| 2113 | } else { |
| 2114 | av_log(logctx, AV_LOG_ERROR, "Unhandled option type: %d\n", type); |
| 2115 | return AVERROR(EINVAL); |
| 2116 | } |
| 2117 | |
| 2118 | return 0; |
| 2119 | } |
| 2120 | |
| 2121 | static int opt_copy_array(void *logctx, const AVOption *o, |
| 2122 | void **pdst, const void * const *psrc) |
no test coverage detected