dvbsuboverlay: initial version, work in progress

This commit is contained in:
Mart Raudsepp 2010-11-29 20:06:07 +00:00 committed by Edward Hervey
parent f64f03264f
commit a8d891dc5e
8 changed files with 3275 additions and 0 deletions

View file

@ -300,6 +300,7 @@ AG_GST_CHECK_PLUGIN(dataurisrc)
AG_GST_CHECK_PLUGIN(dccp) AG_GST_CHECK_PLUGIN(dccp)
AG_GST_CHECK_PLUGIN(debugutils) AG_GST_CHECK_PLUGIN(debugutils)
AG_GST_CHECK_PLUGIN(dtmf) AG_GST_CHECK_PLUGIN(dtmf)
AG_GST_CHECK_PLUGIN(dvbsuboverlay)
AG_GST_CHECK_PLUGIN(dvdspu) AG_GST_CHECK_PLUGIN(dvdspu)
AG_GST_CHECK_PLUGIN(festival) AG_GST_CHECK_PLUGIN(festival)
AG_GST_CHECK_PLUGIN(freeze) AG_GST_CHECK_PLUGIN(freeze)
@ -1725,6 +1726,7 @@ gst/dataurisrc/Makefile
gst/dccp/Makefile gst/dccp/Makefile
gst/debugutils/Makefile gst/debugutils/Makefile
gst/dtmf/Makefile gst/dtmf/Makefile
gst/dvbsuboverlay/Makefile
gst/dvdspu/Makefile gst/dvdspu/Makefile
gst/festival/Makefile gst/festival/Makefile
gst/freeze/Makefile gst/freeze/Makefile

View file

@ -0,0 +1,10 @@
plugin_LTLIBRARIES = libgstdvbsuboverlay.la
libgstdvbsuboverlay_la_SOURCES = dvb-sub.c gstdvbsuboverlay.c
libgstdvbsuboverlay_la_CFLAGS = $(GST_PLUGINS_BAD_CFLAGS) $(GST_PLUGINS_BASE_CFLAGS) $(GST_CFLAGS)
libgstdvbsuboverlay_la_LIBADD = $(GST_PLUGINS_BASE_LIBS) $(GST_LIBS) -lgstvideo-@GST_MAJORMINOR@
libgstdvbsuboverlay_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS)
libgstdvbsuboverlay_la_LIBTOOLFLAGS = --tag=disable-static
noinst_HEADERS = gstdvbsuboverlay.h dvb-sub.h ffmpeg-colorspace.h

6
gst/dvbsuboverlay/TODO Normal file
View file

@ -0,0 +1,6 @@
Check about GST_PAD_PARENT vs gst_pad_get_parent - do we need a reference - is there any danger of losing the parent in the middle or not:
<thaytan> one uses GST_PAD_PARENT in situations where you can be sure the parent exists and will exist for the entire time you need it
<thaytan> and gst_pad_get_parent when you need a ref because the pad might get unparented while you're using it
Ask about individual segment handling on separate sink pads. Is it possible that the separate NEWSEGMENT events on the text and video pad have different start and/or stop values, as to require some code complexity present?

1640
gst/dvbsuboverlay/dvb-sub.c Normal file

File diff suppressed because it is too large Load diff

136
gst/dvbsuboverlay/dvb-sub.h Normal file
View file

