Beispiel #1
0
void mp_ass_configure(ASS_Renderer *priv, struct MPOpts *opts,
                      struct mp_osd_res *dim)
{
    ass_set_frame_size(priv, dim->w, dim->h);
    ass_set_margins(priv, dim->mt, dim->mb, dim->ml, dim->mr);

    int set_use_margins = 0;
#if LIBASS_VERSION >= 0x01010000
    int set_sub_pos = 0;
#endif
    float set_line_spacing = 0;
    float set_font_scale = 1;
    int set_hinting = 0;
    if (opts->ass_style_override) {
        set_use_margins = opts->ass_use_margins;
#if LIBASS_VERSION >= 0x01010000
        set_sub_pos = 100 - opts->sub_pos;
#endif
        set_line_spacing = opts->ass_line_spacing;
        set_font_scale = opts->sub_scale;
        set_hinting = opts->ass_hinting & 3; // +4 was for no hinting if scaled
    }

    ass_set_use_margins(priv, set_use_margins);
#if LIBASS_VERSION >= 0x01010000
    ass_set_line_position(priv, set_sub_pos);
#endif
    ass_set_font_scale(priv, set_font_scale);
    ass_set_hinting(priv, set_hinting);
    ass_set_line_spacing(priv, set_line_spacing);
}
Beispiel #2
0
ASS_Image* ass_mp_render_frame(ASS_Renderer *priv, ASS_Track* track, long long now, int* detect_change) {
	if (ass_force_reload) {
		ass_set_margins(priv, ass_top_margin, ass_bottom_margin, 0, 0);
		ass_set_use_margins(priv, ass_use_margins);
		ass_set_font_scale(priv, ass_font_scale);
		ass_force_reload = 0;
	}
	return ass_render_frame(priv, track, now, detect_change);
}
Beispiel #3
0
static void ass_configure(ASS_Renderer* priv, int w, int h, int unscaled) {
	int hinting;
	ass_set_frame_size(priv, w, h);
	ass_set_use_margins(priv, ass_use_margins);
	ass_set_font_scale(priv, ass_font_scale);
	if (!unscaled && (ass_hinting & 4))
		hinting = 0;
	else
		hinting = ass_hinting & 3;
	ass_set_hinting(priv, hinting);
	ass_set_line_spacing(priv, ass_line_spacing);
}
Beispiel #4
0
void ass_configure(ass_renderer_t* priv, int w, int h, int unscaled) {
    int hinting;
    ass_set_frame_size(priv, w, h);
    ass_set_margins(priv, ass_top_margin, ass_bottom_margin, 0, 0);
    ass_set_use_margins(priv, ass_use_margins);
    ass_set_font_scale(priv, ass_font_scale);
    if (!unscaled && (ass_hinting & 4))
        hinting = 0;
    else
        hinting = ass_hinting & 3;
    ass_set_hinting(priv, hinting);
    ass_set_line_spacing(priv, ass_line_spacing);
}
Beispiel #5
0
void mp_ass_configure(ASS_Renderer *priv, struct MPOpts *opts,
                      struct mp_osd_res *dim)
{
    ass_set_frame_size(priv, dim->w, dim->h);
    ass_set_margins(priv, dim->mt, dim->mb, dim->ml, dim->mr);

    int set_use_margins = 0;
#if LIBASS_VERSION >= 0x01010000
    int set_sub_pos = 0;
#endif
    float set_line_spacing = 0;
    float set_font_scale = 1;
    int set_hinting = 0;
    int set_force_override = 0;
    if (opts->ass_style_override) {
        set_use_margins = opts->ass_use_margins;
#if LIBASS_VERSION >= 0x01010000
        set_sub_pos = 100 - opts->sub_pos;
#endif
        set_line_spacing = opts->ass_line_spacing;
        set_font_scale = opts->sub_scale;
        set_hinting = opts->ass_hinting;
        set_force_override = opts->ass_style_override == 3;
    }

