opusenc: only request and process 1 frame at a time
authorMark Nauwelaerts <mark.nauwelaerts@collabora.co.uk>
Wed, 7 Mar 2012 11:59:28 +0000 (12:59 +0100)
committerMark Nauwelaerts <mark.nauwelaerts@collabora.co.uk>
Wed, 7 Mar 2012 12:03:14 +0000 (13:03 +0100)
... since it is specified in _finish_frame that input buffer may be invalidated
after calling it, and is as such not reliably available for further encoding.

Also, requesting or allowing several frames is only useful if subclass intends
to process these "in 1 run" (as in, 1 output buffer), not for having another
(inner) loop in subclass where the baseclass one will do just fine.

ext/opus/gstopusenc.c

index a87e08b3f741dd0b956422b8c00d4d68546a9421..6a19ffd89f8c6319d5b5254604542b3c8b6116f4 100644 (file)
@@ -384,7 +384,7 @@ gst_opus_enc_setup_base_class (GstOpusEnc * enc, GstAudioEncoder * benc)
       gst_opus_enc_get_latency (enc), gst_opus_enc_get_latency (enc));
   gst_audio_encoder_set_frame_samples_min (benc, enc->frame_samples);
   gst_audio_encoder_set_frame_samples_max (benc, enc->frame_samples);
-  gst_audio_encoder_set_frame_max (benc, 0);
+  gst_audio_encoder_set_frame_max (benc, 1);
 }
 
 static gint
@@ -792,6 +792,8 @@ gst_opus_enc_encode (GstOpusEnc * enc, GstBuffer * buf)
   gsize bsize, size;
   gsize bytes;
   gint ret = GST_FLOW_OK;
+  gint outsize;
+  GstBuffer *outbuf;
 
   g_mutex_lock (enc->property_lock);
 
@@ -816,51 +818,41 @@ gst_opus_enc_encode (GstOpusEnc * enc, GstBuffer * buf)
     goto done;
   }
 
+  g_assert (size == bytes);
 
-  while (size) {
-    gint outsize;
-    GstBuffer *outbuf;
+  ret = gst_pad_alloc_buffer_and_set_caps (GST_AUDIO_ENCODER_SRC_PAD (enc),
+      GST_BUFFER_OFFSET_NONE, enc->max_payload_size * enc->n_channels,
+      GST_PAD_CAPS (GST_AUDIO_ENCODER_SRC_PAD (enc)), &outbuf);
 
-    ret = gst_pad_alloc_buffer_and_set_caps (GST_AUDIO_ENCODER_SRC_PAD (enc),
-        GST_BUFFER_OFFSET_NONE, enc->max_payload_size * enc->n_channels,
-        GST_PAD_CAPS (GST_AUDIO_ENCODER_SRC_PAD (enc)), &outbuf);
-
-    if (GST_FLOW_OK != ret)
-      goto done;
-
-    GST_DEBUG_OBJECT (enc, "encoding %d samples (%d bytes)",
-        enc->frame_samples, (int) bytes);
-
-    outsize =
-        opus_multistream_encode (enc->state, (const gint16 *) data,
-        enc->frame_samples, GST_BUFFER_DATA (outbuf),
-        enc->max_payload_size * enc->n_channels);
+  if (GST_FLOW_OK != ret)
+    goto done;
 
-    if (outsize < 0) {
-      GST_ERROR_OBJECT (enc, "Encoding failed: %d", outsize);
-      ret = GST_FLOW_ERROR;
-      goto done;
-    } else if (outsize > enc->max_payload_size) {
-      GST_WARNING_OBJECT (enc,
-          "Encoded size %d is higher than max payload size (%d bytes)",
-          outsize, enc->max_payload_size);
-      ret = GST_FLOW_ERROR;
-      goto done;
-    }
+  GST_DEBUG_OBJECT (enc, "encoding %d samples (%d bytes)",
+      enc->frame_samples, (int) bytes);
 
-    GST_DEBUG_OBJECT (enc, "Output packet is %u bytes", outsize);
-    GST_BUFFER_SIZE (outbuf) = outsize;
+  outsize =
+      opus_multistream_encode (enc->state, (const gint16 *) data,
+      enc->frame_samples, GST_BUFFER_DATA (outbuf),
+      enc->max_payload_size * enc->n_channels);
 
-    ret =
-        gst_audio_encoder_finish_frame (GST_AUDIO_ENCODER (enc), outbuf,
-        enc->frame_samples);
+  if (outsize < 0) {
+    GST_ERROR_OBJECT (enc, "Encoding failed: %d", outsize);
+    ret = GST_FLOW_ERROR;
+    goto done;
+  } else if (outsize > enc->max_payload_size) {
+    GST_WARNING_OBJECT (enc,
+        "Encoded size %d is higher than max payload size (%d bytes)",
+        outsize, enc->max_payload_size);
+    ret = GST_FLOW_ERROR;
+    goto done;
+  }
 
-    if ((GST_FLOW_OK != ret) && (GST_FLOW_NOT_LINKED != ret))
-      goto done;
+  GST_DEBUG_OBJECT (enc, "Output packet is %u bytes", outsize);
+  GST_BUFFER_SIZE (outbuf) = outsize;
 
-    data += bytes;
-    size -= bytes;
-  }
+  ret =
+      gst_audio_encoder_finish_frame (GST_AUDIO_ENCODER (enc), outbuf,
+      enc->frame_samples);
 
 done: