diff options
Diffstat (limited to 'src/lib/ffmpeg_decoder.cc')
| -rw-r--r-- | src/lib/ffmpeg_decoder.cc | 46 |
1 files changed, 46 insertions, 0 deletions
diff --git a/src/lib/ffmpeg_decoder.cc b/src/lib/ffmpeg_decoder.cc index 767299ea6..e01405191 100644 --- a/src/lib/ffmpeg_decoder.cc +++ b/src/lib/ffmpeg_decoder.cc @@ -27,6 +27,7 @@ #include <iomanip> #include <iostream> #include <stdint.h> +#include <boost/lexical_cast.hpp> extern "C" { #include <tiffio.h> #include <libavcodec/avcodec.h> @@ -47,6 +48,7 @@ extern "C" { #include "util.h" #include "log.h" #include "ffmpeg_decoder.h" +#include "subtitle.h" using namespace std; using namespace boost; @@ -56,15 +58,19 @@ FFmpegDecoder::FFmpegDecoder (boost::shared_ptr<const FilmState> s, boost::share , _format_context (0) , _video_stream (-1) , _audio_stream (-1) + , _subtitle_stream (-1) , _frame (0) , _video_codec_context (0) , _video_codec (0) , _audio_codec_context (0) , _audio_codec (0) + , _subtitle_codec_context (0) + , _subtitle_codec (0) { setup_general (); setup_video (); setup_audio (); + setup_subtitle (); } FFmpegDecoder::~FFmpegDecoder () @@ -76,6 +82,10 @@ FFmpegDecoder::~FFmpegDecoder () if (_video_codec_context) { avcodec_close (_video_codec_context); } + + if (_subtitle_codec_context) { + avcodec_close (_subtitle_codec_context); + } av_free (_frame); avformat_close_input (&_format_context); @@ -101,6 +111,8 @@ FFmpegDecoder::setup_general () _video_stream = i; } else if (_format_context->streams[i]->codec->codec_type == AVMEDIA_TYPE_AUDIO) { _audio_stream = i; + } else if (_format_context->streams[i]->codec->codec_type == AVMEDIA_TYPE_SUBTITLE) { + _subtitle_stream = i; } } @@ -156,6 +168,26 @@ FFmpegDecoder::setup_audio () } } +void +FFmpegDecoder::setup_subtitle () +{ + if (_subtitle_stream < 0) { + return; + } + + _subtitle_codec_context = _format_context->streams[_subtitle_stream]->codec; + _subtitle_codec = avcodec_find_decoder (_subtitle_codec_context->codec_id); + + if (_subtitle_codec == 0) { + throw DecodeError ("could not find subtitle decoder"); + } + + if (avcodec_open2 (_subtitle_codec_context, _subtitle_codec, 0) < 0) { + throw DecodeError ("could not open subtitle decoder"); + } +} + + bool FFmpegDecoder::do_pass () { @@ -210,6 +242,15 @@ FFmpegDecoder::do_pass () assert (_audio_codec_context->channels == _fs->audio_channels); process_audio (_frame->data[0], data_size); } + + } else if (_subtitle_stream >= 0 && _packet.stream_index == _subtitle_stream && _opt->decode_subtitles) { + + int got_subtitle; + AVSubtitle sub; + if (avcodec_decode_subtitle2 (_subtitle_codec_context, &sub, &got_subtitle, &_packet) && got_subtitle) { + process_subtitle (shared_ptr<Subtitle> (new Subtitle (sub))); + avsubtitle_free (&sub); + } } av_free_packet (&_packet); @@ -310,3 +351,8 @@ FFmpegDecoder::sample_aspect_ratio_denominator () const return _video_codec_context->sample_aspect_ratio.den; } +bool +FFmpegDecoder::has_subtitles () const +{ + return (_subtitle_stream != -1); +} |
