361 lines
11 KiB
C++
361 lines
11 KiB
C++
/* Copyright (c) 2012-2016, The Linux Foundation. All rights reserved.
|
|
*
|
|
* Redistribution and use in source and binary forms, with or without
|
|
* modification, are permitted provided that the following conditions are
|
|
* met:
|
|
* * Redistributions of source code must retain the above copyright
|
|
* notice, this list of conditions and the following disclaimer.
|
|
* * Redistributions in binary form must reproduce the above
|
|
* copyright notice, this list of conditions and the following
|
|
* disclaimer in the documentation and/or other materials provided
|
|
* with the distribution.
|
|
* * Neither the name of The Linux Foundation nor the names of its
|
|
* contributors may be used to endorse or promote products derived
|
|
* from this software without specific prior written permission.
|
|
*
|
|
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
|
|
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
|
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
|
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
|
|
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
|
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
|
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
|
|
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
|
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
|
|
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
|
|
* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
*
|
|
*/
|
|
|
|
#ifndef QCAMERA_TEST_H
|
|
#define QCAMERA_TEST_H
|
|
|
|
#include <SkData.h>
|
|
#include <SkBitmap.h>
|
|
#include <SkStream.h>
|
|
|
|
namespace qcamera {
|
|
|
|
using namespace android;
|
|
|
|
#define MAX_CAM_INSTANCES 3
|
|
|
|
class TestContext;
|
|
|
|
class CameraContext : public CameraListener,
|
|
public ICameraRecordingProxyListener{
|
|
public:
|
|
typedef enum {
|
|
READ_METADATA = 1,
|
|
READ_IMAGE = 2,
|
|
READ_ALL = 3
|
|
} ReadMode_t;
|
|
|
|
// This structure is used to store jpeg file sections in memory.
|
|
typedef struct {
|
|
unsigned char * Data;
|
|
int Type;
|
|
size_t Size;
|
|
} Sections_t;
|
|
|
|
public:
|
|
static const char KEY_ZSL[];
|
|
|
|
CameraContext(int cameraIndex);
|
|
virtual ~CameraContext();
|
|
|
|
|
|
|
|
status_t openCamera();
|
|
status_t closeCamera();
|
|
|
|
status_t startPreview();
|
|
status_t stopPreview();
|
|
status_t resumePreview();
|
|
status_t autoFocus();
|
|
status_t enablePreviewCallbacks();
|
|
status_t takePicture();
|
|
status_t startRecording();
|
|
status_t stopRecording();
|
|
status_t startViVRecording();
|
|
status_t stopViVRecording();
|
|
status_t configureViVRecording();
|
|
|
|
status_t nextPreviewSize();
|
|
status_t setPreviewSize(const char *format);
|
|
status_t getCurrentPreviewSize(Size &previewSize);
|
|
|
|
status_t nextPictureSize();
|
|
status_t getCurrentPictureSize(Size &pictureSize);
|
|
status_t setPictureSize(const char *format);
|
|
|
|
status_t nextVideoSize();
|
|
status_t setVideoSize(const char *format);
|
|
status_t getCurrentVideoSize(Size &videoSize);
|
|
status_t configureRecorder();
|
|
status_t unconfigureRecorder();
|
|
Sections_t *FindSection(int SectionType);
|
|
status_t ReadSectionsFromBuffer (unsigned char *buffer,
|
|
size_t buffer_size, ReadMode_t ReadMode);
|
|
virtual IBinder* onAsBinder();
|
|
void setTestCtxInstance(TestContext *instance);
|
|
|
|
void printMenu(sp<CameraContext> currentCamera);
|
|
void printSupportedParams();
|
|
const char *getZSL();
|
|
void setZSL(const char *value);
|
|
|
|
|
|
int getCameraIndex() { return mCameraIndex; }
|
|
int getNumberOfCameras();
|
|
void enablePrintPreview();
|
|
void disablePrintPreview();
|
|
void enablePiPCapture();
|
|
void disablePiPCapture();
|
|
void CheckSectionsAllocated();
|
|
void DiscardData();
|
|
void DiscardSections();
|
|
size_t calcBufferSize(int width, int height);
|
|
size_t calcStride(int width);
|
|
size_t calcYScanLines(int height);
|
|
size_t calcUVScanLines(int height);
|
|
|
|
virtual void notify(int32_t msgType, int32_t ext1, int32_t ext2);
|
|
virtual void postData(int32_t msgType,
|
|
const sp<IMemory>& dataPtr,
|
|
camera_frame_metadata_t *metadata);
|
|
|
|
virtual void postDataTimestamp(nsecs_t timestamp,
|
|
int32_t msgType,
|
|
const sp<IMemory>& dataPtr);
|
|
virtual void dataCallbackTimestamp(nsecs_t timestamp,
|
|
int32_t msgType,
|
|
const sp<IMemory>& dataPtr);
|
|
|
|
private:
|
|
|
|
status_t createPreviewSurface(int width, int height, int32_t pixFormat);
|
|
status_t destroyPreviewSurface();
|
|
|
|
status_t saveFile(const sp<IMemory>& mem, String8 path);
|
|
SkBitmap * PiPCopyToOneFile(SkBitmap *bitmap0, SkBitmap *bitmap1);
|
|
status_t decodeJPEG(const sp<IMemory>& mem, SkBitmap *skBM);
|
|
status_t encodeJPEG(SkWStream * stream, const SkBitmap *bitmap,
|
|
String8 path);
|
|
void previewCallback(const sp<IMemory>& mem);
|
|
|
|
static int JpegIdx;
|
|
int mCameraIndex;
|
|
bool mResizePreview;
|
|
bool mHardwareActive;
|
|
bool mPreviewRunning;
|
|
bool mRecordRunning;
|
|
int mVideoFd;
|
|
int mVideoIdx;
|
|
bool mRecordingHint;
|
|
bool mDoPrintMenu;
|
|
bool mPiPCapture;
|
|
static int mPiPIdx;
|
|
unsigned int mfmtMultiplier;
|
|
int mWidthTmp;
|
|
int mHeightTmp;
|
|
size_t mSectionsRead;
|
|
size_t mSectionsAllocated;
|
|
Sections_t * mSections;
|
|
Sections_t * mJEXIFTmp;
|
|
Sections_t mJEXIFSection;
|
|
int mHaveAll;
|
|
TestContext *mInterpr;
|
|
|
|
sp<Camera> mCamera;
|
|
sp<SurfaceComposerClient> mClient;
|
|
sp<SurfaceControl> mSurfaceControl;
|
|
sp<Surface> mPreviewSurface;
|
|
sp<MediaRecorder> mRecorder;
|
|
CameraParameters mParams;
|
|
SkBitmap *skBMDec;
|
|
SkBitmap skBMtmp;
|
|
sp<IMemory> PiPPtrTmp;
|
|
|
|
size_t mCurrentPreviewSizeIdx;
|
|
Size getPreviewSizeFromVideoSizes(Size currentVideoSize);
|
|
size_t mCurrentPictureSizeIdx;
|
|
size_t mCurrentVideoSizeIdx;
|
|
Vector<Size> mSupportedPreviewSizes;
|
|
Vector<Size> mSupportedPictureSizes;
|
|
Vector<Size> mSupportedVideoSizes;
|
|
|
|
bool mInUse;
|
|
Mutex mLock;
|
|
Condition mCond;
|
|
|
|
void useLock();
|
|
void signalFinished();
|
|
|
|
//------------------------------------------------------------------------
|
|
// JPEG markers consist of one or more 0xFF bytes, followed by a marker
|
|
// code byte (which is not an FF). Here are the marker codes of interest
|
|
// in this program. (See jdmarker.c for a more complete list.)
|
|
//------------------------------------------------------------------------
|
|
#define M_SOF0 0xC0 // Start Of Frame N
|
|
#define M_SOF1 0xC1 // N indicates which compression process
|
|
#define M_SOF2 0xC2 // Only SOF0-SOF2 are now in common use
|
|
#define M_SOF3 0xC3
|
|
#define M_SOF5 0xC5 // NB: codes C4 and CC are NOT SOF markers
|
|
#define M_SOF6 0xC6
|
|
#define M_SOF7 0xC7
|
|
#define M_SOF9 0xC9
|
|
#define M_SOF10 0xCA
|
|
#define M_SOF11 0xCB
|
|
#define M_SOF13 0xCD
|
|
#define M_SOF14 0xCE
|
|
#define M_SOF15 0xCF
|
|
#define M_SOI 0xD8 // Start Of Image (beginning of datastream)
|
|
#define M_EOI 0xD9 // End Of Image (end of datastream)
|
|
#define M_SOS 0xDA // Start Of Scan (begins compressed data)
|
|
#define M_JFIF 0xE0 // Jfif marker
|
|
#define M_EXIF 0xE1 // Exif marker. Also used for XMP data!
|
|
#define M_XMP 0x10E1 // Not a real tag same value as Exif!
|
|
#define M_COM 0xFE // COMment
|
|
#define M_DQT 0xDB
|
|
#define M_DHT 0xC4
|
|
#define M_DRI 0xDD
|
|
#define M_IPTC 0xED // IPTC marker
|
|
#define PSEUDO_IMAGE_MARKER 0x123; // Extra value.
|
|
};
|
|
|
|
class Interpreter
|
|
{
|
|
public:
|
|
enum Commands_e {
|
|
SWITCH_CAMERA_CMD = 'A',
|
|
RESUME_PREVIEW_CMD = '[',
|
|
START_PREVIEW_CMD = '1',
|
|
STOP_PREVIEW_CMD = '2',
|
|
CHANGE_VIDEO_SIZE_CMD = '3',
|
|
CHANGE_PREVIEW_SIZE_CMD = '4',
|
|
CHANGE_PICTURE_SIZE_CMD = '5',
|
|
START_RECORD_CMD = '6',
|
|
STOP_RECORD_CMD = '7',
|
|
START_VIV_RECORD_CMD = '8',
|
|
STOP_VIV_RECORD_CMD = '9',
|
|
DUMP_CAPS_CMD = 'E',
|
|
AUTOFOCUS_CMD = 'f',
|
|
TAKEPICTURE_CMD = 'p',
|
|
TAKEPICTURE_IN_PICTURE_CMD = 'P',
|
|
ENABLE_PRV_CALLBACKS_CMD = '&',
|
|
EXIT_CMD = 'q',
|
|
DELAY = 'd',
|
|
ZSL_CMD = 'z',
|
|
INVALID_CMD = '0'
|
|
};
|
|
|
|
struct Command {
|
|
Command( Commands_e cmd_, char *arg_ = NULL)
|
|
: cmd(cmd_)
|
|
, arg(arg_) {}
|
|
Command()
|
|
: cmd(INVALID_CMD)
|
|
, arg(NULL) {}
|
|
Commands_e cmd;
|
|
char *arg;
|
|
};
|
|
|
|
/* API */
|
|
Interpreter()
|
|
: mUseScript(false)
|
|
, mScript(NULL) {}
|
|
|
|
Interpreter(const char *file);
|
|
~Interpreter();
|
|
|
|
Command getCommand(sp<CameraContext> currentCamera);
|
|
void releasePiPBuff();
|
|
status_t configureViVCodec();
|
|
void setViVSize(Size VideoSize, int camIndex);
|
|
void setTestCtxInst(TestContext *instance);
|
|
status_t unconfigureViVCodec();
|
|
status_t ViVEncoderThread();
|
|
void ViVEncode();
|
|
static void *ThreadWrapper(void *context);
|
|
|
|
private:
|
|
static const int numberOfCommands;
|
|
|
|
bool mUseScript;
|
|
size_t mCmdIndex;
|
|
char *mScript;
|
|
Vector<Command> mCommands;
|
|
TestContext *mTestContext;
|
|
pthread_t mViVEncThread;
|
|
};
|
|
|
|
class TestContext
|
|
{
|
|
friend class CameraContext;
|
|
friend class Interpreter;
|
|
public:
|
|
TestContext();
|
|
~TestContext();
|
|
|
|
size_t GetCamerasNum();
|
|
status_t FunctionalTest();
|
|
status_t AddScriptFromFile(const char *scriptFile);
|
|
void setViVSize(Size VideoSize, int camIndex);
|
|
void PiPLock();
|
|
void PiPUnlock();
|
|
void ViVLock();
|
|
void ViVUnlock();
|
|
|
|
private:
|
|
sp<CameraContext> camera[MAX_CAM_INSTANCES];
|
|
char GetNextCmd(sp<qcamera::CameraContext> currentCamera);
|
|
size_t mCurrentCameraIndex;
|
|
size_t mSaveCurrentCameraIndex;
|
|
Vector< sp<qcamera::CameraContext> > mAvailableCameras;
|
|
bool mTestRunning;
|
|
Interpreter *mInterpreter;
|
|
Mutex mPiPLock;
|
|
Condition mPiPCond;
|
|
bool mPiPinUse;
|
|
Mutex mViVLock;
|
|
Condition mViVCond;
|
|
bool mViVinUse;
|
|
bool mIsZSLOn;
|
|
|
|
typedef struct ViVBuff_t{
|
|
void *buff;
|
|
size_t buffSize;
|
|
size_t YStride;
|
|
size_t UVStride;
|
|
size_t YScanLines;
|
|
size_t UVScanLines;
|
|
size_t srcWidth;
|
|
size_t srcHeight;
|
|
} ViVBuff_t;
|
|
|
|
typedef struct ViVVid_t{
|
|
sp<IGraphicBufferProducer> bufferProducer;
|
|
sp<Surface> surface;
|
|
sp<MediaCodec> codec;
|
|
sp<MediaMuxer> muxer;
|
|
sp<ANativeWindow> ANW;
|
|
Vector<sp<ABuffer> > buffers;
|
|
Size VideoSizes[2];
|
|
int ViVIdx;
|
|
size_t buff_cnt;
|
|
sp<GraphicBuffer> graphBuf;
|
|
void * mappedBuff;
|
|
bool isBuffValid;
|
|
int sourceCameraID;
|
|
int destinationCameraID;
|
|
} vidPiP_t;
|
|
|
|
ViVVid_t mViVVid;
|
|
ViVBuff_t mViVBuff;
|
|
};
|
|
|
|
}; //namespace qcamera
|
|
|
|
#endif
|