From: Carl Hetherington Date: Sat, 25 Oct 2014 13:47:43 +0000 (+0100) Subject: Merge master. X-Git-Tag: v2.0.48~545 X-Git-Url: https://git.carlh.net/gitweb/?p=dcpomatic.git;a=commitdiff_plain;h=b6c780d3107557d452c6612d715d01e2be52dbda Merge master. --- b6c780d3107557d452c6612d715d01e2be52dbda diff --cc ChangeLog index 053c1f106,1978d85f7..07c8218f7 --- a/ChangeLog +++ b/ChangeLog @@@ -1,7 -1,30 +1,34 @@@ + 2014-10-24 Carl Hetherington + + * Add a pause button for jobs. + + * Experimental support for bypassing colourspace conversion (#266). + + * Version 1.76.6 released. + + 2014-10-23 Carl Hetherington + + * Version 1.76.5 released. + + 2014-10-23 Carl Hetherington + + * Version 1.76.4 released. + + 2014-10-23 Carl Hetherington + + * Rename 'Add folder' to 'Add image sequence' + and add some tooltips. + + * Move the "keep video in sequence" button into + the timeline dialogue. + + * Fix mix-placement of content when using the "Down" + button to move it. + +2014-10-22 Carl Hetherington + + * Version 2.0.15 released. + 2014-10-22 Carl Hetherington * Version 1.76.3 released. diff --cc debian/changelog index 5702a6dfd,6f3d19700..9087bd105 --- a/debian/changelog +++ b/debian/changelog @@@ -195,8 -195,10 +195,15 @@@ dcpomatic (2.0.15-1) UNRELEASED; urgenc * New upstream release. * New upstream release. * New upstream release. ++<<<<<<< HEAD + + -- Carl Hetherington Wed, 22 Oct 2014 14:24:53 +0100 ++======= + * New upstream release. + * New upstream release. + + -- Carl Hetherington Fri, 24 Oct 2014 01:19:26 +0100 ++>>>>>>> origin/master dcpomatic (0.87-1) UNRELEASED; urgency=low diff --cc src/lib/dcp_video.cc index f6c671fd1,000000000..cacba190f mode 100644,000000..100644 --- a/src/lib/dcp_video.cc +++ b/src/lib/dcp_video.cc @@@ -1,332 -1,0 +1,339 @@@ +/* + Copyright (C) 2012-2014 Carl Hetherington + Taken from code Copyright (C) 2010-2011 Terrence Meiczinger + + 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. + +*/ + +/** @file src/dcp_video_frame.cc + * @brief A single frame of video destined for a DCP. + * + * Given an Image and some settings, this class knows how to encode + * the image to J2K either on the local host or on a remote server. + * + * Objects of this class are used for the queue that we keep + * of images that require encoding. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "film.h" +#include "dcp_video.h" +#include "config.h" +#include "exceptions.h" +#include "server.h" +#include "util.h" +#include "scaler.h" +#include "image.h" +#include "log.h" +#include "cross.h" +#include "player_video.h" +#include "encoded_data.h" + +#define LOG_GENERAL(...) _log->log (String::compose (__VA_ARGS__), Log::TYPE_GENERAL); + +#include "i18n.h" + +using std::string; +using std::cout; +using boost::shared_ptr; +using boost::lexical_cast; +using dcp::Size; +using dcp::raw_convert; + +#define DCI_COEFFICENT (48.0 / 52.37) + +/** Construct a DCP video frame. + * @param frame Input frame. + * @param index Index of the frame within the DCP. + * @param bw J2K bandwidth to use (see Config::j2k_bandwidth ()) + * @param l Log to write to. + */ +DCPVideo::DCPVideo ( + shared_ptr frame, int index, int dcp_fps, int bw, Resolution r, bool b, shared_ptr l + ) + : _frame (frame) + , _index (index) + , _frames_per_second (dcp_fps) + , _j2k_bandwidth (bw) + , _resolution (r) + , _burn_subtitles (b) + , _log (l) +{ + +} + +DCPVideo::DCPVideo (shared_ptr frame, shared_ptr node, shared_ptr log) + : _frame (frame) + , _log (log) +{ + _index = node->number_child ("Index"); + _frames_per_second = node->number_child ("FramesPerSecond"); + _j2k_bandwidth = node->number_child ("J2KBandwidth"); + _resolution = Resolution (node->optional_number_child("Resolution").get_value_or (RESOLUTION_2K)); + _burn_subtitles = node->bool_child ("BurnSubtitles"); +} + +/** J2K-encode this frame on the local host. + * @return Encoded data. + */ +shared_ptr +DCPVideo::encode_locally () +{ - shared_ptr in_lut = dcp::GammaLUT::cache.get ( - 12, _frame->colour_conversion().input_gamma, _frame->colour_conversion().input_gamma_linearised - ); - - /* XXX: libdcp should probably use boost */ - - double matrix[3][3]; - for (int i = 0; i < 3; ++i) { - for (int j = 0; j < 3; ++j) { - matrix[i][j] = _frame->colour_conversion().matrix (i, j); ++ shared_ptr xyz; ++ ++ if (_frame->colour_conversion()) { ++ ColourConversion conversion = _frame->colour_conversion().get (); ++ shared_ptr in_lut = dcp::GammaLUT::cache.get ( ++ 12, conversion.input_gamma, conversion.input_gamma_linearised ++ ); ++ ++ /* XXX: dcp should probably use boost */ ++ ++ double matrix[3][3]; ++ for (int i = 0; i < 3; ++i) { ++ for (int j = 0; j < 3; ++j) { ++ matrix[i][j] = conversion.matrix (i, j); ++ } + } ++ ++ xyz = dcp::rgb_to_xyz ( ++ _frame->image (AV_PIX_FMT_RGB48LE, _burn_subtitles), ++ in_lut, ++ dcp::GammaLUT::cache.get (16, 1 / conversion.output_gamma, false), ++ matrix ++ ); ++ } else { ++ xyz = dcp::xyz_to_xyz (_frame->image (AV_PIX_FMT_RGB48LE, _burn_subtitles)); + } + - shared_ptr xyz = dcp::rgb_to_xyz ( - _frame->image (AV_PIX_FMT_RGB48LE, _burn_subtitles), - in_lut, - dcp::GammaLUT::cache.get (16, 1 / _frame->colour_conversion().output_gamma, false), - matrix - ); - + /* Set the max image and component sizes based on frame_rate */ + int max_cs_len = ((float) _j2k_bandwidth) / 8 / _frames_per_second; + if (_frame->eyes() == EYES_LEFT || _frame->eyes() == EYES_RIGHT) { + /* In 3D we have only half the normal bandwidth per eye */ + max_cs_len /= 2; + } + int const max_comp_size = max_cs_len / 1.25; + + /* get a J2K compressor handle */ + opj_cinfo_t* cinfo = opj_create_compress (CODEC_J2K); + if (cinfo == 0) { + throw EncodeError (N_("could not create JPEG2000 encoder")); + } + + /* Set encoding parameters to default values */ + opj_cparameters_t parameters; + opj_set_default_encoder_parameters (¶meters); + + /* Set default cinema parameters */ + parameters.tile_size_on = false; + parameters.cp_tdx = 1; + parameters.cp_tdy = 1; + + /* Tile part */ + parameters.tp_flag = 'C'; + parameters.tp_on = 1; + + /* Tile and Image shall be at (0,0) */ + parameters.cp_tx0 = 0; + parameters.cp_ty0 = 0; + parameters.image_offset_x0 = 0; + parameters.image_offset_y0 = 0; + + /* Codeblock size = 32x32 */ + parameters.cblockw_init = 32; + parameters.cblockh_init = 32; + parameters.csty |= 0x01; + + /* The progression order shall be CPRL */ + parameters.prog_order = CPRL; + + /* No ROI */ + parameters.roi_compno = -1; + + parameters.subsampling_dx = 1; + parameters.subsampling_dy = 1; + + /* 9-7 transform */ + parameters.irreversible = 1; + + parameters.tcp_rates[0] = 0; + parameters.tcp_numlayers++; + parameters.cp_disto_alloc = 1; + parameters.cp_rsiz = _resolution == RESOLUTION_2K ? CINEMA2K : CINEMA4K; + if (_resolution == RESOLUTION_4K) { + parameters.numpocs = 2; + parameters.POC[0].tile = 1; + parameters.POC[0].resno0 = 0; + parameters.POC[0].compno0 = 0; + parameters.POC[0].layno1 = 1; + parameters.POC[0].resno1 = parameters.numresolution - 1; + parameters.POC[0].compno1 = 3; + parameters.POC[0].prg1 = CPRL; + parameters.POC[1].tile = 1; + parameters.POC[1].resno0 = parameters.numresolution - 1; + parameters.POC[1].compno0 = 0; + parameters.POC[1].layno1 = 1; + parameters.POC[1].resno1 = parameters.numresolution; + parameters.POC[1].compno1 = 3; + parameters.POC[1].prg1 = CPRL; + } + + parameters.cp_comment = strdup (N_("DCP-o-matic")); + parameters.cp_cinema = _resolution == RESOLUTION_2K ? CINEMA2K_24 : CINEMA4K_24; + + /* 3 components, so use MCT */ + parameters.tcp_mct = 1; + + /* set max image */ + parameters.max_comp_size = max_comp_size; + parameters.tcp_rates[0] = ((float) (3 * xyz->size().width * xyz->size().height * 12)) / (max_cs_len * 8); + + /* Set event manager to null (openjpeg 1.3 bug) */ + cinfo->event_mgr = 0; + + /* Setup the encoder parameters using the current image and user parameters */ + opj_setup_encoder (cinfo, ¶meters, xyz->opj_image ()); + + opj_cio_t* cio = opj_cio_open ((opj_common_ptr) cinfo, 0, 0); + if (cio == 0) { + opj_destroy_compress (cinfo); + throw EncodeError (N_("could not open JPEG2000 stream")); + } + + int const r = opj_encode (cinfo, cio, xyz->opj_image(), 0); + if (r == 0) { + opj_cio_close (cio); + opj_destroy_compress (cinfo); + throw EncodeError (N_("JPEG2000 encoding failed")); + } + + switch (_frame->eyes()) { + case EYES_BOTH: + LOG_GENERAL (N_("Finished locally-encoded frame %1 for mono"), _index); + break; + case EYES_LEFT: + LOG_GENERAL (N_("Finished locally-encoded frame %1 for L"), _index); + break; + case EYES_RIGHT: + LOG_GENERAL (N_("Finished locally-encoded frame %1 for R"), _index); + break; + default: + break; + } + + shared_ptr enc (new LocallyEncodedData (cio->buffer, cio_tell (cio))); + + opj_cio_close (cio); + free (parameters.cp_comment); + opj_destroy_compress (cinfo); + + return enc; +} + +/** Send this frame to a remote server for J2K encoding, then read the result. + * @param serv Server to send to. + * @return Encoded data. + */ +shared_ptr +DCPVideo::encode_remotely (ServerDescription serv) +{ + boost::asio::io_service io_service; + boost::asio::ip::tcp::resolver resolver (io_service); + boost::asio::ip::tcp::resolver::query query (serv.host_name(), raw_convert (Config::instance()->server_port_base ())); + boost::asio::ip::tcp::resolver::iterator endpoint_iterator = resolver.resolve (query); + + shared_ptr socket (new Socket); + + socket->connect (*endpoint_iterator); + + /* Collect all XML metadata */ + xmlpp::Document doc; + xmlpp::Element* root = doc.create_root_node ("EncodingRequest"); + root->add_child("Version")->add_child_text (raw_convert (SERVER_LINK_VERSION)); + add_metadata (root); + + LOG_GENERAL (N_("Sending frame %1 to remote"), _index); + + /* Send XML metadata */ + string xml = doc.write_to_string ("UTF-8"); + socket->write (xml.length() + 1); + socket->write ((uint8_t *) xml.c_str(), xml.length() + 1); + + /* Send binary data */ + _frame->send_binary (socket, _burn_subtitles); + + /* Read the response (JPEG2000-encoded data); this blocks until the data + is ready and sent back. + */ + shared_ptr e (new RemotelyEncodedData (socket->read_uint32 ())); + socket->read (e->data(), e->size()); + + LOG_GENERAL (N_("Finished remotely-encoded frame %1"), _index); + + return e; +} + +void +DCPVideo::add_metadata (xmlpp::Element* el) const +{ + el->add_child("Index")->add_child_text (raw_convert (_index)); + el->add_child("FramesPerSecond")->add_child_text (raw_convert (_frames_per_second)); + el->add_child("J2KBandwidth")->add_child_text (raw_convert (_j2k_bandwidth)); + el->add_child("Resolution")->add_child_text (raw_convert (int (_resolution))); + el->add_child("BurnSubtitles")->add_child_text (_burn_subtitles ? "1" : "0"); + _frame->add_metadata (el, _burn_subtitles); +} + +Eyes +DCPVideo::eyes () const +{ + return _frame->eyes (); +} + +/** @return true if this DCPVideo is definitely the same as another; + * (apart from the frame index), false if it is probably not. + */ +bool +DCPVideo::same (shared_ptr other) const +{ + if (_frames_per_second != other->_frames_per_second || + _j2k_bandwidth != other->_j2k_bandwidth || + _resolution != other->_resolution || + _burn_subtitles != other->_burn_subtitles) { + return false; + } + + return _frame->same (other->_frame); +} diff --cc src/lib/player_video.cc index 8e6fcd5f3,000000000..b5f0b5fa5 mode 100644,000000..100644 --- a/src/lib/player_video.cc +++ b/src/lib/player_video.cc @@@ -1,209 -1,0 +1,212 @@@ +/* + Copyright (C) 2013-2014 Carl Hetherington + + 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 +#include "player_video.h" +#include "image.h" +#include "image_proxy.h" +#include "j2k_image_proxy.h" +#include "scaler.h" + +using std::string; +using std::cout; +using dcp::raw_convert; +using boost::shared_ptr; +using boost::dynamic_pointer_cast; ++using boost::optional; + +PlayerVideo::PlayerVideo ( + shared_ptr in, + DCPTime time, + Crop crop, + boost::optional fade, + dcp::Size inter_size, + dcp::Size out_size, + Scaler const * scaler, + Eyes eyes, + Part part, - ColourConversion colour_conversion ++ optional colour_conversion + ) + : _in (in) + , _time (time) + , _crop (crop) + , _fade (fade) + , _inter_size (inter_size) + , _out_size (out_size) + , _scaler (scaler) + , _eyes (eyes) + , _part (part) + , _colour_conversion (colour_conversion) +{ + +} + +PlayerVideo::PlayerVideo (shared_ptr node, shared_ptr socket, shared_ptr log) +{ + _time = DCPTime (node->number_child ("Time")); + _crop = Crop (node); + _fade = node->optional_number_child ("Fade"); + + _inter_size = dcp::Size (node->number_child ("InterWidth"), node->number_child ("InterHeight")); + _out_size = dcp::Size (node->number_child ("OutWidth"), node->number_child ("OutHeight")); + _scaler = Scaler::from_id (node->string_child ("Scaler")); + _eyes = (Eyes) node->number_child ("Eyes"); + _part = (Part) node->number_child ("Part"); - _colour_conversion = ColourConversion (node); ++ _colour_conversion = ColourConversion::from_xml (node); + + _in = image_proxy_factory (node->node_child ("In"), socket, log); + + if (node->optional_number_child ("SubtitleX")) { + + _subtitle.position = Position (node->number_child ("SubtitleX"), node->number_child ("SubtitleY")); + + _subtitle.image.reset ( + new Image (PIX_FMT_RGBA, dcp::Size (node->number_child ("SubtitleWidth"), node->number_child ("SubtitleHeight")), true) + ); + + _subtitle.image->read_from_socket (socket); + } +} + +void +PlayerVideo::set_subtitle (PositionImage image) +{ + _subtitle = image; +} + +shared_ptr +PlayerVideo::image (AVPixelFormat pixel_format, bool burn_subtitle) const +{ + shared_ptr im = _in->image (); + + Crop total_crop = _crop; + switch (_part) { + case PART_LEFT_HALF: + total_crop.right += im->size().width / 2; + break; + case PART_RIGHT_HALF: + total_crop.left += im->size().width / 2; + break; + case PART_TOP_HALF: + total_crop.bottom += im->size().height / 2; + break; + case PART_BOTTOM_HALF: + total_crop.top += im->size().height / 2; + break; + default: + break; + } + + shared_ptr out = im->crop_scale_window (total_crop, _inter_size, _out_size, _scaler, pixel_format, true); + + if (burn_subtitle && _subtitle.image) { + out->alpha_blend (_subtitle.image, _subtitle.position); + } + + if (_fade) { + out->fade (_fade.get ()); + } + + return out; +} + +void +PlayerVideo::add_metadata (xmlpp::Node* node, bool send_subtitles) const +{ + node->add_child("Time")->add_child_text (raw_convert (_time.get ())); + _crop.as_xml (node); + if (_fade) { + node->add_child("Fade")->add_child_text (raw_convert (_fade.get ())); + } + _in->add_metadata (node->add_child ("In")); + node->add_child("InterWidth")->add_child_text (raw_convert (_inter_size.width)); + node->add_child("InterHeight")->add_child_text (raw_convert (_inter_size.height)); + node->add_child("OutWidth")->add_child_text (raw_convert (_out_size.width)); + node->add_child("OutHeight")->add_child_text (raw_convert (_out_size.height)); + node->add_child("Scaler")->add_child_text (_scaler->id ()); + node->add_child("Eyes")->add_child_text (raw_convert (_eyes)); + node->add_child("Part")->add_child_text (raw_convert (_part)); - _colour_conversion.as_xml (node); ++ if (_colour_conversion) { ++ _colour_conversion.get().as_xml (node); ++ } + if (send_subtitles && _subtitle.image) { + node->add_child ("SubtitleWidth")->add_child_text (raw_convert (_subtitle.image->size().width)); + node->add_child ("SubtitleHeight")->add_child_text (raw_convert (_subtitle.image->size().height)); + node->add_child ("SubtitleX")->add_child_text (raw_convert (_subtitle.position.x)); + node->add_child ("SubtitleY")->add_child_text (raw_convert (_subtitle.position.y)); + } +} + +void +PlayerVideo::send_binary (shared_ptr socket, bool send_subtitles) const +{ + _in->send_binary (socket); + if (send_subtitles && _subtitle.image) { + _subtitle.image->write_to_socket (socket); + } +} + +bool +PlayerVideo::has_j2k () const +{ + /* XXX: burnt-in subtitle; maybe other things */ + + shared_ptr j2k = dynamic_pointer_cast (_in); + if (!j2k) { + return false; + } + + return _crop == Crop () && _inter_size == j2k->size(); +} + +shared_ptr +PlayerVideo::j2k () const +{ + shared_ptr j2k = dynamic_pointer_cast (_in); + assert (j2k); + return j2k->j2k (); +} + +Position +PlayerVideo::inter_position () const +{ + return Position ((_out_size.width - _inter_size.width) / 2, (_out_size.height - _inter_size.height) / 2); +} + +/** @return true if this PlayerVideo is definitely the same as another + * (apart from _time), false if it is probably not + */ +bool +PlayerVideo::same (shared_ptr other) const +{ + if (_in != other->_in || + _crop != other->_crop || + _fade.get_value_or(0) != other->_fade.get_value_or(0) || + _inter_size != other->_inter_size || + _out_size != other->_out_size || + _scaler != other->_scaler || + _eyes != other->_eyes || + _part != other->_part || + _colour_conversion != other->_colour_conversion || + !_subtitle.same (other->_subtitle)) { + return false; + } + + return _in->same (other->_in); +} diff --cc src/lib/player_video.h index e9d260972,000000000..610a7526c mode 100644,000000..100644 --- a/src/lib/player_video.h +++ b/src/lib/player_video.h @@@ -1,102 -1,0 +1,102 @@@ +/* + Copyright (C) 2013-2014 Carl Hetherington + + 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 +extern "C" { +#include +} +#include "types.h" +#include "position.h" +#include "colour_conversion.h" +#include "position_image.h" + +class Image; +class ImageProxy; +class Scaler; +class Socket; +class Log; +class EncodedData; + +/** Everything needed to describe a video frame coming out of the player, but with the + * bits still their raw form. We may want to combine the bits on a remote machine, + * or maybe not even bother to combine them at all. + */ +class PlayerVideo +{ +public: + PlayerVideo ( + boost::shared_ptr, + DCPTime, + Crop, + boost::optional, + dcp::Size, + dcp::Size, + Scaler const *, + Eyes, + Part, - ColourConversion ++ boost::optional + ); + + PlayerVideo (boost::shared_ptr, boost::shared_ptr, boost::shared_ptr); + + void set_subtitle (PositionImage); + + boost::shared_ptr image (AVPixelFormat pix_fmt, bool burn_subtitle) const; + + void add_metadata (xmlpp::Node* node, bool send_subtitles) const; + void send_binary (boost::shared_ptr socket, bool send_subtitles) const; + + bool has_j2k () const; + boost::shared_ptr j2k () const; + + DCPTime time () const { + return _time; + } + + Eyes eyes () const { + return _eyes; + } + - ColourConversion colour_conversion () const { ++ boost::optional colour_conversion () const { + return _colour_conversion; + } + + /** @return Position of the content within the overall image once it has been scaled up */ + Position inter_position () const; + + /** @return Size of the content within the overall image once it has been scaled up */ + dcp::Size inter_size () const { + return _inter_size; + } + + bool same (boost::shared_ptr other) const; + +private: + boost::shared_ptr _in; + DCPTime _time; + Crop _crop; + boost::optional _fade; + dcp::Size _inter_size; + dcp::Size _out_size; + Scaler const * _scaler; + Eyes _eyes; + Part _part; - ColourConversion _colour_conversion; ++ boost::optional _colour_conversion; + PositionImage _subtitle; +}; diff --cc src/lib/playlist.cc index 22412da4a,264d9ab4a..4580e54d4 --- a/src/lib/playlist.cc +++ b/src/lib/playlist.cc @@@ -393,6 -395,23 +399,6 @@@ Playlist::move_later (shared_ptrset_position (c->position ()); - c->set_position (c->position() + c->length_after_trim ()); + c->set_position (c->position() + (*next)->length_after_trim ()); sort (_content.begin(), _content.end(), ContentSorter ()); } - -FrameRateChange -Playlist::active_frame_rate_change (Time t, int dcp_video_frame_rate) const -{ - for (ContentList::const_iterator i = _content.begin(); i != _content.end(); ++i) { - shared_ptr vc = dynamic_pointer_cast (*i); - if (!vc) { - continue; - } - - if (vc->position() >= t && t < vc->end()) { - return FrameRateChange (vc->video_frame_rate(), dcp_video_frame_rate); - } - } - - return FrameRateChange (dcp_video_frame_rate, dcp_video_frame_rate); -} diff --cc src/lib/po/de_DE.po index 68418910c,0dc9cd5df..32a4b67e2 --- a/src/lib/po/de_DE.po +++ b/src/lib/po/de_DE.po @@@ -681,11 -624,19 +687,19 @@@ msgstr "kopiere %1 msgid "could not create file %1" msgstr "Datei %1 konnte nicht erstellt werden." +#: src/lib/ffmpeg.cc:102 +msgid "could not find stream information" +msgstr "Keine Spur-Information gefunden" + - #: src/lib/writer.cc:430 + #: src/lib/ffmpeg.cc:179 + msgid "could not find audio decoder" + msgstr "Ton Dekoder nicht gefunden." + -#: src/lib/ffmpeg.cc:105 -msgid "could not find stream information" -msgstr "Keine Spur-Information gefunden" - + #: src/lib/ffmpeg.cc:158 + msgid "could not find video decoder" + msgstr "Bild-Dekoder nicht gefunden" + + #: src/lib/writer.cc:439 msgid "could not move audio MXF into the DCP (%1)" msgstr "Ton MXF kann nicht in das DCP verschoben werden (%1)" @@@ -816,15 -771,6 +830,9 @@@ msgstr "Standbild msgid "unknown" msgstr "unbekannt" - #~ msgid "could not find audio decoder" - #~ msgstr "Ton Dekoder nicht gefunden." - - #~ msgid "could not find video decoder" - #~ msgstr "Bild-Dekoder nicht gefunden" - +#~ msgid "non-bitmap subtitles not yet supported" +#~ msgstr "Nur Bitmap Untertitel werden unterstützt" + #~ msgid "Could not read DCP to make KDM for" #~ msgstr "DCP konnte nicht zur Schlüsselerstellung geöffnet werden" diff --cc src/lib/po/es_ES.po index e874c6415,4fcfac93a..5dc99462b --- a/src/lib/po/es_ES.po +++ b/src/lib/po/es_ES.po @@@ -675,7 -622,11 +681,15 @@@ msgstr "No se pudo crear el fichero (%1 msgid "could not find stream information" msgstr "no se pudo encontrar información del flujo" +#: src/lib/writer.cc:430 ++msgid "could not find audio decoder" ++msgstr "no se encontró el decodificador de audio" ++ + #: src/lib/ffmpeg.cc:158 + msgid "could not find video decoder" + msgstr "no se pudo encontrar decodificador de vídeo" + + #: src/lib/writer.cc:439 msgid "could not move audio MXF into the DCP (%1)" msgstr "no s puedo mover el audio MXF en el DCP (%1)" @@@ -806,15 -761,6 +820,9 @@@ msgstr "imagen fija msgid "unknown" msgstr "desconocido" - #~ msgid "could not find audio decoder" - #~ msgstr "no se encontró el decodificador de audio" - - #~ msgid "could not find video decoder" - #~ msgstr "no se pudo encontrar decodificador de vídeo" - +#~ msgid "non-bitmap subtitles not yet supported" +#~ msgstr "todavía no se soportan subtítulos que no son en mapas de bits" + #~ msgid "Could not read DCP to make KDM for" #~ msgstr "No se pudo leer el DCP para hacer el KDM" diff --cc src/lib/po/fr_FR.po index 474da73f9,ff1152f39..bf8dc04f7 --- a/src/lib/po/fr_FR.po +++ b/src/lib/po/fr_FR.po @@@ -674,11 -616,19 +680,19 @@@ msgstr "copie de %1 msgid "could not create file %1" msgstr "Écriture vers fichier distant (%1) impossible" +#: src/lib/ffmpeg.cc:102 +msgid "could not find stream information" +msgstr "information du flux introuvable" + - #: src/lib/writer.cc:430 + #: src/lib/ffmpeg.cc:179 + msgid "could not find audio decoder" + msgstr "décodeur audio introuvable" + -#: src/lib/ffmpeg.cc:105 -msgid "could not find stream information" -msgstr "information du flux introuvable" - + #: src/lib/ffmpeg.cc:158 + msgid "could not find video decoder" + msgstr "décodeur vidéo introuvable" + + #: src/lib/writer.cc:439 msgid "could not move audio MXF into the DCP (%1)" msgstr "ne peut déplacer un MXF son dans le DCP (%1)" @@@ -811,15 -765,6 +825,9 @@@ msgstr "%1 [restant] msgid "unknown" msgstr "Inconnu" - #~ msgid "could not find audio decoder" - #~ msgstr "décodeur audio introuvable" - - #~ msgid "could not find video decoder" - #~ msgstr "décodeur vidéo introuvable" - +#~ msgid "non-bitmap subtitles not yet supported" +#~ msgstr "sous-titres non-bitmap non supportés actuellement" + #~ msgid "Could not read DCP to make KDM for" #~ msgstr "DCP illisible pour fabrication de KDM" diff --cc src/lib/po/it_IT.po index a22ccee3c,5863e5ad7..a3b1b9de7 --- a/src/lib/po/it_IT.po +++ b/src/lib/po/it_IT.po @@@ -829,15 -782,6 +843,9 @@@ msgstr "ancora msgid "unknown" msgstr "Errore sconosciuto" - #~ msgid "could not find audio decoder" - #~ msgstr "non riesco a trovare il decoder audio" - - #~ msgid "could not find video decoder" - #~ msgstr "non riesco a trovare il decoder video" - +#~ msgid "non-bitmap subtitles not yet supported" +#~ msgstr "sottotitoli non-bitmap non ancora supportati" + #~ msgid "Cubic interpolating deinterlacer" #~ msgstr "Deinterlacciatore cubico interpolato" diff --cc src/lib/po/nl_NL.po index 81a1e626b,bc953fbbe..414eacdc5 --- a/src/lib/po/nl_NL.po +++ b/src/lib/po/nl_NL.po @@@ -808,14 -763,5 +822,8 @@@ msgstr "still msgid "unknown" msgstr "onbekend" - #~ msgid "could not find audio decoder" - #~ msgstr "kan geen audio decoder vinden" - - #~ msgid "could not find video decoder" - #~ msgstr "kan geen videodecoder vinden" - +#~ msgid "non-bitmap subtitles not yet supported" +#~ msgstr "non-bitmap ondertitels worden nog niet ondersteund" + #~ msgid "Could not read DCP to make KDM for" #~ msgstr "Kan DCP niet lezen om KDM te maken" diff --cc src/lib/po/sv_SE.po index 29127294f,0c11c69e0..75a664191 --- a/src/lib/po/sv_SE.po +++ b/src/lib/po/sv_SE.po @@@ -819,15 -774,6 +833,9 @@@ msgstr "stillbild msgid "unknown" msgstr "okänd" - #~ msgid "could not find audio decoder" - #~ msgstr "kunde inte hitta audio-avkodare" - - #~ msgid "could not find video decoder" - #~ msgstr "kunde inte hitta video-avkodare" - +#~ msgid "non-bitmap subtitles not yet supported" +#~ msgstr "icke-rastergrafiska undertexter stöds inte ännu" + #~ msgid "Could not read DCP to make KDM for" #~ msgstr "Kunde inte läsa DCP för att skapa KDM" diff --cc src/lib/video_content.cc index ba656e4c2,3094a70c8..976bc3aa0 --- a/src/lib/video_content.cc +++ b/src/lib/video_content.cc @@@ -65,12 -61,13 +65,12 @@@ VideoContent::VideoContent (shared_ptr< , _video_frame_type (VIDEO_FRAME_TYPE_2D) , _scale (Config::instance()->default_scale ()) { - setup_default_colour_conversion (); + set_default_colour_conversion (); } -VideoContent::VideoContent (shared_ptr f, Time s, VideoContent::Frame len) +VideoContent::VideoContent (shared_ptr f, DCPTime s, ContentTime len) : Content (f, s) , _video_length (len) - , _original_video_frame_rate (0) , _video_frame_rate (0) , _video_frame_type (VIDEO_FRAME_TYPE_2D) , _scale (Config::instance()->default_scale ()) @@@ -85,12 -83,13 +85,12 @@@ VideoContent::VideoContent (shared_ptr< , _video_frame_type (VIDEO_FRAME_TYPE_2D) , _scale (Config::instance()->default_scale ()) { - setup_default_colour_conversion (); + set_default_colour_conversion (); } -VideoContent::VideoContent (shared_ptr f, shared_ptr node, int version) +VideoContent::VideoContent (shared_ptr f, cxml::ConstNodePtr node, int version) : Content (f, node) { - _video_length = node->number_child ("VideoLength"); _video_size.width = node->number_child ("VideoWidth"); _video_size.height = node->number_child ("VideoHeight"); _video_frame_rate = node->number_child ("VideoFrameRate"); @@@ -116,12 -108,10 +116,15 @@@ } else { _scale = VideoContentScale (node->node_child ("Scale")); } + + - _colour_conversion = ColourConversion (node->node_child ("ColourConversion")); + if (node->optional_node_child ("ColourConversion")) { + _colour_conversion = ColourConversion (node->node_child ("ColourConversion")); + } + if (version >= 32) { + _fade_in = ContentTime (node->number_child ("FadeIn")); + _fade_out = ContentTime (node->number_child ("FadeOut")); + } } VideoContent::VideoContent (shared_ptr f, vector > c) @@@ -186,15 -171,16 +189,17 @@@ VideoContent::as_xml (xmlpp::Node* node node->add_child("VideoFrameType")->add_child_text (raw_convert (static_cast (_video_frame_type))); _crop.as_xml (node); _scale.as_xml (node->add_child("Scale")); - _colour_conversion.as_xml (node->add_child("ColourConversion")); + if (_colour_conversion) { + _colour_conversion.get().as_xml (node->add_child("ColourConversion")); + } + node->add_child("FadeIn")->add_child_text (raw_convert (_fade_in.get ())); + node->add_child("FadeOut")->add_child_text (raw_convert (_fade_out.get ())); } void - VideoContent::setup_default_colour_conversion () + VideoContent::set_default_colour_conversion () { - _colour_conversion = PresetColourConversion (_("sRGB"), 2.4, true, dcp::colour_matrix::srgb_to_xyz, 2.6).conversion; - set_colour_conversion (PresetColourConversion (_("sRGB"), 2.4, true, libdcp::colour_matrix::srgb_to_xyz, 2.6).conversion); ++ set_colour_conversion (PresetColourConversion (_("sRGB"), 2.4, true, dcp::colour_matrix::srgb_to_xyz, 2.6).conversion); } void diff --cc src/lib/video_content.h index e88fb0227,9aa3be521..3c8e5fefd --- a/src/lib/video_content.h +++ b/src/lib/video_content.h @@@ -89,10 -92,9 +89,12 @@@ public void set_bottom_crop (int); void set_scale (VideoContentScale); + void unset_colour_conversion (); void set_colour_conversion (ColourConversion); + void set_default_colour_conversion (); + + void set_fade_in (ContentTime); + void set_fade_out (ContentTime); VideoFrameType video_frame_type () const { boost::mutex::scoped_lock lm (_mutex); @@@ -173,9 -162,7 +175,9 @@@ private VideoFrameType _video_frame_type; Crop _crop; VideoContentScale _scale; - ColourConversion _colour_conversion; + boost::optional _colour_conversion; + ContentTime _fade_in; + ContentTime _fade_out; }; #endif diff --cc src/wx/film_editor.cc index 7f9461d94,4b3898859..881317f3a --- a/src/wx/film_editor.cc +++ b/src/wx/film_editor.cc @@@ -88,11 -92,331 +88,9 @@@ FilmEditor::FilmEditor (wxWindow* paren bind (&FilmEditor::active_jobs_changed, this, _1) ); - Config::instance()->Changed.connect (boost::bind (&FilmEditor::config_changed, this)); - set_film (shared_ptr ()); - -- SetSizerAndFit (s); -} - -void -FilmEditor::make_dcp_panel () -{ - _dcp_panel = new wxPanel (_main_notebook); - _dcp_sizer = new wxBoxSizer (wxVERTICAL); - _dcp_panel->SetSizer (_dcp_sizer); - - wxGridBagSizer* grid = new wxGridBagSizer (DCPOMATIC_SIZER_X_GAP, DCPOMATIC_SIZER_Y_GAP); - _dcp_sizer->Add (grid, 0, wxEXPAND | wxALL, 8); - - int r = 0; - - add_label_to_grid_bag_sizer (grid, _dcp_panel, _("Name"), true, wxGBPosition (r, 0)); - _name = new wxTextCtrl (_dcp_panel, wxID_ANY); - grid->Add (_name, wxGBPosition(r, 1), wxDefaultSpan, wxEXPAND | wxLEFT | wxRIGHT); - ++r; - - int flags = wxALIGN_CENTER_VERTICAL; -#ifdef __WXOSX__ - flags |= wxALIGN_RIGHT; -#endif - - _use_isdcf_name = new wxCheckBox (_dcp_panel, wxID_ANY, _("Use ISDCF name")); - grid->Add (_use_isdcf_name, wxGBPosition (r, 0), wxDefaultSpan, flags); - _edit_isdcf_button = new wxButton (_dcp_panel, wxID_ANY, _("Details...")); - grid->Add (_edit_isdcf_button, wxGBPosition (r, 1), wxDefaultSpan); - ++r; - - add_label_to_grid_bag_sizer (grid, _dcp_panel, _("DCP Name"), true, wxGBPosition (r, 0)); - _dcp_name = new wxStaticText (_dcp_panel, wxID_ANY, wxT ("")); - grid->Add (_dcp_name, wxGBPosition(r, 1), wxDefaultSpan, wxALIGN_CENTER_VERTICAL); - ++r; - - add_label_to_grid_bag_sizer (grid, _dcp_panel, _("Container"), true, wxGBPosition (r, 0)); - _container = new wxChoice (_dcp_panel, wxID_ANY); - grid->Add (_container, wxGBPosition (r, 1), wxDefaultSpan, wxEXPAND); - ++r; - - add_label_to_grid_bag_sizer (grid, _dcp_panel, _("Content Type"), true, wxGBPosition (r, 0)); - _dcp_content_type = new wxChoice (_dcp_panel, wxID_ANY); - grid->Add (_dcp_content_type, wxGBPosition (r, 1)); - ++r; - - { - add_label_to_grid_bag_sizer (grid, _dcp_panel, _("Frame Rate"), true, wxGBPosition (r, 0)); - _frame_rate_sizer = new wxBoxSizer (wxHORIZONTAL); - _frame_rate_choice = new wxChoice (_dcp_panel, wxID_ANY); - _frame_rate_sizer->Add (_frame_rate_choice, 1, wxALIGN_CENTER_VERTICAL); - _frame_rate_spin = new wxSpinCtrl (_dcp_panel, wxID_ANY); - _frame_rate_sizer->Add (_frame_rate_spin, 1, wxALIGN_CENTER_VERTICAL); - setup_frame_rate_widget (); - _best_frame_rate = new wxButton (_dcp_panel, wxID_ANY, _("Use best")); - _frame_rate_sizer->Add (_best_frame_rate, 1, wxALIGN_CENTER_VERTICAL | wxEXPAND); - grid->Add (_frame_rate_sizer, wxGBPosition (r, 1)); - } - ++r; - - _signed = new wxCheckBox (_dcp_panel, wxID_ANY, _("Signed")); - grid->Add (_signed, wxGBPosition (r, 0), wxGBSpan (1, 2)); - ++r; - - _encrypted = new wxCheckBox (_dcp_panel, wxID_ANY, _("Encrypted")); - grid->Add (_encrypted, wxGBPosition (r, 0), wxGBSpan (1, 2)); - ++r; - - add_label_to_grid_bag_sizer (grid, _dcp_panel, _("Audio channels"), true, wxGBPosition (r, 0)); - _audio_channels = new wxSpinCtrl (_dcp_panel, wxID_ANY); - grid->Add (_audio_channels, wxGBPosition (r, 1)); - ++r; - - _three_d = new wxCheckBox (_dcp_panel, wxID_ANY, _("3D")); - grid->Add (_three_d, wxGBPosition (r, 0), wxGBSpan (1, 2)); - ++r; - - add_label_to_grid_bag_sizer (grid, _dcp_panel, _("Resolution"), true, wxGBPosition (r, 0)); - _resolution = new wxChoice (_dcp_panel, wxID_ANY); - grid->Add (_resolution, wxGBPosition (r, 1)); - ++r; - - { - add_label_to_grid_bag_sizer (grid, _dcp_panel, _("JPEG2000 bandwidth"), true, wxGBPosition (r, 0)); - wxSizer* s = new wxBoxSizer (wxHORIZONTAL); - _j2k_bandwidth = new wxSpinCtrl (_dcp_panel, wxID_ANY); - s->Add (_j2k_bandwidth, 1); - add_label_to_sizer (s, _dcp_panel, _("Mbit/s"), false); - grid->Add (s, wxGBPosition (r, 1)); - } - ++r; - - add_label_to_grid_bag_sizer (grid, _dcp_panel, _("Standard"), true, wxGBPosition (r, 0)); - _standard = new wxChoice (_dcp_panel, wxID_ANY); - grid->Add (_standard, wxGBPosition (r, 1), wxDefaultSpan, wxALIGN_CENTER_VERTICAL); - ++r; - - add_label_to_grid_bag_sizer (grid, _dcp_panel, _("Scaler"), true, wxGBPosition (r, 0)); - _scaler = new wxChoice (_dcp_panel, wxID_ANY); - grid->Add (_scaler, wxGBPosition (r, 1), wxDefaultSpan, wxALIGN_CENTER_VERTICAL); - ++r; - - vector const sc = Scaler::all (); - for (vector::const_iterator i = sc.begin(); i != sc.end(); ++i) { - _scaler->Append (std_to_wx ((*i)->name())); - } - - vector const ratio = Ratio::all (); - for (vector::const_iterator i = ratio.begin(); i != ratio.end(); ++i) { - _container->Append (std_to_wx ((*i)->nickname ())); - } - - vector const ct = DCPContentType::all (); - for (vector::const_iterator i = ct.begin(); i != ct.end(); ++i) { - _dcp_content_type->Append (std_to_wx ((*i)->pretty_name ())); - } - - list const dfr = Config::instance()->allowed_dcp_frame_rates (); - for (list::const_iterator i = dfr.begin(); i != dfr.end(); ++i) { - _frame_rate_choice->Append (std_to_wx (boost::lexical_cast (*i))); - } - - _audio_channels->SetRange (0, MAX_DCP_AUDIO_CHANNELS); - _j2k_bandwidth->SetRange (1, Config::instance()->maximum_j2k_bandwidth() / 1000000); - _frame_rate_spin->SetRange (1, 480); - - _resolution->Append (_("2K")); - _resolution->Append (_("4K")); - - _standard->Append (_("SMPTE")); - _standard->Append (_("Interop")); -} - -void -FilmEditor::connect_to_widgets () -{ - _name->Bind (wxEVT_COMMAND_TEXT_UPDATED, boost::bind (&FilmEditor::name_changed, this)); - _use_isdcf_name->Bind (wxEVT_COMMAND_CHECKBOX_CLICKED, boost::bind (&FilmEditor::use_isdcf_name_toggled, this)); - _edit_isdcf_button->Bind(wxEVT_COMMAND_BUTTON_CLICKED, boost::bind (&FilmEditor::edit_isdcf_button_clicked, this)); - _container->Bind (wxEVT_COMMAND_CHOICE_SELECTED, boost::bind (&FilmEditor::container_changed, this)); - _content->Bind (wxEVT_COMMAND_LIST_ITEM_SELECTED, boost::bind (&FilmEditor::content_selection_changed, this)); - _content->Bind (wxEVT_COMMAND_LIST_ITEM_DESELECTED, boost::bind (&FilmEditor::content_selection_changed, this)); - _content->Bind (wxEVT_COMMAND_LIST_ITEM_RIGHT_CLICK, boost::bind (&FilmEditor::content_right_click, this, _1)); - _content->Bind (wxEVT_DROP_FILES, boost::bind (&FilmEditor::content_files_dropped, this, _1)); - _content_add_file->Bind (wxEVT_COMMAND_BUTTON_CLICKED, boost::bind (&FilmEditor::content_add_file_clicked, this)); - _content_add_folder->Bind (wxEVT_COMMAND_BUTTON_CLICKED, boost::bind (&FilmEditor::content_add_folder_clicked, this)); - _content_remove->Bind (wxEVT_COMMAND_BUTTON_CLICKED, boost::bind (&FilmEditor::content_remove_clicked, this)); - _content_earlier->Bind (wxEVT_COMMAND_BUTTON_CLICKED, boost::bind (&FilmEditor::content_earlier_clicked, this)); - _content_later->Bind (wxEVT_COMMAND_BUTTON_CLICKED, boost::bind (&FilmEditor::content_later_clicked, this)); - _content_timeline->Bind (wxEVT_COMMAND_BUTTON_CLICKED, boost::bind (&FilmEditor::content_timeline_clicked, this)); - _scaler->Bind (wxEVT_COMMAND_CHOICE_SELECTED, boost::bind (&FilmEditor::scaler_changed, this)); - _dcp_content_type->Bind (wxEVT_COMMAND_CHOICE_SELECTED, boost::bind (&FilmEditor::dcp_content_type_changed, this)); - _frame_rate_choice->Bind(wxEVT_COMMAND_CHOICE_SELECTED, boost::bind (&FilmEditor::frame_rate_choice_changed, this)); - _frame_rate_spin->Bind (wxEVT_COMMAND_SPINCTRL_UPDATED, boost::bind (&FilmEditor::frame_rate_spin_changed, this)); - _best_frame_rate->Bind (wxEVT_COMMAND_BUTTON_CLICKED, boost::bind (&FilmEditor::best_frame_rate_clicked, this)); - _signed->Bind (wxEVT_COMMAND_CHECKBOX_CLICKED, boost::bind (&FilmEditor::signed_toggled, this)); - _encrypted->Bind (wxEVT_COMMAND_CHECKBOX_CLICKED, boost::bind (&FilmEditor::encrypted_toggled, this)); - _audio_channels->Bind (wxEVT_COMMAND_SPINCTRL_UPDATED, boost::bind (&FilmEditor::audio_channels_changed, this)); - _j2k_bandwidth->Bind (wxEVT_COMMAND_SPINCTRL_UPDATED, boost::bind (&FilmEditor::j2k_bandwidth_changed, this)); - _resolution->Bind (wxEVT_COMMAND_CHOICE_SELECTED, boost::bind (&FilmEditor::resolution_changed, this)); - _three_d->Bind (wxEVT_COMMAND_CHECKBOX_CLICKED, boost::bind (&FilmEditor::three_d_changed, this)); - _standard->Bind (wxEVT_COMMAND_CHOICE_SELECTED, boost::bind (&FilmEditor::standard_changed, this)); -} - -void -FilmEditor::make_content_panel () -{ - _content_panel = new wxPanel (_main_notebook); - _content_sizer = new wxBoxSizer (wxVERTICAL); - _content_panel->SetSizer (_content_sizer); - - { - wxBoxSizer* s = new wxBoxSizer (wxHORIZONTAL); - - _content = new wxListCtrl (_content_panel, wxID_ANY, wxDefaultPosition, wxSize (320, 160), wxLC_REPORT | wxLC_NO_HEADER); - s->Add (_content, 1, wxEXPAND | wxTOP | wxBOTTOM, 6); - - _content->InsertColumn (0, wxT("")); - _content->SetColumnWidth (0, 512); - - wxBoxSizer* b = new wxBoxSizer (wxVERTICAL); - - _content_add_file = new wxButton (_content_panel, wxID_ANY, _("Add file(s)...")); - _content_add_file->SetToolTip (_("Add video, image or sound files to the film.")); - b->Add (_content_add_file, 0, wxEXPAND | wxALL, DCPOMATIC_BUTTON_STACK_GAP); - - _content_add_folder = new wxButton (_content_panel, wxID_ANY, _("Add image\nsequence...")); - _content_add_folder->SetToolTip (_("Add a directory of image files which will be used as a moving image sequence.")); - b->Add (_content_add_folder, 1, wxEXPAND | wxALL, DCPOMATIC_BUTTON_STACK_GAP); - - _content_remove = new wxButton (_content_panel, wxID_ANY, _("Remove")); - _content_remove->SetToolTip (_("Remove the selected piece of content from the film.")); - b->Add (_content_remove, 0, wxEXPAND | wxALL, DCPOMATIC_BUTTON_STACK_GAP); - - _content_earlier = new wxButton (_content_panel, wxID_ANY, _("Up")); - _content_earlier->SetToolTip (_("Move the selected piece of content earlier in the film.")); - b->Add (_content_earlier, 0, wxEXPAND | wxALL, DCPOMATIC_BUTTON_STACK_GAP); - - _content_later = new wxButton (_content_panel, wxID_ANY, _("Down")); - _content_later->SetToolTip (_("Move the selected piece of content later in the film.")); - b->Add (_content_later, 0, wxEXPAND | wxALL, DCPOMATIC_BUTTON_STACK_GAP); - - _content_timeline = new wxButton (_content_panel, wxID_ANY, _("Timeline...")); - _content_timeline->SetToolTip (_("Open the timeline for the film.")); - b->Add (_content_timeline, 0, wxEXPAND | wxALL, DCPOMATIC_BUTTON_STACK_GAP); - - s->Add (b, 0, wxALL, 4); - - _content_sizer->Add (s, 0, wxEXPAND | wxALL, 6); - } - - _content_notebook = new wxNotebook (_content_panel, wxID_ANY); - _content_sizer->Add (_content_notebook, 1, wxEXPAND | wxTOP, 6); - - _video_panel = new VideoPanel (this); - _panels.push_back (_video_panel); - _audio_panel = new AudioPanel (this); - _panels.push_back (_audio_panel); - _subtitle_panel = new SubtitlePanel (this); - _panels.push_back (_subtitle_panel); - _timing_panel = new TimingPanel (this); - _panels.push_back (_timing_panel); - - _content->DragAcceptFiles (true); -} - -/** Called when the name widget has been changed */ -void -FilmEditor::name_changed () -{ - if (!_film) { - return; - } - - _film->set_name (string (_name->GetValue().mb_str())); -} - -void -FilmEditor::j2k_bandwidth_changed () -{ - if (!_film) { - return; - } - - _film->set_j2k_bandwidth (_j2k_bandwidth->GetValue() * 1000000); -} - -void -FilmEditor::signed_toggled () -{ - if (!_film) { - return; - } - - _film->set_signed (_signed->GetValue ()); -} - -void -FilmEditor::encrypted_toggled () -{ - if (!_film) { - return; - } - - _film->set_encrypted (_encrypted->GetValue ()); -} - -/** Called when the frame rate choice widget has been changed */ -void -FilmEditor::frame_rate_choice_changed () -{ - if (!_film) { - return; - } - - _film->set_video_frame_rate ( - boost::lexical_cast ( - wx_to_std (_frame_rate_choice->GetString (_frame_rate_choice->GetSelection ())) - ) - ); -} - -/** Called when the frame rate spin widget has been changed */ -void -FilmEditor::frame_rate_spin_changed () -{ - if (!_film) { - return; - } - - _film->set_video_frame_rate (_frame_rate_spin->GetValue ()); -} - -void -FilmEditor::audio_channels_changed () -{ - if (!_film) { - return; - } - - _film->set_audio_channels (_audio_channels->GetValue ()); -} - -void -FilmEditor::resolution_changed () -{ - if (!_film) { - return; - } - - _film->set_resolution (_resolution->GetSelection() == 0 ? RESOLUTION_2K : RESOLUTION_4K); } -void -FilmEditor::standard_changed () -{ - if (!_film) { - return; - } - - _film->set_interop (_standard->GetSelection() == 1); -} /** Called when the metadata stored in the Film object has changed; * so that we can update the GUI. diff --cc src/wx/po/de_DE.po index d7353e914,4b8b1fdf1..df095e8ce --- a/src/wx/po/de_DE.po +++ b/src/wx/po/de_DE.po @@@ -110,11 -114,17 +119,17 @@@ msgstr " msgid "Add file(s)..." msgstr "Datei(en) hinzufügen..." - #: src/wx/content_panel.cc:69 - msgid "Add folder..." - msgstr "Ordner hinzufügen..." + #: src/wx/film_editor.cc:284 + msgid "" + "Add image\n" + "sequence..." + msgstr "" + + #: src/wx/film_editor.cc:281 + msgid "Add video, image or sound files to the film." + msgstr "" -#: src/wx/editable_list.h:62 +#: src/wx/config_dialog.cc:597 src/wx/editable_list.h:62 msgid "Add..." msgstr "Hinzufügen..." @@@ -799,18 -765,10 +835,22 @@@ msgstr "Kein msgid "Off" msgstr "Aus" +#: src/wx/config_dialog.cc:1167 +msgid "Open console window" +msgstr "" + +#: src/wx/make_signer_chain_dialog.cc:25 +msgid "Organisation" +msgstr "" + +#: src/wx/make_signer_chain_dialog.cc:27 +msgid "Organisational unit" +msgstr "" + + #: src/wx/film_editor.cc:301 + msgid "Open the timeline for the film." + msgstr "" + #: src/wx/screen_dialog.cc:65 msgid "Other" msgstr "Andere" @@@ -1358,24 -1256,9 +1406,6 @@@ msgstr "mal msgid "video" msgstr "Bild" - #~ msgid "1 channel" - #~ msgstr "1 Kanal" - - #~ msgid "Audio channels" - #~ msgstr "Ton Kanäle" - - #~ msgid "Could not decode video for view (%s)" - #~ msgstr "Bild konnte nicht zur Vorschau dekodiert werden (%s)" - - #~ msgid "Hz" - #~ msgstr "Hz" - - #~ msgid "With Subtitles" - #~ msgstr "Mit Untertitelung" - - #~ msgid "channels" - #~ msgstr "Kanäle" -#~ msgid "Add folder..." -#~ msgstr "Ordner hinzufügen..." -- #~ msgid "Default creator" #~ msgstr "Standard 'creator' (DCI)" diff --cc src/wx/po/es_ES.po index 0191fc503,6aea49f52..415d539a1 --- a/src/wx/po/es_ES.po +++ b/src/wx/po/es_ES.po @@@ -111,11 -115,17 +120,17 @@@ msgstr " msgid "Add file(s)..." msgstr "Añadir fichero(s)..." - #: src/wx/content_panel.cc:69 - msgid "Add folder..." - msgstr "Añadir carpeta..." + #: src/wx/film_editor.cc:284 + msgid "" + "Add image\n" + "sequence..." + msgstr "" + + #: src/wx/film_editor.cc:281 + msgid "Add video, image or sound files to the film." + msgstr "" -#: src/wx/editable_list.h:62 +#: src/wx/config_dialog.cc:597 src/wx/editable_list.h:62 msgid "Add..." msgstr "Añadir..." @@@ -806,19 -772,10 +842,23 @@@ msgstr "Ninguno msgid "Off" msgstr "Off" +#: src/wx/config_dialog.cc:1167 +msgid "Open console window" +msgstr "" + +#: src/wx/make_signer_chain_dialog.cc:25 +#, fuzzy +msgid "Organisation" +msgstr "Duración" + +#: src/wx/make_signer_chain_dialog.cc:27 +msgid "Organisational unit" +msgstr "" + + #: src/wx/film_editor.cc:301 + msgid "Open the timeline for the film." + msgstr "" + #: src/wx/screen_dialog.cc:65 msgid "Other" msgstr "Otros" @@@ -1376,24 -1272,9 +1424,6 @@@ msgstr "veces msgid "video" msgstr "vídeo" - #~ msgid "1 channel" - #~ msgstr "1 canal" - - #~ msgid "Audio channels" - #~ msgstr "Canales de audio" - - #~ msgid "Could not decode video for view (%s)" - #~ msgstr "No se pudo decodificar el vídeo para mostrarlo (%s)" - - #~ msgid "Hz" - #~ msgstr "Hz" - - #~ msgid "With Subtitles" - #~ msgstr "Con subtítulos" - - #~ msgid "channels" - #~ msgstr "canales" -#~ msgid "Add folder..." -#~ msgstr "Añadir carpeta..." -- #~ msgid "Default creator" #~ msgstr "Creador por defecto" diff --cc src/wx/po/fr_FR.po index 46c4822d6,a4d26fd01..0ba92f95b --- a/src/wx/po/fr_FR.po +++ b/src/wx/po/fr_FR.po @@@ -110,11 -114,17 +119,17 @@@ msgstr " msgid "Add file(s)..." msgstr "Ajout fichier(s)..." - #: src/wx/content_panel.cc:69 - msgid "Add folder..." - msgstr "Ajout dossier..." + #: src/wx/film_editor.cc:284 + msgid "" + "Add image\n" + "sequence..." + msgstr "" + + #: src/wx/film_editor.cc:281 + msgid "Add video, image or sound files to the film." + msgstr "" -#: src/wx/editable_list.h:62 +#: src/wx/config_dialog.cc:597 src/wx/editable_list.h:62 msgid "Add..." msgstr "Ajouter..." @@@ -798,19 -765,10 +835,23 @@@ msgstr "Aucun msgid "Off" msgstr "Eteint" +#: src/wx/config_dialog.cc:1167 +msgid "Open console window" +msgstr "" + +#: src/wx/make_signer_chain_dialog.cc:25 +#, fuzzy +msgid "Organisation" +msgstr "Durée" + +#: src/wx/make_signer_chain_dialog.cc:27 +msgid "Organisational unit" +msgstr "" + + #: src/wx/film_editor.cc:301 + msgid "Open the timeline for the film." + msgstr "" + #: src/wx/screen_dialog.cc:65 msgid "Other" msgstr "Autre" @@@ -1359,24 -1256,9 +1408,6 @@@ msgstr "fois msgid "video" msgstr "vidéo" - #~ msgid "1 channel" - #~ msgstr "1 canal" - - #~ msgid "Audio channels" - #~ msgstr "Canaux audios" - - #~ msgid "Could not decode video for view (%s)" - #~ msgstr "Décodage de la vidéo pour visualisation impossible (%s)" - - #~ msgid "Hz" - #~ msgstr "Hz" - - #~ msgid "With Subtitles" - #~ msgstr "Avec sous-titres" - - #~ msgid "channels" - #~ msgstr "canaux" -#~ msgid "Add folder..." -#~ msgstr "Ajout dossier..." -- #~ msgid "Default creator" #~ msgstr "Créateur par défaut" diff --cc src/wx/po/it_IT.po index 35cb8db88,9dcce02d1..875be0ddf --- a/src/wx/po/it_IT.po +++ b/src/wx/po/it_IT.po @@@ -109,11 -113,17 +118,17 @@@ msgstr " msgid "Add file(s)..." msgstr "Aggiungi File" - #: src/wx/content_panel.cc:69 - msgid "Add folder..." - msgstr "Aggiungi cartella" + #: src/wx/film_editor.cc:284 + msgid "" + "Add image\n" + "sequence..." + msgstr "" + + #: src/wx/film_editor.cc:281 + msgid "Add video, image or sound files to the film." + msgstr "" -#: src/wx/editable_list.h:62 +#: src/wx/config_dialog.cc:597 src/wx/editable_list.h:62 msgid "Add..." msgstr "Aggiungi..." @@@ -815,19 -782,10 +852,23 @@@ msgstr "Nessuno msgid "Off" msgstr "" +#: src/wx/config_dialog.cc:1167 +msgid "Open console window" +msgstr "" + +#: src/wx/make_signer_chain_dialog.cc:25 +#, fuzzy +msgid "Organisation" +msgstr "Durata" + +#: src/wx/make_signer_chain_dialog.cc:27 +msgid "Organisational unit" +msgstr "" + + #: src/wx/film_editor.cc:301 + msgid "Open the timeline for the film." + msgstr "" + #: src/wx/screen_dialog.cc:65 msgid "Other" msgstr "" @@@ -1387,24 -1285,9 +1436,6 @@@ msgstr " msgid "video" msgstr "Video" - #~ msgid "1 channel" - #~ msgstr "1 canale" - - #~ msgid "Audio channels" - #~ msgstr "Canali audio" - - #~ msgid "Could not decode video for view (%s)" - #~ msgstr "Non posso decodificare il video per guardarlo (%s)" - - #~ msgid "Hz" - #~ msgstr "Hz" - - #~ msgid "With Subtitles" - #~ msgstr "Con sottotitoli" - - #~ msgid "channels" - #~ msgstr "canali" -#~ msgid "Add folder..." -#~ msgstr "Aggiungi cartella" -- #, fuzzy #~ msgid "Default creator" #~ msgstr "Contenitore predefinito" diff --cc src/wx/po/nl_NL.po index e792f84be,509179bfb..c4d3a7c2b --- a/src/wx/po/nl_NL.po +++ b/src/wx/po/nl_NL.po @@@ -110,11 -114,17 +119,17 @@@ msgstr " msgid "Add file(s)..." msgstr "Voeg bestande(n) toe..." - #: src/wx/content_panel.cc:69 - msgid "Add folder..." - msgstr "Voeg map toe..." + #: src/wx/film_editor.cc:284 + msgid "" + "Add image\n" + "sequence..." + msgstr "" + + #: src/wx/film_editor.cc:281 + msgid "Add video, image or sound files to the film." + msgstr "" -#: src/wx/editable_list.h:62 +#: src/wx/config_dialog.cc:597 src/wx/editable_list.h:62 msgid "Add..." msgstr "Toevoegen.." @@@ -808,18 -774,10 +844,22 @@@ msgstr "Geen msgid "Off" msgstr "Uit" +#: src/wx/config_dialog.cc:1167 +msgid "Open console window" +msgstr "" + +#: src/wx/make_signer_chain_dialog.cc:25 +msgid "Organisation" +msgstr "" + +#: src/wx/make_signer_chain_dialog.cc:27 +msgid "Organisational unit" +msgstr "" + + #: src/wx/film_editor.cc:301 + msgid "Open the timeline for the film." + msgstr "" + #: src/wx/screen_dialog.cc:65 msgid "Other" msgstr "Andere" @@@ -1366,24 -1264,9 +1414,6 @@@ msgstr "tijden msgid "video" msgstr "video" - #~ msgid "1 channel" - #~ msgstr "1 channel" - - #~ msgid "Audio channels" - #~ msgstr "Audio kanalen" - - #~ msgid "Could not decode video for view (%s)" - #~ msgstr "Kan video niet decoderen voor preview (%s)" - - #~ msgid "Hz" - #~ msgstr "Hz" - - #~ msgid "With Subtitles" - #~ msgstr "Met ondertiteling" - - #~ msgid "channels" - #~ msgstr "kanalen" -#~ msgid "Add folder..." -#~ msgstr "Voeg map toe..." -- #~ msgid "Default creator" #~ msgstr "Standaard maker" diff --cc src/wx/po/sv_SE.po index 441643cce,5670fc4cb..e52360abd --- a/src/wx/po/sv_SE.po +++ b/src/wx/po/sv_SE.po @@@ -111,11 -115,17 +120,17 @@@ msgstr " msgid "Add file(s)..." msgstr "Lägg till fil(er)..." - #: src/wx/content_panel.cc:69 - msgid "Add folder..." - msgstr "Lägg till folder..." + #: src/wx/film_editor.cc:284 + msgid "" + "Add image\n" + "sequence..." + msgstr "" + + #: src/wx/film_editor.cc:281 + msgid "Add video, image or sound files to the film." + msgstr "" -#: src/wx/editable_list.h:62 +#: src/wx/config_dialog.cc:597 src/wx/editable_list.h:62 msgid "Add..." msgstr "Lägg till..." @@@ -783,8 -747,16 +812,16 @@@ msgstr "JPEG2000-bandbredd msgid "Mbit/s" msgstr "" + #: src/wx/film_editor.cc:293 + msgid "Move the selected piece of content earlier in the film." + msgstr "" + + #: src/wx/film_editor.cc:297 + msgid "Move the selected piece of content later in the film." + msgstr "" + # LÃ¥ter mysko -#: src/wx/video_panel.cc:280 +#: src/wx/video_panel.cc:301 msgid "Multiple content selected" msgstr "Flera innehÃ¥ll valda" @@@ -826,19 -793,10 +863,23 @@@ msgstr "Inget msgid "Off" msgstr "Av" +#: src/wx/config_dialog.cc:1167 +msgid "Open console window" +msgstr "" + +#: src/wx/make_signer_chain_dialog.cc:25 +#, fuzzy +msgid "Organisation" +msgstr "Längd" + +#: src/wx/make_signer_chain_dialog.cc:27 +msgid "Organisational unit" +msgstr "" + + #: src/wx/film_editor.cc:301 + msgid "Open the timeline for the film." + msgstr "" + #: src/wx/screen_dialog.cc:65 msgid "Other" msgstr "" diff --cc src/wx/timeline.cc index 13baef6b7,2e368e57d..556e6f1b3 --- a/src/wx/timeline.cc +++ b/src/wx/timeline.cc @@@ -712,22 -644,19 +712,22 @@@ Timeline::set_position_from_event (wxMo { /* Snap starts to ends */ - Time const d = abs (cv->content()->end() - new_position); + DCPTime const d = DCPTime (cv->content()->end() - new_position).abs (); if (first || d < nearest_distance) { nearest_distance = d; - nearest_new_position = cv->content()->end(); - nearest_new_position = cv->content()->end() + 1; ++ nearest_new_position = cv->content()->end() + DCPTime::delta (); } } { /* Snap ends to starts */ - Time const d = abs (cv->content()->position() - (new_position + _down_view->content()->length_after_trim())); + DCPTime const d = DCPTime ( + cv->content()->position() - (new_position + _down_view->content()->length_after_trim()) + ).abs (); + if (d < nearest_distance) { nearest_distance = d; - nearest_new_position = cv->content()->position() - _down_view->content()->length_after_trim (); - nearest_new_position = cv->content()->position() - _down_view->content()->length_after_trim () - 1; ++ nearest_new_position = cv->content()->position() - _down_view->content()->length_after_trim () - DCPTime::delta(); } } diff --cc src/wx/timeline_dialog.cc index 8ac90b8de,bc3e8db99..2da375ecd --- a/src/wx/timeline_dialog.cc +++ b/src/wx/timeline_dialog.cc @@@ -29,9 -28,10 +29,10 @@@ using std::list using std::cout; using boost::shared_ptr; -TimelineDialog::TimelineDialog (FilmEditor* ed, shared_ptr film) - : wxDialog (ed, wxID_ANY, _("Timeline"), wxDefaultPosition, wxSize (640, 512), wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER | wxFULL_REPAINT_ON_RESIZE) +TimelineDialog::TimelineDialog (ContentPanel* cp, shared_ptr film) + : wxDialog (cp->panel(), wxID_ANY, _("Timeline"), wxDefaultPosition, wxSize (640, 512), wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER | wxFULL_REPAINT_ON_RESIZE) + , _film (film) - , _timeline (this, ed, film) + , _timeline (this, cp, film) { wxBoxSizer* sizer = new wxBoxSizer (wxVERTICAL); diff --cc src/wx/video_panel.cc index a8510cbba,eb0b812a5..569da6c8b --- a/src/wx/video_panel.cc +++ b/src/wx/video_panel.cc @@@ -150,25 -139,42 +150,26 @@@ VideoPanel::VideoPanel (ContentPanel* p &index_to_scale, &scale_to_index ); - _scale->add (grid, wxGBPosition (r, 1)); + _scale->add (grid, wxGBPosition (r, 1), wxGBSpan (1, 2)); ++r; - { - add_label_to_grid_bag_sizer (grid, this, _("Filters"), true, wxGBPosition (r, 0)); - wxSizer* s = new wxBoxSizer (wxHORIZONTAL); - - wxClientDC dc (this); - wxSize size = dc.GetTextExtent (wxT ("A quite long-ish name")); - size.SetHeight (-1); - - _filters = new wxStaticText (this, wxID_ANY, _("None"), wxDefaultPosition, size); - s->Add (_filters, 1, wxEXPAND | wxALIGN_CENTER_VERTICAL | wxTOP | wxBOTTOM | wxRIGHT, 6); - _filters_button = new wxButton (this, wxID_ANY, _("Edit...")); - s->Add (_filters_button, 0, wxALIGN_CENTER_VERTICAL); - grid->Add (s, wxGBPosition (r, 1), wxDefaultSpan, wxALIGN_CENTER_VERTICAL); - } + wxClientDC dc (this); + wxSize size = dc.GetTextExtent (wxT ("A quite long name")); + size.SetHeight (-1); + + add_label_to_grid_bag_sizer (grid, this, _("Filters"), true, wxGBPosition (r, 0)); + _filters = new wxStaticText (this, wxID_ANY, _("None"), wxDefaultPosition, size); + grid->Add (_filters, wxGBPosition (r, 1), wxGBSpan (1, 2), wxALIGN_CENTER_VERTICAL); + _filters_button = new wxButton (this, wxID_ANY, _("Edit...")); + grid->Add (_filters_button, wxGBPosition (r, 3), wxDefaultSpan, wxALIGN_CENTER_VERTICAL); ++r; - add_label_to_grid_bag_sizer (grid, this, _("Colour conversion"), true, wxGBPosition (r, 0)); - { - _enable_colour_conversion = new wxCheckBox (this, wxID_ANY, _("Colour conversion")); - grid->Add (_enable_colour_conversion, wxGBPosition (r, 0), wxDefaultSpan, wxALIGN_CENTER_VERTICAL); - - wxSizer* s = new wxBoxSizer (wxHORIZONTAL); - - wxClientDC dc (this); - wxSize size = dc.GetTextExtent (wxT ("A quite long-ish name")); - size.SetHeight (-1); - - _colour_conversion = new wxStaticText (this, wxID_ANY, wxT (""), wxDefaultPosition, size); - - s->Add (_colour_conversion, 1, wxEXPAND | wxALIGN_CENTER_VERTICAL | wxTOP | wxBOTTOM | wxRIGHT, 6); - _colour_conversion_button = new wxButton (this, wxID_ANY, _("Edit...")); - s->Add (_colour_conversion_button, 0, wxALIGN_CENTER_VERTICAL); - grid->Add (s, wxGBPosition (r, 1), wxDefaultSpan, wxALIGN_CENTER_VERTICAL); - } ++ _enable_colour_conversion = new wxCheckBox (this, wxID_ANY, _("Colour conversion")); ++ grid->Add (_enable_colour_conversion, wxGBPosition (r, 0), wxDefaultSpan, wxALIGN_CENTER_VERTICAL); + _colour_conversion = new wxStaticText (this, wxID_ANY, wxT (""), wxDefaultPosition, size); + grid->Add (_colour_conversion, wxGBPosition (r, 1), wxGBSpan (1, 2), wxALIGN_CENTER_VERTICAL); + _colour_conversion_button = new wxButton (this, wxID_ANY, _("Edit...")); + grid->Add (_colour_conversion_button, wxGBPosition (r, 3), wxDefaultSpan, wxALIGN_CENTER_VERTICAL); ++r; _description = new wxStaticText (this, wxID_ANY, wxT ("\n \n \n \n \n"), wxDefaultPosition, wxDefaultSize); @@@ -197,10 -203,8 +198,11 @@@ _frame_type->wrapped()->Append (_("3D left only")); _frame_type->wrapped()->Append (_("3D right only")); + _fade_in->Changed.connect (boost::bind (&VideoPanel::fade_in_changed, this)); + _fade_out->Changed.connect (boost::bind (&VideoPanel::fade_out_changed, this)); + _filters_button->Bind (wxEVT_COMMAND_BUTTON_CLICKED, boost::bind (&VideoPanel::edit_filters_clicked, this)); + _enable_colour_conversion->Bind (wxEVT_COMMAND_CHECKBOX_CLICKED, boost::bind (&VideoPanel::enable_colour_conversion_clicked, this)); _colour_conversion_button->Bind (wxEVT_COMMAND_BUTTON_CLICKED, boost::bind (&VideoPanel::edit_colour_conversion_clicked, this)); } @@@ -407,20 -403,17 +425,35 @@@ VideoPanel::content_selection_changed ( film_content_changed (FFmpegContentProperty::FILTERS); } +void +VideoPanel::fade_in_changed () +{ + VideoContentList vc = _parent->selected_video (); + for (VideoContentList::const_iterator i = vc.begin(); i != vc.end(); ++i) { + (*i)->set_fade_in (_fade_in->get (_parent->film()->video_frame_rate ())); + } +} + +void +VideoPanel::fade_out_changed () +{ + VideoContentList vc = _parent->selected_video (); + for (VideoContentList::const_iterator i = vc.begin(); i != vc.end(); ++i) { + (*i)->set_fade_out (_fade_out->get (_parent->film()->video_frame_rate ())); + } +} ++ + void + VideoPanel::enable_colour_conversion_clicked () + { - VideoContentList vc = _editor->selected_video_content (); ++ VideoContentList vc = _parent->selected_video (); + if (vc.size() != 1) { + return; + } + + if (_enable_colour_conversion->GetValue()) { + vc.front()->set_default_colour_conversion (); + } else { + vc.front()->unset_colour_conversion (); + } + } diff --cc src/wx/video_panel.h index aa0c6ed53,16ecb7e2e..28d6aa4bb --- a/src/wx/video_panel.h +++ b/src/wx/video_panel.h @@@ -45,9 -37,8 +45,10 @@@ public private: void edit_filters_clicked (); + void enable_colour_conversion_clicked (); void edit_colour_conversion_clicked (); + void fade_in_changed (); + void fade_out_changed (); void setup_description ();