Merge branch 'master' into 2.0--libdcp-1.0
[dcpomatic.git] / src / lib / ffmpeg_content.h
1 /*
2     Copyright (C) 2013 Carl Hetherington <cth@carlh.net>
3
4     This program is free software; you can redistribute it and/or modify
5     it under the terms of the GNU General Public License as published by
6     the Free Software Foundation; either version 2 of the License, or
7     (at your option) any later version.
8
9     This program is distributed in the hope that it will be useful,
10     but WITHOUT ANY WARRANTY; without even the implied warranty of
11     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12     GNU General Public License for more details.
13
14     You should have received a copy of the GNU General Public License
15     along with this program; if not, write to the Free Software
16     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
17
18 */
19
20 #ifndef DCPOMATIC_FFMPEG_CONTENT_H
21 #define DCPOMATIC_FFMPEG_CONTENT_H
22
23 #include <boost/enable_shared_from_this.hpp>
24 #include "video_content.h"
25 #include "audio_content.h"
26 #include "subtitle_content.h"
27 #include "audio_mapping.h"
28
29 struct AVFormatContext;
30 struct AVStream;
31
32 class Filter;
33 class ffmpeg_pts_offset_test;
34
35 class FFmpegStream
36 {
37 public:
38         FFmpegStream (std::string n, int i)
39                 : name (n)
40                 , id (i)
41                 , _legacy_id (false)
42         {}
43                                 
44         FFmpegStream (boost::shared_ptr<const cxml::Node>, int);
45
46         void as_xml (xmlpp::Node *) const;
47
48         /** @param c An AVFormatContext.
49          *  @return Stream index within the AVFormatContext.
50          */
51         int index (AVFormatContext const * c) const;
52         AVStream* stream (AVFormatContext const * c) const;
53
54         std::string name;
55         int id;
56         
57 private:
58         /** If this is true, id is in fact the index */
59         bool _legacy_id;
60 };
61
62 class FFmpegAudioStream : public FFmpegStream
63 {
64 public:
65         FFmpegAudioStream (std::string n, int i, int f, int c)
66                 : FFmpegStream (n, i)
67                 , frame_rate (f)
68                 , channels (c)
69                 , mapping (c)
70         {
71                 mapping.make_default ();
72         }
73
74         FFmpegAudioStream (boost::shared_ptr<const cxml::Node>, int);
75
76         void as_xml (xmlpp::Node *) const;
77
78         int frame_rate;
79         int channels;
80         AudioMapping mapping;
81         boost::optional<double> first_audio;
82
83 private:
84         friend class ffmpeg_pts_offset_test;
85
86         /* Constructor for tests */
87         FFmpegAudioStream ()
88                 : FFmpegStream ("", 0)
89                 , frame_rate (0)
90                 , channels (0)
91                 , mapping (1)
92         {}
93 };
94
95 extern bool operator== (FFmpegAudioStream const & a, FFmpegAudioStream const & b);
96 extern bool operator!= (FFmpegAudioStream const & a, FFmpegAudioStream const & b);
97
98 class FFmpegSubtitleStream : public FFmpegStream
99 {
100 public:
101         FFmpegSubtitleStream (std::string n, int i)
102                 : FFmpegStream (n, i)
103         {}
104         
105         FFmpegSubtitleStream (boost::shared_ptr<const cxml::Node>, int);
106
107         void as_xml (xmlpp::Node *) const;
108 };
109
110 extern bool operator== (FFmpegSubtitleStream const & a, FFmpegSubtitleStream const & b);
111 extern bool operator!= (FFmpegSubtitleStream const & a, FFmpegSubtitleStream const & b);
112
113 class FFmpegContentProperty : public VideoContentProperty
114 {
115 public:
116         static int const SUBTITLE_STREAMS;
117         static int const SUBTITLE_STREAM;
118         static int const AUDIO_STREAMS;
119         static int const AUDIO_STREAM;
120         static int const FILTERS;
121 };
122
123 class FFmpegContent : public VideoContent, public AudioContent, public SubtitleContent
124 {
125 public:
126         FFmpegContent (boost::shared_ptr<const Film>, boost::filesystem::path);
127         FFmpegContent (boost::shared_ptr<const Film>, boost::shared_ptr<const cxml::Node>, int version);
128         FFmpegContent (boost::shared_ptr<const Film>, std::vector<boost::shared_ptr<Content> >);
129
130         boost::shared_ptr<FFmpegContent> shared_from_this () {
131                 return boost::dynamic_pointer_cast<FFmpegContent> (Content::shared_from_this ());
132         }
133         
134         void examine (boost::shared_ptr<Job>);
135         std::string summary () const;
136         std::string technical_summary () const;
137         std::string information () const;
138         void as_xml (xmlpp::Node *) const;
139         DCPTime full_length () const;
140
141         std::string identifier () const;
142         
143         /* AudioContent */
144         int audio_channels () const;
145         AudioFrame audio_length () const;
146         int content_audio_frame_rate () const;
147         int output_audio_frame_rate () const;
148         AudioMapping audio_mapping () const;
149         void set_audio_mapping (AudioMapping);
150
151         void set_filters (std::vector<Filter const *> const &);
152         
153         std::vector<boost::shared_ptr<FFmpegSubtitleStream> > subtitle_streams () const {
154                 boost::mutex::scoped_lock lm (_mutex);
155                 return _subtitle_streams;
156         }
157
158         boost::shared_ptr<FFmpegSubtitleStream> subtitle_stream () const {
159                 boost::mutex::scoped_lock lm (_mutex);
160                 return _subtitle_stream;
161         }
162
163         std::vector<boost::shared_ptr<FFmpegAudioStream> > audio_streams () const {
164                 boost::mutex::scoped_lock lm (_mutex);
165                 return _audio_streams;
166         }
167         
168         boost::shared_ptr<FFmpegAudioStream> audio_stream () const {
169                 boost::mutex::scoped_lock lm (_mutex);
170                 return _audio_stream;
171         }
172
173         std::vector<Filter const *> filters () const {
174                 boost::mutex::scoped_lock lm (_mutex);
175                 return _filters;
176         }
177
178         void set_subtitle_stream (boost::shared_ptr<FFmpegSubtitleStream>);
179         void set_audio_stream (boost::shared_ptr<FFmpegAudioStream>);
180
181         boost::optional<double> first_video () const {
182                 boost::mutex::scoped_lock lm (_mutex);
183                 return _first_video;
184         }
185
186 private:
187         friend class ffmpeg_pts_offset_test;
188         
189         std::vector<boost::shared_ptr<FFmpegSubtitleStream> > _subtitle_streams;
190         boost::shared_ptr<FFmpegSubtitleStream> _subtitle_stream;
191         std::vector<boost::shared_ptr<FFmpegAudioStream> > _audio_streams;
192         boost::shared_ptr<FFmpegAudioStream> _audio_stream;
193         boost::optional<double> _first_video;
194         /** Video filters that should be used when generating DCPs */
195         std::vector<Filter const *> _filters;
196 };
197
198 #endif