    ass_set_use_margins(priv, set_use_margins);
#if LIBASS_VERSION >= 0x01010000
    ass_set_line_position(priv, set_sub_pos);
#endif
#if LIBASS_VERSION >= 0x01000000
    ass_set_shaper(priv, opts->ass_shaper);
#endif
#if LIBASS_VERSION >= 0x01103000
    ass_set_selective_style_override_enabled(priv, set_force_override);
    ASS_Style style = {0};
    mp_ass_set_style(&style, 288, opts->sub_text_style);
    ass_set_selective_style_override(priv, &style);
    free(style.FontName);
#endif
    ass_set_font_scale(priv, set_font_scale);
    ass_set_hinting(priv, set_hinting);
    ass_set_line_spacing(priv, set_line_spacing);
}
Beispiel #6
0
CDVDSubtitlesLibass::CDVDSubtitlesLibass()
{
  //Setting the font directory to the temp dir(where mkv fonts are extracted to)
  std::string strPath = "special://temp/fonts/";

  CLog::Log(LOGINFO, "CDVDSubtitlesLibass: Creating ASS library structure");
  m_library = ass_library_init();
  if(!m_library)
    return;

  ass_set_message_cb(m_library, libass_log, this);

  CLog::Log(LOGINFO, "CDVDSubtitlesLibass: Initializing ASS library font settings");
  // libass uses fontconfig (system lib) which is not wrapped
  //  so translate the path before calling into libass
  ass_set_fonts_dir(m_library,  CSpecialProtocol::TranslatePath(strPath).c_str());
  ass_set_extract_fonts(m_library, 1);
  ass_set_style_overrides(m_library, NULL);

  CLog::Log(LOGINFO, "CDVDSubtitlesLibass: Initializing ASS Renderer");

  m_renderer = ass_renderer_init(m_library);

  if(!m_renderer)
    return;

  //Setting default font to the Arial in \media\fonts (used if FontConfig fails)
  const std::shared_ptr<CSettings> settings = CServiceBroker::GetSettingsComponent()->GetSettings();
  strPath = URIUtils::AddFileToFolder("special://home/media/Fonts/", settings->GetString(CSettings::SETTING_SUBTITLES_FONT));
  if (!XFILE::CFile::Exists(strPath))
    strPath = URIUtils::AddFileToFolder("special://xbmc/media/Fonts/", settings->GetString(CSettings::SETTING_SUBTITLES_FONT));
  int fc = !settings->GetBool(CSettings::SETTING_SUBTITLES_OVERRIDEASSFONTS);

  ass_set_margins(m_renderer, 0, 0, 0, 0);
  ass_set_use_margins(m_renderer, 0);
  ass_set_font_scale(m_renderer, 1);

  // libass uses fontconfig (system lib) which is not wrapped
  //  so translate the path before calling into libass
  ass_set_fonts(m_renderer, CSpecialProtocol::TranslatePath(strPath).c_str(), "Arial", fc, NULL, 1);
}
Beispiel #7
0
ASS_Image* CDVDSubtitlesLibass::RenderImage(int frameWidth, int frameHeight, int videoWidth, int videoHeight, int sourceWidth, int sourceHeight,
                                            double pts, int useMargin, double position, int *changes)
{
  CSingleLock lock(m_section);
  if(!m_renderer || !m_track)
  {
    CLog::Log(LOGERROR, "CDVDSubtitlesLibass: %s - Missing ASS structs(m_track or m_renderer)", __FUNCTION__);
    return NULL;
  }

  double sar = (double)sourceWidth / sourceHeight;
  double dar = (double)videoWidth / videoHeight;
  ass_set_frame_size(m_renderer, frameWidth, frameHeight);
  int topmargin = (frameHeight - videoHeight) / 2;
  int leftmargin = (frameWidth - videoWidth) / 2;
  ass_set_margins(m_renderer, topmargin, topmargin, leftmargin, leftmargin);
  ass_set_use_margins(m_renderer, useMargin);
  ass_set_line_position(m_renderer, position);
  ass_set_aspect_ratio(m_renderer, dar, sar);
  return ass_render_frame(m_renderer, m_track, DVD_TIME_TO_MSEC(pts), changes);
}
static void *ass_reader_thread(void *)
{
	set_threadname("ass_reader_thread");
	while (!sem_wait(&ass_sem)) {
		if (!ass_reader_running)
			break;

		ass_data *a = (ass_data *) ass_queue.pop();
		if (!a) {
			if (!ass_reader_running)
				break;
			continue;
		}

		OpenThreads::ScopedLock<OpenThreads::Mutex> m_lock(ass_mutex);
		std::map<int,ASS_Track*>::iterator it = ass_map.find(a->pid);
		ASS_Track *track;
		if (it == ass_map.end()) {
			CFrameBuffer *fb = CFrameBuffer::getInstance();
			int xres = fb->getScreenWidth(true);
			int yres = fb->getScreenHeight(true);
			if (!ass_library) {
				ass_library = ass_library_init();
				ass_set_extract_fonts(ass_library, 1);
				ass_set_style_overrides(ass_library, NULL);
				ass_renderer = ass_renderer_init(ass_library);
				ass_set_frame_size(ass_renderer, xres, yres);
				ass_set_margins(ass_renderer, 3 * yres / 100, 3 * yres / 100, 3 * xres / 100, 3 * xres / 100);
				ass_set_use_margins(ass_renderer, 1);
				ass_set_hinting(ass_renderer, ASS_HINTING_LIGHT);
				ass_set_aspect_ratio(ass_renderer, 1.0, 1.0);
				ass_font = *sub_font_file;
				ass_set_fonts(ass_renderer, ass_font.c_str(), "Arial", 0, NULL, 1);
			}
			track = ass_new_track(ass_library);
			track->PlayResX = xres;
			track->PlayResY = yres;
			ass_size = sub_font_size;
			ass_set_font_scale(ass_renderer, ((double) ass_size)/ASS_CUSTOM_FONT_SIZE);
			if (a->c->subtitle_header) {
				std::string ass_hdr = ass_subtitle_header_default();
				if (ass_hdr.compare((char*) a->c->subtitle_header)) {
					ass_process_codec_private(track, (char *) a->c->subtitle_header, a->c->subtitle_header_size);
				} else {
					// This is the FFMPEG default ASS header. Use something more suitable instead:
					ass_hdr = ass_subtitle_header_custom();
					ass_process_codec_private(track, (char *) ass_hdr.c_str(), ass_hdr.length());
				}
			}
			ass_map[a->pid] = track;
			if (a->pid == dvbsub_pid)
				ass_track = track;
//fprintf(stderr, "### got subtitle track %d, subtitle header: \n---\n%s\n---\n", pid, c->subtitle_header);
		} else
			track = it->second;
		for (unsigned int i = 0; i < a->sub.num_rects; i++)
			if (a->sub.rects[i]->ass)
				ass_process_data(track, a->sub.rects[i]->ass, strlen(a->sub.rects[i]->ass));
		avsubtitle_free(&a->sub);
		delete a;
	}
	ass_reader_running = false;
	pthread_exit(NULL);
}
Beispiel #9
0
/*****************************************************************************
 * Create: Open libass decoder.
 *****************************************************************************/
