Fix deadlock and segfault in stream

This commit is contained in:
badaix 2020-02-17 22:04:47 +01:00
parent 99e147c5aa
commit fd862f1bd6
2 changed files with 29 additions and 24 deletions

View file

@ -251,8 +251,9 @@ cs::time_point_clk Stream::getNextPlayerChunk(void* outputBuffer, unsigned long
frame_delta_ -= framesCorrection; frame_delta_ -= framesCorrection;
long toRead = frames + framesCorrection; long toRead = frames + framesCorrection;
char* buffer = new char[toRead * format_.frameSize]; if (toRead * format_.frameSize > read_buffer_.size())
cs::time_point_clk tp = getNextPlayerChunk(buffer, toRead); read_buffer_.resize(toRead * format_.frameSize);
cs::time_point_clk tp = getNextPlayerChunk(read_buffer_.data(), toRead);
const auto max = framesCorrection < 0 ? frames : toRead; const auto max = framesCorrection < 0 ? frames : toRead;
// Divide the buffer into one more slice than frames that need to be dropped. // Divide the buffer into one more slice than frames that need to be dropped.
@ -282,22 +283,19 @@ cs::time_point_clk Stream::getNextPlayerChunk(void* outputBuffer, unsigned long
{ {
// Read one frame less per slice from the input, but write a duplicated frame per slice to the output // Read one frame less per slice from the input, but write a duplicated frame per slice to the output
// LOG(TRACE, LOG_TAG) << "duplicate - requested: " << frames << ", read: " << toRead << ", slice: " << n << ", size: " << size << ", out pos: " << // LOG(TRACE, LOG_TAG) << "duplicate - requested: " << frames << ", read: " << toRead << ", slice: " << n << ", size: " << size << ", out pos: " <<
// pos << ", // pos << ", source pos: " << pos - n << "\n";
// source pos: " << pos - n << "\n"; memcpy(static_cast<char*>(outputBuffer) + pos * format_.frameSize, read_buffer_.data() + (pos - n) * format_.frameSize, size * format_.frameSize);
memcpy(static_cast<char*>(outputBuffer) + pos * format_.frameSize, buffer + (pos - n) * format_.frameSize, size * format_.frameSize);
} }
else else
{ {
// Read all input frames, but skip a frame per slice when writing to the output. // Read all input frames, but skip a frame per slice when writing to the output.
// LOG(TRACE, LOG_TAG) << "remove - requested: " << frames << ", read: " << toRead << ", slice: " << n << ", size: " << size << ", out pos: " << pos // LOG(TRACE, LOG_TAG) << "remove - requested: " << frames << ", read: " << toRead << ", slice: " << n << ", size: " << size << ", out pos: " << pos
// - n << // - n << ", source pos: " << pos << "\n";
// ", source pos: " << pos << "\n"; memcpy(static_cast<char*>(outputBuffer) + (pos - n) * format_.frameSize, read_buffer_.data() + pos * format_.frameSize, size * format_.frameSize);
memcpy(static_cast<char*>(outputBuffer) + (pos - n) * format_.frameSize, buffer + pos * format_.frameSize, size * format_.frameSize);
} }
pos += size; pos += size;
} }
delete[] buffer;
return tp; return tp;
} }
@ -378,13 +376,18 @@ bool Stream::getPlayerChunk(void* outputBuffer, const cs::usec& outputBufferDacT
// and the current chunk duration is 50ms, so we need to play 20ms silence (as we don't have data) // and the current chunk duration is 50ms, so we need to play 20ms silence (as we don't have data)
// and can play 30ms of the stream // and can play 30ms of the stream
size_t silent_frames = static_cast<size_t>(-chunk_->format.nsRate() * std::chrono::duration_cast<cs::nsec>(age).count()); size_t silent_frames = static_cast<size_t>(-chunk_->format.nsRate() * std::chrono::duration_cast<cs::nsec>(age).count());
bool result = (silent_frames <= frames);
silent_frames = std::min(silent_frames, frames);
LOG(DEBUG, LOG_TAG) << "Silent frames: " << silent_frames << ", frames: " << frames LOG(DEBUG, LOG_TAG) << "Silent frames: " << silent_frames << ", frames: " << frames
<< ", age: " << std::chrono::duration_cast<cs::usec>(age).count() / 1000. << "\n"; << ", age: " << std::chrono::duration_cast<cs::usec>(age).count() / 1000. << "\n";
getSilentPlayerChunk(outputBuffer, silent_frames); getSilentPlayerChunk(outputBuffer, silent_frames);
getNextPlayerChunk((char*)outputBuffer + (chunk_->format.frameSize * silent_frames), frames - silent_frames); getNextPlayerChunk((char*)outputBuffer + (chunk_->format.frameSize * silent_frames), frames - silent_frames);
if (result)
{
hard_sync_ = false; hard_sync_ = false;
resetBuffers(); resetBuffers();
}
return true; return true;
} }
return false; return false;
@ -472,6 +475,7 @@ bool Stream::getPlayerChunk(void* outputBuffer, const cs::usec& outputBufferDacT
catch (int e) catch (int e)
{ {
LOG(INFO) << "Exception\n"; LOG(INFO) << "Exception\n";
hard_sync_ = true;
return false; return false;
} }
} }

View file

@ -85,6 +85,7 @@ private:
soxr_t soxr_; soxr_t soxr_;
std::vector<char> resample_buffer_; std::vector<char> resample_buffer_;
std::vector<char> read_buffer_;
int frame_delta_; int frame_delta_;
// int64_t next_us_; // int64_t next_us_;