/*
 * Copyright (C) 2012 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef ANDROID_SERVERS_CAMERA_CAMERA2_STREAMINGPROCESSOR_H
#define ANDROID_SERVERS_CAMERA_CAMERA2_STREAMINGPROCESSOR_H

#include <utils/Mutex.h>
#include <utils/String16.h>
#include <gui/BufferItemConsumer.h>

#include "camera/CameraMetadata.h"

namespace android {

class Camera2Client;
class CameraDeviceBase;
class IMemory;

namespace camera2 {

class Parameters;
class Camera2Heap;

/**
 * Management and processing for preview and recording streams
 */
class StreamingProcessor:
            public Thread, public BufferItemConsumer::FrameAvailableListener {
  public:
    StreamingProcessor(sp<Camera2Client> client);
    ~StreamingProcessor();

    status_t setPreviewWindow(sp<Surface> window);

    bool haveValidPreviewWindow() const;

    status_t updatePreviewRequest(const Parameters &params);
    status_t updatePreviewStream(const Parameters &params);
    status_t deletePreviewStream();
    int getPreviewStreamId() const;

    status_t setRecordingBufferCount(size_t count);
    status_t setRecordingFormat(int format, android_dataspace_t dataspace);

    status_t updateRecordingRequest(const Parameters &params);
    // If needsUpdate is set to true, a updateRecordingStream call with params will recreate
    // recording stream
    status_t recordingStreamNeedsUpdate(const Parameters &params, bool *needsUpdate);
    status_t updateRecordingStream(const Parameters &params);
    status_t deleteRecordingStream();
    int getRecordingStreamId() const;

    enum StreamType {
        NONE,
        PREVIEW,
        RECORD
    };
    status_t startStream(StreamType type,
            const Vector<int32_t> &outputStreams);

    // Toggle between paused and unpaused. Stream must be started first.
    status_t togglePauseStream(bool pause);

    status_t stopStream();

    // Returns the request ID for the currently streaming request
    // Returns 0 if there is no active request.
    status_t getActiveRequestId() const;
    status_t incrementStreamingIds();

    // Callback for new recording frames from HAL
    virtual void onFrameAvailable(const BufferItem& item);
    // Callback from stagefright which returns used recording frames
    void releaseRecordingFrame(const sp<IMemory>& mem);

    status_t dump(int fd, const Vector<String16>& args);

  private:
    mutable Mutex mMutex;

    enum {
        NO_STREAM = -1
    };

    wp<Camera2Client> mClient;
    wp<CameraDeviceBase> mDevice;
    int mId;

    StreamType mActiveRequest;
    bool mPaused;

    Vector<int32_t> mActiveStreamIds;

    // Preview-related members
    int32_t mPreviewRequestId;
    int mPreviewStreamId;
    CameraMetadata mPreviewRequest;
    sp<Surface> mPreviewWindow;

    // Recording-related members
    static const nsecs_t kWaitDuration = 50000000; // 50 ms

    int32_t mRecordingRequestId;
    int mRecordingStreamId;
    int mRecordingFrameCount;
    sp<BufferItemConsumer> mRecordingConsumer;
    sp<Surface>  mRecordingWindow;
    CameraMetadata mRecordingRequest;
    sp<camera2::Camera2Heap> mRecordingHeap;

    bool mRecordingFrameAvailable;
    Condition mRecordingFrameAvailableSignal;

    static const size_t kDefaultRecordingHeapCount = 8;
    size_t mRecordingHeapCount;
    Vector<BufferItem> mRecordingBuffers;
    size_t mRecordingHeapHead, mRecordingHeapFree;

    static const int kDefaultRecordingFormat =
            HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED;
    int mRecordingFormat;

    static const android_dataspace kDefaultRecordingDataSpace =
            HAL_DATASPACE_BT709;
    android_dataspace mRecordingDataSpace;

    static const int kDefaultRecordingGrallocUsage =
            GRALLOC_USAGE_HW_VIDEO_ENCODER;
    int mRecordingGrallocUsage;

    virtual bool threadLoop();

    status_t processRecordingFrame();

    // Unilaterally free any buffers still outstanding to stagefright
    void releaseAllRecordingFramesLocked();

    // Determine if the specified stream is currently in use
    static bool isStreamActive(const Vector<int32_t> &streams,
            int32_t recordingStreamId);
};


}; // namespace camera2
}; // namespace android

#endif
