/* 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

static void
gstspu_vobsub_recalc_palette (GstDVDSpu * dvdspu,
    SpuColour * dest, guint8 * idx, guint8 * alpha)
{
  SpuState *state = &dvdspu->spu_state;
  gint i;

  if (state->vobsub.current_clut[idx[0]] != 0) {
    for (i = 0; i < 4; i++, dest++) {
      guint32 col = state->vobsub.current_clut[idx[i]];

      /* Convert incoming 4-bit alpha to 8 bit for blending */
      dest->A = (alpha[i] << 4) | alpha[i];
      dest->Y = ((guint16) ((col >> 16) & 0xff)) * dest->A;
      /* U/V are stored as V/U in the clut words, so switch them */
      dest->V = ((guint16) ((col >> 8) & 0xff)) * dest->A;
      dest->U = ((guint16) (col & 0xff)) * dest->A;
    }
  } else {
    int y = 240;

    /* The CLUT presumably hasn't been set, so we'll just guess some
     * values for the non-transparent colors (white, grey, black) */
    for (i = 0; i < 4; i++, dest++) {
      dest->A = (alpha[i] << 4) | alpha[i];
      if (alpha[i] != 0) {
        dest[0].Y = y * dest[0].A;
        y -= 112;
        if (y < 0)
          y = 0;
      }
      dest[0].U = 128 * dest[0].A;
      dest[0].V = 128 * dest[0].A;
    }
  }
}

/* Recalculate the main, HL & ChgCol palettes */
static void
gstspu_vobsub_update_palettes (GstDVDSpu * dvdspu, SpuState * state)
{
  guint8 index[4];              /* Indices for the palette */
  guint8 alpha[4];              /* Alpha values the palette */

  if (state->vobsub.main_pal_dirty) {
    gstspu_vobsub_recalc_palette (dvdspu, state->vobsub.main_pal,
        state->vobsub.main_idx, state->vobsub.main_alpha);

    /* Need to refresh the hl_ctrl info copies of the main palette too */
    memcpy (state->vobsub.hl_ctrl_i.pix_ctrl_i[0].pal_cache,
        state->vobsub.main_pal, 4 * sizeof (SpuColour));
    memcpy (state->vobsub.hl_ctrl_i.pix_ctrl_i[2].pal_cache,
        state->vobsub.main_pal, 4 * sizeof (SpuColour));

    state->vobsub.main_pal_dirty = FALSE;
  }

  if (state->vobsub.hl_pal_dirty) {
    gstspu_vobsub_recalc_palette (dvdspu,
        state->vobsub.hl_ctrl_i.pix_ctrl_i[1].pal_cache, state->vobsub.hl_idx,
        state->vobsub.hl_alpha);
    state->vobsub.hl_pal_dirty = FALSE;
  }

  /* Update the offset positions for the highlight region */
  if (state->vobsub.hl_rect.top != -1) {
    state->vobsub.hl_ctrl_i.top = state->vobsub.hl_rect.top;
    state->vobsub.hl_ctrl_i.bottom = state->vobsub.hl_rect.bottom;
    state->vobsub.hl_ctrl_i.n_changes = 3;
    state->vobsub.hl_ctrl_i.pix_ctrl_i[0].left = 0;
    state->vobsub.hl_ctrl_i.pix_ctrl_i[1].left = state->vobsub.hl_rect.left;
    state->vobsub.hl_ctrl_i.pix_ctrl_i[2].left =
        state->vobsub.hl_rect.right + 1;
  }

  if (state->vobsub.line_ctrl_i_pal_dirty) {
    gint16 l, c;
    GST_LOG_OBJECT (dvdspu, "Updating chg-col-con palettes");
    for (l = 0; l < state->vobsub.n_line_ctrl_i; l++) {
      SpuVobsubLineCtrlI *cur_line_ctrl = state->vobsub.line_ctrl_i + l;

      for (c = 0; c < cur_line_ctrl->n_changes; c++) {
        SpuVobsubPixCtrlI *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;
        gstspu_vobsub_recalc_palette (dvdspu, cur->pal_cache, index, alpha);
      }
    }
    state->vobsub.line_ctrl_i_pal_dirty = FALSE;
  }
}

