diff options
| author | Carl Hetherington <cth@carlh.net> | 2014-05-01 14:32:45 +0100 |
|---|---|---|
| committer | Carl Hetherington <cth@carlh.net> | 2014-05-01 14:32:45 +0100 |
| commit | c98c87afe29d9ef74bdced8a9c96d7752f3fe80f (patch) | |
| tree | 9fad96b3e680ae368ef7488af80488edd4436394 /src/lib | |
| parent | bbbfb3208e74a4de2f9b4540a17ec43d4e3541a3 (diff) | |
Fix 3D support.
Diffstat (limited to 'src/lib')
| -rw-r--r-- | src/lib/player.cc | 117 | ||||
| -rw-r--r-- | src/lib/player.h | 14 | ||||
| -rw-r--r-- | src/lib/transcoder.cc | 6 | ||||
| -rw-r--r-- | src/lib/video_decoder.cc | 16 | ||||
| -rw-r--r-- | src/lib/video_decoder.h | 4 |
5 files changed, 96 insertions, 61 deletions
diff --git a/src/lib/player.cc b/src/lib/player.cc index 817a390d6..5fe35e34d 100644 --- a/src/lib/player.cc +++ b/src/lib/player.cc @@ -218,7 +218,7 @@ Player::film_changed (Film::Property p) } list<PositionImage> -Player::process_content_image_subtitles (shared_ptr<SubtitleContent> content, list<shared_ptr<ContentImageSubtitle> > subs) +Player::process_content_image_subtitles (shared_ptr<SubtitleContent> content, list<shared_ptr<ContentImageSubtitle> > subs) const { list<PositionImage> all; @@ -269,7 +269,7 @@ Player::process_content_image_subtitles (shared_ptr<SubtitleContent> content, li } list<PositionImage> -Player::process_content_text_subtitles (list<shared_ptr<ContentTextSubtitle> > sub) +Player::process_content_text_subtitles (list<shared_ptr<ContentTextSubtitle> > sub) const { list<PositionImage> all; for (list<shared_ptr<ContentTextSubtitle> >::const_iterator i = sub.begin(); i != sub.end(); ++i) { @@ -305,45 +305,17 @@ Player::black_dcp_video (DCPTime time) const } shared_ptr<DCPVideo> -Player::get_video (DCPTime time, bool accurate) +Player::content_to_dcp ( + shared_ptr<VideoContent> content, + ContentVideo content_video, + list<shared_ptr<Piece> > subs, + DCPTime time, + dcp::Size image_size) const { - if (!_have_valid_pieces) { - setup_pieces (); - } - - list<shared_ptr<Piece> > ov = overlaps<VideoContent> ( - time, - time + DCPTime::from_frames (1, _film->video_frame_rate ()) - ); - - if (ov.empty ()) { - /* No video content at this time */ - return black_dcp_video (time); - } - - /* Create a DCPVideo from the content's video at this time */ - - shared_ptr<Piece> piece = ov.back (); - shared_ptr<VideoDecoder> decoder = dynamic_pointer_cast<VideoDecoder> (piece->decoder); - assert (decoder); - shared_ptr<VideoContent> content = dynamic_pointer_cast<VideoContent> (piece->content); - assert (content); - - optional<ContentVideo> dec = decoder->get_video (dcp_to_content_video (piece, time), accurate); - if (!dec) { - return black_dcp_video (time); - } - - dcp::Size image_size = content->scale().size (content, _video_container_size, _film->frame_size ()); - if (_approximate_size) { - image_size.width &= ~3; - image_size.height &= ~3; - } - shared_ptr<DCPVideo> dcp_video ( new DCPVideo ( - dec->image, - dec->eyes, + content_video.image, + content_video.eyes, content->crop (), image_size, _video_container_size, @@ -352,17 +324,13 @@ Player::get_video (DCPTime time, bool accurate) time ) ); - + + /* Add subtitles */ - - ov = overlaps<SubtitleContent> ( - time, - time + DCPTime::from_frames (1, _film->video_frame_rate ()) - ); list<PositionImage> sub_images; - for (list<shared_ptr<Piece> >::const_iterator i = ov.begin(); i != ov.end(); ++i) { + for (list<shared_ptr<Piece> >::const_iterator i = subs.begin(); i != subs.end(); ++i) { shared_ptr<SubtitleDecoder> subtitle_decoder = dynamic_pointer_cast<SubtitleDecoder> ((*i)->decoder); shared_ptr<SubtitleContent> subtitle_content = dynamic_pointer_cast<SubtitleContent> ((*i)->content); ContentTime const from = dcp_to_content_subtitle (*i, time); @@ -374,10 +342,10 @@ Player::get_video (DCPTime time, bool accurate) subtitle_content, image_subtitles ); - + copy (im.begin(), im.end(), back_inserter (sub_images)); } - + if (_burn_subtitles) { list<shared_ptr<ContentTextSubtitle> > text_subtitles = subtitle_decoder->get_text_subtitles (from, to); if (!text_subtitles.empty ()) { @@ -386,7 +354,7 @@ Player::get_video (DCPTime time, bool accurate) } } } - + if (!sub_images.empty ()) { dcp_video->set_subtitle (merge (sub_images)); } @@ -394,6 +362,59 @@ Player::get_video (DCPTime time, bool accurate) return dcp_video; } +/** @return All DCPVideo at the given time (there may be two frames for 3D) */ +list<shared_ptr<DCPVideo> > +Player::get_video (DCPTime time, bool accurate) +{ + if (!_have_valid_pieces) { + setup_pieces (); + } + + list<shared_ptr<Piece> > ov = overlaps<VideoContent> ( + time, + time + DCPTime::from_frames (1, _film->video_frame_rate ()) + ); + + list<shared_ptr<DCPVideo> > dcp_video; + + if (ov.empty ()) { + /* No video content at this time */ + dcp_video.push_back (black_dcp_video (time)); + return dcp_video; + } + + /* Create a DCPVideo from the content's video at this time */ + + shared_ptr<Piece> piece = ov.back (); + shared_ptr<VideoDecoder> decoder = dynamic_pointer_cast<VideoDecoder> (piece->decoder); + assert (decoder); + shared_ptr<VideoContent> content = dynamic_pointer_cast<VideoContent> (piece->content); + assert (content); + + list<ContentVideo> content_video = decoder->get_video (dcp_to_content_video (piece, time), accurate); + if (content_video.empty ()) { + dcp_video.push_back (black_dcp_video (time)); + return dcp_video; + } + + dcp::Size image_size = content->scale().size (content, _video_container_size, _film->frame_size ()); + if (_approximate_size) { + image_size.width &= ~3; + image_size.height &= ~3; + } + + for (list<ContentVideo>::const_iterator i = content_video.begin(); i != content_video.end(); ++i) { + list<shared_ptr<Piece> > subs = overlaps<SubtitleContent> ( + time, + time + DCPTime::from_frames (1, _film->video_frame_rate ()) + ); + + dcp_video.push_back (content_to_dcp (content, *i, subs, time, image_size)); + } + + return dcp_video; +} + shared_ptr<AudioBuffers> Player::get_audio (DCPTime time, DCPTime length, bool accurate) { diff --git a/src/lib/player.h b/src/lib/player.h index b70bd3f64..9151d20c5 100644 --- a/src/lib/player.h +++ b/src/lib/player.h @@ -32,6 +32,7 @@ #include "content_subtitle.h" #include "position_image.h" #include "piece.h" +#include "content_video.h" class Job; class Film; @@ -104,7 +105,7 @@ class Player : public boost::enable_shared_from_this<Player>, public boost::nonc public: Player (boost::shared_ptr<const Film>, boost::shared_ptr<const Playlist>); - boost::shared_ptr<DCPVideo> get_video (DCPTime time, bool accurate); + std::list<boost::shared_ptr<DCPVideo> > get_video (DCPTime time, bool accurate); boost::shared_ptr<AudioBuffers> get_audio (DCPTime time, DCPTime length, bool accurate); void set_video_container_size (dcp::Size); @@ -135,13 +136,20 @@ private: void film_changed (Film::Property); std::list<PositionImage> process_content_image_subtitles ( boost::shared_ptr<SubtitleContent>, std::list<boost::shared_ptr<ContentImageSubtitle> > - ); - std::list<PositionImage> process_content_text_subtitles (std::list<boost::shared_ptr<ContentTextSubtitle> >); + ) const; + std::list<PositionImage> process_content_text_subtitles (std::list<boost::shared_ptr<ContentTextSubtitle> >) const; void update_subtitle_from_text (); VideoFrame dcp_to_content_video (boost::shared_ptr<const Piece> piece, DCPTime t) const; AudioFrame dcp_to_content_audio (boost::shared_ptr<const Piece> piece, DCPTime t) const; ContentTime dcp_to_content_subtitle (boost::shared_ptr<const Piece> piece, DCPTime t) const; boost::shared_ptr<DCPVideo> black_dcp_video (DCPTime) const; + boost::shared_ptr<DCPVideo> content_to_dcp ( + boost::shared_ptr<VideoContent> content, + ContentVideo content_video, + std::list<boost::shared_ptr<Piece> > subs, + DCPTime time, + dcp::Size image_size + ) const; /** @return Pieces of content type C that overlap a specified time range in the DCP */ template<class C> diff --git a/src/lib/transcoder.cc b/src/lib/transcoder.cc index 810606391..cc41b4256 100644 --- a/src/lib/transcoder.cc +++ b/src/lib/transcoder.cc @@ -36,6 +36,7 @@ using std::string; using std::cout; +using std::list; using boost::shared_ptr; using boost::weak_ptr; using boost::dynamic_pointer_cast; @@ -60,7 +61,10 @@ Transcoder::go () DCPTime const frame = DCPTime::from_frames (1, _film->video_frame_rate ()); for (DCPTime t; t < _film->length(); t += frame) { - _encoder->process_video (_player->get_video (t, true)); + list<shared_ptr<DCPVideo> > v = _player->get_video (t, true); + for (list<shared_ptr<DCPVideo> >::const_iterator i = v.begin(); i != v.end(); ++i) { + _encoder->process_video (*i); + } _encoder->process_audio (_player->get_audio (t, frame, true)); } diff --git a/src/lib/video_decoder.cc b/src/lib/video_decoder.cc index bd609d168..146120fe1 100644 --- a/src/lib/video_decoder.cc +++ b/src/lib/video_decoder.cc @@ -39,19 +39,21 @@ VideoDecoder::VideoDecoder (shared_ptr<const VideoContent> c) } -optional<ContentVideo> +list<ContentVideo> VideoDecoder::decoded_video (VideoFrame frame) { + list<ContentVideo> output; + for (list<ContentVideo>::const_iterator i = _decoded_video.begin(); i != _decoded_video.end(); ++i) { if (i->frame == frame) { - return *i; + output.push_back (*i); } } - return optional<ContentVideo> (); + return output; } -optional<ContentVideo> +list<ContentVideo> VideoDecoder::get_video (VideoFrame frame, bool accurate) { if (_decoded_video.empty() || (frame < _decoded_video.front().frame || frame > (_decoded_video.back().frame + 1))) { @@ -59,7 +61,7 @@ VideoDecoder::get_video (VideoFrame frame, bool accurate) seek (ContentTime::from_frames (frame, _video_content->video_frame_rate()), accurate); } - optional<ContentVideo> dec; + list<ContentVideo> dec; /* Now enough pass() calls should either: * (a) give us what we want, or @@ -70,7 +72,7 @@ VideoDecoder::get_video (VideoFrame frame, bool accurate) * This could all be one statement but it's split up for clarity. */ while (true) { - if (decoded_video (frame)) { + if (!decoded_video(frame).empty ()) { /* We got what we want */ break; } @@ -94,7 +96,7 @@ VideoDecoder::get_video (VideoFrame frame, bool accurate) /* Any frame will do: use the first one that comes out of pass() */ while (_decoded_video.empty() && !pass ()) {} if (!_decoded_video.empty ()) { - dec = _decoded_video.front (); + dec.push_back (_decoded_video.front ()); } } diff --git a/src/lib/video_decoder.h b/src/lib/video_decoder.h index 8715b9714..685b72bc8 100644 --- a/src/lib/video_decoder.h +++ b/src/lib/video_decoder.h @@ -35,7 +35,7 @@ class VideoDecoder : public virtual Decoder public: VideoDecoder (boost::shared_ptr<const VideoContent> c); - boost::optional<ContentVideo> get_video (VideoFrame frame, bool accurate); + std::list<ContentVideo> get_video (VideoFrame frame, bool accurate); boost::shared_ptr<const VideoContent> video_content () const { return _video_content; @@ -49,7 +49,7 @@ protected: void seek (ContentTime time, bool accurate); void video (boost::shared_ptr<const Image>, VideoFrame frame); - boost::optional<ContentVideo> decoded_video (VideoFrame frame); + std::list<ContentVideo> decoded_video (VideoFrame frame); boost::shared_ptr<const VideoContent> _video_content; std::list<ContentVideo> _decoded_video; |
