Subtitle "to" times used to be stored against their "from" times.
[dcpomatic.git] / src / lib / ffmpeg_examiner.cc
1 /*
2     Copyright (C) 2013-2015 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 extern "C" {
21 #include <libavcodec/avcodec.h>
22 #include <libavformat/avformat.h>
23 #include <libavutil/pixfmt.h>
24 #include <libavutil/pixdesc.h>
25 }
26 #include "ffmpeg_examiner.h"
27 #include "ffmpeg_content.h"
28 #include "job.h"
29 #include "ffmpeg_audio_stream.h"
30 #include "ffmpeg_subtitle_stream.h"
31 #include "util.h"
32 #include "safe_stringstream.h"
33 #include <boost/foreach.hpp>
34 #include <iostream>
35
36 #include "i18n.h"
37
38 using std::string;
39 using std::cout;
40 using std::max;
41 using boost::shared_ptr;
42 using boost::optional;
43
44 /** @param job job that the examiner is operating in, or 0 */
45 FFmpegExaminer::FFmpegExaminer (shared_ptr<const FFmpegContent> c, shared_ptr<Job> job)
46         : FFmpeg (c)
47         , _video_length (0)
48         , _need_video_length (false)
49 {
50         /* Find audio and subtitle streams */
51
52         for (uint32_t i = 0; i < _format_context->nb_streams; ++i) {
53                 AVStream* s = _format_context->streams[i];
54                 if (s->codec->codec_type == AVMEDIA_TYPE_AUDIO) {
55
56                         /* This is a hack; sometimes it seems that _audio_codec_context->channel_layout isn't set up,
57                            so bodge it here.  No idea why we should have to do this.
58                         */
59
60                         if (s->codec->channel_layout == 0) {
61                                 s->codec->channel_layout = av_get_default_channel_layout (s->codec->channels);
62                         }
63
64                         _audio_streams.push_back (
65                                 shared_ptr<FFmpegAudioStream> (
66                                         new FFmpegAudioStream (audio_stream_name (s), s->id, s->codec->sample_rate, s->codec->channels)
67                                         )
68                                 );
69
70                 } else if (s->codec->codec_type == AVMEDIA_TYPE_SUBTITLE) {
71                         _subtitle_streams.push_back (shared_ptr<FFmpegSubtitleStream> (new FFmpegSubtitleStream (subtitle_stream_name (s), s->id)));
72                 }
73         }
74
75         /* See if the header has duration information in it */
76         _need_video_length = _format_context->duration == AV_NOPTS_VALUE;
77         if (!_need_video_length) {
78                 _video_length = (double (_format_context->duration) / AV_TIME_BASE) * video_frame_rate().get ();
79         }
80
81         if (job) {
82                 if (_need_video_length) {
83                         job->sub (_("Finding length and subtitles"));
84                 } else {
85                         job->sub (_("Finding subtitles"));
86                 }
87         }
88
89         /* Run through until we find:
90          *   - the first video.
91          *   - the first audio for each stream.
92          *   - the subtitle periods for each stream.
93          *
94          * We have to note subtitle periods as otherwise we have no way of knowing
95          * where we should look for subtitles (video and audio are always present,
96          * so they are ok).
97          */
98
99         int64_t const len = _file_group.length ();
100         while (true) {
101                 int r = av_read_frame (_format_context, &_packet);
102                 if (r < 0) {
103                         break;
104                 }
105
106                 if (job) {
107                         if (len > 0) {
108                                 job->set_progress (float (_format_context->pb->pos) / len);
109                         } else {
110                                 job->set_progress_unknown ();
111                         }
112                 }
113
114                 AVCodecContext* context = _format_context->streams[_packet.stream_index]->codec;
115
116                 if (_packet.stream_index == _video_stream) {
117                         video_packet (context);
118                 }
119
120                 bool got_all_audio = true;
121
122                 for (size_t i = 0; i < _audio_streams.size(); ++i) {
123                         if (_audio_streams[i]->uses_index (_format_context, _packet.stream_index)) {
124                                 audio_packet (context, _audio_streams[i]);
125                         }
126                         if (!_audio_streams[i]->first_audio) {
127                                 got_all_audio = false;
128                         }
129                 }
130
131                 for (size_t i = 0; i < _subtitle_streams.size(); ++i) {
132                         if (_subtitle_streams[i]->uses_index (_format_context, _packet.stream_index)) {
133                                 subtitle_packet (context, _subtitle_streams[i]);
134                         }
135                 }
136
137                 av_free_packet (&_packet);
138
139                 if (_first_video && got_all_audio && _subtitle_streams.empty ()) {
140                         /* All done */
141                         break;
142                 }
143         }
144
145         /* Finish off any hanging subtitles at the end */
146         for (LastSubtitleMap::const_iterator i = _last_subtitle_start.begin(); i != _last_subtitle_start.end(); ++i) {
147                 if (i->second) {
148                         i->first->add_subtitle (
149                                 i->second->id,
150                                 ContentTimePeriod (
151                                         i->second->time,
152                                         ContentTime::from_frames (video_length(), video_frame_rate().get_value_or (24))
153                                         )
154                                 );
155                 }
156         }
157
158         /* We just added subtitles to our streams without taking the PTS offset into account;
159            this is because we might not know the PTS offset when the first subtitle is seen.
160            Now we know the PTS offset so we can apply it to those subtitles.
161         */
162         if (video_frame_rate()) {
163                 BOOST_FOREACH (shared_ptr<FFmpegSubtitleStream> i, _subtitle_streams) {
164                         i->add_offset (pts_offset (_audio_streams, _first_video, video_frame_rate().get()));
165                 }
166         }
167 }
168
169 void
170 FFmpegExaminer::video_packet (AVCodecContext* context)
171 {
172         if (_first_video && !_need_video_length) {
173                 return;
174         }
175
176         int frame_finished;
177         if (avcodec_decode_video2 (context, _frame, &frame_finished, &_packet) >= 0 && frame_finished) {
178                 if (!_first_video) {
179                         _first_video = frame_time (_format_context->streams[_video_stream]);
180                 }
181                 if (_need_video_length) {
182                         _video_length = frame_time (
183                                 _format_context->streams[_video_stream]
184                                 ).get_value_or (ContentTime ()).frames_round (video_frame_rate().get ());
185                 }
186         }
187 }
188
189 void
190 FFmpegExaminer::audio_packet (AVCodecContext* context, shared_ptr<FFmpegAudioStream> stream)
191 {
192         if (stream->first_audio) {
193                 return;
194         }
195
196         int frame_finished;
197         if (avcodec_decode_audio4 (context, _frame, &frame_finished, &_packet) >= 0 && frame_finished) {
198                 stream->first_audio = frame_time (stream->stream (_format_context));
199         }
200 }
201
202 void
203 FFmpegExaminer::subtitle_packet (AVCodecContext* context, shared_ptr<FFmpegSubtitleStream> stream)
204 {
205         int frame_finished;
206         AVSubtitle sub;
207         if (avcodec_decode_subtitle2 (context, &sub, &frame_finished, &_packet) >= 0 && frame_finished) {
208                 string id = subtitle_id (sub);
209                 FFmpegSubtitlePeriod const period = subtitle_period (sub);
210                 LastSubtitleMap::iterator last = _last_subtitle_start.find (stream);
211                 if (last != _last_subtitle_start.end() && last->second) {
212                         /* We have seen the start of a subtitle but not yet the end.  Whatever this is
213                            finishes the previous subtitle, so add it */
214                         stream->add_subtitle (last->second->id, ContentTimePeriod (last->second->time, period.from));
215                         if (sub.num_rects == 0) {
216                                 /* This is a `proper' end-of-subtitle */
217                                 _last_subtitle_start[stream] = optional<SubtitleStart> ();
218                         } else {
219                                 /* This is just another subtitle, so we start again */
220                                 _last_subtitle_start[stream] = SubtitleStart (id, period.from);
221                         }
222                 } else if (sub.num_rects == 1) {
223                         if (period.to) {
224                                 stream->add_subtitle (id, ContentTimePeriod (period.from, period.to.get ()));
225                         } else {
226                                 _last_subtitle_start[stream] = SubtitleStart (id, period.from);
227                         }
228                 }
229                 avsubtitle_free (&sub);
230         }
231 }
232
233 optional<ContentTime>
234 FFmpegExaminer::frame_time (AVStream* s) const
235 {
236         optional<ContentTime> t;
237
238         int64_t const bet = av_frame_get_best_effort_timestamp (_frame);
239         if (bet != AV_NOPTS_VALUE) {
240                 t = ContentTime::from_seconds (bet * av_q2d (s->time_base));
241         }
242
243         return t;
244 }
245
246 optional<double>
247 FFmpegExaminer::video_frame_rate () const
248 {
249         /* This use of r_frame_rate is debateable; there's a few different
250          * frame rates in the format context, but this one seems to be the most
251          * reliable.
252          */
253         return av_q2d (av_stream_get_r_frame_rate (_format_context->streams[_video_stream]));
254 }
255
256 dcp::Size
257 FFmpegExaminer::video_size () const
258 {
259         return dcp::Size (video_codec_context()->width, video_codec_context()->height);
260 }
261
262 /** @return Length according to our content's header */
263 Frame
264 FFmpegExaminer::video_length () const
265 {
266         return max (Frame (1), _video_length);
267 }
268
269 optional<double>
270 FFmpegExaminer::sample_aspect_ratio () const
271 {
272         AVRational sar = av_guess_sample_aspect_ratio (_format_context, _format_context->streams[_video_stream], 0);
273         if (sar.num == 0) {
274                 /* I assume this means that we don't know */
275                 return optional<double> ();
276         }
277         return double (sar.num) / sar.den;
278 }
279
280 string
281 FFmpegExaminer::audio_stream_name (AVStream* s) const
282 {
283         SafeStringStream n;
284
285         n << stream_name (s);
286
287         if (!n.str().empty()) {
288                 n << "; ";
289         }
290
291         n << s->codec->channels << " channels";
292
293         return n.str ();
294 }
295
296 string
297 FFmpegExaminer::subtitle_stream_name (AVStream* s) const
298 {
299         SafeStringStream n;
300
301         n << stream_name (s);
302
303         if (n.str().empty()) {
304                 n << _("unknown");
305         }
306
307         return n.str ();
308 }
309
310 string
311 FFmpegExaminer::stream_name (AVStream* s) const
312 {
313         SafeStringStream n;
314
315         if (s->metadata) {
316                 AVDictionaryEntry const * lang = av_dict_get (s->metadata, "language", 0, 0);
317                 if (lang) {
318                         n << lang->value;
319                 }
320
321                 AVDictionaryEntry const * title = av_dict_get (s->metadata, "title", 0, 0);
322                 if (title) {
323                         if (!n.str().empty()) {
324                                 n << " ";
325                         }
326                         n << title->value;
327                 }
328         }
329
330         return n.str ();
331 }
332
333 int
334 FFmpegExaminer::bits_per_pixel () const
335 {
336         return av_get_bits_per_pixel (av_pix_fmt_desc_get (video_codec_context()->pix_fmt));
337 }
338
339 bool
340 FFmpegExaminer::yuv () const
341 {
342         switch (video_codec_context()->pix_fmt) {
343         case AV_PIX_FMT_YUV420P:
344         case AV_PIX_FMT_YUYV422:
345         case AV_PIX_FMT_YUV422P:
346         case AV_PIX_FMT_YUV444P:
347         case AV_PIX_FMT_YUV410P:
348         case AV_PIX_FMT_YUV411P:
349         case AV_PIX_FMT_YUVJ420P:
350         case AV_PIX_FMT_YUVJ422P:
351         case AV_PIX_FMT_YUVJ444P:
352         case AV_PIX_FMT_UYVY422:
353         case AV_PIX_FMT_UYYVYY411:
354         case AV_PIX_FMT_NV12:
355         case AV_PIX_FMT_NV21:
356         case AV_PIX_FMT_YUV440P:
357         case AV_PIX_FMT_YUVJ440P:
358         case AV_PIX_FMT_YUVA420P:
359         case AV_PIX_FMT_YUV420P16LE:
360         case AV_PIX_FMT_YUV420P16BE:
361         case AV_PIX_FMT_YUV422P16LE:
362         case AV_PIX_FMT_YUV422P16BE:
363         case AV_PIX_FMT_YUV444P16LE:
364         case AV_PIX_FMT_YUV444P16BE:
365         case AV_PIX_FMT_YUV420P9BE:
366         case AV_PIX_FMT_YUV420P9LE:
367         case AV_PIX_FMT_YUV420P10BE:
368         case AV_PIX_FMT_YUV420P10LE:
369         case AV_PIX_FMT_YUV422P10BE:
370         case AV_PIX_FMT_YUV422P10LE:
371         case AV_PIX_FMT_YUV444P9BE:
372         case AV_PIX_FMT_YUV444P9LE:
373         case AV_PIX_FMT_YUV444P10BE:
374         case AV_PIX_FMT_YUV444P10LE:
375         case AV_PIX_FMT_YUV422P9BE:
376         case AV_PIX_FMT_YUV422P9LE:
377         case AV_PIX_FMT_YUVA422P_LIBAV:
378         case AV_PIX_FMT_YUVA444P_LIBAV:
379         case AV_PIX_FMT_YUVA420P9BE:
380         case AV_PIX_FMT_YUVA420P9LE:
381         case AV_PIX_FMT_YUVA422P9BE:
382         case AV_PIX_FMT_YUVA422P9LE:
383         case AV_PIX_FMT_YUVA444P9BE:
384         case AV_PIX_FMT_YUVA444P9LE:
385         case AV_PIX_FMT_YUVA420P10BE:
386         case AV_PIX_FMT_YUVA420P10LE:
387         case AV_PIX_FMT_YUVA422P10BE:
388         case AV_PIX_FMT_YUVA422P10LE:
389         case AV_PIX_FMT_YUVA444P10BE:
390         case AV_PIX_FMT_YUVA444P10LE:
391         case AV_PIX_FMT_YUVA420P16BE:
392         case AV_PIX_FMT_YUVA420P16LE:
393         case AV_PIX_FMT_YUVA422P16BE:
394         case AV_PIX_FMT_YUVA422P16LE:
395         case AV_PIX_FMT_YUVA444P16BE:
396         case AV_PIX_FMT_YUVA444P16LE:
397         case AV_PIX_FMT_NV16:
398         case AV_PIX_FMT_NV20LE:
399         case AV_PIX_FMT_NV20BE:
400         case AV_PIX_FMT_YVYU422:
401         case AV_PIX_FMT_YUVA444P:
402         case AV_PIX_FMT_YUVA422P:
403         case AV_PIX_FMT_YUV420P12BE:
404         case AV_PIX_FMT_YUV420P12LE:
405         case AV_PIX_FMT_YUV420P14BE:
406         case AV_PIX_FMT_YUV420P14LE:
407         case AV_PIX_FMT_YUV422P12BE:
408         case AV_PIX_FMT_YUV422P12LE:
409         case AV_PIX_FMT_YUV422P14BE:
410         case AV_PIX_FMT_YUV422P14LE:
411         case AV_PIX_FMT_YUV444P12BE:
412         case AV_PIX_FMT_YUV444P12LE:
413         case AV_PIX_FMT_YUV444P14BE:
414         case AV_PIX_FMT_YUV444P14LE:
415         case AV_PIX_FMT_YUVJ411P:
416                 return true;
417         default:
418                 return false;
419         }
420 }