Mercurial > hg > aimc
diff trunk/src/Modules/Output/Graphics/Devices/GraphicsOutputDeviceMovie.cc @ 411:a908972d234e
- Added support for movies!
author | tomwalters |
---|---|
date | Thu, 21 Oct 2010 01:46:39 +0000 |
parents | 69466da9745e |
children | b6d5c0cc1849 |
line wrap: on
line diff
--- a/trunk/src/Modules/Output/Graphics/Devices/GraphicsOutputDeviceMovie.cc Tue Oct 19 19:48:37 2010 +0000 +++ b/trunk/src/Modules/Output/Graphics/Devices/GraphicsOutputDeviceMovie.cc Thu Oct 21 01:46:39 2010 +0000 @@ -50,84 +50,90 @@ namespace aimc { -GraphicsOutputDeviceMovie::GraphicsOutputDeviceMovie(Parameters *pParam) - : GraphicsOutputDeviceCairo(pParam) { // or GraphicsOutputDevicePlotutils - m_sMovieFile[0] = '\0'; - m_sSoundFile[0] = '\0'; +GraphicsOutputDeviceMovie::GraphicsOutputDeviceMovie(Parameters *parameters) + : GraphicsOutputDeviceCairo(parameters) { + sound_filename_.clear(); + movie_filename_.clear(); } -bool GraphicsOutputDeviceMovie::Initialize(const char *sSoundFile, - const char *sMovieFile) { +bool GraphicsOutputDeviceMovie::Initialize(Parameters *global_parameters) { + global_parameters_ = global_parameters; + sound_filename_ = global_parameters->GetString("input_filename"); + string file_suffix = parameters_->DefaultString("filename_suffix", ".mov"); + movie_filename_ = global_parameters->GetString("output_filename_base") + + file_suffix; + FILE *f; - AIM_ASSERT(sSoundFile); - AIM_ASSERT(sMovieFile); // Check sound file exists - if ((f = fopen(sSoundFile, "r")) == NULL) { + if ((f = fopen(sound_filename_.c_str(), "r")) == NULL) { LOG_ERROR(_T("Couldn't open sound file '%s' for movie creation."), - sSoundFile); + sound_filename_.c_str()); + sound_filename_.clear(); return false; } fclose(f); - strcpy(m_sSoundFile, sSoundFile); // Check movie output file can be made - if ( (f=fopen(sMovieFile, "w"))==NULL ) { + if ((f = fopen(movie_filename_.c_str(), "w")) == NULL) { LOG_ERROR(_T("Couldn't open movie file '%s' to write to."), - sMovieFile); + movie_filename_.c_str()); + movie_filename_.clear(); return false; } fclose(f); - strcpy(m_sMovieFile, sMovieFile); // Get a temporary image output directory //! \warning Not really safe ... but windows has no mkdtemp() //! \todo Make build system check for mkdtemp() to use it when available. See TODO.txt. - char *sTmpDir = NULL; #ifdef _WINDOWS - if ((sTmpDir = _tempnam(NULL, AIM_NAME)) - && _mkdir(sTmpDir) >= 0) { - strcpy(m_sDir, sTmpDir); - strcat(m_sDir, "\\"); // Make sure to end with trailing slash - } else -#else - strcpy(m_sDir, "/tmp/"AIM_NAME"-movie.XXXXXX"); - if (mkdtemp(m_sDir)) { - strcat(m_sDir, "/"); // Make sure to end with trailing slash - } else -#endif - { + char *temp_dir = NULL; + if ((temp_dir = _tempnam(NULL, AIM_NAME)) + && _mkdir(temp_dir) >= 0) { + directory_ = temp_dir; + directory_ += "\\"; // Make sure to end with trailing slash + } else { LOG_ERROR(_T("Couldn't create a temporary directory for movie output.")); - if (sTmpDir) free(sTmpDir); + if (temp_dir) { + free(temp_dir); + } return false; } - if (sTmpDir) { - free(sTmpDir); + if (temp_dir) { + free(temp_dir); } - - // We want png for movie conversion - //! \bug This may change the user preference in GUI, hmm what to do? See TODO.txt - m_pParam->SetString("output.img.format", "png"); - //if ( !GraphicsOutputDevicePlotutils::Initialize(m_sDir) ) { - if ( !GraphicsOutputDeviceCairo::Initialize(m_sDir) ) { +#else + char temp_dir[PATH_MAX]; + strcpy(temp_dir, "/tmp/"AIM_NAME"-movie.XXXXXX"); + if (mkdtemp(temp_dir)) { + directory_ = temp_dir; + directory_ += "/"; // Make sure to end with trailing slash + } else { + LOG_ERROR(_T("Couldn't create a temporary directory for movie output.")); return false; } - +#endif + + // We want png for movie conversion + parameters_->SetString("output.img.format", "png"); + if ( !GraphicsOutputDeviceCairo::Initialize(directory_) ) { + return false; + } return true; } void GraphicsOutputDeviceMovie::Start() { - //GraphicsOutputDevicePlotutils::Start(); GraphicsOutputDeviceCairo::Start(); - // Just output a single frame to get audio/video in sync, put params in there + // Output a couple of frames to get audio/video in sync, put params in there. + gGrab(); + PlotParameterScreen(); + gRelease(); gGrab(); PlotParameterScreen(); gRelease(); } void GraphicsOutputDeviceMovie::Stop() { - // Make sure Plotutils is really done writing. - //GraphicsOutputDevicePlotutils::Stop(); GraphicsOutputDeviceCairo::Stop(); CloseFile(); @@ -136,33 +142,28 @@ #else printf("Generating movie ... \n"); #endif - AIM_ASSERT(m_pParam); - // Convert images and sound file to a movie - //! \warning Movie files are overwritten without warning - //! \bug ffmpeg only works with colour images, not with bw. So make sure to not use bw only in drawing.. - // Always convert to audio stream of 44.1kHz or problems may occur in playing or conversio. - float fFps = 1000.0 / m_pParam->GetFloat("output.frameperiod"); + AIM_ASSERT(parameters_); + // Convert images and sound file to a movie. + //! \warning Movie files are overwritten without warning. char sffmpegPath[1024]; - if (!m_pParam->IsSet("output.ffmpeg_path")) { + if (!parameters_->IsSet("output.ffmpeg_path")) { strcpy(sffmpegPath,"ffmpeg"); } else { - strcpy(sffmpegPath, m_pParam->GetString("output.ffmpeg_path")); + strcpy(sffmpegPath, parameters_->GetString("output.ffmpeg_path")); } char sCodecOptions[1024]; - if (!m_pParam->IsSet("output.ffmpeg_codec_options")) { + if (!parameters_->IsSet("output.ffmpeg_codec_options")) { strcpy(sCodecOptions,""); } else { - strcpy(sCodecOptions, m_pParam->GetString("output.ffmpeg_codec_options")); + strcpy(sCodecOptions, parameters_->GetString("output.ffmpeg_codec_options")); } - + float frame_rate = global_parameters_->DefaultFloat("frame_rate", -1.0); char sCmdLine[1024]; //!\todo check that snprintf does not want a larger buffer snprintf(sCmdLine, sizeof(sCmdLine)/sizeof(sCmdLine[0]), "%s -r %.2f -y -i \"%s\" -i \"%s%%06d.png\" " - "-title \"%s\" -comment \"Generated by "AIM_NAME" "AIM_VERSION_STRING"\" " "-sameq -r %.2f -ar 44100 -acodec pcm_s16le %s \"%s\"", - sffmpegPath, fFps, m_sSoundFile, m_sDir, - m_pParam->GetString("output.movie.title"), - fFps, sCodecOptions, m_sMovieFile); + sffmpegPath, frame_rate, sound_filename_.c_str(), directory_.c_str(), + frame_rate, sCodecOptions, movie_filename_.c_str()); printf(sCmdLine); printf("\n"); if (system(sCmdLine)) { @@ -199,7 +200,7 @@ #else DIR *dir; struct dirent *dirent; - if (!(dir = opendir(m_sDir))) { + if (!(dir = opendir(directory_.c_str()))) { LOG_ERROR(_T("Couldn't remove files in temporary directory.")); return; } @@ -207,22 +208,22 @@ snprintf(sCmdLine, sizeof(sCmdLine)/sizeof(sCmdLine[0]), "%s%s", - m_sDir, + directory_.c_str(), dirent->d_name); unlink(sCmdLine); } closedir(dir); - rmdir(m_sDir); + rmdir(directory_.c_str()); #endif } void GraphicsOutputDeviceMovie::PlotParameterScreen() { - AIM_ASSERT(m_pParam); + AIM_ASSERT(parameters_); char sStr[50]; int lineno = 1; - float fMarL = m_pParam->GetFloat(_S("graph.margin.left")); - float fMarT = m_pParam->GetFloat(_S("graph.margin.top")); + float fMarL = parameters_->GetFloat(_S("graph.margin.left")); + float fMarT = parameters_->GetFloat(_S("graph.margin.top")); float fTextHeight = 1.0f / 50.0f * 1.2; // change this when fontsizing is there! gText2f(fMarL, 1-(fMarT+fTextHeight*lineno++), @@ -249,7 +250,7 @@ snprintf(sStr, sizeof(sStr)/sizeof(sStr[0]), _S("%s=%s"), pPlotParams[i], - m_pParam->GetString(pPlotParams[i])); + parameters_->GetString(pPlotParams[i])); gText2f(fMarL, 1-(fMarT+fTextHeight*lineno++), sStr);