History

Merge remote-tracking branch 'qatar/master'

* qatar/master: (26 commits) fate: use diff -b in oneline comparison Add missing version bumps and APIchanges/Changelog entries. lavfi: move buffer management function to a separate file. lavfi: move formats-related functions from default.c to formats.c lavfi: move video-related functions to a separate file. fate: make smjpeg a demux test fate: separate sierra-vmd audio and video tests fate: separate smacker audio and video tests libmp3lame: set supported channel layouts. avconv: automatically insert asyncts when -async is used. avconv: add support for audio filters. lavfi: add asyncts filter. lavfi: add aformat filter lavfi: add an audio buffer sink. lavfi: add an audio buffer source. buffersrc: add av_buffersrc_write_frame(). buffersrc: fix invalid read in uninit if the fifo hasn't been allocated lavfi: rename vsrc_buffer.c to buffersrc.c avfiltergraph: reindent lavfi: add channel layout/sample rate negotiation. ... Conflicts: Changelog doc/APIchanges doc/filters.texi ffmpeg.c ffprobe.c libavcodec/libmp3lame.c libavfilter/Makefile libavfilter/af_aformat.c libavfilter/allfilters.c libavfilter/avfilter.c libavfilter/avfilter.h libavfilter/avfiltergraph.c libavfilter/buffersrc.c libavfilter/defaults.c libavfilter/formats.c libavfilter/src_buffer.c libavfilter/version.h libavfilter/vf_yadif.c libavfilter/vsrc_buffer.c libavfilter/vsrc_buffer.h libavutil/avutil.h tests/fate/audio.mak tests/fate/demux.mak tests/fate/video.mak

Michael Niedermayer committed 14 years ago

Commit 1cbf7fb2 parents a48abf5 0ff0af752 files · +3304 −1706Browse files

Showing the changes to libavfilter/avfilter.c (1 of 52 files). Show all

Unified · Split

