shithub: libopusenc

Download patch

ref: 83af4e1b1af6f3575e038aff8c704b9f6a1478cd
parent: 4b7cc4e78aaf63bf3ac16e6ab1d62d8094517023
author: Jean-Marc Valin <jmvalin@jmvalin.ca>
date: Tue May 2 11:08:54 EDT 2017

Applying comments to the last created stream

--- a/src/opusenc.c
+++ b/src/opusenc.c
@@ -87,6 +87,7 @@
   int comment_length;
   int seen_file_icons;
   int close_at_end;
+  int header_is_frozen;
   ogg_int64_t end_granule;
   EncStream *next;
 };
@@ -172,6 +173,7 @@
   stream->serialno_is_set = 0;
   stream->seen_file_icons = 0;
   stream->stream_is_init = 0;
+  stream->header_is_frozen = 0;
   stream->comment = NULL;
   comment_init(&stream->comment, &stream->comment_length, opus_get_version_string());
   if (!stream->comment) goto fail;
@@ -385,6 +387,7 @@
 /* Add/encode any number of float samples to the file. */
 int ope_write_float(OggOpusEnc *enc, const float *pcm, int samples_per_channel) {
   int channels = enc->channels;
+  enc->last_stream->header_is_frozen = 1;
   if (!enc->streams->stream_is_init) init_stream(enc);
   if (samples_per_channel < 0) return OPE_BAD_ARG;
   enc->write_granule += samples_per_channel;
@@ -417,6 +420,7 @@
 /* Add/encode any number of int16 samples to the file. */
 int ope_write(OggOpusEnc *enc, const opus_int16 *pcm, int samples_per_channel) {
   int channels = enc->channels;
+  enc->last_stream->header_is_frozen = 1;
   if (!enc->streams->stream_is_init) init_stream(enc);
   if (samples_per_channel < 0) return OPE_BAD_ARG;
   enc->write_granule += samples_per_channel;
@@ -487,15 +491,21 @@
 
 /* Ends the stream and create a new file (callback-based). */
 int ope_continue_new_callbacks(OggOpusEnc *enc, void *user_data) {
-  (void)enc;
-  (void)user_data;
+  EncStream *new_stream;
+  assert(enc->streams);
+  assert(enc->last_stream);
+  new_stream = stream_create();
+  new_stream->user_data = user_data;
+  enc->last_stream->next = new_stream;
+  enc->last_stream = new_stream;
   return OPE_UNIMPLEMENTED;
 }
 
 /* Add a comment to the file (can only be called before encoding samples). */
 int ope_add_comment(OggOpusEnc *enc, const char *tag, const char *val) {
-  if (enc->streams->stream_is_init) return OPE_TOO_LATE;
-  if (comment_add(&enc->streams->comment, &enc->streams->comment_length, tag, val)) return OPE_INTERNAL_ERROR;
+  if (enc->last_stream->header_is_frozen) return OPE_TOO_LATE;
+  if (enc->last_stream->stream_is_init) return OPE_TOO_LATE;
+  if (comment_add(&enc->last_stream->comment, &enc->last_stream->comment_length, tag, val)) return OPE_INTERNAL_ERROR;
   return OPE_OK;
 }
 
@@ -502,14 +512,15 @@
 int ope_add_picture(OggOpusEnc *enc, const char *spec) {
   const char *error_message;
   char *picture_data;
-  if (enc->streams->stream_is_init) return OPE_TOO_LATE;
-  picture_data = parse_picture_specification(spec, &error_message, &enc->streams->seen_file_icons);
+  if (enc->last_stream->header_is_frozen) return OPE_TOO_LATE;
+  if (enc->last_stream->stream_is_init) return OPE_TOO_LATE;
+  picture_data = parse_picture_specification(spec, &error_message, &enc->last_stream->seen_file_icons);
   if(picture_data==NULL){
     /* FIXME: return proper errors rather than printing a message. */
     fprintf(stderr,"Error parsing picture option: %s\n",error_message);
     return OPE_BAD_ARG;
   }
-  comment_add(&enc->streams->comment, &enc->streams->comment_length, "METADATA_BLOCK_PICTURE", picture_data);
+  comment_add(&enc->last_stream->comment, &enc->last_stream->comment_length, "METADATA_BLOCK_PICTURE", picture_data);
   free(picture_data);
   return OPE_OK;
 }
@@ -516,13 +527,15 @@
 
 /* Sets the Opus comment vendor string (optional, defaults to library info). */
 int ope_set_vendor_string(OggOpusEnc *enc, const char *vendor) {
-  if (enc->streams->stream_is_init) return OPE_TOO_LATE;
+  if (enc->last_stream->header_is_frozen) return OPE_TOO_LATE;
+  if (enc->last_stream->stream_is_init) return OPE_TOO_LATE;
   (void)vendor;
   return OPE_UNIMPLEMENTED;
 }
 
 int ope_flush_header(OggOpusEnc *enc) {
-  if (enc->streams->stream_is_init) return OPE_TOO_LATE;
+  if (enc->last_stream->header_is_frozen) return OPE_TOO_LATE;
+  if (enc->last_stream->stream_is_init) return OPE_TOO_LATE;
   else init_stream(enc);
   return OPE_OK;
 }
@@ -624,8 +637,9 @@
     case OPE_SET_SERIALNO_REQUEST:
     {
       opus_int32 value = va_arg(ap, opus_int32);
-      enc->streams->serialno = value;
-      enc->streams->serialno_is_set = 1;
+      if (enc->last_stream->header_is_frozen) return OPE_TOO_LATE;
+      enc->last_stream->serialno = value;
+      enc->last_stream->serialno_is_set = 1;
       ret = OPE_OK;
     }
     break;