+static
+void m4af_free_itmf_table(m4af_ctx_t *ctx)
+{
+ uint32_t i;
+ m4af_itmf_entry_t *entry = ctx->itmf_table;
+ for (i = 0; i < ctx->num_tags; ++i, ++entry) {
+ if (entry->fcc == M4AF_FOURCC('-','-','-','-'))
+ m4af_free(entry->name);
+ m4af_free(entry->data);
+ }
+ m4af_free(ctx->itmf_table);
+}
+
+static
+void m4af_clear_track(m4af_ctx_t *ctx, int track_idx)
+{
+ m4af_track_t *track = ctx->track + track_idx;
+ if (track->decSpecificInfo)
+ m4af_free(track->decSpecificInfo);
+ if (track->sample_table)
+ m4af_free(track->sample_table);
+ if (track->chunk_table)
+ m4af_free(track->chunk_table);
+ if (track->chunk_buffer)
+ m4af_free(track->chunk_buffer);
+ memset(track, 0, sizeof(m4af_track_t));
+}
+
+void m4af_teardown(m4af_ctx_t **ctxp)
+{
+ unsigned i;
+ m4af_ctx_t *ctx = *ctxp;
+ for (i = 0; i < ctx->num_tracks; ++i)
+ m4af_clear_track(ctx, i);
+ if (ctx->itmf_table)
+ m4af_free_itmf_table(ctx);
+ m4af_free(ctx);
+ *ctxp = 0;
+}
+
+void m4af_set_num_channels(m4af_ctx_t *ctx, uint32_t track_idx,
+ uint16_t channels)
+{
+ ctx->track[track_idx].num_channels = channels;
+}
+
+void m4af_set_fixed_frame_duration(m4af_ctx_t *ctx, uint32_t track_idx,