mirror of
https://github.com/brunoherbelin/vimix.git
synced 2025-12-16 12:49:59 +01:00
Bugfix generation image sequence
Fixed pb with non-power of two height of video, added more informative error messages, fixed UI issue.
This commit is contained in:
@@ -9,6 +9,7 @@
|
|||||||
#include "Log.h"
|
#include "Log.h"
|
||||||
#include "GstToolkit.h"
|
#include "GstToolkit.h"
|
||||||
#include "BaseToolkit.h"
|
#include "BaseToolkit.h"
|
||||||
|
#include "SystemToolkit.h"
|
||||||
#include "Settings.h"
|
#include "Settings.h"
|
||||||
#include "MediaPlayer.h"
|
#include "MediaPlayer.h"
|
||||||
|
|
||||||
@@ -130,7 +131,7 @@ bool MultiFileRecorder::start_record (const std::string &video_filename)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// create a gstreamer pipeline
|
// create a gstreamer pipeline
|
||||||
std::string description = "appsrc name=src ! queue ! videoconvert ! ";
|
std::string description = "appsrc name=src ! queue ! videoconvert ! videoscale ! ";
|
||||||
description += VideoRecorder::profile_description[ profile_ ];
|
description += VideoRecorder::profile_description[ profile_ ];
|
||||||
description += "qtmux ! filesink name=sink";
|
description += "qtmux ! filesink name=sink";
|
||||||
|
|
||||||
@@ -179,8 +180,8 @@ bool MultiFileRecorder::start_record (const std::string &video_filename)
|
|||||||
// specify recorder resolution and framerate in the source caps
|
// specify recorder resolution and framerate in the source caps
|
||||||
GstCaps *caps = gst_caps_new_simple ("video/x-raw",
|
GstCaps *caps = gst_caps_new_simple ("video/x-raw",
|
||||||
"format", G_TYPE_STRING, bpp_ < 4 ? "RGB" : "RGBA",
|
"format", G_TYPE_STRING, bpp_ < 4 ? "RGB" : "RGBA",
|
||||||
"width", G_TYPE_INT, width_,
|
"width", G_TYPE_INT, width_ - width_%2,
|
||||||
"height", G_TYPE_INT, height_,
|
"height", G_TYPE_INT, height_ - height_%2,
|
||||||
"framerate", GST_TYPE_FRACTION, fps_, 1,
|
"framerate", GST_TYPE_FRACTION, fps_, 1,
|
||||||
NULL);
|
NULL);
|
||||||
gst_app_src_set_caps (src_, caps );
|
gst_app_src_set_caps (src_, caps );
|
||||||
@@ -251,7 +252,7 @@ bool MultiFileRecorder::end_record ()
|
|||||||
// wait to receive end of stream
|
// wait to receive end of stream
|
||||||
GstMessage *msg = gst_bus_timed_pop_filtered(bus, GST_SECOND, GST_MESSAGE_EOS);
|
GstMessage *msg = gst_bus_timed_pop_filtered(bus, GST_SECOND, GST_MESSAGE_EOS);
|
||||||
if ( msg == NULL ) {
|
if ( msg == NULL ) {
|
||||||
Log::Warning("MultiFileRecorder: Failed to close recording.");
|
Log::Warning("MultiFileRecorder: could not close.");
|
||||||
ret = false;
|
ret = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -259,10 +260,16 @@ bool MultiFileRecorder::end_record ()
|
|||||||
GstStateChangeReturn r = gst_element_set_state (pipeline_, GST_STATE_NULL);
|
GstStateChangeReturn r = gst_element_set_state (pipeline_, GST_STATE_NULL);
|
||||||
if (r == GST_STATE_CHANGE_ASYNC) {
|
if (r == GST_STATE_CHANGE_ASYNC) {
|
||||||
gst_element_get_state (pipeline_, NULL, NULL, GST_SECOND);
|
gst_element_get_state (pipeline_, NULL, NULL, GST_SECOND);
|
||||||
g_print("... ASYNC END !\n");
|
// g_print("... ASYNC END !\n");
|
||||||
}
|
}
|
||||||
else if (r == GST_STATE_CHANGE_FAILURE) {
|
else if (r == GST_STATE_CHANGE_FAILURE) {
|
||||||
Log::Warning("MultiFileRecorder: Failed to end recording.");
|
Log::Warning("MultiFileRecorder: could not end properly.");
|
||||||
|
ret = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// invalidate if single frame
|
||||||
|
if (frame_count_ < 2) {
|
||||||
|
Log::Warning("MultiFileRecorder: a single image does not make a sequence.");
|
||||||
ret = false;
|
ret = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -311,7 +318,7 @@ bool MultiFileRecorder::finished ()
|
|||||||
|
|
||||||
std::string MultiFileRecorder::assemble (MultiFileRecorder *rec)
|
std::string MultiFileRecorder::assemble (MultiFileRecorder *rec)
|
||||||
{
|
{
|
||||||
std::string filename;
|
std::string filename = std::string();
|
||||||
|
|
||||||
// reset
|
// reset
|
||||||
rec->progress_ = 0.f;
|
rec->progress_ = 0.f;
|
||||||
@@ -329,20 +336,22 @@ std::string MultiFileRecorder::assemble (MultiFileRecorder *rec)
|
|||||||
stbi_info( rec->files_.front().c_str(), &rec->width_, &rec->height_, &rec->bpp_);
|
stbi_info( rec->files_.front().c_str(), &rec->width_, &rec->height_, &rec->bpp_);
|
||||||
|
|
||||||
if ( rec->width_ < 10 || rec->height_ < 10 || rec->bpp_ < 3 ) {
|
if ( rec->width_ < 10 || rec->height_ < 10 || rec->bpp_ < 3 ) {
|
||||||
Log::Warning("MultiFileRecorder: invalid image.");
|
Log::Warning("MultiFileRecorder: Invalid image %s.", rec->files_.front());
|
||||||
return filename;
|
return filename;
|
||||||
}
|
}
|
||||||
|
|
||||||
Log::Info("MultiFileRecorder creating video %d x %d : %d.", rec->width_, rec->height_, rec->bpp_);
|
|
||||||
|
|
||||||
// progress increment
|
// progress increment
|
||||||
float inc_ = 1.f / ( (float) rec->files_.size() + 2.f);
|
float inc_ = 1.f / ( (float) rec->files_.size() + 2.f);
|
||||||
|
|
||||||
// initialize
|
// initialize
|
||||||
rec->frame_count_ = 0;
|
rec->frame_count_ = 0;
|
||||||
filename = BaseToolkit::common_prefix (rec->files_);
|
filename = BaseToolkit::common_prefix (rec->files_);
|
||||||
|
if (!SystemToolkit::path_directory(filename).empty())
|
||||||
|
filename += "image";
|
||||||
filename += "_sequence.mov";
|
filename += "_sequence.mov";
|
||||||
|
|
||||||
|
Log::Info("MultiFileRecorder creating %s, %d x %d px.", filename.c_str(), rec->width_, rec->height_);
|
||||||
|
|
||||||
if ( rec->start_record( filename ) )
|
if ( rec->start_record( filename ) )
|
||||||
{
|
{
|
||||||
// progressing
|
// progressing
|
||||||
@@ -354,14 +363,11 @@ std::string MultiFileRecorder::assemble (MultiFileRecorder *rec)
|
|||||||
if ( rec->cancel_ )
|
if ( rec->cancel_ )
|
||||||
break;
|
break;
|
||||||
|
|
||||||
if ( rec->add_image( *file ) ) {
|
if ( rec->add_image( *file ) )
|
||||||
|
|
||||||
// validate file
|
// validate file
|
||||||
rec->frame_count_++;
|
rec->frame_count_++;
|
||||||
}
|
else
|
||||||
else {
|
Log::Info("MultiFileRecorder could not add %s.", file->c_str());
|
||||||
Log::Info("MultiFileRecorder could not include images %s.", file->c_str());
|
|
||||||
}
|
|
||||||
|
|
||||||
// pause in case appsrc buffer is full
|
// pause in case appsrc buffer is full
|
||||||
int max = 100;
|
int max = 100;
|
||||||
@@ -372,10 +378,15 @@ std::string MultiFileRecorder::assemble (MultiFileRecorder *rec)
|
|||||||
rec->progress_ += inc_;
|
rec->progress_ += inc_;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Give more explanation for possible errors
|
||||||
|
if ( rec->frame_count_ < rec->files_.size())
|
||||||
|
Log::Info("MultiFileRecorder not fully successful; are all images %d x %d px?",rec->width_, rec->height_);
|
||||||
|
|
||||||
// close file properly
|
// close file properly
|
||||||
if ( rec->end_record() ) {
|
if ( rec->end_record() )
|
||||||
Log::Info("MultiFileRecorder %d images encoded (%ld s), saved in %s.", rec->frame_count_, rec->timestamp_, filename.c_str());
|
Log::Info("MultiFileRecorder %d images encoded (%s).", rec->frame_count_, GstToolkit::time_to_string(rec->timestamp_, GstToolkit::TIME_STRING_READABLE).c_str());
|
||||||
}
|
else
|
||||||
|
filename = std::string();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
filename = std::string();
|
filename = std::string();
|
||||||
|
|||||||
@@ -6654,6 +6654,7 @@ void Navigator::RenderNewPannel()
|
|||||||
// clic button to load file
|
// clic button to load file
|
||||||
if ( ImGui::Button( ICON_FA_FOLDER_OPEN " Open images", ImVec2(ImGui::GetContentRegionAvail().x IMGUI_RIGHT_ALIGN, 0)) ) {
|
if ( ImGui::Button( ICON_FA_FOLDER_OPEN " Open images", ImVec2(ImGui::GetContentRegionAvail().x IMGUI_RIGHT_ALIGN, 0)) ) {
|
||||||
sourceSequenceFiles.clear();
|
sourceSequenceFiles.clear();
|
||||||
|
new_source_preview_.setSource();
|
||||||
_selectImagesDialog.open();
|
_selectImagesDialog.open();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -6737,7 +6738,7 @@ void Navigator::RenderNewPannel()
|
|||||||
if ( _video_recorder.finished() ) {
|
if ( _video_recorder.finished() ) {
|
||||||
// video recorder failed if it does not return a valid filename
|
// video recorder failed if it does not return a valid filename
|
||||||
if ( _video_recorder.filename().empty() )
|
if ( _video_recorder.filename().empty() )
|
||||||
Log::Warning("Failed to gemerate image sequence.");
|
Log::Warning("Failed to generate an image sequence.");
|
||||||
else {
|
else {
|
||||||
Log::Notify("Image sequence saved to %s.", _video_recorder.filename().c_str());
|
Log::Notify("Image sequence saved to %s.", _video_recorder.filename().c_str());
|
||||||
// open the file as new recording
|
// open the file as new recording
|
||||||
|
|||||||
Reference in New Issue
Block a user