Some work on cropping in the film viewer; also prevent player from always scaling...
authorCarl Hetherington <cth@carlh.net>
Sun, 16 Jun 2013 13:53:35 +0000 (14:53 +0100)
committerCarl Hetherington <cth@carlh.net>
Sun, 16 Jun 2013 13:53:35 +0000 (14:53 +0100)
src/lib/combiner.cc
src/lib/filter_graph.cc
src/lib/image.cc
src/lib/image.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/image_test.cc

index ca68ef68afb7d11a9834fd6f0f340226c4507e09..44971d135c83116aba5d7a4b4dd3851f78134837 100644 (file)
@@ -34,7 +34,7 @@ Combiner::Combiner ()
 void
 Combiner::process_video (shared_ptr<const Image> image, bool, Time)
 {
-       _image.reset (new SimpleImage (image));
+       _image.reset (new SimpleImage (image, true));
 }
 
 /** Process video for the right half of the frame.
index 472480de300dee5834555ddde7aba22f5fb369a2..b13b232a9a0a5c8405fb9b8d1835120b91a654bb 100644 (file)
@@ -63,11 +63,8 @@ FilterGraph::FilterGraph (shared_ptr<const FFmpegContent> content, libdcp::Size
                filters += ",";
        }
 
-       Crop crop = content->crop ();
-       libdcp::Size cropped_size = _size;
-       cropped_size.width -= crop.left + crop.right;
-       cropped_size.height -= crop.top + crop.bottom;
-       filters += crop_string (Position (crop.left, crop.top), cropped_size);
+       /* XXX; remove */
+       filters += crop_string (Position (), _size);
 
        AVFilterGraph* graph = avfilter_graph_alloc();
        if (graph == 0) {
index 17c969cf2d280fe04e067526066063adb8e59e86..5f7d3f034199f020e6afe714da340663927b862d 100644 (file)
@@ -53,22 +53,28 @@ Image::swap (Image& other)
        std::swap (_pixel_format, other._pixel_format);
 }
 
-/** @param n Component index.
- *  @return Number of lines in the image for the given component.
- */
 int
-Image::lines (int n) const
+Image::line_factor (int n) const
 {
        if (n == 0) {
-               return size().height;
+               return 1;
        }
-       
+
        AVPixFmtDescriptor const * d = av_pix_fmt_desc_get(_pixel_format);
        if (!d) {
                throw PixelFormatError (N_("lines()"), _pixel_format);
        }
        
-       return size().height / pow(2.0f, d->log2_chroma_h);
+       return pow (2.0f, d->log2_chroma_h);
+}
+
+/** @param n Component index.
+ *  @return Number of lines in the image for the given component.
+ */
+int
+Image::lines (int n) const
+{
+       return size().height / line_factor (n);
 }
 
 /** @return Number of components */
@@ -207,9 +213,9 @@ Image::crop (Crop crop, bool aligned) const
        for (int c = 0; c < components(); ++c) {
                int const crop_left_in_bytes = bytes_per_pixel(c) * crop.left;
                int const cropped_width_in_bytes = bytes_per_pixel(c) * cropped_size.width;
-                       
+
                /* Start of the source line, cropped from the top but not the left */
-               uint8_t* in_p = data()[c] + crop.top * stride()[c];
+               uint8_t* in_p = data()[c] + (crop.top / out->line_factor(c)) * stride()[c];
                uint8_t* out_p = out->data()[c];
 
                for (int y = 0; y < out->lines(c); ++y) {
@@ -502,12 +508,11 @@ SimpleImage::SimpleImage (AVFrame* frame)
        }
 }
 
-SimpleImage::SimpleImage (shared_ptr<const Image> other)
+SimpleImage::SimpleImage (shared_ptr<const Image> other, bool aligned)
        : Image (*other.get())
