diff --git a/src/format.h b/src/format.h index 6e7d596d..24f81158 100644 --- a/src/format.h +++ b/src/format.h @@ -23,6 +23,7 @@ typedef struct _format_plugin_tag refbuf_t *(*get_buffer)(struct _format_plugin_tag *self, char *data, unsigned long len); refbuf_queue_t *(*get_predata)(struct _format_plugin_tag *self); + void (*free_plugin)(struct _format_plugin_tag *self); /* for internal state management */ void *_state; diff --git a/src/format_vorbis.c b/src/format_vorbis.c index 2578ab6e..29006f56 100644 --- a/src/format_vorbis.c +++ b/src/format_vorbis.c @@ -24,6 +24,7 @@ typedef struct _vstate_tag refbuf_t *headbuf[10]; } vstate_t; +void format_vorbis_free_plugin(format_plugin_t *self); refbuf_t *format_vorbis_get_buffer(format_plugin_t *self, char *data, unsigned long len); refbuf_queue_t *format_vorbis_get_predata(format_plugin_t *self); @@ -33,10 +34,12 @@ format_plugin_t *format_vorbis_get_plugin(void) vstate_t *state; plugin = (format_plugin_t *)malloc(sizeof(format_plugin_t)); + plugin->type = FORMAT_TYPE_VORBIS; plugin->has_predata = 1; plugin->get_buffer = format_vorbis_get_buffer; plugin->get_predata = format_vorbis_get_predata; + plugin->free_plugin = format_vorbis_free_plugin; state = (vstate_t *)calloc(1, sizeof(vstate_t)); ogg_sync_init(&state->oy); @@ -46,6 +49,29 @@ format_plugin_t *format_vorbis_get_plugin(void) return plugin; } +void format_vorbis_free_plugin(format_plugin_t *self) +{ + int i; + vstate_t *state = (vstate_t *)self->_state; + + /* free memory associated with this plugin instance */ + + /* free state memory */ + ogg_sync_clear(&state->oy); + + for (i = 0; i < 10; i++) { + if (state->headbuf[i]) { + refbuf_release(state->headbuf[i]); + state->headbuf[i] = NULL; + } + } + + free(state); + + /* free the plugin instance */ + free(self); +} + refbuf_t *format_vorbis_get_buffer(format_plugin_t *self, char *data, unsigned long len) { char *buffer; diff --git a/src/source.c b/src/source.c index fe5e4013..9231e5fd 100644 --- a/src/source.c +++ b/src/source.c @@ -90,6 +90,7 @@ int source_free_source(void *key) httpp_destroy(source->parser); avl_tree_free(source->pending_tree, _free_client); avl_tree_free(source->client_tree, _free_client); + source->format->free_plugin(source->format); free(source); return 1;