@ -0,0 +1,136 @@
/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*- */
/*
* libdvbsub - DVB subtitle decoding
* Copyright (C) Mart Raudsepp 2009 <mart.raudsepp@artecdesign.ee>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef _DVB_SUB_H_
#define _DVB_SUB_H_
#include <glib-object.h>
G_BEGIN_DECLS
#define DVB_TYPE_SUB (dvb_sub_get_type ())
#define DVB_SUB(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), DVB_TYPE_SUB, DvbSub))
#define DVB_SUB_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), DVB_TYPE_SUB, DvbSubClass))
#define DVB_IS_SUB(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), DVB_TYPE_SUB))
#define DVB_IS_SUB_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), DVB_TYPE_SUB))
#define DVB_SUB_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), DVB_TYPE_SUB, DvbSubClass))
typedef struct _DvbSubClass DvbSubClass;
typedef struct _DvbSub DvbSub;
struct _DvbSubClass
{
GObjectClass parent_class;
};
/**
* DvbSub:
*
* The #DvbSub struct contains only private fields and should not be
* directly accessed.
*/
struct _DvbSub
{
GObject parent_instance;
/*< private >*/
gpointer private_data;
};
/**
* DVBSubtitlePicture:
* @data: the data in the form of palette indices, each byte represents one pixel
* as an index into the @palette.
* @palette: the palette used for this subtitle rectangle, up to 256 items depending
* on the depth of the subpicture; each palette item is in ARGB form, 8-bits per channel.
* @palette_bits_count: the amount of bits used in indeces into @palette in @data.
* @rowstride: the number of bytes between the start of a row and the start of the next row.
*
* A structure representing the contents of a subtitle rectangle.
*
* FIXME: Expose the depth of the palette, and perhaps also the height in this struct.
*/
typedef struct DVBSubtitlePicture {
guint8 *data;
guint32 *palette;
guint8 palette_bits_count;
int rowstride;
} DVBSubtitlePicture;
/**
* DVBSubtitleRect:
* @x: x coordinate of top left corner
* @y: y coordinate of top left corner
* @w: the width of this subpicture rectangle
* @h: the height of this subpicture rectangle
* @pict: the content of this subpicture rectangle
*
* A structure representing one subtitle objects position, dimension and content.
*/
typedef struct DVBSubtitleRect {
int x;
int y;
int w;
int h;
DVBSubtitlePicture pict;
} DVBSubtitleRect;
/**
* DVBSubtitles:
* @num_rects: the number of #DVBSubtitleRect in @rects
* @rects: dynamic array of #DVBSubtitleRect
*
* A structure representing a set of subtitle objects.
*/
typedef struct DVBSubtitles {
unsigned int num_rects;
DVBSubtitleRect **rects;
} DVBSubtitles;
/**
* DvbSubCallbacks:
* @new_data: called when new subpicture data is available for display. @dvb_sub
* is the #DvbSub instance this callback originates from; @subs is the set of
* subtitle objects that should be display for no more than @page_time_out
* seconds at @pts; @user_data is the same user_data as was passed through
* dvb_sub_set_callbacks();
*
* A set of callbacks that can be installed on the #DvbSub with
* dvb_sub_set_callbacks().
*/
typedef struct {
void (*new_data) (DvbSub *dvb_sub, guint64 pts, DVBSubtitles * subs, guint8 page_time_out, gpointer user_data);
/*< private >*/
gpointer _dvb_sub_reserved[3];
} DvbSubCallbacks;
GType dvb_sub_get_type (void) G_GNUC_CONST;
DvbSub *dvb_sub_new (void);
gint dvb_sub_feed (DvbSub *dvb_sub, guint8 *data, gint len);
gint dvb_sub_feed_with_pts (DvbSub *dvb_sub, guint64 pts, guint8 *data, gint len);
void dvb_sub_set_callbacks (DvbSub *dvb_sub, DvbSubCallbacks *callbacks, gpointer user_data);
void dvb_sub_set_global_log_cb (void (*log_cb) (GLogLevelFlags log_level, const gchar *format, va_list args, gpointer user_data),
gpointer user_data);
G_END_DECLS
#endif /* _DVB_SUB_H_ */

View file

