Add DCP size and length to player.
[dcpomatic.git] / src / lib / util.cc
index 574d1d8894a94b9a6735e81b2246b9632dc8f2b8..1f5b29101de78c7657a2341623590eed7b3ad92f 100644 (file)
@@ -36,6 +36,7 @@
 #include "digester.h"
 #include "audio_processor.h"
 #include "compose.hpp"
+#include "audio_buffers.h"
 #include <dcp/locale_convert.h>
 #include <dcp/util.h>
 #include <dcp/raw_convert.h>
@@ -44,6 +45,7 @@
 #include <dcp/subtitle_asset.h>
 extern "C" {
 #include <libavfilter/avfilter.h>
+#include <libavformat/avformat.h>
 #include <libavcodec/avcodec.h>
 }
 #include <curl/curl.h>
@@ -88,6 +90,7 @@ using std::pair;
 using std::cout;
 using std::bad_alloc;
 using std::set_terminate;
+using std::make_pair;
 using boost::shared_ptr;
 using boost::thread;
 using boost::optional;
@@ -124,6 +127,22 @@ seconds_to_hms (int s)
        return buffer;
 }
 
+string
+time_to_hmsf (DCPTime time, Frame rate)
+{
+       Frame f = time.frames_round (rate);
+       int s = f / rate;
+       f -= (s * rate);
+       int m = s / 60;
+       s -= m * 60;
+       int h = m / 60;
+       m -= h * 60;
+
+       char buffer[64];
+       snprintf (buffer, sizeof(buffer), "%d:%02d:%02d.%d", h, m, s, static_cast<int>(f));
+       return buffer;
+}
+
 /** @param s Number of seconds.
  *  @return String containing an approximate description of s (e.g. "about 2 hours")
  */
@@ -322,6 +341,7 @@ dcpomatic_setup ()
        SetUnhandledExceptionFilter(exception_handler);
 #endif
 
+       av_register_all ();
        avfilter_register_all ();
 
 #ifdef DCPOMATIC_OSX
@@ -706,3 +726,51 @@ careful_string_filter (string s)
 
        return out;
 }
+
+/** @param mapped List of mapped audio channels from a Film.
+ *  @param channels Total number of channels in the Film.
+ *  @return First: number of non-LFE channels, second: number of LFE channels.
+ */
+pair<int, int>
+audio_channel_types (list<int> mapped, int channels)
+{
+       int non_lfe = 0;
+       int lfe = 0;
+
+       BOOST_FOREACH (int i, mapped) {
+               if (i >= channels) {
+                       /* This channel is mapped but is not included in the DCP */
+                       continue;
+               }
+
+               if (static_cast<dcp::Channel> (i) == dcp::LFE) {
+                       ++lfe;
+               } else {
+                       ++non_lfe;
+               }
+       }
+
+       return make_pair (non_lfe, lfe);
+}
+
+shared_ptr<AudioBuffers>
+remap (shared_ptr<const AudioBuffers> input, int output_channels, AudioMapping map)
+{
+       shared_ptr<AudioBuffers> mapped (new AudioBuffers (output_channels, input->frames()));
+       mapped->make_silent ();
+
+       for (int i = 0; i < map.input_channels(); ++i) {
+               for (int j = 0; j < mapped->channels(); ++j) {
+                       if (map.get (i, static_cast<dcp::Channel> (j)) > 0) {
+                               mapped->accumulate_channel (
+                                       input.get(),
+                                       i,
+                                       static_cast<dcp::Channel> (j),
+                                       map.get (i, static_cast<dcp::Channel> (j))
+                                       );
+                       }
+               }
+       }
+
+       return mapped;
+}