From b1283679663c4775504b238378c588f972affcd8 Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Tue, 18 Jun 2013 19:35:24 +0100 Subject: Don't get stuck in an infinite loop when avcodec_decode_audio4 returns an error. --- src/lib/ffmpeg_decoder.cc | 33 ++++++++++++++++++--------------- 1 file changed, 18 insertions(+), 15 deletions(-) (limited to 'src/lib') diff --git a/src/lib/ffmpeg_decoder.cc b/src/lib/ffmpeg_decoder.cc index bcfbea431..cad247e5a 100644 --- a/src/lib/ffmpeg_decoder.cc +++ b/src/lib/ffmpeg_decoder.cc @@ -691,23 +691,26 @@ FFmpegDecoder::decode_audio_packet () int frame_finished; int const decode_result = avcodec_decode_audio4 (_audio_codec_context, _frame, &frame_finished, ©_packet); - if (decode_result >= 0) { - if (frame_finished) { + if (decode_result < 0) { + /* error */ + break; + } + + if (frame_finished) { - /* Where we are in the source, in seconds */ - double const source_pts_seconds = av_q2d (_format_context->streams[copy_packet.stream_index]->time_base) - * av_frame_get_best_effort_timestamp(_frame); - - int const data_size = av_samples_get_buffer_size ( - 0, _audio_codec_context->channels, _frame->nb_samples, audio_sample_format (), 1 - ); - - assert (_audio_codec_context->channels == _film->audio_channels()); - Audio (deinterleave_audio (_frame->data, data_size), source_pts_seconds); - } + /* Where we are in the source, in seconds */ + double const source_pts_seconds = av_q2d (_format_context->streams[copy_packet.stream_index]->time_base) + * av_frame_get_best_effort_timestamp(_frame); - copy_packet.data += decode_result; - copy_packet.size -= decode_result; + int const data_size = av_samples_get_buffer_size ( + 0, _audio_codec_context->channels, _frame->nb_samples, audio_sample_format (), 1 + ); + + assert (_audio_codec_context->channels == _film->audio_channels()); + Audio (deinterleave_audio (_frame->data, data_size), source_pts_seconds); } + + copy_packet.data += decode_result; + copy_packet.size -= decode_result; } } -- cgit v1.2.3 From 20021c03b349ef6cc0ffc04a2d75704fc0c8a40e Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Mon, 24 Jun 2013 00:34:29 +0100 Subject: Try to do ffprobe on content when setting it up. --- src/lib/film.cc | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'src/lib') diff --git a/src/lib/film.cc b/src/lib/film.cc index 8aedd7639..942801a9f 100644 --- a/src/lib/film.cc +++ b/src/lib/film.cc @@ -998,6 +998,15 @@ Film::set_content (string c) if (content_type() == STILL) { set_use_content_audio (false); } + +#ifdef DVDOMATIC_WINDOWS + string ffprobe = "ffprobe.exe "; +#else + string ffprobe = "ffprobe "; +#endif + ffprobe += c; + ffprobe += " 2> " + file ("ffprobe.log"); + system (ffprobe.c_str ()); } void -- cgit v1.2.3 From 355e95ed35092b05896dd1e94e4383df003ded84 Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Mon, 24 Jun 2013 00:57:47 +0100 Subject: Add avdevice DLL to windows installer; log ffprobe command. --- platform/windows/installer.nsi.32.in | 1 + platform/windows/installer.nsi.64.in | 1 + src/lib/film.cc | 1 + 3 files changed, 3 insertions(+) (limited to 'src/lib') diff --git a/platform/windows/installer.nsi.32.in b/platform/windows/installer.nsi.32.in index a36384902..6dd1de2d9 100644 --- a/platform/windows/installer.nsi.32.in +++ b/platform/windows/installer.nsi.32.in @@ -32,6 +32,7 @@ File "%deps%/bin/avcodec-55.dll" File "%deps%/bin/avfilter-3.dll" File "%deps%/bin/avformat-55.dll" File "%deps%/bin/avutil-52.dll" +File "%deps%/bin/avdevice-55.dll" File "%deps%/bin/dcp.dll" File "%deps%/bin/libintl-8.dll" File "%deps%/bin/kumu-libdcp.dll" diff --git a/platform/windows/installer.nsi.64.in b/platform/windows/installer.nsi.64.in index 7f2b1da7b..e98a3a6d8 100644 --- a/platform/windows/installer.nsi.64.in +++ b/platform/windows/installer.nsi.64.in @@ -42,6 +42,7 @@ File "%deps%/bin/avcodec-55.dll" File "%deps%/bin/avfilter-3.dll" File "%deps%/bin/avformat-55.dll" File "%deps%/bin/avutil-52.dll" +File "%deps%/bin/avdevice-55.dll" File "%deps%/bin/dcp.dll" File "%deps%/bin/libintl-8.dll" File "%deps%/bin/kumu-libdcp.dll" diff --git a/src/lib/film.cc b/src/lib/film.cc index 942801a9f..c4a7c4316 100644 --- a/src/lib/film.cc +++ b/src/lib/film.cc @@ -1006,6 +1006,7 @@ Film::set_content (string c) #endif ffprobe += c; ffprobe += " 2> " + file ("ffprobe.log"); + log()->log (String::compose ("Probing with %1", ffprobe)); system (ffprobe.c_str ()); } -- cgit v1.2.3 From 154d5fc4b28394ffcc0e12a680b0a24107d11b84 Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Mon, 24 Jun 2013 01:09:54 +0100 Subject: Quote stuff when calling ffprobe. --- src/lib/film.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/lib') diff --git a/src/lib/film.cc b/src/lib/film.cc index c4a7c4316..a881e957a 100644 --- a/src/lib/film.cc +++ b/src/lib/film.cc @@ -1004,8 +1004,8 @@ Film::set_content (string c) #else string ffprobe = "ffprobe "; #endif - ffprobe += c; - ffprobe += " 2> " + file ("ffprobe.log"); + ffprobe += "\"" + c + "\""; + ffprobe += " 2> \"" + file ("ffprobe.log") + "\""; log()->log (String::compose ("Probing with %1", ffprobe)); system (ffprobe.c_str ()); } -- cgit v1.2.3 From 23945ac9d84e2f77a08591604ec1244535548147 Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Mon, 24 Jun 2013 01:23:12 +0100 Subject: Try to fix path for ffprobe. --- src/lib/film.cc | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'src/lib') diff --git a/src/lib/film.cc b/src/lib/film.cc index a881e957a..273ae0993 100644 --- a/src/lib/film.cc +++ b/src/lib/film.cc @@ -1000,7 +1000,12 @@ Film::set_content (string c) } #ifdef DVDOMATIC_WINDOWS - string ffprobe = "ffprobe.exe "; + char dir[512]; + GetModuleFileName (GetModuleHandle (0), dir, sizeof (dir)); + boost::filesystem::path path_dir (dir); + path_dir = path_dir.parent_path (); + path_dir /= "ffprobe.exe"; + ffprobe = path_dir.string (); #else string ffprobe = "ffprobe "; #endif -- cgit v1.2.3 From b8216704a7f564753cfcc497cf73ea89c0a865c4 Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Mon, 24 Jun 2013 01:25:26 +0100 Subject: Try to fix previous. --- src/lib/film.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/lib') diff --git a/src/lib/film.cc b/src/lib/film.cc index 273ae0993..e3efda450 100644 --- a/src/lib/film.cc +++ b/src/lib/film.cc @@ -1000,12 +1000,12 @@ Film::set_content (string c) } #ifdef DVDOMATIC_WINDOWS - char dir[512]; + wchar_t dir[512]; GetModuleFileName (GetModuleHandle (0), dir, sizeof (dir)); boost::filesystem::path path_dir (dir); path_dir = path_dir.parent_path (); path_dir /= "ffprobe.exe"; - ffprobe = path_dir.string (); + string ffprobe = path_dir.string (); #else string ffprobe = "ffprobe "; #endif -- cgit v1.2.3 From 68b46a970895711694177c26aa4954cf1e23959c Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Mon, 24 Jun 2013 01:45:11 +0100 Subject: Quote ffprobe path. --- src/lib/film.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/lib') diff --git a/src/lib/film.cc b/src/lib/film.cc index e3efda450..041bbc225 100644 --- a/src/lib/film.cc +++ b/src/lib/film.cc @@ -1005,7 +1005,7 @@ Film::set_content (string c) boost::filesystem::path path_dir (dir); path_dir = path_dir.parent_path (); path_dir /= "ffprobe.exe"; - string ffprobe = path_dir.string (); + string ffprobe = "\"" + path_dir.string () + "\" "; #else string ffprobe = "ffprobe "; #endif -- cgit v1.2.3 From 59043fa86b3a70f9e6b205cdeeec9b47678fafef Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Mon, 24 Jun 2013 11:43:25 +0100 Subject: Missing virtual destructor. --- src/lib/filter_graph.h | 1 + 1 file changed, 1 insertion(+) (limited to 'src/lib') diff --git a/src/lib/filter_graph.h b/src/lib/filter_graph.h index 2138943e4..ee378af4c 100644 --- a/src/lib/filter_graph.h +++ b/src/lib/filter_graph.h @@ -33,6 +33,7 @@ class FFmpegDecoder; class FilterGraph { public: + virtual ~FilterGraph () {} virtual bool can_process (libdcp::Size, AVPixelFormat) const = 0; virtual std::list > process (AVFrame *) = 0; }; -- cgit v1.2.3 From 782eae5d6c49d176660440b05d30210f21b6a926 Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Mon, 24 Jun 2013 11:43:31 +0100 Subject: Try to fix ffprobing. --- src/lib/film.cc | 11 +++++++---- src/lib/wscript | 2 +- wscript | 1 + 3 files changed, 9 insertions(+), 5 deletions(-) (limited to 'src/lib') diff --git a/src/lib/film.cc b/src/lib/film.cc index 041bbc225..cb66e2783 100644 --- a/src/lib/film.cc +++ b/src/lib/film.cc @@ -25,6 +25,10 @@ #include #include #include +#ifdef DVDOMATIC_WINDOWS +#undef DATADIR +#include +#endif #include #include #include @@ -1002,10 +1006,9 @@ Film::set_content (string c) #ifdef DVDOMATIC_WINDOWS wchar_t dir[512]; GetModuleFileName (GetModuleHandle (0), dir, sizeof (dir)); - boost::filesystem::path path_dir (dir); - path_dir = path_dir.parent_path (); - path_dir /= "ffprobe.exe"; - string ffprobe = "\"" + path_dir.string () + "\" "; + PathRemoveFileSpec (dir); + SetCurrentDirectory (dir); + string ffprobe = "ffprobe.exe "; #else string ffprobe = "ffprobe "; #endif diff --git a/src/lib/wscript b/src/lib/wscript index 66207b1e4..7c7a64d58 100644 --- a/src/lib/wscript +++ b/src/lib/wscript @@ -69,7 +69,7 @@ def build(bld): obj.source = sources + ' version.cc' if bld.env.TARGET_WINDOWS: - obj.uselib += ' WINSOCK2 BFD DBGHELP IBERTY' + obj.uselib += ' WINSOCK2 BFD DBGHELP IBERTY SHLWAPI' obj.source += ' stack.cpp' obj.target = 'dvdomatic' diff --git a/wscript b/wscript index bc12a0809..8088f4532 100644 --- a/wscript +++ b/wscript @@ -42,6 +42,7 @@ def configure(conf): conf.check(lib = 'bfd', uselib_store = 'BFD', msg = "Checking for library bfd") conf.check(lib = 'dbghelp', uselib_store = 'DBGHELP', msg = "Checking for library dbghelp") conf.check(lib = 'iberty', uselib_store = 'IBERTY', msg = "Checking for library iberty") + conf.check(lib = 'shlwapi', uselib_store = 'SHLWAPI', msg = "Checking for library shlwapi") boost_lib_suffix = '-mt' boost_thread = 'boost_thread_win32-mt' else: -- cgit v1.2.3 From 99aa6b5fd53426eee80b409ed99d1ee86c097cd5 Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Mon, 24 Jun 2013 14:57:32 +0100 Subject: Fix ffprobe on windows to work without a command window etc. --- src/lib/cross.cc | 76 +++++++++++++++++++++++++++++++++++++++++++++++++++++++- src/lib/cross.h | 4 +++ src/lib/film.cc | 18 +------------- 3 files changed, 80 insertions(+), 18 deletions(-) (limited to 'src/lib') diff --git a/src/lib/cross.cc b/src/lib/cross.cc index 7fbba86f9..cdb7f2819 100644 --- a/src/lib/cross.cc +++ b/src/lib/cross.cc @@ -20,11 +20,14 @@ #include #include #include "cross.h" +#include "log.h" #ifdef DVDOMATIC_POSIX #include #endif #ifdef DVDOMATIC_WINDOWS -#include "windows.h" +#include +#undef DATADIR +#include #endif #ifdef DVDOMATIC_OSX #include @@ -33,6 +36,7 @@ using std::pair; using std::ifstream; using std::string; +using boost::shared_ptr; void dvdomatic_sleep (int s) @@ -81,3 +85,73 @@ cpu_info () return info; } +void +run_ffprobe (boost::filesystem::path content, boost::filesystem::path out, shared_ptr log) +{ +#ifdef DVDOMATIC_WINDOWS + SECURITY_ATTRIBUTES security; + security.nLength = sizeof (security); + security.bInheritHandle = TRUE; + security.lpSecurityDescriptor = 0; + + HANDLE child_stderr_read; + HANDLE child_stderr_write; + if (!CreatePipe (&child_stderr_read, &child_stderr_write, &security, 0)) { + log->log ("ffprobe call failed (could not CreatePipe)"); + return; + } + + wchar_t dir[512]; + GetModuleFileName (GetModuleHandle (0), dir, sizeof (dir)); + PathRemoveFileSpec (dir); + SetCurrentDirectory (dir); + + STARTUPINFO startup_info; + ZeroMemory (&startup_info, sizeof (startup_info)); + startup_info.cb = sizeof (startup_info); + startup_info.hStdError = child_stderr_write; + startup_info.dwFlags |= STARTF_USESTDHANDLES; + + wchar_t command[512]; + wcscpy (command, L"ffprobe.exe "); + + wchar_t file[512]; + MultiByteToWideChar (CP_UTF8, 0, content.string().c_str(), -1, file, sizeof(file)); + wcscat (command, file); + + PROCESS_INFORMATION process_info; + ZeroMemory (&process_info, sizeof (process_info)); + if (!CreateProcess (0, command, 0, 0, TRUE, CREATE_NO_WINDOW, 0, 0, &startup_info, &process_info)) { + log->log ("ffprobe call failed (could not CreateProcess)"); + return; + } + + FILE* o = fopen (out.string().c_str(), "w"); + if (!o) { + log->log ("ffprobe call failed (could not create output file)"); + return; + } + + CloseHandle (child_stderr_write); + + while (1) { + char buffer[512]; + DWORD read; + if (!ReadFile(child_stderr_read, buffer, sizeof(buffer), &read, 0) || read == 0) { + break; + } + fwrite (buffer, read, 1, o); + } + + fclose (o); + + WaitForSingleObject (process_info.hProcess, INFINITE); + CloseHandle (process_info.hProcess); + CloseHandle (process_info.hThread); + CloseHandle (child_stderr_read); +#else + string ffprobe = "ffprobe 2> \"" + c + "\" 2> \"" + file ("ffprobe.log"); + log->log (String::compose ("Probing with %1", ffprobe)); + system (ffprobe.c_str ()); +#endif +} diff --git a/src/lib/cross.h b/src/lib/cross.h index 970bf3e9d..1a7a8cb4d 100644 --- a/src/lib/cross.h +++ b/src/lib/cross.h @@ -18,6 +18,9 @@ */ #include +#include + +class Log; #ifdef DVDOMATIC_WINDOWS #define WEXITSTATUS(w) (w) @@ -25,3 +28,4 @@ void dvdomatic_sleep (int); extern std::pair cpu_info (); +extern void run_ffprobe (boost::filesystem::path, boost::filesystem::path, boost::shared_ptr); diff --git a/src/lib/film.cc b/src/lib/film.cc index cb66e2783..3d9b3eeb4 100644 --- a/src/lib/film.cc +++ b/src/lib/film.cc @@ -25,10 +25,6 @@ #include #include #include -#ifdef DVDOMATIC_WINDOWS -#undef DATADIR -#include -#endif #include #include #include @@ -1003,19 +999,7 @@ Film::set_content (string c) set_use_content_audio (false); } -#ifdef DVDOMATIC_WINDOWS - wchar_t dir[512]; - GetModuleFileName (GetModuleHandle (0), dir, sizeof (dir)); - PathRemoveFileSpec (dir); - SetCurrentDirectory (dir); - string ffprobe = "ffprobe.exe "; -#else - string ffprobe = "ffprobe "; -#endif - ffprobe += "\"" + c + "\""; - ffprobe += " 2> \"" + file ("ffprobe.log") + "\""; - log()->log (String::compose ("Probing with %1", ffprobe)); - system (ffprobe.c_str ()); + run_ffprobe (c, file ("ffprobe.log"), _log); } void -- cgit v1.2.3 From f1f25e57c97a6ea28513820912169305795c7d14 Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Mon, 24 Jun 2013 15:09:05 +0100 Subject: Fix linux build. --- src/lib/cross.cc | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src/lib') diff --git a/src/lib/cross.cc b/src/lib/cross.cc index cdb7f2819..a642915f4 100644 --- a/src/lib/cross.cc +++ b/src/lib/cross.cc @@ -20,6 +20,7 @@ #include #include #include "cross.h" +#include "compose.hpp" #include "log.h" #ifdef DVDOMATIC_POSIX #include @@ -150,7 +151,7 @@ run_ffprobe (boost::filesystem::path content, boost::filesystem::path out, share CloseHandle (process_info.hThread); CloseHandle (child_stderr_read); #else - string ffprobe = "ffprobe 2> \"" + c + "\" 2> \"" + file ("ffprobe.log"); + string ffprobe = "ffprobe 2> \"" + content.string() + "\" 2> \"" + out.string(); log->log (String::compose ("Probing with %1", ffprobe)); system (ffprobe.c_str ()); #endif -- cgit v1.2.3 From 362068b534ffefcb87debd4d56b56645f3e25f21 Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Mon, 24 Jun 2013 16:02:52 +0100 Subject: Add logging of mount formats in Linux. --- src/lib/cross.cc | 29 +++++++++++++++++++++++++++++ src/lib/cross.h | 3 ++- src/lib/film.cc | 5 +++++ 3 files changed, 36 insertions(+), 1 deletion(-) (limited to 'src/lib') diff --git a/src/lib/cross.cc b/src/lib/cross.cc index a642915f4..895fb0ac2 100644 --- a/src/lib/cross.cc +++ b/src/lib/cross.cc @@ -24,6 +24,7 @@ #include "log.h" #ifdef DVDOMATIC_POSIX #include +#include #endif #ifdef DVDOMATIC_WINDOWS #include @@ -35,8 +36,10 @@ #endif using std::pair; +using std::list; using std::ifstream; using std::string; +using std::make_pair; using boost::shared_ptr; void @@ -156,3 +159,29 @@ run_ffprobe (boost::filesystem::path content, boost::filesystem::path out, share system (ffprobe.c_str ()); #endif } + +list > +mount_info () +{ + list > m; + +#ifdef DVDOMATIC_POSIX + FILE* f = setmntent ("/etc/mtab", "r"); + if (!f) { + return m; + } + + while (1) { + struct mntent* mnt = getmntent (f); + if (!mnt) { + break; + } + + m.push_back (make_pair (mnt->mnt_dir, mnt->mnt_type)); + } + + endmntent (f); +#endif + + return m; +} diff --git a/src/lib/cross.h b/src/lib/cross.h index 1a7a8cb4d..d9cc2d12f 100644 --- a/src/lib/cross.h +++ b/src/lib/cross.h @@ -26,6 +26,7 @@ class Log; #define WEXITSTATUS(w) (w) #endif -void dvdomatic_sleep (int); +extern void dvdomatic_sleep (int); extern std::pair cpu_info (); extern void run_ffprobe (boost::filesystem::path, boost::filesystem::path, boost::shared_ptr); +extern std::list > mount_info (); diff --git a/src/lib/film.cc b/src/lib/film.cc index 3d9b3eeb4..c4dc9d830 100644 --- a/src/lib/film.cc +++ b/src/lib/film.cc @@ -68,6 +68,7 @@ using std::setfill; using std::min; using std::make_pair; using std::endl; +using std::list; using boost::shared_ptr; using boost::lexical_cast; using boost::to_upper_copy; @@ -329,6 +330,10 @@ Film::make_dcp () #endif pair const c = cpu_info (); log()->log (String::compose ("CPU: %1, %2 processors", c.first, c.second)); + list > const m = mount_info (); + for (list >::const_iterator i = m.begin(); i != m.end(); ++i) { + log()->log (String::compose ("Mount: %1 %2", i->first, i->second)); + } if (format() == 0) { throw MissingSettingError (_("format")); -- cgit v1.2.3 From c1935537a671dea6b3112dbf8a93757eb3fc9e9f Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Thu, 27 Jun 2013 00:24:56 +0100 Subject: Hopefully fix problems with end-trim not working. --- ChangeLog | 4 ++++ src/lib/trimmer.cc | 23 ++++++++++++----------- src/lib/trimmer.h | 1 - wscript | 2 +- 4 files changed, 17 insertions(+), 13 deletions(-) (limited to 'src/lib') diff --git a/ChangeLog b/ChangeLog index e0a8f4bbe..238ad8604 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2013-06-27 Carl Hetherington + + * Hopefully fix problems with end-trim not working. + 2013-06-24 Carl Hetherington * Version 0.103 released. diff --git a/src/lib/trimmer.cc b/src/lib/trimmer.cc index b7afc9299..1ec9e2a5b 100644 --- a/src/lib/trimmer.cc +++ b/src/lib/trimmer.cc @@ -18,6 +18,7 @@ */ #include +#include #include "trimmer.h" using std::cout; @@ -55,18 +56,22 @@ Trimmer::Trimmer ( _audio_end = video_frames_to_audio_frames (_video_end, audio_sample_rate, frames_per_second); } - /* XXX: this is a hack; this flag means that no trim is happening at the end of the film, and I'm - using that to prevent audio trim being rounded to video trim, which breaks the current set - of regression tests. This could be removed if a) the regression tests are regenerated and b) - I can work out what DCP length should be. + /* XXX: this is a hack; if there is no trim at the end, set + the audio end point to infinity so that + shorter-video-than-audio does not trim audio (which breaks + the current set of regression tests). This could be + removed if a) the regression tests are regenerated and b) I + can work out what DCP length should be. */ - _no_trim = (_video_start == 0) && (_video_end == (video_length - video_trim_end)); + if (video_trim_end == 0) { + _audio_end = INT64_MAX; + } } void Trimmer::process_video (shared_ptr image, bool same, shared_ptr sub) { - if (_no_trim || (_video_in >= _video_start && _video_in <= _video_end)) { + if (_video_in >= _video_start && _video_in < _video_end) { Video (image, same, sub); } @@ -76,13 +81,9 @@ Trimmer::process_video (shared_ptr image, bool same, shared_ptr audio) { - if (_no_trim) { - Audio (audio); - return; - } - int64_t offset = _audio_start - _audio_in; if (offset > audio->frames()) { + /* we haven't reached the start of the untrimmed section yet */ _audio_in += audio->frames (); return; } diff --git a/src/lib/trimmer.h b/src/lib/trimmer.h index 98a118fb2..45b3f149a 100644 --- a/src/lib/trimmer.h +++ b/src/lib/trimmer.h @@ -36,5 +36,4 @@ private: int64_t _audio_start; int64_t _audio_end; int64_t _audio_in; - bool _no_trim; }; diff --git a/wscript b/wscript index e04cea069..a4d08d416 100644 --- a/wscript +++ b/wscript @@ -28,7 +28,7 @@ def configure(conf): conf.env.TARGET_OSX = sys.platform == 'darwin' conf.env.TARGET_LINUX = not conf.env.TARGET_WINDOWS and not conf.env.TARGET_OSX - conf.env.append_value('CXXFLAGS', ['-D__STDC_CONSTANT_MACROS', '-msse', '-mfpmath=sse', '-ffast-math', '-fno-strict-aliasing', + conf.env.append_value('CXXFLAGS', ['-D__STDC_CONSTANT_MACROS', '-D__STDC_LIMIT_MACROS', '-msse', '-mfpmath=sse', '-ffast-math', '-fno-strict-aliasing', '-Wall', '-Wno-attributes', '-Wextra']) if conf.env.TARGET_WINDOWS: -- cgit v1.2.3 From 605355f3335d189f6243be42bf254df2ba0442f2 Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Thu, 27 Jun 2013 01:06:07 +0100 Subject: Fix quoting for ffprobe. --- src/lib/cross.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/lib') diff --git a/src/lib/cross.cc b/src/lib/cross.cc index a642915f4..ff0d9f7d1 100644 --- a/src/lib/cross.cc +++ b/src/lib/cross.cc @@ -151,7 +151,7 @@ run_ffprobe (boost::filesystem::path content, boost::filesystem::path out, share CloseHandle (process_info.hThread); CloseHandle (child_stderr_read); #else - string ffprobe = "ffprobe 2> \"" + content.string() + "\" 2> \"" + out.string(); + string ffprobe = "ffprobe \"" + content.string() + "\" 2> \"" + out.string() + "\""; log->log (String::compose ("Probing with %1", ffprobe)); system (ffprobe.c_str ()); #endif -- cgit v1.2.3 From 814f799b280cbf8e73f61ad283a199e211ed0c5e Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Thu, 27 Jun 2013 01:16:37 +0100 Subject: Various bits of backported 1.0 --- src/lib/ffmpeg_decoder.cc | 10 ++++++++++ src/lib/ffmpeg_decoder.h | 5 +++++ src/lib/job.cc | 6 +++++- src/lib/ui_signaller.h | 5 ++++- src/wx/job_manager_view.cc | 1 - test/test.cc | 4 +++- 6 files changed, 27 insertions(+), 4 deletions(-) (limited to 'src/lib') diff --git a/src/lib/ffmpeg_decoder.cc b/src/lib/ffmpeg_decoder.cc index cad247e5a..c2143b949 100644 --- a/src/lib/ffmpeg_decoder.cc +++ b/src/lib/ffmpeg_decoder.cc @@ -61,6 +61,8 @@ using boost::optional; using boost::dynamic_pointer_cast; using libdcp::Size; +boost::mutex FFmpegDecoder::_mutex; + FFmpegDecoder::FFmpegDecoder (shared_ptr f, DecodeOptions o) : Decoder (f, o) , VideoDecoder (f, o) @@ -83,6 +85,8 @@ FFmpegDecoder::FFmpegDecoder (shared_ptr f, DecodeOptions o) FFmpegDecoder::~FFmpegDecoder () { + boost::mutex::scoped_lock lm (_mutex); + if (_audio_codec_context) { avcodec_close (_audio_codec_context); } @@ -157,6 +161,8 @@ FFmpegDecoder::setup_general () void FFmpegDecoder::setup_video () { + boost::mutex::scoped_lock lm (_mutex); + _video_codec_context = _format_context->streams[_video_stream]->codec; _video_codec = avcodec_find_decoder (_video_codec_context->codec_id); @@ -172,6 +178,8 @@ FFmpegDecoder::setup_video () void FFmpegDecoder::setup_audio () { + boost::mutex::scoped_lock lm (_mutex); + if (!_audio_stream) { return; } @@ -194,6 +202,8 @@ FFmpegDecoder::setup_audio () void FFmpegDecoder::setup_subtitle () { + boost::mutex::scoped_lock lm (_mutex); + if (!_subtitle_stream || _subtitle_stream->id() >= int (_format_context->nb_streams)) { return; } diff --git a/src/lib/ffmpeg_decoder.h b/src/lib/ffmpeg_decoder.h index 0c89b973d..198f4294e 100644 --- a/src/lib/ffmpeg_decoder.h +++ b/src/lib/ffmpeg_decoder.h @@ -107,6 +107,9 @@ public: private: + /* No copy construction */ + FFmpegDecoder (FFmpegDecoder const &); + bool pass (); bool do_seek (double p, bool, bool); PixelFormat pixel_format () const; @@ -145,4 +148,6 @@ private: std::list > _filter_graphs; boost::mutex _filter_graphs_mutex; + + static boost::mutex _mutex; }; diff --git a/src/lib/job.cc b/src/lib/job.cc index 9a5812fa7..8bb43a91f 100644 --- a/src/lib/job.cc +++ b/src/lib/job.cc @@ -27,6 +27,7 @@ #include "job.h" #include "util.h" #include "cross.h" +#include "ui_signaller.h" #include "i18n.h" @@ -172,8 +173,11 @@ Job::set_state (State s) boost::mutex::scoped_lock lm (_state_mutex); _state = s; - if (_state == FINISHED_OK || _state == FINISHED_ERROR) { + if (_state == FINISHED_OK || _state == FINISHED_ERROR || _state == FINISHED_CANCELLED) { _ran_for = elapsed_time (); + if (ui_signaller) { + ui_signaller->emit (boost::bind (boost::ref (Finished))); + } } } diff --git a/src/lib/ui_signaller.h b/src/lib/ui_signaller.h index 221bcbe95..0d19660bf 100644 --- a/src/lib/ui_signaller.h +++ b/src/lib/ui_signaller.h @@ -60,7 +60,10 @@ public: } /** This should wake the UI and make it call ui_idle() */ - virtual void wake_ui () = 0; + virtual void wake_ui () { + /* This is only a sensible implementation when there is no GUI... */ + ui_idle (); + } private: /** A io_service which is used as the conduit for messages */ diff --git a/src/wx/job_manager_view.cc b/src/wx/job_manager_view.cc index 5cd9f2e15..cfe09aec8 100644 --- a/src/wx/job_manager_view.cc +++ b/src/wx/job_manager_view.cc @@ -133,7 +133,6 @@ JobManagerView::update () if (!(*i)->finished_cancelled()) { _job_records[*i].gauge->SetValue (100); } - (*i)->Finished (); _job_records[*i].finalised = true; _job_records[*i].cancel->Enable (false); if (!(*i)->error_details().empty ()) { diff --git a/test/test.cc b/test/test.cc index 65b1f9056..74d967a46 100644 --- a/test/test.cc +++ b/test/test.cc @@ -40,6 +40,7 @@ #include "ffmpeg_decoder.h" #include "sndfile_decoder.h" #include "trimmer.h" +#include "ui_signaller.h" #define BOOST_TEST_DYN_LINK #define BOOST_TEST_MODULE dvdomatic_test #include @@ -64,6 +65,8 @@ struct TestConfig Config::instance()->set_default_dci_metadata (DCIMetadata ()); Config::instance()->set_default_format (static_cast (0)); Config::instance()->set_default_dcp_content_type (static_cast (0)); + + ui_signaller = new UISignaller (); } }; @@ -103,4 +106,3 @@ new_test_film (string name) #include "job_test.cc" #include "client_server_test.cc" #include "image_test.cc" - -- cgit v1.2.3 From 86d185b84e9fce2c27ea99e5add202b0ab28b631 Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Thu, 27 Jun 2013 18:56:48 +0100 Subject: Try moving run_ffprobe to before we start using FFmpeg ourselves. --- src/lib/film.cc | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'src/lib') diff --git a/src/lib/film.cc b/src/lib/film.cc index 3d9b3eeb4..827c62082 100644 --- a/src/lib/film.cc +++ b/src/lib/film.cc @@ -943,6 +943,9 @@ Film::set_content (string c) _content = c; } + /* Do this before we start using FFmpeg ourselves */ + run_ffprobe (c, file ("ffprobe.log"), _log); + /* Reset streams here in case the new content doesn't have one or the other */ _content_audio_stream = shared_ptr (); _subtitle_stream = shared_ptr (); @@ -998,8 +1001,6 @@ Film::set_content (string c) if (content_type() == STILL) { set_use_content_audio (false); } - - run_ffprobe (c, file ("ffprobe.log"), _log); } void -- cgit v1.2.3 From 1151383f93f1322409d533da203c6d517268b3ed Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Fri, 28 Jun 2013 13:12:28 +0100 Subject: Log state of use_content_audio when starting a DCP transcode. --- src/lib/film.cc | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'src/lib') diff --git a/src/lib/film.cc b/src/lib/film.cc index 6bc503dc1..ab0e6218e 100644 --- a/src/lib/film.cc +++ b/src/lib/film.cc @@ -318,6 +318,11 @@ Film::make_dcp () log()->log (String::compose ("Content at %1 fps, DCP at %2 fps", source_frame_rate(), dcp_frame_rate())); log()->log (String::compose ("%1 threads", Config::instance()->num_local_encoding_threads())); log()->log (String::compose ("J2K bandwidth %1", j2k_bandwidth())); + if (use_content_audio()) { + log()->log ("Using content's audio"); + } else { + log()->log (String::compose ("Using external audio (%1 files)", external_audio().size())); + } #ifdef DVDOMATIC_DEBUG log()->log ("DVD-o-matic built in debug mode."); #else -- cgit v1.2.3 From 1f6db0a540a160911cd6c73259a807bf0ba36be4 Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Fri, 28 Jun 2013 14:40:27 +0100 Subject: A few OS X build/script fixes. --- platform/osx/waf | 6 +++--- run/makedcp-osx | 2 +- src/lib/cross.cc | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) (limited to 'src/lib') diff --git a/platform/osx/waf b/platform/osx/waf index 7423eb973..dda678542 100755 --- a/platform/osx/waf +++ b/platform/osx/waf @@ -2,10 +2,10 @@ set -e -ENV=/Users/carl/Environments/osx/10.8 -DEPS=/Users/carl/cdist +ENV=/Users/carl/Environments/osx/64 +DEPS=/Users/carl/cdist/64 -export PKG_CONFIG_PATH=$DEPS/lib/pkgconfig:$ENV/lib/pkgconfig +export PKG_CONFIG_PATH=$DEPS/lib/pkgconfig:$ENV/lib/pkgconfig:/usr/lib/pkgconfig export LINKFLAGS="-L$ENV/lib" export CXXFLAGS="-I$ENV/include" export PATH=$PATH:$ENV/bin diff --git a/run/makedcp-osx b/run/makedcp-osx index 1b95ecc5d..03756f524 100755 --- a/run/makedcp-osx +++ b/run/makedcp-osx @@ -1,6 +1,6 @@ #!/bin/bash -export DYLD_LIBRARY_PATH=$DYLD_LIBRARY_PATH:build/src/lib:build/src:/Users/carl/Environments/osx/10.8/lib +export DYLD_LIBRARY_PATH=$DYLD_LIBRARY_PATH:build/src/lib:build/src:/Users/carl/Environments/osx/64/lib if [ "$1" == "--debug" ]; then shift gdb --args build/src/tools/makedcp "$@" diff --git a/src/lib/cross.cc b/src/lib/cross.cc index 86146c1b1..86b657432 100644 --- a/src/lib/cross.cc +++ b/src/lib/cross.cc @@ -22,7 +22,7 @@ #include "cross.h" #include "compose.hpp" #include "log.h" -#ifdef DVDOMATIC_POSIX +#ifdef DVDOMATIC_LINUX #include #include #endif @@ -165,7 +165,7 @@ mount_info () { list > m; -#ifdef DVDOMATIC_POSIX +#ifdef DVDOMATIC_LINUX FILE* f = setmntent ("/etc/mtab", "r"); if (!f) { return m; -- cgit v1.2.3 From 84fa37fa81adee2ab61a987d8f8f5bce0276e16a Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Fri, 28 Jun 2013 15:25:28 +0100 Subject: Some more logging for Mikkel. --- src/lib/film.cc | 6 ++++-- src/wx/film_editor.cc | 2 ++ 2 files changed, 6 insertions(+), 2 deletions(-) (limited to 'src/lib') diff --git a/src/lib/film.cc b/src/lib/film.cc index ab0e6218e..217673a7f 100644 --- a/src/lib/film.cc +++ b/src/lib/film.cc @@ -143,13 +143,13 @@ Film::Film (string d, bool must_exist) _sndfile_stream = SndfileStream::create (); + _log.reset (new FileLog (file ("log"))); + if (must_exist) { read_metadata (); } else { write_metadata (); } - - _log.reset (new FileLog (file ("log"))); } Film::Film (Film const & o) @@ -694,6 +694,8 @@ Film::read_metadata () } _dirty = false; + + _log->log (String::compose ("Loaded film with use_content_audio = %1", use_content_audio ())); } libdcp::Size diff --git a/src/wx/film_editor.cc b/src/wx/film_editor.cc index 6456ae247..dd952e22a 100644 --- a/src/wx/film_editor.cc +++ b/src/wx/film_editor.cc @@ -37,6 +37,7 @@ #include "lib/filter.h" #include "lib/config.h" #include "lib/ffmpeg_decoder.h" +#include "lib/log.h" #include "filter_dialog.h" #include "wx_util.h" #include "film_editor.h" @@ -765,6 +766,7 @@ FilmEditor::film_changed (Film::Property p) setup_frame_rate_description (); break; case Film::USE_CONTENT_AUDIO: + _film->log()->log (String::compose ("Film::USE_CONTENT_AUDIO changed; setting GUI using %1", _film->use_content_audio ())); checked_set (_use_content_audio, _film->use_content_audio()); checked_set (_use_external_audio, !_film->use_content_audio()); setup_dcp_name (); -- cgit v1.2.3 From d13e90a87afd438e1fe79ba94bef0ef0ae6f8101 Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Mon, 1 Jul 2013 15:50:49 +0100 Subject: Fix deadlock. --- src/lib/film.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/lib') diff --git a/src/lib/film.cc b/src/lib/film.cc index 217673a7f..1d4d050bc 100644 --- a/src/lib/film.cc +++ b/src/lib/film.cc @@ -695,7 +695,7 @@ Film::read_metadata () _dirty = false; - _log->log (String::compose ("Loaded film with use_content_audio = %1", use_content_audio ())); + _log->log (String::compose ("Loaded film with use_content_audio = %1", _use_content_audio)); } libdcp::Size -- cgit v1.2.3 From a42d1523bd0d92748d44c067a61aab0a2f63c9b9 Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Mon, 1 Jul 2013 15:50:56 +0100 Subject: Try to fix end trims again. --- src/lib/trimmer.cc | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'src/lib') diff --git a/src/lib/trimmer.cc b/src/lib/trimmer.cc index 1ec9e2a5b..99f04793f 100644 --- a/src/lib/trimmer.cc +++ b/src/lib/trimmer.cc @@ -62,8 +62,15 @@ Trimmer::Trimmer ( the current set of regression tests). This could be removed if a) the regression tests are regenerated and b) I can work out what DCP length should be. + + There is also a problem whereby black video frames inserted + at the start of the output by the matcher are not taken into account, + so if black frames are inserted it means more gets trimmed off the + end than should be. Hack around this in similar fashion with the + _video_end = INT_MAX line. */ if (video_trim_end == 0) { + _video_end = INT_MAX; _audio_end = INT64_MAX; } } -- cgit v1.2.3 From 53ae202ce4fded1e2e90f0b34479870ee08b8d68 Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Tue, 2 Jul 2013 11:32:04 +0100 Subject: Remove debug logging. --- src/lib/film.cc | 2 -- 1 file changed, 2 deletions(-) (limited to 'src/lib') diff --git a/src/lib/film.cc b/src/lib/film.cc index 1d4d050bc..9b7d1bee9 100644 --- a/src/lib/film.cc +++ b/src/lib/film.cc @@ -694,8 +694,6 @@ Film::read_metadata () } _dirty = false; - - _log->log (String::compose ("Loaded film with use_content_audio = %1", _use_content_audio)); } libdcp::Size -- cgit v1.2.3 From 277245b37c7d7dfa1e64096492686a0ee6c80530 Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Wed, 3 Jul 2013 12:24:36 +0100 Subject: Add some more logging to checking of existing picture MXFs. --- src/lib/film.cc | 1 - src/lib/writer.cc | 4 +++- 2 files changed, 3 insertions(+), 2 deletions(-) (limited to 'src/lib') diff --git a/src/lib/film.cc b/src/lib/film.cc index 9b7d1bee9..d92d7a977 100644 --- a/src/lib/film.cc +++ b/src/lib/film.cc @@ -245,7 +245,6 @@ Film::info_dir () const string Film::internal_video_mxf_dir () const { - boost::filesystem::path p; return dir ("video"); } diff --git a/src/lib/writer.cc b/src/lib/writer.cc index 177e929ae..1a6daa1db 100644 --- a/src/lib/writer.cc +++ b/src/lib/writer.cc @@ -18,6 +18,7 @@ */ #include +#include #include #include #include @@ -352,8 +353,9 @@ Writer::check_existing_picture_mxf () boost::filesystem::path p; p /= _film->internal_video_mxf_dir (); p /= _film->internal_video_mxf_filename (); - FILE* mxf = fopen (p.string().c_str(), N_("rb")); + FILE* mxf = fopen (p.string().c_str(), "rb"); if (!mxf) { + _film->log()->log (String::compose ("Could not open existing MXF at %1 (errno=%2)", p.string(), errno)); return; } -- cgit v1.2.3 From b68591911bd8116df0ad987627244b9bdf87de89 Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Wed, 3 Jul 2013 16:33:28 +0100 Subject: Make C++ flags available from makedcp. --- src/lib/version.h | 1 + src/tools/makedcp.cc | 9 +++++++-- wscript | 11 +++++++++-- 3 files changed, 17 insertions(+), 4 deletions(-) (limited to 'src/lib') diff --git a/src/lib/version.h b/src/lib/version.h index 71639e3bc..e1ec9067c 100644 --- a/src/lib/version.h +++ b/src/lib/version.h @@ -1,3 +1,4 @@ extern char const * dvdomatic_version; extern char const * dvdomatic_git_commit; +extern char const * dvdomatic_cxx_flags; diff --git a/src/tools/makedcp.cc b/src/tools/makedcp.cc index e73930d3c..1cd5145ed 100644 --- a/src/tools/makedcp.cc +++ b/src/tools/makedcp.cc @@ -48,7 +48,8 @@ help (string n) cerr << "Syntax: " << n << " [OPTION] \n" << " -v, --version show DVD-o-matic version\n" << " -h, --help show this help\n" - << " -d, --deps list DVD-o-matic dependency details and quit\n" + << " -d, --deps list DVD-o-matic dependency details\n" + << " -f, --flags show flags passed to C++ compiler on build\n" << " -n, --no-progress do not print progress to stdout\n" << " -r, --no-remote do not use any remote servers\n" << "\n" @@ -69,13 +70,14 @@ main (int argc, char* argv[]) { "version", no_argument, 0, 'v'}, { "help", no_argument, 0, 'h'}, { "deps", no_argument, 0, 'd'}, + { "flags", no_argument, 0, 'f'}, { "no-progress", no_argument, 0, 'n'}, { "no-remote", no_argument, 0, 'r'}, { "log-level", required_argument, 0, 'l' }, { 0, 0, 0, 0 } }; - int c = getopt_long (argc, argv, "vhdnrl:", long_options, &option_index); + int c = getopt_long (argc, argv, "vhdfnrl:", long_options, &option_index); if (c == -1) { break; @@ -91,6 +93,9 @@ main (int argc, char* argv[]) case 'd': cout << dependency_version_summary () << "\n"; exit (EXIT_SUCCESS); + case 'f': + cout << dvdomatic_cxx_flags << "\n"; + exit (EXIT_SUCCESS); case 'n': progress = false; break; diff --git a/wscript b/wscript index b87191f42..0008d198f 100644 --- a/wscript +++ b/wscript @@ -206,7 +206,7 @@ def configure(conf): conf.recurse('test') def build(bld): - create_version_cc(VERSION) + create_version_cc(VERSION, bld.env.CXXFLAGS) bld.recurse('src') bld.recurse('test') @@ -232,7 +232,7 @@ def dist(ctx): GRSYMS GRTAGS GSYMS GTAGS """ -def create_version_cc(version): +def create_version_cc(version, cxx_flags): if os.path.exists('.git'): cmd = "LANG= git log --abbrev HEAD^..HEAD ." output = subprocess.Popen(cmd, shell=True, stderr=subprocess.STDOUT, stdout=subprocess.PIPE).communicate()[0].splitlines() @@ -245,6 +245,13 @@ def create_version_cc(version): text = '#include "version.h"\n' text += 'char const * dvdomatic_git_commit = \"%s\";\n' % commit text += 'char const * dvdomatic_version = \"%s\";\n' % version + + t = '' + for f in cxx_flags: + f = f.replace('"', '\\"') + t += f + ' ' + text += 'char const * dvdomatic_cxx_flags = \"%s\";\n' % t[:-1] + print('Writing version information to src/lib/version.cc') o = open('src/lib/version.cc', 'w') o.write(text) -- cgit v1.2.3 From c16a753940f1b03a0c5c268e4132d3f860910dae Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Thu, 4 Jul 2013 00:22:48 +0100 Subject: Initialise the number of threads to the number of cores in the machine (#170). --- ChangeLog | 9 +++++++++ src/lib/config.cc | 3 ++- 2 files changed, 11 insertions(+), 1 deletion(-) (limited to 'src/lib') diff --git a/ChangeLog b/ChangeLog index 733625063..1d8f3fb42 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,12 @@ +2013-07-04 Carl Hetherington + + * Try to initialise the number of threads to the number + of cores in the machine (#170). + + * Pass _FILE_OFFSET_BITS=64 so that fopen() doesn't refuse + to open files of >2GB; fixes failure to re-start jobs + where the MXF has grown larger than 2GB on 32-bit machines. + 2013-07-01 Carl Hetherington * Version 0.106 released. diff --git a/src/lib/config.cc b/src/lib/config.cc index 7d8e82335..d2d7fa2fd 100644 --- a/src/lib/config.cc +++ b/src/lib/config.cc @@ -36,13 +36,14 @@ using std::vector; using std::ifstream; using std::string; using std::ofstream; +using std::max; using boost::shared_ptr; Config* Config::_instance = 0; /** Construct default configuration */ Config::Config () - : _num_local_encoding_threads (2) + : _num_local_encoding_threads (max (2U, boost::thread::hardware_concurrency())) , _server_port (6192) , _reference_scaler (Scaler::from_id (N_("bicubic"))) , _tms_path (N_(".")) -- cgit v1.2.3 From 78c78cdb5c4c6c62ba98fa54c9ba54812149ef7b Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Thu, 4 Jul 2013 00:24:21 +0100 Subject: Try to wrap ffprobe paths in quotes (may fix #168). --- src/lib/cross.cc | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'src/lib') diff --git a/src/lib/cross.cc b/src/lib/cross.cc index 86b657432..124697fb4 100644 --- a/src/lib/cross.cc +++ b/src/lib/cross.cc @@ -117,12 +117,14 @@ run_ffprobe (boost::filesystem::path content, boost::filesystem::path out, share startup_info.dwFlags |= STARTF_USESTDHANDLES; wchar_t command[512]; - wcscpy (command, L"ffprobe.exe "); + wcscpy (command, L"ffprobe.exe \""); wchar_t file[512]; MultiByteToWideChar (CP_UTF8, 0, content.string().c_str(), -1, file, sizeof(file)); wcscat (command, file); + wcscat (command, L"\""); + PROCESS_INFORMATION process_info; ZeroMemory (&process_info, sizeof (process_info)); if (!CreateProcess (0, command, 0, 0, TRUE, CREATE_NO_WINDOW, 0, 0, &startup_info, &process_info)) { -- cgit v1.2.3 From aabf54736d7401437af7f066c51fee91be64e809 Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Thu, 4 Jul 2013 22:29:47 +0100 Subject: Pad silence for things that already have at least some audio. --- src/lib/encoder.cc | 4 ++-- src/lib/film.cc | 15 ++++++++++++++ src/lib/film.h | 10 ++++++++- src/lib/transcoder.cc | 2 +- src/lib/util.cc | 20 +++++++++++++++--- src/lib/util.h | 6 +++++- src/lib/writer.cc | 2 +- src/tools/dvdomatic.cc | 2 +- src/wx/audio_dialog.cc | 6 +++--- src/wx/film_editor.cc | 55 ++++++++++++++++++++++++++++++++++++++++++++++++++ src/wx/film_editor.h | 5 +++++ 11 files changed, 114 insertions(+), 13 deletions(-) (limited to 'src/lib') diff --git a/src/lib/encoder.cc b/src/lib/encoder.cc index 2c989452d..6a99132fd 100644 --- a/src/lib/encoder.cc +++ b/src/lib/encoder.cc @@ -433,10 +433,10 @@ Encoder::encoder_thread (ServerDescription* server) void Encoder::write_audio (shared_ptr data) { - AudioMapping m (_film->audio_channels ()); + AudioMapping m (_film); if (m.dcp_channels() != _film->audio_channels()) { - /* Remap (currently just for mono -> 5.1) */ + /* Remap and pad with silence */ shared_ptr b (new AudioBuffers (m.dcp_channels(), data->frames ())); for (int i = 0; i < m.dcp_channels(); ++i) { diff --git a/src/lib/film.cc b/src/lib/film.cc index d92d7a977..ce555ac8b 100644 --- a/src/lib/film.cc +++ b/src/lib/film.cc @@ -108,6 +108,7 @@ Film::Film (string d, bool must_exist) , _j2k_bandwidth (200000000) , _dci_metadata (Config::instance()->default_dci_metadata ()) , _dcp_frame_rate (0) + , _minimum_audio_channels (0) , _source_frame_rate (0) , _dirty (false) { @@ -185,6 +186,7 @@ Film::Film (Film const & o) , _dci_metadata (o._dci_metadata) , _dci_date (o._dci_date) , _dcp_frame_rate (o._dcp_frame_rate) + , _minimum_audio_channels (o._minimum_audio_channels) , _size (o._size) , _length (o._length) , _content_digest (o._content_digest) @@ -506,6 +508,7 @@ Film::write_metadata () const _dci_metadata.write (f); f << "dci_date " << boost::gregorian::to_iso_string (_dci_date) << endl; f << "dcp_frame_rate " << _dcp_frame_rate << endl; + f << "minimum_audio_channels " << _minimum_audio_channels << endl; f << "width " << _size.width << endl; f << "height " << _size.height << endl; f << "length " << _length.get_value_or(0) << endl; @@ -642,6 +645,8 @@ Film::read_metadata () _dci_date = boost::gregorian::from_undelimited_string (v); } else if (k == "dcp_frame_rate") { _dcp_frame_rate = atoi (v.c_str ()); + } else if (k == "minimum_audio_channels") { + _minimum_audio_channels = atoi (v.c_str ()); } _dci_metadata.read (k, v); @@ -1323,6 +1328,16 @@ Film::set_dcp_frame_rate (int f) signal_changed (DCP_FRAME_RATE); } +void +Film::set_minimum_audio_channels (int c) +{ + { + boost::mutex::scoped_lock lm (_state_mutex); + _minimum_audio_channels = c; + } + signal_changed (MINIMUM_AUDIO_CHANNELS); +} + void Film::set_size (libdcp::Size s) { diff --git a/src/lib/film.h b/src/lib/film.h index dd0a83d94..ca9bd57f4 100644 --- a/src/lib/film.h +++ b/src/lib/film.h @@ -153,7 +153,8 @@ public: CONTENT_AUDIO_STREAMS, SUBTITLE_STREAMS, SOURCE_FRAME_RATE, - DCP_FRAME_RATE + DCP_FRAME_RATE, + MINIMUM_AUDIO_CHANNELS }; @@ -335,6 +336,11 @@ public: return _source_frame_rate; } + int minimum_audio_channels () const { + boost::mutex::scoped_lock lm (_state_mutex); + return _minimum_audio_channels; + } + boost::shared_ptr audio_stream () const; bool has_audio () const; @@ -379,6 +385,7 @@ public: void set_content_audio_streams (std::vector >); void set_subtitle_streams (std::vector >); void set_source_frame_rate (float); + void set_minimum_audio_channels (int); /** Emitted when some property has changed */ mutable boost::signals2::signal Changed; @@ -481,6 +488,7 @@ private: boost::gregorian::date _dci_date; /** Frames per second to run our DCP at */ int _dcp_frame_rate; + int _minimum_audio_channels; /* Data which are cached to speed things up */ diff --git a/src/lib/transcoder.cc b/src/lib/transcoder.cc index 48cf402d7..a202d440c 100644 --- a/src/lib/transcoder.cc +++ b/src/lib/transcoder.cc @@ -73,7 +73,7 @@ Transcoder::Transcoder (shared_ptr f, DecodeOptions o, Job* j, shared_ptr< /* Set up the decoder to use the film's set streams */ _decoders.video->set_subtitle_stream (f->subtitle_stream ()); if (f->audio_stream ()) { - _decoders.audio->set_audio_stream (f->audio_stream ()); + _decoders.audio->set_audio_stream (f->audio_stream ()); } _decoders.video->connect_video (_delay_line); diff --git a/src/lib/util.cc b/src/lib/util.cc index 4cf57368a..83980f828 100644 --- a/src/lib/util.cc +++ b/src/lib/util.cc @@ -61,6 +61,7 @@ extern "C" { #include "filter.h" #include "sound_processor.h" #include "config.h" +#include "film.h" #ifdef DVDOMATIC_WINDOWS #include "stack.hpp" #endif @@ -962,8 +963,9 @@ audio_channel_name (int c) return channels[c]; } -AudioMapping::AudioMapping (int c) - : _source_channels (c) +AudioMapping::AudioMapping (shared_ptr f) + : _source_channels (f->audio_stream() ? f->audio_stream()->channels() : 0) + , _minimum_channels (f->minimum_audio_channels ()) { } @@ -1001,8 +1003,11 @@ AudioMapping::dcp_to_source (libdcp::Channel c) const return static_cast (c); } +/** @return minimum number of DCP channels that we can allow in this + DCP, given the nature of the source. +*/ int -AudioMapping::dcp_channels () const +AudioMapping::minimum_dcp_channels () const { if (_source_channels == 1) { /* The source is mono, so to put the mono channel into @@ -1014,6 +1019,15 @@ AudioMapping::dcp_channels () const return _source_channels; } +/** @return number of channels that there should be in the DCP, including + * any silent padded ones. + */ +int +AudioMapping::dcp_channels () const +{ + return max (_source_channels, _minimum_channels); +} + FrameRateConversion::FrameRateConversion (float source, int dcp) : skip (false) , repeat (false) diff --git a/src/lib/util.h b/src/lib/util.h index 0d745e50c..c9e5bef16 100644 --- a/src/lib/util.h +++ b/src/lib/util.h @@ -50,6 +50,7 @@ extern "C" { #define MAX_AUDIO_CHANNELS 6 class Scaler; +class Film; extern std::string seconds_to_hms (int); extern std::string seconds_to_approximate_hms (int); @@ -287,14 +288,17 @@ private: class AudioMapping { public: - AudioMapping (int); + AudioMapping (boost::shared_ptr); boost::optional source_to_dcp (int c) const; boost::optional dcp_to_source (libdcp::Channel c) const; + + int minimum_dcp_channels () const; int dcp_channels () const; private: int _source_channels; + int _minimum_channels; }; extern int64_t video_frames_to_audio_frames (SourceFrame v, float audio_sample_rate, float frames_per_second); diff --git a/src/lib/writer.cc b/src/lib/writer.cc index 1a6daa1db..cff0b5be2 100644 --- a/src/lib/writer.cc +++ b/src/lib/writer.cc @@ -77,7 +77,7 @@ Writer::Writer (shared_ptr f) _picture_asset_writer = _picture_asset->start_write (_first_nonexistant_frame > 0); - AudioMapping m (_film->audio_channels ()); + AudioMapping m (_film); if (m.dcp_channels() > 0) { _sound_asset.reset ( diff --git a/src/tools/dvdomatic.cc b/src/tools/dvdomatic.cc index de94d0a2f..e0629bb98 100644 --- a/src/tools/dvdomatic.cc +++ b/src/tools/dvdomatic.cc @@ -166,7 +166,7 @@ setup_menu (wxMenuBar* m) add_item (file, _("&Properties..."), ID_file_properties, NEEDS_FILM); #ifndef __WXOSX__ file->AppendSeparator (); -#endif +#endif add_item (file, _("&Exit"), wxID_EXIT, ALWAYS); #ifdef __WXOSX__ diff --git a/src/wx/audio_dialog.cc b/src/wx/audio_dialog.cc index d12b5516f..21e4e5940 100644 --- a/src/wx/audio_dialog.cc +++ b/src/wx/audio_dialog.cc @@ -108,7 +108,7 @@ AudioDialog::setup_channels () return; } - AudioMapping m (_film->audio_stream()->channels ()); + AudioMapping m (_film); for (int i = 0; i < MAX_AUDIO_CHANNELS; ++i) { if (m.dcp_to_source(static_cast(i))) { @@ -134,7 +134,7 @@ AudioDialog::try_to_load_analysis () _plot->set_analysis (a); - AudioMapping m (_film->audio_stream()->channels ()); + AudioMapping m (_film); optional c = m.source_to_dcp (0); if (c) { _channel_checkbox[c.get()]->SetValue (true); @@ -157,7 +157,7 @@ AudioDialog::channel_clicked (wxCommandEvent& ev) assert (c < MAX_AUDIO_CHANNELS); - AudioMapping m (_film->audio_stream()->channels ()); + AudioMapping m (_film); optional s = m.dcp_to_source (static_cast (c)); if (s) { _plot->set_channel_visible (s.get(), _channel_checkbox[c]->GetValue ()); diff --git a/src/wx/film_editor.cc b/src/wx/film_editor.cc index dd952e22a..13bef5a24 100644 --- a/src/wx/film_editor.cc +++ b/src/wx/film_editor.cc @@ -232,6 +232,8 @@ FilmEditor::connect_to_widgets () _dcp_content_type->Connect (wxID_ANY, wxEVT_COMMAND_CHOICE_SELECTED, wxCommandEventHandler (FilmEditor::dcp_content_type_changed), 0, this); _dcp_frame_rate->Connect (wxID_ANY, wxEVT_COMMAND_CHOICE_SELECTED, wxCommandEventHandler (FilmEditor::dcp_frame_rate_changed), 0, this); _best_dcp_frame_rate->Connect (wxID_ANY, wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler (FilmEditor::best_dcp_frame_rate_clicked), 0, this); + _pad_with_silence->Connect (wxID_ANY, wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler (FilmEditor::pad_with_silence_toggled), 0, this); + _minimum_audio_channels->Connect (wxID_ANY, wxEVT_COMMAND_SPINCTRL_UPDATED, wxCommandEventHandler (FilmEditor::minimum_audio_channels_changed), 0, this); _dcp_ab->Connect (wxID_ANY, wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler (FilmEditor::dcp_ab_toggled), 0, this); _still_duration->Connect (wxID_ANY, wxEVT_COMMAND_SPINCTRL_UPDATED, wxCommandEventHandler (FilmEditor::still_duration_changed), 0, this); _trim_start->Connect (wxID_ANY, wxEVT_COMMAND_SPINCTRL_UPDATED, wxCommandEventHandler (FilmEditor::trim_start_changed), 0, this); @@ -392,6 +394,16 @@ FilmEditor::make_audio_panel () grid->Add (s); } + { + _pad_with_silence = new wxCheckBox (_audio_panel, wxID_ANY, _("Pad with silence to")); + grid->Add (_pad_with_silence); + wxBoxSizer* s = new wxBoxSizer (wxHORIZONTAL); + _minimum_audio_channels = new wxSpinCtrl (_audio_panel); + s->Add (_minimum_audio_channels, 1); + add_label_to_sizer (s, _audio_panel, _("channels")); + grid->Add (s); + } + { _use_content_audio = new wxRadioButton (_audio_panel, wxID_ANY, _("Use content's audio"), wxDefaultPosition, wxDefaultSize, wxRB_GROUP); grid->Add (video_control (_use_content_audio)); @@ -415,6 +427,7 @@ FilmEditor::make_audio_panel () _audio_gain->SetRange (-60, 60); _audio_delay->SetRange (-1000, 1000); + _minimum_audio_channels->SetRange (0, MAX_AUDIO_CHANNELS); } void @@ -628,6 +641,7 @@ FilmEditor::film_changed (Film::Property p) setup_streams (); setup_show_audio_sensitivity (); setup_frame_rate_description (); + setup_minimum_audio_channels (); break; case Film::TRUST_CONTENT_HEADER: checked_set (_trust_content_header, _film->trust_content_header ()); @@ -640,6 +654,7 @@ FilmEditor::film_changed (Film::Property p) setup_streams (); setup_show_audio_sensitivity (); setup_frame_rate_description (); + setup_minimum_audio_channels (); break; case Film::FORMAT: { @@ -764,6 +779,7 @@ FilmEditor::film_changed (Film::Property p) setup_audio_control_sensitivity (); setup_show_audio_sensitivity (); setup_frame_rate_description (); + setup_minimum_audio_channels (); break; case Film::USE_CONTENT_AUDIO: _film->log()->log (String::compose ("Film::USE_CONTENT_AUDIO changed; setting GUI using %1", _film->use_content_audio ())); @@ -774,6 +790,7 @@ FilmEditor::film_changed (Film::Property p) setup_audio_control_sensitivity (); setup_show_audio_sensitivity (); setup_frame_rate_description (); + setup_minimum_audio_channels (); break; case Film::SUBTITLE_STREAM: if (_film->subtitle_stream()) { @@ -789,6 +806,7 @@ FilmEditor::film_changed (Film::Property p) setup_audio_details (); setup_show_audio_sensitivity (); setup_frame_rate_description (); + setup_minimum_audio_channels (); break; } case Film::DCP_FRAME_RATE: @@ -808,6 +826,10 @@ FilmEditor::film_changed (Film::Property p) } setup_frame_rate_description (); + case Film::MINIMUM_AUDIO_CHANNELS: + checked_set (_minimum_audio_channels, _film->minimum_audio_channels ()); + setup_minimum_audio_channels (); + break; } } @@ -1185,6 +1207,9 @@ FilmEditor::setup_audio_control_sensitivity () for (int i = 0; i < MAX_AUDIO_CHANNELS; ++i) { _external_audio[i]->Enable (external); } + + _pad_with_silence->Enable (_generally_sensitive && _film && _film->audio_stream() && _film->audio_stream()->channels() < MAX_AUDIO_CHANNELS); + _minimum_audio_channels->Enable (_generally_sensitive && _pad_with_silence->GetValue ()); } void @@ -1411,3 +1436,33 @@ FilmEditor::trim_type_changed (wxCommandEvent &) { _film->set_trim_type (_trim_type->GetSelection () == 0 ? Film::CPL : Film::ENCODE); } + +void +FilmEditor::setup_minimum_audio_channels () +{ + if (!_film || !_film->audio_stream ()) { + _pad_with_silence->SetValue (false); + return; + } + + _pad_with_silence->SetValue (_film->audio_stream()->channels() < _film->minimum_audio_channels()); + + AudioMapping m (_film); + _minimum_audio_channels->SetRange (m.minimum_dcp_channels(), MAX_AUDIO_CHANNELS); +} + +void +FilmEditor::pad_with_silence_toggled (wxCommandEvent &) +{ + setup_audio_control_sensitivity (); +} + +void +FilmEditor::minimum_audio_channels_changed (wxCommandEvent &) +{ + if (!_film) { + return; + } + + _film->set_minimum_audio_channels (_minimum_audio_channels->GetValue ()); +} diff --git a/src/wx/film_editor.h b/src/wx/film_editor.h index e2a4d5836..c2d064ca2 100644 --- a/src/wx/film_editor.h +++ b/src/wx/film_editor.h @@ -85,6 +85,8 @@ private: void external_audio_changed (wxCommandEvent &); void dcp_frame_rate_changed (wxCommandEvent &); void best_dcp_frame_rate_clicked (wxCommandEvent &); + void pad_with_silence_toggled (wxCommandEvent &); + void minimum_audio_channels_changed (wxCommandEvent &); /* Handle changes to the model */ void film_changed (Film::Property); @@ -103,6 +105,7 @@ private: void setup_scaling_description (); void setup_notebook_size (); void setup_frame_rate_description (); + void setup_minimum_audio_channels (); wxControl* video_control (wxControl *); wxControl* still_control (wxControl *); @@ -169,6 +172,8 @@ private: wxStaticText* _source_frame_rate; wxChoice* _dcp_frame_rate; wxButton* _best_dcp_frame_rate; + wxCheckBox* _pad_with_silence; + wxSpinCtrl* _minimum_audio_channels; wxStaticText* _frame_rate_description; /** The Film's length */ wxStaticText* _length; -- cgit v1.2.3 From a43aa6de965cb95fd85425cf5a7dfbdb6f878e22 Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Thu, 4 Jul 2013 22:38:43 +0100 Subject: Put in silence where there was none. --- src/lib/encoder.cc | 15 +++++++++++++++ 1 file changed, 15 insertions(+) (limited to 'src/lib') diff --git a/src/lib/encoder.cc b/src/lib/encoder.cc index 6a99132fd..ebe72b6cd 100644 --- a/src/lib/encoder.cc +++ b/src/lib/encoder.cc @@ -47,6 +47,7 @@ using std::stringstream; using std::vector; using std::list; using std::cout; +using std::min; using std::make_pair; using namespace boost; @@ -149,6 +150,20 @@ Encoder::process_end () } #endif + if (_film->audio_channels() == 0 && _film->minimum_audio_channels() > 0) { + /* Put audio in where there is none at all */ + int64_t af = video_frames_to_audio_frames (_video_frames_out, 48000, _film->dcp_frame_rate ()); + while (af) { + int64_t const this_time = min (af, 24000L); + shared_ptr out (new AudioBuffers (_film->minimum_audio_channels(), this_time)); + out->make_silent (); + out->set_frames (this_time); + write_audio (out); + + af -= this_time; + } + } + boost::mutex::scoped_lock lock (_mutex); _film->log()->log (String::compose (N_("Clearing queue of %1"), _queue.size ())); -- cgit v1.2.3 From 4453965c2ab322122ffa5b51a9fc6efc0f896425 Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Sat, 6 Jul 2013 11:23:56 +0100 Subject: Try to fix build. --- src/lib/encoder.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/lib') diff --git a/src/lib/encoder.cc b/src/lib/encoder.cc index ebe72b6cd..0ac32d3bf 100644 --- a/src/lib/encoder.cc +++ b/src/lib/encoder.cc @@ -154,7 +154,7 @@ Encoder::process_end () /* Put audio in where there is none at all */ int64_t af = video_frames_to_audio_frames (_video_frames_out, 48000, _film->dcp_frame_rate ()); while (af) { - int64_t const this_time = min (af, 24000L); + int64_t const this_time = min (af, static_cast (24000)); shared_ptr out (new AudioBuffers (_film->minimum_audio_channels(), this_time)); out->make_silent (); out->set_frames (this_time); -- cgit v1.2.3 From 50e6acde52c7eaa3afa239bc14f08eced3787bd9 Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Mon, 8 Jul 2013 23:10:01 +0100 Subject: Somewhat hacky fix to crashes in A/B with some filters. --- src/lib/combiner.cc | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'src/lib') diff --git a/src/lib/combiner.cc b/src/lib/combiner.cc index 367cefa7f..f7d634832 100644 --- a/src/lib/combiner.cc +++ b/src/lib/combiner.cc @@ -45,6 +45,14 @@ Combiner::process_video (shared_ptr image, bool, shared_ptr image, bool, shared_ptr sub, double t) { + if (!_image) { + /* It's possible for filters in the A-side to mean that we get a B frame + before any A; just skip the B frame in that case. This at least prevents + a crash, but may not be right. + */ + return; + } + /* Copy the right half of this image into our _image */ /* XXX: this should probably be in the Image class */ for (int i = 0; i < image->components(); ++i) { -- cgit v1.2.3