00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #include "libavcodec/imgconvert.h"
00025 #include "libavutil/pixdesc.h"
00026 #include "avfilter.h"
00027
00028 unsigned avfilter_version(void) {
00029 return LIBAVFILTER_VERSION_INT;
00030 }
00031
00032 const char *avfilter_configuration(void)
00033 {
00034 return FFMPEG_CONFIGURATION;
00035 }
00036
00037 const char *avfilter_license(void)
00038 {
00039 #define LICENSE_PREFIX "libavfilter license: "
00040 return LICENSE_PREFIX FFMPEG_LICENSE + sizeof(LICENSE_PREFIX) - 1;
00041 }
00042
00044 #define link_dpad(link) link->dst-> input_pads[link->dstpad]
00045 #define link_spad(link) link->src->output_pads[link->srcpad]
00046
00047 AVFilterPicRef *avfilter_ref_pic(AVFilterPicRef *ref, int pmask)
00048 {
00049 AVFilterPicRef *ret = av_malloc(sizeof(AVFilterPicRef));
00050 *ret = *ref;
00051 ret->perms &= pmask;
00052 ret->pic->refcount ++;
00053 return ret;
00054 }
00055
00056 void avfilter_unref_pic(AVFilterPicRef *ref)
00057 {
00058 if(!(--ref->pic->refcount))
00059 ref->pic->free(ref->pic);
00060 av_free(ref);
00061 }
00062
00063 void avfilter_insert_pad(unsigned idx, unsigned *count, size_t padidx_off,
00064 AVFilterPad **pads, AVFilterLink ***links,
00065 AVFilterPad *newpad)
00066 {
00067 unsigned i;
00068
00069 idx = FFMIN(idx, *count);
00070
00071 *pads = av_realloc(*pads, sizeof(AVFilterPad) * (*count + 1));
00072 *links = av_realloc(*links, sizeof(AVFilterLink*) * (*count + 1));
00073 memmove(*pads +idx+1, *pads +idx, sizeof(AVFilterPad) * (*count-idx));
00074 memmove(*links+idx+1, *links+idx, sizeof(AVFilterLink*) * (*count-idx));
00075 memcpy(*pads+idx, newpad, sizeof(AVFilterPad));
00076 (*links)[idx] = NULL;
00077
00078 (*count) ++;
00079 for(i = idx+1; i < *count; i ++)
00080 if(*links[i])
00081 (*(unsigned *)((uint8_t *) *links[i] + padidx_off)) ++;
00082 }
00083
00084 int avfilter_link(AVFilterContext *src, unsigned srcpad,
00085 AVFilterContext *dst, unsigned dstpad)
00086 {
00087 AVFilterLink *link;
00088
00089 if(src->output_count <= srcpad || dst->input_count <= dstpad ||
00090 src->outputs[srcpad] || dst->inputs[dstpad])
00091 return -1;
00092
00093 src->outputs[srcpad] =
00094 dst-> inputs[dstpad] = link = av_mallocz(sizeof(AVFilterLink));
00095
00096 link->src = src;
00097 link->dst = dst;
00098 link->srcpad = srcpad;
00099 link->dstpad = dstpad;
00100 link->format = PIX_FMT_NONE;
00101
00102 return 0;
00103 }
00104
00105 int avfilter_insert_filter(AVFilterLink *link, AVFilterContext *filt,
00106 unsigned in, unsigned out)
00107 {
00108 av_log(link->dst, AV_LOG_INFO, "auto-inserting filter '%s' "
00109 "between the filter '%s' and the filter '%s'\n",
00110 filt->name, link->src->name, link->dst->name);
00111
00112 link->dst->inputs[link->dstpad] = NULL;
00113 if(avfilter_link(filt, out, link->dst, link->dstpad)) {
00114
00115 link->dst->inputs[link->dstpad] = link;
00116 return -1;
00117 }
00118
00119
00120 link->dst = filt;
00121 link->dstpad = in;
00122 filt->inputs[in] = link;
00123
00124
00125
00126 if(link->out_formats)
00127 avfilter_formats_changeref(&link->out_formats,
00128 &filt->outputs[out]->out_formats);
00129
00130 return 0;
00131 }
00132
00133 int avfilter_config_links(AVFilterContext *filter)
00134 {
00135 int (*config_link)(AVFilterLink *);
00136 unsigned i;
00137
00138 for(i = 0; i < filter->input_count; i ++) {
00139 AVFilterLink *link = filter->inputs[i];
00140
00141 if(!link) continue;
00142
00143 switch(link->init_state) {
00144 case AVLINK_INIT:
00145 continue;
00146 case AVLINK_STARTINIT:
00147 av_log(filter, AV_LOG_INFO, "circular filter chain detected\n");
00148 return 0;
00149 case AVLINK_UNINIT:
00150 link->init_state = AVLINK_STARTINIT;
00151
00152 if(avfilter_config_links(link->src))
00153 return -1;
00154
00155 if(!(config_link = link_spad(link).config_props))
00156 config_link = avfilter_default_config_output_link;
00157 if(config_link(link))
00158 return -1;
00159
00160 if((config_link = link_dpad(link).config_props))
00161 if(config_link(link))
00162 return -1;
00163
00164 link->init_state = AVLINK_INIT;
00165 }
00166 }
00167
00168 return 0;
00169 }
00170
00171 static void dprintf_picref(void *ctx, AVFilterPicRef *picref, int end)
00172 {
00173 dprintf(ctx,
00174 "picref[%p data[%p, %p, %p, %p] linesize[%d, %d, %d, %d] pts:%"PRId64" pos:%"PRId64" a:%d/%d s:%dx%d]%s",
00175 picref,
00176 picref->data [0], picref->data [1], picref->data [2], picref->data [3],
00177 picref->linesize[0], picref->linesize[1], picref->linesize[2], picref->linesize[3],
00178 picref->pts, picref->pos,
00179 picref->pixel_aspect.num, picref->pixel_aspect.den, picref->w, picref->h,
00180 end ? "\n" : "");
00181 }
00182
00183 static void dprintf_link(void *ctx, AVFilterLink *link, int end)
00184 {
00185 dprintf(ctx,
00186 "link[%p s:%dx%d fmt:%-16s %-16s->%-16s]%s",
00187 link, link->w, link->h,
00188 av_pix_fmt_descriptors[link->format].name,
00189 link->src ? link->src->filter->name : "",
00190 link->dst ? link->dst->filter->name : "",
00191 end ? "\n" : "");
00192 }
00193
00194 #define DPRINTF_START(ctx, func) dprintf(NULL, "%-16s: ", #func)
00195
00196 AVFilterPicRef *avfilter_get_video_buffer(AVFilterLink *link, int perms, int w, int h)
00197 {
00198 AVFilterPicRef *ret = NULL;
00199
00200 DPRINTF_START(NULL, get_video_buffer); dprintf_link(NULL, link, 0); dprintf(NULL, " perms:%d w:%d h:%d\n", perms, w, h);
00201
00202 if(link_dpad(link).get_video_buffer)
00203 ret = link_dpad(link).get_video_buffer(link, perms, w, h);
00204
00205 if(!ret)
00206 ret = avfilter_default_get_video_buffer(link, perms, w, h);
00207
00208 DPRINTF_START(NULL, get_video_buffer); dprintf_link(NULL, link, 0); dprintf(NULL, " returning "); dprintf_picref(NULL, ret, 1);
00209
00210 return ret;
00211 }
00212
00213 int avfilter_request_frame(AVFilterLink *link)
00214 {
00215 DPRINTF_START(NULL, request_frame); dprintf_link(NULL, link, 1);
00216
00217 if(link_spad(link).request_frame)
00218 return link_spad(link).request_frame(link);
00219 else if(link->src->inputs[0])
00220 return avfilter_request_frame(link->src->inputs[0]);
00221 else return -1;
00222 }
00223
00224 int avfilter_poll_frame(AVFilterLink *link)
00225 {
00226 int i, min=INT_MAX;
00227
00228 if(link_spad(link).poll_frame)
00229 return link_spad(link).poll_frame(link);
00230
00231 for (i=0; i<link->src->input_count; i++) {
00232 int val;
00233 if(!link->src->inputs[i])
00234 return -1;
00235 val = avfilter_poll_frame(link->src->inputs[i]);
00236 min = FFMIN(min, val);
00237 }
00238
00239 return min;
00240 }
00241
00242
00243
00244 void avfilter_start_frame(AVFilterLink *link, AVFilterPicRef *picref)
00245 {
00246 void (*start_frame)(AVFilterLink *, AVFilterPicRef *);
00247 AVFilterPad *dst = &link_dpad(link);
00248
00249 DPRINTF_START(NULL, start_frame); dprintf_link(NULL, link, 0); dprintf(NULL, " "); dprintf_picref(NULL, picref, 1);
00250
00251 if(!(start_frame = dst->start_frame))
00252 start_frame = avfilter_default_start_frame;
00253
00254
00255 if((dst->min_perms & picref->perms) != dst->min_perms ||
00256 dst->rej_perms & picref->perms) {
00257
00258
00259
00260
00261
00262
00263
00264 link->cur_pic = avfilter_default_get_video_buffer(link, dst->min_perms, link->w, link->h);
00265 link->srcpic = picref;
00266 link->cur_pic->pts = link->srcpic->pts;
00267 link->cur_pic->pos = link->srcpic->pos;
00268 link->cur_pic->pixel_aspect = link->srcpic->pixel_aspect;
00269 }
00270 else
00271 link->cur_pic = picref;
00272
00273 start_frame(link, link->cur_pic);
00274 }
00275
00276 void avfilter_end_frame(AVFilterLink *link)
00277 {
00278 void (*end_frame)(AVFilterLink *);
00279
00280 if(!(end_frame = link_dpad(link).end_frame))
00281 end_frame = avfilter_default_end_frame;
00282
00283 end_frame(link);
00284
00285
00286
00287 if(link->srcpic) {
00288 avfilter_unref_pic(link->srcpic);
00289 link->srcpic = NULL;
00290 }
00291
00292 }
00293
00294 void avfilter_draw_slice(AVFilterLink *link, int y, int h, int slice_dir)
00295 {
00296 uint8_t *src[4], *dst[4];
00297 int i, j, vsub;
00298 void (*draw_slice)(AVFilterLink *, int, int, int);
00299
00300 DPRINTF_START(NULL, draw_slice); dprintf_link(NULL, link, 0); dprintf(NULL, " y:%d h:%d dir:%d\n", y, h, slice_dir);
00301
00302
00303 if(link->srcpic) {
00304 vsub = av_pix_fmt_descriptors[link->format].log2_chroma_h;
00305
00306 for(i = 0; i < 4; i ++) {
00307 if(link->srcpic->data[i]) {
00308 src[i] = link->srcpic-> data[i] +
00309 (y >> (i==0 ? 0 : vsub)) * link->srcpic-> linesize[i];
00310 dst[i] = link->cur_pic->data[i] +
00311 (y >> (i==0 ? 0 : vsub)) * link->cur_pic->linesize[i];
00312 } else
00313 src[i] = dst[i] = NULL;
00314 }
00315
00316 for(i = 0; i < 4; i ++) {
00317 int planew =
00318 ff_get_plane_bytewidth(link->format, link->cur_pic->w, i);
00319
00320 if(!src[i]) continue;
00321
00322 for(j = 0; j < h >> (i==0 ? 0 : vsub); j ++) {
00323 memcpy(dst[i], src[i], planew);
00324 src[i] += link->srcpic ->linesize[i];
00325 dst[i] += link->cur_pic->linesize[i];
00326 }
00327 }
00328 }
00329
00330 if(!(draw_slice = link_dpad(link).draw_slice))
00331 draw_slice = avfilter_default_draw_slice;
00332 draw_slice(link, y, h, slice_dir);
00333 }
00334
00335 #define MAX_REGISTERED_AVFILTERS_NB 64
00336
00337 static AVFilter *registered_avfilters[MAX_REGISTERED_AVFILTERS_NB + 1];
00338
00339 static int next_registered_avfilter_idx = 0;
00340
00341 AVFilter *avfilter_get_by_name(const char *name)
00342 {
00343 int i;
00344
00345 for (i = 0; registered_avfilters[i]; i++)
00346 if (!strcmp(registered_avfilters[i]->name, name))
00347 return registered_avfilters[i];
00348
00349 return NULL;
00350 }
00351
00352 int avfilter_register(AVFilter *filter)
00353 {
00354 if (next_registered_avfilter_idx == MAX_REGISTERED_AVFILTERS_NB)
00355 return -1;
00356
00357 registered_avfilters[next_registered_avfilter_idx++] = filter;
00358 return 0;
00359 }
00360
00361 AVFilter **av_filter_next(AVFilter **filter)
00362 {
00363 return filter ? ++filter : ®istered_avfilters[0];
00364 }
00365
00366 void avfilter_uninit(void)
00367 {
00368 memset(registered_avfilters, 0, sizeof(registered_avfilters));
00369 next_registered_avfilter_idx = 0;
00370 }
00371
00372 static int pad_count(const AVFilterPad *pads)
00373 {
00374 int count;
00375
00376 for(count = 0; pads->name; count ++) pads ++;
00377 return count;
00378 }
00379
00380 static const char *filter_name(void *p)
00381 {
00382 AVFilterContext *filter = p;
00383 return filter->filter->name;
00384 }
00385
00386 static const AVClass avfilter_class = {
00387 "AVFilter",
00388 filter_name,
00389 NULL,
00390 LIBAVUTIL_VERSION_INT,
00391 };
00392
00393 AVFilterContext *avfilter_open(AVFilter *filter, const char *inst_name)
00394 {
00395 AVFilterContext *ret;
00396
00397 if (!filter)
00398 return 0;
00399
00400 ret = av_mallocz(sizeof(AVFilterContext));
00401
00402 ret->av_class = &avfilter_class;
00403 ret->filter = filter;
00404 ret->name = inst_name ? av_strdup(inst_name) : NULL;
00405 ret->priv = av_mallocz(filter->priv_size);
00406
00407 ret->input_count = pad_count(filter->inputs);
00408 if (ret->input_count) {
00409 ret->input_pads = av_malloc(sizeof(AVFilterPad) * ret->input_count);
00410 memcpy(ret->input_pads, filter->inputs, sizeof(AVFilterPad) * ret->input_count);
00411 ret->inputs = av_mallocz(sizeof(AVFilterLink*) * ret->input_count);
00412 }
00413
00414 ret->output_count = pad_count(filter->outputs);
00415 if (ret->output_count) {
00416 ret->output_pads = av_malloc(sizeof(AVFilterPad) * ret->output_count);
00417 memcpy(ret->output_pads, filter->outputs, sizeof(AVFilterPad) * ret->output_count);
00418 ret->outputs = av_mallocz(sizeof(AVFilterLink*) * ret->output_count);
00419 }
00420
00421 return ret;
00422 }
00423
00424 void avfilter_destroy(AVFilterContext *filter)
00425 {
00426 int i;
00427
00428 if(filter->filter->uninit)
00429 filter->filter->uninit(filter);
00430
00431 for(i = 0; i < filter->input_count; i ++) {
00432 if(filter->inputs[i])
00433 filter->inputs[i]->src->outputs[filter->inputs[i]->srcpad] = NULL;
00434 av_freep(&filter->inputs[i]);
00435 }
00436 for(i = 0; i < filter->output_count; i ++) {
00437 if(filter->outputs[i])
00438 filter->outputs[i]->dst->inputs[filter->outputs[i]->dstpad] = NULL;
00439 av_freep(&filter->outputs[i]);
00440 }
00441
00442 av_freep(&filter->name);
00443 av_freep(&filter->input_pads);
00444 av_freep(&filter->output_pads);
00445 av_freep(&filter->inputs);
00446 av_freep(&filter->outputs);
00447 av_freep(&filter->priv);
00448 av_free(filter);
00449 }
00450
00451 int avfilter_init_filter(AVFilterContext *filter, const char *args, void *opaque)
00452 {
00453 int ret=0;
00454
00455 if(filter->filter->init)
00456 ret = filter->filter->init(filter, args, opaque);
00457 return ret;
00458 }
00459