static char *get_text(struct sd *sd, double pts) { struct sd_ass_priv *ctx = sd->priv; ASS_Track *track = ctx->ass_track; if (pts == MP_NOPTS_VALUE) return NULL; long long ipts = find_timestamp(sd, pts); struct buf b = {ctx->last_text, sizeof(ctx->last_text) - 1}; for (int i = 0; i < track->n_events; ++i) { ASS_Event *event = track->events + i; if (ipts >= event->Start && ipts < event->Start + event->Duration) { if (event->Text) { int start = b.len; ass_to_plaintext(&b, event->Text); if (is_whitespace_only(&b.start[start], b.len - start)) { b.len = start; } else { append(&b, '\n'); } } } } b.start[b.len] = '\0'; if (b.len > 0 && b.start[b.len - 1] == '\n') b.start[b.len - 1] = '\0'; return ctx->last_text; }
static void get_bitmaps(struct sd *sd, struct mp_osd_res dim, int format, double pts, struct sub_bitmaps *res) { struct sd_ass_priv *ctx = sd->priv; struct MPOpts *opts = sd->opts; bool no_ass = !opts->ass_enabled || ctx->on_top || opts->ass_style_override == 5; bool converted = ctx->is_converted || no_ass; ASS_Track *track = no_ass ? ctx->shadow_track : ctx->ass_track; ASS_Renderer *renderer = ctx->ass_renderer; if (pts == MP_NOPTS_VALUE || !renderer) return; double scale = dim.display_par; if (!converted && (!opts->ass_style_override || opts->ass_vsfilter_aspect_compat)) { // Let's use the original video PAR for vsfilter compatibility: double par = ctx->video_params.p_w / (double)ctx->video_params.p_h; if (isnormal(par)) scale *= par; } configure_ass(sd, &dim, converted, track); ass_set_pixel_aspect(renderer, scale); if (!converted && (!opts->ass_style_override || opts->ass_vsfilter_blur_compat)) { ass_set_storage_size(renderer, ctx->video_params.w, ctx->video_params.h); } else { ass_set_storage_size(renderer, 0, 0); } long long ts = find_timestamp(sd, pts); if (ctx->duration_unknown && pts != MP_NOPTS_VALUE) { mp_ass_flush_old_events(track, ts); ctx->num_seen_packets = 0; sd->preload_ok = false; } if (no_ass) fill_plaintext(sd, pts); int changed; ASS_Image *imgs = ass_render_frame(renderer, track, ts, &changed); mp_ass_packer_pack(ctx->packer, &imgs, 1, changed, format, res); if (!converted && res->num_parts > 0) { // mangle_colors() modifies the color field, so copy the thing. MP_TARRAY_GROW(ctx, ctx->bs, res->num_parts); memcpy(ctx->bs, res->parts, sizeof(ctx->bs[0]) * res->num_parts); res->parts = ctx->bs; mangle_colors(sd, res); } }
static void get_bitmaps(struct sd *sd, struct mp_osd_res dim, double pts, struct sub_bitmaps *res) { struct sd_ass_priv *ctx = sd->priv; struct MPOpts *opts = sd->opts; bool no_ass = !opts->ass_enabled || ctx->on_top; bool converted = ctx->is_converted || no_ass; ASS_Track *track = no_ass ? ctx->shadow_track : ctx->ass_track; ASS_Renderer *renderer = ctx->ass_renderer; if (pts == MP_NOPTS_VALUE || !renderer) return; double scale = dim.display_par; if (!converted && (!opts->ass_style_override || opts->ass_vsfilter_aspect_compat)) { // Let's use the original video PAR for vsfilter compatibility: double par = ctx->video_params.p_w / (double)ctx->video_params.p_h; if (isnormal(par)) scale *= par; } configure_ass(sd, &dim, converted, track); ass_set_pixel_aspect(renderer, scale); if (!converted && (!opts->ass_style_override || opts->ass_vsfilter_blur_compat)) { ass_set_storage_size(renderer, ctx->video_params.w, ctx->video_params.h); } else { ass_set_storage_size(renderer, 0, 0); } if (no_ass) fill_plaintext(sd, pts); long long ts = find_timestamp(sd, pts); mp_ass_render_frame(renderer, track, ts, &ctx->parts, res); talloc_steal(ctx, ctx->parts); if (!converted) mangle_colors(sd, res); }