mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-27 12:11:13 +00:00
99 lines
3.2 KiB
C
99 lines
3.2 KiB
C
/* GStreamer DVD Sub-Picture Unit
|
|
* Copyright (C) 2007 Fluendo S.A. <info@fluendo.com>
|
|
* Copyright (C) 2009 Jan Schmidt <thaytan@noraisin.net>
|
|
*
|
|
* 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., 51 Franklin St, Fifth Floor,
|
|
* Boston, MA 02110-1301, 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
|
|
|
|
void
|
|
gstspu_clear_comp_buffers (SpuState * state)
|
|
{
|
|
/* The area to clear is the line inside the disp_rect, each entry 4 bytes,
|
|
* of the sub-sampled UV planes. */
|
|
gint16 left = state->comp_left / 2;
|
|
gint16 right = state->comp_right / 2;
|
|
gint16 uv_width = sizeof (guint32) * (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);
|
|
}
|
|
|
|
void
|
|
gstspu_blend_comp_buffers (SpuState * state, guint8 * planes[3])
|
|
{
|
|
gint16 uv_end;
|
|
gint16 left, x;
|
|
guint8 *out_U;
|
|
guint8 *out_V;
|
|
guint32 *in_U;
|
|
guint32 *in_V;
|
|
guint32 *in_A;
|
|
gint16 comp_last_x = state->comp_right;
|
|
|
|
if (comp_last_x < state->comp_left)
|
|
return; /* Didn't draw in the comp buffers, nothing to do... */
|
|
|
|
#if 0
|
|
GST_LOG ("Blending comp buffers from x=%d to x=%d",
|
|
state->comp_left, state->comp_right);
|
|
#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->comp_left / 2;
|
|
|
|
out_U += left * GST_VIDEO_INFO_COMP_PSTRIDE (&state->info, 1);
|
|
out_V += left * GST_VIDEO_INFO_COMP_PSTRIDE (&state->info, 2);
|
|
for (x = left; x < uv_end; x++) {
|
|
guint32 tmp;
|
|
/* Each entry in the compositing buffer is 4 summed pixels, so the
|
|
* inverse alpha is (4 * 0xff) - in_A[x] */
|
|
guint16 inv_A = (4 * 0xff) - in_A[x];
|
|
|
|
tmp = in_U[x] + inv_A * *out_U;
|
|
*out_U = (guint8) (tmp / (4 * 0xff));
|
|
|
|
tmp = in_V[x] + inv_A * *out_V;
|
|
*out_V = (guint8) (tmp / (4 * 0xff));
|
|
|
|
out_U += GST_VIDEO_INFO_COMP_PSTRIDE (&state->info, 1);
|
|
out_V += GST_VIDEO_INFO_COMP_PSTRIDE (&state->info, 2);
|
|
}
|
|
}
|