diff options
| author | Carl Hetherington <cth@carlh.net> | 2013-07-11 14:29:55 +0100 |
|---|---|---|
| committer | Carl Hetherington <cth@carlh.net> | 2013-07-11 14:29:55 +0100 |
| commit | b655bd3359e9a014da68cd9f61e2a5b1d233247d (patch) | |
| tree | 42ab16fdc9621fd0314a71f051804cdacd1cb823 /src/lib/ffmpeg_decoder.cc | |
| parent | e64acff7da897cd03d88aa9e8e21682545a61cc2 (diff) | |
| parent | 2514ffcd1adcca4fc8e3db894afb5cdc6c857e94 (diff) | |
Merge branch '1.0' of /home/carl/git/dvdomatic into 1.0
Diffstat (limited to 'src/lib/ffmpeg_decoder.cc')
| -rw-r--r-- | src/lib/ffmpeg_decoder.cc | 94 |
1 files changed, 72 insertions, 22 deletions
diff --git a/src/lib/ffmpeg_decoder.cc b/src/lib/ffmpeg_decoder.cc index d8ee278b3..fddb70294 100644 --- a/src/lib/ffmpeg_decoder.cc +++ b/src/lib/ffmpeg_decoder.cc @@ -41,7 +41,6 @@ extern "C" { #include "log.h" #include "ffmpeg_decoder.h" #include "filter_graph.h" -#include "subtitle.h" #include "audio_buffers.h" #include "i18n.h" @@ -61,6 +60,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 +142,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 +469,73 @@ 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) { + subtitle (shared_ptr<Image> (), dcpomatic::Rect<double> (), 0, 0); + return; + } else if (sub.num_rects > 1) { + throw DecodeError (_("multi-part subtitles not yet supported")); + } + + /* Subtitle PTS in seconds (within the source, not taking into account any of the + source that we may have chopped off for the DCP) + */ + double const packet_time = static_cast<double> (sub.pts) / AV_TIME_BASE; + + /* hence start time for this sub */ + Time const from = (packet_time + (double (sub.start_display_time) / 1e3)) * TIME_HZ; + Time const to = (packet_time + (double (sub.end_display_time) / 1e3)) * TIME_HZ; + + AVSubtitleRect const * rect = sub.rects[0]; + + if (rect->type != SUBTITLE_BITMAP) { + throw DecodeError (_("non-bitmap subtitles not yet supported")); + } + + shared_ptr<Image> image (new SimpleImage (PIX_FMT_RGBA, libdcp::Size (rect->w, rect->h), true)); + + /* Start of the first line in the subtitle */ + uint8_t* sub_p = rect->pict.data[0]; + /* sub_p looks up into a RGB palette which is here */ + uint32_t const * palette = (uint32_t *) rect->pict.data[1]; + /* Start of the output data */ + uint32_t* out_p = (uint32_t *) image->data()[0]; + + for (int y = 0; y < rect->h; ++y) { + uint8_t* sub_line_p = sub_p; + uint32_t* out_line_p = out_p; + for (int x = 0; x < rect->w; ++x) { + *out_line_p++ = palette[*sub_line_p++]; + } + sub_p += rect->pict.linesize[0]; + out_p += image->stride()[0] / sizeof (uint32_t); + } + + libdcp::Size const vs = _ffmpeg_content->video_size (); + + subtitle ( + image, + dcpomatic::Rect<double> ( + static_cast<double> (rect->x) / vs.width, + static_cast<double> (rect->y) / vs.height, + static_cast<double> (rect->w) / vs.width, + static_cast<double> (rect->h) / vs.height + ), + from, + to + ); + + + avsubtitle_free (&sub); +} |
