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.
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) {
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 */
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) {
}
}
-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) {
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;
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 ();
{
_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);
+ }
+ }
+}
return _position;
}
+ void set_video_container_size (libdcp::Size);
+
private:
void process_video (boost::weak_ptr<Content>, boost::shared_ptr<const Image>, bool, Time);
Time _position;
AudioBuffers _audio_buffers;
Time _next_audio;
+ boost::optional<libdcp::Size> _video_container_size;
};
#endif
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);
_next_video += film->video_frames_to_time (1);
}
-
+void
+VideoDecoder::set_video_container_size (libdcp::Size s)
+{
+ _video_container_size = s;
+}
/** @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);
boost::shared_ptr<TimedSubtitle> _timed_subtitle;
FrameRateConversion _frame_rate_conversion;
bool _odd;
+ boost::optional<libdcp::Size> _video_container_size;
};
#endif
, _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__
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 ());
}
/* 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
_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
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;
};
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);
+}