summaryrefslogtreecommitdiff
path: root/src/lib/ffmpeg.cc
diff options
context:
space:
mode:
authorCarl Hetherington <cth@carlh.net>2013-06-21 17:38:50 +0100
committerCarl Hetherington <cth@carlh.net>2013-06-21 17:38:50 +0100
commitf1bf21a9c2581591ab80bfc997a22b93046f8c56 (patch)
tree7c0db304d310e656fcaf4766a6c3b27e98df25b1 /src/lib/ffmpeg.cc
parent01791aac0b11e9f296cd31a7803e287203bd8355 (diff)
Split examiner parts off decoder.
Diffstat (limited to 'src/lib/ffmpeg.cc')
-rw-r--r--src/lib/ffmpeg.cc138
1 files changed, 138 insertions, 0 deletions
diff --git a/src/lib/ffmpeg.cc b/src/lib/ffmpeg.cc
new file mode 100644
index 000000000..0d897abfa
--- /dev/null
+++ b/src/lib/ffmpeg.cc
@@ -0,0 +1,138 @@
+/*
+ Copyright (C) 2013 Carl Hetherington <cth@carlh.net>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+*/
+
+extern "C" {
+#include <libavcodec/avcodec.h>
+#include <libavformat/avformat.h>
+#include <libswscale/swscale.h>
+#include <libpostproc/postprocess.h>
+}
+#include "ffmpeg.h"
+#include "ffmpeg_content.h"
+#include "exceptions.h"
+
+#include "i18n.h"
+
+using std::string;
+using std::stringstream;
+using boost::shared_ptr;
+
+boost::mutex FFmpeg::_mutex;
+
+FFmpeg::FFmpeg (boost::shared_ptr<const FFmpegContent> c)
+ : _ffmpeg_content (c)
+ , _format_context (0)
+ , _frame (0)
+ , _video_stream (-1)
+ , _video_codec_context (0)
+ , _video_codec (0)
+ , _audio_codec_context (0)
+ , _audio_codec (0)
+{
+ setup_general ();
+ setup_video ();
+ setup_audio ();
+}
+
+FFmpeg::~FFmpeg ()
+{
+ boost::mutex::scoped_lock lm (_mutex);
+
+ if (_audio_codec_context) {
+ avcodec_close (_audio_codec_context);
+ }
+
+ if (_video_codec_context) {
+ avcodec_close (_video_codec_context);
+ }
+
+ av_free (_frame);
+
+ avformat_close_input (&_format_context);
+}
+
+void
+FFmpeg::setup_general ()
+{
+ av_register_all ();
+
+ if (avformat_open_input (&_format_context, _ffmpeg_content->file().string().c_str(), 0, 0) < 0) {
+ throw OpenFileError (_ffmpeg_content->file().string ());
+ }
+
+ if (avformat_find_stream_info (_format_context, 0) < 0) {
+ throw DecodeError (_("could not find stream information"));
+ }
+
+ /* Find video stream */
+
+ for (uint32_t i = 0; i < _format_context->nb_streams; ++i) {
+ AVStream* s = _format_context->streams[i];
+ if (s->codec->codec_type == AVMEDIA_TYPE_VIDEO) {
+ _video_stream = i;
+ }
+ }
+
+ if (_video_stream < 0) {
+ throw DecodeError (N_("could not find video stream"));
+ }
+
+ _frame = avcodec_alloc_frame ();
+ if (_frame == 0) {
+ throw DecodeError (N_("could not allocate frame"));
+ }
+}
+
+void
+FFmpeg::setup_video ()
+{
+ boost::mutex::scoped_lock lm (_mutex);
+
+ _video_codec_context = _format_context->streams[_video_stream]->codec;
+ _video_codec = avcodec_find_decoder (_video_codec_context->codec_id);
+
+ if (_video_codec == 0) {
+ throw DecodeError (_("could not find video decoder"));
+ }
+
+ if (avcodec_open2 (_video_codec_context, _video_codec, 0) < 0) {
+ throw DecodeError (N_("could not open video decoder"));
+ }
+}
+
+void
+FFmpeg::setup_audio ()
+{
+ boost::mutex::scoped_lock lm (_mutex);
+
+ if (!_ffmpeg_content->audio_stream ()) {
+ return;
+ }
+
+ _audio_codec_context = _format_context->streams[_ffmpeg_content->audio_stream()->id]->codec;
+ _audio_codec = avcodec_find_decoder (_audio_codec_context->codec_id);
+
+ if (_audio_codec == 0) {
+ throw DecodeError (_("could not find audio decoder"));
+ }
+
+ if (avcodec_open2 (_audio_codec_context, _audio_codec, 0) < 0) {
+ throw DecodeError (N_("could not open audio decoder"));
+ }
+}