Skip to content

Commit 0461e26

Browse files
committed
feat: add copy method for NativeI420Buffer and VideoFrame
1 parent 6fc33c1 commit 0461e26

File tree

7 files changed

+64
-25
lines changed

7 files changed

+64
-25
lines changed

webrtc-jni/src/main/cpp/include/JNI_NativeI420Buffer.h

Lines changed: 8 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

webrtc-jni/src/main/cpp/src/JNI_NativeI420Buffer.cpp

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,24 @@ JNIEXPORT jobject JNICALL Java_dev_onvoid_webrtc_media_video_NativeI420Buffer_al
3333
return jBuffer.release();
3434
}
3535

36+
JNIEXPORT jobject JNICALL Java_dev_onvoid_webrtc_media_video_NativeI420Buffer_copy
37+
(JNIEnv* env, jclass caller, jint width, jint height, jobject jSrcY, jint srcStrideY,
38+
jobject jSrcU, jint srcStrideU, jobject jSrcV, jint srcStrideV)
39+
{
40+
const uint8_t * src_y = static_cast<uint8_t*>(env->GetDirectBufferAddress(jSrcY));
41+
const uint8_t * src_u = static_cast<uint8_t*>(env->GetDirectBufferAddress(jSrcU));
42+
const uint8_t * src_v = static_cast<uint8_t*>(env->GetDirectBufferAddress(jSrcV));
43+
44+
webrtc::scoped_refptr<webrtc::I420BufferInterface> i420Buffer = webrtc::I420Buffer::Copy(width, height,
45+
src_y, srcStrideY, src_u, srcStrideU, src_v, srcStrideV);
46+
47+
jni::JavaLocalRef<jobject> jBuffer = jni::I420Buffer::toJava(env, i420Buffer);
48+
49+
i420Buffer->AddRef();
50+
51+
return jBuffer.release();
52+
}
53+
3654
JNIEXPORT void JNICALL Java_dev_onvoid_webrtc_media_video_NativeI420Buffer_cropAndScale
3755
(JNIEnv * env, jclass caller, jobject jSrcY, jint srcStrideY, jobject jSrcU, jint srcStrideU,
3856
jobject jSrcV, jint srcStrideV, jint cropX, jint cropY, jint cropW, jint cropH,

webrtc/src/main/java/dev/onvoid/webrtc/internal/RefCounted.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,9 @@
1818

1919
/**
2020
* Interface for ref counted objects in WebRTC. These objects have significant
21-
* resources that need to be freed when they are no longer in use. Each objects
21+
* resources that need to be freed when they are no longer in use. Each object
2222
* starts with ref count of one when created. If a reference is passed as a
23-
* parameter to a method, the caller has ownesrship of the object by default -
23+
* parameter to a method, the caller has ownership of the object by default -
2424
* calling release is not necessary unless retain is called.
2525
*/
2626
public interface RefCounted {

webrtc/src/main/java/dev/onvoid/webrtc/media/video/NativeI420Buffer.java

Lines changed: 15 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -94,8 +94,6 @@ public int getHeight() {
9494

9595
@Override
9696
public I420Buffer toI420() {
97-
// retain();
98-
9997
return this;
10098
}
10199

@@ -112,11 +110,26 @@ public String toString() {
112110
width, height);
113111
}
114112

113+
/**
114+
* Creates a copy of this I420 buffer. This method performs a deep copy of all data in the buffer.
115+
*
116+
* @return A new NativeI420Buffer instance with the same dimensions and data as this buffer.
117+
*/
118+
public NativeI420Buffer copy() {
119+
return copy(width, height, dataY.slice(), strideY, dataU.slice(), strideU, dataV.slice(), strideV);
120+
}
121+
115122
/**
116123
* Allocates an empty I420Buffer suitable for an image of the given dimensions.
117124
*/
118125
public static native NativeI420Buffer allocate(int width, int height);
119126

127+
/**
128+
* Creates a copy of an I420 buffer with the given dimensions and data.
129+
*/
130+
private static native NativeI420Buffer copy(int width, int height, ByteBuffer dataY, int strideY, ByteBuffer dataU,
131+
int strideU, ByteBuffer dataV, int strideV);
132+
120133
/**
121134
* Wraps existing ByteBuffers into NativeI420Buffer object without copying the
122135
* contents.
@@ -159,23 +172,17 @@ private static VideoFrameBuffer cropAndScale(final I420Buffer buffer, int cropX,
159172
dataU.position(cropX / 2 + cropY / 2 * buffer.getStrideU());
160173
dataV.position(cropX / 2 + cropY / 2 * buffer.getStrideV());
161174

162-
// buffer.retain();
163-
164175
return wrap(scaleWidth, scaleHeight, dataY.slice(), buffer.getStrideY(), dataU.slice(),
165176
buffer.getStrideU(), dataV.slice(), buffer.getStrideV());
166177
}
167178

168-
// buffer.retain();
169-
170179
I420Buffer newBuffer = allocate(scaleWidth, scaleHeight);
171180

172181
cropAndScale(buffer.getDataY(), buffer.getStrideY(), buffer.getDataU(), buffer.getStrideU(),
173182
buffer.getDataV(), buffer.getStrideV(), cropX, cropY, cropWidth, cropHeight,
174183
newBuffer.getDataY(), newBuffer.getStrideY(), newBuffer.getDataU(), newBuffer.getStrideU(),
175184
newBuffer.getDataV(), newBuffer.getStrideV(), scaleWidth, scaleHeight);
176185

177-
// buffer.release();
178-
179186
return newBuffer;
180187
}
181188

webrtc/src/main/java/dev/onvoid/webrtc/media/video/VideoBufferConverter.java

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -39,8 +39,6 @@ public static void convertFromI420(VideoFrameBuffer src, byte[] dst, FourCC four
3939
dst,
4040
i420.getWidth(), i420.getHeight(),
4141
fourCC.value());
42-
43-
// i420.release();
4442
}
4543

4644
public static void convertFromI420(VideoFrameBuffer src, ByteBuffer dst, FourCC fourCC) throws Exception {
@@ -63,7 +61,7 @@ public static void convertFromI420(VideoFrameBuffer src, ByteBuffer dst, FourCC
6361
fourCC.value());
6462
}
6563
else {
66-
byte[] arrayBuffer = null;
64+
byte[] arrayBuffer;
6765

6866
if (dst.hasArray()) {
6967
arrayBuffer = dst.array();
@@ -81,8 +79,6 @@ public static void convertFromI420(VideoFrameBuffer src, ByteBuffer dst, FourCC
8179
i420.getWidth(), i420.getHeight(),
8280
fourCC.value());
8381
}
84-
85-
// i420.release();
8682
}
8783

8884
private native static void I420toByteArray(

webrtc/src/main/java/dev/onvoid/webrtc/media/video/VideoFrame.java

Lines changed: 19 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -18,21 +18,20 @@
1818

1919
import dev.onvoid.webrtc.internal.RefCounted;
2020

21+
/**
22+
* Represents a video frame with an associated frame buffer and metadata.
23+
* This class implements reference counting to manage memory for video frames.
24+
* Video frames contain buffer data along with rotation and timestamp information.
25+
*/
2126
public class VideoFrame implements RefCounted {
2227

23-
/**
24-
* The underlying frame buffer.
25-
*/
28+
/** The underlying frame buffer. */
2629
public final VideoFrameBuffer buffer;
2730

28-
/**
29-
* Rotation of the frame in degrees.
30-
*/
31+
/** Rotation of the frame in degrees. */
3132
public final int rotation;
3233

33-
/**
34-
* Timestamp of the frame in nano seconds.
35-
*/
34+
/** Timestamp of the frame in nanoseconds. */
3635
public final long timestampNs;
3736

3837

@@ -49,6 +48,17 @@ private VideoFrame(VideoFrameBuffer buffer, int rotation, long timestampNs) {
4948
this.timestampNs = timestampNs;
5049
}
5150

51+
/**
52+
* Creates a deep copy of this VideoFrame. The new frame will have its own copy of the buffer data.
53+
*
54+
* @return A new VideoFrame with a copy of the buffer data.
55+
*/
56+
public VideoFrame copy() {
57+
NativeI420Buffer nativeBuffer = (NativeI420Buffer) buffer;
58+
59+
return new VideoFrame(nativeBuffer.copy(), rotation, timestampNs);
60+
}
61+
5262
@Override
5363
public void retain() {
5464
buffer.retain();

webrtc/src/main/java/dev/onvoid/webrtc/media/video/VideoFrameBuffer.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ public interface VideoFrameBuffer extends RefCounted {
3939
I420Buffer toI420();
4040

4141
/**
42-
* Crops a region defined by |cropx|, |cropY|, |cropWidth| and |cropHeight|.
42+
* Crops a region defined by |cropX|, |cropY|, |cropWidth| and |cropHeight|.
4343
* Scales it to size |scaleWidth| x |scaleHeight|.
4444
*/
4545
VideoFrameBuffer cropAndScale(int cropX, int cropY, int cropWidth,

0 commit comments

Comments
 (0)