/*
-- 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 "image.h"
#include "exceptions.h"
#include "scaler.h"
+#include "timer.h"
+ #include "i18n.h"
+
using std::string;
using std::min;
using std::cout;
+ using std::cerr;
using boost::shared_ptr;
-using libdcp::Size;
+using dcp::Size;
int
Image::line_factor (int n) const
*/
assert (aligned ());
+ assert (out_size.width >= inter_size.width);
+ assert (out_size.height >= inter_size.height);
+
+ /* Here's an image of out_size */
shared_ptr<Image> out (new Image (out_format, out_size, out_aligned));
out->make_black ();
-
- dcp::Size cropped_size = crop.apply (size ());
- libdcp::Size const cropped_size = crop.apply (size ());
+ /* Size of the image after any crop */
++ dcp::Size const cropped_size = crop.apply (size ());
+
+ /* Scale context for a scale from cropped_size to inter_size */
struct SwsContext* scale_context = sws_getContext (
- cropped_size.width, cropped_size.height, pixel_format(),
- inter_size.width, inter_size.height, out_format,
- scaler->ffmpeg_id (), 0, 0, 0
+ cropped_size.width, cropped_size.height, pixel_format(),
+ inter_size.width, inter_size.height, out_format,
+ scaler->ffmpeg_id (), 0, 0, 0
);
+ if (!scale_context) {
+ throw StringError (N_("Could not allocate SwsContext"));
+ }
+
+ /* Prepare input data pointers with crop */
uint8_t* scale_in_data[components()];
for (int c = 0; c < components(); ++c) {
scale_in_data[c] = data()[c] + int (rint (bytes_per_pixel(c) * crop.left)) + stride()[c] * (crop.top / line_factor(c));
shared_ptr<VideoContent> content = dynamic_pointer_cast<VideoContent> (piece->content);
assert (content);
- FrameRateConversion frc (content->video_frame_rate(), _film->video_frame_rate());
- if (frc.skip && (frame % 2) == 1) {
- return;
- }
+ FrameRateChange frc (content->video_frame_rate(), _film->video_frame_rate());
- float const ratio = content->ratio() ? content->ratio()->ratio() : content->video_size_after_crop().ratio();
- dcp::Size image_size = fit_ratio_within (ratio, _video_container_size);
- Time const relative_time = (frame * frc.factor() * TIME_HZ / _film->video_frame_rate());
- if (content->trimmed (relative_time)) {
- return;
++ dcp::Size const image_size = content->scale().size (content, _video_container_size);
+ if (_approximate_size) {
+ image_size.width &= ~3;
+ image_size.height &= ~3;
}
- Time const time = content->position() + relative_time + extra - content->trim_start ();
- libdcp::Size const image_size = content->scale().size (content, _video_container_size);
-
shared_ptr<PlayerImage> pi (
new PlayerImage (
- image,
+ video->image,
content->crop(),
image_size,
_video_container_size,
set_terminate (terminate);
- libdcp::init ();
+ Pango::init ();
+ dcp::init ();
Ratio::setup_ratios ();
+ VideoContentScale::setup_scales ();
DCPContentType::setup_dcp_content_types ();
Scaler::setup_scalers ();
Filter::setup_filters ();
#include <iomanip>
#include <libcxml/cxml.h>
-#include <libdcp/colour_matrix.h>
+#include <dcp/colour_matrix.h>
#include "video_content.h"
#include "video_examiner.h"
- #include "ratio.h"
#include "compose.hpp"
+ #include "ratio.h"
#include "config.h"
#include "colour_conversion.h"
#include "util.h"
setup_default_colour_conversion ();
}
- VideoContent::VideoContent (shared_ptr<const Film> f, shared_ptr<const cxml::Node> node)
+ VideoContent::VideoContent (shared_ptr<const Film> f, shared_ptr<const cxml::Node> node, int version)
: Content (f, node)
- , _ratio (0)
{
- _video_length = node->number_child<VideoContent::Frame> ("VideoLength");
+ _video_length = ContentTime (node->number_child<int64_t> ("VideoLength"));
_video_size.width = node->number_child<int> ("VideoWidth");
_video_size.height = node->number_child<int> ("VideoHeight");
_video_frame_rate = node->number_child<float> ("VideoFrameRate");
{
shared_ptr<const Film> film = _film.lock ();
assert (film);
-
- FrameRateConversion frc (video_frame_rate(), film->video_frame_rate());
-
- /* Here we are converting from time (in the DCP) to a frame number in the content.
- Hence we need to use the DCP's frame rate and the double/skip correction, not
- the source's rate.
- */
- return t * film->video_frame_rate() / (frc.factor() * TIME_HZ);
+ return ContentTime (t, FrameRateChange (video_frame_rate(), film->video_frame_rate()));
}
+
+ VideoContentScale::VideoContentScale (Ratio const * r)
+ : _ratio (r)
+ , _scale (true)
+ {
+
+ }
+
+ VideoContentScale::VideoContentScale ()
+ : _ratio (0)
+ , _scale (false)
+ {
+
+ }
+
+ VideoContentScale::VideoContentScale (bool scale)
+ : _ratio (0)
+ , _scale (scale)
+ {
+
+ }
+
+ VideoContentScale::VideoContentScale (shared_ptr<cxml::Node> node)
+ : _ratio (0)
+ , _scale (true)
+ {
+ optional<string> r = node->optional_string_child ("Ratio");
+ if (r) {
+ _ratio = Ratio::from_id (r.get ());
+ } else {
+ _scale = node->bool_child ("Scale");
+ }
+ }
+
+ void
+ VideoContentScale::as_xml (xmlpp::Node* node) const
+ {
+ if (_ratio) {
+ node->add_child("Ratio")->add_child_text (_ratio->id ());
+ } else {
+ node->add_child("Scale")->add_child_text (_scale ? "1" : "0");
+ }
+ }
+
+ string
+ VideoContentScale::id () const
+ {
+ stringstream s;
+
+ if (_ratio) {
+ s << _ratio->id () << "_";
+ } else {
+ s << (_scale ? "S1" : "S0");
+ }
+
+ return s.str ();
+ }
+
+ string
+ VideoContentScale::name () const
+ {
+ if (_ratio) {
+ return _ratio->nickname ();
+ }
+
+ if (_scale) {
+ return _("No stretch");
+ }
+
+ return _("No scale");
+ }
+
+ libdcp::Size
+ VideoContentScale::size (shared_ptr<const VideoContent> c, libdcp::Size container) const
+ {
+ if (_ratio) {
+ return fit_ratio_within (_ratio->ratio (), container);
+ }
+
+ /* Force scale if the container is smaller than the content's image */
+ if (_scale || container.width < c->video_size().width || container.height < c->video_size().height) {
+ return fit_ratio_within (c->video_size().ratio (), container);
+ }
+
+ return c->video_size ();
+ }
+
+ void
+ VideoContentScale::setup_scales ()
+ {
+ vector<Ratio const *> ratios = Ratio::all ();
+ for (vector<Ratio const *>::const_iterator i = ratios.begin(); i != ratios.end(); ++i) {
+ _scales.push_back (VideoContentScale (*i));
+ }
+
+ _scales.push_back (VideoContentScale (true));
+ _scales.push_back (VideoContentScale (false));
+ }
+
+ bool
+ operator== (VideoContentScale const & a, VideoContentScale const & b)
+ {
+ return (a.ratio() == b.ratio() && a.scale() == b.scale());
+ }
+
+ bool
+ operator!= (VideoContentScale const & a, VideoContentScale const & b)
+ {
+ return (a.ratio() != b.ratio() || a.scale() != b.scale());
+ }
typedef int Frame;
VideoContent (boost::shared_ptr<const Film>);
- VideoContent (boost::shared_ptr<const Film>, Time, VideoContent::Frame);
+ VideoContent (boost::shared_ptr<const Film>, DCPTime, ContentTime);
VideoContent (boost::shared_ptr<const Film>, boost::filesystem::path);
- VideoContent (boost::shared_ptr<const Film>, boost::shared_ptr<const cxml::Node>);
+ VideoContent (boost::shared_ptr<const Film>, boost::shared_ptr<const cxml::Node>, int);
VideoContent (boost::shared_ptr<const Film>, std::vector<boost::shared_ptr<Content> >);
void as_xml (xmlpp::Node *) const;
void setup_default_colour_conversion ();
- libdcp::Size _video_size;
+ dcp::Size _video_size;
VideoFrameType _video_frame_type;
Crop _crop;
- Ratio const * _ratio;
+ VideoContentScale _scale;
ColourConversion _colour_conversion;
};
++lines;
}
- Ratio const * ratio = vcs->ratio ();
- dcp::Size container_size = fit_ratio_within (_editor->film()->container()->ratio (), _editor->film()->full_frame ());
- float const ratio_value = ratio ? ratio->ratio() : vcs->video_size_after_crop().ratio ();
- libdcp::Size const container_size = fit_ratio_within (_editor->film()->container()->ratio (), _editor->film()->full_frame ());
- libdcp::Size const scaled = vcs->scale().size (vcs, container_size);
++ dcp::Size const container_size = fit_ratio_within (_editor->film()->container()->ratio (), _editor->film()->full_frame ());
++ dcp::Size const scaled = vcs->scale().size (vcs, container_size);
- /* We have a specified ratio to scale to */
- dcp::Size const scaled = fit_ratio_within (ratio_value, container_size);
-
- d << wxString::Format (
- _("Scaled to %dx%d (%.2f:1)\n"),
- scaled.width, scaled.height,
- scaled.ratio ()
- );
- ++lines;
+ if (scaled != vcs->video_size_after_crop ()) {
+ d << wxString::Format (
+ _("Scaled to %dx%d (%.2f:1)\n"),
+ scaled.width, scaled.height,
+ scaled.ratio ()
+ );
+ ++lines;
+ }
if (scaled != container_size) {
d << wxString::Format (
import sys
APPNAME = 'dcpomatic'
++<<<<<<< HEAD
+VERSION = '2.0.0devel'
++=======
+ VERSION = '1.64.18devel'
++>>>>>>> master
def options(opt):
opt.load('compiler_cxx')