Index: libmpc/trunk/libmpcdec/internal.h
===================================================================
--- libmpc/trunk/libmpcdec/internal.h	(revision 383)
+++ libmpc/trunk/libmpcdec/internal.h	(revision 384)
@@ -66,4 +66,10 @@
 #define DEMUX_BUFFER_SIZE (65536 - MAX_FRAME_SIZE) // need some space as sand box
 
+typedef struct {
+	mpc_uint64_t sample;
+	mpc_uint_t tag_size;
+	char * tag;
+} mpc_chap_t;
+
 struct mpc_demux_t {
 	mpc_reader * r;
@@ -82,4 +88,10 @@
 	mpc_uint_t seek_pwr; /// distance between 2 frames in seek_table = 2^seek_pwr
 	mpc_uint32_t seek_table_size; /// used size in seek_table
+
+	// chapters
+	mpc_seek_t chap_pos; /// supposed position of the first chapter block
+	mpc_int_t chap_nb; /// number of chapters (-1 if unknown, 0 if no chapter)
+	mpc_chap_t * chap; /// chapters position and tag
+	
 };
 
Index: libmpc/trunk/libmpcdec/mpc_demux.c
===================================================================
--- libmpc/trunk/libmpcdec/mpc_demux.c	(revision 383)
+++ libmpc/trunk/libmpcdec/mpc_demux.c	(revision 384)
@@ -258,10 +258,13 @@
 	mpc_uint64_t ptr;
 	mpc_block b;
+	int st_head_size;
 
 	cur = mpc_demux_pos(d);
 	mpc_bits_get_size(&d->bits_reader, &ptr);
 	mpc_demux_seek(d, (ptr - size) * 8 + cur, 11);
-	mpc_bits_get_block(&d->bits_reader, &b);
+	st_head_size = mpc_bits_get_block(&d->bits_reader, &b);
 	if (memcmp(b.key, "ST", 2) == 0) {
+		d->chap_pos = (ptr - size + b.size + st_head_size) * 8 + cur;
+		d->chap_nb = -1;
 		mpc_demux_fill(d, (mpc_uint32_t) b.size, 0);
 		mpc_demux_ST(d);
@@ -270,4 +273,65 @@
 }
 
+static void mpc_demux_chap_find(mpc_demux * d)
+{
+	if (d->chap_pos == 0) {
+		// FIXME : find chapters from end of file
+	}
+	mpc_block b;
+	int tag_size = 0, chap_size = 0, size, i = 0;
+	d->chap_nb = 0;
+	mpc_demux_seek(d, d->chap_pos, 20);
+	size = mpc_bits_get_block(&d->bits_reader, &b);
+	while (memcmp(b.key, "CT", 2) == 0) {
+		mpc_uint64_t chap_sample;
+		d->chap_nb++;
+		chap_size += size;
+		size = mpc_bits_get_size(&d->bits_reader, &chap_sample);
+		chap_size += size;
+		tag_size += b.size - size;
+		mpc_demux_seek(d, d->chap_pos + (chap_size + tag_size) * 8, 20);
+		size = mpc_bits_get_block(&d->bits_reader, &b);
+	}
+
+	d->chap = malloc(sizeof(mpc_chap_t) * d->chap_nb + tag_size);
+	char * ptag = (char*)(d->chap + d->chap_nb);
+
+	mpc_demux_seek(d, d->chap_pos, 11);
+	size = mpc_bits_get_block(&d->bits_reader, &b);
+	while (memcmp(b.key, "CT", 2) == 0) {
+		mpc_demux_fill(d, 11 + (mpc_uint32_t) b.size, 0);
+		size = mpc_bits_get_size(&d->bits_reader, &d->chap[i].sample);
+		memcpy(ptag, d->bits_reader.buff + ((8 - d->bits_reader.count) >> 3), b.size - size);
+		d->bits_reader.buff += b.size - size;
+		d->chap[i].tag_size = b.size - size;
+		d->chap[i].tag = ptag;
+		ptag += b.size - size;
+		i++;
+		size = mpc_bits_get_block(&d->bits_reader, &b);
+	}
+	
+	d->bits_reader.buff -= size;
+}
+
+mpc_int_t mpc_demux_chap_nb(mpc_demux * d)
+{
+	if (d->chap_nb == -1)
+		mpc_demux_chap_find(d);
+	return d->chap_nb;
+}
+
+mpc_uint64_t mpc_demux_chap(mpc_demux * d, int chap_nb, char ** tag, mpc_uint_t * tag_size)
+{
+	if (d->chap_nb == -1)
+		mpc_demux_chap_find(d);
+	if (chap_nb >= d->chap_nb)
+		return 0;
+	if (tag != 0 && tag_size != 0) {
+		*tag = d->chap[chap_nb].tag;
+		*tag_size = d->chap[chap_nb].tag_size;
+	}
+	return d->chap[chap_nb].sample;
+}
+		
 static mpc_status mpc_demux_header(mpc_demux * d)
 {
@@ -339,4 +403,5 @@
 		memset(p_tmp, 0, sizeof(mpc_demux));
 		p_tmp->r = p_reader;
+		p_tmp->chap_nb = -1;
 		mpc_demux_clear_buff(p_tmp);
 		if (mpc_demux_header(p_tmp) == MPC_STATUS_OK &&
@@ -358,4 +423,5 @@
 	mpc_decoder_exit(d->d);
 	free(d->seek_table);
+	free(d->chap);
 	free(d);
 }
