Проблема с не всегда получением необработанного файла из примера программы Camera2Raw - PullRequest
0 голосов
/ 01 мая 2020

У меня проблема с примером программы, которая поставляется с AndroidStudio. Я пробовал это только на S8, поэтому я не уверен, является ли это проблемой с этим конкретным устройством, или это вообще c.

Если я пытаюсь сделать несколько снимков за один снимок, установив mPendingUserCaptures в число, подобное 4, и особенно если я вручную установлю время экспозиции на низкое значение (обычно менее 30 мс или около того), я ВСЕГДА получаю 4 изображения в формате JPG, но иногда я получаю только 3 необработанных файла (последний отсутствует). Проблема в классе ImageSaver, который не всегда вызывается для файла RAW, но всегда для JPG.

Мне было интересно, кто-нибудь когда-либо испытывал что-то подобное, когда иногда не появляется RAW-изображение

1 Ответ

0 голосов
/ 03 мая 2020

Хорошо, так что после нескольких недель охоты на эту ошибку я наконец узнал, что случилось. Я разместил решение здесь, на тот случай, если кто-то еще споткнется об этой проблеме.

Иногда функция publi c void onImageAvailable (читатель ImageReader) {dequeueAndSaveImage (mRawResultQueue, mRawImageReader); } будет вызываться дважды подряд.

Код был:

    Map.Entry<Integer, ImageSaver.ImageSaverBuilder> entry = pendingQueue.firstEntry();
    ImageSaver.ImageSaverBuilder builder = entry.getValue();

Это создает огромную проблему, потому что иногда два изображения будут добавляться в одну и ту же запись TreeMap, поэтому, если мы 4 записи, последняя запись никогда не получит свое изображение: /

The fixed code (I left my extra logs there) looks like this:

   private void dequeueAndSaveImage(TreeMap<Integer, ImageSaver.ImageSaverBuilder> pendingQueue, RefCountedAutoCloseable<ImageReader> reader) {
        synchronized (mCameraStateLock) {

            ImageSaver.ImageSaverBuilder builder=null;
            Map.Entry<Integer, ImageSaver.ImageSaverBuilder> entry;
            int key=4;//shut up, stupid java shit
            for (Map.Entry<Integer, ImageSaver.ImageSaverBuilder> ent : pendingQueue.entrySet()) {
                builder = ent.getValue();
                if(builder.mImage==null) {
                    key = ent.getKey();
                    break;
                }

            }

            //Map.Entry<Integer, ImageSaver.ImageSaverBuilder> entry = pendingQueue.firstEntry();
            //ImageSaver.ImageSaverBuilder builder = entry.getValue();
            Log.w(TAG, "StartingdequeueAndSaveImage, builder: " + builder);

            if(builder.mImage!=null)
            {
                Log.w(TAG, "!!!!!!!!!!!!!!!!!!!!Builder: " + builder + " already has an image!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");
            }

            // Increment reference count to prevent ImageReader from being closed while we
            // are saving its Images in a background thread (otherwise their resources may
            // be freed while we are writing to a file).
            if (reader == null || reader.getAndRetain() == null) {
                Log.e(TAG, "Paused the activity before we could save the image," + " ImageReader already closed.");
                pendingQueue.remove(key);
                return;
            }

            Image image;
            try {
                image = reader.get().acquireNextImage();
            } catch (IllegalStateException e) {
                Log.e(TAG, "Too many images queued for saving, dropping image for request: " + key);
                pendingQueue.remove(key);
                return;
            }

            builder.setRefCountedReader(reader).setImage(image);

            if(image==null)Log.e(TAG, "Cacatul de imagine e null...... Sa ma fut in mortii lor.");

            handleCompletionLocked(key, builder, pendingQueue);
            Log.e(TAG, "Call handled completed in deque" + pendingQueue);
        }
    }
...