+ int ret = ov_open_callbacks(datasource, vf,
+ NULL, /* no initial buffer */
+ 0, /* no initial bytes */
+ c); /* the ov_open_callbacks */
+
+ /* FIXME: provide better error codes */
+ if (ret == OV_EREAD)
+ return -E_OGG_READ;
+ if (ret == OV_ENOTVORBIS)
+ return -E_OGG_READ;
+ if (ret == OV_EVERSION)
+ return -E_OGG_READ;
+ if (ret == OV_EBADHEADER)
+ return -E_OGG_READ;
+ if (ret < 0)
+ return -E_OGG_READ;
+ return 1;
+
+}
+
+static int ogg_save_header(FILE *file, struct audio_format_info *afi)
+{
+ int ret;
+
+ afi->header = para_malloc(afi->header_len);
+ rewind(file);
+ ret = read(fileno(file), afi->header, afi->header_len);
+ if (ret == afi->header_len)
+ return 1;
+ free(afi->header);
+ return -E_OGG_READ;
+}
+
+static int ogg_compute_header_len(FILE *file, struct audio_format_info *afi)
+{
+ int ret, len, in = fileno(file);