Store audio length in AudioStream.
authorCarl Hetherington <cth@carlh.net>
Tue, 10 May 2016 14:06:19 +0000 (15:06 +0100)
committerCarl Hetherington <cth@carlh.net>
Wed, 18 May 2016 10:50:29 +0000 (11:50 +0100)
src/lib/audio_stream.cc
src/lib/audio_stream.h
src/lib/dcp_content.cc
src/lib/ffmpeg_audio_stream.cc
src/lib/ffmpeg_audio_stream.h
src/lib/ffmpeg_examiner.cc
src/lib/sndfile_content.cc
src/lib/sndfile_content.h
test/audio_decoder_test.cc
test/frame_rate_test.cc

index 2119d08344566ef48e9f6a9186079035abd7b1ca..8e260b34643c216a20d9be290520beedc6a50d85 100644 (file)
@@ -1,5 +1,5 @@
 /*
-    Copyright (C) 2015 Carl Hetherington <cth@carlh.net>
+    Copyright (C) 2015-2016 Carl Hetherington <cth@carlh.net>
 
     This program is free software; you can redistribute it and/or modify
     it under the terms of the GNU General Public License as published by
 #include "audio_mapping.h"
 #include "util.h"
 
-AudioStream::AudioStream (int frame_rate, int channels)
+AudioStream::AudioStream (int frame_rate, Frame length, int channels)
        : _frame_rate (frame_rate)
+       , _length (length)
 {
        _mapping = AudioMapping (channels, MAX_DCP_AUDIO_CHANNELS);
 }
 
-AudioStream::AudioStream (int frame_rate, AudioMapping mapping)
+AudioStream::AudioStream (int frame_rate, Frame length, AudioMapping mapping)
        : _frame_rate (frame_rate)
+       , _length (length)
        , _mapping (mapping)
 {
 
index 8d05df268bca62e33b654114bd73ad60659dde83..bf7b284f88cbd4eccd7ee10e6b9d646207dedf5d 100644 (file)
@@ -1,5 +1,5 @@
 /*
-    Copyright (C) 2015 Carl Hetherington <cth@carlh.net>
+    Copyright (C) 2015-2016 Carl Hetherington <cth@carlh.net>
 
     This program is free software; you can redistribute it and/or modify
     it under the terms of the GNU General Public License as published by
@@ -21,6 +21,7 @@
 #define DCPOMATIC_AUDIO_STREAM_H
 
 #include "audio_mapping.h"
+#include "types.h"
 #include <boost/thread/mutex.hpp>
 
 struct audio_sampling_rate_test;
@@ -28,8 +29,8 @@ struct audio_sampling_rate_test;
 class AudioStream
 {
 public:
-       AudioStream (int frame_rate, int channels);
-       AudioStream (int frame_rate, AudioMapping mapping);
+       AudioStream (int frame_rate, Frame length, int channels);
+       AudioStream (int frame_rate, Frame length, AudioMapping mapping);
        virtual ~AudioStream () {}
 
        void set_mapping (AudioMapping mapping);
@@ -44,6 +45,11 @@ public:
                return _frame_rate;
        }
 
+       Frame length () const {
+               boost::mutex::scoped_lock lm (_mutex);
+               return _length;
+       }
+
        int channels () const;
 
 protected:
@@ -54,6 +60,7 @@ private:
        friend struct player_time_calculation_test3;
 
        int _frame_rate;
+       Frame _length;
        AudioMapping _mapping;
 };
 
index dbd9bca8d4cd2fb9d3b87962ab12fcc9b039b772..83374fc3051759f815819cf8c71cb6bb0c57a672 100644 (file)
@@ -78,7 +78,11 @@ DCPContent::DCPContent (shared_ptr<const Film> film, cxml::ConstNodePtr node, in
 
        audio->set_stream (
                AudioStreamPtr (
-                       new AudioStream (node->number_child<int> ("AudioFrameRate"), AudioMapping (node->node_child ("AudioMapping"), version))
+                       new AudioStream (
+                               node->number_child<int> ("AudioFrameRate"),
+                               node->number_child<Frame> ("AudioLength"),
+                               AudioMapping (node->node_child ("AudioMapping"), version)
+                               )
                        )
                );
 
@@ -121,7 +125,7 @@ DCPContent::examine (shared_ptr<Job> job)
        {
                boost::mutex::scoped_lock lm (_mutex);
 
-               AudioStreamPtr as (new AudioStream (examiner->audio_frame_rate(), examiner->audio_channels ()));
+               AudioStreamPtr as (new AudioStream (examiner->audio_frame_rate(), examiner->audio_length(), examiner->audio_channels()));
                audio->set_stream (as);
                AudioMapping m = as->mapping ();
                film()->make_audio_mapping_default (m);
@@ -174,6 +178,7 @@ DCPContent::as_xml (xmlpp::Node* node) const
        if (audio) {
                audio->as_xml (node);
                node->add_child("AudioFrameRate")->add_child_text (raw_convert<string> (audio->stream()->frame_rate()));
+               node->add_child("AudioLength")->add_child_text (raw_convert<string> (audio->stream()->length()));
                audio->stream()->mapping().as_xml (node->add_child("AudioMapping"));
        }
 
index d7fc7eaedf56b24dfdb768cea1c84c0fc122d82f..31cbe260953d38c5693af767a855b8dd40dc41dd 100644 (file)
@@ -27,7 +27,11 @@ using boost::optional;
 
 FFmpegAudioStream::FFmpegAudioStream (cxml::ConstNodePtr node, int version)
        : FFmpegStream (node)
-       , AudioStream (node->number_child<int> ("FrameRate"), AudioMapping (node->node_child ("Mapping"), version))
+       , AudioStream (
+               node->number_child<int> ("FrameRate"),
+               node->optional_number_child<Frame>("Length").get_value_or (0),
+               AudioMapping (node->node_child ("Mapping"), version)
+               )
 {
        optional<ContentTime::Type> const f = node->optional_number_child<ContentTime::Type> ("FirstAudio");
        if (f) {
@@ -40,6 +44,7 @@ FFmpegAudioStream::as_xml (xmlpp::Node* root) const
 {
        FFmpegStream::as_xml (root);
        root->add_child("FrameRate")->add_child_text (raw_convert<string> (frame_rate ()));
+       root->add_child("Length")->add_child_text (raw_convert<string> (length ()));
        mapping().as_xml (root->add_child("Mapping"));
        if (first_audio) {
                root->add_child("FirstAudio")->add_child_text (raw_convert<string> (first_audio.get().get ()));
index 5e782ac1a97e1e451eb2b7fbc332f83157259835..8de43c6323727b3ced2208c34248719dd6c6f428 100644 (file)
@@ -26,9 +26,9 @@ struct ffmpeg_pts_offset_test;
 class FFmpegAudioStream : public FFmpegStream, public AudioStream
 {
 public:
-       FFmpegAudioStream (std::string name, int id, int frame_rate, int channels)
+       FFmpegAudioStream (std::string name, int id, int frame_rate, Frame length, int channels)
                : FFmpegStream (name, id)
-               , AudioStream (frame_rate, channels)
+               , AudioStream (frame_rate, length, channels)
        {}
 
        FFmpegAudioStream (cxml::ConstNodePtr, int);
@@ -45,6 +45,6 @@ private:
        /* Constructor for tests */
        FFmpegAudioStream ()
                : FFmpegStream ("", 0)
