ref: 14bcd76f79da9a225528a5fb9fe781c57a9ca1ad
parent: b718267504c90df4854218b4ffe2d38a4e552da7
author: Jean-Marc Valin <jmvalin@jmvalin.ca>
date: Fri May 5 13:35:14 EDT 2017
Implement pull API
--- a/include/opusenc.h
+++ b/include/opusenc.h
@@ -108,11 +108,17 @@
OPE_EXPORT OggOpusEnc *ope_create_callbacks(const OpusEncCallbacks *callbacks, void *user_data,
int rate, int channels, int family, int *error);
+/** Create a new OggOpus stream, pulling one page at a time. */
+OPE_EXPORT OggOpusEnc *ope_create_pull(int rate, int channels, int family, int *error);
+
/** Add/encode any number of float samples to the file. */
OPE_EXPORT int ope_write_float(OggOpusEnc *enc, const float *pcm, int samples_per_channel);
/** Add/encode any number of int16 samples to the file. */
OPE_EXPORT int ope_write(OggOpusEnc *enc, const opus_int16 *pcm, int samples_per_channel);
+
+/** Get the next page from the stream. Returns 1 if there is a page available, 0 if not. */
+OPE_EXPORT int ope_get_page(OggOpusEnc *enc, unsigned char **page, int *len, int flush);
/** Finalizes the stream, but does not deallocate the object. */
OPE_EXPORT int ope_drain(OggOpusEnc *enc);
--- a/src/opusenc.c
+++ b/src/opusenc.c
@@ -93,6 +93,7 @@
#ifdef USE_OGGP
oggpacker *oggp;
#endif
+ int pull_api;
int rate;
int channels;
float *buffer;
@@ -126,7 +127,7 @@
}
static void oe_flush_page(OggOpusEnc *enc) {
oggp_flush_page(enc->oggp);
- output_pages(enc);
+ if (!enc->pull_api) output_pages(enc);
}
#else
@@ -255,6 +256,7 @@
#ifdef USE_OGGP
enc->oggp = NULL;
#endif
+ enc->pull_api = 0;
enc->packet_callback = NULL;
enc->rate = rate;
enc->channels = channels;
@@ -313,6 +315,13 @@
return NULL;
}
+/* Create a new OggOpus stream, pulling one page at a time. */
+OPE_EXPORT OggOpusEnc *ope_create_pull(int rate, int channels, int family, int *error) {
+ OggOpusEnc *enc = ope_create_callbacks(NULL, NULL, rate, channels, family, error);
+ enc->pull_api = 1;
+ return enc;
+}
+
static void init_stream(OggOpusEnc *enc) {
assert(!enc->streams->stream_is_init);
if (!enc->streams->serialno_is_set) {
@@ -436,7 +445,7 @@
#ifdef USE_OGGP
flush_needed = op.e_o_s;
if (flush_needed) oe_flush_page(enc);
- else output_pages(enc);
+ else if (!enc->pull_api) output_pages(enc);
#else
flush_needed = op.e_o_s || enc->curr_granule - enc->last_page_granule >= enc->max_ogg_delay;
if (flush_needed) {
@@ -577,6 +586,15 @@
return OPE_OK;
}
+/* Get the next page from the stream. Returns 1 if there is a page available, 0 if not. */
+OPE_EXPORT int ope_get_page(OggOpusEnc *enc, unsigned char **page, int *len, int flush) {
+ if (!enc->pull_api) return 0;
+ else {
+ if (flush) oggp_flush_page(enc->oggp);
+ return oggp_get_next_page(enc->oggp, page, len);
+ }
+}
+
int ope_drain(OggOpusEnc *enc) {
/* FIXME: Use a better value. */
int pad_samples = 3000;
@@ -592,7 +610,6 @@
return OPE_OK;
}
-/* Close/finalize the stream. */
void ope_destroy(OggOpusEnc *enc) {
/* FIXME: cleanup non-closed streams if any remain. */
if (enc->chaining_keyframe) free(enc->chaining_keyframe);