FazBrowse GitHub Viewer | Trending |
URL:
| Home
Tools: [Download Repo ZIP]   [Original HTTPS Page]

reimplemented pixel access in video library when using P2D/P3D · shohei/processing@fc0a8fd · GitHub

Repository navigation

Commit fc0a8fd

Browse files
committed
reimplemented pixel access in video library when using P2D/P3D
1 parent f1502ef commit fc0a8fd

4 files changed

Lines changed: 205 additions & 54 deletions

File tree

‎core/src/processing/opengl/Texture.java‎

Lines changed: 48 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,7 @@ public class Texture implements PConstants {
102102

103103
protected Object bufferSource;
104104
protected LinkedList<BufferData> bufferCache = null;
105+
protected LinkedList<BufferData> usedBuffers = null;
105106
protected Method disposeBufferMethod;
106107
public static final int MAX_BUFFER_CACHE_SIZE = 3;
107108

@@ -153,7 +154,6 @@ public Texture(int width, int height, Object params) {
153154
@Override
154155
protected void finalize() throws Throwable {
155156
try {
156-
// PApplet.println("finalize texture");
157157
if (glName != 0) {
158158
PGraphicsOpenGL.finalizeTextureObject(glName, context);
159159
}
@@ -520,27 +520,6 @@ public void get(int[] pixels) {
520520
}
521521

522522

523-
/**
524-
* Copies the contents of the texture to the pixels array.
525-
* @param pixels
526-
*/
527-
// public void loadPixels(int[] pixels) {
528-
// if (hasBuffers()) {
529-
// // Updates the texture AND the pixels array of the image at the same time,
530-
// // getting the pixels directly from the buffer data (and thus avoiding
531-
// // expensive transfer between video and main memory).
532-
// bufferUpdate(pixels);
533-
// }
534-
//
535-
// if (isModified()) {
536-
// // Regular pixel copy from texture.
537-
// get(pixels);
538-
// }
539-
//
540-
// setModified(false);
541-
// }
542-
543-
544523
////////////////////////////////////////////////////////////
545524

546525
// Put methods (the source texture is not resized to cover the entire
@@ -861,16 +840,53 @@ public void copyBufferFromSource(Object natRef, ByteBuffer byteBuf,
861840
bufferCache.add(new BufferData(natRef, byteBuf.asIntBuffer(), w, h));
862841
} else {
863842
// The buffer cache reached the maximum size, so we just dispose
864-
// the new buffer.
843+
// the new buffer by adding it to the list of used buffers.
865844
try {
866-
disposeBufferMethod.invoke(bufferSource, new Object[] { natRef });
845+
usedBuffers.add(new BufferData(natRef, byteBuf.asIntBuffer(), w, h));
867846
} catch (Exception e) {
868847
e.printStackTrace();
869848
}
870849
}
871850
}
872851

873852

853+
public void disposeSourceBuffer() {
854+
System.out.println(" in disposeSourceBuffer");
855+
if (usedBuffers == null) return;
856+
857+
while (0 < usedBuffers.size()) {
858+
BufferData data = null;
859+
try {
860+
data = usedBuffers.remove(0);
861+
System.out.println("Disposing " + data + " in disposeSourceBuffer");
862+
} catch (NoSuchElementException ex) {
863+
PGraphics.showWarning("Cannot remove used buffer");
864+
}
865+
if (data != null) {
866+
data.dispose();
867+
}
868+
}
869+
}
870+
871+
public void getBufferPixels(int[] pixels) {
872+
BufferData data = null;
873+
if (usedBuffers != null && 0 < usedBuffers.size()) {
874+
// the last used buffer is the one currently stored in the opengl the
875+
// texture
876+
data = usedBuffers.getLast();
877+
} else if (bufferCache != null && 0 < bufferCache.size()) {
878+
// The first buffer in the cache will be uploaded to the opengl texture
879+
// the next time it is rendered
880+
data = bufferCache.getFirst();
881+
}
882+
if (data != null) {
883+
data.rgbBuf.rewind();
884+
data.rgbBuf.get(pixels);
885+
convertToARGB(pixels);
886+
}
887+
}
888+
889+
874890
public boolean hasBufferSource() {
875891
return bufferSource != null;
876892
}
@@ -894,35 +910,15 @@ protected boolean bufferUpdate() {
894910
if ((data.w != width) || (data.h != height)) {
895911
init(data.w, data.h);
896912
}
913+
data.rgbBuf.rewind();
897914
setNative(data.rgbBuf, 0, 0, width, height);
898915

899-
data.dispose();
900-
901-
return true;
902-
} else {
903-
return false;
904-
}
905-
}
906-
907-
908-
protected boolean bufferUpdate(int[] pixels) {
909-
BufferData data = null;
910-
try {
911-
data = bufferCache.remove(0);
912-
} catch (NoSuchElementException ex) {
913-
PGraphics.showWarning("Don't have pixel data to copy to texture");
914-
}
915-
916-
if (data != null) {
917-
if ((data.w != width) || (data.h != height)) {
918-
init(data.w, data.h);
916+
// Putting the buffer in the used buffers list to dispose at the end of
917+
// draw.
918+
if (usedBuffers == null) {
919+
usedBuffers = new LinkedList<BufferData>();
919920
}
920-
setNative(data.rgbBuf, 0, 0, width, height);
921-
922-
data.rgbBuf.get(pixels);
923-
convertToARGB(pixels);
924-
925-
data.dispose();
921+
usedBuffers.add(data);
926922

927923
return true;
928924
} else {
@@ -1115,8 +1111,8 @@ protected void convertToARGB(int[] intArray) {
11151111
for (int x = 0; x < width; x++) {
11161112
int pixel = intArray[p++];
11171113
intArray[t++] = ((pixel & 0xFF) << 16) |
1118-
((pixel & 0xFF0000) >> 16) |
1119-
(pixel & 0xFF00FF00);
1114+
((pixel & 0xFF0000) >> 16) |
1115+
(pixel & 0xFF00FF00);
11201116

11211117
}
11221118
}

‎java/libraries/video/src/processing/video/Capture.java‎

Lines changed: 60 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,8 @@ public class Capture extends PImage implements PConstants {
110110
protected Object bufferSink;
111111
protected Method sinkCopyMethod;
112112
protected Method sinkSetMethod;
113+
protected Method sinkDisposeMethod;
114+
protected Method sinkGetMethod;
113115
protected String copyMask;
114116
protected Buffer natBuffer = null;
115117
protected BufferDataAppSink natSink = null;
@@ -417,7 +419,29 @@ public synchronized void read() {
417419
newFrame = true;
418420
}
419421

420-
422+
423+
public synchronized void loadPixels() {
424+
super.loadPixels();
425+
if (useBufferSink) {
426+
if (natBuffer != null) {
427+
// This means that the OpenGL texture hasn't been created so far (the
428+
// video frame not drawn using image()), but the user wants to use the
429+
// pixel array, which we can just get from natBuffer.
430+
IntBuffer buf = natBuffer.getByteBuffer().asIntBuffer();
431+
buf.rewind();
432+
buf.get(pixels);
433+
Video.convertToARGB(pixels, width, height);
434+
} else if (sinkGetMethod != null) {
435+
try {
436+
sinkGetMethod.invoke(bufferSink, new Object[] { pixels });
437+
} catch (Exception e) {
438+
e.printStackTrace();
439+
}
440+
}
441+
}
442+
}
443+
444+
421445
////////////////////////////////////////////////////////////
422446

423447
// List methods.
@@ -800,6 +824,7 @@ protected void initGStreamer(PApplet parent, int rw, int rh, String src,
800824

801825
// register methods
802826
parent.registerMethod("dispose", this);
827+
parent.registerMethod("post", this);
803828

804829
setEventHandlerObject(parent);
805830

@@ -976,6 +1001,13 @@ protected synchronized void invokeEvent(int w, int h, Buffer buffer) {
9761001
available = true;
9771002
bufWidth = w;
9781003
bufHeight = h;
1004+
if (natBuffer != null) {
1005+
// To handle the situation where read() is not called in the sketch, so
1006+
// that the native buffers are not being sent to the sinke, and therefore, not disposed
1007+
// by it.
1008+
System.out.println(" disposing nat buffer before reading new one");
1009+
natBuffer.dispose();
1010+
}
9791011
natBuffer = buffer;
9801012

9811013
// Creates a movieEvent.
@@ -1129,6 +1161,22 @@ protected void getSinkMethods() {
11291161
throw new RuntimeException("Capture: provided sink object doesn't have "+
11301162
"a setBufferSource method.");
11311163
}
1164+
1165+
try {
1166+
sinkDisposeMethod = bufferSink.getClass().getMethod("disposeSourceBuffer",
1167+
new Class[] { });
1168+
} catch (Exception e) {
1169+
throw new RuntimeException("Capture: provided sink object doesn't have " +
1170+
"a disposeSourceBuffer method.");
1171+
}
1172+
1173+
try {
1174+
sinkGetMethod = bufferSink.getClass().getMethod("getBufferPixels",
1175+
new Class[] { int[].class });
1176+
} catch (Exception e) {
1177+
throw new RuntimeException("Capture: provided sink object doesn't have " +
1178+
"a getBufferPixels method.");
1179+
}
11321180
}
11331181

11341182

@@ -1139,4 +1187,15 @@ protected void initCopyMask() {
11391187
copyMask = "red_mask=(int)0xFF, green_mask=(int)0xFF00, blue_mask=(int)0xFF0000";
11401188
}
11411189
}
1190+
1191+
1192+
public synchronized void post() {
1193+
if (useBufferSink && sinkDisposeMethod != null) {
1194+
try {
1195+
sinkDisposeMethod.invoke(bufferSink, new Object[] {});
1196+
} catch (Exception e) {
1197+
e.printStackTrace();
1198+
}
1199+
}
1200+
}
11421201
}

‎java/libraries/video/src/processing/video/Movie.java‎

Lines changed: 59 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,8 @@ public class Movie extends PImage implements PConstants {
8282
protected Object bufferSink;
8383
protected Method sinkCopyMethod;
8484
protected Method sinkSetMethod;
85+
protected Method sinkDisposeMethod;
86+
protected Method sinkGetMethod;
8587
protected String copyMask;
8688
protected Buffer natBuffer = null;
8789
protected BufferDataAppSink natSink = null;
@@ -542,6 +544,28 @@ public void volume(float v) {
542544
}
543545

544546

547+
public synchronized void loadPixels() {
548+
super.loadPixels();
549+
if (useBufferSink) {
550+
if (natBuffer != null) {
551+
// This means that the OpenGL texture hasn't been created so far (the
552+
// video frame not drawn using image()), but the user wants to use the
553+
// pixel array, which we can just get from natBuffer.
554+
IntBuffer buf = natBuffer.getByteBuffer().asIntBuffer();
555+
buf.rewind();
556+
buf.get(pixels);
557+
Video.convertToARGB(pixels, width, height);
558+
} else if (sinkGetMethod != null) {
559+
try {
560+
sinkGetMethod.invoke(bufferSink, new Object[] { pixels });
561+
} catch (Exception e) {
562+
e.printStackTrace();
563+
}
564+
}
565+
}
566+
}
567+
568+
545569
////////////////////////////////////////////////////////////
546570

547571
// Initialization methods.
@@ -609,11 +633,11 @@ protected void initGStreamer(PApplet parent, String filename) {
609633

610634
// we've got a valid movie! let's rock.
611635
try {
612-
// PApplet.println("we've got a valid movie! let's rock.");
613636
this.filename = filename; // for error messages
614637

615638
// register methods
616639
parent.registerMethod("dispose", this);
640+
parent.registerMethod("post", this);
617641

618642
setEventHandlerObject(parent);
619643

@@ -742,6 +766,13 @@ protected synchronized void invokeEvent(int w, int h, Buffer buffer) {
742766
available = true;
743767
bufWidth = w;
744768
bufHeight = h;
769+
if (natBuffer != null) {
770+
// To handle the situation where read() is not called in the sketch, so
771+
// that the native buffers are not being sent to the sinke, and therefore, not disposed
772+
// by it.
773+
System.out.println(" disposing nat buffer before reading new one");
774+
natBuffer.dispose();
775+
}
745776
natBuffer = buffer;
746777

747778
if (playing) {
@@ -894,6 +925,22 @@ protected void getSinkMethods() {
894925
throw new RuntimeException("Movie: provided sink object doesn't have a " +
895926
"setBufferSource method.");
896927
}
928+
929+
try {
930+
sinkDisposeMethod = bufferSink.getClass().getMethod("disposeSourceBuffer",
931+
new Class[] { });
932+
} catch (Exception e) {
933+
throw new RuntimeException("Movie: provided sink object doesn't have " +
934+
"a disposeSourceBuffer method.");
935+
}
936+
937+
try {
938+
sinkGetMethod = bufferSink.getClass().getMethod("getBufferPixels",
939+
new Class[] { int[].class });
940+
} catch (Exception e) {
941+
throw new RuntimeException("Movie: provided sink object doesn't have " +
942+
"a getBufferPixels method.");
943+
}
897944
}
898945

899946

@@ -902,6 +949,17 @@ protected void initCopyMask() {
902949
copyMask = "red_mask=(int)0xFF000000, green_mask=(int)0xFF0000, blue_mask=(int)0xFF00";
903950
} else {
904951
copyMask = "red_mask=(int)0xFF, green_mask=(int)0xFF00, blue_mask=(int)0xFF0000";
952+
}
953+
}
954+
955+
956+
public synchronized void post() {
957+
if (useBufferSink && sinkDisposeMethod != null) {
958+
try {
959+
sinkDisposeMethod.invoke(bufferSink, new Object[] {});
960+
} catch (Exception e) {
961+
e.printStackTrace();
962+
}
905963
}
906964
}
907965
}

0 commit comments

Comments
 (0)

Back | FazBrowse Home | New Git URL