diff options
| author | Carl Hetherington <cth@carlh.net> | 2016-04-12 22:10:54 +0100 |
|---|---|---|
| committer | Carl Hetherington <cth@carlh.net> | 2016-05-18 11:50:29 +0100 |
| commit | 6f344b876689a1234a5eb75041882f06f5d9fe5c (patch) | |
| tree | 3a51f17cab8b8f31b21661b643aaed6a53326031 /src/lib | |
| parent | 36774ee2b48f0bfde43b743592e5816ff58bb7d2 (diff) | |
Reasonably straightforward stuff; main things are adding
a _parent to VideoContent (mainly, but not only, for signalling)
and moving the video shared_ptr into Content, which makes much
more sense to replace dynamic_cast tests for whether something
has video or whatever. Nearly builds.
Diffstat (limited to 'src/lib')
| -rw-r--r-- | src/lib/content.h | 5 | ||||
| -rw-r--r-- | src/lib/dcp_content.cc | 17 | ||||
| -rw-r--r-- | src/lib/dcp_content.h | 2 | ||||
| -rw-r--r-- | src/lib/dcp_decoder.cc | 4 | ||||
| -rw-r--r-- | src/lib/dcp_decoder.h | 4 | ||||
| -rw-r--r-- | src/lib/ffmpeg_content.cc | 21 | ||||
| -rw-r--r-- | src/lib/ffmpeg_content.h | 2 | ||||
| -rw-r--r-- | src/lib/ffmpeg_decoder.cc | 8 | ||||
| -rw-r--r-- | src/lib/ffmpeg_examiner.h | 1 | ||||
| -rw-r--r-- | src/lib/film.cc | 20 | ||||
| -rw-r--r-- | src/lib/image_content.cc | 31 | ||||
| -rw-r--r-- | src/lib/image_content.h | 3 | ||||
| -rw-r--r-- | src/lib/image_decoder.cc | 10 | ||||
| -rw-r--r-- | src/lib/image_decoder.h | 4 | ||||
| -rw-r--r-- | src/lib/image_examiner.cc | 4 | ||||
| -rw-r--r-- | src/lib/player.cc | 43 | ||||
| -rw-r--r-- | src/lib/playlist.cc | 33 | ||||
| -rw-r--r-- | src/lib/types.h | 1 | ||||
| -rw-r--r-- | src/lib/video_content.cc | 63 | ||||
| -rw-r--r-- | src/lib/video_content.h | 17 | ||||
| -rw-r--r-- | src/lib/video_decoder.cc | 7 | ||||
| -rw-r--r-- | src/lib/video_decoder.h | 4 |
22 files changed, 157 insertions, 147 deletions
diff --git a/src/lib/content.h b/src/lib/content.h index d08540a9a..0ce9d39c1 100644 --- a/src/lib/content.h +++ b/src/lib/content.h @@ -166,9 +166,12 @@ public: boost::signals2::signal<void (boost::weak_ptr<Content>, int, bool)> Changed; -protected: + boost::shared_ptr<VideoContent> video; + void signal_changed (int); +protected: + virtual void add_properties (std::list<UserProperty> &) const {} boost::weak_ptr<const Film> _film; diff --git a/src/lib/dcp_content.cc b/src/lib/dcp_content.cc index 3bc28598d..5a9a47fb1 100644 --- a/src/lib/dcp_content.cc +++ b/src/lib/dcp_content.cc @@ -55,7 +55,6 @@ DCPContent::DCPContent (shared_ptr<const Film> film, boost::filesystem::path p) : Content (film) , SingleStreamAudioContent (film) , SubtitleContent (film) - , video (new VideoContent (film)) , _has_subtitles (false) , _encrypted (false) , _kdm_valid (false) @@ -63,6 +62,8 @@ DCPContent::DCPContent (shared_ptr<const Film> film, boost::filesystem::path p) , _reference_audio (false) , _reference_subtitle (false) { + video.reset (new VideoContent (this, film)); + read_directory (p); set_default_colour_conversion (); } @@ -71,8 +72,9 @@ DCPContent::DCPContent (shared_ptr<const Film> film, cxml::ConstNodePtr node, in : Content (film, node) , SingleStreamAudioContent (film, node, version) , SubtitleContent (film, node, version) - , video (new VideoContent (film, node, version)) { + video.reset (new VideoContent (this, film, node, version)); + _name = node->string_child ("Name"); _has_subtitles = node->bool_child ("HasSubtitles"); _encrypted = node->bool_child ("Encrypted"); @@ -165,7 +167,7 @@ DCPTime DCPContent::full_length () const { FrameRateChange const frc (video->video_frame_rate (), film()->video_frame_rate ()); - return DCPTime::from_frames (llrint (video_length () * frc.factor ()), film()->video_frame_rate ()); + return DCPTime::from_frames (llrint (video->video_length () * frc.factor ()), film()->video_frame_rate ()); } string @@ -259,7 +261,7 @@ DCPContent::reels () const list<DCPTimePeriod> p; scoped_ptr<DCPDecoder> decoder; try { - decoder.reset (new DCPDecoder (shared_from_this(), false)); + decoder.reset (new DCPDecoder (shared_from_this(), film()->log(), false)); } catch (...) { /* Could not load the DCP; guess reels */ list<DCPTimePeriod> p; @@ -314,13 +316,14 @@ DCPContent::can_reference (string overlapping, list<string>& why_not) const bool DCPContent::can_reference_video (list<string>& why_not) const { - return can_reference<VideoContent> (_("There is other video content overlapping this DCP; remove it."), why_not); + /* XXX: this needs to be fixed */ + return true; } bool DCPContent::can_reference_audio (list<string>& why_not) const { - DCPDecoder decoder (shared_from_this(), false); + DCPDecoder decoder (shared_from_this(), film()->log(), false); BOOST_FOREACH (shared_ptr<dcp::Reel> i, decoder.reels()) { if (!i->main_sound()) { why_not.push_back (_("The DCP does not have sound in all reels.")); @@ -334,7 +337,7 @@ DCPContent::can_reference_audio (list<string>& why_not) const bool DCPContent::can_reference_subtitle (list<string>& why_not) const { - DCPDecoder decoder (shared_from_this(), false); + DCPDecoder decoder (shared_from_this(), film()->log(), false); BOOST_FOREACH (shared_ptr<dcp::Reel> i, decoder.reels()) { if (!i->main_subtitle()) { why_not.push_back (_("The DCP does not have subtitles in all reels.")); diff --git a/src/lib/dcp_content.h b/src/lib/dcp_content.h index 04352b269..1edc3a3aa 100644 --- a/src/lib/dcp_content.h +++ b/src/lib/dcp_content.h @@ -121,8 +121,6 @@ public: bool can_reference_subtitle (std::list<std::string> &) const; - boost::shared_ptr<VideoContent> video; - protected: void add_properties (std::list<UserProperty>& p) const; diff --git a/src/lib/dcp_decoder.cc b/src/lib/dcp_decoder.cc index 873b3634f..e8c64a086 100644 --- a/src/lib/dcp_decoder.cc +++ b/src/lib/dcp_decoder.cc @@ -42,8 +42,8 @@ using std::cout; using boost::shared_ptr; using boost::dynamic_pointer_cast; -DCPDecoder::DCPDecoder (shared_ptr<const DCPContent> c, bool fast) - : VideoDecoder (c->video) +DCPDecoder::DCPDecoder (shared_ptr<const DCPContent> c, shared_ptr<Log> log, bool fast) + : VideoDecoder (c->video, log) , AudioDecoder (c, fast) , SubtitleDecoder (c) , _dcp_content (c) diff --git a/src/lib/dcp_decoder.h b/src/lib/dcp_decoder.h index 32d334ec1..ce9a3ef9a 100644 --- a/src/lib/dcp_decoder.h +++ b/src/lib/dcp_decoder.h @@ -1,5 +1,5 @@ /* - Copyright (C) 2014 Carl Hetherington <cth@carlh.net> + Copyright (C) 2014-2016 Carl Hetherington <cth@carlh.net> 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 @@ -35,7 +35,7 @@ struct dcp_subtitle_within_dcp_test; class DCPDecoder : public VideoDecoder, public AudioDecoder, public SubtitleDecoder { public: - DCPDecoder (boost::shared_ptr<const DCPContent>, bool fast); + DCPDecoder (boost::shared_ptr<const DCPContent>, boost::shared_ptr<Log> log, bool fast); std::list<boost::shared_ptr<dcp::Reel> > reels () const { return _reels; diff --git a/src/lib/ffmpeg_content.cc b/src/lib/ffmpeg_content.cc index 54e0b470a..a8b7fb716 100644 --- a/src/lib/ffmpeg_content.cc +++ b/src/lib/ffmpeg_content.cc @@ -63,8 +63,9 @@ FFmpegContent::FFmpegContent (shared_ptr<const Film> film, boost::filesystem::pa : Content (film, p) , AudioContent (film, p) , SubtitleContent (film, p) - , video (new VideoContent (film)) { + video.reset (new VideoContent (this, film)); + set_default_colour_conversion (); } @@ -72,8 +73,9 @@ FFmpegContent::FFmpegContent (shared_ptr<const Film> film, cxml::ConstNodePtr no : Content (film, node) , AudioContent (film, node) , SubtitleContent (film, node, version) - , video (new VideoContent (film, node, version)) { + video.reset (new VideoContent (this, film, node, version)); + list<cxml::NodePtr> c = node->node_children ("SubtitleStream"); for (list<cxml::NodePtr>::const_iterator i = c.begin(); i != c.end(); ++i) { _subtitle_streams.push_back (shared_ptr<FFmpegSubtitleStream> (new FFmpegSubtitleStream (*i, version))); @@ -120,8 +122,9 @@ FFmpegContent::FFmpegContent (shared_ptr<const Film> film, vector<boost::shared_ : Content (film, c) , AudioContent (film, c) , SubtitleContent (film, c) - , video (new VideoContent (film, c)) { + video.reset (new VideoContent (this, film, c)); + shared_ptr<FFmpegContent> ref = dynamic_pointer_cast<FFmpegContent> (c[0]); DCPOMATIC_ASSERT (ref); @@ -194,7 +197,7 @@ FFmpegContent::examine (shared_ptr<Job> job) Content::examine (job); shared_ptr<FFmpegExaminer> examiner (new FFmpegExaminer (shared_from_this (), job)); - take_from_video_examiner (examiner); + video->take_from_video_examiner (examiner); set_default_colour_conversion (); { @@ -287,8 +290,8 @@ operator!= (FFmpegStream const & a, FFmpegStream const & b) DCPTime FFmpegContent::full_length () const { - FrameRateChange const frc (video_frame_rate (), film()->video_frame_rate ()); - return DCPTime::from_frames (llrint (video_length_after_3d_combine() * frc.factor()), film()->video_frame_rate()); + FrameRateChange const frc (video->video_frame_rate (), film()->video_frame_rate ()); + return DCPTime::from_frames (llrint (video->video_length_after_3d_combine() * frc.factor()), film()->video_frame_rate()); } void @@ -373,14 +376,14 @@ FFmpegContent::has_text_subtitles () const void FFmpegContent::set_default_colour_conversion () { - dcp::Size const s = video_size (); + dcp::Size const s = video->video_size (); boost::mutex::scoped_lock lm (_mutex); if (s.width < 1080) { - _colour_conversion = PresetColourConversion::from_id ("rec601").conversion; + video->set_colour_conversion (PresetColourConversion::from_id ("rec601").conversion); } else { - _colour_conversion = PresetColourConversion::from_id ("rec709").conversion; + video->set_colour_conversion (PresetColourConversion::from_id ("rec709").conversion); } } diff --git a/src/lib/ffmpeg_content.h b/src/lib/ffmpeg_content.h index f5bbbd31e..d210d63a8 100644 --- a/src/lib/ffmpeg_content.h +++ b/src/lib/ffmpeg_content.h @@ -106,8 +106,6 @@ public: void signal_subtitle_stream_changed (); - boost::shared_ptr<VideoContent> video; - protected: void add_properties (std::list<UserProperty> &) const; diff --git a/src/lib/ffmpeg_decoder.cc b/src/lib/ffmpeg_decoder.cc index 698078b5b..5240decb2 100644 --- a/src/lib/ffmpeg_decoder.cc +++ b/src/lib/ffmpeg_decoder.cc @@ -72,12 +72,12 @@ using boost::split; using dcp::Size; FFmpegDecoder::FFmpegDecoder (shared_ptr<const FFmpegContent> c, shared_ptr<Log> log, bool fast) - : VideoDecoder (c) + : VideoDecoder (c->video, log) , AudioDecoder (c, fast) , SubtitleDecoder (c) , FFmpeg (c) , _log (log) - , _pts_offset (pts_offset (c->ffmpeg_audio_streams(), c->first_video(), c->video_frame_rate())) + , _pts_offset (pts_offset (c->ffmpeg_audio_streams(), c->first_video(), c->video->video_frame_rate())) { } @@ -414,7 +414,7 @@ FFmpegDecoder::decode_video_packet () double const pts = i->second * av_q2d (_format_context->streams[_video_stream]->time_base) + _pts_offset.seconds (); video ( shared_ptr<ImageProxy> (new RawImageProxy (image)), - llrint (pts * _ffmpeg_content->video_frame_rate ()) + llrint (pts * _ffmpeg_content->video->video_frame_rate ()) ); } else { LOG_WARNING_NC ("Dropping frame without PTS"); @@ -548,7 +548,7 @@ FFmpegDecoder::decode_bitmap_subtitle (AVSubtitleRect const * rect, ContentTimeP out_p += image->stride()[0] / sizeof (uint32_t); } - dcp::Size const vs = _ffmpeg_content->video_size (); + dcp::Size const vs = _ffmpeg_content->video->video_size (); dcpomatic::Rect<double> const scaled_rect ( static_cast<double> (rect->x) / vs.width, static_cast<double> (rect->y) / vs.height, diff --git a/src/lib/ffmpeg_examiner.h b/src/lib/ffmpeg_examiner.h index f64ea8d79..b9ca04e4c 100644 --- a/src/lib/ffmpeg_examiner.h +++ b/src/lib/ffmpeg_examiner.h @@ -25,6 +25,7 @@ struct AVStream; class FFmpegAudioStream; class FFmpegSubtitleStream; +class Job; class FFmpegExaminer : public FFmpeg, public VideoExaminer { diff --git a/src/lib/film.cc b/src/lib/film.cc index dbcb9f31a..7d319fc1e 100644 --- a/src/lib/film.cc +++ b/src/lib/film.cc @@ -617,13 +617,12 @@ Film::isdcf_name (bool if_created_now) const if (dcp_content_type() && dcp_content_type()->libdcp_kind() != dcp::TRAILER) { Ratio const * content_ratio = 0; BOOST_FOREACH (shared_ptr<Content> i, content ()) { - shared_ptr<VideoContent> vc = dynamic_pointer_cast<VideoContent> (i); - if (vc) { + if (i->video) { /* Here's the first piece of video content */ - if (vc->scale().ratio ()) { - content_ratio = vc->scale().ratio (); + if (i->video->scale().ratio ()) { + content_ratio = i->video->scale().ratio (); } else { - content_ratio = Ratio::from_ratio (vc->video_size().ratio ()); + content_ratio = Ratio::from_ratio (i->video->video_size().ratio ()); } break; } @@ -1049,7 +1048,7 @@ void Film::add_content (shared_ptr<Content> c) { /* Add {video,subtitle} content after any existing {video,subtitle} content */ - if (dynamic_pointer_cast<VideoContent> (c)) { + if (c->video) { c->set_position (_playlist->video_end ()); } else if (dynamic_pointer_cast<SubtitleContent> (c)) { c->set_position (_playlist->subtitle_end ()); @@ -1377,18 +1376,17 @@ Film::reels () const case REELTYPE_BY_VIDEO_CONTENT: { optional<DCPTime> last_split; - shared_ptr<VideoContent> last_video; + shared_ptr<Content> last_video; ContentList cl = content (); BOOST_FOREACH (shared_ptr<Content> c, content ()) { - shared_ptr<VideoContent> v = dynamic_pointer_cast<VideoContent> (c); - if (v) { - BOOST_FOREACH (DCPTime t, v->reel_split_points()) { + if (c->video) { + BOOST_FOREACH (DCPTime t, c->reel_split_points()) { if (last_split) { p.push_back (DCPTimePeriod (last_split.get(), t)); } last_split = t; } - last_video = v; + last_video = c; } } diff --git a/src/lib/image_content.cc b/src/lib/image_content.cc index ed290dd6c..231eb9f8c 100644 --- a/src/lib/image_content.cc +++ b/src/lib/image_content.cc @@ -40,8 +40,9 @@ using boost::shared_ptr; ImageContent::ImageContent (shared_ptr<const Film> film, boost::filesystem::path p) : Content (film) - , video (new VideoContent (film)) { + video.reset (new VideoContent (this, film)); + if (boost::filesystem::is_regular_file (p) && valid_image_file (p)) { _paths.push_back (p); } else { @@ -64,9 +65,8 @@ ImageContent::ImageContent (shared_ptr<const Film> film, boost::filesystem::path ImageContent::ImageContent (shared_ptr<const Film> film, cxml::ConstNodePtr node, int version) : Content (film, node) - , video (new VideoContent (film, node, version)) { - + video.reset (new VideoContent (this, film, node, version)); } string @@ -115,28 +115,17 @@ ImageContent::examine (shared_ptr<Job> job) DCPOMATIC_ASSERT (film); shared_ptr<ImageExaminer> examiner (new ImageExaminer (film, shared_from_this(), job)); - take_from_video_examiner (examiner); + video->take_from_video_examiner (examiner); set_default_colour_conversion (); } -void -ImageContent::set_video_length (Frame len) -{ - { - boost::mutex::scoped_lock lm (_mutex); - _video_length = len; - } - - signal_changed (ContentProperty::LENGTH); -} - DCPTime ImageContent::full_length () const { shared_ptr<const Film> film = _film.lock (); DCPOMATIC_ASSERT (film); - FrameRateChange const frc (video_frame_rate(), film->video_frame_rate()); - return DCPTime::from_frames (llrint (video_length_after_3d_combine() * frc.factor ()), film->video_frame_rate ()); + FrameRateChange const frc (video->video_frame_rate(), film->video_frame_rate()); + return DCPTime::from_frames (llrint (video->video_length_after_3d_combine() * frc.factor ()), film->video_frame_rate ()); } string @@ -145,7 +134,7 @@ ImageContent::identifier () const SafeStringStream s; s << Content::identifier(); s << "_" << video->identifier (); - s << "_" << video_length(); + s << "_" << video->video_length(); return s.str (); } @@ -161,7 +150,7 @@ ImageContent::set_default_colour_conversion () BOOST_FOREACH (boost::filesystem::path i, _paths) { if (valid_j2k_file (i)) { /* We default to no colour conversion if we have JPEG2000 files */ - unset_colour_conversion (); + video->unset_colour_conversion (); return; } } @@ -171,8 +160,8 @@ ImageContent::set_default_colour_conversion () boost::mutex::scoped_lock lm (_mutex); if (s) { - _colour_conversion = PresetColourConversion::from_id ("srgb").conversion; + video->set_colour_conversion (PresetColourConversion::from_id ("srgb").conversion); } else { - _colour_conversion = PresetColourConversion::from_id ("rec709").conversion; + video->set_colour_conversion (PresetColourConversion::from_id ("rec709").conversion); } } diff --git a/src/lib/image_content.h b/src/lib/image_content.h index 353ce8370..dcdb7b526 100644 --- a/src/lib/image_content.h +++ b/src/lib/image_content.h @@ -42,10 +42,7 @@ public: void set_default_colour_conversion (); - void set_video_length (Frame); bool still () const; - - boost::shared_ptr<VideoContent> video; }; #endif diff --git a/src/lib/image_decoder.cc b/src/lib/image_decoder.cc index 2291daecd..e26574f61 100644 --- a/src/lib/image_decoder.cc +++ b/src/lib/image_decoder.cc @@ -34,8 +34,8 @@ using std::cout; using boost::shared_ptr; using dcp::Size; -ImageDecoder::ImageDecoder (shared_ptr<const ImageContent> c) - : VideoDecoder (c) +ImageDecoder::ImageDecoder (shared_ptr<const ImageContent> c, shared_ptr<Log> log) + : VideoDecoder (c->video, log) , _image_content (c) , _video_position (0) { @@ -45,7 +45,7 @@ ImageDecoder::ImageDecoder (shared_ptr<const ImageContent> c) bool ImageDecoder::pass (PassReason, bool) { - if (_video_position >= _image_content->video_length()) { + if (_video_position >= _image_content->video->video_length()) { return true; } @@ -56,7 +56,7 @@ ImageDecoder::pass (PassReason, bool) /* We can't extract image size from a JPEG2000 codestream without decoding it, so pass in the image content's size here. */ - _image.reset (new J2KImageProxy (path, _image_content->video_size ())); + _image.reset (new J2KImageProxy (path, _image_content->video->video_size ())); } else { _image.reset (new MagickImageProxy (path)); } @@ -71,5 +71,5 @@ void ImageDecoder::seek (ContentTime time, bool accurate) { VideoDecoder::seek (time, accurate); - _video_position = time.frames_round (_image_content->video_frame_rate ()); + _video_position = time.frames_round (_image_content->video->video_frame_rate ()); } diff --git a/src/lib/image_decoder.h b/src/lib/image_decoder.h index e2de56acb..9d81cdac1 100644 --- a/src/lib/image_decoder.h +++ b/src/lib/image_decoder.h @@ -1,5 +1,5 @@ /* - Copyright (C) 2012-2013 Carl Hetherington <cth@carlh.net> + Copyright (C) 2012-2016 Carl Hetherington <cth@carlh.net> 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 @@ -24,7 +24,7 @@ class ImageContent; class ImageDecoder : public VideoDecoder { public: - ImageDecoder (boost::shared_ptr<const ImageContent> c); + ImageDecoder (boost::shared_ptr<const ImageContent> c, boost::shared_ptr<Log> log); boost::shared_ptr<const ImageContent> content () { return _image_content; diff --git a/src/lib/image_examiner.cc b/src/lib/image_examiner.cc index 7b02de956..010275429 100644 --- a/src/lib/image_examiner.cc +++ b/src/lib/image_examiner.cc @@ -85,9 +85,9 @@ ImageExaminer::video_size () const optional<double> ImageExaminer::video_frame_rate () const { - if (_image_content->has_own_video_frame_rate()) { + if (_image_content->video->has_own_video_frame_rate()) { /* The content already knows what frame rate it should be */ - return _image_content->video_frame_rate(); + return _image_content->video->video_frame_rate(); } /* Don't know */ diff --git a/src/lib/player.cc b/src/lib/player.cc index d35c1b76b..2b65fd54e 100644 --- a/src/lib/player.cc +++ b/src/lib/player.cc @@ -113,13 +113,13 @@ Player::setup_pieces () shared_ptr<const FFmpegContent> fc = dynamic_pointer_cast<const FFmpegContent> (i); if (fc) { decoder.reset (new FFmpegDecoder (fc, _film->log(), _fast)); - frc = FrameRateChange (fc->video_frame_rate(), _film->video_frame_rate()); + frc = FrameRateChange (fc->video->video_frame_rate(), _film->video_frame_rate()); } shared_ptr<const DCPContent> dc = dynamic_pointer_cast<const DCPContent> (i); if (dc) { - decoder.reset (new DCPDecoder (dc, _fast)); - frc = FrameRateChange (dc->video_frame_rate(), _film->video_frame_rate()); + decoder.reset (new DCPDecoder (dc, _film->log(), _fast)); + frc = FrameRateChange (dc->video->video_frame_rate(), _film->video_frame_rate()); } /* ImageContent */ @@ -134,10 +134,10 @@ Player::setup_pieces () } if (!decoder) { - decoder.reset (new ImageDecoder (ic)); + decoder.reset (new ImageDecoder (ic, _film->log())); } - frc = FrameRateChange (ic->video_frame_rate(), _film->video_frame_rate()); + frc = FrameRateChange (ic->video->video_frame_rate(), _film->video_frame_rate()); } /* SndfileContent */ @@ -147,22 +147,21 @@ Player::setup_pieces () /* Work out a FrameRateChange for the best overlap video for this content */ DCPTime best_overlap_t; - shared_ptr<VideoContent> best_overlap; + shared_ptr<Content> best_overlap; BOOST_FOREACH (shared_ptr<Content> j, _playlist->content ()) { - shared_ptr<VideoContent> vc = dynamic_pointer_cast<VideoContent> (j); - if (!vc) { + if (!j->video) { continue; } - DCPTime const overlap = min (vc->end(), i->end()) - max (vc->position(), i->position()); + DCPTime const overlap = min (j->end(), i->end()) - max (j->position(), i->position()); if (overlap > best_overlap_t) { - best_overlap = vc; + best_overlap = j; best_overlap_t = overlap; } } if (best_overlap) { - frc = FrameRateChange (best_overlap->video_frame_rate(), _film->video_frame_rate ()); + frc = FrameRateChange (best_overlap->video->video_frame_rate(), _film->video_frame_rate ()); } else { /* No video overlap; e.g. if the DCP is just audio */ frc = FrameRateChange (_film->video_frame_rate(), _film->video_frame_rate ()); @@ -397,17 +396,15 @@ Player::get_video (DCPTime time, bool accurate) } else { /* Some video content at this time */ shared_ptr<Piece> last = *(ov.rbegin ()); - VideoFrameType const last_type = dynamic_pointer_cast<VideoContent> (last->content)->video_frame_type (); + VideoFrameType const last_type = last->content->video->video_frame_type (); /* Get video from appropriate piece(s) */ BOOST_FOREACH (shared_ptr<Piece> piece, ov) { shared_ptr<VideoDecoder> decoder = dynamic_pointer_cast<VideoDecoder> (piece->decoder); DCPOMATIC_ASSERT (decoder); - shared_ptr<VideoContent> video_content = dynamic_pointer_cast<VideoContent> (piece->content); - DCPOMATIC_ASSERT (video_content); - shared_ptr<DCPContent> dcp_content = dynamic_pointer_cast<DCPContent> (video_content); + shared_ptr<DCPContent> dcp_content = dynamic_pointer_cast<DCPContent> (piece->content); if (dcp_content && dcp_content->reference_video () && !_play_referenced) { continue; } @@ -416,8 +413,8 @@ Player::get_video (DCPTime time, bool accurate) /* always use the last video */ piece == last || /* with a corresponding L/R eye if appropriate */ - (last_type == VIDEO_FRAME_TYPE_3D_LEFT && video_content->video_frame_type() == VIDEO_FRAME_TYPE_3D_RIGHT) || - (last_type == VIDEO_FRAME_TYPE_3D_RIGHT && video_content->video_frame_type() == VIDEO_FRAME_TYPE_3D_LEFT); + (last_type == VIDEO_FRAME_TYPE_3D_LEFT && piece->content->video->video_frame_type() == VIDEO_FRAME_TYPE_3D_RIGHT) || + (last_type == VIDEO_FRAME_TYPE_3D_RIGHT && piece->content->video->video_frame_type() == VIDEO_FRAME_TYPE_3D_LEFT); if (use) { /* We want to use this piece */ @@ -425,7 +422,9 @@ Player::get_video (DCPTime time, bool accurate) if (content_video.empty ()) { pvf.push_back (black_player_video_frame (time)); } else { - dcp::Size image_size = video_content->scale().size (video_content, _video_container_size, _film->frame_size ()); + dcp::Size image_size = piece->content->video->scale().size ( + piece->content->video, _video_container_size, _film->frame_size () + ); for (list<ContentVideo>::const_iterator i = content_video.begin(); i != content_video.end(); ++i) { pvf.push_back ( @@ -433,13 +432,13 @@ Player::get_video (DCPTime time, bool accurate) new PlayerVideo ( i->image, content_video_to_dcp (piece, i->frame), - video_content->crop (), - video_content->fade (i->frame), + piece->content->video->crop (), + piece->content->video->fade (i->frame), image_size, _video_container_size, i->eyes, i->part, - video_content->colour_conversion () + piece->content->video->colour_conversion () ) ) ); @@ -770,7 +769,7 @@ Player::get_reel_assets () scoped_ptr<DCPDecoder> decoder; try { - decoder.reset (new DCPDecoder (j, false)); + decoder.reset (new DCPDecoder (j, _film->log(), false)); } catch (...) { return a; } diff --git a/src/lib/playlist.cc b/src/lib/playlist.cc index 82a4666cd..f03f8a9a1 100644 --- a/src/lib/playlist.cc +++ b/src/lib/playlist.cc @@ -110,20 +110,19 @@ Playlist::maybe_sequence () DCPTime next_left; DCPTime next_right; BOOST_FOREACH (shared_ptr<Content> i, _content) { - shared_ptr<VideoContent> vc = dynamic_pointer_cast<VideoContent> (i); - if (!vc) { + if (!i->video) { continue; } - if (vc->video_frame_type() == VIDEO_FRAME_TYPE_3D_RIGHT) { - vc->set_position (next_right); - next_right = vc->end(); + if (i->video->video_frame_type() == VIDEO_FRAME_TYPE_3D_RIGHT) { + i->set_position (next_right); + next_right = i->end(); } else { - vc->set_position (next_left); - next_left = vc->end(); + i->set_position (next_left); + next_left = i->end(); } - placed.push_back (vc); + placed.push_back (i); } /* Subtitles */ @@ -271,15 +270,14 @@ Playlist::best_dcp_frame_rate () const float this_error = 0; BOOST_FOREACH (shared_ptr<Content> j, _content) { - shared_ptr<VideoContent> vc = dynamic_pointer_cast<VideoContent> (j); - if (!vc || !vc->has_own_video_frame_rate()) { + if (!j->video || !j->video->has_own_video_frame_rate()) { continue; } /* Best error for this content; we could use the content as-is or double its rate */ float best_error = min ( - float (fabs (i->source - vc->video_frame_rate ())), - float (fabs (i->source - vc->video_frame_rate () * 2)) + float (fabs (i->source - j->video->video_frame_rate ())), + float (fabs (i->source - j->video->video_frame_rate () * 2)) ); /* Use the largest difference between DCP and source as the "error" */ @@ -373,16 +371,15 @@ FrameRateChange Playlist::active_frame_rate_change (DCPTime t, int dcp_video_frame_rate) const { for (ContentList::const_reverse_iterator i = _content.rbegin(); i != _content.rend(); ++i) { - shared_ptr<const VideoContent> vc = dynamic_pointer_cast<const VideoContent> (*i); - if (!vc) { + if (!(*i)->video) { continue; } - if (vc->position() <= t) { + if ((*i)->position() <= t) { /* This is the first piece of content (going backwards...) that starts before t, so it's the active one. */ - return FrameRateChange (vc->video_frame_rate(), dcp_video_frame_rate); + return FrameRateChange ((*i)->video->video_frame_rate(), dcp_video_frame_rate); } } @@ -403,9 +400,9 @@ ContentSorter::operator() (shared_ptr<Content> a, shared_ptr<Content> b) } /* Put video before audio if they start at the same time */ - if (dynamic_pointer_cast<VideoContent>(a) && !dynamic_pointer_cast<VideoContent>(b)) { + if (a->video && !b->video) { return true; - } else if (!dynamic_pointer_cast<VideoContent>(a) && dynamic_pointer_cast<VideoContent>(b)) { + } else if (!a->video && b->video) { return false; } diff --git a/src/lib/types.h b/src/lib/types.h index 105432f83..33bad1d24 100644 --- a/src/lib/types.h +++ b/src/lib/types.h @@ -48,7 +48,6 @@ namespace xmlpp { #define SERVER_LINK_VERSION (64+0) typedef std::vector<boost::shared_ptr<Content> > ContentList; -typedef std::vector<boost::shared_ptr<VideoContent> > VideoContentList; typedef std::vector<boost::shared_ptr<AudioContent> > AudioContentList; typedef std::vector<boost::shared_ptr<SubtitleContent> > SubtitleContentList; typedef std::vector<boost::shared_ptr<FFmpegContent> > FFmpegContentList; diff --git a/src/lib/video_content.cc b/src/lib/video_content.cc index 91701415e..708edee76 100644 --- a/src/lib/video_content.cc +++ b/src/lib/video_content.cc @@ -18,6 +18,7 @@ */ #include "video_content.h" +#include "content.h" #include "video_examiner.h" #include "compose.hpp" #include "ratio.h" @@ -63,8 +64,9 @@ using boost::shared_ptr; using boost::optional; using boost::dynamic_pointer_cast; -VideoContent::VideoContent (shared_ptr<const Film> film) - : _film (film) +VideoContent::VideoContent (Content* parent, shared_ptr<const Film> film) + : _parent (parent) + , _film (film) , _video_length (0) , _video_frame_type (VIDEO_FRAME_TYPE_2D) , _scale (VideoContentScale (Ratio::from_id ("178"))) @@ -75,8 +77,9 @@ VideoContent::VideoContent (shared_ptr<const Film> film) } -VideoContent::VideoContent (shared_ptr<const Film> film, cxml::ConstNodePtr node, int version) - : _film (film) +VideoContent::VideoContent (Content* parent, shared_ptr<const Film> film, cxml::ConstNodePtr node, int version) + : _parent (parent) + , _film (film) { _video_size.width = node->number_child<int> ("VideoWidth"); _video_size.height = node->number_child<int> ("VideoHeight"); @@ -113,8 +116,9 @@ VideoContent::VideoContent (shared_ptr<const Film> film, cxml::ConstNodePtr node } } -VideoContent::VideoContent (shared_ptr<const Film> film, vector<shared_ptr<Content> > c) - : _film (film) +VideoContent::VideoContent (Content* parent, shared_ptr<const Film> film, vector<shared_ptr<Content> > c) + : _parent (parent) + , _film (film) , _video_length (0) , _yuv (false) { @@ -229,10 +233,10 @@ VideoContent::take_from_video_examiner (shared_ptr<VideoExaminer> d) DCPOMATIC_ASSERT (film); LOG_GENERAL ("Video length obtained from header as %1 frames", _video_length); - signal_changed (VideoContentProperty::VIDEO_SIZE); - signal_changed (VideoContentProperty::VIDEO_FRAME_RATE); - signal_changed (VideoContentProperty::VIDEO_SCALE); - signal_changed (ContentProperty::LENGTH); + _parent->signal_changed (VideoContentProperty::VIDEO_SIZE); + _parent->signal_changed (VideoContentProperty::VIDEO_FRAME_RATE); + _parent->signal_changed (VideoContentProperty::VIDEO_SCALE); + _parent->signal_changed (ContentProperty::LENGTH); } void @@ -248,7 +252,7 @@ VideoContent::set_left_crop (int c) _crop.left = c; } - signal_changed (VideoContentProperty::VIDEO_CROP); + _parent->signal_changed (VideoContentProperty::VIDEO_CROP); } void @@ -263,7 +267,7 @@ VideoContent::set_right_crop (int c) _crop.right = c; } - signal_changed (VideoContentProperty::VIDEO_CROP); + _parent->signal_changed (VideoContentProperty::VIDEO_CROP); } void @@ -278,7 +282,7 @@ VideoContent::set_top_crop (int c) _crop.top = c; } - signal_changed (VideoContentProperty::VIDEO_CROP); + _parent->signal_changed (VideoContentProperty::VIDEO_CROP); } void @@ -293,7 +297,7 @@ VideoContent::set_bottom_crop (int c) _crop.bottom = c; } - signal_changed (VideoContentProperty::VIDEO_CROP); + _parent->signal_changed (VideoContentProperty::VIDEO_CROP); } void @@ -308,7 +312,7 @@ VideoContent::set_scale (VideoContentScale s) _scale = s; } - signal_changed (VideoContentProperty::VIDEO_SCALE); + _parent->signal_changed (VideoContentProperty::VIDEO_SCALE); } /** @return string which includes everything about how this content looks */ @@ -339,7 +343,7 @@ VideoContent::set_video_frame_type (VideoFrameType t) _video_frame_type = t; } - signal_changed (VideoContentProperty::VIDEO_FRAME_TYPE); + _parent->signal_changed (VideoContentProperty::VIDEO_FRAME_TYPE); } string @@ -387,7 +391,7 @@ VideoContent::unset_colour_conversion () _colour_conversion = boost::optional<ColourConversion> (); } - signal_changed (VideoContentProperty::COLOUR_CONVERSION); + _parent->signal_changed (VideoContentProperty::COLOUR_CONVERSION); } void @@ -398,7 +402,7 @@ VideoContent::set_colour_conversion (ColourConversion c) _colour_conversion = c; } - signal_changed (VideoContentProperty::COLOUR_CONVERSION); + _parent->signal_changed (VideoContentProperty::COLOUR_CONVERSION); } void @@ -409,7 +413,7 @@ VideoContent::set_fade_in (Frame t) _fade_in = t; } - signal_changed (VideoContentProperty::VIDEO_FADE_IN); + _parent->signal_changed (VideoContentProperty::VIDEO_FADE_IN); } void @@ -420,7 +424,7 @@ VideoContent::set_fade_out (Frame t) _fade_out = t; } - signal_changed (VideoContentProperty::VIDEO_FADE_OUT); + _parent->signal_changed (VideoContentProperty::VIDEO_FADE_OUT); } /** @return Video size after 3D split and crop */ @@ -470,7 +474,7 @@ VideoContent::set_video_frame_rate (double r) _video_frame_rate = r; } - signal_changed (VideoContentProperty::VIDEO_FRAME_RATE); + _parent->signal_changed (VideoContentProperty::VIDEO_FRAME_RATE); } /** @param f Frame index within the whole (untrimmed) content */ @@ -479,12 +483,12 @@ VideoContent::fade (Frame f) const { DCPOMATIC_ASSERT (f >= 0); - Frame const ts = trim_start().frames_round(video_frame_rate()); + Frame const ts = _parent->trim_start().frames_round(video_frame_rate()); if ((f - ts) < fade_in()) { return double (f - ts) / fade_in(); } - Frame fade_out_start = video_length() - trim_end().frames_round(video_frame_rate()) - fade_out(); + Frame fade_out_start = video_length() - _parent->trim_end().frames_round(video_frame_rate()) - fade_out(); if (f >= fade_out_start) { return 1 - double (f - fade_out_start) / fade_out(); } @@ -529,7 +533,7 @@ VideoContent::processing_description () const shared_ptr<const Film> film = _film.lock (); DCPOMATIC_ASSERT (film); dcp::Size const container_size = film->frame_size (); - dcp::Size const scaled = scale().size (dynamic_pointer_cast<const VideoContent> (shared_from_this ()), container_size, container_size); + dcp::Size const scaled = scale().size (shared_from_this(), container_size, container_size); if (scaled != video_size_after_crop ()) { d << String::compose ( @@ -575,3 +579,14 @@ VideoContent::video_frame_rate () const DCPOMATIC_ASSERT (film); return _video_frame_rate.get_value_or (film->video_frame_rate ()); } + +void +VideoContent::set_video_length (Frame len) +{ + { + boost::mutex::scoped_lock lm (_mutex); + _video_length = len; + } + + _parent->signal_changed (ContentProperty::LENGTH); +} diff --git a/src/lib/video_content.h b/src/lib/video_content.h index b93744053..768f1897d 100644 --- a/src/lib/video_content.h +++ b/src/lib/video_content.h @@ -24,12 +24,15 @@ #include "video_content_scale.h" #include "dcpomatic_time.h" #include "user_property.h" +#include "types.h" #include <boost/thread/mutex.hpp> #include <boost/weak_ptr.hpp> +#include <boost/enable_shared_from_this.hpp> class VideoExaminer; class Ratio; class Film; +class Content; class VideoContentProperty { @@ -44,12 +47,12 @@ public: static int const VIDEO_FADE_OUT; }; -class VideoContent +class VideoContent : public boost::enable_shared_from_this<VideoContent> { public: - VideoContent (boost::shared_ptr<const Film>); - VideoContent (boost::shared_ptr<const Film>, cxml::ConstNodePtr, int); - VideoContent (boost::shared_ptr<const Film>, std::vector<boost::shared_ptr<Content> >); + VideoContent (Content* parent, boost::shared_ptr<const Film>); + VideoContent (Content* parent, boost::shared_ptr<const Film>, cxml::ConstNodePtr, int); + VideoContent (Content* parent, boost::shared_ptr<const Film>, std::vector<boost::shared_ptr<Content> >); void as_xml (xmlpp::Node *) const; std::string technical_summary () const; @@ -174,10 +177,14 @@ public: std::string processing_description () const; -private: + void set_video_length (Frame); + void take_from_video_examiner (boost::shared_ptr<VideoExaminer>); void add_properties (std::list<UserProperty> &) const; +private: + + Content* _parent; boost::weak_ptr<const Film> _film; mutable boost::mutex _mutex; Frame _video_length; diff --git a/src/lib/video_decoder.cc b/src/lib/video_decoder.cc index 0936d1bda..f68f0815c 100644 --- a/src/lib/video_decoder.cc +++ b/src/lib/video_decoder.cc @@ -34,13 +34,14 @@ using std::back_inserter; using boost::shared_ptr; using boost::optional; -VideoDecoder::VideoDecoder (shared_ptr<const VideoContent> c) +VideoDecoder::VideoDecoder (shared_ptr<const VideoContent> c, shared_ptr<Log> log) #ifdef DCPOMATIC_DEBUG : test_gaps (0) , _video_content (c) #else : _video_content (c) #endif + , _log (log) , _last_seek_accurate (true) , _ignore_video (false) { @@ -79,7 +80,7 @@ VideoDecoder::get_video (Frame frame, bool accurate) one after the end of _decoded_video we need to seek. */ - _video_content->film()->log()->log (String::compose ("VD has request for %1", frame), LogEntry::TYPE_DEBUG_DECODE); + _log->log (String::compose ("VD has request for %1", frame), LogEntry::TYPE_DEBUG_DECODE); if (_decoded_video.empty() || frame < _decoded_video.front().frame || frame > (_decoded_video.back().frame + 1)) { seek (ContentTime::from_frames (frame, _video_content->video_frame_rate()), accurate); @@ -252,7 +253,7 @@ VideoDecoder::video (shared_ptr<const ImageProxy> image, Frame frame) return; } - _video_content->film()->log()->log (String::compose ("VD receives %1", frame), LogEntry::TYPE_DEBUG_DECODE); + _log->log (String::compose ("VD receives %1", frame), LogEntry::TYPE_DEBUG_DECODE); /* Work out what we are going to push into _decoded_video next */ list<ContentVideo> to_push; diff --git a/src/lib/video_decoder.h b/src/lib/video_decoder.h index af24b93bc..c787faa04 100644 --- a/src/lib/video_decoder.h +++ b/src/lib/video_decoder.h @@ -34,6 +34,7 @@ class VideoContent; class ImageProxy; class Image; +class Log; /** @class VideoDecoder * @brief Parent for classes which decode video. @@ -41,7 +42,7 @@ class Image; class VideoDecoder : public virtual Decoder { public: - VideoDecoder (boost::shared_ptr<const VideoContent> c); + VideoDecoder (boost::shared_ptr<const VideoContent> c, boost::shared_ptr<Log> log); std::list<ContentVideo> get_video (Frame frame, bool accurate); @@ -66,6 +67,7 @@ protected: void fill_both_eyes (Frame from, Frame to, Eyes); boost::shared_ptr<const VideoContent> _video_content; + boost::shared_ptr<Log> _log; std::list<ContentVideo> _decoded_video; boost::shared_ptr<Image> _black_image; boost::optional<ContentTime> _last_seek_time; |
