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