static inline guint8
gstspu_vobsub_get_nibble (SpuState * state, guint16 * rle_offset)
{
  guint8 ret;

  if (G_UNLIKELY (*rle_offset >= state->vobsub.max_offset))
    return 0;                   /* Overran the buffer */

  ret = state->vobsub.pix_buf_map.data[(*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
gstspu_vobsub_get_rle_code (SpuState * state, guint16 * rle_offset)
{
  guint16 code;

  code = gstspu_vobsub_get_nibble (state, rle_offset);
  if (code < 0x4) {             /* 4 .. f */
    code = (code << 4) | gstspu_vobsub_get_nibble (state, rle_offset);
    if (code < 0x10) {          /* 1x .. 3x */
      code = (code << 4) | gstspu_vobsub_get_nibble (state, rle_offset);
      if (code < 0x40) {        /* 04x .. 0fx */
        code = (code << 4) | gstspu_vobsub_get_nibble (state, rle_offset);
      }
    }
  }
  return code;
}

static inline gboolean
gstspu_vobsub_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->vobsub.cur_Y, x, end, colour->Y, colour->U, colour->V, colour->A);
#endif

  if (colour->A != 0) {
    guint32 inv_A = 0xff - colour->A;

    /* FIXME: This could be more efficient */
    while (x < end) {
      state->vobsub.out_Y[x] =
          (inv_A * state->vobsub.out_Y[x] + colour->Y) / 0xff;
      state->vobsub.out_U[x / 2] += colour->U;
      state->vobsub.out_V[x / 2] += colour->V;
      state->vobsub.out_A[x / 2] += colour->A;
      x++;
    }
    /* Update the compositing buffer so we know how much to blend later */
    *(state->vobsub.comp_last_x_ptr) = end - 1; /* end is the start of the *next* run */

    return TRUE;
  }
  return FALSE;
}

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 gboolean gstspu_vobsub_render_line_with_chgcol (SpuState * state,
    guint8 * planes[3], guint16 * rle_offset);
static gboolean gstspu_vobsub_update_chgcol (SpuState * state);

static gboolean
gstspu_vobsub_render_line (SpuState * state, guint8 * planes[3],
    guint16 * rle_offset)
{
  gint16 x, next_x, end, rle_code, next_draw_x;
  SpuColour *colour;
  gboolean visible = FALSE;

  /* Check for special case of chg_col info to use (either highlight or
   * ChgCol command */
  if (state->vobsub.cur_chg_col != NULL) {
    if (gstspu_vobsub_update_chgcol (state)) {
      /* Check the top & bottom, because we might not be within the region yet */
      if (state->vobsub.cur_Y >= state->vobsub.cur_chg_col->top &&
          state->vobsub.cur_Y <= state->vobsub.cur_chg_col->bottom) {
        return gstspu_vobsub_render_line_with_chgcol (state, planes,
            rle_offset);
      }
    }
  }

  /* No special case. Render as normal */

  /* Set up our output pointers */
  state->vobsub.out_Y = planes[0];
  state->vobsub.out_U = state->comp_bufs[0];
  state->vobsub.out_V = state->comp_bufs[1];
  state->vobsub.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->vobsub.disp_rect.left;
  end = state->vobsub.disp_rect.right + 1;
  while (x < end) {
    rle_code = gstspu_vobsub_get_rle_code (state, rle_offset);
    colour = &state->vobsub.main_pal[rle_code & 3];
    next_x = rle_end_x (rle_code, x, end);
    next_draw_x = next_x;
    if (next_draw_x > state->vobsub.clip_rect.right)
      next_draw_x = state->vobsub.clip_rect.right;      /* ensure no overflow */
    /* Now draw the run between [x,next_x) */
    if (state->vobsub.cur_Y >= state->vobsub.clip_rect.top &&
        state->vobsub.cur_Y <= state->vobsub.clip_rect.bottom)
      visible |= gstspu_vobsub_draw_rle_run (state, x, next_draw_x, colour);
    x = next_x;
  }

  return visible;
}

static gboolean
gstspu_vobsub_update_chgcol (SpuState * state)
{
  if (state->vobsub.cur_chg_col == NULL)
    return FALSE;

  if (state->vobsub.cur_Y <= state->vobsub.cur_chg_col->bottom)
    return TRUE;

  while (state->vobsub.cur_chg_col < state->vobsub.cur_chg_col_end) {
    if (state->vobsub.cur_Y >= state->vobsub.cur_chg_col->top &&
        state->vobsub.cur_Y <= state->vobsub.cur_chg_col->bottom) {
#if 0
      g_print ("Stopped @ entry %d with top %d bottom %d, cur_y %d",
          (gint16) (state->vobsub.cur_chg_col - state->vobsub.line_ctrl_i),
          state->vobsub.cur_chg_col->top, state->vobsub.cur_chg_col->bottom, y);
#endif
      return TRUE;
    }
    state->vobsub.cur_chg_col++;
  }

  /* Finished all our cur_chg_col entries. Use the main palette from here on */
  state->vobsub.cur_chg_col = NULL;
  return FALSE;
}

static gboolean
gstspu_vobsub_render_line_with_chgcol (SpuState * state, guint8 * planes[3],
    guint16 * rle_offset)
{
  SpuVobsubLineCtrlI *chg_col = state->vobsub.cur_chg_col;

  gint16 x, next_x, disp_end, rle_code, run_end, run_draw_end;
  SpuColour *colour;
  SpuVobsubPixCtrlI *cur_pix_ctrl;
  SpuVobsubPixCtrlI *next_pix_ctrl;
  SpuVobsubPixCtrlI *end_pix_ctrl;
  SpuVobsubPixCtrlI dummy_pix_ctrl;
  gboolean visible = FALSE;
  gint16 cur_reg_end;
  gint i;

  state->vobsub.out_Y = planes[0];
  state->vobsub.out_U = state->comp_bufs[0];
  state->vobsub.out_V = state->comp_bufs[1];
  state->vobsub.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->vobsub.disp_rect.left;
  disp_end = state->vobsub.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->vobsub.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 = gstspu_vobsub_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);

      run_draw_end = run_end;
      if (run_draw_end > state->vobsub.clip_rect.right)
        run_draw_end = state->vobsub.clip_rect.right;   /* ensure no overflow */

      if (G_LIKELY (x < run_end)) {
        colour = &cur_pix_ctrl->pal_cache[rle_code & 3];
        visible |= gstspu_vobsub_draw_rle_run (state, x, run_draw_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;
      }
    }
  }

  return visible;
}

