Mercurial > libavcodec.hg
comparison opt.c @ 2873:55809f38eb63 libavcodec
AVOption API improvments
support AVOptions for encoding in ffmpeg.c
author | michael |
---|---|
date | Sun, 11 Sep 2005 11:10:25 +0000 |
parents | 3b999ce45b37 |
children | b6def74f5811 |
comparison
equal
deleted
inserted
replaced
2872:062b2d5d1eba | 2873:55809f38eb63 |
---|---|
50 if(last && last[1].name) return ++last; | 50 if(last && last[1].name) return ++last; |
51 else if(last) return NULL; | 51 else if(last) return NULL; |
52 else return (*(AVClass**)obj)->option; | 52 else return (*(AVClass**)obj)->option; |
53 } | 53 } |
54 | 54 |
55 static int av_set_number(void *obj, const char *name, double num, int den, int64_t intnum){ | 55 static AVOption *av_set_number(void *obj, const char *name, double num, int den, int64_t intnum){ |
56 AVOption *o= find_opt(obj, name); | 56 AVOption *o= find_opt(obj, name); |
57 void *dst; | 57 void *dst; |
58 if(!o || o->offset<=0) | 58 if(!o || o->offset<=0) |
59 return -1; | 59 return NULL; |
60 | 60 |
61 if(o->max*den < num*intnum || o->min*den > num*intnum) | 61 if(o->max*den < num*intnum || o->min*den > num*intnum) |
62 return -1; | 62 return NULL; |
63 | 63 |
64 dst= ((uint8_t*)obj) + o->offset; | 64 dst= ((uint8_t*)obj) + o->offset; |
65 | 65 |
66 switch(o->type){ | 66 switch(o->type){ |
67 case FF_OPT_TYPE_INT: | 67 case FF_OPT_TYPE_INT: *(int *)dst= lrintf(num/den)*intnum; break; |
68 *(int*)dst= lrintf(num/den)*intnum; | 68 case FF_OPT_TYPE_INT64: *(int64_t *)dst= lrintf(num/den)*intnum; break; |
69 break; | 69 case FF_OPT_TYPE_FLOAT: *(float *)dst= num*intnum/den; break; |
70 case FF_OPT_TYPE_INT64: | 70 case FF_OPT_TYPE_DOUBLE:*(double *)dst= num*intnum/den; break; |
71 *(int64_t*)dst= lrintf(num/den)*intnum; | |
72 break; | |
73 case FF_OPT_TYPE_FLOAT: | |
74 *(float*)dst= num*intnum/den; | |
75 break; | |
76 case FF_OPT_TYPE_DOUBLE: | |
77 *(double*)dst= num*intnum/den; | |
78 break; | |
79 case FF_OPT_TYPE_RATIONAL: | 71 case FF_OPT_TYPE_RATIONAL: |
80 if((int)num == num) | 72 if((int)num == num) *(AVRational*)dst= (AVRational){num*intnum, den}; |
81 *(AVRational*)dst= (AVRational){num*intnum, den}; | 73 else *(AVRational*)dst= av_d2q(num*intnum/den, 1<<24); |
82 else | |
83 *(AVRational*)dst= av_d2q(num*intnum/den, 1<<24); | |
84 default: | 74 default: |
85 return -1; | 75 return NULL; |
86 } | 76 } |
87 return 0; | 77 return o; |
88 } | 78 } |
89 | 79 |
90 //FIXME use eval.c maybe? | 80 //FIXME use eval.c maybe? |
91 int av_set_string(void *obj, const char *name, const char *val){ | 81 AVOption *av_set_string(void *obj, const char *name, const char *val){ |
92 AVOption *o= find_opt(obj, name); | 82 AVOption *o= find_opt(obj, name); |
93 if(!o || !val || o->offset<=0) | 83 if(!o || !val || o->offset<=0) |
94 return -1; | 84 return NULL; |
95 if(o->type != FF_OPT_TYPE_STRING){ | 85 if(o->type != FF_OPT_TYPE_STRING){ |
96 double d=0, tmp_d; | 86 double d=0, tmp_d; |
97 for(;;){ | 87 for(;;){ |
98 int i; | 88 int i; |
99 char buf[256], *tail; | 89 char buf[256], *tail; |
111 if(o_named && o_named->type == FF_OPT_TYPE_CONST) | 101 if(o_named && o_named->type == FF_OPT_TYPE_CONST) |
112 d+= o_named->default_val; | 102 d+= o_named->default_val; |
113 else if(!strcmp(buf, "default")) d+= o->default_val; | 103 else if(!strcmp(buf, "default")) d+= o->default_val; |
114 else if(!strcmp(buf, "max" )) d+= o->max; | 104 else if(!strcmp(buf, "max" )) d+= o->max; |
115 else if(!strcmp(buf, "min" )) d+= o->min; | 105 else if(!strcmp(buf, "min" )) d+= o->min; |
116 else return -1; | 106 else return NULL; |
117 } | 107 } |
118 | 108 |
119 if(*val == '+') val++; | 109 if(*val == '+') val++; |
120 if(!*val) | 110 if(!*val) |
121 return av_set_number(obj, name, d, 1, 1); | 111 return av_set_number(obj, name, d, 1, 1); |
122 } | 112 } |
123 return -1; | 113 return NULL; |
124 } | 114 } |
125 | 115 |
126 memcpy(((uint8_t*)obj) + o->offset, val, sizeof(val)); | 116 memcpy(((uint8_t*)obj) + o->offset, val, sizeof(val)); |
127 return 0; | 117 return o; |
128 } | 118 } |
129 | 119 |
130 int av_set_double(void *obj, const char *name, double n){ | 120 AVOption *av_set_double(void *obj, const char *name, double n){ |
131 return av_set_number(obj, name, n, 1, 1); | 121 return av_set_number(obj, name, n, 1, 1); |
132 } | 122 } |
133 | 123 |
134 int av_set_q(void *obj, const char *name, AVRational n){ | 124 AVOption *av_set_q(void *obj, const char *name, AVRational n){ |
135 return av_set_number(obj, name, n.num, n.den, 1); | 125 return av_set_number(obj, name, n.num, n.den, 1); |
136 } | 126 } |
137 | 127 |
138 int av_set_int(void *obj, const char *name, int64_t n){ | 128 AVOption *av_set_int(void *obj, const char *name, int64_t n){ |
139 return av_set_number(obj, name, 1, 1, n); | 129 return av_set_number(obj, name, 1, 1, n); |
140 } | 130 } |
141 | 131 |
142 const char *av_get_string(void *obj, const char *name){ | 132 /** |
143 AVOption *o= find_opt(obj, name); | 133 * |
144 if(!o || o->offset<=0) | 134 * @param buf a buffer which is used for returning non string values as strings, can be NULL |
145 return NULL; | 135 * @param buf_len allocated length in bytes of buf |
146 if(o->type != FF_OPT_TYPE_STRING) //FIXME convert to string? but what about free()? | 136 */ |
147 return NULL; | 137 const char *av_get_string(void *obj, const char *name, AVOption **o_out, char *buf, int buf_len){ |
148 | |
149 return (const char*)(((uint8_t*)obj) + o->offset); | |
150 } | |
151 | |
152 double av_get_double(void *obj, const char *name){ | |
153 AVOption *o= find_opt(obj, name); | 138 AVOption *o= find_opt(obj, name); |
154 void *dst; | 139 void *dst; |
155 if(!o || o->offset<=0) | 140 if(!o || o->offset<=0) |
156 return NAN; | 141 return NULL; |
142 if(o->type != FF_OPT_TYPE_STRING && (!buf || !buf_len)) | |
143 return NULL; | |
157 | 144 |
158 dst= ((uint8_t*)obj) + o->offset; | 145 dst= ((uint8_t*)obj) + o->offset; |
159 | 146 if(o_out) *o_out= o; |
147 | |
148 if(o->type == FF_OPT_TYPE_STRING) | |
149 return dst; | |
150 | |
160 switch(o->type){ | 151 switch(o->type){ |
161 case FF_OPT_TYPE_INT: return *(int*)dst; | 152 case FF_OPT_TYPE_INT: snprintf(buf, buf_len, "%d" , *(int *)dst);break; |
162 case FF_OPT_TYPE_INT64: return *(int64_t*)dst; //FIXME maybe write a av_get_int64() ? | 153 case FF_OPT_TYPE_INT64: snprintf(buf, buf_len, "%Ld", *(int64_t*)dst);break; |
163 case FF_OPT_TYPE_FLOAT: return *(float*)dst; | 154 case FF_OPT_TYPE_FLOAT: snprintf(buf, buf_len, "%f" , *(float *)dst);break; |
164 case FF_OPT_TYPE_DOUBLE: return *(double*)dst; | 155 case FF_OPT_TYPE_DOUBLE: snprintf(buf, buf_len, "%f" , *(double *)dst);break; |
165 case FF_OPT_TYPE_RATIONAL: return av_q2d(*(AVRational*)dst); //FIXME maybe write a av_get_q() ? | 156 case FF_OPT_TYPE_RATIONAL: snprintf(buf, buf_len, "%d/%d", ((AVRational*)dst)->num, ((AVRational*)dst)->den);break; |
166 default: return NAN; | 157 default: return NULL; |
167 } | 158 } |
168 } | 159 return buf; |
160 } | |
161 | |
162 static int av_get_number(void *obj, const char *name, AVOption **o_out, double *num, int *den, int64_t *intnum){ | |
163 AVOption *o= find_opt(obj, name); | |
164 void *dst; | |
165 if(!o || o->offset<=0) | |
166 goto error; | |
167 | |
168 dst= ((uint8_t*)obj) + o->offset; | |
169 | |
170 if(o_out) *o_out= o; | |
171 | |
172 switch(o->type){ | |
173 case FF_OPT_TYPE_INT: *intnum= *(int *)dst;return 0; | |
174 case FF_OPT_TYPE_INT64: *intnum= *(int64_t*)dst;return 0; | |
175 case FF_OPT_TYPE_FLOAT: *num= *(float *)dst;return 0; | |
176 case FF_OPT_TYPE_DOUBLE: *num= *(double *)dst;return 0; | |
177 case FF_OPT_TYPE_RATIONAL: *intnum= ((AVRational*)dst)->num; | |
178 *den = ((AVRational*)dst)->den; | |
179 return 0; | |
180 } | |
181 error: | |
182 *den=*intnum=0; | |
183 return -1; | |
184 } | |
185 | |
186 double av_get_double(void *obj, const char *name, AVOption **o_out){ | |
187 int64_t intnum=1; | |
188 double num=1; | |
189 int den=1; | |
190 | |
191 av_get_number(obj, name, o_out, &num, &den, &intnum); | |
192 return num*intnum/den; | |
193 } | |
194 | |
195 AVRational av_get_q(void *obj, const char *name, AVOption **o_out){ | |
196 int64_t intnum=1; | |
197 double num=1; | |
198 int den=1; | |
199 | |
200 av_get_number(obj, name, o_out, &num, &den, &intnum); | |
201 if(num == 1.0 && (int)intnum == intnum) | |
202 return (AVRational){intnum, den}; | |
203 else | |
204 return av_d2q(num*intnum/den, 1<<24); | |
205 } | |
206 | |
207 int64_t av_get_int(void *obj, const char *name, AVOption **o_out){ | |
208 int64_t intnum=1; | |
209 double num=1; | |
210 int den=1; | |
211 | |
212 av_get_number(obj, name, o_out, &num, &den, &intnum); | |
213 return num*intnum/den; | |
214 } | |
215 | |
216 int av_opt_show(void *obj, FILE *f){ | |
217 AVOption *opt=NULL; | |
218 | |
219 if(!obj) | |
220 return -1; | |
221 #undef fprintf | |
222 fprintf(f, "%s AVOptions:\n", (*(AVClass**)obj)->class_name); | |
223 | |
224 while((opt= av_next_option(obj, opt))){ | |
225 if(!(opt->flags & (AV_OPT_FLAG_ENCODING_PARAM|AV_OPT_FLAG_DECODING_PARAM))) | |
226 continue; | |
227 | |
228 fprintf(f, "-%-17s ", opt->name); | |
229 fprintf(f, "%c", (opt->flags & AV_OPT_FLAG_ENCODING_PARAM) ? 'E' : '.'); | |
230 fprintf(f, "%c", (opt->flags & AV_OPT_FLAG_DECODING_PARAM) ? 'D' : '.'); | |
231 fprintf(f, "%c", (opt->flags & AV_OPT_FLAG_VIDEO_PARAM ) ? 'V' : '.'); | |
232 fprintf(f, "%c", (opt->flags & AV_OPT_FLAG_AUDIO_PARAM ) ? 'A' : '.'); | |
233 fprintf(f, "%c", (opt->flags & AV_OPT_FLAG_SUBTITLE_PARAM) ? 'S' : '.'); | |
234 | |
235 fprintf(f, " %s\n", opt->help); | |
236 } | |
237 return 0; | |
238 } |