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