Android Camera2 API 将流缓冲区发送到本机函数
Android Camera2 API send stream buffer to native function
我正在尝试了解如何处理视频和音频流,将帧数据放入缓冲区。我想在本机 JNI 函数中使用这些缓冲区。此代码正在准备将视频和音频写入 mp4 文件。我应该用什么写入缓冲区?
...
private void setUpMediaRecorder() throws IOException {
final Activity activity = getActivity();
if (null == activity) {
return;
}
mMediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
mMediaRecorder.setVideoSource(MediaRecorder.VideoSource.SURFACE);
mMediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4);
if (mNextVideoAbsolutePath == null || mNextVideoAbsolutePath.isEmpty()) {
mNextVideoAbsolutePath = getVideoFilePath(getActivity());
}
mMediaRecorder.setOutputFile(mNextVideoAbsolutePath);
mMediaRecorder.setVideoEncodingBitRate(10000000);
mMediaRecorder.setVideoFrameRate(30);
mMediaRecorder.setVideoSize(mVideoSize.getWidth(), mVideoSize.getHeight());
mMediaRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.H264);
mMediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AAC);
int rotation = activity.getWindowManager().getDefaultDisplay().getRotation();
switch (mSensorOrientation) {
case SENSOR_ORIENTATION_DEFAULT_DEGREES:
mMediaRecorder.setOrientationHint(DEFAULT_ORIENTATIONS.get(rotation));
break;
case SENSOR_ORIENTATION_INVERSE_DEGREES:
mMediaRecorder.setOrientationHint(INVERSE_ORIENTATIONS.get(rotation));
break;
}
mMediaRecorder.prepare();
}
不太清楚您想读取哪种缓冲区,但很可能您想要 ImageReader。
您可以使用 ImageFormat 进行设置。YUV_420_888 并将 Surface 与 CameraDevice 一起使用。然后它会产生 Image 对象,它有 3 个 Planes,每个 Planes 都有一个 ByteBuffer。您可以通过 JNI 传递 ByteBuffer 并使用 ByteBuffer JNI 方法访问它而不使用副本。
请务必查看为每个平面记录的行和像素跨度,以便正确访问 ByteBuffer 数据。
我正在尝试了解如何处理视频和音频流,将帧数据放入缓冲区。我想在本机 JNI 函数中使用这些缓冲区。此代码正在准备将视频和音频写入 mp4 文件。我应该用什么写入缓冲区?
...
private void setUpMediaRecorder() throws IOException {
final Activity activity = getActivity();
if (null == activity) {
return;
}
mMediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
mMediaRecorder.setVideoSource(MediaRecorder.VideoSource.SURFACE);
mMediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4);
if (mNextVideoAbsolutePath == null || mNextVideoAbsolutePath.isEmpty()) {
mNextVideoAbsolutePath = getVideoFilePath(getActivity());
}
mMediaRecorder.setOutputFile(mNextVideoAbsolutePath);
mMediaRecorder.setVideoEncodingBitRate(10000000);
mMediaRecorder.setVideoFrameRate(30);
mMediaRecorder.setVideoSize(mVideoSize.getWidth(), mVideoSize.getHeight());
mMediaRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.H264);
mMediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AAC);
int rotation = activity.getWindowManager().getDefaultDisplay().getRotation();
switch (mSensorOrientation) {
case SENSOR_ORIENTATION_DEFAULT_DEGREES:
mMediaRecorder.setOrientationHint(DEFAULT_ORIENTATIONS.get(rotation));
break;
case SENSOR_ORIENTATION_INVERSE_DEGREES:
mMediaRecorder.setOrientationHint(INVERSE_ORIENTATIONS.get(rotation));
break;
}
mMediaRecorder.prepare();
}
不太清楚您想读取哪种缓冲区,但很可能您想要 ImageReader。
您可以使用 ImageFormat 进行设置。YUV_420_888 并将 Surface 与 CameraDevice 一起使用。然后它会产生 Image 对象,它有 3 个 Planes,每个 Planes 都有一个 ByteBuffer。您可以通过 JNI 传递 ByteBuffer 并使用 ByteBuffer JNI 方法访问它而不使用副本。
请务必查看为每个平面记录的行和像素跨度,以便正确访问 ByteBuffer 数据。