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");
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;
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);
: 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
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(),
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));
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
*/
#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)
{
}
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 {
{
return _next_video;
}
+
+void
+BlackDecoder::seek (Time t)
+{
+ _next_video = t;
+}
#include "video_decoder.h"
+class NullContent;
+
class BlackDecoder : public VideoDecoder
{
public:
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");
Content::Content (Content const & o)
: boost::enable_shared_from_this<Content> (o)
+ , _film (o._film)
, _file (o._file)
, _digest (o._digest)
, _start (o._start)
}
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);
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);
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:
void
ExamineContentJob::run ()
{
- _content->examine (_film, shared_from_this ());
+ _content->examine (shared_from_this ());
set_progress (1);
set_state (FINISHED_OK);
}
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) {
}
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));
}
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 ());
}
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 ();
}
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 {
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);
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 ())
}
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")));
}
void
Film::write_metadata () const
{
+ if (!boost::filesystem::exists (directory())) {
+ boost::filesystem::create_directory (directory());
+ }
+
boost::mutex::scoped_lock lm (_state_mutex);
LocaleGuard lg;
_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;
}
Time
Film::length () const
{
- return _playlist->length (shared_from_this ());
+ return _playlist->length ();
}
bool
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;
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;
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;
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)
{
}
}
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()));
{
}
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 ();
}
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);
*/
-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 ();
}
#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 "";
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;
};
, _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));
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;
}
/* 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;
}
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... */
}
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();
}
}
void seek_back ();
void seek_forward ();
- Time last_video () const {
- return _last_video;
+ Time position () const {
+ return _position;
}
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;
};
/** @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) {
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);
}
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;
~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>);
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;
--- /dev/null
+/*
+ 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;
+}
*/
+#include <boost/shared_ptr.hpp>
+#include "audio_decoder.h"
+
+class Film;
+class NullContent;
+
class SilenceDecoder : public AudioDecoder
{
public:
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)
}
-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");
}
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());
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 ();
}
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 {
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);
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;
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");
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;
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;
audio_decoder.cc
audio_mapping.cc
audio_source.cc
+ black_decoder.cc
config.cc
combiner.cc
container.cc
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
}
maybe_save_then_delete_film ();
- film.reset (new Film (d->get_path (), false));
+ film.reset (new Film (d->get_path ()));
+ film->write_metadata ();
film->log()->set_level (log_level);
film->set_name (boost::filesystem::path (d->get_path()).filename().generic_string());
set_film ();
if (!film_to_load.empty() && boost::filesystem::is_directory (film_to_load)) {
try {
film.reset (new Film (film_to_load));
+ film->read_metadata ();
film->log()->set_level (log_level);
} catch (exception& e) {
error_dialog (0, std_to_wx (String::compose (wx_to_std (_("Could not load film %1 (%2)")), film_to_load, e.what())));
}
if (!film_to_create.empty ()) {
- film.reset (new Film (film_to_create, false));
+ film.reset (new Film (film_to_create));
+ film->write_metadata ();
film->log()->set_level (log_level);
film->set_name (boost::filesystem::path (film_to_create).filename().generic_string ());
}
if (r == wxID_OK) {
try {
shared_ptr<Film> film (new Film (wx_to_std (c->GetPath ())));
+ film->read_metadata ();
film->make_dcp ();
} catch (std::exception& e) {
wxString p = c->GetPath ();
shared_ptr<Film> film;
try {
- film.reset (new Film (film_dir, true));
+ film.reset (new Film (film_dir));
+ film->read_metadata ();
} catch (std::exception& e) {
cerr << argv[0] << ": error reading film `" << film_dir << "' (" << e.what() << ")\n";
exit (EXIT_FAILURE);
dcpomatic_setup ();
server = new ServerDescription (server_host, 1);
- shared_ptr<Film> film (new Film (film_dir, true));
+ shared_ptr<Film> film (new Film (film_dir));
+ film->read_metadata ();
shared_ptr<Player> player = film->player ();
player->disable_audio ();
boost::filesystem::path p (wx_to_std (paths[i]));
if (ImageMagickContent::valid_file (p)) {
- _film->add_content (shared_ptr<ImageMagickContent> (new ImageMagickContent (p)));
+ _film->add_content (shared_ptr<ImageMagickContent> (new ImageMagickContent (_film, p)));
} else if (SndfileContent::valid_file (p)) {
- _film->add_content (shared_ptr<SndfileContent> (new SndfileContent (p)));
+ _film->add_content (shared_ptr<SndfileContent> (new SndfileContent (_film, p)));
} else {
- _film->add_content (shared_ptr<FFmpegContent> (new FFmpegContent (p)));
+ _film->add_content (shared_ptr<FFmpegContent> (new FFmpegContent (_film, p)));
}
}
}
return;
}
- _player->seek (_player->last_video ());
+ _player->seek (_player->position ());
get_frame ();
_panel->Refresh ();
_panel->Update ();
get_frame ();
if (_film->length()) {
- int const new_slider_position = 4096 * _player->last_video() / _film->length();
+ int const new_slider_position = 4096 * _player->position() / _film->length();
if (new_slider_position != _slider->GetValue()) {
_slider->SetValue (new_slider_position);
}
}
Time const start = content->start ();
- Time const len = content->length (film);
+ Time const len = content->length ();
gc->SetPen (*wxBLACK_PEN);
return Rect (
time_x (content->start ()),
y_pos (_track),
- content->length (film) * _timeline.pixels_per_time_unit(),
+ content->length () * _timeline.pixels_per_time_unit(),
_timeline.track_height()
);
}
boost::filesystem::remove_all (p);
}
- return shared_ptr<Film> (new Film (p.string(), false));
+ shared_ptr<Film> f = shared_ptr<Film> (new Film (p.string()));
+ f->write_metadata ();
}
boost::filesystem::remove_all (test_film);
}
- BOOST_CHECK_THROW (new Film (test_film, true), OpenFileError);
-
- shared_ptr<Film> f (new Film (test_film, false));
+ shared_ptr<Film> f (new Film (test_film));
+ f->write_metadata ();
f->_dci_date = boost::gregorian::from_undelimited_string ("20130211");
BOOST_CHECK (f->container() == 0);
BOOST_CHECK (f->dcp_content_type() == 0);
s << "diff -u test/metadata.ref " << test_film << "/metadata";
BOOST_CHECK_EQUAL (::system (s.str().c_str ()), 0);
- shared_ptr<Film> g (new Film (test_film, true));
+ shared_ptr<Film> g (new Film (test_film));
+ g->read_metadata ();
BOOST_CHECK_EQUAL (g->name(), "fred");
BOOST_CHECK_EQUAL (g->dcp_content_type(), DCPContentType::from_pretty_name ("Short"));