Handle the end of stream
[libopusenc.git] / src / opusenc.c
1 /* Copyright (C)2002-2017 Jean-Marc Valin
2    Copyright (C)2007-2013 Xiph.Org Foundation
3    Copyright (C)2008-2013 Gregory Maxwell
4    File: opusenc.c
5
6    Redistribution and use in source and binary forms, with or without
7    modification, are permitted provided that the following conditions
8    are met:
9
10    - Redistributions of source code must retain the above copyright
11    notice, this list of conditions and the following disclaimer.
12
13    - Redistributions in binary form must reproduce the above copyright
14    notice, this list of conditions and the following disclaimer in the
15    documentation and/or other materials provided with the distribution.
16
17    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
18    ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
19    LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
20    A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
21    OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
22    EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
23    PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
24    PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
25    LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
26    NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
27    SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 */
29
30 #ifdef HAVE_CONFIG_H
31 #include "config.h"
32 #endif
33
34 #include <time.h>
35 #include <unistd.h>
36 #include <stdlib.h>
37 #include <stdio.h>
38 #include <string.h>
39 #include <assert.h>
40 #include <opus_multistream.h>
41 #include "opusenc.h"
42 #include "opus_header.h"
43
44 #define LPC_PADDING 120
45
46 /* Allow up to 2 seconds for delayed decision. */
47 #define MAX_LOOKAHEAD 96000
48 /* We can't have a circular buffer (because of delayed decision), so let's not copy too often. */
49 #define BUFFER_EXTRA 24000
50
51 #define BUFFER_SAMPLES (MAX_LOOKAHEAD + BUFFER_EXTRA)
52
53 #define MIN(a,b) ((a) < (b) ? (a) : (b))
54 #define MAX(a,b) ((a) > (b) ? (a) : (b))
55
56 #define MAX_PACKET_SIZE (1276*8)
57
58 static int oe_write_page(ogg_page *page, OpusEncCallbacks *cb, void *user_data)
59 {
60    int err;
61    err = cb->write(user_data, page->header, page->header_len);
62    if (err) return -1;
63    err = cb->write(user_data, page->body, page->body_len);
64    if (err) return -1;
65    return page->header_len+page->body_len;
66 }
67
68 struct StdioObject {
69   FILE *file;
70 };
71
72 struct OggOpusEnc {
73   OpusMSEncoder *st;
74   int channels;
75   float *buffer;
76   int buffer_start;
77   int buffer_end;
78   int frame_size;
79   int decision_delay;
80   ogg_int64_t curr_granule;
81   ogg_int64_t end_granule;
82   OpusEncCallbacks callbacks;
83   void *user_data;
84   OpusHeader header;
85   char *comment;
86   int comment_length;
87   int os_allocated;
88   ogg_stream_state os;
89   int stream_is_init;
90   int packetno;
91 };
92
93 static int oe_flush_page(OggOpusEnc *enc) {
94   ogg_page og;
95   int ret;
96   int written = 0;
97   while ( (ret = ogg_stream_flush(&enc->os, &og)) ) {
98     if (!ret) break;
99     ret = oe_write_page(&og, &enc->callbacks, enc->user_data);
100     if (ret == -1) {
101       return -1;
102     }
103     written += ret;
104   }
105   return written;
106 }
107
108 int stdio_write(void *user_data, const unsigned char *ptr, int len) {
109   struct StdioObject *obj = (struct StdioObject*)user_data;
110   return fwrite(ptr, 1, len, obj->file) != (size_t)len;
111 }
112
113 int stdio_close(void *user_data) {
114   struct StdioObject *obj = (struct StdioObject*)user_data;
115   int ret = fclose(obj->file);
116   free(obj);
117   return ret;
118 }
119
120 static const OpusEncCallbacks stdio_callbacks = {
121   stdio_write,
122   stdio_close
123 };
124
125 /* Create a new OggOpus file. */
126 OggOpusEnc *ope_create_file(const char *path, int rate, int channels, int family, int *error) {
127   OggOpusEnc *enc;
128   struct StdioObject *obj;
129   obj = malloc(sizeof(*obj));
130   enc = ope_create_callbacks(&stdio_callbacks, obj, rate, channels, family, error);
131   if (enc == NULL || (error && *error)) {
132     return NULL;
133   }
134   obj->file = fopen(path, "wb");
135   if (!obj->file) {
136     if (error) *error = OPE_CANNOT_OPEN;
137     /* FIXME: Destroy the encoder properly. */
138     free(obj);
139     return NULL;
140   }
141   return enc;
142 }
143
144 /* Create a new OggOpus file (callback-based). */
145 OggOpusEnc *ope_create_callbacks(const OpusEncCallbacks *callbacks, void *user_data,
146     int rate, int channels, int family, int *error) {
147   OpusMSEncoder *st=NULL;
148   OggOpusEnc *enc=NULL;
149   int ret;
150   if (family != 0 && family != 1 && family != 255) {
151     if (error) *error = OPE_UNIMPLEMENTED;
152     return NULL;
153   }
154   if (channels <= 0 || channels > 255) {
155     if (error) *error = OPE_BAD_ARG;
156     return NULL;
157   }
158   /* FIXME: Add resampling support. */
159   if (rate != 48000) {
160     if (error) *error = OPE_UNIMPLEMENTED;
161     return NULL;
162   }
163   if ( (enc = malloc(sizeof(*enc))) == NULL) goto fail;
164   enc->channels = channels;
165   enc->frame_size = 960;
166   enc->decision_delay = 96000;
167   enc->header.channels=channels;
168   enc->header.channel_mapping=family;
169   enc->header.input_sample_rate=rate;
170   enc->header.gain=0;
171   st=opus_multistream_surround_encoder_create(48000, channels, enc->header.channel_mapping,
172       &enc->header.nb_streams, &enc->header.nb_coupled,
173       enc->header.stream_map, OPUS_APPLICATION_AUDIO, &ret);
174   if (! (ret == OPUS_OK && st != NULL) ) {
175     goto fail;
176   }
177   opus_multistream_encoder_ctl(st, OPUS_SET_EXPERT_FRAME_DURATION(OPUS_FRAMESIZE_20_MS));
178   enc->os_allocated = 0;
179   enc->stream_is_init = 0;
180   enc->comment = NULL;
181   {
182     opus_int32 tmp;
183     int ret;
184     ret = opus_multistream_encoder_ctl(st, OPUS_GET_LOOKAHEAD(&tmp));
185     if (ret == OPUS_OK) enc->curr_granule = -tmp;
186     else enc->curr_granule = 0;
187   }
188   enc->end_granule = 0;
189   comment_init(&enc->comment, &enc->comment_length, opus_get_version_string());
190   {
191     char encoder_string[1024];
192     snprintf(encoder_string, sizeof(encoder_string), "%s version %s", PACKAGE_NAME, PACKAGE_VERSION);
193     comment_add(&enc->comment, &enc->comment_length, "ENCODER", encoder_string);
194   }
195   if (enc->comment == NULL) goto fail;
196   if ( (enc->buffer = malloc(sizeof(*enc->buffer)*BUFFER_SAMPLES*channels)) == NULL) goto fail;
197   enc->buffer_start = enc->buffer_end = 0;
198   enc->st = st;
199   enc->callbacks = *callbacks;
200   enc->user_data = user_data;
201   if (error) *error = OPUS_OK;
202   return enc;
203 fail:
204   if (enc) {
205     free(enc);
206     if (enc->buffer) free(enc->buffer);
207   }
208   if (st) {
209     opus_multistream_encoder_destroy(st);
210   }
211   return NULL;
212 }
213
214 static void init_stream(OggOpusEnc *enc) {
215   time_t start_time;
216   int serialno;
217   assert(!enc->stream_is_init);
218   start_time = time(NULL);
219   srand(((getpid()&65535)<<15)^start_time);
220
221   serialno = rand();
222   if (ogg_stream_init(&enc->os, serialno) == -1) {
223     assert(0);
224     /* FIXME: How the hell do we handle that? */
225   }
226   /* FIXME: Compute preskip. */
227   enc->header.preskip = 0;
228   comment_pad(&enc->comment, &enc->comment_length, 512);
229
230   /*Write header*/
231   {
232     ogg_packet op;
233     /*The Identification Header is 19 bytes, plus a Channel Mapping Table for
234       mapping families other than 0. The Channel Mapping Table is 2 bytes +
235       1 byte per channel. Because the maximum number of channels is 255, the
236       maximum size of this header is 19 + 2 + 255 = 276 bytes.*/
237     unsigned char header_data[276];
238     int packet_size = opus_header_to_packet(&enc->header, header_data, sizeof(header_data));
239     op.packet=header_data;
240     op.bytes=packet_size;
241     op.b_o_s=1;
242     op.e_o_s=0;
243     op.granulepos=0;
244     op.packetno=0;
245     ogg_stream_packetin(&enc->os, &op);
246     oe_flush_page(enc);
247
248     op.packet = (unsigned char *)enc->comment;
249     op.bytes = enc->comment_length;
250     op.b_o_s = 0;
251     op.e_o_s = 0;
252     op.granulepos = 0;
253     op.packetno = 1;
254     ogg_stream_packetin(&enc->os, &op);
255     oe_flush_page(enc);
256   }
257   enc->stream_is_init = 1;
258   enc->packetno = 2;
259 }
260
261 static void shift_buffer(OggOpusEnc *enc) {
262     memmove(enc->buffer, &enc->buffer[enc->channels*enc->buffer_start], enc->channels*(enc->buffer_end-enc->buffer_start)*sizeof(*enc->buffer));
263     enc->buffer_end -= enc->buffer_start;
264     enc->buffer_start = 0;
265 }
266
267 static void encode_buffer(OggOpusEnc *enc) {
268   while (enc->buffer_end-enc->buffer_start > enc->frame_size + enc->decision_delay) {
269     ogg_packet op;
270     ogg_page og;
271     int nbBytes;
272     unsigned char packet[MAX_PACKET_SIZE];
273     nbBytes = opus_multistream_encode_float(enc->st, &enc->buffer[enc->channels*enc->buffer_start],
274         enc->buffer_end-enc->buffer_start, packet, MAX_PACKET_SIZE);
275     /* FIXME: How do we handle failure here. */
276     assert(nbBytes > 0);
277     enc->curr_granule += enc->frame_size;
278     op.packet=packet;
279     op.bytes=nbBytes;
280     op.b_o_s=0;
281     op.e_o_s=0;
282     op.packetno=enc->packetno++;
283     op.granulepos=enc->curr_granule;
284     if (enc->curr_granule >= enc->end_granule) {
285       op.granulepos=enc->end_granule;
286       ogg_stream_packetin(&enc->os, &op);
287       while (ogg_stream_flush_fill(&enc->os, &og, 255*255)) {
288         int ret = oe_write_page(&og, &enc->callbacks, enc->user_data);
289         /* FIXME: what do we do if this fails? */
290         assert(ret != -1);
291         return;
292       }
293     }
294     ogg_stream_packetin(&enc->os, &op);
295     /* FIXME: Use flush to enforce latency constraint. */
296     while (ogg_stream_pageout_fill(&enc->os, &og, 255*255)) {
297       int ret = oe_write_page(&og, &enc->callbacks, enc->user_data);
298       /* FIXME: what do we do if this fails? */
299       assert(ret != -1);
300     }
301     enc->buffer_start += enc->frame_size;
302   }
303   /* If we've reached the end of the buffer, move everything back to the front. */
304   if (enc->buffer_end == BUFFER_SAMPLES) {
305     shift_buffer(enc);
306   }
307   /* This function must never leave the buffer full. */
308   assert(enc->buffer_end < BUFFER_SAMPLES);
309 }
310
311 /* Add/encode any number of float samples to the file. */
312 int ope_write_float(OggOpusEnc *enc, const float *pcm, int samples_per_channel) {
313   int channels = enc->channels;
314   if (!enc->stream_is_init) init_stream(enc);
315   enc->end_granule += samples_per_channel;
316   /* FIXME: Add resampling support. */
317   do {
318     int i;
319     int curr;
320     int space_left = BUFFER_SAMPLES-enc->buffer_end;
321     curr = MIN(samples_per_channel, space_left);
322     for (i=0;i<channels*curr;i++) {
323       enc->buffer[channels*enc->buffer_end+i] = pcm[i];
324     }
325     enc->buffer_end += curr;
326     pcm += curr*channels;
327     samples_per_channel -= curr;
328     encode_buffer(enc);
329   } while (samples_per_channel > 0);
330   return OPE_OK;
331 }
332
333 /* Add/encode any number of int16 samples to the file. */
334 int ope_write(OggOpusEnc *enc, const opus_int16 *pcm, int samples_per_channel) {
335   int channels = enc->channels;
336   if (!enc->stream_is_init) init_stream(enc);
337   enc->end_granule += samples_per_channel;
338   /* FIXME: Add resampling support. */
339   do {
340     int i;
341     int curr;
342     int space_left = BUFFER_SAMPLES-enc->buffer_end;
343     curr = MIN(samples_per_channel, space_left);
344     for (i=0;i<channels*curr;i++) {
345       enc->buffer[channels*enc->buffer_end+i] = (1.f/32768)*pcm[i];
346     }
347     enc->buffer_end += curr;
348     pcm += curr*channels;
349     samples_per_channel -= curr;
350     encode_buffer(enc);
351   } while (samples_per_channel > 0);
352   return OPE_OK;
353 }
354
355 static void finalize_stream(OggOpusEnc *enc) {
356   /* FIXME: Use a better value. */
357   int pad_samples = 3000;
358   if (!enc->stream_is_init) init_stream(enc);
359   shift_buffer(enc);
360   /* FIXME: Do LPC extension instead. */
361   memset(&enc->buffer[enc->channels*enc->buffer_end], 0, pad_samples*enc->channels);
362   enc->decision_delay = 0;
363   enc->buffer_end += pad_samples;
364   assert(enc->buffer_end <= BUFFER_SAMPLES);
365   encode_buffer(enc);
366 }
367
368 /* Close/finalize the stream. */
369 int ope_close_and_free(OggOpusEnc *enc) {
370   finalize_stream(enc);
371   free(enc->buffer);
372   opus_multistream_encoder_destroy(enc->st);
373   if (enc->os_allocated) ogg_stream_clear(&enc->os);
374   return OPE_OK;
375 }
376
377 /* Ends the stream and create a new stream within the same file. */
378 int ope_chain_current(OggOpusEnc *enc) {
379   (void)enc;
380   return OPE_UNIMPLEMENTED;
381 }
382
383 /* Ends the stream and create a new file. */
384 int ope_continue_new_file(OggOpusEnc *enc, const char *path) {
385   (void)enc;
386   (void)path;
387   return OPE_UNIMPLEMENTED;
388 }
389
390 /* Ends the stream and create a new file (callback-based). */
391 int ope_continue_new_callbacks(OggOpusEnc *enc, void *user_data) {
392   (void)enc;
393   (void)user_data;
394   return OPE_UNIMPLEMENTED;
395 }
396
397 /* Add a comment to the file (can only be called before encoding samples). */
398 int ope_add_comment(OggOpusEnc *enc, const char *tag, const char *val) {
399   if (comment_add(&enc->comment, &enc->comment_length, tag, val)) return OPE_INTERNAL_ERROR;
400   return OPE_OK;
401 }
402
403 /* Sets the Opus comment vendor string (optional, defaults to library info). */
404 int ope_set_vendor_string(OggOpusEnc *enc, const char *vendor) {
405   (void)enc;
406   (void)vendor;
407   return OPE_UNIMPLEMENTED;
408 }
409
410 /* Goes straight to the libopus ctl() functions. */
411 int ope_encoder_ctl(OggOpusEnc *enc, int request, ...) {
412   (void)enc;
413   (void)request;
414   return OPE_UNIMPLEMENTED;
415 }
416
417 /* ctl()-type call for the OggOpus layer. */
418 int ope_set_params(OggOpusEnc *enc, int request, ...) {
419   (void)enc;
420   (void)request;
421   return OPE_UNIMPLEMENTED;
422 }