libavfilter/avfilter.c+20−354
@@ -24,11 +24,11 @@ · 23 unmodified lines
24#include "libavutil/pixdesc.h"24#include "libavutil/pixdesc.h"
25#include "libavutil/rational.h"25#include "libavutil/rational.h"
26#include "libavutil/audioconvert.h"26#include "libavutil/audioconvert.h"
27#include "libavutil/imgutils.h"
28#include "libavutil/avassert.h"27#include "libavutil/avassert.h"
29#include "libavutil/avstring.h"28#include "libavutil/avstring.h"
30 29
31#include "avfilter.h"30#include "avfilter.h"
31#include "formats.h"
32#include "internal.h"32#include "internal.h"
33 33
34unsigned avfilter_version(void) {34unsigned avfilter_version(void) {
@@ -47,7 +47,7 @@ const char *avfilter_license(void) · 12 unmodified lines
47 return LICENSE_PREFIX FFMPEG_LICENSE + sizeof(LICENSE_PREFIX) - 1;47 return LICENSE_PREFIX FFMPEG_LICENSE + sizeof(LICENSE_PREFIX) - 1;
48}48}
49 49
50static void command_queue_pop(AVFilterContext *filter)50void ff_command_queue_pop(AVFilterContext *filter)
51{51{
52 AVFilterCommand *c= filter->command_queue;52 AVFilterCommand *c= filter->command_queue;
53 av_freep(&c->arg);53 av_freep(&c->arg);
@@ -56,133 +56,6 @@ static void command_queue_pop(AVFilterContext *filter) · 2 unmodified lines
56 av_free(c);56 av_free(c);
57}57}
58 58
59AVFilterBufferRef *avfilter_ref_buffer(AVFilterBufferRef *ref, int pmask)
60{
61 AVFilterBufferRef *ret = av_malloc(sizeof(AVFilterBufferRef));
62 if (!ret)
63 return NULL;
64 *ret = *ref;
65 if (ref->type == AVMEDIA_TYPE_VIDEO) {
66 ret->video = av_malloc(sizeof(AVFilterBufferRefVideoProps));
67 if (!ret->video) {
68 av_free(ret);
69 return NULL;
70 }
71 *ret->video = *ref->video;
72 ret->extended_data = ret->data;
73 } else if (ref->type == AVMEDIA_TYPE_AUDIO) {
74 ret->audio = av_malloc(sizeof(AVFilterBufferRefAudioProps));
75 if (!ret->audio) {
76 av_free(ret);
77 return NULL;
78 }
79 *ret->audio = *ref->audio;
80
81 if (ref->extended_data && ref->extended_data != ref->data) {
82 int nb_channels = av_get_channel_layout_nb_channels(ref->audio->channel_layout);
83 if (!(ret->extended_data = av_malloc(sizeof(*ret->extended_data) *
84 nb_channels))) {
85 av_freep(&ret->audio);
86 av_freep(&ret);
87 return NULL;
88 }
89 memcpy(ret->extended_data, ref->extended_data,
90 sizeof(*ret->extended_data) * nb_channels);
91 } else
92 ret->extended_data = ret->data;
93 }
94 ret->perms &= pmask;
95 ret->buf->refcount ++;
96 return ret;
97}
98
99static void free_pool(AVFilterPool *pool)
100{
101 int i;
102
103 av_assert0(pool->refcount > 0);
104
105 for (i = 0; i < POOL_SIZE; i++) {
106 if (pool->pic[i]) {
107 AVFilterBufferRef *picref = pool->pic[i];
108 /* free buffer: picrefs stored in the pool are not
109 * supposed to contain a free callback */
110 av_assert0(!picref->buf->refcount);
111 av_freep(&picref->buf->data[0]);
112 av_freep(&picref->buf);
113
114 av_freep(&picref->audio);
115 av_freep(&picref->video);
116 av_freep(&pool->pic[i]);
117 pool->count--;
118 }
119 }
120 pool->draining = 1;
121
122 if (!--pool->refcount) {
123 av_assert0(!pool->count);
124 av_free(pool);
125 }
126}
127
128static void store_in_pool(AVFilterBufferRef *ref)
129{
130 int i;
131 AVFilterPool *pool= ref->buf->priv;
132
133 av_assert0(ref->buf->data[0]);
134 av_assert0(pool->refcount>0);
135
136 if (pool->count == POOL_SIZE) {
137 AVFilterBufferRef *ref1 = pool->pic[0];
138 av_freep(&ref1->video);
139 av_freep(&ref1->audio);
140 av_freep(&ref1->buf->data[0]);
141 av_freep(&ref1->buf);
142 av_free(ref1);
143 memmove(&pool->pic[0], &pool->pic[1], sizeof(void*)*(POOL_SIZE-1));
144 pool->count--;
145 pool->pic[POOL_SIZE-1] = NULL;
146 }
147
148 for (i = 0; i < POOL_SIZE; i++) {
149 if (!pool->pic[i]) {
150 pool->pic[i] = ref;
151 pool->count++;
152 break;
153 }
154 }
155 if (pool->draining) {
156 free_pool(pool);
157 } else
158 --pool->refcount;
159}
160
161void avfilter_unref_buffer(AVFilterBufferRef *ref)
162{
163 if (!ref)
164 return;
165 av_assert0(ref->buf->refcount > 0);
166 if (!(--ref->buf->refcount)) {
167 if (!ref->buf->free) {
168 store_in_pool(ref);
169 return;
170 }
171 ref->buf->free(ref->buf);
172 }
173 if (ref->extended_data != ref->data)
174 av_freep(&ref->extended_data);
175 av_freep(&ref->video);
176 av_freep(&ref->audio);
177 av_free(ref);
178}
179
180void avfilter_unref_bufferp(AVFilterBufferRef **ref)
181{
182 avfilter_unref_buffer(*ref);
183 *ref = NULL;
184}
185
186void avfilter_insert_pad(unsigned idx, unsigned *count, size_t padidx_off,59void avfilter_insert_pad(unsigned idx, unsigned *count, size_t padidx_off,
187 AVFilterPad **pads, AVFilterLink ***links,60 AVFilterPad **pads, AVFilterLink ***links,
188 AVFilterPad *newpad)61 AVFilterPad *newpad)
@@ -240,7 +113,7 @@ void avfilter_link_free(AVFilterLink **link) · 51 unmodified lines
240 return;113 return;
241 114
242 if ((*link)->pool)115 if ((*link)->pool)
243 free_pool((*link)->pool);116 ff_free_pool((*link)->pool);
244 117
245 av_freep(link);118 av_freep(link);
246}119}
@@ -272,12 +145,15 @@ int avfilter_insert_filter(AVFilterLink *link, AVFilterContext *filt, · 25 unmodified lines
272 if (link->out_formats)145 if (link->out_formats)
273 avfilter_formats_changeref(&link->out_formats,146 avfilter_formats_changeref(&link->out_formats,
274 &filt->outputs[filt_dstpad_idx]->out_formats);147 &filt->outputs[filt_dstpad_idx]->out_formats);
275 if (link->out_chlayouts)148 if (link->out_channel_layouts)
276 avfilter_formats_changeref(&link->out_chlayouts,149 ff_channel_layouts_changeref(&link->out_channel_layouts,
277 &filt->outputs[filt_dstpad_idx]->out_chlayouts);150 &filt->outputs[filt_dstpad_idx]->out_channel_layouts);
278 if (link->out_packing)151 if (link->out_packing)
279 avfilter_formats_changeref(&link->out_packing,152 avfilter_formats_changeref(&link->out_packing,
280 &filt->outputs[filt_dstpad_idx]->out_packing);153 &filt->outputs[filt_dstpad_idx]->out_packing);
154 if (link->out_samplerates)
155 avfilter_formats_changeref(&link->out_samplerates,
156 &filt->outputs[filt_dstpad_idx]->out_samplerates);
281 157
282 return 0;158 return 0;
283}159}
@@ -329,6 +205,7 @@ int avfilter_config_links(AVFilterContext *filter) · 45 unmodified lines
329 link->sample_aspect_ratio = inlink ?205 link->sample_aspect_ratio = inlink ?
330 inlink->sample_aspect_ratio : (AVRational){1,1};206 inlink->sample_aspect_ratio : (AVRational){1,1};
331 207
208#if 1
332 if (inlink) {209 if (inlink) {
333 if (!link->w)210 if (!link->w)
334 link->w = inlink->w;211 link->w = inlink->w;
@@ -359,6 +236,7 @@ int avfilter_config_links(AVFilterContext *filter) · 24 unmodified lines
359 link->time_base = (AVRational) {1, link->sample_rate};236 link->time_base = (AVRational) {1, link->sample_rate};
360 }237 }
361 238
239#endif
362 if ((config_link = link->dstpad->config_props))240 if ((config_link = link->dstpad->config_props))
363 if ((ret = config_link(link)) < 0)241 if ((ret = config_link(link)) < 0)
364 return ret;242 return ret;
@@ -370,47 +248,6 @@ int avfilter_config_links(AVFilterContext *filter) · 5 unmodified lines
370 return 0;248 return 0;
371}249}
372 250
373static char *ff_get_ref_perms_string(char *buf, size_t buf_size, int perms)
374{
375 snprintf(buf, buf_size, "%s%s%s%s%s%s",
376 perms & AV_PERM_READ ? "r" : "",
377 perms & AV_PERM_WRITE ? "w" : "",
378 perms & AV_PERM_PRESERVE ? "p" : "",
379 perms & AV_PERM_REUSE ? "u" : "",
380 perms & AV_PERM_REUSE2 ? "U" : "",
381 perms & AV_PERM_NEG_LINESIZES ? "n" : "");
382 return buf;
383}
384
385static void ff_dlog_ref(void *ctx, AVFilterBufferRef *ref, int end)
386{
387 av_unused char buf[16];
388 av_dlog(ctx,
389 "ref[%p buf:%p refcount:%d perms:%s data:%p linesize[%d, %d, %d, %d] pts:%"PRId64" pos:%"PRId64,
390 ref, ref->buf, ref->buf->refcount, ff_get_ref_perms_string(buf, sizeof(buf), ref->perms), ref->data[0],
391 ref->linesize[0], ref->linesize[1], ref->linesize[2], ref->linesize[3],
392 ref->pts, ref->pos);
393
394 if (ref->video) {
395 av_dlog(ctx, " a:%d/%d s:%dx%d i:%c iskey:%d type:%c",
396 ref->video->sample_aspect_ratio.num, ref->video->sample_aspect_ratio.den,
397 ref->video->w, ref->video->h,
398 !ref->video->interlaced ? 'P' : /* Progressive */
399 ref->video->top_field_first ? 'T' : 'B', /* Top / Bottom */
400 ref->video->key_frame,
401 av_get_picture_type_char(ref->video->pict_type));
402 }
403 if (ref->audio) {
404 av_dlog(ctx, " cl:%"PRId64"d n:%d r:%d p:%d",
405 ref->audio->channel_layout,
406 ref->audio->nb_samples,
407 ref->audio->sample_rate,
408 ref->audio->planar);
409 }
410
411 av_dlog(ctx, "]%s", end ? "\n" : "");
412}
413
414void ff_dlog_link(void *ctx, AVFilterLink *link, int end)251void ff_dlog_link(void *ctx, AVFilterLink *link, int end)
415{252{
416 if (link->type == AVMEDIA_TYPE_VIDEO) {253 if (link->type == AVMEDIA_TYPE_VIDEO) {
@@ -435,71 +272,6 @@ void ff_dlog_link(void *ctx, AVFilterLink *link, int end) · 18 unmodified lines
435 }272 }
436}273}
437 274
438AVFilterBufferRef *avfilter_get_video_buffer(AVFilterLink *link, int perms, int w, int h)
439{
440 AVFilterBufferRef *ret = NULL;
441
442 av_unused char buf[16];
443 FF_DPRINTF_START(NULL, get_video_buffer); ff_dlog_link(NULL, link, 0);
444 av_dlog(NULL, " perms:%s w:%d h:%d\n", ff_get_ref_perms_string(buf, sizeof(buf), perms), w, h);
445
446 if (link->dstpad->get_video_buffer)
447 ret = link->dstpad->get_video_buffer(link, perms, w, h);
448
449 if (!ret)
450 ret = avfilter_default_get_video_buffer(link, perms, w, h);
451
452 if (ret)
453 ret->type = AVMEDIA_TYPE_VIDEO;
454
455 FF_DPRINTF_START(NULL, get_video_buffer); ff_dlog_link(NULL, link, 0); av_dlog(NULL, " returning "); ff_dlog_ref(NULL, ret, 1);
456
457 return ret;
458}
459
460AVFilterBufferRef *
461avfilter_get_video_buffer_ref_from_arrays(uint8_t * const data[4], const int linesize[4], int perms,
462 int w, int h, enum PixelFormat format)
463{
464 AVFilterBuffer *pic = av_mallocz(sizeof(AVFilterBuffer));
465 AVFilterBufferRef *picref = av_mallocz(sizeof(AVFilterBufferRef));
466
467 if (!pic || !picref)
468 goto fail;
469
470 picref->buf = pic;
471 picref->buf->free = ff_avfilter_default_free_buffer;
472 if (!(picref->video = av_mallocz(sizeof(AVFilterBufferRefVideoProps))))
473 goto fail;
474
475 pic->w = picref->video->w = w;
476 pic->h = picref->video->h = h;
477
478 /* make sure the buffer gets read permission or it's useless for output */
479 picref->perms = perms | AV_PERM_READ;
480
481 pic->refcount = 1;
482 picref->type = AVMEDIA_TYPE_VIDEO;
483 pic->format = picref->format = format;
484
485 memcpy(pic->data, data, 4*sizeof(data[0]));
486 memcpy(pic->linesize, linesize, 4*sizeof(linesize[0]));
487 memcpy(picref->data, pic->data, sizeof(picref->data));
488 memcpy(picref->linesize, pic->linesize, sizeof(picref->linesize));
489
490 pic-> extended_data = pic->data;
491 picref->extended_data = picref->data;
492
493 return picref;
494
495fail:
496 if (picref && picref->video)
497 av_free(picref->video);
498 av_free(picref);
499 av_free(pic);
500 return NULL;
501}
502
503int avfilter_request_frame(AVFilterLink *link)275int avfilter_request_frame(AVFilterLink *link)
504{276{
505 FF_DPRINTF_START(NULL, request_frame); ff_dlog_link(NULL, link, 1);277 FF_DPRINTF_START(NULL, request_frame); ff_dlog_link(NULL, link, 1);
@@ -538,107 +310,6 @@ void ff_update_link_current_pts(AVFilterLink *link, int64_t pts) · 32 unmodified lines
538 ff_avfilter_graph_update_heap(link->graph, link);310 ff_avfilter_graph_update_heap(link->graph, link);
539}311}
540 312
541/* XXX: should we do the duplicating of the picture ref here, instead of
542 * forcing the source filter to do it? */
543void avfilter_start_frame(AVFilterLink *link, AVFilterBufferRef *picref)
544{
545 void (*start_frame)(AVFilterLink *, AVFilterBufferRef *);
546 AVFilterPad *dst = link->dstpad;
547 int perms = picref->perms;
548 AVFilterCommand *cmd= link->dst->command_queue;
549
550 FF_DPRINTF_START(NULL, start_frame); ff_dlog_link(NULL, link, 0); av_dlog(NULL, " "); ff_dlog_ref(NULL, picref, 1);
551
552 if (!(start_frame = dst->start_frame))
553 start_frame = avfilter_default_start_frame;
554
555 if (picref->linesize[0] < 0)
556 perms |= AV_PERM_NEG_LINESIZES;
557 /* prepare to copy the picture if it has insufficient permissions */
558 if ((dst->min_perms & perms) != dst->min_perms || dst->rej_perms & perms) {
559 av_log(link->dst, AV_LOG_DEBUG,
560 "frame copy needed (have perms %x, need %x, reject %x)\n",
561 picref->perms,
562 link->dstpad->min_perms, link->dstpad->rej_perms);
563
564 link->cur_buf = avfilter_get_video_buffer(link, dst->min_perms, link->w, link->h);
565 link->src_buf = picref;
566 avfilter_copy_buffer_ref_props(link->cur_buf, link->src_buf);
567 }
568 else
569 link->cur_buf = picref;
570
571 while(cmd && cmd->time <= picref->pts * av_q2d(link->time_base)){
572 av_log(link->dst, AV_LOG_DEBUG,
573 "Processing command time:%f command:%s arg:%s\n",
574 cmd->time, cmd->command, cmd->arg);
575 avfilter_process_command(link->dst, cmd->command, cmd->arg, 0, 0, cmd->flags);
576 command_queue_pop(link->dst);
577 cmd= link->dst->command_queue;
578 }
579
580 start_frame(link, link->cur_buf);
581 ff_update_link_current_pts(link, link->cur_buf->pts);
582}
583
584void avfilter_end_frame(AVFilterLink *link)
585{
586 void (*end_frame)(AVFilterLink *);
587
588 if (!(end_frame = link->dstpad->end_frame))
589 end_frame = avfilter_default_end_frame;
590
591 end_frame(link);
592
593 /* unreference the source picture if we're feeding the destination filter
594 * a copied version dues to permission issues */
595 if (link->src_buf) {
596 avfilter_unref_buffer(link->src_buf);
597 link->src_buf = NULL;
598 }
599}
600
601void avfilter_draw_slice(AVFilterLink *link, int y, int h, int slice_dir)
602{
603 uint8_t *src[4], *dst[4];
604 int i, j, vsub;
605 void (*draw_slice)(AVFilterLink *, int, int, int);
606
607 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);
608
609 /* copy the slice if needed for permission reasons */
610 if (link->src_buf) {
611 vsub = av_pix_fmt_descriptors[link->format].log2_chroma_h;
612
613 for (i = 0; i < 4; i++) {
614 if (link->src_buf->data[i]) {
615 src[i] = link->src_buf-> data[i] +
616 (y >> (i==1 || i==2 ? vsub : 0)) * link->src_buf-> linesize[i];
617 dst[i] = link->cur_buf->data[i] +
618 (y >> (i==1 || i==2 ? vsub : 0)) * link->cur_buf->linesize[i];
619 } else
620 src[i] = dst[i] = NULL;
621 }
622
623 for (i = 0; i < 4; i++) {
624 int planew =
625 av_image_get_linesize(link->format, link->cur_buf->video->w, i);
626
627 if (!src[i]) continue;
628
629 for (j = 0; j < h >> (i==1 || i==2 ? vsub : 0); j++) {
630 memcpy(dst[i], src[i], planew);
631 src[i] += link->src_buf->linesize[i];
632 dst[i] += link->cur_buf->linesize[i];
633 }
634 }
635 }
636
637 if (!(draw_slice = link->dstpad->draw_slice))
638 draw_slice = avfilter_default_draw_slice;
639 draw_slice(link, y, h, slice_dir);
640}
641
642int avfilter_process_command(AVFilterContext *filter, const char *cmd, const char *arg, char *res, int res_len, int flags)313int avfilter_process_command(AVFilterContext *filter, const char *cmd, const char *arg, char *res, int res_len, int flags)
643{314{
644 if(!strcmp(cmd, "ping")){315 if(!strcmp(cmd, "ping")){
@@ -788,6 +459,10 @@ void avfilter_free(AVFilterContext *filter) · 143 unmodified lines
788 link->src->outputs[link->srcpad - link->src->output_pads] = NULL;459 link->src->outputs[link->srcpad - link->src->output_pads] = NULL;
789 avfilter_formats_unref(&link->in_formats);460 avfilter_formats_unref(&link->in_formats);
790 avfilter_formats_unref(&link->out_formats);461 avfilter_formats_unref(&link->out_formats);
462 avfilter_formats_unref(&link->in_samplerates);
463 avfilter_formats_unref(&link->out_samplerates);
464 ff_channel_layouts_unref(&link->in_channel_layouts);
465 ff_channel_layouts_unref(&link->out_channel_layouts);
791 }466 }
792 avfilter_link_free(&link);467 avfilter_link_free(&link);
793 }468 }
@@ -797,6 +472,10 @@ void avfilter_free(AVFilterContext *filter) · 3 unmodified lines
797 link->dst->inputs[link->dstpad - link->dst->input_pads] = NULL;472 link->dst->inputs[link->dstpad - link->dst->input_pads] = NULL;
798 avfilter_formats_unref(&link->in_formats);473 avfilter_formats_unref(&link->in_formats);
799 avfilter_formats_unref(&link->out_formats);474 avfilter_formats_unref(&link->out_formats);
475 avfilter_formats_unref(&link->in_samplerates);
476 avfilter_formats_unref(&link->out_samplerates);
477 ff_channel_layouts_unref(&link->in_channel_layouts);
478 ff_channel_layouts_unref(&link->out_channel_layouts);
800 }479 }
801 avfilter_link_free(&link);480 avfilter_link_free(&link);
802 }481 }
@@ -808,7 +487,7 @@ void avfilter_free(AVFilterContext *filter) · 5 unmodified lines
808 av_freep(&filter->outputs);487 av_freep(&filter->outputs);
809 av_freep(&filter->priv);488 av_freep(&filter->priv);
810 while(filter->command_queue){489 while(filter->command_queue){
811 command_queue_pop(filter);490 ff_command_queue_pop(filter);
812 }491 }
813 av_free(filter);492 av_free(filter);
814}493}
@@ -821,16 +500,3 @@ int avfilter_init_filter(AVFilterContext *filter, const char *args, void *opaque · 6 unmodified lines
821 ret = filter->filter->init(filter, args, opaque);500 ret = filter->filter->init(filter, args, opaque);
822 return ret;501 return ret;
823}502}
824
825void avfilter_copy_buffer_ref_props(AVFilterBufferRef *dst, AVFilterBufferRef *src)
826{
827 // copy common properties
828 dst->pts = src->pts;
829 dst->pos = src->pos;
830
831 switch (src->type) {
832 case AVMEDIA_TYPE_VIDEO: *dst->video = *src->video; break;
833 case AVMEDIA_TYPE_AUDIO: *dst->audio = *src->audio; break;
834 default: break;
835 }
836}

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t