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>
26 #include "ffmpeg_content.h"
27 #include "ffmpeg_audio_stream.h"
28 #include "ffmpeg_subtitle_stream.h"
29 #include "exceptions.h"
31 #include "raw_convert.h"
37 using boost::shared_ptr;
39 boost::mutex FFmpeg::_mutex;
41 FFmpeg::FFmpeg (boost::shared_ptr<const FFmpegContent> c)
44 , _avio_buffer_size (4096)
56 boost::mutex::scoped_lock lm (_mutex);
58 for (uint32_t i = 0; i < _format_context->nb_streams; ++i) {
59 avcodec_close (_format_context->streams[i]->codec);
62 av_frame_free (&_frame);
63 avformat_close_input (&_format_context);
67 avio_read_wrapper (void* data, uint8_t* buffer, int amount)
69 return reinterpret_cast<FFmpeg*>(data)->avio_read (buffer, amount);
73 avio_seek_wrapper (void* data, int64_t offset, int whence)
75 return reinterpret_cast<FFmpeg*>(data)->avio_seek (offset, whence);
79 FFmpeg::setup_general ()
83 _file_group.set_paths (_ffmpeg_content->paths ());
84 _avio_buffer = static_cast<uint8_t*> (wrapped_av_malloc (_avio_buffer_size));
85 _avio_context = avio_alloc_context (_avio_buffer, _avio_buffer_size, 0, this, avio_read_wrapper, 0, avio_seek_wrapper);
86 _format_context = avformat_alloc_context ();
87 _format_context->pb = _avio_context;
89 AVDictionary* options = 0;
90 /* These durations are in microseconds, and represent how far into the content file
91 we will look for streams.
93 av_dict_set (&options, "analyzeduration", raw_convert<string> (5 * 60 * 1000000).c_str(), 0);
94 av_dict_set (&options, "probesize", raw_convert<string> (5 * 60 * 1000000).c_str(), 0);
96 if (avformat_open_input (&_format_context, 0, 0, &options) < 0) {
97 throw OpenFileError (_ffmpeg_content->path(0).string ());
100 if (avformat_find_stream_info (_format_context, 0) < 0) {
101 throw DecodeError (_("could not find stream information"));
104 /* Find video stream */
106 for (uint32_t i = 0; i < _format_context->nb_streams; ++i) {
107 AVStream* s = _format_context->streams[i];
108 /* Files from iTunes sometimes have two video streams, one with the avg_frame_rate.num and .den set
109 to zero. Ignore these streams.
111 if (s->codec->codec_type == AVMEDIA_TYPE_VIDEO && s->avg_frame_rate.num > 0 && s->avg_frame_rate.den > 0) {
116 if (_video_stream < 0) {
117 throw DecodeError (N_("could not find video stream"));
120 /* Hack: if the AVStreams have zero IDs, put some in. We
121 use the IDs so that we can cope with VOBs, in which streams
122 move about in index but remain with the same ID in different
123 VOBs. However, some files have all-zero IDs, hence this hack.
127 while (i < _format_context->nb_streams && _format_context->streams[i]->id == 0) {
131 if (i == _format_context->nb_streams) {
132 /* Put in our own IDs */
133 for (uint32_t i = 0; i < _format_context->nb_streams; ++i) {
134 _format_context->streams[i]->id = i;
138 _frame = av_frame_alloc ();
140 throw DecodeError (N_("could not allocate frame"));
145 FFmpeg::setup_decoders ()
147 boost::mutex::scoped_lock lm (_mutex);
149 for (uint32_t i = 0; i < _format_context->nb_streams; ++i) {
150 AVCodecContext* context = _format_context->streams[i]->codec;
152 AVCodec* codec = avcodec_find_decoder (context->codec_id);
155 /* This option disables decoding of DCA frame footers in our patched version
156 of FFmpeg. I believe these footers are of no use to us, and they can cause
157 problems when FFmpeg fails to decode them (mantis #352).
159 AVDictionary* options = 0;
160 av_dict_set (&options, "disable_footer", "1", 0);
162 if (avcodec_open2 (context, codec, &options) < 0) {
163 throw DecodeError (N_("could not open decoder"));
167 /* We are silently ignoring any failures to find suitable decoders here */
172 FFmpeg::video_codec_context () const
174 return _format_context->streams[_video_stream]->codec;
178 FFmpeg::audio_codec_context () const
180 if (!_ffmpeg_content->audio_stream ()) {
184 return _ffmpeg_content->audio_stream()->stream(_format_context)->codec;
188 FFmpeg::subtitle_codec_context () const
190 if (!_ffmpeg_content->subtitle_stream ()) {
194 return _ffmpeg_content->subtitle_stream()->stream(_format_context)->codec;
198 FFmpeg::avio_read (uint8_t* buffer, int const amount)
200 return _file_group.read (buffer, amount);
204 FFmpeg::avio_seek (int64_t const pos, int whence)
206 if (whence == AVSEEK_SIZE) {
207 return _file_group.length ();
210 return _file_group.seek (pos, whence);