dvdspu element donated by Fluendo. It implements a DVD Sub-Picture
Original commit message from CVS: * configure.ac: * gst/dvdspu/.cvsignore: * gst/dvdspu/Notes.txt: * gst/dvdspu/gstdvdspu-render.c: (dvdspu_recalc_palette), (dvdspu_update_palettes), (dvdspu_clear_comp_buffers), (dvdspu_get_nibble), (dvdspu_get_rle_code), (dvdspu_draw_rle_run), (rle_end_x), (dvdspu_render_line), (dvdspu_update_chgcol), (dvdspu_render_line_with_chgcol), (dvdspu_blend_comp_buffers), (gstdvdspu_render_spu): * gst/dvdspu/gstdvdspu.c: (dvdspu_base_init), (dvdspu_class_init), (dvdspu_init), (dvdspu_clear), (dvdspu_dispose), (dvdspu_finalize), (dvdspu_flush_spu_info), (dvdspu_buffer_alloc), (dvdspu_src_event), (dvdspu_video_set_caps), (dvdspu_video_proxy_getcaps), (dvdspu_video_event), (dvdspu_video_chain), (dvspu_handle_vid_buffer), (dvdspu_redraw_still), (gstdvdspu_parse_chg_colcon), (dvdspu_exec_cmd_blk), (dvdspu_finish_spu_buf), (dvdspu_setup_cmd_blk), (dvdspu_handle_new_spu_buf), (dvdspu_handle_dvd_event), (dvdspu_dump_dcsq), (dvdspu_advance_spu), (dvdspu_check_still_updates), (dvdspu_subpic_chain), (dvdspu_subpic_event), (dvdspu_change_state), (gstdvdspu_plugin_init): * gst/dvdspu/gstdvdspu.h: dvdspu element donated by Fluendo. It implements a DVD Sub-Picture Unit, decoding and overlaying DVD subtitles and menu graphics. * gst/mpeg2sub/.cvsignore: * gst/mpeg2sub/Makefile.am: * gst/mpeg2sub/Notes.txt: * gst/mpeg2sub/gstmpeg2subt.c: * gst/mpeg2sub/gstmpeg2subt.h: * gst/mpeg2sub/mpeg2subt.vcproj: Delete old and broken mpeg2subt element that was never ported from 0.8
This commit is contained in:
parent
b0d65aa59b
commit
077f84ac1f
37
ChangeLog
37
ChangeLog
@ -1,3 +1,40 @@
|
|||||||
|
2007-08-27 Jan Schmidt <thaytan@mad.scientist.com>
|
||||||
|
|
||||||
|
* configure.ac:
|
||||||
|
* gst/dvdspu/.cvsignore:
|
||||||
|
* gst/dvdspu/Notes.txt:
|
||||||
|
* gst/dvdspu/gstdvdspu-render.c: (dvdspu_recalc_palette),
|
||||||
|
(dvdspu_update_palettes), (dvdspu_clear_comp_buffers),
|
||||||
|
(dvdspu_get_nibble), (dvdspu_get_rle_code), (dvdspu_draw_rle_run),
|
||||||
|
(rle_end_x), (dvdspu_render_line), (dvdspu_update_chgcol),
|
||||||
|
(dvdspu_render_line_with_chgcol), (dvdspu_blend_comp_buffers),
|
||||||
|
(gstdvdspu_render_spu):
|
||||||
|
* gst/dvdspu/gstdvdspu.c: (dvdspu_base_init), (dvdspu_class_init),
|
||||||
|
(dvdspu_init), (dvdspu_clear), (dvdspu_dispose), (dvdspu_finalize),
|
||||||
|
(dvdspu_flush_spu_info), (dvdspu_buffer_alloc), (dvdspu_src_event),
|
||||||
|
(dvdspu_video_set_caps), (dvdspu_video_proxy_getcaps),
|
||||||
|
(dvdspu_video_event), (dvdspu_video_chain),
|
||||||
|
(dvspu_handle_vid_buffer), (dvdspu_redraw_still),
|
||||||
|
(gstdvdspu_parse_chg_colcon), (dvdspu_exec_cmd_blk),
|
||||||
|
(dvdspu_finish_spu_buf), (dvdspu_setup_cmd_blk),
|
||||||
|
(dvdspu_handle_new_spu_buf), (dvdspu_handle_dvd_event),
|
||||||
|
(dvdspu_dump_dcsq), (dvdspu_advance_spu),
|
||||||
|
(dvdspu_check_still_updates), (dvdspu_subpic_chain),
|
||||||
|
(dvdspu_subpic_event), (dvdspu_change_state),
|
||||||
|
(gstdvdspu_plugin_init):
|
||||||
|
* gst/dvdspu/gstdvdspu.h:
|
||||||
|
|
||||||
|
dvdspu element donated by Fluendo. It implements a DVD Sub-Picture
|
||||||
|
Unit, decoding and overlaying DVD subtitles and menu graphics.
|
||||||
|
|
||||||
|
* gst/mpeg2sub/.cvsignore:
|
||||||
|
* gst/mpeg2sub/Makefile.am:
|
||||||
|
* gst/mpeg2sub/Notes.txt:
|
||||||
|
* gst/mpeg2sub/gstmpeg2subt.c:
|
||||||
|
* gst/mpeg2sub/gstmpeg2subt.h:
|
||||||
|
* gst/mpeg2sub/mpeg2subt.vcproj:
|
||||||
|
Delete old and broken mpeg2subt element that was never ported from 0.8
|
||||||
|
|
||||||
2007-08-24 Julien MOUTTE <julien@moutte.net>
|
2007-08-24 Julien MOUTTE <julien@moutte.net>
|
||||||
|
|
||||||
* gst/flv/gstflvdemux.c: (gst_flv_demux_flush),
|
* gst/flv/gstflvdemux.c: (gst_flv_demux_flush),
|
||||||
|
@ -83,6 +83,7 @@ GST_PLUGINS_ALL="\
|
|||||||
bayer \
|
bayer \
|
||||||
cdxaparse \
|
cdxaparse \
|
||||||
deinterlace \
|
deinterlace \
|
||||||
|
dvdspu \
|
||||||
equalizer \
|
equalizer \
|
||||||
festival \
|
festival \
|
||||||
filter \
|
filter \
|
||||||
@ -989,6 +990,7 @@ gst/app/Makefile
|
|||||||
gst/bayer/Makefile
|
gst/bayer/Makefile
|
||||||
gst/cdxaparse/Makefile
|
gst/cdxaparse/Makefile
|
||||||
gst/deinterlace/Makefile
|
gst/deinterlace/Makefile
|
||||||
|
gst/dvdspu/Makefile
|
||||||
gst/equalizer/Makefile
|
gst/equalizer/Makefile
|
||||||
gst/festival/Makefile
|
gst/festival/Makefile
|
||||||
gst/filter/Makefile
|
gst/filter/Makefile
|
||||||
|
521
gst/dvdspu/gstdvdspu-render.c
Normal file
521
gst/dvdspu/gstdvdspu-render.c
Normal file
@ -0,0 +1,521 @@
|
|||||||
|
/* GStreamer DVD Sub-Picture Unit
|
||||||
|
* Copyright (C) 2007 Fluendo S.A. <info@fluendo.com>
|
||||||
|
*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
|
# include <config.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include <gst/gst.h>
|
||||||
|
|
||||||
|
#include "gstdvdspu.h"
|
||||||
|
|
||||||
|
GST_DEBUG_CATEGORY_EXTERN (dvdspu_debug);
|
||||||
|
#define GST_CAT_DEFAULT dvdspu_debug
|
||||||
|
|
||||||
|
static void
|
||||||
|
dvdspu_recalc_palette (GstDVDSpu * dvdspu,
|
||||||
|
SpuColour * dest, guint8 * idx, guint8 * alpha)
|
||||||
|
{
|
||||||
|
SpuState *state = &dvdspu->spu_state;
|
||||||
|
gint i;
|
||||||
|
|
||||||
|
for (i = 0; i < 4; i++, dest++) {
|
||||||
|
guint32 col = state->current_clut[idx[i]];
|
||||||
|
|
||||||
|
dest->Y = (guint16) ((col >> 16) & 0xff) * alpha[i];
|
||||||
|
/* U/V are stored as V/U in the clut words, so switch them */
|
||||||
|
dest->U = (guint16) (col & 0xff) * alpha[i];
|
||||||
|
dest->V = (guint16) ((col >> 8) & 0xff) * alpha[i];
|
||||||
|
dest->A = alpha[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Recalculate the main, HL & ChgCol palettes */
|
||||||
|
static void
|
||||||
|
dvdspu_update_palettes (GstDVDSpu * dvdspu, SpuState * state)
|
||||||
|
{
|
||||||
|
gint16 l, c;
|
||||||
|
guint8 index[4]; /* Indices for the palette */
|
||||||
|
guint8 alpha[4]; /* Alpha values the palette */
|
||||||
|
|
||||||
|
if (state->main_pal_dirty) {
|
||||||
|
dvdspu_recalc_palette (dvdspu, state->main_pal, state->main_idx,
|
||||||
|
state->main_alpha);
|
||||||
|
|
||||||
|
/* Need to refresh the hl_ctrl info copies of the main palette too */
|
||||||
|
memcpy (state->hl_ctrl_i.pix_ctrl_i[0].pal_cache, state->main_pal,
|
||||||
|
4 * sizeof (SpuColour));
|
||||||
|
memcpy (state->hl_ctrl_i.pix_ctrl_i[2].pal_cache, state->main_pal,
|
||||||
|
4 * sizeof (SpuColour));
|
||||||
|
|
||||||
|
state->main_pal_dirty = FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (state->hl_pal_dirty) {
|
||||||
|
dvdspu_recalc_palette (dvdspu, state->hl_ctrl_i.pix_ctrl_i[1].pal_cache,
|
||||||
|
state->hl_idx, state->hl_alpha);
|
||||||
|
state->hl_pal_dirty = FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Update the offset positions for the highlight region */
|
||||||
|
if (state->hl_rect.top != -1) {
|
||||||
|
state->hl_ctrl_i.top = state->hl_rect.top;
|
||||||
|
state->hl_ctrl_i.bottom = state->hl_rect.bottom;
|
||||||
|
state->hl_ctrl_i.n_changes = 3;
|
||||||
|
state->hl_ctrl_i.pix_ctrl_i[0].left = 0;
|
||||||
|
state->hl_ctrl_i.pix_ctrl_i[1].left = state->hl_rect.left;
|
||||||
|
state->hl_ctrl_i.pix_ctrl_i[2].left = state->hl_rect.right + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (state->line_ctrl_i_pal_dirty) {
|
||||||
|
GST_LOG_OBJECT (dvdspu, "Updating chg-col-con palettes");
|
||||||
|
for (l = 0; l < state->n_line_ctrl_i; l++) {
|
||||||
|
SpuLineCtrlI *cur_line_ctrl = state->line_ctrl_i + l;
|
||||||
|
|
||||||
|
for (c = 0; c < cur_line_ctrl->n_changes; c++) {
|
||||||
|
SpuPixCtrlI *cur = cur_line_ctrl->pix_ctrl_i + c;
|
||||||
|
|
||||||
|
index[3] = (cur->palette >> 28) & 0x0f;
|
||||||
|
index[2] = (cur->palette >> 24) & 0x0f;
|
||||||
|
index[1] = (cur->palette >> 20) & 0x0f;
|
||||||
|
index[0] = (cur->palette >> 16) & 0x0f;
|
||||||
|
|
||||||
|
alpha[3] = (cur->palette >> 12) & 0x0f;
|
||||||
|
alpha[2] = (cur->palette >> 8) & 0x0f;
|
||||||
|
alpha[1] = (cur->palette >> 4) & 0x0f;
|
||||||
|
alpha[0] = (cur->palette) & 0x0f;
|
||||||
|
dvdspu_recalc_palette (dvdspu, cur->pal_cache, index, alpha);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
state->line_ctrl_i_pal_dirty = FALSE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
dvdspu_clear_comp_buffers (SpuState * state)
|
||||||
|
{
|
||||||
|
/* The area to clear is the line inside the disp_rect, each entry 2 bytes,
|
||||||
|
* of the sub-sampled UV planes. */
|
||||||
|
gint16 left = state->disp_rect.left / 2;
|
||||||
|
gint16 right = state->disp_rect.right / 2;
|
||||||
|
gint16 uv_width = 2 * (right - left + 1);
|
||||||
|
|
||||||
|
memset (state->comp_bufs[0] + left, 0, uv_width);
|
||||||
|
memset (state->comp_bufs[1] + left, 0, uv_width);
|
||||||
|
memset (state->comp_bufs[2] + left, 0, uv_width);
|
||||||
|
|
||||||
|
state->comp_last_x[0] = -1;
|
||||||
|
state->comp_last_x[1] = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline guint8
|
||||||
|
dvdspu_get_nibble (SpuState * state, guint16 * rle_offset)
|
||||||
|
{
|
||||||
|
guint8 ret;
|
||||||
|
|
||||||
|
if (G_UNLIKELY (*rle_offset >= state->max_offset))
|
||||||
|
return 0; /* Overran the buffer */
|
||||||
|
|
||||||
|
ret = GST_BUFFER_DATA (state->pix_buf)[(*rle_offset) / 2];
|
||||||
|
|
||||||
|
/* If the offset is even, we shift the answer down 4 bits, otherwise not */
|
||||||
|
if (*rle_offset & 0x01)
|
||||||
|
ret &= 0x0f;
|
||||||
|
else
|
||||||
|
ret = ret >> 4;
|
||||||
|
|
||||||
|
(*rle_offset)++;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static guint16
|
||||||
|
dvdspu_get_rle_code (SpuState * state, guint16 * rle_offset)
|
||||||
|
{
|
||||||
|
guint16 code;
|
||||||
|
|
||||||
|
code = dvdspu_get_nibble (state, rle_offset);
|
||||||
|
if (code < 0x4) { /* 4 .. f */
|
||||||
|
code = (code << 4) | dvdspu_get_nibble (state, rle_offset);
|
||||||
|
if (code < 0x10) { /* 1x .. 3x */
|
||||||
|
code = (code << 4) | dvdspu_get_nibble (state, rle_offset);
|
||||||
|
if (code < 0x40) { /* 04x .. 0fx */
|
||||||
|
code = (code << 4) | dvdspu_get_nibble (state, rle_offset);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return code;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void
|
||||||
|
dvdspu_draw_rle_run (SpuState * state, gint16 x, gint16 end, SpuColour * colour)
|
||||||
|
{
|
||||||
|
#if 0
|
||||||
|
GST_LOG ("Y: %d x: %d end %d col %d %d %d %d",
|
||||||
|
state->cur_Y, x, end, colour->Y, colour->U, colour->V, colour->A);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (colour->A != 0) {
|
||||||
|
guint8 inv_A = 0xf - colour->A;
|
||||||
|
|
||||||
|
/* FIXME: This could be more efficient */
|
||||||
|
while (x < end) {
|
||||||
|
state->out_Y[x] = (inv_A * state->out_Y[x] + colour->Y) / 0xf;
|
||||||
|
state->out_U[x / 2] += colour->U;
|
||||||
|
state->out_V[x / 2] += colour->V;
|
||||||
|
state->out_A[x / 2] += colour->A;
|
||||||
|
x++;
|
||||||
|
}
|
||||||
|
/* Update the compositing buffer so we know how much to blend later */
|
||||||
|
*(state->comp_last_x_ptr) = end;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline gint16
|
||||||
|
rle_end_x (guint16 rle_code, gint16 x, gint16 end)
|
||||||
|
{
|
||||||
|
/* run length = rle_code >> 2 */
|
||||||
|
if (G_UNLIKELY (((rle_code >> 2) == 0)))
|
||||||
|
return end;
|
||||||
|
else
|
||||||
|
return MIN (end, x + (rle_code >> 2));
|
||||||
|
}
|
||||||
|
|
||||||
|
static void dvdspu_render_line_with_chgcol (SpuState * state,
|
||||||
|
guint8 * planes[3], guint16 * rle_offset);
|
||||||
|
static gboolean dvdspu_update_chgcol (SpuState * state);
|
||||||
|
|
||||||
|
static void
|
||||||
|
dvdspu_render_line (SpuState * state, guint8 * planes[3], guint16 * rle_offset)
|
||||||
|
{
|
||||||
|
gint16 x, next_x, end, rle_code;
|
||||||
|
SpuColour *colour;
|
||||||
|
|
||||||
|
/* Check for special case of chg_col info to use (either highlight or
|
||||||
|
* ChgCol command */
|
||||||
|
if (state->cur_chg_col != NULL) {
|
||||||
|
if (dvdspu_update_chgcol (state)) {
|
||||||
|
/* Check the top & bottom, because we might not be within the region yet */
|
||||||
|
if (state->cur_Y >= state->cur_chg_col->top &&
|
||||||
|
state->cur_Y <= state->cur_chg_col->bottom) {
|
||||||
|
dvdspu_render_line_with_chgcol (state, planes, rle_offset);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* No special case. Render as normal */
|
||||||
|
|
||||||
|
/* Set up our output pointers */
|
||||||
|
state->out_Y = planes[0];
|
||||||
|
state->out_U = state->comp_bufs[0];
|
||||||
|
state->out_V = state->comp_bufs[1];
|
||||||
|
state->out_A = state->comp_bufs[2];
|
||||||
|
/* We always need to start our RLE decoding byte_aligned */
|
||||||
|
*rle_offset = GST_ROUND_UP_2 (*rle_offset);
|
||||||
|
|
||||||
|
x = state->disp_rect.left;
|
||||||
|
end = state->disp_rect.right + 1;
|
||||||
|
while (x < end) {
|
||||||
|
rle_code = dvdspu_get_rle_code (state, rle_offset);
|
||||||
|
colour = &state->main_pal[rle_code & 3];
|
||||||
|
next_x = rle_end_x (rle_code, x, end);
|
||||||
|
/* Now draw the run between [x,next_x) */
|
||||||
|
dvdspu_draw_rle_run (state, x, next_x, colour);
|
||||||
|
x = next_x;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
dvdspu_update_chgcol (SpuState * state)
|
||||||
|
{
|
||||||
|
if (state->cur_chg_col == NULL)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
if (state->cur_Y <= state->cur_chg_col->bottom)
|
||||||
|
return TRUE;
|
||||||
|
|
||||||
|
while (state->cur_chg_col < state->cur_chg_col_end) {
|
||||||
|
if (state->cur_Y >= state->cur_chg_col->top &&
|
||||||
|
state->cur_Y <= state->cur_chg_col->bottom) {
|
||||||
|
#if 0
|
||||||
|
g_print ("Stopped @ entry %d with top %d bottom %d, cur_y %d",
|
||||||
|
(gint16) (state->cur_chg_col - state->line_ctrl_i),
|
||||||
|
state->cur_chg_col->top, state->cur_chg_col->bottom, y);
|
||||||
|
#endif
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
state->cur_chg_col++;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Finished all our cur_chg_col entries. Use the main palette from here on */
|
||||||
|
state->cur_chg_col = NULL;
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
dvdspu_render_line_with_chgcol (SpuState * state, guint8 * planes[3],
|
||||||
|
guint16 * rle_offset)
|
||||||
|
{
|
||||||
|
SpuLineCtrlI *chg_col = state->cur_chg_col;
|
||||||
|
|
||||||
|
gint16 x, next_x, disp_end, rle_code, run_end;
|
||||||
|
SpuColour *colour;
|
||||||
|
SpuPixCtrlI *cur_pix_ctrl;
|
||||||
|
SpuPixCtrlI *next_pix_ctrl;
|
||||||
|
SpuPixCtrlI *end_pix_ctrl;
|
||||||
|
SpuPixCtrlI dummy_pix_ctrl;
|
||||||
|
gint16 cur_reg_end;
|
||||||
|
gint i;
|
||||||
|
|
||||||
|
state->out_Y = planes[0];
|
||||||
|
state->out_U = state->comp_bufs[0];
|
||||||
|
state->out_V = state->comp_bufs[1];
|
||||||
|
state->out_A = state->comp_bufs[2];
|
||||||
|
|
||||||
|
/* We always need to start our RLE decoding byte_aligned */
|
||||||
|
*rle_offset = GST_ROUND_UP_2 (*rle_offset);
|
||||||
|
|
||||||
|
/* Our run will cover the display rect */
|
||||||
|
x = state->disp_rect.left;
|
||||||
|
disp_end = state->disp_rect.right + 1;
|
||||||
|
|
||||||
|
/* Work out the first pixel control info, which may point to the dummy entry if
|
||||||
|
* the global palette/alpha need using initally */
|
||||||
|
cur_pix_ctrl = chg_col->pix_ctrl_i;
|
||||||
|
end_pix_ctrl = chg_col->pix_ctrl_i + chg_col->n_changes;
|
||||||
|
|
||||||
|
if (cur_pix_ctrl->left != 0) {
|
||||||
|
next_pix_ctrl = cur_pix_ctrl;
|
||||||
|
cur_pix_ctrl = &dummy_pix_ctrl;
|
||||||
|
for (i = 0; i < 4; i++) /* Copy the main palette to our dummy entry */
|
||||||
|
dummy_pix_ctrl.pal_cache[i] = state->main_pal[i];
|
||||||
|
} else {
|
||||||
|
next_pix_ctrl = cur_pix_ctrl + 1;
|
||||||
|
}
|
||||||
|
if (next_pix_ctrl < end_pix_ctrl)
|
||||||
|
cur_reg_end = next_pix_ctrl->left;
|
||||||
|
else
|
||||||
|
cur_reg_end = disp_end;
|
||||||
|
|
||||||
|
/* Render stuff */
|
||||||
|
while (x < disp_end) {
|
||||||
|
rle_code = dvdspu_get_rle_code (state, rle_offset);
|
||||||
|
next_x = rle_end_x (rle_code, x, disp_end);
|
||||||
|
|
||||||
|
/* Now draw the run between [x,next_x), crossing palette regions as needed */
|
||||||
|
while (x < next_x) {
|
||||||
|
run_end = MIN (next_x, cur_reg_end);
|
||||||
|
|
||||||
|
if (G_LIKELY (x < run_end)) {
|
||||||
|
colour = &cur_pix_ctrl->pal_cache[rle_code & 3];
|
||||||
|
dvdspu_draw_rle_run (state, x, run_end, colour);
|
||||||
|
x = run_end;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (x >= cur_reg_end) {
|
||||||
|
/* Advance to next region */
|
||||||
|
cur_pix_ctrl = next_pix_ctrl;
|
||||||
|
next_pix_ctrl++;
|
||||||
|
|
||||||
|
if (next_pix_ctrl < end_pix_ctrl)
|
||||||
|
cur_reg_end = next_pix_ctrl->left;
|
||||||
|
else
|
||||||
|
cur_reg_end = disp_end;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
dvdspu_blend_comp_buffers (SpuState * state, guint8 * planes[3])
|
||||||
|
{
|
||||||
|
gint16 uv_end;
|
||||||
|
gint16 left, x;
|
||||||
|
guint8 *out_U;
|
||||||
|
guint8 *out_V;
|
||||||
|
guint16 *in_U;
|
||||||
|
guint16 *in_V;
|
||||||
|
guint16 *in_A;
|
||||||
|
gint16 comp_last_x = MAX (state->comp_last_x[0], state->comp_last_x[1]);
|
||||||
|
|
||||||
|
if (comp_last_x < state->disp_rect.left)
|
||||||
|
return; /* Didn't draw in the comp buffers, nothing to do... */
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
GST_LOG ("Blending comp buffers from disp_rect.left %d to x=%d",
|
||||||
|
state->disp_rect.left, comp_last_x);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Set up the output pointers */
|
||||||
|
out_U = planes[1]; /* U plane */
|
||||||
|
out_V = planes[2]; /* V plane */
|
||||||
|
|
||||||
|
/* Input starts at the first pixel of the compositing buffer */
|
||||||
|
in_U = state->comp_bufs[0]; /* U comp buffer */
|
||||||
|
in_V = state->comp_bufs[1]; /* V comp buffer */
|
||||||
|
in_A = state->comp_bufs[2]; /* A comp buffer */
|
||||||
|
|
||||||
|
/* Calculate how many pixels to blend based on the maximum X value that was
|
||||||
|
* drawn in the render_line function, divided by 2 (rounding up) to account
|
||||||
|
* for UV sub-sampling */
|
||||||
|
uv_end = (comp_last_x + 1) / 2;
|
||||||
|
left = state->disp_rect.left / 2;
|
||||||
|
|
||||||
|
for (x = left; x < uv_end; x++) {
|
||||||
|
guint16 tmp;
|
||||||
|
guint16 inv_A = (4 * 0xf) - in_A[x];
|
||||||
|
|
||||||
|
/* Each entry in the compositing buffer is 4 summed pixels, so the
|
||||||
|
* inverse alpha is (4 * 0x0f) - in_A[x] */
|
||||||
|
tmp = in_U[x] + inv_A * out_U[x];
|
||||||
|
out_U[x] = (guint8) (tmp / (4 * 0xf));
|
||||||
|
|
||||||
|
tmp = in_V[x] + inv_A * out_V[x];
|
||||||
|
out_V[x] = (guint8) (tmp / (4 * 0xf));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
gstdvdspu_render_spu (GstDVDSpu * dvdspu, GstBuffer * buf)
|
||||||
|
{
|
||||||
|
SpuState *state = &dvdspu->spu_state;
|
||||||
|
guint8 *planes[3]; /* YUV frame pointers */
|
||||||
|
gint y, last_y;
|
||||||
|
|
||||||
|
/* Set up our initial state */
|
||||||
|
|
||||||
|
/* Store the start of each plane */
|
||||||
|
planes[0] = GST_BUFFER_DATA (buf);
|
||||||
|
planes[1] = planes[0] + (state->Y_height * state->Y_stride);
|
||||||
|
planes[2] = planes[1] + (state->UV_height * state->UV_stride);
|
||||||
|
|
||||||
|
/* Sanity check */
|
||||||
|
g_return_if_fail (planes[2] + (state->UV_height * state->UV_stride) <=
|
||||||
|
GST_BUFFER_DATA (buf) + GST_BUFFER_SIZE (buf));
|
||||||
|
|
||||||
|
GST_DEBUG ("Rendering SPU. disp_rect %d,%d to %d,%d. hl_rect %d,%d to %d,%d",
|
||||||
|
state->disp_rect.left, state->disp_rect.top,
|
||||||
|
state->disp_rect.right, state->disp_rect.bottom,
|
||||||
|
state->hl_rect.left, state->hl_rect.top,
|
||||||
|
state->hl_rect.right, state->hl_rect.bottom);
|
||||||
|
|
||||||
|
/* We start rendering from the first line of the display rect */
|
||||||
|
y = state->disp_rect.top;
|
||||||
|
|
||||||
|
/* Update our plane references to the first line of the disp_rect */
|
||||||
|
planes[0] += state->Y_stride * y;
|
||||||
|
planes[1] += state->UV_stride * (y / 2);
|
||||||
|
planes[2] += state->UV_stride * (y / 2);
|
||||||
|
|
||||||
|
/* When reading RLE data, we track the offset in nibbles... */
|
||||||
|
state->cur_offsets[0] = state->pix_data[0] * 2;
|
||||||
|
state->cur_offsets[1] = state->pix_data[1] * 2;
|
||||||
|
state->max_offset = GST_BUFFER_SIZE (state->pix_buf) * 2;
|
||||||
|
|
||||||
|
/* Update all the palette caches */
|
||||||
|
dvdspu_update_palettes (dvdspu, state);
|
||||||
|
|
||||||
|
/* Set up HL or Change Color & Contrast rect tracking */
|
||||||
|
if (state->hl_rect.top != -1) {
|
||||||
|
state->cur_chg_col = &state->hl_ctrl_i;
|
||||||
|
state->cur_chg_col_end = state->cur_chg_col + 1;
|
||||||
|
} else if (state->n_line_ctrl_i > 0) {
|
||||||
|
state->cur_chg_col = state->line_ctrl_i;
|
||||||
|
state->cur_chg_col_end = state->cur_chg_col + state->n_line_ctrl_i;
|
||||||
|
} else
|
||||||
|
state->cur_chg_col = NULL;
|
||||||
|
|
||||||
|
/* start_y is always an even number and we render lines in pairs from there,
|
||||||
|
* accumulating 2 lines of chroma then blending it. We might need to render a
|
||||||
|
* single line at the end if the display rect ends on an even line too. */
|
||||||
|
last_y = (state->disp_rect.bottom - 1) & ~(0x01);
|
||||||
|
for (state->cur_Y = y; state->cur_Y <= last_y; state->cur_Y++) {
|
||||||
|
/* Reset the compositing buffer */
|
||||||
|
dvdspu_clear_comp_buffers (state);
|
||||||
|
/* Render even line */
|
||||||
|
state->comp_last_x_ptr = state->comp_last_x;
|
||||||
|
dvdspu_render_line (state, planes, &state->cur_offsets[0]);
|
||||||
|
/* Advance the luminance output pointer */
|
||||||
|
planes[0] += state->Y_stride;
|
||||||
|
state->cur_Y++;
|
||||||
|
|
||||||
|
/* Render odd line */
|
||||||
|
state->comp_last_x_ptr = state->comp_last_x + 1;
|
||||||
|
dvdspu_render_line (state, planes, &state->cur_offsets[1]);
|
||||||
|
/* Blend the accumulated UV compositing buffers onto the output */
|
||||||
|
dvdspu_blend_comp_buffers (state, planes);
|
||||||
|
|
||||||
|
/* Update all the output pointers */
|
||||||
|
planes[0] += state->Y_stride;
|
||||||
|
planes[1] += state->UV_stride;
|
||||||
|
planes[2] += state->UV_stride;
|
||||||
|
}
|
||||||
|
if (state->cur_Y == state->disp_rect.bottom) {
|
||||||
|
g_assert ((state->disp_rect.bottom & 0x01) == 0);
|
||||||
|
|
||||||
|
/* Render a remaining lone last even line. y already has the correct value
|
||||||
|
* after the above loop exited. */
|
||||||
|
dvdspu_clear_comp_buffers (state);
|
||||||
|
state->comp_last_x_ptr = state->comp_last_x;
|
||||||
|
dvdspu_render_line (state, planes, &state->cur_offsets[0]);
|
||||||
|
dvdspu_blend_comp_buffers (state, planes);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* for debugging purposes, draw a faint rectangle at the edges of the disp_rect */
|
||||||
|
#if 0
|
||||||
|
do {
|
||||||
|
guint8 *cur;
|
||||||
|
gint16 pos;
|
||||||
|
|
||||||
|
cur = GST_BUFFER_DATA (buf) + state->Y_stride * state->disp_rect.top;
|
||||||
|
for (pos = state->disp_rect.left + 1; pos < state->disp_rect.right; pos++)
|
||||||
|
cur[pos] = (cur[pos] / 2) + 0x8;
|
||||||
|
cur = GST_BUFFER_DATA (buf) + state->Y_stride * state->disp_rect.bottom;
|
||||||
|
for (pos = state->disp_rect.left + 1; pos < state->disp_rect.right; pos++)
|
||||||
|
cur[pos] = (cur[pos] / 2) + 0x8;
|
||||||
|
cur = GST_BUFFER_DATA (buf) + state->Y_stride * state->disp_rect.top;
|
||||||
|
for (pos = state->disp_rect.top; pos <= state->disp_rect.bottom; pos++) {
|
||||||
|
cur[state->disp_rect.left] = (cur[state->disp_rect.left] / 2) + 0x8;
|
||||||
|
cur[state->disp_rect.right] = (cur[state->disp_rect.right] / 2) + 0x8;
|
||||||
|
cur += state->Y_stride;
|
||||||
|
}
|
||||||
|
} while (0);
|
||||||
|
#endif
|
||||||
|
/* For debugging purposes, draw a faint rectangle around the highlight rect */
|
||||||
|
#if 0
|
||||||
|
if (state->hl_rect.top != -1) {
|
||||||
|
guint8 *cur;
|
||||||
|
gint16 pos;
|
||||||
|
|
||||||
|
cur = GST_BUFFER_DATA (buf) + state->Y_stride * state->hl_rect.top;
|
||||||
|
for (pos = state->hl_rect.left + 1; pos < state->hl_rect.right; pos++)
|
||||||
|
cur[pos] = (cur[pos] / 2) + 0x8;
|
||||||
|
cur = GST_BUFFER_DATA (buf) + state->Y_stride * state->hl_rect.bottom;
|
||||||
|
for (pos = state->hl_rect.left + 1; pos < state->hl_rect.right; pos++)
|
||||||
|
cur[pos] = (cur[pos] / 2) + 0x8;
|
||||||
|
cur = GST_BUFFER_DATA (buf) + state->Y_stride * state->hl_rect.top;
|
||||||
|
for (pos = state->hl_rect.top; pos <= state->hl_rect.bottom; pos++) {
|
||||||
|
cur[state->hl_rect.left] = (cur[state->hl_rect.left] / 2) + 0x8;
|
||||||
|
cur[state->hl_rect.right] = (cur[state->hl_rect.right] / 2) + 0x8;
|
||||||
|
cur += state->Y_stride;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
1376
gst/dvdspu/gstdvdspu.c
Normal file
1376
gst/dvdspu/gstdvdspu.c
Normal file
File diff suppressed because it is too large
Load Diff
226
gst/dvdspu/gstdvdspu.h
Normal file
226
gst/dvdspu/gstdvdspu.h
Normal file
@ -0,0 +1,226 @@
|
|||||||
|
/* GStreamer DVD Sub-Picture Unit
|
||||||
|
* Copyright (C) 2007 Fluendo S.A. <info@fluendo.com>
|
||||||
|
*
|
||||||
|
* 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 __GSTDVDSPU_H__
|
||||||
|
#define __GSTDVDSPU_H__
|
||||||
|
|
||||||
|
#include <gst/gst.h>
|
||||||
|
|
||||||
|
G_BEGIN_DECLS
|
||||||
|
|
||||||
|
#define GST_TYPE_GSTDVDSPU \
|
||||||
|
(dvdspu_get_type())
|
||||||
|
#define GSTDVDSPU(obj) \
|
||||||
|
(G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_GSTDVDSPU,GstDVDSpu))
|
||||||
|
#define GSTDVDSPU_CLASS(klass) \
|
||||||
|
(G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_GSTDVDSPU,GstDVDSpuClass))
|
||||||
|
#define GST_IS_PLUGIN_TEMPLATE(obj) \
|
||||||
|
(G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_GSTDVDSPU))
|
||||||
|
#define GST_IS_PLUGIN_TEMPLATE_CLASS(klass) \
|
||||||
|
(G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_GSTDVDSPU))
|
||||||
|
|
||||||
|
#define GSTDVDSPU_LOCK(s) g_mutex_lock ((s)->spu_lock);
|
||||||
|
#define GSTDVDSPU_UNLOCK(s) g_mutex_unlock ((s)->spu_lock);
|
||||||
|
|
||||||
|
typedef struct GstDVDSpu GstDVDSpu;
|
||||||
|
typedef struct GstDVDSpuClass GstDVDSpuClass;
|
||||||
|
typedef struct SpuRect SpuRect;
|
||||||
|
typedef struct SpuPixCtrlI SpuPixCtrlI;
|
||||||
|
typedef struct SpuLineCtrlI SpuLineCtrlI;
|
||||||
|
typedef struct SpuColour SpuColour;
|
||||||
|
typedef enum SpuStateFlags SpuStateFlags;
|
||||||
|
typedef struct SpuState SpuState;
|
||||||
|
typedef struct SpuPacket SpuPacket;
|
||||||
|
|
||||||
|
typedef enum SpuCmd SpuCmd;
|
||||||
|
|
||||||
|
/* Describe the limits of a rectangle */
|
||||||
|
struct SpuRect {
|
||||||
|
gint16 left;
|
||||||
|
gint16 top;
|
||||||
|
gint16 right;
|
||||||
|
gint16 bottom;
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Store a pre-multiplied colour value. The YUV fields hold the YUV values
|
||||||
|
* multiplied by the 8-bit alpha, to save computing it while rendering */
|
||||||
|
struct SpuColour {
|
||||||
|
guint16 Y;
|
||||||
|
guint16 U;
|
||||||
|
guint16 V;
|
||||||
|
guint8 A;
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Pixel Control Info from a Change Color Contrast command */
|
||||||
|
struct SpuPixCtrlI {
|
||||||
|
gint16 left;
|
||||||
|
guint32 palette;
|
||||||
|
|
||||||
|
/* Pre-multiplied palette values, updated as
|
||||||
|
* needed */
|
||||||
|
SpuColour pal_cache[4];
|
||||||
|
};
|
||||||
|
|
||||||
|
struct SpuLineCtrlI {
|
||||||
|
guint8 n_changes; /* 1 to 8 */
|
||||||
|
SpuPixCtrlI pix_ctrl_i[8];
|
||||||
|
|
||||||
|
gint16 top;
|
||||||
|
gint16 bottom;
|
||||||
|
};
|
||||||
|
|
||||||
|
enum SpuCmd {
|
||||||
|
SPU_CMD_FSTA_DSP = 0x00, /* Forced Display */
|
||||||
|
SPU_CMD_DSP = 0x01, /* Display Start */
|
||||||
|
SPU_CMD_STP_DSP = 0x02, /* Display Off */
|
||||||
|
SPU_CMD_SET_COLOR = 0x03, /* Set the color indexes for the palette */
|
||||||
|
SPU_CMD_SET_ALPHA = 0x04, /* Set the alpha indexes for the palette */
|
||||||
|
SPU_CMD_SET_DAREA = 0x05, /* Set the display area for the SPU */
|
||||||
|
SPU_CMD_DSPXA = 0x06, /* Pixel data addresses */
|
||||||
|
SPU_CMD_CHG_COLCON = 0x07, /* Change Color & Contrast */
|
||||||
|
SPU_CMD_END = 0xff
|
||||||
|
};
|
||||||
|
|
||||||
|
enum SpuStateFlags {
|
||||||
|
SPU_STATE_NONE = 0x00,
|
||||||
|
/* Flags cleared on a flush */
|
||||||
|
SPU_STATE_DISPLAY = 0x01,
|
||||||
|
SPU_STATE_FORCED_DSP = 0x02,
|
||||||
|
SPU_STATE_STILL_FRAME = 0x04,
|
||||||
|
/* Persistent flags */
|
||||||
|
SPU_STATE_FORCED_ONLY = 0x100
|
||||||
|
};
|
||||||
|
|
||||||
|
#define SPU_STATE_FLAGS_MASK (0xff)
|
||||||
|
|
||||||
|
struct SpuState {
|
||||||
|
GstClockTime next_ts; /* Next event TS in running time */
|
||||||
|
|
||||||
|
GstClockTime base_ts; /* base TS for cmd blk delays in running time */
|
||||||
|
GstBuffer *buf; /* Current SPU packet we're executing commands from */
|
||||||
|
guint16 cur_cmd_blk; /* Offset into the buf for the current cmd block */
|
||||||
|
|
||||||
|
SpuStateFlags flags;
|
||||||
|
|
||||||
|
/* Top + Bottom field offsets in the buffer. 0 = not set */
|
||||||
|
guint16 pix_data[2];
|
||||||
|
GstBuffer *pix_buf; /* Current SPU packet the pix_data references */
|
||||||
|
|
||||||
|
SpuRect disp_rect;
|
||||||
|
SpuRect hl_rect;
|
||||||
|
|
||||||
|
guint32 current_clut[16]; /* Colour lookup table from incoming events */
|
||||||
|
|
||||||
|
guint8 main_idx[4]; /* Indices for current main palette */
|
||||||
|
guint8 main_alpha[4]; /* Alpha values for main palette */
|
||||||
|
|
||||||
|
guint8 hl_idx[4]; /* Indices for current highlight palette */
|
||||||
|
guint8 hl_alpha[4]; /* Alpha values for highlight palette */
|
||||||
|
|
||||||
|
/* Pre-multiplied colour palette for the main palette */
|
||||||
|
SpuColour main_pal[4];
|
||||||
|
gboolean main_pal_dirty;
|
||||||
|
|
||||||
|
/* Line control info for rendering the highlight palette */
|
||||||
|
SpuLineCtrlI hl_ctrl_i;
|
||||||
|
gboolean hl_pal_dirty; /* Indicates that the HL palette info needs refreshing */
|
||||||
|
|
||||||
|
/* LineCtrlI Info from a Change Color & Contrast command */
|
||||||
|
SpuLineCtrlI *line_ctrl_i;
|
||||||
|
gint16 n_line_ctrl_i;
|
||||||
|
gboolean line_ctrl_i_pal_dirty; /* Indicates that the palettes for the line_ctrl_i
|
||||||
|
* need recalculating */
|
||||||
|
|
||||||
|
/* Rendering state vars below */
|
||||||
|
guint16 *comp_bufs[3]; /* Compositing buffers for U+V & A */
|
||||||
|
gint16 comp_last_x[2]; /* Maximum X values we rendered into the comp buffer (odd & even) */
|
||||||
|
gint16 *comp_last_x_ptr; /* Ptr to the current comp_last_x value to be updated by the render */
|
||||||
|
gint16 vid_width, vid_height;
|
||||||
|
gint16 Y_stride, UV_stride;
|
||||||
|
gint16 Y_height, UV_height;
|
||||||
|
|
||||||
|
gint fps_n, fps_d;
|
||||||
|
|
||||||
|
/* Current Y Position */
|
||||||
|
gint16 cur_Y;
|
||||||
|
|
||||||
|
/* Current offset in nibbles into the pix_data */
|
||||||
|
guint16 cur_offsets[2];
|
||||||
|
guint16 max_offset;
|
||||||
|
|
||||||
|
/* current ChgColCon Line Info */
|
||||||
|
SpuLineCtrlI *cur_chg_col;
|
||||||
|
SpuLineCtrlI *cur_chg_col_end;
|
||||||
|
|
||||||
|
/* Output position tracking */
|
||||||
|
guint8 *out_Y;
|
||||||
|
guint16 *out_U;
|
||||||
|
guint16 *out_V;
|
||||||
|
guint16 *out_A;
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Structure used to store the queue of pending SPU packets. The start_ts is
|
||||||
|
* stored in running time...
|
||||||
|
* Also used to carry in-band events so they remain serialised properly */
|
||||||
|
struct SpuPacket {
|
||||||
|
GstClockTime event_ts;
|
||||||
|
GstBuffer *buf;
|
||||||
|
GstEvent *event;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct GstDVDSpu
|
||||||
|
{
|
||||||
|
GstElement element;
|
||||||
|
|
||||||
|
GstPad *videosinkpad;
|
||||||
|
GstPad *subpic_sinkpad;
|
||||||
|
GstPad *srcpad;
|
||||||
|
|
||||||
|
/* Mutex to protect state we access from different chain funcs */
|
||||||
|
GMutex *spu_lock;
|
||||||
|
|
||||||
|
GstSegment video_seg;
|
||||||
|
GstSegment subp_seg;
|
||||||
|
|
||||||
|
SpuState spu_state;
|
||||||
|
|
||||||
|
/* GQueue of SpuBuf structures */
|
||||||
|
GQueue *pending_spus;
|
||||||
|
|
||||||
|
/* Accumulator for collecting partial SPU buffers until they're complete */
|
||||||
|
GstBuffer *partial_spu;
|
||||||
|
|
||||||
|
/* Store either a reference or a copy of the last video frame for duplication
|
||||||
|
* during still-frame conditions */
|
||||||
|
GstBuffer *ref_frame;
|
||||||
|
|
||||||
|
/* Buffer to push after handling a DVD event, if any */
|
||||||
|
GstBuffer *pending_frame;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct GstDVDSpuClass
|
||||||
|
{
|
||||||
|
GstElementClass parent_class;
|
||||||
|
};
|
||||||
|
|
||||||
|
GType gstdvdspu_get_type (void);
|
||||||
|
void gstdvdspu_render_spu (GstDVDSpu *dvdspu, GstBuffer *buf);
|
||||||
|
|
||||||
|
G_END_DECLS
|
||||||
|
|
||||||
|
#endif /* __GSTDVDSPU_H__ */
|
@ -1,12 +0,0 @@
|
|||||||
|
|
||||||
plugin_LTLIBRARIES = libgstmpeg2subt.la
|
|
||||||
|
|
||||||
libgstmpeg2subt_la_SOURCES = gstmpeg2subt.c
|
|
||||||
|
|
||||||
libgstmpeg2subt_la_CFLAGS = $(GST_CFLAGS)
|
|
||||||
libgstmpeg2subt_la_LIBADD =
|
|
||||||
libgstmpeg2subt_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS)
|
|
||||||
|
|
||||||
noinst_HEADERS = gstmpeg2subt.h
|
|
||||||
|
|
||||||
EXTRA_DIST = Notes.txt
|
|
File diff suppressed because it is too large
Load Diff
@ -1,114 +0,0 @@
|
|||||||
/* GStreamer
|
|
||||||
* Copyright (C) <1999> Erik Walthinsen <omega@cse.ogi.edu>
|
|
||||||
*
|
|
||||||
* 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_MPEG2SUBT_H__
|
|
||||||
#define __GST_MPEG2SUBT_H__
|
|
||||||
|
|
||||||
|
|
||||||
#include <gst/gst.h>
|
|
||||||
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif /* __cplusplus */
|
|
||||||
|
|
||||||
|
|
||||||
#define GST_TYPE_MPEG2SUBT \
|
|
||||||
(gst_mpeg2subt_get_type())
|
|
||||||
#define GST_MPEG2SUBT(obj) \
|
|
||||||
(G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_MPEG2SUBT,GstMpeg2Subt))
|
|
||||||
#define GST_MPEG2SUBT_CLASS(klass) \
|
|
||||||
(G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_MPEG2SUBT,GstMpeg2SubtClass))
|
|
||||||
#define GST_IS_MPEG2SUBT(obj) \
|
|
||||||
(G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_MPEG2SUBT))
|
|
||||||
#define GST_IS_MPEG2SUBT_CLASS(klass) \
|
|
||||||
(G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_MPEG2SUBT))
|
|
||||||
|
|
||||||
typedef struct _GstMpeg2Subt GstMpeg2Subt;
|
|
||||||
typedef struct _GstMpeg2SubtClass GstMpeg2SubtClass;
|
|
||||||
|
|
||||||
/* Hold premultimplied colour values */
|
|
||||||
typedef struct YUVA_val {
|
|
||||||
guint16 Y;
|
|
||||||
guint16 U;
|
|
||||||
guint16 V;
|
|
||||||
guint16 A;
|
|
||||||
} YUVA_val;
|
|
||||||
|
|
||||||
struct _GstMpeg2Subt {
|
|
||||||
GstElement element;
|
|
||||||
|
|
||||||
GstPad *videopad,*subtitlepad,*srcpad;
|
|
||||||
|
|
||||||
GstBuffer *partialbuf; /* Collect together subtitle buffers until we have a full control sequence */
|
|
||||||
GstBuffer *hold_frame; /* Hold back one frame of video */
|
|
||||||
GstBuffer *still_frame;
|
|
||||||
|
|
||||||
guint16 packet_size;
|
|
||||||
guint16 data_size;
|
|
||||||
|
|
||||||
gint offset[2];
|
|
||||||
|
|
||||||
YUVA_val palette_cache[4];
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Store 1 line width of U, V and A respectively.
|
|
||||||
* Y is composited direct onto the frame.
|
|
||||||
*/
|
|
||||||
guint16 *out_buffers[3];
|
|
||||||
guchar subtitle_index[4];
|
|
||||||
guchar menu_index[4];
|
|
||||||
guchar subtitle_alpha[4];
|
|
||||||
guchar menu_alpha[4];
|
|
||||||
|
|
||||||
guint32 current_clut[16];
|
|
||||||
|
|
||||||
gboolean have_title;
|
|
||||||
gboolean forced_display;
|
|
||||||
|
|
||||||
GstClockTime start_display_time;
|
|
||||||
GstClockTime end_display_time;
|
|
||||||
gint left, top,
|
|
||||||
right, bottom;
|
|
||||||
gint clip_left, clip_top,
|
|
||||||
clip_right, clip_bottom;
|
|
||||||
|
|
||||||
gint in_width, in_height;
|
|
||||||
gint current_button;
|
|
||||||
|
|
||||||
GstData *pending_video_buffer;
|
|
||||||
GstClockTime next_video_time;
|
|
||||||
GstData *pending_subtitle_buffer;
|
|
||||||
GstClockTime next_subtitle_time;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct _GstMpeg2SubtClass {
|
|
||||||
GstElementClass parent_class;
|
|
||||||
};
|
|
||||||
|
|
||||||
GType gst_mpeg2subt_get_type(void);
|
|
||||||
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif /* __cplusplus */
|
|
||||||
|
|
||||||
|
|
||||||
#endif /* __GST_MPEG2SUBT_H__ */
|
|
@ -1,148 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="Windows-1252"?>
|
|
||||||
<VisualStudioProject
|
|
||||||
ProjectType="Visual C++"
|
|
||||||
Version="7.10"
|
|
||||||
Name="mpeg2subt"
|
|
||||||
ProjectGUID="{979C216F-0ACF-4956-AE00-055A42D678BB}"
|
|
||||||
Keyword="Win32Proj">
|
|
||||||
<Platforms>
|
|
||||||
<Platform
|
|
||||||
Name="Win32"/>
|
|
||||||
</Platforms>
|
|
||||||
<Configurations>
|
|
||||||
<Configuration
|
|
||||||
Name="Debug|Win32"
|
|
||||||
OutputDirectory="../../win32/Debug"
|
|
||||||
IntermediateDirectory="../../win32/Debug"
|
|
||||||
ConfigurationType="2"
|
|
||||||
CharacterSet="2">
|
|
||||||
<Tool
|
|
||||||
Name="VCCLCompilerTool"
|
|
||||||
Optimization="0"
|
|
||||||
AdditionalIncludeDirectories="../../../gstreamer/win32;../../../gstreamer;../../../gstreamer/libs;../../../glib;../../../glib/glib;../../../glib/gmodule;"../../gst-libs";../../../popt/include;../../../libxml2/include/libxml2"
|
|
||||||
PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_USRDLL;mpeg2subt_EXPORTS;HAVE_CONFIG_H;_USE_MATH_DEFINES"
|
|
||||||
MinimalRebuild="TRUE"
|
|
||||||
BasicRuntimeChecks="3"
|
|
||||||
RuntimeLibrary="3"
|
|
||||||
UsePrecompiledHeader="0"
|
|
||||||
WarningLevel="3"
|
|
||||||
Detect64BitPortabilityProblems="TRUE"
|
|
||||||
DebugInformationFormat="4"/>
|
|
||||||
<Tool
|
|
||||||
Name="VCCustomBuildTool"/>
|
|
||||||
<Tool
|
|
||||||
Name="VCLinkerTool"
|
|
||||||
AdditionalDependencies="glib-2.0.lib gmodule-2.0.lib gthread-2.0.lib gobject-2.0.lib libgstreamer.lib gstbytestream.lib iconv.lib intl.lib"
|
|
||||||
OutputFile="$(OutDir)/gstmpeg2subt.dll"
|
|
||||||
LinkIncremental="2"
|
|
||||||
AdditionalLibraryDirectories="../../../gstreamer/win32/Debug;../../../glib/glib;../../../glib/gmodule;../../../glib/gthread;../../../glib/gobject;../../../gettext/lib;../../../libiconv/lib"
|
|
||||||
ModuleDefinitionFile=""
|
|
||||||
GenerateDebugInformation="TRUE"
|
|
||||||
ProgramDatabaseFile="$(OutDir)/mpeg2subt.pdb"
|
|
||||||
SubSystem="2"
|
|
||||||
OptimizeReferences="2"
|
|
||||||
ImportLibrary="$(OutDir)/gstmpeg2subt.lib"
|
|
||||||
TargetMachine="1"/>
|
|
||||||
<Tool
|
|
||||||
Name="VCMIDLTool"/>
|
|
||||||
<Tool
|
|
||||||
Name="VCPostBuildEventTool"
|
|
||||||
CommandLine="copy /Y $(TargetPath) c:\gstreamer\plugins"/>
|
|
||||||
<Tool
|
|
||||||
Name="VCPreBuildEventTool"/>
|
|
||||||
<Tool
|
|
||||||
Name="VCPreLinkEventTool"/>
|
|
||||||
<Tool
|
|
||||||
Name="VCResourceCompilerTool"/>
|
|
||||||
<Tool
|
|
||||||
Name="VCWebServiceProxyGeneratorTool"/>
|
|
||||||
<Tool
|
|
||||||
Name="VCXMLDataGeneratorTool"/>
|
|
||||||
<Tool
|
|
||||||
Name="VCWebDeploymentTool"/>
|
|
||||||
<Tool
|
|
||||||
Name="VCManagedWrapperGeneratorTool"/>
|
|
||||||
<Tool
|
|
||||||
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
|
|
||||||
</Configuration>
|
|
||||||
<Configuration
|
|
||||||
Name="Release|Win32"
|
|
||||||
OutputDirectory="../../win32/Release"
|
|
||||||
IntermediateDirectory="../../win32/Release"
|
|
||||||
ConfigurationType="2"
|
|
||||||
CharacterSet="2">
|
|
||||||
<Tool
|
|
||||||
Name="VCCLCompilerTool"
|
|
||||||
AdditionalIncludeDirectories="../../../gstreamer/win32;../../../gstreamer;../../../gstreamer/libs;../../../glib;../../../glib/glib;../../../glib/gmodule;"../../gst-libs";../../../popt/include;../../../libxml2/include/libxml2"
|
|
||||||
PreprocessorDefinitions="WIN32;NDEBUG;GST_DISABLE_GST_DEBUG;_WINDOWS;_USRDLL;mpeg2subt_EXPORTS;HAVE_CONFIG_H;_USE_MATH_DEFINES"
|
|
||||||
RuntimeLibrary="2"
|
|
||||||
UsePrecompiledHeader="0"
|
|
||||||
WarningLevel="3"
|
|
||||||
Detect64BitPortabilityProblems="TRUE"
|
|
||||||
DebugInformationFormat="3"/>
|
|
||||||
<Tool
|
|
||||||
Name="VCCustomBuildTool"/>
|
|
||||||
<Tool
|
|
||||||
Name="VCLinkerTool"
|
|
||||||
AdditionalDependencies="glib-2.0.lib gmodule-2.0.lib gthread-2.0.lib gobject-2.0.lib libgstreamer.lib gstbytestream.lib iconv.lib intl.lib"
|
|
||||||
OutputFile="$(OutDir)/gstmpeg2subt.dll"
|
|
||||||
LinkIncremental="1"
|
|
||||||
AdditionalLibraryDirectories="../../../gstreamer/win32/Release;../../../glib/glib;../../../glib/gmodule;../../../glib/gthread;../../../glib/gobject;../../../gettext/lib;../../../libiconv/lib"
|
|
||||||
ModuleDefinitionFile=""
|
|
||||||
GenerateDebugInformation="TRUE"
|
|
||||||
SubSystem="2"
|
|
||||||
OptimizeReferences="2"
|
|
||||||
EnableCOMDATFolding="2"
|
|
||||||
ImportLibrary="$(OutDir)/gstmpeg2subt.lib"
|
|
||||||
TargetMachine="1"/>
|
|
||||||
<Tool
|
|
||||||
Name="VCMIDLTool"/>
|
|
||||||
<Tool
|
|
||||||
Name="VCPostBuildEventTool"
|
|
||||||
CommandLine="copy /Y $(TargetPath) c:\gstreamer\plugins"/>
|
|
||||||
<Tool
|
|
||||||
Name="VCPreBuildEventTool"/>
|
|
||||||
<Tool
|
|
||||||
Name="VCPreLinkEventTool"/>
|
|
||||||
<Tool
|
|
||||||
Name="VCResourceCompilerTool"/>
|
|
||||||
<Tool
|
|
||||||
Name="VCWebServiceProxyGeneratorTool"/>
|
|
||||||
<Tool
|
|
||||||
Name="VCXMLDataGeneratorTool"/>
|
|
||||||
<Tool
|
|
||||||
Name="VCWebDeploymentTool"/>
|
|
||||||
<Tool
|
|
||||||
Name="VCManagedWrapperGeneratorTool"/>
|
|
||||||
<Tool
|
|
||||||
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
|
|
||||||
</Configuration>
|
|
||||||
</Configurations>
|
|
||||||
<References>
|
|
||||||
</References>
|
|
||||||
<Files>
|
|
||||||
<Filter
|
|
||||||
Name="Source Files"
|
|
||||||
Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx"
|
|
||||||
UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}">
|
|
||||||
<File
|
|
||||||
RelativePath=".\gstmpeg2subt.c">
|
|
||||||
</File>
|
|
||||||
</Filter>
|
|
||||||
<Filter
|
|
||||||
Name="Header Files"
|
|
||||||
Filter="h;hpp;hxx;hm;inl;inc;xsd"
|
|
||||||
UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}">
|
|
||||||
<File
|
|
||||||
RelativePath=".\gstmpeg2subt.h">
|
|
||||||
</File>
|
|
||||||
</Filter>
|
|
||||||
<Filter
|
|
||||||
Name="Resource Files"
|
|
||||||
Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx"
|
|
||||||
UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}">
|
|
||||||
</Filter>
|
|
||||||
</Files>
|
|
||||||
<Globals>
|
|
||||||
</Globals>
|
|
||||||
</VisualStudioProject>
|
|
Loading…
x
Reference in New Issue
Block a user