Exemplo n.º 1
0
static int SubpictureValidate( subpicture_t *p_subpic,
                               bool b_fmt_src, const video_format_t *p_fmt_src,
                               bool b_fmt_dst, const video_format_t *p_fmt_dst,
                               mtime_t i_ts )
{
    decoder_sys_t *p_sys = p_subpic->updater.p_sys->p_dec_sys;
    ass_handle_t *p_ass = p_sys->p_ass;

    vlc_mutex_lock( &libass_lock );

    /* FIXME why this mix of src/dst */
    video_format_t fmt = *p_fmt_dst;
    fmt.i_chroma         = VLC_CODEC_RGBA;
    fmt.i_bits_per_pixel = 0;
    fmt.i_width          =
    fmt.i_visible_width  = p_fmt_src->i_width;
    fmt.i_height         =
    fmt.i_visible_height = p_fmt_src->i_height;
    fmt.i_x_offset       =
    fmt.i_y_offset       = 0;

    if( b_fmt_src || b_fmt_dst )
    {
        ass_set_frame_size( p_ass->p_renderer, fmt.i_width, fmt.i_height );
#if defined( LIBASS_VERSION ) && LIBASS_VERSION >= 0x00907000
        ass_set_aspect_ratio( p_ass->p_renderer, 1.0, 1.0 ); // TODO ?
#else
        ass_set_aspect_ratio( p_ass->p_renderer, 1.0 ); // TODO ?
#endif
        p_ass->fmt = fmt;
    }

    /* */
    const mtime_t i_stream_date = p_subpic->updater.p_sys->i_pts + (i_ts - p_subpic->i_start);
    int i_changed;
    ASS_Image *p_img = ass_render_frame( p_ass->p_renderer, p_sys->p_track,
                                         i_stream_date/1000, &i_changed );

    if( !i_changed && !b_fmt_src && !b_fmt_dst &&
        (p_img != NULL) == (p_subpic->p_region != NULL) )
    {
        vlc_mutex_unlock( &libass_lock );
        return VLC_SUCCESS;
    }
    p_subpic->updater.p_sys->p_img = p_img;

    /* The lock is released by SubpictureUpdate */
    return VLC_EGENERIC;
}
Exemplo n.º 2
0
static void eosd_ass_update(struct mp_eosd_source *src, const struct mp_eosd_settings *res, double ts)
{
	long long ts_ms = (ts + sub_delay) * 1000 + .5;
	ASS_Image *aimg;
	struct mp_eosd_image *img;
	if (res->changed || !src->initialized) {
		double dar = (double) (res->w - res->ml - res->mr) / (res->h - res->mt - res->mb);
		ass_configure(ass_renderer, res->w, res->h, res->unscaled);
		ass_set_margins(ass_renderer, res->mt, res->mb, res->ml, res->mr);
		ass_set_aspect_ratio(ass_renderer, dar, (double)res->srcw / res->srch);
		src->initialized = 1;
	}
	aimg = sub_visibility && ass_track && ts != MP_NOPTS_VALUE ?
		ass_mp_render_frame(ass_renderer, ass_track, ts_ms, &src->changed) :
		NULL;
	if (!aimg != !src->images)
		src->changed = 2;
	if (src->changed) {
		eosd_image_remove_all(src);
		while (aimg) {
			img = eosd_image_alloc();
			img->w      = aimg->w;
			img->h      = aimg->h;
			img->bitmap = aimg->bitmap;
			img->stride = aimg->stride;
			img->color  = aimg->color;
			img->dst_x  = aimg->dst_x;
			img->dst_y  = aimg->dst_y;
			eosd_image_append(src, img);
			aimg = aimg->next;
		}
	}
	prev_visibility = sub_visibility;
}
Exemplo n.º 3
0
static int config_input(AVFilterLink *inlink)
{
    AssContext *ass = inlink->dst->priv;

    ff_draw_init(&ass->draw, inlink->format, ass->alpha ? FF_DRAW_PROCESS_ALPHA : 0);

    ass_set_frame_size  (ass->renderer, inlink->w, inlink->h);
    if (ass->original_w && ass->original_h)
        ass_set_aspect_ratio(ass->renderer, (double)inlink->w / inlink->h,
                             (double)ass->original_w / ass->original_h);
    if (ass->shaping != -1)
        ass_set_shaper(ass->renderer, ass->shaping);

    return 0;
}
Exemplo n.º 4
0
static int SubpictureValidate( subpicture_t *p_subpic,
                               bool b_fmt_src, const video_format_t *p_fmt_src,
                               bool b_fmt_dst, const video_format_t *p_fmt_dst,
                               mtime_t i_ts )
{
    decoder_sys_t *p_sys = p_subpic->updater.p_sys->p_dec_sys;

    vlc_mutex_lock( &p_sys->lock );

    video_format_t fmt = *p_fmt_dst;
    fmt.i_chroma         = VLC_CODEC_RGBA;
    fmt.i_bits_per_pixel = 0;
    fmt.i_visible_width  = fmt.i_width;
    fmt.i_visible_height = fmt.i_height;
    fmt.i_x_offset       = 0;
    fmt.i_y_offset       = 0;
    if( b_fmt_src || b_fmt_dst )
    {
        ass_set_frame_size( p_sys->p_renderer, fmt.i_width, fmt.i_height );
        const double src_ratio = (double)p_fmt_src->i_width / p_fmt_src->i_height;
        const double dst_ratio = (double)p_fmt_dst->i_width / p_fmt_dst->i_height;
        ass_set_aspect_ratio( p_sys->p_renderer, dst_ratio / src_ratio, 1 );
        p_sys->fmt = fmt;
    }

    /* */
    const mtime_t i_stream_date = p_subpic->updater.p_sys->i_pts + (i_ts - p_subpic->i_start);
    int i_changed;
    ASS_Image *p_img = ass_render_frame( p_sys->p_renderer, p_sys->p_track,
                                         i_stream_date/1000, &i_changed );

    if( !i_changed && !b_fmt_src && !b_fmt_dst &&
        (p_img != NULL) == (p_subpic->p_region != NULL) )
    {
        vlc_mutex_unlock( &p_sys->lock );
        return VLC_SUCCESS;
    }
    p_subpic->updater.p_sys->p_img = p_img;

    /* The lock is released by SubpictureUpdate */
    return VLC_EGENERIC;
}
Exemplo n.º 5
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);
}
Exemplo n.º 6
0
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;

    if (pts == MP_NOPTS_VALUE || !sd->ass_renderer)
        return;

    ASS_Renderer *renderer = sd->ass_renderer;
    double scale = dim.display_par;
    if (!ctx->is_converted && (!opts->ass_style_override ||
                               opts->ass_vsfilter_aspect_compat))
    {
        // Let's use the original video PAR for vsfilter compatibility:
        double par = scale
            * (ctx->video_params.d_w / (double)ctx->video_params.d_h)
            / (ctx->video_params.w   / (double)ctx->video_params.h);
        if (isnormal(par))
            scale = par;
    }
    mp_ass_configure(renderer, opts, &dim);
    ass_set_aspect_ratio(renderer, scale, 1);