-               , AudioStream (0, 0)
+               , AudioStream (0, 0, 0)
        {}
 };
index 44d6a87dfdd6b262b4eaafd5d54ab678d7c809d8..bf9bafbfa8400a6c24a7386913e1bc0480e81e8b 100644 (file)
@@ -61,9 +61,17 @@ FFmpegExaminer::FFmpegExaminer (shared_ptr<const FFmpegContent> c, shared_ptr<Jo
                                s->codec->channel_layout = av_get_default_channel_layout (s->codec->channels);
                        }
 
+                       DCPOMATIC_ASSERT (_format_context->duration != AV_NOPTS_VALUE);
+
                        _audio_streams.push_back (
                                shared_ptr<FFmpegAudioStream> (
-                                       new FFmpegAudioStream (audio_stream_name (s), s->id, s->codec->sample_rate, s->codec->channels)
+                                       new FFmpegAudioStream (
+                                               audio_stream_name (s),
+                                               s->id,
+                                               s->codec->sample_rate,
+                                               (double (_format_context->duration) / AV_TIME_BASE) * s->codec->sample_rate,
+                                               s->codec->channels
+                                               )
                                        )
                                );
 
index bf5f3af5bbd22775b0a2ef4a9134ae6bfaf2a031..81e467d1d27feb2878fe4175f4890b28f23914fd 100644 (file)
@@ -46,14 +46,18 @@ SndfileContent::SndfileContent (shared_ptr<const Film> film, boost::filesystem::
 
 SndfileContent::SndfileContent (shared_ptr<const Film> film, cxml::ConstNodePtr node, int version)
        : Content (film, node)
-       , _audio_length (node->number_child<Frame> ("AudioLength"))
 {
        audio = AudioContent::from_xml (this, film, node);
 
        if (audio) {
                audio->set_stream (
                        AudioStreamPtr (
-                               new AudioStream (node->number_child<int> ("AudioFrameRate"), AudioMapping (node->node_child ("AudioMapping"), version)))
+                               new AudioStream (
+                                       node->number_child<int> ("AudioFrameRate"),
+                                       node->number_child<Frame> ("AudioLength"),
+                                       AudioMapping (node->node_child ("AudioMapping"), version)
+                                       )
+                               )
                        );
        }
 }
