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"
33 using std::stringstream;
34 using boost::shared_ptr;
36 boost::mutex FFmpeg::_mutex;
38 FFmpeg::FFmpeg (boost::shared_ptr<const FFmpegContent> c)
43 , _video_codec_context (0)
45 , _audio_codec_context (0)
55 boost::mutex::scoped_lock lm (_mutex);
57 if (_audio_codec_context) {
58 avcodec_close (_audio_codec_context);
61 if (_video_codec_context) {
62 avcodec_close (_video_codec_context);
67 avformat_close_input (&_format_context);
71 FFmpeg::setup_general ()
75 if (avformat_open_input (&_format_context, _ffmpeg_content->file().string().c_str(), 0, 0) < 0) {
76 throw OpenFileError (_ffmpeg_content->file().string ());
79 if (avformat_find_stream_info (_format_context, 0) < 0) {
80 throw DecodeError (_("could not find stream information"));
83 /* Find video stream */
85 for (uint32_t i = 0; i < _format_context->nb_streams; ++i) {
86 AVStream* s = _format_context->streams[i];
87 if (s->codec->codec_type == AVMEDIA_TYPE_VIDEO) {
92 if (_video_stream < 0) {
93 throw DecodeError (N_("could not find video stream"));
96 _frame = avcodec_alloc_frame ();
98 throw DecodeError (N_("could not allocate frame"));
103 FFmpeg::setup_video ()
105 boost::mutex::scoped_lock lm (_mutex);
107 _video_codec_context = _format_context->streams[_video_stream]->codec;
108 _video_codec = avcodec_find_decoder (_video_codec_context->codec_id);
110 if (_video_codec == 0) {
111 throw DecodeError (_("could not find video decoder"));
114 if (avcodec_open2 (_video_codec_context, _video_codec, 0) < 0) {
115 throw DecodeError (N_("could not open video decoder"));
120 FFmpeg::setup_audio ()
122 boost::mutex::scoped_lock lm (_mutex);
124 if (!_ffmpeg_content->audio_stream ()) {
128 _audio_codec_context = _format_context->streams[_ffmpeg_content->audio_stream()->id]->codec;
129 _audio_codec = avcodec_find_decoder (_audio_codec_context->codec_id);
131 if (_audio_codec == 0) {
132 throw DecodeError (_("could not find audio decoder"));
135 if (avcodec_open2 (_audio_codec_context, _audio_codec, 0) < 0) {
136 throw DecodeError (N_("could not open audio decoder"));