X-Git-Url: https://main.carlh.net/gitweb/?a=blobdiff_plain;f=src%2Flib%2Fplayer.cc;h=de513ea170132228b8898e1ea17a255e611ec08e;hb=78dd04db5ee5d1aa5fc915f04dc71cb53d33d059;hp=396dc990684667b93060df953cb767f6e6246335;hpb=5d117c316fe68686885a931bf028cbd8afa5c0e1;p=dcpomatic.git diff --git a/src/lib/player.cc b/src/lib/player.cc index 396dc9906..de513ea17 100644 --- a/src/lib/player.cc +++ b/src/lib/player.cc @@ -1,5 +1,5 @@ /* - Copyright (C) 2013-2014 Carl Hetherington + Copyright (C) 2013-2015 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 @@ -73,6 +73,7 @@ Player::Player (shared_ptr f, shared_ptr p) , _playlist (p) , _have_valid_pieces (false) , _approximate_size (false) + , _ignore_video (false) { _playlist_changed_connection = _playlist->Changed.connect (bind (&Player::playlist_changed, this)); _playlist_content_changed_connection = _playlist->ContentChanged.connect (bind (&Player::content_changed, this, _1, _2, _3)); @@ -173,6 +174,11 @@ Player::setup_pieces () frc = best_overlap_frc; } + shared_ptr vd = dynamic_pointer_cast (decoder); + if (vd && _ignore_video) { + vd->set_ignore_video (); + } + _pieces.push_back (shared_ptr (new Piece (*i, decoder, frc.get ()))); } @@ -208,7 +214,9 @@ Player::content_changed (weak_ptr w, int property, bool frequent) property == SubtitleContentProperty::SUBTITLE_Y_SCALE || property == VideoContentProperty::VIDEO_CROP || property == VideoContentProperty::VIDEO_SCALE || - property == VideoContentProperty::VIDEO_FRAME_RATE + property == VideoContentProperty::VIDEO_FRAME_RATE || + property == VideoContentProperty::VIDEO_FADE_IN || + property == VideoContentProperty::VIDEO_FADE_OUT ) { Changed (frequent); @@ -321,7 +329,7 @@ Player::get_video (DCPTime time, bool accurate) if (!_have_valid_pieces) { setup_pieces (); } - + list > ov = overlaps ( time, time + DCPTime::from_frames (1, _film->video_frame_rate ()) @@ -337,9 +345,9 @@ Player::get_video (DCPTime time, bool accurate) shared_ptr piece = ov.back (); shared_ptr decoder = dynamic_pointer_cast (piece->decoder); - assert (decoder); + DCPOMATIC_ASSERT (decoder); shared_ptr content = dynamic_pointer_cast (piece->content); - assert (content); + DCPOMATIC_ASSERT (content); list content_video = decoder->get_video (dcp_to_content_video (piece, time), accurate); if (content_video.empty ()) { @@ -352,7 +360,7 @@ Player::get_video (DCPTime time, bool accurate) image_size.width &= ~3; image_size.height &= ~3; } - + for (list::const_iterator i = content_video.begin(); i != content_video.end(); ++i) { pvf.push_back ( shared_ptr ( @@ -415,9 +423,9 @@ Player::get_audio (DCPTime time, DCPTime length, bool accurate) for (list >::iterator i = ov.begin(); i != ov.end(); ++i) { shared_ptr content = dynamic_pointer_cast ((*i)->content); - assert (content); + DCPOMATIC_ASSERT (content); shared_ptr decoder = dynamic_pointer_cast ((*i)->decoder); - assert (decoder); + DCPOMATIC_ASSERT (decoder); if (content->audio_frame_rate() == 0) { /* This AudioContent has no audio (e.g. if it is an FFmpegContent with no @@ -428,19 +436,24 @@ Player::get_audio (DCPTime time, DCPTime length, bool accurate) /* The time that we should request from the content */ DCPTime request = time - DCPTime::from_seconds (content->audio_delay() / 1000.0); + AudioFrame request_frames = length_frames; DCPTime offset; if (request < DCPTime ()) { /* We went off the start of the content, so we will need to offset the stuff we get back. */ offset = -request; + request_frames += request.frames (_film->audio_frame_rate ()); + if (request_frames < 0) { + request_frames = 0; + } request = DCPTime (); } AudioFrame const content_frame = dcp_to_content_audio (*i, request); /* Audio from this piece's decoder (which might be more or less than what we asked for) */ - shared_ptr all = decoder->get_audio (content_frame, length_frames, accurate); + shared_ptr all = decoder->get_audio (content_frame, request_frames, accurate); /* Gain */ if (content->audio_gain() != 0) { @@ -472,7 +485,7 @@ Player::get_audio (DCPTime time, DCPTime length, bool accurate) all->audio.get(), content_frame - all->frame, offset.frames (_film->audio_frame_rate()), - min (AudioFrame (all->audio->frames()), length_frames) - offset.frames (_film->audio_frame_rate ()) + min (AudioFrame (all->audio->frames()), request_frames) ); } @@ -488,13 +501,13 @@ Player::dcp_to_content_video (shared_ptr piece, DCPTime t) const s = DCPTime (min (piece->content->length_after_trim().get(), s.get())); /* Convert this to the content frame */ - return DCPTime (s + piece->content->trim_start()).frames (_film->video_frame_rate()) * piece->frc.factor (); + return DCPTime (s + piece->content->trim_start()).frames (_film->video_frame_rate()) / piece->frc.factor (); } DCPTime Player::content_video_to_dcp (shared_ptr piece, VideoFrame f) const { - DCPTime t = DCPTime::from_frames (f / piece->frc.factor (), _film->video_frame_rate()) - piece->content->trim_start () + piece->content->position (); + DCPTime t = DCPTime::from_frames (f * piece->frc.factor (), _film->video_frame_rate()) - piece->content->trim_start () + piece->content->position (); if (t < DCPTime ()) { t = DCPTime (); } @@ -551,12 +564,6 @@ Player::get_subtitles (DCPTime time, DCPTime length, bool starting) continue; } - /* XXX: this will break down if we have multiple subtitle content */ - ps.language = subtitle_content->subtitle_language(); - if (ps.language.empty ()) { - ps.language = _("Unknown"); - } - shared_ptr subtitle_decoder = dynamic_pointer_cast ((*j)->decoder); ContentTime const from = dcp_to_content_subtitle (*j, time); /* XXX: this video_frame_rate() should be the rate that the subtitle content has been prepared for */ @@ -592,3 +599,32 @@ Player::get_subtitles (DCPTime time, DCPTime length, bool starting) return ps; } + +list > +Player::get_subtitle_fonts () +{ + if (!_have_valid_pieces) { + setup_pieces (); + } + + list > fonts; + BOOST_FOREACH (shared_ptr& p, _pieces) { + shared_ptr sc = dynamic_pointer_cast (p->content); + if (sc) { + /* XXX: things may go wrong if there are duplicate font IDs + with different font files. + */ + list > f = sc->fonts (); + copy (f.begin(), f.end(), back_inserter (fonts)); + } + } + + return fonts; +} + +/** Set this player never to produce any video data */ +void +Player::set_ignore_video () +{ + _ignore_video = true; +}