*/
virtual bool seek (SourceFrame);
+ boost::signals2::signal<void()> OutputChanged;
+
protected:
/** our Film */
boost::shared_ptr<Film> _film;
setup_video ();
setup_audio ();
setup_subtitle ();
+
+ f->Changed.connect (bind (&FFmpegDecoder::film_changed, this, _1));
}
FFmpegDecoder::~FFmpegDecoder ()
void
FFmpegDecoder::filter_and_emit_video (AVFrame* frame)
{
+ boost::mutex::scoped_lock lm (_filter_graphs_mutex);
+
shared_ptr<FilterGraph> graph;
list<shared_ptr<FilterGraph> >::iterator i = _filter_graphs.begin();
int64_t const t = static_cast<int64_t>(f) / (av_q2d (_format_context->streams[_video_stream]->time_base) * frames_per_second());
int const r = av_seek_frame (_format_context, _video_stream, t, 0);
avcodec_flush_buffers (_video_codec_context);
+
+ if (r >= 0) {
+ OutputChanged ();
+ }
+
return r < 0;
}
_film->log()->log (String::compose ("Frame removed at %1s", out_pts_seconds));
}
}
+
+void
+FFmpegDecoder::film_changed (Film::Property p)
+{
+ switch (p) {
+ case Film::CROP:
+ {
+ boost::mutex::scoped_lock lm (_filter_graphs_mutex);
+ _filter_graphs.clear ();
+ }
+ OutputChanged ();
+ break;
+
+ default:
+ break;
+ }
+}
+
#include <stdint.h>
#include <boost/shared_ptr.hpp>
#include <boost/optional.hpp>
+#include <boost/thread/mutex.hpp>
extern "C" {
#include <libavcodec/avcodec.h>
#include <libpostproc/postprocess.h>
#include "decoder.h"
#include "video_decoder.h"
#include "audio_decoder.h"
+#include "film.h"
struct AVFilterGraph;
struct AVCodecContext;
void maybe_add_subtitle ();
boost::shared_ptr<AudioBuffers> deinterleave_audio (uint8_t* data, int size);
+ void film_changed (Film::Property);
+
std::string stream_name (AVStream* s) const;
AVFormatContext* _format_context;
boost::optional<double> _first_audio;
std::list<boost::shared_ptr<FilterGraph> > _filter_graphs;
+ boost::mutex _filter_graphs_mutex;
};
o->video_sync = false;
_decoders = decoder_factory (_film, o, 0);
_decoders.video->Video.connect (bind (&FilmViewer::process_video, this, _1, _2));
+ _decoders.video->OutputChanged.connect (boost::bind (&FilmViewer::decoder_changed, this));
film_changed (Film::CROP);
film_changed (Film::FORMAT);
}
+void
+FilmViewer::decoder_changed ()
+{
+ shared_ptr<Image> last = _display;
+ while (last == _display) {
+ _decoders.video->pass ();
+ }
+ _panel->Refresh ();
+ _panel->Update ();
+}
+
void
FilmViewer::timer (wxTimerEvent& ev)
{
void
FilmViewer::slider_moved (wxCommandEvent& ev)
{
- if (_decoders.video->seek (_slider->GetValue() * _film->length().get() / 4096)) {
- return;
- }
-
- shared_ptr<Image> last = _display;
- while (last == _display) {
- _decoders.video->pass ();
- }
- _panel->Refresh ();
- _panel->Update ();
+ _decoders.video->seek (_slider->GetValue() * _film->length().get() / 4096);
}
void
void calculate_sizes ();
void check_play_state ();
void update_from_raw ();
+ void decoder_changed ();
boost::shared_ptr<Film> _film;