[FFmpeg-soc] [soc]: r4567 - in afilters: af_null.c avfilter.c avfilter.h dummy.c

kdub subversion at mplayerhq.hu
Thu Jul 2 14:29:38 CEST 2009


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 <kdub432 at 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 */
 
 }
 


More information about the FFmpeg-soc mailing list