more splitting
[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 static void oe_flush_page(OggOpusEnc *enc) {
125   oggp_flush_page(enc->oggp);
126   output_pages(enc);
127 }
128
129 #else
130
131 static int oe_write_page(OggOpusEnc *enc, ogg_page *page, void *user_data)
132 {
133   int length;
134   int err;
135   err = enc->callbacks.write(user_data, page->header, page->header_len);
136   if (err) return -1;
137   err = enc->callbacks.write(user_data, page->body, page->body_len);
138   if (err) return -1;
139   length = page->header_len+page->body_len;
140   if (enc->page_callback) enc->page_callback(user_data, length, 0);
141   return length;
142 }
143
144 static void oe_flush_page(OggOpusEnc *enc) {
145   ogg_page og;
146   int ret;
147
148   while ( (ret = ogg_stream_flush_fill(&enc->streams->os, &og, 255*255))) {
149     if (ogg_page_packets(&og) != 0) enc->last_page_granule = ogg_page_granulepos(&og) + enc->streams->granule_offset;
150     ret = oe_write_page(enc, &og, enc->streams->user_data);
151     if (ret == -1) {
152       return;
153     }
154   }
155 }
156 #endif
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 #ifndef USE_OGGP
388     ogg_page og;
389 #endif
390     int nbBytes;
391     unsigned char packet[MAX_PACKET_SIZE];
392     int is_keyframe=0;
393     opus_multistream_encoder_ctl(enc->st, OPUS_GET_PREDICTION_DISABLED(&pred));
394     /* FIXME: a frame that follows a keyframe generally doesn't need to be a keyframe
395        unless there's two consecutive stream boundaries. */
396     if (enc->curr_granule + 2*enc->frame_size>= end_granule48k && enc->streams->next) {
397       opus_multistream_encoder_ctl(enc->st, OPUS_SET_PREDICTION_DISABLED(1));
398       is_keyframe = 1;
399     }
400     nbBytes = opus_multistream_encode_float(enc->st, &enc->buffer[enc->channels*enc->buffer_start],
401         enc->buffer_end-enc->buffer_start, packet, MAX_PACKET_SIZE);
402     /* FIXME: How do we handle failure here. */
403     opus_multistream_encoder_ctl(enc->st, OPUS_SET_PREDICTION_DISABLED(pred));
404     assert(nbBytes > 0);
405     enc->curr_granule += enc->frame_size;
406     op.packet=packet;
407     op.bytes=nbBytes;
408     op.b_o_s=0;
409     op.packetno=enc->streams->packetno++;
410     do {
411       op.granulepos=enc->curr_granule-enc->streams->granule_offset;
412       op.e_o_s=enc->curr_granule >= end_granule48k;
413       cont = 0;
414       if (op.e_o_s) op.granulepos=end_granule48k-enc->streams->granule_offset;
415       ogg_stream_packetin(&enc->streams->os, &op);
416       {
417         unsigned char *p;
418         p = oggp_get_packet_buffer(enc->oggp, MAX_PACKET_SIZE);
419         memcpy(p, packet, nbBytes);
420         oggp_commit_packet(enc->oggp, nbBytes, op.granulepos, op.e_o_s);
421       }
422       if (enc->packet_callback) enc->packet_callback(enc->streams->user_data, op.packet, op.bytes, 0);
423       /* FIXME: Also flush on too many segments. */
424 #ifdef USE_OGGP
425       flush_needed = op.e_o_s;
426       if (flush_needed) oe_flush_page(enc);
427       else output_pages(enc);
428 #else
429       flush_needed = op.e_o_s || enc->curr_granule - enc->last_page_granule >= enc->max_ogg_delay;
430       if (flush_needed) {
431         oe_flush_page(enc);
432       } else {
433         while (ogg_stream_pageout_fill(&enc->streams->os, &og, 255*255)) {
434           if (ogg_page_packets(&og) != 0) enc->last_page_granule = ogg_page_granulepos(&og) + enc->streams->granule_offset;
435           int ret = oe_write_page(enc, &og, enc->streams->user_data);
436           /* FIXME: what do we do if this fails? */
437           assert(ret != -1);
438         }
439       }
440 #endif
441       if (op.e_o_s) {
442         EncStream *tmp;
443         tmp = enc->streams->next;
444         if (enc->streams->close_at_end) enc->callbacks.close(enc->streams->user_data);
445         stream_destroy(enc->streams);
446         enc->streams = tmp;
447         if (!tmp) enc->last_stream = NULL;
448         if (enc->last_stream == NULL) return;
449         /* We're done with this stream, start the next one. */
450         enc->header.preskip = end_granule48k + enc->frame_size - enc->curr_granule;
451         enc->streams->granule_offset = enc->curr_granule - enc->frame_size;
452         if (enc->chaining_keyframe) {
453           enc->header.preskip += enc->frame_size;
454           enc->streams->granule_offset -= enc->frame_size;
455         }
456         init_stream(enc);
457         if (enc->chaining_keyframe) {
458           ogg_packet op2;
459           op2.packet = enc->chaining_keyframe;
460           op2.bytes = enc->chaining_keyframe_length;
461           op2.b_o_s = 0;
462           op2.e_o_s = 0;
463           op2.packetno=enc->streams->packetno++;
464           op2.granulepos=enc->curr_granule - enc->streams->granule_offset - enc->frame_size;
465           ogg_stream_packetin(&enc->streams->os, &op2);
466           {
467             unsigned char *p;
468             p = oggp_get_packet_buffer(enc->oggp, MAX_PACKET_SIZE);
469             memcpy(p, enc->chaining_keyframe, enc->chaining_keyframe_length);
470             oggp_commit_packet(enc->oggp, enc->chaining_keyframe_length, op2.granulepos, 0);
471           }
472           if (enc->packet_callback) enc->packet_callback(enc->streams->user_data, op2.packet, op2.bytes, 0);
473         }
474         end_granule48k = (enc->streams->end_granule*48000 + enc->rate - 1)/enc->rate + enc->global_granule_offset;
475         cont = 1;
476       }
477     } while (cont);
478     if (enc->chaining_keyframe) free(enc->chaining_keyframe);
479     if (is_keyframe) {
480       enc->chaining_keyframe = malloc(nbBytes);
481       enc->chaining_keyframe_length = nbBytes;
482       memcpy(enc->chaining_keyframe, packet, nbBytes);
483     } else {
484       enc->chaining_keyframe = NULL;
485       enc->chaining_keyframe_length = -1;
486     }
487     enc->buffer_start += enc->frame_size;
488   }
489   /* If we've reached the end of the buffer, move everything back to the front. */
490   if (enc->buffer_end == BUFFER_SAMPLES) {
491     shift_buffer(enc);
492   }
493   /* This function must never leave the buffer full. */
494   assert(enc->buffer_end < BUFFER_SAMPLES);
495 }
496
497 /* Add/encode any number of float samples to the file. */
498 int ope_write_float(OggOpusEnc *enc, const float *pcm, int samples_per_channel) {
499   int channels = enc->channels;
500   enc->last_stream->header_is_frozen = 1;
501   if (!enc->streams->stream_is_init) init_stream(enc);
502   if (samples_per_channel < 0) return OPE_BAD_ARG;
503   enc->write_granule += samples_per_channel;
504   enc->last_stream->end_granule = enc->write_granule;
505   do {
506     int i;
507     spx_uint32_t in_samples, out_samples;
508     out_samples = BUFFER_SAMPLES-enc->buffer_end;
509     if (enc->re != NULL) {
510       in_samples = samples_per_channel;
511       speex_resampler_process_interleaved_float(enc->re, pcm, &in_samples, &enc->buffer[channels*enc->buffer_end], &out_samples);
512     } else {
513       int curr;
514       curr = MIN((spx_uint32_t)samples_per_channel, out_samples);
515       for (i=0;i<channels*curr;i++) {
516       enc->buffer[channels*enc->buffer_end+i] = pcm[i];
517       }
518       in_samples = out_samples = curr;
519     }
520     enc->buffer_end += out_samples;
521     pcm += in_samples*channels;
522     samples_per_channel -= in_samples;
523     encode_buffer(enc);
524   } while (samples_per_channel > 0);
525   return OPE_OK;
526 }
527
528 #define CONVERT_BUFFER 256
529
530 /* Add/encode any number of int16 samples to the file. */
531 int ope_write(OggOpusEnc *enc, const opus_int16 *pcm, int samples_per_channel) {
532   int channels = enc->channels;
533   enc->last_stream->header_is_frozen = 1;
534   if (!enc->streams->stream_is_init) init_stream(enc);
535   if (samples_per_channel < 0) return OPE_BAD_ARG;
536   enc->write_granule += samples_per_channel;
537   enc->last_stream->end_granule = enc->write_granule;
538   do {
539     int i;
540     spx_uint32_t in_samples, out_samples;
541     out_samples = BUFFER_SAMPLES-enc->buffer_end;
542     if (enc->re != NULL) {
543       float buf[CONVERT_BUFFER*MAX_CHANNELS];
544       in_samples = MIN(CONVERT_BUFFER, samples_per_channel);
545       for (i=0;i<channels*(int)in_samples;i++) {
546         buf[i] = (1.f/32768)*pcm[i];
547       }
548       speex_resampler_process_interleaved_float(enc->re, buf, &in_samples, &enc->buffer[channels*enc->buffer_end], &out_samples);
549     } else {
550       int curr;
551       curr = MIN((spx_uint32_t)samples_per_channel, out_samples);
552       for (i=0;i<channels*curr;i++) {
553         enc->buffer[channels*enc->buffer_end+i] = (1.f/32768)*pcm[i];
554       }
555       in_samples = out_samples = curr;
556     }
557     enc->buffer_end += out_samples;
558     pcm += in_samples*channels;
559     samples_per_channel -= in_samples;
560     encode_buffer(enc);
561   } while (samples_per_channel > 0);
562   return OPE_OK;
563 }
564
565 static void finalize_all_streams(OggOpusEnc *enc) {
566   /* FIXME: Use a better value. */
567   int pad_samples = 3000;
568   if (!enc->streams->stream_is_init) init_stream(enc);
569   shift_buffer(enc);
570   /* FIXME: Do LPC extension instead. */
571   memset(&enc->buffer[enc->channels*enc->buffer_end], 0, pad_samples*enc->channels);
572   enc->decision_delay = 0;
573   enc->buffer_end += pad_samples;
574   assert(enc->buffer_end <= BUFFER_SAMPLES);
575   encode_buffer(enc);
576   assert(enc->streams == NULL);
577 }
578
579 /* Close/finalize the stream. */
580 int ope_close_and_free(OggOpusEnc *enc) {
581   finalize_all_streams(enc);
582   if (enc->chaining_keyframe) free(enc->chaining_keyframe);
583   free(enc->buffer);
584   opus_multistream_encoder_destroy(enc->st);
585   if (enc->re) speex_resampler_destroy(enc->re);
586   free(enc);
587   return OPE_OK;
588 }
589
590 /* Ends the stream and create a new stream within the same file. */
591 int ope_chain_current(OggOpusEnc *enc) {
592   enc->last_stream->close_at_end = 0;
593   return ope_continue_new_callbacks(enc, enc->last_stream->user_data);
594 }
595
596 /* Ends the stream and create a new file. */
597 int ope_continue_new_file(OggOpusEnc *enc, const char *path) {
598   int ret;
599   struct StdioObject *obj;
600   if (!(obj = malloc(sizeof(*obj)))) return OPE_ALLOC_FAIL;
601   obj->file = fopen(path, "wb");
602   if (!obj->file) {
603     free(obj);
604     /* By trying to open the file first, we can recover if we can't open it. */
605     return OPE_CANNOT_OPEN;
606   }
607   ret = ope_continue_new_callbacks(enc, obj);
608   if (ret == OPE_OK) return ret;
609   fclose(obj->file);
610   free(obj);
611   return ret;
612 }
613
614 /* Ends the stream and create a new file (callback-based). */
615 int ope_continue_new_callbacks(OggOpusEnc *enc, void *user_data) {
616   EncStream *new_stream;
617   assert(enc->streams);
618   assert(enc->last_stream);
619   new_stream = stream_create();
620   if (!new_stream) return OPE_ALLOC_FAIL;
621   new_stream->user_data = user_data;
622   enc->last_stream->next = new_stream;
623   enc->last_stream = new_stream;
624   return OPE_OK;
625 }
626
627 /* Add a comment to the file (can only be called before encoding samples). */
628 int ope_add_comment(OggOpusEnc *enc, const char *tag, const char *val) {
629   if (enc->last_stream->header_is_frozen) return OPE_TOO_LATE;
630   if (enc->last_stream->stream_is_init) return OPE_TOO_LATE;
631   if (comment_add(&enc->last_stream->comment, &enc->last_stream->comment_length, tag, val)) return OPE_ALLOC_FAIL;
632   return OPE_OK;
633 }
634
635 int ope_add_picture(OggOpusEnc *enc, const char *spec) {
636   const char *error_message;
637   char *picture_data;
638   if (enc->last_stream->header_is_frozen) return OPE_TOO_LATE;
639   if (enc->last_stream->stream_is_init) return OPE_TOO_LATE;
640   picture_data = parse_picture_specification(spec, &error_message, &enc->last_stream->seen_file_icons);
641   if(picture_data==NULL){
642     /* FIXME: return proper errors rather than printing a message. */
643     fprintf(stderr,"Error parsing picture option: %s\n",error_message);
644     return OPE_BAD_ARG;
645   }
646   comment_add(&enc->last_stream->comment, &enc->last_stream->comment_length, "METADATA_BLOCK_PICTURE", picture_data);
647   free(picture_data);
648   return OPE_OK;
649 }
650
651 /* Sets the Opus comment vendor string (optional, defaults to library info). */
652 int ope_set_vendor_string(OggOpusEnc *enc, const char *vendor) {
653   if (enc->last_stream->header_is_frozen) return OPE_TOO_LATE;
654   if (enc->last_stream->stream_is_init) return OPE_TOO_LATE;
655   if (comment_replace_vendor_string(&enc->last_stream->comment, &enc->last_stream->comment_length, vendor)) return OPE_ALLOC_FAIL;
656   return OPE_OK;
657 }
658
659 int ope_flush_header(OggOpusEnc *enc) {
660   if (enc->last_stream->header_is_frozen) return OPE_TOO_LATE;
661   if (enc->last_stream->stream_is_init) return OPE_TOO_LATE;
662   else init_stream(enc);
663   return OPE_OK;
664 }
665
666 /* Goes straight to the libopus ctl() functions. */
667 int ope_encoder_ctl(OggOpusEnc *enc, int request, ...) {
668   int ret;
669   int translate;
670   va_list ap;
671   va_start(ap, request);
672   switch (request) {
673     case OPUS_SET_APPLICATION_REQUEST:
674     case OPUS_SET_BITRATE_REQUEST:
675     case OPUS_SET_MAX_BANDWIDTH_REQUEST:
676     case OPUS_SET_VBR_REQUEST:
677     case OPUS_SET_BANDWIDTH_REQUEST:
678     case OPUS_SET_COMPLEXITY_REQUEST:
679     case OPUS_SET_INBAND_FEC_REQUEST:
680     case OPUS_SET_PACKET_LOSS_PERC_REQUEST:
681     case OPUS_SET_DTX_REQUEST:
682     case OPUS_SET_VBR_CONSTRAINT_REQUEST:
683     case OPUS_SET_FORCE_CHANNELS_REQUEST:
684     case OPUS_SET_SIGNAL_REQUEST:
685     case OPUS_SET_LSB_DEPTH_REQUEST:
686     case OPUS_SET_PREDICTION_DISABLED_REQUEST:
687 #ifdef OPUS_SET_PHASE_INVERSION_DISABLED_REQUEST
688     case OPUS_SET_PHASE_INVERSION_DISABLED_REQUEST:
689 #endif
690     {
691       opus_int32 value = va_arg(ap, opus_int32);
692       ret = opus_multistream_encoder_ctl(enc->st, request, value);
693     }
694     break;
695     case OPUS_SET_EXPERT_FRAME_DURATION_REQUEST:
696     {
697       opus_int32 value = va_arg(ap, opus_int32);
698       int max_supported = OPUS_FRAMESIZE_60_MS;
699 #ifdef OPUS_FRAMESIZE_120_MS
700       max_supported = OPUS_FRAMESIZE_120_MS;
701 #endif
702       if (value < OPUS_FRAMESIZE_2_5_MS || value > max_supported) {
703         ret = OPUS_UNIMPLEMENTED;
704         break;
705       }
706       ret = opus_multistream_encoder_ctl(enc->st, request, value);
707       if (ret == OPUS_OK) {
708         if (value <= OPUS_FRAMESIZE_40_MS)
709           enc->frame_size = 120<<(value-OPUS_FRAMESIZE_2_5_MS);
710         else
711           enc->frame_size = (value-OPUS_FRAMESIZE_2_5_MS-2)*960;
712       }
713     }
714     break;
715     case OPUS_MULTISTREAM_GET_ENCODER_STATE_REQUEST:
716     {
717       opus_int32 stream_id;
718       OpusEncoder **value;
719       stream_id = va_arg(ap, opus_int32);
720       value = va_arg(ap, OpusEncoder**);
721       ret = opus_multistream_encoder_ctl(enc->st, request, stream_id, value);
722     }
723     break;
724
725     /* ****************** libopusenc-specific requests. ********************** */
726     case OPE_SET_DECISION_DELAY_REQUEST:
727     {
728       opus_int32 value = va_arg(ap, opus_int32);
729       if (value < 0) {
730         ret = OPE_BAD_ARG;
731         break;
732       }
733       enc->decision_delay = value;
734       ret = OPE_OK;
735     }
736     break;
737     case OPE_SET_MUXING_DELAY_REQUEST:
738     {
739       opus_int32 value = va_arg(ap, opus_int32);
740       if (value < 0) {
741         ret = OPE_BAD_ARG;
742         break;
743       }
744       enc->max_ogg_delay = value;
745       oggp_set_muxing_delay(enc->oggp, enc->max_ogg_delay);
746       ret = OPE_OK;
747     }
748     break;
749     case OPE_SET_COMMENT_PADDING_REQUEST:
750     {
751       opus_int32 value = va_arg(ap, opus_int32);
752       if (value < 0) {
753         ret = OPE_BAD_ARG;
754         break;
755       }
756       enc->comment_padding = value;
757       ret = OPE_OK;
758     }
759     break;
760     case OPE_SET_SERIALNO_REQUEST:
761     {
762       opus_int32 value = va_arg(ap, opus_int32);
763       if (enc->last_stream->header_is_frozen) return OPE_TOO_LATE;
764       enc->last_stream->serialno = value;
765       enc->last_stream->serialno_is_set = 1;
766       ret = OPE_OK;
767     }
768     case OPE_SET_PACKET_CALLBACK_REQUEST:
769     {
770       ope_packet_func value = va_arg(ap, ope_packet_func);
771       enc->packet_callback = value;
772       ret = OPE_OK;
773     }
774     break;
775     case OPE_SET_PAGE_CALLBACK_REQUEST:
776     {
777       ope_page_func value = va_arg(ap, ope_page_func);
778       enc->page_callback = value;
779       ret = OPE_OK;
780     }
781     break;
782     default:
783       return OPE_UNIMPLEMENTED;
784   }
785   va_end(ap);
786   translate = request < 14000 || (ret < 0 && ret >= -10);
787   if (translate) {
788     if (ret == OPUS_BAD_ARG) ret = OPE_BAD_ARG;
789     else if (ret == OPUS_INTERNAL_ERROR) ret = OPE_INTERNAL_ERROR;
790     else if (ret == OPUS_UNIMPLEMENTED) ret = OPE_UNIMPLEMENTED;
791     else if (ret == OPUS_ALLOC_FAIL) ret = OPE_ALLOC_FAIL;
792     else ret = OPE_INTERNAL_ERROR;
793   }
794   assert(ret == 0 || ret < -10);
795   return ret;
796 }