[libbluray-devel] Optimized copying to application-allocated frame buffer.
hpi1
git at videolan.org
Tue May 7 14:07:51 CEST 2013
libbluray | branch: master | hpi1 <hpi1 at anonymous.org> | Tue May 7 13:41:47 2013 +0300| [4b1e1230b890be46094acfd6673cf47960a86491] | committer: hpi1
Optimized copying to application-allocated frame buffer.
(copy only changed region)
> http://git.videolan.org/gitweb.cgi/libbluray.git/?a=commit;h=4b1e1230b890be46094acfd6673cf47960a86491
---
src/libbluray/bdj/native/org_videolan_Libbluray.c | 43 +++++++++++++++++++--
1 file changed, 39 insertions(+), 4 deletions(-)
diff --git a/src/libbluray/bdj/native/org_videolan_Libbluray.c b/src/libbluray/bdj/native/org_videolan_Libbluray.c
index 12575ce..3b8abc4 100644
--- a/src/libbluray/bdj/native/org_videolan_Libbluray.c
+++ b/src/libbluray/bdj/native/org_videolan_Libbluray.c
@@ -424,18 +424,27 @@ JNIEXPORT void JNICALL Java_org_videolan_Libbluray_updateGraphicN(JNIEnv * env,
BDJAVA* bdj = (BDJAVA*)(intptr_t)np;
- BD_DEBUG(DBG_JNI, "updateGraphicN()\n");
+ BD_DEBUG(DBG_JNI, "updateGraphicN(%d,%d-%d,%d)\n", x0, y0, x1, y1);
+ /* app callback not initialized ? */
if (!bdj || !bdj->osd_cb) {
return;
}
+ /* close ? */
if (!rgbArray) {
bdj->osd_cb(bdj->bd, NULL, (int)width, (int)height, 0, 0, 0, 0);
return;
}
+ /* nothing to draw ? */
+ if (x1 < x0 || y1 < y0 || (x1 | y1) < 0) {
+ return;
+ }
+
if (bdj->buf && bdj->buf->buf[BD_OVERLAY_IG]) {
+ jint y, *dst;
+ jsize offset;
/* copy to application-allocated buffer */
@@ -443,20 +452,46 @@ JNIEXPORT void JNICALL Java_org_videolan_Libbluray_updateGraphicN(JNIEnv * env,
bdj->buf->lock(bdj->buf);
}
+ /* check buffer size */
if (bdj->buf->width != width || bdj->buf->height != height) {
BD_DEBUG(DBG_BDJ | DBG_CRIT, "Incorrect ARGB frame buffer size (is: %dx%d expect: %dx%d)\n",
bdj->buf->width, bdj->buf->height, width, height);
}
- jsize len = bdj->buf->width * bdj->buf->height;
- (*env)->GetIntArrayRegion(env, rgbArray, 0, len, (jint*)bdj->buf->buf[BD_OVERLAY_IG]);
+ /* clip */
+ if (y1 >= bdj->buf->height) {
+ BD_DEBUG(DBG_BDJ | DBG_CRIT, "Cropping %d rows from bottom\n", y1 - bdj->buf->height);
+ y1 = bdj->buf->height - 1;
+ }
+ if (x1 >= bdj->buf->width) {
+ BD_DEBUG(DBG_BDJ | DBG_CRIT, "Cropping %d pixels from right\n", x1 - bdj->buf->width);
+ x1 = bdj->buf->width - 1;
+ }
+
+ /* copy */
+
+ offset = y0 * width + x0;
+ dst = (jint*)bdj->buf->buf[BD_OVERLAY_IG] + y0 * bdj->buf->width + x0;
+
+ for (y = y0; y <= y1; y++) {
+ (*env)->GetIntArrayRegion(env, rgbArray, offset, x1 - x0 + 1, dst);
+ offset += width;
+ dst += bdj->buf->width;
+ }
+
+ /* check for errors */
+ if ((*env)->ExceptionOccurred(env)) {
+ BD_DEBUG(DBG_BDJ | DBG_CRIT, "Array access error at %d (+%d)\n", offset, x1 - x0 + 1);
+ (*env)->ExceptionDescribe(env);
+ (*env)->ExceptionClear(env);
+ }
if (bdj->buf->unlock) {
bdj->buf->unlock(bdj->buf);
}
bdj->osd_cb(bdj->bd, bdj->buf->buf[BD_OVERLAY_IG], (int)width, (int)height,
- 0, 0, width-1, height-1);
+ x0, y0, x1, y1);
} else {
More information about the libbluray-devel
mailing list