X-Git-Url: https://git.carlh.net/gitweb/?a=blobdiff_plain;f=src%2Flib%2Frender_subtitles.cc;h=5f587c3137504c759df8ba29306e4e0b99fb0926;hb=565490c24a46d0aa941f75cf2a03b195246008b4;hp=9426427fd507385a12973e0b02823af4c15b19da;hpb=b064fa7e95ad31accffafc21a28fa7ede0161212;p=dcpomatic.git diff --git a/src/lib/render_subtitles.cc b/src/lib/render_subtitles.cc index 9426427fd..5f587c313 100644 --- a/src/lib/render_subtitles.cc +++ b/src/lib/render_subtitles.cc @@ -85,7 +85,7 @@ set_source_rgba (Cairo::RefPtr context, dcp::Colour colour, floa * at the same time and with the same fade in/out. */ static PositionImage -render_line (list subtitles, list > fonts, dcp::Size target, DCPTime time) +render_line (list subtitles, list > fonts, dcp::Size target, DCPTime time, int frame_rate) { /* XXX: this method can only handle italic / bold changes mid-line, nothing else yet. @@ -123,7 +123,8 @@ render_line (list subtitles, list > fonts, dcp: /* ...and add a bit more for luck */ height += target.height / 11; - shared_ptr image (new Image (AV_PIX_FMT_RGBA, dcp::Size (target.width, height), false)); + /* FFmpeg BGRA means first byte blue, second byte green, third byte red, fourth byte alpha */ + shared_ptr image (new Image (AV_PIX_FMT_BGRA, dcp::Size (target.width, height), false)); image->make_black (); #ifdef DCPOMATIC_HAVE_FORMAT_STRIDE_FOR_WIDTH @@ -132,6 +133,7 @@ render_line (list subtitles, list > fonts, dcp: Cairo::FORMAT_ARGB32, image->size().width, image->size().height, + /* Cairo ARGB32 means first byte blue, second byte green, third byte red, fourth byte alpha */ Cairo::ImageSurface::format_stride_for_width (Cairo::FORMAT_ARGB32, image->size().width) ); #else @@ -240,15 +242,21 @@ render_line (list subtitles, list > fonts, dcp: /* Compute fade factor */ float fade_factor = 1; - DCPTime const fade_in_start = DCPTime::from_seconds (subtitles.front().in().as_seconds ()); + /* Round the fade start/end to the nearest frame start. Otherwise if a subtitle starts just after + the start of a frame it will be faded out. + */ + DCPTime const fade_in_start = DCPTime::from_seconds(subtitles.front().in().as_seconds()).round(frame_rate); DCPTime const fade_in_end = fade_in_start + DCPTime::from_seconds (subtitles.front().fade_up_time().as_seconds ()); - DCPTime const fade_out_end = DCPTime::from_seconds (subtitles.front().out().as_seconds ()); + DCPTime const fade_out_end = DCPTime::from_seconds (subtitles.front().out().as_seconds()).round(frame_rate); DCPTime const fade_out_start = fade_out_end - DCPTime::from_seconds (subtitles.front().fade_down_time().as_seconds ()); + if (fade_in_start <= time && time <= fade_in_end && fade_in_start != fade_in_end) { - fade_factor = DCPTime(time - fade_in_start).seconds() / DCPTime(fade_in_end - fade_in_start).seconds(); - } else if (fade_out_start <= time && time <= fade_out_end && fade_out_start != fade_out_end) { - fade_factor = 1 - DCPTime(time - fade_out_start).seconds() / DCPTime(fade_out_end - fade_out_start).seconds(); - } else if (time < fade_in_start || time > fade_out_end) { + fade_factor *= DCPTime(time - fade_in_start).seconds() / DCPTime(fade_in_end - fade_in_start).seconds(); + } + if (fade_out_start <= time && time <= fade_out_end && fade_out_start != fade_out_end) { + fade_factor *= 1 - DCPTime(time - fade_out_start).seconds() / DCPTime(fade_out_end - fade_out_start).seconds(); + } + if (time < fade_in_start || time > fade_out_end) { fade_factor = 0; } @@ -342,23 +350,25 @@ render_line (list subtitles, list > fonts, dcp: return PositionImage (image, Position (max (0, x), max (0, y))); } -/** @param time Time of the frame that these subtitles are going on */ +/** @param time Time of the frame that these subtitles are going on. + * @param frame_rate DCP frame rate. + */ list -render_subtitles (list subtitles, list > fonts, dcp::Size target, DCPTime time) +render_subtitles (list subtitles, list > fonts, dcp::Size target, DCPTime time, int frame_rate) { list pending; list images; BOOST_FOREACH (SubtitleString const & i, subtitles) { if (!pending.empty() && fabs (i.v_position() - pending.back().v_position()) > 1e-4) { - images.push_back (render_line (pending, fonts, target, time)); + images.push_back (render_line (pending, fonts, target, time, frame_rate)); pending.clear (); } pending.push_back (i); } if (!pending.empty ()) { - images.push_back (render_line (pending, fonts, target, time)); + images.push_back (render_line (pending, fonts, target, time, frame_rate)); } return images;