static int Create( vlc_object_t *p_this )
{
    decoder_t *p_dec = (decoder_t *)p_this;
    decoder_sys_t *p_sys;

    if( p_dec->fmt_in.i_codec != VLC_CODEC_SSA )
        return VLC_EGENERIC;

    p_dec->pf_decode_sub = DecodeBlock;
    p_dec->pf_flush      = Flush;

    p_dec->p_sys = p_sys = malloc( sizeof( decoder_sys_t ) );
    if( !p_sys )
        return VLC_ENOMEM;

    /* */
    vlc_mutex_init( &p_sys->lock );
    p_sys->i_refcount = 1;
    memset( &p_sys->fmt, 0, sizeof(p_sys->fmt) );
    p_sys->i_max_stop = VLC_TS_INVALID;
    p_sys->p_library  = NULL;
    p_sys->p_renderer = NULL;
    p_sys->p_track    = NULL;

    /* Create libass library */
    ASS_Library *p_library = p_sys->p_library = ass_library_init();
    if( !p_library )
    {
        msg_Warn( p_dec, "Libass library creation failed" );
        DecSysRelease( p_sys );
        return VLC_EGENERIC;
    }

    /* load attachments */
    input_attachment_t  **pp_attachments;
    int                   i_attachments;
    if( decoder_GetInputAttachments( p_dec, &pp_attachments, &i_attachments ))
    {
        i_attachments = 0;
        pp_attachments = NULL;
    }
    for( int k = 0; k < i_attachments; k++ )
    {
        input_attachment_t *p_attach = pp_attachments[k];

        bool found = false;

        /* Check mimetype*/
        if( !strcasecmp( p_attach->psz_mime, "application/x-truetype-font" ) )
            found = true;
        /* Then extension */
        else if( !found && strlen( p_attach->psz_name ) > 4 )
        {
            char *ext = p_attach->psz_name + strlen( p_attach->psz_name ) - 4;

            if( !strcasecmp( ext, ".ttf" ) || !strcasecmp( ext, ".otf" ) || !strcasecmp( ext, ".ttc" ) )
                found = true;
        }

        if( found )
        {
            msg_Dbg( p_dec, "adding embedded font %s", p_attach->psz_name );

            ass_add_font( p_sys->p_library, p_attach->psz_name, p_attach->p_data, p_attach->i_data );
        }
        vlc_input_attachment_Delete( p_attach );
    }
    free( pp_attachments );

    ass_set_extract_fonts( p_library, true );
    ass_set_style_overrides( p_library, NULL );

    /* Create the renderer */
    ASS_Renderer *p_renderer = p_sys->p_renderer = ass_renderer_init( p_library );
    if( !p_renderer )
    {
        msg_Warn( p_dec, "Libass renderer creation failed" );
        DecSysRelease( p_sys );
        return VLC_EGENERIC;
    }

    ass_set_use_margins( p_renderer, false);
    //if( false )
    //    ass_set_margins( p_renderer, int t, int b, int l, int r);
    ass_set_hinting( p_renderer, ASS_HINTING_LIGHT );
    ass_set_font_scale( p_renderer, 1.0 );
    ass_set_line_spacing( p_renderer, 0.0 );

#if defined( __ANDROID__ )
    const char *psz_font = "/system/fonts/DroidSans-Bold.ttf";
    const char *psz_family = "Droid Sans Bold";
#elif defined( __APPLE__ )
    const char *psz_font = NULL; /* We don't ship a default font with VLC */
    const char *psz_family = "Helvetica Neue"; /* Use HN if we can't find anything more suitable - Arial is not on all Apple platforms */
#else
    const char *psz_font = NULL; /* We don't ship a default font with VLC */
    const char *psz_family = "Arial"; /* Use Arial if we can't find anything more suitable */
#endif

#ifdef HAVE_FONTCONFIG
#if defined(_WIN32)
    dialog_progress_bar_t *p_dialog =
        dialog_ProgressCreate( p_dec,
                               _("Building font cache"),
                               _( "Please wait while your font cache is rebuilt.\n"
                                  "This should take less than a minute." ), NULL );
#endif
    ass_set_fonts( p_renderer, psz_font, psz_family, 1, NULL, 1 );  // setup default font/family
#if defined(_WIN32)
    if( p_dialog )
    {
        dialog_ProgressSet( p_dialog, NULL, 1.0 );
        dialog_ProgressDestroy( p_dialog );
    }
#endif
#else
    ass_set_fonts( p_renderer, psz_font, psz_family, 1, NULL, 1 );
#endif

    /* Add a track */
    ASS_Track *p_track = p_sys->p_track = ass_new_track( p_sys->p_library );
    if( !p_track )
    {
        DecSysRelease( p_sys );
        return VLC_EGENERIC;
    }
    ass_process_codec_private( p_track, p_dec->fmt_in.p_extra, p_dec->fmt_in.i_extra );

    p_dec->fmt_out.i_cat = SPU_ES;
    p_dec->fmt_out.i_codec = VLC_CODEC_RGBA;

    return VLC_SUCCESS;
}
Beispiel #10
0
static void configure_ass(struct sd *sd, struct mp_osd_res *dim,
                          bool converted, ASS_Track *track)
{
    struct MPOpts *opts = sd->opts;
    struct sd_ass_priv *ctx = sd->priv;
    ASS_Renderer *priv = ctx->ass_renderer;

    ass_set_frame_size(priv, dim->w, dim->h);
    ass_set_margins(priv, dim->mt, dim->mb, dim->ml, dim->mr);

    bool set_use_margins = false;
    int set_sub_pos = 0;
    float set_line_spacing = 0;
    float set_font_scale = 1;
    int set_hinting = 0;
    bool set_scale_with_window = false;
    bool set_scale_by_window = true;
    bool total_override = false;
    // With forced overrides, apply the --sub-* specific options
    if (converted || opts->ass_style_override == 3) {
        set_scale_with_window = opts->sub_scale_with_window;
        set_use_margins = opts->sub_use_margins;
        set_scale_by_window = opts->sub_scale_by_window;
        total_override = true;
    } else {
        set_scale_with_window = opts->ass_scale_with_window;
        set_use_margins = opts->ass_use_margins;
    }
    if (converted || opts->ass_style_override) {
        set_sub_pos = 100 - opts->sub_pos;
        set_line_spacing = opts->ass_line_spacing;
        set_hinting = opts->ass_hinting;
        set_font_scale = opts->sub_scale;
    }
    if (set_scale_with_window) {
        int vidh = dim->h - (dim->mt + dim->mb);
        set_font_scale *= dim->h / (float)MPMAX(vidh, 1);
    }
    if (!set_scale_by_window) {
        double factor = dim->h / 720.0;
        if (factor != 0.0)
            set_font_scale /= factor;
    }
    ass_set_use_margins(priv, set_use_margins);
    ass_set_line_position(priv, set_sub_pos);
    ass_set_shaper(priv, opts->ass_shaper);
    int set_force_flags = 0;
    if (total_override)
        set_force_flags |= ASS_OVERRIDE_BIT_STYLE | ASS_OVERRIDE_BIT_FONT_SIZE;
    if (opts->ass_style_override == 4)
        set_force_flags |= ASS_OVERRIDE_BIT_FONT_SIZE;
    ass_set_selective_style_override_enabled(priv, set_force_flags);
    ASS_Style style = {0};
    mp_ass_set_style(&style, 288, opts->sub_text_style);
    ass_set_selective_style_override(priv, &style);
    free(style.FontName);
    if (converted && track->default_style < track->n_styles) {
        mp_ass_set_style(track->styles + track->default_style,
                         track->PlayResY, opts->sub_text_style);
    }
    ass_set_font_scale(priv, set_font_scale);
    ass_set_hinting(priv, set_hinting);
    ass_set_line_spacing(priv, set_line_spacing);
}
Beispiel #11
0
static ass_handle_t *AssHandleHold( decoder_t *p_dec )
{
    vlc_mutex_lock( &libass_lock );

    ass_handle_t *p_ass = NULL;
    ASS_Library *p_library = NULL;
    ASS_Renderer *p_renderer = NULL;
    vlc_value_t val;

    var_Create( p_dec->p_libvlc, "libass-handle", VLC_VAR_ADDRESS );
    if( var_Get( p_dec->p_libvlc, "libass-handle", &val ) )
        val.p_address = NULL;

    if( val.p_address )
    {
        p_ass = val.p_address;

        p_ass->i_refcount++;

        vlc_mutex_unlock( &libass_lock );
        return p_ass;
    }

    /* */
    p_ass = malloc( sizeof(*p_ass) );
    if( !p_ass )
        goto error;

    /* */
    p_ass->p_libvlc = VLC_OBJECT(p_dec->p_libvlc);
    p_ass->i_refcount = 1;

    /* Create libass library */
    p_ass->p_library = p_library = ass_library_init();
    if( !p_library )
        goto error;

    /* load attachments */
    input_attachment_t  **pp_attachments;
    int                   i_attachments;

    if( decoder_GetInputAttachments( p_dec, &pp_attachments, &i_attachments ))
    {
        i_attachments = 0;
        pp_attachments = NULL;
    }
    for( int k = 0; k < i_attachments; k++ )
    {
        input_attachment_t *p_attach = pp_attachments[k];

        if( !strcasecmp( p_attach->psz_mime, "application/x-truetype-font" ) )
        {
            msg_Dbg( p_dec, "adding embedded font %s", p_attach->psz_name );

            ass_add_font( p_ass->p_library, p_attach->psz_name, p_attach->p_data, p_attach->i_data );
        }
        vlc_input_attachment_Delete( p_attach );
    }
    free( pp_attachments );

    ass_set_extract_fonts( p_library, true );
    ass_set_style_overrides( p_library, NULL );

    /* Create the renderer */
    p_ass->p_renderer = p_renderer = ass_renderer_init( p_library );
    if( !p_renderer )
        goto error;

    ass_set_use_margins( p_renderer, false);
    //if( false )
    //    ass_set_margins( p_renderer, int t, int b, int l, int r);
    ass_set_hinting( p_renderer, ASS_HINTING_LIGHT );
    ass_set_font_scale( p_renderer, 1.0 );
    ass_set_line_spacing( p_renderer, 0.0 );

    const char *psz_font = NULL; /* We don't ship a default font with VLC */
    const char *psz_family = "Arial"; /* Use Arial if we can't find anything more suitable */

#ifdef HAVE_FONTCONFIG
#if defined(WIN32)
    dialog_progress_bar_t *p_dialog = dialog_ProgressCreate( p_dec,
        _("Building font cache"),
        _( "Please wait while your font cache is rebuilt.\n"
        "This should take less than a minute." ), NULL );
    if( p_dialog )
        dialog_ProgressSet( p_dialog, NULL, 0.2 );
#endif
#if defined( LIBASS_VERSION ) && LIBASS_VERSION >= 0x00907000
    ass_set_fonts( p_renderer, psz_font, psz_family, true, NULL, 1 );  // setup default font/family
#else
    ass_set_fonts( p_renderer, psz_font, psz_family );  // setup default font/family
#endif
#ifdef WIN32
    if( p_dialog )
    {
        dialog_ProgressSet( p_dialog, NULL, 1.0 );
        dialog_ProgressDestroy( p_dialog );
        p_dialog = NULL;
    }
#endif
#else
    /* FIXME you HAVE to give him a font if no fontconfig */
#if defined( LIBASS_VERSION ) && LIBASS_VERSION >= 0x00907000
    ass_set_fonts( p_renderer, psz_font, psz_family, false, NULL, 1 );
#else
    ass_set_fonts_nofc( p_renderer, psz_font, psz_family );
#endif
#endif
    memset( &p_ass->fmt, 0, sizeof(p_ass->fmt) );

    /* */
    val.p_address = p_ass;
    var_Set( p_dec->p_libvlc, "libass-handle", val );

    /* */
    vlc_mutex_unlock( &libass_lock );
    return p_ass;

error:
    if( p_renderer )
        ass_renderer_done( p_renderer );
    if( p_library )
        ass_library_done( p_library );

    msg_Warn( p_dec, "Libass creation failed" );

    free( p_ass );
    vlc_mutex_unlock( &libass_lock );
    return NULL;
}
Beispiel #12
0
static void VS_CC assInit(VSMap *in, VSMap *out, void **instanceData,
                          VSNode *node, VSCore *core, const VSAPI *vsapi)
{
    AssData *d = (AssData *) * instanceData;
    vsapi->setVideoInfo(d->vi, 2, node);

    d->ass_library = ass_library_init();

    if(!d->ass_library) {
        vsapi->setError(out, "failed to initialize ASS library");
        return;
    }

    ass_set_message_cb(d->ass_library, assDebugCallback, (void *)d->debuglevel);
    ass_set_extract_fonts(d->ass_library, 0);
    ass_set_style_overrides(d->ass_library, 0);

    d->ass_renderer = ass_renderer_init(d->ass_library);

    if(!d->ass_renderer) {
        vsapi->setError(out, "failed to initialize ASS renderer");
        return;
    }

    ass_set_font_scale(d->ass_renderer, d->scale);
    ass_set_frame_size(d->ass_renderer, d->vi[0].width, d->vi[0].height);
    ass_set_margins(d->ass_renderer,
                    d->margins[0], d->margins[1], d->margins[2], d->margins[3]);
    ass_set_use_margins(d->ass_renderer, 1);

    if(d->linespacing)
        ass_set_line_spacing(d->ass_renderer, d->linespacing);

    if(d->sar) {
        ass_set_aspect_ratio(d->ass_renderer,
                             (double)d->vi[0].width /
                             d->vi[0].height * d->sar, 1);
    }

    if(d->fontdir)
        ass_set_fonts_dir(d->ass_library, d->fontdir);

    ass_set_fonts(d->ass_renderer, NULL, NULL, 1, NULL, 1);

    if(d->file == NULL) {
        char *str, *text, x[16], y[16];
        size_t siz;
        const char *fmt = "[Script Info]\n"
                          "ScriptType: v4.00+\n"
                          "PlayResX: %s\n"
                          "PlayResY: %s\n"
                          "[V4+ Styles]\n"
                          "Format: Name, Fontname, Fontsize, PrimaryColour, SecondaryColour, OutlineColour, BackColour, Bold, Italic, Underline, StrikeOut, ScaleX, ScaleY, Spacing, Angle, BorderStyle, Outline, Shadow, Alignment, MarginL, MarginR, MarginV, Encoding\n"
                          "Style: Default,%s\n"
                          "[Events]\n"
                          "Format: Layer, Start, End, Style, Name, MarginL, MarginR, MarginV, Effect, Text\n"
                          "Dialogue: 0,0:00:00.00,0:00:10.00,Default,,0,0,0,,%s\n";

        sprintf(x, "%d", d->vi[0].width);
        sprintf(y, "%d", d->vi[0].height);

        text = strrepl(d->text, "\n", "\\N");

        siz = (strlen(fmt) + strlen(x) + strlen(y) + strlen(d->style) +
               strlen(text)) * sizeof(char);

        str = malloc(siz);
        sprintf(str, fmt, x, y, d->style, text);

        free(text);

        d->ass = ass_new_track(d->ass_library);
        ass_process_data(d->ass, str, strlen(str));

        free(str);
    } else {
        d->ass = ass_read_file(d->ass_library, (char *)d->file, (char *)d->charset);
    }

    if(!d->ass) {
        vsapi->setError(out, "unable to parse input file");
        return;
    }
}
Beispiel #13
0
/*****************************************************************************
 * Create: Open libass decoder.
 *****************************************************************************/
