00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 
00010 
00011 
00012 
00013 
00014 
00015 
00016 
00017 
00018 
00019 
00020 
00021 
00022 #include "libavutil/common.h"
00023 #include "libavutil/pixdesc.h"
00024 #include "libavutil/rational.h"
00025 #include "libavutil/audioconvert.h"
00026 #include "libavutil/avassert.h"
00027 #include "libavutil/avstring.h"
00028 
00029 #include "avfilter.h"
00030 #include "formats.h"
00031 #include "internal.h"
00032 #include "audio.h"
00033 
00034 char *ff_get_ref_perms_string(char *buf, size_t buf_size, int perms)
00035 {
00036     snprintf(buf, buf_size, "%s%s%s%s%s%s",
00037              perms & AV_PERM_READ      ? "r" : "",
00038              perms & AV_PERM_WRITE     ? "w" : "",
00039              perms & AV_PERM_PRESERVE  ? "p" : "",
00040              perms & AV_PERM_REUSE     ? "u" : "",
00041              perms & AV_PERM_REUSE2    ? "U" : "",
00042              perms & AV_PERM_NEG_LINESIZES ? "n" : "");
00043     return buf;
00044 }
00045 
00046 void ff_tlog_ref(void *ctx, AVFilterBufferRef *ref, int end)
00047 {
00048     av_unused char buf[16];
00049     ff_tlog(ctx,
00050             "ref[%p buf:%p refcount:%d perms:%s data:%p linesize[%d, %d, %d, %d] pts:%"PRId64" pos:%"PRId64,
00051             ref, ref->buf, ref->buf->refcount, ff_get_ref_perms_string(buf, sizeof(buf), ref->perms), ref->data[0],
00052             ref->linesize[0], ref->linesize[1], ref->linesize[2], ref->linesize[3],
00053             ref->pts, ref->pos);
00054 
00055     if (ref->video) {
00056         ff_tlog(ctx, " a:%d/%d s:%dx%d i:%c iskey:%d type:%c",
00057                 ref->video->sample_aspect_ratio.num, ref->video->sample_aspect_ratio.den,
00058                 ref->video->w, ref->video->h,
00059                 !ref->video->interlaced     ? 'P' :         
00060                 ref->video->top_field_first ? 'T' : 'B',    
00061                 ref->video->key_frame,
00062                 av_get_picture_type_char(ref->video->pict_type));
00063     }
00064     if (ref->audio) {
00065         ff_tlog(ctx, " cl:%"PRId64"d n:%d r:%d",
00066                 ref->audio->channel_layout,
00067                 ref->audio->nb_samples,
00068                 ref->audio->sample_rate);
00069     }
00070 
00071     ff_tlog(ctx, "]%s", end ? "\n" : "");
00072 }
00073 
00074 unsigned avfilter_version(void) {
00075     av_assert0(LIBAVFILTER_VERSION_MICRO >= 100);
00076     return LIBAVFILTER_VERSION_INT;
00077 }
00078 
00079 const char *avfilter_configuration(void)
00080 {
00081     return FFMPEG_CONFIGURATION;
00082 }
00083 
00084 const char *avfilter_license(void)
00085 {
00086 #define LICENSE_PREFIX "libavfilter license: "
00087     return LICENSE_PREFIX FFMPEG_LICENSE + sizeof(LICENSE_PREFIX) - 1;
00088 }
00089 
00090 void ff_command_queue_pop(AVFilterContext *filter)
00091 {
00092     AVFilterCommand *c= filter->command_queue;
00093     av_freep(&c->arg);
00094     av_freep(&c->command);
00095     filter->command_queue= c->next;
00096     av_free(c);
00097 }
00098 
00099 void ff_insert_pad(unsigned idx, unsigned *count, size_t padidx_off,
00100                    AVFilterPad **pads, AVFilterLink ***links,
00101                    AVFilterPad *newpad)
00102 {
00103     unsigned i;
00104 
00105     idx = FFMIN(idx, *count);
00106 
00107     *pads  = av_realloc(*pads,  sizeof(AVFilterPad)   * (*count + 1));
00108     *links = av_realloc(*links, sizeof(AVFilterLink*) * (*count + 1));
00109     memmove(*pads +idx+1, *pads +idx, sizeof(AVFilterPad)   * (*count-idx));
00110     memmove(*links+idx+1, *links+idx, sizeof(AVFilterLink*) * (*count-idx));
00111     memcpy(*pads+idx, newpad, sizeof(AVFilterPad));
00112     (*links)[idx] = NULL;
00113 
00114     (*count)++;
00115     for (i = idx+1; i < *count; i++)
00116         if (*links[i])
00117             (*(unsigned *)((uint8_t *) *links[i] + padidx_off))++;
00118 }
00119 
00120 int avfilter_link(AVFilterContext *src, unsigned srcpad,
00121                   AVFilterContext *dst, unsigned dstpad)
00122 {
00123     AVFilterLink *link;
00124 
00125     if (src->nb_outputs <= srcpad || dst->nb_inputs <= dstpad ||
00126         src->outputs[srcpad]      || dst->inputs[dstpad])
00127         return -1;
00128 
00129     if (src->output_pads[srcpad].type != dst->input_pads[dstpad].type) {
00130         av_log(src, AV_LOG_ERROR,
00131                "Media type mismatch between the '%s' filter output pad %d (%s) and the '%s' filter input pad %d (%s)\n",
00132                src->name, srcpad, (char *)av_x_if_null(av_get_media_type_string(src->output_pads[srcpad].type), "?"),
00133                dst->name, dstpad, (char *)av_x_if_null(av_get_media_type_string(dst-> input_pads[dstpad].type), "?"));
00134         return AVERROR(EINVAL);
00135     }
00136 
00137     src->outputs[srcpad] =
00138     dst-> inputs[dstpad] = link = av_mallocz(sizeof(AVFilterLink));
00139 
00140     link->src     = src;
00141     link->dst     = dst;
00142     link->srcpad  = &src->output_pads[srcpad];
00143     link->dstpad  = &dst->input_pads[dstpad];
00144     link->type    = src->output_pads[srcpad].type;
00145     av_assert0(PIX_FMT_NONE == -1 && AV_SAMPLE_FMT_NONE == -1);
00146     link->format  = -1;
00147 
00148     return 0;
00149 }
00150 
00151 void avfilter_link_free(AVFilterLink **link)
00152 {
00153     if (!*link)
00154         return;
00155 
00156     if ((*link)->pool)
00157         ff_free_pool((*link)->pool);
00158 
00159     avfilter_unref_bufferp(&(*link)->partial_buf);
00160 
00161     av_freep(link);
00162 }
00163 
00164 void avfilter_link_set_closed(AVFilterLink *link, int closed)
00165 {
00166     link->closed = closed;
00167 }
00168 
00169 int avfilter_insert_filter(AVFilterLink *link, AVFilterContext *filt,
00170                            unsigned filt_srcpad_idx, unsigned filt_dstpad_idx)
00171 {
00172     int ret;
00173     unsigned dstpad_idx = link->dstpad - link->dst->input_pads;
00174 
00175     av_log(link->dst, AV_LOG_VERBOSE, "auto-inserting filter '%s' "
00176            "between the filter '%s' and the filter '%s'\n",
00177            filt->name, link->src->name, link->dst->name);
00178 
00179     link->dst->inputs[dstpad_idx] = NULL;
00180     if ((ret = avfilter_link(filt, filt_dstpad_idx, link->dst, dstpad_idx)) < 0) {
00181         
00182         link->dst->inputs[dstpad_idx] = link;
00183         return ret;
00184     }
00185 
00186     
00187     link->dst = filt;
00188     link->dstpad = &filt->input_pads[filt_srcpad_idx];
00189     filt->inputs[filt_srcpad_idx] = link;
00190 
00191     
00192 
00193     if (link->out_formats)
00194         ff_formats_changeref(&link->out_formats,
00195                                    &filt->outputs[filt_dstpad_idx]->out_formats);
00196 
00197     if (link->out_samplerates)
00198         ff_formats_changeref(&link->out_samplerates,
00199                                    &filt->outputs[filt_dstpad_idx]->out_samplerates);
00200     if (link->out_channel_layouts)
00201         ff_channel_layouts_changeref(&link->out_channel_layouts,
00202                                      &filt->outputs[filt_dstpad_idx]->out_channel_layouts);
00203 
00204     return 0;
00205 }
00206 
00207 int avfilter_config_links(AVFilterContext *filter)
00208 {
00209     int (*config_link)(AVFilterLink *);
00210     unsigned i;
00211     int ret;
00212 
00213     for (i = 0; i < filter->nb_inputs; i ++) {
00214         AVFilterLink *link = filter->inputs[i];
00215         AVFilterLink *inlink = link->src->nb_inputs ?
00216             link->src->inputs[0] : NULL;
00217 
00218         if (!link) continue;
00219 
00220         link->current_pts = AV_NOPTS_VALUE;
00221 
00222         switch (link->init_state) {
00223         case AVLINK_INIT:
00224             continue;
00225         case AVLINK_STARTINIT:
00226             av_log(filter, AV_LOG_INFO, "circular filter chain detected\n");
00227             return 0;
00228         case AVLINK_UNINIT:
00229             link->init_state = AVLINK_STARTINIT;
00230 
00231             if ((ret = avfilter_config_links(link->src)) < 0)
00232                 return ret;
00233 
00234             if (!(config_link = link->srcpad->config_props)) {
00235                 if (link->src->nb_inputs != 1) {
00236                     av_log(link->src, AV_LOG_ERROR, "Source filters and filters "
00237                                                     "with more than one input "
00238                                                     "must set config_props() "
00239                                                     "callbacks on all outputs\n");
00240                     return AVERROR(EINVAL);
00241                 }
00242             } else if ((ret = config_link(link)) < 0) {
00243                 av_log(link->src, AV_LOG_ERROR,
00244                        "Failed to configure output pad on %s\n",
00245                        link->src->name);
00246                 return ret;
00247             }
00248 
00249             switch (link->type) {
00250             case AVMEDIA_TYPE_VIDEO:
00251                 if (!link->time_base.num && !link->time_base.den)
00252                     link->time_base = inlink ? inlink->time_base : AV_TIME_BASE_Q;
00253 
00254                 if (!link->sample_aspect_ratio.num && !link->sample_aspect_ratio.den)
00255                     link->sample_aspect_ratio = inlink ?
00256                         inlink->sample_aspect_ratio : (AVRational){1,1};
00257 
00258                 if (inlink && !link->frame_rate.num && !link->frame_rate.den)
00259                     link->frame_rate = inlink->frame_rate;
00260 
00261                 if (inlink) {
00262                     if (!link->w)
00263                         link->w = inlink->w;
00264                     if (!link->h)
00265                         link->h = inlink->h;
00266                 } else if (!link->w || !link->h) {
00267                     av_log(link->src, AV_LOG_ERROR,
00268                            "Video source filters must set their output link's "
00269                            "width and height\n");
00270                     return AVERROR(EINVAL);
00271                 }
00272                 break;
00273 
00274             case AVMEDIA_TYPE_AUDIO:
00275                 if (inlink) {
00276                     if (!link->sample_rate)
00277                         link->sample_rate = inlink->sample_rate;
00278                     if (!link->time_base.num && !link->time_base.den)
00279                         link->time_base = inlink->time_base;
00280                     if (!link->channel_layout)
00281                         link->channel_layout = inlink->channel_layout;
00282                 } else if (!link->sample_rate) {
00283                     av_log(link->src, AV_LOG_ERROR,
00284                            "Audio source filters must set their output link's "
00285                            "sample_rate\n");
00286                     return AVERROR(EINVAL);
00287                 }
00288 
00289                 if (!link->time_base.num && !link->time_base.den)
00290                     link->time_base = (AVRational) {1, link->sample_rate};
00291             }
00292 
00293             if ((config_link = link->dstpad->config_props))
00294                 if ((ret = config_link(link)) < 0) {
00295                     av_log(link->src, AV_LOG_ERROR,
00296                            "Failed to configure input pad on %s\n",
00297                            link->dst->name);
00298                     return ret;
00299                 }
00300 
00301             link->init_state = AVLINK_INIT;
00302         }
00303     }
00304 
00305     return 0;
00306 }
00307 
00308 void ff_tlog_link(void *ctx, AVFilterLink *link, int end)
00309 {
00310     if (link->type == AVMEDIA_TYPE_VIDEO) {
00311         ff_tlog(ctx,
00312                 "link[%p s:%dx%d fmt:%s %s->%s]%s",
00313                 link, link->w, link->h,
00314                 av_pix_fmt_descriptors[link->format].name,
00315                 link->src ? link->src->filter->name : "",
00316                 link->dst ? link->dst->filter->name : "",
00317                 end ? "\n" : "");
00318     } else {
00319         char buf[128];
00320         av_get_channel_layout_string(buf, sizeof(buf), -1, link->channel_layout);
00321 
00322         ff_tlog(ctx,
00323                 "link[%p r:%d cl:%s fmt:%s %s->%s]%s",
00324                 link, (int)link->sample_rate, buf,
00325                 av_get_sample_fmt_name(link->format),
00326                 link->src ? link->src->filter->name : "",
00327                 link->dst ? link->dst->filter->name : "",
00328                 end ? "\n" : "");
00329     }
00330 }
00331 
00332 int ff_request_frame(AVFilterLink *link)
00333 {
00334     int ret = -1;
00335     FF_TPRINTF_START(NULL, request_frame); ff_tlog_link(NULL, link, 1);
00336 
00337     if (link->closed)
00338         return AVERROR_EOF;
00339     if (link->srcpad->request_frame)
00340         ret = link->srcpad->request_frame(link);
00341     else if (link->src->inputs[0])
00342         ret = ff_request_frame(link->src->inputs[0]);
00343     if (ret == AVERROR_EOF && link->partial_buf) {
00344         AVFilterBufferRef *pbuf = link->partial_buf;
00345         link->partial_buf = NULL;
00346         ff_filter_samples_framed(link, pbuf);
00347         return 0;
00348     }
00349     if (ret == AVERROR_EOF)
00350         link->closed = 1;
00351     return ret;
00352 }
00353 
00354 int ff_poll_frame(AVFilterLink *link)
00355 {
00356     int i, min = INT_MAX;
00357 
00358     if (link->srcpad->poll_frame)
00359         return link->srcpad->poll_frame(link);
00360 
00361     for (i = 0; i < link->src->nb_inputs; i++) {
00362         int val;
00363         if (!link->src->inputs[i])
00364             return -1;
00365         val = ff_poll_frame(link->src->inputs[i]);
00366         min = FFMIN(min, val);
00367     }
00368 
00369     return min;
00370 }
00371 
00372 void ff_update_link_current_pts(AVFilterLink *link, int64_t pts)
00373 {
00374     if (pts == AV_NOPTS_VALUE)
00375         return;
00376     link->current_pts = av_rescale_q(pts, link->time_base, AV_TIME_BASE_Q);
00377     
00378     if (link->graph && link->age_index >= 0)
00379         ff_avfilter_graph_update_heap(link->graph, link);
00380 }
00381 
00382 int avfilter_process_command(AVFilterContext *filter, const char *cmd, const char *arg, char *res, int res_len, int flags)
00383 {
00384     if(!strcmp(cmd, "ping")){
00385         av_strlcatf(res, res_len, "pong from:%s %s\n", filter->filter->name, filter->name);
00386         return 0;
00387     }else if(filter->filter->process_command) {
00388         return filter->filter->process_command(filter, cmd, arg, res, res_len, flags);
00389     }
00390     return AVERROR(ENOSYS);
00391 }
00392 
00393 #define MAX_REGISTERED_AVFILTERS_NB 128
00394 
00395 static AVFilter *registered_avfilters[MAX_REGISTERED_AVFILTERS_NB + 1];
00396 
00397 static int next_registered_avfilter_idx = 0;
00398 
00399 AVFilter *avfilter_get_by_name(const char *name)
00400 {
00401     int i;
00402 
00403     for (i = 0; registered_avfilters[i]; i++)
00404         if (!strcmp(registered_avfilters[i]->name, name))
00405             return registered_avfilters[i];
00406 
00407     return NULL;
00408 }
00409 
00410 int avfilter_register(AVFilter *filter)
00411 {
00412     if (next_registered_avfilter_idx == MAX_REGISTERED_AVFILTERS_NB) {
00413         av_log(NULL, AV_LOG_ERROR,
00414                "Maximum number of registered filters %d reached, "
00415                "impossible to register filter with name '%s'\n",
00416                MAX_REGISTERED_AVFILTERS_NB, filter->name);
00417         return AVERROR(ENOMEM);
00418     }
00419 
00420     registered_avfilters[next_registered_avfilter_idx++] = filter;
00421     return 0;
00422 }
00423 
00424 AVFilter **av_filter_next(AVFilter **filter)
00425 {
00426     return filter ? ++filter : ®istered_avfilters[0];
00427 }
00428 
00429 void avfilter_uninit(void)
00430 {
00431     memset(registered_avfilters, 0, sizeof(registered_avfilters));
00432     next_registered_avfilter_idx = 0;
00433 }
00434 
00435 static int pad_count(const AVFilterPad *pads)
00436 {
00437     int count;
00438 
00439     if (!pads)
00440         return 0;
00441 
00442     for(count = 0; pads->name; count ++) pads ++;
00443     return count;
00444 }
00445 
00446 static const char *default_filter_name(void *filter_ctx)
00447 {
00448     AVFilterContext *ctx = filter_ctx;
00449     return ctx->name ? ctx->name : ctx->filter->name;
00450 }
00451 
00452 static void *filter_child_next(void *obj, void *prev)
00453 {
00454     AVFilterContext *ctx = obj;
00455     if (!prev && ctx->filter && ctx->filter->priv_class)
00456         return ctx->priv;
00457     return NULL;
00458 }
00459 
00460 static const AVClass *filter_child_class_next(const AVClass *prev)
00461 {
00462     AVFilter **filter_ptr = NULL;
00463 
00464     
00465     while (prev && *(filter_ptr = av_filter_next(filter_ptr)))
00466         if ((*filter_ptr)->priv_class == prev)
00467             break;
00468 
00469     
00470     if (prev && !(*filter_ptr))
00471         return NULL;
00472 
00473     
00474     while (*(filter_ptr = av_filter_next(filter_ptr)))
00475         if ((*filter_ptr)->priv_class)
00476             return (*filter_ptr)->priv_class;
00477     return NULL;
00478 }
00479 
00480 static const AVClass avfilter_class = {
00481     .class_name = "AVFilter",
00482     .item_name  = default_filter_name,
00483     .version    = LIBAVUTIL_VERSION_INT,
00484     .category   = AV_CLASS_CATEGORY_FILTER,
00485     .child_next = filter_child_next,
00486     .child_class_next = filter_child_class_next,
00487 };
00488 
00489 const AVClass *avfilter_get_class(void)
00490 {
00491     return &avfilter_class;
00492 }
00493 
00494 int avfilter_open(AVFilterContext **filter_ctx, AVFilter *filter, const char *inst_name)
00495 {
00496     AVFilterContext *ret;
00497     *filter_ctx = NULL;
00498 
00499     if (!filter)
00500         return AVERROR(EINVAL);
00501 
00502     ret = av_mallocz(sizeof(AVFilterContext));
00503     if (!ret)
00504         return AVERROR(ENOMEM);
00505 
00506     ret->av_class = &avfilter_class;
00507     ret->filter   = filter;
00508     ret->name     = inst_name ? av_strdup(inst_name) : NULL;
00509     if (filter->priv_size) {
00510         ret->priv     = av_mallocz(filter->priv_size);
00511         if (!ret->priv)
00512             goto err;
00513     }
00514 
00515     ret->nb_inputs = pad_count(filter->inputs);
00516     if (ret->nb_inputs ) {
00517         ret->input_pads   = av_malloc(sizeof(AVFilterPad) * ret->nb_inputs);
00518         if (!ret->input_pads)
00519             goto err;
00520         memcpy(ret->input_pads, filter->inputs, sizeof(AVFilterPad) * ret->nb_inputs);
00521         ret->inputs       = av_mallocz(sizeof(AVFilterLink*) * ret->nb_inputs);
00522         if (!ret->inputs)
00523             goto err;
00524     }
00525 
00526     ret->nb_outputs = pad_count(filter->outputs);
00527     if (ret->nb_outputs) {
00528         ret->output_pads  = av_malloc(sizeof(AVFilterPad) * ret->nb_outputs);
00529         if (!ret->output_pads)
00530             goto err;
00531         memcpy(ret->output_pads, filter->outputs, sizeof(AVFilterPad) * ret->nb_outputs);
00532         ret->outputs      = av_mallocz(sizeof(AVFilterLink*) * ret->nb_outputs);
00533         if (!ret->outputs)
00534             goto err;
00535     }
00536 #if FF_API_FOO_COUNT
00537     ret->output_count = ret->nb_outputs;
00538     ret->input_count  = ret->nb_inputs;
00539 #endif
00540 
00541     *filter_ctx = ret;
00542     return 0;
00543 
00544 err:
00545     av_freep(&ret->inputs);
00546     av_freep(&ret->input_pads);
00547     ret->nb_inputs = 0;
00548     av_freep(&ret->outputs);
00549     av_freep(&ret->output_pads);
00550     ret->nb_outputs = 0;
00551     av_freep(&ret->priv);
00552     av_free(ret);
00553     return AVERROR(ENOMEM);
00554 }
00555 
00556 void avfilter_free(AVFilterContext *filter)
00557 {
00558     int i;
00559     AVFilterLink *link;
00560 
00561     if (!filter)
00562         return;
00563 
00564     if (filter->filter->uninit)
00565         filter->filter->uninit(filter);
00566 
00567     for (i = 0; i < filter->nb_inputs; i++) {
00568         if ((link = filter->inputs[i])) {
00569             if (link->src)
00570                 link->src->outputs[link->srcpad - link->src->output_pads] = NULL;
00571             ff_formats_unref(&link->in_formats);
00572             ff_formats_unref(&link->out_formats);
00573             ff_formats_unref(&link->in_samplerates);
00574             ff_formats_unref(&link->out_samplerates);
00575             ff_channel_layouts_unref(&link->in_channel_layouts);
00576             ff_channel_layouts_unref(&link->out_channel_layouts);
00577         }
00578         avfilter_link_free(&link);
00579     }
00580     for (i = 0; i < filter->nb_outputs; i++) {
00581         if ((link = filter->outputs[i])) {
00582             if (link->dst)
00583                 link->dst->inputs[link->dstpad - link->dst->input_pads] = NULL;
00584             ff_formats_unref(&link->in_formats);
00585             ff_formats_unref(&link->out_formats);
00586             ff_formats_unref(&link->in_samplerates);
00587             ff_formats_unref(&link->out_samplerates);
00588             ff_channel_layouts_unref(&link->in_channel_layouts);
00589             ff_channel_layouts_unref(&link->out_channel_layouts);
00590         }
00591         avfilter_link_free(&link);
00592     }
00593 
00594     av_freep(&filter->name);
00595     av_freep(&filter->input_pads);
00596     av_freep(&filter->output_pads);
00597     av_freep(&filter->inputs);
00598     av_freep(&filter->outputs);
00599     av_freep(&filter->priv);
00600     while(filter->command_queue){
00601         ff_command_queue_pop(filter);
00602     }
00603     av_free(filter);
00604 }
00605 
00606 int avfilter_init_filter(AVFilterContext *filter, const char *args, void *opaque)
00607 {
00608     int ret=0;
00609 
00610     if (filter->filter->init_opaque)
00611         ret = filter->filter->init_opaque(filter, args, opaque);
00612     else if (filter->filter->init)
00613         ret = filter->filter->init(filter, args);
00614     return ret;
00615 }
00616 
00617 const char *avfilter_pad_get_name(AVFilterPad *pads, int pad_idx)
00618 {
00619     return pads[pad_idx].name;
00620 }
00621 
00622 enum AVMediaType avfilter_pad_get_type(AVFilterPad *pads, int pad_idx)
00623 {
00624     return pads[pad_idx].type;
00625 }