2 Copyright (C) 2013-2014 Carl Hetherington <cth@carlh.net>
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.
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.
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.
21 #include <libavcodec/avcodec.h>
22 #include <libavformat/avformat.h>
23 #include <libswscale/swscale.h>
25 #include <dcp/raw_convert.h>
27 #include "ffmpeg_content.h"
28 #include "ffmpeg_audio_stream.h"
29 #include "ffmpeg_subtitle_stream.h"
30 #include "exceptions.h"
37 using std::stringstream;
38 using boost::shared_ptr;
39 using dcp::raw_convert;
41 boost::mutex FFmpeg::_mutex;
43 FFmpeg::FFmpeg (boost::shared_ptr<const FFmpegContent> c)
46 , _avio_buffer_size (4096)
58 boost::mutex::scoped_lock lm (_mutex);
60 for (uint32_t i = 0; i < _format_context->nb_streams; ++i) {
61 avcodec_close (_format_context->streams[i]->codec);
64 av_frame_free (&_frame);
65 avformat_close_input (&_format_context);
69 avio_read_wrapper (void* data, uint8_t* buffer, int amount)
71 return reinterpret_cast<FFmpeg*>(data)->avio_read (buffer, amount);
75 avio_seek_wrapper (void* data, int64_t offset, int whence)
77 return reinterpret_cast<FFmpeg*>(data)->avio_seek (offset, whence);
81 FFmpeg::setup_general ()
85 _file_group.set_paths (_ffmpeg_content->paths ());
86 _avio_buffer = static_cast<uint8_t*> (wrapped_av_malloc (_avio_buffer_size));
87 _avio_context = avio_alloc_context (_avio_buffer, _avio_buffer_size, 0, this, avio_read_wrapper, 0, avio_seek_wrapper);
88 _format_context = avformat_alloc_context ();
89 _format_context->pb = _avio_context;
91 AVDictionary* options = 0;
92 /* These durations are in microseconds, and represent how far into the content file
93 we will look for streams.
95 av_dict_set (&options, "analyzeduration", raw_convert<string> (5 * 60 * 1000000).c_str(), 0);
96 av_dict_set (&options, "probesize", raw_convert<string> (5 * 60 * 1000000).c_str(), 0);
98 if (avformat_open_input (&_format_context, 0, 0, &options) < 0) {
99 throw OpenFileError (_ffmpeg_content->path(0).string ());
102 if (avformat_find_stream_info (_format_context, 0) < 0) {
103 throw DecodeError (_("could not find stream information"));
106 /* Find video stream */
108 for (uint32_t i = 0; i < _format_context->nb_streams; ++i) {
109 AVStream* s = _format_context->streams[i];
110 if (s->codec->codec_type == AVMEDIA_TYPE_VIDEO) {
115 if (_video_stream < 0) {
116 throw DecodeError (N_("could not find video stream"));
119 /* Hack: if the AVStreams have zero IDs, put some in. We
120 use the IDs so that we can cope with VOBs, in which streams
121 move about in index but remain with the same ID in different
122 VOBs. However, some files have all-zero IDs, hence this hack.
126 while (i < _format_context->nb_streams && _format_context->streams[i]->id == 0) {
130 if (i == _format_context->nb_streams) {
131 /* Put in our own IDs */
132 for (uint32_t i = 0; i < _format_context->nb_streams; ++i) {
133 _format_context->streams[i]->id = i;
137 _frame = av_frame_alloc ();
139 throw DecodeError (N_("could not allocate frame"));
144 FFmpeg::setup_decoders ()
146 boost::mutex::scoped_lock lm (_mutex);
148 for (uint32_t i = 0; i < _format_context->nb_streams; ++i) {
149 AVCodecContext* context = _format_context->streams[i]->codec;
151 AVCodec* codec = avcodec_find_decoder (context->codec_id);
153 if (avcodec_open2 (context, codec, 0) < 0) {
154 throw DecodeError (N_("could not open decoder"));
158 /* We are silently ignoring any failures to find suitable decoders here */
163 FFmpeg::video_codec_context () const
165 return _format_context->streams[_video_stream]->codec;
169 FFmpeg::audio_codec_context () const
171 if (!_ffmpeg_content->audio_stream ()) {
175 return _ffmpeg_content->audio_stream()->stream(_format_context)->codec;
179 FFmpeg::subtitle_codec_context () const
181 if (!_ffmpeg_content->subtitle_stream ()) {
185 return _ffmpeg_content->subtitle_stream()->stream(_format_context)->codec;
189 FFmpeg::avio_read (uint8_t* buffer, int const amount)
191 return _file_group.read (buffer, amount);
195 FFmpeg::avio_seek (int64_t const pos, int whence)
197 if (whence == AVSEEK_SIZE) {
198 return _file_group.length ();
201 return _file_group.seek (pos, whence);