Various small fixes.
authorCarl Hetherington <cth@carlh.net>
Tue, 1 Apr 2014 20:44:06 +0000 (21:44 +0100)
committerCarl Hetherington <cth@carlh.net>
Tue, 1 Apr 2014 20:44:06 +0000 (21:44 +0100)
src/lib/audio_decoder.cc
src/lib/content_video.h
src/lib/player.cc
src/lib/player.h
src/lib/video_decoder.cc
src/lib/video_decoder.h
src/wx/film_viewer.cc
src/wx/film_viewer.h
test/seek_zero_test.cc

index 616abf8464c85d538ae0f0ee16d8db7adb0b0e92..9606c378c62d3babd09cf28c94b131c312aeaf39 100644 (file)
@@ -36,6 +36,7 @@ using boost::shared_ptr;
 
 AudioDecoder::AudioDecoder (shared_ptr<const AudioContent> content)
        : _audio_content (content)
+       , _decoded_audio (shared_ptr<AudioBuffers> (new AudioBuffers (content->audio_channels(), 0)), 0)
 {
        if (content->output_audio_frame_rate() != content->content_audio_frame_rate() && content->audio_channels ()) {
                _resampler.reset (new Resampler (content->content_audio_frame_rate(), content->output_audio_frame_rate(), content->audio_channels ()));
index 96ce5450c2619f21a0213e18aa8624a110311906..20b5b8dec310a066eeb17e8c4a273ec32a826f2e 100644 (file)
 
 */
 
+#ifndef DCPOMATIC_CONTENT_VIDEO_H
+#define DCPOMATIC_CONTENT_VIDEO_H
+
+class Image;
+
 /** @class ContentVideo
  *  @brief A frame of video straight out of some content.
  */
@@ -37,3 +42,5 @@ public:
        Eyes eyes;
        VideoFrame frame;
 };
+
+#endif
index 8902929cc5f33616d15da6a34ff20434633ae75e..02ae4e5c91b1b94b77b40d51c199942ab4ef10a6 100644 (file)
@@ -319,7 +319,8 @@ Player::get_video (DCPTime time, bool accurate)
        shared_ptr<VideoContent> content = dynamic_pointer_cast<VideoContent> (piece->content);
        assert (content);
 
-       shared_ptr<ContentVideo> dec = decoder->get_video (dcp_to_content_video (piece, time), accurate);
+       optional<ContentVideo> dec = decoder->get_video (dcp_to_content_video (piece, time), accurate);
+       assert (dec);
 
        dcp::Size image_size = content->scale().size (content, _video_container_size, _film->frame_size ());
        if (_approximate_size) {
index be5cbddb4a15d051f6793ba4cbf0992d65248128..852e7243f1355546cab3a6dba2252c57bf635f86 100644 (file)
@@ -138,7 +138,7 @@ private:
        {
                std::list<boost::shared_ptr<Piece> > overlaps;
                for (typename std::list<boost::shared_ptr<Piece> >::const_iterator i = _pieces.begin(); i != _pieces.end(); ++i) {
-                       if (boost::dynamic_pointer_cast<C> ((*i)->content) && (*i)->content->position() >= t && (*i)->content->end() < t) {
+                       if (boost::dynamic_pointer_cast<C> ((*i)->content) && (*i)->content->position() <= t && t < (*i)->content->end()) {
                                overlaps.push_back (*i);
                        }
                }
index f3d3a31041583b6a7b0fba7a115b7e29f8d45d7b..34299bd3c1c87d781312e2e80853e3c260d8cb4f 100644 (file)
@@ -34,27 +34,27 @@ VideoDecoder::VideoDecoder (shared_ptr<const VideoContent> c)
 
 }
 
-shared_ptr<ContentVideo>
+optional<ContentVideo>
 VideoDecoder::decoded_video (VideoFrame frame)
 {
-       for (list<shared_ptr<ContentVideo> >::const_iterator i = _decoded_video.begin(); i != _decoded_video.end(); ++i) {
-               if ((*i)->frame == frame) {
+       for (list<ContentVideo>::const_iterator i = _decoded_video.begin(); i != _decoded_video.end(); ++i) {
+               if (i->frame == frame) {
                        return *i;
                }
        }
 
-       return shared_ptr<ContentVideo> ();
+       return optional<ContentVideo> ();
 }
 
-shared_ptr<ContentVideo>
+optional<ContentVideo>
 VideoDecoder::get_video (VideoFrame frame, bool accurate)
 {
-       if (_decoded_video.empty() || (frame < _decoded_video.front()->frame || frame > (_decoded_video.back()->frame + 1))) {
+       if (_decoded_video.empty() || (frame < _decoded_video.front().frame || frame > (_decoded_video.back().frame + 1))) {
                /* Either we have no decoded data, or what we do have is a long way from what we want: seek */
                seek (ContentTime::from_frames (frame, _video_content->video_frame_rate()), accurate);
        }
 
-       shared_ptr<ContentVideo> dec;
+       optional<ContentVideo> dec;
 
        /* Now enough pass() calls will either:
         *  (a) give us what we want, or
@@ -73,7 +73,7 @@ VideoDecoder::get_video (VideoFrame frame, bool accurate)
        }
 
        /* Clean up decoded_video */
-       while (!_decoded_video.empty() && _decoded_video.front()->frame < (frame - 1)) {
+       while (!_decoded_video.empty() && _decoded_video.front().frame < (frame - 1)) {
                _decoded_video.pop_front ();
        }
 
@@ -85,25 +85,37 @@ VideoDecoder::get_video (VideoFrame frame, bool accurate)
 void
 VideoDecoder::video (shared_ptr<const Image> image, VideoFrame frame)
 {
+       /* Fill in gaps */
+       /* XXX: 3D */
+       while (!_decoded_video.empty () && (_decoded_video.back().frame + 1) < frame) {
+               _decoded_video.push_back (
+                       ContentVideo (
+                               _decoded_video.back().image,
+                               _decoded_video.back().eyes,
+                               _decoded_video.back().frame + 1
+                               )
+                       );
+       }
+       
        switch (_video_content->video_frame_type ()) {
        case VIDEO_FRAME_TYPE_2D:
-               _decoded_video.push_back (shared_ptr<ContentVideo> (new ContentVideo (image, EYES_BOTH, frame)));
+               _decoded_video.push_back (ContentVideo (image, EYES_BOTH, frame));
                break;
        case VIDEO_FRAME_TYPE_3D_ALTERNATE:
-               _decoded_video.push_back (shared_ptr<ContentVideo> (new ContentVideo (image, (frame % 2) ? EYES_RIGHT : EYES_LEFT, frame)));
+               _decoded_video.push_back (ContentVideo (image, (frame % 2) ? EYES_RIGHT : EYES_LEFT, frame));
                break;
        case VIDEO_FRAME_TYPE_3D_LEFT_RIGHT:
        {
                int const half = image->size().width / 2;
-               _decoded_video.push_back (shared_ptr<ContentVideo> (new ContentVideo (image->crop (Crop (0, half, 0, 0), true), EYES_LEFT, frame)));
-               _decoded_video.push_back (shared_ptr<ContentVideo> (new ContentVideo (image->crop (Crop (half, 0, 0, 0), true), EYES_RIGHT, frame)));
+               _decoded_video.push_back (ContentVideo (image->crop (Crop (0, half, 0, 0), true), EYES_LEFT, frame));
+               _decoded_video.push_back (ContentVideo (image->crop (Crop (half, 0, 0, 0), true), EYES_RIGHT, frame));
                break;
        }
        case VIDEO_FRAME_TYPE_3D_TOP_BOTTOM:
        {
                int const half = image->size().height / 2;
-               _decoded_video.push_back (shared_ptr<ContentVideo> (new ContentVideo (image->crop (Crop (0, 0, 0, half), true), EYES_LEFT, frame)));
-               _decoded_video.push_back (shared_ptr<ContentVideo> (new ContentVideo (image->crop (Crop (0, 0, half, 0), true), EYES_RIGHT, frame)));
+               _decoded_video.push_back (ContentVideo (image->crop (Crop (0, 0, 0, half), true), EYES_LEFT, frame));
+               _decoded_video.push_back (ContentVideo (image->crop (Crop (0, 0, half, 0), true), EYES_RIGHT, frame));
                break;
        }
        default:
index 7c7ec35b9031c25a01e5e5a6decd2c5b51c9ccaf..86a9489b111338241dc5907cb7d8f9ad0e685229 100644 (file)
 #include "decoder.h"
 #include "video_content.h"
 #include "util.h"
+#include "content_video.h"
 
 class VideoContent;
 class Image;
-class ContentVideo;
 
 class VideoDecoder : public virtual Decoder
 {
 public:
        VideoDecoder (boost::shared_ptr<const VideoContent> c);
 
-       boost::shared_ptr<ContentVideo> get_video (VideoFrame frame, bool accurate);
+       boost::optional<ContentVideo> get_video (VideoFrame frame, bool accurate);
 
        boost::shared_ptr<const VideoContent> video_content () const {
                return _video_content;
@@ -45,10 +45,10 @@ protected:
 
        void seek (ContentTime time, bool accurate);
        void video (boost::shared_ptr<const Image>, VideoFrame frame);
-       boost::shared_ptr<ContentVideo> decoded_video (VideoFrame frame);
+       boost::optional<ContentVideo> decoded_video (VideoFrame frame);
 
        boost::shared_ptr<const VideoContent> _video_content;
-       std::list<boost::shared_ptr<ContentVideo> > _decoded_video;
+       std::list<ContentVideo> _decoded_video;
 };
 
 #endif
index 1d8a1d3227dddb38dd78a66886c5a628ba87d675..33af202bc7164c31efd650fd8c854ad30b697f16 100644 (file)
@@ -122,7 +122,7 @@ FilmViewer::set_film (shared_ptr<Film> f)
        _frame.reset ();
        
        _slider->SetValue (0);
-       set_position_text (DCPTime ());
+       set_position_text ();
        
        if (!_film) {
                return;
@@ -146,6 +146,10 @@ FilmViewer::set_film (shared_ptr<Film> f)
 void
 FilmViewer::get (DCPTime p, bool accurate)
 {
+       if (!_player) {
+               return;
+       }
+
        shared_ptr<DCPVideo> dcp_video = _player->get_video (p, accurate);
        if (dcp_video) {
                _frame = dcp_video->image (PIX_FMT_BGRA, true);
@@ -154,7 +158,9 @@ FilmViewer::get (DCPTime p, bool accurate)
                _frame.reset ();
        }
 
-       set_position_text (p);
+       _position = p;
+       
+       set_position_text ();
        _panel->Refresh ();
        _panel->Update ();
 }
@@ -162,10 +168,6 @@ FilmViewer::get (DCPTime p, bool accurate)
 void
 FilmViewer::timer ()
 {
-       if (!_player) {
-               return;
-       }
-       
        get (_position + DCPTime::from_frames (1, _film->video_frame_rate ()), true);
 
        DCPTime const len = _film->length ();
@@ -214,7 +216,7 @@ FilmViewer::paint_panel ()
 void
 FilmViewer::slider_moved ()
 {
-       if (!_film || !_player) {
+       if (!_film) {
                return;
        }
 
@@ -292,7 +294,7 @@ FilmViewer::check_play_state ()
 }
 
 void
-FilmViewer::set_position_text (DCPTime t)
+FilmViewer::set_position_text ()
 {
        if (!_film) {
                _frame_number->SetLabel ("0");
@@ -302,9 +304,9 @@ FilmViewer::set_position_text (DCPTime t)
                
        double const fps = _film->video_frame_rate ();
        /* Count frame number from 1 ... not sure if this is the best idea */
-       _frame_number->SetLabel (wxString::Format (wxT("%d"), int (rint (t.seconds() * fps)) + 1));
+       _frame_number->SetLabel (wxString::Format (wxT("%d"), int (rint (_position.seconds() * fps)) + 1));
        
-       double w = t.seconds ();
+       double w = _position.seconds ();
        int const h = (w / 3600);
        w -= h * 3600;
        int const m = (w / 60);
@@ -338,10 +340,6 @@ FilmViewer::active_jobs_changed (bool a)
 void
 FilmViewer::back_clicked ()
 {
-       if (!_player) {
-               return;
-       }
-
        DCPTime p = _position - DCPTime::from_frames (1, _film->video_frame_rate ());
        if (p < DCPTime ()) {
                p = DCPTime ();
@@ -353,10 +351,6 @@ FilmViewer::back_clicked ()
 void
 FilmViewer::forward_clicked ()
 {
-       if (!_player) {
-               return;
-       }
-
        get (_position + DCPTime::from_frames (1, _film->video_frame_rate ()), true);
 }
 
index 52876030cc9017a9aa31e8ed64709dd0cd2019bd..207004f29715b6a5958b478df586f24fb5124719 100644 (file)
@@ -1,5 +1,5 @@
 /*
-    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
@@ -52,7 +52,7 @@ private:
        void back_clicked ();
        void forward_clicked ();
        void player_changed (bool);
-       void set_position_text (DCPTime);
+       void set_position_text ();
        void get (DCPTime, bool);
 
        boost::shared_ptr<Film> _film;
index cda4f0729fe1833dc41c67b7b65aa636310ae6bb..150e12d9016e389a6477d731f7d6155608eb24dc 100644 (file)
@@ -1,5 +1,5 @@
 /*
-    Copyright (C) 2013 Carl Hetherington <cth@carlh.net>
+    Copyright (C) 2013-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
@@ -34,6 +34,7 @@
 using std::cout;
 using boost::shared_ptr;
 using boost::dynamic_pointer_cast;
+using boost::optional;
 
 BOOST_AUTO_TEST_CASE (seek_zero_test)
 {
@@ -47,8 +48,8 @@ BOOST_AUTO_TEST_CASE (seek_zero_test)
        wait_for_jobs ();
 
        FFmpegDecoder decoder (content, film->log());
-       shared_ptr<ContentVideo> a = decoder.get_video (0, true);
-       shared_ptr<ContentVideo> b = decoder.get_video (0, true);
+       optional<ContentVideo> a = decoder.get_video (0, true);
+       optional<ContentVideo> b = decoder.get_video (0, true);
        BOOST_CHECK_EQUAL (a->frame, 0);
        BOOST_CHECK_EQUAL (b->frame, 0);
 }