diff options
| author | Carl Hetherington <cth@carlh.net> | 2013-01-09 18:48:19 +0000 |
|---|---|---|
| committer | Carl Hetherington <cth@carlh.net> | 2013-01-09 18:48:19 +0000 |
| commit | 29d863fb2533fe754a82a5274caf19a3b19e2994 (patch) | |
| tree | 01b50cb12db11676b95cbeb1a0cae8ba45508688 /src/lib | |
| parent | dfa88d5ad8760d10c15864d01aae9eb8222060ea (diff) | |
| parent | c4cce451a4234e3e41865d7dc5073ed3ad061e3c (diff) | |
Merge master.
Diffstat (limited to 'src/lib')
| -rw-r--r-- | src/lib/encoder.cc | 39 | ||||
| -rw-r--r-- | src/lib/encoder.h | 8 | ||||
| -rw-r--r-- | src/lib/ffmpeg_compatibility.cc | 8 | ||||
| -rw-r--r-- | src/lib/ffmpeg_compatibility.h | 7 | ||||
| -rw-r--r-- | src/lib/film.cc | 2 | ||||
| -rw-r--r-- | src/lib/film.h | 2 | ||||
| -rw-r--r-- | src/lib/filter_graph.h | 1 | ||||
| -rw-r--r-- | src/lib/format.cc | 1 | ||||
| -rw-r--r-- | src/lib/image.cc | 20 | ||||
| -rw-r--r-- | src/lib/image.h | 2 | ||||
| -rw-r--r-- | src/lib/make_dcp_job.cc | 2 | ||||
| -rw-r--r-- | src/lib/matcher.h | 1 | ||||
| -rw-r--r-- | src/lib/util.cc | 14 | ||||
| -rw-r--r-- | src/lib/util.h | 1 |
14 files changed, 77 insertions, 31 deletions
diff --git a/src/lib/encoder.cc b/src/lib/encoder.cc index 07ce8f3bc..693bd5bc8 100644 --- a/src/lib/encoder.cc +++ b/src/lib/encoder.cc @@ -42,6 +42,7 @@ using std::stringstream; using std::vector; using std::list; using std::cout; +using std::make_pair; using namespace boost; int const Encoder::_history_size = 25; @@ -65,7 +66,7 @@ Encoder::Encoder (shared_ptr<const Film> f, shared_ptr<const EncodeOptions> o) /* Create sound output files with .tmp suffixes; we will rename them if and when we complete. */ - for (int i = 0; i < _film->audio_channels(); ++i) { + for (int i = 0; i < dcp_audio_channels (_film->audio_channels()); ++i) { SF_INFO sf_info; sf_info.samplerate = dcp_audio_sample_rate (_film->audio_stream()->sample_rate()); /* We write mono files */ @@ -136,7 +137,7 @@ void Encoder::process_end () { #if HAVE_SWRESAMPLE - if (_film->audio_stream() && _swr_context) { + if (_film->audio_stream() && _film->audio_stream()->channels() && _swr_context) { shared_ptr<AudioBuffers> out (new AudioBuffers (_film->audio_stream()->channels(), 256)); @@ -163,7 +164,7 @@ Encoder::process_end () close_sound_files (); /* Rename .wav.tmp files to .wav */ - for (int i = 0; i < _film->audio_channels(); ++i) { + for (int i = 0; i < dcp_audio_channels (_film->audio_channels()); ++i) { if (boost::filesystem::exists (_opt->multichannel_audio_out_path (i, false))) { boost::filesystem::remove (_opt->multichannel_audio_out_path (i, false)); } @@ -207,6 +208,12 @@ Encoder::process_end () _film->log()->log (String::compose ("Local encode failed (%1)", e.what ())); } } + + /* Now do links (or copies on windows) to duplicate frames */ + for (list<pair<int, int> >::iterator i = _links_required.begin(); i != _links_required.end(); ++i) { + link (_opt->frame_out_path (i->first, false), _opt->frame_out_path (i->second, false)); + link (_opt->hash_out_path (i->first, false), _opt->hash_out_path (i->second, false)); + } } /** @return an estimate of the current number of frames we are encoding per second, @@ -305,9 +312,11 @@ Encoder::process_video (shared_ptr<Image> image, bool same, boost::shared_ptr<Su } if (same && _last_real_frame) { - /* Use the last frame that we encoded */ - link (_opt->frame_out_path (_last_real_frame.get(), false), _opt->frame_out_path (_video_frame, false)); - link (_opt->hash_out_path (_last_real_frame.get(), false), _opt->hash_out_path (_video_frame, false)); + /* Use the last frame that we encoded. We need to postpone doing the actual link, + as on windows the link is really a copy and the reference frame might not have + finished encoding yet. + */ + _links_required.push_back (make_pair (_last_real_frame.get(), _video_frame)); } else { /* Queue this new frame for encoding */ pair<string, string> const s = Filter::ffmpeg_strings (_film->filters()); @@ -380,6 +389,22 @@ Encoder::process_audio (shared_ptr<AudioBuffers> data) } #endif + if (_film->audio_channels() == 1) { + /* We need to switch things around so that the mono channel is on + the centre channel of a 5.1 set (with other channels silent). + */ + + shared_ptr<AudioBuffers> b (new AudioBuffers (6, data->frames ())); + b->make_silent (libdcp::LEFT); + b->make_silent (libdcp::RIGHT); + memcpy (b->data()[libdcp::CENTRE], data->data()[0], data->frames() * sizeof(float)); + b->make_silent (libdcp::LFE); + b->make_silent (libdcp::LS); + b->make_silent (libdcp::RS); + + data = b; + } + write_audio (data); _audio_frame += data->frames (); @@ -388,7 +413,7 @@ Encoder::process_audio (shared_ptr<AudioBuffers> data) void Encoder::write_audio (shared_ptr<const AudioBuffers> audio) { - for (int i = 0; i < _film->audio_channels(); ++i) { + for (int i = 0; i < audio->channels(); ++i) { sf_write_float (_sound_files[i], audio->data(i), audio->frames()); } diff --git a/src/lib/encoder.h b/src/lib/encoder.h index e5916ad3a..52ccfc166 100644 --- a/src/lib/encoder.h +++ b/src/lib/encoder.h @@ -121,7 +121,13 @@ private: #if HAVE_SWRESAMPLE SwrContext* _swr_context; -#endif +#endif + + /** List of links that we need to create when all frames have been processed; + * such that we need to call link (first, second) for each member of this list. + * In other words, `first' is a `real' frame and `second' should be a link to `first'. + */ + std::list<std::pair<int, int> > _links_required; std::vector<SNDFILE*> _sound_files; int64_t _audio_frames_written; diff --git a/src/lib/ffmpeg_compatibility.cc b/src/lib/ffmpeg_compatibility.cc index c47cdf5ce..09f9276ac 100644 --- a/src/lib/ffmpeg_compatibility.cc +++ b/src/lib/ffmpeg_compatibility.cc @@ -107,3 +107,11 @@ avfilter_inout_alloc () return (AVFilterInOut *) av_malloc (sizeof (AVFilterInOut)); } #endif + +#ifndef HAVE_AV_FRAME_GET_BEST_EFFORT_TIMESTAMP +int64_t av_frame_get_best_effort_timestamp (AVFrame const * f) +{ + return f->best_effort_timestamp; +} + +#endif diff --git a/src/lib/ffmpeg_compatibility.h b/src/lib/ffmpeg_compatibility.h index 80cc79ffb..772d22c33 100644 --- a/src/lib/ffmpeg_compatibility.h +++ b/src/lib/ffmpeg_compatibility.h @@ -22,3 +22,10 @@ struct AVFilterInOut; extern AVFilter* get_sink (); extern AVFilterInOut* avfilter_inout_alloc (); +#ifndef HAVE_AV_PIXEL_FORMAT +#define AVPixelFormat PixelFormat +#endif + +#ifndef HAVE_AV_FRAME_GET_BEST_EFFORT_TIMESTAMP +extern int64_t av_frame_get_best_effort_timestamp (AVFrame const *); +#endif diff --git a/src/lib/film.cc b/src/lib/film.cc index cae4f5f93..6e49dd4ea 100644 --- a/src/lib/film.cc +++ b/src/lib/film.cc @@ -247,6 +247,8 @@ Film::make_dcp (bool transcode) char buffer[128]; gethostname (buffer, sizeof (buffer)); log()->log (String::compose ("Starting to make DCP on %1", buffer)); + log()->log (String::compose ("Content is %1; type %2", content_path(), (content_type() == STILL ? "still" : "video"))); + log()->log (String::compose ("Content length %1", length())); } if (format() == 0) { diff --git a/src/lib/film.h b/src/lib/film.h index eda2060b8..b2f57eac8 100644 --- a/src/lib/film.h +++ b/src/lib/film.h @@ -466,7 +466,7 @@ private: /** Size, in pixels, of the source (ignoring cropping) */ Size _size; - /** Actual length of the source (in video frames) from examining it */ + /** The length of the source, in video frames (as far as we know) */ boost::optional<SourceFrame> _length; /** MD5 digest of our content file */ std::string _content_digest; diff --git a/src/lib/filter_graph.h b/src/lib/filter_graph.h index a4b9ef75f..9e6ac6252 100644 --- a/src/lib/filter_graph.h +++ b/src/lib/filter_graph.h @@ -25,6 +25,7 @@ #define DVDOMATIC_FILTER_GRAPH_H #include "util.h" +#include "ffmpeg_compatibility.h" class Image; class VideoFilter; diff --git a/src/lib/format.cc b/src/lib/format.cc index eb42593fe..975862411 100644 --- a/src/lib/format.cc +++ b/src/lib/format.cc @@ -75,6 +75,7 @@ Format::setup_formats () _formats.push_back (new FixedFormat (166, Size (1793, 1080), "166", "1.66", "F")); _formats.push_back (new FixedFormat (166, Size (1998, 1080), "166-in-flat", "1.66 within Flat", "F")); _formats.push_back (new FixedFormat (178, Size (1998, 1080), "178-in-flat", "16:9 within Flat", "F")); + _formats.push_back (new FixedFormat (178, Size (1920, 1080), "178", "16:9", "F")); _formats.push_back (new FixedFormat (185, Size (1998, 1080), "185", "Flat", "F")); _formats.push_back (new FixedFormat (239, Size (2048, 858), "239", "Scope", "S")); _formats.push_back (new VariableFormat (Size (1998, 1080), "var-185", "Flat", "F")); diff --git a/src/lib/image.cc b/src/lib/image.cc index e136a8469..f774f476f 100644 --- a/src/lib/image.cc +++ b/src/lib/image.cc @@ -448,26 +448,6 @@ SimpleImage::~SimpleImage () av_free (_stride); } -SimpleImage::SimpleImage (shared_ptr<const Image> im, bool aligned) - : Image (im->pixel_format()) -{ - assert (components() == im->components()); - - for (int c = 0; c < components(); ++c) { - - assert (line_size()[c] == im->line_size()[c]); - - uint8_t* t = data()[c]; - uint8_t* o = im->data()[c]; - - for (int y = 0; y < lines(c); ++y) { - memcpy (t, o, line_size()[c]); - t += stride()[c]; - o += im->stride()[c]; - } - } -} - uint8_t ** SimpleImage::data () const { diff --git a/src/lib/image.h b/src/lib/image.h index 13b92d72f..e19c6f54b 100644 --- a/src/lib/image.h +++ b/src/lib/image.h @@ -32,6 +32,7 @@ extern "C" { #include <libavfilter/avfilter.h> } #include "util.h" +#include "ffmpeg_compatibility.h" class Scaler; class RGBFrameImage; @@ -124,7 +125,6 @@ public: SimpleImage (AVPixelFormat, Size, bool); SimpleImage (SimpleImage const &); SimpleImage& operator= (SimpleImage const &); - SimpleImage (boost::shared_ptr<const Image>, bool aligned); ~SimpleImage (); uint8_t ** data () const; diff --git a/src/lib/make_dcp_job.cc b/src/lib/make_dcp_job.cc index a8b80fd67..e42018ad5 100644 --- a/src/lib/make_dcp_job.cc +++ b/src/lib/make_dcp_job.cc @@ -132,7 +132,7 @@ MakeDCPJob::run () &dcp.Progress, dfr.frames_per_second, frames, - _film->audio_channels(), + dcp_audio_channels (_film->audio_channels()), _film->encrypted() ) ); diff --git a/src/lib/matcher.h b/src/lib/matcher.h index 9bd30fe62..b94c28446 100644 --- a/src/lib/matcher.h +++ b/src/lib/matcher.h @@ -19,6 +19,7 @@ #include <boost/optional.hpp> #include "processor.h" +#include "ffmpeg_compatibility.h" class Matcher : public AudioVideoProcessor { diff --git a/src/lib/util.cc b/src/lib/util.cc index 9d42a52e5..987c2b9e5 100644 --- a/src/lib/util.cc +++ b/src/lib/util.cc @@ -367,6 +367,20 @@ dcp_audio_sample_rate (int fs) return 96000; } +int +dcp_audio_channels (int f) +{ + if (f == 1) { + /* The source is mono, so to put the mono channel into + the centre we need to generate a 5.1 soundtrack. + */ + return 6; + } + + return f; +} + + bool operator== (Size const & a, Size const & b) { return (a.width == b.width && a.height == b.height); diff --git a/src/lib/util.h b/src/lib/util.h index 3832cc579..0744d9c09 100644 --- a/src/lib/util.h +++ b/src/lib/util.h @@ -184,6 +184,7 @@ struct Rect extern std::string crop_string (Position, Size); extern int dcp_audio_sample_rate (int); extern DCPFrameRate dcp_frame_rate (float); +extern int dcp_audio_channels (int); extern std::string colour_lut_index_to_name (int index); extern int stride_round_up (int, int const *, int); extern int stride_lookup (int c, int const * stride); |
