From: Carl Hetherington Date: Wed, 4 Jun 2014 11:33:41 +0000 (+0100) Subject: Merge master. X-Git-Tag: v2.0.48~804 X-Git-Url: https://main.carlh.net/gitweb/?p=dcpomatic.git;a=commitdiff_plain;h=8102046b2f29e0c7b234c29bf204b056cb30e64f Merge master. --- 8102046b2f29e0c7b234c29bf204b056cb30e64f diff --cc ChangeLog index e31fc719e,a0e776b0e..78954c82d --- a/ChangeLog +++ b/ChangeLog @@@ -1,7 -1,25 +1,29 @@@ +2014-03-07 Carl Hetherington + + * Add subtitle view. + + 2014-06-03 Carl Hetherington + + * Fix bad resampling of separate sound file sources that + have specified video frame rates. + + * Version 1.69.20 released. + + 2014-06-03 Carl Hetherington + + * Re-calculate and update audio plots when the mapping is changed. + + * Change the -3dB preset to -6dB since we are talking about + amplitude, not power. + + * Version 1.69.19 released. + + 2014-06-02 Carl Hetherington + + * Empirical hack to prevent over-read of array + by libswscale; may fix crashes at the start of + DCP encodes. + 2014-05-29 Carl Hetherington * Version 1.69.18 released. diff --cc src/lib/audio_mapping.cc index 7d7e9f828,e35c1ae94..b3757c5f1 --- a/src/lib/audio_mapping.cc +++ b/src/lib/audio_mapping.cc @@@ -19,9 -19,10 +19,10 @@@ #include #include -#include +#include #include "audio_mapping.h" #include "util.h" + #include "md5_digester.h" using std::list; using std::cout; diff --cc src/lib/dcp_video_frame.cc index 1aae64ac7,09b909696..4054f05cd --- a/src/lib/dcp_video_frame.cc +++ b/src/lib/dcp_video_frame.cc @@@ -42,13 -42,13 +42,12 @@@ #include #include #include -#include -#include -#include -#include -#include -#include -#include +#include - #include +#include +#include +#include +#include +#include #include #include "film.h" #include "dcp_video_frame.h" diff --cc src/lib/image.cc index d4ec6f99a,8a8fb1c7b..8e7a51fd8 --- a/src/lib/image.cc +++ b/src/lib/image.cc @@@ -31,8 -30,7 +30,9 @@@ extern "C" #include "image.h" #include "exceptions.h" #include "scaler.h" +#include "timer.h" +#include "rect.h" + #include "md5_digester.h" #include "i18n.h" @@@ -668,20 -629,12 +673,11 @@@ merge (list images string Image::digest () const { - MD5_CTX md5_context; - MD5_Init (&md5_context); + MD5Digester digester; for (int i = 0; i < components(); ++i) { - MD5_Update (&md5_context, data()[i], line_size()[i]); - } - - unsigned char digest[MD5_DIGEST_LENGTH]; - MD5_Final (digest, &md5_context); - - stringstream s; - for (int i = 0; i < MD5_DIGEST_LENGTH; ++i) { - s << std::hex << std::setfill('0') << std::setw(2) << ((int) digest[i]); + digester.add (data()[i], line_size()[i]); } - return s.str (); + return digester.get (); } - diff --cc src/lib/player.cc index 77def1e60,68df8ea70..c3489b7e1 --- a/src/lib/player.cc +++ b/src/lib/player.cc @@@ -191,97 -269,79 +191,98 @@@ Player::content_changed (weak_ptr weak_piece, shared_ptr audio, AudioContent::Frame frame, bool already_resampled) +Player::playlist_changed () { - shared_ptr piece = weak_piece.lock (); - if (!piece) { - return; - } + _have_valid_pieces = false; + Changed (false); +} - shared_ptr content = dynamic_pointer_cast (piece->content); - assert (content); +void +Player::set_video_container_size (dcp::Size s) +{ + _video_container_size = s; - if (!already_resampled) { - /* Gain */ - if (content->audio_gain() != 0) { - shared_ptr gain (new AudioBuffers (audio)); - gain->apply_gain (content->audio_gain ()); - audio = gain; - } - - /* Resample */ - if (content->content_audio_frame_rate() != content->output_audio_frame_rate()) { - shared_ptr r = resampler (content, true); - pair, AudioContent::Frame> ro = r->run (audio, frame); - audio = ro.first; - frame = ro.second; - } - } - - Time const relative_time = _film->audio_frames_to_time (frame); + _black_image.reset (new Image (PIX_FMT_RGB24, _video_container_size, true)); + _black_image->make_black (); +} - if (content->trimmed (relative_time)) { - return; +void +Player::film_changed (Film::Property p) +{ + /* Here we should notice Film properties that affect our output, and + alert listeners that our output now would be different to how it was + last time we were run. + */ + + if (p == Film::SCALER || p == Film::WITH_SUBTITLES || p == Film::CONTAINER || p == Film::VIDEO_FRAME_RATE) { + Changed (false); } +} - Time time = content->position() + (content->audio_delay() * TIME_HZ / 1000) + relative_time - content->trim_start (); +list +Player::process_content_image_subtitles (shared_ptr content, list > subs) const +{ + list all; - /* Remap channels */ - shared_ptr dcp_mapped (new AudioBuffers (_film->audio_channels(), audio->frames())); - dcp_mapped->make_silent (); - - AudioMapping map = content->audio_mapping (); - for (int i = 0; i < map.content_channels(); ++i) { - for (int j = 0; j < _film->audio_channels(); ++j) { - if (map.get (i, static_cast (j)) > 0) { - dcp_mapped->accumulate_channel ( - audio.get(), - i, - static_cast (j), - map.get (i, static_cast (j)) - ); - } + for (list >::const_iterator i = subs.begin(); i != subs.end(); ++i) { + if (!(*i)->image) { + continue; } + + dcpomatic::Rect in_rect = (*i)->rectangle; + dcp::Size scaled_size; + + in_rect.x += content->subtitle_x_offset (); + in_rect.y += content->subtitle_y_offset (); + + /* We will scale the subtitle up to fit _video_container_size, and also by the additional subtitle_scale */ + scaled_size.width = in_rect.width * _video_container_size.width * content->subtitle_scale (); + scaled_size.height = in_rect.height * _video_container_size.height * content->subtitle_scale (); + + /* Then we need a corrective translation, consisting of two parts: + * + * 1. that which is the result of the scaling of the subtitle by _video_container_size; this will be + * rect.x * _video_container_size.width and rect.y * _video_container_size.height. + * + * 2. that to shift the origin of the scale by subtitle_scale to the centre of the subtitle; this will be + * (width_before_subtitle_scale * (1 - subtitle_scale) / 2) and + * (height_before_subtitle_scale * (1 - subtitle_scale) / 2). + * + * Combining these two translations gives these expressions. + */ + + all.push_back ( + PositionImage ( + (*i)->image->scale ( + scaled_size, + Scaler::from_id ("bicubic"), + (*i)->image->pixel_format (), + true + ), + Position ( + rint (_video_container_size.width * (in_rect.x + (in_rect.width * (1 - content->subtitle_scale ()) / 2))), + rint (_video_container_size.height * (in_rect.y + (in_rect.height * (1 - content->subtitle_scale ()) / 2))) + ) + ) + ); } - audio = dcp_mapped; + return all; +} - /* We must cut off anything that comes before the start of all time */ - if (time < 0) { - int const frames = - time * _film->audio_frame_rate() / TIME_HZ; - if (frames >= audio->frames ()) { - return; +list +Player::process_content_text_subtitles (list > sub) const +{ + list all; + for (list >::const_iterator i = sub.begin(); i != sub.end(); ++i) { + if (!(*i)->subs.empty ()) { + all.push_back (render_subtitles ((*i)->subs, _video_container_size)); } - - shared_ptr trimmed (new AudioBuffers (audio->channels(), audio->frames() - frames)); - trimmed->copy_from (audio.get(), audio->frames() - frames, frames, 0); - - audio = trimmed; - time = 0; } - _audio_merger.push (audio, time); - piece->audio_position += _film->audio_frames_to_time (audio->frames ()); + return all; } void diff --cc src/lib/util.cc index 6e370f577,bbe6f77e1..074e08cb7 --- a/src/lib/util.cc +++ b/src/lib/util.cc @@@ -44,15 -44,13 +44,14 @@@ #endif #include #include - #include +#include #include #include -#include -#include -#include -#include -#include +#include +#include +#include +#include +#include extern "C" { #include #include @@@ -71,7 -69,7 +70,8 @@@ #include "job.h" #include "cross.h" #include "video_content.h" +#include "rect.h" + #include "md5_digester.h" #ifdef DCPOMATIC_WINDOWS #include "stack.hpp" #endif @@@ -464,17 -462,36 +447,9 @@@ md5_digest (vector (_menu_column - 1), 1 / sqrt (2)); - _map.set (_menu_row, static_cast (_menu_column - 1), pow (10, -6.0 / 20)); ++ _map.set (_menu_row, static_cast (_menu_column - 1), pow (10, -6.0 / 20)); map_changed (); }