shithub: libopusenc

Download patch

ref: af46badf173d49ea8e3df8be62e65db6254f8de2
parent: 25bc5312b786284d279c03c2fe601123f7100323
author: Jean-Marc Valin <jmvalin@jmvalin.ca>
date: Thu May 4 14:50:33 EDT 2017

more packer code

--- a/src/ogg_packer.c
+++ b/src/ogg_packer.c
@@ -25,6 +25,7 @@
 */
 
 #include <stdlib.h>
+#include <string.h>
 #include "ogg_packer.h"
 
 #define MAX_HEADER_SIZE (27+255)
@@ -46,13 +47,17 @@
   unsigned char *alloc_buf;
   int buf_size;
   int buf_fill;
+  int buf_begin;
   unsigned char *lacing;
   int lacing_size;
   int lacing_fill;
+  int lacing_begin;
   oggp_page *pages;
   int pages_size;
   int pages_fill;
   int muxing_delay;
+  int is_eos;
+  oggp_uint64 curr_granule;
 };
 
 /** Allocates an oggpacker object */
@@ -76,8 +81,13 @@
 
   oggp->serialno = serialno;
   oggp->buf_fill = 0;
+  oggp->buf_begin = 0;
   oggp->lacing_fill = 0;
+  oggp->lacing_begin = 0;
   oggp->pages_fill = 0;
+
+  oggp->is_eos = 0;
+  oggp->curr_granule = 0;
 fail:
   if (oggp) {
     if (oggp->lacing) free(oggp->lacing);
@@ -106,23 +116,80 @@
     size "bytes", but fewer bytes can be written. The buffer remains valid through
     a call to oggp_close_page() or oggp_get_next_page(), but is invalidated by
     another call to oggp_get_packet_buffer() or by a call to oggp_commit_packet(). */
-unsigned char *oggp_get_packet_buffer(oggpacker *oggp, int bytes);
+unsigned char *oggp_get_packet_buffer(oggpacker *oggp, int bytes) {
+  if (oggp->buf_fill + bytes > oggp->buf_size) {
+    /* FIXME: make room somehow. */
+  }
+  return &oggp->buf[oggp->buf_fill];
+}
 
 /** Tells the oggpacker that the packet buffer obtained from
     oggp_get_packet_buffer() has been filled and the number of bytes written
     has to be no more than what was originally asked for. */
-int oggp_commit_packet(oggpacker *oggp, int bytes, oggp_uint64 granulepos, int eos);
+int oggp_commit_packet(oggpacker *oggp, int bytes, oggp_uint64 granulepos, int eos) {
+  int i;
+  int nb_255s;
+  oggp->buf_fill += bytes;
+  nb_255s = bytes/255;
+  /* FIXME: Check if we should flush before the packet. */
+  /* FIXME: Check lacing size */
+  for (i=0;i<nb_255s;i++) {
+    oggp->lacing[oggp->lacing_fill+i] = 255;
+  }
+  oggp->lacing[oggp->lacing_fill+nb_255s] = bytes - 255*nb_255s;
+  oggp->curr_granule = granulepos;
+  oggp->is_eos = eos;
+  /* FIXME: Check if we should flush after the packet. */
+  return 0;
+}
 
 /** Create a page from the data written so far (and not yet part of a previous page).
     If there is too much data for one page, then either:
     1) all page continuations will be closed too (close_cont=1)
     2) all but the last page continuations will be closed (close_cont=0)*/
-int oggp_flush_page(oggpacker *oggp, int close_cont);
+int oggp_flush_page(oggpacker *oggp, int close_cont) {
+  oggp_page *p;
+  /* FIXME: Check we have a free page. */
+  /* FIXME: Check there is at least one packet. */
+  p = &oggp->pages[oggp->pages_fill++];
+  p->granulepos = oggp->curr_granule;
 
+  p->buf_pos = oggp->buf_begin;
+  p->buf_size = oggp->buf_fill - oggp->buf_begin;
+  p->lacing_pos = oggp->lacing_begin;
+  p->lacing_size = oggp->lacing_fill - oggp->lacing_begin;
+  /* FIXME: Handle bos/eos and continued pages. */
+  p->flags = 0;
+  (void)close_cont;
+  return 0;
+}
+
 /** Get a pointer to the contents of the next available page. Pointer is
     invalidated on the next call to oggp_get_next_page(). */
-int oggp_get_next_page(oggpacker *oggp, unsigned char **page, int *bytes);
+int oggp_get_next_page(oggpacker *oggp, unsigned char **page, int *bytes) {
+  oggp_page *p;
+  unsigned char *ptr;
+  int header_size;
+  p = &oggp->pages[0];
+  header_size = 27 + p->lacing_size;
+  ptr = &oggp->buf[p->buf_pos - header_size];
+  memcpy(&ptr[27], &oggp->lacing[p->lacing_pos], p->lacing_size);
+  memcpy(ptr, "OggS", 4);
+  /* FIXME: Write the other fields. */
 
+  *page = ptr;
+  *bytes = p->buf_size + header_size;
+  oggp->pages_fill--;
+  memmove(&oggp->pages[0], &oggp->pages[1], oggp->pages_fill);
+  return 0;
+}
+
 /** Creates a new (chained) stream. This closes all outstanding pages. These
     pages remain available with oggp_get_next_page(). */
-int oggp_chain(oggpacker *oggp, int serialno);
+int oggp_chain(oggpacker *oggp, int serialno) {
+  oggp_flush_page(oggp, 1);
+  oggp->serialno = serialno;
+  oggp->curr_granule = 0;
+  oggp->is_eos = 0;
+  return 0;
+}