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