static int Create( vlc_object_t *p_this )
{
    decoder_t *p_dec = (decoder_t *)p_this;
    decoder_sys_t *p_sys;

    if( p_dec->fmt_in.i_codec != VLC_CODEC_SSA )
        return VLC_EGENERIC;

    p_dec->pf_decode_sub = DecodeBlock;

    p_dec->p_sys = p_sys = malloc( sizeof( decoder_sys_t ) );
    if( !p_sys )
        return VLC_ENOMEM;

    /* */
    vlc_mutex_init( &p_sys->lock );
    p_sys->i_refcount = 1;
    memset( &p_sys->fmt, 0, sizeof(p_sys->fmt) );
    p_sys->i_max_stop = VLC_TS_INVALID;
    p_sys->p_library  = NULL;
    p_sys->p_renderer = NULL;
    p_sys->p_track    = NULL;

    /* Create libass library */
    ASS_Library *p_library = p_sys->p_library = ass_library_init();
    if( !p_library )
    {
        msg_Warn( p_dec, "Libass library creation failed" );
        DecSysRelease( p_sys );
        return VLC_EGENERIC;
    }

    /* load attachments */
    input_attachment_t  **pp_attachments;
    int                   i_attachments;
    if( decoder_GetInputAttachments( p_dec, &pp_attachments, &i_attachments ))
    {
        i_attachments = 0;
        pp_attachments = NULL;
    }
    for( int k = 0; k < i_attachments; k++ )
    {
        input_attachment_t *p_attach = pp_attachments[k];

        if( !strcasecmp( p_attach->psz_mime, "application/x-truetype-font" ) )
        {
            msg_Dbg( p_dec, "adding embedded font %s", p_attach->psz_name );

            ass_add_font( p_sys->p_library, p_attach->psz_name, p_attach->p_data, p_attach->i_data );
        }
        vlc_input_attachment_Delete( p_attach );
    }
    free( pp_attachments );

    ass_set_extract_fonts( p_library, true );
    ass_set_style_overrides( p_library, NULL );

    /* Create the renderer */
    ASS_Renderer *p_renderer = p_sys->p_renderer = ass_renderer_init( p_library );
    if( !p_renderer )
    {
        msg_Warn( p_dec, "Libass renderer creation failed" );
        DecSysRelease( p_sys );
        return VLC_EGENERIC;
    }

    ass_set_use_margins( p_renderer, false);
    //if( false )
    //    ass_set_margins( p_renderer, int t, int b, int l, int r);
    ass_set_hinting( p_renderer, ASS_HINTING_LIGHT );
    ass_set_font_scale( p_renderer, 1.0 );
    ass_set_line_spacing( p_renderer, 0.0 );

    const char *psz_font = NULL; /* We don't ship a default font with VLC */
    const char *psz_family = "Arial"; /* Use Arial if we can't find anything more suitable */

#ifdef ANDROID
    /* is this useful? */
    ass_set_fonts_dir( p_library, "/system/fonts" );
    /* don't crash libass */
    psz_font = "/system/fonts/DroidSansFallback.ttf";
#endif

#ifdef HAVE_FONTCONFIG
#if defined(WIN32)
    dialog_progress_bar_t *p_dialog =
        dialog_ProgressCreate( p_dec,
                               _("Building font cache"),
                               _( "Please wait while your font cache is rebuilt.\n"
                                  "This should take less than a minute." ), NULL );
    if( p_dialog )
        dialog_ProgressSet( p_dialog, NULL, 0.2 );
#endif
    ass_set_fonts( p_renderer, psz_font, psz_family, true, NULL, 1 );  // setup default font/family
#ifdef WIN32
    if( p_dialog )
    {
        dialog_ProgressSet( p_dialog, NULL, 1.0 );
        dialog_ProgressDestroy( p_dialog );
    }
#endif
#else
    /* FIXME you HAVE to give him a font if no fontconfig */
    ass_set_fonts( p_renderer, psz_font, psz_family, false, NULL, 1 );
#endif

    /* Add a track */
    ASS_Track *p_track = p_sys->p_track = ass_new_track( p_sys->p_library );
    if( !p_track )
    {
        DecSysRelease( p_sys );
        return VLC_EGENERIC;
    }
    ass_process_codec_private( p_track, p_dec->fmt_in.p_extra, p_dec->fmt_in.i_extra );

    p_dec->fmt_out.i_cat = SPU_ES;
    p_dec->fmt_out.i_codec = VLC_CODEC_RGBA;

    return VLC_SUCCESS;
}
Beispiel #14
0
/*****************************************************************************
 * Create: Open libass decoder.
 *****************************************************************************/
