aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorAndrée Ekroth <andree.ekroth@gmail.com>2014-01-13 22:25:41 +0100
committerAndrée Ekroth <andree.ekroth@gmail.com>2014-01-13 22:28:29 +0100
commitcd5817b67e89d4f47546809ad0299bdec1823147 (patch)
treecf5e12dc9887fc6faec4306f627308d991f48d20 /src
parent56a7fcf189b904a9d1f6e96f7efa0233c742190a (diff)
downloadmpd-cd5817b67e89d4f47546809ad0299bdec1823147.tar.gz
mpd-cd5817b67e89d4f47546809ad0299bdec1823147.tar.xz
mpd-cd5817b67e89d4f47546809ad0299bdec1823147.zip
encoder/shine: fix segfault workaround
Initializing and closing the Shine library without writing any data results in a segmentation fault. The current workaround writes zeroes if there was no actual data.
Diffstat (limited to 'src')
-rw-r--r--src/encoder/ShineEncoderPlugin.cxx22
1 files changed, 17 insertions, 5 deletions
diff --git a/src/encoder/ShineEncoderPlugin.cxx b/src/encoder/ShineEncoderPlugin.cxx
index 3097810b9..39e400a58 100644
--- a/src/encoder/ShineEncoderPlugin.cxx
+++ b/src/encoder/ShineEncoderPlugin.cxx
@@ -57,7 +57,7 @@ struct ShineEncoder {
bool Setup(Error &error);
- bool WriteChunk(bool flush, Error &error);
+ bool WriteChunk(bool flush);
};
static constexpr Domain shine_encoder_domain("shine_encoder");
@@ -142,7 +142,9 @@ shine_encoder_open(Encoder *_encoder, AudioFormat &audio_format, Error &error)
encoder->stereo[0] = new int16_t[encoder->frame_size];
encoder->stereo[1] = new int16_t[encoder->frame_size];
- encoder->input_pos = 0;
+ /* workaround for bug:
+ https://github.com/savonet/shine/issues/11 */
+ encoder->input_pos = SHINE_MAX_SAMPLES + 1;
encoder->output_buffer.Construct(BUFFER_INIT_SIZE);
@@ -154,6 +156,12 @@ shine_encoder_close(Encoder *_encoder)
{
ShineEncoder *encoder = (ShineEncoder *)_encoder;
+ if (encoder->input_pos > SHINE_MAX_SAMPLES) {
+ /* write zero chunk */
+ encoder->input_pos = 0;
+ encoder->WriteChunk(true);
+ }
+
shine_close(encoder->shine);
delete[] encoder->stereo[0];
delete[] encoder->stereo[1];
@@ -161,7 +169,7 @@ shine_encoder_close(Encoder *_encoder)
}
bool
-ShineEncoder::WriteChunk(bool flush, gcc_unused Error &error)
+ShineEncoder::WriteChunk(bool flush)
{
if (flush || input_pos == frame_size) {
long written;
@@ -195,6 +203,10 @@ shine_encoder_write(Encoder *_encoder,
length /= sizeof(*data) * encoder->audio_format.channels;
size_t written = 0;
+ if (encoder->input_pos > SHINE_MAX_SAMPLES) {
+ encoder->input_pos = 0;
+ }
+
/* write all data to de-interleaved buffers */
while (written < length) {
for (;
@@ -207,7 +219,7 @@ shine_encoder_write(Encoder *_encoder,
encoder->stereo[1][encoder->input_pos] = data[base + 1];
}
/* write if chunk is filled */
- encoder->WriteChunk(false, error);
+ encoder->WriteChunk(false);
}
return true;
@@ -220,7 +232,7 @@ shine_encoder_flush(Encoder *_encoder, gcc_unused Error &error)
long written;
/* flush buffers and flush shine */
- encoder->WriteChunk(true, error);
+ encoder->WriteChunk(true);
const uint8_t *data = shine_flush(encoder->shine, &written);
if (written > 0)