Author: kdub Date: Thu Jul 2 14:29:37 2009 New Revision: 4567 Log: A source filter, and somewhat working example of usage of the library
Modified: afilters/af_null.c afilters/avfilter.c afilters/avfilter.h afilters/dummy.c Modified: afilters/af_null.c ============================================================================== --- afilters/af_null.c Wed Jul 1 19:45:17 2009 (r4566) +++ afilters/af_null.c Thu Jul 2 14:29:37 2009 (r4567) @@ -21,42 +21,5 @@ * null filter */ -#include <stdio.h> -#include "avfilter.h" - - -typedef struct -{ - int history[100]; /*just an example */ -} af_null_priv_t; - -static int start_buf(AVFilterLink *link, AVFilterSamplesRef *sample_ref) -{ - av_log(0,0, "Starting buffer\n"); - return; -} - -static int end_buf(AVFilterLink *link, AVFilterSamplesRef *sample_ref) -{ - av_log(0,0, "Ending buffer\n"); - return; -} - -AVFilter avfilter_af_null = -{ - .name = "audio_null", - - .priv_size = sizeof(af_null_priv_t), - - .inputs = (AVFilterPad[]) {{ .name = "default", - .type = CODEC_TYPE_AUDIO, - .start_buffer = start_buf, - .end_buffer = end_buf }, - { .name = NULL}}, - - .outputs = (AVFilterPad[]) {{ .name = "default", - .type = CODEC_TYPE_AUDIO, }, - { .name = NULL}}, -}; Modified: afilters/avfilter.c ============================================================================== --- afilters/avfilter.c Wed Jul 1 19:45:17 2009 (r4566) +++ afilters/avfilter.c Thu Jul 2 14:29:37 2009 (r4567) @@ -85,6 +85,7 @@ int avfilter_link(AVFilterContext *src, src->outputs[srcpad] || dst->inputs[dstpad]) return -1; + av_log(0,0,"src is %X, dst is %X\n",src, dst); src->outputs[srcpad] = dst-> inputs[dstpad] = link = av_mallocz(sizeof(AVFilterLink)); @@ -92,8 +93,19 @@ int avfilter_link(AVFilterContext *src, link->dst = dst; link->srcpad = srcpad; link->dstpad = dstpad; + + link->format = PIX_FMT_NONE; + /* FIXME shouldnt do static buffer alloc like this really, should be + variable */ + link->link_size = 128; + link->srcbuf = (AVFilterBufferRef*) av_malloc(sizeof(AVFilterBufferRef)); + link->srcbuf->buffer = (AVFilterBuffer*) av_malloc(sizeof(AVFilterBuffer)); + link->srcbuf->buffer->data = (int16_t*) av_malloc(link->link_size * + sizeof(int16_t)); + link->srcbuf->buffer->n_samples = link->link_size; + return 0; } @@ -131,7 +143,7 @@ int avfilter_config_links(AVFilterContex for(i = 0; i < filter->input_count; i ++) { AVFilterLink *link = filter->inputs[i]; - + av_log(0,0,"link is %x\n", filter->inputs[i]); if(!link) continue; switch(link->init_state) { @@ -231,23 +243,40 @@ void avfilter_start_frame(AVFilterLink * start_frame(link, link->cur_pic); } -void avfilter_start_buffer(AVFilterLink *link, AVFilterSamplesRef *sample_ref) +void avfilter_filter_buffer(AVFilterLink *link, AVFilterBufferRef *sample_ref) { - void (*start_buf) (AVFilterLink *, AVFilterSamplesRef *); - AVFilterPad *dst = &link_dpad(link); + void (*filter_input_buffer) (AVFilterLink *, AVFilterBufferRef *); + void (*filter_output_buffer) (AVFilterLink *, AVFilterBufferRef *); - if (!(start_buf = dst->start_buffer)) + AVFilterPad *src = &link->src->output_pads[link->srcpad]; + AVFilterPad *dst = &link->dst->input_pads[link->dstpad]; + + int input_func = 1, output_func = 1; + + if (!(filter_output_buffer = dst->filter_buffer)) { - av_log(0,0,"it is %x\n", 0); - start_buf = NULL; /* FIXME: should have a default function pointer + av_log(0,0,"LINK HAS NO OUTPUT?\n", 0); + filter_output_buffer = NULL; /* FIXME: should have a default function pointer like avfilter_default_start_buffer */ + output_func = 0; } + if (!(filter_input_buffer = src->filter_buffer)) + { + av_log(0,0,"LINK HAS NO INPUT?\n", 0); + filter_input_buffer = NULL; /* FIXME: should have a default function pointer + like avfilter_default_start_buffer */ + input_func = 0; + } - av_log(0,0,"it is %x\n", start_buf); + //av_log(0,0,"it is %x\n", filter_buffer); link->cur_buf = sample_ref; - start_buf(link, link->cur_pic); + if (output_func) + filter_output_buffer(link, link->srcbuf); + + if (input_func) + filter_input_buffer(link, link->srcbuf); } Modified: afilters/avfilter.h ============================================================================== --- afilters/avfilter.h Wed Jul 1 19:45:17 2009 (r4566) +++ afilters/avfilter.h Thu Jul 2 14:29:37 2009 (r4567) @@ -104,30 +104,29 @@ typedef struct AVFilterPicRef /* two structures that contain the data to be processed for the audio buf */ /* contains samples. audio analogue to AVFilterPic */ -typedef struct AVFilterSamples +typedef struct AVFilterBuffer { /* data */ void *data; int data_size; /* data size in bytes */ int n_samples; - void *priv; - void (*free)(struct AVFilterSamples *samples); + void (*free)(struct AVFilterBuffer *samples); -}AVFilterSamples; +}AVFilterBuffer; /** * A reference to an audio buffer. contains info about the AVFilterSamples * Do not use AVFilterSamples directly */ -typedef struct AVFilterSamplesRef +typedef struct AVFilterBufferRef { - AVFilterSamples *samples; + AVFilterBuffer *buffer; int sample_type; /* contains type of sample in the buffer*/ int sample_rate; -}AVFilterSamplesRef; +}AVFilterBufferRef; @@ -381,12 +380,10 @@ struct AVFilterPad /** - * Process an audio buffer. This function is where the audio filter should - * recieve and process data + * Process an audio buffer. Filters can hook into this function to do the + * actual audio processing */ - int (*start_buffer)(AVFilterLink *link, AVFilterSamplesRef *sample_ref); - - int (*end_buffer)(AVFilterLink *link, AVFilterSamplesRef *sample_ref); + int (*filter_buffer)(AVFilterLink *link, AVFilterBufferRef *sample_ref); }; @@ -513,14 +510,14 @@ struct AVFilterLink * filters. */ AVFilterPicRef *srcpic; - AVFilterPicRef *cur_pic; AVFilterPicRef *outpic; /** the audio buffer reference is sent accross the link by the source. */ - AVFilterSamplesRef *srcbuf; - AVFilterSamplesRef *cur_buf; - AVFilterSamplesRef *outbuf; + AVFilterBufferRef *srcbuf; + int link_size; /* size of data sent accross link each time */ + AVFilterBufferRef *cur_buf; + AVFilterBufferRef *outbuf; }; /** @@ -535,7 +532,8 @@ int avfilter_link(AVFilterContext *src, AVFilterContext *dst, unsigned dstpad); /** - * Negotiates the colorspace, dimensions, etc of all inputs to a filter. + * Negotiates the colorspace, dimensions, etc (video) or the +* samplerate, sample, format, etc (audio) of all inputs to a filter. * @param filter the filter to negotiate the properties for its inputs * @return zero on successful negotiation */ Modified: afilters/dummy.c ============================================================================== --- afilters/dummy.c Wed Jul 1 19:45:17 2009 (r4566) +++ afilters/dummy.c Thu Jul 2 14:29:37 2009 (r4567) @@ -1,10 +1,214 @@ /* temporary development file for avfilters * (c) 2009 Kevin DuBois <kdub...@gmail.com> +* GPL v2 */ -#include "af_null.c" /*FIXME: bad, i know. prototyping :) */ +#include <stdio.h> +#include "avfilter.h" + +typedef struct +{ + int history[100]; /*just an example */ + +} af_null_priv_t; + + +static int filter(AVFilterLink *link, AVFilterBufferRef *sample_ref) +{ + av_log(0,0, "Filter buffer\n"); + int num_samples = sample_ref->buffer->n_samples; + int i; + + int16_t *data; + data = (int16_t*) sample_ref->buffer->data; + for (i=0; i < num_samples; i++) + { + data[i] = data[i] +1; + } + + return 0; +} + +AVFilter avfilter_af_null = +{ + .name = "audio_null", + + .priv_size = sizeof(af_null_priv_t), + + .inputs = (AVFilterPad[]) {{ .name = "default", + .type = CODEC_TYPE_AUDIO, + .filter_buffer = filter }, + { .name = NULL}}, + + .outputs = (AVFilterPad[]) {{ .name = "default", + .type = CODEC_TYPE_AUDIO, }, + { .name = NULL}}, +}; + + +typedef struct +{ + int first_used; + int last_used; + + AVFilterBufferRef buf_ref; + +} af_src_priv_t; + +static int av_asrc_buffer_add_samples(AVFilterContext *ctx, + AVFilterBufferRef * samples) +{ + printf("LOAD BYTES into SRC\n"); + af_src_priv_t *priv; + priv = ctx->priv; + + printf("last used: %i\n", priv->last_used); + /* find the last point in the buffer */ + int first = priv->first_used; + int last = priv->last_used; + + int attempted_load = samples->buffer->n_samples; + if (first <= last ) /* buffer has room */ + { + if (attempted_load > priv->buf_ref.buffer->n_samples) + { + /* error */ + printf("Error! not enough room\n"); + return attempted_load - priv->buf_ref.buffer->n_samples; + } + memcpy(&priv->buf_ref.buffer->data[last] , samples->buffer->data, attempted_load); + priv->last_used = priv->last_used + attempted_load; + } + + + printf("<<<<<<<<Buffer State>>>>>>>>\n"); + printf("First Used:\t%i\n",priv->first_used); + printf("Last Used:\t%i\n", priv->last_used); + +} + +static int dump_next(AVFilterLink *lnk, AVFilterBufferRef *sample_ref) +{ + printf("TAKE BYTES from SRC\n"); + + af_src_priv_t *priv; + priv = (af_src_priv_t*) lnk->src->priv; + + + printf("Link size is %i\n", lnk->link_size); + +// memcpy(sample_ref, priv->buf_ref.buffer , lnk->link_size); + + /* move samples cursor to next fresh point */ + priv->first_used = priv->first_used + lnk->link_size; + + printf("<<<<<<<<Buffer State>>>>>>>>\n"); + printf("First Used:\t%i\n",priv->first_used); + printf("Last Used:\t%i\n", priv->last_used); + + printf("dumping buffer\n"); + return 0; + +} + + +static int src_buf_init (AVFilterContext *ctx, + const char *args, void *opaque) +{ + /* allocate a fixed size for the input buffer */ + /* arbitrary value, will be modifiable */ + + printf("SRC BUF INIT\n"); + af_src_priv_t *priv; + priv = ctx->priv; + + priv->buf_ref.buffer = (AVFilterBuffer*) malloc(sizeof(AVFilterBuffer)); + + priv->buf_ref.buffer->n_samples = 1024; + priv->buf_ref.buffer->data = (int16_t *) + calloc(priv->buf_ref.buffer->n_samples, sizeof(int16_t)); + + priv->first_used = 0; + priv->last_used = 0; + + return 0; +} + +AVFilter avfilter_af_src = +{ + .name = "audio_src", + + .priv_size = 0, + + .init = src_buf_init, + .inputs = (AVFilterPad[]) {{.name = NULL}}, + .outputs = (AVFilterPad[]) { {.name = "default", + .type = CODEC_TYPE_AUDIO, + .filter_buffer = dump_next}, + {.name = NULL}} + +}; + + +#if 0 +int dump_avfiltlink(AVFilterLink *link) +{ + if (!link) + return 0; + + printf("\tLink dump...\n"); + printf("\tSource:\t0x%x\n", link->src); + printf("\tDest:\t0x%x\n", link->dst); + + + switch (link->init_state) + { + case AVLINK_UNINIT: + printf("\tState: AVLINK_UNINIT\n"); + break; + case AVLINK_STARTINIT: + printf("\tState: AVLINK_STARTINIT\n"); + break; + case AVLINK_INIT: + printf("\tState: AVLINK_INIT\n"); + break; + default: + printf("\tState: ???\n"); + break; + } + +} + +int dump_avfiltcont(AVFilterContext *cont) +{ + printf("\n--------------AVFILTCONT DUMP-------------\n"); + if (!cont) + { + printf("Error, null argument\n"); + printf("------------END AVFILTCONT DUMP-----------\n\n"); + return -1; + } + + printf("Cont addr:\t%X\n", cont); + printf("Class:\t\t%x\n", cont->av_class); + printf("Filter:\t\t%x\n", cont->filter); + printf("Name:\t\t%s\n", cont->name); + printf("Input Count:\t%i\n", cont->input_count); + printf("Input Pads:\t%x\n", cont->input_pads); + printf("Input Links:\t%x\n", cont->inputs); +// dump_avfiltlink(cont->inputs[0]); + printf("Output Count:\t%i\n", cont->output_count); + printf("Output Pads:\t%x\n", cont->output_pads); + printf("Output Links:\t%x\n", cont->outputs); + dump_avfiltlink(cont->outputs[0]); + + printf("------------END AVFILTCONT DUMP-----------\n\n"); + return 0; +} +#endif + int main() { @@ -14,56 +218,57 @@ int main() /* Simulates a 1024 buffer of sl16 audio data */ /* temporary setup, probably a cleaner way i want to do all this */ int16_t * tbuf; - int i, n_samples = 1024; + int i, n_samples = 512; tbuf = calloc(n_samples, sizeof(int16_t)); for(i=0;i<n_samples;i++) { +#define SINEWAVE 0 +#if SINEWAVE tbuf[i] = (int16_t) 100 * sin(2*3.141/100 * i); +#else + tbuf[i] = i; +#endif } // sine wave, period 1024/100, range, 100 -> -100 - - AVFilterSamples samples; + AVFilterBuffer samples; samples.n_samples = n_samples; samples.data = tbuf; samples.data_size = sizeof(int16_t); - - AVFilterSamplesRef sample_buf; - sample_buf.samples = &samples; + AVFilterBufferRef sample_buf; + sample_buf.buffer = &samples; sample_buf.sample_type = 10; sample_buf.sample_rate = 128000; - /* avfilter context */ - AVFilterContext * avfiltcont; - AVFilter *avfilt; + /* set up source filter */ + AVFilterContext *src_context=NULL; + AVFilter *src_filter; + src_filter = &avfilter_af_src; + src_context = avfilter_open(src_filter, "filter_src"); + avfilter_register(src_filter); - /*set up avfilter */ + /* set up actual filter */ + AVFilterContext * avfiltcont=NULL; + AVFilter *avfilt; avfilt = &avfilter_af_null; - - /* this should initialize the avfiltcont */ - printf("Opening avfilter\n"); - avfiltcont = avfilter_open(avfilt, "kevinfilter"); - printf("avfilter_open done\n"); - - - /* Register filters*/ + avfiltcont = avfilter_open(avfilt, "filterID1234"); avfilter_register(avfilt); - /* initialize the filters */ - printf("Starting filter chain\n"); + /*init filters */ avfilter_init_filter(avfiltcont, NULL, NULL); + avfilter_init_filter(src_context, NULL, NULL); - printf("Alright, we got %i inputs and %i outputs\n", - avfiltcont->input_count, - avfiltcont->output_count); + /* link filters */ + avfilter_link(src_context, 0, avfiltcont, 0); + avfilter_config_links(src_context); + avfilter_config_links(avfiltcont); - /* run the filter */ - printf("Running filter chain\n"); - /* FIXME: trying to run segfaults :(. didnt set up linking right, i think*/ - avfilter_start_buffer(avfiltcont->inputs, &sample_buf); - //avfilter_start_buffer(AVFilterLink *link, AVFilterPicRef *picref); + /* load some samples in the source filter */ + av_asrc_buffer_add_samples(src_context, &sample_buf); + + /* run this link */ + avfilter_filter_buffer(src_context->outputs[0], &sample_buf); - /* uninit things */ } _______________________________________________ FFmpeg-soc mailing list FFmpeg-soc@mplayerhq.hu https://lists.mplayerhq.hu/mailman/listinfo/ffmpeg-soc