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