diff options
| author | Carl Hetherington <cth@carlh.net> | 2022-11-06 23:44:33 +0100 |
|---|---|---|
| committer | Carl Hetherington <cth@carlh.net> | 2022-11-06 23:44:33 +0100 |
| commit | 9b94bc2c884289cc0b5125e918a115a342a12ff2 (patch) | |
| tree | c097825581459a6a7565f993045765858e02c4fa | |
| parent | c42ce0e5b188d6fe0b022f1aec4fdcb04c4835f1 (diff) | |
Extract ImageStore.
| -rw-r--r-- | src/lib/ffmpeg_file_encoder.cc | 34 | ||||
| -rw-r--r-- | src/lib/ffmpeg_file_encoder.h | 11 | ||||
| -rw-r--r-- | src/lib/image_store.cc | 66 | ||||
| -rw-r--r-- | src/lib/image_store.h | 51 | ||||
| -rw-r--r-- | src/lib/wscript | 1 |
5 files changed, 121 insertions, 42 deletions
diff --git a/src/lib/ffmpeg_file_encoder.cc b/src/lib/ffmpeg_file_encoder.cc index 791edb9bc..fe39c6b2e 100644 --- a/src/lib/ffmpeg_file_encoder.cc +++ b/src/lib/ffmpeg_file_encoder.cc @@ -411,18 +411,7 @@ FFmpegFileEncoder::video (shared_ptr<PlayerVideo> video, DCPTime time) DCPOMATIC_ASSERT (frame); for (int i = 0; i < 3; ++i) { - { - boost::mutex::scoped_lock lm (_pending_images_mutex); - auto key = image->data()[i]; - auto iter = _pending_images.find(key); - if (iter != _pending_images.end()) { - iter->second.second++; - } else { - _pending_images[key] = { image, 1 }; - } - } - - auto buffer = av_buffer_create(image->data()[i], image->stride()[i] * image->size().height, &buffer_free, this, 0); + auto buffer = _pending_images.create_buffer(image, i); frame->buf[i] = av_buffer_ref (buffer); frame->data[i] = buffer->data; frame->linesize[i] = image->stride()[i]; @@ -496,24 +485,3 @@ FFmpegFileEncoder::subtitle (PlayerText, DCPTimePeriod) { } - - -void -FFmpegFileEncoder::buffer_free (void* opaque, uint8_t* data) -{ - reinterpret_cast<FFmpegFileEncoder*>(opaque)->buffer_free2(data); -} - - -void -FFmpegFileEncoder::buffer_free2 (uint8_t* data) -{ - boost::mutex::scoped_lock lm (_pending_images_mutex); - 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 f0b3eac8c..78840d6a8 100644 --- a/src/lib/ffmpeg_file_encoder.h +++ b/src/lib/ffmpeg_file_encoder.h @@ -27,6 +27,7 @@ #include "dcpomatic_time.h" #include "encoder.h" #include "event_history.h" +#include "image_store.h" #include "log.h" #include <dcp/key.h> #include <dcp/warnings.h> @@ -80,9 +81,6 @@ private: void audio_frame (int size); - static void buffer_free(void* opaque, uint8_t* data); - void buffer_free2(uint8_t* data); - AVCodec const * _video_codec = nullptr; AVCodecContext* _video_codec_context = nullptr; std::vector<std::shared_ptr<ExportAudioStream>> _audio_streams; @@ -105,12 +103,7 @@ 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. 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::pair<std::shared_ptr<const Image>, int>> _pending_images; - boost::mutex _pending_images_mutex; + ImageStore _pending_images; static int _video_stream_index; static int _audio_stream_index_base; diff --git a/src/lib/image_store.cc b/src/lib/image_store.cc new file mode 100644 index 000000000..6c40e34f8 --- /dev/null +++ b/src/lib/image_store.cc @@ -0,0 +1,66 @@ +/* + Copyright (C) 2017-2018 Carl Hetherington <cth@carlh.net> + + This file is part of DCP-o-matic. + + DCP-o-matic is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + DCP-o-matic is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with DCP-o-matic. If not, see <http://www.gnu.org/licenses/>. + +*/ + + +#include "image.h" +#include "image_store.h" +extern "C" { +#include <libavutil/buffer.h> +} + + +using std::shared_ptr; + + +void +ImageStore::buffer_free(void* opaque, uint8_t* data) +{ + reinterpret_cast<ImageStore*>(opaque)->buffer_free2(data); +} + + +void +ImageStore::buffer_free2(uint8_t* data) +{ + boost::mutex::scoped_lock lm(_mutex); + auto iter = _images.find(data); + if (iter != _images.end()) { + iter->second.second--; + if (iter->second.second == 0) { + _images.erase(data); + } + } +} + + +AVBufferRef* +ImageStore::create_buffer(shared_ptr<const Image> image, int component) +{ + boost::mutex::scoped_lock lm(_mutex); + auto key = image->data()[component]; + auto iter = _images.find(key); + if (iter != _images.end()) { + iter->second.second++; + } else { + _images[key] = { image, 1 }; + } + + return av_buffer_create(image->data()[component], image->stride()[component] * image->size().height, &buffer_free, this, 0); +} diff --git a/src/lib/image_store.h b/src/lib/image_store.h new file mode 100644 index 000000000..ebe115453 --- /dev/null +++ b/src/lib/image_store.h @@ -0,0 +1,51 @@ +/* + Copyright (C) 2017-2018 Carl Hetherington <cth@carlh.net> + + This file is part of DCP-o-matic. + + DCP-o-matic is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + DCP-o-matic is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with DCP-o-matic. If not, see <http://www.gnu.org/licenses/>. + +*/ + + +#include <boost/thread.hpp> +#include <map> + + +class AVBufferRef; +class Image; + + +/** Store of shared_ptr<Image> to keep them alive whilst raw pointers into + * 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. + */ +class ImageStore +{ +public: + ImageStore() {} + + ImageStore(ImageStore const&) = delete; + ImageStore& operator=(ImageStore const&) = delete; + + AVBufferRef* create_buffer(std::shared_ptr<const Image>, int component); + +private: + + static void buffer_free(void* opaque, uint8_t* data); + void buffer_free2(uint8_t* data); + + std::map<uint8_t*, std::pair<std::shared_ptr<const Image>, int>> _images; + boost::mutex _mutex; +}; diff --git a/src/lib/wscript b/src/lib/wscript index d3aec7769..cf97623f9 100644 --- a/src/lib/wscript +++ b/src/lib/wscript @@ -130,6 +130,7 @@ sources = """ image_jpeg.cc image_png.cc image_proxy.cc + image_store.cc j2k_image_proxy.cc job.cc job_manager.cc |
