Хорошо, я нахожусь в конце моего остроумия. Я пишу приложение для дроидов, которое получает данные предварительного просмотра, обрабатывает их, а затем отображает измененные данные на экране. Пока все хорошо - за исключением того факта, что после некоторого неопределенного промежутка времени (обычно минуты или две) YUV-данные, которые поступают во время обратного вызова onPreviewFrame, ... катятся ... по горизонтали. Я захватил сырой yuv на SD-карту:
[похоже, я пока не могу публиковать фотографии, поэтому вот URL: raw yuv capture ]
Это мое первое приложение для дроидов, но я потратил много времени, работая над различными программами для настольного видео. Когда я увидел это, мне сразу пришло в голову, что у меня возникла проблема с синхронизацией потоков, и из-за этого буфер каким-то странным образом перезаписывался.
И мой код действительно изначально использовал рабочий поток. Таким образом, чтобы исключить вероятность того, что проблема была выпущена потоком, я вынул рабочий поток и поместил все в onPreviewFrame. Опять та же проблема: перекос данных YUV.
Затем я немного погуглил и обнаружил, что тяжелая обработка внутри onPreviewFrame может привести к случайным странностям. Чтобы обойти это , я изменил свой обратный вызов на разновидность OneShot, что привело к коду, который я сейчас использую:
public void surfaceCreated(SurfaceHolder holder) {
Log.i(TAG, "surfaceCreated");
mCamera = Camera.open();
mCamera.setOneShotPreviewCallback(new PreviewCallback() {
public void onPreviewFrame(byte[] data, Camera camera) {
Canvas canvas = mHolder.lockCanvas();
try
{
Bitmap bmp = processFrame(data);
if (bmp != null) {
if (canvas != null) {
canvas.drawBitmap(bmp, (canvas.getWidth() - getFrameWidth()) / 2, (canvas.getHeight() - getFrameHeight()) / 2, null);
}
bmp.recycle();
}
}
catch(Exception e)
{
e.printStackTrace();
}
finally
{
mHolder.unlockCanvasAndPost(canvas);
mCamera.setOneShotPreviewCallback(this);
}
}
});
}
К сожалению, я все еще получаю искаженные данные yuv.
Мое тестирующее устройство - HTC EVO 4G. Я знаю, что у этого телефона есть свои проблемы, но я до сих пор настороженно отношу это к аппаратной ошибке, главным образом потому, что я почти уверен, что это из-за ошибки программиста. Проблема в том, что я сжал свой код до костей, и проблема все еще проявляется.
Кто-нибудь сталкивался с этим раньше?