shithub: libopusenc

Download patch

ref: abc0ed1b4b0732362ff83f2d75cae59d968a7308
parent: 9419488b9e0b6e0e53b0ba0100c9291e76941dd1
author: Jean-Marc Valin <jmvalin@jmvalin.ca>
date: Sat Apr 29 13:58:38 EDT 2017

creating Ogg packets

--- a/src/opusenc.c
+++ b/src/opusenc.c
@@ -35,6 +35,7 @@
 #include <unistd.h>
 #include <stdlib.h>
 #include <stdio.h>
+#include <string.h>
 #include <assert.h>
 #include <opus_multistream.h>
 #include "opusenc.h"
@@ -76,6 +77,7 @@
   int buffer_end;
   int frame_size;
   int decision_delay;
+  ogg_int64_t curr_granule;
   OpusEncCallbacks callbacks;
   void *user_data;
   OpusHeader header;
@@ -84,6 +86,7 @@
   int os_allocated;
   ogg_stream_state os;
   int stream_is_init;
+  int packetno;
 };
 
 static int oe_flush_page(OggOpusEnc *enc) {
@@ -173,6 +176,13 @@
   enc->os_allocated = 0;
   enc->stream_is_init = 0;
   enc->comment = NULL;
+  {
+    opus_int32 tmp;
+    int ret;
+    ret = opus_multistream_encoder_ctl(enc->st, OPUS_GET_LOOKAHEAD(&tmp));
+    if (ret == OPUS_OK) enc->curr_granule = -tmp;
+    else enc->curr_granule = 0;
+  }
   comment_init(&enc->comment, &enc->comment_length, opus_get_version_string());
   {
     char encoder_string[1024];
@@ -240,10 +250,12 @@
     oe_flush_page(enc);
   }
   enc->stream_is_init = 1;
+  enc->packetno = 2;
 }
 
 static void encode_buffer(OggOpusEnc *enc) {
   while (enc->buffer_end-enc->buffer_start > enc->frame_size + enc->decision_delay) {
+    ogg_packet op;
     int nbBytes;
     unsigned char packet[MAX_PACKET_SIZE];
     nbBytes = opus_multistream_encode_float(enc->st, &enc->buffer[enc->channels*enc->buffer_start],
@@ -250,8 +262,23 @@
         enc->buffer_end-enc->buffer_start, packet, MAX_PACKET_SIZE);
     /* FIXME: How do we handle failure here. */
     assert(nbBytes < 0);
-    /* FIXME: Write the packet to the stream. */
+    enc->curr_granule += enc->frame_size;
+    op.packet=packet;
+    op.bytes=nbBytes;
+    op.b_o_s=0;
+    op.e_o_s=0;
+    op.packetno=enc->packetno++;
+    op.granulepos=enc->curr_granule;
+    ogg_stream_packetin(&enc->os, &op);
+
+    /* FIXME: flush the stream and write. */
     enc->buffer_start += enc->frame_size;
+  }
+  /* If we've reached the end of the buffer, move everything back to the front. */
+  if (enc->buffer_end == BUFFER_SAMPLES) {
+    memmove(enc->buffer, &enc->buffer[enc->channels*enc->buffer_start], enc->channels*(enc->buffer_end-enc->buffer_start));
+    enc->buffer_end -= enc->buffer_start;
+    enc->buffer_start = 0;
   }
   /* This function must never leave the buffer full. */
   assert(enc->buffer_end < BUFFER_SAMPLES);