作者 ookk303

更新

正在显示 18 个修改的文件 包含 4858 行增加3 行删除

要显示太多修改。

为保证性能只显示 18 of 18+ 个文件。

... ... @@ -8,8 +8,20 @@ ModuleLib
project_build/AUTEL_道通PSDK
project_build/GDU_普宙PSDK
project_build/Only_Serial/build
project_build/Only_Serial/Upgrade_Package
project_build/Only_Serial/*
!project_build/Only_Serial/application
!project_build/Only_Serial/CMakeLists.txt
project_build/DJI_大疆PSDK
project_build/DJI_大疆PSDK/*
!project_build/DJI_大疆PSDK/samples
project_build/DJI_大疆PSDK/samples/sample_c++
project_build/DJI_大疆PSDK/samples/sample_c/platform/*
!project_build/DJI_大疆PSDK/samples/sample_c/platform/linux
project_build/DJI_大疆PSDK/samples/sample_c/platform/linux/all/*
!project_build/DJI_大疆PSDK/samples/sample_c/platform/linux/all/application
!project_build/DJI_大疆PSDK/samples/sample_c/platform/linux/all/hal
!project_build/DJI_大疆PSDK/samples/sample_c/platform/linux/all/CMakeLists.txt
... ...
/**
********************************************************************
* @file dji_media_file_core.c
* @brief
*
* @copyright (c) 2021 DJI. All rights reserved.
*
* All information contained herein is, and remains, the property of DJI.
* The intellectual and technical concepts contained herein are proprietary
* to DJI and may be covered by U.S. and foreign patents, patents in process,
* and protected by trade secret or copyright law. Dissemination of this
* information, including but not limited to data and other proprietary
* material(s) incorporated within the information, in any form, is strictly
* prohibited without the express written consent of DJI.
*
* If you receive this source code without DJI’s authorization, you may not
* further disseminate the information, and you must immediately remove the
* source code and notify DJI of its removal. DJI reserves the right to pursue
* legal actions against you for any loss(es) or damage(s) caused by your
* failure to do so.
*
*********************************************************************
*/
/* Includes ------------------------------------------------------------------*/
#include <string.h>
#include <dji_logger.h>
#include "dji_media_file_core.h"
#include "dji_media_file_jpg.h"
#include "dji_media_file_mp4.h"
#include "dji_platform.h"
/* Private constants ---------------------------------------------------------*/
/* Private types -------------------------------------------------------------*/
/* Private functions declaration ---------------------------------------------*/
/* Private values ------------------------------------------------------------*/
//@formatter:off
static const T_DjiMediaFileOptItem s_mediaFileOpt[] =
{
//JPEG File Operation Item
{
DJI_CAMERA_FILE_TYPE_JPEG ,
DjiMediaFile_IsSupported_JPG,
DjiMediaFile_GetAttrFunc_JPG,
DjiMediaFile_GetDataOrigin_JPG,
DjiMediaFile_GetFileSizeOrigin_JPG,
DjiMediaFile_CreateThumbNail_JPG,
DjiMediaFile_GetFileSizeThumbNail_JPG,
DjiMediaFile_GetDataThumbNail_JPG,
DjiMediaFile_DestroyThumbNail_JPG,
DjiMediaFile_CreateScreenNail_JPG,
DjiMediaFile_GetFileSizeScreenNail_JPG,
DjiMediaFile_GetDataScreenNail_JPG,
DjiMediaFile_DestroyScreenNail_JPG,
},
//MP4 File Operation Item
{
DJI_CAMERA_FILE_TYPE_MP4 ,
DjiMediaFile_IsSupported_MP4,
DjiMediaFile_GetAttrFunc_MP4,
DjiMediaFile_GetDataOrigin_MP4,
DjiMediaFile_GetFileSizeOrigin_MP4,
DjiMediaFile_CreateThumbNail_MP4,
DjiMediaFile_GetFileSizeThumbNail_MP4,
DjiMediaFile_GetDataThumbNail_MP4,
DjiMediaFile_DestroyThumbNail_MP4,
DjiMediaFile_CreateScreenNail_MP4,
DjiMediaFile_GetFileSizeScreenNail_MP4,
DjiMediaFile_GetDataScreenNail_MP4,
DjiMediaFile_DestroyScreenNail_MP4,
},
};
static const uint32_t s_mediaFileOptCount = sizeof (s_mediaFileOpt) / sizeof(T_DjiMediaFileOptItem);
//@formatter:on
/* Exported functions definition ---------------------------------------------*/
bool DjiMediaFile_IsSupported(const char *filePath)
{
int i;
for (i = 0; i < s_mediaFileOptCount; i++) {
if (s_mediaFileOpt[i].isSupportedFunc(filePath) == true) {
return true;
}
}
return false;
}
T_DjiReturnCode DjiMediaFile_CreateHandle(const char *filePath, T_DjiMediaFileHandle *pMediaFileHandle)
{
int optIndex;
T_DjiOsalHandler *osalHandler = DjiPlatform_GetOsalHandler();
for (optIndex = 0; optIndex < s_mediaFileOptCount; optIndex++) {
if (s_mediaFileOpt[optIndex].isSupportedFunc(filePath) == true) {
break;
}
}
if (optIndex == s_mediaFileOptCount) {
return DJI_ERROR_SYSTEM_MODULE_CODE_INVALID_PARAMETER;
}
*pMediaFileHandle = osalHandler->Malloc(sizeof(T_DjiMediaFile));
if (*pMediaFileHandle == NULL) {
return DJI_ERROR_SYSTEM_MODULE_CODE_MEMORY_ALLOC_FAILED;
}
(*pMediaFileHandle)->filePath = osalHandler->Malloc(strlen(filePath) + 1);
if ((*pMediaFileHandle)->filePath == NULL) {
return DJI_ERROR_SYSTEM_MODULE_CODE_MEMORY_ALLOC_FAILED;
}
(*pMediaFileHandle)->mediaFileOptItem = s_mediaFileOpt[optIndex];
(*pMediaFileHandle)->mediaFileThm.privThm = NULL;
(*pMediaFileHandle)->mediaFileScr.privScr = NULL;
strcpy((*pMediaFileHandle)->filePath, filePath);
return DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS;
}
T_DjiReturnCode DjiMediaFile_DestroyHandle(T_DjiMediaFileHandle mediaFileHandle)
{
T_DjiOsalHandler *osalHandler = DjiPlatform_GetOsalHandler();
osalHandler->Free(mediaFileHandle->filePath);
osalHandler->Free(mediaFileHandle);
return DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS;
}
T_DjiReturnCode DjiMediaFile_GetMediaFileType(T_DjiMediaFileHandle mediaFileHandle,
E_DjiCameraMediaFileType *mediaFileType)
{
*mediaFileType = mediaFileHandle->mediaFileOptItem.mediaFileType;
return DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS;
}
T_DjiReturnCode DjiMediaFile_GetMediaFileAttr(T_DjiMediaFileHandle mediaFileHandle,
T_DjiCameraMediaFileAttr *mediaFileAttr)
{
if (mediaFileHandle->mediaFileOptItem.getAttrFunc == NULL) {
USER_LOG_ERROR("Media file handle getAttrFunc null error");
return DJI_ERROR_SYSTEM_MODULE_CODE_INVALID_PARAMETER;
}
return mediaFileHandle->mediaFileOptItem.getAttrFunc(mediaFileHandle, mediaFileAttr);
}
T_DjiReturnCode DjiMediaFile_GetDataOrg(struct _DjiMediaFile *mediaFileHandle, uint32_t offset, uint16_t len,
uint8_t *data, uint32_t *realLen)
{
if (mediaFileHandle->mediaFileOptItem.getDataOrgFunc == NULL) {
USER_LOG_ERROR("Media file handle getDataOrgFunc null error");
return DJI_ERROR_SYSTEM_MODULE_CODE_INVALID_PARAMETER;
}
return mediaFileHandle->mediaFileOptItem.getDataOrgFunc(mediaFileHandle, offset, len, data, realLen);
}
T_DjiReturnCode DjiMediaFile_GetFileSizeOrg(struct _DjiMediaFile *mediaFileHandle, uint32_t *fileSize)
{
if (mediaFileHandle->mediaFileOptItem.getFileSizeOrgFunc == NULL) {
USER_LOG_ERROR("Media file handle getFileSizeOrgFunc null error");
return DJI_ERROR_SYSTEM_MODULE_CODE_INVALID_PARAMETER;
}
return mediaFileHandle->mediaFileOptItem.getFileSizeOrgFunc(mediaFileHandle, fileSize);
}
T_DjiReturnCode DjiMediaFile_CreateThm(T_DjiMediaFileHandle mediaFileHandle)
{
if (mediaFileHandle->mediaFileOptItem.createThmFunc == NULL) {
USER_LOG_ERROR("Media file handle createThmFunc null error");
return DJI_ERROR_SYSTEM_MODULE_CODE_INVALID_PARAMETER;
}
return mediaFileHandle->mediaFileOptItem.createThmFunc(mediaFileHandle);
}
T_DjiReturnCode DjiMediaFile_GetFileSizeThm(T_DjiMediaFileHandle mediaFileHandle, uint32_t *fileSize)
{
if (mediaFileHandle->mediaFileOptItem.getFileSizeThmFunc == NULL) {
USER_LOG_ERROR("Media file handle getFileSizeThmFunc null error");
return DJI_ERROR_SYSTEM_MODULE_CODE_INVALID_PARAMETER;
}
return mediaFileHandle->mediaFileOptItem.getFileSizeThmFunc(mediaFileHandle, fileSize);
}
T_DjiReturnCode DjiMediaFile_GetDataThm(T_DjiMediaFileHandle mediaFileHandle, uint32_t offset, uint16_t len,
uint8_t *data, uint16_t *realLen)
{
if (mediaFileHandle->mediaFileOptItem.getDataThmFunc == NULL) {
USER_LOG_ERROR("Media file handle getDataThmFunc null error");
return DJI_ERROR_SYSTEM_MODULE_CODE_INVALID_PARAMETER;
}
return mediaFileHandle->mediaFileOptItem.getDataThmFunc(mediaFileHandle, offset, len, data, realLen);
}
T_DjiReturnCode DjiMediaFile_DestoryThm(T_DjiMediaFileHandle mediaFileHandle)
{
if (mediaFileHandle->mediaFileOptItem.destroyThmFunc == NULL) {
USER_LOG_ERROR("Media file handle destroyThmFunc null error");
return DJI_ERROR_SYSTEM_MODULE_CODE_INVALID_PARAMETER;
}
return mediaFileHandle->mediaFileOptItem.destroyThmFunc(mediaFileHandle);
}
T_DjiReturnCode DjiMediaFile_CreateScr(T_DjiMediaFileHandle mediaFileHandle)
{
if (mediaFileHandle->mediaFileOptItem.creatScrFunc == NULL) {
USER_LOG_ERROR("Media file handle creatScrFunc null error");
return DJI_ERROR_SYSTEM_MODULE_CODE_INVALID_PARAMETER;
}
return mediaFileHandle->mediaFileOptItem.creatScrFunc(mediaFileHandle);
}
T_DjiReturnCode DjiMediaFile_GetFileSizeScr(T_DjiMediaFileHandle mediaFileHandle, uint32_t *fileSize)
{
if (mediaFileHandle->mediaFileOptItem.getFileSizeScrFunc == NULL) {
USER_LOG_ERROR("Media file handle getFileSizeScrFunc null error");
return DJI_ERROR_SYSTEM_MODULE_CODE_INVALID_PARAMETER;
}
return mediaFileHandle->mediaFileOptItem.getFileSizeScrFunc(mediaFileHandle, fileSize);
}
T_DjiReturnCode DjiMediaFile_GetDataScr(T_DjiMediaFileHandle mediaFileHandle, uint32_t offset, uint16_t len,
uint8_t *data, uint16_t *realLen)
{
if (mediaFileHandle->mediaFileOptItem.getDataScrFunc == NULL) {
USER_LOG_ERROR("Media file handle getDataScrFunc null error");
return DJI_ERROR_SYSTEM_MODULE_CODE_INVALID_PARAMETER;
}
return mediaFileHandle->mediaFileOptItem.getDataScrFunc(mediaFileHandle, offset, len, data, realLen);
}
T_DjiReturnCode DjiMediaFile_DestroyScr(T_DjiMediaFileHandle mediaFileHandle)
{
if (mediaFileHandle->mediaFileOptItem.destroyScrFunc == NULL) {
USER_LOG_ERROR("Media file handle destroyScrFunc null error");
return DJI_ERROR_SYSTEM_MODULE_CODE_INVALID_PARAMETER;
}
return mediaFileHandle->mediaFileOptItem.destroyScrFunc(mediaFileHandle);
}
/* Private functions definition-----------------------------------------------*/
/****************** (C) COPYRIGHT DJI Innovations *****END OF FILE****/
... ...
/**
********************************************************************
* @file dji_media_file_core.h
* @brief This is the header file for "dji_media_file_core.c", defining the structure and
* (exported) function prototypes.
*
* @copyright (c) 2021 DJI. All rights reserved.
*
* All information contained herein is, and remains, the property of DJI.
* The intellectual and technical concepts contained herein are proprietary
* to DJI and may be covered by U.S. and foreign patents, patents in process,
* and protected by trade secret or copyright law. Dissemination of this
* information, including but not limited to data and other proprietary
* material(s) incorporated within the information, in any form, is strictly
* prohibited without the express written consent of DJI.
*
* If you receive this source code without DJI’s authorization, you may not
* further disseminate the information, and you must immediately remove the
* source code and notify DJI of its removal. DJI reserves the right to pursue
* legal actions against you for any loss(es) or damage(s) caused by your
* failure to do so.
*
*********************************************************************
*/
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef PSDK_MEDIA_FILE_CORE_H
#define PSDK_MEDIA_FILE_CORE_H
#ifdef __cplusplus
extern "C" {
#endif
/* Includes ------------------------------------------------------------------*/
#include <dji_typedef.h>
#include <dji_payload_camera.h>
/* Exported constants --------------------------------------------------------*/
#define PSDK_MEDIA_FILE_PATH_LEN_MAX 512 /*max file path len */
#define PSDK_MEDIA_DIR_PATH_LEN_MAX 256 /*max dir path len */
/* Exported types ------------------------------------------------------------*/
typedef struct {
void *privThm;
} T_DjiMediaFileThm;
typedef struct {
void *privScr;
} T_DjiMediaFileScr;
struct _DjiMediaFile;
typedef struct {
E_DjiCameraMediaFileType mediaFileType;
bool (*isSupportedFunc)(const char *filePath);
T_DjiReturnCode (*getAttrFunc)(struct _DjiMediaFile *mediaFileHandle, T_DjiCameraMediaFileAttr *mediaFileAttr);
T_DjiReturnCode (*getDataOrgFunc)(struct _DjiMediaFile *mediaFileHandle, uint32_t offset, uint16_t len,
uint8_t *data, uint32_t *realLen);
T_DjiReturnCode (*getFileSizeOrgFunc)(struct _DjiMediaFile *mediaFileHandle, uint32_t *fileSize);
T_DjiReturnCode (*createThmFunc)(struct _DjiMediaFile *mediaFileHandle);
T_DjiReturnCode (*getFileSizeThmFunc)(struct _DjiMediaFile *mediaFileHandle, uint32_t *fileSize);
T_DjiReturnCode (*getDataThmFunc)(struct _DjiMediaFile *mediaFileHandle, uint32_t offset, uint16_t len,
uint8_t *data, uint16_t *realLen);
T_DjiReturnCode (*destroyThmFunc)(struct _DjiMediaFile *mediaFileHandle);
T_DjiReturnCode (*creatScrFunc)(struct _DjiMediaFile *mediaFileHandle);
T_DjiReturnCode (*getFileSizeScrFunc)(struct _DjiMediaFile *mediaFileHandle, uint32_t *fileSize);
T_DjiReturnCode (*getDataScrFunc)(struct _DjiMediaFile *mediaFileHandle, uint32_t offset, uint16_t len,
uint8_t *data, uint16_t *realLen);
T_DjiReturnCode (*destroyScrFunc)(struct _DjiMediaFile *mediaFileHandle);
} T_DjiMediaFileOptItem;
typedef struct _DjiMediaFile {
char *filePath;
T_DjiMediaFileOptItem mediaFileOptItem;
T_DjiMediaFileThm mediaFileThm;
T_DjiMediaFileScr mediaFileScr;
} T_DjiMediaFile, *T_DjiMediaFileHandle;
/* Exported functions --------------------------------------------------------*/
bool DjiMediaFile_IsSupported(const char *filePath);
T_DjiReturnCode DjiMediaFile_CreateHandle(const char *filePath, T_DjiMediaFileHandle *pMediaFileHandle);
T_DjiReturnCode DjiMediaFile_DestroyHandle(T_DjiMediaFileHandle mediaFileHandle);
T_DjiReturnCode DjiMediaFile_GetMediaFileType(T_DjiMediaFileHandle mediaFileHandle,
E_DjiCameraMediaFileType *mediaFileType);
T_DjiReturnCode DjiMediaFile_GetMediaFileAttr(T_DjiMediaFileHandle mediaFileHandle,
T_DjiCameraMediaFileAttr *mediaFileAttr);
T_DjiReturnCode DjiMediaFile_GetDataOrg(struct _DjiMediaFile *mediaFileHandle, uint32_t offset, uint16_t len,
uint8_t *data, uint32_t *realLen);
T_DjiReturnCode DjiMediaFile_GetFileSizeOrg(struct _DjiMediaFile *mediaFileHandle, uint32_t *fileSize);
T_DjiReturnCode DjiMediaFile_CreateThm(T_DjiMediaFileHandle mediaFileHandle);
T_DjiReturnCode DjiMediaFile_GetFileSizeThm(T_DjiMediaFileHandle mediaFileHandle, uint32_t *fileSize);
T_DjiReturnCode DjiMediaFile_GetDataThm(T_DjiMediaFileHandle mediaFileHandle, uint32_t offset, uint16_t len,
uint8_t *data, uint16_t *realLen);
T_DjiReturnCode DjiMediaFile_DestoryThm(T_DjiMediaFileHandle mediaFileHandle);
T_DjiReturnCode DjiMediaFile_CreateScr(T_DjiMediaFileHandle mediaFileHandle);
T_DjiReturnCode DjiMediaFile_GetFileSizeScr(T_DjiMediaFileHandle mediaFileHandle, uint32_t *fileSize);
T_DjiReturnCode DjiMediaFile_GetDataScr(T_DjiMediaFileHandle mediaFileHandle, uint32_t offset, uint16_t len,
uint8_t *data, uint16_t *realLen);
T_DjiReturnCode DjiMediaFile_DestroyScr(T_DjiMediaFileHandle mediaFileHandle);
#ifdef __cplusplus
}
#endif
#endif // PSDK_MEDIA_FILE_CORE_H
/************************ (C) COPYRIGHT DJI Innovations *******END OF FILE******/
... ...
/**
********************************************************************
* @file dji_media_file_jpg.c
* @brief
*
* @copyright (c) 2021 DJI. All rights reserved.
*
* All information contained herein is, and remains, the property of DJI.
* The intellectual and technical concepts contained herein are proprietary
* to DJI and may be covered by U.S. and foreign patents, patents in process,
* and protected by trade secret or copyright law. Dissemination of this
* information, including but not limited to data and other proprietary
* material(s) incorporated within the information, in any form, is strictly
* prohibited without the express written consent of DJI.
*
* If you receive this source code without DJI’s authorization, you may not
* further disseminate the information, and you must immediately remove the
* source code and notify DJI of its removal. DJI reserves the right to pursue
* legal actions against you for any loss(es) or damage(s) caused by your
* failure to do so.
*
*********************************************************************
*/
/* Includes ------------------------------------------------------------------*/
#include "dji_media_file_jpg.h"
#include "dji_media_file_core.h"
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <dji_logger.h>
#include <utils/util_misc.h>
#include "dji_platform.h"
#include "utils/util_time.h"
#include "utils/util_file.h"
/* Private constants ---------------------------------------------------------*/
#define JPG_FILE_SUFFIX ".jpg"
#define JPG_TEMP_FILE_TEMPLATE_STR "JPG_TEMP_XXXXXX.jpg"
#define JPG_TEMP_FILE_PATH_MAX_LEN 50
#define FFMPEG_CMD_BUF_SIZE 1024
#define JPG_THM_SCALE_CFG_STR "scale=100:-1"
#define JPG_SCR_SCALE_CFG_STR "scale=600:-1"
/* Private types -------------------------------------------------------------*/
typedef struct {
FILE *tempFile;
char tempfilePath[JPG_TEMP_FILE_PATH_MAX_LEN];
} T_DjiJPGTempFilePriv;
/* Private functions declaration ---------------------------------------------*/
static T_DjiReturnCode DjiMediaFile_CreateTempFilePriv_JPG(const char *srcFilePath, const char *scaleCfgStr,
T_DjiJPGTempFilePriv **pTempFilePrivHandle);
static T_DjiReturnCode DjiMediaFile_DestroyTempFilePriv_JPG(T_DjiJPGTempFilePriv *tempFilePrivHandle);
/* Exported functions definition ---------------------------------------------*/
bool DjiMediaFile_IsSupported_JPG(const char *filePath)
{
if (filePath == NULL) {
USER_LOG_ERROR("input parameter is null error");
return false;
}
if (strcmp(&filePath[strlen(filePath) - 4], JPG_FILE_SUFFIX) == 0) {
return true;
}
return false;
}
T_DjiReturnCode DjiMediaFile_GetAttrFunc_JPG(struct _DjiMediaFile *mediaFileHandle,
T_DjiCameraMediaFileAttr *mediaFileAttr)
{
USER_UTIL_UNUSED(mediaFileHandle);
mediaFileAttr->attrVideoDuration = 0;
return DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS;
}
T_DjiReturnCode DjiMediaFile_GetDataOrigin_JPG(struct _DjiMediaFile *mediaFileHandle, uint32_t offset, uint16_t len,
uint8_t *data, uint32_t *realLen)
{
return UtilFile_GetFileDataByPath(mediaFileHandle->filePath, offset, len, data, realLen);
}
T_DjiReturnCode DjiMediaFile_GetFileSizeOrigin_JPG(struct _DjiMediaFile *mediaFileHandle, uint32_t *fileSize)
{
return UtilFile_GetFileSizeByPath(mediaFileHandle->filePath, fileSize);
}
T_DjiReturnCode DjiMediaFile_CreateThumbNail_JPG(struct _DjiMediaFile *mediaFileHandle)
{
return DjiMediaFile_CreateTempFilePriv_JPG(mediaFileHandle->filePath, JPG_THM_SCALE_CFG_STR,
(T_DjiJPGTempFilePriv **) &mediaFileHandle->mediaFileThm.privThm);
}
T_DjiReturnCode DjiMediaFile_GetFileSizeThumbNail_JPG(struct _DjiMediaFile *mediaFileHandle, uint32_t *fileSize)
{
T_DjiJPGTempFilePriv *jpgFileThmPriv = (T_DjiJPGTempFilePriv *) mediaFileHandle->mediaFileThm.privThm;
return UtilFile_GetFileSize(jpgFileThmPriv->tempFile, fileSize);
}
T_DjiReturnCode
DjiMediaFile_GetDataThumbNail_JPG(struct _DjiMediaFile *mediaFileHandle, uint32_t offset, uint16_t len,
uint8_t *data, uint16_t *realLen)
{
T_DjiJPGTempFilePriv *jpgFileThmPriv = (T_DjiJPGTempFilePriv *) mediaFileHandle->mediaFileThm.privThm;
return UtilFile_GetFileData(jpgFileThmPriv->tempFile, offset, len, data, realLen);
}
T_DjiReturnCode DjiMediaFile_DestroyThumbNail_JPG(struct _DjiMediaFile *mediaFileHandle)
{
return DjiMediaFile_DestroyTempFilePriv_JPG(mediaFileHandle->mediaFileThm.privThm);
}
T_DjiReturnCode DjiMediaFile_CreateScreenNail_JPG(struct _DjiMediaFile *mediaFileHandle)
{
return DjiMediaFile_CreateTempFilePriv_JPG(mediaFileHandle->filePath, JPG_SCR_SCALE_CFG_STR,
(T_DjiJPGTempFilePriv **) &mediaFileHandle->mediaFileScr.privScr);
}
T_DjiReturnCode DjiMediaFile_GetFileSizeScreenNail_JPG(struct _DjiMediaFile *mediaFileHandle, uint32_t *fileSize)
{
T_DjiJPGTempFilePriv *jpgFileScrPriv = (T_DjiJPGTempFilePriv *) mediaFileHandle->mediaFileScr.privScr;
return UtilFile_GetFileSize(jpgFileScrPriv->tempFile, fileSize);
}
T_DjiReturnCode
DjiMediaFile_GetDataScreenNail_JPG(struct _DjiMediaFile *mediaFileHandle, uint32_t offset, uint16_t len,
uint8_t *data, uint16_t *realLen)
{
T_DjiJPGTempFilePriv *jpgFileScrPriv = (T_DjiJPGTempFilePriv *) mediaFileHandle->mediaFileScr.privScr;
return UtilFile_GetFileData(jpgFileScrPriv->tempFile, offset, len, data, realLen);
}
T_DjiReturnCode DjiMediaFile_DestroyScreenNail_JPG(struct _DjiMediaFile *mediaFileHandle)
{
return DjiMediaFile_DestroyTempFilePriv_JPG(mediaFileHandle->mediaFileScr.privScr);
}
/* Private functions definition-----------------------------------------------*/
static T_DjiReturnCode DjiMediaFile_CreateTempFilePriv_JPG(const char *srcFilePath, const char *scaleCfgStr,
T_DjiJPGTempFilePriv **pTempFilePrivHandle)
{
char ffmpeg_cmd[FFMPEG_CMD_BUF_SIZE];
int cmdRet;
T_DjiRunTimeStamps tiStart, tiEnd;
T_DjiJPGTempFilePriv *jpgTempFilePriv;
T_DjiReturnCode psdkStat;
int tempFd;
T_DjiOsalHandler *osalHandler = DjiPlatform_GetOsalHandler();
tiStart = DjiUtilTime_GetRunTimeStamps();
*pTempFilePrivHandle = osalHandler->Malloc(sizeof(T_DjiJPGTempFilePriv));
if (*pTempFilePrivHandle == NULL) {
return DJI_ERROR_SYSTEM_MODULE_CODE_MEMORY_ALLOC_FAILED;
}
jpgTempFilePriv = *pTempFilePrivHandle;
//get temp file name
strcpy(jpgTempFilePriv->tempfilePath, JPG_TEMP_FILE_TEMPLATE_STR);
tempFd = mkstemps(jpgTempFilePriv->tempfilePath, strlen(JPG_FILE_SUFFIX));
if (tempFd < 0) {
USER_LOG_ERROR("JPG Create Temp File Error, tempFd = %d\n", tempFd);
psdkStat = DJI_ERROR_SYSTEM_MODULE_CODE_SYSTEM_ERROR;
goto err_create_temp;
}
close(tempFd);
unlink(jpgTempFilePriv->tempfilePath);
//ffmpeg cmd send
snprintf(ffmpeg_cmd, FFMPEG_CMD_BUF_SIZE, "ffmpeg -i \"%s\" -vf %s %s 1>/dev/null 2>&1",
srcFilePath, scaleCfgStr, jpgTempFilePriv->tempfilePath);
cmdRet = system(ffmpeg_cmd);
tiEnd = DjiUtilTime_GetRunTimeStamps();
USER_LOG_DEBUG("JPG Create TempFile, RealTime = %ld us\n", tiEnd.realUsec - tiStart.realUsec);
if (cmdRet != 0) {
USER_LOG_ERROR("JPG ffmpeg cmd call error, ret = %d\n", cmdRet);
psdkStat = DJI_ERROR_SYSTEM_MODULE_CODE_SYSTEM_ERROR;
goto err_system_cmd;
}
//open temp file
jpgTempFilePriv->tempFile = fopen(jpgTempFilePriv->tempfilePath, "rb+");
if (jpgTempFilePriv->tempFile == NULL) {
psdkStat = DJI_ERROR_SYSTEM_MODULE_CODE_SYSTEM_ERROR;
goto err_file_open;
}
//unlink temp file
unlink(jpgTempFilePriv->tempfilePath);
return DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS;
err_file_open:
unlink(jpgTempFilePriv->tempfilePath);
err_system_cmd:
err_create_temp:
osalHandler->Free(*pTempFilePrivHandle);
return psdkStat;
}
static T_DjiReturnCode DjiMediaFile_DestroyTempFilePriv_JPG(T_DjiJPGTempFilePriv *tempFilePrivHandle)
{
T_DjiOsalHandler *osalHandler = DjiPlatform_GetOsalHandler();
fclose(tempFilePrivHandle->tempFile);
osalHandler->Free(tempFilePrivHandle);
return DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS;
}
/****************** (C) COPYRIGHT DJI Innovations *****END OF FILE****/
... ...
/**
********************************************************************
* @file dji_media_file_jpg.h
* @brief This is the header file for "dji_media_file_jpg.c", defining the structure and
* (exported) function prototypes.
*
* @copyright (c) 2021 DJI. All rights reserved.
*
* All information contained herein is, and remains, the property of DJI.
* The intellectual and technical concepts contained herein are proprietary
* to DJI and may be covered by U.S. and foreign patents, patents in process,
* and protected by trade secret or copyright law. Dissemination of this
* information, including but not limited to data and other proprietary
* material(s) incorporated within the information, in any form, is strictly
* prohibited without the express written consent of DJI.
*
* If you receive this source code without DJI’s authorization, you may not
* further disseminate the information, and you must immediately remove the
* source code and notify DJI of its removal. DJI reserves the right to pursue
* legal actions against you for any loss(es) or damage(s) caused by your
* failure to do so.
*
*********************************************************************
*/
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef PSDK_MEDIA_FILE_JPG_H
#define PSDK_MEDIA_FILE_JPG_H
#ifdef __cplusplus
extern "C" {
#endif
/* Includes ------------------------------------------------------------------*/
#include <dji_payload_camera.h>
#include <dji_typedef.h>
#include "dji_media_file_core.h"
/* Exported constants --------------------------------------------------------*/
/* Exported types ------------------------------------------------------------*/
/* Exported functions --------------------------------------------------------*/
bool DjiMediaFile_IsSupported_JPG(const char *filePath);
T_DjiReturnCode DjiMediaFile_GetAttrFunc_JPG(struct _DjiMediaFile *mediaFileHandle,
T_DjiCameraMediaFileAttr *mediaFileAttr);
T_DjiReturnCode DjiMediaFile_GetDataOrigin_JPG(struct _DjiMediaFile *mediaFileHandle, uint32_t offset, uint16_t len,
uint8_t *data, uint32_t *realLen);
T_DjiReturnCode DjiMediaFile_GetFileSizeOrigin_JPG(struct _DjiMediaFile *mediaFileHandle, uint32_t *fileSize);
T_DjiReturnCode DjiMediaFile_CreateThumbNail_JPG(struct _DjiMediaFile *mediaFileHandle);
T_DjiReturnCode DjiMediaFile_GetFileSizeThumbNail_JPG(struct _DjiMediaFile *mediaFileHandle, uint32_t *fileSize);
T_DjiReturnCode
DjiMediaFile_GetDataThumbNail_JPG(struct _DjiMediaFile *mediaFileHandle, uint32_t offset, uint16_t len,
uint8_t *data, uint16_t *realLen);
T_DjiReturnCode DjiMediaFile_DestroyThumbNail_JPG(struct _DjiMediaFile *mediaFileHandle);
T_DjiReturnCode DjiMediaFile_CreateScreenNail_JPG(struct _DjiMediaFile *mediaFileHandle);
T_DjiReturnCode DjiMediaFile_GetFileSizeScreenNail_JPG(struct _DjiMediaFile *mediaFileHandle, uint32_t *fileSize);
T_DjiReturnCode
DjiMediaFile_GetDataScreenNail_JPG(struct _DjiMediaFile *mediaFileHandle, uint32_t offset, uint16_t len,
uint8_t *data, uint16_t *realLen);
T_DjiReturnCode DjiMediaFile_DestroyScreenNail_JPG(struct _DjiMediaFile *mediaFileHandle);
#ifdef __cplusplus
}
#endif
#endif // PSDK_MEIDA_FILE_JPG_H
/************************ (C) COPYRIGHT DJI Innovations *******END OF FILE******/
... ...
/**
********************************************************************
* @file dji_media_file_mp4.c
* @brief
*
* @copyright (c) 2021 DJI. All rights reserved.
*
* All information contained herein is, and remains, the property of DJI.
* The intellectual and technical concepts contained herein are proprietary
* to DJI and may be covered by U.S. and foreign patents, patents in process,
* and protected by trade secret or copyright law. Dissemination of this
* information, including but not limited to data and other proprietary
* material(s) incorporated within the information, in any form, is strictly
* prohibited without the express written consent of DJI.
*
* If you receive this source code without DJI’s authorization, you may not
* further disseminate the information, and you must immediately remove the
* source code and notify DJI of its removal. DJI reserves the right to pursue
* legal actions against you for any loss(es) or damage(s) caused by your
* failure to do so.
*
*********************************************************************
*/
/* Includes ------------------------------------------------------------------*/
#include "dji_media_file_mp4.h"
#include "dji_media_file_core.h"
#include <string.h>
#include <unistd.h>
#include <stdio.h>
#include <dji_logger.h>
#include <stdlib.h>
#include "dji_platform.h"
#include "utils/util_time.h"
#include "utils/util_file.h"
/* Private constants ---------------------------------------------------------*/
#define MP4_FILE_SUFFIX ".mp4"
#define MP4_TEMP_FILE_TEMPLATE_STR "MP4_TEMP_XXXXXX.jpg"
#define MP4_TEMP_FILE_PATH_MAX_LEN 50
#define FFMPEG_CMD_BUF_SIZE (256 + 256)
#define MP4_THM_SCALE_CFG_STR "scale=100:-1"
#define MP4_SCR_SCALE_CFG_STR "scale=600:-1"
/* Private types -------------------------------------------------------------*/
typedef struct {
FILE *tempFile;
char tempfilePath[MP4_TEMP_FILE_PATH_MAX_LEN];
} T_DjiMP4TempPicPriv;
/* Private functions declaration ---------------------------------------------*/
static T_DjiReturnCode DjiMediaFile_CreateTempPicPriv_MP4(const char *srcFilePath, const char *scaleCfgStr,
T_DjiMP4TempPicPriv **pTempPicPrivHandle);
static T_DjiReturnCode DjiMediaFile_DestroyTempPicPriv_MP4(T_DjiMP4TempPicPriv *tempPicPrivHandle);
/* Private values ------------------------------------------------------------*/
/* Exported functions definition ---------------------------------------------*/
bool DjiMediaFile_IsSupported_MP4(const char *filePath)
{
if (filePath == NULL) {
USER_LOG_ERROR("input parameter is null error");
return false;
}
if (strcmp(&filePath[strlen(filePath) - 4], MP4_FILE_SUFFIX) == 0) {
return true;
}
return false;
}
T_DjiReturnCode DjiMediaFile_GetAttrFunc_MP4(struct _DjiMediaFile *mediaFileHandle,
T_DjiCameraMediaFileAttr *mediaFileAttr)
{
FILE *fp;
char ffmpegCmdStr[FFMPEG_CMD_BUF_SIZE];
float hour, minute, second;
char tempTailStr[128];
int ret;
T_DjiReturnCode psdkStat;
snprintf(ffmpegCmdStr, FFMPEG_CMD_BUF_SIZE, "ffmpeg -i \"%s\" 2>&1 | grep \"Duration\"", mediaFileHandle->filePath);
fp = popen(ffmpegCmdStr, "r");
if (fp == NULL) {
return DJI_ERROR_SYSTEM_MODULE_CODE_SYSTEM_ERROR;
}
ret = fscanf(fp, " Duration: %f:%f:%f,%127s", &hour, &minute, &second, tempTailStr);
if (ret <= 0) {
USER_LOG_ERROR("MP4 File Get Duration Error\n");
psdkStat = DJI_ERROR_SYSTEM_MODULE_CODE_SYSTEM_ERROR;
goto out;
}
mediaFileAttr->attrVideoDuration = (uint32_t) (hour * 3600 + minute * 60 + second + 0.5);
/*! The user needs to obtain the frame rate and resolution of the video file by ffmpeg tools.
* Also the frame rate and resolution of video need convert to enum E_DjiCameraVideoFrameRate or
* E_DjiCameraVideoResolution.
*/
mediaFileAttr->attrVideoFrameRate = DJI_CAMERA_VIDEO_FRAME_RATE_30_FPS;
mediaFileAttr->attrVideoResolution = DJI_CAMERA_VIDEO_RESOLUTION_1920x1080;
psdkStat = DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS;
out:
pclose(fp);
return psdkStat;
}
T_DjiReturnCode DjiMediaFile_GetDataOrigin_MP4(struct _DjiMediaFile *mediaFileHandle, uint32_t offset, uint16_t len,
uint8_t *data, uint32_t *realLen)
{
return UtilFile_GetFileDataByPath(mediaFileHandle->filePath, offset, len, data, realLen);
}
T_DjiReturnCode DjiMediaFile_GetFileSizeOrigin_MP4(struct _DjiMediaFile *mediaFileHandle, uint32_t *fileSize)
{
return UtilFile_GetFileSizeByPath(mediaFileHandle->filePath, fileSize);
}
T_DjiReturnCode DjiMediaFile_CreateThumbNail_MP4(struct _DjiMediaFile *mediaFileHandle)
{
return DjiMediaFile_CreateTempPicPriv_MP4(mediaFileHandle->filePath, MP4_THM_SCALE_CFG_STR,
(T_DjiMP4TempPicPriv **) &mediaFileHandle->mediaFileThm.privThm);
}
T_DjiReturnCode DjiMediaFile_GetFileSizeThumbNail_MP4(struct _DjiMediaFile *mediaFileHandle, uint32_t *fileSize)
{
T_DjiMP4TempPicPriv *jpgFileThmPriv = (T_DjiMP4TempPicPriv *) mediaFileHandle->mediaFileThm.privThm;
return UtilFile_GetFileSize(jpgFileThmPriv->tempFile, fileSize);
}
T_DjiReturnCode
DjiMediaFile_GetDataThumbNail_MP4(struct _DjiMediaFile *mediaFileHandle, uint32_t offset, uint16_t len,
uint8_t *data, uint16_t *realLen)
{
T_DjiMP4TempPicPriv *jpgFileThmPriv = (T_DjiMP4TempPicPriv *) mediaFileHandle->mediaFileThm.privThm;
return UtilFile_GetFileData(jpgFileThmPriv->tempFile, offset, len, data, realLen);
}
T_DjiReturnCode DjiMediaFile_DestroyThumbNail_MP4(struct _DjiMediaFile *MediaFileHandle)
{
return DjiMediaFile_DestroyTempPicPriv_MP4(MediaFileHandle->mediaFileThm.privThm);
}
T_DjiReturnCode DjiMediaFile_CreateScreenNail_MP4(struct _DjiMediaFile *mediaFileHandle)
{
return DjiMediaFile_CreateTempPicPriv_MP4(mediaFileHandle->filePath, MP4_SCR_SCALE_CFG_STR,
(T_DjiMP4TempPicPriv **) &mediaFileHandle->mediaFileScr.privScr);
}
T_DjiReturnCode DjiMediaFile_GetFileSizeScreenNail_MP4(struct _DjiMediaFile *mediaFileHandle, uint32_t *fileSize)
{
T_DjiMP4TempPicPriv *jpgFileScrPriv = (T_DjiMP4TempPicPriv *) mediaFileHandle->mediaFileScr.privScr;
return UtilFile_GetFileSize(jpgFileScrPriv->tempFile, fileSize);
}
T_DjiReturnCode
DjiMediaFile_GetDataScreenNail_MP4(struct _DjiMediaFile *mediaFileHandle, uint32_t offset, uint16_t len,
uint8_t *data, uint16_t *realLen)
{
T_DjiMP4TempPicPriv *jpgFileScrPriv = (T_DjiMP4TempPicPriv *) mediaFileHandle->mediaFileScr.privScr;
return UtilFile_GetFileData(jpgFileScrPriv->tempFile, offset, len, data, realLen);
}
T_DjiReturnCode DjiMediaFile_DestroyScreenNail_MP4(struct _DjiMediaFile *mediaFileHandle)
{
return DjiMediaFile_DestroyTempPicPriv_MP4(mediaFileHandle->mediaFileScr.privScr);
}
/* Private functions definition-----------------------------------------------*/
static T_DjiReturnCode DjiMediaFile_CreateTempPicPriv_MP4(const char *srcFilePath, const char *scaleCfgStr,
T_DjiMP4TempPicPriv **pTempPicPrivHandle)
{
char ffmpeg_cmd[FFMPEG_CMD_BUF_SIZE];
int cmdRet;
T_DjiRunTimeStamps tiStart, tiEnd;
T_DjiMP4TempPicPriv *mp4TempPicFile;
T_DjiReturnCode psdkStat;
int tempFd;
T_DjiOsalHandler *osalHandler = DjiPlatform_GetOsalHandler();
tiStart = DjiUtilTime_GetRunTimeStamps();
*pTempPicPrivHandle = osalHandler->Malloc(sizeof(T_DjiMP4TempPicPriv));
if (*pTempPicPrivHandle == NULL) {
return DJI_ERROR_SYSTEM_MODULE_CODE_MEMORY_ALLOC_FAILED;
}
mp4TempPicFile = *pTempPicPrivHandle;
//get temp file name
strcpy(mp4TempPicFile->tempfilePath, MP4_TEMP_FILE_TEMPLATE_STR);
tempFd = mkstemps(mp4TempPicFile->tempfilePath, strlen(MP4_FILE_SUFFIX));
if (tempFd < 0) {
USER_LOG_ERROR("JPG Create Temp File Error, tempFd = %d\n", tempFd);
psdkStat = DJI_ERROR_SYSTEM_MODULE_CODE_SYSTEM_ERROR;
goto err_create_temp;
}
close(tempFd);
unlink(mp4TempPicFile->tempfilePath);
//ffmpeg cmd send
snprintf(ffmpeg_cmd, FFMPEG_CMD_BUF_SIZE, "ffmpeg -i \"%s\" -vf %s -ss 00:00:00 -vframes 1 %s 1>/dev/null 2>&1",
srcFilePath, scaleCfgStr, mp4TempPicFile->tempfilePath);
cmdRet = system(ffmpeg_cmd);
tiEnd = DjiUtilTime_GetRunTimeStamps();
USER_LOG_DEBUG("JPG Create TempFile, RealTime = %ld us\n", tiEnd.realUsec - tiStart.realUsec);
if (cmdRet != 0) {
USER_LOG_ERROR("JPG ffmpeg cmd call error, ret = %d\n", cmdRet);
psdkStat = DJI_ERROR_SYSTEM_MODULE_CODE_SYSTEM_ERROR;
goto err_system_cmd;
}
//open temp file
mp4TempPicFile->tempFile = fopen(mp4TempPicFile->tempfilePath, "rb+");
if (mp4TempPicFile->tempFile == NULL) {
psdkStat = DJI_ERROR_SYSTEM_MODULE_CODE_SYSTEM_ERROR;
goto err_file_open;
}
//unlink temp file
unlink(mp4TempPicFile->tempfilePath);
return DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS;
err_file_open:
unlink(mp4TempPicFile->tempfilePath);
err_system_cmd:
err_create_temp:
osalHandler->Free(*pTempPicPrivHandle);
return psdkStat;
}
static T_DjiReturnCode DjiMediaFile_DestroyTempPicPriv_MP4(T_DjiMP4TempPicPriv *tempPicPrivHandle)
{
T_DjiOsalHandler *osalHandler = DjiPlatform_GetOsalHandler();
fclose(tempPicPrivHandle->tempFile);
osalHandler->Free(tempPicPrivHandle);
return DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS;
}
/****************** (C) COPYRIGHT DJI Innovations *****END OF FILE****/
... ...
/**
********************************************************************
* @file dji_media_file_mp4.h
* @brief This is the header file for "dji_media_file_mp4.c", defining the structure and
* (exported) function prototypes.
*
* @copyright (c) 2021 DJI. All rights reserved.
*
* All information contained herein is, and remains, the property of DJI.
* The intellectual and technical concepts contained herein are proprietary
* to DJI and may be covered by U.S. and foreign patents, patents in process,
* and protected by trade secret or copyright law. Dissemination of this
* information, including but not limited to data and other proprietary
* material(s) incorporated within the information, in any form, is strictly
* prohibited without the express written consent of DJI.
*
* If you receive this source code without DJI’s authorization, you may not
* further disseminate the information, and you must immediately remove the
* source code and notify DJI of its removal. DJI reserves the right to pursue
* legal actions against you for any loss(es) or damage(s) caused by your
* failure to do so.
*
*********************************************************************
*/
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef PSDK_MEDIA_FILE_MP4_H
#define PSDK_MEDIA_FILE_MP4_H
#ifdef __cplusplus
extern "C" {
#endif
/* Includes ------------------------------------------------------------------*/
#include <dji_payload_camera.h>
#include <dji_typedef.h>
#include "dji_media_file_core.h"
/* Exported constants --------------------------------------------------------*/
/* Exported types ------------------------------------------------------------*/
/* Exported functions --------------------------------------------------------*/
bool DjiMediaFile_IsSupported_MP4(const char *filePath);
T_DjiReturnCode DjiMediaFile_GetAttrFunc_MP4(struct _DjiMediaFile *mediaFileHandle,
T_DjiCameraMediaFileAttr *mediaFileAttr);
T_DjiReturnCode DjiMediaFile_GetDataOrigin_MP4(struct _DjiMediaFile *mediaFileHandle, uint32_t offset, uint16_t len,
uint8_t *data, uint32_t *realLen);
T_DjiReturnCode DjiMediaFile_GetFileSizeOrigin_MP4(struct _DjiMediaFile *mediaFileHandle, uint32_t *fileSize);
T_DjiReturnCode DjiMediaFile_CreateThumbNail_MP4(struct _DjiMediaFile *mediaFileHandle);
T_DjiReturnCode DjiMediaFile_GetFileSizeThumbNail_MP4(struct _DjiMediaFile *mediaFileHandle, uint32_t *fileSize);
T_DjiReturnCode
DjiMediaFile_GetDataThumbNail_MP4(struct _DjiMediaFile *mediaFileHandle, uint32_t offset, uint16_t len,
uint8_t *data, uint16_t *realLen);
T_DjiReturnCode DjiMediaFile_DestroyThumbNail_MP4(struct _DjiMediaFile *MediaFileHandle);
T_DjiReturnCode DjiMediaFile_CreateScreenNail_MP4(struct _DjiMediaFile *mediaFileHandle);
T_DjiReturnCode DjiMediaFile_GetFileSizeScreenNail_MP4(struct _DjiMediaFile *mediaFileHandle, uint32_t *fileSize);
T_DjiReturnCode
DjiMediaFile_GetDataScreenNail_MP4(struct _DjiMediaFile *mediaFileHandle, uint32_t offset, uint16_t len,
uint8_t *data, uint16_t *realLen);
T_DjiReturnCode DjiMediaFile_DestroyScreenNail_MP4(struct _DjiMediaFile *mediaFileHandle);
#ifdef __cplusplus
}
#endif
#endif // PSDK_MEDIA_FILE_MP4_H
/************************ (C) COPYRIGHT DJI Innovations *******END OF FILE******/
... ...
/**
********************************************************************
* @file test_payload_cam_emu_common.c
* @brief
*
* @copyright (c) 2021 DJI. All rights reserved.
*
* All information contained herein is, and remains, the property of DJI.
* The intellectual and technical concepts contained herein are proprietary
* to DJI and may be covered by U.S. and foreign patents, patents in process,
* and protected by trade secret or copyright law. Dissemination of this
* information, including but not limited to data and other proprietary
* material(s) incorporated within the information, in any form, is strictly
* prohibited without the express written consent of DJI.
*
* If you receive this source code without DJI’s authorization, you may not
* further disseminate the information, and you must immediately remove the
* source code and notify DJI of its removal. DJI reserves the right to pursue
* legal actions against you for any loss(es) or damage(s) caused by your
* failure to do so.
*
*********************************************************************
*/
/* Includes ------------------------------------------------------------------*/
#include "math.h"
#include "test_payload_cam_emu_base.h"
#include "utils/util_misc.h"
#include "dji_logger.h"
#include "dji_platform.h"
#include "dji_payload_camera.h"
#include "dji_aircraft_info.h"
#include "dji_gimbal.h"
#include "dji_xport.h"
#include "gimbal_emu/test_payload_gimbal_emu.h"
#include "Psdk_UI_io.h"
/* Private constants ---------------------------------------------------------*/
#define PAYLOAD_CAMERA_EMU_TASK_FREQ (100)
#define PAYLOAD_CAMERA_EMU_TASK_STACK_SIZE (2048)
#define SDCARD_TOTAL_SPACE_IN_MB (32 * 1024)
#define SDCARD_PER_PHOTO_SPACE_IN_MB (4)
#define SDCARD_PER_SECONDS_RECORD_SPACE_IN_MB (2)
#define ZOOM_OPTICAL_FOCAL_MAX_LENGTH (300)
#define ZOOM_OPTICAL_FOCAL_MIN_LENGTH (10)
#define ZOOM_OPTICAL_FOCAL_LENGTH_STEP (10)
#define ZOOM_OPTICAL_FOCAL_LENGTH_CTRL_STEP (5)
#define ZOOM_DIGITAL_BASE_FACTOR (1.0)
#define ZOOM_DIGITAL_STEP_FACTOR (0.1)
#define ZOOM_DIGITAL_MAX_FACTOR (6.0)
#define FOCUS_MAX_RINGVALUE (1000)
#define FOCUS_MID_RINGVALUE (500)
#define IMAGE_SENSOR_X_SIZE (88.0f) // unit: 0.1mm
#define IMAGE_SENSOR_Y_SIZE (66.0f) // unit: 0.1mm
#define CENTER_POINT_IN_SCREEN_X_VALUE (0.5f)
#define CENTER_POINT_IN_SCREEN_Y_VALUE (0.5f)
#define TAP_ZOOM_DURATION (2000) // unit: ms
#define INTERVAL_PHOTOGRAPH_ALWAYS_COUNT (255)
#define INTERVAL_PHOTOGRAPH_INTERVAL_INIT_VALUE (1) // unit: s
#define TAKING_PHOTO_SPENT_TIME_MS_EMU (500)
#define PHOTO_FILE_PATH "../../../../../api_sample/camera_media_emu/media_file/DJI_0001_ORG.jpg"
// Attention: you can select which camera function you want to run, default: all on.
#define USER_CAMERA_EMU_METERING_ON 1
#define USER_CAMERA_EMU_FOCUS_ON 1
#define USER_CAMERA_EMU_HYBRID_ZOOM_ON 1
#define USER_CAMERA_EMU_TAP_ZOOM_ON 1
/* Private types -------------------------------------------------------------*/
typedef struct {
E_DjiGimbalRotationMode rotationMode;
T_DjiGimbalRotationProperty rotationProperty;
T_DjiAttitude3d rotationValue;
} T_TestCameraGimbalRotationArgument;
/* Private variables ---------------------------------------------------------*/
static bool s_isCamInited = false;
static T_DjiCameraCommonHandler s_commonHandler;
static T_DjiCameraExposureMeteringHandler s_exposureMeteringHandler;
static T_DjiCameraFocusHandler s_focusHandler;
static T_DjiCameraDigitalZoomHandler s_digitalZoomHandler;
static T_DjiCameraOpticalZoomHandler s_opticalZoomHandler;
static T_DjiCameraTapZoomHandler s_tapZoomHandler;
static T_DjiTaskHandle s_userCameraThread;
static T_DjiCameraSystemState s_cameraState = {0};
static E_DjiCameraShootPhotoMode s_cameraShootPhotoMode = DJI_CAMERA_SHOOT_PHOTO_MODE_SINGLE;
static E_DjiCameraBurstCount s_cameraBurstCount = DJI_CAMERA_BURST_COUNT_2;
static T_DjiCameraPhotoTimeIntervalSettings s_cameraPhotoTimeIntervalSettings = {INTERVAL_PHOTOGRAPH_ALWAYS_COUNT,
INTERVAL_PHOTOGRAPH_INTERVAL_INIT_VALUE};
static T_DjiCameraSDCardState s_cameraSDCardState = {0};
static T_DjiMutexHandle s_commonMutex = {0};
static E_DjiCameraMeteringMode s_cameraMeteringMode = DJI_CAMERA_METERING_MODE_CENTER;
static T_DjiCameraSpotMeteringTarget s_cameraSpotMeteringTarget = {0};
static E_DjiCameraFocusMode s_cameraFocusMode = DJI_CAMERA_FOCUS_MODE_AUTO;
static T_DjiCameraPointInScreen s_cameraFocusTarget = {0};
static uint32_t s_cameraFocusRingValue = FOCUS_MID_RINGVALUE;
static T_DjiCameraFocusAssistantSettings s_cameraFocusAssistantSettings = {0};
static E_DjiCameraZoomDirection s_cameraZoomDirection = DJI_CAMERA_ZOOM_DIRECTION_OUT;
static E_DjiCameraZoomSpeed s_cameraZoomSpeed = DJI_CAMERA_ZOOM_SPEED_NORMAL;
static uint32_t s_cameraOpticalZoomFocalLength = ZOOM_OPTICAL_FOCAL_MIN_LENGTH;
static dji_f32_t s_cameraDigitalZoomFactor = ZOOM_DIGITAL_BASE_FACTOR;
static bool s_isStartContinuousOpticalZoom = false;
static bool s_isOpticalZoomReachLimit = false;
static T_DjiMutexHandle s_zoomMutex = {0};
static bool s_isTapZoomEnabled = false;
static T_DjiCameraTapZoomState s_cameraTapZoomState = {0};
static uint8_t s_tapZoomMultiplier = 1;
static uint32_t s_tapZoomStartTime = 0;
static bool s_isStartTapZoom = false;
static bool s_isTapZooming = false;
static T_TestCameraGimbalRotationArgument s_tapZoomNewestGimbalRotationArgument = {0};
static uint32_t s_tapZoomNewestTargetHybridFocalLength = 0; // unit: 0.1mm
static T_DjiMutexHandle s_tapZoomMutex = NULL;
static E_DjiCameraVideoStreamType s_cameraVideoStreamType;
/* Private functions declaration ---------------------------------------------*/
static T_DjiReturnCode GetSystemState(T_DjiCameraSystemState *systemState);
static T_DjiReturnCode SetMode(E_DjiCameraMode mode);
static T_DjiReturnCode StartRecordVideo(void);
static T_DjiReturnCode StopRecordVideo(void);
static T_DjiReturnCode StartShootPhoto(void);
static T_DjiReturnCode StopShootPhoto(void);
static T_DjiReturnCode SetShootPhotoMode(E_DjiCameraShootPhotoMode mode);
static T_DjiReturnCode GetShootPhotoMode(E_DjiCameraShootPhotoMode *mode);
static T_DjiReturnCode SetPhotoBurstCount(E_DjiCameraBurstCount burstCount);
static T_DjiReturnCode GetPhotoBurstCount(E_DjiCameraBurstCount *burstCount);
static T_DjiReturnCode SetPhotoTimeIntervalSettings(T_DjiCameraPhotoTimeIntervalSettings settings);
static T_DjiReturnCode GetPhotoTimeIntervalSettings(T_DjiCameraPhotoTimeIntervalSettings *settings);
static T_DjiReturnCode GetSDCardState(T_DjiCameraSDCardState *sdCardState);
static T_DjiReturnCode FormatSDCard(void);
static T_DjiReturnCode SetMeteringMode(E_DjiCameraMeteringMode mode);
static T_DjiReturnCode GetMeteringMode(E_DjiCameraMeteringMode *mode);
static T_DjiReturnCode SetSpotMeteringTarget(T_DjiCameraSpotMeteringTarget target);
static T_DjiReturnCode GetSpotMeteringTarget(T_DjiCameraSpotMeteringTarget *target);
static T_DjiReturnCode SetFocusMode(E_DjiCameraFocusMode mode);
static T_DjiReturnCode GetFocusMode(E_DjiCameraFocusMode *mode);
static T_DjiReturnCode SetFocusTarget(T_DjiCameraPointInScreen target);
static T_DjiReturnCode GetFocusTarget(T_DjiCameraPointInScreen *target);
static T_DjiReturnCode SetFocusAssistantSettings(T_DjiCameraFocusAssistantSettings settings);
static T_DjiReturnCode GetFocusAssistantSettings(T_DjiCameraFocusAssistantSettings *settings);
static T_DjiReturnCode SetFocusRingValue(uint32_t value);
static T_DjiReturnCode GetFocusRingValue(uint32_t *value);
static T_DjiReturnCode GetFocusRingValueUpperBound(uint32_t *value);
static T_DjiReturnCode SetDigitalZoomFactor(dji_f32_t factor);
static T_DjiReturnCode SetOpticalZoomFocalLength(uint32_t focalLength);
static T_DjiReturnCode GetOpticalZoomFocalLength(uint32_t *focalLength);
static T_DjiReturnCode GetOpticalZoomSpec(T_DjiCameraOpticalZoomSpec *spec);
static T_DjiReturnCode StartContinuousOpticalZoom(E_DjiCameraZoomDirection direction, E_DjiCameraZoomSpeed speed);
static T_DjiReturnCode StopContinuousOpticalZoom(void);
static T_DjiReturnCode GetTapZoomState(T_DjiCameraTapZoomState *state);
static T_DjiReturnCode SetTapZoomEnabled(bool enabledFlag);
static T_DjiReturnCode GetTapZoomEnabled(bool *enabledFlag);
static T_DjiReturnCode SetTapZoomMultiplier(uint8_t multiplier);
static T_DjiReturnCode GetTapZoomMultiplier(uint8_t *multiplier);
static T_DjiReturnCode TapZoomAtTarget(T_DjiCameraPointInScreen target);
static T_DjiReturnCode DjiTest_CameraHybridZoom(uint32_t focalLength);
static T_DjiReturnCode DjiTest_CameraRotationGimbal(T_TestCameraGimbalRotationArgument gimbalRotationArgument);
static void *UserCamera_Task(void *arg);
/* Exported functions definition ---------------------------------------------*/
/* Private functions definition-----------------------------------------------*/
static T_DjiReturnCode GetSystemState(T_DjiCameraSystemState *systemState)
{
T_DjiReturnCode returnCode;
T_DjiOsalHandler *osalHandler = DjiPlatform_GetOsalHandler();
returnCode = osalHandler->MutexLock(s_commonMutex);
if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
USER_LOG_ERROR("lock mutex error: 0x%08llX.", returnCode);
return returnCode;
}
*systemState = s_cameraState;
returnCode = osalHandler->MutexUnlock(s_commonMutex);
if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
USER_LOG_ERROR("unlock mutex error: 0x%08llX.", returnCode);
return returnCode;
}
return DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS;
}
//设置模式
static T_DjiReturnCode SetMode(E_DjiCameraMode mode)
{
T_DjiReturnCode returnCode;
T_DjiOsalHandler *osalHandler = DjiPlatform_GetOsalHandler();
returnCode = osalHandler->MutexLock(s_commonMutex);
if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
USER_LOG_ERROR("lock mutex error: 0x%08llX.", returnCode);
return returnCode;
}
s_cameraState.cameraMode = mode;
USER_LOG_INFO("set camera mode:%d", mode);
returnCode = osalHandler->MutexUnlock(s_commonMutex);
if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
USER_LOG_ERROR("unlock mutex error: 0x%08llX.", returnCode);
return returnCode;
}
return DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS;
}
// 开始录像
static T_DjiReturnCode StartRecordVideo(void)
{
T_DjiReturnCode djiStat;
T_DjiReturnCode returnCode = DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS;
T_DjiOsalHandler *osalHandler = DjiPlatform_GetOsalHandler();
djiStat = osalHandler->MutexLock(s_commonMutex);
if (djiStat != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
USER_LOG_ERROR("lock mutex error: 0x%08llX.", djiStat);
return djiStat;
}
if (s_cameraState.isRecording != false) {
USER_LOG_ERROR("camera is already in recording state");
returnCode = DJI_ERROR_SYSTEM_MODULE_CODE_NONSUPPORT_IN_CURRENT_STATE;
goto out;
}
s_cameraState.isRecording = true;
USER_LOG_INFO("start record video");
//录像通知函数
if(JZsdk_Psdk_UI_io_VideoRecord(1) != 0)
{
//录像开启失败
s_cameraState.isRecording = false;
}
out:
djiStat = osalHandler->MutexUnlock(s_commonMutex);
if (djiStat != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
USER_LOG_ERROR("unlock mutex error: 0x%08llX.", djiStat);
return djiStat;
}
return returnCode;
}
//结束录像
static T_DjiReturnCode StopRecordVideo(void)
{
T_DjiReturnCode djiStat;
T_DjiReturnCode returnCode = DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS;
T_DjiOsalHandler *osalHandler = DjiPlatform_GetOsalHandler();
djiStat = osalHandler->MutexLock(s_commonMutex);
if (djiStat != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
USER_LOG_ERROR("lock mutex error: 0x%08llX.", djiStat);
return djiStat;
}
if (s_cameraState.isRecording != true) {
USER_LOG_ERROR("camera is not in recording state");
returnCode = DJI_ERROR_SYSTEM_MODULE_CODE_NONSUPPORT_IN_CURRENT_STATE;
goto out;
}
s_cameraState.isRecording = false;
s_cameraState.isStoring = true;
s_cameraState.currentVideoRecordingTimeInSeconds = 0;
USER_LOG_INFO("stop record video");
//录像通知函数
if(JZsdk_Psdk_UI_io_VideoRecord(0) != 0)
{
//关闭失败
s_cameraState.isRecording = true;
s_cameraState.isStoring = false;
}
out:
djiStat = osalHandler->MutexUnlock(s_commonMutex);
if (djiStat != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
USER_LOG_ERROR("unlock mutex error: 0x%08llX.", djiStat);
return djiStat;
}
return returnCode;
}
//拍照功能
static T_DjiReturnCode StartShootPhoto(void)
{
T_DjiReturnCode returnCode;
T_DjiOsalHandler *osalHandler = DjiPlatform_GetOsalHandler();
returnCode = osalHandler->MutexLock(s_commonMutex);
if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
USER_LOG_ERROR("lock mutex error: 0x%08llX.", returnCode);
return returnCode;
}
USER_LOG_INFO("start shoot photo");
s_cameraState.isStoring = true;
// 拍照模式的判定
if (s_cameraShootPhotoMode == DJI_CAMERA_SHOOT_PHOTO_MODE_SINGLE) {
s_cameraState.shootingState = DJI_CAMERA_SHOOTING_SINGLE_PHOTO;
// 这里接过去推流那边 以获取拍照内容
JZsdk_Psdk_UI_io_ShootPhoto();
} else if (s_cameraShootPhotoMode == DJI_CAMERA_SHOOT_PHOTO_MODE_BURST) {
s_cameraState.shootingState = DJI_CAMERA_SHOOTING_BURST_PHOTO;
//暂时不做连拍
//JZsdk_Psdk_UI_io_BurstShootPhoto(s_cameraBurstCount);
} else if (s_cameraShootPhotoMode == DJI_CAMERA_SHOOT_PHOTO_MODE_INTERVAL) {
s_cameraState.shootingState = DJI_CAMERA_SHOOTING_INTERVAL_PHOTO;
s_cameraState.isShootingIntervalStart = true;
s_cameraState.currentPhotoShootingIntervalTimeInSeconds = s_cameraPhotoTimeIntervalSettings.timeIntervalSeconds;
}
returnCode = osalHandler->MutexUnlock(s_commonMutex);
if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
USER_LOG_ERROR("unlock mutex error: 0x%08llX.", returnCode);
return returnCode;
}
return DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS;
}
//停止拍照
static T_DjiReturnCode StopShootPhoto(void)
{
T_DjiReturnCode returnCode;
T_DjiOsalHandler *osalHandler = DjiPlatform_GetOsalHandler();
returnCode = osalHandler->MutexLock(s_commonMutex);
if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
USER_LOG_ERROR("lock mutex error: 0x%08llX.", returnCode);
return returnCode;
}
USER_LOG_INFO("stop shoot photo");
s_cameraState.shootingState = DJI_CAMERA_SHOOTING_PHOTO_IDLE;
//改成转码后再取消锁定
//s_cameraState.isStoring = false;
s_cameraState.isShootingIntervalStart = false;
returnCode = osalHandler->MutexUnlock(s_commonMutex);
if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
USER_LOG_ERROR("unlock mutex error: 0x%08llX.", returnCode);
return returnCode;
}
return DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS;
}
//设置拍摄模式
static T_DjiReturnCode SetShootPhotoMode(E_DjiCameraShootPhotoMode mode)
{
T_DjiReturnCode returnCode;
T_DjiOsalHandler *osalHandler = DjiPlatform_GetOsalHandler();
returnCode = osalHandler->MutexLock(s_commonMutex);
if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
USER_LOG_ERROR("lock mutex error: 0x%08llX.", returnCode);
return returnCode;
}
s_cameraShootPhotoMode = mode;
USER_LOG_INFO("set shoot photo mode:%d", mode);
returnCode = osalHandler->MutexUnlock(s_commonMutex);
if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
USER_LOG_ERROR("unlock mutex error: 0x%08llX.", returnCode);
return returnCode;
}
return DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS;
}
static T_DjiReturnCode GetShootPhotoMode(E_DjiCameraShootPhotoMode *mode)
{
T_DjiReturnCode returnCode;
T_DjiOsalHandler *osalHandler = DjiPlatform_GetOsalHandler();
returnCode = osalHandler->MutexLock(s_commonMutex);
if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
USER_LOG_ERROR("lock mutex error: 0x%08llX.", returnCode);
return returnCode;
}
*mode = s_cameraShootPhotoMode;
returnCode = osalHandler->MutexUnlock(s_commonMutex);
if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
USER_LOG_ERROR("unlock mutex error: 0x%08llX.", returnCode);\
return returnCode;
}
return DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS;
}
//加载相机的连拍数量
static T_DjiReturnCode SetPhotoBurstCount(E_DjiCameraBurstCount burstCount)
{
T_DjiReturnCode returnCode;
T_DjiOsalHandler *osalHandler = DjiPlatform_GetOsalHandler();
returnCode = osalHandler->MutexLock(s_commonMutex);
if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
USER_LOG_ERROR("lock mutex error: 0x%08llX.", returnCode);
return returnCode;
}
s_cameraBurstCount = burstCount;
USER_LOG_INFO("set photo burst count:%d", burstCount);
returnCode = osalHandler->MutexUnlock(s_commonMutex);
if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
USER_LOG_ERROR("unlock mutex error: 0x%08llX.", returnCode);
return returnCode;
}
return DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS;
}
//得到相机设定的连拍数量
static T_DjiReturnCode GetPhotoBurstCount(E_DjiCameraBurstCount *burstCount)
{
T_DjiReturnCode returnCode;
T_DjiOsalHandler *osalHandler = DjiPlatform_GetOsalHandler();
returnCode = osalHandler->MutexLock(s_commonMutex);
if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
USER_LOG_ERROR("lock mutex error: 0x%08llX.", returnCode);
return returnCode;
}
*burstCount = s_cameraBurstCount;
returnCode = osalHandler->MutexUnlock(s_commonMutex);
if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
USER_LOG_ERROR("unlock mutex error: 0x%08llX.", returnCode);
return returnCode;
}
return DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS;
}
//设置定时拍摄的时间
static T_DjiReturnCode SetPhotoTimeIntervalSettings(T_DjiCameraPhotoTimeIntervalSettings settings)
{
T_DjiReturnCode returnCode;
T_DjiOsalHandler *osalHandler = DjiPlatform_GetOsalHandler();
returnCode = osalHandler->MutexLock(s_commonMutex);
if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
USER_LOG_ERROR("lock mutex error: 0x%08llX.", returnCode);
return returnCode;
}
s_cameraPhotoTimeIntervalSettings.captureCount = settings.captureCount;
s_cameraPhotoTimeIntervalSettings.timeIntervalSeconds = settings.timeIntervalSeconds;
USER_LOG_INFO("set photo interval settings count:%d seconds:%d", settings.captureCount,
settings.timeIntervalSeconds);
s_cameraState.currentPhotoShootingIntervalCount = settings.captureCount;
returnCode = osalHandler->MutexUnlock(s_commonMutex);
if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
USER_LOG_ERROR("unlock mutex error: 0x%08llX.", returnCode);
return returnCode;
}
return DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS;
}
//得到定时拍摄的时间
static T_DjiReturnCode GetPhotoTimeIntervalSettings(T_DjiCameraPhotoTimeIntervalSettings *settings)
{
T_DjiReturnCode returnCode;
T_DjiOsalHandler *osalHandler = DjiPlatform_GetOsalHandler();
returnCode = osalHandler->MutexLock(s_commonMutex);
if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
USER_LOG_ERROR("lock mutex error: 0x%08llX.", returnCode);
return returnCode;
}
memcpy(settings, &s_cameraPhotoTimeIntervalSettings, sizeof(T_DjiCameraPhotoTimeIntervalSettings));
returnCode = osalHandler->MutexUnlock(s_commonMutex);
if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
USER_LOG_ERROR("unlock mutex error: 0x%08llX.", returnCode);
return returnCode;
}
return DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS;
}
//得到sd佧的状态
static T_DjiReturnCode GetSDCardState(T_DjiCameraSDCardState *sdCardState)
{
T_DjiReturnCode returnCode;
T_DjiOsalHandler *osalHandler = DjiPlatform_GetOsalHandler();
returnCode = osalHandler->MutexLock(s_commonMutex);
if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
USER_LOG_ERROR("lock mutex error: 0x%08llX.", returnCode);
return returnCode;
}
memcpy(sdCardState, &s_cameraSDCardState, sizeof(T_DjiCameraSDCardState));
returnCode = osalHandler->MutexUnlock(s_commonMutex);
if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
USER_LOG_ERROR("unlock mutex error: 0x%08llX.", returnCode);
return returnCode;
}
return DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS;
}
// 格式化sd佧
static T_DjiReturnCode FormatSDCard(void)
{
T_DjiReturnCode returnCode;
T_DjiOsalHandler *osalHandler = DjiPlatform_GetOsalHandler();
returnCode = osalHandler->MutexLock(s_commonMutex);
if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
USER_LOG_ERROR("lock mutex error: 0x%08llX.", returnCode);
return returnCode;
}
USER_LOG_INFO("format sdcard");
memset(&s_cameraSDCardState, 0, sizeof(T_DjiCameraSDCardState));
s_cameraSDCardState.isInserted = true;
s_cameraSDCardState.isVerified = true;
s_cameraSDCardState.totalSpaceInMB = SDCARD_TOTAL_SPACE_IN_MB;
s_cameraSDCardState.remainSpaceInMB = SDCARD_TOTAL_SPACE_IN_MB;
s_cameraSDCardState.availableCaptureCount = SDCARD_TOTAL_SPACE_IN_MB / SDCARD_PER_PHOTO_SPACE_IN_MB;
s_cameraSDCardState.availableRecordingTimeInSeconds =
SDCARD_TOTAL_SPACE_IN_MB / SDCARD_PER_SECONDS_RECORD_SPACE_IN_MB;
returnCode = osalHandler->MutexUnlock(s_commonMutex);
if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
USER_LOG_ERROR("unlock mutex error: 0x%08llX.", returnCode);
return returnCode;
}
return DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS;
}
//设置测量模式
static T_DjiReturnCode SetMeteringMode(E_DjiCameraMeteringMode mode)
{
USER_LOG_INFO("set metering mode:%d", mode);
s_cameraMeteringMode = mode;
return DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS;
}
static T_DjiReturnCode GetMeteringMode(E_DjiCameraMeteringMode *mode)
{
*mode = s_cameraMeteringMode;
return DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS;
}
static T_DjiReturnCode SetSpotMeteringTarget(T_DjiCameraSpotMeteringTarget target)
{
USER_LOG_INFO("set spot metering area col:%d row:%d", target.col, target.row);
memcpy(&s_cameraSpotMeteringTarget, &target, sizeof(T_DjiCameraSpotMeteringTarget));
return DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS;
}
static T_DjiReturnCode GetSpotMeteringTarget(T_DjiCameraSpotMeteringTarget *target)
{
memcpy(target, &s_cameraSpotMeteringTarget, sizeof(T_DjiCameraSpotMeteringTarget));
return DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS;
}
static T_DjiReturnCode SetFocusMode(E_DjiCameraFocusMode mode)
{
USER_LOG_INFO("set focus mode:%d", mode);
s_cameraFocusMode = mode;
return DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS;
}
static T_DjiReturnCode GetFocusMode(E_DjiCameraFocusMode *mode)
{
*mode = s_cameraFocusMode;
return DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS;
}
static T_DjiReturnCode SetFocusTarget(T_DjiCameraPointInScreen target)
{
USER_LOG_INFO("set focus target x:%.2f y:%.2f", target.focusX, target.focusY);
memcpy(&s_cameraFocusTarget, &target, sizeof(T_DjiCameraPointInScreen));
int PointX = (int)(target.focusX *100);
int PointY = (int)(target.focusY *100);
//发送到对焦点
//USER_LOG_INFO("Px:%d Py:%d",PointX,PointY);
JZsdK_SetFocusTarget(PointX, PointY);
return DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS;
}
static T_DjiReturnCode GetFocusTarget(T_DjiCameraPointInScreen *target)
{
memcpy(target, &s_cameraFocusTarget, sizeof(T_DjiCameraPointInScreen));
return DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS;
}
static T_DjiReturnCode SetFocusAssistantSettings(T_DjiCameraFocusAssistantSettings settings)
{
USER_LOG_INFO("set focus assistant setting MF:%d AF:%d", settings.isEnabledMF, settings.isEnabledAF);
memcpy(&s_cameraFocusAssistantSettings, &settings, sizeof(T_DjiCameraFocusAssistantSettings));
return DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS;
}
static T_DjiReturnCode GetFocusAssistantSettings(T_DjiCameraFocusAssistantSettings *settings)
{
memcpy(settings, &s_cameraFocusAssistantSettings, sizeof(T_DjiCameraFocusAssistantSettings));
return DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS;
}
static T_DjiReturnCode SetFocusRingValue(uint32_t value)
{
USER_LOG_INFO("set focus ring value:%d", value);
s_cameraFocusRingValue = value;
return DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS;
}
static T_DjiReturnCode GetFocusRingValue(uint32_t *value)
{
*value = s_cameraFocusRingValue;
return DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS;
}
static T_DjiReturnCode GetFocusRingValueUpperBound(uint32_t *value)
{
*value = FOCUS_MAX_RINGVALUE;
return DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS;
}
static T_DjiReturnCode SetDigitalZoomFactor(dji_f32_t factor)
{
T_DjiReturnCode returnCode;
T_DjiOsalHandler *osalHandler = DjiPlatform_GetOsalHandler();
returnCode = osalHandler->MutexLock(s_zoomMutex);
if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
USER_LOG_ERROR("lock mutex error: 0x%08llX.", returnCode);
return returnCode;
}
USER_LOG_INFO("set digital zoom factor:%.2f", factor);
s_cameraDigitalZoomFactor = factor;
returnCode = osalHandler->MutexUnlock(s_zoomMutex);
if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
USER_LOG_ERROR("unlock mutex error: 0x%08llX.", returnCode);
return returnCode;
}
return DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS;
}
static T_DjiReturnCode SetOpticalZoomFocalLength(uint32_t focalLength)
{
T_DjiReturnCode returnCode;
T_DjiOsalHandler *osalHandler = DjiPlatform_GetOsalHandler();
returnCode = osalHandler->MutexLock(s_zoomMutex);
if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
USER_LOG_ERROR("lock mutex error: 0x%08llX.", returnCode);
return returnCode;
}
USER_LOG_INFO("set optical zoom focal length:%d", focalLength);
s_isOpticalZoomReachLimit = false;
s_cameraDigitalZoomFactor = ZOOM_DIGITAL_BASE_FACTOR;
s_cameraOpticalZoomFocalLength = ZOOM_OPTICAL_FOCAL_MIN_LENGTH;
returnCode = osalHandler->MutexUnlock(s_zoomMutex);
if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
USER_LOG_ERROR("unlock mutex error: 0x%08llX.", returnCode);
return returnCode;
}
return DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS;
}
static T_DjiReturnCode GetOpticalZoomFocalLength(uint32_t *focalLength)
{
T_DjiReturnCode returnCode;
T_DjiOsalHandler *osalHandler = DjiPlatform_GetOsalHandler();
returnCode = osalHandler->MutexLock(s_zoomMutex);
if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
USER_LOG_ERROR("lock mutex error: 0x%08llX.", returnCode);
return returnCode;
}
*focalLength = s_cameraOpticalZoomFocalLength;
returnCode = osalHandler->MutexUnlock(s_zoomMutex);
if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
USER_LOG_ERROR("unlock mutex error: 0x%08llX.", returnCode);
return returnCode;
}
return DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS;
}
static T_DjiReturnCode GetOpticalZoomSpec(T_DjiCameraOpticalZoomSpec *spec)
{
spec->maxFocalLength = ZOOM_OPTICAL_FOCAL_MAX_LENGTH;
spec->minFocalLength = ZOOM_OPTICAL_FOCAL_MIN_LENGTH;
spec->focalLengthStep = ZOOM_OPTICAL_FOCAL_LENGTH_STEP;
return DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS;
}
static T_DjiReturnCode StartContinuousOpticalZoom(E_DjiCameraZoomDirection direction, E_DjiCameraZoomSpeed speed)
{
T_DjiReturnCode returnCode;
T_DjiOsalHandler *osalHandler = DjiPlatform_GetOsalHandler();
returnCode = osalHandler->MutexLock(s_zoomMutex);
if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
USER_LOG_ERROR("lock mutex error: 0x%08llX.", returnCode);
return returnCode;
}
USER_LOG_INFO("start continuous optical zoom direction:%d speed:%d", direction, speed);
s_isStartContinuousOpticalZoom = true;
s_cameraZoomDirection = direction;
s_cameraZoomSpeed = speed;
returnCode = osalHandler->MutexUnlock(s_zoomMutex);
if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
USER_LOG_ERROR("unlock mutex error: 0x%08llX.", returnCode);
return returnCode;
}
return DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS;
}
static T_DjiReturnCode StopContinuousOpticalZoom(void)
{
T_DjiReturnCode returnCode;
T_DjiOsalHandler *osalHandler = DjiPlatform_GetOsalHandler();
returnCode = osalHandler->MutexLock(s_zoomMutex);
if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
USER_LOG_ERROR("lock mutex error: 0x%08llX.", returnCode);
return returnCode;
}
USER_LOG_INFO("stop continuous optical zoom");
s_isStartContinuousOpticalZoom = false;
s_cameraZoomDirection = DJI_CAMERA_ZOOM_DIRECTION_OUT;
s_cameraZoomSpeed = DJI_CAMERA_ZOOM_SPEED_NORMAL;
returnCode = osalHandler->MutexUnlock(s_zoomMutex);
if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
USER_LOG_ERROR("unlock mutex error: 0x%08llX.", returnCode);
return returnCode;
}
return DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS;
}
static T_DjiReturnCode GetTapZoomState(T_DjiCameraTapZoomState *state)
{
T_DjiReturnCode returnCode;
T_DjiOsalHandler *osalHandler = DjiPlatform_GetOsalHandler();
returnCode = osalHandler->MutexLock(s_tapZoomMutex);
if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
USER_LOG_ERROR("lock mutex error: 0x%08llX.", returnCode);
return returnCode;
}
memcpy(state, &s_cameraTapZoomState, sizeof(T_DjiCameraTapZoomState));
returnCode = osalHandler->MutexUnlock(s_tapZoomMutex);
if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
USER_LOG_ERROR("unlock mutex error: 0x%08llX.", returnCode);
return returnCode;
}
return DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS;
}
static T_DjiReturnCode SetTapZoomEnabled(bool enabledFlag)
{
USER_LOG_INFO("set tap zoom enabled flag: %d.", enabledFlag);
s_isTapZoomEnabled = enabledFlag;
return DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS;
}
static T_DjiReturnCode GetTapZoomEnabled(bool *enabledFlag)
{
*enabledFlag = s_isTapZoomEnabled;
return DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS;
}
static T_DjiReturnCode SetTapZoomMultiplier(uint8_t multiplier)
{
USER_LOG_INFO("set tap zoom multiplier: %d.", multiplier);
s_tapZoomMultiplier = multiplier;
return DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS;
}
static T_DjiReturnCode GetTapZoomMultiplier(uint8_t *multiplier)
{
*multiplier = s_tapZoomMultiplier;
return DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS;
}
static T_DjiReturnCode TapZoomAtTarget(T_DjiCameraPointInScreen target)
{
T_DjiReturnCode returnCode;
E_DjiGimbalRotationMode rotationMode;
T_DjiGimbalRotationProperty rotationProperty = {0};
T_DjiAttitude3d rotationValue = {0};
float hybridFocalLength = 0; // unit: 0.1mm
T_DjiOsalHandler *osalHandler = DjiPlatform_GetOsalHandler();
USER_LOG_INFO("tap zoom at target: x %f, y %f.", target.focusX, target.focusY);
if (s_isTapZoomEnabled != true) {
USER_LOG_WARN("tap zoom is not enabled.");
return DJI_ERROR_SYSTEM_MODULE_CODE_SYSTEM_ERROR;
}
if (s_isTapZooming || s_isStartTapZoom) {
USER_LOG_WARN("The last tap zoom process is not over.");
return DJI_ERROR_SYSTEM_MODULE_CODE_NONSUPPORT_IN_CURRENT_STATE;
}
rotationMode = DJI_GIMBAL_ROTATION_MODE_RELATIVE_ANGLE;
rotationProperty.relativeAngleRotation.actionTime = TAP_ZOOM_DURATION / 10;
returnCode = osalHandler->MutexLock(s_zoomMutex);
if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
USER_LOG_ERROR("lock mutex error: 0x%08llX.", returnCode);
return returnCode;
}
/* Calculation formula: rotation angle = arctan((coordinate of target in sensor - coordinate of center point in
* sensor) / hybrid focal length). Here, suppose that images of all pixels of sensor are displayed in screen,
* and that center of the image sensor coincides with center of rotation of the gimbal, and that optical axis of
* camera coincides with x-axis of gimbal. */
hybridFocalLength = (dji_f32_t) s_cameraOpticalZoomFocalLength * s_cameraDigitalZoomFactor;
returnCode = osalHandler->MutexUnlock(s_zoomMutex);
if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
USER_LOG_ERROR("unlock mutex error: 0x%08llX.", returnCode);
return returnCode;
}
rotationValue.pitch = (int32_t) (
atan2f((target.focusY - CENTER_POINT_IN_SCREEN_Y_VALUE) * IMAGE_SENSOR_Y_SIZE, hybridFocalLength) * 1800 /
DJI_PI);
rotationValue.yaw = (int32_t) (
atan2f((target.focusX - CENTER_POINT_IN_SCREEN_X_VALUE) * IMAGE_SENSOR_X_SIZE, hybridFocalLength) * 1800 /
DJI_PI);
returnCode = osalHandler->MutexLock(s_tapZoomMutex);
if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
USER_LOG_ERROR("lock mutex error: 0x%08llX.", returnCode);
return returnCode;
}
s_tapZoomNewestGimbalRotationArgument.rotationMode = rotationMode;
s_tapZoomNewestGimbalRotationArgument.rotationProperty = rotationProperty;
s_tapZoomNewestGimbalRotationArgument.rotationValue = rotationValue;
s_tapZoomNewestTargetHybridFocalLength = (uint32_t) (hybridFocalLength * (float) s_tapZoomMultiplier);
returnCode = osalHandler->MutexUnlock(s_tapZoomMutex);
if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
USER_LOG_ERROR("unlock mutex error: 0x%08llX.", returnCode);
return returnCode;
}
s_isStartTapZoom = true;
return DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS;
}
static T_DjiReturnCode DjiTest_CameraHybridZoom(uint32_t focalLength)
{
if (focalLength >= ZOOM_OPTICAL_FOCAL_MIN_LENGTH && focalLength <= ZOOM_OPTICAL_FOCAL_MAX_LENGTH) {
s_cameraOpticalZoomFocalLength = focalLength;
s_cameraDigitalZoomFactor = ZOOM_DIGITAL_BASE_FACTOR;
} else if (focalLength < ZOOM_OPTICAL_FOCAL_MIN_LENGTH) {
s_cameraOpticalZoomFocalLength = ZOOM_OPTICAL_FOCAL_MIN_LENGTH;
s_cameraDigitalZoomFactor = ZOOM_DIGITAL_BASE_FACTOR;
USER_LOG_ERROR("focal length %d is smaller than min optical focal length %d.", focalLength,
ZOOM_OPTICAL_FOCAL_MIN_LENGTH);
return DJI_ERROR_SYSTEM_MODULE_CODE_OUT_OF_RANGE;
} else {
s_cameraOpticalZoomFocalLength = ZOOM_OPTICAL_FOCAL_MAX_LENGTH;
s_cameraDigitalZoomFactor = (float) focalLength / ZOOM_OPTICAL_FOCAL_MAX_LENGTH;
}
return DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS;
}
static T_DjiReturnCode DjiTest_CameraRotationGimbal(T_TestCameraGimbalRotationArgument gimbalRotationArgument)
{
T_DjiReturnCode returnCode;
T_DjiAircraftInfoBaseInfo aircraftBaseInfo = {0};
returnCode = DjiAircraftInfo_GetBaseInfo(&aircraftBaseInfo);
if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
USER_LOG_ERROR("get aircraft information error: 0x%08llX.", returnCode);
return returnCode;
}
if (aircraftBaseInfo.djiAdapterType == DJI_SDK_ADAPTER_TYPE_SKYPORT_V2 ||
aircraftBaseInfo.djiAdapterType == DJI_SDK_ADAPTER_TYPE_NONE) {
returnCode = DjiTest_GimbalRotate(gimbalRotationArgument.rotationMode, gimbalRotationArgument.rotationProperty,
gimbalRotationArgument.rotationValue);
if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
USER_LOG_ERROR("rotate gimbal error: 0x%08llX.", returnCode);
return returnCode;
}
} else if (aircraftBaseInfo.djiAdapterType == DJI_SDK_ADAPTER_TYPE_XPORT) {
returnCode = DjiXPort_RotateSync(gimbalRotationArgument.rotationMode, gimbalRotationArgument.rotationProperty,
gimbalRotationArgument.rotationValue);
if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
USER_LOG_ERROR("rotate XPort error: 0x%08llX.", returnCode);
return returnCode;
}
} else {
USER_LOG_ERROR("PSDK adapter type is invalid: %d.", aircraftBaseInfo.djiAdapterType);
return DJI_ERROR_SYSTEM_MODULE_CODE_NONSUPPORT;
}
return DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS;
}
#ifndef __CC_ARM
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wmissing-noreturn"
#pragma GCC diagnostic ignored "-Wreturn-type"
#endif
static void *UserCamera_Task(void *arg)
{
static uint32_t photoCnt = 0;
static uint32_t step = 0;
T_DjiReturnCode returnCode;
int32_t tempFocalLength = 0;
dji_f32_t tempDigitalFactor = 0.0f;
uint32_t currentTime = 0;
bool isStartIntervalPhotoAction = false;
T_DjiOsalHandler *osalHandler = DjiPlatform_GetOsalHandler();
USER_UTIL_UNUSED(arg);
while (1) {
osalHandler->TaskSleepMs(1000 / PAYLOAD_CAMERA_EMU_TASK_FREQ);
step++;
returnCode = osalHandler->MutexLock(s_commonMutex);
if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
USER_LOG_ERROR("lock mutex error: 0x%08llX.", returnCode);
continue;
}
s_cameraSDCardState.availableRecordingTimeInSeconds =
s_cameraSDCardState.remainSpaceInMB / SDCARD_PER_SECONDS_RECORD_SPACE_IN_MB;
s_cameraSDCardState.availableCaptureCount = s_cameraSDCardState.remainSpaceInMB / SDCARD_PER_PHOTO_SPACE_IN_MB;
//l理解你的照片 短和逻辑存储
//realize your photo shoot and storage logic here
if (s_cameraState.shootingState != DJI_CAMERA_SHOOTING_PHOTO_IDLE &&
photoCnt++ > TAKING_PHOTO_SPENT_TIME_MS_EMU / (1000 / PAYLOAD_CAMERA_EMU_TASK_FREQ)) {
photoCnt = 0;
//在拍摄结束后 把照片放入仓库
//store the photo after shooting finished
if (s_cameraShootPhotoMode == DJI_CAMERA_SHOOT_PHOTO_MODE_SINGLE) {
s_cameraSDCardState.remainSpaceInMB =
s_cameraSDCardState.remainSpaceInMB - SDCARD_PER_PHOTO_SPACE_IN_MB;
s_cameraState.isStoring = false;
s_cameraState.shootingState = DJI_CAMERA_SHOOTING_PHOTO_IDLE;
} else if (s_cameraShootPhotoMode == DJI_CAMERA_SHOOT_PHOTO_MODE_BURST) {
s_cameraSDCardState.remainSpaceInMB =
s_cameraSDCardState.remainSpaceInMB - SDCARD_PER_PHOTO_SPACE_IN_MB * s_cameraBurstCount;
s_cameraState.isStoring = false;
s_cameraState.shootingState = DJI_CAMERA_SHOOTING_PHOTO_IDLE;
} else if (s_cameraShootPhotoMode == DJI_CAMERA_SHOOT_PHOTO_MODE_INTERVAL) {
if (isStartIntervalPhotoAction == true) {
s_cameraState.isStoring = false;
s_cameraState.shootingState = DJI_CAMERA_SHOOTING_PHOTO_IDLE;
s_cameraSDCardState.remainSpaceInMB =
s_cameraSDCardState.remainSpaceInMB - SDCARD_PER_PHOTO_SPACE_IN_MB;
}
}
// 检查 sd卡 的 保留空间
//check the remain space of sdcard
if (s_cameraSDCardState.remainSpaceInMB > SDCARD_TOTAL_SPACE_IN_MB) {
s_cameraSDCardState.remainSpaceInMB = 0;
s_cameraSDCardState.isFull = true;
}
#if dji_ARCH_SYS_LINUX
T_DjiCameraMediaFileInfo mediaFileInfo = {0};
// 退入 媒体文件信息
// push added media file information
if (s_cameraShootPhotoMode == dji_CAMERA_SHOOT_PHOTO_MODE_SINGLE) {
if (UtilFile_IsFileExist(PHOTO_FILE_PATH) == true) {
psdkStat = PsdkTest_CameraMediaGetFileInfo(PHOTO_FILE_PATH, &mediaFileInfo);
if (psdkStat != dji_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
PsdkLogger_UserLogError("Get media file info error 0x%08llX", psdkStat);
}
psdkStat = PsdkPayloadCamera_PushAddedMediaFileInfo(PHOTO_FILE_PATH, mediaFileInfo);
if (psdkStat != dji_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
PsdkLogger_UserLogError("Push added media file info error 0x%08llX", psdkStat);
}
} else {
PsdkLogger_UserLogWarn("Can't found the media file by path. "
"Probably because media file has not existed. "
"Please check media file if exists. ");
}
}
#endif
}
returnCode = osalHandler->MutexUnlock(s_commonMutex);
if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
USER_LOG_ERROR("unlock mutex error: 0x%08llX.", returnCode);
continue;
}
// 10Hz
if (USER_UTIL_IS_WORK_TURN(step, 10, PAYLOAD_CAMERA_EMU_TASK_FREQ)) {
returnCode = osalHandler->MutexLock(s_zoomMutex);
if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
USER_LOG_ERROR("lock mutex error: 0x%08llX.", returnCode);
continue;
}
#ifdef USER_CAMERA_EMU_HYBRID_ZOOM_ON
//Add logic here for zoom camera
if (s_isStartContinuousOpticalZoom == true) {
tempDigitalFactor = s_cameraDigitalZoomFactor;
tempFocalLength = (int32_t) s_cameraOpticalZoomFocalLength;
if (s_isOpticalZoomReachLimit == false) {
if (s_cameraZoomDirection == DJI_CAMERA_ZOOM_DIRECTION_IN) {
tempFocalLength += ((int) s_cameraZoomSpeed - DJI_CAMERA_ZOOM_SPEED_SLOWEST + 1) *
ZOOM_OPTICAL_FOCAL_LENGTH_CTRL_STEP;
} else if (s_cameraZoomDirection == DJI_CAMERA_ZOOM_DIRECTION_OUT) {
tempFocalLength -= ((int) s_cameraZoomSpeed - DJI_CAMERA_ZOOM_SPEED_SLOWEST + 1) *
ZOOM_OPTICAL_FOCAL_LENGTH_CTRL_STEP;
}
if (tempFocalLength > ZOOM_OPTICAL_FOCAL_MAX_LENGTH) {
s_isOpticalZoomReachLimit = true;
tempFocalLength = ZOOM_OPTICAL_FOCAL_MAX_LENGTH;
}
if (tempFocalLength < ZOOM_OPTICAL_FOCAL_MIN_LENGTH) {
tempFocalLength = ZOOM_OPTICAL_FOCAL_MIN_LENGTH;
}
} else {
if (s_cameraZoomDirection == DJI_CAMERA_ZOOM_DIRECTION_IN) {
tempDigitalFactor += (dji_f32_t) ZOOM_DIGITAL_STEP_FACTOR;
} else if (s_cameraZoomDirection == DJI_CAMERA_ZOOM_DIRECTION_OUT) {
tempDigitalFactor -= (dji_f32_t) ZOOM_DIGITAL_STEP_FACTOR;
}
if (tempDigitalFactor > (dji_f32_t) ZOOM_DIGITAL_MAX_FACTOR) {
tempDigitalFactor = (dji_f32_t) ZOOM_DIGITAL_MAX_FACTOR;
}
if (tempDigitalFactor < (dji_f32_t) ZOOM_DIGITAL_BASE_FACTOR) {
s_isOpticalZoomReachLimit = false;
tempDigitalFactor = ZOOM_DIGITAL_BASE_FACTOR;
}
}
s_cameraOpticalZoomFocalLength = (uint16_t) tempFocalLength;
s_cameraDigitalZoomFactor = tempDigitalFactor;
}
#endif
#if USER_CAMERA_EMU_TAP_ZOOM_ON
returnCode = osalHandler->MutexLock(s_tapZoomMutex);
if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
USER_LOG_ERROR("lock mutex error: 0x%08llX.", returnCode);
goto out;
}
if (s_isStartTapZoom) {
s_isStartTapZoom = false;
s_isTapZooming = true;
returnCode = osalHandler->GetTimeMs(&s_tapZoomStartTime);
if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
USER_LOG_ERROR("get start time error: 0x%08llX.", returnCode);
}
returnCode = DjiTest_CameraRotationGimbal(s_tapZoomNewestGimbalRotationArgument);
if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS)
USER_LOG_ERROR("rotate gimbal error: 0x%08llX.", returnCode);
else
s_cameraTapZoomState.isGimbalMoving = true;
returnCode = DjiTest_CameraHybridZoom(s_tapZoomNewestTargetHybridFocalLength);
if (returnCode == DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
s_cameraTapZoomState.zoomState = (dji_f32_t) s_tapZoomNewestTargetHybridFocalLength >
((dji_f32_t) s_cameraOpticalZoomFocalLength *
s_cameraDigitalZoomFactor)
? DJI_CAMERA_TAP_ZOOM_STATE_ZOOM_IN
: DJI_CAMERA_TAP_ZOOM_STATE_ZOOM_OUT;
} else if (returnCode == DJI_ERROR_SYSTEM_MODULE_CODE_OUT_OF_RANGE) {
USER_LOG_ERROR("hybrid zoom focal length beyond limit.");
s_cameraTapZoomState.zoomState = DJI_CAMERA_TAP_ZOOM_STATE_ZOOM_LIMITED;
} else {
USER_LOG_ERROR("hybrid zoom error: 0x%08llX.", returnCode);
}
} else if (s_isTapZooming) {
returnCode = osalHandler->GetTimeMs(&currentTime);
if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
USER_LOG_ERROR("get start time error: 0x%08llX.", returnCode);
}
if ((currentTime - s_tapZoomStartTime) >= TAP_ZOOM_DURATION) {
s_cameraTapZoomState.zoomState = DJI_CAMERA_TAP_ZOOM_STATE_IDLE;
s_cameraTapZoomState.isGimbalMoving = false;
s_isTapZooming = false;
}
}
returnCode = osalHandler->MutexUnlock(s_tapZoomMutex);
if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
USER_LOG_ERROR("unlock mutex error: 0x%08llX.", returnCode);
goto out;
}
#endif
out:
returnCode = osalHandler->MutexUnlock(s_zoomMutex);
if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
USER_LOG_ERROR("unlock mutex error: 0x%08llX.", returnCode);
continue;
}
}
// 1Hz
if (USER_UTIL_IS_WORK_TURN(step, 1, PAYLOAD_CAMERA_EMU_TASK_FREQ)) {
returnCode = osalHandler->MutexLock(s_commonMutex);
if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
USER_LOG_ERROR("lock mutex error: 0x%08llX.", returnCode);
continue;
}
if (s_cameraState.isRecording) {
s_cameraState.currentVideoRecordingTimeInSeconds++;
s_cameraSDCardState.remainSpaceInMB =
s_cameraSDCardState.remainSpaceInMB - SDCARD_PER_SECONDS_RECORD_SPACE_IN_MB;
if (s_cameraSDCardState.remainSpaceInMB > SDCARD_TOTAL_SPACE_IN_MB) {
s_cameraSDCardState.remainSpaceInMB = 0;
s_cameraSDCardState.isFull = true;
}
}
if (s_cameraState.isShootingIntervalStart == false) {
isStartIntervalPhotoAction = false;
}
if (s_cameraShootPhotoMode == DJI_CAMERA_SHOOT_PHOTO_MODE_INTERVAL
&& s_cameraState.isShootingIntervalStart == true && s_cameraPhotoTimeIntervalSettings.captureCount > 0
&& s_cameraPhotoTimeIntervalSettings.timeIntervalSeconds > 0) {
s_cameraState.currentPhotoShootingIntervalTimeInSeconds--;
if ((s_cameraState.currentPhotoShootingIntervalTimeInSeconds == 0 &&
s_cameraState.currentPhotoShootingIntervalCount > 0) ||
(s_cameraState.isShootingIntervalStart == true && isStartIntervalPhotoAction == false)) {
isStartIntervalPhotoAction = true;
s_cameraState.shootingState = DJI_CAMERA_SHOOTING_INTERVAL_PHOTO;
s_cameraState.isStoring = true;
s_cameraState.currentPhotoShootingIntervalTimeInSeconds
= s_cameraPhotoTimeIntervalSettings.timeIntervalSeconds;
if (s_cameraState.currentPhotoShootingIntervalCount < INTERVAL_PHOTOGRAPH_ALWAYS_COUNT) {
USER_LOG_INFO("interval taking photograph count:%d interval_time:%ds",
(s_cameraPhotoTimeIntervalSettings.captureCount -
s_cameraState.currentPhotoShootingIntervalCount + 1),
s_cameraPhotoTimeIntervalSettings.timeIntervalSeconds);
JZsdk_Psdk_UI_io_ShootPhoto();
s_cameraState.currentPhotoShootingIntervalCount--;
if (s_cameraState.currentPhotoShootingIntervalCount == 0) {
s_cameraState.shootingState = DJI_CAMERA_SHOOTING_PHOTO_IDLE;
s_cameraState.isStoring = false;
s_cameraState.isShootingIntervalStart = false;
}
} else {
USER_LOG_INFO("interval taking photograph always, interval_time:%ds",
s_cameraPhotoTimeIntervalSettings.timeIntervalSeconds);
JZsdk_Psdk_UI_io_ShootPhoto();
s_cameraState.currentPhotoShootingIntervalCount--;
}
}
}
returnCode = osalHandler->MutexUnlock(s_commonMutex);
if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
USER_LOG_ERROR("unlock mutex error: 0x%08llX.", returnCode);
continue;
}
}
}
}
#ifndef __CC_ARM
#pragma GCC diagnostic pop
#endif
/* Private functions definition-----------------------------------------------*/
// 照相机 菜单 基础 开始 服务
T_DjiReturnCode DjiTest_CameraEmuBaseStartService(void)
{
T_DjiReturnCode returnCode;
char ipAddr[DJI_IP_ADDR_STR_SIZE_MAX] = {0};
uint16_t port = 0;
T_DjiOsalHandler *osalHandler = DjiPlatform_GetOsalHandler();
T_DjiAircraftInfoBaseInfo aircraftInfoBaseInfo = {0};
returnCode = osalHandler->MutexCreate(&s_commonMutex);
if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
USER_LOG_ERROR("create mutex used to lock tap zoom arguments error: 0x%08llX", returnCode);
return returnCode;
}
returnCode = osalHandler->MutexCreate(&s_zoomMutex);
if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
USER_LOG_ERROR("create mutex used to lock tap zoom arguments error: 0x%08llX", returnCode);
return returnCode;
}
returnCode = osalHandler->MutexCreate(&s_tapZoomMutex);
if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
USER_LOG_ERROR("create mutex used to lock tap zoom arguments error: 0x%08llX", returnCode);
return returnCode;
}
returnCode = DjiPayloadCamera_Init();
if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
USER_LOG_ERROR("init payload camera error:0x%08llX", returnCode);
return returnCode;
}
// 初始化 sd卡的环境
/* Init the SDcard parameters */
s_cameraSDCardState.isInserted = true;
s_cameraSDCardState.isVerified = true;
s_cameraSDCardState.totalSpaceInMB = SDCARD_TOTAL_SPACE_IN_MB;
s_cameraSDCardState.remainSpaceInMB = SDCARD_TOTAL_SPACE_IN_MB;
s_cameraSDCardState.availableCaptureCount = SDCARD_TOTAL_SPACE_IN_MB / SDCARD_PER_PHOTO_SPACE_IN_MB;
s_cameraSDCardState.availableRecordingTimeInSeconds =
SDCARD_TOTAL_SPACE_IN_MB / SDCARD_PER_SECONDS_RECORD_SPACE_IN_MB;
// 注册相机 指令 的 权柄
/* Register the camera common handler */
s_commonHandler.GetSystemState = GetSystemState;
s_commonHandler.SetMode = SetMode;
s_commonHandler.GetMode = DjiTest_CameraGetMode;
s_commonHandler.StartRecordVideo = StartRecordVideo;
s_commonHandler.StopRecordVideo = StopRecordVideo;
s_commonHandler.StartShootPhoto = StartShootPhoto;
s_commonHandler.StopShootPhoto = StopShootPhoto;
s_commonHandler.SetShootPhotoMode = SetShootPhotoMode;
s_commonHandler.GetShootPhotoMode = GetShootPhotoMode;
s_commonHandler.SetPhotoBurstCount = SetPhotoBurstCount;
s_commonHandler.GetPhotoBurstCount = GetPhotoBurstCount;
s_commonHandler.SetPhotoTimeIntervalSettings = SetPhotoTimeIntervalSettings;
s_commonHandler.GetPhotoTimeIntervalSettings = GetPhotoTimeIntervalSettings;
s_commonHandler.GetSDCardState = GetSDCardState;
s_commonHandler.FormatSDCard = FormatSDCard;
returnCode = DjiPayloadCamera_RegCommonHandler(&s_commonHandler);
if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
USER_LOG_ERROR("camera register common handler error:0x%08llX", returnCode);
}
/* Register the camera metering handler */
#if USER_CAMERA_EMU_METERING_ON
s_exposureMeteringHandler.SetMeteringMode = SetMeteringMode;
s_exposureMeteringHandler.GetMeteringMode = GetMeteringMode;
s_exposureMeteringHandler.SetSpotMeteringTarget = SetSpotMeteringTarget;
s_exposureMeteringHandler.GetSpotMeteringTarget = GetSpotMeteringTarget;
returnCode = DjiPayloadCamera_RegExposureMeteringHandler(&s_exposureMeteringHandler);
if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
USER_LOG_ERROR("camera register exposure metering handler error:0x%08llX", returnCode);
return returnCode;
}
#endif
// 注册 相机 焦点 句柄
/* Register the camera focus handler */
#if USER_CAMERA_EMU_FOCUS_ON
s_focusHandler.SetFocusMode = SetFocusMode;
s_focusHandler.GetFocusMode = GetFocusMode;
s_focusHandler.SetFocusTarget = SetFocusTarget;
s_focusHandler.GetFocusTarget = GetFocusTarget;
s_focusHandler.SetFocusAssistantSettings = SetFocusAssistantSettings;
s_focusHandler.GetFocusAssistantSettings = GetFocusAssistantSettings;
s_focusHandler.SetFocusRingValue = SetFocusRingValue;
s_focusHandler.GetFocusRingValue = GetFocusRingValue;
s_focusHandler.GetFocusRingValueUpperBound = GetFocusRingValueUpperBound;
returnCode = DjiPayloadCamera_RegFocusHandler(&s_focusHandler);
if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
USER_LOG_ERROR("camera register adjustable focal point handler error:0x%08llX", returnCode);
return returnCode;
}
#endif
// 注册 相机 数码变焦 的句柄
/* Register the camera digital zoom handler */
#if USER_CAMERA_EMU_HYBRID_ZOOM_ON
s_digitalZoomHandler.SetDigitalZoomFactor = SetDigitalZoomFactor;
s_digitalZoomHandler.GetDigitalZoomFactor = DjiTest_CameraGetDigitalZoomFactor;
returnCode = DjiPayloadCamera_RegDigitalZoomHandler(&s_digitalZoomHandler);
if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
USER_LOG_ERROR("camera register digital zoom handler error:0x%08llX", returnCode);
return returnCode;
}
// 注册 相机 光学 变焦
/* Register the camera optical zoom handler */
s_opticalZoomHandler.SetOpticalZoomFocalLength = SetOpticalZoomFocalLength;
s_opticalZoomHandler.GetOpticalZoomFocalLength = GetOpticalZoomFocalLength;
s_opticalZoomHandler.GetOpticalZoomFactor = DjiTest_CameraGetOpticalZoomFactor;
s_opticalZoomHandler.GetOpticalZoomSpec = GetOpticalZoomSpec;
s_opticalZoomHandler.StartContinuousOpticalZoom = StartContinuousOpticalZoom;
s_opticalZoomHandler.StopContinuousOpticalZoom = StopContinuousOpticalZoom;
returnCode = DjiPayloadCamera_RegOpticalZoomHandler(&s_opticalZoomHandler);
if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
USER_LOG_ERROR("camera register optical zoom handler error:0x%08llX", returnCode);
return returnCode;
}
#endif
// 注册 利用变焦
/* Register the camera tap zoom handler */
#if USER_CAMERA_EMU_TAP_ZOOM_ON
s_tapZoomHandler.GetTapZoomState = GetTapZoomState;
s_tapZoomHandler.SetTapZoomEnabled = SetTapZoomEnabled;
s_tapZoomHandler.GetTapZoomEnabled = GetTapZoomEnabled;
s_tapZoomHandler.SetTapZoomMultiplier = SetTapZoomMultiplier;
s_tapZoomHandler.GetTapZoomMultiplier = GetTapZoomMultiplier;
s_tapZoomHandler.TapZoomAtTarget = TapZoomAtTarget;
returnCode = DjiPayloadCamera_RegTapZoomHandler(&s_tapZoomHandler);
if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
USER_LOG_ERROR("camera register tap zoom handler error:0x%08llX", returnCode);
return returnCode;
}
#endif
// 注册 相机的 菜单 任务
/* Create the camera emu taskHandle */
if (osalHandler->TaskCreate("user_camera_task", UserCamera_Task,
PAYLOAD_CAMERA_EMU_TASK_STACK_SIZE, NULL, &s_userCameraThread)
!= DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
USER_LOG_ERROR("user camera taskHandle create error");
return DJI_ERROR_SYSTEM_MODULE_CODE_UNKNOWN;
}
// 得到 相机 的 基础 信息
if (DjiAircraftInfo_GetBaseInfo(&aircraftInfoBaseInfo) != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
USER_LOG_ERROR("get aircraft information error.");
return DJI_ERROR_SYSTEM_MODULE_CODE_UNKNOWN;
}
// 设置 视频 流 的 类型
returnCode = DjiPayloadCamera_SetVideoStreamType(DJI_CAMERA_VIDEO_STREAM_TYPE_H264_DJI_FORMAT);
if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
USER_LOG_ERROR("DJI camera set video stream error.");
return DJI_ERROR_SYSTEM_MODULE_CODE_UNKNOWN;
}
//设置传输视频的类型
s_cameraVideoStreamType = DJI_CAMERA_VIDEO_STREAM_TYPE_H264_DJI_FORMAT;
// 获取视频流远程地址 飞机云台的地址
returnCode = DjiPayloadCamera_GetVideoStreamRemoteAddress(ipAddr, &port);
if (returnCode == DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
USER_LOG_DEBUG("Get video stream remote address: %s, port: %d", ipAddr, port);
} else {
USER_LOG_ERROR("get video stream remote address error.");
return DJI_ERROR_SYSTEM_MODULE_CODE_UNKNOWN;
}
s_isCamInited = true;
return DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS;
}
T_DjiReturnCode DjiTest_CameraGetDigitalZoomFactor(dji_f32_t *factor)
{
T_DjiReturnCode returnCode;
T_DjiOsalHandler *osalHandler = DjiPlatform_GetOsalHandler();
returnCode = osalHandler->MutexLock(s_zoomMutex);
if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
USER_LOG_ERROR("lock mutex error: 0x%08llX.", returnCode);
return returnCode;
}
*factor = s_cameraDigitalZoomFactor;
returnCode = osalHandler->MutexUnlock(s_zoomMutex);
if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
USER_LOG_ERROR("unlock mutex error: 0x%08llX.", returnCode);
return returnCode;
}
return DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS;
}
T_DjiReturnCode DjiTest_CameraGetOpticalZoomFactor(dji_f32_t *factor)
{
T_DjiReturnCode returnCode;
T_DjiOsalHandler *osalHandler = DjiPlatform_GetOsalHandler();
returnCode = osalHandler->MutexLock(s_zoomMutex);
if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
USER_LOG_ERROR("lock mutex error: 0x%08llX.", returnCode);
return returnCode;
}
//Formula:factor = currentFocalLength / minFocalLength
*factor = (dji_f32_t) s_cameraOpticalZoomFocalLength / ZOOM_OPTICAL_FOCAL_MIN_LENGTH;
returnCode = osalHandler->MutexUnlock(s_zoomMutex);
if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
USER_LOG_ERROR("unlock mutex error: 0x%08llX.", returnCode);
return returnCode;
}
return DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS;
}
T_DjiReturnCode DjiTest_CameraGetMode(E_DjiCameraMode *mode)
{
T_DjiReturnCode returnCode;
T_DjiOsalHandler *osalHandler = DjiPlatform_GetOsalHandler();
returnCode = osalHandler->MutexLock(s_commonMutex);
if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
USER_LOG_ERROR("lock mutex error: 0x%08llX.", returnCode);
return returnCode;
}
*mode = s_cameraState.cameraMode;
returnCode = osalHandler->MutexUnlock(s_commonMutex);
if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
USER_LOG_ERROR("unlock mutex error: 0x%08llX.", returnCode);
return returnCode;
}
return DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS;
}
T_DjiReturnCode DjiTest_CameraGetVideoStreamType(E_DjiCameraVideoStreamType *type)
{
if (s_isCamInited == false) {
return DJI_ERROR_SYSTEM_MODULE_CODE_NONSUPPORT_IN_CURRENT_STATE;
}
*type = s_cameraVideoStreamType;
return DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS;
}
bool DjiTest_CameraIsInited(void)
{
return s_isCamInited;
}
/****************** (C) COPYRIGHT DJI Innovations *****END OF FILE****/
//手动添加 by ookk303
// 0空闲中 1录像中 2单拍中 3连拍中 4转码中
void DJI_CamEmu_base_CameraTransLock(int flag)
{
switch (flag)
{
case 0:
{
s_cameraState.isRecording = 0;
s_cameraState.isStoring = 0;
break;
}
case 1:
{
s_cameraState.isRecording = 1;
s_cameraState.isStoring = 0;
break;
}
case 2:
{
s_cameraState.isRecording = 0;
s_cameraState.isStoring = 1;
break;
}
case 3:
{
s_cameraState.isRecording = 0;
s_cameraState.isStoring = 1;
break;
}
case 4:
{
s_cameraState.isRecording = 0;
s_cameraState.isStoring = 1;
break;
}
default:
break;
}
}
\ No newline at end of file
... ...
/**
********************************************************************
* @file test_payload_cam_emu_common.h
* @brief This is the header file for "test_payload_cam_emu.c", defining the structure and
* (exported) function prototypes.
*
* @copyright (c) 2021 DJI. All rights reserved.
*
* All information contained herein is, and remains, the property of DJI.
* The intellectual and technical concepts contained herein are proprietary
* to DJI and may be covered by U.S. and foreign patents, patents in process,
* and protected by trade secret or copyright law. Dissemination of this
* information, including but not limited to data and other proprietary
* material(s) incorporated within the information, in any form, is strictly
* prohibited without the express written consent of DJI.
*
* If you receive this source code without DJI’s authorization, you may not
* further disseminate the information, and you must immediately remove the
* source code and notify DJI of its removal. DJI reserves the right to pursue
* legal actions against you for any loss(es) or damage(s) caused by your
* failure to do so.
*
*********************************************************************
*/
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef TEST_PAYLOAD_CAM_EMU_BASE_H
#define TEST_PAYLOAD_CAM_EMU_BASE_H
/* Includes ------------------------------------------------------------------*/
#include "dji_typedef.h"
#include "dji_payload_camera.h"
#ifdef __cplusplus
extern "C" {
#endif
/* Exported constants --------------------------------------------------------*/
/* Exported types ------------------------------------------------------------*/
/* Exported functions --------------------------------------------------------*/
T_DjiReturnCode DjiTest_CameraEmuBaseStartService(void);
T_DjiReturnCode DjiTest_CameraGetDigitalZoomFactor(dji_f32_t *factor);
T_DjiReturnCode DjiTest_CameraGetOpticalZoomFactor(dji_f32_t *factor);
T_DjiReturnCode DjiTest_CameraGetMode(E_DjiCameraMode *mode);
T_DjiReturnCode DjiTest_CameraGetVideoStreamType(E_DjiCameraVideoStreamType *type);
bool DjiTest_CameraIsInited(void);
void DJI_CamEmu_base_CameraTransLock(int flag);
#ifdef __cplusplus
}
#endif
#endif // TEST_PAYLOAD_CAM_EMU_BASE_H
/************************ (C) COPYRIGHT DJI Innovations *******END OF FILE******/
... ...
/**
********************************************************************
* @file test_payload_cam_emu_media.c
* @brief
*
* @copyright (c) 2021 DJI. All rights reserved.
*
* All information contained herein is, and remains, the property of DJI.
* The intellectual and technical concepts contained herein are proprietary
* to DJI and may be covered by U.S. and foreign patents, patents in process,
* and protected by trade secret or copyright law. Dissemination of this
* information, including but not limited to data and other proprietary
* material(s) incorporated within the information, in any form, is strictly
* prohibited without the express written consent of DJI.
*
* If you receive this source code without DJI’s authorization, you may not
* further disseminate the information, and you must immediately remove the
* source code and notify DJI of its removal. DJI reserves the right to pursue
* legal actions against you for any loss(es) or damage(s) caused by your
* failure to do so.
*
*********************************************************************
*/
/* Includes ------------------------------------------------------------------*/
#include <fcntl.h>
#include <stdlib.h>
#include "dji_logger.h"
#include "utils/util_misc.h"
#include "utils/util_time.h"
#include "utils/util_file.h"
#include "utils/util_buffer.h"
#include "test_payload_cam_emu_media.h"
#include "test_payload_cam_emu_base.h"
#include "camera_emu/dji_media_file_manage/dji_media_file_core.h"
#include "dji_high_speed_data_channel.h"
#include "dji_aircraft_info.h"
#include "Dji_Control/DJI_VideoDeal.h"
#include <pthread.h>
/* Private constants ---------------------------------------------------------*/
#define FFMPEG_CMD_BUF_SIZE (256 + 256)
#define SEND_VIDEO_TASK_FREQ 120
#define VIDEO_FRAME_MAX_COUNT 18000 // max video duration 10 minutes
#define VIDEO_FRAME_AUD_LEN 6
#define DATA_SEND_FROM_VIDEO_STREAM_MAX_LEN 60000
//飞机传输通道值占比
#define TRANS_RATIO_DATA (10)
#define TRANS_RATIO_VIDEO (85)
#define TRANS_RATIO_DOWNLOAD (5)
/* Private types -------------------------------------------------------------*/
typedef enum {
TEST_PAYLOAD_CAMERA_MEDIA_PLAY_COMMAND_STOP = 0,
TEST_PAYLOAD_CAMERA_MEDIA_PLAY_COMMAND_PAUSE = 1,
TEST_PAYLOAD_CAMERA_MEDIA_PLAY_COMMAND_START = 2,
} E_TestPayloadCameraPlaybackCommand;
typedef struct {
uint8_t isInPlayProcess;
uint16_t videoIndex;
char filePath[DJI_FILE_PATH_SIZE_MAX];
uint32_t videoLengthMs;
uint64_t startPlayTimestampsUs;
uint64_t playPosMs;
} T_DjiPlaybackInfo;
typedef struct {
E_TestPayloadCameraPlaybackCommand command;
uint32_t timeMs;
char path[DJI_FILE_PATH_SIZE_MAX];
} T_TestPayloadCameraPlaybackCommand;
typedef struct {
float durationS;
uint32_t positionInFile;
uint32_t size;
} T_TestPayloadCameraVideoFrameInfo;
/* Private functions declaration ---------------------------------------------*/
static T_DjiReturnCode DjiPlayback_StopPlay(T_DjiPlaybackInfo *playbackInfo);
static T_DjiReturnCode DjiPlayback_PausePlay(T_DjiPlaybackInfo *playbackInfo);
static T_DjiReturnCode DjiPlayback_SetPlayFile(T_DjiPlaybackInfo *playbackInfo, const char *filePath,
uint16_t index);
static T_DjiReturnCode DjiPlayback_SeekPlay(T_DjiPlaybackInfo *playbackInfo, uint32_t seekPos);
static T_DjiReturnCode DjiPlayback_StartPlay(T_DjiPlaybackInfo *playbackInfo);
static T_DjiReturnCode DjiPlayback_GetPlaybackStatus(T_DjiPlaybackInfo *playbackInfo,
T_DjiCameraPlaybackStatus *playbackStatus);
static T_DjiReturnCode DjiPlayback_GetVideoLengthMs(const char *filePath, uint32_t *videoLengthMs);
static T_DjiReturnCode DjiPlayback_StartPlayProcess(const char *filePath, uint32_t playPosMs);
static T_DjiReturnCode DjiPlayback_StopPlayProcess(void);
static T_DjiReturnCode
DjiPlayback_VideoFileTranscode(const char *inPath, const char *outFormat, char *outPath, uint16_t outPathBufferSize);
static T_DjiReturnCode
DjiPlayback_GetFrameInfoOfVideoFile(const char *path, T_TestPayloadCameraVideoFrameInfo *frameInfo,
uint32_t frameInfoBufferCount, uint32_t *frameCount);
static T_DjiReturnCode DjiPlayback_GetFrameRateOfVideoFile(const char *path, float *frameRate);
static T_DjiReturnCode
DjiPlayback_GetFrameNumberByTime(T_TestPayloadCameraVideoFrameInfo *frameInfo, uint32_t frameCount,
uint32_t *frameNumber, uint32_t timeMs);
static T_DjiReturnCode GetMediaFileDir(char *dirPath);
static T_DjiReturnCode GetMediaFileOriginData(const char *filePath, uint32_t offset, uint32_t length,
uint8_t *data);
static T_DjiReturnCode CreateMediaFileThumbNail(const char *filePath);
static T_DjiReturnCode GetMediaFileThumbNailInfo(const char *filePath, T_DjiCameraMediaFileInfo *fileInfo);
static T_DjiReturnCode GetMediaFileThumbNailData(const char *filePath, uint32_t offset, uint32_t length,
uint8_t *data);
static T_DjiReturnCode DestroyMediaFileThumbNail(const char *filePath);
static T_DjiReturnCode CreateMediaFileScreenNail(const char *filePath);
static T_DjiReturnCode GetMediaFileScreenNailInfo(const char *filePath, T_DjiCameraMediaFileInfo *fileInfo);
static T_DjiReturnCode GetMediaFileScreenNailData(const char *filePath, uint32_t offset, uint32_t length,
uint8_t *data);
static T_DjiReturnCode DestroyMediaFileScreenNail(const char *filePath);
static T_DjiReturnCode DeleteMediaFile(char *filePath);
static T_DjiReturnCode SetMediaPlaybackFile(const char *filePath);
static T_DjiReturnCode StartMediaPlayback(void);
static T_DjiReturnCode StopMediaPlayback(void);
static T_DjiReturnCode PauseMediaPlayback(void);
static T_DjiReturnCode SeekMediaPlayback(uint32_t playbackPosition);
static T_DjiReturnCode GetMediaPlaybackStatus(T_DjiCameraPlaybackStatus *status);
static T_DjiReturnCode StartDownloadNotification(void);
static T_DjiReturnCode StopDownloadNotification(void);
_Noreturn static void *UserCameraMedia_SendVideoTask(void *arg);
_Noreturn static void *TestCameraMedia_SendVideoTask(void *arg);
/* Private variables -------------------------------------------------------------*/
static T_DjiCameraMediaDownloadPlaybackHandler s_psdkCameraMedia = {0};
static T_DjiPlaybackInfo s_playbackInfo = {0};
static T_DjiTaskHandle s_userSendVideoThread;
static T_UtilBuffer s_mediaPlayCommandBufferHandler = {0};
static T_DjiMutexHandle s_mediaPlayCommandBufferMutex = {0};
static T_DjiSemaHandle s_mediaPlayWorkSem = NULL;
static uint8_t s_mediaPlayCommandBuffer[sizeof(T_TestPayloadCameraPlaybackCommand) * 32] = {0};
static const char *s_frameKeyChar = "[PACKET]";
static const char *s_frameDurationTimeKeyChar = "duration_time";
static const char *s_framePositionKeyChar = "pos";
static const char *s_frameSizeKeyChar = "size";
static T_DjiMediaFileHandle s_mediaFileThumbNailHandle;
static T_DjiMediaFileHandle s_mediaFileScreenNailHandle;
static const uint8_t s_frameAudInfo[VIDEO_FRAME_AUD_LEN] = {0x00, 0x00, 0x00, 0x01, 0x09, 0x10};
static char s_mediaFileDirPath[DJI_FILE_PATH_SIZE_MAX] = {0};
static bool s_isMediaFileDirPathConfigured = false;
/* Exported functions definition ---------------------------------------------*/
// 接口函数定义
// 照相机 菜单 媒体 开始 服务
T_DjiReturnCode DjiTest_CameraEmuMediaStartService(int mode)
{
T_DjiOsalHandler *osalHandler = DjiPlatform_GetOsalHandler();
T_DjiReturnCode returnCode;
const T_DjiDataChannelBandwidthProportionOfHighspeedChannel bandwidthProportionOfHighspeedChannel =
{TRANS_RATIO_DATA, TRANS_RATIO_VIDEO, TRANS_RATIO_DOWNLOAD};
T_DjiAircraftInfoBaseInfo aircraftInfoBaseInfo = {0};
if (DjiAircraftInfo_GetBaseInfo(&aircraftInfoBaseInfo) != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
USER_LOG_ERROR("get aircraft information error.");
return DJI_ERROR_SYSTEM_MODULE_CODE_UNKNOWN;
}
s_psdkCameraMedia.GetMediaFileDir = GetMediaFileDir;
s_psdkCameraMedia.GetMediaFileOriginInfo = DjiTest_CameraMediaGetFileInfo;
s_psdkCameraMedia.GetMediaFileOriginData = GetMediaFileOriginData;
s_psdkCameraMedia.CreateMediaFileThumbNail = CreateMediaFileThumbNail;
s_psdkCameraMedia.GetMediaFileThumbNailInfo = GetMediaFileThumbNailInfo;
s_psdkCameraMedia.GetMediaFileThumbNailData = GetMediaFileThumbNailData;
s_psdkCameraMedia.DestroyMediaFileThumbNail = DestroyMediaFileThumbNail;
s_psdkCameraMedia.CreateMediaFileScreenNail = CreateMediaFileScreenNail;
s_psdkCameraMedia.GetMediaFileScreenNailInfo = GetMediaFileScreenNailInfo;
s_psdkCameraMedia.GetMediaFileScreenNailData = GetMediaFileScreenNailData;
s_psdkCameraMedia.DestroyMediaFileScreenNail = DestroyMediaFileScreenNail;
s_psdkCameraMedia.DeleteMediaFile = DeleteMediaFile;
s_psdkCameraMedia.SetMediaPlaybackFile = SetMediaPlaybackFile;
s_psdkCameraMedia.StartMediaPlayback = StartMediaPlayback;
s_psdkCameraMedia.StopMediaPlayback = StopMediaPlayback;
s_psdkCameraMedia.PauseMediaPlayback = PauseMediaPlayback;
s_psdkCameraMedia.SeekMediaPlayback = SeekMediaPlayback;
s_psdkCameraMedia.GetMediaPlaybackStatus = GetMediaPlaybackStatus;
s_psdkCameraMedia.StartDownloadNotification = StartDownloadNotification;
s_psdkCameraMedia.StopDownloadNotification = StopDownloadNotification;
if (DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS != osalHandler->SemaphoreCreate(0, &s_mediaPlayWorkSem)) {
USER_LOG_ERROR("SemaphoreCreate(\"%s\") error.", "s_mediaPlayWorkSem");
return DJI_ERROR_SYSTEM_MODULE_CODE_UNKNOWN;
}
if (osalHandler->MutexCreate(&s_mediaPlayCommandBufferMutex) != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
USER_LOG_ERROR("mutex create error");
return DJI_ERROR_SYSTEM_MODULE_CODE_UNKNOWN;
}
UtilBuffer_Init(&s_mediaPlayCommandBufferHandler, s_mediaPlayCommandBuffer, sizeof(s_mediaPlayCommandBuffer));
if (aircraftInfoBaseInfo.aircraftType == DJI_AIRCRAFT_TYPE_M300_RTK ||
aircraftInfoBaseInfo.aircraftType == DJI_AIRCRAFT_TYPE_M350_RTK) {
returnCode = DjiPayloadCamera_RegMediaDownloadPlaybackHandler(&s_psdkCameraMedia);
if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
USER_LOG_ERROR("psdk camera media function init error.");
return DJI_ERROR_SYSTEM_MODULE_CODE_UNKNOWN;
}
}
returnCode = DjiHighSpeedDataChannel_SetBandwidthProportion(bandwidthProportionOfHighspeedChannel);
if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
USER_LOG_ERROR("Set data channel bandwidth width proportion error.");
return DJI_ERROR_SYSTEM_MODULE_CODE_UNKNOWN;
}
if (mode == 0)
{
// 大疆平台 获得 套接字 权柄
if (DjiPlatform_GetHalNetworkHandler() != NULL || DjiPlatform_GetHalUsbBulkHandler() != NULL) {
// 创建相机媒体任务,使用者相机媒体任务,
returnCode = osalHandler->TaskCreate("user_camera_media_task", UserCameraMedia_SendVideoTask, 2048,
NULL, &s_userSendVideoThread);
if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
USER_LOG_ERROR("user send video task create error.");
return DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS;
}
}
}
else if (mode == 1)
{
if (DjiPlatform_GetHalNetworkHandler() != NULL || DjiPlatform_GetHalUsbBulkHandler() != NULL) {
// 创建测试图传线程
returnCode = osalHandler->TaskCreate("user_camera_media_task", TestCameraMedia_SendVideoTask, 2048,
NULL, &s_userSendVideoThread);
if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
USER_LOG_ERROR("user send video task create error.");
return DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS;
}
}
}
return DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS;
}
T_DjiReturnCode DjiTest_CameraEmuSetMediaFilePath(const char *path)
{
memset(s_mediaFileDirPath, 0, sizeof(s_mediaFileDirPath));
memcpy(s_mediaFileDirPath, path, USER_UTIL_MIN(strlen(path), sizeof(s_mediaFileDirPath) - 1));
s_isMediaFileDirPathConfigured = true;
return DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS;
}
T_DjiReturnCode DjiTest_CameraMediaGetFileInfo(const char *filePath, T_DjiCameraMediaFileInfo *fileInfo)
{
T_DjiReturnCode returnCode;
T_DjiMediaFileHandle mediaFileHandle;
returnCode = DjiMediaFile_CreateHandle(filePath, &mediaFileHandle);
if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
USER_LOG_ERROR("Media file create handle error stat:0x%08llX", returnCode);
return returnCode;
}
returnCode = DjiMediaFile_GetMediaFileType(mediaFileHandle, &fileInfo->type);
if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
USER_LOG_ERROR("Media file get type error stat:0x%08llX", returnCode);
goto out;
}
returnCode = DjiMediaFile_GetMediaFileAttr(mediaFileHandle, &fileInfo->mediaFileAttr);
if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
USER_LOG_ERROR("Media file get attr error stat:0x%08llX", returnCode);
goto out;
}
returnCode = DjiMediaFile_GetFileSizeOrg(mediaFileHandle, &fileInfo->fileSize);
if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
USER_LOG_ERROR("Media file get size error stat:0x%08llX", returnCode);
goto out;
}
out:
returnCode = DjiMediaFile_DestroyHandle(mediaFileHandle);
if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
USER_LOG_ERROR("Media file destroy handle error stat:0x%08llX", returnCode);
return returnCode;
}
return returnCode;
}
/* Private functions definition-----------------------------------------------*/
static T_DjiReturnCode DjiPlayback_StopPlay(T_DjiPlaybackInfo *playbackInfo)
{
T_DjiReturnCode returnCode;
returnCode = DjiPlayback_StopPlayProcess();
if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
USER_LOG_ERROR("stop play error ");
}
playbackInfo->isInPlayProcess = 0;
playbackInfo->playPosMs = 0;
return returnCode;
}
static T_DjiReturnCode DjiPlayback_PausePlay(T_DjiPlaybackInfo *playbackInfo)
{
T_DjiReturnCode returnCode = DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS;
T_DjiOsalHandler *osalHandler = DjiPlatform_GetOsalHandler();
T_TestPayloadCameraPlaybackCommand playbackCommand = {0};
if (playbackInfo->isInPlayProcess) {
playbackCommand.command = TEST_PAYLOAD_CAMERA_MEDIA_PLAY_COMMAND_PAUSE;
if (osalHandler->MutexLock(s_mediaPlayCommandBufferMutex) != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
USER_LOG_ERROR("mutex lock error");
return DJI_ERROR_SYSTEM_MODULE_CODE_UNKNOWN;
}
if (UtilBuffer_GetUnusedSize(&s_mediaPlayCommandBufferHandler) >= sizeof(T_TestPayloadCameraPlaybackCommand)) {
UtilBuffer_Put(&s_mediaPlayCommandBufferHandler, (const uint8_t *) &playbackCommand,
sizeof(T_TestPayloadCameraPlaybackCommand));
} else {
USER_LOG_ERROR("Media playback command buffer is full.");
returnCode = DJI_ERROR_SYSTEM_MODULE_CODE_OUT_OF_RANGE;
}
if (osalHandler->MutexUnlock(s_mediaPlayCommandBufferMutex) != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
USER_LOG_ERROR("mutex unlock error");
return DJI_ERROR_SYSTEM_MODULE_CODE_UNKNOWN;
}
osalHandler->SemaphorePost(s_mediaPlayWorkSem);
}
playbackInfo->isInPlayProcess = 0;
return returnCode;
}
static T_DjiReturnCode DjiPlayback_SetPlayFile(T_DjiPlaybackInfo *playbackInfo, const char *filePath, uint16_t index)
{
T_DjiReturnCode returnCode;
if (strlen(filePath) > DJI_FILE_PATH_SIZE_MAX) {
USER_LOG_ERROR("Dji playback file path out of length range error\n");
return DJI_ERROR_SYSTEM_MODULE_CODE_INVALID_PARAMETER;
}
strcpy(playbackInfo->filePath, filePath);
playbackInfo->videoIndex = index;
returnCode = DjiPlayback_GetVideoLengthMs(filePath, &playbackInfo->videoLengthMs);
if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
return DJI_ERROR_SYSTEM_MODULE_CODE_UNKNOWN;
}
return DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS;
}
static T_DjiReturnCode DjiPlayback_SeekPlay(T_DjiPlaybackInfo *playbackInfo, uint32_t seekPos)
{
T_DjiRunTimeStamps ti;
T_DjiReturnCode returnCode;
returnCode = DjiPlayback_PausePlay(playbackInfo);
if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
USER_LOG_ERROR("pause play error \n");
return returnCode;
}
playbackInfo->playPosMs = seekPos;
returnCode = DjiPlayback_StartPlayProcess(playbackInfo->filePath, playbackInfo->playPosMs);
if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
USER_LOG_ERROR("start playback process error \n");
return returnCode;
}
playbackInfo->isInPlayProcess = 1;
ti = DjiUtilTime_GetRunTimeStamps();
playbackInfo->startPlayTimestampsUs = ti.realUsec - playbackInfo->playPosMs * 1000;
return DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS;
}
static T_DjiReturnCode DjiPlayback_StartPlay(T_DjiPlaybackInfo *playbackInfo)
{
T_DjiRunTimeStamps ti;
T_DjiReturnCode returnCode;
if (playbackInfo->isInPlayProcess == 1) {
//already in playing, return DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS
return DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS;
}
returnCode = DjiPlayback_StartPlayProcess(playbackInfo->filePath, playbackInfo->playPosMs);
if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
USER_LOG_ERROR("start play process error \n");
return returnCode;
}
playbackInfo->isInPlayProcess = 1;
ti = DjiUtilTime_GetRunTimeStamps();
playbackInfo->startPlayTimestampsUs = ti.realUsec - playbackInfo->playPosMs * 1000;
return DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS;
}
static T_DjiReturnCode DjiPlayback_GetPlaybackStatus(T_DjiPlaybackInfo *playbackInfo,
T_DjiCameraPlaybackStatus *playbackStatus)
{
T_DjiRunTimeStamps timeStamps;
memset(playbackStatus, 0, sizeof(T_DjiCameraPlaybackStatus));
//update playback pos info
if (playbackInfo->isInPlayProcess) {
timeStamps = DjiUtilTime_GetRunTimeStamps();
playbackInfo->playPosMs = (timeStamps.realUsec - playbackInfo->startPlayTimestampsUs) / 1000;
if (playbackInfo->playPosMs >= playbackInfo->videoLengthMs) {
if (DjiPlayback_PausePlay(playbackInfo) != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
return DJI_ERROR_SYSTEM_MODULE_CODE_UNKNOWN;
}
}
}
//set playback status
if (playbackInfo->isInPlayProcess == 0 && playbackInfo->playPosMs != 0) {
playbackStatus->playbackMode = DJI_CAMERA_PLAYBACK_MODE_PAUSE;
} else if (playbackInfo->isInPlayProcess) {
playbackStatus->playbackMode = DJI_CAMERA_PLAYBACK_MODE_PLAY;
} else {
playbackStatus->playbackMode = DJI_CAMERA_PLAYBACK_MODE_STOP;
}
playbackStatus->playPosMs = playbackInfo->playPosMs;
playbackStatus->videoLengthMs = playbackInfo->videoLengthMs;
if (playbackInfo->videoLengthMs != 0) {
playbackStatus->videoPlayProcess =
(playbackInfo->videoLengthMs - playbackInfo->playPosMs) / playbackInfo->videoLengthMs;
} else {
playbackStatus->videoPlayProcess = 0;
}
return DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS;
}
// 获取视频长度
static T_DjiReturnCode DjiPlayback_GetVideoLengthMs(const char *filePath, uint32_t *videoLengthMs)
{
FILE *fp;
T_DjiReturnCode returnCode;
char ffmpegCmdStr[FFMPEG_CMD_BUF_SIZE];
float hour, minute, second;
char tempTailStr[128];
int ret;
snprintf(ffmpegCmdStr, FFMPEG_CMD_BUF_SIZE, "ffmpeg -i \"%s\" 2>&1 | grep \"Duration\"", filePath);
fp = popen(ffmpegCmdStr, "r");
if (fp == NULL) {
return DJI_ERROR_SYSTEM_MODULE_CODE_SYSTEM_ERROR;
}
ret = fscanf(fp, " Duration: %f:%f:%f,%127s", &hour, &minute, &second, tempTailStr);
if (ret <= 0) {
USER_LOG_ERROR("MP4 File Get Duration Error\n");
returnCode = DJI_ERROR_SYSTEM_MODULE_CODE_SYSTEM_ERROR;
goto out;
}
*videoLengthMs = (uint32_t) ((hour * 3600 + minute * 60 + second) * 1000);
returnCode = DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS;
out:
pclose(fp);
return returnCode;
}
// 开始播放进程
static T_DjiReturnCode DjiPlayback_StartPlayProcess(const char *filePath, uint32_t playPosMs)
{
T_DjiReturnCode returnCode = DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS;
T_TestPayloadCameraPlaybackCommand mediaPlayCommand = {0};
T_DjiOsalHandler *osalHandler = DjiPlatform_GetOsalHandler();
mediaPlayCommand.command = TEST_PAYLOAD_CAMERA_MEDIA_PLAY_COMMAND_START;
mediaPlayCommand.timeMs = playPosMs;
if (strlen(filePath) >= sizeof(mediaPlayCommand.path)) {
USER_LOG_ERROR("File path is too long.");
return DJI_ERROR_SYSTEM_MODULE_CODE_OUT_OF_RANGE;
}
memcpy(mediaPlayCommand.path, filePath, strlen(filePath));
if (osalHandler->MutexLock(s_mediaPlayCommandBufferMutex) != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
USER_LOG_ERROR("mutex lock error");
return DJI_ERROR_SYSTEM_MODULE_CODE_UNKNOWN;
}
if (UtilBuffer_GetUnusedSize(&s_mediaPlayCommandBufferHandler) >= sizeof(T_TestPayloadCameraPlaybackCommand)) {
UtilBuffer_Put(&s_mediaPlayCommandBufferHandler, (const uint8_t *) &mediaPlayCommand,
sizeof(T_TestPayloadCameraPlaybackCommand));
} else {
USER_LOG_ERROR("Media playback command buffer is full.");
returnCode = DJI_ERROR_SYSTEM_MODULE_CODE_OUT_OF_RANGE;
}
if (osalHandler->MutexUnlock(s_mediaPlayCommandBufferMutex) != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
USER_LOG_ERROR("mutex unlock error");
return DJI_ERROR_SYSTEM_MODULE_CODE_UNKNOWN;
}
osalHandler->SemaphorePost(s_mediaPlayWorkSem);
return returnCode;
}
static T_DjiReturnCode DjiPlayback_StopPlayProcess(void)
{
T_DjiReturnCode returnCode = DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS;
T_TestPayloadCameraPlaybackCommand playbackCommand = {0};
T_DjiOsalHandler *osalHandler = DjiPlatform_GetOsalHandler();
playbackCommand.command = TEST_PAYLOAD_CAMERA_MEDIA_PLAY_COMMAND_STOP;
if (osalHandler->MutexLock(s_mediaPlayCommandBufferMutex) != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
USER_LOG_ERROR("mutex lock error");
return DJI_ERROR_SYSTEM_MODULE_CODE_UNKNOWN;
}
if (UtilBuffer_GetUnusedSize(&s_mediaPlayCommandBufferHandler) >= sizeof(T_TestPayloadCameraPlaybackCommand)) {
UtilBuffer_Put(&s_mediaPlayCommandBufferHandler, (const uint8_t *) &playbackCommand,
sizeof(T_TestPayloadCameraPlaybackCommand));
} else {
USER_LOG_ERROR("Media playback command buffer is full.");
returnCode = DJI_ERROR_SYSTEM_MODULE_CODE_OUT_OF_RANGE;
}
if (osalHandler->MutexUnlock(s_mediaPlayCommandBufferMutex) != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
USER_LOG_ERROR("mutex unlock error");
return DJI_ERROR_SYSTEM_MODULE_CODE_UNKNOWN;
}
osalHandler->SemaphorePost(s_mediaPlayWorkSem);
return returnCode;
}
static T_DjiReturnCode DjiPlayback_VideoFileTranscode(const char *inPath, const char *outFormat, char *outPath,
uint16_t outPathBufferSize)
{
T_DjiReturnCode returnCode = DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS;
T_DjiReturnCode djiStatus = DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS;
FILE *fpCommand = NULL;
char ffmpegCmdStr[FFMPEG_CMD_BUF_SIZE];
char *directory = NULL;
T_DjiOsalHandler *osalHandler = DjiPlatform_GetOsalHandler();
directory = osalHandler->Malloc(DJI_FILE_PATH_SIZE_MAX);
if (directory == NULL) {
USER_LOG_ERROR("malloc memory for directory fail.");
return DJI_ERROR_SYSTEM_MODULE_CODE_MEMORY_ALLOC_FAILED;
}
// USER_LOG_INFO("inPath%s",inPath);
djiStatus = DjiUserUtil_GetCurrentFileDirPath(inPath, DJI_FILE_PATH_SIZE_MAX, directory);
if (djiStatus != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
USER_LOG_ERROR("get directory of file error: 0x%08llX.", djiStatus);
returnCode = djiStatus;
goto out;
}
// USER_LOG_INFO("inPath%s",inPath);
snprintf(outPath, outPathBufferSize, "%sout.%s", directory, outFormat);
// 结果为 /root/sdcard/media_file/out.h264
USER_LOG_INFO("%sout.%s ", directory, outFormat);
snprintf(ffmpegCmdStr, FFMPEG_CMD_BUF_SIZE,
"echo \"y\" | ffmpeg -i \"%s\" -codec copy -f \"%s\" \"%s\" 1>/dev/null 2>&1", inPath,
outFormat, outPath);
// 结果为 echo "y" | ffmpeg -i "/root/sdcard/media_file/PSDK_0005.h264" -codec copy -f "h264" "/root/sdcard/media_file/out.h264" 1>/dev/null 2>&1
USER_LOG_INFO("ffmpegCmdStr:%s",ffmpegCmdStr);
fpCommand = popen(ffmpegCmdStr, "r");
if (fpCommand == NULL) {
USER_LOG_ERROR("execute transcode command fail.");
returnCode = DJI_ERROR_SYSTEM_MODULE_CODE_UNKNOWN;
goto out;
}
pclose(fpCommand);
out:
osalHandler->Free(directory);
return returnCode;
}
// 获得视频的帧信息
static T_DjiReturnCode
DjiPlayback_GetFrameInfoOfVideoFile(const char *path, T_TestPayloadCameraVideoFrameInfo *frameInfo,
uint32_t frameInfoBufferCount, uint32_t *frameCount)
{
long ret;
T_DjiReturnCode returnCode = DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS;
FILE *fpCommand = NULL;
char ffmpegCmdStr[FFMPEG_CMD_BUF_SIZE];
char *frameInfoString = NULL;
char *frameLocation = NULL;
char frameParameterFormat[50] = {0};
char *frameDurationTimeLocation = NULL;
float frameDurationTimeS = 0;
uint32_t frameNumber = 0;
char *framePositionLocation = NULL;
uint32_t framePosition = 0;
char *frameSizeLocation = NULL;
uint32_t frameSize = 0;
T_DjiOsalHandler *osalHandler = DjiPlatform_GetOsalHandler();
frameInfoString = osalHandler->Malloc(VIDEO_FRAME_MAX_COUNT * 1024);
if (frameInfoString == NULL) {
USER_LOG_ERROR("malloc memory for frame info fail.");
return DJI_ERROR_SYSTEM_MODULE_CODE_MEMORY_ALLOC_FAILED;
}
memset(frameInfoString, 0, VIDEO_FRAME_MAX_COUNT * 1024);
snprintf(ffmpegCmdStr, FFMPEG_CMD_BUF_SIZE, "ffprobe -show_packets \"%s\" 2>/dev/null", path);
fpCommand = popen(ffmpegCmdStr, "r");
if (fpCommand == NULL) {
USER_LOG_ERROR("execute show frames commands fail.");
returnCode = DJI_ERROR_SYSTEM_MODULE_CODE_UNKNOWN;
goto out2;
}
ret = (long) fread(frameInfoString, 1, VIDEO_FRAME_MAX_COUNT * 1024, fpCommand);
if (ret < 0) {
USER_LOG_ERROR("read show frames commands result error.");
goto out1;
}
frameInfoString[ret] = '\0';
frameLocation = frameInfoString;
*frameCount = 0;
while (1) {
// find frame
frameLocation = strstr(frameLocation, s_frameKeyChar);
if (frameLocation == NULL) {
USER_LOG_DEBUG("reach file tail.");
break;
}
// find frame duration
frameDurationTimeLocation = strstr(frameLocation, s_frameDurationTimeKeyChar);
if (frameDurationTimeLocation == NULL) {
USER_LOG_ERROR("can not find pkt_duration_time.");
returnCode = DJI_ERROR_SYSTEM_MODULE_CODE_NOT_FOUND;
goto out1;
}
ret = snprintf(frameParameterFormat, sizeof(frameParameterFormat), "%s=%%f", s_frameDurationTimeKeyChar);
if (ret < 0) {
USER_LOG_ERROR("snprintf frameParameterFormat fail.");
returnCode = DJI_ERROR_SYSTEM_MODULE_CODE_UNKNOWN;
goto out1;
}
ret = sscanf(frameDurationTimeLocation, frameParameterFormat, &frameDurationTimeS);
if (ret <= 0) {
USER_LOG_ERROR("can not find pkt_duration_time.");
returnCode = DJI_ERROR_SYSTEM_MODULE_CODE_NOT_FOUND;
goto out1;
}
frameInfo[frameNumber].durationS = frameDurationTimeS;
// find frame position
framePositionLocation = strstr(frameLocation, s_framePositionKeyChar);
if (framePositionLocation == NULL) {
USER_LOG_ERROR("can not found pkt_pos.");
returnCode = DJI_ERROR_SYSTEM_MODULE_CODE_NOT_FOUND;
goto out1;
}
ret = snprintf(frameParameterFormat, sizeof(frameParameterFormat), "%s=%%d", s_framePositionKeyChar);
if (ret < 0) {
USER_LOG_ERROR("snprintf frameParameterFormat fail.");
returnCode = DJI_ERROR_SYSTEM_MODULE_CODE_UNKNOWN;
goto out1;
}
ret = sscanf(framePositionLocation, frameParameterFormat, &framePosition);
if (ret <= 0) {
USER_LOG_ERROR("can not found pkt_pos.");
returnCode = DJI_ERROR_SYSTEM_MODULE_CODE_NOT_FOUND;
goto out1;
}
frameInfo[frameNumber].positionInFile = framePosition;
// find frame size
//frameSizeLocation 由 frameLocation s_frameSizeKeyChar 拼接而成
frameSizeLocation = strstr(frameLocation, s_frameSizeKeyChar);
if (frameSizeLocation == NULL) {
USER_LOG_ERROR("can not found pkt_size.");
returnCode = DJI_ERROR_SYSTEM_MODULE_CODE_NOT_FOUND;
goto out1;
}
ret = snprintf(frameParameterFormat, sizeof(frameParameterFormat), "%s=%%d", s_frameSizeKeyChar);
if (ret < 0) {
USER_LOG_ERROR("snprintf frameParameterFormat fail.");
returnCode = DJI_ERROR_SYSTEM_MODULE_CODE_UNKNOWN;
goto out1;
}
// 从frameSizeLocation 读取数据流 到 frameSize
ret = sscanf(frameSizeLocation, frameParameterFormat, &frameSize);
if (ret <= 0) {
USER_LOG_ERROR("can not find pkt_size.");
returnCode = DJI_ERROR_SYSTEM_MODULE_CODE_NOT_FOUND;
goto out1;
}
frameInfo[frameNumber].size = frameSize;
frameLocation += strlen(s_frameKeyChar);
frameNumber++;
(*frameCount)++;
if (frameNumber >= frameInfoBufferCount) {
USER_LOG_ERROR("frame buffer is full.");
returnCode = DJI_ERROR_SYSTEM_MODULE_CODE_OUT_OF_RANGE;
goto out1;
}
}
out1:
pclose(fpCommand);
out2:
osalHandler->Free(frameInfoString);
return returnCode;
}
//获取视频的帧速率
static T_DjiReturnCode DjiPlayback_GetFrameRateOfVideoFile(const char *path, float *frameRate)
{
int ret;
T_DjiReturnCode returnCode = DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS;
FILE *fpCommand = NULL;
char ffmpegCmdStr[FFMPEG_CMD_BUF_SIZE] = {0};
int frameRateMolecule = 0;
int frameRateDenominator = 0;
//改动 手动获取
//path = "/root/sdcard/media_file/PSDK_0005.h264";
//查看文件流信息指令 ffprobe -show_frames filename
//ffprobe -show_streams "/root/sdcard/media_file/PSDK_0005.h264" 2>/dev/null | grep r_frame_rate
snprintf(ffmpegCmdStr, FFMPEG_CMD_BUF_SIZE, "ffprobe -show_streams \"%s\" 2>/dev/null | grep r_frame_rate", path);
fpCommand = popen(ffmpegCmdStr, "r");
if (fpCommand == NULL) {
USER_LOG_ERROR("execute show frame rate command fail.");
return DJI_ERROR_SYSTEM_MODULE_CODE_UNKNOWN;
}
USER_LOG_INFO("ffmpegCmdStr:%s", ffmpegCmdStr);
//此处报错
// 从fpcommand中读取数据 %d %d 放入到frameRateMolecule frameRateDenominator
// 失败返还-1f
ret = fscanf(fpCommand, "r_frame_rate=%d/%d", &frameRateMolecule, &frameRateDenominator);
if (ret <= 0) {
USER_LOG_ERROR("can not find frame rate.");
returnCode = DJI_ERROR_SYSTEM_MODULE_CODE_NOT_FOUND;
goto out;
}
*frameRate = (float) frameRateMolecule / (float) frameRateDenominator;
out:
pclose(fpCommand);
return returnCode;
}
//获取视频帧数
static T_DjiReturnCode DjiPlayback_GetFrameNumberByTime(T_TestPayloadCameraVideoFrameInfo *frameInfo,
uint32_t frameCount, uint32_t *frameNumber, uint32_t timeMs)
{
uint32_t i = 0;
double camulativeTimeS = 0;
double timeS = (double) timeMs / 1000.0;
for (i = 0; i < frameCount; ++i) {
camulativeTimeS += frameInfo[i].durationS;
if (camulativeTimeS >= timeS) {
*frameNumber = i;
return DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS;
}
}
return DJI_ERROR_SYSTEM_MODULE_CODE_NOT_FOUND;
}
static T_DjiReturnCode GetMediaFileDir(char *dirPath)
{
T_DjiReturnCode returnCode;
char curFileDirPath[DJI_FILE_PATH_SIZE_MAX];
char tempPath[DJI_FILE_PATH_SIZE_MAX];
USER_LOG_INFO("自动获取相册地址");
// returnCode = DjiUserUtil_GetCurrentFileDirPath("/root/sdcard/DCIM", DJI_FILE_PATH_SIZE_MAX, curFileDirPath);
// if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
// USER_LOG_ERROR("Get file current path error, stat = 0x%08llX", returnCode);
// return returnCode;
// }
snprintf(curFileDirPath,DJI_FILE_PATH_SIZE_MAX,"/root/sdcard/DCIM");
snprintf(dirPath, DJI_FILE_PATH_SIZE_MAX, "%s", curFileDirPath);
return DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS;
}
static T_DjiReturnCode GetMediaFileOriginData(const char *filePath, uint32_t offset, uint32_t length, uint8_t *data)
{
T_DjiReturnCode returnCode;
uint32_t realLen = 0;
T_DjiMediaFileHandle mediaFileHandle;
returnCode = DjiMediaFile_CreateHandle(filePath, &mediaFileHandle);
if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
USER_LOG_ERROR("Media file create handle error stat:0x%08llX", returnCode);
return returnCode;
}
returnCode = DjiMediaFile_GetDataOrg(mediaFileHandle, offset, length, data, &realLen);
if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
USER_LOG_ERROR("Media file get data error stat:0x%08llX", returnCode);
return returnCode;
}
returnCode = DjiMediaFile_DestroyHandle(mediaFileHandle);
if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
USER_LOG_ERROR("Media file destroy handle error stat:0x%08llX", returnCode);
return returnCode;
}
return DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS;
}
static T_DjiReturnCode CreateMediaFileThumbNail(const char *filePath)
{
T_DjiReturnCode returnCode;
returnCode = DjiMediaFile_CreateHandle(filePath, &s_mediaFileThumbNailHandle);
if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
USER_LOG_ERROR("Media file create handle error stat:0x%08llX", returnCode);
return returnCode;
}
returnCode = DjiMediaFile_CreateThm(s_mediaFileThumbNailHandle);
if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
USER_LOG_ERROR("Media file create thumb nail error stat:0x%08llX", returnCode);
return returnCode;
}
return DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS;
}
static T_DjiReturnCode GetMediaFileThumbNailInfo(const char *filePath, T_DjiCameraMediaFileInfo *fileInfo)
{
T_DjiReturnCode returnCode;
USER_UTIL_UNUSED(filePath);
if (s_mediaFileThumbNailHandle == NULL) {
USER_LOG_ERROR("Media file thumb nail handle null error");
return DJI_ERROR_SYSTEM_MODULE_CODE_INVALID_PARAMETER;
}
returnCode = DjiMediaFile_GetMediaFileType(s_mediaFileThumbNailHandle, &fileInfo->type);
if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
USER_LOG_ERROR("Media file get type error stat:0x%08llX", returnCode);
return returnCode;
}
returnCode = DjiMediaFile_GetMediaFileAttr(s_mediaFileThumbNailHandle, &fileInfo->mediaFileAttr);
if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
USER_LOG_ERROR("Media file get attr error stat:0x%08llX", returnCode);
return returnCode;
}
returnCode = DjiMediaFile_GetFileSizeThm(s_mediaFileThumbNailHandle, &fileInfo->fileSize);
if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
USER_LOG_ERROR("Media file get size error stat:0x%08llX", returnCode);
return returnCode;
}
return DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS;
}
static T_DjiReturnCode GetMediaFileThumbNailData(const char *filePath, uint32_t offset, uint32_t length, uint8_t *data)
{
T_DjiReturnCode returnCode;
uint16_t realLen = 0;
USER_UTIL_UNUSED(filePath);
if (s_mediaFileThumbNailHandle == NULL) {
USER_LOG_ERROR("Media file thumb nail handle null error");
return DJI_ERROR_SYSTEM_MODULE_CODE_INVALID_PARAMETER;
}
returnCode = DjiMediaFile_GetDataThm(s_mediaFileThumbNailHandle, offset, length, data, &realLen);
if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
USER_LOG_ERROR("Media file get data error stat:0x%08llX", returnCode);
return returnCode;
}
return DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS;
}
static T_DjiReturnCode DestroyMediaFileThumbNail(const char *filePath)
{
T_DjiReturnCode returnCode;
USER_UTIL_UNUSED(filePath);
if (s_mediaFileThumbNailHandle == NULL) {
USER_LOG_ERROR("Media file thumb nail handle null error");
return DJI_ERROR_SYSTEM_MODULE_CODE_INVALID_PARAMETER;
}
returnCode = DjiMediaFile_DestoryThm(s_mediaFileThumbNailHandle);
if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
USER_LOG_ERROR("Media file destroy thumb nail error stat:0x%08llX", returnCode);
return returnCode;
}
returnCode = DjiMediaFile_DestroyHandle(s_mediaFileThumbNailHandle);
if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
USER_LOG_ERROR("Media file destroy handle error stat:0x%08llX", returnCode);
return returnCode;
}
return DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS;
}
static T_DjiReturnCode CreateMediaFileScreenNail(const char *filePath)
{
T_DjiReturnCode returnCode;
returnCode = DjiMediaFile_CreateHandle(filePath, &s_mediaFileScreenNailHandle);
if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
USER_LOG_ERROR("Media file create handle error stat:0x%08llX", returnCode);
return returnCode;
}
returnCode = DjiMediaFile_CreateScr(s_mediaFileScreenNailHandle);
if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
USER_LOG_ERROR("Media file create screen nail error stat:0x%08llX", returnCode);
return returnCode;
}
return DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS;
}
static T_DjiReturnCode GetMediaFileScreenNailInfo(const char *filePath, T_DjiCameraMediaFileInfo *fileInfo)
{
T_DjiReturnCode returnCode;
USER_UTIL_UNUSED(filePath);
if (s_mediaFileScreenNailHandle == NULL) {
USER_LOG_ERROR("Media file screen nail handle null error");
return DJI_ERROR_SYSTEM_MODULE_CODE_INVALID_PARAMETER;
}
returnCode = DjiMediaFile_GetMediaFileType(s_mediaFileScreenNailHandle, &fileInfo->type);
if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
USER_LOG_ERROR("Media file get type error stat:0x%08llX", returnCode);
return returnCode;
}
returnCode = DjiMediaFile_GetMediaFileAttr(s_mediaFileScreenNailHandle, &fileInfo->mediaFileAttr);
if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
USER_LOG_ERROR("Media file get attr error stat:0x%08llX", returnCode);
return returnCode;
}
returnCode = DjiMediaFile_GetFileSizeScr(s_mediaFileScreenNailHandle, &fileInfo->fileSize);
if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
USER_LOG_ERROR("Media file get size error stat:0x%08llX", returnCode);
return returnCode;
}
return DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS;
}
static T_DjiReturnCode GetMediaFileScreenNailData(const char *filePath, uint32_t offset, uint32_t length,
uint8_t *data)
{
T_DjiReturnCode returnCode;
uint16_t realLen = 0;
USER_UTIL_UNUSED(filePath);
if (s_mediaFileScreenNailHandle == NULL) {
USER_LOG_ERROR("Media file screen nail handle null error");
return DJI_ERROR_SYSTEM_MODULE_CODE_INVALID_PARAMETER;
}
returnCode = DjiMediaFile_GetDataScr(s_mediaFileScreenNailHandle, offset, length, data, &realLen);
if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
USER_LOG_ERROR("Media file get size error stat:0x%08llX", returnCode);
return returnCode;
}
return DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS;
}
static T_DjiReturnCode DestroyMediaFileScreenNail(const char *filePath)
{
T_DjiReturnCode returnCode;
USER_UTIL_UNUSED(filePath);
if (s_mediaFileScreenNailHandle == NULL) {
USER_LOG_ERROR("Media file screen nail handle null error");
return DJI_ERROR_SYSTEM_MODULE_CODE_INVALID_PARAMETER;
}
returnCode = DjiMediaFile_DestroyScr(s_mediaFileScreenNailHandle);
if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
USER_LOG_ERROR("Media file destroy screen nail error stat:0x%08llX", returnCode);
return returnCode;
}
returnCode = DjiMediaFile_DestroyHandle(s_mediaFileScreenNailHandle);
if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
USER_LOG_ERROR("Media file destroy handle error stat:0x%08llX", returnCode);
return returnCode;
}
return DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS;
}
static T_DjiReturnCode DeleteMediaFile(char *filePath)
{
T_DjiReturnCode returnCode;
USER_LOG_INFO("delete media file:%s", filePath);
returnCode = DjiFile_Delete(filePath);
if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
USER_LOG_ERROR("Media file delete error stat:0x%08llX", returnCode);
return returnCode;
}
return DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS;
}
static T_DjiReturnCode SetMediaPlaybackFile(const char *filePath)
{
USER_LOG_INFO("set media playback file:%s", filePath);
T_DjiReturnCode returnCode;
returnCode = DjiPlayback_StopPlay(&s_playbackInfo);
if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
return returnCode;
}
returnCode = DjiPlayback_SetPlayFile(&s_playbackInfo, filePath, 0);
if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
return returnCode;
}
returnCode = DjiPlayback_StartPlay(&s_playbackInfo);
if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
return returnCode;
}
return DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS;
}
static T_DjiReturnCode StartMediaPlayback(void)
{
T_DjiReturnCode returnCode;
USER_LOG_INFO("start media playback");
returnCode = DjiPlayback_StartPlay(&s_playbackInfo);
if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
USER_LOG_ERROR("start media playback status error, stat:0x%08llX", returnCode);
return returnCode;
}
return returnCode;
}
static T_DjiReturnCode StopMediaPlayback(void)
{
T_DjiReturnCode returnCode;
USER_LOG_INFO("stop media playback");
returnCode = DjiPlayback_StopPlay(&s_playbackInfo);
if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
USER_LOG_ERROR("stop media playback error, stat:0x%08llX", returnCode);
return returnCode;
}
return returnCode;
}
static T_DjiReturnCode PauseMediaPlayback(void)
{
T_DjiReturnCode returnCode;
USER_LOG_INFO("pause media playback");
returnCode = DjiPlayback_PausePlay(&s_playbackInfo);
if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
USER_LOG_ERROR("pause media playback error, stat:0x%08llX", returnCode);
return returnCode;
}
return returnCode;
}
static T_DjiReturnCode SeekMediaPlayback(uint32_t playbackPosition)
{
T_DjiReturnCode returnCode;
USER_LOG_INFO("seek media playback:%d", playbackPosition);
returnCode = DjiPlayback_SeekPlay(&s_playbackInfo, playbackPosition);
if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
USER_LOG_ERROR("seek media playback error, stat:0x%08llX", returnCode);
return returnCode;
}
return returnCode;
}
static T_DjiReturnCode GetMediaPlaybackStatus(T_DjiCameraPlaybackStatus *status)
{
T_DjiReturnCode returnCode;
returnCode = DjiPlayback_GetPlaybackStatus(&s_playbackInfo, status);
if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
USER_LOG_ERROR("get playback status error, stat:0x%08llX", returnCode);
return returnCode;
}
status->videoPlayProcess = (uint8_t) (((float) s_playbackInfo.playPosMs / (float) s_playbackInfo.videoLengthMs) *
100);
USER_LOG_DEBUG("get media playback status %d %d %d %d", status->videoPlayProcess, status->playPosMs,
status->videoLengthMs, status->playbackMode);
return DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS;
}
static T_DjiReturnCode StartDownloadNotification(void)
{
T_DjiReturnCode returnCode;
T_DjiDataChannelBandwidthProportionOfHighspeedChannel bandwidthProportion = {0};
USER_LOG_DEBUG("media download start notification.");
bandwidthProportion.dataStream = 0;
bandwidthProportion.videoStream = 0;
bandwidthProportion.downloadStream = 100;
returnCode = DjiHighSpeedDataChannel_SetBandwidthProportion(bandwidthProportion);
if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
USER_LOG_ERROR("Set bandwidth proportion for high speed channel error, stat:0x%08llX.", returnCode);
return returnCode;
}
return DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS;
}
static T_DjiReturnCode StopDownloadNotification(void)
{
T_DjiReturnCode returnCode;
T_DjiDataChannelBandwidthProportionOfHighspeedChannel bandwidthProportion = {0};
USER_LOG_DEBUG("media download stop notification.");
bandwidthProportion.dataStream = TRANS_RATIO_DATA;
bandwidthProportion.videoStream = TRANS_RATIO_VIDEO;
bandwidthProportion.downloadStream = TRANS_RATIO_DOWNLOAD;
returnCode = DjiHighSpeedDataChannel_SetBandwidthProportion(bandwidthProportion);
if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
USER_LOG_ERROR("Set bandwidth proportion for high speed channel error, stat:0x%08llX.", returnCode);
return returnCode;
}
return DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS;
}
#ifndef __CC_ARM
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wmissing-noreturn"
#pragma GCC diagnostic ignored "-Wreturn-type"
#endif
// 任务
static void *UserCameraMedia_SendVideoTask(void *arg)
{
int ret;
// 回调错误
T_DjiReturnCode returnCode;
//发送视频的阶数
static uint32_t sendVideoStep = 0;
// 传输的视频文件
FILE *fpFile = NULL;
//传输数据长度 一帧不能超过65kb 超过需要分割
unsigned long dataLength = 0;
// 将要发送的产度
uint16_t lengthOfDataToBeSent = 0;
// 上次已发送的长度
int lengthOfDataHaveBeenSent = 0;
// 视频数据队列
char *dataBuffer = NULL;
// 回放指令
T_TestPayloadCameraPlaybackCommand playbackCommand = {0};
//
uint16_t bufferReadSize = 0;
// 视频文件的地址
char *videoFilePath = NULL;
// 转码文件的地址
char *transcodedFilePath = NULL;
float frameRate = 1.0f;
uint32_t waitDuration = 1000 / SEND_VIDEO_TASK_FREQ;
uint32_t rightNow = 0;
uint32_t sendExpect = 0;
// 帧信息
T_TestPayloadCameraVideoFrameInfo *frameInfo = NULL;
// 帧数
uint32_t frameNumber = 0;
// 总帧
uint32_t frameCount = 0;
// 开始时间的 延迟
uint32_t startTimeMs = 0;
// 发送文件的标识
bool sendVideoFlag = true;
// 发送 一次 的 时间 标示
bool sendOneTimeFlag = false;
// 视频流状态
T_DjiDataChannelState videoStreamState = {0};
// 拍照模式
E_DjiCameraMode mode = DJI_CAMERA_MODE_SHOOT_PHOTO;
// ousl硬件层 句柄
T_DjiOsalHandler *osalHandler = DjiPlatform_GetOsalHandler();
uint32_t frameBufSize = 0;
// 视频流类型
E_DjiCameraVideoStreamType videoStreamType;
// 通用 文件路径
char curFileDirPath[DJI_FILE_PATH_SIZE_MAX];
// 临时路径
char tempPath[DJI_FILE_PATH_SIZE_MAX];
USER_UTIL_UNUSED(arg);
// 获取视频流文件信息
// 获取 通用地址 的错误
returnCode = DjiUserUtil_GetCurrentFileDirPath("/root/sdcard/DCIM", DJI_FILE_PATH_SIZE_MAX, curFileDirPath);
if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
USER_LOG_ERROR("Get file current path error, stat = 0x%08llX", returnCode);
pthread_exit(NULL);
}
USER_LOG_INFO("curFileDirPath:%s",curFileDirPath);
if (s_isMediaFileDirPathConfigured == true) {
snprintf(tempPath, DJI_FILE_PATH_SIZE_MAX, "%sPSDK_0005.h264", s_mediaFileDirPath);
} else {
snprintf(tempPath, DJI_FILE_PATH_SIZE_MAX, "%smedia_file/PSDK_0005.h264", curFileDirPath);
}
// 写入用于推送文件的临时地址
// USER_LOG_INFO("tempPath:%s",tempPath);
// 视频流处理线程初始化
// 为视频文件申请
videoFilePath = osalHandler->Malloc(DJI_FILE_PATH_SIZE_MAX);
if (videoFilePath == NULL) {
USER_LOG_ERROR("malloc memory for video file path fail.");
pthread_exit(NULL);
}
// 转码文件的地址
transcodedFilePath = osalHandler->Malloc(DJI_FILE_PATH_SIZE_MAX);
if (transcodedFilePath == NULL) {
USER_LOG_ERROR("malloc memory for transcoded file path fail.");
pthread_exit(NULL);
}
// 帧信息
frameInfo = osalHandler->Malloc(VIDEO_FRAME_MAX_COUNT * sizeof(T_TestPayloadCameraVideoFrameInfo));
if (frameInfo == NULL) {
USER_LOG_ERROR("malloc memory for frame info fail.");
pthread_exit(NULL);
}
memset(frameInfo, 0, VIDEO_FRAME_MAX_COUNT * sizeof(T_TestPayloadCameraVideoFrameInfo));
//停止 回放播放程序
returnCode = DjiPlayback_StopPlayProcess();
if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
USER_LOG_ERROR("stop playback and start liveview error: 0x%08llX.", returnCode);
pthread_exit(NULL);
}
(void)osalHandler->GetTimeMs(&rightNow);
sendExpect = rightNow + waitDuration;
while (1) {
// (void)osalHandler->GetTimeMs(&rightNow);
// if (sendExpect > rightNow) {
// waitDuration = sendExpect - rightNow;
// } else {
// waitDuration = 1000 / SEND_VIDEO_TASK_FREQ;
// }
// (void)osalHandler->SemaphoreTimedWait(s_mediaPlayWorkSem, waitDuration);
osalHandler->TaskSleepMs(40);
// response playback command
// 响应播放命令
if (osalHandler->MutexLock(s_mediaPlayCommandBufferMutex) != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
USER_LOG_ERROR("mutex lock error");
continue;
}
bufferReadSize = UtilBuffer_Get(&s_mediaPlayCommandBufferHandler, (uint8_t *) &playbackCommand,
sizeof(T_TestPayloadCameraPlaybackCommand));
if (osalHandler->MutexUnlock(s_mediaPlayCommandBufferMutex) != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
USER_LOG_ERROR("mutex unlock error"); //互斥锁 解锁 失败
continue;
}
//&& playbackCommand.command != TEST_PAYLOAD_CAMERA_MEDIA_PLAY_COMMAND_STOP
// if (bufferReadSize != sizeof(T_TestPayloadCameraPlaybackCommand) && playbackCommand.command != TEST_PAYLOAD_CAMERA_MEDIA_PLAY_COMMAND_STOP)
// {
// goto send;
// }
returnCode = DjiTest_CameraGetVideoStreamType(&videoStreamType);
if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
continue;
}
//printf("视频流类型videoStreamType%d\n",videoStreamType);
// 根据 输入的指令 选择功能
switch (playbackCommand.command) {
case TEST_PAYLOAD_CAMERA_MEDIA_PLAY_COMMAND_STOP:
//snprintf(videoFilePath, DJI_FILE_PATH_SIZE_MAX, "%s", tempPath);
startTimeMs = 0;
//sendVideoFlag = true;
//sendOneTimeFlag = false;
//录像回放函数
DJI_VideoReplay_input(playbackCommand.command, 0, NULL);
goto Push_end;
break;
// 暂停视频播放
case TEST_PAYLOAD_CAMERA_MEDIA_PLAY_COMMAND_PAUSE:
//sendVideoFlag = false;
//goto send;
//录像回放函数
DJI_VideoReplay_input(playbackCommand.command, 0, NULL);
goto Push_end;
break;
// 开始视频播放
case TEST_PAYLOAD_CAMERA_MEDIA_PLAY_COMMAND_START:
//snprintf(videoFilePath, DJI_FILE_PATH_SIZE_MAX, "%s", playbackCommand.path);
startTimeMs = playbackCommand.timeMs;
// sendVideoFlag = true;
// sendOneTimeFlag = true;
//录像回放函数
DJI_VideoReplay_input(playbackCommand.command, playbackCommand.timeMs, playbackCommand.path);
goto Push_end;
break;
// 其余输入 负载的指令无效
default:
USER_LOG_ERROR("playback command invalid: %d.", playbackCommand.command);
sendVideoFlag = false;
goto send;
}
// video send preprocess 视频发送预处理
//转码函数
returnCode = DjiPlayback_VideoFileTranscode(videoFilePath, "h264", transcodedFilePath,
DJI_FILE_PATH_SIZE_MAX);
if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
USER_LOG_ERROR("transcode video file error: 0x%08llX.", returnCode);
continue;
}
// 获取视频文件中的帧速率
returnCode = DjiPlayback_GetFrameRateOfVideoFile(transcodedFilePath, &frameRate);
if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
USER_LOG_ERROR("get frame rate of video error: 0x%08llX.", returnCode);
continue;
}
// 获取视频文件中的 帧信息
returnCode = DjiPlayback_GetFrameInfoOfVideoFile(transcodedFilePath, frameInfo, VIDEO_FRAME_MAX_COUNT,
&frameCount);
if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
USER_LOG_ERROR("get frame info of video error: 0x%08llX.", returnCode);
continue;
}
// 根据时间获取 帧数
returnCode = DjiPlayback_GetFrameNumberByTime(frameInfo, frameCount, &frameNumber,
startTimeMs);
if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
USER_LOG_ERROR("get start frame number error: 0x%08llX.", returnCode);
continue;
}
if (fpFile != NULL)
fclose(fpFile);
// fpfile 为转码文件
fpFile = fopen(transcodedFilePath, "rb+");
if (fpFile == NULL) {
USER_LOG_ERROR("open video file fail.");
continue;
}
send:
if (fpFile == NULL) {
USER_LOG_ERROR("open video file fail.");
continue;
}
if (sendVideoFlag != true)
continue;
returnCode = DjiTest_CameraGetMode(&mode);
if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
continue;
}
returnCode = DjiTest_CameraGetVideoStreamType(&videoStreamType);
if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
continue;
}
if (mode == DJI_CAMERA_MODE_PLAYBACK && s_playbackInfo.isInPlayProcess == false) {
continue;
}
if (!USER_UTIL_IS_WORK_TURN(sendVideoStep++, frameRate, SEND_VIDEO_TASK_FREQ))
continue;
frameBufSize = frameInfo[frameNumber].size;
if (videoStreamType == DJI_CAMERA_VIDEO_STREAM_TYPE_H264_DJI_FORMAT) {
frameBufSize = frameBufSize + VIDEO_FRAME_AUD_LEN;
}
// 视频流解析
// 视频内容的长度 分配 帧的内容长度数量 个 1字节
dataBuffer = calloc(frameBufSize, 1);
if (dataBuffer == NULL) {
USER_LOG_ERROR("malloc fail.");
goto free;
}
ret = fseek(fpFile, frameInfo[frameNumber].positionInFile, SEEK_SET);
if (ret != 0) {
USER_LOG_ERROR("fseek fail.");
goto free;
}
// 读取内容长度
dataLength = fread(dataBuffer, 1, frameInfo[frameNumber].size, fpFile);
if (dataLength != frameInfo[frameNumber].size) {
USER_LOG_ERROR("read data from video file error.");
} else {
USER_LOG_DEBUG("read data from video file success, len = %d B\r\n", dataLength);
}
// 如果 视频流类型 为 大疆H264 类型
if (videoStreamType == DJI_CAMERA_VIDEO_STREAM_TYPE_H264_DJI_FORMAT) {
// 将 审核的帧信息 复制到 数据内容 的 帧信息【帧数】大小 长度为 视频帧审核长度
//USER_LOG_INFO("播放类型为大疆h264型");
memcpy(&dataBuffer[frameInfo[frameNumber].size], s_frameAudInfo, VIDEO_FRAME_AUD_LEN);
dataLength = dataLength + VIDEO_FRAME_AUD_LEN;
}
lengthOfDataHaveBeenSent = 0;
while (dataLength - lengthOfDataHaveBeenSent) {
lengthOfDataToBeSent = USER_UTIL_MIN(DATA_SEND_FROM_VIDEO_STREAM_MAX_LEN,
dataLength - lengthOfDataHaveBeenSent);
// 推送(发送) 视频流 (databuffer序列 (存储的一帧图片数据+ 已经发送的数据长度 , 将要发送的数据长度 )
// 用于返还 视频流通道的状态
returnCode = DjiPayloadCamera_SendVideoStream((const uint8_t *) dataBuffer + lengthOfDataHaveBeenSent,
lengthOfDataToBeSent);
if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
USER_LOG_ERROR("send video stream error: 0x%08llX.", returnCode);
}
lengthOfDataHaveBeenSent += lengthOfDataToBeSent;
}
(void)osalHandler->GetTimeMs(&sendExpect);
sendExpect += (1000 / frameRate);
if ((frameNumber++) >= frameCount) {
USER_LOG_DEBUG("reach file tail.");
frameNumber = 0;
if (sendOneTimeFlag == true)
sendVideoFlag = false;
}
// 调整帧速率
returnCode = DjiPayloadCamera_GetVideoStreamState(&videoStreamState);
if (returnCode == DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
USER_LOG_DEBUG(
"video stream state: realtimeBandwidthLimit: %d, realtimeBandwidthBeforeFlowController: %d, realtimeBandwidthAfterFlowController:%d busyState: %d.",
videoStreamState.realtimeBandwidthLimit, videoStreamState.realtimeBandwidthBeforeFlowController,
videoStreamState.realtimeBandwidthAfterFlowController,
videoStreamState.busyState);
} else {
USER_LOG_ERROR("get video stream state error.");
}
free:
free(dataBuffer);
Push_end:
continue;
}
VideoSend_end:
if(ret < 0)
USER_LOG_ERROR("推流模块加载失败");
}
//录像播放测试函数,用于研发新产品时,图传播放录像使用
static void *TestCameraMedia_SendVideoTask(void *arg)
{
int ret;
// 回调错误
T_DjiReturnCode returnCode;
//发送视频的阶数
static uint32_t sendVideoStep = 0;
// 传输的视频文件
FILE *fpFile = NULL;
//传输数据长度 一帧不能超过65kb 超过需要分割
unsigned long dataLength = 0;
// 将要发送的产度
uint16_t lengthOfDataToBeSent = 0;
// 上次已发送的长度
int lengthOfDataHaveBeenSent = 0;
// 视频数据队列
char *dataBuffer = NULL;
// 回放指令
T_TestPayloadCameraPlaybackCommand playbackCommand = {0};
//
uint16_t bufferReadSize = 0;
// 视频文件的地址
char *videoFilePath = NULL;
// 转码文件的地址
char *transcodedFilePath = NULL;
float frameRate = 1.0f;
// 帧信息
T_TestPayloadCameraVideoFrameInfo *frameInfo = NULL;
// 帧数
uint32_t frameNumber = 0;
// 总帧
uint32_t frameCount = 0;
// 开始时间的 延迟
uint32_t startTimeMs = 0;
// 发送文件的标识
bool sendVideoFlag = true;
// 发送 一次 的 时间 标示
bool sendOneTimeFlag = false;
// 视频流状态
T_DjiDataChannelState videoStreamState = {0};
// 拍照模式
E_DjiCameraMode mode = DJI_CAMERA_MODE_SHOOT_PHOTO;
// ousl硬件层 句柄
T_DjiOsalHandler *osalHandler = DjiPlatform_GetOsalHandler();
uint32_t frameBufSize = 0;
// 视频流类型
E_DjiCameraVideoStreamType videoStreamType;
// 通用 文件路径
char curFileDirPath[DJI_FILE_PATH_SIZE_MAX];
// 临时路径
char tempPath[DJI_FILE_PATH_SIZE_MAX];
USER_UTIL_UNUSED(arg);
// 获取视频流文件信息
// 获取 通用地址 的错误
returnCode = DjiUserUtil_GetCurrentFileDirPath("/root/sdcard/DCIM", DJI_FILE_PATH_SIZE_MAX, curFileDirPath);
if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
USER_LOG_ERROR("Get file current path error, stat = 0x%08llX", returnCode);
exit(1);
}
USER_LOG_INFO("curFileDirPath:%s",curFileDirPath);
// if (s_isMediaFileDirPathConfigured == true) {
// snprintf(tempPath, DJI_FILE_PATH_SIZE_MAX, "%sPSDK_0005.h264", s_mediaFileDirPath);
// } else {
// snprintf(tempPath, DJI_FILE_PATH_SIZE_MAX, "%smedia_file/PSDK_0005.h264", curFileDirPath);
// }
snprintf(tempPath, DJI_FILE_PATH_SIZE_MAX, "/root/sdcard/media_file/PSDK_0005.h264", curFileDirPath);
// 写入用于推送文件的临时地址
// USER_LOG_INFO("tempPath:%s",tempPath);
// 视频流处理线程初始化
// 为视频文件申请
videoFilePath = osalHandler->Malloc(DJI_FILE_PATH_SIZE_MAX);
if (videoFilePath == NULL) {
USER_LOG_ERROR("malloc memory for video file path fail.");
exit(1);
}
// 转码文件的地址
transcodedFilePath = osalHandler->Malloc(DJI_FILE_PATH_SIZE_MAX);
if (transcodedFilePath == NULL) {
USER_LOG_ERROR("malloc memory for transcoded file path fail.");
exit(1);
}
// 帧信息
frameInfo = osalHandler->Malloc(VIDEO_FRAME_MAX_COUNT * sizeof(T_TestPayloadCameraVideoFrameInfo));
if (frameInfo == NULL) {
USER_LOG_ERROR("malloc memory for frame info fail.");
exit(1);
}
memset(frameInfo, 0, VIDEO_FRAME_MAX_COUNT * sizeof(T_TestPayloadCameraVideoFrameInfo));
//停止 回放播放程序
returnCode = DjiPlayback_StopPlayProcess();
if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
USER_LOG_ERROR("stop playback and start liveview error: 0x%08llX.", returnCode);
exit(1);
}
while (1) {
osalHandler->TaskSleepMs(1000 / SEND_VIDEO_TASK_FREQ);
// response playback command
if (osalHandler->MutexLock(s_mediaPlayCommandBufferMutex) != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
USER_LOG_ERROR("mutex lock error");
continue;
}
bufferReadSize = UtilBuffer_Get(&s_mediaPlayCommandBufferHandler, (uint8_t *) &playbackCommand,
sizeof(T_TestPayloadCameraPlaybackCommand));
if (osalHandler->MutexUnlock(s_mediaPlayCommandBufferMutex) != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
USER_LOG_ERROR("mutex unlock error");
continue;
}
if (bufferReadSize != sizeof(T_TestPayloadCameraPlaybackCommand))
goto send;
switch (playbackCommand.command) {
case TEST_PAYLOAD_CAMERA_MEDIA_PLAY_COMMAND_STOP:
snprintf(videoFilePath, DJI_FILE_PATH_SIZE_MAX, "%s", tempPath);
startTimeMs = 0;
sendVideoFlag = true;
sendOneTimeFlag = false;
break;
case TEST_PAYLOAD_CAMERA_MEDIA_PLAY_COMMAND_PAUSE:
sendVideoFlag = false;
goto send;
case TEST_PAYLOAD_CAMERA_MEDIA_PLAY_COMMAND_START:
snprintf(videoFilePath, DJI_FILE_PATH_SIZE_MAX, "%s", playbackCommand.path);
startTimeMs = playbackCommand.timeMs;
sendVideoFlag = true;
sendOneTimeFlag = true;
break;
default:
USER_LOG_ERROR("playback command invalid: %d.", playbackCommand.command);
sendVideoFlag = false;
goto send;
}
// video send preprocess
returnCode = DjiPlayback_VideoFileTranscode(videoFilePath, "h264", transcodedFilePath,
DJI_FILE_PATH_SIZE_MAX);
if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
USER_LOG_ERROR("transcode video file error: 0x%08llX.", returnCode);
continue;
}
returnCode = DjiPlayback_GetFrameRateOfVideoFile(transcodedFilePath, &frameRate);
if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
USER_LOG_ERROR("get frame rate of video error: 0x%08llX.", returnCode);
continue;
}
returnCode = DjiPlayback_GetFrameInfoOfVideoFile(transcodedFilePath, frameInfo, VIDEO_FRAME_MAX_COUNT,
&frameCount);
if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
USER_LOG_ERROR("get frame info of video error: 0x%08llX.", returnCode);
continue;
}
returnCode = DjiPlayback_GetFrameNumberByTime(frameInfo, frameCount, &frameNumber,
startTimeMs);
if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
USER_LOG_ERROR("get start frame number error: 0x%08llX.", returnCode);
continue;
}
if (fpFile != NULL)
fclose(fpFile);
fpFile = fopen(transcodedFilePath, "rb+");
if (fpFile == NULL) {
USER_LOG_ERROR("open video file fail.");
continue;
}
send:
if (fpFile == NULL) {
USER_LOG_ERROR("open video file fail.");
continue;
}
if (sendVideoFlag != true)
continue;
returnCode = DjiTest_CameraGetMode(&mode);
if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
continue;
}
returnCode = DjiTest_CameraGetVideoStreamType(&videoStreamType);
if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
continue;
}
if (mode == DJI_CAMERA_MODE_PLAYBACK && s_playbackInfo.isInPlayProcess == false) {
continue;
}
if (!USER_UTIL_IS_WORK_TURN(sendVideoStep++, frameRate, SEND_VIDEO_TASK_FREQ))
continue;
frameBufSize = frameInfo[frameNumber].size;
if (videoStreamType == DJI_CAMERA_VIDEO_STREAM_TYPE_H264_DJI_FORMAT) {
frameBufSize = frameBufSize + VIDEO_FRAME_AUD_LEN;
}
dataBuffer = calloc(frameBufSize, 1);
if (dataBuffer == NULL) {
USER_LOG_ERROR("malloc fail.");
goto free;
}
ret = fseek(fpFile, frameInfo[frameNumber].positionInFile, SEEK_SET);
if (ret != 0) {
USER_LOG_ERROR("fseek fail.");
goto free;
}
dataLength = fread(dataBuffer, 1, frameInfo[frameNumber].size, fpFile);
if (dataLength != frameInfo[frameNumber].size) {
USER_LOG_ERROR("read data from video file error.");
} else {
USER_LOG_DEBUG("read data from video file success, len = %d B\r\n", dataLength);
}
if (videoStreamType == DJI_CAMERA_VIDEO_STREAM_TYPE_H264_DJI_FORMAT) {
memcpy(&dataBuffer[frameInfo[frameNumber].size], s_frameAudInfo, VIDEO_FRAME_AUD_LEN);
dataLength = dataLength + VIDEO_FRAME_AUD_LEN;
}
lengthOfDataHaveBeenSent = 0;
while (dataLength - lengthOfDataHaveBeenSent) {
lengthOfDataToBeSent = USER_UTIL_MIN(DATA_SEND_FROM_VIDEO_STREAM_MAX_LEN,
dataLength - lengthOfDataHaveBeenSent);
returnCode = DjiPayloadCamera_SendVideoStream((const uint8_t *) dataBuffer + lengthOfDataHaveBeenSent,
lengthOfDataToBeSent);
if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
USER_LOG_ERROR("send video stream error: 0x%08llX.", returnCode);
}
lengthOfDataHaveBeenSent += lengthOfDataToBeSent;
}
if ((frameNumber++) >= frameCount) {
USER_LOG_DEBUG("reach file tail.");
frameNumber = 0;
if (sendOneTimeFlag == true)
sendVideoFlag = false;
}
returnCode = DjiPayloadCamera_GetVideoStreamState(&videoStreamState);
if (returnCode == DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
USER_LOG_DEBUG(
"video stream state: realtimeBandwidthLimit: %d, realtimeBandwidthBeforeFlowController: %d, realtimeBandwidthAfterFlowController:%d busyState: %d.",
videoStreamState.realtimeBandwidthLimit, videoStreamState.realtimeBandwidthBeforeFlowController,
videoStreamState.realtimeBandwidthAfterFlowController,
videoStreamState.busyState);
} else {
USER_LOG_ERROR("get video stream state error.");
}
free:
free(dataBuffer);
}
VideoSend_end:
if(ret < 0)
USER_LOG_ERROR("推流模块加载失败");
}
#ifndef __CC_ARM
#pragma GCC diagnostic pop
#endif
//#endif
/****************** (C) COPYRIGHT DJI Innovations *****END OF FILE****/
... ...
/**
********************************************************************
* @file test_payload_cam_emu_media.h
* @brief This is the header file for "test_payload_cam_media.c", defining the structure and
* (exported) function prototypes.
*
* @copyright (c) 2021 DJI. All rights reserved.
*
* All information contained herein is, and remains, the property of DJI.
* The intellectual and technical concepts contained herein are proprietary
* to DJI and may be covered by U.S. and foreign patents, patents in process,
* and protected by trade secret or copyright law. Dissemination of this
* information, including but not limited to data and other proprietary
* material(s) incorporated within the information, in any form, is strictly
* prohibited without the express written consent of DJI.
*
* If you receive this source code without DJI’s authorization, you may not
* further disseminate the information, and you must immediately remove the
* source code and notify DJI of its removal. DJI reserves the right to pursue
* legal actions against you for any loss(es) or damage(s) caused by your
* failure to do so.
*
*********************************************************************
*/
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef TEST_PAYLOAD_CAM_EMU_MEDIA_H
#define TEST_PAYLOAD_CAM_EMU_MEDIA_H
/* Includes ------------------------------------------------------------------*/
#include "dji_typedef.h"
#include "dji_payload_camera.h"
#ifdef __cplusplus
extern "C" {
#endif
/* Exported constants --------------------------------------------------------*/
/* Exported types ------------------------------------------------------------*/
/* Exported functions --------------------------------------------------------*/
T_DjiReturnCode DjiTest_CameraEmuMediaStartService(int mode);
T_DjiReturnCode DjiTest_CameraEmuSetMediaFilePath(const char *path);
T_DjiReturnCode DjiTest_CameraMediaGetFileInfo(const char *filePath, T_DjiCameraMediaFileInfo *fileInfo);
#ifdef __cplusplus
}
#endif
#endif // TEST_PAYLOAD_CAM_EMU_MEDIA_H
/************************ (C) COPYRIGHT DJI Innovations *******END OF FILE******/
... ...
/**
********************************************************************
* @file test_camera_manager.h
* @brief This is the header file for "test_camera_manager.c", defining the structure and
* (exported) function prototypes.
*
* @copyright (c) 2021 DJI. All rights reserved.
*
* All information contained herein is, and remains, the property of DJI.
* The intellectual and technical concepts contained herein are proprietary
* to DJI and may be covered by U.S. and foreign patents, patents in process,
* and protected by trade secret or copyright law. Dissemination of this
* information, including but not limited to data and other proprietary
* material(s) incorporated within the information, in any form, is strictly
* prohibited without the express written consent of DJI.
*
* If you receive this source code without DJI’s authorization, you may not
* further disseminate the information, and you must immediately remove the
* source code and notify DJI of its removal. DJI reserves the right to pursue
* legal actions against you for any loss(es) or damage(s) caused by your
* failure to do so.
*
*********************************************************************
*/
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef TEST_CAMERA_MANAGER_H
#define TEST_CAMERA_MANAGER_H
/* Includes ------------------------------------------------------------------*/
#include "dji_typedef.h"
#include "dji_camera_manager.h"
#ifdef __cplusplus
extern "C" {
#endif
/* Exported constants --------------------------------------------------------*/
/* Exported types ------------------------------------------------------------*/
typedef enum {
E_DJI_TEST_CAMERA_MANAGER_SAMPLE_SELECT_SET_CAMERA_SHUTTER_SPEED,
E_DJI_TEST_CAMERA_MANAGER_SAMPLE_SELECT_SET_CAMERA_APERTURE,
E_DJI_TEST_CAMERA_MANAGER_SAMPLE_SELECT_SET_CAMERA_EV,
E_DJI_TEST_CAMERA_MANAGER_SAMPLE_SELECT_SET_CAMERA_ISO,
E_DJI_TEST_CAMERA_MANAGER_SAMPLE_SELECT_SET_CAMERA_FOCUS_POINT,
E_DJI_TEST_CAMERA_MANAGER_SAMPLE_SELECT_SET_CAMERA_TAP_ZOOM_POINT,
E_DJI_TEST_CAMERA_MANAGER_SAMPLE_SELECT_SET_CAMERA_ZOOM_PARAM,
E_DJI_TEST_CAMERA_MANAGER_SAMPLE_SELECT_SHOOT_SINGLE_PHOTO,
E_DJI_TEST_CAMERA_MANAGER_SAMPLE_SELECT_SHOOT_BURST_PHOTO,
E_DJI_TEST_CAMERA_MANAGER_SAMPLE_SELECT_SHOOT_INTERVAL_PHOTO,
E_DJI_TEST_CAMERA_MANAGER_SAMPLE_SELECT_RECORD_VIDEO,
E_DJI_TEST_CAMERA_MANAGER_SAMPLE_SELECT_DOWNLOAD_AND_DELETE_MEDIA_FILE,
E_DJI_TEST_CAMERA_MANAGER_SAMPLE_SELECT_DOWNLOAD_FILE_LIST_BY_SLICES,
E_DJI_TEST_CAMERA_MANAGER_SAMPLE_SELECT_THERMOMETRY,
E_DJI_TEST_CAMERA_MANAGER_SAMPLE_SELECT_GET_LIDAR_RANGING_INFO,
E_DJI_TEST_CAMERA_MANAGER_SAMPLE_SELECT_IR_CAMERA_ZOOM_PARAM,
E_DJI_TEST_CAMERA_MANAGER_SAMPLE_SELECT_SET_NIGHT_SCENE_MODE,
E_DJI_TEST_CAMERA_MANAGER_SAMPLE_SELECT_SET_CAPTURE_RECORDING_STREAMS,
E_DJI_TEST_CAMERA_MANAGER_SAMPLE_SELECT_SHOW_STORAGE_INFO,
E_DJI_TEST_CAMERA_MANAGER_SAMPLE_SELECT_FORMAT_SD_CARD,
E_DJI_TEST_CAMERA_MANAGER_SAMPLE_SELECT_SET_LINK_ZOOM,
E_DJI_TEST_CAMERA_MANAGER_SAMPLE_SELECT_SET_USER_CUSTOM_DIR_FILE_NAME,
E_DJI_TEST_CAMERA_MANAGER_SAMPLE_SELECT_RESET_CAMERA_SETTINGS,
E_DJI_TEST_CAMERA_MANAGER_SAMPLE_SELECT_SET_AE_LOCK_MODE,
E_DJI_TEST_CAMERA_MANAGER_SAMPLE_SELECT_SET_FOCUS_RING_VALUE,
E_DJI_TEST_CAMERA_MANAGER_SAMPLE_SELECT_CONNECT_STATUS_TEST,
E_DJI_TEST_CAMERA_MANAGER_SAMPLE_SELECT_SET_GET_PHOTO_VIDEO_PARAM,
E_DJI_TEST_CAMERA_MANAGER_SAMPLE_SELECT_SET_METERING_MODE,
E_DJI_TEST_CAMERA_MANAGER_SAMPLE_SELECT_SET_METERING_POINT,
E_DJI_TEST_CAMERA_MANAGER_SAMPLE_SELECT_FFC_MODE_AND_TRRIGER,
E_DJI_TEST_CAMERA_MANAGER_SAMPLE_SELECT_SET_GAIN_MODE,
E_DJI_TEST_CAMERA_MANAGER_SAMPLE_SELECT_GET_CAMERA_STATUS,
E_DJI_TEST_CAMERA_MANAGER_SAMPLE_SELECT_SUBSCRIBE_POINT_CLOUD,
E_DJI_TEST_CAMERA_MANAGER_SAMPLE_SELECT_INDEX_MAX
} E_DjiTestCameraManagerSampleSelect;
/* Exported functions --------------------------------------------------------*/
/*! @brief Sample to set exposure compensation value for camera, using async
* api
*
* @note In this interface, exposure compensation value will be got then be
* set.
* @param index payload node index, input limit see enum
* DJI::OSDK::PayloadIndexType
* @param dataTarget the target exposure compensation value
* @return T_DjiReturnCode error code
*/
T_DjiReturnCode DjiTest_CameraManagerSetEV(E_DjiMountPosition position,
E_DjiCameraManagerExposureCompensation exposureCompensation);
/*! @brief Sample to set exposure mode for camera, using async api
*
* @note In this interface, exposure will be got then be set.
* @param index payload node index, input limit see enum
* DJI::OSDK::PayloadIndexType
* @param dataTarget the target exposure mode
* @return T_DjiReturnCode error code
*/
T_DjiReturnCode DjiTest_CameraManagerSetExposureMode(E_DjiMountPosition position,
E_DjiCameraManagerExposureMode exposureMode);
/*! @brief Sample to set ISO value for camera, using async api
*
* @note In this interface, ISO will be got then be set.
* @param index payload node index, input limit see enum
* DJI::OSDK::PayloadIndexType
* @param dataTarget the target ISO value
* @return T_DjiReturnCode error code
*/
T_DjiReturnCode DjiTest_CameraManagerSetISO(E_DjiMountPosition position,
E_DjiCameraManagerISO isoData);
/*! @brief Sample to set shutter speed for camera, using async api
*
* @note In this interface, shutter speed will be got then be set.
* @param index payload node index, input limit see enum
* DJI::OSDK::PayloadIndexType
* @param dataTarget the target shutter speed
* @return T_DjiReturnCode error code
*/
T_DjiReturnCode DjiTest_CameraManagerSetShutterSpeed(E_DjiMountPosition position,
E_DjiCameraManagerShutterSpeed shutterSpeed);
/*! @brief Sample to set shutter aperture value for camera, using async api
*
* @note In this interface, aperture value will be got then be set.
* @param index payload node index, input limit see enum
* DJI::OSDK::PayloadIndexType
* @param dataTarget the target aperture value
* @return T_DjiReturnCode error code
*/
T_DjiReturnCode DjiTest_CameraManagerSetAperture(E_DjiMountPosition position,
E_DjiCameraManagerAperture aperture);
/*! @brief Sample to set focus point for camera, using async api
*
* @note In this interface, focus mode will be set to be AUTO. Then the
* focus point will be set to be (x, y)
* @param index payload node index, input limit see enum
* DJI::OSDK::PayloadIndexType
* @param x the x value of target focus point, 0~1
* @param y the y value of target focus point, 0~1
* @return T_DjiReturnCode error code
*/
T_DjiReturnCode DjiTest_CameraManagerSetFocusPoint(E_DjiMountPosition position,
T_DjiCameraManagerFocusPosData tapFocusPos);
/*! @brief Sample to set tap-zoom point for camera, using async api
*
* @note In this interface, tap-zoom function will be enable and the
* multiplier will be set. Then the tap-zoom function will start with the
* target tap-zoom point (x, y)
* @param index payload node index, input limit see enum
* DJI::OSDK::PayloadIndexType
* @param multiplier the zoom multiplier of each tap zoom
* @param x the x value of target tap-zoom point, 0~1
* @param y the y value of target tap-zoom point, 0~1
* @return T_DjiReturnCode error code
*/
T_DjiReturnCode DjiTest_CameraManagerSetTapZoomPoint(E_DjiMountPosition position, uint8_t multiplier,
T_DjiCameraManagerTapZoomPosData tapZoomPosData);
/*! @brief Sample to execute continuous zoom on camera, using sync api
*
* @note It is only supported by X5, X5R and X5S camera on Osmo with lens
* Olympus M.Zuiko ED 14-42mm f/3.5-5.6 EZ, Z3 camera, Z30 camera.
* @note In this interface, the zoom will start with the designated direction
* and speed, and will stop after zoomTimeInSecond second(s).
* @param index payload node index, input limit see enum
* DJI::OSDK::PayloadIndexType
* @param direction the choice of zoom out or zoom in
* @param speed zooming speed
* @return T_DjiReturnCode error code
*/
T_DjiReturnCode DjiTest_CameraManagerStartContinuousZoom(E_DjiMountPosition position,
E_DjiCameraZoomDirection zoomDirection,
E_DjiCameraZoomSpeed zoomSpeed);
/*! @brief Sample to execute position zoom on camera, using sync api
*
* @note It is only supported by X5, X5R and X5S camera on Osmo with lens
* Olympus M.Zuiko ED 14-42mm f/3.5-5.6 EZ, Z3 camera, Z30 camera.
* @note In this interface, the zoom will set the zoom factor as the your
* target value.
* @param index payload node index, input limit see enum
* DJI::OSDK::PayloadIndexType
* @param factor target zoom factor
* @return T_DjiReturnCode error code
*/
T_DjiReturnCode DjiTest_CameraManagerOpticalZoom(E_DjiMountPosition position,
E_DjiCameraZoomDirection zoomDirection,
dji_f32_t factor);
/*! @brief Sample to stop continuous zoom on camera, using async api
*
* @note It is only supported by X5, X5R and X5S camera on Osmo with lens
* Olympus M.Zuiko ED 14-42mm f/3.5-5.6 EZ, Z3 camera, Z30 camera.
* @param index payload node index, input limit see enum
* DJI::OSDK::PayloadIndexType
* @return T_DjiReturnCode error code
*/
T_DjiReturnCode DjiTest_CameraManagerStopContinuousZoom(E_DjiMountPosition position);
/*! @brief Sample to shoot single photo, using async api
*
* @note In this interface, camera will be set to be the SHOOT_PHOTO mode
* then start to shoot a single photo.
* @param index payload node index, input limit see enum
* DJI::OSDK::PayloadIndexType
* @return T_DjiReturnCode error code
*/
T_DjiReturnCode DjiTest_CameraManagerStartShootSinglePhoto(E_DjiMountPosition position);
/*! @brief Sample to shoot burst photo, using async api
*
* @note In this interface, camera will be set to be the SHOOT_PHOTO mode
* then start to shoot a burst photo.
* @param index payload node index, input limit see enum
* DJI::OSDK::PayloadIndexType
* @param count The number of pictures in each burst shooting
* @return T_DjiReturnCode error code
*/
T_DjiReturnCode DjiTest_CameraManagerStartShootBurstPhoto(E_DjiMountPosition position,
E_DjiCameraBurstCount burstCount);
/*! @brief Sample to start shooting interval photo, using async api
*
* @note In this interface, camera will be set to be the SHOOT_PHOTO mode
* then start to shoot a interval photo.
* @param index payload node index, input limit see enum
* DJI::OSDK::PayloadIndexType
* @param intervalData the parameter of interval shooting
* @return T_DjiReturnCode error code
*/
T_DjiReturnCode DjiTest_CameraManagerStartShootIntervalPhoto(E_DjiMountPosition position,
T_DjiCameraPhotoTimeIntervalSettings intervalData);
/*! @brief Sample to stop shooting, using async api
*
* @note In this interface, camera will stop all the shooting action
* @param index payload node index, input limit see enum
* DJI::OSDK::PayloadIndexType
* @return T_DjiReturnCode error code
*/
T_DjiReturnCode DjiTest_CameraManagerStopShootPhoto(E_DjiMountPosition position);
/*! @brief Sample to start record video, using async api
*
* @note In this interface, camera will be set to be the RECORD_VIDEO mode
* then start to record video.
* @param index payload node index, input limit see enum
* DJI::OSDK::PayloadIndexType
* @return T_DjiReturnCode error code
*/
T_DjiReturnCode DjiTest_CameraManagerStartRecordVideo(E_DjiMountPosition position);
/*! @brief Sample to stop record video, using async api
*
* @note In this interface, camera will be set to be the RECORD_VIDEO mode
* then stop recording video.
* @param index payload node index, input limit see enum
* DJI::OSDK::PayloadIndexType
* @return T_DjiReturnCode error code
*/
T_DjiReturnCode DjiTest_CameraManagerStopRecordVideo(E_DjiMountPosition position);
T_DjiReturnCode DjiTest_CameraManagerRunSample(E_DjiMountPosition mountPosition,
E_DjiTestCameraManagerSampleSelect cameraManagerSampleSelect);
#ifdef __cplusplus
}
#endif
#endif // TEST_CAMERA_MANAGER_H
/************************ (C) COPYRIGHT DJI Innovations *******END OF FILE******/
... ...