2 Copyright (C) 2013 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>
24 #include <libpostproc/postprocess.h>
27 #include "ffmpeg_content.h"
28 #include "exceptions.h"
34 using std::stringstream;
35 using boost::shared_ptr;
36 using boost::lexical_cast;
38 boost::mutex FFmpeg::_mutex;
40 /** @param long_probe true to do a long probe of the file looking for streams */
41 FFmpeg::FFmpeg (boost::shared_ptr<const FFmpegContent> c, bool long_probe)
44 , _avio_buffer_size (4096)
50 setup_general (long_probe);
57 boost::mutex::scoped_lock lm (_mutex);
59 for (uint32_t i = 0; i < _format_context->nb_streams; ++i) {
60 AVCodecContext* context = _format_context->streams[i]->codec;
61 if (context->codec_type == AVMEDIA_TYPE_VIDEO || context->codec_type == AVMEDIA_TYPE_AUDIO) {
62 avcodec_close (context);
66 avcodec_free_frame (&_frame);
68 avformat_close_input (&_format_context);
72 avio_read_wrapper (void* data, uint8_t* buffer, int amount)
74 return reinterpret_cast<FFmpeg*>(data)->avio_read (buffer, amount);
78 avio_seek_wrapper (void* data, int64_t offset, int whence)
80 return reinterpret_cast<FFmpeg*>(data)->avio_seek (offset, whence);
84 FFmpeg::setup_general (bool long_probe)
88 _file_group.set_paths (_ffmpeg_content->paths ());
89 _avio_buffer = static_cast<uint8_t*> (av_malloc (_avio_buffer_size));
90 _avio_context = avio_alloc_context (_avio_buffer, _avio_buffer_size, 0, this, avio_read_wrapper, 0, avio_seek_wrapper);
91 _format_context = avformat_alloc_context ();
92 _format_context->pb = _avio_context;
94 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", lexical_cast<string> (5 * 60 * 1e6).c_str(), 0);
100 av_dict_set (&options, "probesize", lexical_cast<string> (5 * 60 * 1e6).c_str(), 0);
103 if (avformat_open_input (&_format_context, 0, 0, &options) < 0) {
104 throw OpenFileError (_ffmpeg_content->path(0).string ());
107 if (avformat_find_stream_info (_format_context, 0) < 0) {
108 throw DecodeError (_("could not find stream information"));
111 /* Find video stream */
113 for (uint32_t i = 0; i < _format_context->nb_streams; ++i) {
114 AVStream* s = _format_context->streams[i];
115 if (s->codec->codec_type == AVMEDIA_TYPE_VIDEO) {
120 if (_video_stream < 0) {
121 throw DecodeError (N_("could not find video stream"));
124 _frame = avcodec_alloc_frame ();
126 throw DecodeError (N_("could not allocate frame"));
131 FFmpeg::setup_video ()
133 boost::mutex::scoped_lock lm (_mutex);
135 AVCodecContext* context = _format_context->streams[_video_stream]->codec;
136 AVCodec* codec = avcodec_find_decoder (context->codec_id);
139 throw DecodeError (_("could not find video decoder"));
142 if (avcodec_open2 (context, codec, 0) < 0) {
143 throw DecodeError (N_("could not open video decoder"));
148 FFmpeg::setup_audio ()
150 boost::mutex::scoped_lock lm (_mutex);
152 for (uint32_t i = 0; i < _format_context->nb_streams; ++i) {
153 AVCodecContext* context = _format_context->streams[i]->codec;
154 if (context->codec_type != AVMEDIA_TYPE_AUDIO) {
158 AVCodec* codec = avcodec_find_decoder (context->codec_id);
160 throw DecodeError (_("could not find audio decoder"));
163 if (avcodec_open2 (context, codec, 0) < 0) {
164 throw DecodeError (N_("could not open audio decoder"));
171 FFmpeg::video_codec_context () const
173 return _format_context->streams[_video_stream]->codec;
177 FFmpeg::audio_codec_context () const
179 return _format_context->streams[_ffmpeg_content->audio_stream()->id]->codec;
183 FFmpeg::avio_read (uint8_t* buffer, int const amount)
185 return _file_group.read (buffer, amount);
189 FFmpeg::avio_seek (int64_t const pos, int whence)
191 if (whence == AVSEEK_SIZE) {
192 return _file_group.length ();
195 return _file_group.seek (pos, whence);