static void
gstspu_vobsub_blend_comp_buffers (SpuState * state, guint8 * planes[3])
{
  state->comp_left = state->vobsub.disp_rect.left;
  state->comp_right =
      MAX (state->vobsub.comp_last_x[0], state->vobsub.comp_last_x[1]);

  state->comp_left = MAX (state->comp_left, state->vobsub.clip_rect.left);
  state->comp_right = MIN (state->comp_right, state->vobsub.clip_rect.right);

  gstspu_blend_comp_buffers (state, planes);
}

static void
gstspu_vobsub_clear_comp_buffers (SpuState * state)
{
  state->comp_left = state->vobsub.clip_rect.left;
  state->comp_right = state->vobsub.clip_rect.right;

  gstspu_clear_comp_buffers (state);

  state->vobsub.comp_last_x[0] = -1;
  state->vobsub.comp_last_x[1] = -1;
}

static void
gstspu_vobsub_draw_highlight (SpuState * state,
    GstVideoFrame * frame, SpuRect * rect)
{
  guint8 *cur;
  gint16 pos;
  gint ystride;

  ystride = GST_VIDEO_FRAME_COMP_STRIDE (frame, 0);

  cur = GST_VIDEO_FRAME_COMP_DATA (frame, 0) + ystride * rect->top;
  for (pos = rect->left + 1; pos < rect->right; pos++)
    cur[pos] = (cur[pos] / 2) + 0x8;
  cur = GST_VIDEO_FRAME_COMP_DATA (frame, 0) + ystride * rect->bottom;
  for (pos = rect->left + 1; pos < rect->right; pos++)
    cur[pos] = (cur[pos] / 2) + 0x8;
  cur = GST_VIDEO_FRAME_COMP_DATA (frame, 0) + ystride * rect->top;
  for (pos = rect->top; pos <= rect->bottom; pos++) {
    cur[rect->left] = (cur[rect->left] / 2) + 0x8;
    cur[rect->right] = (cur[rect->right] / 2) + 0x8;
    cur += ystride;
  }
}

