assrender: port to 0.11

This commit is contained in:
Wim Taymans 2011-10-06 10:58:32 +02:00
parent c94c332578
commit 67dac04012
3 changed files with 143 additions and 177 deletions

View file

@ -304,7 +304,7 @@ GST_PLUGINS_NONPORTED=" adpcmdec adpcmenc aiff asfmux \
sdi segmentclip siren speed subenc stereo tta videofilters \
videomaxrate videomeasure videoparsers videosignal vmnc y4m \
decklink dvb fbdev linsys shm vcd \
voaacenc assrender apexsink bz2 camerabin2 cdaudio celt cog curl dc1394 dirac dts resindvd \
voaacenc apexsink bz2 camerabin2 cdaudio celt cog curl dc1394 dirac dts resindvd \
faac gsettings gsm jp2k ladspa modplug mpeg2enc mplex mimic \
musepack musicbrainz nas neon ofa rsvg schro sdl sndfile soundtouch timidity \
vp8 wildmidi xvid "

View file

@ -57,23 +57,19 @@ enum
PROP_EMBEDDEDFONTS
};
#define FORMATS "{ RGB, BGR, xRGB, xBGR, RGBx, BGRx, I420 }"
static GstStaticPadTemplate src_factory = GST_STATIC_PAD_TEMPLATE ("src",
GST_PAD_SRC,
GST_PAD_ALWAYS,
GST_STATIC_CAPS (GST_VIDEO_CAPS_RGB ";" GST_VIDEO_CAPS_BGR ";"
GST_VIDEO_CAPS_xRGB ";" GST_VIDEO_CAPS_xBGR ";"
GST_VIDEO_CAPS_RGBx ";" GST_VIDEO_CAPS_BGRx ";"
GST_VIDEO_CAPS_YUV ("I420"))
GST_STATIC_CAPS (GST_VIDEO_CAPS_MAKE (FORMATS))
);
static GstStaticPadTemplate video_sink_factory =
GST_STATIC_PAD_TEMPLATE ("video_sink",
GST_STATIC_PAD_TEMPLATE ("video_sink",
GST_PAD_SINK,
GST_PAD_ALWAYS,
GST_STATIC_CAPS (GST_VIDEO_CAPS_RGB ";" GST_VIDEO_CAPS_BGR ";"
GST_VIDEO_CAPS_xRGB ";" GST_VIDEO_CAPS_xBGR ";"
GST_VIDEO_CAPS_RGBx ";" GST_VIDEO_CAPS_BGRx ";"
GST_VIDEO_CAPS_YUV ("I420"))
GST_STATIC_CAPS (GST_VIDEO_CAPS_MAKE (FORMATS))
);
static GstStaticPadTemplate text_sink_factory =
@ -93,9 +89,10 @@ static void gst_ass_render_finalize (GObject * object);
static GstStateChangeReturn gst_ass_render_change_state (GstElement * element,
GstStateChange transition);
GST_BOILERPLATE (GstAssRender, gst_ass_render, GstElement, GST_TYPE_ELEMENT);
#define gst_ass_render_parent_class parent_class
G_DEFINE_TYPE (GstAssRender, gst_ass_render, GST_TYPE_ELEMENT);
static GstCaps *gst_ass_render_getcaps (GstPad * pad);
static GstCaps *gst_ass_render_getcaps (GstPad * pad, GstCaps * filter);
static gboolean gst_ass_render_setcaps_video (GstPad * pad, GstCaps * caps);
static gboolean gst_ass_render_setcaps_text (GstPad * pad, GstCaps * caps);
@ -107,30 +104,8 @@ static gboolean gst_ass_render_event_video (GstPad * pad, GstEvent * event);
static gboolean gst_ass_render_event_text (GstPad * pad, GstEvent * event);
static gboolean gst_ass_render_event_src (GstPad * pad, GstEvent * event);
static GstFlowReturn gst_ass_render_bufferalloc_video (GstPad * pad,
guint64 offset, guint size, GstCaps * caps, GstBuffer ** buffer);
static gboolean gst_ass_render_query_src (GstPad * pad, GstQuery * query);
static void
gst_ass_render_base_init (gpointer gclass)
{
GstElementClass *element_class = (GstElementClass *) gclass;
gst_element_class_add_pad_template (element_class,
gst_static_pad_template_get (&src_factory));
gst_element_class_add_pad_template (element_class,
gst_static_pad_template_get (&video_sink_factory));
gst_element_class_add_pad_template (element_class,
gst_static_pad_template_get (&text_sink_factory));
gst_element_class_set_details_simple (element_class, "ASS/SSA Render",
"Mixer/Video/Overlay/Subtitle",
"Renders ASS/SSA subtitles with libass",
"Benjamin Schmitz <vortex@wolpzone.de>, "
"Sebastian Dröge <sebastian.droege@collabora.co.uk>");
}
/* initialize the plugin's class */
static void
gst_ass_render_class_init (GstAssRenderClass * klass)
@ -153,6 +128,19 @@ gst_ass_render_class_init (GstAssRenderClass * klass)
gstelement_class->change_state =
GST_DEBUG_FUNCPTR (gst_ass_render_change_state);
gst_element_class_add_pad_template (gstelement_class,
gst_static_pad_template_get (&src_factory));
gst_element_class_add_pad_template (gstelement_class,
gst_static_pad_template_get (&video_sink_factory));
gst_element_class_add_pad_template (gstelement_class,
gst_static_pad_template_get (&text_sink_factory));
gst_element_class_set_details_simple (gstelement_class, "ASS/SSA Render",
"Mixer/Video/Overlay/Subtitle",
"Renders ASS/SSA subtitles with libass",
"Benjamin Schmitz <vortex@wolpzone.de>, "
"Sebastian Dröge <sebastian.droege@collabora.co.uk>");
}
#if defined(LIBASS_VERSION) && LIBASS_VERSION >= 0x00907000
@ -178,7 +166,7 @@ _libass_message_cb (gint level, const gchar * fmt, va_list args,
#endif
static void
gst_ass_render_init (GstAssRender * render, GstAssRenderClass * gclass)
gst_ass_render_init (GstAssRender * render)
{
GST_DEBUG_OBJECT (render, "init");
@ -188,11 +176,6 @@ gst_ass_render_init (GstAssRender * render, GstAssRenderClass * gclass)
render->text_sinkpad =
gst_pad_new_from_static_template (&text_sink_factory, "text_sink");
gst_pad_set_setcaps_function (render->video_sinkpad,
GST_DEBUG_FUNCPTR (gst_ass_render_setcaps_video));
gst_pad_set_setcaps_function (render->text_sinkpad,
GST_DEBUG_FUNCPTR (gst_ass_render_setcaps_text));
gst_pad_set_getcaps_function (render->srcpad,
GST_DEBUG_FUNCPTR (gst_ass_render_getcaps));
gst_pad_set_getcaps_function (render->video_sinkpad,
@ -210,9 +193,6 @@ gst_ass_render_init (GstAssRender * render, GstAssRenderClass * gclass)
gst_pad_set_event_function (render->srcpad,
GST_DEBUG_FUNCPTR (gst_ass_render_event_src));
gst_pad_set_bufferalloc_function (render->video_sinkpad,
GST_DEBUG_FUNCPTR (gst_ass_render_bufferalloc_video));
gst_pad_set_query_function (render->srcpad,
GST_DEBUG_FUNCPTR (gst_ass_render_query_src));
@ -220,8 +200,7 @@ gst_ass_render_init (GstAssRender * render, GstAssRenderClass * gclass)
gst_element_add_pad (GST_ELEMENT (render), render->video_sinkpad);
gst_element_add_pad (GST_ELEMENT (render), render->text_sinkpad);
render->width = 0;
render->height = 0;
gst_video_info_init (&render->info);
render->subtitle_mutex = g_mutex_new ();
render->subtitle_cond = g_cond_new ();
@ -434,7 +413,7 @@ gst_ass_render_event_src (GstPad * pad, GstEvent * event)
}
static GstCaps *
gst_ass_render_getcaps (GstPad * pad)
gst_ass_render_getcaps (GstPad * pad, GstCaps * filter)
{
GstAssRender *render = GST_ASS_RENDER (gst_pad_get_parent (pad));
GstPad *otherpad;
@ -446,7 +425,7 @@ gst_ass_render_getcaps (GstPad * pad)
otherpad = render->srcpad;
/* we can do what the peer can */
caps = gst_pad_peer_get_caps (otherpad);
caps = gst_pad_peer_get_caps (otherpad, filter);
if (caps) {
GstCaps *temp;
const GstCaps *templ;
@ -469,19 +448,24 @@ gst_ass_render_getcaps (GstPad * pad)
#define CREATE_RGB_BLIT_FUNCTION(name,bpp,R,G,B) \
static void \
blit_##name (GstAssRender * render, ASS_Image * ass_image, GstBuffer * buffer) \
blit_##name (GstAssRender * render, ASS_Image * ass_image, GstVideoFrame * frame) \
{ \
guint counter = 0; \
gint alpha, r, g, b, k; \
const guint8 *src; \
guint8 *dst; \
guint8 *dst, *data; \
gint x, y, w, h; \
gint width = render->width; \
gint height = render->height; \
gint dst_stride = GST_ROUND_UP_4 (width * bpp); \
gint width; \
gint height; \
gint dst_stride; \
gint dst_skip; \
gint src_skip; \
\
width = GST_VIDEO_FRAME_WIDTH (frame); \
height = GST_VIDEO_FRAME_HEIGHT (frame); \
dst_stride = GST_VIDEO_FRAME_PLANE_STRIDE (frame, 0); \
data = GST_VIDEO_FRAME_PLANE_DATA (frame, 0); \
\
while (ass_image) { \
if (ass_image->dst_y > height || ass_image->dst_x > width) \
goto next; \
@ -492,7 +476,7 @@ blit_##name (GstAssRender * render, ASS_Image * ass_image, GstBuffer * buffer) \
g = ((ass_image->color) >> 16) & 0xff; \
b = ((ass_image->color) >> 8) & 0xff; \
src = ass_image->bitmap; \
dst = buffer->data + ass_image->dst_y * dst_stride + ass_image->dst_x * bpp; \
dst = data + ass_image->dst_y * dst_stride + ass_image->dst_x * bpp; \
\
w = MIN (ass_image->w, width - ass_image->dst_x); \
h = MIN (ass_image->h, height - ass_image->dst_y); \
@ -562,7 +546,7 @@ rgb_to_v (gint r, gint g, gint b)
}
static void
blit_i420 (GstAssRender * render, ASS_Image * ass_image, GstBuffer * buffer)
blit_i420 (GstAssRender * render, ASS_Image * ass_image, GstVideoFrame * frame)
{
guint counter = 0;
gint alpha, r, g, b, k, k2;
@ -575,25 +559,20 @@ blit_i420 (GstAssRender * render, ASS_Image * ass_image, GstBuffer * buffer)
gint w2;
gint src_stride;
#endif
gint width = render->width;
gint height = render->height;
gint y_offset, y_stride;
gint u_offset, u_stride;
gint v_offset, v_stride;
gint width, height;
guint8 *y_data, *u_data, *v_data;
gint y_stride, u_stride, v_stride;
y_offset =
gst_video_format_get_component_offset (GST_VIDEO_FORMAT_I420, 0, width,
height);
u_offset =
gst_video_format_get_component_offset (GST_VIDEO_FORMAT_I420, 1, width,
height);
v_offset =
gst_video_format_get_component_offset (GST_VIDEO_FORMAT_I420, 2, width,
height);
width = GST_VIDEO_FRAME_WIDTH (frame);
height = GST_VIDEO_FRAME_HEIGHT (frame);
y_stride = gst_video_format_get_row_stride (GST_VIDEO_FORMAT_I420, 0, width);
u_stride = gst_video_format_get_row_stride (GST_VIDEO_FORMAT_I420, 1, width);
v_stride = gst_video_format_get_row_stride (GST_VIDEO_FORMAT_I420, 2, width);
y_data = GST_VIDEO_FRAME_COMP_DATA (frame, 0);
u_data = GST_VIDEO_FRAME_COMP_DATA (frame, 1);
v_data = GST_VIDEO_FRAME_COMP_DATA (frame, 2);
y_stride = GST_VIDEO_FRAME_COMP_STRIDE (frame, 0);
u_stride = GST_VIDEO_FRAME_COMP_STRIDE (frame, 1);
v_stride = GST_VIDEO_FRAME_COMP_STRIDE (frame, 2);
while (ass_image) {
if (ass_image->dst_y > height || ass_image->dst_x > width)
@ -619,19 +598,14 @@ blit_i420 (GstAssRender * render, ASS_Image * ass_image, GstBuffer * buffer)
#endif
src = ass_image->bitmap;
dst_y =
buffer->data + y_offset + ass_image->dst_y * y_stride +
ass_image->dst_x;
dst_u =
buffer->data + u_offset + (ass_image->dst_y / 2) * u_stride +
ass_image->dst_x / 2;
dst_v =
buffer->data + v_offset + (ass_image->dst_y / 2) * v_stride +
ass_image->dst_x / 2;
#if 0
dst_y = y_data + ass_image->dst_y * y_stride + ass_image->dst_x;
dst_u = u_data + (ass_image->dst_y / 2) * u_stride + ass_image->dst_x / 2;
dst_v = v_data + (ass_image->dst_y / 2) * v_stride + ass_image->dst_x / 2;
#endif
for (y = 0; y < h; y++) {
dst_y = buffer->data + y_offset + (ass_image->dst_y + y) * y_stride +
ass_image->dst_x;
dst_y = y_data + (ass_image->dst_y + y) * y_stride + ass_image->dst_x;
for (x = 0; x < w; x++) {
k = src[y * ass_image->w + x] * alpha / 255;
dst_y[x] = (k * Y + (255 - k) * dst_y[x]) / 255;
@ -640,12 +614,8 @@ blit_i420 (GstAssRender * render, ASS_Image * ass_image, GstBuffer * buffer)
y = 0;
if (ass_image->dst_y & 1) {
dst_u =
buffer->data + u_offset + (ass_image->dst_y / 2) * u_stride +
ass_image->dst_x / 2;
dst_v =
buffer->data + v_offset + (ass_image->dst_y / 2) * v_stride +
ass_image->dst_x / 2;
dst_u = u_data + (ass_image->dst_y / 2) * u_stride + ass_image->dst_x / 2;
dst_v = v_data + (ass_image->dst_y / 2) * v_stride + ass_image->dst_x / 2;
x = 0;
if (ass_image->dst_x & 1) {
k2 = src[y * ass_image->w + x] * alpha / 255;
@ -674,11 +644,9 @@ blit_i420 (GstAssRender * render, ASS_Image * ass_image, GstBuffer * buffer)
}
for (; y < h - 1; y += 2) {
dst_u =
buffer->data + u_offset + ((ass_image->dst_y + y) / 2) * u_stride +
dst_u = u_data + ((ass_image->dst_y + y) / 2) * u_stride +
ass_image->dst_x / 2;
dst_v =
buffer->data + v_offset + ((ass_image->dst_y + y) / 2) * v_stride +
dst_v = v_data + ((ass_image->dst_y + y) / 2) * v_stride +
ass_image->dst_x / 2;
x = 0;
if (ass_image->dst_x & 1) {
@ -712,12 +680,8 @@ blit_i420 (GstAssRender * render, ASS_Image * ass_image, GstBuffer * buffer)
}
if (y < h) {
dst_u =
buffer->data + u_offset + (ass_image->dst_y / 2) * u_stride +
ass_image->dst_x / 2;
dst_v =
buffer->data + v_offset + (ass_image->dst_y / 2) * v_stride +
ass_image->dst_x / 2;
dst_u = u_data + (ass_image->dst_y / 2) * u_stride + ass_image->dst_x / 2;
dst_v = v_data + (ass_image->dst_y / 2) * v_stride + ass_image->dst_x / 2;
x = 0;
if (ass_image->dst_x & 1) {
k2 = src[y * ass_image->w + x] * alpha / 255;
@ -762,25 +726,18 @@ gst_ass_render_setcaps_video (GstPad * pad, GstCaps * caps)
gboolean ret = FALSE;
gint par_n = 1, par_d = 1;
gdouble dar;
GstVideoInfo info;
render->width = 0;
render->height = 0;
if (!gst_video_info_from_caps (&info, caps))
goto invalid_caps;
if (!gst_video_format_parse_caps (caps, &render->format, &render->width,
&render->height) ||
!gst_video_parse_caps_framerate (caps, &render->fps_n, &render->fps_d)) {
GST_ERROR_OBJECT (render, "Can't parse caps: %" GST_PTR_FORMAT, caps);
ret = FALSE;
goto out;
}
gst_video_parse_caps_pixel_aspect_ratio (caps, &par_n, &par_d);
render->info = info;
ret = gst_pad_set_caps (render->srcpad, caps);
if (!ret)
goto out;
switch (render->format) {
switch (GST_VIDEO_INFO_FORMAT (&info)) {
case GST_VIDEO_FORMAT_RGB:
render->blit = blit_rgb;
break;
@ -808,15 +765,15 @@ gst_ass_render_setcaps_video (GstPad * pad, GstCaps * caps)
}
g_mutex_lock (render->ass_mutex);
ass_set_frame_size (render->ass_renderer, render->width, render->height);
ass_set_frame_size (render->ass_renderer, info.width, info.height);
dar = (((gdouble) par_n) * ((gdouble) render->width))
/ (((gdouble) par_d) * ((gdouble) render->height));
dar = (((gdouble) par_n) * ((gdouble) info.width))
/ (((gdouble) par_d) * ((gdouble) info.height));
#if !defined(LIBASS_VERSION) || LIBASS_VERSION < 0x00907000
ass_set_aspect_ratio (render->ass_renderer, dar);
#else
ass_set_aspect_ratio (render->ass_renderer,
dar, ((gdouble) render->width) / ((gdouble) render->height));
dar, ((gdouble) info.width) / ((gdouble) info.height));
#endif
ass_set_font_scale (render->ass_renderer, 1.0);
ass_set_hinting (render->ass_renderer, ASS_HINTING_LIGHT);
@ -840,6 +797,14 @@ out:
gst_object_unref (render);
return ret;
/* ERRORS */
invalid_caps:
{
GST_ERROR_OBJECT (render, "Can't parse caps: %" GST_PTR_FORMAT, caps);
ret = FALSE;
goto out;
}
}
static gboolean
@ -850,7 +815,7 @@ gst_ass_render_setcaps_text (GstPad * pad, GstCaps * caps)
const GValue *value;
GstBuffer *priv;
gchar *codec_private;
guint codec_private_size;
gsize codec_private_size;
gboolean ret = FALSE;
structure = gst_caps_get_structure (caps, 0);
@ -865,8 +830,8 @@ gst_ass_render_setcaps_text (GstPad * pad, GstCaps * caps)
priv = gst_value_get_buffer (value);
g_return_val_if_fail (priv != NULL, FALSE);
codec_private = (gchar *) GST_BUFFER_DATA (priv);
codec_private_size = GST_BUFFER_SIZE (priv);
codec_private =
gst_buffer_map (priv, &codec_private_size, NULL, GST_MAP_READ);
if (!render->ass_track)
render->ass_track = ass_new_track (render->ass_library);
@ -874,6 +839,8 @@ gst_ass_render_setcaps_text (GstPad * pad, GstCaps * caps)
ass_process_codec_private (render->ass_track,
codec_private, codec_private_size);
gst_buffer_unmap (priv, codec_private, codec_private_size);
GST_DEBUG_OBJECT (render, "ass track created");
render->track_init_ok = TRUE;
@ -898,8 +865,8 @@ static void
gst_ass_render_process_text (GstAssRender * render, GstBuffer * buffer,
GstClockTime running_time, GstClockTime duration)
{
gchar *data = (gchar *) GST_BUFFER_DATA (buffer);
guint size = GST_BUFFER_SIZE (buffer);
gchar *data;
gsize size;
gdouble pts_start, pts_end;
pts_start = running_time;
@ -911,41 +878,24 @@ gst_ass_render_process_text (GstAssRender * render, GstBuffer * buffer,
"Processing subtitles with running time %" GST_TIME_FORMAT
" and duration %" GST_TIME_FORMAT, GST_TIME_ARGS (running_time),
GST_TIME_ARGS (duration));
data = gst_buffer_map (buffer, &size, NULL, GST_MAP_READ);
g_mutex_lock (render->ass_mutex);
ass_process_chunk (render->ass_track, data, size, pts_start, pts_end);
g_mutex_unlock (render->ass_mutex);
gst_buffer_unmap (buffer, data, size);
gst_buffer_unref (buffer);
}
static GstFlowReturn
gst_ass_render_bufferalloc_video (GstPad * pad, guint64 offset, guint size,
GstCaps * caps, GstBuffer ** buffer)
{
GstAssRender *render = GST_ASS_RENDER (gst_pad_get_parent (pad));
GstFlowReturn ret = GST_FLOW_WRONG_STATE;
GstPad *allocpad;
GST_OBJECT_LOCK (render);
allocpad = render->srcpad ? gst_object_ref (render->srcpad) : NULL;
GST_OBJECT_UNLOCK (render);
if (allocpad) {
ret = gst_pad_alloc_buffer (allocpad, offset, size, caps, buffer);
gst_object_unref (allocpad);
}
gst_object_unref (render);
return ret;
}
static GstFlowReturn
gst_ass_render_chain_video (GstPad * pad, GstBuffer * buffer)
{
GstAssRender *render = GST_ASS_RENDER (GST_PAD_PARENT (pad));
GstFlowReturn ret = GST_FLOW_OK;
gboolean in_seg = FALSE;
gint64 start, stop, clip_start = 0, clip_stop = 0;
guint64 start, stop, clip_start = 0, clip_stop = 0;
ASS_Image *ass_image;
if (!GST_BUFFER_TIMESTAMP_IS_VALID (buffer)) {
@ -978,14 +928,13 @@ gst_ass_render_chain_video (GstPad * pad, GstBuffer * buffer)
/* if the buffer is only partially in the segment, fix up stamps */
if (clip_start != start || (stop != -1 && clip_stop != stop)) {
GST_DEBUG_OBJECT (render, "clipping buffer timestamp/duration to segment");
buffer = gst_buffer_make_metadata_writable (buffer);
buffer = gst_buffer_make_writable (buffer);
GST_BUFFER_TIMESTAMP (buffer) = clip_start;
if (stop != -1)
GST_BUFFER_DURATION (buffer) = clip_stop - clip_start;
}
gst_segment_set_last_stop (&render->video_segment, GST_FORMAT_TIME,
clip_start);
render->video_segment.position = clip_start;
g_mutex_lock (render->subtitle_mutex);
if (render->subtitle_pending) {
@ -1055,8 +1004,13 @@ gst_ass_render_chain_video (GstPad * pad, GstBuffer * buffer)
g_mutex_unlock (render->ass_mutex);
if (ass_image != NULL) {
GstVideoFrame frame;
buffer = gst_buffer_make_writable (buffer);
render->blit (render, ass_image, buffer);
gst_video_frame_map (&frame, &render->info, buffer, GST_MAP_WRITE);
render->blit (render, ass_image, &frame);
gst_video_frame_unmap (&frame);
} else {
GST_LOG_OBJECT (render, "nothing to render right now");
}
@ -1084,7 +1038,7 @@ gst_ass_render_chain_text (GstPad * pad, GstBuffer * buffer)
GstClockTime timestamp, duration;
GstClockTime sub_running_time, vid_running_time;
GstClockTime sub_running_time_end;
gint64 cstart, cstop;
guint64 cstart, cstop;
gboolean in_seg;
if (render->subtitle_flushing) {
@ -1118,8 +1072,7 @@ gst_ass_render_chain_text (GstPad * pad, GstBuffer * buffer)
GST_BUFFER_TIMESTAMP (buffer) = timestamp = cstart;
GST_BUFFER_DURATION (buffer) = duration = cstop - cstart;
gst_segment_set_last_stop (&render->subtitle_segment, GST_FORMAT_TIME,
GST_BUFFER_TIMESTAMP (buffer));
render->subtitle_segment.position = GST_BUFFER_TIMESTAMP (buffer);
sub_running_time =
gst_segment_to_running_time (&render->subtitle_segment, GST_FORMAT_TIME,
@ -1129,11 +1082,12 @@ gst_ass_render_chain_text (GstPad * pad, GstBuffer * buffer)
timestamp + duration);
vid_running_time =
gst_segment_to_running_time (&render->video_segment, GST_FORMAT_TIME,
render->video_segment.last_stop);
render->video_segment.position);
if (render->fps_n && render->fps_d)
if (render->info.fps_n && render->info.fps_d)
vid_running_time +=
gst_util_uint64_scale (GST_SECOND, render->fps_d, render->fps_n);
gst_util_uint64_scale (GST_SECOND, render->info.fps_d,
render->info.fps_n);
if (sub_running_time > vid_running_time + GST_SECOND / 2) {
g_assert (render->subtitle_pending == NULL);
@ -1175,6 +1129,7 @@ gst_ass_render_chain_text (GstPad * pad, GstBuffer * buffer)
static void
gst_ass_render_handle_tags (GstAssRender * render, GstTagList * taglist)
{
#if 0
static const gchar *mimetypes[] = {
"application/x-font-ttf",
"application/x-font-otf",
@ -1184,8 +1139,8 @@ gst_ass_render_handle_tags (GstAssRender * render, GstTagList * taglist)
".otf",
".ttf"
};
#endif
guint tag_size;
guint index;
if (!taglist)
return;
@ -1194,17 +1149,21 @@ gst_ass_render_handle_tags (GstAssRender * render, GstTagList * taglist)
if (tag_size > 0 && render->embeddedfonts) {
const GValue *value;
GstBuffer *buf;
#if 0
GstCaps *caps;
GstStructure *structure;
gboolean valid_mimetype, valid_extension;
guint j;
const gchar *filename;
#endif
guint index;
GST_DEBUG_OBJECT (render, "TAG event has attachments");
for (index = 0; index < tag_size; index++) {
value = gst_tag_list_get_value_index (taglist, GST_TAG_ATTACHMENT, index);
buf = gst_value_get_buffer (value);
#if 0
if (!buf || !GST_BUFFER_CAPS (buf))
continue;
@ -1242,6 +1201,7 @@ gst_ass_render_handle_tags (GstAssRender * render, GstTagList * taglist)
GST_DEBUG_OBJECT (render, "registered new font %s", filename);
g_mutex_unlock (render->ass_mutex);
}
#endif
}
}
}
@ -1256,24 +1216,28 @@ gst_ass_render_event_video (GstPad * pad, GstEvent * event)
GST_EVENT_TYPE_NAME (event));
switch (GST_EVENT_TYPE (event)) {
case GST_EVENT_NEWSEGMENT:
case GST_EVENT_CAPS:
{
GstFormat format;
gdouble rate;
gint64 start, stop, time;
gboolean update;
GstCaps *caps;
gst_event_parse_caps (event, &caps);
ret = gst_ass_render_setcaps_video (pad, caps);
gst_event_unref (event);
break;
}
case GST_EVENT_SEGMENT:
{
GstSegment segment;
GST_DEBUG_OBJECT (render, "received new segment");
gst_event_parse_new_segment (event, &update, &rate, &format, &start,
&stop, &time);
gst_event_copy_segment (event, &segment);
if (format == GST_FORMAT_TIME) {
if (segment.format == GST_FORMAT_TIME) {
GST_DEBUG_OBJECT (render, "VIDEO SEGMENT now: %" GST_SEGMENT_FORMAT,
&render->video_segment);
gst_segment_set_newsegment (&render->video_segment, update, rate,
format, start, stop, time);
render->video_segment = segment;
GST_DEBUG_OBJECT (render, "VIDEO SEGMENT after: %" GST_SEGMENT_FORMAT,
&render->video_segment);
@ -1320,24 +1284,28 @@ gst_ass_render_event_text (GstPad * pad, GstEvent * event)
GST_DEBUG_OBJECT (pad, "received text event %s", GST_EVENT_TYPE_NAME (event));
switch (GST_EVENT_TYPE (event)) {
case GST_EVENT_NEWSEGMENT:
case GST_EVENT_CAPS:
{
GstFormat format;
gdouble rate;
gint64 start, stop, time;
gboolean update;
GstCaps *caps;
gst_event_parse_caps (event, &caps);
ret = gst_ass_render_setcaps_text (pad, caps);
gst_event_unref (event);
break;
}
case GST_EVENT_SEGMENT:
{
GstSegment segment;
GST_DEBUG_OBJECT (render, "received new segment");
gst_event_parse_new_segment (event, &update, &rate, &format, &start,
&stop, &time);
gst_event_copy_segment (event, &segment);
if (format == GST_FORMAT_TIME) {
if (segment.format == GST_FORMAT_TIME) {
GST_DEBUG_OBJECT (render, "SUBTITLE SEGMENT now: %" GST_SEGMENT_FORMAT,
&render->subtitle_segment);
gst_segment_set_newsegment (&render->subtitle_segment, update, rate,
format, start, stop, time);
render->subtitle_segment = segment;
GST_DEBUG_OBJECT (render,
"SUBTITLE SEGMENT after: %" GST_SEGMENT_FORMAT,

View file

@ -43,7 +43,7 @@ G_BEGIN_DECLS
typedef struct _GstAssRender GstAssRender;
typedef struct _GstAssRenderClass GstAssRenderClass;
typedef void (*GstAssRenderBlitFunction) (GstAssRender *render, ASS_Image *ass_image, GstBuffer *buffer);
typedef void (*GstAssRenderBlitFunction) (GstAssRender *render, ASS_Image *ass_image, GstVideoFrame *frame);
struct _GstAssRender
{
@ -57,9 +57,7 @@ struct _GstAssRender
/* <private> */
GstSegment video_segment;
GstVideoFormat format;
gint width, height;
gint fps_n, fps_d;
GstVideoInfo info;
GstAssRenderBlitFunction blit;
GMutex *subtitle_mutex;