summaryrefslogtreecommitdiff
path: root/src/lib
diff options
context:
space:
mode:
authorCarl Hetherington <cth@carlh.net>2013-05-23 17:18:49 +0100
committerCarl Hetherington <cth@carlh.net>2013-05-23 17:18:49 +0100
commit64a2f1bb6a7b972607fa363631ef7a47444e8217 (patch)
tree020c028a93f113e372e70f485857ce04dea5db3d /src/lib
parent8c6fe8e1e8c8f6d5932606f2a5b6e1b87681ae38 (diff)
Various bits and pieces.
Diffstat (limited to 'src/lib')
-rw-r--r--src/lib/audio_content.cc12
-rw-r--r--src/lib/audio_content.h8
-rw-r--r--src/lib/audio_decoder.cc15
-rw-r--r--src/lib/audio_decoder.h5
-rw-r--r--src/lib/black_decoder.cc17
-rw-r--r--src/lib/black_decoder.h2
-rw-r--r--src/lib/content.cc16
-rw-r--r--src/lib/content.h17
-rw-r--r--src/lib/examine_content_job.cc2
-rw-r--r--src/lib/ffmpeg_content.cc33
-rw-r--r--src/lib/ffmpeg_content.h10
-rw-r--r--src/lib/ffmpeg_decoder.cc1
-rw-r--r--src/lib/film.cc30
-rw-r--r--src/lib/film.h4
-rw-r--r--src/lib/imagemagick_content.cc25
-rw-r--r--src/lib/imagemagick_content.h8
-rw-r--r--src/lib/null_content.cc30
-rw-r--r--src/lib/null_content.h17
-rw-r--r--src/lib/player.cc24
-rw-r--r--src/lib/player.h10
-rw-r--r--src/lib/playlist.cc12
-rw-r--r--src/lib/playlist.h4
-rw-r--r--src/lib/silence_decoder.cc56
-rw-r--r--src/lib/silence_decoder.h6
-rw-r--r--src/lib/sndfile_content.cc38
-rw-r--r--src/lib/sndfile_content.h10
-rw-r--r--src/lib/types.h2
-rw-r--r--src/lib/video_content.cc12
-rw-r--r--src/lib/video_content.h6
-rw-r--r--src/lib/video_decoder.h2
-rw-r--r--src/lib/wscript3
31 files changed, 277 insertions, 160 deletions
diff --git a/src/lib/audio_content.cc b/src/lib/audio_content.cc
index a3942f64b..607e71c50 100644
--- a/src/lib/audio_content.cc
+++ b/src/lib/audio_content.cc
@@ -32,24 +32,24 @@ int const AudioContentProperty::AUDIO_FRAME_RATE = 202;
int const AudioContentProperty::AUDIO_GAIN = 203;
int const AudioContentProperty::AUDIO_DELAY = 204;
-AudioContent::AudioContent (Time s)
- : Content (s)
+AudioContent::AudioContent (shared_ptr<const Film> f, Time s)
+ : Content (f, s)
, _audio_gain (0)
, _audio_delay (0)
{
}
-AudioContent::AudioContent (boost::filesystem::path f)
- : Content (f)
+AudioContent::AudioContent (shared_ptr<const Film> f, boost::filesystem::path p)
+ : Content (f, p)
, _audio_gain (0)
, _audio_delay (0)
{
}
-AudioContent::AudioContent (shared_ptr<const cxml::Node> node)
- : Content (node)
+AudioContent::AudioContent (shared_ptr<const Film> f, shared_ptr<const cxml::Node> node)
+ : Content (f, node)
{
_audio_gain = node->number_child<float> ("AudioGain");
_audio_delay = node->number_child<int> ("AudioDelay");
diff --git a/src/lib/audio_content.h b/src/lib/audio_content.h
index e767fd326..0c5287eaf 100644
--- a/src/lib/audio_content.h
+++ b/src/lib/audio_content.h
@@ -42,9 +42,9 @@ public:
class AudioContent : public virtual Content
{
public:
- AudioContent (Time);
- AudioContent (boost::filesystem::path);
- AudioContent (boost::shared_ptr<const cxml::Node>);
+ AudioContent (boost::shared_ptr<const Film>, Time);
+ AudioContent (boost::shared_ptr<const Film>, boost::filesystem::path);
+ AudioContent (boost::shared_ptr<const Film>, boost::shared_ptr<const cxml::Node>);
AudioContent (AudioContent const &);
void as_xml (xmlpp::Node *) const;
@@ -52,7 +52,7 @@ public:
virtual int audio_channels () const = 0;
virtual ContentAudioFrame audio_length () const = 0;
virtual int content_audio_frame_rate () const = 0;
- virtual int output_audio_frame_rate (boost::shared_ptr<const Film>) const = 0;
+ virtual int output_audio_frame_rate () const = 0;
virtual AudioMapping audio_mapping () const = 0;
void set_audio_gain (float);
diff --git a/src/lib/audio_decoder.cc b/src/lib/audio_decoder.cc
index ddda816a5..6712e0624 100644
--- a/src/lib/audio_decoder.cc
+++ b/src/lib/audio_decoder.cc
@@ -32,15 +32,18 @@ AudioDecoder::AudioDecoder (shared_ptr<const Film> f, shared_ptr<const AudioCont
: Decoder (f)
, _next_audio (0)
, _audio_content (c)
- , _output_audio_frame_rate (_audio_content->output_audio_frame_rate (f))
{
- if (_audio_content->content_audio_frame_rate() != _output_audio_frame_rate) {
+ if (_audio_content->content_audio_frame_rate() != _audio_content->output_audio_frame_rate()) {
shared_ptr<const Film> film = _film.lock ();
assert (film);
stringstream s;
- s << String::compose ("Will resample audio from %1 to %2", _audio_content->content_audio_frame_rate(), _output_audio_frame_rate);
+ s << String::compose (
+ "Will resample audio from %1 to %2",
+ _audio_content->content_audio_frame_rate(), _audio_content->output_audio_frame_rate()
+ );
+
film->log()->log (s.str ());
/* We will be using planar float data when we call the
@@ -55,7 +58,7 @@ AudioDecoder::AudioDecoder (shared_ptr<const Film> f, shared_ptr<const AudioCont
0,
av_get_default_channel_layout (MAX_AUDIO_CHANNELS),
AV_SAMPLE_FMT_FLTP,
- _output_audio_frame_rate,
+ _audio_content->output_audio_frame_rate(),
av_get_default_channel_layout (MAX_AUDIO_CHANNELS),
AV_SAMPLE_FMT_FLTP,
_audio_content->content_audio_frame_rate(),
@@ -115,7 +118,9 @@ AudioDecoder::audio (shared_ptr<const AudioBuffers> data, Time time)
if (_swr_context) {
/* Compute the resampled frames count and add 32 for luck */
- int const max_resampled_frames = ceil ((int64_t) data->frames() * _output_audio_frame_rate / _audio_content->content_audio_frame_rate()) + 32;
+ int const max_resampled_frames = ceil (
+ (int64_t) data->frames() * _audio_content->output_audio_frame_rate() / _audio_content->content_audio_frame_rate()
+ ) + 32;
shared_ptr<AudioBuffers> resampled (new AudioBuffers (MAX_AUDIO_CHANNELS, max_resampled_frames));
diff --git a/src/lib/audio_decoder.h b/src/lib/audio_decoder.h
index 0f7cb6dbd..fb9f23f03 100644
--- a/src/lib/audio_decoder.h
+++ b/src/lib/audio_decoder.h
@@ -46,11 +46,10 @@ protected:
void audio (boost::shared_ptr<const AudioBuffers>, Time);
Time _next_audio;
-
-private:
boost::shared_ptr<const AudioContent> _audio_content;
+
+private:
SwrContext* _swr_context;
- int _output_audio_frame_rate;
};
#endif
diff --git a/src/lib/black_decoder.cc b/src/lib/black_decoder.cc
index 482cd2ce1..e8e1a3df2 100644
--- a/src/lib/black_decoder.cc
+++ b/src/lib/black_decoder.cc
@@ -18,9 +18,14 @@
*/
#include "black_decoder.h"
+#include "image.h"
+#include "null_content.h"
-BlackDecoder::BlackDecoder (shared_ptr<Film> f, shared_ptr<NullContent> c)
- : VideoDecoder (f, c)
+using boost::shared_ptr;
+
+BlackDecoder::BlackDecoder (shared_ptr<const Film> f, shared_ptr<NullContent> c)
+ : Decoder (f)
+ , VideoDecoder (f, c)
{
}
@@ -29,7 +34,7 @@ void
BlackDecoder::pass ()
{
if (!_image) {
- _image.reset (new SimpleImage (AV_PIX_FMT_RGB24, video_size ()));
+ _image.reset (new SimpleImage (AV_PIX_FMT_RGB24, video_size(), true));
_image->make_black ();
video (_image, false, _next_video);
} else {
@@ -59,3 +64,9 @@ BlackDecoder::next () const
{
return _next_video;
}
+
+void
+BlackDecoder::seek (Time t)
+{
+ _next_video = t;
+}
diff --git a/src/lib/black_decoder.h b/src/lib/black_decoder.h
index bb3e7711d..b4beb0fdd 100644
--- a/src/lib/black_decoder.h
+++ b/src/lib/black_decoder.h
@@ -19,6 +19,8 @@
#include "video_decoder.h"
+class NullContent;
+
class BlackDecoder : public VideoDecoder
{
public:
diff --git a/src/lib/content.cc b/src/lib/content.cc
index 43d0ef958..395359fa7 100644
--- a/src/lib/content.cc
+++ b/src/lib/content.cc
@@ -29,20 +29,23 @@ using std::string;
using boost::shared_ptr;
using boost::lexical_cast;
-Content::Content (Time s)
- : _start (s)
+Content::Content (shared_ptr<const Film> f, Time s)
+ : _film (f)
+ , _start (s)
{
}
-Content::Content (boost::filesystem::path f)
- : _file (f)
+Content::Content (shared_ptr<const Film> f, boost::filesystem::path p)
+ : _film (f)
+ , _file (p)
, _start (0)
{
}
-Content::Content (shared_ptr<const cxml::Node> node)
+Content::Content (shared_ptr<const Film> f, shared_ptr<const cxml::Node> node)
+ : _film (f)
{
_file = node->string_child ("File");
_digest = node->string_child ("Digest");
@@ -51,6 +54,7 @@ Content::Content (shared_ptr<const cxml::Node> node)
Content::Content (Content const & o)
: boost::enable_shared_from_this<Content> (o)
+ , _film (o._film)
, _file (o._file)
, _digest (o._digest)
, _start (o._start)
@@ -68,7 +72,7 @@ Content::as_xml (xmlpp::Node* node) const
}
void
-Content::examine (shared_ptr<Film>, shared_ptr<Job>)
+Content::examine (shared_ptr<Job>)
{
string const d = md5_digest (_file);
boost::mutex::scoped_lock lm (_mutex);
diff --git a/src/lib/content.h b/src/lib/content.h
index db1e56bc4..bcfbef7e3 100644
--- a/src/lib/content.h
+++ b/src/lib/content.h
@@ -39,17 +39,17 @@ class Film;
class Content : public boost::enable_shared_from_this<Content>
{
public:
- Content (Time);
- Content (boost::filesystem::path);
- Content (boost::shared_ptr<const cxml::Node>);
+ Content (boost::shared_ptr<const Film>, Time);
+ Content (boost::shared_ptr<const Film>, boost::filesystem::path);
+ Content (boost::shared_ptr<const Film>, boost::shared_ptr<const cxml::Node>);
Content (Content const &);
- virtual void examine (boost::shared_ptr<Film>, boost::shared_ptr<Job>);
+ virtual void examine (boost::shared_ptr<Job>);
virtual std::string summary () const = 0;
virtual std::string information () const = 0;
virtual void as_xml (xmlpp::Node *) const;
virtual boost::shared_ptr<Content> clone () const = 0;
- virtual Time length (boost::shared_ptr<const Film>) const = 0;
+ virtual Time length () const = 0;
boost::filesystem::path file () const {
boost::mutex::scoped_lock lm (_mutex);
@@ -66,15 +66,16 @@ public:
return _start;
}
- Time end (boost::shared_ptr<const Film> f) const {
- return start() + length(f);
+ Time end () const {
+ return start() + length();
}
boost::signals2::signal<void (boost::weak_ptr<Content>, int)> Changed;
protected:
void signal_changed (int);
-
+
+ boost::weak_ptr<const Film> _film;
mutable boost::mutex _mutex;
private:
diff --git a/src/lib/examine_content_job.cc b/src/lib/examine_content_job.cc
index 21ab4a71d..6d5f4faf9 100644
--- a/src/lib/examine_content_job.cc
+++ b/src/lib/examine_content_job.cc
@@ -47,7 +47,7 @@ ExamineContentJob::name () const
void
ExamineContentJob::run ()
{
- _content->examine (_film, shared_from_this ());
+ _content->examine (shared_from_this ());
set_progress (1);
set_state (FINISHED_OK);
}
diff --git a/src/lib/ffmpeg_content.cc b/src/lib/ffmpeg_content.cc
index 2a4283353..ad7af07d8 100644
--- a/src/lib/ffmpeg_content.cc
+++ b/src/lib/ffmpeg_content.cc
@@ -42,18 +42,18 @@ int const FFmpegContentProperty::SUBTITLE_STREAM = 101;
int const FFmpegContentProperty::AUDIO_STREAMS = 102;
int const FFmpegContentProperty::AUDIO_STREAM = 103;
-FFmpegContent::FFmpegContent (boost::filesystem::path f)
- : Content (f)
- , VideoContent (f)
- , AudioContent (f)
+FFmpegContent::FFmpegContent (shared_ptr<const Film> f, boost::filesystem::path p)
+ : Content (f, p)
+ , VideoContent (f, p)
+ , AudioContent (f, p)
{
}
-FFmpegContent::FFmpegContent (shared_ptr<const cxml::Node> node)
- : Content (node)
- , VideoContent (node)
- , AudioContent (node)
+FFmpegContent::FFmpegContent (shared_ptr<const Film> f, shared_ptr<const cxml::Node> node)
+ : Content (f, node)
+ , VideoContent (f, node)
+ , AudioContent (f, node)
{
list<shared_ptr<cxml::Node> > c = node->node_children ("SubtitleStream");
for (list<shared_ptr<cxml::Node> >::const_iterator i = c.begin(); i != c.end(); ++i) {
@@ -112,11 +112,14 @@ FFmpegContent::as_xml (xmlpp::Node* node) const
}
void
-FFmpegContent::examine (shared_ptr<Film> film, shared_ptr<Job> job)
+FFmpegContent::examine (shared_ptr<Job> job)
{
job->set_progress_unknown ();
- Content::examine (film, job);
+ Content::examine (job);
+
+ shared_ptr<const Film> film = _film.lock ();
+ assert (film);
shared_ptr<FFmpegDecoder> decoder (new FFmpegDecoder (film, shared_from_this (), true, false, false));
@@ -233,8 +236,11 @@ FFmpegContent::content_audio_frame_rate () const
}
int
-FFmpegContent::output_audio_frame_rate (shared_ptr<const Film> film) const
+FFmpegContent::output_audio_frame_rate () const
{
+ shared_ptr<const Film> film = _film.lock ();
+ assert (film);
+
/* Resample to a DCI-approved sample rate */
double t = dcp_audio_frame_rate (content_audio_frame_rate ());
@@ -308,8 +314,11 @@ FFmpegContent::clone () const
}
Time
-FFmpegContent::length (shared_ptr<const Film> film) const
+FFmpegContent::length () const
{
+ shared_ptr<const Film> film = _film.lock ();
+ assert (film);
+
FrameRateConversion frc (video_frame_rate (), film->dcp_video_frame_rate ());
return video_length() * frc.factor() * TIME_HZ / film->dcp_video_frame_rate ();
}
diff --git a/src/lib/ffmpeg_content.h b/src/lib/ffmpeg_content.h
index 9d842515e..d5b986996 100644
--- a/src/lib/ffmpeg_content.h
+++ b/src/lib/ffmpeg_content.h
@@ -80,26 +80,26 @@ public:
class FFmpegContent : public VideoContent, public AudioContent
{
public:
- FFmpegContent (boost::filesystem::path);
- FFmpegContent (boost::shared_ptr<const cxml::Node>);
+ FFmpegContent (boost::shared_ptr<const Film>, boost::filesystem::path);
+ FFmpegContent (boost::shared_ptr<const Film>, boost::shared_ptr<const cxml::Node>);
FFmpegContent (FFmpegContent const &);
boost::shared_ptr<FFmpegContent> shared_from_this () {
return boost::dynamic_pointer_cast<FFmpegContent> (Content::shared_from_this ());
}
- void examine (boost::shared_ptr<Film>, boost::shared_ptr<Job>);
+ void examine (boost::shared_ptr<Job>);
std::string summary () const;
std::string information () const;
void as_xml (xmlpp::Node *) const;
boost::shared_ptr<Content> clone () const;
- Time length (boost::shared_ptr<const Film>) const;
+ Time length () const;
/* AudioContent */
int audio_channels () const;
ContentAudioFrame audio_length () const;
int content_audio_frame_rate () const;
- int output_audio_frame_rate (boost::shared_ptr<const Film>) const;
+ int output_audio_frame_rate () const;
AudioMapping audio_mapping () const;
std::vector<boost::shared_ptr<FFmpegSubtitleStream> > subtitle_streams () const {
diff --git a/src/lib/ffmpeg_decoder.cc b/src/lib/ffmpeg_decoder.cc
index f7bb97944..b45ba8585 100644
--- a/src/lib/ffmpeg_decoder.cc
+++ b/src/lib/ffmpeg_decoder.cc
@@ -473,6 +473,7 @@ void
FFmpegDecoder::do_seek (Time t, bool backwards, bool accurate)
{
int64_t const vt = t / (av_q2d (_format_context->streams[_video_stream]->time_base) * TIME_HZ);
+ cout << "seek-> " << t << "\n";
av_seek_frame (_format_context, _video_stream, vt, backwards ? AVSEEK_FLAG_BACKWARD : 0);
avcodec_flush_buffers (_video_codec_context);
diff --git a/src/lib/film.cc b/src/lib/film.cc
index b561c2d15..9103024ab 100644
--- a/src/lib/film.cc
+++ b/src/lib/film.cc
@@ -83,15 +83,12 @@ using libdcp::Size;
int const Film::state_version = 4;
-/** Construct a Film object in a given directory, reading any metadata
- * file that exists in that directory. An exception will be thrown if
- * must_exist is true and the specified directory does not exist.
+/** Construct a Film object in a given directory.
*
* @param d Film directory.
- * @param must_exist true to throw an exception if does not exist.
*/
-Film::Film (string d, bool must_exist)
+Film::Film (string d)
: _playlist (new Playlist)
, _use_dci_name (true)
, _dcp_content_type (Config::instance()->default_dcp_content_type ())
@@ -131,21 +128,6 @@ Film::Film (string d, bool must_exist)
}
set_directory (result.string ());
-
- if (!boost::filesystem::exists (directory())) {
- if (must_exist) {
- throw OpenFileError (directory());
- } else {
- boost::filesystem::create_directory (directory());
- }
- }
-
- if (must_exist) {
- read_metadata ();
- } else {
- write_metadata ();
- }
-
_log.reset (new FileLog (file ("log")));
}
@@ -388,6 +370,10 @@ Film::encoded_frames () const
void
Film::write_metadata () const
{
+ if (!boost::filesystem::exists (directory())) {
+ boost::filesystem::create_directory (directory());
+ }
+
boost::mutex::scoped_lock lm (_state_mutex);
LocaleGuard lg;
@@ -477,7 +463,7 @@ Film::read_metadata ()
_dcp_video_frame_rate = f.number_child<int> ("DCPVideoFrameRate");
_dci_date = boost::gregorian::from_undelimited_string (f.string_child ("DCIDate"));
- _playlist->set_from_xml (f.node_child ("Playlist"));
+ _playlist->set_from_xml (shared_from_this(), f.node_child ("Playlist"));
_dirty = false;
}
@@ -865,7 +851,7 @@ Film::remove_content (shared_ptr<Content> c)
Time
Film::length () const
{
- return _playlist->length (shared_from_this ());
+ return _playlist->length ();
}
bool
diff --git a/src/lib/film.h b/src/lib/film.h
index 71a3b1c34..b8d4ee40e 100644
--- a/src/lib/film.h
+++ b/src/lib/film.h
@@ -56,7 +56,7 @@ class Player;
class Film : public boost::enable_shared_from_this<Film>
{
public:
- Film (std::string d, bool must_exist = true);
+ Film (std::string d);
Film (Film const &);
std::string info_dir () const;
@@ -86,6 +86,7 @@ public:
std::string file (std::string f) const;
std::string dir (std::string d) const;
+ void read_metadata ();
void write_metadata () const;
std::string dci_name (bool if_created_now) const;
@@ -259,7 +260,6 @@ private:
void signal_changed (Property);
void analyse_audio_finished ();
std::string video_state_identifier () const;
- void read_metadata ();
void playlist_changed ();
void playlist_content_changed (boost::weak_ptr<Content>, int);
std::string filename_safe_name () const;
diff --git a/src/lib/imagemagick_content.cc b/src/lib/imagemagick_content.cc
index f9daf204e..ac04fb15b 100644
--- a/src/lib/imagemagick_content.cc
+++ b/src/lib/imagemagick_content.cc
@@ -29,16 +29,16 @@ using std::string;
using std::stringstream;
using boost::shared_ptr;
-ImageMagickContent::ImageMagickContent (boost::filesystem::path f)
- : Content (f)
- , VideoContent (f)
+ImageMagickContent::ImageMagickContent (shared_ptr<const Film> f, boost::filesystem::path p)
+ : Content (f, p)
+ , VideoContent (f, p)
{
}
-ImageMagickContent::ImageMagickContent (shared_ptr<const cxml::Node> node)
- : Content (node)
- , VideoContent (node)
+ImageMagickContent::ImageMagickContent (shared_ptr<const Film> f, shared_ptr<const cxml::Node> node)
+ : Content (f, node)
+ , VideoContent (f, node)
{
}
@@ -66,9 +66,13 @@ ImageMagickContent::as_xml (xmlpp::Node* node) const
}
void
-ImageMagickContent::examine (shared_ptr<Film> film, shared_ptr<Job> job)
+ImageMagickContent::examine (shared_ptr<Job> job)
{
- Content::examine (film, job);
+ Content::examine (job);
+
+ shared_ptr<const Film> film = _film.lock ();
+ assert (film);
+
shared_ptr<ImageMagickDecoder> decoder (new ImageMagickDecoder (film, shared_from_this()));
{
@@ -100,8 +104,11 @@ ImageMagickContent::set_video_length (ContentVideoFrame len)
}
Time
-ImageMagickContent::length (shared_ptr<const Film> film) const
+ImageMagickContent::length () const
{
+ shared_ptr<const Film> film = _film.lock ();
+ assert (film);
+
FrameRateConversion frc (24, film->dcp_video_frame_rate ());
return video_length() * frc.factor() * TIME_HZ / film->dcp_video_frame_rate ();
}
diff --git a/src/lib/imagemagick_content.h b/src/lib/imagemagick_content.h
index b7f2cd2c3..e3e827892 100644
--- a/src/lib/imagemagick_content.h
+++ b/src/lib/imagemagick_content.h
@@ -27,18 +27,18 @@ namespace cxml {
class ImageMagickContent : public VideoContent
{
public:
- ImageMagickContent (boost::filesystem::path);
- ImageMagickContent (boost::shared_ptr<const cxml::Node>);
+ ImageMagickContent (boost::shared_ptr<const Film>, boost::filesystem::path);
+ ImageMagickContent (boost::shared_ptr<const Film>, boost::shared_ptr<const cxml::Node>);
boost::shared_ptr<ImageMagickContent> shared_from_this () {
return boost::dynamic_pointer_cast<ImageMagickContent> (Content::shared_from_this ());
};
- void examine (boost::shared_ptr<Film>, boost::shared_ptr<Job>);
+ void examine (boost::shared_ptr<Job>);
std::string summary () const;
void as_xml (xmlpp::Node *) const;
boost::shared_ptr<Content> clone () const;
- Time length (boost::shared_ptr<const Film>) const;
+ Time length () const;
void set_video_length (ContentVideoFrame);
diff --git a/src/lib/null_content.cc b/src/lib/null_content.cc
index 0e275a393..0084972c2 100644
--- a/src/lib/null_content.cc
+++ b/src/lib/null_content.cc
@@ -17,12 +17,32 @@
*/
-NullContent::NullContent (Time s, Time len, shared_ptr<const Film> f)
- : Content (s)
- , VideoContent (s, f->time_to_video_frames (len))
- , AudioContent (s)
+#include "null_content.h"
+#include "film.h"
+
+using boost::shared_ptr;
+
+NullContent::NullContent (shared_ptr<const Film> f, Time s, Time len)
+ : Content (f, s)
+ , VideoContent (f, s, f->time_to_video_frames (len))
+ , AudioContent (f, s)
, _audio_length (f->time_to_audio_frames (len))
- , _content_audio_frame_rate (f->dcp_audio_frame_rate ())
+ , _length (len)
+{
+
+}
+
+int
+NullContent::content_audio_frame_rate () const
{
+ return output_audio_frame_rate ();
+}
+
+int
+NullContent::output_audio_frame_rate () const
+{
+ shared_ptr<const Film> film = _film.lock ();
+ assert (film);
+ return film->dcp_audio_frame_rate ();
}
diff --git a/src/lib/null_content.h b/src/lib/null_content.h
index e68008782..d4a3b7371 100644
--- a/src/lib/null_content.h
+++ b/src/lib/null_content.h
@@ -19,12 +19,13 @@
#include <string>
#include <boost/shared_ptr.hpp>
-#include "content.h"
+#include "video_content.h"
+#include "audio_content.h"
class NullContent : public VideoContent, public AudioContent
{
public:
- NullContent (Time, Time, boost::shared_ptr<const Film>);
+ NullContent (boost::shared_ptr<const Film>, Time, Time);
std::string summary () const {
return "";
@@ -48,23 +49,19 @@ public:
return _audio_length;
}
- int content_audio_frame_rate () const {
- return _content_audio_frame_rate;
- }
+ int content_audio_frame_rate () const;
- int output_audio_frame_rate (boost::shared_ptr<const Film> f) const {
- return f->dcp_audio_frame_rate ();
- }
+ int output_audio_frame_rate () const;
AudioMapping audio_mapping () const {
return AudioMapping ();
}
- Time length (boost::shared_ptr<const Film>) const {
+ Time length () const {
return _length;
}
private:
ContentAudioFrame _audio_length;
- ContentAudioFrame _content_audio_frame_rate;
+ Time _length;
};
diff --git a/src/lib/player.cc b/src/lib/player.cc
index b0a408c10..c87e27ba3 100644
--- a/src/lib/player.cc
+++ b/src/lib/player.cc
@@ -62,8 +62,6 @@ Player::Player (shared_ptr<const Film> f, shared_ptr<const Playlist> p)
, _have_valid_pieces (false)
, _position (0)
, _audio_buffers (MAX_AUDIO_CHANNELS, 0)
- , _last_video (0)
- , _last_was_black (false)
, _next_audio (0)
{
_playlist->Changed.connect (bind (&Player::playlist_changed, this));
@@ -104,7 +102,7 @@ Player::pass ()
shared_ptr<Piece> earliest;
for (list<shared_ptr<Piece> >::iterator i = _pieces.begin(); i != _pieces.end(); ++i) {
- if ((*i)->content->end(_film) < _position) {
+ if ((*i)->content->end() < _position) {
continue;
}
@@ -124,7 +122,7 @@ Player::pass ()
/* Move position to earliest active next emission */
for (list<shared_ptr<Piece> >::iterator i = _pieces.begin(); i != _pieces.end(); ++i) {
- if ((*i)->content->end(_film) < _position) {
+ if ((*i)->content->end() < _position) {
continue;
}
@@ -200,6 +198,16 @@ Player::seek (Time t)
return;
}
+ for (list<shared_ptr<Piece> >::iterator i = _pieces.begin(); i != _pieces.end(); ++i) {
+ if ((*i)->content->end() < t) {
+ continue;
+ }
+
+ (*i)->decoder->seek (t);
+ }
+
+ _position = t;
+
/* XXX: don't seek audio because we don't need to... */
}
@@ -290,18 +298,18 @@ Player::setup_pieces ()
if (dynamic_pointer_cast<VideoContent> ((*i)->content)) {
Time const diff = video_pos - (*i)->content->start();
if (diff > 0) {
- shared_ptr<NullContent> nc (new NullContent (video_pos, diff));
+ shared_ptr<NullContent> nc (new NullContent (_film, video_pos, diff));
_pieces.push_back (shared_ptr<Piece> (new Piece (nc, shared_ptr<Decoder> (new BlackDecoder (_film, nc)))));
}
- video_pos = (*i)->content->start() + (*i)->content->length(_film);
+ video_pos = (*i)->content->end();
} else {
Time const diff = audio_pos - (*i)->content->start();
if (diff > 0) {
- shared_ptr<NullContent> nc (new NullContent (audio_pos, diff));
+ shared_ptr<NullContent> nc (new NullContent (_film, audio_pos, diff));
_pieces.push_back (shared_ptr<Piece> (new Piece (nc, shared_ptr<Decoder> (new SilenceDecoder (_film, nc)))));
}
- audio_pos = (*i)->content->start() + (*i)->content->length(_film);
+ audio_pos = (*i)->content->end();
}
}
diff --git a/src/lib/player.h b/src/lib/player.h
index c8f6eecb8..a5fe844f0 100644
--- a/src/lib/player.h
+++ b/src/lib/player.h
@@ -56,8 +56,8 @@ public:
void seek_back ();
void seek_forward ();
- Time last_video () const {
- return _last_video;
+ Time position () const {
+ return _position;
}
private:
@@ -81,13 +81,7 @@ private:
/** Time of the earliest thing not yet to have been emitted */
Time _position;
- Time _last_black;
- Time _last_silence;
-
- /* XXX: position and last_video? Need both? */
AudioBuffers _audio_buffers;
- Time _last_video;
- bool _last_was_black;
Time _next_audio;
};
diff --git a/src/lib/playlist.cc b/src/lib/playlist.cc
index 36d6c6b52..7ab320558 100644
--- a/src/lib/playlist.cc
+++ b/src/lib/playlist.cc
@@ -122,7 +122,7 @@ Playlist::video_digest () const
/** @param node <Playlist> node */
void
-Playlist::set_from_xml (shared_ptr<const cxml::Node> node)
+Playlist::set_from_xml (shared_ptr<const Film> film, shared_ptr<const cxml::Node> node)
{
list<shared_ptr<cxml::Node> > c = node->node_children ("Content");
for (list<shared_ptr<cxml::Node> >::iterator i = c.begin(); i != c.end(); ++i) {
@@ -131,11 +131,11 @@ Playlist::set_from_xml (shared_ptr<const cxml::Node> node)
boost::shared_ptr<Content> content;
if (type == "FFmpeg") {
- content.reset (new FFmpegContent (*i));
+ content.reset (new FFmpegContent (film, *i));
} else if (type == "ImageMagick") {
- content.reset (new ImageMagickContent (*i));
+ content.reset (new ImageMagickContent (film, *i));
} else if (type == "Sndfile") {
- content.reset (new SndfileContent (*i));
+ content.reset (new SndfileContent (film, *i));
}
_content.push_back (content);
@@ -261,11 +261,11 @@ Playlist::best_dcp_frame_rate () const
}
Time
-Playlist::length (shared_ptr<const Film> film) const
+Playlist::length () const
{
Time len = 0;
for (ContentList::const_iterator i = _content.begin(); i != _content.end(); ++i) {
- len = max (len, (*i)->end (film));
+ len = max (len, (*i)->end ());
}
return len;
diff --git a/src/lib/playlist.h b/src/lib/playlist.h
index e8cac0247..aff6017fa 100644
--- a/src/lib/playlist.h
+++ b/src/lib/playlist.h
@@ -61,7 +61,7 @@ public:
~Playlist ();
void as_xml (xmlpp::Node *);
- void set_from_xml (boost::shared_ptr<const cxml::Node>);
+ void set_from_xml (boost::shared_ptr<const Film>, boost::shared_ptr<const cxml::Node>);
void add (boost::shared_ptr<Content>);
void remove (boost::shared_ptr<Content>);
@@ -83,7 +83,7 @@ public:
void set_loop (int l);
- Time length (boost::shared_ptr<const Film>) const;
+ Time length () const;
int best_dcp_frame_rate () const;
mutable boost::signals2::signal<void ()> Changed;
diff --git a/src/lib/silence_decoder.cc b/src/lib/silence_decoder.cc
new file mode 100644
index 000000000..9eee5bb10
--- /dev/null
+++ b/src/lib/silence_decoder.cc
@@ -0,0 +1,56 @@
+/*
+ Copyright (C) 2013 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
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+*/
+
+#include "silence_decoder.h"
+#include "null_content.h"
+#include "audio_buffers.h"
+
+using std::min;
+using boost::shared_ptr;
+
+SilenceDecoder::SilenceDecoder (shared_ptr<const Film> f, shared_ptr<NullContent> c)
+ : Decoder (f)
+ , AudioDecoder (f, c)
+{
+
+}
+
+void
+SilenceDecoder::pass ()
+{
+ shared_ptr<const Film> film = _film.lock ();
+ assert (film);
+
+ Time const this_time = min (_audio_content->length() - _next_audio, TIME_HZ / 2);
+ shared_ptr<AudioBuffers> data (new AudioBuffers (MAX_AUDIO_CHANNELS, film->time_to_audio_frames (this_time)));
+ data->make_silent ();
+ audio (data, _next_audio);
+}
+
+void
+SilenceDecoder::seek (Time t)
+{
+ _next_audio = t;
+}
+
+Time
+SilenceDecoder::next () const
+{
+ return _next_audio;
+}
diff --git a/src/lib/silence_decoder.h b/src/lib/silence_decoder.h
index eec3c8ed9..e2a004d61 100644
--- a/src/lib/silence_decoder.h
+++ b/src/lib/silence_decoder.h
@@ -17,6 +17,12 @@
*/
+#include <boost/shared_ptr.hpp>
+#include "audio_decoder.h"
+
+class Film;
+class NullContent;
+
class SilenceDecoder : public AudioDecoder
{
public:
diff --git a/src/lib/sndfile_content.cc b/src/lib/sndfile_content.cc
index 758ae942d..0f895c95e 100644
--- a/src/lib/sndfile_content.cc
+++ b/src/lib/sndfile_content.cc
@@ -33,9 +33,9 @@ using std::cout;
using boost::shared_ptr;
using boost::lexical_cast;
-SndfileContent::SndfileContent (boost::filesystem::path f)
- : Content (f)
- , AudioContent (f)
+SndfileContent::SndfileContent (shared_ptr<const Film> f, boost::filesystem::path p)
+ : Content (f, p)
+ , AudioContent (f, p)
, _audio_channels (0)
, _audio_length (0)
, _audio_frame_rate (0)
@@ -43,9 +43,9 @@ SndfileContent::SndfileContent (boost::filesystem::path f)
}
-SndfileContent::SndfileContent (shared_ptr<const cxml::Node> node)
- : Content (node)
- , AudioContent (node)
+SndfileContent::SndfileContent (shared_ptr<const Film> f, shared_ptr<const cxml::Node> node)
+ : Content (f, node)
+ , AudioContent (f, node)
{
_audio_channels = node->number_child<int> ("AudioChannels");
_audio_length = node->number_child<ContentAudioFrame> ("AudioLength");
@@ -93,10 +93,13 @@ SndfileContent::clone () const
}
void
-SndfileContent::examine (shared_ptr<Film> film, shared_ptr<Job> job)
+SndfileContent::examine (shared_ptr<Job> job)
{
job->set_progress_unknown ();
- Content::examine (film, job);
+ Content::examine (job);
+
+ shared_ptr<const Film> film = _film.lock ();
+ assert (film);
SndfileDecoder dec (film, shared_from_this());
@@ -122,15 +125,20 @@ SndfileContent::as_xml (xmlpp::Node* node) const
node->add_child("AudioFrameRate")->add_child_text (lexical_cast<string> (_audio_frame_rate));
}
-int
-SndfileContent::output_audio_frame_rate (shared_ptr<const Film>) const
+Time
+SndfileContent::length () const
{
- /* Resample to a DCI-approved sample rate */
- return dcp_audio_frame_rate (content_audio_frame_rate ());
+ shared_ptr<const Film> film = _film.lock ();
+ assert (film);
+
+ return film->audio_frames_to_time (audio_length ());
}
-Time
-SndfileContent::length (shared_ptr<const Film> film) const
+int
+SndfileContent::output_audio_frame_rate () const
{
- return film->audio_frames_to_time (audio_length ());
+ shared_ptr<const Film> film = _film.lock ();
+ assert (film);
+
+ return film->dcp_audio_frame_rate ();
}
diff --git a/src/lib/sndfile_content.h b/src/lib/sndfile_content.h
index bb7fa5f50..17423b8ed 100644
--- a/src/lib/sndfile_content.h
+++ b/src/lib/sndfile_content.h
@@ -31,19 +31,19 @@ namespace cxml {
class SndfileContent : public AudioContent
{
public:
- SndfileContent (boost::filesystem::path);
- SndfileContent (boost::shared_ptr<const cxml::Node>);
+ SndfileContent (boost::shared_ptr<const Film>, boost::filesystem::path);
+ SndfileContent (boost::shared_ptr<const Film>, boost::shared_ptr<const cxml::Node>);
boost::shared_ptr<SndfileContent> shared_from_this () {
return boost::dynamic_pointer_cast<SndfileContent> (Content::shared_from_this ());
}
- void examine (boost::shared_ptr<Film>, boost::shared_ptr<Job>);
+ void examine (boost::shared_ptr<Job>);
std::string summary () const;
std::string information () const;
void as_xml (xmlpp::Node *) const;
boost::shared_ptr<Content> clone () const;
- Time length (boost::shared_ptr<const Film>) const;
+ Time length () const;
/* AudioContent */
int audio_channels () const {
@@ -61,7 +61,7 @@ public:
return _audio_frame_rate;
}
- int output_audio_frame_rate (boost::shared_ptr<const Film>) const;
+ int output_audio_frame_rate () const;
AudioMapping audio_mapping () const {
boost::mutex::scoped_lock lm (_mutex);
diff --git a/src/lib/types.h b/src/lib/types.h
index 4b8b8072d..8f2fe2c71 100644
--- a/src/lib/types.h
+++ b/src/lib/types.h
@@ -31,7 +31,7 @@ typedef int64_t ContentAudioFrame;
typedef int ContentVideoFrame;
typedef int64_t Time;
#define TIME_MAX INT64_MAX
-#define TIME_HZ 96000
+#define TIME_HZ ((Time) 96000)
typedef int64_t OutputAudioFrame;
typedef int OutputVideoFrame;
diff --git a/src/lib/video_content.cc b/src/lib/video_content.cc
index e07773048..2e413678f 100644
--- a/src/lib/video_content.cc
+++ b/src/lib/video_content.cc
@@ -34,22 +34,22 @@ using std::setprecision;
using boost::shared_ptr;
using boost::lexical_cast;
-VideoContent::VideoContent (Time s, ContentVideoFrame len)
- : Content (s)
+VideoContent::VideoContent (shared_ptr<const Film> f, Time s, ContentVideoFrame len)
+ : Content (f, s)
, _video_length (len)
{
}
-VideoContent::VideoContent (boost::filesystem::path f)
- : Content (f)
+VideoContent::VideoContent (shared_ptr<const Film> f, boost::filesystem::path p)
+ : Content (f, p)
, _video_length (0)
{
}
-VideoContent::VideoContent (shared_ptr<const cxml::Node> node)
- : Content (node)
+VideoContent::VideoContent (shared_ptr<const Film> f, shared_ptr<const cxml::Node> node)
+ : Content (f, node)
{
_video_length = node->number_child<ContentVideoFrame> ("VideoLength");
_video_size.width = node->number_child<int> ("VideoWidth");
diff --git a/src/lib/video_content.h b/src/lib/video_content.h
index 8b0461e3f..7dde927af 100644
--- a/src/lib/video_content.h
+++ b/src/lib/video_content.h
@@ -37,9 +37,9 @@ public:
class VideoContent : public virtual Content
{
public:
- VideoContent (Time);
- VideoContent (boost::filesystem::path);
- VideoContent (boost::shared_ptr<const cxml::Node>);
+ VideoContent (boost::shared_ptr<const Film>, Time, ContentVideoFrame);
+ VideoContent (boost::shared_ptr<const Film>, boost::filesystem::path);
+ VideoContent (boost::shared_ptr<const Film>, boost::shared_ptr<const cxml::Node>);
VideoContent (VideoContent const &);
void as_xml (xmlpp::Node *) const;
diff --git a/src/lib/video_decoder.h b/src/lib/video_decoder.h
index 0f1432907..b31766b50 100644
--- a/src/lib/video_decoder.h
+++ b/src/lib/video_decoder.h
@@ -46,9 +46,9 @@ protected:
void subtitle (boost::shared_ptr<TimedSubtitle>);
Time _next_video;
+ boost::shared_ptr<const VideoContent> _video_content;
private:
- boost::shared_ptr<const VideoContent> _video_content;
boost::shared_ptr<TimedSubtitle> _timed_subtitle;
FrameRateConversion _frame_rate_conversion;
bool _odd;
diff --git a/src/lib/wscript b/src/lib/wscript
index 1da245484..e7349a9c4 100644
--- a/src/lib/wscript
+++ b/src/lib/wscript
@@ -11,6 +11,7 @@ sources = """
audio_decoder.cc
audio_mapping.cc
audio_source.cc
+ black_decoder.cc
config.cc
combiner.cc
container.cc
@@ -38,11 +39,13 @@ sources = """
job_manager.cc
log.cc
lut.cc
+ null_content.cc
player.cc
playlist.cc
scp_dcp_job.cc
scaler.cc
server.cc
+ silence_decoder.cc
sndfile_content.cc
sndfile_decoder.cc
sound_processor.cc