@@ -85,10 +85,13 @@ gstspu_blend_comp_buffers (SpuState * state, guint8 * planes[3])
* inverse alpha is (4 * 0xff) - in_A[x] */
guint16 inv_A = (4 * 0xff) - in_A[x];
- tmp = in_U[x] + inv_A * out_U[x];
- out_U[x] = (guint8) (tmp / (4 * 0xff));
+ tmp = in_U[x] + inv_A * *out_U;
+ *out_U = (guint8) (tmp / (4 * 0xff));
- tmp = in_V[x] + inv_A * out_V[x];
- out_V[x] = (guint8) (tmp / (4 * 0xff));
+ tmp = in_V[x] + inv_A * *out_V;
+ *out_V = (guint8) (tmp / (4 * 0xff));
+
+ out_U += state->UV_pixstride;
+ out_V += state->UV_pixstride;
}
}
@@ -55,7 +55,7 @@ static GstStaticPadTemplate video_sink_factory =
GST_STATIC_PAD_TEMPLATE ("video",
GST_PAD_SINK,
GST_PAD_ALWAYS,
- GST_STATIC_CAPS ("video/x-raw-yuv, " "format = (fourcc) { I420 }, "
+ GST_STATIC_CAPS ("video/x-raw-yuv, " "format = (fourcc) { I420, NV12 }, "
"width = (int) [ 16, 4096 ], " "height = (int) [ 16, 4096 ]")
/* FIXME: Can support YV12 one day too */
);
@@ -63,7 +63,7 @@ GST_STATIC_PAD_TEMPLATE ("video",
static GstStaticPadTemplate src_factory = GST_STATIC_PAD_TEMPLATE ("src",
GST_PAD_SRC,
GST_PAD_ALWAYS,
- GST_STATIC_CAPS ("video/x-raw-yuv, " "format = (fourcc) { I420 }, "
+ GST_STATIC_CAPS ("video/x-raw-yuv, " "format = (fourcc) { I420, NV12 }, "
"width = (int) [ 16, 4096 ], " "height = (int) [ 16, 4096 ]")
/* FIXME: Can support YV12 one day too */
);
@@ -320,13 +320,15 @@ gst_dvd_spu_video_set_caps (GstPad * pad, GstCaps * caps)
gint w, h;
gint i;
gint fps_n, fps_d;
+ guint32 format;
SpuState *state;
s = gst_caps_get_structure (caps, 0);
if (!gst_structure_get_int (s, "width", &w) ||
!gst_structure_get_int (s, "height", &h) ||
- !gst_structure_get_fraction (s, "framerate", &fps_n, &fps_d)) {
+ !gst_structure_get_fraction (s, "framerate", &fps_n, &fps_d) ||
+ !gst_structure_get_fourcc (s, "format", &format)) {
goto done;
}
@@ -341,14 +343,24 @@ gst_dvd_spu_video_set_caps (GstPad * pad, GstCaps * caps)
state->Y_height = GST_ROUND_UP_2 (h);
state->UV_height = state->Y_height / 2;
- if (state->vid_width != w) {
- state->vid_width = w;
- state->Y_stride = GST_ROUND_UP_4 (w);
+ state->vid_width = w;
+ state->Y_stride = GST_ROUND_UP_4 (w);
+
+ state->U_offset = state->Y_height * state->Y_stride;
+
+ if (format == GST_STR_FOURCC("NV12")) {
+ state->UV_stride = GST_ROUND_UP_4 (state->Y_stride);
+ state->V_offset = 1;
+ state->UV_pixstride = 2;
+ } else {
state->UV_stride = GST_ROUND_UP_4 (state->Y_stride / 2);
- for (i = 0; i < 3; i++) {
- state->comp_bufs[i] = g_realloc (state->comp_bufs[i],
- sizeof (guint32) * state->UV_stride);
- }
+ state->V_offset = state->UV_stride * state->UV_height;
+ state->UV_pixstride = 1;
+ }
+
+ for (i = 0; i < 3; i++) {
+ state->comp_bufs[i] = g_realloc (state->comp_bufs[i],
+ sizeof (guint32) * state->UV_stride);
}
DVD_SPU_UNLOCK (dvdspu);
@@ -73,6 +73,8 @@ struct SpuState {
gint16 vid_width, vid_height;
gint16 Y_stride, UV_stride;
gint16 Y_height, UV_height;
+ gint32 U_offset, V_offset;
+ gint8 UV_pixstride;
guint32 *comp_bufs[3]; /* Compositing buffers for U+V & A */
guint16 comp_left;
@@ -194,12 +194,8 @@ pgs_composition_object_render (PgsCompositionObject * obj, SpuState * state,
/* Store the start of each plane */
planes[0] = GST_BUFFER_DATA (dest_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 (dest_buf) + GST_BUFFER_SIZE (dest_buf));
+ planes[1] = planes[0] + state->U_offset;
+ planes[2] = planes[1] + state->V_offset;
y = MIN (obj->y, state->Y_height);
@@ -396,12 +396,8 @@ gstspu_vobsub_render (GstDVDSpu * dvdspu, GstBuffer * buf)
/* 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));
+ planes[1] = planes[0] + state->U_offset;
+ planes[2] = planes[1] + state->V_offset;
GST_DEBUG_OBJECT (dvdspu,
"Rendering SPU. disp_rect %d,%d to %d,%d. hl_rect %d,%d to %d,%d",