示例#1
0
csri_inst *csri_open_mem(csri_rend *renderer,
	const void *data, size_t length, struct csri_openflag *flags)
{
	csri_inst *rv;
	if (renderer != &csri_libass)
		return NULL;

	rv = (csri_inst *)malloc(sizeof(csri_inst));
	if (!rv)
		return NULL;

	rv->ass_renderer = ass_renderer_init(renderer->ass_library);
	if (!rv->ass_renderer) {
		free(rv);
		return NULL;
	}
	ass_set_font_scale(rv->ass_renderer, 1.);
	ass_set_fonts(rv->ass_renderer, NULL, "Sans");
	rv->ass_track = ass_read_memory(csri_libass.ass_library,
		(void *)data, length, "UTF-8");
	if (!rv->ass_track) {
		ass_renderer_done(rv->ass_renderer);
		free(rv);
		return NULL;
	}
	return rv;
}
示例#2
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);
}
示例#3
0
static csri_inst *libass_init_stream(csri_rend *renderer,
	const void *header, size_t headerlen,
	struct csri_openflag *flags)
{
	csri_inst *rv;

	if (renderer != &csri_libass)
		return NULL;

	rv = (csri_inst *)malloc(sizeof(csri_inst));
	if (!rv)
		return NULL;

	rv->ass_renderer = ass_renderer_init(renderer->ass_library);
	if (!rv->ass_renderer) {
		free(rv);
		return NULL;
	}
	ass_set_font_scale(rv->ass_renderer, 1.);
	ass_set_fonts(rv->ass_renderer, NULL, "Sans");
	rv->ass_track = ass_new_track(csri_libass.ass_library);
	if (!rv->ass_track) {
		ass_renderer_done(rv->ass_renderer);
		free(rv);
		return NULL;
	}
	ass_process_codec_private(rv->ass_track, (void *)header, headerlen);
	return rv;
}
示例#4
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);
}
示例#5
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);
}
示例#6
0
文件: ass_mp.c 项目: dreamerc/mplayer
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);
}
示例#7
0
文件: ass_mp.c 项目: ainstushar/mpv
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);
}
示例#8
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);
}
示例#9
0
LibassConfiguration libass_configure(Configuration conf)
{
    LibassConfiguration libass_conf;
    
    ASS_Library *library = ass_library_init();

    if (library == NULL) {
        printf("Couldn't initialize ass library ...\n");
        exit(EXIT_FAILURE);
    }
    
    libass_conf.library = library;
    
    ASS_Renderer *renderer = ass_renderer_init(library);

    if (renderer == NULL) {
        printf("Couldn't initialize ass library ...\n");
        exit(EXIT_FAILURE);
    }

    ass_set_frame_size(renderer, conf.width, conf.height);

    if (conf.display_aspect != -1.0)
        ass_set_aspect_ratio(renderer, conf.display_aspect, 
                        ((double)conf.width) / ((double)conf.height));

    ass_set_margins(renderer, 20, 20, 60, 60);

    ass_set_fonts(renderer, NULL, "Arial", 1, NULL, 1);
    ass_set_font_scale(renderer, conf.font_scale);
    
    libass_conf.renderer = renderer;
    
    return libass_conf;
    
}
示例#10
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;
}
示例#11
0
文件: sd_ass.c 项目: Archer-sys/mpv
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);
}
示例#12
0
int main(int argc, char *argv[])
{
	POINT mouse;
	//while (true)
	{
		GetCursorPos(&mouse);
		printf("\r%d-%d         ", mouse.x, mouse.y);
	}
	

	return interlace_RGB();
	return matrix();

//	char URI[] = "//mnt/sdcard/%E9%98%BF%E4%B8%BD%E4%BA%9A%E5%A8%9C%E5%90%89%E5%88%A9%E6%96%AF-%20Shake%E8%8B%B9%E6%9E%9C.3dv";
	char URI[] = "//mnt/sdcard/HELLO!.3dv";
	char decoded_URI[1024];

	URIDecode(URI, decoded_URI, sizeof(decoded_URI));

	char k = 0xef;

	bool a = k == 0xef;


    const int frame_w = 1920;
    const int frame_h = 1080;

	setlocale(LC_ALL, "CHS");

    if (argc < 4) {
        printf("usage: %s <image file> <subtitle file> <time>\n", argv[0]);
        exit(1);
    }

    char *imgfile = argv[1];
    char *subfile = argv[2];
    double tm = strtod(argv[3], 0);

	FILE * f = fopen(subfile, "rb");
	fseek(f, 0, SEEK_END);
	int file_size = ftell(f);
	fseek(f, 0, SEEK_SET);
	char *src = (char*)malloc(file_size);
	char *utf8 = (char*)malloc(file_size*3);
	fread(src, 1, file_size, f);
	fclose(f);

	int utf8_size = ConvertToUTF8(src, file_size, utf8, file_size*3);

	ass_library = ass_library_init();
	if (!ass_library) {
		printf("ass_library_init failed!\n");
		exit(1);
		}

	//ass_set_message_cb(ass_library, msg_callback, NULL);

	//ass_set_extract_fonts(ass_library, 0);
	//ass_set_style_overrides(ass_library, NULL);


	ass_renderer = ass_renderer_init(ass_library);
	if (!ass_renderer) {
		printf("ass_renderer_init failed!\n");
		exit(1);
		}


	ass_set_frame_size(ass_renderer, frame_w, frame_h);
	ass_set_font_scale(ass_renderer, 1.0);
	//ass_set_hinting(ass_renderer, ASS_HINTING_NORMAL);
	ass_set_fonts(ass_renderer, "Arial", "Sans", 1, "Z:\\fonts.conf", 1);
	
	ASS_Track *track = ass_read_memory(ass_library, utf8, utf8_size, NULL);

	free(src);
	free(utf8);

    if (!track) {
        printf("track init failed!\n");
        return 1;
    }

    ASS_Image *img = NULL;
	int n = 0;
	int changed = 0;
	image_t *frame = gen_image(frame_w, frame_h);
	int n2 = 0;
	int l = GetTickCount();
	timeBeginPeriod(1);
	for(int i=0; i<int(tm*1000); i+=40)
	{
		img = ass_render_frame(ass_renderer, track, i, &changed);

		if (n==0) l = GetTickCount();
		if (changed && img)
		{
			int l = timeGetTime();
			n++;
			memset(frame->buffer, 63, frame->stride * frame->height);
			blend(frame, img);
			wchar_t pathname[MAX_PATH];
			wsprintfW(pathname, L"Z:\\ass%02d.bmp", n);
			save_bitmap((DWORD*)frame->buffer, pathname, frame_w, frame_h);

			//printf("\rrender cost %dms.\t\t\n", timeGetTime()-l);
		}

		n2 ++;

		if (i%10000 == 0)
		printf("\r%d/%d ms rendered, %d frame output.", i, int(tm*1000), n);
	}

    ass_free_track(track);
    ass_renderer_done(ass_renderer);
    ass_library_done(ass_library);


    free(frame->buffer);
    free(frame);

    return 0;
}
示例#13
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;
}
示例#14
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;
    }
}
示例#15
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;
}
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);
}
static void* dvbsub_thread(void* /*arg*/)
{
	struct timespec restartWait;
	struct timeval now;
	set_threadname("dvbsub:main");

	sub_debug.print(Debug::VERBOSE, "%s started\n", __FUNCTION__);
	if (!dvbSubtitleConverter)
		dvbSubtitleConverter = new cDvbSubtitleConverter;

	int timeout = 1000000;
#if HAVE_SPARK_HARDWARE || HAVE_DUCKBOX_HARDWARE
	CFrameBuffer *fb = CFrameBuffer::getInstance();
	int xres = fb->getScreenWidth(true);
	int yres = fb->getScreenHeight(true);
	int clr_x0 = xres, clr_y0 = yres, clr_x1 = 0, clr_y1 = 0;
	uint32_t colortable[256];
	memset(colortable, 0, sizeof(colortable));
	uint32_t last_color = 0;
#endif

	while(dvbsub_running) {
#if HAVE_SPARK_HARDWARE || HAVE_DUCKBOX_HARDWARE
		if (ass_track) {
			usleep(100000); // FIXME ... should poll instead

			OpenThreads::ScopedLock<OpenThreads::Mutex> m_lock(ass_mutex);

			if (!ass_track)
				continue;

			if (ass_size != sub_font_size) {
				ass_size = sub_font_size;
				ass_set_font_scale(ass_renderer, ((double) ass_size)/ASS_CUSTOM_FONT_SIZE);
			}

			int detect_change = 0;
			int64_t pts;
			getPlayerPts(&pts);
			ASS_Image *image = ass_render_frame(ass_renderer, ass_track, pts/90, &detect_change);
			if (detect_change) {
				if (clr_x1 && clr_y1) {
					fb->paintBox(clr_x0, clr_y0, clr_x1 + 1, clr_y1 + 1, 0);
					clr_x0 = xres;
					clr_y0 = yres;
					clr_x1 = clr_y1 = 0;
				}

				while (image) {
					if (last_color != image->color) {
						last_color = image->color;
						uint32_t c = last_color >> 8, a = 255 - (last_color & 0xff);
						for (int i = 0; i < 256; i++) {
							uint32_t k = (a * i) >> 8;
							colortable[i] = k ? (c | (k << 24)) : 0;
						}
					}
					if (image->w && image->h && image->dst_x > -1 && image->dst_x + image->w < xres && image->dst_y > -1 && image->dst_y + image->h < yres) {
						if (image->dst_x < clr_x0)
							clr_x0 = image->dst_x;
						if (image->dst_y < clr_y0)
							clr_y0 = image->dst_y;
						if (image->dst_x + image->w > clr_x1)
							clr_x1 = image->dst_x + image->w;
						if (image->dst_y + image->h > clr_y1)
							clr_y1 = image->dst_y + image->h;

						uint32_t *lfb = fb->getFrameBufferPointer() + image->dst_x + xres * image->dst_y;
						unsigned char *bm = image->bitmap;
						int bm_add = image->stride - image->w;
						int lfb_add = xres - image->w;
						for (int y = 0; y < image->h; y++) {
							for (int x = 0; x < image->w; x++) {
								if (*bm)
									*lfb = colortable[*bm];
								lfb++, bm++;
							}
							lfb += lfb_add;
							bm += bm_add;
						}
					}
					image = image->next;
				}
				fb->getInstance()->blit();
			}
			continue;
		} else {
			if (clr_x1 && clr_y1) {
示例#18
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;
}