Runs.
[dcpomatic.git] / src / lib / ffmpeg_content.cc
1 #include "ffmpeg_content.h"
2 #include "ffmpeg_decoder.h"
3 #include "options.h"
4 #include "compose.hpp"
5 #include "job.h"
6 #include "util.h"
7 #include "log.h"
8
9 #include "i18n.h"
10
11 using std::string;
12 using boost::shared_ptr;
13
14 int const FFmpegContentProperty::SUBTITLE_STREAMS = 100;
15 int const FFmpegContentProperty::SUBTITLE_STREAM = 101;
16 int const FFmpegContentProperty::AUDIO_STREAMS = 102;
17 int const FFmpegContentProperty::AUDIO_STREAM = 103;
18
19 FFmpegContent::FFmpegContent (boost::filesystem::path f)
20         : Content (f)
21         , VideoContent (f)
22         , AudioContent (f)
23 {
24
25 }
26
27 void
28 FFmpegContent::examine (shared_ptr<Film> film, shared_ptr<Job> job, bool quick)
29 {
30         job->descend (0.5);
31         Content::examine (film, job, quick);
32         job->ascend ();
33
34         job->set_progress_unknown ();
35
36         DecodeOptions o;
37         o.decode_audio = false;
38         shared_ptr<FFmpegDecoder> decoder (new FFmpegDecoder (film, shared_from_this (), o));
39
40         ContentVideoFrame video_length = 0;
41         if (quick) {
42                 video_length = decoder->video_length ();
43                 film->log()->log (String::compose ("Video length obtained from header as %1 frames", decoder->video_length ()));
44         } else {
45                 while (!decoder->pass ()) {
46                         /* keep going */
47                 }
48
49                 video_length = decoder->video_frame ();
50                 film->log()->log (String::compose ("Video length examined as %1 frames", decoder->video_frame ()));
51         }
52
53         {
54                 boost::mutex::scoped_lock lm (_mutex);
55
56                 _video_length = video_length;
57
58                 _subtitle_streams = decoder->subtitle_streams ();
59                 if (!_subtitle_streams.empty ()) {
60                         _subtitle_stream = _subtitle_streams.front ();
61                 }
62                 
63                 _audio_streams = decoder->audio_streams ();
64                 if (!_audio_streams.empty ()) {
65                         _audio_stream = _audio_streams.front ();
66                 }
67         }
68
69         take_from_video_decoder (decoder);
70
71         Changed (VideoContentProperty::VIDEO_LENGTH);
72         Changed (FFmpegContentProperty::SUBTITLE_STREAMS);
73         Changed (FFmpegContentProperty::SUBTITLE_STREAM);
74         Changed (FFmpegContentProperty::AUDIO_STREAMS);
75         Changed (FFmpegContentProperty::AUDIO_STREAM);
76 }
77
78 string
79 FFmpegContent::summary () const
80 {
81         return String::compose (_("Movie: %1"), file().filename ());
82 }
83
84 void
85 FFmpegContent::set_subtitle_stream (FFmpegSubtitleStream s)
86 {
87         {
88                 boost::mutex::scoped_lock lm (_mutex);
89                 _subtitle_stream = s;
90         }
91
92         Changed (FFmpegContentProperty::SUBTITLE_STREAM);
93 }
94
95 void
96 FFmpegContent::set_audio_stream (FFmpegAudioStream s)
97 {
98         {
99                 boost::mutex::scoped_lock lm (_mutex);
100                 _audio_stream = s;
101         }
102
103         Changed (FFmpegContentProperty::AUDIO_STREAM);
104 }
105
106 ContentAudioFrame
107 FFmpegContent::audio_length () const
108 {
109         if (!_audio_stream) {
110                 return 0;
111         }
112         
113         return video_frames_to_audio_frames (_video_length, audio_frame_rate(), video_frame_rate());
114 }
115
116 int
117 FFmpegContent::audio_channels () const
118 {
119         if (!_audio_stream) {
120                 return 0;
121         }
122
123         return _audio_stream->channels ();
124 }
125
126 int
127 FFmpegContent::audio_frame_rate () const
128 {
129         if (!_audio_stream) {
130                 return 0;
131         }
132
133         return _audio_stream->frame_rate;
134 }
135
136 int64_t
137 FFmpegContent::audio_channel_layout () const
138 {
139         if (!_audio_stream) {
140                 return 0;
141         }
142
143         return _audio_stream->channel_layout;
144 }
145         
146 bool
147 operator== (FFmpegSubtitleStream const & a, FFmpegSubtitleStream const & b)
148 {
149         return a.id == b.id;
150 }
151
152 bool
153 operator== (FFmpegAudioStream const & a, FFmpegAudioStream const & b)
154 {
155         return a.id == b.id;
156 }