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 "libavutil/pixdesc.h"
00025 #include "libavutil/rational.h"
00026 #include "libavutil/audioconvert.h"
00027 #include "libavutil/imgutils.h"
00028 #include "libavutil/avassert.h"
00029 #include "libavutil/avstring.h"
00030 #include "avfilter.h"
00031 #include "internal.h"
00032
00033 unsigned avfilter_version(void) {
00034 av_assert0(LIBAVFILTER_VERSION_MICRO >= 100);
00035 return LIBAVFILTER_VERSION_INT;
00036 }
00037
00038 const char *avfilter_configuration(void)
00039 {
00040 return FFMPEG_CONFIGURATION;
00041 }
00042
00043 const char *avfilter_license(void)
00044 {
00045 #define LICENSE_PREFIX "libavfilter license: "
00046 return LICENSE_PREFIX FFMPEG_LICENSE + sizeof(LICENSE_PREFIX) - 1;
00047 }
00048
00049 static void command_queue_pop(AVFilterContext *filter)
00050 {
00051 AVFilterCommand *c= filter->command_queue;
00052 av_freep(&c->arg);
00053 av_freep(&c->command);
00054 filter->command_queue= c->next;
00055 av_free(c);
00056 }
00057
00058 AVFilterBufferRef *avfilter_ref_buffer(AVFilterBufferRef *ref, int pmask)
00059 {
00060 AVFilterBufferRef *ret = av_malloc(sizeof(AVFilterBufferRef));
00061 if (!ret)
00062 return NULL;
00063 *ret = *ref;
00064 if (ref->type == AVMEDIA_TYPE_VIDEO) {
00065 ret->video = av_malloc(sizeof(AVFilterBufferRefVideoProps));
00066 if (!ret->video) {
00067 av_free(ret);
00068 return NULL;
00069 }
00070 *ret->video = *ref->video;
00071 } else if (ref->type == AVMEDIA_TYPE_AUDIO) {
00072 ret->audio = av_malloc(sizeof(AVFilterBufferRefAudioProps));
00073 if (!ret->audio) {
00074 av_free(ret);
00075 return NULL;
00076 }
00077 *ret->audio = *ref->audio;
00078 }
00079 ret->perms &= pmask;
00080 ret->buf->refcount ++;
00081 return ret;
00082 }
00083
00084 static void free_pool(AVFilterPool *pool)
00085 {
00086 int i;
00087
00088 av_assert0(pool->refcount > 0);
00089
00090 for (i = 0; i < POOL_SIZE; i++) {
00091 if (pool->pic[i]) {
00092 AVFilterBufferRef *picref = pool->pic[i];
00093
00094
00095 av_assert0(!picref->buf->refcount);
00096 av_freep(&picref->buf->data[0]);
00097 av_freep(&picref->buf);
00098
00099 av_freep(&picref->audio);
00100 av_freep(&picref->video);
00101 av_freep(&pool->pic[i]);
00102 pool->count--;
00103 }
00104 }
00105 pool->draining = 1;
00106
00107 if (!--pool->refcount) {
00108 av_assert0(!pool->count);
00109 av_free(pool);
00110 }
00111 }
00112
00113 static void store_in_pool(AVFilterBufferRef *ref)
00114 {
00115 int i;
00116 AVFilterPool *pool= ref->buf->priv;
00117
00118 av_assert0(ref->buf->data[0]);
00119 av_assert0(pool->refcount>0);
00120
00121 if (pool->count == POOL_SIZE) {
00122 AVFilterBufferRef *ref1 = pool->pic[0];
00123 av_freep(&ref1->video);
00124 av_freep(&ref1->audio);
00125 av_freep(&ref1->buf->data[0]);
00126 av_freep(&ref1->buf);
00127 av_free(ref1);
00128 memmove(&pool->pic[0], &pool->pic[1], sizeof(void*)*(POOL_SIZE-1));
00129 pool->count--;
00130 pool->pic[POOL_SIZE-1] = NULL;
00131 }
00132
00133 for (i = 0; i < POOL_SIZE; i++) {
00134 if (!pool->pic[i]) {
00135 pool->pic[i] = ref;
00136 pool->count++;
00137 break;
00138 }
00139 }
00140 if (pool->draining) {
00141 free_pool(pool);
00142 } else
00143 --pool->refcount;
00144 }
00145
00146 void avfilter_unref_buffer(AVFilterBufferRef *ref)
00147 {
00148 if (!ref)
00149 return;
00150 av_assert0(ref->buf->refcount > 0);
00151 if (!(--ref->buf->refcount)) {
00152 if (!ref->buf->free) {
00153 store_in_pool(ref);
00154 return;
00155 }
00156 ref->buf->free(ref->buf);
00157 }
00158 av_freep(&ref->video);
00159 av_freep(&ref->audio);
00160 av_free(ref);
00161 }
00162
00163 void avfilter_insert_pad(unsigned idx, unsigned *count, size_t padidx_off,
00164 AVFilterPad **pads, AVFilterLink ***links,
00165 AVFilterPad *newpad)
00166 {
00167 unsigned i;
00168
00169 idx = FFMIN(idx, *count);
00170
00171 *pads = av_realloc(*pads, sizeof(AVFilterPad) * (*count + 1));
00172 *links = av_realloc(*links, sizeof(AVFilterLink*) * (*count + 1));
00173 memmove(*pads +idx+1, *pads +idx, sizeof(AVFilterPad) * (*count-idx));
00174 memmove(*links+idx+1, *links+idx, sizeof(AVFilterLink*) * (*count-idx));
00175 memcpy(*pads+idx, newpad, sizeof(AVFilterPad));
00176 (*links)[idx] = NULL;
00177
00178 (*count)++;
00179 for (i = idx+1; i < *count; i++)
00180 if (*links[i])
00181 (*(unsigned *)((uint8_t *) *links[i] + padidx_off))++;
00182 }
00183
00184 int avfilter_link(AVFilterContext *src, unsigned srcpad,
00185 AVFilterContext *dst, unsigned dstpad)
00186 {
00187 AVFilterLink *link;
00188
00189 if (src->output_count <= srcpad || dst->input_count <= dstpad ||
00190 src->outputs[srcpad] || dst->inputs[dstpad])
00191 return -1;
00192
00193 if (src->output_pads[srcpad].type != dst->input_pads[dstpad].type) {
00194 av_log(src, AV_LOG_ERROR,
00195 "Media type mismatch between the '%s' filter output pad %d and the '%s' filter input pad %d\n",
00196 src->name, srcpad, dst->name, dstpad);
00197 return AVERROR(EINVAL);
00198 }
00199
00200 src->outputs[srcpad] =
00201 dst-> inputs[dstpad] = link = av_mallocz(sizeof(AVFilterLink));
00202
00203 link->src = src;
00204 link->dst = dst;
00205 link->srcpad = &src->output_pads[srcpad];
00206 link->dstpad = &dst->input_pads[dstpad];
00207 link->type = src->output_pads[srcpad].type;
00208 assert(PIX_FMT_NONE == -1 && AV_SAMPLE_FMT_NONE == -1);
00209 link->format = -1;
00210
00211 return 0;
00212 }
00213
00214 void avfilter_link_free(AVFilterLink **link)
00215 {
00216 if (!*link)
00217 return;
00218
00219 if ((*link)->pool)
00220 free_pool((*link)->pool);
00221
00222 av_freep(link);
00223 }
00224
00225 int avfilter_insert_filter(AVFilterLink *link, AVFilterContext *filt,
00226 unsigned filt_srcpad_idx, unsigned filt_dstpad_idx)
00227 {
00228 int ret;
00229 unsigned dstpad_idx = link->dstpad - link->dst->input_pads;
00230
00231 av_log(link->dst, AV_LOG_INFO, "auto-inserting filter '%s' "
00232 "between the filter '%s' and the filter '%s'\n",
00233 filt->name, link->src->name, link->dst->name);
00234
00235 link->dst->inputs[dstpad_idx] = NULL;
00236 if ((ret = avfilter_link(filt, filt_dstpad_idx, link->dst, dstpad_idx)) < 0) {
00237
00238 link->dst->inputs[dstpad_idx] = link;
00239 return ret;
00240 }
00241
00242
00243 link->dst = filt;
00244 link->dstpad = &filt->input_pads[filt_srcpad_idx];
00245 filt->inputs[filt_srcpad_idx] = link;
00246
00247
00248
00249 if (link->out_formats)
00250 avfilter_formats_changeref(&link->out_formats,
00251 &filt->outputs[filt_dstpad_idx]->out_formats);
00252 if (link->out_chlayouts)
00253 avfilter_formats_changeref(&link->out_chlayouts,
00254 &filt->outputs[filt_dstpad_idx]->out_chlayouts);
00255 if (link->out_packing)
00256 avfilter_formats_changeref(&link->out_packing,
00257 &filt->outputs[filt_dstpad_idx]->out_packing);
00258
00259 return 0;
00260 }
00261
00262 int avfilter_config_links(AVFilterContext *filter)
00263 {
00264 int (*config_link)(AVFilterLink *);
00265 unsigned i;
00266 int ret;
00267
00268 for (i = 0; i < filter->input_count; i ++) {
00269 AVFilterLink *link = filter->inputs[i];
00270 AVFilterLink *inlink = link->src->input_count ?
00271 link->src->inputs[0] : NULL;
00272
00273 if (!link) continue;
00274
00275 switch (link->init_state) {
00276 case AVLINK_INIT:
00277 continue;
00278 case AVLINK_STARTINIT:
00279 av_log(filter, AV_LOG_INFO, "circular filter chain detected\n");
00280 return 0;
00281 case AVLINK_UNINIT:
00282 link->init_state = AVLINK_STARTINIT;
00283
00284 if ((ret = avfilter_config_links(link->src)) < 0)
00285 return ret;
00286
00287 if (!(config_link = link->srcpad->config_props)) {
00288 if (link->src->input_count != 1) {
00289 av_log(link->src, AV_LOG_ERROR, "Source filters and filters "
00290 "with more than one input "
00291 "must set config_props() "
00292 "callbacks on all outputs\n");
00293 return AVERROR(EINVAL);
00294 }
00295 } else if ((ret = config_link(link)) < 0)
00296 return ret;
00297
00298 switch (link->type) {
00299 case AVMEDIA_TYPE_VIDEO:
00300 if (!link->time_base.num && !link->time_base.den)
00301 link->time_base = inlink ? inlink->time_base : AV_TIME_BASE_Q;
00302
00303 if (!link->sample_aspect_ratio.num && !link->sample_aspect_ratio.den)
00304 link->sample_aspect_ratio = inlink ?
00305 inlink->sample_aspect_ratio : (AVRational){1,1};
00306
00307 if (inlink) {
00308 if (!link->w)
00309 link->w = inlink->w;
00310 if (!link->h)
00311 link->h = inlink->h;
00312 } else if (!link->w || !link->h) {
00313 av_log(link->src, AV_LOG_ERROR,
00314 "Video source filters must set their output link's "
00315 "width and height\n");
00316 return AVERROR(EINVAL);
00317 }
00318 break;
00319
00320 case AVMEDIA_TYPE_AUDIO:
00321 if (inlink) {
00322 if (!link->sample_rate)
00323 link->sample_rate = inlink->sample_rate;
00324 if (!link->time_base.num && !link->time_base.den)
00325 link->time_base = inlink->time_base;
00326 } else if (!link->sample_rate) {
00327 av_log(link->src, AV_LOG_ERROR,
00328 "Audio source filters must set their output link's "
00329 "sample_rate\n");
00330 return AVERROR(EINVAL);
00331 }
00332
00333 if (!link->time_base.num && !link->time_base.den)
00334 link->time_base = (AVRational) {1, link->sample_rate};
00335 }
00336
00337 if ((config_link = link->dstpad->config_props))
00338 if ((ret = config_link(link)) < 0)
00339 return ret;
00340
00341 link->init_state = AVLINK_INIT;
00342 }
00343 }
00344
00345 return 0;
00346 }
00347
00348 static char *ff_get_ref_perms_string(char *buf, size_t buf_size, int perms)
00349 {
00350 snprintf(buf, buf_size, "%s%s%s%s%s%s",
00351 perms & AV_PERM_READ ? "r" : "",
00352 perms & AV_PERM_WRITE ? "w" : "",
00353 perms & AV_PERM_PRESERVE ? "p" : "",
00354 perms & AV_PERM_REUSE ? "u" : "",
00355 perms & AV_PERM_REUSE2 ? "U" : "",
00356 perms & AV_PERM_NEG_LINESIZES ? "n" : "");
00357 return buf;
00358 }
00359
00360 static void ff_dlog_ref(void *ctx, AVFilterBufferRef *ref, int end)
00361 {
00362 av_unused char buf[16];
00363 av_dlog(ctx,
00364 "ref[%p buf:%p refcount:%d perms:%s data:%p linesize[%d, %d, %d, %d] pts:%"PRId64" pos:%"PRId64,
00365 ref, ref->buf, ref->buf->refcount, ff_get_ref_perms_string(buf, sizeof(buf), ref->perms), ref->data[0],
00366 ref->linesize[0], ref->linesize[1], ref->linesize[2], ref->linesize[3],
00367 ref->pts, ref->pos);
00368
00369 if (ref->video) {
00370 av_dlog(ctx, " a:%d/%d s:%dx%d i:%c iskey:%d type:%c",
00371 ref->video->sample_aspect_ratio.num, ref->video->sample_aspect_ratio.den,
00372 ref->video->w, ref->video->h,
00373 !ref->video->interlaced ? 'P' :
00374 ref->video->top_field_first ? 'T' : 'B',
00375 ref->video->key_frame,
00376 av_get_picture_type_char(ref->video->pict_type));
00377 }
00378 if (ref->audio) {
00379 av_dlog(ctx, " cl:%"PRId64"d n:%d r:%d p:%d",
00380 ref->audio->channel_layout,
00381 ref->audio->nb_samples,
00382 ref->audio->sample_rate,
00383 ref->audio->planar);
00384 }
00385
00386 av_dlog(ctx, "]%s", end ? "\n" : "");
00387 }
00388
00389 static void ff_dlog_link(void *ctx, AVFilterLink *link, int end)
00390 {
00391 if (link->type == AVMEDIA_TYPE_VIDEO) {
00392 av_dlog(ctx,
00393 "link[%p s:%dx%d fmt:%s %s->%s]%s",
00394 link, link->w, link->h,
00395 av_pix_fmt_descriptors[link->format].name,
00396 link->src ? link->src->filter->name : "",
00397 link->dst ? link->dst->filter->name : "",
00398 end ? "\n" : "");
00399 } else {
00400 char buf[128];
00401 av_get_channel_layout_string(buf, sizeof(buf), -1, link->channel_layout);
00402
00403 av_dlog(ctx,
00404 "link[%p r:%d cl:%s fmt:%s %s->%s]%s",
00405 link, (int)link->sample_rate, buf,
00406 av_get_sample_fmt_name(link->format),
00407 link->src ? link->src->filter->name : "",
00408 link->dst ? link->dst->filter->name : "",
00409 end ? "\n" : "");
00410 }
00411 }
00412
00413 #define FF_DPRINTF_START(ctx, func) av_dlog(NULL, "%-16s: ", #func)
00414
00415 AVFilterBufferRef *avfilter_get_video_buffer(AVFilterLink *link, int perms, int w, int h)
00416 {
00417 AVFilterBufferRef *ret = NULL;
00418
00419 av_unused char buf[16];
00420 FF_DPRINTF_START(NULL, get_video_buffer); ff_dlog_link(NULL, link, 0);
00421 av_dlog(NULL, " perms:%s w:%d h:%d\n", ff_get_ref_perms_string(buf, sizeof(buf), perms), w, h);
00422
00423 if (link->dstpad->get_video_buffer)
00424 ret = link->dstpad->get_video_buffer(link, perms, w, h);
00425
00426 if (!ret)
00427 ret = avfilter_default_get_video_buffer(link, perms, w, h);
00428
00429 if (ret)
00430 ret->type = AVMEDIA_TYPE_VIDEO;
00431
00432 FF_DPRINTF_START(NULL, get_video_buffer); ff_dlog_link(NULL, link, 0); av_dlog(NULL, " returning "); ff_dlog_ref(NULL, ret, 1);
00433
00434 return ret;
00435 }
00436
00437 AVFilterBufferRef *
00438 avfilter_get_video_buffer_ref_from_arrays(uint8_t * const data[4], const int linesize[4], int perms,
00439 int w, int h, enum PixelFormat format)
00440 {
00441 AVFilterBuffer *pic = av_mallocz(sizeof(AVFilterBuffer));
00442 AVFilterBufferRef *picref = av_mallocz(sizeof(AVFilterBufferRef));
00443
00444 if (!pic || !picref)
00445 goto fail;
00446
00447 picref->buf = pic;
00448 picref->buf->free = ff_avfilter_default_free_buffer;
00449 if (!(picref->video = av_mallocz(sizeof(AVFilterBufferRefVideoProps))))
00450 goto fail;
00451
00452 pic->w = picref->video->w = w;
00453 pic->h = picref->video->h = h;
00454
00455
00456 picref->perms = perms | AV_PERM_READ;
00457
00458 pic->refcount = 1;
00459 picref->type = AVMEDIA_TYPE_VIDEO;
00460 pic->format = picref->format = format;
00461
00462 memcpy(pic->data, data, 4*sizeof(data[0]));
00463 memcpy(pic->linesize, linesize, 4*sizeof(linesize[0]));
00464 memcpy(picref->data, pic->data, sizeof(picref->data));
00465 memcpy(picref->linesize, pic->linesize, sizeof(picref->linesize));
00466
00467 return picref;
00468
00469 fail:
00470 if (picref && picref->video)
00471 av_free(picref->video);
00472 av_free(picref);
00473 av_free(pic);
00474 return NULL;
00475 }
00476
00477 AVFilterBufferRef *avfilter_get_audio_buffer(AVFilterLink *link,
00478 int perms, int nb_samples)
00479 {
00480 AVFilterBufferRef *ret = NULL;
00481
00482 if (link->dstpad->get_audio_buffer)
00483 ret = link->dstpad->get_audio_buffer(link, perms, nb_samples);
00484
00485 if (!ret)
00486 ret = avfilter_default_get_audio_buffer(link, perms, nb_samples);
00487
00488 if (ret)
00489 ret->type = AVMEDIA_TYPE_AUDIO;
00490
00491 return ret;
00492 }
00493
00494 AVFilterBufferRef *
00495 avfilter_get_audio_buffer_ref_from_arrays(uint8_t *data[8], int linesize[8], int perms,
00496 int nb_samples, enum AVSampleFormat sample_fmt,
00497 uint64_t channel_layout, int planar)
00498 {
00499 AVFilterBuffer *samples = av_mallocz(sizeof(AVFilterBuffer));
00500 AVFilterBufferRef *samplesref = av_mallocz(sizeof(AVFilterBufferRef));
00501
00502 if (!samples || !samplesref)
00503 goto fail;
00504
00505 samplesref->buf = samples;
00506 samplesref->buf->free = ff_avfilter_default_free_buffer;
00507 if (!(samplesref->audio = av_mallocz(sizeof(AVFilterBufferRefAudioProps))))
00508 goto fail;
00509
00510 samplesref->audio->nb_samples = nb_samples;
00511 samplesref->audio->channel_layout = channel_layout;
00512 samplesref->audio->planar = planar;
00513
00514
00515 samplesref->perms = perms | AV_PERM_READ;
00516
00517 samples->refcount = 1;
00518 samplesref->type = AVMEDIA_TYPE_AUDIO;
00519 samplesref->format = sample_fmt;
00520
00521 memcpy(samples->data, data, sizeof(samples->data));
00522 memcpy(samples->linesize, linesize, sizeof(samples->linesize));
00523 memcpy(samplesref->data, data, sizeof(samplesref->data));
00524 memcpy(samplesref->linesize, linesize, sizeof(samplesref->linesize));
00525
00526 return samplesref;
00527
00528 fail:
00529 if (samplesref && samplesref->audio)
00530 av_freep(&samplesref->audio);
00531 av_freep(&samplesref);
00532 av_freep(&samples);
00533 return NULL;
00534 }
00535
00536 int avfilter_request_frame(AVFilterLink *link)
00537 {
00538 FF_DPRINTF_START(NULL, request_frame); ff_dlog_link(NULL, link, 1);
00539
00540 if (link->srcpad->request_frame)
00541 return link->srcpad->request_frame(link);
00542 else if (link->src->inputs[0])
00543 return avfilter_request_frame(link->src->inputs[0]);
00544 else return -1;
00545 }
00546
00547 int avfilter_poll_frame(AVFilterLink *link)
00548 {
00549 int i, min = INT_MAX;
00550
00551 if (link->srcpad->poll_frame)
00552 return link->srcpad->poll_frame(link);
00553
00554 for (i = 0; i < link->src->input_count; i++) {
00555 int val;
00556 if (!link->src->inputs[i])
00557 return -1;
00558 val = avfilter_poll_frame(link->src->inputs[i]);
00559 min = FFMIN(min, val);
00560 }
00561
00562 return min;
00563 }
00564
00565
00566
00567 void avfilter_start_frame(AVFilterLink *link, AVFilterBufferRef *picref)
00568 {
00569 void (*start_frame)(AVFilterLink *, AVFilterBufferRef *);
00570 AVFilterPad *dst = link->dstpad;
00571 int perms = picref->perms;
00572 AVFilterCommand *cmd= link->dst->command_queue;
00573
00574 FF_DPRINTF_START(NULL, start_frame); ff_dlog_link(NULL, link, 0); av_dlog(NULL, " "); ff_dlog_ref(NULL, picref, 1);
00575
00576 if (!(start_frame = dst->start_frame))
00577 start_frame = avfilter_default_start_frame;
00578
00579 if (picref->linesize[0] < 0)
00580 perms |= AV_PERM_NEG_LINESIZES;
00581
00582 if ((dst->min_perms & perms) != dst->min_perms || dst->rej_perms & perms) {
00583 av_log(link->dst, AV_LOG_DEBUG,
00584 "frame copy needed (have perms %x, need %x, reject %x)\n",
00585 picref->perms,
00586 link->dstpad->min_perms, link->dstpad->rej_perms);
00587
00588 link->cur_buf = avfilter_get_video_buffer(link, dst->min_perms, link->w, link->h);
00589 link->src_buf = picref;
00590 avfilter_copy_buffer_ref_props(link->cur_buf, link->src_buf);
00591 }
00592 else
00593 link->cur_buf = picref;
00594
00595 while(cmd && cmd->time <= picref->pts * av_q2d(link->time_base)){
00596 av_log(link->dst, AV_LOG_DEBUG,
00597 "Processing command time:%f command:%s arg:%s\n",
00598 cmd->time, cmd->command, cmd->arg);
00599 avfilter_process_command(link->dst, cmd->command, cmd->arg, 0, 0, cmd->flags);
00600 command_queue_pop(link->dst);
00601 cmd= link->dst->command_queue;
00602 }
00603
00604 start_frame(link, link->cur_buf);
00605 }
00606
00607 void avfilter_end_frame(AVFilterLink *link)
00608 {
00609 void (*end_frame)(AVFilterLink *);
00610
00611 if (!(end_frame = link->dstpad->end_frame))
00612 end_frame = avfilter_default_end_frame;
00613
00614 end_frame(link);
00615
00616
00617
00618 if (link->src_buf) {
00619 avfilter_unref_buffer(link->src_buf);
00620 link->src_buf = NULL;
00621 }
00622 }
00623
00624 void avfilter_draw_slice(AVFilterLink *link, int y, int h, int slice_dir)
00625 {
00626 uint8_t *src[4], *dst[4];
00627 int i, j, vsub;
00628 void (*draw_slice)(AVFilterLink *, int, int, int);
00629
00630 FF_DPRINTF_START(NULL, draw_slice); ff_dlog_link(NULL, link, 0); av_dlog(NULL, " y:%d h:%d dir:%d\n", y, h, slice_dir);
00631
00632
00633 if (link->src_buf) {
00634 vsub = av_pix_fmt_descriptors[link->format].log2_chroma_h;
00635
00636 for (i = 0; i < 4; i++) {
00637 if (link->src_buf->data[i]) {
00638 src[i] = link->src_buf-> data[i] +
00639 (y >> (i==1 || i==2 ? vsub : 0)) * link->src_buf-> linesize[i];
00640 dst[i] = link->cur_buf->data[i] +
00641 (y >> (i==1 || i==2 ? vsub : 0)) * link->cur_buf->linesize[i];
00642 } else
00643 src[i] = dst[i] = NULL;
00644 }
00645
00646 for (i = 0; i < 4; i++) {
00647 int planew =
00648 av_image_get_linesize(link->format, link->cur_buf->video->w, i);
00649
00650 if (!src[i]) continue;
00651
00652 for (j = 0; j < h >> (i==1 || i==2 ? vsub : 0); j++) {
00653 memcpy(dst[i], src[i], planew);
00654 src[i] += link->src_buf->linesize[i];
00655 dst[i] += link->cur_buf->linesize[i];
00656 }
00657 }
00658 }
00659
00660 if (!(draw_slice = link->dstpad->draw_slice))
00661 draw_slice = avfilter_default_draw_slice;
00662 draw_slice(link, y, h, slice_dir);
00663 }
00664
00665 int avfilter_process_command(AVFilterContext *filter, const char *cmd, const char *arg, char *res, int res_len, int flags)
00666 {
00667 if(!strcmp(cmd, "ping")){
00668 av_strlcatf(res, res_len, "pong from:%s %s\n", filter->filter->name, filter->name);
00669 return 0;
00670 }else if(filter->filter->process_command) {
00671 return filter->filter->process_command(filter, cmd, arg, res, res_len, flags);
00672 }
00673 return AVERROR(ENOSYS);
00674 }
00675
00676 void avfilter_filter_samples(AVFilterLink *link, AVFilterBufferRef *samplesref)
00677 {
00678 void (*filter_samples)(AVFilterLink *, AVFilterBufferRef *);
00679 AVFilterPad *dst = link->dstpad;
00680 int i;
00681
00682 FF_DPRINTF_START(NULL, filter_samples); ff_dlog_link(NULL, link, 1);
00683
00684 if (!(filter_samples = dst->filter_samples))
00685 filter_samples = avfilter_default_filter_samples;
00686
00687
00688 if ((dst->min_perms & samplesref->perms) != dst->min_perms ||
00689 dst->rej_perms & samplesref->perms) {
00690
00691 av_log(link->dst, AV_LOG_DEBUG,
00692 "Copying audio data in avfilter (have perms %x, need %x, reject %x)\n",
00693 samplesref->perms, link->dstpad->min_perms, link->dstpad->rej_perms);
00694
00695 link->cur_buf = avfilter_default_get_audio_buffer(link, dst->min_perms,
00696 samplesref->audio->nb_samples);
00697 link->cur_buf->pts = samplesref->pts;
00698 link->cur_buf->audio->sample_rate = samplesref->audio->sample_rate;
00699
00700
00701 for (i = 0; samplesref->data[i] && i < 8; i++)
00702 memcpy(link->cur_buf->data[i], samplesref->data[i], samplesref->linesize[0]);
00703
00704 avfilter_unref_buffer(samplesref);
00705 } else
00706 link->cur_buf = samplesref;
00707
00708 filter_samples(link, link->cur_buf);
00709 }
00710
00711 #define MAX_REGISTERED_AVFILTERS_NB 128
00712
00713 static AVFilter *registered_avfilters[MAX_REGISTERED_AVFILTERS_NB + 1];
00714
00715 static int next_registered_avfilter_idx = 0;
00716
00717 AVFilter *avfilter_get_by_name(const char *name)
00718 {
00719 int i;
00720
00721 for (i = 0; registered_avfilters[i]; i++)
00722 if (!strcmp(registered_avfilters[i]->name, name))
00723 return registered_avfilters[i];
00724
00725 return NULL;
00726 }
00727
00728 int avfilter_register(AVFilter *filter)
00729 {
00730 if (next_registered_avfilter_idx == MAX_REGISTERED_AVFILTERS_NB) {
00731 av_log(NULL, AV_LOG_ERROR,
00732 "Maximum number of registered filters %d reached, "
00733 "impossible to register filter with name '%s'\n",
00734 MAX_REGISTERED_AVFILTERS_NB, filter->name);
00735 return AVERROR(ENOMEM);
00736 }
00737
00738 registered_avfilters[next_registered_avfilter_idx++] = filter;
00739 return 0;
00740 }
00741
00742 AVFilter **av_filter_next(AVFilter **filter)
00743 {
00744 return filter ? ++filter : ®istered_avfilters[0];
00745 }
00746
00747 void avfilter_uninit(void)
00748 {
00749 memset(registered_avfilters, 0, sizeof(registered_avfilters));
00750 next_registered_avfilter_idx = 0;
00751 }
00752
00753 static int pad_count(const AVFilterPad *pads)
00754 {
00755 int count;
00756
00757 for(count = 0; pads->name; count ++) pads ++;
00758 return count;
00759 }
00760
00761 static const char *filter_name(void *p)
00762 {
00763 AVFilterContext *filter = p;
00764 return filter->filter->name;
00765 }
00766
00767 static const AVClass avfilter_class = {
00768 "AVFilter",
00769 filter_name,
00770 NULL,
00771 LIBAVUTIL_VERSION_INT,
00772 };
00773
00774 int avfilter_open(AVFilterContext **filter_ctx, AVFilter *filter, const char *inst_name)
00775 {
00776 AVFilterContext *ret;
00777 *filter_ctx = NULL;
00778
00779 if (!filter)
00780 return AVERROR(EINVAL);
00781
00782 ret = av_mallocz(sizeof(AVFilterContext));
00783 if (!ret)
00784 return AVERROR(ENOMEM);
00785
00786 ret->av_class = &avfilter_class;
00787 ret->filter = filter;
00788 ret->name = inst_name ? av_strdup(inst_name) : NULL;
00789 if (filter->priv_size) {
00790 ret->priv = av_mallocz(filter->priv_size);
00791 if (!ret->priv)
00792 goto err;
00793 }
00794
00795 ret->input_count = pad_count(filter->inputs);
00796 if (ret->input_count) {
00797 ret->input_pads = av_malloc(sizeof(AVFilterPad) * ret->input_count);
00798 if (!ret->input_pads)
00799 goto err;
00800 memcpy(ret->input_pads, filter->inputs, sizeof(AVFilterPad) * ret->input_count);
00801 ret->inputs = av_mallocz(sizeof(AVFilterLink*) * ret->input_count);
00802 if (!ret->inputs)
00803 goto err;
00804 }
00805
00806 ret->output_count = pad_count(filter->outputs);
00807 if (ret->output_count) {
00808 ret->output_pads = av_malloc(sizeof(AVFilterPad) * ret->output_count);
00809 if (!ret->output_pads)
00810 goto err;
00811 memcpy(ret->output_pads, filter->outputs, sizeof(AVFilterPad) * ret->output_count);
00812 ret->outputs = av_mallocz(sizeof(AVFilterLink*) * ret->output_count);
00813 if (!ret->outputs)
00814 goto err;
00815 }
00816
00817 *filter_ctx = ret;
00818 return 0;
00819
00820 err:
00821 av_freep(&ret->inputs);
00822 av_freep(&ret->input_pads);
00823 ret->input_count = 0;
00824 av_freep(&ret->outputs);
00825 av_freep(&ret->output_pads);
00826 ret->output_count = 0;
00827 av_freep(&ret->priv);
00828 av_free(ret);
00829 return AVERROR(ENOMEM);
00830 }
00831
00832 void avfilter_free(AVFilterContext *filter)
00833 {
00834 int i;
00835 AVFilterLink *link;
00836
00837 if (filter->filter->uninit)
00838 filter->filter->uninit(filter);
00839
00840 for (i = 0; i < filter->input_count; i++) {
00841 if ((link = filter->inputs[i])) {
00842 if (link->src)
00843 link->src->outputs[link->srcpad - link->src->output_pads] = NULL;
00844 avfilter_formats_unref(&link->in_formats);
00845 avfilter_formats_unref(&link->out_formats);
00846 }
00847 avfilter_link_free(&link);
00848 }
00849 for (i = 0; i < filter->output_count; i++) {
00850 if ((link = filter->outputs[i])) {
00851 if (link->dst)
00852 link->dst->inputs[link->dstpad - link->dst->input_pads] = NULL;
00853 avfilter_formats_unref(&link->in_formats);
00854 avfilter_formats_unref(&link->out_formats);
00855 }
00856 avfilter_link_free(&link);
00857 }
00858
00859 av_freep(&filter->name);
00860 av_freep(&filter->input_pads);
00861 av_freep(&filter->output_pads);
00862 av_freep(&filter->inputs);
00863 av_freep(&filter->outputs);
00864 av_freep(&filter->priv);
00865 while(filter->command_queue){
00866 command_queue_pop(filter);
00867 }
00868 av_free(filter);
00869 }
00870
00871 int avfilter_init_filter(AVFilterContext *filter, const char *args, void *opaque)
00872 {
00873 int ret=0;
00874
00875 if (filter->filter->init)
00876 ret = filter->filter->init(filter, args, opaque);
00877 return ret;
00878 }
00879