X-Git-Url: https://main.carlh.net/gitweb/?a=blobdiff_plain;f=src%2Flib%2Fdcp_decoder.cc;h=e8ace8beedcfb61b2b0604103acd099c64e4b5d0;hb=e03d6f9bc6af9dfa8602c82cc52040a92144deaf;hp=1098bb87a8c94a8df56cf2ca0f3a7d40cd24f72c;hpb=84012cdd64f451891febd36154b7226ea21a899b;p=dcpomatic.git diff --git a/src/lib/dcp_decoder.cc b/src/lib/dcp_decoder.cc index 1098bb87a..e8ace8bee 100644 --- a/src/lib/dcp_decoder.cc +++ b/src/lib/dcp_decoder.cc @@ -1,5 +1,5 @@ /* - Copyright (C) 2014-2018 Carl Hetherington + Copyright (C) 2014-2020 Carl Hetherington This file is part of DCP-o-matic. @@ -28,6 +28,7 @@ #include "ffmpeg_image_proxy.h" #include "image.h" #include "config.h" +#include "frame_interval_checker.h" #include #include #include @@ -60,15 +61,17 @@ DCPDecoder::DCPDecoder (shared_ptr film, shared_ptrvideo) { - video.reset (new VideoDecoder (this, c)); - } - if (c->audio) { - audio.reset (new AudioDecoder (this, c->audio, fast)); - } - BOOST_FOREACH (shared_ptr i, c->text) { - /* XXX: this time here should be the time of the first subtitle, not 0 */ - text.push_back (shared_ptr (new TextDecoder (this, i, ContentTime()))); + if (c->can_be_played()) { + if (c->video) { + video.reset (new VideoDecoder (this, c)); + } + if (c->audio) { + audio.reset (new AudioDecoder (this, c->audio, fast)); + } + BOOST_FOREACH (shared_ptr i, c->text) { + /* XXX: this time here should be the time of the first subtitle, not 0 */ + text.push_back (shared_ptr (new TextDecoder (this, i, ContentTime()))); + } } list > cpl_list = cpls (); @@ -104,7 +107,14 @@ DCPDecoder::DCPDecoder (shared_ptr film, shared_ptrcan_be_played ()) { + if (!_dcp_content->can_be_played()) { + return true; + } + + if (_reel == _reels.end()) { + if (audio) { + audio->flush (); + } return true; } @@ -202,8 +212,14 @@ void DCPDecoder::pass_texts (ContentTime next, dcp::Size size) { list >::const_iterator decoder = text.begin (); + if (decoder == text.end()) { + /* It's possible that there is now a main subtitle but no TextDecoders, for example if + the CPL has just changed but the TextContent's texts have not been recreated yet. + */ + return; + } + if ((*_reel)->main_subtitle()) { - DCPOMATIC_ASSERT (decoder != text.end ()); pass_texts ( next, (*_reel)->main_subtitle()->asset(), @@ -214,8 +230,8 @@ DCPDecoder::pass_texts (ContentTime next, dcp::Size size) ); ++decoder; } + BOOST_FOREACH (shared_ptr i, (*_reel)->closed_captions()) { - DCPOMATIC_ASSERT (decoder != text.end ()); pass_texts ( next, i->asset(), _dcp_content->reference_text(TEXT_CLOSED_CAPTION), i->entry_point(), *decoder, size ); @@ -259,45 +275,20 @@ DCPDecoder::pass_texts ( strings.push_back (*is); } + /* XXX: perhaps these image subs should also be collected together like the string ones are; + this would need to be done both here and in DCPSubtitleDecoder. + */ + shared_ptr ii = dynamic_pointer_cast (i); if (ii) { - FFmpegImageProxy proxy (ii->png_image()); - shared_ptr image = proxy.image().first; - /* set up rect with height and width */ - dcpomatic::Rect rect(0, 0, image->size().width / double(size.width), image->size().height / double(size.height)); - - /* add in position */ - - switch (ii->h_align()) { - case dcp::HALIGN_LEFT: - rect.x += ii->h_position(); - break; - case dcp::HALIGN_CENTER: - rect.x += 0.5 + ii->h_position() - rect.width / 2; - break; - case dcp::HALIGN_RIGHT: - rect.x += 1 - ii->h_position() - rect.width; - break; - } - - switch (ii->v_align()) { - case dcp::VALIGN_TOP: - rect.y += ii->v_position(); - break; - case dcp::VALIGN_CENTER: - rect.y += 0.5 + ii->v_position() - rect.height / 2; - break; - case dcp::VALIGN_BOTTOM: - rect.y += 1 - ii->v_position() - rect.height; - break; - } - - decoder->emit_bitmap ( + emit_subtitle_image ( ContentTimePeriod ( ContentTime::from_frames (_offset - entry_point, vfr) + ContentTime::from_seconds (i->in().as_seconds ()), ContentTime::from_frames (_offset - entry_point, vfr) + ContentTime::from_seconds (i->out().as_seconds ()) ), - image, rect + *ii, + size, + decoder ); } } @@ -425,3 +416,9 @@ DCPDecoder::set_forced_reduction (optional reduction) { _forced_reduction = reduction; } + +ContentTime +DCPDecoder::position () const +{ + return ContentTime::from_frames(_offset, _dcp_content->active_video_frame_rate(film())) + _next; +}