X-Git-Url: https://git.carlh.net/gitweb/?a=blobdiff_plain;f=src%2Flib%2Futil.cc;h=8c570059821d35ca3290dd250524d3f682b2c6f9;hb=1c73379ed8483dcf71c5ccfc459c2c22516a9aef;hp=82f31b8f137a8f372d5285a2f677530309cb9f97;hpb=e163200eaaf65c63d5105949432140f4084de037;p=dcpomatic.git diff --git a/src/lib/util.cc b/src/lib/util.cc index 82f31b8f1..8c5700598 100644 --- a/src/lib/util.cc +++ b/src/lib/util.cc @@ -47,6 +47,7 @@ #include "ratio.h" #include "rect.h" #include "render_text.h" +#include "scope_guard.h" #include "string_text.h" #include "text_decoder.h" #include "util.h" @@ -73,6 +74,7 @@ LIBDCP_ENABLE_WARNINGS #include #include #include +#include #include #include #include @@ -81,7 +83,6 @@ LIBDCP_DISABLE_WARNINGS #include LIBDCP_ENABLE_WARNINGS #ifdef DCPOMATIC_WINDOWS -#include #include #endif #include @@ -361,6 +362,59 @@ dcpomatic_setup_path_encoding () #endif } + +class LogSink : public Kumu::ILogSink +{ +public: + LogSink () {} + LogSink (LogSink const&) = delete; + LogSink& operator= (LogSink const&) = delete; + + void WriteEntry(const Kumu::LogEntry& entry) override { + Kumu::AutoMutex L(m_lock); + WriteEntryToListeners(entry); + if (entry.TestFilter(m_filter)) { + string buffer; + entry.CreateStringWithOptions(buffer, m_options); + LOG_GENERAL("asdcplib: %1", buffer); + } + } +}; + + +void +capture_asdcp_logs () +{ + static LogSink log_sink; + Kumu::SetDefaultLogSink(&log_sink); +} + + +static +void +ffmpeg_log_callback(void* ptr, int level, const char* fmt, va_list vl) +{ + if (level > AV_LOG_WARNING) { + return; + } + + char line[1024]; + static int prefix = 0; + av_log_format_line(ptr, level, fmt, vl, line, sizeof (line), &prefix); + string str(line); + boost::algorithm::trim(str); + dcpomatic_log->log(String::compose("FFmpeg: %1", str), LogEntry::TYPE_GENERAL); +} + + +static +void +capture_ffmpeg_logs() +{ + av_log_set_callback(ffmpeg_log_callback); +} + + /** Call the required functions to set up DCP-o-matic's static arrays, etc. * Must be called from the UI thread, if there is one. */ @@ -412,7 +466,7 @@ LIBDCP_ENABLE_WARNINGS optional(), false, false, false, dcp::Colour(), 42, 1, dcp::Time(), dcp::Time(), 0, dcp::HAlign::CENTER, 0, dcp::VAlign::CENTER, 0, dcp::Direction::LTR, "Hello dolly", dcp::Effect::NONE, dcp::Colour(), dcp::Time(), dcp::Time(), 0 ); - subs.push_back(StringText(ss, 0, {}, dcp::SubtitleStandard::SMPTE_2014)); + subs.push_back(StringText(ss, 0, make_shared("foo"), dcp::SubtitleStandard::SMPTE_2014)); render_text (subs, dcp::Size(640, 480), DCPTime(), 24); #endif @@ -428,6 +482,7 @@ LIBDCP_ENABLE_WARNINGS ui_thread = boost::this_thread::get_id (); capture_asdcp_logs (); + capture_ffmpeg_logs(); } #ifdef DCPOMATIC_WINDOWS @@ -1013,33 +1068,6 @@ start_of_thread (string) #endif -class LogSink : public Kumu::ILogSink -{ -public: - LogSink () {} - LogSink (LogSink const&) = delete; - LogSink& operator= (LogSink const&) = delete; - - void WriteEntry(const Kumu::LogEntry& entry) override { - Kumu::AutoMutex L(m_lock); - WriteEntryToListeners(entry); - if (entry.TestFilter(m_filter)) { - string buffer; - entry.CreateStringWithOptions(buffer, m_options); - LOG_GENERAL("asdcplib: %1", buffer); - } - } -}; - - -void -capture_asdcp_logs () -{ - static LogSink log_sink; - Kumu::SetDefaultLogSink(&log_sink); -} - - string error_details(boost::system::error_code ec) { @@ -1053,3 +1081,38 @@ contains_assetmap(boost::filesystem::path dir) return boost::filesystem::is_regular_file(dir / "ASSETMAP") || boost::filesystem::is_regular_file(dir / "ASSETMAP.xml"); } + +string +word_wrap(string input, int columns) +{ + icu::Locale locale; + UErrorCode status = U_ZERO_ERROR; + auto iter = icu::BreakIterator::createLineInstance(locale, status); + ScopeGuard sg = [iter]() { delete iter; }; + if (U_FAILURE(status)) { + return input; + } + + auto input_icu = icu::UnicodeString::fromUTF8(icu::StringPiece(input)); + iter->setText(input_icu); + + int position = 0; + string output; + while (position < input_icu.length()) { + int end_of_line = iter->preceding(position + columns + 1); + icu::UnicodeString line; + if (end_of_line <= position) { + /* There's no good line-break position; just break in the middle of a word */ + line = input_icu.tempSubString(position, columns); + position += columns; + } else { + line = input_icu.tempSubString(position, end_of_line - position); + position = end_of_line; + } + line.toUTF8String(output); + output += "\n"; + } + + return output; +} +