X-Git-Url: https://git.carlh.net/gitweb/?a=blobdiff_plain;f=src%2Flib%2Frender_subtitles.cc;h=5f587c3137504c759df8ba29306e4e0b99fb0926;hb=cebabb10b6055a168ac3aa1470751e17898a3b89;hp=1984d9c670b2fd4d529d0595579071d2f42cefab;hpb=36b99f997b4a859945bad7adf96f8d76864be7d6;p=dcpomatic.git diff --git a/src/lib/render_subtitles.cc b/src/lib/render_subtitles.cc index 1984d9c67..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; } @@ -277,7 +285,6 @@ render_line (list subtitles, list > fonts, dcp: } if (subtitles.front().effect() == dcp::BORDER) { - cout << "border it " << (subtitles.front().outline_width * target.width) << " " << fade_factor << ".\n"; /* Border effect; stroke the subtitle with a large (arbitrarily chosen) line width */ set_source_rgba (context, subtitles.front().effect_colour(), fade_factor); context->set_line_width (subtitles.front().outline_width * target.width / 2048.0); @@ -343,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;