shithub: libopusenc

Download patch

ref: d8cae227349529c25ce64376fdaa050b5f64ef43
parent: b84512ec76f92590264ae39b11d9369b297a4261
author: Jean-Marc Valin <jmvalin@jmvalin.ca>
date: Wed May 3 21:59:16 EDT 2017

Add packet and page callbacks

--- a/include/opusenc.h
+++ b/include/opusenc.h
@@ -61,14 +61,18 @@
 
 
 /* These are the "raw" request values -- they should usually not be used. */
-#define OPE_SET_DECISION_DELAY_REQUEST 14000
-#define OPE_GET_DECISION_DELAY_REQUEST 14001
-#define OPE_SET_MUXING_DELAY_REQUEST 14002
-#define OPE_GET_MUXING_DELAY_REQUEST 14003
-#define OPE_SET_COMMENT_PADDING_REQUEST 14004
-#define OPE_GET_COMMENT_PADDING_REQUEST 14005
-#define OPE_SET_SERIALNO_REQUEST 14006
-#define OPE_GET_SERIALNO_REQUEST 14007
+#define OPE_SET_DECISION_DELAY_REQUEST      14000
+#define OPE_GET_DECISION_DELAY_REQUEST      14001
+#define OPE_SET_MUXING_DELAY_REQUEST        14002
+#define OPE_GET_MUXING_DELAY_REQUEST        14003
+#define OPE_SET_COMMENT_PADDING_REQUEST     14004
+#define OPE_GET_COMMENT_PADDING_REQUEST     14005
+#define OPE_SET_SERIALNO_REQUEST            14006
+#define OPE_GET_SERIALNO_REQUEST            14007
+#define OPE_SET_PACKET_CALLBACK_REQUEST     14008
+#define OPE_GET_PACKET_CALLBACK_REQUEST     14009
+#define OPE_SET_PAGE_CALLBACK_REQUEST       14010
+#define OPE_GET_PAGE_CALLBACK_REQUEST       14011
 
 #define OPE_SET_DECISION_DELAY(x) OPE_SET_DECISION_DELAY_REQUEST, __opus_check_int(x)
 #define OPE_GET_DECISION_DELAY(x) OPE_GET_DECISION_DELAY_REQUEST, __opus_check_int_ptr(x)
@@ -78,12 +82,20 @@
 #define OPE_GET_COMMENT_PADDING(x) OPE_GET_COMMENT_PADDING_REQUEST, __opus_check_int_ptr(x)
 #define OPE_SET_SERIALNO(x) OPE_SET_SERIALNO_REQUEST, __opus_check_int(x)
 #define OPE_GET_SERIALNO(x) OPE_GET_SERIALNO_REQUEST, __opus_check_int_ptr(x)
+/* FIXME: Add type-checking macros to these. */
+#define OPE_SET_PACKET_CALLBACK(x) OPE_SET_PACKET_CALLBACK_REQUEST, (x)
+#define OPE_GET_PACKET_CALLBACK(x) OPE_GET_PACKET_CALLBACK_REQUEST, (x)
+#define OPE_SET_PAGE_CALLBACK(x) OPE_SET_PAGE_CALLBACK_REQUEST, (x)
+#define OPE_GET_PAGE_CALLBACK(x) OPE_GET_PAGE_CALLBACK_REQUEST, (x)
 
-
 typedef int (*ope_write_func)(void *user_data, const unsigned char *ptr, int len);
 
 typedef int (*ope_close_func)(void *user_data);
 
+typedef int (*ope_packet_func)(void *user_data, const unsigned char *packet_ptr, int packet_len, opus_uint32 flags);
+
+typedef int (*ope_page_func)(void *user_data, int page_len, opus_uint32 flags);
+
 /** Callback functions for accessing the stream. */
 typedef struct {
   /** Callback for writing to the stream. */
@@ -134,9 +146,6 @@
 
 /** Goes straight to the libopus ctl() functions. */
 OPE_EXPORT int ope_encoder_ctl(OggOpusEnc *enc, int request, ...);
-
-/** ctl()-type call for the OggOpus layer. */
-OPE_EXPORT int ope_set_params(OggOpusEnc *enc, int request, ...);
 
 # if defined(__cplusplus)
 }
--- a/src/opusenc.c
+++ b/src/opusenc.c
@@ -60,16 +60,6 @@
 
 #define MAX_PACKET_SIZE (1276*8)
 
-static int oe_write_page(ogg_page *page, OpusEncCallbacks *cb, void *user_data)
-{
-   int err;
-   err = cb->write(user_data, page->header, page->header_len);
-   if (err) return -1;
-   err = cb->write(user_data, page->body, page->body_len);
-   if (err) return -1;
-   return page->header_len+page->body_len;
-}
-
 struct StdioObject {
   FILE *file;
 };
