Revert of Android VideoCapturer: Send ByteBuffer instead of byte[] (patchset #1 id:1 of https://codereview.webrtc.org/1372813002/ )

Reason for revert:
The top row in the video stream from the camera is messed up. The byte[] pointer is not the same as GetDirectBufferAddress() apparently.

Original issue's description:
> Android VideoCapturer: Send ByteBuffer instead of byte[]
>
> The purpose with this CL is to replace GetByteArrayElements() and ReleaseByteArrayElements() with GetDirectBufferAddress().
>
> R=hbos@webrtc.org
>
> Committed: https://crrev.com/cb3649b40b3fd6d5bbb0a92003b717e46ce90924
> Cr-Commit-Position: refs/heads/master@{#10091}

TBR=hbos@webrtc.org
NOPRESUBMIT=true
NOTREECHECKS=true
NOTRY=true

Review URL: https://codereview.webrtc.org/1377783002

Cr-Commit-Position: refs/heads/master@{#10103}
This commit is contained in:
magjed
2015-09-29 01:13:43 -07:00
committed by Commit bot
parent fb9e76369d
commit b5815c8013
4 changed files with 31 additions and 26 deletions

View File

@ -35,7 +35,6 @@ import android.util.Size;
import org.webrtc.CameraEnumerationAndroid.CaptureFormat; import org.webrtc.CameraEnumerationAndroid.CaptureFormat;
import org.webrtc.VideoRenderer.I420Frame; import org.webrtc.VideoRenderer.I420Frame;
import java.nio.ByteBuffer;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashSet; import java.util.HashSet;
import java.util.List; import java.util.List;
@ -105,11 +104,11 @@ public class VideoCapturerAndroidTest extends ActivityTestCase {
} }
@Override @Override
public void OnFrameCaptured(ByteBuffer frame, int width, int height, public void OnFrameCaptured(byte[] frame, int length, int width, int height,
int rotation, long timeStamp) { int rotation, long timeStamp) {
synchronized (frameLock) { synchronized (frameLock) {
++framesCaptured; ++framesCaptured;
frameSize = frame.capacity(); frameSize = length;
timestamps.add(timeStamp); timestamps.add(timeStamp);
frameLock.notify(); frameLock.notify();
} }

View File

@ -569,11 +569,12 @@ public class VideoCapturerAndroid extends VideoCapturer implements PreviewCallba
} }
rotation = (info.orientation + rotation) % 360; rotation = (info.orientation + rotation) % 360;
// Mark the frame owning |data| as used. // Mark the frame owning |data| as used.
final ByteBuffer buffer = videoBuffers.reserveByteBuffer(data, captureTimeNs); // Note that since data is directBuffer,
if (buffer != null) { // data.length >= videoBuffers.frameSize.
if (videoBuffers.reserveByteBuffer(data, captureTimeNs)) {
cameraFramesCount++; cameraFramesCount++;
frameObserver.OnFrameCaptured(buffer, captureFormat.width, captureFormat.height, frameObserver.OnFrameCaptured(data, videoBuffers.frameSize, captureFormat.width,
rotation, captureTimeNs); captureFormat.height, rotation, captureTimeNs);
} else { } else {
Logging.w(TAG, "reserveByteBuffer failed - dropping frame."); Logging.w(TAG, "reserveByteBuffer failed - dropping frame.");
} }
@ -655,8 +656,7 @@ public class VideoCapturerAndroid extends VideoCapturer implements PreviewCallba
: " Pending buffers: " + pendingFramesTimeStamps() + ".")); : " Pending buffers: " + pendingFramesTimeStamps() + "."));
} }
// Returns the reserved byte buffer, or null on failure. public boolean reserveByteBuffer(byte[] data, long timeStamp) {
public ByteBuffer reserveByteBuffer(byte[] data, long timeStamp) {
checkIsOnValidThread(); checkIsOnValidThread();
final ByteBuffer buffer = queuedBuffers.remove(data); final ByteBuffer buffer = queuedBuffers.remove(data);
if (buffer == null) { if (buffer == null) {
@ -664,21 +664,21 @@ public class VideoCapturerAndroid extends VideoCapturer implements PreviewCallba
// capture format in |startPreviewOnCameraThread|. Drop these old frames. // capture format in |startPreviewOnCameraThread|. Drop these old frames.
Logging.w(TAG, "Received callback buffer from previous configuration with length: " Logging.w(TAG, "Received callback buffer from previous configuration with length: "
+ (data == null ? "null" : data.length)); + (data == null ? "null" : data.length));
return null; return false;
} }
if (buffer.capacity() != frameSize) { if (buffer.capacity() != frameSize) {
throw new IllegalStateException("Callback buffer has unexpected frame size"); throw new IllegalStateException("Callback buffer has unexpected frame size");
} }
if (pendingBuffers.containsKey(timeStamp)) { if (pendingBuffers.containsKey(timeStamp)) {
Logging.e(TAG, "Timestamp already present in pending buffers - they need to be unique"); Logging.e(TAG, "Timestamp already present in pending buffers - they need to be unique");
return null; return false;
} }
pendingBuffers.put(timeStamp, buffer); pendingBuffers.put(timeStamp, buffer);
if (queuedBuffers.isEmpty()) { if (queuedBuffers.isEmpty()) {
Logging.v(TAG, "Camera is running out of capture buffers." Logging.v(TAG, "Camera is running out of capture buffers."
+ " Pending buffers: " + pendingFramesTimeStamps()); + " Pending buffers: " + pendingFramesTimeStamps());
} }
return buffer; return true;
} }
public void returnBuffer(long timeStamp) { public void returnBuffer(long timeStamp) {
@ -722,8 +722,8 @@ public class VideoCapturerAndroid extends VideoCapturer implements PreviewCallba
// Delivers a captured frame. Called on a Java thread owned by // Delivers a captured frame. Called on a Java thread owned by
// VideoCapturerAndroid. // VideoCapturerAndroid.
abstract void OnFrameCaptured(ByteBuffer buffer, int width, int height, int rotation, abstract void OnFrameCaptured(byte[] data, int length, int width, int height,
long timeStamp); int rotation, long timeStamp);
// Requests an output format from the video capturer. Captured frames // Requests an output format from the video capturer. Captured frames
// by the camera will be scaled/or dropped by the video capturer. // by the camera will be scaled/or dropped by the video capturer.
@ -746,9 +746,9 @@ public class VideoCapturerAndroid extends VideoCapturer implements PreviewCallba
} }
@Override @Override
public void OnFrameCaptured(ByteBuffer buffer, int width, int height, int rotation, public void OnFrameCaptured(byte[] data, int length, int width, int height,
long timeStamp) { int rotation, long timeStamp) {
nativeOnFrameCaptured(nativeCapturer, buffer, width, height, rotation, timeStamp); nativeOnFrameCaptured(nativeCapturer, data, length, width, height, rotation, timeStamp);
} }
@Override @Override
@ -759,7 +759,7 @@ public class VideoCapturerAndroid extends VideoCapturer implements PreviewCallba
private native void nativeCapturerStarted(long nativeCapturer, private native void nativeCapturerStarted(long nativeCapturer,
boolean success); boolean success);
private native void nativeOnFrameCaptured(long nativeCapturer, private native void nativeOnFrameCaptured(long nativeCapturer,
ByteBuffer buffer, int width, int height, int rotation, long timeStamp); byte[] data, int length, int width, int height, int rotation, long timeStamp);
private native void nativeOnOutputFormatRequest(long nativeCapturer, private native void nativeOnOutputFormatRequest(long nativeCapturer,
int width, int height, int fps); int width, int height, int fps);
} }

