Почему этот код имеет проблемы с производительностью даже без синхронизированного ключевого слова?
Почему следующий код имеет проблемы с производительностью, кадр с камеры не является плавным.
public class VideoCaptureAndroid implements PreviewCallback, Callback{
private Integer deviceRotation = Integer.MAX_VALUE;
public VideoCaptureAndroid(Context context, int id, long native_capturer) {
deviceRotationNotifier = new OrientationEventListener(context, SensorManager.SENSOR_DELAY_NORMAL) {
public void onOrientationChanged(int orientation) {
if (orientation == ORIENTATION_UNKNOWN) {
Log.d(TAG, "The device rotation angle is unknown.");
return;
}
synchronized(deviceRotation) {
if (deviceRotation != orientation) {
deviceRotation = orientation;
}
}
}
};
Exchanger<Handler> handlerExchanger = new Exchanger<Handler>();
cameraThread = new CameraThread(handlerExchanger);
cameraThread.start();
}
public synchronized void onPreviewFrame(byte[] data, Camera callbackCamera) {
int frameRotation = info.orientation;
if (info.facing == Camera.CameraInfo.CAMERA_FACING_FRONT) {
frameRotation = (info.orientation - deviceRotation + 360) % 360;
} else if (info.facing == Camera.CameraInfo.CAMERA_FACING_BACK) {
frameRotation = (info.orientation + deviceRotation) % 360;
}
onFrame(data, data.length, native_capturer, frameRotation);
camera.addCallbackBuffer(data);
}
}
Кажется, если я закомментирую следующий код, кадр будет гладким, и никаких проблем с производительностью. Но я не использовал synchronized
в onPreviewFrame
чтобы получить доступ к deviceRotation
почему это повлияет onOrientationChanged
?
if (info.facing == Camera.CameraInfo.CAMERA_FACING_FRONT) {
frameRotation = (info.orientation - deviceRotation + 360) % 360;
} else if (info.facing == Camera.CameraInfo.CAMERA_FACING_BACK) {
frameRotation = (info.orientation + deviceRotation) % 360;
}
1 ответ
Код, который вы указали, скорее всего, не проблема. Операции по модулю медленные, но выполнение одного кадра в каждом кадре не окажет большого влияния. frameRotation
значение передается onFrame()
что мы можем только предположить, применяет матрицу или другое преобразование для поворота данных. Это дорогостоящая операция и, скорее всего, включает использование одного или нескольких временных буферов (или Bitmap
объекты), которая использует кучу и также медленно. Я предполагаю что info.orientation
передается без изменений onFrame()
не приведет к настройке кадра. Следовательно, удаление двух указанных вами строк не приведет к тяжелой обработке в onFrame()
Именно поэтому джиттер исчезает.
Вы можете отследить это лучше, используя traceview или systrace для подтверждения.