summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorCarl Hetherington <cth@carlh.net>2014-05-01 14:32:45 +0100
committerCarl Hetherington <cth@carlh.net>2014-05-01 14:32:45 +0100
commitc98c87afe29d9ef74bdced8a9c96d7752f3fe80f (patch)
tree9fad96b3e680ae368ef7488af80488edd4436394 /src
parentbbbfb3208e74a4de2f9b4540a17ec43d4e3541a3 (diff)
Fix 3D support.
Diffstat (limited to 'src')
-rw-r--r--src/lib/player.cc117
-rw-r--r--src/lib/player.h14
-rw-r--r--src/lib/transcoder.cc6
-rw-r--r--src/lib/video_decoder.cc16
-rw-r--r--src/lib/video_decoder.h4
-rw-r--r--src/tools/server_test.cc2
-rw-r--r--src/wx/film_viewer.cc6
7 files changed, 100 insertions, 65 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;
diff --git a/src/tools/server_test.cc b/src/tools/server_test.cc
index ad3cf9481..ba1669756 100644
--- a/src/tools/server_test.cc
+++ b/src/tools/server_test.cc
@@ -156,7 +156,7 @@ main (int argc, char* argv[])
DCPTime const frame = DCPTime::from_frames (1, film->video_frame_rate ());
for (DCPTime t; t < film->length(); t += frame) {
- process_video (player->get_video (t, true));
+ process_video (player->get_video(t, true).front ());
}
} catch (std::exception& e) {
cerr << "Error: " << e.what() << "\n";
diff --git a/src/wx/film_viewer.cc b/src/wx/film_viewer.cc
index 33af202bc..e517c9cca 100644
--- a/src/wx/film_viewer.cc
+++ b/src/wx/film_viewer.cc
@@ -150,9 +150,9 @@ FilmViewer::get (DCPTime p, bool accurate)
return;
}
- shared_ptr<DCPVideo> dcp_video = _player->get_video (p, accurate);
- if (dcp_video) {
- _frame = dcp_video->image (PIX_FMT_BGRA, true);
+ list<shared_ptr<DCPVideo> > dcp_video = _player->get_video (p, accurate);
+ if (!dcp_video.empty ()) {
+ _frame = dcp_video.front()->image (PIX_FMT_BGRA, true);
_frame = _frame->scale (_frame->size(), Scaler::from_id ("fastbilinear"), PIX_FMT_RGB24, false);
} else {
_frame.reset ();