/*
- Copyright (C) 2012 Carl Hetherington <cth@carlh.net>
+ Copyright (C) 2012-2014 Carl Hetherington <cth@carlh.net>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
#include "lib/examine_content_job.h"
#include "lib/filter.h"
#include "lib/player.h"
+#include "lib/player_video_frame.h"
#include "lib/video_content.h"
-#include "lib/ffmpeg_content.h"
-#include "lib/still_image_content.h"
#include "lib/video_decoder.h"
#include "film_viewer.h"
#include "wx_util.h"
using std::max;
using std::cout;
using std::list;
+using std::bad_alloc;
using std::make_pair;
using boost::shared_ptr;
using boost::dynamic_pointer_cast;
_film = f;
_frame.reset ();
- _queue.clear ();
-
+
_slider->SetValue (0);
set_position_text (0);
return;
}
- _player = f->make_player ();
+ try {
+ _player = f->make_player ();
+ } catch (bad_alloc) {
+ error_dialog (this, _("There is not enough free memory to do that."));
+ _film.reset ();
+ return;
+ }
+
_player->disable_audio ();
- _player->Video.connect (boost::bind (&FilmViewer::process_video, this, _1, _2, _5));
+ _player->Video.connect (boost::bind (&FilmViewer::process_video, this, _1, _3));
_player->Changed.connect (boost::bind (&FilmViewer::player_changed, this, _1));
calculate_sizes ();
*/
_got_frame = false;
- _player->repeat_last_video ();
+ if (!_player->repeat_last_video ()) {
+ fetch_next_frame ();
+ }
+
_panel->Refresh ();
_panel->Update ();
}
return;
}
- shared_ptr<Image> packed_frame (new Image (_frame, false));
-
- wxImage frame (_out_size.width, _out_size.height, packed_frame->data()[0], true);
+ wxImage frame (_out_size.width, _out_size.height, _frame->data()[0], true);
wxBitmap frame_bitmap (frame);
dc.DrawBitmap (frame_bitmap, 0, 0);
FilmViewer::slider_moved ()
{
if (_film && _player) {
- _player->seek (_slider->GetValue() * _film->length() / 4096, false);
+ Time t = _slider->GetValue() * _film->length() / 4096;
+ /* Ensure that we hit the end of the film at the end of the slider */
+ if (t >= _film->length ()) {
+ t = _film->length() - _film->video_frames_to_time (1);
+ }
+ _player->seek (t, false);
fetch_next_frame ();
}
}
}
void
-FilmViewer::process_video (shared_ptr<const Image> image, Eyes eyes, Time t)
+FilmViewer::process_video (shared_ptr<PlayerVideoFrame> pvf, Time t)
{
- if (eyes == EYES_RIGHT) {
- return;
- }
-
- if (_got_frame) {
- /* This is an additional frame emitted by a single pass. Store it. */
- _queue.push_front (make_pair (image, t));
+ if (pvf->eyes() == EYES_RIGHT) {
return;
}
- _frame = image;
+ _frame = pvf->image ();
_got_frame = true;
set_position_text (t);
_got_frame = false;
- if (!_queue.empty ()) {
- process_video (_queue.back().first, EYES_BOTH, _queue.back().second);
- _queue.pop_back ();
- } else {
- try {
- while (!_got_frame && !_player->pass ()) {}
- } catch (DecodeError& e) {
- _play_button->SetValue (false);
- check_play_state ();
- error_dialog (this, wxString::Format (_("Could not decode video for view (%s)"), std_to_wx(e.what()).data()));
- }
+ try {
+ while (!_got_frame && !_player->pass ()) {}
+ } catch (DecodeError& e) {
+ _play_button->SetValue (false);
+ check_play_state ();
+ error_dialog (this, wxString::Format (_("Could not decode video for view (%s)"), std_to_wx(e.what()).data()));
+ } catch (OpenFileError& e) {
+ /* There was a problem opening a content file; we'll let this slide as it
+ probably means a missing content file, which we're already taking care of.
+ */
}
_panel->Refresh ();
if (frequent) {
return;
}
-
+
calculate_sizes ();
fetch_current_frame_again ();
}