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