chaining seems to be working
[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 <stdarg.h>
35 #include <time.h>
36 #include <unistd.h>
37 #include <stdlib.h>
38 #include <stdio.h>
39 #include <string.h>
40 #include <assert.h>
41 #include <opus_multistream.h>
42 #include "opusenc.h"
43 #include "opus_header.h"
44 #include "speex_resampler.h"
45 #include "picture.h"
46 #include "ogg_packer.h"
47
48 #define MAX_CHANNELS 8
49
50 #define LPC_PADDING 120
51
52 /* Allow up to 2 seconds for delayed decision. */
53 #define MAX_LOOKAHEAD 96000
54 /* We can't have a circular buffer (because of delayed decision), so let's not copy too often. */
55 #define BUFFER_EXTRA 24000
56
57 #define BUFFER_SAMPLES (MAX_LOOKAHEAD + BUFFER_EXTRA)
58
59 #define MIN(a,b) ((a) < (b) ? (a) : (b))
60 #define MAX(a,b) ((a) > (b) ? (a) : (b))
61
62 #define MAX_PACKET_SIZE (1276*8)
63
64 struct StdioObject {
65   FILE *file;
66 };
67
68 typedef struct EncStream EncStream;
69
70 struct EncStream {
71   void *user_data;
72   ogg_stream_state os;
73   int serialno_is_set;
74   int serialno;
75   int stream_is_init;
76   int packetno;
77   char *comment;
78   int comment_length;
79   int seen_file_icons;
80   int close_at_end;
81   int header_is_frozen;
82   ogg_int64_t end_granule;
83   ogg_int64_t granule_offset;
84   EncStream *next;
85 };
86
87 struct OggOpusEnc {
88   OpusMSEncoder *st;
89   oggpacker *oggp;
90   int rate;
91   int channels;
92   float *buffer;
93   int buffer_start;
94   int buffer_end;
95   SpeexResamplerState *re;
96   int frame_size;
97   int decision_delay;
98   int max_ogg_delay;
99   int global_granule_offset;
100   ogg_int64_t curr_granule;
101   ogg_int64_t write_granule;
102   ogg_int64_t last_page_granule;
103   unsigned char *chaining_keyframe;
104   int chaining_keyframe_length;
105   OpusEncCallbacks callbacks;
106   ope_packet_func packet_callback;
107   ope_page_func page_callback;
108   OpusHeader header;
109   int comment_padding;
110   EncStream *streams;
111   EncStream *last_stream;
112 };
113
114 static int oe_write_page(OggOpusEnc *enc, ogg_page *page, void *user_data)
115 {
116   int length;
117   int err;
118   err = enc->callbacks.write(user_data, page->header, page->header_len);
119   if (err) return -1;
120   err = enc->callbacks.write(user_data, page->body, page->body_len);
121   if (err) return -1;
122   length = page->header_len+page->body_len;
123   if (enc->page_callback) enc->page_callback(user_data, length, 0);
124   return length;
125 }
126
127 static int oe_flush_page(OggOpusEnc *enc) {
128   ogg_page og;
129   int ret;
130   int written = 0;
131
132   oggp_flush_page(enc->oggp);
133   {
134     unsigned char *page;
135     int len;
136     while (oggp_get_next_page(enc->oggp, &page, &len)) {
137       fwrite(page, 1, len, stdout);
138       fflush(stdout);
139     }
140   }
141
142   while ( (ret = ogg_stream_flush_fill(&enc->streams->os, &og, 255*255))) {
143     if (!ret) break;
144     if (ogg_page_packets(&og) != 0) enc->last_page_granule = ogg_page_granulepos(&og) + enc->streams->granule_offset;
145     ret = oe_write_page(enc, &og, enc->streams->user_data);
146     if (ret == -1) {
147       return -1;
148     }
149     written += ret;
150   }
151   return written;
152 }
153
154 int stdio_write(void *user_data, const unsigned char *ptr, int len) {
155   struct StdioObject *obj = (struct StdioObject*)user_data;
156   return fwrite(ptr, 1, len, obj->file) != (size_t)len;
157 }
158
159 int stdio_close(void *user_data) {
160   struct StdioObject *obj = (struct StdioObject*)user_data;
161   int ret = fclose(obj->file);
162   free(obj);
163   return ret;
164 }
165
166 static const OpusEncCallbacks stdio_callbacks = {
167   stdio_write,
168   stdio_close
169 };
170
171 /* Create a new OggOpus file. */
172 OggOpusEnc *ope_create_file(const char *path, int rate, int channels, int family, int *error) {
173   OggOpusEnc *enc;
174   struct StdioObject *obj;
175   obj = malloc(sizeof(*obj));
176   enc = ope_create_callbacks(&stdio_callbacks, obj, rate, channels, family, error);
177   if (enc == NULL || (error && *error)) {
178     return NULL;
179   }
180   obj->file = fopen(path, "wb");
181   if (!obj->file) {
182     if (error) *error = OPE_CANNOT_OPEN;
183     /* FIXME: Destroy the encoder properly. */
184     free(obj);
185     return NULL;
186   }
187   return enc;
188 }
189
190 EncStream *stream_create() {
191   EncStream *stream;
192   stream = malloc(sizeof(*stream));
193   if (!stream) return NULL;
194   stream->next = NULL;
195   stream->close_at_end = 1;
196   stream->serialno_is_set = 0;
197   stream->seen_file_icons = 0;
198   stream->stream_is_init = 0;
199   stream->header_is_frozen = 0;
200   stream->granule_offset = 0;
201   stream->comment = NULL;
202   comment_init(&stream->comment, &stream->comment_length, opus_get_version_string());
203   if (!stream->comment) goto fail;
204   {
205     char encoder_string[1024];
206     snprintf(encoder_string, sizeof(encoder_string), "%s version %s", PACKAGE_NAME, PACKAGE_VERSION);
207     comment_add(&stream->comment, &stream->comment_length, "ENCODER", encoder_string);
208   }
209   return stream;
210 fail:
211   if (stream->comment) free(stream->comment);
212   free(stream);
213   return NULL;
214 }
215
216 static void stream_destroy(EncStream *stream) {
217   if (stream->comment) free(stream->comment);
218   if (stream->stream_is_init) ogg_stream_clear(&stream->os);
219   free(stream);
220 }
221
222 /* Create a new OggOpus file (callback-based). */
223 OggOpusEnc *ope_create_callbacks(const OpusEncCallbacks *callbacks, void *user_data,
224     int rate, int channels, int family, int *error) {
225   OpusMSEncoder *st=NULL;
226   OggOpusEnc *enc=NULL;
227   int ret;
228   if (family != 0 && family != 1 && family != 255) {
229     if (error) *error = OPE_UNIMPLEMENTED;
230     return NULL;
231   }
232   if (channels <= 0 || channels > 255) {
233     if (error) *error = OPE_BAD_ARG;
234     return NULL;
235   }
236   /* FIXME: Add resampling support. */
237   if (rate <= 0) {
238     if (error) *error = OPE_BAD_ARG;
239     return NULL;
240   }
241
242   if ( (enc = malloc(sizeof(*enc))) == NULL) goto fail;
243   enc->streams = NULL;
244   if ( (enc->streams = stream_create()) == NULL) goto fail;
245   enc->streams->next = NULL;
246   enc->last_stream = enc->streams;
247   enc->oggp = NULL;
248   enc->packet_callback = NULL;
249   enc->page_callback = NULL;
250   enc->rate = rate;
251   enc->channels = channels;
252   enc->frame_size = 960;
253   enc->decision_delay = 96000;
254   enc->max_ogg_delay = 48000;
255   enc->chaining_keyframe = NULL;
256   enc->chaining_keyframe_length = -1;
257   enc->comment_padding = 512;
258   enc->header.channels=channels;
259   enc->header.channel_mapping=family;
260   enc->header.input_sample_rate=rate;
261   enc->header.gain=0;
262   st=opus_multistream_surround_encoder_create(48000, channels, enc->header.channel_mapping,
263       &enc->header.nb_streams, &enc->header.nb_coupled,
264       enc->header.stream_map, OPUS_APPLICATION_AUDIO, &ret);
265   if (! (ret == OPUS_OK && st != NULL) ) {
266     goto fail;
267   }
268   if (rate != 48000) {
269     enc->re = speex_resampler_init(channels, rate, 48000, 5, NULL);
270     if (enc->re == NULL) goto fail;
271     speex_resampler_skip_zeros(enc->re);
272   } else {
273     enc->re = NULL;
274   }
275   opus_multistream_encoder_ctl(st, OPUS_SET_EXPERT_FRAME_DURATION(OPUS_FRAMESIZE_20_MS));
276   {
277     opus_int32 tmp;
278     int ret;
279     ret = opus_multistream_encoder_ctl(st, OPUS_GET_LOOKAHEAD(&tmp));
280     if (ret == OPUS_OK) enc->header.preskip = tmp;
281     else enc->header.preskip = 0;
282     enc->global_granule_offset = enc->header.preskip;
283   }
284   enc->curr_granule = 0;
285   enc->write_granule = 0;
286   enc->last_page_granule = 0;
287   if ( (enc->buffer = malloc(sizeof(*enc->buffer)*BUFFER_SAMPLES*channels)) == NULL) goto fail;
288   enc->buffer_start = enc->buffer_end = 0;
289   enc->st = st;
290   enc->callbacks = *callbacks;
291   enc->streams->user_data = user_data;
292   if (error) *error = OPE_OK;
293   return enc;
294 fail:
295   if (enc) {
296     free(enc);
297     if (enc->buffer) free(enc->buffer);
298     if (enc->streams) stream_destroy(enc->streams);
299   }
300   if (st) {
301     opus_multistream_encoder_destroy(st);
302   }
303   if (error) *error = OPE_ALLOC_FAIL;
304   return NULL;
305 }
306
307 static void init_stream(OggOpusEnc *enc) {
308   assert(!enc->streams->stream_is_init);
309   if (!enc->streams->serialno_is_set) {
310     enc->streams->serialno = rand();
311   }
312
313   if (enc->oggp != NULL) oggp_chain(enc->oggp, enc->streams->serialno);
314   else enc->oggp = oggp_create(enc->streams->serialno);
315   /* FIXME: How the hell do we handle failure here? */
316
317   if (ogg_stream_init(&enc->streams->os, enc->streams->serialno) == -1) {
318     assert(0);
319     /* FIXME: How the hell do we handle that? */
320   }
321   comment_pad(&enc->streams->comment, &enc->streams->comment_length, enc->comment_padding);
322
323   /*Write header*/
324   {
325     ogg_packet op;
326     /*The Identification Header is 19 bytes, plus a Channel Mapping Table for
327       mapping families other than 0. The Channel Mapping Table is 2 bytes +
328       1 byte per channel. Because the maximum number of channels is 255, the
329       maximum size of this header is 19 + 2 + 255 = 276 bytes.*/
330     unsigned char header_data[276];
331     int packet_size = opus_header_to_packet(&enc->header, header_data, sizeof(header_data));
332     op.packet=header_data;
333     op.bytes=packet_size;
334     op.b_o_s=1;
335     op.e_o_s=0;
336     op.granulepos=0;
337     op.packetno=0;
338     ogg_stream_packetin(&enc->streams->os, &op);
339
340     unsigned char *p;
341     p = oggp_get_packet_buffer(enc->oggp, 276);
342     memcpy(p, header_data, packet_size);
343     oggp_commit_packet(enc->oggp, packet_size, 0, 0);
344
345     oe_flush_page(enc);
346
347     op.packet = (unsigned char *)enc->streams->comment;
348     op.bytes = enc->streams->comment_length;
349     op.b_o_s = 0;
350     op.e_o_s = 0;
351     op.granulepos = 0;
352     op.packetno = 1;
353     ogg_stream_packetin(&enc->streams->os, &op);
354
355     p = oggp_get_packet_buffer(enc->oggp, enc->streams->comment_length);
356     memcpy(p, enc->streams->comment, enc->streams->comment_length);
357     oggp_commit_packet(enc->oggp, enc->streams->comment_length, 0, 0);
358
359     oe_flush_page(enc);
360   }
361   enc->streams->stream_is_init = 1;
362   enc->streams->packetno = 2;
363 }
364
365 static void shift_buffer(OggOpusEnc *enc) {
366     memmove(enc->buffer, &enc->buffer[enc->channels*enc->buffer_start], enc->channels*(enc->buffer_end-enc->buffer_start)*sizeof(*enc->buffer));
367     enc->buffer_end -= enc->buffer_start;
368     enc->buffer_start = 0;
369 }
370
371 static void encode_buffer(OggOpusEnc *enc) {
372   /* Round up when converting the granule pos because the decoder will round down. */
373   ogg_int64_t end_granule48k = (enc->streams->end_granule*48000 + enc->rate - 1)/enc->rate + enc->global_granule_offset;
374   while (enc->buffer_end-enc->buffer_start > enc->frame_size + enc->decision_delay) {
375     int cont;
376     opus_int32 pred;
377     int flush_needed;
378     ogg_packet op;
379     ogg_page og;
380     int nbBytes;
381     unsigned char packet[MAX_PACKET_SIZE];
382     int is_keyframe=0;
383     opus_multistream_encoder_ctl(enc->st, OPUS_GET_PREDICTION_DISABLED(&pred));
384     /* FIXME: a frame that follows a keyframe generally doesn't need to be a keyframe
385        unless there's two consecutive stream boundaries. */
386     if (enc->curr_granule + 2*enc->frame_size>= end_granule48k && enc->streams->next) {
387       opus_multistream_encoder_ctl(enc->st, OPUS_SET_PREDICTION_DISABLED(1));
388       is_keyframe = 1;
389     }
390     nbBytes = opus_multistream_encode_float(enc->st, &enc->buffer[enc->channels*enc->buffer_start],
391         enc->buffer_end-enc->buffer_start, packet, MAX_PACKET_SIZE);
392     /* FIXME: How do we handle failure here. */
393     opus_multistream_encoder_ctl(enc->st, OPUS_SET_PREDICTION_DISABLED(pred));
394     assert(nbBytes > 0);
395     enc->curr_granule += enc->frame_size;
396     op.packet=packet;
397     op.bytes=nbBytes;
398     op.b_o_s=0;
399     op.packetno=enc->streams->packetno++;
400     do {
401       op.granulepos=enc->curr_granule-enc->streams->granule_offset;
402       op.e_o_s=enc->curr_granule >= end_granule48k;
403       cont = 0;
404       if (op.e_o_s) op.granulepos=end_granule48k-enc->streams->granule_offset;
405       ogg_stream_packetin(&enc->streams->os, &op);
406       {
407         unsigned char *p;
408         p = oggp_get_packet_buffer(enc->oggp, MAX_PACKET_SIZE);
409         memcpy(p, packet, nbBytes);
410         oggp_commit_packet(enc->oggp, nbBytes, op.granulepos, op.e_o_s);
411       }
412       if (enc->packet_callback) enc->packet_callback(enc->streams->user_data, op.packet, op.bytes, 0);
413       /* FIXME: Also flush on too many segments. */
414       flush_needed = op.e_o_s || enc->curr_granule - enc->last_page_granule > enc->max_ogg_delay;
415       if (flush_needed) {
416 #if 1
417         oe_flush_page(enc);
418 #else
419         oggp_flush_page(enc->oggp);
420         {
421           unsigned char *page;
422           int len;
423           while (oggp_get_next_page(enc->oggp, &page, &len)) {
424             fwrite(page, 1, len, stdout);
425             fflush(stdout);
426           }
427         }
428         while (ogg_stream_flush_fill(&enc->streams->os, &og, 255*255)) {
429           if (ogg_page_packets(&og) != 0) enc->last_page_granule = ogg_page_granulepos(&og) + enc->streams->granule_offset;
430           int ret = oe_write_page(enc, &og, enc->streams->user_data);
431           /* FIXME: what do we do if this fails? */
432           assert(ret != -1);
433         }
434 #endif
435       } else {
436         while (ogg_stream_pageout_fill(&enc->streams->os, &og, 255*255)) {
437           if (ogg_page_packets(&og) != 0) enc->last_page_granule = ogg_page_granulepos(&og) + enc->streams->granule_offset;
438           int ret = oe_write_page(enc, &og, enc->streams->user_data);
439           /* FIXME: what do we do if this fails? */
440           assert(ret != -1);
441         }
442       }
443       if (op.e_o_s) {
444         EncStream *tmp;
445         tmp = enc->streams->next;
446         if (enc->streams->close_at_end) enc->callbacks.close(enc->streams->user_data);
447         stream_destroy(enc->streams);
448         enc->streams = tmp;
449         if (!tmp) enc->last_stream = NULL;
450         if (enc->last_stream == NULL) return;
451         /* We're done with this stream, start the next one. */
452         enc->header.preskip = end_granule48k + enc->frame_size - enc->curr_granule;
453         enc->streams->granule_offset = enc->curr_granule - enc->frame_size;
454         if (enc->chaining_keyframe) {
455           enc->header.preskip += enc->frame_size;
456           enc->streams->granule_offset -= enc->frame_size;
457         }
458         init_stream(enc);
459         if (enc->chaining_keyframe) {
460           ogg_packet op2;
461           op2.packet = enc->chaining_keyframe;
462           op2.bytes = enc->chaining_keyframe_length;
463           op2.b_o_s = 0;
464           op2.e_o_s = 0;
465           op2.packetno=enc->streams->packetno++;
466           op2.granulepos=enc->curr_granule - enc->streams->granule_offset - enc->frame_size;
467           ogg_stream_packetin(&enc->streams->os, &op2);
468           {
469             unsigned char *p;
470             p = oggp_get_packet_buffer(enc->oggp, MAX_PACKET_SIZE);
471             memcpy(p, enc->chaining_keyframe, enc->chaining_keyframe_length);
472             oggp_commit_packet(enc->oggp, enc->chaining_keyframe_length, op2.granulepos, 0);
473           }
474           if (enc->packet_callback) enc->packet_callback(enc->streams->user_data, op2.packet, op2.bytes, 0);
475         }
476         end_granule48k = (enc->streams->end_granule*48000 + enc->rate - 1)/enc->rate + enc->global_granule_offset;
477         cont = 1;
478       }
479     } while (cont);
480     if (enc->chaining_keyframe) free(enc->chaining_keyframe);
481     if (is_keyframe) {
482       enc->chaining_keyframe = malloc(nbBytes);
483       enc->chaining_keyframe_length = nbBytes;
484       memcpy(enc->chaining_keyframe, packet, nbBytes);
485     } else {
486       enc->chaining_keyframe = NULL;
487       enc->chaining_keyframe_length = -1;
488     }
489     enc->buffer_start += enc->frame_size;
490   }
491   /* If we've reached the end of the buffer, move everything back to the front. */
492   if (enc->buffer_end == BUFFER_SAMPLES) {
493     shift_buffer(enc);
494   }
495   /* This function must never leave the buffer full. */
496   assert(enc->buffer_end < BUFFER_SAMPLES);
497 }
498
499 /* Add/encode any number of float samples to the file. */
500 int ope_write_float(OggOpusEnc *enc, const float *pcm, int samples_per_channel) {
501   int channels = enc->channels;
502   enc->last_stream->header_is_frozen = 1;
503   if (!enc->streams->stream_is_init) init_stream(enc);
504   if (samples_per_channel < 0) return OPE_BAD_ARG;
505   enc->write_granule += samples_per_channel;
506   enc->last_stream->end_granule = enc->write_granule;
507   do {
508     int i;
509     spx_uint32_t in_samples, out_samples;
510     out_samples = BUFFER_SAMPLES-enc->buffer_end;
511     if (enc->re != NULL) {
512       in_samples = samples_per_channel;
513       speex_resampler_process_interleaved_float(enc->re, pcm, &in_samples, &enc->buffer[channels*enc->buffer_end], &out_samples);
514     } else {
515       int curr;
516       curr = MIN((spx_uint32_t)samples_per_channel, out_samples);
517       for (i=0;i<channels*curr;i++) {
518       enc->buffer[channels*enc->buffer_end+i] = pcm[i];
519       }
520       in_samples = out_samples = curr;
521     }
522     enc->buffer_end += out_samples;
523     pcm += in_samples*channels;
524     samples_per_channel -= in_samples;
525     encode_buffer(enc);
526   } while (samples_per_channel > 0);
527   return OPE_OK;
528 }
529
530 #define CONVERT_BUFFER 256
531
532 /* Add/encode any number of int16 samples to the file. */
533 int ope_write(OggOpusEnc *enc, const opus_int16 *pcm, int samples_per_channel) {
534   int channels = enc->channels;
535   enc->last_stream->header_is_frozen = 1;
536   if (!enc->streams->stream_is_init) init_stream(enc);
537   if (samples_per_channel < 0) return OPE_BAD_ARG;
538   enc->write_granule += samples_per_channel;
539   enc->last_stream->end_granule = enc->write_granule;
540   do {
541     int i;
542     spx_uint32_t in_samples, out_samples;
543     out_samples = BUFFER_SAMPLES-enc->buffer_end;
544     if (enc->re != NULL) {
545       float buf[CONVERT_BUFFER*MAX_CHANNELS];
546       in_samples = MIN(CONVERT_BUFFER, samples_per_channel);
547       for (i=0;i<channels*(int)in_samples;i++) {
548         buf[i] = (1.f/32768)*pcm[i];
549       }
550       speex_resampler_process_interleaved_float(enc->re, buf, &in_samples, &enc->buffer[channels*enc->buffer_end], &out_samples);
551     } else {
552       int curr;
553       curr = MIN((spx_uint32_t)samples_per_channel, out_samples);
554       for (i=0;i<channels*curr;i++) {
555         enc->buffer[channels*enc->buffer_end+i] = (1.f/32768)*pcm[i];
556       }
557       in_samples = out_samples = curr;
558     }
559     enc->buffer_end += out_samples;
560     pcm += in_samples*channels;
561     samples_per_channel -= in_samples;
562     encode_buffer(enc);
563   } while (samples_per_channel > 0);
564   return OPE_OK;
565 }
566
567 static void finalize_all_streams(OggOpusEnc *enc) {
568   /* FIXME: Use a better value. */
569   int pad_samples = 3000;
570   if (!enc->streams->stream_is_init) init_stream(enc);
571   shift_buffer(enc);
572   /* FIXME: Do LPC extension instead. */
573   memset(&enc->buffer[enc->channels*enc->buffer_end], 0, pad_samples*enc->channels);
574   enc->decision_delay = 0;
575   enc->buffer_end += pad_samples;
576   assert(enc->buffer_end <= BUFFER_SAMPLES);
577   encode_buffer(enc);
578   assert(enc->streams == NULL);
579 }
580
581 /* Close/finalize the stream. */
582 int ope_close_and_free(OggOpusEnc *enc) {
583   finalize_all_streams(enc);
584   if (enc->chaining_keyframe) free(enc->chaining_keyframe);
585   free(enc->buffer);
586   opus_multistream_encoder_destroy(enc->st);
587   if (enc->re) speex_resampler_destroy(enc->re);
588   free(enc);
589   return OPE_OK;
590 }
591
592 /* Ends the stream and create a new stream within the same file. */
593 int ope_chain_current(OggOpusEnc *enc) {
594   enc->last_stream->close_at_end = 0;
595   return ope_continue_new_callbacks(enc, enc->last_stream->user_data);
596 }
597
598 /* Ends the stream and create a new file. */
599 int ope_continue_new_file(OggOpusEnc *enc, const char *path) {
600   int ret;
601   struct StdioObject *obj;
602   if (!(obj = malloc(sizeof(*obj)))) return OPE_ALLOC_FAIL;
603   obj->file = fopen(path, "wb");
604   if (!obj->file) {
605     free(obj);
606     /* By trying to open the file first, we can recover if we can't open it. */
607     return OPE_CANNOT_OPEN;
608   }
609   ret = ope_continue_new_callbacks(enc, obj);
610   if (ret == OPE_OK) return ret;
611   fclose(obj->file);
612   free(obj);
613   return ret;
614 }
615
616 /* Ends the stream and create a new file (callback-based). */
617 int ope_continue_new_callbacks(OggOpusEnc *enc, void *user_data) {
618   EncStream *new_stream;
619   assert(enc->streams);
620   assert(enc->last_stream);
621   new_stream = stream_create();
622   if (!new_stream) return OPE_ALLOC_FAIL;
623   new_stream->user_data = user_data;
624   enc->last_stream->next = new_stream;
625   enc->last_stream = new_stream;
626   return OPE_OK;
627 }
628
629 /* Add a comment to the file (can only be called before encoding samples). */
630 int ope_add_comment(OggOpusEnc *enc, const char *tag, const char *val) {
631   if (enc->last_stream->header_is_frozen) return OPE_TOO_LATE;
632   if (enc->last_stream->stream_is_init) return OPE_TOO_LATE;
633   if (comment_add(&enc->last_stream->comment, &enc->last_stream->comment_length, tag, val)) return OPE_ALLOC_FAIL;
634   return OPE_OK;
635 }
636
637 int ope_add_picture(OggOpusEnc *enc, const char *spec) {
638   const char *error_message;
639   char *picture_data;
640   if (enc->last_stream->header_is_frozen) return OPE_TOO_LATE;
641   if (enc->last_stream->stream_is_init) return OPE_TOO_LATE;
642   picture_data = parse_picture_specification(spec, &error_message, &enc->last_stream->seen_file_icons);
643   if(picture_data==NULL){
644     /* FIXME: return proper errors rather than printing a message. */
645     fprintf(stderr,"Error parsing picture option: %s\n",error_message);
646     return OPE_BAD_ARG;
647   }
648   comment_add(&enc->last_stream->comment, &enc->last_stream->comment_length, "METADATA_BLOCK_PICTURE", picture_data);
649   free(picture_data);
650   return OPE_OK;
651 }
652
653 /* Sets the Opus comment vendor string (optional, defaults to library info). */
654 int ope_set_vendor_string(OggOpusEnc *enc, const char *vendor) {
655   if (enc->last_stream->header_is_frozen) return OPE_TOO_LATE;
656   if (enc->last_stream->stream_is_init) return OPE_TOO_LATE;
657   if (comment_replace_vendor_string(&enc->last_stream->comment, &enc->last_stream->comment_length, vendor)) return OPE_ALLOC_FAIL;
658   return OPE_OK;
659 }
660
661 int ope_flush_header(OggOpusEnc *enc) {
662   if (enc->last_stream->header_is_frozen) return OPE_TOO_LATE;
663   if (enc->last_stream->stream_is_init) return OPE_TOO_LATE;
664   else init_stream(enc);
665   return OPE_OK;
666 }
667
668 /* Goes straight to the libopus ctl() functions. */
669 int ope_encoder_ctl(OggOpusEnc *enc, int request, ...) {
670   int ret;
671   int translate;
672   va_list ap;
673   va_start(ap, request);
674   switch (request) {
675     case OPUS_SET_APPLICATION_REQUEST:
676     case OPUS_SET_BITRATE_REQUEST:
677     case OPUS_SET_MAX_BANDWIDTH_REQUEST:
678     case OPUS_SET_VBR_REQUEST:
679     case OPUS_SET_BANDWIDTH_REQUEST:
680     case OPUS_SET_COMPLEXITY_REQUEST:
681     case OPUS_SET_INBAND_FEC_REQUEST:
682     case OPUS_SET_PACKET_LOSS_PERC_REQUEST:
683     case OPUS_SET_DTX_REQUEST:
684     case OPUS_SET_VBR_CONSTRAINT_REQUEST:
685     case OPUS_SET_FORCE_CHANNELS_REQUEST:
686     case OPUS_SET_SIGNAL_REQUEST:
687     case OPUS_SET_LSB_DEPTH_REQUEST:
688     case OPUS_SET_PREDICTION_DISABLED_REQUEST:
689 #ifdef OPUS_SET_PHASE_INVERSION_DISABLED_REQUEST
690     case OPUS_SET_PHASE_INVERSION_DISABLED_REQUEST:
691 #endif
692     {
693       opus_int32 value = va_arg(ap, opus_int32);
694       ret = opus_multistream_encoder_ctl(enc->st, request, value);
695     }
696     break;
697     case OPUS_SET_EXPERT_FRAME_DURATION_REQUEST:
698     {
699       opus_int32 value = va_arg(ap, opus_int32);
700       int max_supported = OPUS_FRAMESIZE_60_MS;
701 #ifdef OPUS_FRAMESIZE_120_MS
702       max_supported = OPUS_FRAMESIZE_120_MS;
703 #endif
704       if (value < OPUS_FRAMESIZE_2_5_MS || value > max_supported) {
705         ret = OPUS_UNIMPLEMENTED;
706         break;
707       }
708       ret = opus_multistream_encoder_ctl(enc->st, request, value);
709       if (ret == OPUS_OK) {
710         if (value <= OPUS_FRAMESIZE_40_MS)
711           enc->frame_size = 120<<(value-OPUS_FRAMESIZE_2_5_MS);
712         else
713           enc->frame_size = (value-OPUS_FRAMESIZE_2_5_MS-2)*960;
714       }
715     }
716     break;
717     case OPUS_MULTISTREAM_GET_ENCODER_STATE_REQUEST:
718     {
719       opus_int32 stream_id;
720       OpusEncoder **value;
721       stream_id = va_arg(ap, opus_int32);
722       value = va_arg(ap, OpusEncoder**);
723       ret = opus_multistream_encoder_ctl(enc->st, request, stream_id, value);
724     }
725     break;
726
727     /* ****************** libopusenc-specific requests. ********************** */
728     case OPE_SET_DECISION_DELAY_REQUEST:
729     {
730       opus_int32 value = va_arg(ap, opus_int32);
731       if (value < 0) {
732         ret = OPE_BAD_ARG;
733         break;
734       }
735       enc->decision_delay = value;
736       ret = OPE_OK;
737     }
738     break;
739     case OPE_SET_MUXING_DELAY_REQUEST:
740     {
741       opus_int32 value = va_arg(ap, opus_int32);
742       if (value < 0) {
743         ret = OPE_BAD_ARG;
744         break;
745       }
746       enc->max_ogg_delay = value;
747       ret = OPE_OK;
748     }
749     break;
750     case OPE_SET_COMMENT_PADDING_REQUEST:
751     {
752       opus_int32 value = va_arg(ap, opus_int32);
753       if (value < 0) {
754         ret = OPE_BAD_ARG;
755         break;
756       }
757       enc->comment_padding = value;
758       ret = OPE_OK;
759     }
760     break;
761     case OPE_SET_SERIALNO_REQUEST:
762     {
763       opus_int32 value = va_arg(ap, opus_int32);
764       if (enc->last_stream->header_is_frozen) return OPE_TOO_LATE;
765       enc->last_stream->serialno = value;
766       enc->last_stream->serialno_is_set = 1;
767       ret = OPE_OK;
768     }
769     case OPE_SET_PACKET_CALLBACK_REQUEST:
770     {
771       ope_packet_func value = va_arg(ap, ope_packet_func);
772       enc->packet_callback = value;
773       ret = OPE_OK;
774     }
775     break;
776     case OPE_SET_PAGE_CALLBACK_REQUEST:
777     {
778       ope_page_func value = va_arg(ap, ope_page_func);
779       enc->page_callback = value;
780       ret = OPE_OK;
781     }
782     break;
783     default:
784       return OPE_UNIMPLEMENTED;
785   }
786   va_end(ap);
787   translate = request < 14000 || (ret < 0 && ret >= -10);
788   if (translate) {
789     if (ret == OPUS_BAD_ARG) ret = OPE_BAD_ARG;
790     else if (ret == OPUS_INTERNAL_ERROR) ret = OPE_INTERNAL_ERROR;
791     else if (ret == OPUS_UNIMPLEMENTED) ret = OPE_UNIMPLEMENTED;
792     else if (ret == OPUS_ALLOC_FAIL) ret = OPE_ALLOC_FAIL;
793     else ret = OPE_INTERNAL_ERROR;
794   }
795   assert(ret == 0 || ret < -10);
796   return ret;
797 }