+2014-03-07 Carl Hetherington <cth@carlh.net>
+
+ * Add subtitle view.
+
+ 2014-03-17 Carl Hetherington <cth@carlh.net>
+
+ * Improve appearance of config dialog on OS X.
+
+ 2014-03-15 Carl Hetherington <cth@carlh.net>
+
+ * Improve appearance of new film and KDM dialogs on OS X.
+
+ * Fix KDM dialog to predictably set up its initial range to
+ a week from now.
+
+ * Remove support for FFmpeg post-processing filters as they apparently
+ do not support > 8bpp. I don't think they are worth the pain of
+ quantizing and then telling the user what has happened.
+
+ 2014-03-12 Carl Hetherington <cth@carlh.net>
+
+ * Version 1.66.1 released.
+
+ 2014-03-12 Carl Hetherington <cth@carlh.net>
+
+ * Hopefully fix i18n on OS X (#324).
+
+ 2014-03-10 Carl Hetherington <cth@carlh.net>
+
+ * Version 1.66.0 released.
+
+ 2014-03-09 Carl Hetherington <cth@carlh.net>
+
+ * Version 1.65.2 released.
+
+ 2014-03-09 Carl Hetherington <cth@carlh.net>
+
+ * Restore old behaviour of "no-stretch" mode with crop.
+
+ * Fix display of no-scale display mode in the player.
+
2014-03-08 Carl Hetherington <cth@carlh.net>
+ * Version 1.65.1 released.
+
+ 2014-03-08 Carl Hetherington <cth@carlh.net>
+
+ * Fix incorrect audio analyses on multiple-stream content.
+
* Support for unsigned 8-bit audio (hmm!).
2014-03-06 Carl Hetherington <cth@carlh.net>
void set_default_dcp_content_type (DCPContentType const * t) {
_default_dcp_content_type = t;
+ write ();
}
- void set_dcp_metadata (libdcp::XMLMetadata m) {
+ void set_dcp_metadata (dcp::XMLMetadata m) {
_dcp_metadata = m;
+ write ();
}
void set_default_j2k_bandwidth (int b) {
for (list<pair<shared_ptr<Image>, int64_t> >::iterator i = images.begin(); i != images.end(); ++i) {
shared_ptr<Image> image = i->first;
- if (!post_process.empty ()) {
- image = image->post_process (post_process, true);
- }
if (i->second != AV_NOPTS_VALUE) {
-
- double const pts = i->second * av_q2d (_format_context->streams[_video_stream]->time_base) + _pts_offset;
-
- if (_just_sought) {
- /* We just did a seek, so disable any attempts to correct for where we
- are / should be.
- */
- _video_position = rint (pts * _ffmpeg_content->video_frame_rate ());
- _just_sought = false;
- }
-
- double const next = _video_position / _ffmpeg_content->video_frame_rate();
- double const one_frame = 1 / _ffmpeg_content->video_frame_rate ();
- double delta = pts - next;
-
- while (delta > one_frame) {
- /* This PTS is more than one frame forward in time of where we think we should be; emit
- a black frame.
- */
-
- /* XXX: I think this should be a copy of the last frame... */
- boost::shared_ptr<Image> black (
- new Image (
- static_cast<AVPixelFormat> (_frame->format),
- libdcp::Size (video_codec_context()->width, video_codec_context()->height),
- true
- )
- );
-
- black->make_black ();
- video (image, false, _video_position);
- delta -= one_frame;
- }
-
- if (delta > -one_frame) {
- /* This PTS is within a frame of being right; emit this (otherwise it will be dropped) */
- video (image, false, _video_position);
- }
-
+ video (image, false, ContentTime::from_seconds (i->second * av_q2d (_format_context->streams[_video_stream]->time_base)) + _pts_offset);
} else {
- shared_ptr<const Film> film = _film.lock ();
- assert (film);
- film->log()->log ("Dropping frame without PTS");
+ _log->log ("Dropping frame without PTS");
}
}
_sequence_video = f.bool_child ("SequenceVideo");
_three_d = f.bool_child ("ThreeD");
_interop = f.bool_child ("Interop");
- _key = libdcp::Key (f.string_child ("Key"));
+ _key = dcp::Key (f.string_child ("Key"));
- _playlist->set_from_xml (shared_from_this(), f.node_child ("Playlist"), _state_version);
+
+ list<string> notes;
+ /* This method is the only one that can return notes (so far) */
+ _playlist->set_from_xml (shared_from_this(), f.node_child ("Playlist"), _state_version, notes);
_dirty = false;
+ return notes;
}
/** Given a directory name, return its full path within the Film's directory.
signal_changed (SEQUENCE_VIDEO);
}
-libdcp::Size
+ /** @return Size of the largest possible image in whatever resolution we are using */
+dcp::Size
Film::full_frame () const
{
switch (_resolution) {
}
assert (false);
- return libdcp::Size ();
+ return dcp::Size ();
}
-libdcp::Size
+ /** @return Size of the frame */
-libdcp::KDM
++dcp::Size
+ Film::frame_size () const
+ {
+ return fit_ratio_within (container()->ratio(), full_frame ());
+ }
+
+dcp::KDM
Film::make_kdm (
- shared_ptr<libdcp::Certificate> target,
+ shared_ptr<dcp::Certificate> target,
boost::filesystem::path dcp_dir,
boost::posix_time::ptime from,
boost::posix_time::ptime until
return _dirty;
}
- libdcp::Size full_frame () const;
- libdcp::Size frame_size () const;
+ dcp::Size full_frame () const;
++ dcp::Size frame_size () const;
std::list<boost::filesystem::path> dcps () const;
int line_factor (int) const;
int lines (int) const;
- boost::shared_ptr<Image> scale (libdcp::Size, Scaler const *, AVPixelFormat, bool aligned) const;
+ boost::shared_ptr<Image> scale (dcp::Size, Scaler const *, AVPixelFormat, bool aligned) const;
- boost::shared_ptr<Image> post_process (std::string, bool aligned) const;
boost::shared_ptr<Image> crop (Crop c, bool aligned) const;
- boost::shared_ptr<Image> crop_scale_window (Crop c, libdcp::Size, libdcp::Size, Scaler const *, AVPixelFormat, bool aligned) const;
+ boost::shared_ptr<Image> crop_scale_window (Crop c, dcp::Size, dcp::Size, Scaler const *, AVPixelFormat, bool aligned) const;
void make_black ();
void alpha_blend (boost::shared_ptr<const Image> image, Position<int> pos);
return _("No scale");
}
-libdcp::Size
-VideoContentScale::size (shared_ptr<const VideoContent> c, libdcp::Size display_container, libdcp::Size film_container) const
+ /** @param display_container Size of the container that we are displaying this content in.
+ * @param film_container The size of the film's image.
+ */
- VideoContentScale::size (shared_ptr<const VideoContent> c, dcp::Size container) const
+dcp::Size
++VideoContentScale::size (shared_ptr<const VideoContent> c, dcp::Size display_container, dcp::Size film_container) const
{
if (_ratio) {
- return fit_ratio_within (_ratio->ratio (), container);
+ return fit_ratio_within (_ratio->ratio (), display_container);
}
- /* Force scale if the container is smaller than the content's image */
- if (_scale || container.width < c->video_size().width || container.height < c->video_size().height) {
- return fit_ratio_within (c->video_size().ratio (), container);
+ libdcp::Size const ac = c->video_size_after_crop ();
+
+ /* Force scale if the film_container is smaller than the content's image */
+ if (_scale || film_container.width < ac.width || film_container.height < ac.height) {
+ return fit_ratio_within (ac.ratio (), display_container);
}
- return c->video_size ();
+ /* Scale the image so that it will be in the right place in film_container, even if display_container is a
+ different size.
+ */
+ return libdcp::Size (
+ c->video_size().width * float(display_container.width) / film_container.width,
+ c->video_size().height * float(display_container.height) / film_container.height
+ );
}
void
VideoContentScale (bool);
VideoContentScale (boost::shared_ptr<cxml::Node>);
- dcp::Size size (boost::shared_ptr<const VideoContent>, dcp::Size) const;
- libdcp::Size size (boost::shared_ptr<const VideoContent>, libdcp::Size, libdcp::Size) const;
++ dcp::Size size (boost::shared_ptr<const VideoContent>, dcp::Size, dcp::Size) const;
std::string id () const;
std::string name () const;
void as_xml (xmlpp::Node *) const;
*/
if (_film->three_d ()) {
- _picture_asset.reset (new libdcp::StereoPictureAsset (_film->internal_video_mxf_dir (), _film->internal_video_mxf_filename ()));
+ _picture_mxf.reset (new dcp::StereoPictureMXF (dcp::Fraction (_film->video_frame_rate (), 1)));
} else {
- _picture_asset.reset (new libdcp::MonoPictureAsset (_film->internal_video_mxf_dir (), _film->internal_video_mxf_filename ()));
+ _picture_mxf.reset (new dcp::MonoPictureMXF (dcp::Fraction (_film->video_frame_rate (), 1)));
}
- _picture_mxf->set_size (fit_ratio_within (_film->container()->ratio(), _film->full_frame ()));
- _picture_asset->set_edit_rate (_film->video_frame_rate ());
- _picture_asset->set_size (_film->frame_size ());
- _picture_asset->set_interop (_film->interop ());
++ _picture_mxf->set_size (_film->frame_size ());
if (_film->encrypted ()) {
- _picture_asset->set_key (_film->key ());
+ _picture_mxf->set_key (_film->key ());
}
- _picture_asset_writer = _picture_asset->start_write (_first_nonexistant_frame > 0);
+ _picture_mxf_writer = _picture_mxf->start_write (
+ _film->internal_video_mxf_dir() / _film->internal_video_mxf_filename(),
+ _film->interop() ? dcp::INTEROP : dcp::SMPTE,
+ _first_nonexistant_frame > 0
+ );
- _sound_asset.reset (new libdcp::SoundAsset (_film->directory (), _film->audio_mxf_filename ()));
- _sound_asset->set_edit_rate (_film->video_frame_rate ());
- _sound_asset->set_channels (_film->audio_channels ());
- _sound_asset->set_sampling_rate (_film->audio_frame_rate ());
- _sound_asset->set_interop (_film->interop ());
+ _sound_mxf.reset (new dcp::SoundMXF (dcp::Fraction (_film->video_frame_rate(), 1), _film->audio_frame_rate (), _film->audio_channels ()));
if (_film->encrypted ()) {
- _sound_asset->set_key (_film->key ());
+ _sound_mxf->set_key (_film->key ());
}
- /* Write the sound asset into the film directory so that we leave the creation
+ /* Write the sound MXF into the film directory so that we leave the creation
of the DCP directory until the last minute.
*/
- _sound_asset_writer = _sound_asset->start_write ();
+ _sound_mxf_writer = _sound_mxf->start_write (_film->directory() / _film->audio_mxf_filename(), _film->interop() ? dcp::INTEROP : dcp::SMPTE);
_thread = new boost::thread (boost::bind (&Writer::thread, this));
#include <boost/lexical_cast.hpp>
#include <boost/filesystem.hpp>
#include <wx/stdpaths.h>
- #include <wx/notebook.h>
+ #include <wx/preferences.h>
+ #include <wx/filepicker.h>
+ #include <wx/spinctrl.h>
-#include <libdcp/colour_matrix.h>
+#include <dcp/colour_matrix.h>
#include "lib/config.h"
#include "lib/ratio.h"
#include "lib/scaler.h"
++lines;
}
- dcp::Size const container_size = fit_ratio_within (_editor->film()->container()->ratio (), _editor->film()->full_frame ());
- dcp::Size const scaled = vcs->scale().size (vcs, container_size);
- libdcp::Size const container_size = _editor->film()->frame_size ();
- libdcp::Size const scaled = vcs->scale().size (vcs, container_size, container_size);
++ dcp::Size const container_size = _editor->film()->frame_size ();
++ dcp::Size const scaled = vcs->scale().size (vcs, container_size, container_size);
if (scaled != vcs->video_size_after_crop ()) {
d << wxString::Format (