Remove film player, DVD ripping, alignment, screen configs; never finished and not...
[dcpomatic.git] / src / lib / util.cc
1 /*
2     Copyright (C) 2012 Carl Hetherington <cth@carlh.net>
3     Copyright (C) 2000-2007 Paul Davis
4
5     This program is free software; you can redistribute it and/or modify
6     it under the terms of the GNU General Public License as published by
7     the Free Software Foundation; either version 2 of the License, or
8     (at your option) any later version.
9
10     This program is distributed in the hope that it will be useful,
11     but WITHOUT ANY WARRANTY; without even the implied warranty of
12     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13     GNU General Public License for more details.
14
15     You should have received a copy of the GNU General Public License
16     along with this program; if not, write to the Free Software
17     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18
19 */
20
21 /** @file src/lib/util.cc
22  *  @brief Some utility functions and classes.
23  */
24
25 #include <sstream>
26 #include <iomanip>
27 #include <iostream>
28 #include <fstream>
29 #ifdef DVDOMATIC_POSIX
30 #include <execinfo.h>
31 #include <cxxabi.h>
32 #endif
33 #include <libssh/libssh.h>
34 #include <signal.h>
35 #include <boost/algorithm/string.hpp>
36 #include <boost/bind.hpp>
37 #include <boost/lambda/lambda.hpp>
38 #include <boost/lexical_cast.hpp>
39 #include <boost/thread.hpp>
40 #include <openjpeg.h>
41 #include <openssl/md5.h>
42 #include <magick/MagickCore.h>
43 #include <magick/version.h>
44 #include <libdcp/version.h>
45 extern "C" {
46 #include <libavcodec/avcodec.h>
47 #include <libavformat/avformat.h>
48 #include <libswscale/swscale.h>
49 #include <libavfilter/avfiltergraph.h>
50 #include <libpostproc/postprocess.h>
51 #include <libavutil/pixfmt.h>
52 }
53 #include "util.h"
54 #include "exceptions.h"
55 #include "scaler.h"
56 #include "format.h"
57 #include "dcp_content_type.h"
58 #include "filter.h"
59 #include "sound_processor.h"
60
61 using namespace std;
62 using namespace boost;
63
64 thread::id ui_thread;
65
66 /** Convert some number of seconds to a string representation
67  *  in hours, minutes and seconds.
68  *
69  *  @param s Seconds.
70  *  @return String of the form H:M:S (where H is hours, M
71  *  is minutes and S is seconds).
72  */
73 string
74 seconds_to_hms (int s)
75 {
76         int m = s / 60;
77         s -= (m * 60);
78         int h = m / 60;
79         m -= (h * 60);
80
81         stringstream hms;
82         hms << h << ":";
83         hms.width (2);
84         hms << setfill ('0') << m << ":";
85         hms.width (2);
86         hms << setfill ('0') << s;
87
88         return hms.str ();
89 }
90
91 /** @param s Number of seconds.
92  *  @return String containing an approximate description of s (e.g. "about 2 hours")
93  */
94 string
95 seconds_to_approximate_hms (int s)
96 {
97         int m = s / 60;
98         s -= (m * 60);
99         int h = m / 60;
100         m -= (h * 60);
101
102         stringstream ap;
103         
104         if (h > 0) {
105                 if (m > 30) {
106                         ap << (h + 1) << " hours";
107                 } else {
108                         if (h == 1) {
109                                 ap << "1 hour";
110                         } else {
111                                 ap << h << " hours";
112                         }
113                 }
114         } else if (m > 0) {
115                 if (m == 1) {
116                         ap << "1 minute";
117                 } else {
118                         ap << m << " minutes";
119                 }
120         } else {
121                 ap << s << " seconds";
122         }
123
124         return ap.str ();
125 }
126
127 #ifdef DVDOMATIC_POSIX
128 /** @param l Mangled C++ identifier.
129  *  @return Demangled version.
130  */
131 static string
132 demangle (string l)
133 {
134         string::size_type const b = l.find_first_of ("(");
135         if (b == string::npos) {
136                 return l;
137         }
138
139         string::size_type const p = l.find_last_of ("+");
140         if (p == string::npos) {
141                 return l;
142         }
143
144         if ((p - b) <= 1) {
145                 return l;
146         }
147         
148         string const fn = l.substr (b + 1, p - b - 1);
149
150         int status;
151         try {
152                 
153                 char* realname = abi::__cxa_demangle (fn.c_str(), 0, 0, &status);
154                 string d (realname);
155                 free (realname);
156                 return d;
157                 
158         } catch (std::exception) {
159                 
160         }
161         
162         return l;
163 }
164
165 /** Write a stacktrace to an ostream.
166  *  @param out Stream to write to.
167  *  @param levels Number of levels to go up the call stack.
168  */
169 void
170 stacktrace (ostream& out, int levels)
171 {
172         void *array[200];
173         size_t size;
174         char **strings;
175         size_t i;
176      
177         size = backtrace (array, 200);
178         strings = backtrace_symbols (array, size);
179      
180         if (strings) {
181                 for (i = 0; i < size && (levels == 0 || i < size_t(levels)); i++) {
182                         out << "  " << demangle (strings[i]) << endl;
183                 }
184                 
185                 free (strings);
186         }
187 }
188 #endif
189
190 /** @param v Version as used by FFmpeg.
191  *  @return A string representation of v.
192  */
193 static string
194 ffmpeg_version_to_string (int v)
195 {
196         stringstream s;
197         s << ((v & 0xff0000) >> 16) << "." << ((v & 0xff00) >> 8) << "." << (v & 0xff);
198         return s.str ();
199 }
200
201 /** Return a user-readable string summarising the versions of our dependencies */
202 string
203 dependency_version_summary ()
204 {
205         stringstream s;
206         s << "libopenjpeg " << opj_version () << ", "
207           << "libavcodec " << ffmpeg_version_to_string (avcodec_version()) << ", "
208           << "libavfilter " << ffmpeg_version_to_string (avfilter_version()) << ", "
209           << "libavformat " << ffmpeg_version_to_string (avformat_version()) << ", "
210           << "libavutil " << ffmpeg_version_to_string (avutil_version()) << ", "
211           << "libpostproc " << ffmpeg_version_to_string (postproc_version()) << ", "
212           << "libswscale " << ffmpeg_version_to_string (swscale_version()) << ", "
213           << MagickVersion << ", "
214           << "libssh " << ssh_version (0) << ", "
215           << "libdcp " << libdcp::version << " git " << libdcp::git_commit;
216
217         return s.str ();
218 }
219
220 double
221 seconds (struct timeval t)
222 {
223         return t.tv_sec + (double (t.tv_usec) / 1e6);
224 }
225
226 /** Call the required functions to set up DVD-o-matic's static arrays, etc.
227  *  Must be called from the UI thread, if there is one.
228  */
229 void
230 dvdomatic_setup ()
231 {
232         Format::setup_formats ();
233         DCPContentType::setup_dcp_content_types ();
234         Scaler::setup_scalers ();
235         Filter::setup_filters ();
236         SoundProcessor::setup_sound_processors ();
237
238         ui_thread = this_thread::get_id ();
239 }
240
241 string
242 crop_string (Position start, Size size)
243 {
244         stringstream s;
245         s << "crop=" << size.width << ":" << size.height << ":" << start.x << ":" << start.y;
246         return s.str ();
247 }
248
249 vector<string>
250 split_at_spaces_considering_quotes (string s)
251 {
252         vector<string> out;
253         bool in_quotes = false;
254         string c;
255         for (string::size_type i = 0; i < s.length(); ++i) {
256                 if (s[i] == ' ' && !in_quotes) {
257                         out.push_back (c);
258                         c = "";
259                 } else if (s[i] == '"') {
260                         in_quotes = !in_quotes;
261                 } else {
262                         c += s[i];
263                 }
264         }
265
266         out.push_back (c);
267         return out;
268 }
269
270 string
271 md5_digest (void const * data, int size)
272 {
273         MD5_CTX md5_context;
274         MD5_Init (&md5_context);
275         MD5_Update (&md5_context, data, size);
276         unsigned char digest[MD5_DIGEST_LENGTH];
277         MD5_Final (digest, &md5_context);
278         
279         stringstream s;
280         for (int i = 0; i < MD5_DIGEST_LENGTH; ++i) {
281                 s << hex << setfill('0') << setw(2) << ((int) digest[i]);
282         }
283
284         return s.str ();
285 }
286
287 /** @param file File name.
288  *  @return MD5 digest of file's contents.
289  */
290 string
291 md5_digest (string file)
292 {
293         ifstream f (file.c_str(), ios::binary);
294         if (!f.good ()) {
295                 throw OpenFileError (file);
296         }
297         
298         f.seekg (0, ios::end);
299         int bytes = f.tellg ();
300         f.seekg (0, ios::beg);
301
302         int const buffer_size = 64 * 1024;
303         char buffer[buffer_size];
304
305         MD5_CTX md5_context;
306         MD5_Init (&md5_context);
307         while (bytes > 0) {
308                 int const t = min (bytes, buffer_size);
309                 f.read (buffer, t);
310                 MD5_Update (&md5_context, buffer, t);
311                 bytes -= t;
312         }
313
314         unsigned char digest[MD5_DIGEST_LENGTH];
315         MD5_Final (digest, &md5_context);
316
317         stringstream s;
318         for (int i = 0; i < MD5_DIGEST_LENGTH; ++i) {
319                 s << hex << setfill('0') << setw(2) << ((int) digest[i]);
320         }
321
322         return s.str ();
323 }
324
325 DCPFrameRate
326 dcp_frame_rate (float fps)
327 {
328         DCPFrameRate dfr;
329
330         dfr.run_fast = (fps != rint (fps));
331         dfr.frames_per_second = rint (fps);
332         dfr.skip = 1;
333
334         /* XXX: somewhat arbitrary */
335         if (fps == 50) {
336                 dfr.frames_per_second = 25;
337                 dfr.skip = 2;
338         }
339
340         return dfr;
341 }
342
343 /** @param An arbitrary sampling rate.
344  *  @return The appropriate DCP-approved sampling rate (48kHz or 96kHz).
345  */
346 int
347 dcp_audio_sample_rate (int fs)
348 {
349         if (fs <= 48000) {
350                 return 48000;
351         }
352
353         return 96000;
354 }
355
356 bool operator== (Size const & a, Size const & b)
357 {
358         return (a.width == b.width && a.height == b.height);
359 }
360
361 bool operator== (Crop const & a, Crop const & b)
362 {
363         return (a.left == b.left && a.right == b.right && a.top == b.top && a.bottom == b.bottom);
364 }
365
366 bool operator!= (Crop const & a, Crop const & b)
367 {
368         return !(a == b);
369 }
370
371 /** @param index Colour LUT index.
372  *  @return Human-readable name.
373  */
374 string
375 colour_lut_index_to_name (int index)
376 {
377         switch (index) {
378         case 0:
379                 return "sRGB";
380         case 1:
381                 return "Rec 709";
382         }
383
384         assert (false);
385         return "";
386 }
387
388 Socket::Socket ()
389         : _deadline (_io_service)
390         , _socket (_io_service)
391         , _buffer_data (0)
392 {
393         _deadline.expires_at (posix_time::pos_infin);
394         check ();
395 }
396
397 void
398 Socket::check ()
399 {
400         if (_deadline.expires_at() <= asio::deadline_timer::traits_type::now ()) {
401                 _socket.close ();
402                 _deadline.expires_at (posix_time::pos_infin);
403         }
404
405         _deadline.async_wait (boost::bind (&Socket::check, this));
406 }
407
408 /** Blocking connect with timeout.
409  *  @param endpoint End-point to connect to.
410  *  @param timeout Time-out in seconds.
411  */
412 void
413 Socket::connect (asio::ip::basic_resolver_entry<asio::ip::tcp> const & endpoint, int timeout)
414 {
415         system::error_code ec = asio::error::would_block;
416         _socket.async_connect (endpoint, lambda::var(ec) = lambda::_1);
417         do {
418                 _io_service.run_one();
419         } while (ec == asio::error::would_block);
420
421         if (ec || !_socket.is_open ()) {
422                 throw NetworkError ("connect timed out");
423         }
424 }
425
426 /** Blocking write with timeout.
427  *  @param data Buffer to write.
428  *  @param size Number of bytes to write.
429  *  @param timeout Time-out, in seconds.
430  */
431 void
432 Socket::write (uint8_t const * data, int size, int timeout)
433 {
434         _deadline.expires_from_now (posix_time::seconds (timeout));
435         system::error_code ec = asio::error::would_block;
436
437         asio::async_write (_socket, asio::buffer (data, size), lambda::var(ec) = lambda::_1);
438         do {
439                 _io_service.run_one ();
440         } while (ec == asio::error::would_block);
441
442         if (ec) {
443                 throw NetworkError ("write timed out");
444         }
445 }
446
447 /** Blocking read with timeout.
448  *  @param data Buffer to read to.
449  *  @param size Number of bytes to read.
450  *  @param timeout Time-out, in seconds.
451  */
452 int
453 Socket::read (uint8_t* data, int size, int timeout)
454 {
455         _deadline.expires_from_now (posix_time::seconds (timeout));
456         system::error_code ec = asio::error::would_block;
457
458         int amount_read = 0;
459
460         _socket.async_read_some (
461                 asio::buffer (data, size),
462                 (lambda::var(ec) = lambda::_1, lambda::var(amount_read) = lambda::_2)
463                 );
464
465         do {
466                 _io_service.run_one ();
467         } while (ec == asio::error::would_block);
468         
469         if (ec) {
470                 amount_read = 0;
471         }
472
473         return amount_read;
474 }
475
476 /** Mark some data as being `consumed', so that it will not be returned
477  *  as data again.
478  *  @param size Amount of data to consume, in bytes.
479  */
480 void
481 Socket::consume (int size)
482 {
483         assert (_buffer_data >= size);
484         
485         _buffer_data -= size;
486         if (_buffer_data > 0) {
487                 /* Shift still-valid data to the start of the buffer */
488                 memmove (_buffer, _buffer + size, _buffer_data);
489         }
490 }
491
492 /** Read a definite amount of data from our socket, and mark
493  *  it as consumed.
494  *  @param data Where to put the data.
495  *  @param size Number of bytes to read.
496  */
497 void
498 Socket::read_definite_and_consume (uint8_t* data, int size, int timeout)
499 {
500         int const from_buffer = min (_buffer_data, size);
501         if (from_buffer > 0) {
502                 /* Get data from our buffer */
503                 memcpy (data, _buffer, from_buffer);
504                 consume (from_buffer);
505                 /* Update our output state */
506                 data += from_buffer;
507                 size -= from_buffer;
508         }
509
510         /* read() the rest */
511         while (size > 0) {
512                 int const n = read (data, size, timeout);
513                 if (n <= 0) {
514                         throw NetworkError ("could not read");
515                 }
516
517                 data += n;
518                 size -= n;
519         }
520 }
521
522 /** Read as much data as is available, up to some limit.
523  *  @param data Where to put the data.
524  *  @param size Maximum amount of data to read.
525  */
526 void
527 Socket::read_indefinite (uint8_t* data, int size, int timeout)
528 {
529         assert (size < int (sizeof (_buffer)));
530
531         /* Amount of extra data we need to read () */
532         int to_read = size - _buffer_data;
533         while (to_read > 0) {
534                 /* read as much of it as we can (into our buffer) */
535                 int const n = read (_buffer + _buffer_data, to_read, timeout);
536                 if (n <= 0) {
537                         throw NetworkError ("could not read");
538                 }
539
540                 to_read -= n;
541                 _buffer_data += n;
542         }
543
544         assert (_buffer_data >= size);
545
546         /* copy data into the output buffer */
547         assert (size >= _buffer_data);
548         memcpy (data, _buffer, size);
549 }
550
551 Rect
552 Rect::intersection (Rect const & other) const
553 {
554         int const tx = max (x, other.x);
555         int const ty = max (y, other.y);
556         
557         return Rect (
558                 tx, ty,
559                 min (x + width, other.x + other.width) - tx,
560                 min (y + height, other.y + other.height) - ty
561                 );
562 }
563
564 /** Round a number up to the nearest multiple of another number.
565  *  @param a Number to round.
566  *  @param t Multiple to round to.
567  *  @return Rounded number.
568  */
569
570 int
571 round_up (int a, int t)
572 {
573         a += (t - 1);
574         return a - (a % t);
575 }
576
577 /** Read a sequence of key / value pairs from a text stream;
578  *  the keys are the first words on the line, and the values are
579  *  the remainder of the line following the key.  Lines beginning
580  *  with # are ignored.
581  *  @param s Stream to read.
582  *  @return key/value pairs.
583  */
584 multimap<string, string>
585 read_key_value (istream &s) 
586 {
587         multimap<string, string> kv;
588         
589         string line;
590         while (getline (s, line)) {
591                 if (line.empty ()) {
592                         continue;
593                 }
594                 
595                 if (line[0] == '#') {
596                         continue;
597                 }
598
599                 if (line[line.size() - 1] == '\r') {
600                         line = line.substr (0, line.size() - 1);
601                 }
602
603                 size_t const s = line.find (' ');
604                 if (s == string::npos) {
605                         continue;
606                 }
607
608                 kv.insert (make_pair (line.substr (0, s), line.substr (s + 1)));
609         }
610
611         return kv;
612 }
613
614 string
615 get_required_string (multimap<string, string> const & kv, string k)
616 {
617         if (kv.count (k) > 1) {
618                 throw StringError ("unexpected multiple keys in key-value set");
619         }
620
621         multimap<string, string>::const_iterator i = kv.find (k);
622         
623         if (i == kv.end ()) {
624                 throw StringError (String::compose ("missing key %1 in key-value set", k));
625         }
626
627         return i->second;
628 }
629
630 int
631 get_required_int (multimap<string, string> const & kv, string k)
632 {
633         string const v = get_required_string (kv, k);
634         return lexical_cast<int> (v);
635 }
636
637 float
638 get_required_float (multimap<string, string> const & kv, string k)
639 {
640         string const v = get_required_string (kv, k);
641         return lexical_cast<float> (v);
642 }
643
644 string
645 get_optional_string (multimap<string, string> const & kv, string k)
646 {
647         if (kv.count (k) > 1) {
648                 throw StringError ("unexpected multiple keys in key-value set");
649         }
650
651         multimap<string, string>::const_iterator i = kv.find (k);
652         if (i == kv.end ()) {
653                 return "";
654         }
655
656         return i->second;
657 }
658
659 int
660 get_optional_int (multimap<string, string> const & kv, string k)
661 {
662         if (kv.count (k) > 1) {
663                 throw StringError ("unexpected multiple keys in key-value set");
664         }
665
666         multimap<string, string>::const_iterator i = kv.find (k);
667         if (i == kv.end ()) {
668                 return 0;
669         }
670
671         return lexical_cast<int> (i->second);
672 }
673
674 AudioBuffers::AudioBuffers (int channels, int frames)
675         : _channels (channels)
676         , _frames (frames)
677         , _allocated_frames (frames)
678 {
679         _data = new float*[_channels];
680         for (int i = 0; i < _channels; ++i) {
681                 _data[i] = new float[frames];
682         }
683 }
684
685 AudioBuffers::AudioBuffers (AudioBuffers const & other)
686         : _channels (other._channels)
687         , _frames (other._frames)
688         , _allocated_frames (other._frames)
689 {
690         _data = new float*[_channels];
691         for (int i = 0; i < _channels; ++i) {
692                 _data[i] = new float[_frames];
693                 memcpy (_data[i], other._data[i], _frames * sizeof (float));
694         }
695 }
696
697 AudioBuffers::~AudioBuffers ()
698 {
699         for (int i = 0; i < _channels; ++i) {
700                 delete[] _data[i];
701         }
702
703         delete[] _data;
704 }
705
706 float*
707 AudioBuffers::data (int c) const
708 {
709         assert (c >= 0 && c < _channels);
710         return _data[c];
711 }
712         
713 void
714 AudioBuffers::set_frames (int f)
715 {
716         assert (f <= _allocated_frames);
717         _frames = f;
718 }
719
720 void
721 AudioBuffers::make_silent ()
722 {
723         for (int i = 0; i < _channels; ++i) {
724                 for (int j = 0; j < _frames; ++j) {
725                         _data[i][j] = 0;
726                 }
727         }
728 }
729
730 void
731 AudioBuffers::copy_from (AudioBuffers* from, int frames_to_copy, int read_offset, int write_offset)
732 {
733         assert (from->channels() == channels());
734
735         for (int i = 0; i < _channels; ++i) {
736                 memcpy (_data[i] + write_offset, from->_data[i] + read_offset, frames_to_copy * sizeof(float));
737         }
738 }
739
740 void
741 AudioBuffers::move (int from, int to, int frames)
742 {
743         if (frames == 0) {
744                 return;
745         }
746         
747         assert (from >= 0);
748         assert (from < _frames);
749         assert (to >= 0);
750         assert (to < _frames);
751         assert (frames > 0);
752         assert (frames <= _frames);
753         assert ((from + frames) <= _frames);
754         assert ((to + frames) <= _frames);
755         
756         for (int i = 0; i < _channels; ++i) {
757                 memmove (_data[i] + to, _data[i] + from, frames * sizeof(float));
758         }
759 }
760
761 void
762 ensure_ui_thread ()
763 {
764         assert (this_thread::get_id() == ui_thread);
765 }
766
767 int64_t
768 video_frames_to_audio_frames (SourceFrame v, float audio_sample_rate, float frames_per_second)
769 {
770         return ((int64_t) v * audio_sample_rate / frames_per_second);
771 }