void
gstspu_vobsub_render (GstDVDSpu * dvdspu, GstVideoFrame * frame)
{
  SpuState *state = &dvdspu->spu_state;
  guint8 *planes[3];            /* YUV frame pointers */
  gint y, last_y;
  gint width, height;
  gint strides[3];
  gint offset_index = 0;

  /* Set up our initial state */
  if (G_UNLIKELY (state->vobsub.pix_buf == NULL))
    return;

  if (!gst_buffer_map (state->vobsub.pix_buf, &state->vobsub.pix_buf_map,
          GST_MAP_READ))
    return;

  /* Store the start of each plane */
  planes[0] = GST_VIDEO_FRAME_COMP_DATA (frame, 0);
  planes[1] = GST_VIDEO_FRAME_COMP_DATA (frame, 1);
  planes[2] = GST_VIDEO_FRAME_COMP_DATA (frame, 2);

  strides[0] = GST_VIDEO_FRAME_COMP_STRIDE (frame, 0);
  strides[1] = GST_VIDEO_FRAME_COMP_STRIDE (frame, 1);
  strides[2] = GST_VIDEO_FRAME_COMP_STRIDE (frame, 2);

  width = GST_VIDEO_FRAME_WIDTH (frame);
  height = GST_VIDEO_FRAME_HEIGHT (frame);

  GST_DEBUG_OBJECT (dvdspu,
      "Rendering SPU. disp_rect %d,%d to %d,%d. hl_rect %d,%d to %d,%d",
      state->vobsub.disp_rect.left, state->vobsub.disp_rect.top,
      state->vobsub.disp_rect.right, state->vobsub.disp_rect.bottom,
      state->vobsub.hl_rect.left, state->vobsub.hl_rect.top,
      state->vobsub.hl_rect.right, state->vobsub.hl_rect.bottom);

  GST_DEBUG_OBJECT (dvdspu, "video size %d,%d", width, height);

  /* When reading RLE data, we track the offset in nibbles... */
  state->vobsub.cur_offsets[0] = state->vobsub.pix_data[0] * 2;
  state->vobsub.cur_offsets[1] = state->vobsub.pix_data[1] * 2;
  state->vobsub.max_offset = state->vobsub.pix_buf_map.size * 2;

  /* Update all the palette caches */
  gstspu_vobsub_update_palettes (dvdspu, state);

  /* Set up HL or Change Color & Contrast rect tracking */
  if (state->vobsub.hl_rect.top != -1) {
    state->vobsub.cur_chg_col = &state->vobsub.hl_ctrl_i;
    state->vobsub.cur_chg_col_end = state->vobsub.cur_chg_col + 1;
  } else if (state->vobsub.n_line_ctrl_i > 0) {
    state->vobsub.cur_chg_col = state->vobsub.line_ctrl_i;
    state->vobsub.cur_chg_col_end =
        state->vobsub.cur_chg_col + state->vobsub.n_line_ctrl_i;
  } else
    state->vobsub.cur_chg_col = NULL;

  state->vobsub.clip_rect.left = state->vobsub.disp_rect.left;
  state->vobsub.clip_rect.right = state->vobsub.disp_rect.right;

  /* center the image when display rectangle exceeds the video width */
  if (width <= state->vobsub.disp_rect.right) {
    gint left, disp_width;

    disp_width = state->vobsub.disp_rect.right - state->vobsub.disp_rect.left
        + 1;
    left = (width - disp_width) / 2;
    state->vobsub.disp_rect.left = left;
    state->vobsub.disp_rect.right = left + disp_width - 1;

    /* if it clips to the right, shift it left, but only till zero */
    if (state->vobsub.disp_rect.right >= width) {
      gint shift = state->vobsub.disp_rect.right - width - 1;
      if (shift > state->vobsub.disp_rect.left)
        shift = state->vobsub.disp_rect.left;
      state->vobsub.disp_rect.left -= shift;
      state->vobsub.disp_rect.right -= shift;
    }

    /* init clip to disp */
    state->vobsub.clip_rect.left = state->vobsub.disp_rect.left;
    state->vobsub.clip_rect.right = state->vobsub.disp_rect.right;

    /* clip right after the shift */
    if (state->vobsub.clip_rect.right >= width)
      state->vobsub.clip_rect.right = width - 1;

    GST_DEBUG_OBJECT (dvdspu,
        "clipping width to %d,%d", state->vobsub.clip_rect.left,
        state->vobsub.clip_rect.right);
  }

  /* for the height, bring it up till it fits as well as it can. We
   * assume the picture is in the lower part. We should better check where it
   * is and do something more clever. */
  state->vobsub.clip_rect.top = state->vobsub.disp_rect.top;
  state->vobsub.clip_rect.bottom = state->vobsub.disp_rect.bottom;
  if (height <= state->vobsub.disp_rect.bottom) {

    /* shift it up, but only till zero */
    gint shift = state->vobsub.disp_rect.bottom - height - 1;
    if (shift > state->vobsub.disp_rect.top)
      shift = state->vobsub.disp_rect.top;
    state->vobsub.disp_rect.top -= shift;
    state->vobsub.disp_rect.bottom -= shift;

    /* start on even line */
    if (state->vobsub.disp_rect.top & 1) {
      state->vobsub.disp_rect.top--;
      state->vobsub.disp_rect.bottom--;
    }

    /* init clip to disp */
    state->vobsub.clip_rect.top = state->vobsub.disp_rect.top;
    state->vobsub.clip_rect.bottom = state->vobsub.disp_rect.bottom;

    /* clip bottom after the shift */
    if (state->vobsub.clip_rect.bottom >= height)
      state->vobsub.clip_rect.bottom = height - 1;

    GST_DEBUG_OBJECT (dvdspu,
        "clipping height to %d,%d", state->vobsub.clip_rect.top,
        state->vobsub.clip_rect.bottom);
  }

  /* We start rendering from the first line of the display rect */
  y = state->vobsub.disp_rect.top;
  /* We render most lines in pairs starting from an even y,
   * accumulating 2 lines of chroma then blending it. We might need to render a
   * single line at the start and end if the display rect starts on an odd line
   * or ends on an even one */
  if (y > state->vobsub.disp_rect.bottom)
    return;                     /* Empty clip rect, nothing to do */

  /* Update our plane references to the first line of the disp_rect */
  planes[0] += strides[0] * y;
  planes[1] += strides[1] * (y / 2);
  planes[2] += strides[2] * (y / 2);

  /* If the render rect starts on an odd line, render that only to start */
  state->vobsub.cur_Y = y;
  if (state->vobsub.cur_Y & 0x1) {
    gboolean clip, visible = FALSE;

    clip = (state->vobsub.cur_Y < state->vobsub.clip_rect.top
        || state->vobsub.cur_Y > state->vobsub.clip_rect.bottom);

    if (!clip) {
      /* Render a first odd line. */
      gstspu_vobsub_clear_comp_buffers (state);
      state->vobsub.comp_last_x_ptr = state->vobsub.comp_last_x + 1;
      visible |=
          gstspu_vobsub_render_line (state, planes,
          &state->vobsub.cur_offsets[offset_index]);
      if (visible)
        gstspu_vobsub_blend_comp_buffers (state, planes);
    }

    /* Update all the output pointers */
    state->vobsub.cur_Y++;
    planes[0] += strides[0];
    planes[1] += strides[1];
    planes[2] += strides[2];
    /* Switch the offset index 0 <=> 1 */
    offset_index ^= 0x1;
  }

  last_y = (state->vobsub.disp_rect.bottom - 1) & ~(0x01);
  for (; state->vobsub.cur_Y <= last_y; state->vobsub.cur_Y++) {
    gboolean clip, visible = FALSE;

    clip = (state->vobsub.cur_Y < state->vobsub.clip_rect.top
        || state->vobsub.cur_Y > state->vobsub.clip_rect.bottom);

    /* Reset the compositing buffer */
    gstspu_vobsub_clear_comp_buffers (state);
    /* Render even line */
    state->vobsub.comp_last_x_ptr = state->vobsub.comp_last_x;
    gstspu_vobsub_render_line (state, planes,
        &state->vobsub.cur_offsets[offset_index]);

    /* Advance the luminance output pointer */
    planes[0] += strides[0];
    /* Switch the offset index 0 <=> 1 */
    offset_index ^= 0x1;

    state->vobsub.cur_Y++;

    /* Render odd line */
    state->vobsub.comp_last_x_ptr = state->vobsub.comp_last_x + 1;
    visible |=
        gstspu_vobsub_render_line (state, planes,
        &state->vobsub.cur_offsets[offset_index]);

    if (visible && !clip) {
      /* Blend the accumulated UV compositing buffers onto the output */
      gstspu_vobsub_blend_comp_buffers (state, planes);
    }

    /* Update all the output pointers */
    planes[0] += strides[0];
    planes[1] += strides[1];
    planes[2] += strides[2];
    /* Switch the offset index 0 <=> 1 */
    offset_index ^= 0x1;
  }

  if (state->vobsub.cur_Y == state->vobsub.disp_rect.bottom) {
    gboolean clip, visible = FALSE;

    clip = (state->vobsub.cur_Y < state->vobsub.clip_rect.top
        || state->vobsub.cur_Y > state->vobsub.clip_rect.bottom);

    g_return_if_fail ((state->vobsub.disp_rect.bottom & 0x01) == 0);

    if (!clip) {
      /* Render a remaining lone last even line. y already has the correct value
       * after the above loop exited. */
      gstspu_vobsub_clear_comp_buffers (state);
      state->vobsub.comp_last_x_ptr = state->vobsub.comp_last_x;
      visible |=
          gstspu_vobsub_render_line (state, planes,
          &state->vobsub.cur_offsets[offset_index]);
      if (visible)
        gstspu_vobsub_blend_comp_buffers (state, planes);
    }
  }

  /* for debugging purposes, draw a faint rectangle at the edges of the disp_rect */
  if ((dvdspu_debug_flags & GST_DVD_SPU_DEBUG_RENDER_RECTANGLE) != 0) {
    gstspu_vobsub_draw_highlight (state, frame, &state->vobsub.disp_rect);
  }
  /* For debugging purposes, draw a faint rectangle around the highlight rect */
  if ((dvdspu_debug_flags & GST_DVD_SPU_DEBUG_HIGHLIGHT_RECTANGLE) != 0
      && state->vobsub.hl_rect.top != -1) {
    gstspu_vobsub_draw_highlight (state, frame, &state->vobsub.hl_rect);
  }

  gst_buffer_unmap (state->vobsub.pix_buf, &state->vobsub.pix_buf_map);
}
