summaryrefslogtreecommitdiff
path: root/src/lib
diff options
context:
space:
mode:
authorCarl Hetherington <cth@carlh.net>2013-01-09 18:48:19 +0000
committerCarl Hetherington <cth@carlh.net>2013-01-09 18:48:19 +0000
commit29d863fb2533fe754a82a5274caf19a3b19e2994 (patch)
tree01b50cb12db11676b95cbeb1a0cae8ba45508688 /src/lib
parentdfa88d5ad8760d10c15864d01aae9eb8222060ea (diff)
parentc4cce451a4234e3e41865d7dc5073ed3ad061e3c (diff)
Merge master.
Diffstat (limited to 'src/lib')
-rw-r--r--src/lib/encoder.cc39
-rw-r--r--src/lib/encoder.h8
-rw-r--r--src/lib/ffmpeg_compatibility.cc8
-rw-r--r--src/lib/ffmpeg_compatibility.h7
-rw-r--r--src/lib/film.cc2
-rw-r--r--src/lib/film.h2
-rw-r--r--src/lib/filter_graph.h1
-rw-r--r--src/lib/format.cc1
-rw-r--r--src/lib/image.cc20
-rw-r--r--src/lib/image.h2
-rw-r--r--src/lib/make_dcp_job.cc2
-rw-r--r--src/lib/matcher.h1
-rw-r--r--src/lib/util.cc14
-rw-r--r--src/lib/util.h1
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);