@@ -111,6 +101,8 @@
   unsigned char *chaining_keyframe;
   int chaining_keyframe_length;
   OpusEncCallbacks callbacks;
+  ope_packet_func packet_callback;
+  ope_page_func page_callback;
   OpusHeader header;
   int comment_padding;
   EncStream *streams;
@@ -117,6 +109,19 @@
   EncStream *last_stream;
 };
 
+static int oe_write_page(OggOpusEnc *enc, ogg_page *page, void *user_data)
+{
+  int length;
+  int err;
+  err = enc->callbacks.write(user_data, page->header, page->header_len);
+  if (err) return -1;
+  err = enc->callbacks.write(user_data, page->body, page->body_len);
+  if (err) return -1;
+  length = page->header_len+page->body_len;
+  if (enc->page_callback) enc->page_callback(user_data, length, 0);
+  return length;
+}
+
 static int oe_flush_page(OggOpusEnc *enc) {
   ogg_page og;
   int ret;
@@ -123,7 +128,7 @@
   int written = 0;
   while ( (ret = ogg_stream_flush(&enc->streams->os, &og)) ) {
     if (!ret) break;
-    ret = oe_write_page(&og, &enc->callbacks, enc->streams->user_data);
+    ret = oe_write_page(enc, &og, enc->streams->user_data);
     if (ret == -1) {
       return -1;
     }
@@ -225,6 +230,8 @@
   if ( (enc->streams = stream_create()) == NULL) goto fail;
   enc->streams->next = NULL;
   enc->last_stream = enc->streams;
+  enc->packet_callback = NULL;
+  enc->page_callback = NULL;
   enc->rate = rate;
   enc->channels = channels;
   enc->frame_size = 960;
@@ -366,12 +373,13 @@
       cont = 0;
       if (op.e_o_s) op.granulepos=end_granule48k-enc->streams->granule_offset;
       ogg_stream_packetin(&enc->streams->os, &op);
+      if (enc->packet_callback) enc->packet_callback(enc->streams->user_data, op.packet, op.bytes, 0);
       /* FIXME: Also flush on too many segments. */
       flush_needed = op.e_o_s || enc->curr_granule - enc->last_page_granule > enc->max_ogg_delay;
       if (flush_needed) {
         while (ogg_stream_flush_fill(&enc->streams->os, &og, 255*255)) {
           if (ogg_page_packets(&og) != 0) enc->last_page_granule = ogg_page_granulepos(&og) + enc->streams->granule_offset;
-          int ret = oe_write_page(&og, &enc->callbacks, enc->streams->user_data);
+          int ret = oe_write_page(enc, &og, enc->streams->user_data);
           /* FIXME: what do we do if this fails? */
           assert(ret != -1);
         }
@@ -378,7 +386,7 @@
       } else {
         while (ogg_stream_pageout_fill(&enc->streams->os, &og, 255*255)) {
           if (ogg_page_packets(&og) != 0) enc->last_page_granule = ogg_page_granulepos(&og) + enc->streams->granule_offset;
-          int ret = oe_write_page(&og, &enc->callbacks, enc->streams->user_data);
+          int ret = oe_write_page(enc, &og, enc->streams->user_data);
           /* FIXME: what do we do if this fails? */
           assert(ret != -1);
         }
@@ -408,6 +416,7 @@
           op2.packetno=enc->streams->packetno++;
           op2.granulepos=enc->curr_granule - enc->streams->granule_offset - enc->frame_size;
           ogg_stream_packetin(&enc->streams->os, &op2);
+          if (enc->packet_callback) enc->packet_callback(enc->streams->user_data, op2.packet, op2.bytes, 0);
         }
         end_granule48k = (enc->streams->end_granule*48000 + enc->rate - 1)/enc->rate + enc->global_granule_offset;
         cont = 1;
@@ -700,6 +709,19 @@
       if (enc->last_stream->header_is_frozen) return OPE_TOO_LATE;
       enc->last_stream->serialno = value;
       enc->last_stream->serialno_is_set = 1;
+      ret = OPE_OK;
+    }
+    case OPE_SET_PACKET_CALLBACK_REQUEST:
+    {
+      ope_packet_func value = va_arg(ap, ope_packet_func);
+      enc->packet_callback = value;
+      ret = OPE_OK;
+    }
+    break;
+    case OPE_SET_PAGE_CALLBACK_REQUEST:
+    {
+      ope_page_func value = va_arg(ap, ope_page_func);
+      enc->page_callback = value;
       ret = OPE_OK;
     }
     break;