diff options
| author | Carl Hetherington <cth@carlh.net> | 2013-07-10 15:04:57 +0100 |
|---|---|---|
| committer | Carl Hetherington <cth@carlh.net> | 2013-07-10 15:04:57 +0100 |
| commit | 611f2241c6732c2c38d87e129e51cf9d8d7a08b8 (patch) | |
| tree | 0c00420654d322856aecb5c6bbaeb483b3db7211 /src | |
| parent | ade36b7e120838840d0f645763b8e0814eaf9ee4 (diff) | |
Basic return of subtitles.
Diffstat (limited to 'src')
| -rw-r--r-- | src/lib/ffmpeg_decoder.cc | 48 | ||||
| -rw-r--r-- | src/lib/ffmpeg_decoder.h | 4 | ||||
| -rw-r--r-- | src/lib/player.cc | 44 | ||||
| -rw-r--r-- | src/lib/player.h | 5 | ||||
| -rw-r--r-- | src/lib/subtitle.h | 1 | ||||
| -rw-r--r-- | src/lib/subtitle_decoder.cc | 41 | ||||
| -rw-r--r-- | src/lib/subtitle_decoder.h | 35 | ||||
| -rw-r--r-- | src/lib/video_decoder.cc | 18 | ||||
| -rw-r--r-- | src/lib/wscript | 1 |
9 files changed, 141 insertions, 56 deletions
diff --git a/src/lib/ffmpeg_decoder.cc b/src/lib/ffmpeg_decoder.cc index d8ee278b3..3714c1542 100644 --- a/src/lib/ffmpeg_decoder.cc +++ b/src/lib/ffmpeg_decoder.cc @@ -61,6 +61,7 @@ FFmpegDecoder::FFmpegDecoder (shared_ptr<const Film> f, shared_ptr<const FFmpegC : Decoder (f) , VideoDecoder (f) , AudioDecoder (f) + , SubtitleDecoder (f) , FFmpeg (c) , _subtitle_codec_context (0) , _subtitle_codec (0) @@ -142,27 +143,7 @@ FFmpegDecoder::pass () } else if (_ffmpeg_content->audio_stream() && _packet.stream_index == _ffmpeg_content->audio_stream()->id && _decode_audio) { decode_audio_packet (); } else if (_ffmpeg_content->subtitle_stream() && _packet.stream_index == _ffmpeg_content->subtitle_stream()->id) { -#if 0 - - int got_subtitle; - AVSubtitle sub; - if (avcodec_decode_subtitle2 (_subtitle_codec_context, &sub, &got_subtitle, &_packet) && got_subtitle) { - /* Sometimes we get an empty AVSubtitle, which is used by some codecs to - indicate that the previous subtitle should stop. - */ - if (sub.num_rects > 0) { - shared_ptr<TimedSubtitle> ts; - try { - subtitle (shared_ptr<TimedSubtitle> (new TimedSubtitle (sub))); - } catch (...) { - /* some problem with the subtitle; we probably didn't understand it */ - } - } else { - subtitle (shared_ptr<TimedSubtitle> ()); - } - avsubtitle_free (&sub); - } -#endif + decode_subtitle_packet (); } av_free_packet (&_packet); @@ -489,3 +470,28 @@ FFmpegDecoder::done () const return vd && ad; } +void +FFmpegDecoder::decode_subtitle_packet () +{ + int got_subtitle; + AVSubtitle sub; + if (avcodec_decode_subtitle2 (_subtitle_codec_context, &sub, &got_subtitle, &_packet) < 0 || !got_subtitle) { + return; + } + + /* Sometimes we get an empty AVSubtitle, which is used by some codecs to + indicate that the previous subtitle should stop. + */ + if (sub.num_rects > 0) { + shared_ptr<TimedSubtitle> ts; + try { + subtitle (shared_ptr<TimedSubtitle> (new TimedSubtitle (sub))); + } catch (...) { + /* some problem with the subtitle; we probably didn't understand it */ + } + } else { + subtitle (shared_ptr<TimedSubtitle> ()); + } + + avsubtitle_free (&sub); +} diff --git a/src/lib/ffmpeg_decoder.h b/src/lib/ffmpeg_decoder.h index eebf75445..8819954db 100644 --- a/src/lib/ffmpeg_decoder.h +++ b/src/lib/ffmpeg_decoder.h @@ -35,6 +35,7 @@ extern "C" { #include "decoder.h" #include "video_decoder.h" #include "audio_decoder.h" +#include "subtitle_decoder.h" #include "ffmpeg.h" class Film; @@ -43,7 +44,7 @@ class ffmpeg_pts_offset_test; /** @class FFmpegDecoder * @brief A decoder using FFmpeg to decode content. */ -class FFmpegDecoder : public VideoDecoder, public AudioDecoder, public FFmpeg +class FFmpegDecoder : public VideoDecoder, public AudioDecoder, public SubtitleDecoder, public FFmpeg { public: FFmpegDecoder (boost::shared_ptr<const Film>, boost::shared_ptr<const FFmpegContent>, bool video, bool audio); @@ -69,6 +70,7 @@ private: bool decode_video_packet (); void decode_audio_packet (); + void decode_subtitle_packet (); void maybe_add_subtitle (); boost::shared_ptr<AudioBuffers> deinterleave_audio (uint8_t** data, int size); diff --git a/src/lib/player.cc b/src/lib/player.cc index 6b7dc2722..2bafbdcd5 100644 --- a/src/lib/player.cc +++ b/src/lib/player.cc @@ -31,6 +31,7 @@ #include "image.h" #include "ratio.h" #include "resampler.h" +#include "subtitle.h" using std::list; using std::cout; @@ -215,48 +216,46 @@ Player::process_video (weak_ptr<Piece> weak_piece, shared_ptr<const Image> image return; } - image = image->crop (content->crop(), true); + shared_ptr<Image> work_image = image->crop (content->crop(), true); libdcp::Size const image_size = content->ratio()->size (_video_container_size); - image = image->scale_and_convert_to_rgb (image_size, _film->scaler(), true); + work_image = work_image->scale_and_convert_to_rgb (image_size, _film->scaler(), true); -#if 0 - if (film->with_subtitles ()) { + Time time = content->start() + (frame * frc.factor() * TIME_HZ / _film->dcp_video_frame_rate()); + + if (_film->with_subtitles ()) { shared_ptr<Subtitle> sub; - if (_timed_subtitle && _timed_subtitle->displayed_at (t)) { - sub = _timed_subtitle->subtitle (); + if (_subtitle && _subtitle->displayed_at (time - _subtitle_offset)) { + sub = _subtitle->subtitle (); } if (sub) { dcpomatic::Rect const tx = subtitle_transformed_area ( float (image_size.width) / content->video_size().width, float (image_size.height) / content->video_size().height, - sub->area(), film->subtitle_offset(), film->subtitle_scale() + sub->area(), _film->subtitle_offset(), _film->subtitle_scale() ); - shared_ptr<Image> im = sub->image()->scale (tx.size(), film->scaler(), true); - image->alpha_blend (im, tx.position()); + shared_ptr<Image> im = sub->image()->scale (tx.size(), _film->scaler(), true); + work_image->alpha_blend (im, tx.position()); } } -#endif if (image_size != _video_container_size) { assert (image_size.width <= _video_container_size.width); assert (image_size.height <= _video_container_size.height); shared_ptr<Image> im (new SimpleImage (PIX_FMT_RGB24, _video_container_size, true)); im->make_black (); - im->copy (image, Position ((_video_container_size.width - image_size.width) / 2, (_video_container_size.height - image_size.height) / 2)); - image = im; + im->copy (work_image, Position ((_video_container_size.width - image_size.width) / 2, (_video_container_size.height - image_size.height) / 2)); + work_image = im; } - Time time = content->start() + (frame * frc.factor() * TIME_HZ / _film->dcp_video_frame_rate()); - - Video (image, same, time); + Video (work_image, same, time); time += TIME_HZ / _film->dcp_video_frame_rate(); if (frc.repeat) { - Video (image, true, time); + Video (work_image, true, time); time += TIME_HZ / _film->dcp_video_frame_rate(); } @@ -390,6 +389,7 @@ Player::setup_pieces () fd->Video.connect (bind (&Player::process_video, this, piece, _1, _2, _3)); fd->Audio.connect (bind (&Player::process_audio, this, piece, _1, _2)); + fd->Subtitle.connect (bind (&Player::process_subtitle, this, piece, _1)); piece->decoder = fd; } @@ -514,3 +514,15 @@ Player::film_changed (Film::Property p) Changed (); } } + +void +Player::process_subtitle (weak_ptr<Piece> weak_piece, shared_ptr<TimedSubtitle> sub) +{ + shared_ptr<Piece> piece = weak_piece.lock (); + if (!piece) { + return; + } + + _subtitle = sub; + _subtitle_offset = piece->content->start (); +} diff --git a/src/lib/player.h b/src/lib/player.h index 15fa4dbd6..f96d5ac69 100644 --- a/src/lib/player.h +++ b/src/lib/player.h @@ -35,6 +35,7 @@ class AudioContent; class Piece; class Image; class Resampler; +class TimedSubtitle; /** @class Player * @brief A class which can `play' a Playlist; emitting its audio and video. @@ -77,6 +78,7 @@ private: void process_video (boost::weak_ptr<Piece>, boost::shared_ptr<const Image>, bool, VideoContent::Frame); void process_audio (boost::weak_ptr<Piece>, boost::shared_ptr<const AudioBuffers>, AudioContent::Frame); + void process_subtitle (boost::weak_ptr<Piece>, boost::shared_ptr<TimedSubtitle>); void setup_pieces (); void playlist_changed (); void content_changed (boost::weak_ptr<Content>, int); @@ -107,6 +109,9 @@ private: libdcp::Size _video_container_size; boost::shared_ptr<Image> _black_frame; std::map<boost::shared_ptr<AudioContent>, boost::shared_ptr<Resampler> > _resamplers; + + boost::shared_ptr<TimedSubtitle> _subtitle; + Time _subtitle_offset; }; #endif diff --git a/src/lib/subtitle.h b/src/lib/subtitle.h index 1020397cc..47735c453 100644 --- a/src/lib/subtitle.h +++ b/src/lib/subtitle.h @@ -60,6 +60,7 @@ subtitle_transformed_area ( ); /** A Subtitle class with details of the time over which it should be shown */ +/** XXX: merge with Subtitle? */ class TimedSubtitle { public: diff --git a/src/lib/subtitle_decoder.cc b/src/lib/subtitle_decoder.cc new file mode 100644 index 000000000..0ffe5e501 --- /dev/null +++ b/src/lib/subtitle_decoder.cc @@ -0,0 +1,41 @@ +/* + 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. + +*/ + +#include <boost/shared_ptr.hpp> +#include "subtitle_decoder.h" +#include "subtitle.h" + +using boost::shared_ptr; + +SubtitleDecoder::SubtitleDecoder (shared_ptr<const Film> f) + : Decoder (f) +{ + +} + + +/** Called by subclasses when a subtitle is ready. + * s may be 0 to say that there is no current subtitle. + * @param s New current subtitle, or 0. + */ +void +SubtitleDecoder::subtitle (shared_ptr<TimedSubtitle> s) +{ + Subtitle (s); +} diff --git a/src/lib/subtitle_decoder.h b/src/lib/subtitle_decoder.h new file mode 100644 index 000000000..0c299f61f --- /dev/null +++ b/src/lib/subtitle_decoder.h @@ -0,0 +1,35 @@ +/* + 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. + +*/ + +#include <boost/signals2.hpp> +#include "decoder.h" + +class Film; +class TimedSubtitle; + +class SubtitleDecoder : public virtual Decoder +{ +public: + SubtitleDecoder (boost::shared_ptr<const Film>); + + boost::signals2::signal<void (boost::shared_ptr<TimedSubtitle>)> Subtitle; + +protected: + void subtitle (boost::shared_ptr<TimedSubtitle>); +}; diff --git a/src/lib/video_decoder.cc b/src/lib/video_decoder.cc index f61e63d4d..0616cd437 100644 --- a/src/lib/video_decoder.cc +++ b/src/lib/video_decoder.cc @@ -42,21 +42,3 @@ VideoDecoder::video (shared_ptr<const Image> image, bool same, VideoContent::Fra _video_position = frame + 1; } -#if 0 - -/** Called by subclasses when a subtitle is ready. - * s may be 0 to say that there is no current subtitle. - * @param s New current subtitle, or 0. - */ -void -VideoDecoder::subtitle (shared_ptr<TimedSubtitle> s) -{ - _timed_subtitle = s; - - if (_timed_subtitle) { - Position const p = _timed_subtitle->subtitle()->position (); - _timed_subtitle->subtitle()->set_position (Position (p.x - _video_content->crop().left, p.y - _video_content->crop().top)); - } -} -#endif - diff --git a/src/lib/wscript b/src/lib/wscript index 2f8653984..34d44ec5b 100644 --- a/src/lib/wscript +++ b/src/lib/wscript @@ -44,6 +44,7 @@ sources = """ sndfile_content.cc sndfile_decoder.cc sound_processor.cc + subtitle_decoder.cc subtitle.cc timer.cc transcode_job.cc |