+       , _size (other->size())
+       , _aligned (aligned)
 {
-       _size = other->size ();
-       _aligned = true;
-
        allocate ();
 
        for (int i = 0; i < components(); ++i) {
index f9bda7460327e62706ef2fa3a982c0b4efe478b3..5407ce66e502f8fc7a74d092549a2090eecf81fe 100644 (file)
@@ -69,6 +69,7 @@ public:
        virtual bool aligned () const = 0;
 
        int components () const;
+       int line_factor (int) const;
        int lines (int) const;
 
        boost::shared_ptr<Image> scale_and_convert_to_rgb (libdcp::Size, Scaler const *, bool) const;
@@ -109,7 +110,7 @@ public:
        SimpleImage (AVPixelFormat, libdcp::Size, bool);
        SimpleImage (AVFrame *);
        SimpleImage (SimpleImage const &);
-       SimpleImage (boost::shared_ptr<const Image>);
+       SimpleImage (boost::shared_ptr<const Image>, bool);
        SimpleImage& operator= (SimpleImage const &);
        ~SimpleImage ();
 
index 85b4cbd4f77a1c016605bee7274545c7a9d520af..1931ec0f54e821245397f4ec8c7344938bd814bc 100644 (file)
@@ -382,3 +382,15 @@ Player::playlist_changed ()
 {
        _have_valid_pieces = false;
 }
+
+void
+Player::set_video_container_size (libdcp::Size s)
+{
+       _video_container_size = s;
+       for (list<shared_ptr<Piece> >::iterator i = _pieces.begin(); i != _pieces.end(); ++i) {
+               shared_ptr<VideoDecoder> vd = dynamic_pointer_cast<VideoDecoder> ((*i)->decoder);
+               if (vd) {
+                       vd->set_video_container_size (s);
+               }
+       }
+}
index b004540935ef81f967ec2508184722a4b7be3548..95f419b5e4a6b65d9ad55155b4a31423a7e6680e 100644 (file)
@@ -61,6 +61,8 @@ public:
                return _position;
        }
 
+       void set_video_container_size (libdcp::Size);
+
 private:
 
        void process_video (boost::weak_ptr<Content>, boost::shared_ptr<const Image>, bool, Time);
@@ -86,6 +88,7 @@ private:
        Time _position;
        AudioBuffers _audio_buffers;
        Time _next_audio;
+       boost::optional<libdcp::Size> _video_container_size;
 };
 
 #endif
index d1a8fc6e66c172edcb3e82168392517cb0a76ca6..58aceb4077cfc4ebfc9fdecc0bf2e2b90ad90681 100644 (file)
@@ -56,7 +56,7 @@ VideoDecoder::video (shared_ptr<Image> image, bool same, Time t)
        shared_ptr<const Film> film = _film.lock ();
        assert (film);
        
-       libdcp::Size const container_size = film->container()->size (film->full_frame ());
+       libdcp::Size const container_size = _video_container_size.get_value_or (film->container()->size (film->full_frame ()));
        libdcp::Size const image_size = _video_content->ratio()->size (container_size);
        
        shared_ptr<Image> out = image->scale_and_convert_to_rgb (image_size, film->scaler(), true);
@@ -144,4 +144,8 @@ VideoDecoder::seek_forward ()
        _next_video += film->video_frames_to_time (1);
 }
 
-       
+void
+VideoDecoder::set_video_container_size (libdcp::Size s)
+{
+       _video_container_size = s;
+}
index b47d7fc3a3fb56909e9a120d216a9207e6b00571..f0d140d803149b314202d462797f7360f4dfa00c 100644 (file)
@@ -44,6 +44,8 @@ public:
        /** @return length according to our content's header */
        virtual ContentVideoFrame video_length () const = 0;
 
+       void set_video_container_size (libdcp::Size);
+
 protected:
        
        void video (boost::shared_ptr<Image>, bool, Time);
@@ -57,6 +59,7 @@ private:
        boost::shared_ptr<TimedSubtitle> _timed_subtitle;
        FrameRateConversion _frame_rate_conversion;
        bool _odd;
+       boost::optional<libdcp::Size> _video_container_size;
 };
 
 #endif
