diff options
| author | Carl Hetherington <cth@carlh.net> | 2012-12-10 22:20:39 +0000 |
|---|---|---|
| committer | Carl Hetherington <cth@carlh.net> | 2012-12-10 22:20:39 +0000 |
| commit | e9d0d7bf9871b7e7fa8d154535cf0bbc7e7bd466 (patch) | |
| tree | 8d0a7a5c83eaa8cc5899b72151ab68ef0e5a8914 /src/lib | |
| parent | 6a77e41813c542f6f6a6c528941d4b2bdc7eb3ca (diff) | |
Try to allow users to specify that the film's header should be trusted wrt length when building thumbnails, thus speeding up examine-content by a factor of 2-ish.
Diffstat (limited to 'src/lib')
| -rw-r--r-- | src/lib/examine_content_job.cc | 83 | ||||
| -rw-r--r-- | src/lib/ffmpeg_decoder.cc | 6 | ||||
| -rw-r--r-- | src/lib/ffmpeg_decoder.h | 3 | ||||
| -rw-r--r-- | src/lib/film.cc | 2 | ||||
| -rw-r--r-- | src/lib/imagemagick_decoder.h | 5 | ||||
| -rw-r--r-- | src/lib/transcoder.cc | 8 | ||||
| -rw-r--r-- | src/lib/transcoder.h | 4 | ||||
| -rw-r--r-- | src/lib/video_decoder.h | 2 |
8 files changed, 80 insertions, 33 deletions
diff --git a/src/lib/examine_content_job.cc b/src/lib/examine_content_job.cc index 8db74801f..93333605b 100644 --- a/src/lib/examine_content_job.cc +++ b/src/lib/examine_content_job.cc @@ -60,51 +60,78 @@ ExamineContentJob::name () const void ExamineContentJob::run () { - /* Decode the content to get an accurate length */ + float progress_remaining = 1; - /* We don't want to use any existing length here, as progress - will be messed up. + /* Set the film's length to either + a) a length judged by running through the content or + b) the length from a decoder's header. */ - _film->unset_length (); - - shared_ptr<Options> o (new Options ("", "", "")); - o->out_size = Size (512, 512); - o->apply_crop = false; - o->decode_audio = false; - - descend (0.5); - pair<shared_ptr<VideoDecoder>, shared_ptr<AudioDecoder> > decoders = decoder_factory (_film, o, this); + if (!_film->trust_content_header()) { + /* Decode the content to get an accurate length */ + + /* We don't want to use any existing length here, as progress + will be messed up. + */ + _film->unset_length (); + + shared_ptr<Options> o (new Options ("", "", "")); + o->out_size = Size (512, 512); + o->apply_crop = false; + o->decode_audio = false; + + descend (0.5); + + pair<shared_ptr<VideoDecoder>, shared_ptr<AudioDecoder> > decoders = decoder_factory (_film, o, this); + + set_progress_unknown (); + while (!decoders.first->pass()) { + /* keep going */ + } + + _film->set_length (decoders.first->video_frame()); + + _film->log()->log (String::compose ("Video length examined as %1 frames", _film->length().get())); + + ascend (); + + progress_remaining -= 0.5; + + } else { - set_progress_unknown (); - while (!decoders.first->pass()) { - /* keep going */ + /* Get a quick decoder to get the content's length from its header. + It would have been nice to just use the thumbnail transcoder's decoder, + but that's a bit fiddly, and this isn't too expensive. + */ + + shared_ptr<Options> o (new Options ("", "", "")); + o->out_size = Size (1024, 1024); + pair<shared_ptr<VideoDecoder>, shared_ptr<AudioDecoder> > d = decoder_factory (_film, o, 0); + _film->set_length (d.first->length()); + + _film->log()->log (String::compose ("Video length obtained from header as %1 frames", _film->length().get())); } - _film->set_length (decoders.first->video_frame()); - - _film->log()->log (String::compose ("Video length is %1 frames", _film->length())); - - ascend (); - /* Now make thumbnails for it */ - descend (0.5); + descend (progress_remaining); try { - o.reset (new Options (_film->dir ("thumbs"), ".png", "")); + shared_ptr<Options> o (new Options (_film->dir ("thumbs"), ".png", "")); o->out_size = _film->size (); o->apply_crop = false; o->decode_audio = false; - if (_film->length() > 0) { - o->decode_video_skip = _film->length().get() / 128; - } else { - o->decode_video_skip = 0; - } + o->decode_video_skip = _film->length().get() / 128; o->decode_subtitles = true; shared_ptr<ImageMagickEncoder> e (new ImageMagickEncoder (_film, o)); Transcoder w (_film, o, this, e); w.go (); + + /* Now set the film's length from the transcoder's decoder, since we + went to all the trouble of going through the content. + */ + + _film->set_length (w.video_decoder()->video_frame()); } catch (std::exception& e) { diff --git a/src/lib/ffmpeg_decoder.cc b/src/lib/ffmpeg_decoder.cc index ef9c05fa6..fd522a5ac 100644 --- a/src/lib/ffmpeg_decoder.cc +++ b/src/lib/ffmpeg_decoder.cc @@ -629,3 +629,9 @@ FFmpegAudioStream::to_string () const return String::compose ("ffmpeg %1 %2 %3 %4", _id, _sample_rate, _channel_layout, _name); } +/** @return Length (in video frames) according to our content's header */ +SourceFrame +FFmpegDecoder::length () const +{ + return (double(_format_context->duration) / AV_TIME_BASE) * frames_per_second(); +} diff --git a/src/lib/ffmpeg_decoder.h b/src/lib/ffmpeg_decoder.h index 87eebe1ec..1771551fc 100644 --- a/src/lib/ffmpeg_decoder.h +++ b/src/lib/ffmpeg_decoder.h @@ -56,7 +56,7 @@ public: , _name (n) , _id (i) {} - + std::string to_string () const; std::string name () const { @@ -89,6 +89,7 @@ public: float frames_per_second () const; Size native_size () const; + SourceFrame length () const; int time_base_numerator () const; int time_base_denominator () const; int sample_aspect_ratio_numerator () const; diff --git a/src/lib/film.cc b/src/lib/film.cc index 563147f68..e2a4cbeda 100644 --- a/src/lib/film.cc +++ b/src/lib/film.cc @@ -1003,7 +1003,7 @@ Film::set_trust_content_header (bool t) signal_changed (TRUST_CONTENT_HEADER); - if (!_trust_content_header) { + if (!_trust_content_header) && !content().empty()) { /* We just said that we don't trust the content's header */ examine_content (); } diff --git a/src/lib/imagemagick_decoder.h b/src/lib/imagemagick_decoder.h index f636191f2..de49c1b56 100644 --- a/src/lib/imagemagick_decoder.h +++ b/src/lib/imagemagick_decoder.h @@ -35,6 +35,11 @@ public: Size native_size () const; + SourceFrame length () const { + /* We don't know */ + return 0; + } + int audio_channels () const { return 0; } diff --git a/src/lib/transcoder.cc b/src/lib/transcoder.cc index 537b9b664..a7e79b05f 100644 --- a/src/lib/transcoder.cc +++ b/src/lib/transcoder.cc @@ -64,7 +64,9 @@ Transcoder::Transcoder (shared_ptr<Film> f, shared_ptr<const Options> o, Job* j, /* Set up the decoder to use the film's set streams */ _decoders.first->set_subtitle_stream (f->subtitle_stream ()); - _decoders.second->set_audio_stream (f->audio_stream ()); + if (_decoders.second) { + _decoders.second->set_audio_stream (f->audio_stream ()); + } if (_matcher) { _decoders.first->connect_video (_matcher); @@ -73,7 +75,7 @@ Transcoder::Transcoder (shared_ptr<Film> f, shared_ptr<const Options> o, Job* j, _decoders.first->connect_video (_encoder); } - if (_matcher && _delay_line) { + if (_matcher && _delay_line && _decoders.second) { _decoders.second->connect_audio (_delay_line); _delay_line->connect_audio (_matcher); _matcher->connect_audio (_gain); @@ -97,7 +99,7 @@ Transcoder::go () _decoders.first->set_progress (); } - if (!done[1] && dynamic_pointer_cast<Decoder> (_decoders.second) != dynamic_pointer_cast<Decoder> (_decoders.first)) { + if (!done[1] && _decoders.second && dynamic_pointer_cast<Decoder> (_decoders.second) != dynamic_pointer_cast<Decoder> (_decoders.first)) { done[1] = _decoders.second->pass (); } else { done[1] = true; diff --git a/src/lib/transcoder.h b/src/lib/transcoder.h index e3ca2bb32..4a9667b3c 100644 --- a/src/lib/transcoder.h +++ b/src/lib/transcoder.h @@ -49,6 +49,10 @@ public: void go (); + boost::shared_ptr<VideoDecoder> video_decoder () const { + return _decoders.first; + } + protected: /** A Job that is running this Transcoder, or 0 */ Job* _job; diff --git a/src/lib/video_decoder.h b/src/lib/video_decoder.h index ea1899840..685138a58 100644 --- a/src/lib/video_decoder.h +++ b/src/lib/video_decoder.h @@ -33,6 +33,8 @@ public: virtual float frames_per_second () const = 0; /** @return native size in pixels */ virtual Size native_size () const = 0; + /** @return length (in source video frames), according to our content's header */ + virtual SourceFrame length () const = 0; virtual int time_base_numerator () const = 0; virtual int time_base_denominator () const = 0; |
