2 Copyright (C) 2012 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.
20 /** @file src/ffmpeg_decoder.cc
21 * @brief A decoder using FFmpeg to decode content.
32 #include <libavcodec/avcodec.h>
33 #include <libavformat/avformat.h>
34 #include <libswscale/swscale.h>
35 #include <libpostproc/postprocess.h>
40 #include "transcoder.h"
43 #include "film_state.h"
45 #include "exceptions.h"
49 #include "ffmpeg_decoder.h"
52 using namespace boost;
54 FFmpegDecoder::FFmpegDecoder (boost::shared_ptr<const FilmState> s, boost::shared_ptr<const Options> o, Job* j, Log* l, bool minimal, bool ignore_length)
55 : Decoder (s, o, j, l, minimal, ignore_length)
60 , _video_codec_context (0)
62 , _audio_codec_context (0)
70 FFmpegDecoder::~FFmpegDecoder ()
72 if (_audio_codec_context) {
73 avcodec_close (_audio_codec_context);
76 if (_video_codec_context) {
77 avcodec_close (_video_codec_context);
81 avformat_close_input (&_format_context);
85 FFmpegDecoder::setup_general ()
91 if ((r = avformat_open_input (&_format_context, _fs->content_path().c_str(), 0, 0)) != 0) {
92 throw OpenFileError (_fs->content_path ());
95 if (avformat_find_stream_info (_format_context, 0) < 0) {
96 throw DecodeError ("could not find stream information");
99 for (uint32_t i = 0; i < _format_context->nb_streams; ++i) {
100 if (_format_context->streams[i]->codec->codec_type == AVMEDIA_TYPE_VIDEO) {
102 } else if (_format_context->streams[i]->codec->codec_type == AVMEDIA_TYPE_AUDIO) {
107 if (_video_stream < 0) {
108 throw DecodeError ("could not find video stream");
111 _frame = avcodec_alloc_frame ();
113 throw DecodeError ("could not allocate frame");
118 FFmpegDecoder::setup_video ()
120 _video_codec_context = _format_context->streams[_video_stream]->codec;
121 _video_codec = avcodec_find_decoder (_video_codec_context->codec_id);
123 if (_video_codec == 0) {
124 throw DecodeError ("could not find video decoder");
127 if (avcodec_open2 (_video_codec_context, _video_codec, 0) < 0) {
128 throw DecodeError ("could not open video decoder");
133 FFmpegDecoder::setup_audio ()
135 if (_audio_stream < 0) {
139 _audio_codec_context = _format_context->streams[_audio_stream]->codec;
140 _audio_codec = avcodec_find_decoder (_audio_codec_context->codec_id);
142 if (_audio_codec == 0) {
143 throw DecodeError ("could not find audio decoder");
146 if (avcodec_open2 (_audio_codec_context, _audio_codec, 0) < 0) {
147 throw DecodeError ("could not open audio decoder");
150 /* This is a hack; sometimes it seems that _audio_codec_context->channel_layout isn't set up,
151 so bodge it here. No idea why we should have to do this.
154 if (_audio_codec_context->channel_layout == 0) {
155 _audio_codec_context->channel_layout = av_get_default_channel_layout (audio_channels ());
160 FFmpegDecoder::do_pass ()
162 int r = av_read_frame (_format_context, &_packet);
167 if (_packet.stream_index == _video_stream && _opt->decode_video) {
170 if (avcodec_decode_video2 (_video_codec_context, _frame, &frame_finished, &_packet) >= 0 && frame_finished) {
171 process_video (_frame);
174 } else if (_audio_stream >= 0 && _packet.stream_index == _audio_stream && _opt->decode_audio) {
176 avcodec_get_frame_defaults (_frame);
179 if (avcodec_decode_audio4 (_audio_codec_context, _frame, &frame_finished, &_packet) >= 0 && frame_finished) {
180 int const data_size = av_samples_get_buffer_size (
181 0, _audio_codec_context->channels, _frame->nb_samples, audio_sample_format (), 1
184 assert (_audio_codec_context->channels == _fs->audio_channels);
185 process_audio (_frame->data[0], data_size);
189 av_free_packet (&_packet);
194 FFmpegDecoder::length_in_frames () const
196 return (_format_context->duration / AV_TIME_BASE) * frames_per_second ();
200 FFmpegDecoder::frames_per_second () const
202 return av_q2d (_format_context->streams[_video_stream]->avg_frame_rate);
206 FFmpegDecoder::audio_channels () const
208 if (_audio_codec_context == 0) {
212 return _audio_codec_context->channels;
216 FFmpegDecoder::audio_sample_rate () const
218 if (_audio_codec_context == 0) {
222 return _audio_codec_context->sample_rate;
226 FFmpegDecoder::audio_sample_format () const
228 if (_audio_codec_context == 0) {
229 return (AVSampleFormat) 0;
232 return _audio_codec_context->sample_fmt;
236 FFmpegDecoder::audio_channel_layout () const
238 if (_audio_codec_context == 0) {
242 return _audio_codec_context->channel_layout;
246 FFmpegDecoder::native_size () const
248 return Size (_video_codec_context->width, _video_codec_context->height);
252 FFmpegDecoder::pixel_format () const
254 return _video_codec_context->pix_fmt;
258 FFmpegDecoder::time_base_numerator () const
260 return _video_codec_context->time_base.num;
264 FFmpegDecoder::time_base_denominator () const
266 return _video_codec_context->time_base.den;
270 FFmpegDecoder::sample_aspect_ratio_numerator () const
272 return _video_codec_context->sample_aspect_ratio.num;
276 FFmpegDecoder::sample_aspect_ratio_denominator () const
278 return _video_codec_context->sample_aspect_ratio.den;