index 8f4278c488f67bcdffd06a151b0ab4cc345f5b5e..3385aa2b39d805de3da2eac23b04f8a14b4d9f09 100644 (file)
@@ -60,7 +60,6 @@ FilmViewer::FilmViewer (shared_ptr<Film> f, wxWindow* p)
        , _frame (new wxStaticText (this, wxID_ANY, wxT("")))
        , _timecode (new wxStaticText (this, wxID_ANY, wxT("")))
        , _play_button (new wxToggleButton (this, wxID_ANY, _("Play")))
-       , _display_frame_x (0)
        , _got_frame (false)
 {
 #ifndef __WXOSX__
@@ -221,16 +220,9 @@ FilmViewer::paint_panel (wxPaintEvent &)
                return;
        }
 
-       if (_display_frame_x) {
-               dc.SetPen(*wxBLACK_PEN);
-               dc.SetBrush(*wxBLACK_BRUSH);
-               dc.DrawRectangle (0, 0, _display_frame_x, _film_size.height);
-               dc.DrawRectangle (_display_frame_x + _film_size.width, 0, _display_frame_x, _film_size.height);
-       }
-
-       wxImage frame (_film_size.width, _film_size.height, _display_frame->data()[0], true);
+       wxImage frame (_out_size.width, _out_size.height, _display_frame->data()[0], true);
        wxBitmap frame_bitmap (frame);
-       dc.DrawBitmap (frame_bitmap, _display_frame_x, 0);
+       dc.DrawBitmap (frame_bitmap, 0, 0);
 
        if (_out_size.width < _panel_size.width) {
                wxPen p (GetBackgroundColour ());
@@ -294,7 +286,7 @@ FilmViewer::raw_to_display ()
        }
 
        /* Get a compacted image as we have to feed it to wxWidgets */
-       _display_frame = _raw_frame->scale_and_convert_to_rgb (_film_size, _film->scaler(), false);
+       _display_frame.reset (new SimpleImage (_raw_frame, false));
 }      
 
 void
@@ -319,21 +311,12 @@ FilmViewer::calculate_sizes ()
                _out_size.width = _out_size.height * film_ratio;
        }
 
-       /* Work out how much padding there is in terms of our display; this will be the x position
-          of our _display_frame.
-       */
-       _display_frame_x = 0;
-//     if (format) {
-//             _display_frame_x = static_cast<float> (format->dcp_padding (_film)) * _out_size.width / format->dcp_size().width;
-//     }
-
-       _film_size = _out_size;
-       _film_size.width -= _display_frame_x * 2;
-
        /* Catch silly values */
        if (_out_size.width < 64) {
                _out_size.width = 64;
        }
+
+       _player->set_video_container_size (_out_size);
 }
 
 void
index 39755ed35e57958cc6d38c53a463c1c7ab576586..6c18c7c5bc97b12298fcf9571bf759e6f96afc17 100644 (file)
@@ -90,16 +90,10 @@ private:
 
        boost::shared_ptr<const Image> _raw_frame;
        boost::shared_ptr<const Image> _display_frame;
-       /* The x offset at which we display the actual film content; this corresponds
-          to the film's padding converted to our coordinates.
-       */
-       int _display_frame_x;
        bool _got_frame;
 
        /** Size of our output (including padding if we have any) */
        libdcp::Size _out_size;
-       /** Size that we will make our film (equal to _out_size unless we have padding) */
-       libdcp::Size _film_size;
        /** Size of the panel that we have available */
        libdcp::Size _panel_size;
 };
index a9ec3042aba4b10023625b281b070571e296831f..9dd3a1ba4e656484777dc6c7c4ca22e58afa105d 100644 (file)
@@ -97,3 +97,13 @@ BOOST_AUTO_TEST_CASE (compact_image_test)
        delete t;
        delete u;
 }
+
+BOOST_AUTO_TEST_CASE (crop_image_test)
+{
+       /* This was to check out a bug with valgrind, and is probably not very useful */
+       shared_ptr<SimpleImage> image (new SimpleImage (PIX_FMT_YUV420P, libdcp::Size (16, 16), true));
+       image->make_black ();
+       Crop crop;
+       crop.top = 3;
+       image->crop (crop, false);
+}