summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCarl Hetherington <cth@carlh.net>2022-10-24 20:37:02 +0200
committerCarl Hetherington <cth@carlh.net>2022-10-24 23:50:44 +0200
commit01a24fe341fcd6a7265e118806827f006d4f84f8 (patch)
tree04446ecc753842206b034a57bfcdbf395ceb0c62
parentf2e3522a9dcf7bd0a7a1f1073e45b4450e3b68f0 (diff)
Hopefully fix crash when the same frame is encoded twice.prores-debug
Previously if some frame X was passed to the encoder twice I think this would happen: X1 written; X stored to _pending_images X2 written; _pending_images remains the same X1 encode finishes; X is discarded from _pending_images Data for X2 is read by the encoder but was just freed I think this might have resulted in intermittent crashes, which were fairly common in the 2.17.x branch with the test ffmpeg_encoder_prores_regression_1 But I didn't conclusively prove it.
-rw-r--r--src/lib/ffmpeg_file_encoder.cc16
-rw-r--r--src/lib/ffmpeg_file_encoder.h5
2 files changed, 16 insertions, 5 deletions
diff --git a/src/lib/ffmpeg_file_encoder.cc b/src/lib/ffmpeg_file_encoder.cc
index 1294b9b3c..8045600fe 100644
--- a/src/lib/ffmpeg_file_encoder.cc
+++ b/src/lib/ffmpeg_file_encoder.cc
@@ -411,7 +411,13 @@ FFmpegFileEncoder::video (shared_ptr<PlayerVideo> video, DCPTime time)
{
boost::mutex::scoped_lock lm (_pending_images_mutex);
- _pending_images[image->data()[0]] = image;
+ auto key = image->data()[0];
+ auto iter = _pending_images.find(key);
+ if (iter != _pending_images.end()) {
+ iter->second.second++;
+ } else {
+ _pending_images[key] = { image, 1 };
+ }
}
for (int i = 0; i < 3; ++i) {
@@ -502,7 +508,11 @@ void
FFmpegFileEncoder::buffer_free2 (uint8_t* data)
{
boost::mutex::scoped_lock lm (_pending_images_mutex);
- if (_pending_images.find(data) != _pending_images.end()) {
- _pending_images.erase (data);
+ auto iter = _pending_images.find(data);
+ if (iter != _pending_images.end()) {
+ iter->second.second--;
+ if (iter->second.second == 0) {
+ _pending_images.erase(data);
+ }
}
}
diff --git a/src/lib/ffmpeg_file_encoder.h b/src/lib/ffmpeg_file_encoder.h
index 5bf501370..f0b3eac8c 100644
--- a/src/lib/ffmpeg_file_encoder.h
+++ b/src/lib/ffmpeg_file_encoder.h
@@ -106,9 +106,10 @@ private:
std::shared_ptr<AudioBuffers> _pending_audio;
/** Store of shared_ptr<Image> to keep them alive whilst raw pointers into
- their data have been passed to FFmpeg.
+ their data have been passed to FFmpeg. The second part of the pair is
+ a count of how many copies of the same key must be kept.
*/
- std::map<uint8_t*, std::shared_ptr<const Image>> _pending_images;
+ std::map<uint8_t*, std::pair<std::shared_ptr<const Image>, int>> _pending_images;
boost::mutex _pending_images_mutex;
static int _video_stream_index;