@ -0,0 +1,116 @@
/*
* This file is copied from ffmpeg's libavcodec/colorspace.h
* for the YUV_TO_RGB{1,2}_CCIR macros.
* Original copyright header and contents follows:
*/
/*
* Colorspace conversion defines
* Copyright (c) 2001, 2002, 2003 Fabrice Bellard
*
* This file is part of FFmpeg.
*
* FFmpeg is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* FFmpeg is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
/**
* @file libavcodec/colorspace.h
* Various defines for YUV<->RGB conversion
*/
#ifndef AVCODEC_COLORSPACE_H
#define AVCODEC_COLORSPACE_H
#define SCALEBITS 10
#define ONE_HALF (1 << (SCALEBITS - 1))
#define FIX(x) ((int) ((x) * (1<<SCALEBITS) + 0.5))
#define YUV_TO_RGB1_CCIR(cb1, cr1)\
{\
cb = (cb1) - 128;\
cr = (cr1) - 128;\
r_add = FIX(1.40200*255.0/224.0) * cr + ONE_HALF;\
g_add = - FIX(0.34414*255.0/224.0) * cb - FIX(0.71414*255.0/224.0) * cr + \
ONE_HALF;\
b_add = FIX(1.77200*255.0/224.0) * cb + ONE_HALF;\
}
#define YUV_TO_RGB2_CCIR(r, g, b, y1)\
{\
y = ((y1) - 16) * FIX(255.0/219.0);\
r = cm[(y + r_add) >> SCALEBITS];\
g = cm[(y + g_add) >> SCALEBITS];\
b = cm[(y + b_add) >> SCALEBITS];\
}
#define YUV_TO_RGB1(cb1, cr1)\
{\
cb = (cb1) - 128;\
cr = (cr1) - 128;\
r_add = FIX(1.40200) * cr + ONE_HALF;\
g_add = - FIX(0.34414) * cb - FIX(0.71414) * cr + ONE_HALF;\
b_add = FIX(1.77200) * cb + ONE_HALF;\
}
#define YUV_TO_RGB2(r, g, b, y1)\
{\
y = (y1) << SCALEBITS;\
r = cm[(y + r_add) >> SCALEBITS];\
g = cm[(y + g_add) >> SCALEBITS];\
b = cm[(y + b_add) >> SCALEBITS];\
}
#define Y_CCIR_TO_JPEG(y)\
cm[((y) * FIX(255.0/219.0) + (ONE_HALF - 16 * FIX(255.0/219.0))) >> SCALEBITS]
#define Y_JPEG_TO_CCIR(y)\
(((y) * FIX(219.0/255.0) + (ONE_HALF + (16 << SCALEBITS))) >> SCALEBITS)
#define C_CCIR_TO_JPEG(y)\
cm[(((y) - 128) * FIX(127.0/112.0) + (ONE_HALF + (128 << SCALEBITS))) >> SCALEBITS]
/* NOTE: the clamp is really necessary! */
static inline int C_JPEG_TO_CCIR(int y) {
y = (((y - 128) * FIX(112.0/127.0) + (ONE_HALF + (128 << SCALEBITS))) >> SCALEBITS);
if (y < 16)
y = 16;
return y;
}
#define RGB_TO_Y(r, g, b) \
((FIX(0.29900) * (r) + FIX(0.58700) * (g) + \
FIX(0.11400) * (b) + ONE_HALF) >> SCALEBITS)
#define RGB_TO_U(r1, g1, b1, shift)\
(((- FIX(0.16874) * r1 - FIX(0.33126) * g1 + \
FIX(0.50000) * b1 + (ONE_HALF << shift) - 1) >> (SCALEBITS + shift)) + 128)
#define RGB_TO_V(r1, g1, b1, shift)\
(((FIX(0.50000) * r1 - FIX(0.41869) * g1 - \
FIX(0.08131) * b1 + (ONE_HALF << shift) - 1) >> (SCALEBITS + shift)) + 128)
#define RGB_TO_Y_CCIR(r, g, b) \
((FIX(0.29900*219.0/255.0) * (r) + FIX(0.58700*219.0/255.0) * (g) + \
FIX(0.11400*219.0/255.0) * (b) + (ONE_HALF + (16 << SCALEBITS))) >> SCALEBITS)
#define RGB_TO_U_CCIR(r1, g1, b1, shift)\
(((- FIX(0.16874*224.0/255.0) * r1 - FIX(0.33126*224.0/255.0) * g1 + \
FIX(0.50000*224.0/255.0) * b1 + (ONE_HALF << shift) - 1) >> (SCALEBITS + shift)) + 128)
#define RGB_TO_V_CCIR(r1, g1, b1, shift)\
(((FIX(0.50000*224.0/255.0) * r1 - FIX(0.41869*224.0/255.0) * g1 - \
FIX(0.08131*224.0/255.0) * b1 + (ONE_HALF << shift) - 1) >> (SCALEBITS + shift)) + 128)
#endif /* AVCODEC_COLORSPACE_H */

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,90 @@
/* GStreamer DVB subtitles overlay
* Copyright (c) 2010 Mart Raudsepp <mart.raudsepp@collabora.co.uk>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public License
* along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#ifndef __GST_DVBSUB_OVERLAY_H__
#define __GST_DVBSUB_OVERLAY_H__
#include <gst/gst.h>
#include <gst/video/video.h>
#include "dvb-sub.h"
G_BEGIN_DECLS
#define GST_TYPE_DVBSUB_OVERLAY (gst_dvbsub_overlay_get_type())
#define GST_DVBSUB_OVERLAY(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_DVBSUB_OVERLAY,GstDVBSubOverlay))
#define GST_DVBSUB_OVERLAY_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_DVBSUB_OVERLAY,GstDVBSubOverlayClass))
#define GST_IS_DVBSUB_OVERLAY(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_DVBSUB_OVERLAY))
#define GST_IS_DVBSUB_OVERLAY_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_DVBSUB_OVERLAY))
typedef struct _GstDVBSubOverlay GstDVBSubOverlay;
typedef struct _GstDVBSubOverlayClass GstDVBSubOverlayClass;
typedef void (*GstAssRenderBlitFunction) (GstDVBSubOverlay *overlay, DVBSubtitles *subs, GstBuffer *buffer);
struct _GstDVBSubOverlay
{
GstElement element;
GstPad *video_sinkpad, *text_sinkpad, *srcpad;
/* properties */
gboolean enable;
/* <private> */
GstSegment video_segment;
GstSegment subtitle_segment;
GstVideoFormat format;
gint width, height;
gint fps_n, fps_d;
GstAssRenderBlitFunction blit;
guint subtitle_buffer; /* FIXME: This should hold the pre-rendered
* subtitle regions for fast blending on top
* of each frame. Currently just a number of
* active regions that ought to get blended,
* to get all the timing code working,
* leaving the actual conversion from
* libdvbsub to a suitable cache format and
* blending to later */
GMutex *subtitle_mutex;
GCond *subtitle_cond; /* to signal removal of a queued text
* buffer, arrival of a text buffer,
* a text segment update, or a change
* in status (e.g. shutdown, flushing)
* FIXME: Update comment for dvbsub case */
GstBuffer *subtitle_pending;
gboolean subtitle_flushing;
gboolean subtitle_eos;
GMutex *dvbsub_mutex; /* FIXME: Do we need a mutex lock in case of libdvbsub? Probably, but... */
DvbSub *dvb_sub;
gboolean renderer_init_ok;
};
struct _GstDVBSubOverlayClass
{
GstElementClass parent_class;
};
GType gst_dvbsub_overlay_get_type (void);
G_END_DECLS
#endif