From: Carl Hetherington Date: Tue, 9 Apr 2013 22:43:00 +0000 (+0100) Subject: Merge ImageMagick and FFmpeg content into VideoContent list; remove seek_to_last... X-Git-Tag: v2.0.48~1337^2~460 X-Git-Url: https://git.carlh.net/gitweb/?p=dcpomatic.git;a=commitdiff_plain;h=b66010a281acd3e3e58ef7202bce55023fc29d7f Merge ImageMagick and FFmpeg content into VideoContent list; remove seek_to_last hacks. --- diff --git a/run/dvdomatic b/run/dvdomatic index 147c001cd..dbc63d44a 100755 --- a/run/dvdomatic +++ b/run/dvdomatic @@ -3,7 +3,7 @@ export LD_LIBRARY_PATH=build/src/lib:build/src/wx:build/src/asdcplib/src:$LD_LIBRARY_PATH if [ "$1" == "--debug" ]; then shift - gdb --args build/src/tools/dvdomatic "$*" + gdb --args build/src/tools/dvdomatic $* elif [ "$1" == "--valgrind" ]; then shift valgrind --tool="memcheck" build/src/tools/dvdomatic $* @@ -11,5 +11,5 @@ elif [ "$1" == "--i18n" ]; then shift LANGUAGE=fr_FR.UTF8 LANG=fr_FR.UTF8 build/src/tools/dvdomatic "$*" else - build/src/tools/dvdomatic "$*" + build/src/tools/dvdomatic $* fi diff --git a/src/lib/decoder.cc b/src/lib/decoder.cc index c40446919..082ad5076 100644 --- a/src/lib/decoder.cc +++ b/src/lib/decoder.cc @@ -41,7 +41,7 @@ Decoder::Decoder (shared_ptr f) _film_connection = f->Changed.connect (bind (&Decoder::film_changed, this, _1)); } -/** Seek to a position as a source timestamp in seconds. +/** Seek to a position as a content timestamp in seconds. * @return true on error. */ bool @@ -49,12 +49,3 @@ Decoder::seek (double) { throw DecodeError (N_("decoder does not support seek")); } - -/** Seek so that the next frame we will produce is the same as the last one. - * @return true on error. - */ -bool -Decoder::seek_to_last () -{ - throw DecodeError (N_("decoder does not support seek")); -} diff --git a/src/lib/decoder.h b/src/lib/decoder.h index 34accf6c7..0fffef257 100644 --- a/src/lib/decoder.h +++ b/src/lib/decoder.h @@ -56,7 +56,6 @@ public: virtual bool pass () = 0; virtual bool seek (double); - virtual bool seek_to_last (); protected: boost::shared_ptr _film; diff --git a/src/lib/ffmpeg_decoder.cc b/src/lib/ffmpeg_decoder.cc index a0949f635..d0b1de748 100644 --- a/src/lib/ffmpeg_decoder.cc +++ b/src/lib/ffmpeg_decoder.cc @@ -518,22 +518,12 @@ FFmpegDecoder::filter_and_emit_video (AVFrame* frame) bool FFmpegDecoder::seek (double p) { - return do_seek (p, false); -} - -bool -FFmpegDecoder::seek_to_last () -{ - /* This AVSEEK_FLAG_BACKWARD in do_seek is a bit of a hack; without it, if we ask for a seek to the same place as last time + /* This use of AVSEEK_FLAG_BACKWARD is a bit of a hack; without it, if we ask for a seek to the same place as last time (used when we change decoder parameters and want to re-fetch the frame) we end up going forwards rather than staying in the same place. */ - return do_seek (last_source_time(), true); -} - -bool -FFmpegDecoder::do_seek (double p, bool backwards) -{ + bool const backwards = (p == last_content_time()); + int64_t const vt = p / av_q2d (_format_context->streams[_video_stream]->time_base); int const r = av_seek_frame (_format_context, _video_stream, vt, backwards ? AVSEEK_FLAG_BACKWARD : 0); diff --git a/src/lib/ffmpeg_decoder.h b/src/lib/ffmpeg_decoder.h index cd37d20c6..f6a53874a 100644 --- a/src/lib/ffmpeg_decoder.h +++ b/src/lib/ffmpeg_decoder.h @@ -77,7 +77,6 @@ public: } bool seek (double); - bool seek_to_last (); bool pass (); private: @@ -86,7 +85,6 @@ private: FFmpegDecoder (FFmpegDecoder const &); FFmpegDecoder& operator= (FFmpegDecoder const &); - bool do_seek (double p, bool); PixelFormat pixel_format () const; AVSampleFormat audio_sample_format () const; int bytes_per_audio_sample () const; diff --git a/src/lib/film.cc b/src/lib/film.cc index b36dc8f9c..35a07b399 100644 --- a/src/lib/film.cc +++ b/src/lib/film.cc @@ -69,6 +69,7 @@ using std::setfill; using std::min; using std::make_pair; using std::endl; +using std::cout; using std::list; using boost::shared_ptr; using boost::lexical_cast; @@ -1084,7 +1085,6 @@ Film::move_content_earlier (shared_ptr c) --j; swap (*i, *j); - _playlist->setup (_content); } signal_changed (CONTENT); @@ -1107,7 +1107,6 @@ Film::move_content_later (shared_ptr c) } swap (*i, *j); - _playlist->setup (_content); } signal_changed (CONTENT); diff --git a/src/lib/imagemagick_content.cc b/src/lib/imagemagick_content.cc index 59fde40bb..24f6d338d 100644 --- a/src/lib/imagemagick_content.cc +++ b/src/lib/imagemagick_content.cc @@ -32,7 +32,7 @@ ImageMagickContent::ImageMagickContent (boost::filesystem::path f) : Content (f) , VideoContent (f) { - + } ImageMagickContent::ImageMagickContent (shared_ptr node) diff --git a/src/lib/imagemagick_decoder.cc b/src/lib/imagemagick_decoder.cc index 6a2be1a7c..7049b7d6e 100644 --- a/src/lib/imagemagick_decoder.cc +++ b/src/lib/imagemagick_decoder.cc @@ -105,16 +105,6 @@ ImageMagickDecoder::pixel_format () const return PIX_FMT_RGB24; } -bool -ImageMagickDecoder::seek_to_last () -{ - if (_position > 0) { - --_position; - } - - return false; -} - bool ImageMagickDecoder::seek (double t) { diff --git a/src/lib/imagemagick_decoder.h b/src/lib/imagemagick_decoder.h index cb524b44b..52c7bec18 100644 --- a/src/lib/imagemagick_decoder.h +++ b/src/lib/imagemagick_decoder.h @@ -50,7 +50,6 @@ public: } bool seek (double); - bool seek_to_last (); bool pass (); protected: diff --git a/src/lib/player.cc b/src/lib/player.cc index 756c3b854..19899f6da 100644 --- a/src/lib/player.cc +++ b/src/lib/player.cc @@ -20,7 +20,9 @@ #include "player.h" #include "film.h" #include "ffmpeg_decoder.h" +#include "ffmpeg_content.h" #include "imagemagick_decoder.h" +#include "imagemagick_content.h" #include "sndfile_decoder.h" #include "sndfile_content.h" #include "playlist.h" @@ -39,7 +41,6 @@ Player::Player (shared_ptr f, shared_ptr p) , _audio (true) , _subtitles (true) , _have_valid_decoders (false) - , _ffmpeg_decoder_done (false) , _video_sync (true) { _playlist->Changed.connect (bind (&Player::playlist_changed, this)); @@ -74,25 +75,13 @@ Player::pass () bool done = true; - if (_playlist->video_from() == Playlist::VIDEO_FFMPEG || _playlist->audio_from() == Playlist::AUDIO_FFMPEG) { - if (!_ffmpeg_decoder_done) { - if (_ffmpeg_decoder->pass ()) { - _ffmpeg_decoder_done = true; - } else { - done = false; - } + if (_video_decoder != _video_decoders.end ()) { + if ((*_video_decoder)->pass ()) { + _video_decoder++; } - } - - if (_playlist->video_from() == Playlist::VIDEO_IMAGEMAGICK) { - if (_imagemagick_decoder != _imagemagick_decoders.end ()) { - if ((*_imagemagick_decoder)->pass ()) { - _imagemagick_decoder++; - } - - if (_imagemagick_decoder != _imagemagick_decoders.end ()) { - done = false; - } + + if (_video_decoder != _video_decoders.end ()) { + done = false; } } @@ -114,26 +103,18 @@ void Player::set_progress (shared_ptr job) { /* Assume progress can be divined from how far through the video we are */ - switch (_playlist->video_from ()) { - case Playlist::VIDEO_NONE: - break; - case Playlist::VIDEO_FFMPEG: - if (_playlist->video_length ()) { - job->set_progress (float(_ffmpeg_decoder->video_frame()) / _playlist->video_length ()); - } - break; - case Playlist::VIDEO_IMAGEMAGICK: - { - int n = 0; - for (list >::iterator i = _imagemagick_decoders.begin(); i != _imagemagick_decoders.end(); ++i) { - if (_imagemagick_decoder == i) { - job->set_progress (float (n) / _imagemagick_decoders.size ()); - } - ++n; - } - break; + + if (_video_decoder == _video_decoders.end() || !_playlist->video_length()) { + return; } + + ContentVideoFrame p = 0; + list >::iterator i = _video_decoders.begin (); + while (i != _video_decoders.end() && i != _video_decoder) { + p += (*i)->video_length (); } + + job->set_progress (float ((*_video_decoder)->video_frame ()) / _playlist->video_length ()); } void @@ -173,109 +154,67 @@ Player::seek (double t) _have_valid_decoders = true; } - bool r = false; - - switch (_playlist->video_from()) { - case Playlist::VIDEO_NONE: - break; - case Playlist::VIDEO_FFMPEG: - if (!_ffmpeg_decoder || _ffmpeg_decoder->seek (t)) { - r = true; - } - /* We're seeking, so all `all done' bets are off */ - _ffmpeg_decoder_done = false; - break; - case Playlist::VIDEO_IMAGEMAGICK: - /* Find the decoder that contains this position */ - _imagemagick_decoder = _imagemagick_decoders.begin (); - while (_imagemagick_decoder != _imagemagick_decoders.end ()) { - double const this_length = (*_imagemagick_decoder)->video_length() / _film->video_frame_rate (); - if (t < this_length) { - break; - } - t -= this_length; - ++_imagemagick_decoder; + /* Find the decoder that contains this position */ + _video_decoder = _video_decoders.begin (); + while (_video_decoder != _video_decoders.end ()) { + double const this_length = (*_video_decoder)->video_length() / _film->video_frame_rate (); + if (t < this_length) { + break; } - - if (_imagemagick_decoder != _imagemagick_decoders.end()) { - (*_imagemagick_decoder)->seek (t); - } else { - r = true; - } - break; - } - - /* XXX: don't seek audio because we don't need to... */ - - return r; -} - -bool -Player::seek_to_last () -{ - if (!_have_valid_decoders) { - setup_decoders (); - _have_valid_decoders = true; + t -= this_length; + ++_video_decoder; } - - bool r = false; - switch (_playlist->video_from ()) { - case Playlist::VIDEO_NONE: - break; - case Playlist::VIDEO_FFMPEG: - if (!_ffmpeg_decoder || _ffmpeg_decoder->seek_to_last ()) { - r = true; - } - - /* We're seeking, so all `all done' bets are off */ - _ffmpeg_decoder_done = false; - break; - case Playlist::VIDEO_IMAGEMAGICK: - if ((*_imagemagick_decoder)->seek_to_last ()) { - r = true; - } - break; + if (_video_decoder != _video_decoders.end()) { + (*_video_decoder)->seek (t); + } else { + return true; } /* XXX: don't seek audio because we don't need to... */ - return r; + return false; } void Player::setup_decoders () { - if ((_video && _playlist->video_from() == Playlist::VIDEO_FFMPEG) || (_audio && _playlist->audio_from() == Playlist::AUDIO_FFMPEG)) { - _ffmpeg_decoder.reset ( - new FFmpegDecoder ( - _film, - _playlist->ffmpeg(), - _video && _playlist->video_from() == Playlist::VIDEO_FFMPEG, - _audio && _playlist->audio_from() == Playlist::AUDIO_FFMPEG, - _subtitles && _film->with_subtitles(), - _video_sync - ) - ); - } - - if (_video && _playlist->video_from() == Playlist::VIDEO_FFMPEG) { - _ffmpeg_decoder->connect_video (shared_from_this ()); - } + if (_video) { + list > vc = _playlist->video (); + for (list >::iterator i = vc.begin(); i != vc.end(); ++i) { + + shared_ptr d; + + /* XXX: into content? */ + + shared_ptr fc = dynamic_pointer_cast (*i); + if (fc) { + shared_ptr fd ( + new FFmpegDecoder ( + _film, fc, _video, + _audio && _playlist->audio_from() == Playlist::AUDIO_FFMPEG, + _subtitles && _film->with_subtitles(), + _video_sync + ) + ); + + if (_playlist->audio_from() == Playlist::AUDIO_FFMPEG) { + fd->Audio.connect (bind (&Player::process_audio, this, fc, _1)); + } + + d = fd; + } - if (_audio && _playlist->audio_from() == Playlist::AUDIO_FFMPEG) { - _ffmpeg_decoder->Audio.connect (bind (&Player::process_audio, this, _playlist->ffmpeg (), _1)); - } + shared_ptr ic = dynamic_pointer_cast (*i); + if (ic) { + d.reset (new ImageMagickDecoder (_film, ic)); + } - if (_video && _playlist->video_from() == Playlist::VIDEO_IMAGEMAGICK) { - list > ic = _playlist->imagemagick (); - for (list >::iterator i = ic.begin(); i != ic.end(); ++i) { - shared_ptr d (new ImageMagickDecoder (_film, *i)); - _imagemagick_decoders.push_back (d); d->connect_video (shared_from_this ()); + _video_decoders.push_back (d); } - _imagemagick_decoder = _imagemagick_decoders.begin (); + _video_decoder = _video_decoders.begin (); } if (_audio && _playlist->audio_from() == Playlist::AUDIO_SNDFILE) { @@ -297,23 +236,12 @@ Player::disable_video_sync () double Player::last_video_time () const { - switch (_playlist->video_from ()) { - case Playlist::VIDEO_NONE: - return 0; - case Playlist::VIDEO_FFMPEG: - return _ffmpeg_decoder->last_source_time (); - case Playlist::VIDEO_IMAGEMAGICK: - { - double t = 0; - for (list >::const_iterator i = _imagemagick_decoders.begin(); i != _imagemagick_decoder; ++i) { - t += (*i)->video_length() / (*i)->video_frame_rate (); - } - - return t + (*_imagemagick_decoder)->last_source_time (); - } + double t = 0; + for (list >::const_iterator i = _video_decoders.begin(); i != _video_decoder; ++i) { + t += (*i)->video_length() / (*i)->video_frame_rate (); } - return 0; + return t + (*_video_decoder)->last_content_time (); } void @@ -326,6 +254,7 @@ Player::content_changed (weak_ptr w, int p) if (p == VideoContentProperty::VIDEO_LENGTH) { if (dynamic_pointer_cast (c)) { + /* FFmpeg content length changes are serious; we need new decoders */ _have_valid_decoders = false; } } diff --git a/src/lib/player.h b/src/lib/player.h index afc856316..8a82ab298 100644 --- a/src/lib/player.h +++ b/src/lib/player.h @@ -28,8 +28,7 @@ #include "video_sink.h" #include "audio_sink.h" -class FFmpegDecoder; -class ImageMagickDecoder; +class VideoDecoder; class SndfileDecoder; class Job; class Film; @@ -49,7 +48,6 @@ public: bool pass (); void set_progress (boost::shared_ptr); bool seek (double); - bool seek_to_last (); double last_video_time () const; @@ -68,10 +66,8 @@ private: bool _subtitles; bool _have_valid_decoders; - boost::shared_ptr _ffmpeg_decoder; - bool _ffmpeg_decoder_done; - std::list > _imagemagick_decoders; - std::list >::iterator _imagemagick_decoder; + std::list > _video_decoders; + std::list >::iterator _video_decoder; std::list > _sndfile_decoders; boost::shared_ptr _sndfile_buffers; diff --git a/src/lib/playlist.cc b/src/lib/playlist.cc index 3f7905fa9..d26dae730 100644 --- a/src/lib/playlist.cc +++ b/src/lib/playlist.cc @@ -21,9 +21,9 @@ #include "playlist.h" #include "sndfile_content.h" #include "sndfile_decoder.h" -#include "ffmpeg_content.h" +#include "video_content.h" #include "ffmpeg_decoder.h" -#include "imagemagick_content.h" +#include "ffmpeg_content.h" #include "imagemagick_decoder.h" #include "job.h" @@ -31,13 +31,13 @@ using std::list; using std::cout; using std::vector; using std::min; +using std::max; using boost::shared_ptr; using boost::weak_ptr; using boost::dynamic_pointer_cast; Playlist::Playlist () - : _video_from (VIDEO_NONE) - , _audio_from (AUDIO_NONE) + : _audio_from (AUDIO_FFMPEG) { } @@ -45,11 +45,9 @@ Playlist::Playlist () void Playlist::setup (ContentList content) { - _video_from = VIDEO_NONE; - _audio_from = AUDIO_NONE; + _audio_from = AUDIO_FFMPEG; - _ffmpeg.reset (); - _imagemagick.clear (); + _video.clear (); _sndfile.clear (); for (list::iterator i = _content_connections.begin(); i != _content_connections.end(); ++i) { @@ -59,24 +57,11 @@ Playlist::setup (ContentList content) _content_connections.clear (); for (ContentList::const_iterator i = content.begin(); i != content.end(); ++i) { - shared_ptr fc = dynamic_pointer_cast (*i); - if (fc) { - assert (!_ffmpeg); - _ffmpeg = fc; - _video_from = VIDEO_FFMPEG; - if (_audio_from == AUDIO_NONE) { - _audio_from = AUDIO_FFMPEG; - } + shared_ptr vc = dynamic_pointer_cast (*i); + if (vc) { + _video.push_back (vc); } - shared_ptr ic = dynamic_pointer_cast (*i); - if (ic) { - _imagemagick.push_back (ic); - if (_video_from == VIDEO_NONE) { - _video_from = VIDEO_IMAGEMAGICK; - } - } - shared_ptr sc = dynamic_pointer_cast (*i); if (sc) { _sndfile.push_back (sc); @@ -92,53 +77,65 @@ Playlist::setup (ContentList content) ContentAudioFrame Playlist::audio_length () const { + ContentAudioFrame len = 0; + switch (_audio_from) { - case AUDIO_NONE: - return 0; case AUDIO_FFMPEG: - return _ffmpeg->audio_length (); + for (list >::const_iterator i = _video.begin(); i != _video.end(); ++i) { + shared_ptr fc = dynamic_pointer_cast (*i); + if (fc) { + len += fc->audio_length (); + } + } + break; case AUDIO_SNDFILE: - { - ContentAudioFrame l = 0; for (list >::const_iterator i = _sndfile.begin(); i != _sndfile.end(); ++i) { - l += (*i)->audio_length (); + len += (*i)->audio_length (); } - return l; - } + break; } - return 0; + return len; } int Playlist::audio_channels () const { + int channels = 0; + switch (_audio_from) { - case AUDIO_NONE: - return 0; case AUDIO_FFMPEG: - return _ffmpeg->audio_channels (); + for (list >::const_iterator i = _video.begin(); i != _video.end(); ++i) { + shared_ptr fc = dynamic_pointer_cast (*i); + if (fc) { + channels = max (channels, fc->audio_channels ()); + } + } + break; case AUDIO_SNDFILE: - { - int c = 0; for (list >::const_iterator i = _sndfile.begin(); i != _sndfile.end(); ++i) { - c += (*i)->audio_channels (); + channels += (*i)->audio_channels (); } - return c; - } + break; } - return 0; + return channels; } int Playlist::audio_frame_rate () const { + /* XXX: assuming that all content has the same rate */ + switch (_audio_from) { - case AUDIO_NONE: - return 0; case AUDIO_FFMPEG: - return _ffmpeg->audio_frame_rate (); + { + shared_ptr fc = first_ffmpeg (); + if (fc) { + return fc->audio_channels (); + } + break; + } case AUDIO_SNDFILE: return _sndfile.front()->audio_frame_rate (); } @@ -149,11 +146,17 @@ Playlist::audio_frame_rate () const int64_t Playlist::audio_channel_layout () const { + /* XXX: assuming that all content has the same layout */ + switch (_audio_from) { - case AUDIO_NONE: - return 0; case AUDIO_FFMPEG: - return _ffmpeg->audio_channel_layout (); + { + shared_ptr fc = first_ffmpeg (); + if (fc) { + return fc->audio_channel_layout (); + } + break; + } case AUDIO_SNDFILE: /* XXX */ return 0; @@ -165,59 +168,41 @@ Playlist::audio_channel_layout () const float Playlist::video_frame_rate () const { - switch (_video_from) { - case VIDEO_NONE: + if (_video.empty ()) { return 0; - case VIDEO_FFMPEG: - return _ffmpeg->video_frame_rate (); - case VIDEO_IMAGEMAGICK: - return 24; } - - return 0; + + /* XXX: assuming all the same */ + return _video.front()->video_frame_rate (); } libdcp::Size Playlist::video_size () const { - switch (_video_from) { - case VIDEO_NONE: + if (_video.empty ()) { return libdcp::Size (); - case VIDEO_FFMPEG: - return _ffmpeg->video_size (); - case VIDEO_IMAGEMAGICK: - /* XXX */ - return _imagemagick.front()->video_size (); } - return libdcp::Size (); + /* XXX: assuming all the same */ + return _video.front()->video_size (); } ContentVideoFrame Playlist::video_length () const { - switch (_video_from) { - case VIDEO_NONE: - return 0; - case VIDEO_FFMPEG: - return _ffmpeg->video_length (); - case VIDEO_IMAGEMAGICK: - { - ContentVideoFrame l = 0; - for (list >::const_iterator i = _imagemagick.begin(); i != _imagemagick.end(); ++i) { - l += (*i)->video_length (); - } - return l; + ContentVideoFrame len = 0; + for (list >::const_iterator i = _video.begin(); i != _video.end(); ++i) { + len += (*i)->video_length (); } - } - - return 0; + + return len; } bool Playlist::has_audio () const { - return _audio_from != AUDIO_NONE; + /* XXX */ + return true; } void @@ -226,32 +211,51 @@ Playlist::content_changed (weak_ptr c, int p) ContentChanged (c, p); } +shared_ptr +Playlist::first_ffmpeg () const +{ + for (list >::const_iterator i = _video.begin(); i != _video.end(); ++i) { + shared_ptr fc = dynamic_pointer_cast (*i); + if (fc) { + return fc; + } + } + + return shared_ptr (); +} + + AudioMapping Playlist::default_audio_mapping () const { AudioMapping m; switch (_audio_from) { - case AUDIO_NONE: - break; case AUDIO_FFMPEG: - if (_ffmpeg->audio_channels() == 1) { + { + shared_ptr fc = first_ffmpeg (); + if (!fc) { + break; + } + + /* XXX: assumes all the same */ + if (fc->audio_channels() == 1) { /* Map mono sources to centre */ - m.add (AudioMapping::Channel (_ffmpeg, 0), libdcp::CENTRE); + m.add (AudioMapping::Channel (fc, 0), libdcp::CENTRE); } else { - int const N = min (_ffmpeg->audio_channels (), MAX_AUDIO_CHANNELS); + int const N = min (fc->audio_channels (), MAX_AUDIO_CHANNELS); /* Otherwise just start with a 1:1 mapping */ for (int i = 0; i < N; ++i) { - m.add (AudioMapping::Channel (_ffmpeg, i), (libdcp::Channel) i); + m.add (AudioMapping::Channel (fc, i), (libdcp::Channel) i); } } break; + } case AUDIO_SNDFILE: { int n = 0; for (list >::const_iterator i = _sndfile.begin(); i != _sndfile.end(); ++i) { - cout << "sndfile " << (*i)->audio_channels() << "\n"; for (int j = 0; j < (*i)->audio_channels(); ++j) { m.add (AudioMapping::Channel (*i, j), (libdcp::Channel) n); ++n; diff --git a/src/lib/playlist.h b/src/lib/playlist.h index 1d189cb07..4dd27f675 100644 --- a/src/lib/playlist.h +++ b/src/lib/playlist.h @@ -56,32 +56,17 @@ public: AudioMapping default_audio_mapping () const; - enum VideoFrom { - VIDEO_NONE, - VIDEO_FFMPEG, - VIDEO_IMAGEMAGICK - }; - enum AudioFrom { - AUDIO_NONE, AUDIO_FFMPEG, AUDIO_SNDFILE }; - VideoFrom video_from () const { - return _video_from; - } - AudioFrom audio_from () const { return _audio_from; } - boost::shared_ptr ffmpeg () const { - return _ffmpeg; - } - - std::list > imagemagick () const { - return _imagemagick; + std::list > video () const { + return _video; } std::list > sndfile () const { @@ -93,12 +78,11 @@ public: private: void content_changed (boost::weak_ptr, int); + boost::shared_ptr first_ffmpeg () const; - VideoFrom _video_from; AudioFrom _audio_from; - boost::shared_ptr _ffmpeg; - std::list > _imagemagick; + std::list > _video; std::list > _sndfile; std::list _content_connections; diff --git a/src/lib/video_decoder.cc b/src/lib/video_decoder.cc index fd2b28d7f..99d711693 100644 --- a/src/lib/video_decoder.cc +++ b/src/lib/video_decoder.cc @@ -32,7 +32,7 @@ using boost::optional; VideoDecoder::VideoDecoder (shared_ptr f) : Decoder (f) , _video_frame (0) - , _last_source_time (0) + , _last_content_time (0) { } @@ -88,7 +88,7 @@ VideoDecoder::signal_video (shared_ptr image, bool same, shared_ptr, bool, boost::shared_ptr, double); int _video_frame; - double _last_source_time; + double _last_content_time; boost::shared_ptr _timed_subtitle; diff --git a/src/tools/dvdomatic.cc b/src/tools/dvdomatic.cc index 6c27892b0..239b4a517 100644 --- a/src/tools/dvdomatic.cc +++ b/src/tools/dvdomatic.cc @@ -59,6 +59,7 @@ static FilmViewer* film_viewer = 0; static shared_ptr film; static std::string log_level; static std::string film_to_load; +static std::string film_to_create; static wxMenu* jobs_menu = 0; static wxLocale* locale = 0; @@ -439,13 +440,15 @@ private: #if wxMINOR_VERSION == 9 static const wxCmdLineEntryDesc command_line_description[] = { { wxCMD_LINE_OPTION, "l", "log", "set log level (silent, verbose or timing)", wxCMD_LINE_VAL_STRING, wxCMD_LINE_PARAM_OPTIONAL }, - { wxCMD_LINE_PARAM, 0, 0, "film to load", wxCMD_LINE_VAL_STRING, wxCMD_LINE_PARAM_MULTIPLE | wxCMD_LINE_PARAM_OPTIONAL }, + { wxCMD_LINE_SWITCH, "n", "new", "create new film", wxCMD_LINE_VAL_NONE, wxCMD_LINE_PARAM_OPTIONAL }, + { wxCMD_LINE_PARAM, 0, 0, "film to load or create", wxCMD_LINE_VAL_STRING, wxCMD_LINE_PARAM_MULTIPLE | wxCMD_LINE_PARAM_OPTIONAL }, { wxCMD_LINE_NONE, "", "", "", wxCmdLineParamType (0), 0 } }; #else static const wxCmdLineEntryDesc command_line_description[] = { { wxCMD_LINE_OPTION, wxT("l"), wxT("log"), wxT("set log level (silent, verbose or timing)"), wxCMD_LINE_VAL_STRING, wxCMD_LINE_PARAM_OPTIONAL }, - { wxCMD_LINE_PARAM, 0, 0, wxT("film to load"), wxCMD_LINE_VAL_STRING, wxCMD_LINE_PARAM_MULTIPLE | wxCMD_LINE_PARAM_OPTIONAL }, + { wxCMD_LINE_SWITCH, wxT("n"), wxT("new"), wxT("create new film"), wxCMD_LINE_VAL_NONE, wxCMD_LINE_PARAM_OPTIONAL }, + { wxCMD_LINE_PARAM, 0, 0, wxT("film to load or create"), wxCMD_LINE_VAL_STRING, wxCMD_LINE_PARAM_MULTIPLE | wxCMD_LINE_PARAM_OPTIONAL }, { wxCMD_LINE_NONE, wxT(""), wxT(""), wxT(""), wxCmdLineParamType (0), 0 } }; #endif @@ -525,6 +528,12 @@ class App : public wxApp } } + if (!film_to_create.empty ()) { + film.reset (new Film (film_to_create, false)); + film->log()->set_level (log_level); + film->set_name (boost::filesystem::path (film_to_create).filename().generic_string ()); + } + Frame* f = new Frame (_("DVD-o-matic")); SetTopWindow (f); f->Maximize (); @@ -545,11 +554,15 @@ class App : public wxApp bool OnCmdLineParsed (wxCmdLineParser& parser) { if (parser.GetParamCount() > 0) { - film_to_load = wx_to_std (parser.GetParam(0)); + if (parser.FoundSwitch (wxT ("new"))) { + film_to_create = wx_to_std (parser.GetParam (0)); + } else { + film_to_load = wx_to_std (parser.GetParam(0)); + } } wxString log; - if (parser.Found(wxT("log"), &log)) { + if (parser.Found (wxT ("log"), &log)) { log_level = wx_to_std (log); } diff --git a/src/wx/film_viewer.cc b/src/wx/film_viewer.cc index f8373d3fd..8fca8f370 100644 --- a/src/wx/film_viewer.cc +++ b/src/wx/film_viewer.cc @@ -157,7 +157,7 @@ FilmViewer::set_film (shared_ptr f) void FilmViewer::update_from_decoder () { - if (!_player || _player->seek_to_last ()) { + if (!_player || _player->seek (_player->last_video_time ())) { return; }