, decoder (d)
, video_position (c->position ())
, audio_position (c->position ())
+ , repeat_to_do (0)
+ , repeat_done (0)
{}
/** Set this piece to repeat a video frame a given number of times */
continue;
}
- if (dynamic_pointer_cast<AudioDecoder> ((*i)->decoder)) {
+ shared_ptr<AudioDecoder> ad = dynamic_pointer_cast<AudioDecoder> ((*i)->decoder);
+ if (ad && ad->has_audio ()) {
audio_done_up_to = min (audio_done_up_to.get_value_or (TIME_MAX), (*i)->audio_position);
}
}
pi->set_subtitle (_out_subtitle.image, _out_subtitle.position + container_offset);
}
+
#ifdef DCPOMATIC_DEBUG
_last_video = piece->content;
/* Remap channels */
shared_ptr<AudioBuffers> dcp_mapped (new AudioBuffers (_film->audio_channels(), audio->frames()));
dcp_mapped->make_silent ();
- list<pair<int, libdcp::Channel> > map = content->audio_mapping().content_to_dcp ();
- for (list<pair<int, libdcp::Channel> >::iterator i = map.begin(); i != map.end(); ++i) {
- if (i->first < audio->channels() && i->second < dcp_mapped->channels()) {
- dcp_mapped->accumulate_channel (audio.get(), i->first, i->second);
+
+ 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<libdcp::Channel> (j)) > 0) {
+ dcp_mapped->accumulate_channel (
+ audio.get(),
+ i,
+ static_cast<libdcp::Channel> (j),
+ map.get (i, static_cast<libdcp::Channel> (j))
+ );
+ }
}
}
Player::flush ()
{
TimedAudioBuffers<Time> tb = _audio_merger.flush ();
- if (tb.audio) {
+ if (_audio && tb.audio) {
Audio (tb.audio, tb.time);
_audio_position += _film->audio_frames_to_time (tb.audio->frames ());
}
- while (_video_position < _audio_position) {
+ while (_video && _video_position < _audio_position) {
emit_black ();
}
- while (_audio_position < _video_position) {
+ while (_audio && _audio_position < _video_position) {
emit_silence (_film->time_to_audio_frames (_video_position - _audio_position));
}
for (ContentList::iterator i = content.begin(); i != content.end(); ++i) {
+ if (!(*i)->paths_valid ()) {
+ continue;
+ }
+
shared_ptr<Piece> piece (new Piece (*i));
/* XXX: into content? */
if (
property == ContentProperty::POSITION || property == ContentProperty::LENGTH ||
- property == ContentProperty::TRIM_START || property == ContentProperty::TRIM_END
+ property == ContentProperty::TRIM_START || property == ContentProperty::TRIM_END ||
+ property == VideoContentProperty::VIDEO_FRAME_TYPE
) {
_have_valid_pieces = false;
Changed (frequent);
- } else if (property == SubtitleContentProperty::SUBTITLE_OFFSET || property == SubtitleContentProperty::SUBTITLE_SCALE) {
+ } else if (
+ property == SubtitleContentProperty::SUBTITLE_X_OFFSET ||
+ property == SubtitleContentProperty::SUBTITLE_Y_OFFSET ||
+ property == SubtitleContentProperty::SUBTITLE_SCALE
+ ) {
update_subtitle ();
Changed (frequent);
} else if (
- property == VideoContentProperty::VIDEO_FRAME_TYPE || property == VideoContentProperty::VIDEO_CROP ||
- property == VideoContentProperty::VIDEO_RATIO
+ property == VideoContentProperty::VIDEO_CROP || property == VideoContentProperty::VIDEO_RATIO ||
+ property == VideoContentProperty::VIDEO_FRAME_RATE
) {
Changed (frequent);
} else if (property == ContentProperty::PATH) {
+ _have_valid_pieces = false;
Changed (frequent);
}
}
last time we were run.
*/
- if (p == Film::SCALER || p == Film::WITH_SUBTITLES || p == Film::CONTAINER) {
+ if (p == Film::SCALER || p == Film::WITH_SUBTITLES || p == Film::CONTAINER || p == Film::VIDEO_FRAME_RATE) {
Changed (false);
}
}
dcpomatic::Rect<double> in_rect = _in_subtitle.rect;
libdcp::Size scaled_size;
- in_rect.y += sc->subtitle_offset ();
+ in_rect.x += sc->subtitle_x_offset ();
+ in_rect.y += sc->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 * sc->subtitle_scale ();
_in_subtitle.image->pixel_format (),
true
);
- _out_subtitle.from = _in_subtitle.from + piece->content->position ();
- _out_subtitle.to = _in_subtitle.to + piece->content->position ();
+
+ /* XXX: hack */
+ Time from = _in_subtitle.from;
+ Time to = _in_subtitle.to;
+ shared_ptr<VideoContent> vc = dynamic_pointer_cast<VideoContent> (piece->content);
+ if (vc) {
+ from = rint (from * vc->video_frame_rate() / _film->video_frame_rate());
+ to = rint (to * vc->video_frame_rate() / _film->video_frame_rate());
+ }
+
+ _out_subtitle.from = from + piece->content->position ();
+ _out_subtitle.to = to + piece->content->position ();
}
/** Re-emit the last frame that was emitted, using current settings for crop, ratio, scaler and subtitles.