2 Copyright (C) 2013-2015 Carl Hetherington <cth@carlh.net>
4 This file is part of DCP-o-matic.
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.
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.
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/>.
22 #include <libavcodec/avcodec.h>
23 #include <libavformat/avformat.h>
24 #include <libavutil/pixfmt.h>
25 #include <libavutil/pixdesc.h>
27 #include "ffmpeg_examiner.h"
28 #include "ffmpeg_content.h"
30 #include "ffmpeg_audio_stream.h"
31 #include "ffmpeg_subtitle_stream.h"
33 #include <boost/foreach.hpp>
41 using boost::shared_ptr;
42 using boost::optional;
44 /** @param job job that the examiner is operating in, or 0 */
45 FFmpegExaminer::FFmpegExaminer (shared_ptr<const FFmpegContent> c, shared_ptr<Job> job)
48 , _need_video_length (false)
50 /* Find audio and subtitle streams */
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) {
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.
60 if (s->codec->channel_layout == 0) {
61 s->codec->channel_layout = av_get_default_channel_layout (s->codec->channels);
64 DCPOMATIC_ASSERT (_format_context->duration != AV_NOPTS_VALUE);
65 DCPOMATIC_ASSERT (s->codec->codec);
66 DCPOMATIC_ASSERT (s->codec->codec->name);
68 _audio_streams.push_back (
69 shared_ptr<FFmpegAudioStream> (
70 new FFmpegAudioStream (
72 s->codec->codec->name,
74 s->codec->sample_rate,
75 (double (_format_context->duration) / AV_TIME_BASE) * s->codec->sample_rate,
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)));
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 ();
95 if (_need_video_length) {
96 job->sub (_("Finding length and subtitles"));
97 } else if (!_subtitle_streams.empty()) {
98 job->sub (_("Finding subtitles"));
100 job->sub (_("Finding length"));
104 /* Run through until we find:
106 * - the first audio for each stream.
107 * - the subtitle periods for each stream.
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,
114 int64_t const len = _file_group.length ();
116 int r = av_read_frame (_format_context, &_packet);
123 job->set_progress (float (_format_context->pb->pos) / len);
125 job->set_progress_unknown ();
129 AVCodecContext* context = _format_context->streams[_packet.stream_index]->codec;
131 if (_video_stream && _packet.stream_index == _video_stream.get()) {
132 video_packet (context);
135 bool got_all_audio = true;
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]);
141 if (!_audio_streams[i]->first_audio) {
142 got_all_audio = false;
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]);
152 av_packet_unref (&_packet);
154 if (_first_video && got_all_audio && _subtitle_streams.empty ()) {
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) {
163 if (i->first->unknown_to (i->second->id)) {
164 i->first->set_subtitle_to (
166 ContentTime::from_frames (video_length(), video_frame_rate().get_value_or (24))
172 /* We just added subtitles to our streams without taking the PTS offset into account;
173 this is because we might not know the PTS offset when the first subtitle is seen.
174 Now we know the PTS offset so we can apply it to those subtitles.
176 if (has_video() && video_frame_rate()) {
177 BOOST_FOREACH (shared_ptr<FFmpegSubtitleStream> i, _subtitle_streams) {
178 i->add_offset (pts_offset (_audio_streams, _first_video, video_frame_rate().get()));
184 FFmpegExaminer::video_packet (AVCodecContext* context)
186 DCPOMATIC_ASSERT (_video_stream);
188 if (_first_video && !_need_video_length) {
193 if (avcodec_decode_video2 (context, _frame, &frame_finished, &_packet) >= 0 && frame_finished) {
195 _first_video = frame_time (_format_context->streams[_video_stream.get()]);
197 if (_need_video_length) {
198 _video_length = frame_time (
199 _format_context->streams[_video_stream.get()]
200 ).get_value_or (ContentTime ()).frames_round (video_frame_rate().get ());
206 FFmpegExaminer::audio_packet (AVCodecContext* context, shared_ptr<FFmpegAudioStream> stream)
208 if (stream->first_audio) {
213 if (avcodec_decode_audio4 (context, _frame, &frame_finished, &_packet) >= 0 && frame_finished) {
214 stream->first_audio = frame_time (stream->stream (_format_context));
219 FFmpegExaminer::subtitle_packet (AVCodecContext* context, shared_ptr<FFmpegSubtitleStream> stream)
223 if (avcodec_decode_subtitle2 (context, &sub, &frame_finished, &_packet) >= 0 && frame_finished) {
224 string id = subtitle_id (sub);
225 FFmpegSubtitlePeriod const period = subtitle_period (sub);
226 bool const starts_image = subtitle_starts_image (sub);
228 /* Some streams (notably DVB streams) have subtitles which have a specified end time
229 but which are then stopped earlier than this by a zero-num_rect subtitle.
232 LastSubtitleMap::iterator last = _last_subtitle_start.find (stream);
233 if (sub.num_rects == 0 && last != _last_subtitle_start.end() && last->second) {
234 /* Set (or fix) the `to' time for the last subtitle */
235 stream->set_subtitle_to (last->second->id, period.from);
236 _last_subtitle_start[stream] = optional<SubtitleStart> ();
237 } else if (sub.num_rects > 0) {
238 /* Add a subtitle; if we don't know the `to' time we set it to the from time and fix it later */
240 stream->add_image_subtitle (id, ContentTimePeriod (period.from, period.to.get_value_or (period.from)));
242 stream->add_text_subtitle (id, ContentTimePeriod (period.from, period.to.get_value_or (period.from)));
245 _last_subtitle_start[stream] = SubtitleStart (id, starts_image, period.from);
248 for (unsigned int i = 0; i < sub.num_rects; ++i) {
249 if (sub.rects[i]->type == SUBTITLE_BITMAP) {
250 #ifdef DCPOMATIC_HAVE_AVSUBTITLERECT_PICT
251 uint32_t* palette = (uint32_t *) sub.rects[i]->pict.data[1];
252 for (int j = 0; j < sub.rects[i]->nb_colors; ++j) {
254 (palette[j] & 0x00ff0000) >> 16,
255 (palette[j] & 0x0000ff00) >> 8,
256 (palette[j] & 0x000000ff) >> 0,
257 (palette[j] & 0xff000000) >> 24
260 stream->set_colour (rgba, rgba);
263 uint32_t* palette = (uint32_t *) sub.rects[i]->data[1];
264 for (int j = 0; j < sub.rects[i]->nb_colors; ++j) {
266 (palette[j] & 0x00ff0000) >> 16,
267 (palette[j] & 0x0000ff00) >> 8,
268 (palette[j] & 0x000000ff) >> 0,
269 (palette[j] & 0xff000000) >> 24
272 stream->set_colour (rgba, rgba);
278 avsubtitle_free (&sub);
282 optional<ContentTime>
283 FFmpegExaminer::frame_time (AVStream* s) const
285 optional<ContentTime> t;
287 int64_t const bet = av_frame_get_best_effort_timestamp (_frame);
288 if (bet != AV_NOPTS_VALUE) {
289 t = ContentTime::from_seconds (bet * av_q2d (s->time_base));
296 FFmpegExaminer::video_frame_rate () const
298 DCPOMATIC_ASSERT (_video_stream);
299 /* This use of r_frame_rate is debateable; there's a few different
300 * frame rates in the format context, but this one seems to be the most
303 return av_q2d (av_stream_get_r_frame_rate (_format_context->streams[_video_stream.get()]));
307 FFmpegExaminer::video_size () const
309 return dcp::Size (video_codec_context()->width, video_codec_context()->height);
312 /** @return Length according to our content's header */
314 FFmpegExaminer::video_length () const
316 return max (Frame (1), _video_length);
320 FFmpegExaminer::sample_aspect_ratio () const
322 DCPOMATIC_ASSERT (_video_stream);
323 AVRational sar = av_guess_sample_aspect_ratio (_format_context, _format_context->streams[_video_stream.get()], 0);
325 /* I assume this means that we don't know */
326 return optional<double> ();
328 return double (sar.num) / sar.den;
332 FFmpegExaminer::subtitle_stream_name (AVStream* s) const
334 string n = stream_name (s);
344 FFmpegExaminer::stream_name (AVStream* s) const
349 AVDictionaryEntry const * lang = av_dict_get (s->metadata, "language", 0, 0);
354 AVDictionaryEntry const * title = av_dict_get (s->metadata, "title", 0, 0);
367 FFmpegExaminer::bits_per_pixel () const
369 if (video_codec_context()->pix_fmt == -1) {
370 throw DecodeError (_("Could not find pixel format for video."));
373 AVPixFmtDescriptor const * d = av_pix_fmt_desc_get (video_codec_context()->pix_fmt);
374 DCPOMATIC_ASSERT (d);
375 return av_get_bits_per_pixel (d);
379 FFmpegExaminer::yuv () const
381 switch (video_codec_context()->pix_fmt) {
382 case AV_PIX_FMT_YUV420P:
383 case AV_PIX_FMT_YUYV422:
384 case AV_PIX_FMT_YUV422P:
385 case AV_PIX_FMT_YUV444P:
386 case AV_PIX_FMT_YUV410P:
387 case AV_PIX_FMT_YUV411P:
388 case AV_PIX_FMT_YUVJ420P:
389 case AV_PIX_FMT_YUVJ422P:
390 case AV_PIX_FMT_YUVJ444P:
391 case AV_PIX_FMT_UYVY422:
392 case AV_PIX_FMT_UYYVYY411:
393 case AV_PIX_FMT_NV12:
394 case AV_PIX_FMT_NV21:
395 case AV_PIX_FMT_YUV440P:
396 case AV_PIX_FMT_YUVJ440P:
397 case AV_PIX_FMT_YUVA420P:
398 case AV_PIX_FMT_YUV420P16LE:
399 case AV_PIX_FMT_YUV420P16BE:
400 case AV_PIX_FMT_YUV422P16LE:
401 case AV_PIX_FMT_YUV422P16BE:
402 case AV_PIX_FMT_YUV444P16LE:
403 case AV_PIX_FMT_YUV444P16BE:
404 case AV_PIX_FMT_YUV420P9BE:
405 case AV_PIX_FMT_YUV420P9LE:
406 case AV_PIX_FMT_YUV420P10BE:
407 case AV_PIX_FMT_YUV420P10LE:
408 case AV_PIX_FMT_YUV422P10BE:
409 case AV_PIX_FMT_YUV422P10LE:
410 case AV_PIX_FMT_YUV444P9BE:
411 case AV_PIX_FMT_YUV444P9LE:
412 case AV_PIX_FMT_YUV444P10BE:
413 case AV_PIX_FMT_YUV444P10LE:
414 case AV_PIX_FMT_YUV422P9BE:
415 case AV_PIX_FMT_YUV422P9LE:
416 case AV_PIX_FMT_YUVA420P9BE:
417 case AV_PIX_FMT_YUVA420P9LE:
418 case AV_PIX_FMT_YUVA422P9BE:
419 case AV_PIX_FMT_YUVA422P9LE:
420 case AV_PIX_FMT_YUVA444P9BE:
421 case AV_PIX_FMT_YUVA444P9LE:
422 case AV_PIX_FMT_YUVA420P10BE:
423 case AV_PIX_FMT_YUVA420P10LE:
424 case AV_PIX_FMT_YUVA422P10BE:
425 case AV_PIX_FMT_YUVA422P10LE:
426 case AV_PIX_FMT_YUVA444P10BE:
427 case AV_PIX_FMT_YUVA444P10LE:
428 case AV_PIX_FMT_YUVA420P16BE:
429 case AV_PIX_FMT_YUVA420P16LE:
430 case AV_PIX_FMT_YUVA422P16BE:
431 case AV_PIX_FMT_YUVA422P16LE:
432 case AV_PIX_FMT_YUVA444P16BE:
433 case AV_PIX_FMT_YUVA444P16LE:
434 case AV_PIX_FMT_NV16:
435 case AV_PIX_FMT_NV20LE:
436 case AV_PIX_FMT_NV20BE:
437 case AV_PIX_FMT_YVYU422:
438 case AV_PIX_FMT_YUVA444P:
439 case AV_PIX_FMT_YUVA422P:
440 case AV_PIX_FMT_YUV420P12BE:
441 case AV_PIX_FMT_YUV420P12LE:
442 case AV_PIX_FMT_YUV420P14BE:
443 case AV_PIX_FMT_YUV420P14LE:
444 case AV_PIX_FMT_YUV422P12BE:
445 case AV_PIX_FMT_YUV422P12LE:
446 case AV_PIX_FMT_YUV422P14BE:
447 case AV_PIX_FMT_YUV422P14LE:
448 case AV_PIX_FMT_YUV444P12BE:
449 case AV_PIX_FMT_YUV444P12LE:
450 case AV_PIX_FMT_YUV444P14BE:
451 case AV_PIX_FMT_YUV444P14LE:
452 case AV_PIX_FMT_YUVJ411P:
460 FFmpegExaminer::has_video () const
462 return static_cast<bool> (_video_stream);