From patchwork Tue Jan 3 22:02:48 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Rob Clark X-Patchwork-Id: 6038 Return-Path: X-Original-To: patchwork@peony.canonical.com Delivered-To: patchwork@peony.canonical.com Received: from fiordland.canonical.com (fiordland.canonical.com [91.189.94.145]) by peony.canonical.com (Postfix) with ESMTP id 9A73323F7F for ; Tue, 3 Jan 2012 22:03:07 +0000 (UTC) Received: from mail-ey0-f180.google.com (mail-ey0-f180.google.com [209.85.215.180]) by fiordland.canonical.com (Postfix) with ESMTP id 8E91AA18058 for ; Tue, 3 Jan 2012 22:03:07 +0000 (UTC) Received: by mail-ey0-f180.google.com with SMTP id c11so16120253eaa.11 for ; Tue, 03 Jan 2012 14:03:07 -0800 (PST) Received: by 10.205.132.148 with SMTP id hu20mr9881409bkc.96.1325628185391; Tue, 03 Jan 2012 14:03:05 -0800 (PST) X-Forwarded-To: linaro-patchwork@canonical.com X-Forwarded-For: patch@linaro.org linaro-patchwork@canonical.com Delivered-To: patches@linaro.org Received: by 10.205.82.144 with SMTP id ac16cs352489bkc; Tue, 3 Jan 2012 14:03:05 -0800 (PST) Received: by 10.236.185.9 with SMTP id t9mr25823443yhm.50.1325628183305; Tue, 03 Jan 2012 14:03:03 -0800 (PST) Received: from mail-gy0-f178.google.com (mail-gy0-f178.google.com [209.85.160.178]) by mx.google.com with ESMTPS id e4si8118805anm.40.2012.01.03.14.03.02 (version=TLSv1/SSLv3 cipher=OTHER); Tue, 03 Jan 2012 14:03:03 -0800 (PST) Received-SPF: pass (google.com: domain of robdclark@gmail.com designates 209.85.160.178 as permitted sender) client-ip=209.85.160.178; Authentication-Results: mx.google.com; spf=pass (google.com: domain of robdclark@gmail.com designates 209.85.160.178 as permitted sender) smtp.mail=robdclark@gmail.com; dkim=pass (test mode) header.i=@gmail.com Received: by ghbg19 with SMTP id g19so4457119ghb.37 for ; Tue, 03 Jan 2012 14:03:02 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=gamma; h=sender:from:to:cc:subject:date:message-id:x-mailer:in-reply-to :references; bh=9HmpTxFai1fOclwpz/1CdDqIAAfiSj6LGvDtLK0EolQ=; b=W9W9XBilZRrMZVaExKWeynrCQlBwUGmXRxLQb/aH3YwsBE7N5yfFog7Ajm6Q/6duJA JvRh726dJs2Zo7+LFialyTbmXYfbWBNpD13ocR8ovsJGZwXsVzI57kG+Xa+FPy343DDW R5JBw8VlUbCj6KJsJGzbNiwWPvUzw+0oZnLHI= Received: by 10.236.136.72 with SMTP id v48mr27181957yhi.34.1325628182712; Tue, 03 Jan 2012 14:03:02 -0800 (PST) Received: from localhost (dragon.ti.com. [192.94.94.33]) by mx.google.com with ESMTPS id j21sm130000372ann.0.2012.01.03.14.03.01 (version=TLSv1/SSLv3 cipher=OTHER); Tue, 03 Jan 2012 14:03:02 -0800 (PST) Sender: Rob Clark From: Rob Clark To: patches@linaro.org Cc: Rob Clark Subject: [PATCH 06/19] dvdspu: some optimizations Date: Tue, 3 Jan 2012 16:02:48 -0600 Message-Id: <1325628171-4803-5-git-send-email-rob@ti.com> X-Mailer: git-send-email 1.7.5.4 In-Reply-To: <1325628171-4803-1-git-send-email-rob@ti.com> References: <1325628171-4803-1-git-send-email-rob@ti.com> Detect invisible pixels, and skip gstspu_vobsub_blend_comp_buffers() when there are only invisible pixels. This significantly reduces the CPU load in cases of DVDs which don't use the clip_rect to exclude processing for parts of the screen where the video is visible. --- See: https://bugzilla.gnome.org/show_bug.cgi?id=667221 gst/dvdspu/gstspu-common.h | 1 + gst/dvdspu/gstspu-pgs.c | 4 ++- gst/dvdspu/gstspu-vobsub-render.c | 42 ++++++++++++++++++++++-------------- 3 files changed, 30 insertions(+), 17 deletions(-) diff --git a/gst/dvdspu/gstspu-common.h b/gst/dvdspu/gstspu-common.h index 206e882..494dab0 100644 --- a/gst/dvdspu/gstspu-common.h +++ b/gst/dvdspu/gstspu-common.h @@ -45,6 +45,7 @@ struct SpuColour { guint16 U; guint16 V; guint8 A; + guint8 vis; /* is this color visible? */ }; void gstspu_clear_comp_buffers (SpuState * state); diff --git a/gst/dvdspu/gstspu-pgs.c b/gst/dvdspu/gstspu-pgs.c index abfa539..ce6156d 100644 --- a/gst/dvdspu/gstspu-pgs.c +++ b/gst/dvdspu/gstspu-pgs.c @@ -258,7 +258,7 @@ pgs_composition_object_render (PgsCompositionObject * obj, SpuState * state, } colour = &state->pgs.palette[pal_id]; - if (colour->A) { + if (colour->A && colour->vis) { guint32 inv_A = 0xff - colour->A; if (G_UNLIKELY (x + run_len > max_x)) run_len = (max_x - x); @@ -492,6 +492,8 @@ parse_set_palette (GstDVDSpu * dvdspu, guint8 type, guint8 * payload, state->pgs.palette[n].U = U * A; state->pgs.palette[n].V = V * A; state->pgs.palette[n].A = A; + state->pgs.palette[n].vis = state->pgs.palette[n].Y || + state->pgs.palette[n].U || state->pgs.palette[n].V; payload += PGS_PALETTE_ENTRY_SIZE; } diff --git a/gst/dvdspu/gstspu-vobsub-render.c b/gst/dvdspu/gstspu-vobsub-render.c index b945592..66abd9f 100644 --- a/gst/dvdspu/gstspu-vobsub-render.c +++ b/gst/dvdspu/gstspu-vobsub-render.c @@ -47,6 +47,7 @@ gstspu_vobsub_recalc_palette (GstDVDSpu * dvdspu, /* 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; + dest->vis = dest->Y || dest->V || dest->U; } } else { int y = 240; @@ -168,7 +169,7 @@ gstspu_vobsub_get_rle_code (SpuState * state, guint16 * rle_offset) return code; } -static inline void +static inline gboolean gstspu_vobsub_draw_rle_run (SpuState * state, gint16 x, gint16 end, SpuColour * colour) { @@ -177,7 +178,7 @@ gstspu_vobsub_draw_rle_run (SpuState * state, gint16 x, gint16 end, state->vobsub.cur_Y, x, end, colour->Y, colour->U, colour->V, colour->A); #endif - if (colour->A != 0) { + if ((colour->A != 0) && colour->vis) { guint32 inv_A = 0xff - colour->A; /* FIXME: This could be more efficient */ @@ -191,7 +192,10 @@ gstspu_vobsub_draw_rle_run (SpuState * state, gint16 x, gint16 end, } /* 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 @@ -204,16 +208,17 @@ rle_end_x (guint16 rle_code, gint16 x, gint16 end) return MIN (end, x + (rle_code >> 2)); } -static void gstspu_vobsub_render_line_with_chgcol (SpuState * state, +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 void +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 */ @@ -222,8 +227,7 @@ gstspu_vobsub_render_line (SpuState * state, guint8 * planes[3], /* 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) { - gstspu_vobsub_render_line_with_chgcol (state, planes, rle_offset); - return; + return gstspu_vobsub_render_line_with_chgcol (state, planes, rle_offset); } } } @@ -248,9 +252,11 @@ gstspu_vobsub_render_line (SpuState * state, guint8 * planes[3], 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) */ - gstspu_vobsub_draw_rle_run (state, x, next_draw_x, colour); + visible |= gstspu_vobsub_draw_rle_run (state, x, next_draw_x, colour); x = next_x; } + + return visible; } static gboolean @@ -280,7 +286,7 @@ gstspu_vobsub_update_chgcol (SpuState * state) return FALSE; } -static void +static gboolean gstspu_vobsub_render_line_with_chgcol (SpuState * state, guint8 * planes[3], guint16 * rle_offset) { @@ -292,6 +298,7 @@ gstspu_vobsub_render_line_with_chgcol (SpuState * state, guint8 * planes[3], SpuVobsubPixCtrlI *next_pix_ctrl; SpuVobsubPixCtrlI *end_pix_ctrl; SpuVobsubPixCtrlI dummy_pix_ctrl; + gboolean visible = FALSE; gint16 cur_reg_end; gint i; @@ -340,7 +347,7 @@ gstspu_vobsub_render_line_with_chgcol (SpuState * state, guint8 * planes[3], if (G_LIKELY (x < run_end)) { colour = &cur_pix_ctrl->pal_cache[rle_code & 3]; - gstspu_vobsub_draw_rle_run (state, x, run_draw_end, colour); + visible |= gstspu_vobsub_draw_rle_run (state, x, run_draw_end, colour); x = run_end; } @@ -356,6 +363,8 @@ gstspu_vobsub_render_line_with_chgcol (SpuState * state, guint8 * planes[3], } } } + + return visible; } static void @@ -510,7 +519,7 @@ gstspu_vobsub_render (GstDVDSpu * dvdspu, GstBuffer * buf) for (state->vobsub.cur_Y = y; state->vobsub.cur_Y <= last_y; state->vobsub.cur_Y++) { - gboolean clip; + gboolean clip, visible = FALSE; clip = (state->vobsub.cur_Y < state->vobsub.clip_rect.top || state->vobsub.cur_Y > state->vobsub.clip_rect.bottom); @@ -519,7 +528,7 @@ gstspu_vobsub_render (GstDVDSpu * dvdspu, GstBuffer * buf) 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[0]); + visible |= gstspu_vobsub_render_line (state, planes, &state->vobsub.cur_offsets[0]); if (!clip) { /* Advance the luminance output pointer */ planes[0] += state->Y_stride; @@ -528,9 +537,9 @@ gstspu_vobsub_render (GstDVDSpu * dvdspu, GstBuffer * buf) /* Render odd line */ state->vobsub.comp_last_x_ptr = state->vobsub.comp_last_x + 1; - gstspu_vobsub_render_line (state, planes, &state->vobsub.cur_offsets[1]); + visible |= gstspu_vobsub_render_line (state, planes, &state->vobsub.cur_offsets[1]); - if (!clip) { + if (visible && !clip) { /* Blend the accumulated UV compositing buffers onto the output */ gstspu_vobsub_blend_comp_buffers (state, planes); @@ -541,7 +550,7 @@ gstspu_vobsub_render (GstDVDSpu * dvdspu, GstBuffer * buf) } } if (state->vobsub.cur_Y == state->vobsub.disp_rect.bottom) { - gboolean clip; + gboolean clip, visible = FALSE; clip = (state->vobsub.cur_Y < state->vobsub.clip_rect.top || state->vobsub.cur_Y > state->vobsub.clip_rect.bottom); @@ -553,8 +562,9 @@ gstspu_vobsub_render (GstDVDSpu * dvdspu, GstBuffer * buf) * after the above loop exited. */ gstspu_vobsub_clear_comp_buffers (state); state->vobsub.comp_last_x_ptr = state->vobsub.comp_last_x; - gstspu_vobsub_render_line (state, planes, &state->vobsub.cur_offsets[0]); - gstspu_vobsub_blend_comp_buffers (state, planes); + visible |= gstspu_vobsub_render_line (state, planes, &state->vobsub.cur_offsets[0]); + if (visible) + gstspu_vobsub_blend_comp_buffers (state, planes); } }