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 "exceptions.h"
36 using std::stringstream;
37 using boost::shared_ptr;
38 using dcp::raw_convert;
40 boost::mutex FFmpeg::_mutex;
42 FFmpeg::FFmpeg (boost::shared_ptr<const FFmpegContent> c)
45 , _avio_buffer_size (4096)
58 boost::mutex::scoped_lock lm (_mutex);
60 for (uint32_t i = 0; i < _format_context->nb_streams; ++i) {
61 AVCodecContext* context = _format_context->streams[i]->codec;
62 if (context->codec_type == AVMEDIA_TYPE_VIDEO || context->codec_type == AVMEDIA_TYPE_AUDIO) {
63 avcodec_close (context);
67 av_frame_free (&_frame);
69 avformat_close_input (&_format_context);
73 avio_read_wrapper (void* data, uint8_t* buffer, int amount)
75 return reinterpret_cast<FFmpeg*>(data)->avio_read (buffer, amount);
79 avio_seek_wrapper (void* data, int64_t offset, int whence)
81 return reinterpret_cast<FFmpeg*>(data)->avio_seek (offset, whence);
85 FFmpeg::setup_general ()
89 _file_group.set_paths (_ffmpeg_content->paths ());
90 _avio_buffer = static_cast<uint8_t*> (wrapped_av_malloc (_avio_buffer_size));
91 _avio_context = avio_alloc_context (_avio_buffer, _avio_buffer_size, 0, this, avio_read_wrapper, 0, avio_seek_wrapper);
92 _format_context = avformat_alloc_context ();
93 _format_context->pb = _avio_context;
95 AVDictionary* options = 0;
96 /* These durations are in microseconds, and represent how far into the content file
97 we will look for streams.
99 av_dict_set (&options, "analyzeduration", raw_convert<string> (5 * 60 * 1000000).c_str(), 0);
100 av_dict_set (&options, "probesize", raw_convert<string> (5 * 60 * 1000000).c_str(), 0);
102 if (avformat_open_input (&_format_context, 0, 0, &options) < 0) {
103 throw OpenFileError (_ffmpeg_content->path(0).string ());
106 if (avformat_find_stream_info (_format_context, 0) < 0) {
107 throw DecodeError (_("could not find stream information"));
110 /* Find video stream */
112 for (uint32_t i = 0; i < _format_context->nb_streams; ++i) {
113 AVStream* s = _format_context->streams[i];
114 if (s->codec->codec_type == AVMEDIA_TYPE_VIDEO) {
119 if (_video_stream < 0) {
120 throw DecodeError (N_("could not find video stream"));
123 /* Hack: if the AVStreams have zero IDs, put some in. We
124 use the IDs so that we can cope with VOBs, in which streams
125 move about in index but remain with the same ID in different
126 VOBs. However, some files have all-zero IDs, hence this hack.
130 while (i < _format_context->nb_streams && _format_context->streams[i]->id == 0) {
134 if (i == _format_context->nb_streams) {
135 /* Put in our own IDs */
136 for (uint32_t i = 0; i < _format_context->nb_streams; ++i) {
137 _format_context->streams[i]->id = i;
141 _frame = av_frame_alloc ();
143 throw DecodeError (N_("could not allocate frame"));
148 FFmpeg::setup_video ()
150 boost::mutex::scoped_lock lm (_mutex);
152 assert (_video_stream >= 0);
153 AVCodecContext* context = _format_context->streams[_video_stream]->codec;
154 AVCodec* codec = avcodec_find_decoder (context->codec_id);
157 throw DecodeError (_("could not find video decoder"));
160 if (avcodec_open2 (context, codec, 0) < 0) {
161 throw DecodeError (N_("could not open video decoder"));
166 FFmpeg::setup_audio ()
168 boost::mutex::scoped_lock lm (_mutex);
170 for (uint32_t i = 0; i < _format_context->nb_streams; ++i) {
171 AVCodecContext* context = _format_context->streams[i]->codec;
172 if (context->codec_type != AVMEDIA_TYPE_AUDIO) {
176 AVCodec* codec = avcodec_find_decoder (context->codec_id);
178 throw DecodeError (_("could not find audio decoder"));
181 if (avcodec_open2 (context, codec, 0) < 0) {
182 throw DecodeError (N_("could not open audio decoder"));
189 FFmpeg::video_codec_context () const
191 return _format_context->streams[_video_stream]->codec;
195 FFmpeg::audio_codec_context () const
197 if (!_ffmpeg_content->audio_stream ()) {
201 return _ffmpeg_content->audio_stream()->stream(_format_context)->codec;
205 FFmpeg::avio_read (uint8_t* buffer, int const amount)
207 return _file_group.read (buffer, amount);
211 FFmpeg::avio_seek (int64_t const pos, int whence)
213 if (whence == AVSEEK_SIZE) {
214 return _file_group.length ();
217 return _file_group.seek (pos, whence);