No-op; fix GPL address and use the explicit-program-name version.
[dcpomatic.git] / src / lib / ffmpeg_examiner.cc
1 /*
2     Copyright (C) 2013-2015 Carl Hetherington <cth@carlh.net>
3
4     This file is part of DCP-o-matic.
5
6     DCP-o-matic is free software; you can redistribute it and/or modify
7     it under the terms of the GNU General Public License as published by
8     the Free Software Foundation; either version 2 of the License, or
9     (at your option) any later version.
10
11     DCP-o-matic is distributed in the hope that it will be useful,
12     but WITHOUT ANY WARRANTY; without even the implied warranty of
13     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14     GNU General Public License for more details.
15
16     You should have received a copy of the GNU General Public License
17     along with DCP-o-matic.  If not, see <http://www.gnu.org/licenses/>.
18
19 */
20
21 extern "C" {
22 #include <libavcodec/avcodec.h>
23 #include <libavformat/avformat.h>
24 #include <libavutil/pixfmt.h>
25 #include <libavutil/pixdesc.h>
26 }
27 #include "ffmpeg_examiner.h"
28 #include "ffmpeg_content.h"
29 #include "job.h"
30 #include "ffmpeg_audio_stream.h"
31 #include "ffmpeg_subtitle_stream.h"
32 #include "util.h"
33 #include "safe_stringstream.h"
34 #include <boost/foreach.hpp>
35 #include <iostream>
36
37 #include "i18n.h"
38
39 using std::string;
40 using std::cout;
41 using std::max;
42 using boost::shared_ptr;
43 using boost::optional;
44
45 /** @param job job that the examiner is operating in, or 0 */
46 FFmpegExaminer::FFmpegExaminer (shared_ptr<const FFmpegContent> c, shared_ptr<Job> job)
47         : FFmpeg (c)
48         , _video_length (0)
49         , _need_video_length (false)
50 {
51         /* Find audio and subtitle streams */
52
53         for (uint32_t i = 0; i < _format_context->nb_streams; ++i) {
54                 AVStream* s = _format_context->streams[i];
55                 if (s->codec->codec_type == AVMEDIA_TYPE_AUDIO) {
56
57                         /* This is a hack; sometimes it seems that _audio_codec_context->channel_layout isn't set up,
58                            so bodge it here.  No idea why we should have to do this.
59                         */
60
61                         if (s->codec->channel_layout == 0) {
62                                 s->codec->channel_layout = av_get_default_channel_layout (s->codec->channels);
63                         }
64
65                         DCPOMATIC_ASSERT (_format_context->duration != AV_NOPTS_VALUE);
66
67                         _audio_streams.push_back (
68                                 shared_ptr<FFmpegAudioStream> (
69                                         new FFmpegAudioStream (
70                                                 audio_stream_name (s),
71                                                 s->id,
72                                                 s->codec->sample_rate,
73                                                 (double (_format_context->duration) / AV_TIME_BASE) * s->codec->sample_rate,
74                                                 s->codec->channels
75                                                 )
76                                         )
77                                 );
78
79                 } else if (s->codec->codec_type == AVMEDIA_TYPE_SUBTITLE) {
80                         _subtitle_streams.push_back (shared_ptr<FFmpegSubtitleStream> (new FFmpegSubtitleStream (subtitle_stream_name (s), s->id)));
81                 }
82         }
83
84         if (has_video ()) {
85                 /* See if the header has duration information in it */
86                 _need_video_length = _format_context->duration == AV_NOPTS_VALUE;
87                 if (!_need_video_length) {
88                         _video_length = (double (_format_context->duration) / AV_TIME_BASE) * video_frame_rate().get ();
89                 }
90         }
91
92         if (job) {
93                 if (_need_video_length) {
94                         job->sub (_("Finding length and subtitles"));
95                 } else {
96                         job->sub (_("Finding subtitles"));
97                 }
98         }
99
100         /* Run through until we find:
101          *   - the first video.
102          *   - the first audio for each stream.
103          *   - the subtitle periods for each stream.
104          *
105          * We have to note subtitle periods as otherwise we have no way of knowing
106          * where we should look for subtitles (video and audio are always present,
107          * so they are ok).
108          */
109
110         int64_t const len = _file_group.length ();
111         while (true) {
112                 int r = av_read_frame (_format_context, &_packet);
113                 if (r < 0) {
114                         break;
115                 }
116
117                 if (job) {
118                         if (len > 0) {
119                                 job->set_progress (float (_format_context->pb->pos) / len);
120                         } else {
121                                 job->set_progress_unknown ();
122                         }
123                 }
124
125                 AVCodecContext* context = _format_context->streams[_packet.stream_index]->codec;
126
127                 if (_video_stream && _packet.stream_index == _video_stream.get()) {
128                         video_packet (context);
129                 }
130
131                 bool got_all_audio = true;
132
133                 for (size_t i = 0; i < _audio_streams.size(); ++i) {
134                         if (_audio_streams[i]->uses_index (_format_context, _packet.stream_index)) {
135                                 audio_packet (context, _audio_streams[i]);
136                         }
137                         if (!_audio_streams[i]->first_audio) {
138                                 got_all_audio = false;
139                         }
140                 }
141
142                 for (size_t i = 0; i < _subtitle_streams.size(); ++i) {
143                         if (_subtitle_streams[i]->uses_index (_format_context, _packet.stream_index)) {
144                                 subtitle_packet (context, _subtitle_streams[i]);
145                         }
146                 }
147
148                 av_packet_unref (&_packet);
149
150                 if (_first_video && got_all_audio && _subtitle_streams.empty ()) {
151                         /* All done */
152                         break;
153                 }
154         }
155
156         /* Finish off any hanging subtitles at the end */
157         for (LastSubtitleMap::const_iterator i = _last_subtitle_start.begin(); i != _last_subtitle_start.end(); ++i) {
158                 if (i->second) {
159                         if (i->second->image) {
160                                 i->first->add_image_subtitle (
161                                         i->second->id,
162                                         ContentTimePeriod (
163                                                 i->second->time,
164                                                 ContentTime::from_frames (video_length(), video_frame_rate().get_value_or (24))
165                                                 )
166                                         );
167                         } else {
168                                 i->first->add_text_subtitle (
169                                         i->second->id,
170                                         ContentTimePeriod (
171                                                 i->second->time,
172                                                 ContentTime::from_frames (video_length(), video_frame_rate().get_value_or (24))
173                                                 )
174                                         );
175                         }
176                 }
177         }
178
179         /* We just added subtitles to our streams without taking the PTS offset into account;
180            this is because we might not know the PTS offset when the first subtitle is seen.
181            Now we know the PTS offset so we can apply it to those subtitles.
182         */
183         if (has_video() && video_frame_rate()) {
184                 BOOST_FOREACH (shared_ptr<FFmpegSubtitleStream> i, _subtitle_streams) {
185                         i->add_offset (pts_offset (_audio_streams, _first_video, video_frame_rate().get()));
186                 }
187         }
188 }
189
190 void
191 FFmpegExaminer::video_packet (AVCodecContext* context)
192 {
193         DCPOMATIC_ASSERT (_video_stream);
194
195         if (_first_video && !_need_video_length) {
196                 return;
197         }
198
199         int frame_finished;
200         if (avcodec_decode_video2 (context, _frame, &frame_finished, &_packet) >= 0 && frame_finished) {
201                 if (!_first_video) {
202                         _first_video = frame_time (_format_context->streams[_video_stream.get()]);
203                 }
204                 if (_need_video_length) {
205                         _video_length = frame_time (
206                                 _format_context->streams[_video_stream.get()]
207                                 ).get_value_or (ContentTime ()).frames_round (video_frame_rate().get ());
208                 }
209         }
210 }
211
212 void
213 FFmpegExaminer::audio_packet (AVCodecContext* context, shared_ptr<FFmpegAudioStream> stream)
214 {
215         if (stream->first_audio) {
216                 return;
217         }
218
219         int frame_finished;
220         if (avcodec_decode_audio4 (context, _frame, &frame_finished, &_packet) >= 0 && frame_finished) {
221                 stream->first_audio = frame_time (stream->stream (_format_context));
222         }
223 }
224
225 void
226 FFmpegExaminer::subtitle_packet (AVCodecContext* context, shared_ptr<FFmpegSubtitleStream> stream)
227 {
228         int frame_finished;
229         AVSubtitle sub;
230         if (avcodec_decode_subtitle2 (context, &sub, &frame_finished, &_packet) >= 0 && frame_finished) {
231                 string id = subtitle_id (sub);
232                 FFmpegSubtitlePeriod const period = subtitle_period (sub);
233                 bool const starts_image = subtitle_starts_image (sub);
234
235                 LastSubtitleMap::iterator last = _last_subtitle_start.find (stream);
236                 if (last != _last_subtitle_start.end() && last->second) {
237                         /* We have seen the start of a subtitle but not yet the end.  Whatever this is
238                            finishes the previous subtitle, so add it */
239                         if (last->second->image) {
240                                 stream->add_image_subtitle (last->second->id, ContentTimePeriod (last->second->time, period.from));
241                         } else {
242                                 stream->add_text_subtitle (last->second->id, ContentTimePeriod (last->second->time, period.from));
243                         }
244                         if (sub.num_rects == 0) {
245                                 /* This is a `proper' end-of-subtitle */
246                                 _last_subtitle_start[stream] = optional<SubtitleStart> ();
247                         } else {
248                                 /* This is just another subtitle, so we start again */
249                                 _last_subtitle_start[stream] = SubtitleStart (id, starts_image, period.from);
250                         }
251                 } else if (sub.num_rects == 1) {
252                         if (period.to) {
253                                 if (starts_image) {
254                                         stream->add_image_subtitle (id, ContentTimePeriod (period.from, period.to.get ()));
255                                 } else {
256                                         stream->add_text_subtitle (id, ContentTimePeriod (period.from, period.to.get ()));
257                                 }
258                         } else {
259                                 _last_subtitle_start[stream] = SubtitleStart (id, starts_image, period.from);
260                         }
261                 }
262
263                 for (unsigned int i = 0; i < sub.num_rects; ++i) {
264                         if (sub.rects[i]->type == SUBTITLE_BITMAP) {
265 #ifdef DCPOMATIC_HAVE_AVSUBTITLERECT_PICT
266                                 uint32_t* palette = (uint32_t *) sub.rects[i]->pict.data[1];
267                                 for (int j = 0; j < sub.rects[i]->nb_colors; ++j) {
268                                         RGBA rgba  (
269                                                 (palette[j] & 0x00ff0000) >> 16,
270                                                 (palette[j] & 0x0000ff00) >> 8,
271                                                 (palette[j] & 0x000000ff) >> 0,
272                                                 (palette[j] & 0xff000000) >> 24
273                                                 );
274
275                                         stream->set_colour (rgba, rgba);
276                                 }
277 #else
278                                 uint32_t* palette = (uint32_t *) sub.rects[i]->data[1];
279                                 for (int j = 0; j < sub.rects[i]->nb_colors; ++j) {
280                                         RGBA rgba  (
281                                                 (palette[j] & 0x00ff0000) >> 16,
282                                                 (palette[j] & 0x0000ff00) >> 8,
283                                                 (palette[j] & 0x000000ff) >> 0,
284                                                 (palette[j] & 0xff000000) >> 24
285                                                 );
286
287                                         stream->set_colour (rgba, rgba);
288                                 }
289 #endif
290                         }
291                 }
292
293                 avsubtitle_free (&sub);
294         }
295 }
296
297 optional<ContentTime>
298 FFmpegExaminer::frame_time (AVStream* s) const
299 {
300         optional<ContentTime> t;
301
302         int64_t const bet = av_frame_get_best_effort_timestamp (_frame);
303         if (bet != AV_NOPTS_VALUE) {
304                 t = ContentTime::from_seconds (bet * av_q2d (s->time_base));
305         }
306
307         return t;
308 }
309
310 optional<double>
311 FFmpegExaminer::video_frame_rate () const
312 {
313         DCPOMATIC_ASSERT (_video_stream);
314         /* This use of r_frame_rate is debateable; there's a few different
315          * frame rates in the format context, but this one seems to be the most
316          * reliable.
317          */
318         return av_q2d (av_stream_get_r_frame_rate (_format_context->streams[_video_stream.get()]));
319 }
320
321 dcp::Size
322 FFmpegExaminer::video_size () const
323 {
324         return dcp::Size (video_codec_context()->width, video_codec_context()->height);
325 }
326
327 /** @return Length according to our content's header */
328 Frame
329 FFmpegExaminer::video_length () const
330 {
331         return max (Frame (1), _video_length);
332 }
333
334 optional<double>
335 FFmpegExaminer::sample_aspect_ratio () const
336 {
337         DCPOMATIC_ASSERT (_video_stream);
338         AVRational sar = av_guess_sample_aspect_ratio (_format_context, _format_context->streams[_video_stream.get()], 0);
339         if (sar.num == 0) {
340                 /* I assume this means that we don't know */
341                 return optional<double> ();
342         }
343         return double (sar.num) / sar.den;
344 }
345
346 string
347 FFmpegExaminer::audio_stream_name (AVStream* s) const
348 {
349         SafeStringStream n;
350
351         n << stream_name (s);
352
353         if (!n.str().empty()) {
354                 n << "; ";
355         }
356
357         n << s->codec->channels << " channels";
358
359         return n.str ();
360 }
361
362 string
363 FFmpegExaminer::subtitle_stream_name (AVStream* s) const
364 {
365         SafeStringStream n;
366
367         n << stream_name (s);
368
369         if (n.str().empty()) {
370                 n << _("unknown");
371         }
372
373         return n.str ();
374 }
375
376 string
377 FFmpegExaminer::stream_name (AVStream* s) const
378 {
379         SafeStringStream n;
380
381         if (s->metadata) {
382                 AVDictionaryEntry const * lang = av_dict_get (s->metadata, "language", 0, 0);
383                 if (lang) {
384                         n << lang->value;
385                 }
386
387                 AVDictionaryEntry const * title = av_dict_get (s->metadata, "title", 0, 0);
388                 if (title) {
389                         if (!n.str().empty()) {
390                                 n << " ";
391                         }
392                         n << title->value;
393                 }
394         }
395
396         return n.str ();
397 }
398
399 int
400 FFmpegExaminer::bits_per_pixel () const
401 {
402         if (video_codec_context()->pix_fmt == -1) {
403                 throw DecodeError (_("Could not find pixel format for video."));
404         }
405
406         AVPixFmtDescriptor const * d = av_pix_fmt_desc_get (video_codec_context()->pix_fmt);
407         DCPOMATIC_ASSERT (d);
408         return av_get_bits_per_pixel (d);
409 }
410
411 bool
412 FFmpegExaminer::yuv () const
413 {
414         switch (video_codec_context()->pix_fmt) {
415         case AV_PIX_FMT_YUV420P:
416         case AV_PIX_FMT_YUYV422:
417         case AV_PIX_FMT_YUV422P:
418         case AV_PIX_FMT_YUV444P:
419         case AV_PIX_FMT_YUV410P:
420         case AV_PIX_FMT_YUV411P:
421         case AV_PIX_FMT_YUVJ420P:
422         case AV_PIX_FMT_YUVJ422P:
423         case AV_PIX_FMT_YUVJ444P:
424         case AV_PIX_FMT_UYVY422:
425         case AV_PIX_FMT_UYYVYY411:
426         case AV_PIX_FMT_NV12:
427         case AV_PIX_FMT_NV21:
428         case AV_PIX_FMT_YUV440P:
429         case AV_PIX_FMT_YUVJ440P:
430         case AV_PIX_FMT_YUVA420P:
431         case AV_PIX_FMT_YUV420P16LE:
432         case AV_PIX_FMT_YUV420P16BE:
433         case AV_PIX_FMT_YUV422P16LE:
434         case AV_PIX_FMT_YUV422P16BE:
435         case AV_PIX_FMT_YUV444P16LE:
436         case AV_PIX_FMT_YUV444P16BE:
437         case AV_PIX_FMT_YUV420P9BE:
438         case AV_PIX_FMT_YUV420P9LE:
439         case AV_PIX_FMT_YUV420P10BE:
440         case AV_PIX_FMT_YUV420P10LE:
441         case AV_PIX_FMT_YUV422P10BE:
442         case AV_PIX_FMT_YUV422P10LE:
443         case AV_PIX_FMT_YUV444P9BE:
444         case AV_PIX_FMT_YUV444P9LE:
445         case AV_PIX_FMT_YUV444P10BE:
446         case AV_PIX_FMT_YUV444P10LE:
447         case AV_PIX_FMT_YUV422P9BE:
448         case AV_PIX_FMT_YUV422P9LE:
449         case AV_PIX_FMT_YUVA420P9BE:
450         case AV_PIX_FMT_YUVA420P9LE:
451         case AV_PIX_FMT_YUVA422P9BE:
452         case AV_PIX_FMT_YUVA422P9LE:
453         case AV_PIX_FMT_YUVA444P9BE:
454         case AV_PIX_FMT_YUVA444P9LE:
455         case AV_PIX_FMT_YUVA420P10BE:
456         case AV_PIX_FMT_YUVA420P10LE:
457         case AV_PIX_FMT_YUVA422P10BE:
458         case AV_PIX_FMT_YUVA422P10LE:
459         case AV_PIX_FMT_YUVA444P10BE:
460         case AV_PIX_FMT_YUVA444P10LE:
461         case AV_PIX_FMT_YUVA420P16BE:
462         case AV_PIX_FMT_YUVA420P16LE:
463         case AV_PIX_FMT_YUVA422P16BE:
464         case AV_PIX_FMT_YUVA422P16LE:
465         case AV_PIX_FMT_YUVA444P16BE:
466         case AV_PIX_FMT_YUVA444P16LE:
467         case AV_PIX_FMT_NV16:
468         case AV_PIX_FMT_NV20LE:
469         case AV_PIX_FMT_NV20BE:
470         case AV_PIX_FMT_YVYU422:
471         case AV_PIX_FMT_YUVA444P:
472         case AV_PIX_FMT_YUVA422P:
473         case AV_PIX_FMT_YUV420P12BE:
474         case AV_PIX_FMT_YUV420P12LE:
475         case AV_PIX_FMT_YUV420P14BE:
476         case AV_PIX_FMT_YUV420P14LE:
477         case AV_PIX_FMT_YUV422P12BE:
478         case AV_PIX_FMT_YUV422P12LE:
479         case AV_PIX_FMT_YUV422P14BE:
480         case AV_PIX_FMT_YUV422P14LE:
481         case AV_PIX_FMT_YUV444P12BE:
482         case AV_PIX_FMT_YUV444P12LE:
483         case AV_PIX_FMT_YUV444P14BE:
484         case AV_PIX_FMT_YUV444P14LE:
485         case AV_PIX_FMT_YUVJ411P:
486                 return true;
487         default:
488                 return false;
489         }
490 }
491
492 bool
493 FFmpegExaminer::has_video () const
494 {
495         return static_cast<bool> (_video_stream);
496 }