271180d5d0970521e58e45f45fa087131abca9d3
[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 <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                         DCPOMATIC_ASSERT (_format_context->duration != AV_NOPTS_VALUE);
65                         DCPOMATIC_ASSERT (s->codec->codec);
66                         DCPOMATIC_ASSERT (s->codec->codec->name);
67
68                         _audio_streams.push_back (
69                                 shared_ptr<FFmpegAudioStream> (
70                                         new FFmpegAudioStream (
71                                                 stream_name (s),
72                                                 s->codec->codec->name,
73                                                 s->id,
74                                                 s->codec->sample_rate,
75                                                 (double (_format_context->duration) / AV_TIME_BASE) * s->codec->sample_rate,
76                                                 s->codec->channels
77                                                 )
78                                         )
79                                 );
80
81                 } else if (s->codec->codec_type == AVMEDIA_TYPE_SUBTITLE) {
82                         _subtitle_streams.push_back (shared_ptr<FFmpegSubtitleStream> (new FFmpegSubtitleStream (subtitle_stream_name (s), s->id)));
83                 }
84         }
85
86         if (has_video ()) {
87                 /* See if the header has duration information in it */
88                 _need_video_length = _format_context->duration == AV_NOPTS_VALUE;
89                 if (!_need_video_length) {
90                         _video_length = (double (_format_context->duration) / AV_TIME_BASE) * video_frame_rate().get ();
91                 }
92         }
93
94         if (job) {
95                 if (_need_video_length) {
96                         job->sub (_("Finding length and subtitles"));
97                 } else if (!_subtitle_streams.empty()) {
98                         job->sub (_("Finding subtitles"));
99                 } else {
100                         job->sub (_("Finding length"));
101                 }
102         }
103
104         /* Run through until we find:
105          *   - the first video.
106          *   - the first audio for each stream.
107          *   - the subtitle periods for each stream.
108          *
109          * We have to note subtitle periods as otherwise we have no way of knowing
110          * where we should look for subtitles (video and audio are always present,
111          * so they are ok).
112          */
113
114         int64_t const len = _file_group.length ();
115         while (true) {
116                 int r = av_read_frame (_format_context, &_packet);
117                 if (r < 0) {
118                         break;
119                 }
120
121                 if (job) {
122                         if (len > 0) {
123                                 job->set_progress (float (_format_context->pb->pos) / len);
124                         } else {
125                                 job->set_progress_unknown ();
126                         }
127                 }
128
129                 AVCodecContext* context = _format_context->streams[_packet.stream_index]->codec;
130
131                 if (_video_stream && _packet.stream_index == _video_stream.get()) {
132                         video_packet (context);
133                 }
134
135                 bool got_all_audio = true;
136
137                 for (size_t i = 0; i < _audio_streams.size(); ++i) {
138                         if (_audio_streams[i]->uses_index (_format_context, _packet.stream_index)) {
139                                 audio_packet (context, _audio_streams[i]);
140                         }
141                         if (!_audio_streams[i]->first_audio) {
142                                 got_all_audio = false;
143                         }
144                 }
145
146                 for (size_t i = 0; i < _subtitle_streams.size(); ++i) {
147                         if (_subtitle_streams[i]->uses_index (_format_context, _packet.stream_index)) {
148                                 subtitle_packet (context, _subtitle_streams[i]);
149                         }
150                 }
151
152                 av_packet_unref (&_packet);
153
154                 if (_first_video && got_all_audio && _subtitle_streams.empty ()) {
155                         /* All done */
156                         break;
157                 }
158         }
159
160         /* Finish off any hanging subtitles at the end */
161         for (LastSubtitleMap::const_iterator i = _last_subtitle_start.begin(); i != _last_subtitle_start.end(); ++i) {
162                 if (i->second) {
163                         if (i->second->image) {
164                                 i->first->add_image_subtitle (
165                                         i->second->id,
166                                         ContentTimePeriod (
167                                                 i->second->time,
168                                                 ContentTime::from_frames (video_length(), video_frame_rate().get_value_or (24))
169                                                 )
170                                         );
171                         } else {
172                                 i->first->add_text_subtitle (
173                                         i->second->id,
174                                         ContentTimePeriod (
175                                                 i->second->time,
176                                                 ContentTime::from_frames (video_length(), video_frame_rate().get_value_or (24))
177                                                 )
178                                         );
179                         }
180                 }
181         }
182
183         /* We just added subtitles to our streams without taking the PTS offset into account;
184            this is because we might not know the PTS offset when the first subtitle is seen.
185            Now we know the PTS offset so we can apply it to those subtitles.
186         */
187         if (has_video() && video_frame_rate()) {
188                 BOOST_FOREACH (shared_ptr<FFmpegSubtitleStream> i, _subtitle_streams) {
189                         i->add_offset (pts_offset (_audio_streams, _first_video, video_frame_rate().get()));
190                 }
191         }
192 }
193
194 void
195 FFmpegExaminer::video_packet (AVCodecContext* context)
196 {
197         DCPOMATIC_ASSERT (_video_stream);
198
199         if (_first_video && !_need_video_length) {
200                 return;
201         }
202
203         int frame_finished;
204         if (avcodec_decode_video2 (context, _frame, &frame_finished, &_packet) >= 0 && frame_finished) {
205                 if (!_first_video) {
206                         _first_video = frame_time (_format_context->streams[_video_stream.get()]);
207                 }
208                 if (_need_video_length) {
209                         _video_length = frame_time (
210                                 _format_context->streams[_video_stream.get()]
211                                 ).get_value_or (ContentTime ()).frames_round (video_frame_rate().get ());
212                 }
213         }
214 }
215
216 void
217 FFmpegExaminer::audio_packet (AVCodecContext* context, shared_ptr<FFmpegAudioStream> stream)
218 {
219         if (stream->first_audio) {
220                 return;
221         }
222
223         int frame_finished;
224         if (avcodec_decode_audio4 (context, _frame, &frame_finished, &_packet) >= 0 && frame_finished) {
225                 stream->first_audio = frame_time (stream->stream (_format_context));
226         }
227 }
228
229 void
230 FFmpegExaminer::subtitle_packet (AVCodecContext* context, shared_ptr<FFmpegSubtitleStream> stream)
231 {
232         int frame_finished;
233         AVSubtitle sub;
234         if (avcodec_decode_subtitle2 (context, &sub, &frame_finished, &_packet) >= 0 && frame_finished) {
235                 string id = subtitle_id (sub);
236                 FFmpegSubtitlePeriod const period = subtitle_period (sub);
237                 bool const starts_image = subtitle_starts_image (sub);
238
239                 /* Some streams (notably DVB streams) have subtitles which have a specified end time
240                    but which are then stopped earlier than this by a zero-num_rect subtitle.
241                 */
242
243                 LastSubtitleMap::iterator last = _last_subtitle_start.find (stream);
244                 if (sub.num_rects == 0 && last != _last_subtitle_start.end() && last->second) {
245                         /* Set (or fix) the `to' time for the last subtitle */
246                         stream->set_subtitle_to (last->second->id, period.from);
247                         _last_subtitle_start[stream] = optional<SubtitleStart> ();
248                 } else if (sub.num_rects > 0) {
249                         /* Add a subtitle; if we don't know the `to' time we set it to the from time and fix it later */
250                         if (starts_image) {
251                                 stream->add_image_subtitle (id, ContentTimePeriod (period.from, period.to.get_value_or (period.from)));
252                         } else {
253                                 stream->add_text_subtitle (id, ContentTimePeriod (period.from, period.to.get_value_or (period.from)));
254                         }
255
256                         _last_subtitle_start[stream] = SubtitleStart (id, starts_image, period.from);
257                 }
258
259                 for (unsigned int i = 0; i < sub.num_rects; ++i) {
260                         if (sub.rects[i]->type == SUBTITLE_BITMAP) {
261 #ifdef DCPOMATIC_HAVE_AVSUBTITLERECT_PICT
262                                 uint32_t* palette = (uint32_t *) sub.rects[i]->pict.data[1];
263                                 for (int j = 0; j < sub.rects[i]->nb_colors; ++j) {
264                                         RGBA rgba  (
265                                                 (palette[j] & 0x00ff0000) >> 16,
266                                                 (palette[j] & 0x0000ff00) >> 8,
267                                                 (palette[j] & 0x000000ff) >> 0,
268                                                 (palette[j] & 0xff000000) >> 24
269                                                 );
270
271                                         stream->set_colour (rgba, rgba);
272                                 }
273 #else
274                                 uint32_t* palette = (uint32_t *) sub.rects[i]->data[1];
275                                 for (int j = 0; j < sub.rects[i]->nb_colors; ++j) {
276                                         RGBA rgba  (
277                                                 (palette[j] & 0x00ff0000) >> 16,
278                                                 (palette[j] & 0x0000ff00) >> 8,
279                                                 (palette[j] & 0x000000ff) >> 0,
280                                                 (palette[j] & 0xff000000) >> 24
281                                                 );
282
283                                         stream->set_colour (rgba, rgba);
284                                 }
285 #endif
286                         }
287                 }
288
289                 avsubtitle_free (&sub);
290         }
291 }
292
293 optional<ContentTime>
294 FFmpegExaminer::frame_time (AVStream* s) const
295 {
296         optional<ContentTime> t;
297
298         int64_t const bet = av_frame_get_best_effort_timestamp (_frame);
299         if (bet != AV_NOPTS_VALUE) {
300                 t = ContentTime::from_seconds (bet * av_q2d (s->time_base));
301         }
302
303         return t;
304 }
305
306 optional<double>
307 FFmpegExaminer::video_frame_rate () const
308 {
309         DCPOMATIC_ASSERT (_video_stream);
310         /* This use of r_frame_rate is debateable; there's a few different
311          * frame rates in the format context, but this one seems to be the most
312          * reliable.
313          */
314         return av_q2d (av_stream_get_r_frame_rate (_format_context->streams[_video_stream.get()]));
315 }
316
317 dcp::Size
318 FFmpegExaminer::video_size () const
319 {
320         return dcp::Size (video_codec_context()->width, video_codec_context()->height);
321 }
322
323 /** @return Length according to our content's header */
324 Frame
325 FFmpegExaminer::video_length () const
326 {
327         return max (Frame (1), _video_length);
328 }
329
330 optional<double>
331 FFmpegExaminer::sample_aspect_ratio () const
332 {
333         DCPOMATIC_ASSERT (_video_stream);
334         AVRational sar = av_guess_sample_aspect_ratio (_format_context, _format_context->streams[_video_stream.get()], 0);
335         if (sar.num == 0) {
336                 /* I assume this means that we don't know */
337                 return optional<double> ();
338         }
339         return double (sar.num) / sar.den;
340 }
341
342 string
343 FFmpegExaminer::subtitle_stream_name (AVStream* s) const
344 {
345         string n = stream_name (s);
346
347         if (n.empty()) {
348                 n = _("unknown");
349         }
350
351         return n;
352 }
353
354 string
355 FFmpegExaminer::stream_name (AVStream* s) const
356 {
357         string n;
358
359         if (s->metadata) {
360                 AVDictionaryEntry const * lang = av_dict_get (s->metadata, "language", 0, 0);
361                 if (lang) {
362                         n = lang->value;
363                 }
364
365                 AVDictionaryEntry const * title = av_dict_get (s->metadata, "title", 0, 0);
366                 if (title) {
367                         if (!n.empty()) {
368                                 n += " ";
369                         }
370                         n += title->value;
371                 }
372         }
373
374         return n;
375 }
376
377 int
378 FFmpegExaminer::bits_per_pixel () const
379 {
380         if (video_codec_context()->pix_fmt == -1) {
381                 throw DecodeError (_("Could not find pixel format for video."));
382         }
383
384         AVPixFmtDescriptor const * d = av_pix_fmt_desc_get (video_codec_context()->pix_fmt);
385         DCPOMATIC_ASSERT (d);
386         return av_get_bits_per_pixel (d);
387 }
388
389 bool
390 FFmpegExaminer::yuv () const
391 {
392         switch (video_codec_context()->pix_fmt) {
393         case AV_PIX_FMT_YUV420P:
394         case AV_PIX_FMT_YUYV422:
395         case AV_PIX_FMT_YUV422P:
396         case AV_PIX_FMT_YUV444P:
397         case AV_PIX_FMT_YUV410P:
398         case AV_PIX_FMT_YUV411P:
399         case AV_PIX_FMT_YUVJ420P:
400         case AV_PIX_FMT_YUVJ422P:
401         case AV_PIX_FMT_YUVJ444P:
402         case AV_PIX_FMT_UYVY422:
403         case AV_PIX_FMT_UYYVYY411:
404         case AV_PIX_FMT_NV12:
405         case AV_PIX_FMT_NV21:
406         case AV_PIX_FMT_YUV440P:
407         case AV_PIX_FMT_YUVJ440P:
408         case AV_PIX_FMT_YUVA420P:
409         case AV_PIX_FMT_YUV420P16LE:
410         case AV_PIX_FMT_YUV420P16BE:
411         case AV_PIX_FMT_YUV422P16LE:
412         case AV_PIX_FMT_YUV422P16BE:
413         case AV_PIX_FMT_YUV444P16LE:
414         case AV_PIX_FMT_YUV444P16BE:
415         case AV_PIX_FMT_YUV420P9BE:
416         case AV_PIX_FMT_YUV420P9LE:
417         case AV_PIX_FMT_YUV420P10BE:
418         case AV_PIX_FMT_YUV420P10LE:
419         case AV_PIX_FMT_YUV422P10BE:
420         case AV_PIX_FMT_YUV422P10LE:
421         case AV_PIX_FMT_YUV444P9BE:
422         case AV_PIX_FMT_YUV444P9LE:
423         case AV_PIX_FMT_YUV444P10BE:
424         case AV_PIX_FMT_YUV444P10LE:
425         case AV_PIX_FMT_YUV422P9BE:
426         case AV_PIX_FMT_YUV422P9LE:
427         case AV_PIX_FMT_YUVA420P9BE:
428         case AV_PIX_FMT_YUVA420P9LE:
429         case AV_PIX_FMT_YUVA422P9BE:
430         case AV_PIX_FMT_YUVA422P9LE:
431         case AV_PIX_FMT_YUVA444P9BE:
432         case AV_PIX_FMT_YUVA444P9LE:
433         case AV_PIX_FMT_YUVA420P10BE:
434         case AV_PIX_FMT_YUVA420P10LE:
435         case AV_PIX_FMT_YUVA422P10BE:
436         case AV_PIX_FMT_YUVA422P10LE:
437         case AV_PIX_FMT_YUVA444P10BE:
438         case AV_PIX_FMT_YUVA444P10LE:
439         case AV_PIX_FMT_YUVA420P16BE:
440         case AV_PIX_FMT_YUVA420P16LE:
441         case AV_PIX_FMT_YUVA422P16BE:
442         case AV_PIX_FMT_YUVA422P16LE:
443         case AV_PIX_FMT_YUVA444P16BE:
444         case AV_PIX_FMT_YUVA444P16LE:
445         case AV_PIX_FMT_NV16:
446         case AV_PIX_FMT_NV20LE:
447         case AV_PIX_FMT_NV20BE:
448         case AV_PIX_FMT_YVYU422:
449         case AV_PIX_FMT_YUVA444P:
450         case AV_PIX_FMT_YUVA422P:
451         case AV_PIX_FMT_YUV420P12BE:
452         case AV_PIX_FMT_YUV420P12LE:
453         case AV_PIX_FMT_YUV420P14BE:
454         case AV_PIX_FMT_YUV420P14LE:
455         case AV_PIX_FMT_YUV422P12BE:
456         case AV_PIX_FMT_YUV422P12LE:
457         case AV_PIX_FMT_YUV422P14BE:
458         case AV_PIX_FMT_YUV422P14LE:
459         case AV_PIX_FMT_YUV444P12BE:
460         case AV_PIX_FMT_YUV444P12LE:
461         case AV_PIX_FMT_YUV444P14BE:
462         case AV_PIX_FMT_YUV444P14LE:
463         case AV_PIX_FMT_YUVJ411P:
464                 return true;
465         default:
466                 return false;
467         }
468 }
469
470 bool
471 FFmpegExaminer::has_video () const
472 {
473         return static_cast<bool> (_video_stream);
474 }