onPreviewFrame возвращает искаженные данные YUV - PullRequest
3 голосов
/ 18 августа 2011

Хорошо, я нахожусь в конце моего остроумия. Я пишу приложение для дроидов, которое получает данные предварительного просмотра, обрабатывает их, а затем отображает измененные данные на экране. Пока все хорошо - за исключением того факта, что после некоторого неопределенного промежутка времени (обычно минуты или две) 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. Я знаю, что у этого телефона есть свои проблемы, но я до сих пор настороженно отношу это к аппаратной ошибке, главным образом потому, что я почти уверен, что это из-за ошибки программиста. Проблема в том, что я сжал свой код до костей, и проблема все еще проявляется.

Кто-нибудь сталкивался с этим раньше?

1 Ответ

3 голосов
/ 18 августа 2011

Ну, похоже, это проблема с телефонами HTC. Это - это именно та проблема, которая у меня возникла. Здесь говорят, что это вызвано ослаблением объектива задней камеры, и решение состоит в том, чтобы сильно надавить на него большим пальцем на несколько секунд, чтобы установить его на место.

В конце концов, это не проблема программного обеспечения.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...