View File

@ -176,13 +176,13 @@ void AndroidVideoCapturerJni::OnCapturerStarted(bool success) {
success); success);
} }
void AndroidVideoCapturerJni::OnIncomingFrame(const uint8_t* video_frame, void AndroidVideoCapturerJni::OnIncomingFrame(void* video_frame,
int length, int length,
int width, int width,
int height, int height,
int rotation, int rotation,
int64 time_stamp) { int64 time_stamp) {
const uint8_t* y_plane = video_frame; const uint8_t* y_plane = static_cast<uint8_t*>(video_frame);
// Android guarantees that the stride is a multiple of 16. // Android guarantees that the stride is a multiple of 16.
// http://developer.android.com/reference/android/hardware/Camera.Parameters.html#setPreviewFormat%28int%29 // http://developer.android.com/reference/android/hardware/Camera.Parameters.html#setPreviewFormat%28int%29
int y_stride; int y_stride;
@ -215,14 +215,20 @@ void AndroidVideoCapturerJni::OnOutputFormatRequest(int width,
JNIEnv* AndroidVideoCapturerJni::jni() { return AttachCurrentThreadIfNeeded(); } JNIEnv* AndroidVideoCapturerJni::jni() { return AttachCurrentThreadIfNeeded(); }
JOW(void, VideoCapturerAndroid_00024NativeObserver_nativeOnFrameCaptured) JOW(void, VideoCapturerAndroid_00024NativeObserver_nativeOnFrameCaptured)
(JNIEnv* jni, jclass, jlong j_capturer, jobject j_byte_buffer, (JNIEnv* jni, jclass, jlong j_capturer, jbyteArray j_frame, jint length,
jint width, jint height, jint rotation, jlong ts) { jint width, jint height, jint rotation, jlong ts) {
const uint8_t* bytes = jboolean is_copy = true;
static_cast<uint8_t*>(jni->GetDirectBufferAddress(j_byte_buffer)); jbyte* bytes = jni->GetByteArrayElements(j_frame, &is_copy);
const int length = jni->GetDirectBufferCapacity(j_byte_buffer); // If this is a copy of the original frame, it means that the memory
RTC_CHECK(bytes != nullptr && length != -1) << "ByteBuffer is not direct"; // is not direct memory and thus VideoCapturerAndroid does not guarantee
// that the memory is valid when we have released |j_frame|.
// TODO(magjed): Move ReleaseByteArrayElements() into ReturnBuffer() and
// remove this check.
RTC_CHECK(!is_copy)
<< "NativeObserver_nativeOnFrameCaptured: frame is a copy";
reinterpret_cast<AndroidVideoCapturerJni*>(j_capturer) reinterpret_cast<AndroidVideoCapturerJni*>(j_capturer)
->OnIncomingFrame(bytes, length, width, height, rotation, ts); ->OnIncomingFrame(bytes, length, width, height, rotation, ts);
jni->ReleaseByteArrayElements(j_frame, bytes, JNI_ABORT);
} }
JOW(void, VideoCapturerAndroid_00024NativeObserver_nativeCapturerStarted) JOW(void, VideoCapturerAndroid_00024NativeObserver_nativeCapturerStarted)

View File

@ -61,7 +61,7 @@ class AndroidVideoCapturerJni : public webrtc::AndroidVideoCapturerDelegate {
// Called from VideoCapturerAndroid::NativeObserver on a Java thread. // Called from VideoCapturerAndroid::NativeObserver on a Java thread.
void OnCapturerStarted(bool success); void OnCapturerStarted(bool success);
void OnIncomingFrame(const uint8_t* video_frame, void OnIncomingFrame(void* video_frame,
int length, int length,
int width, int width,
int height, int height,