Move intialization from constructor to internalInitialize and create a member variable that keeps track of initialization

This commit is contained in:
Ylva Selling
2022-10-03 17:05:17 -04:00
parent 2737679da2
commit 03a8e58955
2 changed files with 88 additions and 84 deletions
@@ -89,88 +89,7 @@ FfmpegTileProvider::FfmpegTileProvider(const ghoul::Dictionary& dictionary) {
_videoFile = p.file;
_startTime = p.startTime;
std::string path = absPath(_videoFile).string();
// Open video
int openRes = avformat_open_input(
&_formatContext,
path.c_str(),
nullptr,
nullptr
);
if (openRes < 0) {
throw ghoul::RuntimeError(fmt::format("Failed to open input for file {}", path));
}
// Find stream info
if (avformat_find_stream_info(_formatContext, nullptr) < 0) {
throw ghoul::RuntimeError(fmt::format("Failed to get stream info for {}", path));
}
// DEBUG dump info
av_dump_format(_formatContext, 0, path.c_str(), false);
// Find the video stream
for (unsigned int i = 0; i < _formatContext->nb_streams; ++i) {
AVMediaType codec = _formatContext->streams[i]->codecpar->codec_type;
if (codec == AVMEDIA_TYPE_VIDEO) {
_streamIndex = i;
_videoStream = _formatContext->streams[_streamIndex];
break;
}
}
if (_streamIndex == -1 || _videoStream == nullptr) {
throw ghoul::RuntimeError(fmt::format("Failed to find video stream for {}", path));
}
// Find decoder
_decoder = avcodec_find_decoder(_videoStream->codecpar->codec_id);
if (!_decoder) {
throw ghoul::RuntimeError(fmt::format("Failed to find decoder for {}", path));
}
// Find codec
_codecContext = avcodec_alloc_context3(nullptr);
int contextSuccess = avcodec_parameters_to_context(
_codecContext,
_videoStream->codecpar
);
if (contextSuccess < 0) {
throw ghoul::RuntimeError(
fmt::format("Failed to create codec context for {}", path)
);
}
// Open the decoder
if (avcodec_open2(_codecContext, _decoder, nullptr) < 0) {
throw ghoul::RuntimeError(fmt::format("Failed to open codec for {}", path));
}
// Allocate the video frames
_packet = av_packet_alloc();
_avFrame = av_frame_alloc(); // Raw frame
_glFrame = av_frame_alloc(); // Color-converted frame
// Fill the destination frame for the convertion
int glFrameSize = av_image_get_buffer_size(
AV_PIX_FMT_RGB24,
FinalResolution.x,
FinalResolution.y,
1
);
uint8_t* internalBuffer =
reinterpret_cast<uint8_t*>(av_malloc(glFrameSize * sizeof(uint8_t)));
av_image_fill_arrays(
_glFrame->data,
_glFrame->linesize,
internalBuffer,
AV_PIX_FMT_RGB24,
FinalResolution.x,
FinalResolution.y,
1
);
// Update times
_lastFrameTime = std::chrono::system_clock::now();
}
Tile FfmpegTileProvider::tile(const TileIndex& tileIndex) {
@@ -264,6 +183,9 @@ TileDepthTransform FfmpegTileProvider::depthTransform() {
void FfmpegTileProvider::update() {
ZoneScoped
if (!_isInitialized) {
return;
}
// Check if it is time for a new frame
std::chrono::system_clock::time_point now = std::chrono::system_clock::now();
std::chrono::system_clock::duration diff = now - _lastFrameTime;
@@ -401,8 +323,89 @@ float FfmpegTileProvider::noDataValueAsFloat() {
}
void FfmpegTileProvider::internalInitialize() {
// TODO: Currently the update function is called before this
// function - fix that and then move constructor code here
std::string path = absPath(_videoFile).string();
// Open video
int openRes = avformat_open_input(
&_formatContext,
path.c_str(),
nullptr,
nullptr
);
if (openRes < 0) {
throw ghoul::RuntimeError(fmt::format("Failed to open input for file {}", path));
}
// Find stream info
if (avformat_find_stream_info(_formatContext, nullptr) < 0) {
throw ghoul::RuntimeError(fmt::format("Failed to get stream info for {}", path));
}
// DEBUG dump info
av_dump_format(_formatContext, 0, path.c_str(), false);
// Find the video stream
for (unsigned int i = 0; i < _formatContext->nb_streams; ++i) {
AVMediaType codec = _formatContext->streams[i]->codecpar->codec_type;
if (codec == AVMEDIA_TYPE_VIDEO) {
_streamIndex = i;
_videoStream = _formatContext->streams[_streamIndex];
break;
}
}
if (_streamIndex == -1 || _videoStream == nullptr) {
throw ghoul::RuntimeError(fmt::format("Failed to find video stream for {}", path));
}
// Find decoder
_decoder = avcodec_find_decoder(_videoStream->codecpar->codec_id);
if (!_decoder) {
throw ghoul::RuntimeError(fmt::format("Failed to find decoder for {}", path));
}
// Find codec
_codecContext = avcodec_alloc_context3(nullptr);
int contextSuccess = avcodec_parameters_to_context(
_codecContext,
_videoStream->codecpar
);
if (contextSuccess < 0) {
throw ghoul::RuntimeError(
fmt::format("Failed to create codec context for {}", path)
);
}
// Open the decoder
if (avcodec_open2(_codecContext, _decoder, nullptr) < 0) {
throw ghoul::RuntimeError(fmt::format("Failed to open codec for {}", path));
}
// Allocate the video frames
_packet = av_packet_alloc();
_avFrame = av_frame_alloc(); // Raw frame
_glFrame = av_frame_alloc(); // Color-converted frame
// Fill the destination frame for the convertion
int glFrameSize = av_image_get_buffer_size(
AV_PIX_FMT_RGB24,
FinalResolution.x,
FinalResolution.y,
1
);
uint8_t* internalBuffer =
reinterpret_cast<uint8_t*>(av_malloc(glFrameSize * sizeof(uint8_t)));
av_image_fill_arrays(
_glFrame->data,
_glFrame->linesize,
internalBuffer,
AV_PIX_FMT_RGB24,
FinalResolution.x,
FinalResolution.y,
1
);
// Update times
_lastFrameTime = std::chrono::system_clock::now();
_isInitialized = true;
}
FfmpegTileProvider::~FfmpegTileProvider() {
@@ -69,6 +69,7 @@ private:
std::chrono::system_clock::time_point _lastFrameTime;
std::string _startTime;
bool _tileIsReady = false;
bool _isInitialized = false;
AVFormatContext* _formatContext = nullptr;
AVCodecContext* _codecContext = nullptr;