@@ -68,10 +72,9 @@ SndfileContent::as_xml (xmlpp::Node* node) const
        if (audio) {
                audio->as_xml (node);
                node->add_child("AudioFrameRate")->add_child_text (raw_convert<string> (audio->stream()->frame_rate ()));
+               node->add_child("AudioLength")->add_child_text (raw_convert<string> (audio->stream()->length ()));
                audio->stream()->mapping().as_xml (node->add_child("AudioMapping"));
        }
-
-       node->add_child("AudioLength")->add_child_text (raw_convert<string> (audio_length ()));
 }
 
 
@@ -108,12 +111,11 @@ SndfileContent::examine (shared_ptr<Job> job)
 
        {
                boost::mutex::scoped_lock lm (_mutex);
-               AudioStreamPtr as (new AudioStream (ex->audio_frame_rate(), ex->audio_channels ()));
+               AudioStreamPtr as (new AudioStream (ex->audio_frame_rate(), ex->audio_length(), ex->audio_channels ()));
                audio->set_stream (as);
                AudioMapping m = as->mapping ();
                film()->make_audio_mapping_default (m);
                as->set_mapping (m);
-               _audio_length = ex->audio_length ();
        }
 
        signal_changed (AudioContentProperty::STREAMS);
@@ -123,5 +125,5 @@ DCPTime
 SndfileContent::full_length () const
 {
        FrameRateChange const frc (active_video_frame_rate(), film()->video_frame_rate());
-       return DCPTime::from_frames (audio_length() / frc.speed_up, audio->stream()->frame_rate ());
+       return DCPTime::from_frames (audio->stream()->length() / frc.speed_up, audio->stream()->frame_rate ());
 }
index 73d02edec3f91a37c14a2f9f3dea1d8650583566..cdb842c042f471d234eb5df17ab543cb8b2be149 100644 (file)
@@ -43,14 +43,6 @@ public:
        void as_xml (xmlpp::Node *) const;
 
        static bool valid_file (boost::filesystem::path);
-
-private:
-       Frame audio_length () const {
-               boost::mutex::scoped_lock lm (_mutex);
-               return _audio_length;
-       }
-
-       Frame _audio_length;
 };
 
 #endif
index 73d5154929f82e9a08889ed3b03440506955d4ef..7dba67b5a8505a821127221eaf18a5ee9d693f3b 100644 (file)
@@ -42,7 +42,7 @@ public:
                : Content (film)
        {
                audio.reset (new AudioContent (this, film));
-               audio->set_stream (AudioStreamPtr (new AudioStream (48000, 2)));
+               audio->set_stream (AudioStreamPtr (new AudioStream (48000, audio_length(), 2)));
        }
 
        std::string summary () const {
index 9c2e9ec3fc490ace0ffeacae190f7fe1f06b049c..68846470525cf86a77ff346430c3c8e56057ab78 100644 (file)
@@ -261,7 +261,7 @@ BOOST_AUTO_TEST_CASE (audio_sampling_rate_test)
        afr.push_back (30);
        Config::instance()->set_allowed_dcp_frame_rates (afr);
 
-       shared_ptr<FFmpegAudioStream> stream (new FFmpegAudioStream ("foo", 0, 0, 0));
+       shared_ptr<FFmpegAudioStream> stream (new FFmpegAudioStream ("foo", 0, 0, 0, 0));
        content->audio->add_stream (stream);
        content->_video_frame_rate = 24;
        film->set_video_frame_rate (24);