static int Create( vlc_object_t *p_this )
{
    decoder_t *p_dec = (decoder_t *)p_this;
    decoder_sys_t *p_sys;

    if( p_dec->fmt_in.i_codec != VLC_CODEC_SSA )
        return VLC_EGENERIC;

    p_dec->pf_decode_sub = DecodeBlock;

    p_dec->p_sys = p_sys = malloc( sizeof( decoder_sys_t ) );
    if( !p_sys )
        return VLC_ENOMEM;

    /* */
    vlc_mutex_init( &p_sys->lock );
    p_sys->i_refcount = 1;
    memset( &p_sys->fmt, 0, sizeof(p_sys->fmt) );
    p_sys->i_max_stop = VLC_TS_INVALID;
    p_sys->p_library  = NULL;
    p_sys->p_renderer = NULL;
    p_sys->p_track    = NULL;

    /* Create libass library */
    ASS_Library *p_library = p_sys->p_library = ass_library_init();
    if( !p_library )
    {
        msg_Warn( p_dec, "Libass library creation failed" );
        DecSysRelease( p_sys );
        return VLC_EGENERIC;
    }

    /* load attachments */
    input_attachment_t  **pp_attachments;
    int                   i_attachments;
    if( decoder_GetInputAttachments( p_dec, &pp_attachments, &i_attachments ))
    {
        i_attachments = 0;
        pp_attachments = NULL;
    }
    for( int k = 0; k < i_attachments; k++ )
    {
        input_attachment_t *p_attach = pp_attachments[k];

        bool found = false;

        /* Check mimetype*/
        if( !strcasecmp( p_attach->psz_mime, "application/x-truetype-font" ) )
            found = true;
        /* Then extension */
        else if( !found && strlen( p_attach->psz_name ) > 4 )
        {
            char *ext = p_attach->psz_name + strlen( p_attach->psz_name ) - 4;

            if( !strcasecmp( ext, ".ttf" ) || !strcasecmp( ext, ".otf" ) || !strcasecmp( ext, ".ttc" ) )
                found = true;
        }

        if( found )
        {
            msg_Dbg( p_dec, "adding embedded font %s", p_attach->psz_name );

            ass_add_font( p_sys->p_library, p_attach->psz_name, p_attach->p_data, p_attach->i_data );
        }
        vlc_input_attachment_Delete( p_attach );
    }
    free( pp_attachments );

    ass_set_extract_fonts( p_library, true );
    ass_set_style_overrides( p_library, NULL );

    /* Create the renderer */
    ASS_Renderer *p_renderer = p_sys->p_renderer = ass_renderer_init( p_library );
    if( !p_renderer )
    {
        msg_Warn( p_dec, "Libass renderer creation failed" );
        DecSysRelease( p_sys );
        return VLC_EGENERIC;
    }

    ass_set_use_margins( p_renderer, false);
    //if( false )
    //    ass_set_margins( p_renderer, int t, int b, int l, int r);
    ass_set_hinting( p_renderer, ASS_HINTING_LIGHT );
    ass_set_font_scale( p_renderer, 1.0 );
    ass_set_line_spacing( p_renderer, 0.0 );

#if defined( __ANDROID__ )
    const char *psz_font = "/system/fonts/DroidSans-Bold.ttf";
    const char *psz_family = "Droid Sans Bold";
#elif defined (__APPLE__)
#if !TARGET_OS_IPHONE
    const char *psz_font = NULL; /* We don't ship a default font with VLC */
    const char *psz_family = "Arial"; /* Use Arial if we can't find anything more suitable */
#else
    CFURLRef fileURL;
    fileURL = CFBundleCopyResourceURL(CFBundleGetMainBundle(), CFSTR("OpenSans-Regular.ttf"),
                                      NULL,
                                      NULL);
    if (!fileURL)
        return VLC_EGENERIC;

    CFStringRef urlString = CFURLCopyFileSystemPath(fileURL, kCFURLPOSIXPathStyle);
    CFRelease(fileURL);

    if (!urlString)
        return VLC_EGENERIC;

    CFIndex length = CFStringGetLength(urlString);
    if (!length)
        return VLC_EGENERIC;
    length++;

    char *psz_path = (char *)malloc(length);
    CFStringGetCString(urlString, psz_path, length, kCFStringEncodingUTF8);
    CFRelease(urlString);

    const char *psz_font = (const char *)strdup(psz_path);
    free(psz_path);
    const char *psz_family = "Open Sans";
#endif
#else
    const char *psz_font = NULL; /* We don't ship a default font with VLC */
    const char *psz_family = "Arial"; /* Use Arial if we can't find anything more suitable */
#endif

#ifdef HAVE_FONTCONFIG
#if defined(_WIN32) || defined(__APPLE__)
    dialog_progress_bar_t *p_dialog =
        dialog_ProgressCreate( p_dec,
                               _("Building font cache"),
                               _( "Please wait while your font cache is rebuilt.\n"
                                  "This should take less than a minute." ), NULL );
#endif
    ass_set_fonts( p_renderer, psz_font, psz_family, true, NULL, 1 );  // setup default font/family
#if defined(_WIN32) || defined(__APPLE__)
    if( p_dialog )
    {
        dialog_ProgressSet( p_dialog, NULL, 1.0 );
        dialog_ProgressDestroy( p_dialog );
    }
#endif
#else
    /* FIXME you HAVE to give him a font if no fontconfig */
    ass_set_fonts( p_renderer, psz_font, psz_family, false, NULL, 1 );
#endif

    /* Add a track */
    ASS_Track *p_track = p_sys->p_track = ass_new_track( p_sys->p_library );
    if( !p_track )
    {
        DecSysRelease( p_sys );
        return VLC_EGENERIC;
    }
    ass_process_codec_private( p_track, p_dec->fmt_in.p_extra, p_dec->fmt_in.i_extra );

    p_dec->fmt_out.i_cat = SPU_ES;
    p_dec->fmt_out.i_codec = VLC_CODEC_RGBA;

    return VLC_SUCCESS;
}