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)
59 , _subtitle_stream (-1)
61 , _video_codec_context (0)
63 , _audio_codec_context (0)
65 , _subtitle_codec_context (0)
67 , _have_subtitle (false)
75 FFmpegDecoder::~FFmpegDecoder ()
77 if (_audio_codec_context) {
78 avcodec_close (_audio_codec_context);
81 if (_video_codec_context) {
82 avcodec_close (_video_codec_context);
86 avsubtitle_free (&_subtitle);
89 if (_subtitle_codec_context) {
90 avcodec_close (_subtitle_codec_context);
94 avformat_close_input (&_format_context);
98 FFmpegDecoder::setup_general ()
104 if ((r = avformat_open_input (&_format_context, _fs->content_path().c_str(), 0, 0)) != 0) {
105 throw OpenFileError (_fs->content_path ());
108 if (avformat_find_stream_info (_format_context, 0) < 0) {
109 throw DecodeError ("could not find stream information");
112 for (uint32_t i = 0; i < _format_context->nb_streams; ++i) {
113 if (_format_context->streams[i]->codec->codec_type == AVMEDIA_TYPE_VIDEO) {
115 } else if (_format_context->streams[i]->codec->codec_type == AVMEDIA_TYPE_AUDIO) {
117 } else if (_format_context->streams[i]->codec->codec_type == AVMEDIA_TYPE_SUBTITLE) {
118 _subtitle_stream = i;
122 if (_video_stream < 0) {
123 throw DecodeError ("could not find video stream");
126 _frame = avcodec_alloc_frame ();
128 throw DecodeError ("could not allocate frame");
133 FFmpegDecoder::setup_video ()
135 _video_codec_context = _format_context->streams[_video_stream]->codec;
136 _video_codec = avcodec_find_decoder (_video_codec_context->codec_id);
138 if (_video_codec == 0) {
139 throw DecodeError ("could not find video decoder");
142 if (avcodec_open2 (_video_codec_context, _video_codec, 0) < 0) {
143 throw DecodeError ("could not open video decoder");
148 FFmpegDecoder::setup_audio ()
150 if (_audio_stream < 0) {
154 _audio_codec_context = _format_context->streams[_audio_stream]->codec;
155 _audio_codec = avcodec_find_decoder (_audio_codec_context->codec_id);
157 if (_audio_codec == 0) {
158 throw DecodeError ("could not find audio decoder");
161 if (avcodec_open2 (_audio_codec_context, _audio_codec, 0) < 0) {
162 throw DecodeError ("could not open audio decoder");
165 /* This is a hack; sometimes it seems that _audio_codec_context->channel_layout isn't set up,
166 so bodge it here. No idea why we should have to do this.
169 if (_audio_codec_context->channel_layout == 0) {
170 _audio_codec_context->channel_layout = av_get_default_channel_layout (audio_channels ());
175 FFmpegDecoder::setup_subtitle ()
177 if (_subtitle_stream < 0) {
181 _subtitle_codec_context = _format_context->streams[_subtitle_stream]->codec;
182 _subtitle_codec = avcodec_find_decoder (_subtitle_codec_context->codec_id);
184 if (_subtitle_codec == 0) {
185 throw DecodeError ("could not find subtitle decoder");
188 if (avcodec_open2 (_subtitle_codec_context, _subtitle_codec, 0) < 0) {
189 throw DecodeError ("could not open subtitle decoder");
195 FFmpegDecoder::do_pass ()
197 int r = av_read_frame (_format_context, &_packet);
199 if (r != AVERROR_EOF) {
200 throw DecodeError ("error on av_read_frame");
203 /* Get any remaining frames */
210 if (_opt->decode_video) {
211 while (avcodec_decode_video2 (_video_codec_context, _frame, &frame_finished, &_packet) >= 0 && frame_finished) {
213 process_video (_frame);
217 if (_audio_stream >= 0 && _opt->decode_audio) {
218 while (avcodec_decode_audio4 (_audio_codec_context, _frame, &frame_finished, &_packet) >= 0 && frame_finished) {
219 int const data_size = av_samples_get_buffer_size (
220 0, _audio_codec_context->channels, _frame->nb_samples, audio_sample_format (), 1
223 assert (_audio_codec_context->channels == _fs->audio_channels);
224 process_audio (_frame->data[0], data_size);
231 if (_packet.stream_index == _video_stream && _opt->decode_video) {
234 if (avcodec_decode_video2 (_video_codec_context, _frame, &frame_finished, &_packet) >= 0 && frame_finished) {
236 cout << "decoded some video.\n";
237 if (_have_subtitle) {
238 cout << "have a subtitle; " << _subtitle.num_rects << "\n";
239 for (unsigned int i = 0; i < _subtitle.num_rects; ++i) {
240 AVSubtitleRect* rect = _subtitle.rects[i];
241 if (rect->type != SUBTITLE_BITMAP) {
242 cout << "not a bitmap\n";
243 throw DecodeError ("non-bitmap subtitles not yet supported");
246 /* XXX: all this assumes YUV420 in _frame */
248 assert (rect->nb_colors == 4);
249 assert (rect->pict.data[0]);
251 /* Start of the first line in the target frame */
252 uint8_t* frame_y_p = _frame->data[0] + rect->y * _frame->linesize[0];
253 uint8_t* frame_u_p = _frame->data[1] + (rect->y / 2) * _frame->linesize[1];
254 uint8_t* frame_v_p = _frame->data[2] + (rect->y / 2) * _frame->linesize[2];
256 /* Start of the first line in the subtitle */
257 uint8_t* sub_p = rect->pict.data[0];
259 cout << "frame ls 0 is " << _frame->linesize[0] << "\n";
260 cout << "frame ls 1 is " << _frame->linesize[1] << "\n";
261 cout << "frame ls 2 is " << _frame->linesize[2] << "\n";
263 uint32_t* palette = (uint32_t *) rect->pict.data[1];
265 for (int sub_y = 0; sub_y < rect->h; ++sub_y) {
266 uint8_t* sub_line_p = sub_p;
267 uint8_t* frame_line_y_p = frame_y_p + rect->x;
268 uint8_t* frame_line_u_p = frame_u_p + (rect->x / 2);
269 uint8_t* frame_line_v_p = frame_v_p + (rect->x / 2);
271 uint8_t current_u = 0;
272 uint8_t current_v = 0;
273 int subsample_step = 0;
275 for (int sub_x = 0; sub_x < rect->w; ++sub_x) {
277 uint32_t const val = palette[*sub_line_p++];
278 int const red = (val & 0xff);
279 int const green = (val & 0xff00) >> 8;
280 int const blue = (val & 0xff0000) >> 16;
281 int const alpha = (val & 0xff000000) >> 24;
284 *frame_line_y_p = RGB_TO_Y_CCIR (red, green, blue);
288 current_u |= ((RGB_TO_U_CCIR (red, green, blue, 0) & 0xf0) >> 4) << (4 * subsample_step);
289 current_v |= ((RGB_TO_V_CCIR (red, green, blue, 0) & 0xf0) >> 4) << (4 * subsample_step);
291 if (subsample_step == 1 && (sub_y % 2) == 0) {
293 *frame_line_u_p = current_u;
294 *frame_line_v_p = current_v;
298 current_u = current_v = 0;
301 subsample_step = (subsample_step + 1) % 2;
304 sub_p += rect->pict.linesize[0];
305 frame_y_p += _frame->linesize[0];
306 if ((sub_y % 2) == 0) {
307 frame_u_p += _frame->linesize[1];
308 frame_v_p += _frame->linesize[2];
314 process_video (_frame);
317 } else if (_audio_stream >= 0 && _packet.stream_index == _audio_stream && _opt->decode_audio) {
319 avcodec_get_frame_defaults (_frame);
322 if (avcodec_decode_audio4 (_audio_codec_context, _frame, &frame_finished, &_packet) >= 0 && frame_finished) {
323 int const data_size = av_samples_get_buffer_size (
324 0, _audio_codec_context->channels, _frame->nb_samples, audio_sample_format (), 1
327 assert (_audio_codec_context->channels == _fs->audio_channels);
328 process_audio (_frame->data[0], data_size);
331 } else if (_subtitle_stream >= 0 && _packet.stream_index == _subtitle_stream) {
333 if (_have_subtitle) {
334 avsubtitle_free (&_subtitle);
335 _have_subtitle = false;
339 if (avcodec_decode_subtitle2 (_subtitle_codec_context, &_subtitle, &got_subtitle, &_packet) && got_subtitle) {
340 cout << "got a subtitle.\n";
341 _have_subtitle = true;
345 av_free_packet (&_packet);
350 FFmpegDecoder::length_in_frames () const
352 return (_format_context->duration / AV_TIME_BASE) * frames_per_second ();
356 FFmpegDecoder::frames_per_second () const
358 return av_q2d (_format_context->streams[_video_stream]->avg_frame_rate);
362 FFmpegDecoder::audio_channels () const
364 if (_audio_codec_context == 0) {
368 return _audio_codec_context->channels;
372 FFmpegDecoder::audio_sample_rate () const
374 if (_audio_codec_context == 0) {
378 return _audio_codec_context->sample_rate;
382 FFmpegDecoder::audio_sample_format () const
384 if (_audio_codec_context == 0) {
385 return (AVSampleFormat) 0;
388 return _audio_codec_context->sample_fmt;
392 FFmpegDecoder::audio_channel_layout () const
394 if (_audio_codec_context == 0) {
398 return _audio_codec_context->channel_layout;
402 FFmpegDecoder::native_size () const
404 return Size (_video_codec_context->width, _video_codec_context->height);
408 FFmpegDecoder::pixel_format () const
410 return _video_codec_context->pix_fmt;
414 FFmpegDecoder::time_base_numerator () const
416 return _video_codec_context->time_base.num;
420 FFmpegDecoder::time_base_denominator () const
422 return _video_codec_context->time_base.den;
426 FFmpegDecoder::sample_aspect_ratio_numerator () const
428 return _video_codec_context->sample_aspect_ratio.num;
432 FFmpegDecoder::sample_aspect_ratio_denominator () const
434 return _video_codec_context->sample_aspect_ratio.den;