Logging improvements to allow prettier displays in the server GUI.
[dcpomatic.git] / src / lib / ffmpeg_decoder.cc
index 475418d3d2be34f9d30a65b7cfcfcce5e3089f69..83bce18308ae3b42de919ad6ffc26fe356ee3d61 100644 (file)
@@ -47,10 +47,10 @@ extern "C" {
 
 #include "i18n.h"
 
-#define LOG_GENERAL(...) _log->log (String::compose (__VA_ARGS__), Log::TYPE_GENERAL);
-#define LOG_ERROR(...) _log->log (String::compose (__VA_ARGS__), Log::TYPE_ERROR);
-#define LOG_WARNING_NC(...) _log->log (__VA_ARGS__, Log::TYPE_WARNING);
-#define LOG_WARNING(...) _log->log (String::compose (__VA_ARGS__), Log::TYPE_WARNING);
+#define LOG_GENERAL(...) _log->log (String::compose (__VA_ARGS__), LogEntry::TYPE_GENERAL);
+#define LOG_ERROR(...) _log->log (String::compose (__VA_ARGS__), LogEntry::TYPE_ERROR);
+#define LOG_WARNING_NC(...) _log->log (__VA_ARGS__, LogEntry::TYPE_WARNING);
+#define LOG_WARNING(...) _log->log (String::compose (__VA_ARGS__), LogEntry::TYPE_WARNING);
 
 using std::cout;
 using std::vector;
@@ -324,7 +324,7 @@ FFmpegDecoder::decode_audio_packet ()
                }
 
                if (frame_finished) {
-                       ContentTime const ct = ContentTime::from_seconds (
+                       ContentTime ct = ContentTime::from_seconds (
                                av_frame_get_best_effort_timestamp (_frame) *
                                av_q2d ((*stream)->stream (_format_context)->time_base))
                                + _pts_offset;
@@ -333,7 +333,19 @@ FFmpegDecoder::decode_audio_packet ()
                                0, (*stream)->stream(_format_context)->codec->channels, _frame->nb_samples, audio_sample_format (*stream), 1
                                );
 
-                       audio (*stream, deinterleave_audio (*stream, _frame->data, data_size), ct);
+                       shared_ptr<AudioBuffers> data = deinterleave_audio (*stream, _frame->data, data_size);
+
+                       if (ct < ContentTime ()) {
+                               /* Discard audio data that comes before time 0 */
+                               Frame const remove = min (int64_t (data->frames()), (-ct).frames_ceil(double((*stream)->frame_rate ())));
+                               data->move (remove, 0, data->frames() - remove);
+                               data->set_frames (data->frames() - remove);
+                               ct += ContentTime::from_frames (remove, (*stream)->frame_rate ());
+                       }
+
+                       if (data->frames() > 0) {
+                               audio (*stream, data, ct);
+                       }
                }
 
                copy_packet.data += decode_result;
@@ -400,8 +412,6 @@ FFmpegDecoder::decode_subtitle_packet ()
                   indicate that the previous subtitle should stop.  We can ignore it here.
                */
                return;
-       } else if (sub.num_rects > 1) {
-               throw DecodeError (_("multi-part subtitles not yet supported"));
        }
 
        /* Subtitle PTS (within the source, not taking into account any of the
@@ -418,20 +428,22 @@ FFmpegDecoder::decode_subtitle_packet ()
                period.to = ffmpeg_content()->subtitle_stream()->find_subtitle_to (period.from);
        }
 
-       AVSubtitleRect const * rect = sub.rects[0];
-
-       switch (rect->type) {
-       case SUBTITLE_NONE:
-               break;
-       case SUBTITLE_BITMAP:
-               decode_bitmap_subtitle (rect, period);
-               break;
-       case SUBTITLE_TEXT:
-               cout << "XXX: SUBTITLE_TEXT " << rect->text << "\n";
-               break;
-       case SUBTITLE_ASS:
-               cout << "XXX: SUBTITLE_ASS " << rect->ass << "\n";
-               break;
+       for (unsigned int i = 0; i < sub.num_rects; ++i) {
+               AVSubtitleRect const * rect = sub.rects[i];
+
+               switch (rect->type) {
+               case SUBTITLE_NONE:
+                       break;
+               case SUBTITLE_BITMAP:
+                       decode_bitmap_subtitle (rect, period);
+                       break;
+               case SUBTITLE_TEXT:
+                       cout << "XXX: SUBTITLE_TEXT " << rect->text << "\n";
+                       break;
+               case SUBTITLE_ASS:
+                       cout << "XXX: SUBTITLE_ASS " << rect->ass << "\n";
+                       break;
+               }
        }
 
        avsubtitle_free (&sub);