using boost::shared_ptr;
using boost::optional;
-AudioDecoder::AudioDecoder (Decoder* parent, shared_ptr<const AudioContent> content, shared_ptr<Log> log)
+AudioDecoder::AudioDecoder (Decoder* parent, shared_ptr<const AudioContent> content, shared_ptr<Log> log, bool fast)
: DecoderPart (parent, log)
, _content (content)
+ , _fast (fast)
{
/* Set up _positions so that we have one for each stream */
BOOST_FOREACH (AudioStreamPtr i, content->streams ()) {
);
resampler.reset (new Resampler (stream->frame_rate(), _content->resampled_frame_rate(), stream->channels()));
+ if (_fast) {
+ resampler->set_fast ();
+ }
_resamplers[stream] = resampler;
}
}
class AudioDecoder : public boost::enable_shared_from_this<AudioDecoder>, public DecoderPart
{
public:
- AudioDecoder (Decoder* parent, boost::shared_ptr<const AudioContent> content, boost::shared_ptr<Log> log);
+ AudioDecoder (Decoder* parent, boost::shared_ptr<const AudioContent> content, boost::shared_ptr<Log> log, bool fast);
ContentTime position () const;
void emit (AudioStreamPtr stream, boost::shared_ptr<const AudioBuffers>, ContentTime);
/** Frame after the last one that was emitted from Data for each AudioStream */
std::map<AudioStreamPtr, Frame> _positions;
std::map<AudioStreamPtr, boost::shared_ptr<Resampler> > _resamplers;
+
+ bool _fast;
};
#endif
{
shared_ptr<DCPDecoder> decoder;
try {
- decoder.reset (new DCPDecoder (shared_from_this(), film()->log()));
+ decoder.reset (new DCPDecoder (shared_from_this(), film()->log(), false));
} catch (dcp::DCPReadError) {
/* We couldn't read the DCP, so it's probably missing */
return false;
{
shared_ptr<DCPDecoder> decoder;
try {
- decoder.reset (new DCPDecoder (shared_from_this(), film()->log()));
+ decoder.reset (new DCPDecoder (shared_from_this(), film()->log(), false));
} catch (dcp::DCPReadError) {
/* We couldn't read the DCP, so it's probably missing */
return false;
using boost::dynamic_pointer_cast;
using boost::optional;
-DCPDecoder::DCPDecoder (shared_ptr<const DCPContent> c, shared_ptr<Log> log)
+DCPDecoder::DCPDecoder (shared_ptr<const DCPContent> c, shared_ptr<Log> log, bool fast)
: DCP (c)
, _decode_referenced (false)
{
video.reset (new VideoDecoder (this, c, log));
if (c->audio) {
- audio.reset (new AudioDecoder (this, c->audio, log));
+ audio.reset (new AudioDecoder (this, c->audio, log, fast));
}
if (c->subtitle) {
subtitle.reset (new SubtitleDecoder (this, c->subtitle, log));
class DCPDecoder : public DCP, public Decoder
{
public:
- DCPDecoder (boost::shared_ptr<const DCPContent>, boost::shared_ptr<Log> log);
+ DCPDecoder (boost::shared_ptr<const DCPContent>, boost::shared_ptr<Log> log, bool fast);
std::list<boost::shared_ptr<dcp::Reel> > reels () const {
return _reels;
using boost::dynamic_pointer_cast;
shared_ptr<Decoder>
-decoder_factory (shared_ptr<const Content> content, shared_ptr<Log> log)
+decoder_factory (shared_ptr<const Content> content, shared_ptr<Log> log, bool fast)
{
shared_ptr<const FFmpegContent> fc = dynamic_pointer_cast<const FFmpegContent> (content);
if (fc) {
- return shared_ptr<Decoder> (new FFmpegDecoder (fc, log));
+ return shared_ptr<Decoder> (new FFmpegDecoder (fc, log, fast));
}
shared_ptr<const DCPContent> dc = dynamic_pointer_cast<const DCPContent> (content);
if (dc) {
- return shared_ptr<Decoder> (new DCPDecoder (dc, log));
+ return shared_ptr<Decoder> (new DCPDecoder (dc, log, fast));
}
shared_ptr<const ImageContent> ic = dynamic_pointer_cast<const ImageContent> (content);
extern boost::shared_ptr<Decoder> decoder_factory (
boost::shared_ptr<const Content> content,
- boost::shared_ptr<Log> log
+ boost::shared_ptr<Log> log,
+ bool fast
);
using boost::dynamic_pointer_cast;
using dcp::Size;
-FFmpegDecoder::FFmpegDecoder (shared_ptr<const FFmpegContent> c, shared_ptr<Log> log)
+FFmpegDecoder::FFmpegDecoder (shared_ptr<const FFmpegContent> c, shared_ptr<Log> log, bool fast)
: FFmpeg (c)
, _log (log)
, _have_current_subtitle (false)
}
if (c->audio) {
- audio.reset (new AudioDecoder (this, c->audio, log));
+ audio.reset (new AudioDecoder (this, c->audio, log, fast));
}
if (c->subtitle) {
class FFmpegDecoder : public FFmpeg, public Decoder
{
public:
- FFmpegDecoder (boost::shared_ptr<const FFmpegContent>, boost::shared_ptr<Log>);
+ FFmpegDecoder (boost::shared_ptr<const FFmpegContent>, boost::shared_ptr<Log> log, bool fast);
bool pass ();
void seek (ContentTime time, bool);
continue;
}
- shared_ptr<Decoder> decoder = decoder_factory (i, _film->log());
+ shared_ptr<Decoder> decoder = decoder_factory (i, _film->log(), _fast);
FrameRateChange frc (i->active_video_frame_rate(), _film->video_frame_rate());
if (!decoder) {
_always_burn_subtitles = burn;
}
+/** Sets up the player to be faster, possibly at the expense of quality */
void
Player::set_fast ()
{
scoped_ptr<DCPDecoder> decoder;
try {
- decoder.reset (new DCPDecoder (j, _film->log()));
+ decoder.reset (new DCPDecoder (j, _film->log(), false));
} catch (...) {
return a;
}
ContentList c = _parent->selected_subtitle ();
DCPOMATIC_ASSERT (c.size() == 1);
- shared_ptr<Decoder> decoder = decoder_factory (c.front(), _parent->film()->log());
+ shared_ptr<Decoder> decoder = decoder_factory (c.front(), _parent->film()->log(), false);
if (decoder) {
_subtitle_view = new SubtitleView (this, _parent->film(), decoder, c.front()->position ());
film->examine_and_add_content (content);
wait_for_jobs ();
- shared_ptr<DCPDecoder> decoder (new DCPDecoder (content, film->log()));
+ shared_ptr<DCPDecoder> decoder (new DCPDecoder (content, film->log(), false));
decoder->subtitle->TextStart.connect (bind (store, _1));
stored = optional<ContentTextSubtitle> ();
film->examine_and_add_content (content);
wait_for_jobs ();
shared_ptr<Log> log (new NullLog);
- shared_ptr<FFmpegDecoder> decoder (new FFmpegDecoder (content, log));
+ shared_ptr<FFmpegDecoder> decoder (new FFmpegDecoder (content, log, false));
decoder->video->Data.connect (bind (&store, _1));
for (vector<int>::const_iterator i = frames.begin(); i != frames.end(); ++i) {
/* Sound == video so no offset required */
content->_first_video = ContentTime ();
content->ffmpeg_audio_streams().front()->first_audio = ContentTime ();
- FFmpegDecoder decoder (content, film->log());
+ FFmpegDecoder decoder (content, film->log(), false);
BOOST_CHECK_EQUAL (decoder._pts_offset.get(), 0);
}
/* Common offset should be removed */
content->_first_video = ContentTime::from_seconds (600);
content->ffmpeg_audio_streams().front()->first_audio = ContentTime::from_seconds (600);
- FFmpegDecoder decoder (content, film->log());
+ FFmpegDecoder decoder (content, film->log(), false);
BOOST_CHECK_EQUAL (decoder._pts_offset.get(), ContentTime::from_seconds(-600).get());
}
/* Video is on a frame boundary */
content->_first_video = ContentTime::from_frames (1, 24);
content->ffmpeg_audio_streams().front()->first_audio = ContentTime ();
- FFmpegDecoder decoder (content, film->log());
+ FFmpegDecoder decoder (content, film->log(), false);
BOOST_CHECK_EQUAL (decoder._pts_offset.get(), 0);
}
double const frame = 1.0 / 24.0;
content->_first_video = ContentTime::from_seconds (frame + 0.0215);
content->ffmpeg_audio_streams().front()->first_audio = ContentTime ();
- FFmpegDecoder decoder (content, film->log());
+ FFmpegDecoder decoder (content, film->log(), false);
BOOST_CHECK_CLOSE (decoder._pts_offset.seconds(), (frame - 0.0215), 0.00001);
}
double const frame = 1.0 / 24.0;
content->_first_video = ContentTime::from_seconds (frame + 0.0215 + 4.1);
content->ffmpeg_audio_streams().front()->first_audio = ContentTime::from_seconds (4.1);
- FFmpegDecoder decoder (content, film->log());
+ FFmpegDecoder decoder (content, film->log(), false);
BOOST_CHECK_CLOSE (decoder._pts_offset.seconds(), (frame - 0.0215) - 4.1, 0.1);
}
}