summaryrefslogtreecommitdiff
path: root/src/lib/player_video.h
blob: e27975932109e4d1fe39223dd33e02ebe5d726ea (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
/*
    Copyright (C) 2013-2021 Carl Hetherington <cth@carlh.net>

    This file is part of DCP-o-matic.

    DCP-o-matic is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 2 of the License, or
    (at your option) any later version.

    DCP-o-matic is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with DCP-o-matic.  If not, see <http://www.gnu.org/licenses/>.

*/


#ifndef DCPOMATIC_PLAYER_VIDEO_H
#define DCPOMATIC_PLAYER_VIDEO_H


#include "colour_conversion.h"
#include "dcpomatic_time.h"
#include "image.h"
#include "position.h"
#include "position_image.h"
#include "types.h"
extern "C" {
#include <libavutil/pixfmt.h>
}
#include <boost/thread/mutex.hpp>


class Image;
class ImageProxy;
class Film;
class Socket;


/** Everything needed to describe a video frame coming out of the player, but with the
 *  bits still their raw form.  We may want to combine the bits on a remote machine,
 *  or maybe not even bother to combine them at all.
 */
class PlayerVideo
{
public:
	PlayerVideo (
		std::shared_ptr<const ImageProxy> image,
		Crop crop,
		boost::optional<double> fade,
		dcp::Size inter_size,
		dcp::Size out_size,
		Eyes eyes,
		Part part,
		boost::optional<ColourConversion> colour_conversion,
		VideoRange video_range,
		std::weak_ptr<Content> content,
		boost::optional<dcpomatic::ContentTime> video_time,
		bool error
		);

	PlayerVideo (std::shared_ptr<cxml::Node>, std::shared_ptr<Socket>);

	PlayerVideo (PlayerVideo const&) = delete;
	PlayerVideo& operator= (PlayerVideo const&) = delete;

	std::shared_ptr<PlayerVideo> shallow_copy () const;

	void set_text (PositionImage);
	boost::optional<PositionImage> text () const {
		return _text;
	}

	bool have_image() const;
	void prepare (std::function<AVPixelFormat (AVPixelFormat)> pixel_format, VideoRange video_range, Image::Alignment alignment, bool fast, bool proxy_only);
	std::shared_ptr<Image> image (std::function<AVPixelFormat (AVPixelFormat)> pixel_format, VideoRange video_range, bool fast) const;
	std::shared_ptr<const Image> raw_image () const;

	static AVPixelFormat force (AVPixelFormat);
	static AVPixelFormat keep_xyz_or_rgb (AVPixelFormat);

	void add_metadata(xmlpp::Element* element) const;
	void write_to_socket (std::shared_ptr<Socket> socket) const;

	bool reset_metadata (std::shared_ptr<const Film> film, dcp::Size player_video_container_size);

	bool has_j2k () const;
	std::shared_ptr<const dcp::Data> j2k () const;

	Eyes eyes () const {
		return _eyes;
	}

	void set_eyes (Eyes e) {
		_eyes = e;
	}

	boost::optional<ColourConversion> colour_conversion () const {
		return _colour_conversion;
	}

	/** @return Position of the content within the overall image once it has been scaled up */
	Position<int> inter_position () const;

	/** @return Size of the content within the overall image once it has been scaled up */
	dcp::Size inter_size () const {
		return _inter_size;
	}

	dcp::Size out_size () const {
		return _out_size;
	}

	bool same (std::shared_ptr<const PlayerVideo> other) const;

	size_t memory_used () const;

	std::weak_ptr<Content> content () const {
		return _content;
	}

	bool error () const {
		return _error;
	}

private:
	void make_image (std::function<AVPixelFormat (AVPixelFormat)> pixel_format, VideoRange video_range, bool fast) const;
	bool have_image_unlocked() const;

	std::shared_ptr<const ImageProxy> _in;
	Crop _crop;
	boost::optional<double> _fade;
	dcp::Size _inter_size;
	dcp::Size _out_size;
	Eyes _eyes;
	Part _part;
	boost::optional<ColourConversion> _colour_conversion;
	VideoRange _video_range;
	boost::optional<PositionImage> _text;
	/** Content that we came from.  This is so that reset_metadata() can work. */
	std::weak_ptr<Content> _content;
	/** Video time that we came from.  Again, this is for reset_metadata() */
	boost::optional<dcpomatic::ContentTime> _video_time;

	mutable boost::mutex _mutex;
	mutable std::shared_ptr<Image> _image;
	/** _crop that was used to make _image */
	mutable Crop _image_crop;
	/** _inter_size that was used to make _image */
	mutable dcp::Size _image_inter_size;
	/** _out_size that was used to make _image */
	mutable dcp::Size _image_out_size;
	/** _fade that was used to make _image */
	mutable boost::optional<double> _image_fade;
	/** true if there was an error when decoding our image */
	mutable bool _error;
};


#endif