#if LIBASS_VERSION >= 0x01020000
    if (!ctx->is_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);
    }
#endif
    mp_ass_render_frame(renderer, ctx->ass_track, pts * 1000 + .5,
                        &ctx->parts, res);
    talloc_steal(ctx, ctx->parts);

    if (!ctx->is_converted)
        mangle_colors(sd, res);
}
Exemplo n.º 7
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;
    
}
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);
}
Exemplo n.º 9
0
static int control(struct vf_instance_s* vf, int request, void* data)
{
    switch(request){
    case VFCTRL_GET_DEINTERLACE:
    {
        if(!video_out) return CONTROL_FALSE; // vo not configured?
        return(video_out->control(VOCTRL_GET_DEINTERLACE, data)
                == VO_TRUE) ? CONTROL_TRUE : CONTROL_FALSE;
    }
    case VFCTRL_SET_DEINTERLACE:
    {
        if(!video_out) return CONTROL_FALSE; // vo not configured?
        return(video_out->control(VOCTRL_SET_DEINTERLACE, data)
                == VO_TRUE) ? CONTROL_TRUE : CONTROL_FALSE;
    }
    case VFCTRL_DRAW_OSD:
	if(!vo_config_count) return CONTROL_FALSE; // vo not configured?
	video_out->draw_osd();
	return CONTROL_TRUE;
    case VFCTRL_FLIP_PAGE:
    {
	if(!vo_config_count) return CONTROL_FALSE; // vo not configured?
	video_out->flip_page();
	return CONTROL_TRUE;
    }
    case VFCTRL_SET_EQUALIZER:
    {
	vf_equalizer_t *eq=data;
	if(!vo_config_count) return CONTROL_FALSE; // vo not configured?
	return((video_out->control(VOCTRL_SET_EQUALIZER, eq->item, eq->value) == VO_TRUE) ? CONTROL_TRUE : CONTROL_FALSE);
    }
    case VFCTRL_GET_EQUALIZER:
    {
	vf_equalizer_t *eq=data;
	if(!vo_config_count) return CONTROL_FALSE; // vo not configured?
	return((video_out->control(VOCTRL_GET_EQUALIZER, eq->item, &eq->value) == VO_TRUE) ? CONTROL_TRUE : CONTROL_FALSE);
    }
#ifdef USE_ASS
    case VFCTRL_INIT_EOSD:
    {
        vf->priv->ass_priv = ass_renderer_init((ass_library_t*)data);
        if (!vf->priv->ass_priv) return CONTROL_FALSE;
        ass_configure_fonts(vf->priv->ass_priv);
        vf->priv->prev_visibility = 0;
        return CONTROL_TRUE;
    }
    case VFCTRL_DRAW_EOSD:
    {
        mp_eosd_images_t images = {NULL, 2};
        double pts = vf->priv->pts;
        if (!vo_config_count || !vf->priv->ass_priv) return CONTROL_FALSE;
        if (sub_visibility && vf->priv->ass_priv && ass_track && (pts != MP_NOPTS_VALUE)) {
            mp_eosd_res_t res;
            memset(&res, 0, sizeof(res));
            if (video_out->control(VOCTRL_GET_EOSD_RES, &res) == VO_TRUE) {
                ass_set_frame_size(vf->priv->ass_priv, res.w, res.h);
                ass_set_margins(vf->priv->ass_priv, res.mt, res.mb, res.ml, res.mr);
                ass_set_aspect_ratio(vf->priv->ass_priv, (double)res.w / res.h);
            }

            images.imgs = ass_render_frame(vf->priv->ass_priv, ass_track, (pts+sub_delay) * 1000 + .5, &images.changed);
            if (!vf->priv->prev_visibility)
                images.changed = 2;
            vf->priv->prev_visibility = 1;
        } else
            vf->priv->prev_visibility = 0;
        vf->priv->prev_visibility = sub_visibility;
        return (video_out->control(VOCTRL_DRAW_EOSD, &images) == VO_TRUE) ? CONTROL_TRUE : CONTROL_FALSE;
    }
#endif
    case VFCTRL_GET_PTS:
    {
	*(double *)data = vf->priv->pts;
	return CONTROL_TRUE;
    }
    }
    // return video_out->control(request,data);
    return CONTROL_UNKNOWN;
}
Exemplo n.º 10
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;
    }
}