合并分支 'dev_00.00.02.00' 到 'master'
Dev 00.00.02.02 查看合并请求 !2
正在显示
18 个修改的文件
包含
4866 行增加
和
1 行删除
| 1 | # Compiled class file | 1 | # Compiled class file |
| 2 | -project_build | 2 | + |
| 3 | ThirdParty | 3 | ThirdParty |
| 4 | ModuleLib | 4 | ModuleLib |
| 5 | 备份 | 5 | 备份 |
| 6 | + | ||
| 7 | + | ||
| 8 | +project_build/AUTEL_道通PSDK | ||
| 9 | +project_build/GDU_普宙PSDK | ||
| 10 | + | ||
| 11 | +project_build/Only_Serial/* | ||
| 12 | +!project_build/Only_Serial/application | ||
| 13 | +!project_build/Only_Serial/CMakeLists.txt | ||
| 14 | + | ||
| 15 | + | ||
| 16 | +project_build/DJI_大疆PSDK/* | ||
| 17 | +!project_build/DJI_大疆PSDK/samples | ||
| 18 | +project_build/DJI_大疆PSDK/samples/sample_c++ | ||
| 19 | + | ||
| 20 | +project_build/DJI_大疆PSDK/samples/sample_c/platform/* | ||
| 21 | +!project_build/DJI_大疆PSDK/samples/sample_c/platform/linux | ||
| 22 | + | ||
| 23 | + | ||
| 24 | +project_build/DJI_大疆PSDK/samples/sample_c/platform/linux/all/* | ||
| 25 | +!project_build/DJI_大疆PSDK/samples/sample_c/platform/linux/all/application | ||
| 26 | +!project_build/DJI_大疆PSDK/samples/sample_c/platform/linux/all/hal | ||
| 27 | +!project_build/DJI_大疆PSDK/samples/sample_c/platform/linux/all/CMakeLists.txt |
| 1 | +/** | ||
| 2 | + ******************************************************************** | ||
| 3 | + * @file dji_media_file_core.c | ||
| 4 | + * @brief | ||
| 5 | + * | ||
| 6 | + * @copyright (c) 2021 DJI. All rights reserved. | ||
| 7 | + * | ||
| 8 | + * All information contained herein is, and remains, the property of DJI. | ||
| 9 | + * The intellectual and technical concepts contained herein are proprietary | ||
| 10 | + * to DJI and may be covered by U.S. and foreign patents, patents in process, | ||
| 11 | + * and protected by trade secret or copyright law. Dissemination of this | ||
| 12 | + * information, including but not limited to data and other proprietary | ||
| 13 | + * material(s) incorporated within the information, in any form, is strictly | ||
| 14 | + * prohibited without the express written consent of DJI. | ||
| 15 | + * | ||
| 16 | + * If you receive this source code without DJI’s authorization, you may not | ||
| 17 | + * further disseminate the information, and you must immediately remove the | ||
| 18 | + * source code and notify DJI of its removal. DJI reserves the right to pursue | ||
| 19 | + * legal actions against you for any loss(es) or damage(s) caused by your | ||
| 20 | + * failure to do so. | ||
| 21 | + * | ||
| 22 | + ********************************************************************* | ||
| 23 | + */ | ||
| 24 | + | ||
| 25 | +/* Includes ------------------------------------------------------------------*/ | ||
| 26 | +#include <string.h> | ||
| 27 | +#include <dji_logger.h> | ||
| 28 | + | ||
| 29 | +#include "dji_media_file_core.h" | ||
| 30 | +#include "dji_media_file_jpg.h" | ||
| 31 | +#include "dji_media_file_mp4.h" | ||
| 32 | +#include "dji_platform.h" | ||
| 33 | + | ||
| 34 | +/* Private constants ---------------------------------------------------------*/ | ||
| 35 | + | ||
| 36 | +/* Private types -------------------------------------------------------------*/ | ||
| 37 | + | ||
| 38 | +/* Private functions declaration ---------------------------------------------*/ | ||
| 39 | + | ||
| 40 | +/* Private values ------------------------------------------------------------*/ | ||
| 41 | +//@formatter:off | ||
| 42 | +static const T_DjiMediaFileOptItem s_mediaFileOpt[] = | ||
| 43 | +{ | ||
| 44 | + //JPEG File Operation Item | ||
| 45 | + { | ||
| 46 | + DJI_CAMERA_FILE_TYPE_JPEG , | ||
| 47 | + DjiMediaFile_IsSupported_JPG, | ||
| 48 | + DjiMediaFile_GetAttrFunc_JPG, | ||
| 49 | + DjiMediaFile_GetDataOrigin_JPG, | ||
| 50 | + DjiMediaFile_GetFileSizeOrigin_JPG, | ||
| 51 | + DjiMediaFile_CreateThumbNail_JPG, | ||
| 52 | + DjiMediaFile_GetFileSizeThumbNail_JPG, | ||
| 53 | + DjiMediaFile_GetDataThumbNail_JPG, | ||
| 54 | + DjiMediaFile_DestroyThumbNail_JPG, | ||
| 55 | + DjiMediaFile_CreateScreenNail_JPG, | ||
| 56 | + DjiMediaFile_GetFileSizeScreenNail_JPG, | ||
| 57 | + DjiMediaFile_GetDataScreenNail_JPG, | ||
| 58 | + DjiMediaFile_DestroyScreenNail_JPG, | ||
| 59 | + }, | ||
| 60 | + //MP4 File Operation Item | ||
| 61 | + { | ||
| 62 | + DJI_CAMERA_FILE_TYPE_MP4 , | ||
| 63 | + DjiMediaFile_IsSupported_MP4, | ||
| 64 | + DjiMediaFile_GetAttrFunc_MP4, | ||
| 65 | + DjiMediaFile_GetDataOrigin_MP4, | ||
| 66 | + DjiMediaFile_GetFileSizeOrigin_MP4, | ||
| 67 | + DjiMediaFile_CreateThumbNail_MP4, | ||
| 68 | + DjiMediaFile_GetFileSizeThumbNail_MP4, | ||
| 69 | + DjiMediaFile_GetDataThumbNail_MP4, | ||
| 70 | + DjiMediaFile_DestroyThumbNail_MP4, | ||
| 71 | + DjiMediaFile_CreateScreenNail_MP4, | ||
| 72 | + DjiMediaFile_GetFileSizeScreenNail_MP4, | ||
| 73 | + DjiMediaFile_GetDataScreenNail_MP4, | ||
| 74 | + DjiMediaFile_DestroyScreenNail_MP4, | ||
| 75 | + }, | ||
| 76 | +}; | ||
| 77 | +static const uint32_t s_mediaFileOptCount = sizeof (s_mediaFileOpt) / sizeof(T_DjiMediaFileOptItem); | ||
| 78 | +//@formatter:on | ||
| 79 | + | ||
| 80 | +/* Exported functions definition ---------------------------------------------*/ | ||
| 81 | +bool DjiMediaFile_IsSupported(const char *filePath) | ||
| 82 | +{ | ||
| 83 | + int i; | ||
| 84 | + | ||
| 85 | + for (i = 0; i < s_mediaFileOptCount; i++) { | ||
| 86 | + if (s_mediaFileOpt[i].isSupportedFunc(filePath) == true) { | ||
| 87 | + return true; | ||
| 88 | + } | ||
| 89 | + } | ||
| 90 | + | ||
| 91 | + return false; | ||
| 92 | +} | ||
| 93 | + | ||
| 94 | +T_DjiReturnCode DjiMediaFile_CreateHandle(const char *filePath, T_DjiMediaFileHandle *pMediaFileHandle) | ||
| 95 | +{ | ||
| 96 | + int optIndex; | ||
| 97 | + T_DjiOsalHandler *osalHandler = DjiPlatform_GetOsalHandler(); | ||
| 98 | + | ||
| 99 | + for (optIndex = 0; optIndex < s_mediaFileOptCount; optIndex++) { | ||
| 100 | + if (s_mediaFileOpt[optIndex].isSupportedFunc(filePath) == true) { | ||
| 101 | + break; | ||
| 102 | + } | ||
| 103 | + } | ||
| 104 | + | ||
| 105 | + if (optIndex == s_mediaFileOptCount) { | ||
| 106 | + return DJI_ERROR_SYSTEM_MODULE_CODE_INVALID_PARAMETER; | ||
| 107 | + } | ||
| 108 | + | ||
| 109 | + *pMediaFileHandle = osalHandler->Malloc(sizeof(T_DjiMediaFile)); | ||
| 110 | + if (*pMediaFileHandle == NULL) { | ||
| 111 | + return DJI_ERROR_SYSTEM_MODULE_CODE_MEMORY_ALLOC_FAILED; | ||
| 112 | + } | ||
| 113 | + | ||
| 114 | + (*pMediaFileHandle)->filePath = osalHandler->Malloc(strlen(filePath) + 1); | ||
| 115 | + if ((*pMediaFileHandle)->filePath == NULL) { | ||
| 116 | + return DJI_ERROR_SYSTEM_MODULE_CODE_MEMORY_ALLOC_FAILED; | ||
| 117 | + } | ||
| 118 | + | ||
| 119 | + (*pMediaFileHandle)->mediaFileOptItem = s_mediaFileOpt[optIndex]; | ||
| 120 | + (*pMediaFileHandle)->mediaFileThm.privThm = NULL; | ||
| 121 | + (*pMediaFileHandle)->mediaFileScr.privScr = NULL; | ||
| 122 | + | ||
| 123 | + strcpy((*pMediaFileHandle)->filePath, filePath); | ||
| 124 | + | ||
| 125 | + return DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS; | ||
| 126 | +} | ||
| 127 | + | ||
| 128 | +T_DjiReturnCode DjiMediaFile_DestroyHandle(T_DjiMediaFileHandle mediaFileHandle) | ||
| 129 | +{ | ||
| 130 | + T_DjiOsalHandler *osalHandler = DjiPlatform_GetOsalHandler(); | ||
| 131 | + | ||
| 132 | + osalHandler->Free(mediaFileHandle->filePath); | ||
| 133 | + osalHandler->Free(mediaFileHandle); | ||
| 134 | + | ||
| 135 | + return DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS; | ||
| 136 | +} | ||
| 137 | + | ||
| 138 | +T_DjiReturnCode DjiMediaFile_GetMediaFileType(T_DjiMediaFileHandle mediaFileHandle, | ||
| 139 | + E_DjiCameraMediaFileType *mediaFileType) | ||
| 140 | +{ | ||
| 141 | + *mediaFileType = mediaFileHandle->mediaFileOptItem.mediaFileType; | ||
| 142 | + | ||
| 143 | + return DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS; | ||
| 144 | +} | ||
| 145 | + | ||
| 146 | +T_DjiReturnCode DjiMediaFile_GetMediaFileAttr(T_DjiMediaFileHandle mediaFileHandle, | ||
| 147 | + T_DjiCameraMediaFileAttr *mediaFileAttr) | ||
| 148 | +{ | ||
| 149 | + if (mediaFileHandle->mediaFileOptItem.getAttrFunc == NULL) { | ||
| 150 | + USER_LOG_ERROR("Media file handle getAttrFunc null error"); | ||
| 151 | + return DJI_ERROR_SYSTEM_MODULE_CODE_INVALID_PARAMETER; | ||
| 152 | + } | ||
| 153 | + | ||
| 154 | + return mediaFileHandle->mediaFileOptItem.getAttrFunc(mediaFileHandle, mediaFileAttr); | ||
| 155 | +} | ||
| 156 | + | ||
| 157 | +T_DjiReturnCode DjiMediaFile_GetDataOrg(struct _DjiMediaFile *mediaFileHandle, uint32_t offset, uint16_t len, | ||
| 158 | + uint8_t *data, uint32_t *realLen) | ||
| 159 | +{ | ||
| 160 | + if (mediaFileHandle->mediaFileOptItem.getDataOrgFunc == NULL) { | ||
| 161 | + USER_LOG_ERROR("Media file handle getDataOrgFunc null error"); | ||
| 162 | + return DJI_ERROR_SYSTEM_MODULE_CODE_INVALID_PARAMETER; | ||
| 163 | + } | ||
| 164 | + | ||
| 165 | + return mediaFileHandle->mediaFileOptItem.getDataOrgFunc(mediaFileHandle, offset, len, data, realLen); | ||
| 166 | +} | ||
| 167 | + | ||
| 168 | +T_DjiReturnCode DjiMediaFile_GetFileSizeOrg(struct _DjiMediaFile *mediaFileHandle, uint32_t *fileSize) | ||
| 169 | +{ | ||
| 170 | + if (mediaFileHandle->mediaFileOptItem.getFileSizeOrgFunc == NULL) { | ||
| 171 | + USER_LOG_ERROR("Media file handle getFileSizeOrgFunc null error"); | ||
| 172 | + return DJI_ERROR_SYSTEM_MODULE_CODE_INVALID_PARAMETER; | ||
| 173 | + } | ||
| 174 | + | ||
| 175 | + return mediaFileHandle->mediaFileOptItem.getFileSizeOrgFunc(mediaFileHandle, fileSize); | ||
| 176 | +} | ||
| 177 | + | ||
| 178 | +T_DjiReturnCode DjiMediaFile_CreateThm(T_DjiMediaFileHandle mediaFileHandle) | ||
| 179 | +{ | ||
| 180 | + if (mediaFileHandle->mediaFileOptItem.createThmFunc == NULL) { | ||
| 181 | + USER_LOG_ERROR("Media file handle createThmFunc null error"); | ||
| 182 | + return DJI_ERROR_SYSTEM_MODULE_CODE_INVALID_PARAMETER; | ||
| 183 | + } | ||
| 184 | + | ||
| 185 | + return mediaFileHandle->mediaFileOptItem.createThmFunc(mediaFileHandle); | ||
| 186 | +} | ||
| 187 | + | ||
| 188 | +T_DjiReturnCode DjiMediaFile_GetFileSizeThm(T_DjiMediaFileHandle mediaFileHandle, uint32_t *fileSize) | ||
| 189 | +{ | ||
| 190 | + if (mediaFileHandle->mediaFileOptItem.getFileSizeThmFunc == NULL) { | ||
| 191 | + USER_LOG_ERROR("Media file handle getFileSizeThmFunc null error"); | ||
| 192 | + return DJI_ERROR_SYSTEM_MODULE_CODE_INVALID_PARAMETER; | ||
| 193 | + } | ||
| 194 | + | ||
| 195 | + return mediaFileHandle->mediaFileOptItem.getFileSizeThmFunc(mediaFileHandle, fileSize); | ||
| 196 | +} | ||
| 197 | + | ||
| 198 | +T_DjiReturnCode DjiMediaFile_GetDataThm(T_DjiMediaFileHandle mediaFileHandle, uint32_t offset, uint16_t len, | ||
| 199 | + uint8_t *data, uint16_t *realLen) | ||
| 200 | +{ | ||
| 201 | + if (mediaFileHandle->mediaFileOptItem.getDataThmFunc == NULL) { | ||
| 202 | + USER_LOG_ERROR("Media file handle getDataThmFunc null error"); | ||
| 203 | + return DJI_ERROR_SYSTEM_MODULE_CODE_INVALID_PARAMETER; | ||
| 204 | + } | ||
| 205 | + | ||
| 206 | + return mediaFileHandle->mediaFileOptItem.getDataThmFunc(mediaFileHandle, offset, len, data, realLen); | ||
| 207 | +} | ||
| 208 | + | ||
| 209 | +T_DjiReturnCode DjiMediaFile_DestoryThm(T_DjiMediaFileHandle mediaFileHandle) | ||
| 210 | +{ | ||
| 211 | + if (mediaFileHandle->mediaFileOptItem.destroyThmFunc == NULL) { | ||
| 212 | + USER_LOG_ERROR("Media file handle destroyThmFunc null error"); | ||
| 213 | + return DJI_ERROR_SYSTEM_MODULE_CODE_INVALID_PARAMETER; | ||
| 214 | + } | ||
| 215 | + | ||
| 216 | + return mediaFileHandle->mediaFileOptItem.destroyThmFunc(mediaFileHandle); | ||
| 217 | +} | ||
| 218 | + | ||
| 219 | +T_DjiReturnCode DjiMediaFile_CreateScr(T_DjiMediaFileHandle mediaFileHandle) | ||
| 220 | +{ | ||
| 221 | + if (mediaFileHandle->mediaFileOptItem.creatScrFunc == NULL) { | ||
| 222 | + USER_LOG_ERROR("Media file handle creatScrFunc null error"); | ||
| 223 | + return DJI_ERROR_SYSTEM_MODULE_CODE_INVALID_PARAMETER; | ||
| 224 | + } | ||
| 225 | + | ||
| 226 | + return mediaFileHandle->mediaFileOptItem.creatScrFunc(mediaFileHandle); | ||
| 227 | +} | ||
| 228 | + | ||
| 229 | +T_DjiReturnCode DjiMediaFile_GetFileSizeScr(T_DjiMediaFileHandle mediaFileHandle, uint32_t *fileSize) | ||
| 230 | +{ | ||
| 231 | + if (mediaFileHandle->mediaFileOptItem.getFileSizeScrFunc == NULL) { | ||
| 232 | + USER_LOG_ERROR("Media file handle getFileSizeScrFunc null error"); | ||
| 233 | + return DJI_ERROR_SYSTEM_MODULE_CODE_INVALID_PARAMETER; | ||
| 234 | + } | ||
| 235 | + | ||
| 236 | + return mediaFileHandle->mediaFileOptItem.getFileSizeScrFunc(mediaFileHandle, fileSize); | ||
| 237 | +} | ||
| 238 | + | ||
| 239 | +T_DjiReturnCode DjiMediaFile_GetDataScr(T_DjiMediaFileHandle mediaFileHandle, uint32_t offset, uint16_t len, | ||
| 240 | + uint8_t *data, uint16_t *realLen) | ||
| 241 | +{ | ||
| 242 | + if (mediaFileHandle->mediaFileOptItem.getDataScrFunc == NULL) { | ||
| 243 | + USER_LOG_ERROR("Media file handle getDataScrFunc null error"); | ||
| 244 | + return DJI_ERROR_SYSTEM_MODULE_CODE_INVALID_PARAMETER; | ||
| 245 | + } | ||
| 246 | + | ||
| 247 | + return mediaFileHandle->mediaFileOptItem.getDataScrFunc(mediaFileHandle, offset, len, data, realLen); | ||
| 248 | +} | ||
| 249 | + | ||
| 250 | +T_DjiReturnCode DjiMediaFile_DestroyScr(T_DjiMediaFileHandle mediaFileHandle) | ||
| 251 | +{ | ||
| 252 | + if (mediaFileHandle->mediaFileOptItem.destroyScrFunc == NULL) { | ||
| 253 | + USER_LOG_ERROR("Media file handle destroyScrFunc null error"); | ||
| 254 | + return DJI_ERROR_SYSTEM_MODULE_CODE_INVALID_PARAMETER; | ||
| 255 | + } | ||
| 256 | + | ||
| 257 | + return mediaFileHandle->mediaFileOptItem.destroyScrFunc(mediaFileHandle); | ||
| 258 | +} | ||
| 259 | + | ||
| 260 | +/* Private functions definition-----------------------------------------------*/ | ||
| 261 | + | ||
| 262 | +/****************** (C) COPYRIGHT DJI Innovations *****END OF FILE****/ |
| 1 | +/** | ||
| 2 | + ******************************************************************** | ||
| 3 | + * @file dji_media_file_core.h | ||
| 4 | + * @brief This is the header file for "dji_media_file_core.c", defining the structure and | ||
| 5 | + * (exported) function prototypes. | ||
| 6 | + * | ||
| 7 | + * @copyright (c) 2021 DJI. All rights reserved. | ||
| 8 | + * | ||
| 9 | + * All information contained herein is, and remains, the property of DJI. | ||
| 10 | + * The intellectual and technical concepts contained herein are proprietary | ||
| 11 | + * to DJI and may be covered by U.S. and foreign patents, patents in process, | ||
| 12 | + * and protected by trade secret or copyright law. Dissemination of this | ||
| 13 | + * information, including but not limited to data and other proprietary | ||
| 14 | + * material(s) incorporated within the information, in any form, is strictly | ||
| 15 | + * prohibited without the express written consent of DJI. | ||
| 16 | + * | ||
| 17 | + * If you receive this source code without DJI’s authorization, you may not | ||
| 18 | + * further disseminate the information, and you must immediately remove the | ||
| 19 | + * source code and notify DJI of its removal. DJI reserves the right to pursue | ||
| 20 | + * legal actions against you for any loss(es) or damage(s) caused by your | ||
| 21 | + * failure to do so. | ||
| 22 | + * | ||
| 23 | + ********************************************************************* | ||
| 24 | + */ | ||
| 25 | + | ||
| 26 | +/* Define to prevent recursive inclusion -------------------------------------*/ | ||
| 27 | +#ifndef PSDK_MEDIA_FILE_CORE_H | ||
| 28 | +#define PSDK_MEDIA_FILE_CORE_H | ||
| 29 | + | ||
| 30 | +#ifdef __cplusplus | ||
| 31 | +extern "C" { | ||
| 32 | +#endif | ||
| 33 | + | ||
| 34 | +/* Includes ------------------------------------------------------------------*/ | ||
| 35 | +#include <dji_typedef.h> | ||
| 36 | +#include <dji_payload_camera.h> | ||
| 37 | + | ||
| 38 | +/* Exported constants --------------------------------------------------------*/ | ||
| 39 | +#define PSDK_MEDIA_FILE_PATH_LEN_MAX 512 /*max file path len */ | ||
| 40 | +#define PSDK_MEDIA_DIR_PATH_LEN_MAX 256 /*max dir path len */ | ||
| 41 | + | ||
| 42 | +/* Exported types ------------------------------------------------------------*/ | ||
| 43 | +typedef struct { | ||
| 44 | + void *privThm; | ||
| 45 | +} T_DjiMediaFileThm; | ||
| 46 | + | ||
| 47 | +typedef struct { | ||
| 48 | + void *privScr; | ||
| 49 | +} T_DjiMediaFileScr; | ||
| 50 | + | ||
| 51 | +struct _DjiMediaFile; | ||
| 52 | + | ||
| 53 | +typedef struct { | ||
| 54 | + E_DjiCameraMediaFileType mediaFileType; | ||
| 55 | + bool (*isSupportedFunc)(const char *filePath); | ||
| 56 | + | ||
| 57 | + T_DjiReturnCode (*getAttrFunc)(struct _DjiMediaFile *mediaFileHandle, T_DjiCameraMediaFileAttr *mediaFileAttr); | ||
| 58 | + | ||
| 59 | + T_DjiReturnCode (*getDataOrgFunc)(struct _DjiMediaFile *mediaFileHandle, uint32_t offset, uint16_t len, | ||
| 60 | + uint8_t *data, uint32_t *realLen); | ||
| 61 | + T_DjiReturnCode (*getFileSizeOrgFunc)(struct _DjiMediaFile *mediaFileHandle, uint32_t *fileSize); | ||
| 62 | + | ||
| 63 | + T_DjiReturnCode (*createThmFunc)(struct _DjiMediaFile *mediaFileHandle); | ||
| 64 | + T_DjiReturnCode (*getFileSizeThmFunc)(struct _DjiMediaFile *mediaFileHandle, uint32_t *fileSize); | ||
| 65 | + T_DjiReturnCode (*getDataThmFunc)(struct _DjiMediaFile *mediaFileHandle, uint32_t offset, uint16_t len, | ||
| 66 | + uint8_t *data, uint16_t *realLen); | ||
| 67 | + T_DjiReturnCode (*destroyThmFunc)(struct _DjiMediaFile *mediaFileHandle); | ||
| 68 | + | ||
| 69 | + T_DjiReturnCode (*creatScrFunc)(struct _DjiMediaFile *mediaFileHandle); | ||
| 70 | + T_DjiReturnCode (*getFileSizeScrFunc)(struct _DjiMediaFile *mediaFileHandle, uint32_t *fileSize); | ||
| 71 | + T_DjiReturnCode (*getDataScrFunc)(struct _DjiMediaFile *mediaFileHandle, uint32_t offset, uint16_t len, | ||
| 72 | + uint8_t *data, uint16_t *realLen); | ||
| 73 | + T_DjiReturnCode (*destroyScrFunc)(struct _DjiMediaFile *mediaFileHandle); | ||
| 74 | +} T_DjiMediaFileOptItem; | ||
| 75 | + | ||
| 76 | +typedef struct _DjiMediaFile { | ||
| 77 | + char *filePath; | ||
| 78 | + T_DjiMediaFileOptItem mediaFileOptItem; | ||
| 79 | + T_DjiMediaFileThm mediaFileThm; | ||
| 80 | + T_DjiMediaFileScr mediaFileScr; | ||
| 81 | +} T_DjiMediaFile, *T_DjiMediaFileHandle; | ||
| 82 | + | ||
| 83 | +/* Exported functions --------------------------------------------------------*/ | ||
| 84 | +bool DjiMediaFile_IsSupported(const char *filePath); | ||
| 85 | +T_DjiReturnCode DjiMediaFile_CreateHandle(const char *filePath, T_DjiMediaFileHandle *pMediaFileHandle); | ||
| 86 | +T_DjiReturnCode DjiMediaFile_DestroyHandle(T_DjiMediaFileHandle mediaFileHandle); | ||
| 87 | + | ||
| 88 | +T_DjiReturnCode DjiMediaFile_GetMediaFileType(T_DjiMediaFileHandle mediaFileHandle, | ||
| 89 | + E_DjiCameraMediaFileType *mediaFileType); | ||
| 90 | +T_DjiReturnCode DjiMediaFile_GetMediaFileAttr(T_DjiMediaFileHandle mediaFileHandle, | ||
| 91 | + T_DjiCameraMediaFileAttr *mediaFileAttr); | ||
| 92 | + | ||
| 93 | +T_DjiReturnCode DjiMediaFile_GetDataOrg(struct _DjiMediaFile *mediaFileHandle, uint32_t offset, uint16_t len, | ||
| 94 | + uint8_t *data, uint32_t *realLen); | ||
| 95 | +T_DjiReturnCode DjiMediaFile_GetFileSizeOrg(struct _DjiMediaFile *mediaFileHandle, uint32_t *fileSize); | ||
| 96 | + | ||
| 97 | +T_DjiReturnCode DjiMediaFile_CreateThm(T_DjiMediaFileHandle mediaFileHandle); | ||
| 98 | +T_DjiReturnCode DjiMediaFile_GetFileSizeThm(T_DjiMediaFileHandle mediaFileHandle, uint32_t *fileSize); | ||
| 99 | +T_DjiReturnCode DjiMediaFile_GetDataThm(T_DjiMediaFileHandle mediaFileHandle, uint32_t offset, uint16_t len, | ||
| 100 | + uint8_t *data, uint16_t *realLen); | ||
| 101 | +T_DjiReturnCode DjiMediaFile_DestoryThm(T_DjiMediaFileHandle mediaFileHandle); | ||
| 102 | + | ||
| 103 | +T_DjiReturnCode DjiMediaFile_CreateScr(T_DjiMediaFileHandle mediaFileHandle); | ||
| 104 | +T_DjiReturnCode DjiMediaFile_GetFileSizeScr(T_DjiMediaFileHandle mediaFileHandle, uint32_t *fileSize); | ||
| 105 | +T_DjiReturnCode DjiMediaFile_GetDataScr(T_DjiMediaFileHandle mediaFileHandle, uint32_t offset, uint16_t len, | ||
| 106 | + uint8_t *data, uint16_t *realLen); | ||
| 107 | +T_DjiReturnCode DjiMediaFile_DestroyScr(T_DjiMediaFileHandle mediaFileHandle); | ||
| 108 | + | ||
| 109 | +#ifdef __cplusplus | ||
| 110 | +} | ||
| 111 | +#endif | ||
| 112 | + | ||
| 113 | +#endif // PSDK_MEDIA_FILE_CORE_H | ||
| 114 | + | ||
| 115 | +/************************ (C) COPYRIGHT DJI Innovations *******END OF FILE******/ |
| 1 | +/** | ||
| 2 | + ******************************************************************** | ||
| 3 | + * @file dji_media_file_jpg.c | ||
| 4 | + * @brief | ||
| 5 | + * | ||
| 6 | + * @copyright (c) 2021 DJI. All rights reserved. | ||
| 7 | + * | ||
| 8 | + * All information contained herein is, and remains, the property of DJI. | ||
| 9 | + * The intellectual and technical concepts contained herein are proprietary | ||
| 10 | + * to DJI and may be covered by U.S. and foreign patents, patents in process, | ||
| 11 | + * and protected by trade secret or copyright law. Dissemination of this | ||
| 12 | + * information, including but not limited to data and other proprietary | ||
| 13 | + * material(s) incorporated within the information, in any form, is strictly | ||
| 14 | + * prohibited without the express written consent of DJI. | ||
| 15 | + * | ||
| 16 | + * If you receive this source code without DJI’s authorization, you may not | ||
| 17 | + * further disseminate the information, and you must immediately remove the | ||
| 18 | + * source code and notify DJI of its removal. DJI reserves the right to pursue | ||
| 19 | + * legal actions against you for any loss(es) or damage(s) caused by your | ||
| 20 | + * failure to do so. | ||
| 21 | + * | ||
| 22 | + ********************************************************************* | ||
| 23 | + */ | ||
| 24 | + | ||
| 25 | + | ||
| 26 | +/* Includes ------------------------------------------------------------------*/ | ||
| 27 | +#include "dji_media_file_jpg.h" | ||
| 28 | +#include "dji_media_file_core.h" | ||
| 29 | +#include <stdio.h> | ||
| 30 | +#include <string.h> | ||
| 31 | +#include <stdlib.h> | ||
| 32 | +#include <unistd.h> | ||
| 33 | +#include <dji_logger.h> | ||
| 34 | +#include <utils/util_misc.h> | ||
| 35 | +#include "dji_platform.h" | ||
| 36 | +#include "utils/util_time.h" | ||
| 37 | +#include "utils/util_file.h" | ||
| 38 | + | ||
| 39 | +/* Private constants ---------------------------------------------------------*/ | ||
| 40 | +#define JPG_FILE_SUFFIX ".jpg" | ||
| 41 | +#define JPG_TEMP_FILE_TEMPLATE_STR "JPG_TEMP_XXXXXX.jpg" | ||
| 42 | +#define JPG_TEMP_FILE_PATH_MAX_LEN 50 | ||
| 43 | +#define FFMPEG_CMD_BUF_SIZE 1024 | ||
| 44 | + | ||
| 45 | +#define JPG_THM_SCALE_CFG_STR "scale=100:-1" | ||
| 46 | +#define JPG_SCR_SCALE_CFG_STR "scale=600:-1" | ||
| 47 | + | ||
| 48 | +/* Private types -------------------------------------------------------------*/ | ||
| 49 | +typedef struct { | ||
| 50 | + FILE *tempFile; | ||
| 51 | + char tempfilePath[JPG_TEMP_FILE_PATH_MAX_LEN]; | ||
| 52 | +} T_DjiJPGTempFilePriv; | ||
| 53 | + | ||
| 54 | +/* Private functions declaration ---------------------------------------------*/ | ||
| 55 | +static T_DjiReturnCode DjiMediaFile_CreateTempFilePriv_JPG(const char *srcFilePath, const char *scaleCfgStr, | ||
| 56 | + T_DjiJPGTempFilePriv **pTempFilePrivHandle); | ||
| 57 | +static T_DjiReturnCode DjiMediaFile_DestroyTempFilePriv_JPG(T_DjiJPGTempFilePriv *tempFilePrivHandle); | ||
| 58 | + | ||
| 59 | +/* Exported functions definition ---------------------------------------------*/ | ||
| 60 | +bool DjiMediaFile_IsSupported_JPG(const char *filePath) | ||
| 61 | +{ | ||
| 62 | + if (filePath == NULL) { | ||
| 63 | + USER_LOG_ERROR("input parameter is null error"); | ||
| 64 | + return false; | ||
| 65 | + } | ||
| 66 | + | ||
| 67 | + if (strcmp(&filePath[strlen(filePath) - 4], JPG_FILE_SUFFIX) == 0) { | ||
| 68 | + return true; | ||
| 69 | + } | ||
| 70 | + | ||
| 71 | + return false; | ||
| 72 | +} | ||
| 73 | + | ||
| 74 | +T_DjiReturnCode DjiMediaFile_GetAttrFunc_JPG(struct _DjiMediaFile *mediaFileHandle, | ||
| 75 | + T_DjiCameraMediaFileAttr *mediaFileAttr) | ||
| 76 | +{ | ||
| 77 | + USER_UTIL_UNUSED(mediaFileHandle); | ||
| 78 | + | ||
| 79 | + mediaFileAttr->attrVideoDuration = 0; | ||
| 80 | + | ||
| 81 | + return DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS; | ||
| 82 | +} | ||
| 83 | + | ||
| 84 | +T_DjiReturnCode DjiMediaFile_GetDataOrigin_JPG(struct _DjiMediaFile *mediaFileHandle, uint32_t offset, uint16_t len, | ||
| 85 | + uint8_t *data, uint32_t *realLen) | ||
| 86 | +{ | ||
| 87 | + return UtilFile_GetFileDataByPath(mediaFileHandle->filePath, offset, len, data, realLen); | ||
| 88 | +} | ||
| 89 | + | ||
| 90 | +T_DjiReturnCode DjiMediaFile_GetFileSizeOrigin_JPG(struct _DjiMediaFile *mediaFileHandle, uint32_t *fileSize) | ||
| 91 | +{ | ||
| 92 | + return UtilFile_GetFileSizeByPath(mediaFileHandle->filePath, fileSize); | ||
| 93 | +} | ||
| 94 | + | ||
| 95 | +T_DjiReturnCode DjiMediaFile_CreateThumbNail_JPG(struct _DjiMediaFile *mediaFileHandle) | ||
| 96 | +{ | ||
| 97 | + return DjiMediaFile_CreateTempFilePriv_JPG(mediaFileHandle->filePath, JPG_THM_SCALE_CFG_STR, | ||
| 98 | + (T_DjiJPGTempFilePriv **) &mediaFileHandle->mediaFileThm.privThm); | ||
| 99 | +} | ||
| 100 | + | ||
| 101 | +T_DjiReturnCode DjiMediaFile_GetFileSizeThumbNail_JPG(struct _DjiMediaFile *mediaFileHandle, uint32_t *fileSize) | ||
| 102 | +{ | ||
| 103 | + T_DjiJPGTempFilePriv *jpgFileThmPriv = (T_DjiJPGTempFilePriv *) mediaFileHandle->mediaFileThm.privThm; | ||
| 104 | + | ||
| 105 | + return UtilFile_GetFileSize(jpgFileThmPriv->tempFile, fileSize); | ||
| 106 | +} | ||
| 107 | + | ||
| 108 | +T_DjiReturnCode | ||
| 109 | +DjiMediaFile_GetDataThumbNail_JPG(struct _DjiMediaFile *mediaFileHandle, uint32_t offset, uint16_t len, | ||
| 110 | + uint8_t *data, uint16_t *realLen) | ||
| 111 | +{ | ||
| 112 | + T_DjiJPGTempFilePriv *jpgFileThmPriv = (T_DjiJPGTempFilePriv *) mediaFileHandle->mediaFileThm.privThm; | ||
| 113 | + | ||
| 114 | + return UtilFile_GetFileData(jpgFileThmPriv->tempFile, offset, len, data, realLen); | ||
| 115 | +} | ||
| 116 | + | ||
| 117 | +T_DjiReturnCode DjiMediaFile_DestroyThumbNail_JPG(struct _DjiMediaFile *mediaFileHandle) | ||
| 118 | +{ | ||
| 119 | + return DjiMediaFile_DestroyTempFilePriv_JPG(mediaFileHandle->mediaFileThm.privThm); | ||
| 120 | +} | ||
| 121 | + | ||
| 122 | +T_DjiReturnCode DjiMediaFile_CreateScreenNail_JPG(struct _DjiMediaFile *mediaFileHandle) | ||
| 123 | +{ | ||
| 124 | + return DjiMediaFile_CreateTempFilePriv_JPG(mediaFileHandle->filePath, JPG_SCR_SCALE_CFG_STR, | ||
| 125 | + (T_DjiJPGTempFilePriv **) &mediaFileHandle->mediaFileScr.privScr); | ||
| 126 | +} | ||
| 127 | + | ||
| 128 | +T_DjiReturnCode DjiMediaFile_GetFileSizeScreenNail_JPG(struct _DjiMediaFile *mediaFileHandle, uint32_t *fileSize) | ||
| 129 | +{ | ||
| 130 | + T_DjiJPGTempFilePriv *jpgFileScrPriv = (T_DjiJPGTempFilePriv *) mediaFileHandle->mediaFileScr.privScr; | ||
| 131 | + | ||
| 132 | + return UtilFile_GetFileSize(jpgFileScrPriv->tempFile, fileSize); | ||
| 133 | +} | ||
| 134 | + | ||
| 135 | +T_DjiReturnCode | ||
| 136 | +DjiMediaFile_GetDataScreenNail_JPG(struct _DjiMediaFile *mediaFileHandle, uint32_t offset, uint16_t len, | ||
| 137 | + uint8_t *data, uint16_t *realLen) | ||
| 138 | +{ | ||
| 139 | + T_DjiJPGTempFilePriv *jpgFileScrPriv = (T_DjiJPGTempFilePriv *) mediaFileHandle->mediaFileScr.privScr; | ||
| 140 | + | ||
| 141 | + return UtilFile_GetFileData(jpgFileScrPriv->tempFile, offset, len, data, realLen); | ||
| 142 | +} | ||
| 143 | + | ||
| 144 | +T_DjiReturnCode DjiMediaFile_DestroyScreenNail_JPG(struct _DjiMediaFile *mediaFileHandle) | ||
| 145 | +{ | ||
| 146 | + return DjiMediaFile_DestroyTempFilePriv_JPG(mediaFileHandle->mediaFileScr.privScr); | ||
| 147 | +} | ||
| 148 | + | ||
| 149 | +/* Private functions definition-----------------------------------------------*/ | ||
| 150 | +static T_DjiReturnCode DjiMediaFile_CreateTempFilePriv_JPG(const char *srcFilePath, const char *scaleCfgStr, | ||
| 151 | + T_DjiJPGTempFilePriv **pTempFilePrivHandle) | ||
| 152 | +{ | ||
| 153 | + char ffmpeg_cmd[FFMPEG_CMD_BUF_SIZE]; | ||
| 154 | + int cmdRet; | ||
| 155 | + T_DjiRunTimeStamps tiStart, tiEnd; | ||
| 156 | + T_DjiJPGTempFilePriv *jpgTempFilePriv; | ||
| 157 | + T_DjiReturnCode psdkStat; | ||
| 158 | + int tempFd; | ||
| 159 | + T_DjiOsalHandler *osalHandler = DjiPlatform_GetOsalHandler(); | ||
| 160 | + | ||
| 161 | + tiStart = DjiUtilTime_GetRunTimeStamps(); | ||
| 162 | + | ||
| 163 | + *pTempFilePrivHandle = osalHandler->Malloc(sizeof(T_DjiJPGTempFilePriv)); | ||
| 164 | + if (*pTempFilePrivHandle == NULL) { | ||
| 165 | + return DJI_ERROR_SYSTEM_MODULE_CODE_MEMORY_ALLOC_FAILED; | ||
| 166 | + } | ||
| 167 | + | ||
| 168 | + jpgTempFilePriv = *pTempFilePrivHandle; | ||
| 169 | + | ||
| 170 | + //get temp file name | ||
| 171 | + strcpy(jpgTempFilePriv->tempfilePath, JPG_TEMP_FILE_TEMPLATE_STR); | ||
| 172 | + tempFd = mkstemps(jpgTempFilePriv->tempfilePath, strlen(JPG_FILE_SUFFIX)); | ||
| 173 | + if (tempFd < 0) { | ||
| 174 | + USER_LOG_ERROR("JPG Create Temp File Error, tempFd = %d\n", tempFd); | ||
| 175 | + psdkStat = DJI_ERROR_SYSTEM_MODULE_CODE_SYSTEM_ERROR; | ||
| 176 | + goto err_create_temp; | ||
| 177 | + } | ||
| 178 | + close(tempFd); | ||
| 179 | + unlink(jpgTempFilePriv->tempfilePath); | ||
| 180 | + | ||
| 181 | + //ffmpeg cmd send | ||
| 182 | + snprintf(ffmpeg_cmd, FFMPEG_CMD_BUF_SIZE, "ffmpeg -i \"%s\" -vf %s %s 1>/dev/null 2>&1", | ||
| 183 | + srcFilePath, scaleCfgStr, jpgTempFilePriv->tempfilePath); | ||
| 184 | + | ||
| 185 | + cmdRet = system(ffmpeg_cmd); | ||
| 186 | + | ||
| 187 | + tiEnd = DjiUtilTime_GetRunTimeStamps(); | ||
| 188 | + | ||
| 189 | + USER_LOG_DEBUG("JPG Create TempFile, RealTime = %ld us\n", tiEnd.realUsec - tiStart.realUsec); | ||
| 190 | + | ||
| 191 | + if (cmdRet != 0) { | ||
| 192 | + USER_LOG_ERROR("JPG ffmpeg cmd call error, ret = %d\n", cmdRet); | ||
| 193 | + psdkStat = DJI_ERROR_SYSTEM_MODULE_CODE_SYSTEM_ERROR; | ||
| 194 | + goto err_system_cmd; | ||
| 195 | + } | ||
| 196 | + | ||
| 197 | + //open temp file | ||
| 198 | + jpgTempFilePriv->tempFile = fopen(jpgTempFilePriv->tempfilePath, "rb+"); | ||
| 199 | + if (jpgTempFilePriv->tempFile == NULL) { | ||
| 200 | + psdkStat = DJI_ERROR_SYSTEM_MODULE_CODE_SYSTEM_ERROR; | ||
| 201 | + goto err_file_open; | ||
| 202 | + } | ||
| 203 | + | ||
| 204 | + //unlink temp file | ||
| 205 | + unlink(jpgTempFilePriv->tempfilePath); | ||
| 206 | + | ||
| 207 | + return DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS; | ||
| 208 | + | ||
| 209 | +err_file_open: | ||
| 210 | + unlink(jpgTempFilePriv->tempfilePath); | ||
| 211 | +err_system_cmd: | ||
| 212 | +err_create_temp: | ||
| 213 | + osalHandler->Free(*pTempFilePrivHandle); | ||
| 214 | + | ||
| 215 | + return psdkStat; | ||
| 216 | +} | ||
| 217 | + | ||
| 218 | +static T_DjiReturnCode DjiMediaFile_DestroyTempFilePriv_JPG(T_DjiJPGTempFilePriv *tempFilePrivHandle) | ||
| 219 | +{ | ||
| 220 | + T_DjiOsalHandler *osalHandler = DjiPlatform_GetOsalHandler(); | ||
| 221 | + | ||
| 222 | + fclose(tempFilePrivHandle->tempFile); | ||
| 223 | + osalHandler->Free(tempFilePrivHandle); | ||
| 224 | + | ||
| 225 | + return DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS; | ||
| 226 | +} | ||
| 227 | + | ||
| 228 | +/****************** (C) COPYRIGHT DJI Innovations *****END OF FILE****/ |
| 1 | +/** | ||
| 2 | + ******************************************************************** | ||
| 3 | + * @file dji_media_file_jpg.h | ||
| 4 | + * @brief This is the header file for "dji_media_file_jpg.c", defining the structure and | ||
| 5 | + * (exported) function prototypes. | ||
| 6 | + * | ||
| 7 | + * @copyright (c) 2021 DJI. All rights reserved. | ||
| 8 | + * | ||
| 9 | + * All information contained herein is, and remains, the property of DJI. | ||
| 10 | + * The intellectual and technical concepts contained herein are proprietary | ||
| 11 | + * to DJI and may be covered by U.S. and foreign patents, patents in process, | ||
| 12 | + * and protected by trade secret or copyright law. Dissemination of this | ||
| 13 | + * information, including but not limited to data and other proprietary | ||
| 14 | + * material(s) incorporated within the information, in any form, is strictly | ||
| 15 | + * prohibited without the express written consent of DJI. | ||
| 16 | + * | ||
| 17 | + * If you receive this source code without DJI’s authorization, you may not | ||
| 18 | + * further disseminate the information, and you must immediately remove the | ||
| 19 | + * source code and notify DJI of its removal. DJI reserves the right to pursue | ||
| 20 | + * legal actions against you for any loss(es) or damage(s) caused by your | ||
| 21 | + * failure to do so. | ||
| 22 | + * | ||
| 23 | + ********************************************************************* | ||
| 24 | + */ | ||
| 25 | + | ||
| 26 | +/* Define to prevent recursive inclusion -------------------------------------*/ | ||
| 27 | +#ifndef PSDK_MEDIA_FILE_JPG_H | ||
| 28 | +#define PSDK_MEDIA_FILE_JPG_H | ||
| 29 | + | ||
| 30 | +#ifdef __cplusplus | ||
| 31 | +extern "C" { | ||
| 32 | +#endif | ||
| 33 | + | ||
| 34 | +/* Includes ------------------------------------------------------------------*/ | ||
| 35 | +#include <dji_payload_camera.h> | ||
| 36 | +#include <dji_typedef.h> | ||
| 37 | +#include "dji_media_file_core.h" | ||
| 38 | + | ||
| 39 | +/* Exported constants --------------------------------------------------------*/ | ||
| 40 | + | ||
| 41 | + | ||
| 42 | +/* Exported types ------------------------------------------------------------*/ | ||
| 43 | + | ||
| 44 | + | ||
| 45 | +/* Exported functions --------------------------------------------------------*/ | ||
| 46 | +bool DjiMediaFile_IsSupported_JPG(const char *filePath); | ||
| 47 | + | ||
| 48 | +T_DjiReturnCode DjiMediaFile_GetAttrFunc_JPG(struct _DjiMediaFile *mediaFileHandle, | ||
| 49 | + T_DjiCameraMediaFileAttr *mediaFileAttr); | ||
| 50 | + | ||
| 51 | +T_DjiReturnCode DjiMediaFile_GetDataOrigin_JPG(struct _DjiMediaFile *mediaFileHandle, uint32_t offset, uint16_t len, | ||
| 52 | + uint8_t *data, uint32_t *realLen); | ||
| 53 | +T_DjiReturnCode DjiMediaFile_GetFileSizeOrigin_JPG(struct _DjiMediaFile *mediaFileHandle, uint32_t *fileSize); | ||
| 54 | + | ||
| 55 | +T_DjiReturnCode DjiMediaFile_CreateThumbNail_JPG(struct _DjiMediaFile *mediaFileHandle); | ||
| 56 | +T_DjiReturnCode DjiMediaFile_GetFileSizeThumbNail_JPG(struct _DjiMediaFile *mediaFileHandle, uint32_t *fileSize); | ||
| 57 | +T_DjiReturnCode | ||
| 58 | +DjiMediaFile_GetDataThumbNail_JPG(struct _DjiMediaFile *mediaFileHandle, uint32_t offset, uint16_t len, | ||
| 59 | + uint8_t *data, uint16_t *realLen); | ||
| 60 | +T_DjiReturnCode DjiMediaFile_DestroyThumbNail_JPG(struct _DjiMediaFile *mediaFileHandle); | ||
| 61 | + | ||
| 62 | +T_DjiReturnCode DjiMediaFile_CreateScreenNail_JPG(struct _DjiMediaFile *mediaFileHandle); | ||
| 63 | +T_DjiReturnCode DjiMediaFile_GetFileSizeScreenNail_JPG(struct _DjiMediaFile *mediaFileHandle, uint32_t *fileSize); | ||
| 64 | +T_DjiReturnCode | ||
| 65 | +DjiMediaFile_GetDataScreenNail_JPG(struct _DjiMediaFile *mediaFileHandle, uint32_t offset, uint16_t len, | ||
| 66 | + uint8_t *data, uint16_t *realLen); | ||
| 67 | +T_DjiReturnCode DjiMediaFile_DestroyScreenNail_JPG(struct _DjiMediaFile *mediaFileHandle); | ||
| 68 | + | ||
| 69 | +#ifdef __cplusplus | ||
| 70 | +} | ||
| 71 | +#endif | ||
| 72 | + | ||
| 73 | +#endif // PSDK_MEIDA_FILE_JPG_H | ||
| 74 | + | ||
| 75 | +/************************ (C) COPYRIGHT DJI Innovations *******END OF FILE******/ |
| 1 | +/** | ||
| 2 | + ******************************************************************** | ||
| 3 | + * @file dji_media_file_mp4.c | ||
| 4 | + * @brief | ||
| 5 | + * | ||
| 6 | + * @copyright (c) 2021 DJI. All rights reserved. | ||
| 7 | + * | ||
| 8 | + * All information contained herein is, and remains, the property of DJI. | ||
| 9 | + * The intellectual and technical concepts contained herein are proprietary | ||
| 10 | + * to DJI and may be covered by U.S. and foreign patents, patents in process, | ||
| 11 | + * and protected by trade secret or copyright law. Dissemination of this | ||
| 12 | + * information, including but not limited to data and other proprietary | ||
| 13 | + * material(s) incorporated within the information, in any form, is strictly | ||
| 14 | + * prohibited without the express written consent of DJI. | ||
| 15 | + * | ||
| 16 | + * If you receive this source code without DJI’s authorization, you may not | ||
| 17 | + * further disseminate the information, and you must immediately remove the | ||
| 18 | + * source code and notify DJI of its removal. DJI reserves the right to pursue | ||
| 19 | + * legal actions against you for any loss(es) or damage(s) caused by your | ||
| 20 | + * failure to do so. | ||
| 21 | + * | ||
| 22 | + ********************************************************************* | ||
| 23 | + */ | ||
| 24 | + | ||
| 25 | + | ||
| 26 | +/* Includes ------------------------------------------------------------------*/ | ||
| 27 | +#include "dji_media_file_mp4.h" | ||
| 28 | +#include "dji_media_file_core.h" | ||
| 29 | +#include <string.h> | ||
| 30 | +#include <unistd.h> | ||
| 31 | +#include <stdio.h> | ||
| 32 | +#include <dji_logger.h> | ||
| 33 | +#include <stdlib.h> | ||
| 34 | +#include "dji_platform.h" | ||
| 35 | +#include "utils/util_time.h" | ||
| 36 | +#include "utils/util_file.h" | ||
| 37 | + | ||
| 38 | +/* Private constants ---------------------------------------------------------*/ | ||
| 39 | + | ||
| 40 | +#define MP4_FILE_SUFFIX ".mp4" | ||
| 41 | +#define MP4_TEMP_FILE_TEMPLATE_STR "MP4_TEMP_XXXXXX.jpg" | ||
| 42 | +#define MP4_TEMP_FILE_PATH_MAX_LEN 50 | ||
| 43 | +#define FFMPEG_CMD_BUF_SIZE (256 + 256) | ||
| 44 | + | ||
| 45 | +#define MP4_THM_SCALE_CFG_STR "scale=100:-1" | ||
| 46 | +#define MP4_SCR_SCALE_CFG_STR "scale=600:-1" | ||
| 47 | + | ||
| 48 | +/* Private types -------------------------------------------------------------*/ | ||
| 49 | +typedef struct { | ||
| 50 | + FILE *tempFile; | ||
| 51 | + char tempfilePath[MP4_TEMP_FILE_PATH_MAX_LEN]; | ||
| 52 | +} T_DjiMP4TempPicPriv; | ||
| 53 | + | ||
| 54 | +/* Private functions declaration ---------------------------------------------*/ | ||
| 55 | +static T_DjiReturnCode DjiMediaFile_CreateTempPicPriv_MP4(const char *srcFilePath, const char *scaleCfgStr, | ||
| 56 | + T_DjiMP4TempPicPriv **pTempPicPrivHandle); | ||
| 57 | +static T_DjiReturnCode DjiMediaFile_DestroyTempPicPriv_MP4(T_DjiMP4TempPicPriv *tempPicPrivHandle); | ||
| 58 | + | ||
| 59 | +/* Private values ------------------------------------------------------------*/ | ||
| 60 | + | ||
| 61 | +/* Exported functions definition ---------------------------------------------*/ | ||
| 62 | +bool DjiMediaFile_IsSupported_MP4(const char *filePath) | ||
| 63 | +{ | ||
| 64 | + if (filePath == NULL) { | ||
| 65 | + USER_LOG_ERROR("input parameter is null error"); | ||
| 66 | + return false; | ||
| 67 | + } | ||
| 68 | + | ||
| 69 | + if (strcmp(&filePath[strlen(filePath) - 4], MP4_FILE_SUFFIX) == 0) { | ||
| 70 | + return true; | ||
| 71 | + } | ||
| 72 | + | ||
| 73 | + return false; | ||
| 74 | +} | ||
| 75 | + | ||
| 76 | +T_DjiReturnCode DjiMediaFile_GetAttrFunc_MP4(struct _DjiMediaFile *mediaFileHandle, | ||
| 77 | + T_DjiCameraMediaFileAttr *mediaFileAttr) | ||
| 78 | +{ | ||
| 79 | + FILE *fp; | ||
| 80 | + char ffmpegCmdStr[FFMPEG_CMD_BUF_SIZE]; | ||
| 81 | + float hour, minute, second; | ||
| 82 | + char tempTailStr[128]; | ||
| 83 | + int ret; | ||
| 84 | + T_DjiReturnCode psdkStat; | ||
| 85 | + | ||
| 86 | + snprintf(ffmpegCmdStr, FFMPEG_CMD_BUF_SIZE, "ffmpeg -i \"%s\" 2>&1 | grep \"Duration\"", mediaFileHandle->filePath); | ||
| 87 | + fp = popen(ffmpegCmdStr, "r"); | ||
| 88 | + | ||
| 89 | + if (fp == NULL) { | ||
| 90 | + return DJI_ERROR_SYSTEM_MODULE_CODE_SYSTEM_ERROR; | ||
| 91 | + } | ||
| 92 | + | ||
| 93 | + ret = fscanf(fp, " Duration: %f:%f:%f,%127s", &hour, &minute, &second, tempTailStr); | ||
| 94 | + if (ret <= 0) { | ||
| 95 | + USER_LOG_ERROR("MP4 File Get Duration Error\n"); | ||
| 96 | + psdkStat = DJI_ERROR_SYSTEM_MODULE_CODE_SYSTEM_ERROR; | ||
| 97 | + goto out; | ||
| 98 | + } | ||
| 99 | + | ||
| 100 | + mediaFileAttr->attrVideoDuration = (uint32_t) (hour * 3600 + minute * 60 + second + 0.5); | ||
| 101 | + | ||
| 102 | + /*! The user needs to obtain the frame rate and resolution of the video file by ffmpeg tools. | ||
| 103 | + * Also the frame rate and resolution of video need convert to enum E_DjiCameraVideoFrameRate or | ||
| 104 | + * E_DjiCameraVideoResolution. | ||
| 105 | + */ | ||
| 106 | + mediaFileAttr->attrVideoFrameRate = DJI_CAMERA_VIDEO_FRAME_RATE_30_FPS; | ||
| 107 | + mediaFileAttr->attrVideoResolution = DJI_CAMERA_VIDEO_RESOLUTION_1920x1080; | ||
| 108 | + | ||
| 109 | + psdkStat = DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS; | ||
| 110 | + | ||
| 111 | +out: | ||
| 112 | + pclose(fp); | ||
| 113 | + | ||
| 114 | + return psdkStat; | ||
| 115 | +} | ||
| 116 | + | ||
| 117 | +T_DjiReturnCode DjiMediaFile_GetDataOrigin_MP4(struct _DjiMediaFile *mediaFileHandle, uint32_t offset, uint16_t len, | ||
| 118 | + uint8_t *data, uint32_t *realLen) | ||
| 119 | +{ | ||
| 120 | + return UtilFile_GetFileDataByPath(mediaFileHandle->filePath, offset, len, data, realLen); | ||
| 121 | +} | ||
| 122 | + | ||
| 123 | +T_DjiReturnCode DjiMediaFile_GetFileSizeOrigin_MP4(struct _DjiMediaFile *mediaFileHandle, uint32_t *fileSize) | ||
| 124 | +{ | ||
| 125 | + return UtilFile_GetFileSizeByPath(mediaFileHandle->filePath, fileSize); | ||
| 126 | +} | ||
| 127 | + | ||
| 128 | +T_DjiReturnCode DjiMediaFile_CreateThumbNail_MP4(struct _DjiMediaFile *mediaFileHandle) | ||
| 129 | +{ | ||
| 130 | + | ||
| 131 | + return DjiMediaFile_CreateTempPicPriv_MP4(mediaFileHandle->filePath, MP4_THM_SCALE_CFG_STR, | ||
| 132 | + (T_DjiMP4TempPicPriv **) &mediaFileHandle->mediaFileThm.privThm); | ||
| 133 | +} | ||
| 134 | + | ||
| 135 | +T_DjiReturnCode DjiMediaFile_GetFileSizeThumbNail_MP4(struct _DjiMediaFile *mediaFileHandle, uint32_t *fileSize) | ||
| 136 | +{ | ||
| 137 | + T_DjiMP4TempPicPriv *jpgFileThmPriv = (T_DjiMP4TempPicPriv *) mediaFileHandle->mediaFileThm.privThm; | ||
| 138 | + | ||
| 139 | + return UtilFile_GetFileSize(jpgFileThmPriv->tempFile, fileSize); | ||
| 140 | +} | ||
| 141 | + | ||
| 142 | +T_DjiReturnCode | ||
| 143 | +DjiMediaFile_GetDataThumbNail_MP4(struct _DjiMediaFile *mediaFileHandle, uint32_t offset, uint16_t len, | ||
| 144 | + uint8_t *data, uint16_t *realLen) | ||
| 145 | +{ | ||
| 146 | + T_DjiMP4TempPicPriv *jpgFileThmPriv = (T_DjiMP4TempPicPriv *) mediaFileHandle->mediaFileThm.privThm; | ||
| 147 | + | ||
| 148 | + return UtilFile_GetFileData(jpgFileThmPriv->tempFile, offset, len, data, realLen); | ||
| 149 | +} | ||
| 150 | + | ||
| 151 | +T_DjiReturnCode DjiMediaFile_DestroyThumbNail_MP4(struct _DjiMediaFile *MediaFileHandle) | ||
| 152 | +{ | ||
| 153 | + return DjiMediaFile_DestroyTempPicPriv_MP4(MediaFileHandle->mediaFileThm.privThm); | ||
| 154 | +} | ||
| 155 | + | ||
| 156 | +T_DjiReturnCode DjiMediaFile_CreateScreenNail_MP4(struct _DjiMediaFile *mediaFileHandle) | ||
| 157 | +{ | ||
| 158 | + return DjiMediaFile_CreateTempPicPriv_MP4(mediaFileHandle->filePath, MP4_SCR_SCALE_CFG_STR, | ||
| 159 | + (T_DjiMP4TempPicPriv **) &mediaFileHandle->mediaFileScr.privScr); | ||
| 160 | +} | ||
| 161 | + | ||
| 162 | +T_DjiReturnCode DjiMediaFile_GetFileSizeScreenNail_MP4(struct _DjiMediaFile *mediaFileHandle, uint32_t *fileSize) | ||
| 163 | +{ | ||
| 164 | + T_DjiMP4TempPicPriv *jpgFileScrPriv = (T_DjiMP4TempPicPriv *) mediaFileHandle->mediaFileScr.privScr; | ||
| 165 | + | ||
| 166 | + return UtilFile_GetFileSize(jpgFileScrPriv->tempFile, fileSize); | ||
| 167 | +} | ||
| 168 | + | ||
| 169 | +T_DjiReturnCode | ||
| 170 | +DjiMediaFile_GetDataScreenNail_MP4(struct _DjiMediaFile *mediaFileHandle, uint32_t offset, uint16_t len, | ||
| 171 | + uint8_t *data, uint16_t *realLen) | ||
| 172 | +{ | ||
| 173 | + T_DjiMP4TempPicPriv *jpgFileScrPriv = (T_DjiMP4TempPicPriv *) mediaFileHandle->mediaFileScr.privScr; | ||
| 174 | + | ||
| 175 | + return UtilFile_GetFileData(jpgFileScrPriv->tempFile, offset, len, data, realLen); | ||
| 176 | +} | ||
| 177 | + | ||
| 178 | +T_DjiReturnCode DjiMediaFile_DestroyScreenNail_MP4(struct _DjiMediaFile *mediaFileHandle) | ||
| 179 | +{ | ||
| 180 | + return DjiMediaFile_DestroyTempPicPriv_MP4(mediaFileHandle->mediaFileScr.privScr); | ||
| 181 | +} | ||
| 182 | + | ||
| 183 | +/* Private functions definition-----------------------------------------------*/ | ||
| 184 | +static T_DjiReturnCode DjiMediaFile_CreateTempPicPriv_MP4(const char *srcFilePath, const char *scaleCfgStr, | ||
| 185 | + T_DjiMP4TempPicPriv **pTempPicPrivHandle) | ||
| 186 | +{ | ||
| 187 | + char ffmpeg_cmd[FFMPEG_CMD_BUF_SIZE]; | ||
| 188 | + int cmdRet; | ||
| 189 | + T_DjiRunTimeStamps tiStart, tiEnd; | ||
| 190 | + T_DjiMP4TempPicPriv *mp4TempPicFile; | ||
| 191 | + T_DjiReturnCode psdkStat; | ||
| 192 | + int tempFd; | ||
| 193 | + T_DjiOsalHandler *osalHandler = DjiPlatform_GetOsalHandler(); | ||
| 194 | + | ||
| 195 | + tiStart = DjiUtilTime_GetRunTimeStamps(); | ||
| 196 | + | ||
| 197 | + *pTempPicPrivHandle = osalHandler->Malloc(sizeof(T_DjiMP4TempPicPriv)); | ||
| 198 | + if (*pTempPicPrivHandle == NULL) { | ||
| 199 | + return DJI_ERROR_SYSTEM_MODULE_CODE_MEMORY_ALLOC_FAILED; | ||
| 200 | + } | ||
| 201 | + | ||
| 202 | + mp4TempPicFile = *pTempPicPrivHandle; | ||
| 203 | + | ||
| 204 | + //get temp file name | ||
| 205 | + strcpy(mp4TempPicFile->tempfilePath, MP4_TEMP_FILE_TEMPLATE_STR); | ||
| 206 | + tempFd = mkstemps(mp4TempPicFile->tempfilePath, strlen(MP4_FILE_SUFFIX)); | ||
| 207 | + if (tempFd < 0) { | ||
| 208 | + USER_LOG_ERROR("JPG Create Temp File Error, tempFd = %d\n", tempFd); | ||
| 209 | + psdkStat = DJI_ERROR_SYSTEM_MODULE_CODE_SYSTEM_ERROR; | ||
| 210 | + goto err_create_temp; | ||
| 211 | + } | ||
| 212 | + close(tempFd); | ||
| 213 | + unlink(mp4TempPicFile->tempfilePath); | ||
| 214 | + | ||
| 215 | + //ffmpeg cmd send | ||
| 216 | + snprintf(ffmpeg_cmd, FFMPEG_CMD_BUF_SIZE, "ffmpeg -i \"%s\" -vf %s -ss 00:00:00 -vframes 1 %s 1>/dev/null 2>&1", | ||
| 217 | + srcFilePath, scaleCfgStr, mp4TempPicFile->tempfilePath); | ||
| 218 | + | ||
| 219 | + cmdRet = system(ffmpeg_cmd); | ||
| 220 | + | ||
| 221 | + tiEnd = DjiUtilTime_GetRunTimeStamps(); | ||
| 222 | + | ||
| 223 | + USER_LOG_DEBUG("JPG Create TempFile, RealTime = %ld us\n", tiEnd.realUsec - tiStart.realUsec); | ||
| 224 | + | ||
| 225 | + if (cmdRet != 0) { | ||
| 226 | + USER_LOG_ERROR("JPG ffmpeg cmd call error, ret = %d\n", cmdRet); | ||
| 227 | + psdkStat = DJI_ERROR_SYSTEM_MODULE_CODE_SYSTEM_ERROR; | ||
| 228 | + goto err_system_cmd; | ||
| 229 | + } | ||
| 230 | + | ||
| 231 | + //open temp file | ||
| 232 | + mp4TempPicFile->tempFile = fopen(mp4TempPicFile->tempfilePath, "rb+"); | ||
| 233 | + if (mp4TempPicFile->tempFile == NULL) { | ||
| 234 | + psdkStat = DJI_ERROR_SYSTEM_MODULE_CODE_SYSTEM_ERROR; | ||
| 235 | + goto err_file_open; | ||
| 236 | + } | ||
| 237 | + | ||
| 238 | + //unlink temp file | ||
| 239 | + unlink(mp4TempPicFile->tempfilePath); | ||
| 240 | + | ||
| 241 | + return DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS; | ||
| 242 | + | ||
| 243 | +err_file_open: | ||
| 244 | + unlink(mp4TempPicFile->tempfilePath); | ||
| 245 | +err_system_cmd: | ||
| 246 | +err_create_temp: | ||
| 247 | + osalHandler->Free(*pTempPicPrivHandle); | ||
| 248 | + | ||
| 249 | + return psdkStat; | ||
| 250 | +} | ||
| 251 | + | ||
| 252 | +static T_DjiReturnCode DjiMediaFile_DestroyTempPicPriv_MP4(T_DjiMP4TempPicPriv *tempPicPrivHandle) | ||
| 253 | +{ | ||
| 254 | + T_DjiOsalHandler *osalHandler = DjiPlatform_GetOsalHandler(); | ||
| 255 | + | ||
| 256 | + fclose(tempPicPrivHandle->tempFile); | ||
| 257 | + osalHandler->Free(tempPicPrivHandle); | ||
| 258 | + | ||
| 259 | + return DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS; | ||
| 260 | +} | ||
| 261 | + | ||
| 262 | +/****************** (C) COPYRIGHT DJI Innovations *****END OF FILE****/ |
| 1 | +/** | ||
| 2 | + ******************************************************************** | ||
| 3 | + * @file dji_media_file_mp4.h | ||
| 4 | + * @brief This is the header file for "dji_media_file_mp4.c", defining the structure and | ||
| 5 | + * (exported) function prototypes. | ||
| 6 | + * | ||
| 7 | + * @copyright (c) 2021 DJI. All rights reserved. | ||
| 8 | + * | ||
| 9 | + * All information contained herein is, and remains, the property of DJI. | ||
| 10 | + * The intellectual and technical concepts contained herein are proprietary | ||
| 11 | + * to DJI and may be covered by U.S. and foreign patents, patents in process, | ||
| 12 | + * and protected by trade secret or copyright law. Dissemination of this | ||
| 13 | + * information, including but not limited to data and other proprietary | ||
| 14 | + * material(s) incorporated within the information, in any form, is strictly | ||
| 15 | + * prohibited without the express written consent of DJI. | ||
| 16 | + * | ||
| 17 | + * If you receive this source code without DJI’s authorization, you may not | ||
| 18 | + * further disseminate the information, and you must immediately remove the | ||
| 19 | + * source code and notify DJI of its removal. DJI reserves the right to pursue | ||
| 20 | + * legal actions against you for any loss(es) or damage(s) caused by your | ||
| 21 | + * failure to do so. | ||
| 22 | + * | ||
| 23 | + ********************************************************************* | ||
| 24 | + */ | ||
| 25 | + | ||
| 26 | +/* Define to prevent recursive inclusion -------------------------------------*/ | ||
| 27 | +#ifndef PSDK_MEDIA_FILE_MP4_H | ||
| 28 | +#define PSDK_MEDIA_FILE_MP4_H | ||
| 29 | + | ||
| 30 | +#ifdef __cplusplus | ||
| 31 | +extern "C" { | ||
| 32 | +#endif | ||
| 33 | + | ||
| 34 | +/* Includes ------------------------------------------------------------------*/ | ||
| 35 | +#include <dji_payload_camera.h> | ||
| 36 | +#include <dji_typedef.h> | ||
| 37 | +#include "dji_media_file_core.h" | ||
| 38 | + | ||
| 39 | +/* Exported constants --------------------------------------------------------*/ | ||
| 40 | + | ||
| 41 | + | ||
| 42 | +/* Exported types ------------------------------------------------------------*/ | ||
| 43 | + | ||
| 44 | + | ||
| 45 | +/* Exported functions --------------------------------------------------------*/ | ||
| 46 | +bool DjiMediaFile_IsSupported_MP4(const char *filePath); | ||
| 47 | + | ||
| 48 | +T_DjiReturnCode DjiMediaFile_GetAttrFunc_MP4(struct _DjiMediaFile *mediaFileHandle, | ||
| 49 | + T_DjiCameraMediaFileAttr *mediaFileAttr); | ||
| 50 | + | ||
| 51 | +T_DjiReturnCode DjiMediaFile_GetDataOrigin_MP4(struct _DjiMediaFile *mediaFileHandle, uint32_t offset, uint16_t len, | ||
| 52 | + uint8_t *data, uint32_t *realLen); | ||
| 53 | +T_DjiReturnCode DjiMediaFile_GetFileSizeOrigin_MP4(struct _DjiMediaFile *mediaFileHandle, uint32_t *fileSize); | ||
| 54 | + | ||
| 55 | +T_DjiReturnCode DjiMediaFile_CreateThumbNail_MP4(struct _DjiMediaFile *mediaFileHandle); | ||
| 56 | +T_DjiReturnCode DjiMediaFile_GetFileSizeThumbNail_MP4(struct _DjiMediaFile *mediaFileHandle, uint32_t *fileSize); | ||
| 57 | +T_DjiReturnCode | ||
| 58 | +DjiMediaFile_GetDataThumbNail_MP4(struct _DjiMediaFile *mediaFileHandle, uint32_t offset, uint16_t len, | ||
| 59 | + uint8_t *data, uint16_t *realLen); | ||
| 60 | +T_DjiReturnCode DjiMediaFile_DestroyThumbNail_MP4(struct _DjiMediaFile *MediaFileHandle); | ||
| 61 | + | ||
| 62 | +T_DjiReturnCode DjiMediaFile_CreateScreenNail_MP4(struct _DjiMediaFile *mediaFileHandle); | ||
| 63 | +T_DjiReturnCode DjiMediaFile_GetFileSizeScreenNail_MP4(struct _DjiMediaFile *mediaFileHandle, uint32_t *fileSize); | ||
| 64 | +T_DjiReturnCode | ||
| 65 | +DjiMediaFile_GetDataScreenNail_MP4(struct _DjiMediaFile *mediaFileHandle, uint32_t offset, uint16_t len, | ||
| 66 | + uint8_t *data, uint16_t *realLen); | ||
| 67 | +T_DjiReturnCode DjiMediaFile_DestroyScreenNail_MP4(struct _DjiMediaFile *mediaFileHandle); | ||
| 68 | + | ||
| 69 | +#ifdef __cplusplus | ||
| 70 | +} | ||
| 71 | +#endif | ||
| 72 | + | ||
| 73 | +#endif // PSDK_MEDIA_FILE_MP4_H | ||
| 74 | + | ||
| 75 | +/************************ (C) COPYRIGHT DJI Innovations *******END OF FILE******/ |
project_build/DJI_大疆PSDK/samples/sample_c/module_sample/camera_emu/media_file/PSDK_0001_ORG.jpg
0 → 100644
2.1 MB
project_build/DJI_大疆PSDK/samples/sample_c/module_sample/camera_emu/media_file/PSDK_0002_ORG.jpg
0 → 100644
2.4 MB
project_build/DJI_大疆PSDK/samples/sample_c/module_sample/camera_emu/media_file/PSDK_0003_ORG.jpg
0 → 100644
1.0 MB
project_build/DJI_大疆PSDK/samples/sample_c/module_sample/camera_emu/media_file/PSDK_0004_ORG.mp4
0 → 100644
不能预览此文件类型
project_build/DJI_大疆PSDK/samples/sample_c/module_sample/camera_emu/media_file/PSDK_0005.h264
0 → 100644
不能预览此文件类型
project_build/DJI_大疆PSDK/samples/sample_c/module_sample/camera_emu/test_payload_cam_emu_base.c
0 → 100644
| 1 | +/** | ||
| 2 | + ******************************************************************** | ||
| 3 | + * @file test_payload_cam_emu_common.c | ||
| 4 | + * @brief | ||
| 5 | + * | ||
| 6 | + * @copyright (c) 2021 DJI. All rights reserved. | ||
| 7 | + * | ||
| 8 | + * All information contained herein is, and remains, the property of DJI. | ||
| 9 | + * The intellectual and technical concepts contained herein are proprietary | ||
| 10 | + * to DJI and may be covered by U.S. and foreign patents, patents in process, | ||
| 11 | + * and protected by trade secret or copyright law. Dissemination of this | ||
| 12 | + * information, including but not limited to data and other proprietary | ||
| 13 | + * material(s) incorporated within the information, in any form, is strictly | ||
| 14 | + * prohibited without the express written consent of DJI. | ||
| 15 | + * | ||
| 16 | + * If you receive this source code without DJI’s authorization, you may not | ||
| 17 | + * further disseminate the information, and you must immediately remove the | ||
| 18 | + * source code and notify DJI of its removal. DJI reserves the right to pursue | ||
| 19 | + * legal actions against you for any loss(es) or damage(s) caused by your | ||
| 20 | + * failure to do so. | ||
| 21 | + * | ||
| 22 | + ********************************************************************* | ||
| 23 | + */ | ||
| 24 | + | ||
| 25 | +/* Includes ------------------------------------------------------------------*/ | ||
| 26 | +#include "math.h" | ||
| 27 | +#include "test_payload_cam_emu_base.h" | ||
| 28 | +#include "utils/util_misc.h" | ||
| 29 | +#include "dji_logger.h" | ||
| 30 | +#include "dji_platform.h" | ||
| 31 | +#include "dji_payload_camera.h" | ||
| 32 | +#include "dji_aircraft_info.h" | ||
| 33 | +#include "dji_gimbal.h" | ||
| 34 | +#include "dji_xport.h" | ||
| 35 | +#include "gimbal_emu/test_payload_gimbal_emu.h" | ||
| 36 | + | ||
| 37 | +#include "Psdk_UI_io.h" | ||
| 38 | + | ||
| 39 | + | ||
| 40 | +/* Private constants ---------------------------------------------------------*/ | ||
| 41 | +#define PAYLOAD_CAMERA_EMU_TASK_FREQ (100) | ||
| 42 | +#define PAYLOAD_CAMERA_EMU_TASK_STACK_SIZE (2048) | ||
| 43 | +#define SDCARD_TOTAL_SPACE_IN_MB (32 * 1024) | ||
| 44 | +#define SDCARD_PER_PHOTO_SPACE_IN_MB (4) | ||
| 45 | +#define SDCARD_PER_SECONDS_RECORD_SPACE_IN_MB (2) | ||
| 46 | +#define ZOOM_OPTICAL_FOCAL_MAX_LENGTH (300) | ||
| 47 | +#define ZOOM_OPTICAL_FOCAL_MIN_LENGTH (10) | ||
| 48 | +#define ZOOM_OPTICAL_FOCAL_LENGTH_STEP (10) | ||
| 49 | +#define ZOOM_OPTICAL_FOCAL_LENGTH_CTRL_STEP (5) | ||
| 50 | +#define ZOOM_DIGITAL_BASE_FACTOR (1.0) | ||
| 51 | +#define ZOOM_DIGITAL_STEP_FACTOR (0.1) | ||
| 52 | +#define ZOOM_DIGITAL_MAX_FACTOR (6.0) | ||
| 53 | +#define FOCUS_MAX_RINGVALUE (1000) | ||
| 54 | +#define FOCUS_MID_RINGVALUE (500) | ||
| 55 | +#define IMAGE_SENSOR_X_SIZE (88.0f) // unit: 0.1mm | ||
| 56 | +#define IMAGE_SENSOR_Y_SIZE (66.0f) // unit: 0.1mm | ||
| 57 | +#define CENTER_POINT_IN_SCREEN_X_VALUE (0.5f) | ||
| 58 | +#define CENTER_POINT_IN_SCREEN_Y_VALUE (0.5f) | ||
| 59 | +#define TAP_ZOOM_DURATION (2000) // unit: ms | ||
| 60 | +#define INTERVAL_PHOTOGRAPH_ALWAYS_COUNT (255) | ||
| 61 | +#define INTERVAL_PHOTOGRAPH_INTERVAL_INIT_VALUE (1) // unit: s | ||
| 62 | +#define TAKING_PHOTO_SPENT_TIME_MS_EMU (500) | ||
| 63 | +#define PHOTO_FILE_PATH "../../../../../api_sample/camera_media_emu/media_file/DJI_0001_ORG.jpg" | ||
| 64 | + | ||
| 65 | +// Attention: you can select which camera function you want to run, default: all on. | ||
| 66 | +#define USER_CAMERA_EMU_METERING_ON 1 | ||
| 67 | +#define USER_CAMERA_EMU_FOCUS_ON 1 | ||
| 68 | +#define USER_CAMERA_EMU_HYBRID_ZOOM_ON 1 | ||
| 69 | +#define USER_CAMERA_EMU_TAP_ZOOM_ON 1 | ||
| 70 | + | ||
| 71 | +/* Private types -------------------------------------------------------------*/ | ||
| 72 | +typedef struct { | ||
| 73 | + E_DjiGimbalRotationMode rotationMode; | ||
| 74 | + T_DjiGimbalRotationProperty rotationProperty; | ||
| 75 | + T_DjiAttitude3d rotationValue; | ||
| 76 | +} T_TestCameraGimbalRotationArgument; | ||
| 77 | + | ||
| 78 | +/* Private variables ---------------------------------------------------------*/ | ||
| 79 | +static bool s_isCamInited = false; | ||
| 80 | + | ||
| 81 | +static T_DjiCameraCommonHandler s_commonHandler; | ||
| 82 | +static T_DjiCameraExposureMeteringHandler s_exposureMeteringHandler; | ||
| 83 | +static T_DjiCameraFocusHandler s_focusHandler; | ||
| 84 | +static T_DjiCameraDigitalZoomHandler s_digitalZoomHandler; | ||
| 85 | +static T_DjiCameraOpticalZoomHandler s_opticalZoomHandler; | ||
| 86 | +static T_DjiCameraTapZoomHandler s_tapZoomHandler; | ||
| 87 | + | ||
| 88 | +static T_DjiTaskHandle s_userCameraThread; | ||
| 89 | + | ||
| 90 | +static T_DjiCameraSystemState s_cameraState = {0}; | ||
| 91 | +static E_DjiCameraShootPhotoMode s_cameraShootPhotoMode = DJI_CAMERA_SHOOT_PHOTO_MODE_SINGLE; | ||
| 92 | +static E_DjiCameraBurstCount s_cameraBurstCount = DJI_CAMERA_BURST_COUNT_2; | ||
| 93 | +static T_DjiCameraPhotoTimeIntervalSettings s_cameraPhotoTimeIntervalSettings = {INTERVAL_PHOTOGRAPH_ALWAYS_COUNT, | ||
| 94 | + INTERVAL_PHOTOGRAPH_INTERVAL_INIT_VALUE}; | ||
| 95 | +static T_DjiCameraSDCardState s_cameraSDCardState = {0}; | ||
| 96 | +static T_DjiMutexHandle s_commonMutex = {0}; | ||
| 97 | + | ||
| 98 | +static E_DjiCameraMeteringMode s_cameraMeteringMode = DJI_CAMERA_METERING_MODE_CENTER; | ||
| 99 | +static T_DjiCameraSpotMeteringTarget s_cameraSpotMeteringTarget = {0}; | ||
| 100 | + | ||
| 101 | +static E_DjiCameraFocusMode s_cameraFocusMode = DJI_CAMERA_FOCUS_MODE_AUTO; | ||
| 102 | +static T_DjiCameraPointInScreen s_cameraFocusTarget = {0}; | ||
| 103 | +static uint32_t s_cameraFocusRingValue = FOCUS_MID_RINGVALUE; | ||
| 104 | +static T_DjiCameraFocusAssistantSettings s_cameraFocusAssistantSettings = {0}; | ||
| 105 | + | ||
| 106 | +static E_DjiCameraZoomDirection s_cameraZoomDirection = DJI_CAMERA_ZOOM_DIRECTION_OUT; | ||
| 107 | +static E_DjiCameraZoomSpeed s_cameraZoomSpeed = DJI_CAMERA_ZOOM_SPEED_NORMAL; | ||
| 108 | +static uint32_t s_cameraOpticalZoomFocalLength = ZOOM_OPTICAL_FOCAL_MIN_LENGTH; | ||
| 109 | +static dji_f32_t s_cameraDigitalZoomFactor = ZOOM_DIGITAL_BASE_FACTOR; | ||
| 110 | +static bool s_isStartContinuousOpticalZoom = false; | ||
| 111 | +static bool s_isOpticalZoomReachLimit = false; | ||
| 112 | +static T_DjiMutexHandle s_zoomMutex = {0}; | ||
| 113 | + | ||
| 114 | +static bool s_isTapZoomEnabled = false; | ||
| 115 | +static T_DjiCameraTapZoomState s_cameraTapZoomState = {0}; | ||
| 116 | +static uint8_t s_tapZoomMultiplier = 1; | ||
| 117 | +static uint32_t s_tapZoomStartTime = 0; | ||
| 118 | +static bool s_isStartTapZoom = false; | ||
| 119 | +static bool s_isTapZooming = false; | ||
| 120 | +static T_TestCameraGimbalRotationArgument s_tapZoomNewestGimbalRotationArgument = {0}; | ||
| 121 | +static uint32_t s_tapZoomNewestTargetHybridFocalLength = 0; // unit: 0.1mm | ||
| 122 | +static T_DjiMutexHandle s_tapZoomMutex = NULL; | ||
| 123 | +static E_DjiCameraVideoStreamType s_cameraVideoStreamType; | ||
| 124 | + | ||
| 125 | +/* Private functions declaration ---------------------------------------------*/ | ||
| 126 | +static T_DjiReturnCode GetSystemState(T_DjiCameraSystemState *systemState); | ||
| 127 | +static T_DjiReturnCode SetMode(E_DjiCameraMode mode); | ||
| 128 | +static T_DjiReturnCode StartRecordVideo(void); | ||
| 129 | +static T_DjiReturnCode StopRecordVideo(void); | ||
| 130 | +static T_DjiReturnCode StartShootPhoto(void); | ||
| 131 | +static T_DjiReturnCode StopShootPhoto(void); | ||
| 132 | +static T_DjiReturnCode SetShootPhotoMode(E_DjiCameraShootPhotoMode mode); | ||
| 133 | +static T_DjiReturnCode GetShootPhotoMode(E_DjiCameraShootPhotoMode *mode); | ||
| 134 | +static T_DjiReturnCode SetPhotoBurstCount(E_DjiCameraBurstCount burstCount); | ||
| 135 | +static T_DjiReturnCode GetPhotoBurstCount(E_DjiCameraBurstCount *burstCount); | ||
| 136 | +static T_DjiReturnCode SetPhotoTimeIntervalSettings(T_DjiCameraPhotoTimeIntervalSettings settings); | ||
| 137 | +static T_DjiReturnCode GetPhotoTimeIntervalSettings(T_DjiCameraPhotoTimeIntervalSettings *settings); | ||
| 138 | +static T_DjiReturnCode GetSDCardState(T_DjiCameraSDCardState *sdCardState); | ||
| 139 | +static T_DjiReturnCode FormatSDCard(void); | ||
| 140 | + | ||
| 141 | +static T_DjiReturnCode SetMeteringMode(E_DjiCameraMeteringMode mode); | ||
| 142 | +static T_DjiReturnCode GetMeteringMode(E_DjiCameraMeteringMode *mode); | ||
| 143 | +static T_DjiReturnCode SetSpotMeteringTarget(T_DjiCameraSpotMeteringTarget target); | ||
| 144 | +static T_DjiReturnCode GetSpotMeteringTarget(T_DjiCameraSpotMeteringTarget *target); | ||
| 145 | + | ||
| 146 | +static T_DjiReturnCode SetFocusMode(E_DjiCameraFocusMode mode); | ||
| 147 | +static T_DjiReturnCode GetFocusMode(E_DjiCameraFocusMode *mode); | ||
| 148 | +static T_DjiReturnCode SetFocusTarget(T_DjiCameraPointInScreen target); | ||
| 149 | +static T_DjiReturnCode GetFocusTarget(T_DjiCameraPointInScreen *target); | ||
| 150 | +static T_DjiReturnCode SetFocusAssistantSettings(T_DjiCameraFocusAssistantSettings settings); | ||
| 151 | +static T_DjiReturnCode GetFocusAssistantSettings(T_DjiCameraFocusAssistantSettings *settings); | ||
| 152 | +static T_DjiReturnCode SetFocusRingValue(uint32_t value); | ||
| 153 | +static T_DjiReturnCode GetFocusRingValue(uint32_t *value); | ||
| 154 | +static T_DjiReturnCode GetFocusRingValueUpperBound(uint32_t *value); | ||
| 155 | + | ||
| 156 | +static T_DjiReturnCode SetDigitalZoomFactor(dji_f32_t factor); | ||
| 157 | +static T_DjiReturnCode SetOpticalZoomFocalLength(uint32_t focalLength); | ||
| 158 | +static T_DjiReturnCode GetOpticalZoomFocalLength(uint32_t *focalLength); | ||
| 159 | +static T_DjiReturnCode GetOpticalZoomSpec(T_DjiCameraOpticalZoomSpec *spec); | ||
| 160 | +static T_DjiReturnCode StartContinuousOpticalZoom(E_DjiCameraZoomDirection direction, E_DjiCameraZoomSpeed speed); | ||
| 161 | +static T_DjiReturnCode StopContinuousOpticalZoom(void); | ||
| 162 | +static T_DjiReturnCode GetTapZoomState(T_DjiCameraTapZoomState *state); | ||
| 163 | +static T_DjiReturnCode SetTapZoomEnabled(bool enabledFlag); | ||
| 164 | +static T_DjiReturnCode GetTapZoomEnabled(bool *enabledFlag); | ||
| 165 | +static T_DjiReturnCode SetTapZoomMultiplier(uint8_t multiplier); | ||
| 166 | +static T_DjiReturnCode GetTapZoomMultiplier(uint8_t *multiplier); | ||
| 167 | +static T_DjiReturnCode TapZoomAtTarget(T_DjiCameraPointInScreen target); | ||
| 168 | +static T_DjiReturnCode DjiTest_CameraHybridZoom(uint32_t focalLength); | ||
| 169 | +static T_DjiReturnCode DjiTest_CameraRotationGimbal(T_TestCameraGimbalRotationArgument gimbalRotationArgument); | ||
| 170 | + | ||
| 171 | +static void *UserCamera_Task(void *arg); | ||
| 172 | + | ||
| 173 | +/* Exported functions definition ---------------------------------------------*/ | ||
| 174 | + | ||
| 175 | +/* Private functions definition-----------------------------------------------*/ | ||
| 176 | +static T_DjiReturnCode GetSystemState(T_DjiCameraSystemState *systemState) | ||
| 177 | +{ | ||
| 178 | + T_DjiReturnCode returnCode; | ||
| 179 | + T_DjiOsalHandler *osalHandler = DjiPlatform_GetOsalHandler(); | ||
| 180 | + | ||
| 181 | + returnCode = osalHandler->MutexLock(s_commonMutex); | ||
| 182 | + if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) { | ||
| 183 | + USER_LOG_ERROR("lock mutex error: 0x%08llX.", returnCode); | ||
| 184 | + return returnCode; | ||
| 185 | + } | ||
| 186 | + | ||
| 187 | + *systemState = s_cameraState; | ||
| 188 | + | ||
| 189 | + returnCode = osalHandler->MutexUnlock(s_commonMutex); | ||
| 190 | + if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) { | ||
| 191 | + USER_LOG_ERROR("unlock mutex error: 0x%08llX.", returnCode); | ||
| 192 | + return returnCode; | ||
| 193 | + } | ||
| 194 | + | ||
| 195 | + return DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS; | ||
| 196 | +} | ||
| 197 | + | ||
| 198 | +//设置模式 | ||
| 199 | +static T_DjiReturnCode SetMode(E_DjiCameraMode mode) | ||
| 200 | +{ | ||
| 201 | + T_DjiReturnCode returnCode; | ||
| 202 | + T_DjiOsalHandler *osalHandler = DjiPlatform_GetOsalHandler(); | ||
| 203 | + | ||
| 204 | + returnCode = osalHandler->MutexLock(s_commonMutex); | ||
| 205 | + if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) { | ||
| 206 | + USER_LOG_ERROR("lock mutex error: 0x%08llX.", returnCode); | ||
| 207 | + return returnCode; | ||
| 208 | + } | ||
| 209 | + | ||
| 210 | + s_cameraState.cameraMode = mode; | ||
| 211 | + USER_LOG_INFO("set camera mode:%d", mode); | ||
| 212 | + | ||
| 213 | + returnCode = osalHandler->MutexUnlock(s_commonMutex); | ||
| 214 | + if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) { | ||
| 215 | + USER_LOG_ERROR("unlock mutex error: 0x%08llX.", returnCode); | ||
| 216 | + return returnCode; | ||
| 217 | + } | ||
| 218 | + | ||
| 219 | + return DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS; | ||
| 220 | +} | ||
| 221 | + | ||
| 222 | + | ||
| 223 | +// 开始录像 | ||
| 224 | +static T_DjiReturnCode StartRecordVideo(void) | ||
| 225 | +{ | ||
| 226 | + T_DjiReturnCode djiStat; | ||
| 227 | + T_DjiReturnCode returnCode = DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS; | ||
| 228 | + T_DjiOsalHandler *osalHandler = DjiPlatform_GetOsalHandler(); | ||
| 229 | + | ||
| 230 | + djiStat = osalHandler->MutexLock(s_commonMutex); | ||
| 231 | + if (djiStat != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) { | ||
| 232 | + USER_LOG_ERROR("lock mutex error: 0x%08llX.", djiStat); | ||
| 233 | + return djiStat; | ||
| 234 | + } | ||
| 235 | + | ||
| 236 | + if (s_cameraState.isRecording != false) { | ||
| 237 | + USER_LOG_ERROR("camera is already in recording state"); | ||
| 238 | + returnCode = DJI_ERROR_SYSTEM_MODULE_CODE_NONSUPPORT_IN_CURRENT_STATE; | ||
| 239 | + goto out; | ||
| 240 | + } | ||
| 241 | + | ||
| 242 | + s_cameraState.isRecording = true; | ||
| 243 | + USER_LOG_INFO("start record video"); | ||
| 244 | + //录像通知函数 | ||
| 245 | + if(JZsdk_Psdk_UI_io_VideoRecord(1) != 0) | ||
| 246 | + { | ||
| 247 | + //录像开启失败 | ||
| 248 | + s_cameraState.isRecording = false; | ||
| 249 | + } | ||
| 250 | + | ||
| 251 | +out: | ||
| 252 | + djiStat = osalHandler->MutexUnlock(s_commonMutex); | ||
| 253 | + if (djiStat != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) { | ||
| 254 | + USER_LOG_ERROR("unlock mutex error: 0x%08llX.", djiStat); | ||
| 255 | + return djiStat; | ||
| 256 | + } | ||
| 257 | + | ||
| 258 | + return returnCode; | ||
| 259 | +} | ||
| 260 | + | ||
| 261 | +//结束录像 | ||
| 262 | +static T_DjiReturnCode StopRecordVideo(void) | ||
| 263 | +{ | ||
| 264 | + T_DjiReturnCode djiStat; | ||
| 265 | + T_DjiReturnCode returnCode = DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS; | ||
| 266 | + T_DjiOsalHandler *osalHandler = DjiPlatform_GetOsalHandler(); | ||
| 267 | + | ||
| 268 | + djiStat = osalHandler->MutexLock(s_commonMutex); | ||
| 269 | + if (djiStat != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) { | ||
| 270 | + USER_LOG_ERROR("lock mutex error: 0x%08llX.", djiStat); | ||
| 271 | + return djiStat; | ||
| 272 | + } | ||
| 273 | + | ||
| 274 | + if (s_cameraState.isRecording != true) { | ||
| 275 | + USER_LOG_ERROR("camera is not in recording state"); | ||
| 276 | + returnCode = DJI_ERROR_SYSTEM_MODULE_CODE_NONSUPPORT_IN_CURRENT_STATE; | ||
| 277 | + goto out; | ||
| 278 | + } | ||
| 279 | + | ||
| 280 | + s_cameraState.isRecording = false; | ||
| 281 | + s_cameraState.isStoring = true; | ||
| 282 | + s_cameraState.currentVideoRecordingTimeInSeconds = 0; | ||
| 283 | + | ||
| 284 | + USER_LOG_INFO("stop record video"); | ||
| 285 | + //录像通知函数 | ||
| 286 | + if(JZsdk_Psdk_UI_io_VideoRecord(0) != 0) | ||
| 287 | + { | ||
| 288 | + //关闭失败 | ||
| 289 | + s_cameraState.isRecording = true; | ||
| 290 | + s_cameraState.isStoring = false; | ||
| 291 | + } | ||
| 292 | + | ||
| 293 | +out: | ||
| 294 | + djiStat = osalHandler->MutexUnlock(s_commonMutex); | ||
| 295 | + if (djiStat != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) { | ||
| 296 | + USER_LOG_ERROR("unlock mutex error: 0x%08llX.", djiStat); | ||
| 297 | + return djiStat; | ||
| 298 | + } | ||
| 299 | + | ||
| 300 | + return returnCode; | ||
| 301 | +} | ||
| 302 | + | ||
| 303 | +//拍照功能 | ||
| 304 | +static T_DjiReturnCode StartShootPhoto(void) | ||
| 305 | +{ | ||
| 306 | + T_DjiReturnCode returnCode; | ||
| 307 | + T_DjiOsalHandler *osalHandler = DjiPlatform_GetOsalHandler(); | ||
| 308 | + | ||
| 309 | + returnCode = osalHandler->MutexLock(s_commonMutex); | ||
| 310 | + if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) { | ||
| 311 | + USER_LOG_ERROR("lock mutex error: 0x%08llX.", returnCode); | ||
| 312 | + return returnCode; | ||
| 313 | + } | ||
| 314 | + | ||
| 315 | + USER_LOG_INFO("start shoot photo"); | ||
| 316 | + s_cameraState.isStoring = true; | ||
| 317 | + | ||
| 318 | + // 拍照模式的判定 | ||
| 319 | + if (s_cameraShootPhotoMode == DJI_CAMERA_SHOOT_PHOTO_MODE_SINGLE) { | ||
| 320 | + s_cameraState.shootingState = DJI_CAMERA_SHOOTING_SINGLE_PHOTO; | ||
| 321 | + // 这里接过去推流那边 以获取拍照内容 | ||
| 322 | + JZsdk_Psdk_UI_io_ShootPhoto(); | ||
| 323 | + | ||
| 324 | + } else if (s_cameraShootPhotoMode == DJI_CAMERA_SHOOT_PHOTO_MODE_BURST) { | ||
| 325 | + s_cameraState.shootingState = DJI_CAMERA_SHOOTING_BURST_PHOTO; | ||
| 326 | + //暂时不做连拍 | ||
| 327 | + //JZsdk_Psdk_UI_io_BurstShootPhoto(s_cameraBurstCount); | ||
| 328 | + | ||
| 329 | + } else if (s_cameraShootPhotoMode == DJI_CAMERA_SHOOT_PHOTO_MODE_INTERVAL) { | ||
| 330 | + s_cameraState.shootingState = DJI_CAMERA_SHOOTING_INTERVAL_PHOTO; | ||
| 331 | + s_cameraState.isShootingIntervalStart = true; | ||
| 332 | + s_cameraState.currentPhotoShootingIntervalTimeInSeconds = s_cameraPhotoTimeIntervalSettings.timeIntervalSeconds; | ||
| 333 | + } | ||
| 334 | + | ||
| 335 | + returnCode = osalHandler->MutexUnlock(s_commonMutex); | ||
| 336 | + if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) { | ||
| 337 | + USER_LOG_ERROR("unlock mutex error: 0x%08llX.", returnCode); | ||
| 338 | + return returnCode; | ||
| 339 | + } | ||
| 340 | + | ||
| 341 | + return DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS; | ||
| 342 | +} | ||
| 343 | + | ||
| 344 | +//停止拍照 | ||
| 345 | +static T_DjiReturnCode StopShootPhoto(void) | ||
| 346 | +{ | ||
| 347 | + T_DjiReturnCode returnCode; | ||
| 348 | + T_DjiOsalHandler *osalHandler = DjiPlatform_GetOsalHandler(); | ||
| 349 | + | ||
| 350 | + returnCode = osalHandler->MutexLock(s_commonMutex); | ||
| 351 | + if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) { | ||
| 352 | + USER_LOG_ERROR("lock mutex error: 0x%08llX.", returnCode); | ||
| 353 | + return returnCode; | ||
| 354 | + } | ||
| 355 | + | ||
| 356 | + USER_LOG_INFO("stop shoot photo"); | ||
| 357 | + s_cameraState.shootingState = DJI_CAMERA_SHOOTING_PHOTO_IDLE; | ||
| 358 | + | ||
| 359 | + //改成转码后再取消锁定 | ||
| 360 | + //s_cameraState.isStoring = false; | ||
| 361 | + s_cameraState.isShootingIntervalStart = false; | ||
| 362 | + | ||
| 363 | + returnCode = osalHandler->MutexUnlock(s_commonMutex); | ||
| 364 | + if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) { | ||
| 365 | + USER_LOG_ERROR("unlock mutex error: 0x%08llX.", returnCode); | ||
| 366 | + return returnCode; | ||
| 367 | + } | ||
| 368 | + | ||
| 369 | + return DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS; | ||
| 370 | +} | ||
| 371 | + | ||
| 372 | + | ||
| 373 | +//设置拍摄模式 | ||
| 374 | +static T_DjiReturnCode SetShootPhotoMode(E_DjiCameraShootPhotoMode mode) | ||
| 375 | +{ | ||
| 376 | + T_DjiReturnCode returnCode; | ||
| 377 | + T_DjiOsalHandler *osalHandler = DjiPlatform_GetOsalHandler(); | ||
| 378 | + | ||
| 379 | + returnCode = osalHandler->MutexLock(s_commonMutex); | ||
| 380 | + if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) { | ||
| 381 | + USER_LOG_ERROR("lock mutex error: 0x%08llX.", returnCode); | ||
| 382 | + return returnCode; | ||
| 383 | + } | ||
| 384 | + | ||
| 385 | + s_cameraShootPhotoMode = mode; | ||
| 386 | + USER_LOG_INFO("set shoot photo mode:%d", mode); | ||
| 387 | + | ||
| 388 | + returnCode = osalHandler->MutexUnlock(s_commonMutex); | ||
| 389 | + if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) { | ||
| 390 | + USER_LOG_ERROR("unlock mutex error: 0x%08llX.", returnCode); | ||
| 391 | + return returnCode; | ||
| 392 | + } | ||
| 393 | + | ||
| 394 | + return DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS; | ||
| 395 | +} | ||
| 396 | + | ||
| 397 | +static T_DjiReturnCode GetShootPhotoMode(E_DjiCameraShootPhotoMode *mode) | ||
| 398 | +{ | ||
| 399 | + T_DjiReturnCode returnCode; | ||
| 400 | + T_DjiOsalHandler *osalHandler = DjiPlatform_GetOsalHandler(); | ||
| 401 | + | ||
| 402 | + returnCode = osalHandler->MutexLock(s_commonMutex); | ||
| 403 | + if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) { | ||
| 404 | + USER_LOG_ERROR("lock mutex error: 0x%08llX.", returnCode); | ||
| 405 | + return returnCode; | ||
| 406 | + } | ||
| 407 | + | ||
| 408 | + *mode = s_cameraShootPhotoMode; | ||
| 409 | + | ||
| 410 | + returnCode = osalHandler->MutexUnlock(s_commonMutex); | ||
| 411 | + if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) { | ||
| 412 | + USER_LOG_ERROR("unlock mutex error: 0x%08llX.", returnCode);\ | ||
| 413 | + return returnCode; | ||
| 414 | + } | ||
| 415 | + | ||
| 416 | + return DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS; | ||
| 417 | +} | ||
| 418 | + | ||
| 419 | +//加载相机的连拍数量 | ||
| 420 | +static T_DjiReturnCode SetPhotoBurstCount(E_DjiCameraBurstCount burstCount) | ||
| 421 | +{ | ||
| 422 | + T_DjiReturnCode returnCode; | ||
| 423 | + T_DjiOsalHandler *osalHandler = DjiPlatform_GetOsalHandler(); | ||
| 424 | + | ||
| 425 | + returnCode = osalHandler->MutexLock(s_commonMutex); | ||
| 426 | + if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) { | ||
| 427 | + USER_LOG_ERROR("lock mutex error: 0x%08llX.", returnCode); | ||
| 428 | + return returnCode; | ||
| 429 | + } | ||
| 430 | + | ||
| 431 | + s_cameraBurstCount = burstCount; | ||
| 432 | + USER_LOG_INFO("set photo burst count:%d", burstCount); | ||
| 433 | + | ||
| 434 | + returnCode = osalHandler->MutexUnlock(s_commonMutex); | ||
| 435 | + if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) { | ||
| 436 | + USER_LOG_ERROR("unlock mutex error: 0x%08llX.", returnCode); | ||
| 437 | + return returnCode; | ||
| 438 | + } | ||
| 439 | + | ||
| 440 | + return DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS; | ||
| 441 | +} | ||
| 442 | + | ||
| 443 | + | ||
| 444 | +//得到相机设定的连拍数量 | ||
| 445 | +static T_DjiReturnCode GetPhotoBurstCount(E_DjiCameraBurstCount *burstCount) | ||
| 446 | +{ | ||
| 447 | + T_DjiReturnCode returnCode; | ||
| 448 | + T_DjiOsalHandler *osalHandler = DjiPlatform_GetOsalHandler(); | ||
| 449 | + | ||
| 450 | + returnCode = osalHandler->MutexLock(s_commonMutex); | ||
| 451 | + if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) { | ||
| 452 | + USER_LOG_ERROR("lock mutex error: 0x%08llX.", returnCode); | ||
| 453 | + return returnCode; | ||
| 454 | + } | ||
| 455 | + | ||
| 456 | + *burstCount = s_cameraBurstCount; | ||
| 457 | + | ||
| 458 | + returnCode = osalHandler->MutexUnlock(s_commonMutex); | ||
| 459 | + if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) { | ||
| 460 | + USER_LOG_ERROR("unlock mutex error: 0x%08llX.", returnCode); | ||
| 461 | + return returnCode; | ||
| 462 | + } | ||
| 463 | + | ||
| 464 | + return DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS; | ||
| 465 | +} | ||
| 466 | + | ||
| 467 | +//设置定时拍摄的时间 | ||
| 468 | +static T_DjiReturnCode SetPhotoTimeIntervalSettings(T_DjiCameraPhotoTimeIntervalSettings settings) | ||
| 469 | +{ | ||
| 470 | + T_DjiReturnCode returnCode; | ||
| 471 | + T_DjiOsalHandler *osalHandler = DjiPlatform_GetOsalHandler(); | ||
| 472 | + | ||
| 473 | + returnCode = osalHandler->MutexLock(s_commonMutex); | ||
| 474 | + if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) { | ||
| 475 | + USER_LOG_ERROR("lock mutex error: 0x%08llX.", returnCode); | ||
| 476 | + return returnCode; | ||
| 477 | + } | ||
| 478 | + | ||
| 479 | + s_cameraPhotoTimeIntervalSettings.captureCount = settings.captureCount; | ||
| 480 | + s_cameraPhotoTimeIntervalSettings.timeIntervalSeconds = settings.timeIntervalSeconds; | ||
| 481 | + USER_LOG_INFO("set photo interval settings count:%d seconds:%d", settings.captureCount, | ||
| 482 | + settings.timeIntervalSeconds); | ||
| 483 | + s_cameraState.currentPhotoShootingIntervalCount = settings.captureCount; | ||
| 484 | + | ||
| 485 | + returnCode = osalHandler->MutexUnlock(s_commonMutex); | ||
| 486 | + if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) { | ||
| 487 | + USER_LOG_ERROR("unlock mutex error: 0x%08llX.", returnCode); | ||
| 488 | + return returnCode; | ||
| 489 | + } | ||
| 490 | + | ||
| 491 | + return DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS; | ||
| 492 | +} | ||
| 493 | + | ||
| 494 | +//得到定时拍摄的时间 | ||
| 495 | +static T_DjiReturnCode GetPhotoTimeIntervalSettings(T_DjiCameraPhotoTimeIntervalSettings *settings) | ||
| 496 | +{ | ||
| 497 | + T_DjiReturnCode returnCode; | ||
| 498 | + T_DjiOsalHandler *osalHandler = DjiPlatform_GetOsalHandler(); | ||
| 499 | + | ||
| 500 | + returnCode = osalHandler->MutexLock(s_commonMutex); | ||
| 501 | + if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) { | ||
| 502 | + USER_LOG_ERROR("lock mutex error: 0x%08llX.", returnCode); | ||
| 503 | + return returnCode; | ||
| 504 | + } | ||
| 505 | + | ||
| 506 | + memcpy(settings, &s_cameraPhotoTimeIntervalSettings, sizeof(T_DjiCameraPhotoTimeIntervalSettings)); | ||
| 507 | + | ||
| 508 | + returnCode = osalHandler->MutexUnlock(s_commonMutex); | ||
| 509 | + if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) { | ||
| 510 | + USER_LOG_ERROR("unlock mutex error: 0x%08llX.", returnCode); | ||
| 511 | + return returnCode; | ||
| 512 | + } | ||
| 513 | + | ||
| 514 | + return DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS; | ||
| 515 | +} | ||
| 516 | + | ||
| 517 | +//得到sd佧的状态 | ||
| 518 | +static T_DjiReturnCode GetSDCardState(T_DjiCameraSDCardState *sdCardState) | ||
| 519 | +{ | ||
| 520 | + T_DjiReturnCode returnCode; | ||
| 521 | + T_DjiOsalHandler *osalHandler = DjiPlatform_GetOsalHandler(); | ||
| 522 | + | ||
| 523 | + returnCode = osalHandler->MutexLock(s_commonMutex); | ||
| 524 | + if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) { | ||
| 525 | + USER_LOG_ERROR("lock mutex error: 0x%08llX.", returnCode); | ||
| 526 | + return returnCode; | ||
| 527 | + } | ||
| 528 | + | ||
| 529 | + memcpy(sdCardState, &s_cameraSDCardState, sizeof(T_DjiCameraSDCardState)); | ||
| 530 | + | ||
| 531 | + returnCode = osalHandler->MutexUnlock(s_commonMutex); | ||
| 532 | + if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) { | ||
| 533 | + USER_LOG_ERROR("unlock mutex error: 0x%08llX.", returnCode); | ||
| 534 | + return returnCode; | ||
| 535 | + } | ||
| 536 | + | ||
| 537 | + return DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS; | ||
| 538 | +} | ||
| 539 | + | ||
| 540 | +// 格式化sd佧 | ||
| 541 | +static T_DjiReturnCode FormatSDCard(void) | ||
| 542 | +{ | ||
| 543 | + T_DjiReturnCode returnCode; | ||
| 544 | + T_DjiOsalHandler *osalHandler = DjiPlatform_GetOsalHandler(); | ||
| 545 | + | ||
| 546 | + returnCode = osalHandler->MutexLock(s_commonMutex); | ||
| 547 | + if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) { | ||
| 548 | + USER_LOG_ERROR("lock mutex error: 0x%08llX.", returnCode); | ||
| 549 | + return returnCode; | ||
| 550 | + } | ||
| 551 | + | ||
| 552 | + USER_LOG_INFO("format sdcard"); | ||
| 553 | + | ||
| 554 | + memset(&s_cameraSDCardState, 0, sizeof(T_DjiCameraSDCardState)); | ||
| 555 | + s_cameraSDCardState.isInserted = true; | ||
| 556 | + s_cameraSDCardState.isVerified = true; | ||
| 557 | + s_cameraSDCardState.totalSpaceInMB = SDCARD_TOTAL_SPACE_IN_MB; | ||
| 558 | + s_cameraSDCardState.remainSpaceInMB = SDCARD_TOTAL_SPACE_IN_MB; | ||
| 559 | + s_cameraSDCardState.availableCaptureCount = SDCARD_TOTAL_SPACE_IN_MB / SDCARD_PER_PHOTO_SPACE_IN_MB; | ||
| 560 | + s_cameraSDCardState.availableRecordingTimeInSeconds = | ||
| 561 | + SDCARD_TOTAL_SPACE_IN_MB / SDCARD_PER_SECONDS_RECORD_SPACE_IN_MB; | ||
| 562 | + | ||
| 563 | + returnCode = osalHandler->MutexUnlock(s_commonMutex); | ||
| 564 | + if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) { | ||
| 565 | + USER_LOG_ERROR("unlock mutex error: 0x%08llX.", returnCode); | ||
| 566 | + return returnCode; | ||
| 567 | + } | ||
| 568 | + | ||
| 569 | + return DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS; | ||
| 570 | +} | ||
| 571 | + | ||
| 572 | + | ||
| 573 | +//设置测量模式 | ||
| 574 | +static T_DjiReturnCode SetMeteringMode(E_DjiCameraMeteringMode mode) | ||
| 575 | +{ | ||
| 576 | + USER_LOG_INFO("set metering mode:%d", mode); | ||
| 577 | + s_cameraMeteringMode = mode; | ||
| 578 | + | ||
| 579 | + return DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS; | ||
| 580 | +} | ||
| 581 | + | ||
| 582 | +static T_DjiReturnCode GetMeteringMode(E_DjiCameraMeteringMode *mode) | ||
| 583 | +{ | ||
| 584 | + *mode = s_cameraMeteringMode; | ||
| 585 | + | ||
| 586 | + return DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS; | ||
| 587 | +} | ||
| 588 | + | ||
| 589 | +static T_DjiReturnCode SetSpotMeteringTarget(T_DjiCameraSpotMeteringTarget target) | ||
| 590 | +{ | ||
| 591 | + USER_LOG_INFO("set spot metering area col:%d row:%d", target.col, target.row); | ||
| 592 | + memcpy(&s_cameraSpotMeteringTarget, &target, sizeof(T_DjiCameraSpotMeteringTarget)); | ||
| 593 | + | ||
| 594 | + return DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS; | ||
| 595 | +} | ||
| 596 | + | ||
| 597 | +static T_DjiReturnCode GetSpotMeteringTarget(T_DjiCameraSpotMeteringTarget *target) | ||
| 598 | +{ | ||
| 599 | + memcpy(target, &s_cameraSpotMeteringTarget, sizeof(T_DjiCameraSpotMeteringTarget)); | ||
| 600 | + | ||
| 601 | + return DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS; | ||
| 602 | +} | ||
| 603 | + | ||
| 604 | +static T_DjiReturnCode SetFocusMode(E_DjiCameraFocusMode mode) | ||
| 605 | +{ | ||
| 606 | + USER_LOG_INFO("set focus mode:%d", mode); | ||
| 607 | + s_cameraFocusMode = mode; | ||
| 608 | + | ||
| 609 | + return DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS; | ||
| 610 | +} | ||
| 611 | + | ||
| 612 | +static T_DjiReturnCode GetFocusMode(E_DjiCameraFocusMode *mode) | ||
| 613 | +{ | ||
| 614 | + *mode = s_cameraFocusMode; | ||
| 615 | + | ||
| 616 | + return DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS; | ||
| 617 | +} | ||
| 618 | + | ||
| 619 | +static T_DjiReturnCode SetFocusTarget(T_DjiCameraPointInScreen target) | ||
| 620 | +{ | ||
| 621 | + USER_LOG_INFO("set focus target x:%.2f y:%.2f", target.focusX, target.focusY); | ||
| 622 | + memcpy(&s_cameraFocusTarget, &target, sizeof(T_DjiCameraPointInScreen)); | ||
| 623 | + | ||
| 624 | + int PointX = (int)(target.focusX *100); | ||
| 625 | + int PointY = (int)(target.focusY *100); | ||
| 626 | + | ||
| 627 | + //发送到对焦点 | ||
| 628 | + //USER_LOG_INFO("Px:%d Py:%d",PointX,PointY); | ||
| 629 | + JZsdK_SetFocusTarget(PointX, PointY); | ||
| 630 | + | ||
| 631 | + return DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS; | ||
| 632 | +} | ||
| 633 | + | ||
| 634 | +static T_DjiReturnCode GetFocusTarget(T_DjiCameraPointInScreen *target) | ||
| 635 | +{ | ||
| 636 | + memcpy(target, &s_cameraFocusTarget, sizeof(T_DjiCameraPointInScreen)); | ||
| 637 | + | ||
| 638 | + return DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS; | ||
| 639 | +} | ||
| 640 | + | ||
| 641 | +static T_DjiReturnCode SetFocusAssistantSettings(T_DjiCameraFocusAssistantSettings settings) | ||
| 642 | +{ | ||
| 643 | + USER_LOG_INFO("set focus assistant setting MF:%d AF:%d", settings.isEnabledMF, settings.isEnabledAF); | ||
| 644 | + memcpy(&s_cameraFocusAssistantSettings, &settings, sizeof(T_DjiCameraFocusAssistantSettings)); | ||
| 645 | + | ||
| 646 | + return DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS; | ||
| 647 | +} | ||
| 648 | + | ||
| 649 | +static T_DjiReturnCode GetFocusAssistantSettings(T_DjiCameraFocusAssistantSettings *settings) | ||
| 650 | +{ | ||
| 651 | + memcpy(settings, &s_cameraFocusAssistantSettings, sizeof(T_DjiCameraFocusAssistantSettings)); | ||
| 652 | + | ||
| 653 | + return DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS; | ||
| 654 | +} | ||
| 655 | + | ||
| 656 | +static T_DjiReturnCode SetFocusRingValue(uint32_t value) | ||
| 657 | +{ | ||
| 658 | + USER_LOG_INFO("set focus ring value:%d", value); | ||
| 659 | + s_cameraFocusRingValue = value; | ||
| 660 | + | ||
| 661 | + return DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS; | ||
| 662 | +} | ||
| 663 | + | ||
| 664 | +static T_DjiReturnCode GetFocusRingValue(uint32_t *value) | ||
| 665 | +{ | ||
| 666 | + *value = s_cameraFocusRingValue; | ||
| 667 | + | ||
| 668 | + return DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS; | ||
| 669 | +} | ||
| 670 | + | ||
| 671 | +static T_DjiReturnCode GetFocusRingValueUpperBound(uint32_t *value) | ||
| 672 | +{ | ||
| 673 | + *value = FOCUS_MAX_RINGVALUE; | ||
| 674 | + | ||
| 675 | + return DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS; | ||
| 676 | +} | ||
| 677 | + | ||
| 678 | +static T_DjiReturnCode SetDigitalZoomFactor(dji_f32_t factor) | ||
| 679 | +{ | ||
| 680 | + T_DjiReturnCode returnCode; | ||
| 681 | + T_DjiOsalHandler *osalHandler = DjiPlatform_GetOsalHandler(); | ||
| 682 | + | ||
| 683 | + returnCode = osalHandler->MutexLock(s_zoomMutex); | ||
| 684 | + if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) { | ||
| 685 | + USER_LOG_ERROR("lock mutex error: 0x%08llX.", returnCode); | ||
| 686 | + return returnCode; | ||
| 687 | + } | ||
| 688 | + | ||
| 689 | + USER_LOG_INFO("set digital zoom factor:%.2f", factor); | ||
| 690 | + s_cameraDigitalZoomFactor = factor; | ||
| 691 | + | ||
| 692 | + returnCode = osalHandler->MutexUnlock(s_zoomMutex); | ||
| 693 | + if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) { | ||
| 694 | + USER_LOG_ERROR("unlock mutex error: 0x%08llX.", returnCode); | ||
| 695 | + return returnCode; | ||
| 696 | + } | ||
| 697 | + | ||
| 698 | + return DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS; | ||
| 699 | +} | ||
| 700 | + | ||
| 701 | +static T_DjiReturnCode SetOpticalZoomFocalLength(uint32_t focalLength) | ||
| 702 | +{ | ||
| 703 | + T_DjiReturnCode returnCode; | ||
| 704 | + T_DjiOsalHandler *osalHandler = DjiPlatform_GetOsalHandler(); | ||
| 705 | + | ||
| 706 | + returnCode = osalHandler->MutexLock(s_zoomMutex); | ||
| 707 | + if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) { | ||
| 708 | + USER_LOG_ERROR("lock mutex error: 0x%08llX.", returnCode); | ||
| 709 | + return returnCode; | ||
| 710 | + } | ||
| 711 | + | ||
| 712 | + USER_LOG_INFO("set optical zoom focal length:%d", focalLength); | ||
| 713 | + s_isOpticalZoomReachLimit = false; | ||
| 714 | + s_cameraDigitalZoomFactor = ZOOM_DIGITAL_BASE_FACTOR; | ||
| 715 | + s_cameraOpticalZoomFocalLength = ZOOM_OPTICAL_FOCAL_MIN_LENGTH; | ||
| 716 | + | ||
| 717 | + returnCode = osalHandler->MutexUnlock(s_zoomMutex); | ||
| 718 | + if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) { | ||
| 719 | + USER_LOG_ERROR("unlock mutex error: 0x%08llX.", returnCode); | ||
| 720 | + return returnCode; | ||
| 721 | + } | ||
| 722 | + | ||
| 723 | + return DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS; | ||
| 724 | +} | ||
| 725 | + | ||
| 726 | +static T_DjiReturnCode GetOpticalZoomFocalLength(uint32_t *focalLength) | ||
| 727 | +{ | ||
| 728 | + T_DjiReturnCode returnCode; | ||
| 729 | + T_DjiOsalHandler *osalHandler = DjiPlatform_GetOsalHandler(); | ||
| 730 | + | ||
| 731 | + returnCode = osalHandler->MutexLock(s_zoomMutex); | ||
| 732 | + if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) { | ||
| 733 | + USER_LOG_ERROR("lock mutex error: 0x%08llX.", returnCode); | ||
| 734 | + return returnCode; | ||
| 735 | + } | ||
| 736 | + | ||
| 737 | + *focalLength = s_cameraOpticalZoomFocalLength; | ||
| 738 | + | ||
| 739 | + returnCode = osalHandler->MutexUnlock(s_zoomMutex); | ||
| 740 | + if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) { | ||
| 741 | + USER_LOG_ERROR("unlock mutex error: 0x%08llX.", returnCode); | ||
| 742 | + return returnCode; | ||
| 743 | + } | ||
| 744 | + | ||
| 745 | + return DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS; | ||
| 746 | +} | ||
| 747 | + | ||
| 748 | +static T_DjiReturnCode GetOpticalZoomSpec(T_DjiCameraOpticalZoomSpec *spec) | ||
| 749 | +{ | ||
| 750 | + spec->maxFocalLength = ZOOM_OPTICAL_FOCAL_MAX_LENGTH; | ||
| 751 | + spec->minFocalLength = ZOOM_OPTICAL_FOCAL_MIN_LENGTH; | ||
| 752 | + spec->focalLengthStep = ZOOM_OPTICAL_FOCAL_LENGTH_STEP; | ||
| 753 | + | ||
| 754 | + return DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS; | ||
| 755 | +} | ||
| 756 | + | ||
| 757 | +static T_DjiReturnCode StartContinuousOpticalZoom(E_DjiCameraZoomDirection direction, E_DjiCameraZoomSpeed speed) | ||
| 758 | +{ | ||
| 759 | + T_DjiReturnCode returnCode; | ||
| 760 | + T_DjiOsalHandler *osalHandler = DjiPlatform_GetOsalHandler(); | ||
| 761 | + | ||
| 762 | + returnCode = osalHandler->MutexLock(s_zoomMutex); | ||
| 763 | + if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) { | ||
| 764 | + USER_LOG_ERROR("lock mutex error: 0x%08llX.", returnCode); | ||
| 765 | + return returnCode; | ||
| 766 | + } | ||
| 767 | + | ||
| 768 | + USER_LOG_INFO("start continuous optical zoom direction:%d speed:%d", direction, speed); | ||
| 769 | + s_isStartContinuousOpticalZoom = true; | ||
| 770 | + s_cameraZoomDirection = direction; | ||
| 771 | + s_cameraZoomSpeed = speed; | ||
| 772 | + | ||
| 773 | + returnCode = osalHandler->MutexUnlock(s_zoomMutex); | ||
| 774 | + if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) { | ||
| 775 | + USER_LOG_ERROR("unlock mutex error: 0x%08llX.", returnCode); | ||
| 776 | + return returnCode; | ||
| 777 | + } | ||
| 778 | + | ||
| 779 | + return DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS; | ||
| 780 | +} | ||
| 781 | + | ||
| 782 | +static T_DjiReturnCode StopContinuousOpticalZoom(void) | ||
| 783 | +{ | ||
| 784 | + T_DjiReturnCode returnCode; | ||
| 785 | + T_DjiOsalHandler *osalHandler = DjiPlatform_GetOsalHandler(); | ||
| 786 | + | ||
| 787 | + returnCode = osalHandler->MutexLock(s_zoomMutex); | ||
| 788 | + if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) { | ||
| 789 | + USER_LOG_ERROR("lock mutex error: 0x%08llX.", returnCode); | ||
| 790 | + return returnCode; | ||
| 791 | + } | ||
| 792 | + | ||
| 793 | + USER_LOG_INFO("stop continuous optical zoom"); | ||
| 794 | + s_isStartContinuousOpticalZoom = false; | ||
| 795 | + s_cameraZoomDirection = DJI_CAMERA_ZOOM_DIRECTION_OUT; | ||
| 796 | + s_cameraZoomSpeed = DJI_CAMERA_ZOOM_SPEED_NORMAL; | ||
| 797 | + | ||
| 798 | + returnCode = osalHandler->MutexUnlock(s_zoomMutex); | ||
| 799 | + if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) { | ||
| 800 | + USER_LOG_ERROR("unlock mutex error: 0x%08llX.", returnCode); | ||
| 801 | + return returnCode; | ||
| 802 | + } | ||
| 803 | + | ||
| 804 | + return DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS; | ||
| 805 | +} | ||
| 806 | + | ||
| 807 | +static T_DjiReturnCode GetTapZoomState(T_DjiCameraTapZoomState *state) | ||
| 808 | +{ | ||
| 809 | + T_DjiReturnCode returnCode; | ||
| 810 | + T_DjiOsalHandler *osalHandler = DjiPlatform_GetOsalHandler(); | ||
| 811 | + | ||
| 812 | + returnCode = osalHandler->MutexLock(s_tapZoomMutex); | ||
| 813 | + if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) { | ||
| 814 | + USER_LOG_ERROR("lock mutex error: 0x%08llX.", returnCode); | ||
| 815 | + return returnCode; | ||
| 816 | + } | ||
| 817 | + | ||
| 818 | + memcpy(state, &s_cameraTapZoomState, sizeof(T_DjiCameraTapZoomState)); | ||
| 819 | + | ||
| 820 | + returnCode = osalHandler->MutexUnlock(s_tapZoomMutex); | ||
| 821 | + if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) { | ||
| 822 | + USER_LOG_ERROR("unlock mutex error: 0x%08llX.", returnCode); | ||
| 823 | + return returnCode; | ||
| 824 | + } | ||
| 825 | + | ||
| 826 | + return DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS; | ||
| 827 | +} | ||
| 828 | + | ||
| 829 | +static T_DjiReturnCode SetTapZoomEnabled(bool enabledFlag) | ||
| 830 | +{ | ||
| 831 | + USER_LOG_INFO("set tap zoom enabled flag: %d.", enabledFlag); | ||
| 832 | + s_isTapZoomEnabled = enabledFlag; | ||
| 833 | + | ||
| 834 | + return DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS; | ||
| 835 | +} | ||
| 836 | + | ||
| 837 | +static T_DjiReturnCode GetTapZoomEnabled(bool *enabledFlag) | ||
| 838 | +{ | ||
| 839 | + *enabledFlag = s_isTapZoomEnabled; | ||
| 840 | + | ||
| 841 | + return DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS; | ||
| 842 | +} | ||
| 843 | + | ||
| 844 | +static T_DjiReturnCode SetTapZoomMultiplier(uint8_t multiplier) | ||
| 845 | +{ | ||
| 846 | + USER_LOG_INFO("set tap zoom multiplier: %d.", multiplier); | ||
| 847 | + s_tapZoomMultiplier = multiplier; | ||
| 848 | + | ||
| 849 | + return DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS; | ||
| 850 | +} | ||
| 851 | + | ||
| 852 | +static T_DjiReturnCode GetTapZoomMultiplier(uint8_t *multiplier) | ||
| 853 | +{ | ||
| 854 | + *multiplier = s_tapZoomMultiplier; | ||
| 855 | + | ||
| 856 | + return DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS; | ||
| 857 | +} | ||
| 858 | + | ||
| 859 | +static T_DjiReturnCode TapZoomAtTarget(T_DjiCameraPointInScreen target) | ||
| 860 | +{ | ||
| 861 | + T_DjiReturnCode returnCode; | ||
| 862 | + E_DjiGimbalRotationMode rotationMode; | ||
| 863 | + T_DjiGimbalRotationProperty rotationProperty = {0}; | ||
| 864 | + T_DjiAttitude3d rotationValue = {0}; | ||
| 865 | + float hybridFocalLength = 0; // unit: 0.1mm | ||
| 866 | + T_DjiOsalHandler *osalHandler = DjiPlatform_GetOsalHandler(); | ||
| 867 | + | ||
| 868 | + USER_LOG_INFO("tap zoom at target: x %f, y %f.", target.focusX, target.focusY); | ||
| 869 | + | ||
| 870 | + if (s_isTapZoomEnabled != true) { | ||
| 871 | + USER_LOG_WARN("tap zoom is not enabled."); | ||
| 872 | + return DJI_ERROR_SYSTEM_MODULE_CODE_SYSTEM_ERROR; | ||
| 873 | + } | ||
| 874 | + | ||
| 875 | + if (s_isTapZooming || s_isStartTapZoom) { | ||
| 876 | + USER_LOG_WARN("The last tap zoom process is not over."); | ||
| 877 | + return DJI_ERROR_SYSTEM_MODULE_CODE_NONSUPPORT_IN_CURRENT_STATE; | ||
| 878 | + } | ||
| 879 | + | ||
| 880 | + rotationMode = DJI_GIMBAL_ROTATION_MODE_RELATIVE_ANGLE; | ||
| 881 | + rotationProperty.relativeAngleRotation.actionTime = TAP_ZOOM_DURATION / 10; | ||
| 882 | + | ||
| 883 | + returnCode = osalHandler->MutexLock(s_zoomMutex); | ||
| 884 | + if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) { | ||
| 885 | + USER_LOG_ERROR("lock mutex error: 0x%08llX.", returnCode); | ||
| 886 | + return returnCode; | ||
| 887 | + } | ||
| 888 | + | ||
| 889 | + /* Calculation formula: rotation angle = arctan((coordinate of target in sensor - coordinate of center point in | ||
| 890 | + * sensor) / hybrid focal length). Here, suppose that images of all pixels of sensor are displayed in screen, | ||
| 891 | + * and that center of the image sensor coincides with center of rotation of the gimbal, and that optical axis of | ||
| 892 | + * camera coincides with x-axis of gimbal. */ | ||
| 893 | + hybridFocalLength = (dji_f32_t) s_cameraOpticalZoomFocalLength * s_cameraDigitalZoomFactor; | ||
| 894 | + | ||
| 895 | + returnCode = osalHandler->MutexUnlock(s_zoomMutex); | ||
| 896 | + if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) { | ||
| 897 | + USER_LOG_ERROR("unlock mutex error: 0x%08llX.", returnCode); | ||
| 898 | + return returnCode; | ||
| 899 | + } | ||
| 900 | + | ||
| 901 | + rotationValue.pitch = (int32_t) ( | ||
| 902 | + atan2f((target.focusY - CENTER_POINT_IN_SCREEN_Y_VALUE) * IMAGE_SENSOR_Y_SIZE, hybridFocalLength) * 1800 / | ||
| 903 | + DJI_PI); | ||
| 904 | + rotationValue.yaw = (int32_t) ( | ||
| 905 | + atan2f((target.focusX - CENTER_POINT_IN_SCREEN_X_VALUE) * IMAGE_SENSOR_X_SIZE, hybridFocalLength) * 1800 / | ||
| 906 | + DJI_PI); | ||
| 907 | + | ||
| 908 | + returnCode = osalHandler->MutexLock(s_tapZoomMutex); | ||
| 909 | + if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) { | ||
| 910 | + USER_LOG_ERROR("lock mutex error: 0x%08llX.", returnCode); | ||
| 911 | + return returnCode; | ||
| 912 | + } | ||
| 913 | + | ||
| 914 | + s_tapZoomNewestGimbalRotationArgument.rotationMode = rotationMode; | ||
| 915 | + s_tapZoomNewestGimbalRotationArgument.rotationProperty = rotationProperty; | ||
| 916 | + s_tapZoomNewestGimbalRotationArgument.rotationValue = rotationValue; | ||
| 917 | + s_tapZoomNewestTargetHybridFocalLength = (uint32_t) (hybridFocalLength * (float) s_tapZoomMultiplier); | ||
| 918 | + | ||
| 919 | + returnCode = osalHandler->MutexUnlock(s_tapZoomMutex); | ||
| 920 | + if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) { | ||
| 921 | + USER_LOG_ERROR("unlock mutex error: 0x%08llX.", returnCode); | ||
| 922 | + return returnCode; | ||
| 923 | + } | ||
| 924 | + | ||
| 925 | + s_isStartTapZoom = true; | ||
| 926 | + | ||
| 927 | + return DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS; | ||
| 928 | +} | ||
| 929 | + | ||
| 930 | +static T_DjiReturnCode DjiTest_CameraHybridZoom(uint32_t focalLength) | ||
| 931 | +{ | ||
| 932 | + if (focalLength >= ZOOM_OPTICAL_FOCAL_MIN_LENGTH && focalLength <= ZOOM_OPTICAL_FOCAL_MAX_LENGTH) { | ||
| 933 | + s_cameraOpticalZoomFocalLength = focalLength; | ||
| 934 | + s_cameraDigitalZoomFactor = ZOOM_DIGITAL_BASE_FACTOR; | ||
| 935 | + } else if (focalLength < ZOOM_OPTICAL_FOCAL_MIN_LENGTH) { | ||
| 936 | + s_cameraOpticalZoomFocalLength = ZOOM_OPTICAL_FOCAL_MIN_LENGTH; | ||
| 937 | + s_cameraDigitalZoomFactor = ZOOM_DIGITAL_BASE_FACTOR; | ||
| 938 | + | ||
| 939 | + USER_LOG_ERROR("focal length %d is smaller than min optical focal length %d.", focalLength, | ||
| 940 | + ZOOM_OPTICAL_FOCAL_MIN_LENGTH); | ||
| 941 | + return DJI_ERROR_SYSTEM_MODULE_CODE_OUT_OF_RANGE; | ||
| 942 | + } else { | ||
| 943 | + s_cameraOpticalZoomFocalLength = ZOOM_OPTICAL_FOCAL_MAX_LENGTH; | ||
| 944 | + s_cameraDigitalZoomFactor = (float) focalLength / ZOOM_OPTICAL_FOCAL_MAX_LENGTH; | ||
| 945 | + } | ||
| 946 | + | ||
| 947 | + return DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS; | ||
| 948 | +} | ||
| 949 | + | ||
| 950 | +static T_DjiReturnCode DjiTest_CameraRotationGimbal(T_TestCameraGimbalRotationArgument gimbalRotationArgument) | ||
| 951 | +{ | ||
| 952 | + T_DjiReturnCode returnCode; | ||
| 953 | + T_DjiAircraftInfoBaseInfo aircraftBaseInfo = {0}; | ||
| 954 | + | ||
| 955 | + returnCode = DjiAircraftInfo_GetBaseInfo(&aircraftBaseInfo); | ||
| 956 | + if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) { | ||
| 957 | + USER_LOG_ERROR("get aircraft information error: 0x%08llX.", returnCode); | ||
| 958 | + return returnCode; | ||
| 959 | + } | ||
| 960 | + | ||
| 961 | + if (aircraftBaseInfo.djiAdapterType == DJI_SDK_ADAPTER_TYPE_SKYPORT_V2 || | ||
| 962 | + aircraftBaseInfo.djiAdapterType == DJI_SDK_ADAPTER_TYPE_NONE) { | ||
| 963 | + returnCode = DjiTest_GimbalRotate(gimbalRotationArgument.rotationMode, gimbalRotationArgument.rotationProperty, | ||
| 964 | + gimbalRotationArgument.rotationValue); | ||
| 965 | + if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) { | ||
| 966 | + USER_LOG_ERROR("rotate gimbal error: 0x%08llX.", returnCode); | ||
| 967 | + return returnCode; | ||
| 968 | + } | ||
| 969 | + } else if (aircraftBaseInfo.djiAdapterType == DJI_SDK_ADAPTER_TYPE_XPORT) { | ||
| 970 | + returnCode = DjiXPort_RotateSync(gimbalRotationArgument.rotationMode, gimbalRotationArgument.rotationProperty, | ||
| 971 | + gimbalRotationArgument.rotationValue); | ||
| 972 | + if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) { | ||
| 973 | + USER_LOG_ERROR("rotate XPort error: 0x%08llX.", returnCode); | ||
| 974 | + return returnCode; | ||
| 975 | + } | ||
| 976 | + } else { | ||
| 977 | + USER_LOG_ERROR("PSDK adapter type is invalid: %d.", aircraftBaseInfo.djiAdapterType); | ||
| 978 | + return DJI_ERROR_SYSTEM_MODULE_CODE_NONSUPPORT; | ||
| 979 | + } | ||
| 980 | + | ||
| 981 | + return DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS; | ||
| 982 | +} | ||
| 983 | + | ||
| 984 | +#ifndef __CC_ARM | ||
| 985 | +#pragma GCC diagnostic push | ||
| 986 | +#pragma GCC diagnostic ignored "-Wmissing-noreturn" | ||
| 987 | +#pragma GCC diagnostic ignored "-Wreturn-type" | ||
| 988 | +#endif | ||
| 989 | + | ||
| 990 | +static void *UserCamera_Task(void *arg) | ||
| 991 | +{ | ||
| 992 | + static uint32_t photoCnt = 0; | ||
| 993 | + static uint32_t step = 0; | ||
| 994 | + T_DjiReturnCode returnCode; | ||
| 995 | + int32_t tempFocalLength = 0; | ||
| 996 | + dji_f32_t tempDigitalFactor = 0.0f; | ||
| 997 | + uint32_t currentTime = 0; | ||
| 998 | + bool isStartIntervalPhotoAction = false; | ||
| 999 | + T_DjiOsalHandler *osalHandler = DjiPlatform_GetOsalHandler(); | ||
| 1000 | + | ||
| 1001 | + USER_UTIL_UNUSED(arg); | ||
| 1002 | + | ||
| 1003 | + while (1) { | ||
| 1004 | + osalHandler->TaskSleepMs(1000 / PAYLOAD_CAMERA_EMU_TASK_FREQ); | ||
| 1005 | + step++; | ||
| 1006 | + | ||
| 1007 | + returnCode = osalHandler->MutexLock(s_commonMutex); | ||
| 1008 | + if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) { | ||
| 1009 | + USER_LOG_ERROR("lock mutex error: 0x%08llX.", returnCode); | ||
| 1010 | + continue; | ||
| 1011 | + } | ||
| 1012 | + | ||
| 1013 | + s_cameraSDCardState.availableRecordingTimeInSeconds = | ||
| 1014 | + s_cameraSDCardState.remainSpaceInMB / SDCARD_PER_SECONDS_RECORD_SPACE_IN_MB; | ||
| 1015 | + s_cameraSDCardState.availableCaptureCount = s_cameraSDCardState.remainSpaceInMB / SDCARD_PER_PHOTO_SPACE_IN_MB; | ||
| 1016 | + | ||
| 1017 | +//l理解你的照片 短和逻辑存储 | ||
| 1018 | + //realize your photo shoot and storage logic here | ||
| 1019 | + if (s_cameraState.shootingState != DJI_CAMERA_SHOOTING_PHOTO_IDLE && | ||
| 1020 | + photoCnt++ > TAKING_PHOTO_SPENT_TIME_MS_EMU / (1000 / PAYLOAD_CAMERA_EMU_TASK_FREQ)) { | ||
| 1021 | + photoCnt = 0; | ||
| 1022 | + | ||
| 1023 | +//在拍摄结束后 把照片放入仓库 | ||
| 1024 | + //store the photo after shooting finished | ||
| 1025 | + if (s_cameraShootPhotoMode == DJI_CAMERA_SHOOT_PHOTO_MODE_SINGLE) { | ||
| 1026 | + s_cameraSDCardState.remainSpaceInMB = | ||
| 1027 | + s_cameraSDCardState.remainSpaceInMB - SDCARD_PER_PHOTO_SPACE_IN_MB; | ||
| 1028 | + s_cameraState.isStoring = false; | ||
| 1029 | + s_cameraState.shootingState = DJI_CAMERA_SHOOTING_PHOTO_IDLE; | ||
| 1030 | + } else if (s_cameraShootPhotoMode == DJI_CAMERA_SHOOT_PHOTO_MODE_BURST) { | ||
| 1031 | + s_cameraSDCardState.remainSpaceInMB = | ||
| 1032 | + s_cameraSDCardState.remainSpaceInMB - SDCARD_PER_PHOTO_SPACE_IN_MB * s_cameraBurstCount; | ||
| 1033 | + s_cameraState.isStoring = false; | ||
| 1034 | + s_cameraState.shootingState = DJI_CAMERA_SHOOTING_PHOTO_IDLE; | ||
| 1035 | + } else if (s_cameraShootPhotoMode == DJI_CAMERA_SHOOT_PHOTO_MODE_INTERVAL) { | ||
| 1036 | + if (isStartIntervalPhotoAction == true) { | ||
| 1037 | + s_cameraState.isStoring = false; | ||
| 1038 | + s_cameraState.shootingState = DJI_CAMERA_SHOOTING_PHOTO_IDLE; | ||
| 1039 | + s_cameraSDCardState.remainSpaceInMB = | ||
| 1040 | + s_cameraSDCardState.remainSpaceInMB - SDCARD_PER_PHOTO_SPACE_IN_MB; | ||
| 1041 | + } | ||
| 1042 | + } | ||
| 1043 | + | ||
| 1044 | +// 检查 sd卡 的 保留空间 | ||
| 1045 | + //check the remain space of sdcard | ||
| 1046 | + if (s_cameraSDCardState.remainSpaceInMB > SDCARD_TOTAL_SPACE_IN_MB) { | ||
| 1047 | + s_cameraSDCardState.remainSpaceInMB = 0; | ||
| 1048 | + s_cameraSDCardState.isFull = true; | ||
| 1049 | + } | ||
| 1050 | + | ||
| 1051 | +#if dji_ARCH_SYS_LINUX | ||
| 1052 | + T_DjiCameraMediaFileInfo mediaFileInfo = {0}; | ||
| 1053 | + | ||
| 1054 | +// 退入 媒体文件信息 | ||
| 1055 | + // push added media file information | ||
| 1056 | + if (s_cameraShootPhotoMode == dji_CAMERA_SHOOT_PHOTO_MODE_SINGLE) { | ||
| 1057 | + if (UtilFile_IsFileExist(PHOTO_FILE_PATH) == true) { | ||
| 1058 | + psdkStat = PsdkTest_CameraMediaGetFileInfo(PHOTO_FILE_PATH, &mediaFileInfo); | ||
| 1059 | + if (psdkStat != dji_ERROR_SYSTEM_MODULE_CODE_SUCCESS) { | ||
| 1060 | + PsdkLogger_UserLogError("Get media file info error 0x%08llX", psdkStat); | ||
| 1061 | + } | ||
| 1062 | + | ||
| 1063 | + psdkStat = PsdkPayloadCamera_PushAddedMediaFileInfo(PHOTO_FILE_PATH, mediaFileInfo); | ||
| 1064 | + if (psdkStat != dji_ERROR_SYSTEM_MODULE_CODE_SUCCESS) { | ||
| 1065 | + PsdkLogger_UserLogError("Push added media file info error 0x%08llX", psdkStat); | ||
| 1066 | + } | ||
| 1067 | + } else { | ||
| 1068 | + PsdkLogger_UserLogWarn("Can't found the media file by path. " | ||
| 1069 | + "Probably because media file has not existed. " | ||
| 1070 | + "Please check media file if exists. "); | ||
| 1071 | + } | ||
| 1072 | + } | ||
| 1073 | +#endif | ||
| 1074 | + } | ||
| 1075 | + | ||
| 1076 | + returnCode = osalHandler->MutexUnlock(s_commonMutex); | ||
| 1077 | + if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) { | ||
| 1078 | + USER_LOG_ERROR("unlock mutex error: 0x%08llX.", returnCode); | ||
| 1079 | + continue; | ||
| 1080 | + } | ||
| 1081 | + | ||
| 1082 | + // 10Hz | ||
| 1083 | + if (USER_UTIL_IS_WORK_TURN(step, 10, PAYLOAD_CAMERA_EMU_TASK_FREQ)) { | ||
| 1084 | + returnCode = osalHandler->MutexLock(s_zoomMutex); | ||
| 1085 | + if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) { | ||
| 1086 | + USER_LOG_ERROR("lock mutex error: 0x%08llX.", returnCode); | ||
| 1087 | + continue; | ||
| 1088 | + } | ||
| 1089 | + | ||
| 1090 | +#ifdef USER_CAMERA_EMU_HYBRID_ZOOM_ON | ||
| 1091 | + //Add logic here for zoom camera | ||
| 1092 | + if (s_isStartContinuousOpticalZoom == true) { | ||
| 1093 | + tempDigitalFactor = s_cameraDigitalZoomFactor; | ||
| 1094 | + tempFocalLength = (int32_t) s_cameraOpticalZoomFocalLength; | ||
| 1095 | + if (s_isOpticalZoomReachLimit == false) { | ||
| 1096 | + if (s_cameraZoomDirection == DJI_CAMERA_ZOOM_DIRECTION_IN) { | ||
| 1097 | + tempFocalLength += ((int) s_cameraZoomSpeed - DJI_CAMERA_ZOOM_SPEED_SLOWEST + 1) * | ||
| 1098 | + ZOOM_OPTICAL_FOCAL_LENGTH_CTRL_STEP; | ||
| 1099 | + } else if (s_cameraZoomDirection == DJI_CAMERA_ZOOM_DIRECTION_OUT) { | ||
| 1100 | + tempFocalLength -= ((int) s_cameraZoomSpeed - DJI_CAMERA_ZOOM_SPEED_SLOWEST + 1) * | ||
| 1101 | + ZOOM_OPTICAL_FOCAL_LENGTH_CTRL_STEP; | ||
| 1102 | + } | ||
| 1103 | + | ||
| 1104 | + if (tempFocalLength > ZOOM_OPTICAL_FOCAL_MAX_LENGTH) { | ||
| 1105 | + s_isOpticalZoomReachLimit = true; | ||
| 1106 | + tempFocalLength = ZOOM_OPTICAL_FOCAL_MAX_LENGTH; | ||
| 1107 | + } | ||
| 1108 | + | ||
| 1109 | + if (tempFocalLength < ZOOM_OPTICAL_FOCAL_MIN_LENGTH) { | ||
| 1110 | + tempFocalLength = ZOOM_OPTICAL_FOCAL_MIN_LENGTH; | ||
| 1111 | + } | ||
| 1112 | + } else { | ||
| 1113 | + if (s_cameraZoomDirection == DJI_CAMERA_ZOOM_DIRECTION_IN) { | ||
| 1114 | + tempDigitalFactor += (dji_f32_t) ZOOM_DIGITAL_STEP_FACTOR; | ||
| 1115 | + } else if (s_cameraZoomDirection == DJI_CAMERA_ZOOM_DIRECTION_OUT) { | ||
| 1116 | + tempDigitalFactor -= (dji_f32_t) ZOOM_DIGITAL_STEP_FACTOR; | ||
| 1117 | + } | ||
| 1118 | + | ||
| 1119 | + if (tempDigitalFactor > (dji_f32_t) ZOOM_DIGITAL_MAX_FACTOR) { | ||
| 1120 | + tempDigitalFactor = (dji_f32_t) ZOOM_DIGITAL_MAX_FACTOR; | ||
| 1121 | + } | ||
| 1122 | + | ||
| 1123 | + if (tempDigitalFactor < (dji_f32_t) ZOOM_DIGITAL_BASE_FACTOR) { | ||
| 1124 | + s_isOpticalZoomReachLimit = false; | ||
| 1125 | + tempDigitalFactor = ZOOM_DIGITAL_BASE_FACTOR; | ||
| 1126 | + } | ||
| 1127 | + } | ||
| 1128 | + s_cameraOpticalZoomFocalLength = (uint16_t) tempFocalLength; | ||
| 1129 | + s_cameraDigitalZoomFactor = tempDigitalFactor; | ||
| 1130 | + } | ||
| 1131 | +#endif | ||
| 1132 | + | ||
| 1133 | +#if USER_CAMERA_EMU_TAP_ZOOM_ON | ||
| 1134 | + returnCode = osalHandler->MutexLock(s_tapZoomMutex); | ||
| 1135 | + if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) { | ||
| 1136 | + USER_LOG_ERROR("lock mutex error: 0x%08llX.", returnCode); | ||
| 1137 | + goto out; | ||
| 1138 | + } | ||
| 1139 | + | ||
| 1140 | + if (s_isStartTapZoom) { | ||
| 1141 | + s_isStartTapZoom = false; | ||
| 1142 | + s_isTapZooming = true; | ||
| 1143 | + | ||
| 1144 | + returnCode = osalHandler->GetTimeMs(&s_tapZoomStartTime); | ||
| 1145 | + if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) { | ||
| 1146 | + USER_LOG_ERROR("get start time error: 0x%08llX.", returnCode); | ||
| 1147 | + } | ||
| 1148 | + | ||
| 1149 | + returnCode = DjiTest_CameraRotationGimbal(s_tapZoomNewestGimbalRotationArgument); | ||
| 1150 | + if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) | ||
| 1151 | + USER_LOG_ERROR("rotate gimbal error: 0x%08llX.", returnCode); | ||
| 1152 | + else | ||
| 1153 | + s_cameraTapZoomState.isGimbalMoving = true; | ||
| 1154 | + | ||
| 1155 | + returnCode = DjiTest_CameraHybridZoom(s_tapZoomNewestTargetHybridFocalLength); | ||
| 1156 | + if (returnCode == DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) { | ||
| 1157 | + s_cameraTapZoomState.zoomState = (dji_f32_t) s_tapZoomNewestTargetHybridFocalLength > | ||
| 1158 | + ((dji_f32_t) s_cameraOpticalZoomFocalLength * | ||
| 1159 | + s_cameraDigitalZoomFactor) | ||
| 1160 | + ? DJI_CAMERA_TAP_ZOOM_STATE_ZOOM_IN | ||
| 1161 | + : DJI_CAMERA_TAP_ZOOM_STATE_ZOOM_OUT; | ||
| 1162 | + } else if (returnCode == DJI_ERROR_SYSTEM_MODULE_CODE_OUT_OF_RANGE) { | ||
| 1163 | + USER_LOG_ERROR("hybrid zoom focal length beyond limit."); | ||
| 1164 | + s_cameraTapZoomState.zoomState = DJI_CAMERA_TAP_ZOOM_STATE_ZOOM_LIMITED; | ||
| 1165 | + } else { | ||
| 1166 | + USER_LOG_ERROR("hybrid zoom error: 0x%08llX.", returnCode); | ||
| 1167 | + } | ||
| 1168 | + } else if (s_isTapZooming) { | ||
| 1169 | + returnCode = osalHandler->GetTimeMs(¤tTime); | ||
| 1170 | + if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) { | ||
| 1171 | + USER_LOG_ERROR("get start time error: 0x%08llX.", returnCode); | ||
| 1172 | + } | ||
| 1173 | + | ||
| 1174 | + if ((currentTime - s_tapZoomStartTime) >= TAP_ZOOM_DURATION) { | ||
| 1175 | + s_cameraTapZoomState.zoomState = DJI_CAMERA_TAP_ZOOM_STATE_IDLE; | ||
| 1176 | + s_cameraTapZoomState.isGimbalMoving = false; | ||
| 1177 | + s_isTapZooming = false; | ||
| 1178 | + } | ||
| 1179 | + } | ||
| 1180 | + | ||
| 1181 | + returnCode = osalHandler->MutexUnlock(s_tapZoomMutex); | ||
| 1182 | + if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) { | ||
| 1183 | + USER_LOG_ERROR("unlock mutex error: 0x%08llX.", returnCode); | ||
| 1184 | + goto out; | ||
| 1185 | + } | ||
| 1186 | +#endif | ||
| 1187 | + | ||
| 1188 | +out: | ||
| 1189 | + returnCode = osalHandler->MutexUnlock(s_zoomMutex); | ||
| 1190 | + if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) { | ||
| 1191 | + USER_LOG_ERROR("unlock mutex error: 0x%08llX.", returnCode); | ||
| 1192 | + continue; | ||
| 1193 | + } | ||
| 1194 | + } | ||
| 1195 | + | ||
| 1196 | + // 1Hz | ||
| 1197 | + if (USER_UTIL_IS_WORK_TURN(step, 1, PAYLOAD_CAMERA_EMU_TASK_FREQ)) { | ||
| 1198 | + returnCode = osalHandler->MutexLock(s_commonMutex); | ||
| 1199 | + if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) { | ||
| 1200 | + USER_LOG_ERROR("lock mutex error: 0x%08llX.", returnCode); | ||
| 1201 | + continue; | ||
| 1202 | + } | ||
| 1203 | + | ||
| 1204 | + if (s_cameraState.isRecording) { | ||
| 1205 | + s_cameraState.currentVideoRecordingTimeInSeconds++; | ||
| 1206 | + s_cameraSDCardState.remainSpaceInMB = | ||
| 1207 | + s_cameraSDCardState.remainSpaceInMB - SDCARD_PER_SECONDS_RECORD_SPACE_IN_MB; | ||
| 1208 | + if (s_cameraSDCardState.remainSpaceInMB > SDCARD_TOTAL_SPACE_IN_MB) { | ||
| 1209 | + s_cameraSDCardState.remainSpaceInMB = 0; | ||
| 1210 | + s_cameraSDCardState.isFull = true; | ||
| 1211 | + } | ||
| 1212 | + } | ||
| 1213 | + | ||
| 1214 | + if (s_cameraState.isShootingIntervalStart == false) { | ||
| 1215 | + isStartIntervalPhotoAction = false; | ||
| 1216 | + } | ||
| 1217 | + | ||
| 1218 | + if (s_cameraShootPhotoMode == DJI_CAMERA_SHOOT_PHOTO_MODE_INTERVAL | ||
| 1219 | + && s_cameraState.isShootingIntervalStart == true && s_cameraPhotoTimeIntervalSettings.captureCount > 0 | ||
| 1220 | + && s_cameraPhotoTimeIntervalSettings.timeIntervalSeconds > 0) { | ||
| 1221 | + s_cameraState.currentPhotoShootingIntervalTimeInSeconds--; | ||
| 1222 | + | ||
| 1223 | + if ((s_cameraState.currentPhotoShootingIntervalTimeInSeconds == 0 && | ||
| 1224 | + s_cameraState.currentPhotoShootingIntervalCount > 0) || | ||
| 1225 | + (s_cameraState.isShootingIntervalStart == true && isStartIntervalPhotoAction == false)) { | ||
| 1226 | + | ||
| 1227 | + isStartIntervalPhotoAction = true; | ||
| 1228 | + | ||
| 1229 | + s_cameraState.shootingState = DJI_CAMERA_SHOOTING_INTERVAL_PHOTO; | ||
| 1230 | + s_cameraState.isStoring = true; | ||
| 1231 | + s_cameraState.currentPhotoShootingIntervalTimeInSeconds | ||
| 1232 | + = s_cameraPhotoTimeIntervalSettings.timeIntervalSeconds; | ||
| 1233 | + if (s_cameraState.currentPhotoShootingIntervalCount < INTERVAL_PHOTOGRAPH_ALWAYS_COUNT) { | ||
| 1234 | + USER_LOG_INFO("interval taking photograph count:%d interval_time:%ds", | ||
| 1235 | + (s_cameraPhotoTimeIntervalSettings.captureCount - | ||
| 1236 | + s_cameraState.currentPhotoShootingIntervalCount + 1), | ||
| 1237 | + s_cameraPhotoTimeIntervalSettings.timeIntervalSeconds); | ||
| 1238 | + JZsdk_Psdk_UI_io_ShootPhoto(); | ||
| 1239 | + s_cameraState.currentPhotoShootingIntervalCount--; | ||
| 1240 | + if (s_cameraState.currentPhotoShootingIntervalCount == 0) { | ||
| 1241 | + s_cameraState.shootingState = DJI_CAMERA_SHOOTING_PHOTO_IDLE; | ||
| 1242 | + s_cameraState.isStoring = false; | ||
| 1243 | + s_cameraState.isShootingIntervalStart = false; | ||
| 1244 | + } | ||
| 1245 | + } else { | ||
| 1246 | + USER_LOG_INFO("interval taking photograph always, interval_time:%ds", | ||
| 1247 | + s_cameraPhotoTimeIntervalSettings.timeIntervalSeconds); | ||
| 1248 | + JZsdk_Psdk_UI_io_ShootPhoto(); | ||
| 1249 | + | ||
| 1250 | + s_cameraState.currentPhotoShootingIntervalCount--; | ||
| 1251 | + } | ||
| 1252 | + } | ||
| 1253 | + } | ||
| 1254 | + | ||
| 1255 | + returnCode = osalHandler->MutexUnlock(s_commonMutex); | ||
| 1256 | + if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) { | ||
| 1257 | + USER_LOG_ERROR("unlock mutex error: 0x%08llX.", returnCode); | ||
| 1258 | + continue; | ||
| 1259 | + } | ||
| 1260 | + } | ||
| 1261 | + } | ||
| 1262 | +} | ||
| 1263 | + | ||
| 1264 | +#ifndef __CC_ARM | ||
| 1265 | +#pragma GCC diagnostic pop | ||
| 1266 | +#endif | ||
| 1267 | + | ||
| 1268 | +/* Private functions definition-----------------------------------------------*/ | ||
| 1269 | +// 照相机 菜单 基础 开始 服务 | ||
| 1270 | +T_DjiReturnCode DjiTest_CameraEmuBaseStartService(void) | ||
| 1271 | +{ | ||
| 1272 | + T_DjiReturnCode returnCode; | ||
| 1273 | + char ipAddr[DJI_IP_ADDR_STR_SIZE_MAX] = {0}; | ||
| 1274 | + uint16_t port = 0; | ||
| 1275 | + T_DjiOsalHandler *osalHandler = DjiPlatform_GetOsalHandler(); | ||
| 1276 | + T_DjiAircraftInfoBaseInfo aircraftInfoBaseInfo = {0}; | ||
| 1277 | + | ||
| 1278 | + returnCode = osalHandler->MutexCreate(&s_commonMutex); | ||
| 1279 | + if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) { | ||
| 1280 | + USER_LOG_ERROR("create mutex used to lock tap zoom arguments error: 0x%08llX", returnCode); | ||
| 1281 | + return returnCode; | ||
| 1282 | + } | ||
| 1283 | + | ||
| 1284 | + returnCode = osalHandler->MutexCreate(&s_zoomMutex); | ||
| 1285 | + if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) { | ||
| 1286 | + USER_LOG_ERROR("create mutex used to lock tap zoom arguments error: 0x%08llX", returnCode); | ||
| 1287 | + return returnCode; | ||
| 1288 | + } | ||
| 1289 | + | ||
| 1290 | + returnCode = osalHandler->MutexCreate(&s_tapZoomMutex); | ||
| 1291 | + if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) { | ||
| 1292 | + USER_LOG_ERROR("create mutex used to lock tap zoom arguments error: 0x%08llX", returnCode); | ||
| 1293 | + return returnCode; | ||
| 1294 | + } | ||
| 1295 | + | ||
| 1296 | + returnCode = DjiPayloadCamera_Init(); | ||
| 1297 | + if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) { | ||
| 1298 | + USER_LOG_ERROR("init payload camera error:0x%08llX", returnCode); | ||
| 1299 | + return returnCode; | ||
| 1300 | + } | ||
| 1301 | + | ||
| 1302 | +// 初始化 sd卡的环境 | ||
| 1303 | + /* Init the SDcard parameters */ | ||
| 1304 | + s_cameraSDCardState.isInserted = true; | ||
| 1305 | + s_cameraSDCardState.isVerified = true; | ||
| 1306 | + s_cameraSDCardState.totalSpaceInMB = SDCARD_TOTAL_SPACE_IN_MB; | ||
| 1307 | + s_cameraSDCardState.remainSpaceInMB = SDCARD_TOTAL_SPACE_IN_MB; | ||
| 1308 | + s_cameraSDCardState.availableCaptureCount = SDCARD_TOTAL_SPACE_IN_MB / SDCARD_PER_PHOTO_SPACE_IN_MB; | ||
| 1309 | + s_cameraSDCardState.availableRecordingTimeInSeconds = | ||
| 1310 | + SDCARD_TOTAL_SPACE_IN_MB / SDCARD_PER_SECONDS_RECORD_SPACE_IN_MB; | ||
| 1311 | + | ||
| 1312 | +// 注册相机 指令 的 权柄 | ||
| 1313 | + /* Register the camera common handler */ | ||
| 1314 | + s_commonHandler.GetSystemState = GetSystemState; | ||
| 1315 | + s_commonHandler.SetMode = SetMode; | ||
| 1316 | + s_commonHandler.GetMode = DjiTest_CameraGetMode; | ||
| 1317 | + s_commonHandler.StartRecordVideo = StartRecordVideo; | ||
| 1318 | + s_commonHandler.StopRecordVideo = StopRecordVideo; | ||
| 1319 | + s_commonHandler.StartShootPhoto = StartShootPhoto; | ||
| 1320 | + s_commonHandler.StopShootPhoto = StopShootPhoto; | ||
| 1321 | + s_commonHandler.SetShootPhotoMode = SetShootPhotoMode; | ||
| 1322 | + s_commonHandler.GetShootPhotoMode = GetShootPhotoMode; | ||
| 1323 | + s_commonHandler.SetPhotoBurstCount = SetPhotoBurstCount; | ||
| 1324 | + s_commonHandler.GetPhotoBurstCount = GetPhotoBurstCount; | ||
| 1325 | + s_commonHandler.SetPhotoTimeIntervalSettings = SetPhotoTimeIntervalSettings; | ||
| 1326 | + s_commonHandler.GetPhotoTimeIntervalSettings = GetPhotoTimeIntervalSettings; | ||
| 1327 | + s_commonHandler.GetSDCardState = GetSDCardState; | ||
| 1328 | + s_commonHandler.FormatSDCard = FormatSDCard; | ||
| 1329 | + | ||
| 1330 | + returnCode = DjiPayloadCamera_RegCommonHandler(&s_commonHandler); | ||
| 1331 | + if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) { | ||
| 1332 | + USER_LOG_ERROR("camera register common handler error:0x%08llX", returnCode); | ||
| 1333 | + } | ||
| 1334 | + | ||
| 1335 | + /* Register the camera metering handler */ | ||
| 1336 | +#if USER_CAMERA_EMU_METERING_ON | ||
| 1337 | + s_exposureMeteringHandler.SetMeteringMode = SetMeteringMode; | ||
| 1338 | + s_exposureMeteringHandler.GetMeteringMode = GetMeteringMode; | ||
| 1339 | + s_exposureMeteringHandler.SetSpotMeteringTarget = SetSpotMeteringTarget; | ||
| 1340 | + s_exposureMeteringHandler.GetSpotMeteringTarget = GetSpotMeteringTarget; | ||
| 1341 | + | ||
| 1342 | + returnCode = DjiPayloadCamera_RegExposureMeteringHandler(&s_exposureMeteringHandler); | ||
| 1343 | + if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) { | ||
| 1344 | + USER_LOG_ERROR("camera register exposure metering handler error:0x%08llX", returnCode); | ||
| 1345 | + return returnCode; | ||
| 1346 | + } | ||
| 1347 | +#endif | ||
| 1348 | + | ||
| 1349 | +// 注册 相机 焦点 句柄 | ||
| 1350 | + /* Register the camera focus handler */ | ||
| 1351 | +#if USER_CAMERA_EMU_FOCUS_ON | ||
| 1352 | + s_focusHandler.SetFocusMode = SetFocusMode; | ||
| 1353 | + s_focusHandler.GetFocusMode = GetFocusMode; | ||
| 1354 | + s_focusHandler.SetFocusTarget = SetFocusTarget; | ||
| 1355 | + s_focusHandler.GetFocusTarget = GetFocusTarget; | ||
| 1356 | + s_focusHandler.SetFocusAssistantSettings = SetFocusAssistantSettings; | ||
| 1357 | + s_focusHandler.GetFocusAssistantSettings = GetFocusAssistantSettings; | ||
| 1358 | + s_focusHandler.SetFocusRingValue = SetFocusRingValue; | ||
| 1359 | + s_focusHandler.GetFocusRingValue = GetFocusRingValue; | ||
| 1360 | + s_focusHandler.GetFocusRingValueUpperBound = GetFocusRingValueUpperBound; | ||
| 1361 | + | ||
| 1362 | + returnCode = DjiPayloadCamera_RegFocusHandler(&s_focusHandler); | ||
| 1363 | + if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) { | ||
| 1364 | + USER_LOG_ERROR("camera register adjustable focal point handler error:0x%08llX", returnCode); | ||
| 1365 | + return returnCode; | ||
| 1366 | + } | ||
| 1367 | +#endif | ||
| 1368 | + | ||
| 1369 | +// 注册 相机 数码变焦 的句柄 | ||
| 1370 | + /* Register the camera digital zoom handler */ | ||
| 1371 | +#if USER_CAMERA_EMU_HYBRID_ZOOM_ON | ||
| 1372 | + s_digitalZoomHandler.SetDigitalZoomFactor = SetDigitalZoomFactor; | ||
| 1373 | + s_digitalZoomHandler.GetDigitalZoomFactor = DjiTest_CameraGetDigitalZoomFactor; | ||
| 1374 | + | ||
| 1375 | + returnCode = DjiPayloadCamera_RegDigitalZoomHandler(&s_digitalZoomHandler); | ||
| 1376 | + if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) { | ||
| 1377 | + USER_LOG_ERROR("camera register digital zoom handler error:0x%08llX", returnCode); | ||
| 1378 | + return returnCode; | ||
| 1379 | + } | ||
| 1380 | + | ||
| 1381 | +// 注册 相机 光学 变焦 | ||
| 1382 | + /* Register the camera optical zoom handler */ | ||
| 1383 | + s_opticalZoomHandler.SetOpticalZoomFocalLength = SetOpticalZoomFocalLength; | ||
| 1384 | + s_opticalZoomHandler.GetOpticalZoomFocalLength = GetOpticalZoomFocalLength; | ||
| 1385 | + s_opticalZoomHandler.GetOpticalZoomFactor = DjiTest_CameraGetOpticalZoomFactor; | ||
| 1386 | + s_opticalZoomHandler.GetOpticalZoomSpec = GetOpticalZoomSpec; | ||
| 1387 | + s_opticalZoomHandler.StartContinuousOpticalZoom = StartContinuousOpticalZoom; | ||
| 1388 | + s_opticalZoomHandler.StopContinuousOpticalZoom = StopContinuousOpticalZoom; | ||
| 1389 | + | ||
| 1390 | + returnCode = DjiPayloadCamera_RegOpticalZoomHandler(&s_opticalZoomHandler); | ||
| 1391 | + if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) { | ||
| 1392 | + USER_LOG_ERROR("camera register optical zoom handler error:0x%08llX", returnCode); | ||
| 1393 | + return returnCode; | ||
| 1394 | + } | ||
| 1395 | +#endif | ||
| 1396 | + | ||
| 1397 | +// 注册 利用变焦 | ||
| 1398 | + /* Register the camera tap zoom handler */ | ||
| 1399 | +#if USER_CAMERA_EMU_TAP_ZOOM_ON | ||
| 1400 | + s_tapZoomHandler.GetTapZoomState = GetTapZoomState; | ||
| 1401 | + s_tapZoomHandler.SetTapZoomEnabled = SetTapZoomEnabled; | ||
| 1402 | + s_tapZoomHandler.GetTapZoomEnabled = GetTapZoomEnabled; | ||
| 1403 | + s_tapZoomHandler.SetTapZoomMultiplier = SetTapZoomMultiplier; | ||
| 1404 | + s_tapZoomHandler.GetTapZoomMultiplier = GetTapZoomMultiplier; | ||
| 1405 | + s_tapZoomHandler.TapZoomAtTarget = TapZoomAtTarget; | ||
| 1406 | + | ||
| 1407 | + returnCode = DjiPayloadCamera_RegTapZoomHandler(&s_tapZoomHandler); | ||
| 1408 | + if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) { | ||
| 1409 | + USER_LOG_ERROR("camera register tap zoom handler error:0x%08llX", returnCode); | ||
| 1410 | + return returnCode; | ||
| 1411 | + } | ||
| 1412 | +#endif | ||
| 1413 | + | ||
| 1414 | +// 注册 相机的 菜单 任务 | ||
| 1415 | + /* Create the camera emu taskHandle */ | ||
| 1416 | + if (osalHandler->TaskCreate("user_camera_task", UserCamera_Task, | ||
| 1417 | + PAYLOAD_CAMERA_EMU_TASK_STACK_SIZE, NULL, &s_userCameraThread) | ||
| 1418 | + != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) { | ||
| 1419 | + USER_LOG_ERROR("user camera taskHandle create error"); | ||
| 1420 | + return DJI_ERROR_SYSTEM_MODULE_CODE_UNKNOWN; | ||
| 1421 | + } | ||
| 1422 | + | ||
| 1423 | +// 得到 相机 的 基础 信息 | ||
| 1424 | + if (DjiAircraftInfo_GetBaseInfo(&aircraftInfoBaseInfo) != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) { | ||
| 1425 | + USER_LOG_ERROR("get aircraft information error."); | ||
| 1426 | + return DJI_ERROR_SYSTEM_MODULE_CODE_UNKNOWN; | ||
| 1427 | + } | ||
| 1428 | + | ||
| 1429 | +// 设置 视频 流 的 类型 | ||
| 1430 | + returnCode = DjiPayloadCamera_SetVideoStreamType(DJI_CAMERA_VIDEO_STREAM_TYPE_H264_DJI_FORMAT); | ||
| 1431 | + if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) { | ||
| 1432 | + USER_LOG_ERROR("DJI camera set video stream error."); | ||
| 1433 | + return DJI_ERROR_SYSTEM_MODULE_CODE_UNKNOWN; | ||
| 1434 | + } | ||
| 1435 | + | ||
| 1436 | + //设置传输视频的类型 | ||
| 1437 | + s_cameraVideoStreamType = DJI_CAMERA_VIDEO_STREAM_TYPE_H264_DJI_FORMAT; | ||
| 1438 | + | ||
| 1439 | +// 获取视频流远程地址 飞机云台的地址 | ||
| 1440 | + returnCode = DjiPayloadCamera_GetVideoStreamRemoteAddress(ipAddr, &port); | ||
| 1441 | + if (returnCode == DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) { | ||
| 1442 | + USER_LOG_DEBUG("Get video stream remote address: %s, port: %d", ipAddr, port); | ||
| 1443 | + } else { | ||
| 1444 | + USER_LOG_ERROR("get video stream remote address error."); | ||
| 1445 | + return DJI_ERROR_SYSTEM_MODULE_CODE_UNKNOWN; | ||
| 1446 | + } | ||
| 1447 | + | ||
| 1448 | + s_isCamInited = true; | ||
| 1449 | + | ||
| 1450 | + return DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS; | ||
| 1451 | +} | ||
| 1452 | + | ||
| 1453 | +T_DjiReturnCode DjiTest_CameraGetDigitalZoomFactor(dji_f32_t *factor) | ||
| 1454 | +{ | ||
| 1455 | + T_DjiReturnCode returnCode; | ||
| 1456 | + T_DjiOsalHandler *osalHandler = DjiPlatform_GetOsalHandler(); | ||
| 1457 | + | ||
| 1458 | + returnCode = osalHandler->MutexLock(s_zoomMutex); | ||
| 1459 | + if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) { | ||
| 1460 | + USER_LOG_ERROR("lock mutex error: 0x%08llX.", returnCode); | ||
| 1461 | + return returnCode; | ||
| 1462 | + } | ||
| 1463 | + | ||
| 1464 | + *factor = s_cameraDigitalZoomFactor; | ||
| 1465 | + | ||
| 1466 | + returnCode = osalHandler->MutexUnlock(s_zoomMutex); | ||
| 1467 | + if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) { | ||
| 1468 | + USER_LOG_ERROR("unlock mutex error: 0x%08llX.", returnCode); | ||
| 1469 | + return returnCode; | ||
| 1470 | + } | ||
| 1471 | + | ||
| 1472 | + return DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS; | ||
| 1473 | +} | ||
| 1474 | + | ||
| 1475 | +T_DjiReturnCode DjiTest_CameraGetOpticalZoomFactor(dji_f32_t *factor) | ||
| 1476 | +{ | ||
| 1477 | + T_DjiReturnCode returnCode; | ||
| 1478 | + T_DjiOsalHandler *osalHandler = DjiPlatform_GetOsalHandler(); | ||
| 1479 | + | ||
| 1480 | + returnCode = osalHandler->MutexLock(s_zoomMutex); | ||
| 1481 | + if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) { | ||
| 1482 | + USER_LOG_ERROR("lock mutex error: 0x%08llX.", returnCode); | ||
| 1483 | + return returnCode; | ||
| 1484 | + } | ||
| 1485 | + | ||
| 1486 | + //Formula:factor = currentFocalLength / minFocalLength | ||
| 1487 | + *factor = (dji_f32_t) s_cameraOpticalZoomFocalLength / ZOOM_OPTICAL_FOCAL_MIN_LENGTH; | ||
| 1488 | + | ||
| 1489 | + returnCode = osalHandler->MutexUnlock(s_zoomMutex); | ||
| 1490 | + if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) { | ||
| 1491 | + USER_LOG_ERROR("unlock mutex error: 0x%08llX.", returnCode); | ||
| 1492 | + return returnCode; | ||
| 1493 | + } | ||
| 1494 | + | ||
| 1495 | + return DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS; | ||
| 1496 | +} | ||
| 1497 | + | ||
| 1498 | +T_DjiReturnCode DjiTest_CameraGetMode(E_DjiCameraMode *mode) | ||
| 1499 | +{ | ||
| 1500 | + T_DjiReturnCode returnCode; | ||
| 1501 | + T_DjiOsalHandler *osalHandler = DjiPlatform_GetOsalHandler(); | ||
| 1502 | + | ||
| 1503 | + returnCode = osalHandler->MutexLock(s_commonMutex); | ||
| 1504 | + if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) { | ||
| 1505 | + USER_LOG_ERROR("lock mutex error: 0x%08llX.", returnCode); | ||
| 1506 | + return returnCode; | ||
| 1507 | + } | ||
| 1508 | + | ||
| 1509 | + *mode = s_cameraState.cameraMode; | ||
| 1510 | + | ||
| 1511 | + returnCode = osalHandler->MutexUnlock(s_commonMutex); | ||
| 1512 | + if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) { | ||
| 1513 | + USER_LOG_ERROR("unlock mutex error: 0x%08llX.", returnCode); | ||
| 1514 | + return returnCode; | ||
| 1515 | + } | ||
| 1516 | + | ||
| 1517 | + return DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS; | ||
| 1518 | +} | ||
| 1519 | + | ||
| 1520 | +T_DjiReturnCode DjiTest_CameraGetVideoStreamType(E_DjiCameraVideoStreamType *type) | ||
| 1521 | +{ | ||
| 1522 | + if (s_isCamInited == false) { | ||
| 1523 | + return DJI_ERROR_SYSTEM_MODULE_CODE_NONSUPPORT_IN_CURRENT_STATE; | ||
| 1524 | + } | ||
| 1525 | + | ||
| 1526 | + *type = s_cameraVideoStreamType; | ||
| 1527 | + | ||
| 1528 | + return DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS; | ||
| 1529 | +} | ||
| 1530 | + | ||
| 1531 | +bool DjiTest_CameraIsInited(void) | ||
| 1532 | +{ | ||
| 1533 | + return s_isCamInited; | ||
| 1534 | +} | ||
| 1535 | + | ||
| 1536 | +/****************** (C) COPYRIGHT DJI Innovations *****END OF FILE****/ | ||
| 1537 | + | ||
| 1538 | + | ||
| 1539 | + | ||
| 1540 | +//手动添加 by ookk303 | ||
| 1541 | +// 0空闲中 1录像中 2单拍中 3连拍中 4转码中 | ||
| 1542 | +void DJI_CamEmu_base_CameraTransLock(int flag) | ||
| 1543 | +{ | ||
| 1544 | + switch (flag) | ||
| 1545 | + { | ||
| 1546 | + case 0: | ||
| 1547 | + { | ||
| 1548 | + s_cameraState.isRecording = 0; | ||
| 1549 | + s_cameraState.isStoring = 0; | ||
| 1550 | + break; | ||
| 1551 | + } | ||
| 1552 | + | ||
| 1553 | + case 1: | ||
| 1554 | + { | ||
| 1555 | + s_cameraState.isRecording = 1; | ||
| 1556 | + s_cameraState.isStoring = 0; | ||
| 1557 | + break; | ||
| 1558 | + } | ||
| 1559 | + | ||
| 1560 | + case 2: | ||
| 1561 | + { | ||
| 1562 | + s_cameraState.isRecording = 0; | ||
| 1563 | + s_cameraState.isStoring = 1; | ||
| 1564 | + break; | ||
| 1565 | + } | ||
| 1566 | + | ||
| 1567 | + case 3: | ||
| 1568 | + { | ||
| 1569 | + s_cameraState.isRecording = 0; | ||
| 1570 | + s_cameraState.isStoring = 1; | ||
| 1571 | + break; | ||
| 1572 | + } | ||
| 1573 | + | ||
| 1574 | + case 4: | ||
| 1575 | + { | ||
| 1576 | + s_cameraState.isRecording = 0; | ||
| 1577 | + s_cameraState.isStoring = 1; | ||
| 1578 | + break; | ||
| 1579 | + } | ||
| 1580 | + | ||
| 1581 | + default: | ||
| 1582 | + break; | ||
| 1583 | + } | ||
| 1584 | +} |
project_build/DJI_大疆PSDK/samples/sample_c/module_sample/camera_emu/test_payload_cam_emu_base.h
0 → 100644
| 1 | +/** | ||
| 2 | + ******************************************************************** | ||
| 3 | + * @file test_payload_cam_emu_common.h | ||
| 4 | + * @brief This is the header file for "test_payload_cam_emu.c", defining the structure and | ||
| 5 | + * (exported) function prototypes. | ||
| 6 | + * | ||
| 7 | + * @copyright (c) 2021 DJI. All rights reserved. | ||
| 8 | + * | ||
| 9 | + * All information contained herein is, and remains, the property of DJI. | ||
| 10 | + * The intellectual and technical concepts contained herein are proprietary | ||
| 11 | + * to DJI and may be covered by U.S. and foreign patents, patents in process, | ||
| 12 | + * and protected by trade secret or copyright law. Dissemination of this | ||
| 13 | + * information, including but not limited to data and other proprietary | ||
| 14 | + * material(s) incorporated within the information, in any form, is strictly | ||
| 15 | + * prohibited without the express written consent of DJI. | ||
| 16 | + * | ||
| 17 | + * If you receive this source code without DJI’s authorization, you may not | ||
| 18 | + * further disseminate the information, and you must immediately remove the | ||
| 19 | + * source code and notify DJI of its removal. DJI reserves the right to pursue | ||
| 20 | + * legal actions against you for any loss(es) or damage(s) caused by your | ||
| 21 | + * failure to do so. | ||
| 22 | + * | ||
| 23 | + ********************************************************************* | ||
| 24 | + */ | ||
| 25 | + | ||
| 26 | +/* Define to prevent recursive inclusion -------------------------------------*/ | ||
| 27 | +#ifndef TEST_PAYLOAD_CAM_EMU_BASE_H | ||
| 28 | +#define TEST_PAYLOAD_CAM_EMU_BASE_H | ||
| 29 | + | ||
| 30 | +/* Includes ------------------------------------------------------------------*/ | ||
| 31 | +#include "dji_typedef.h" | ||
| 32 | +#include "dji_payload_camera.h" | ||
| 33 | + | ||
| 34 | +#ifdef __cplusplus | ||
| 35 | +extern "C" { | ||
| 36 | +#endif | ||
| 37 | + | ||
| 38 | +/* Exported constants --------------------------------------------------------*/ | ||
| 39 | + | ||
| 40 | +/* Exported types ------------------------------------------------------------*/ | ||
| 41 | + | ||
| 42 | +/* Exported functions --------------------------------------------------------*/ | ||
| 43 | +T_DjiReturnCode DjiTest_CameraEmuBaseStartService(void); | ||
| 44 | +T_DjiReturnCode DjiTest_CameraGetDigitalZoomFactor(dji_f32_t *factor); | ||
| 45 | +T_DjiReturnCode DjiTest_CameraGetOpticalZoomFactor(dji_f32_t *factor); | ||
| 46 | +T_DjiReturnCode DjiTest_CameraGetMode(E_DjiCameraMode *mode); | ||
| 47 | +T_DjiReturnCode DjiTest_CameraGetVideoStreamType(E_DjiCameraVideoStreamType *type); | ||
| 48 | +bool DjiTest_CameraIsInited(void); | ||
| 49 | +void DJI_CamEmu_base_CameraTransLock(int flag); | ||
| 50 | + | ||
| 51 | +#ifdef __cplusplus | ||
| 52 | +} | ||
| 53 | +#endif | ||
| 54 | + | ||
| 55 | +#endif // TEST_PAYLOAD_CAM_EMU_BASE_H | ||
| 56 | +/************************ (C) COPYRIGHT DJI Innovations *******END OF FILE******/ |
project_build/DJI_大疆PSDK/samples/sample_c/module_sample/camera_emu/test_payload_cam_emu_media.c
0 → 100644
| 1 | +/** | ||
| 2 | + ******************************************************************** | ||
| 3 | + * @file test_payload_cam_emu_media.c | ||
| 4 | + * @brief | ||
| 5 | + * | ||
| 6 | + * @copyright (c) 2021 DJI. All rights reserved. | ||
| 7 | + * | ||
| 8 | + * All information contained herein is, and remains, the property of DJI. | ||
| 9 | + * The intellectual and technical concepts contained herein are proprietary | ||
| 10 | + * to DJI and may be covered by U.S. and foreign patents, patents in process, | ||
| 11 | + * and protected by trade secret or copyright law. Dissemination of this | ||
| 12 | + * information, including but not limited to data and other proprietary | ||
| 13 | + * material(s) incorporated within the information, in any form, is strictly | ||
| 14 | + * prohibited without the express written consent of DJI. | ||
| 15 | + * | ||
| 16 | + * If you receive this source code without DJI’s authorization, you may not | ||
| 17 | + * further disseminate the information, and you must immediately remove the | ||
| 18 | + * source code and notify DJI of its removal. DJI reserves the right to pursue | ||
| 19 | + * legal actions against you for any loss(es) or damage(s) caused by your | ||
| 20 | + * failure to do so. | ||
| 21 | + * | ||
| 22 | + ********************************************************************* | ||
| 23 | + */ | ||
| 24 | + | ||
| 25 | +/* Includes ------------------------------------------------------------------*/ | ||
| 26 | +#include <fcntl.h> | ||
| 27 | +#include <stdlib.h> | ||
| 28 | +#include "dji_logger.h" | ||
| 29 | +#include "utils/util_misc.h" | ||
| 30 | +#include "utils/util_time.h" | ||
| 31 | +#include "utils/util_file.h" | ||
| 32 | +#include "utils/util_buffer.h" | ||
| 33 | +#include "test_payload_cam_emu_media.h" | ||
| 34 | +#include "test_payload_cam_emu_base.h" | ||
| 35 | +#include "camera_emu/dji_media_file_manage/dji_media_file_core.h" | ||
| 36 | +#include "dji_high_speed_data_channel.h" | ||
| 37 | +#include "dji_aircraft_info.h" | ||
| 38 | + | ||
| 39 | +#include "Dji_Control/DJI_VideoDeal.h" | ||
| 40 | +#include <pthread.h> | ||
| 41 | + | ||
| 42 | +/* Private constants ---------------------------------------------------------*/ | ||
| 43 | +#define FFMPEG_CMD_BUF_SIZE (256 + 256) | ||
| 44 | +#define SEND_VIDEO_TASK_FREQ 120 | ||
| 45 | +#define VIDEO_FRAME_MAX_COUNT 18000 // max video duration 10 minutes | ||
| 46 | +#define VIDEO_FRAME_AUD_LEN 6 | ||
| 47 | +#define DATA_SEND_FROM_VIDEO_STREAM_MAX_LEN 60000 | ||
| 48 | + | ||
| 49 | +//飞机传输通道值占比 | ||
| 50 | +#define TRANS_RATIO_DATA (10) | ||
| 51 | +#define TRANS_RATIO_VIDEO (85) | ||
| 52 | +#define TRANS_RATIO_DOWNLOAD (5) | ||
| 53 | + | ||
| 54 | +/* Private types -------------------------------------------------------------*/ | ||
| 55 | +typedef enum { | ||
| 56 | + TEST_PAYLOAD_CAMERA_MEDIA_PLAY_COMMAND_STOP = 0, | ||
| 57 | + TEST_PAYLOAD_CAMERA_MEDIA_PLAY_COMMAND_PAUSE = 1, | ||
| 58 | + TEST_PAYLOAD_CAMERA_MEDIA_PLAY_COMMAND_START = 2, | ||
| 59 | +} E_TestPayloadCameraPlaybackCommand; | ||
| 60 | + | ||
| 61 | +typedef struct { | ||
| 62 | + uint8_t isInPlayProcess; | ||
| 63 | + uint16_t videoIndex; | ||
| 64 | + char filePath[DJI_FILE_PATH_SIZE_MAX]; | ||
| 65 | + uint32_t videoLengthMs; | ||
| 66 | + uint64_t startPlayTimestampsUs; | ||
| 67 | + uint64_t playPosMs; | ||
| 68 | +} T_DjiPlaybackInfo; | ||
| 69 | + | ||
| 70 | +typedef struct { | ||
| 71 | + E_TestPayloadCameraPlaybackCommand command; | ||
| 72 | + uint32_t timeMs; | ||
| 73 | + char path[DJI_FILE_PATH_SIZE_MAX]; | ||
| 74 | +} T_TestPayloadCameraPlaybackCommand; | ||
| 75 | + | ||
| 76 | +typedef struct { | ||
| 77 | + float durationS; | ||
| 78 | + uint32_t positionInFile; | ||
| 79 | + uint32_t size; | ||
| 80 | +} T_TestPayloadCameraVideoFrameInfo; | ||
| 81 | + | ||
| 82 | +/* Private functions declaration ---------------------------------------------*/ | ||
| 83 | +static T_DjiReturnCode DjiPlayback_StopPlay(T_DjiPlaybackInfo *playbackInfo); | ||
| 84 | +static T_DjiReturnCode DjiPlayback_PausePlay(T_DjiPlaybackInfo *playbackInfo); | ||
| 85 | +static T_DjiReturnCode DjiPlayback_SetPlayFile(T_DjiPlaybackInfo *playbackInfo, const char *filePath, | ||
| 86 | + uint16_t index); | ||
| 87 | +static T_DjiReturnCode DjiPlayback_SeekPlay(T_DjiPlaybackInfo *playbackInfo, uint32_t seekPos); | ||
| 88 | +static T_DjiReturnCode DjiPlayback_StartPlay(T_DjiPlaybackInfo *playbackInfo); | ||
| 89 | +static T_DjiReturnCode DjiPlayback_GetPlaybackStatus(T_DjiPlaybackInfo *playbackInfo, | ||
| 90 | + T_DjiCameraPlaybackStatus *playbackStatus); | ||
| 91 | +static T_DjiReturnCode DjiPlayback_GetVideoLengthMs(const char *filePath, uint32_t *videoLengthMs); | ||
| 92 | +static T_DjiReturnCode DjiPlayback_StartPlayProcess(const char *filePath, uint32_t playPosMs); | ||
| 93 | +static T_DjiReturnCode DjiPlayback_StopPlayProcess(void); | ||
| 94 | +static T_DjiReturnCode | ||
| 95 | +DjiPlayback_VideoFileTranscode(const char *inPath, const char *outFormat, char *outPath, uint16_t outPathBufferSize); | ||
| 96 | +static T_DjiReturnCode | ||
| 97 | +DjiPlayback_GetFrameInfoOfVideoFile(const char *path, T_TestPayloadCameraVideoFrameInfo *frameInfo, | ||
| 98 | + uint32_t frameInfoBufferCount, uint32_t *frameCount); | ||
| 99 | +static T_DjiReturnCode DjiPlayback_GetFrameRateOfVideoFile(const char *path, float *frameRate); | ||
| 100 | +static T_DjiReturnCode | ||
| 101 | +DjiPlayback_GetFrameNumberByTime(T_TestPayloadCameraVideoFrameInfo *frameInfo, uint32_t frameCount, | ||
| 102 | + uint32_t *frameNumber, uint32_t timeMs); | ||
| 103 | +static T_DjiReturnCode GetMediaFileDir(char *dirPath); | ||
| 104 | +static T_DjiReturnCode GetMediaFileOriginData(const char *filePath, uint32_t offset, uint32_t length, | ||
| 105 | + uint8_t *data); | ||
| 106 | + | ||
| 107 | +static T_DjiReturnCode CreateMediaFileThumbNail(const char *filePath); | ||
| 108 | +static T_DjiReturnCode GetMediaFileThumbNailInfo(const char *filePath, T_DjiCameraMediaFileInfo *fileInfo); | ||
| 109 | +static T_DjiReturnCode GetMediaFileThumbNailData(const char *filePath, uint32_t offset, uint32_t length, | ||
| 110 | + uint8_t *data); | ||
| 111 | +static T_DjiReturnCode DestroyMediaFileThumbNail(const char *filePath); | ||
| 112 | + | ||
| 113 | +static T_DjiReturnCode CreateMediaFileScreenNail(const char *filePath); | ||
| 114 | +static T_DjiReturnCode GetMediaFileScreenNailInfo(const char *filePath, T_DjiCameraMediaFileInfo *fileInfo); | ||
| 115 | +static T_DjiReturnCode GetMediaFileScreenNailData(const char *filePath, uint32_t offset, uint32_t length, | ||
| 116 | + uint8_t *data); | ||
| 117 | +static T_DjiReturnCode DestroyMediaFileScreenNail(const char *filePath); | ||
| 118 | + | ||
| 119 | +static T_DjiReturnCode DeleteMediaFile(char *filePath); | ||
| 120 | +static T_DjiReturnCode SetMediaPlaybackFile(const char *filePath); | ||
| 121 | +static T_DjiReturnCode StartMediaPlayback(void); | ||
| 122 | +static T_DjiReturnCode StopMediaPlayback(void); | ||
| 123 | +static T_DjiReturnCode PauseMediaPlayback(void); | ||
| 124 | +static T_DjiReturnCode SeekMediaPlayback(uint32_t playbackPosition); | ||
| 125 | +static T_DjiReturnCode GetMediaPlaybackStatus(T_DjiCameraPlaybackStatus *status); | ||
| 126 | + | ||
| 127 | +static T_DjiReturnCode StartDownloadNotification(void); | ||
| 128 | +static T_DjiReturnCode StopDownloadNotification(void); | ||
| 129 | + | ||
| 130 | +_Noreturn static void *UserCameraMedia_SendVideoTask(void *arg); | ||
| 131 | +_Noreturn static void *TestCameraMedia_SendVideoTask(void *arg); | ||
| 132 | + | ||
| 133 | +/* Private variables -------------------------------------------------------------*/ | ||
| 134 | +static T_DjiCameraMediaDownloadPlaybackHandler s_psdkCameraMedia = {0}; | ||
| 135 | +static T_DjiPlaybackInfo s_playbackInfo = {0}; | ||
| 136 | +static T_DjiTaskHandle s_userSendVideoThread; | ||
| 137 | +static T_UtilBuffer s_mediaPlayCommandBufferHandler = {0}; | ||
| 138 | +static T_DjiMutexHandle s_mediaPlayCommandBufferMutex = {0}; | ||
| 139 | +static T_DjiSemaHandle s_mediaPlayWorkSem = NULL; | ||
| 140 | +static uint8_t s_mediaPlayCommandBuffer[sizeof(T_TestPayloadCameraPlaybackCommand) * 32] = {0}; | ||
| 141 | +static const char *s_frameKeyChar = "[PACKET]"; | ||
| 142 | +static const char *s_frameDurationTimeKeyChar = "duration_time"; | ||
| 143 | +static const char *s_framePositionKeyChar = "pos"; | ||
| 144 | +static const char *s_frameSizeKeyChar = "size"; | ||
| 145 | +static T_DjiMediaFileHandle s_mediaFileThumbNailHandle; | ||
| 146 | +static T_DjiMediaFileHandle s_mediaFileScreenNailHandle; | ||
| 147 | +static const uint8_t s_frameAudInfo[VIDEO_FRAME_AUD_LEN] = {0x00, 0x00, 0x00, 0x01, 0x09, 0x10}; | ||
| 148 | +static char s_mediaFileDirPath[DJI_FILE_PATH_SIZE_MAX] = {0}; | ||
| 149 | +static bool s_isMediaFileDirPathConfigured = false; | ||
| 150 | + | ||
| 151 | +/* Exported functions definition ---------------------------------------------*/ | ||
| 152 | +// 接口函数定义 | ||
| 153 | +// 照相机 菜单 媒体 开始 服务 | ||
| 154 | + | ||
| 155 | +T_DjiReturnCode DjiTest_CameraEmuMediaStartService(int mode) | ||
| 156 | +{ | ||
| 157 | + T_DjiOsalHandler *osalHandler = DjiPlatform_GetOsalHandler(); | ||
| 158 | + T_DjiReturnCode returnCode; | ||
| 159 | + const T_DjiDataChannelBandwidthProportionOfHighspeedChannel bandwidthProportionOfHighspeedChannel = | ||
| 160 | + {TRANS_RATIO_DATA, TRANS_RATIO_VIDEO, TRANS_RATIO_DOWNLOAD}; | ||
| 161 | + | ||
| 162 | + T_DjiAircraftInfoBaseInfo aircraftInfoBaseInfo = {0}; | ||
| 163 | + | ||
| 164 | + if (DjiAircraftInfo_GetBaseInfo(&aircraftInfoBaseInfo) != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) { | ||
| 165 | + USER_LOG_ERROR("get aircraft information error."); | ||
| 166 | + return DJI_ERROR_SYSTEM_MODULE_CODE_UNKNOWN; | ||
| 167 | + } | ||
| 168 | + | ||
| 169 | + s_psdkCameraMedia.GetMediaFileDir = GetMediaFileDir; | ||
| 170 | + s_psdkCameraMedia.GetMediaFileOriginInfo = DjiTest_CameraMediaGetFileInfo; | ||
| 171 | + s_psdkCameraMedia.GetMediaFileOriginData = GetMediaFileOriginData; | ||
| 172 | + | ||
| 173 | + s_psdkCameraMedia.CreateMediaFileThumbNail = CreateMediaFileThumbNail; | ||
| 174 | + s_psdkCameraMedia.GetMediaFileThumbNailInfo = GetMediaFileThumbNailInfo; | ||
| 175 | + s_psdkCameraMedia.GetMediaFileThumbNailData = GetMediaFileThumbNailData; | ||
| 176 | + s_psdkCameraMedia.DestroyMediaFileThumbNail = DestroyMediaFileThumbNail; | ||
| 177 | + | ||
| 178 | + s_psdkCameraMedia.CreateMediaFileScreenNail = CreateMediaFileScreenNail; | ||
| 179 | + s_psdkCameraMedia.GetMediaFileScreenNailInfo = GetMediaFileScreenNailInfo; | ||
| 180 | + s_psdkCameraMedia.GetMediaFileScreenNailData = GetMediaFileScreenNailData; | ||
| 181 | + s_psdkCameraMedia.DestroyMediaFileScreenNail = DestroyMediaFileScreenNail; | ||
| 182 | + | ||
| 183 | + s_psdkCameraMedia.DeleteMediaFile = DeleteMediaFile; | ||
| 184 | + | ||
| 185 | + s_psdkCameraMedia.SetMediaPlaybackFile = SetMediaPlaybackFile; | ||
| 186 | + | ||
| 187 | + s_psdkCameraMedia.StartMediaPlayback = StartMediaPlayback; | ||
| 188 | + s_psdkCameraMedia.StopMediaPlayback = StopMediaPlayback; | ||
| 189 | + s_psdkCameraMedia.PauseMediaPlayback = PauseMediaPlayback; | ||
| 190 | + s_psdkCameraMedia.SeekMediaPlayback = SeekMediaPlayback; | ||
| 191 | + s_psdkCameraMedia.GetMediaPlaybackStatus = GetMediaPlaybackStatus; | ||
| 192 | + | ||
| 193 | + s_psdkCameraMedia.StartDownloadNotification = StartDownloadNotification; | ||
| 194 | + s_psdkCameraMedia.StopDownloadNotification = StopDownloadNotification; | ||
| 195 | + | ||
| 196 | + if (DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS != osalHandler->SemaphoreCreate(0, &s_mediaPlayWorkSem)) { | ||
| 197 | + USER_LOG_ERROR("SemaphoreCreate(\"%s\") error.", "s_mediaPlayWorkSem"); | ||
| 198 | + return DJI_ERROR_SYSTEM_MODULE_CODE_UNKNOWN; | ||
| 199 | + } | ||
| 200 | + | ||
| 201 | + if (osalHandler->MutexCreate(&s_mediaPlayCommandBufferMutex) != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) { | ||
| 202 | + USER_LOG_ERROR("mutex create error"); | ||
| 203 | + return DJI_ERROR_SYSTEM_MODULE_CODE_UNKNOWN; | ||
| 204 | + } | ||
| 205 | + | ||
| 206 | + UtilBuffer_Init(&s_mediaPlayCommandBufferHandler, s_mediaPlayCommandBuffer, sizeof(s_mediaPlayCommandBuffer)); | ||
| 207 | + | ||
| 208 | + if (aircraftInfoBaseInfo.aircraftType == DJI_AIRCRAFT_TYPE_M300_RTK || | ||
| 209 | + aircraftInfoBaseInfo.aircraftType == DJI_AIRCRAFT_TYPE_M350_RTK) { | ||
| 210 | + returnCode = DjiPayloadCamera_RegMediaDownloadPlaybackHandler(&s_psdkCameraMedia); | ||
| 211 | + if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) { | ||
| 212 | + USER_LOG_ERROR("psdk camera media function init error."); | ||
| 213 | + return DJI_ERROR_SYSTEM_MODULE_CODE_UNKNOWN; | ||
| 214 | + } | ||
| 215 | + } | ||
| 216 | + | ||
| 217 | + returnCode = DjiHighSpeedDataChannel_SetBandwidthProportion(bandwidthProportionOfHighspeedChannel); | ||
| 218 | + if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) { | ||
| 219 | + USER_LOG_ERROR("Set data channel bandwidth width proportion error."); | ||
| 220 | + return DJI_ERROR_SYSTEM_MODULE_CODE_UNKNOWN; | ||
| 221 | + } | ||
| 222 | + | ||
| 223 | + if (mode == 0) | ||
| 224 | + { | ||
| 225 | + // 大疆平台 获得 套接字 权柄 | ||
| 226 | + if (DjiPlatform_GetHalNetworkHandler() != NULL || DjiPlatform_GetHalUsbBulkHandler() != NULL) { | ||
| 227 | + // 创建相机媒体任务,使用者相机媒体任务, | ||
| 228 | + returnCode = osalHandler->TaskCreate("user_camera_media_task", UserCameraMedia_SendVideoTask, 2048, | ||
| 229 | + NULL, &s_userSendVideoThread); | ||
| 230 | + if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) { | ||
| 231 | + USER_LOG_ERROR("user send video task create error."); | ||
| 232 | + return DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS; | ||
| 233 | + } | ||
| 234 | + } | ||
| 235 | + } | ||
| 236 | + else if (mode == 1) | ||
| 237 | + { | ||
| 238 | + if (DjiPlatform_GetHalNetworkHandler() != NULL || DjiPlatform_GetHalUsbBulkHandler() != NULL) { | ||
| 239 | + // 创建测试图传线程 | ||
| 240 | + returnCode = osalHandler->TaskCreate("user_camera_media_task", TestCameraMedia_SendVideoTask, 2048, | ||
| 241 | + NULL, &s_userSendVideoThread); | ||
| 242 | + if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) { | ||
| 243 | + USER_LOG_ERROR("user send video task create error."); | ||
| 244 | + return DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS; | ||
| 245 | + } | ||
| 246 | + } | ||
| 247 | + } | ||
| 248 | + | ||
| 249 | + return DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS; | ||
| 250 | +} | ||
| 251 | + | ||
| 252 | +T_DjiReturnCode DjiTest_CameraEmuSetMediaFilePath(const char *path) | ||
| 253 | +{ | ||
| 254 | + memset(s_mediaFileDirPath, 0, sizeof(s_mediaFileDirPath)); | ||
| 255 | + memcpy(s_mediaFileDirPath, path, USER_UTIL_MIN(strlen(path), sizeof(s_mediaFileDirPath) - 1)); | ||
| 256 | + s_isMediaFileDirPathConfigured = true; | ||
| 257 | + | ||
| 258 | + return DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS; | ||
| 259 | +} | ||
| 260 | + | ||
| 261 | +T_DjiReturnCode DjiTest_CameraMediaGetFileInfo(const char *filePath, T_DjiCameraMediaFileInfo *fileInfo) | ||
| 262 | +{ | ||
| 263 | + T_DjiReturnCode returnCode; | ||
| 264 | + T_DjiMediaFileHandle mediaFileHandle; | ||
| 265 | + | ||
| 266 | + returnCode = DjiMediaFile_CreateHandle(filePath, &mediaFileHandle); | ||
| 267 | + if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) { | ||
| 268 | + USER_LOG_ERROR("Media file create handle error stat:0x%08llX", returnCode); | ||
| 269 | + return returnCode; | ||
| 270 | + } | ||
| 271 | + | ||
| 272 | + returnCode = DjiMediaFile_GetMediaFileType(mediaFileHandle, &fileInfo->type); | ||
| 273 | + if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) { | ||
| 274 | + USER_LOG_ERROR("Media file get type error stat:0x%08llX", returnCode); | ||
| 275 | + goto out; | ||
| 276 | + } | ||
| 277 | + | ||
| 278 | + returnCode = DjiMediaFile_GetMediaFileAttr(mediaFileHandle, &fileInfo->mediaFileAttr); | ||
| 279 | + if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) { | ||
| 280 | + USER_LOG_ERROR("Media file get attr error stat:0x%08llX", returnCode); | ||
| 281 | + goto out; | ||
| 282 | + } | ||
| 283 | + | ||
| 284 | + returnCode = DjiMediaFile_GetFileSizeOrg(mediaFileHandle, &fileInfo->fileSize); | ||
| 285 | + if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) { | ||
| 286 | + USER_LOG_ERROR("Media file get size error stat:0x%08llX", returnCode); | ||
| 287 | + goto out; | ||
| 288 | + } | ||
| 289 | + | ||
| 290 | +out: | ||
| 291 | + returnCode = DjiMediaFile_DestroyHandle(mediaFileHandle); | ||
| 292 | + if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) { | ||
| 293 | + USER_LOG_ERROR("Media file destroy handle error stat:0x%08llX", returnCode); | ||
| 294 | + return returnCode; | ||
| 295 | + } | ||
| 296 | + | ||
| 297 | + return returnCode; | ||
| 298 | +} | ||
| 299 | + | ||
| 300 | +/* Private functions definition-----------------------------------------------*/ | ||
| 301 | +static T_DjiReturnCode DjiPlayback_StopPlay(T_DjiPlaybackInfo *playbackInfo) | ||
| 302 | +{ | ||
| 303 | + T_DjiReturnCode returnCode; | ||
| 304 | + | ||
| 305 | + returnCode = DjiPlayback_StopPlayProcess(); | ||
| 306 | + if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) { | ||
| 307 | + USER_LOG_ERROR("stop play error "); | ||
| 308 | + } | ||
| 309 | + | ||
| 310 | + playbackInfo->isInPlayProcess = 0; | ||
| 311 | + playbackInfo->playPosMs = 0; | ||
| 312 | + | ||
| 313 | + return returnCode; | ||
| 314 | +} | ||
| 315 | + | ||
| 316 | +static T_DjiReturnCode DjiPlayback_PausePlay(T_DjiPlaybackInfo *playbackInfo) | ||
| 317 | +{ | ||
| 318 | + T_DjiReturnCode returnCode = DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS; | ||
| 319 | + T_DjiOsalHandler *osalHandler = DjiPlatform_GetOsalHandler(); | ||
| 320 | + | ||
| 321 | + T_TestPayloadCameraPlaybackCommand playbackCommand = {0}; | ||
| 322 | + if (playbackInfo->isInPlayProcess) { | ||
| 323 | + playbackCommand.command = TEST_PAYLOAD_CAMERA_MEDIA_PLAY_COMMAND_PAUSE; | ||
| 324 | + | ||
| 325 | + if (osalHandler->MutexLock(s_mediaPlayCommandBufferMutex) != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) { | ||
| 326 | + USER_LOG_ERROR("mutex lock error"); | ||
| 327 | + return DJI_ERROR_SYSTEM_MODULE_CODE_UNKNOWN; | ||
| 328 | + } | ||
| 329 | + | ||
| 330 | + if (UtilBuffer_GetUnusedSize(&s_mediaPlayCommandBufferHandler) >= sizeof(T_TestPayloadCameraPlaybackCommand)) { | ||
| 331 | + UtilBuffer_Put(&s_mediaPlayCommandBufferHandler, (const uint8_t *) &playbackCommand, | ||
| 332 | + sizeof(T_TestPayloadCameraPlaybackCommand)); | ||
| 333 | + } else { | ||
| 334 | + USER_LOG_ERROR("Media playback command buffer is full."); | ||
| 335 | + returnCode = DJI_ERROR_SYSTEM_MODULE_CODE_OUT_OF_RANGE; | ||
| 336 | + } | ||
| 337 | + | ||
| 338 | + if (osalHandler->MutexUnlock(s_mediaPlayCommandBufferMutex) != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) { | ||
| 339 | + USER_LOG_ERROR("mutex unlock error"); | ||
| 340 | + return DJI_ERROR_SYSTEM_MODULE_CODE_UNKNOWN; | ||
| 341 | + } | ||
| 342 | + osalHandler->SemaphorePost(s_mediaPlayWorkSem); | ||
| 343 | + } | ||
| 344 | + | ||
| 345 | + playbackInfo->isInPlayProcess = 0; | ||
| 346 | + | ||
| 347 | + return returnCode; | ||
| 348 | +} | ||
| 349 | + | ||
| 350 | +static T_DjiReturnCode DjiPlayback_SetPlayFile(T_DjiPlaybackInfo *playbackInfo, const char *filePath, uint16_t index) | ||
| 351 | +{ | ||
| 352 | + T_DjiReturnCode returnCode; | ||
| 353 | + | ||
| 354 | + if (strlen(filePath) > DJI_FILE_PATH_SIZE_MAX) { | ||
| 355 | + USER_LOG_ERROR("Dji playback file path out of length range error\n"); | ||
| 356 | + return DJI_ERROR_SYSTEM_MODULE_CODE_INVALID_PARAMETER; | ||
| 357 | + } | ||
| 358 | + | ||
| 359 | + strcpy(playbackInfo->filePath, filePath); | ||
| 360 | + playbackInfo->videoIndex = index; | ||
| 361 | + | ||
| 362 | + returnCode = DjiPlayback_GetVideoLengthMs(filePath, &playbackInfo->videoLengthMs); | ||
| 363 | + | ||
| 364 | + if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) { | ||
| 365 | + return DJI_ERROR_SYSTEM_MODULE_CODE_UNKNOWN; | ||
| 366 | + } | ||
| 367 | + | ||
| 368 | + return DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS; | ||
| 369 | +} | ||
| 370 | + | ||
| 371 | +static T_DjiReturnCode DjiPlayback_SeekPlay(T_DjiPlaybackInfo *playbackInfo, uint32_t seekPos) | ||
| 372 | +{ | ||
| 373 | + T_DjiRunTimeStamps ti; | ||
| 374 | + T_DjiReturnCode returnCode; | ||
| 375 | + | ||
| 376 | + returnCode = DjiPlayback_PausePlay(playbackInfo); | ||
| 377 | + if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) { | ||
| 378 | + USER_LOG_ERROR("pause play error \n"); | ||
| 379 | + return returnCode; | ||
| 380 | + } | ||
| 381 | + | ||
| 382 | + playbackInfo->playPosMs = seekPos; | ||
| 383 | + returnCode = DjiPlayback_StartPlayProcess(playbackInfo->filePath, playbackInfo->playPosMs); | ||
| 384 | + if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) { | ||
| 385 | + USER_LOG_ERROR("start playback process error \n"); | ||
| 386 | + return returnCode; | ||
| 387 | + } | ||
| 388 | + | ||
| 389 | + playbackInfo->isInPlayProcess = 1; | ||
| 390 | + ti = DjiUtilTime_GetRunTimeStamps(); | ||
| 391 | + playbackInfo->startPlayTimestampsUs = ti.realUsec - playbackInfo->playPosMs * 1000; | ||
| 392 | + | ||
| 393 | + return DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS; | ||
| 394 | +} | ||
| 395 | + | ||
| 396 | +static T_DjiReturnCode DjiPlayback_StartPlay(T_DjiPlaybackInfo *playbackInfo) | ||
| 397 | +{ | ||
| 398 | + T_DjiRunTimeStamps ti; | ||
| 399 | + T_DjiReturnCode returnCode; | ||
| 400 | + | ||
| 401 | + if (playbackInfo->isInPlayProcess == 1) { | ||
| 402 | + //already in playing, return DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS | ||
| 403 | + return DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS; | ||
| 404 | + } | ||
| 405 | + | ||
| 406 | + returnCode = DjiPlayback_StartPlayProcess(playbackInfo->filePath, playbackInfo->playPosMs); | ||
| 407 | + if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) { | ||
| 408 | + USER_LOG_ERROR("start play process error \n"); | ||
| 409 | + return returnCode; | ||
| 410 | + } | ||
| 411 | + | ||
| 412 | + playbackInfo->isInPlayProcess = 1; | ||
| 413 | + | ||
| 414 | + ti = DjiUtilTime_GetRunTimeStamps(); | ||
| 415 | + playbackInfo->startPlayTimestampsUs = ti.realUsec - playbackInfo->playPosMs * 1000; | ||
| 416 | + | ||
| 417 | + return DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS; | ||
| 418 | +} | ||
| 419 | + | ||
| 420 | +static T_DjiReturnCode DjiPlayback_GetPlaybackStatus(T_DjiPlaybackInfo *playbackInfo, | ||
| 421 | + T_DjiCameraPlaybackStatus *playbackStatus) | ||
| 422 | +{ | ||
| 423 | + T_DjiRunTimeStamps timeStamps; | ||
| 424 | + | ||
| 425 | + memset(playbackStatus, 0, sizeof(T_DjiCameraPlaybackStatus)); | ||
| 426 | + | ||
| 427 | + //update playback pos info | ||
| 428 | + if (playbackInfo->isInPlayProcess) { | ||
| 429 | + timeStamps = DjiUtilTime_GetRunTimeStamps(); | ||
| 430 | + playbackInfo->playPosMs = (timeStamps.realUsec - playbackInfo->startPlayTimestampsUs) / 1000; | ||
| 431 | + | ||
| 432 | + if (playbackInfo->playPosMs >= playbackInfo->videoLengthMs) { | ||
| 433 | + if (DjiPlayback_PausePlay(playbackInfo) != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) { | ||
| 434 | + return DJI_ERROR_SYSTEM_MODULE_CODE_UNKNOWN; | ||
| 435 | + } | ||
| 436 | + } | ||
| 437 | + } | ||
| 438 | + | ||
| 439 | + //set playback status | ||
| 440 | + if (playbackInfo->isInPlayProcess == 0 && playbackInfo->playPosMs != 0) { | ||
| 441 | + playbackStatus->playbackMode = DJI_CAMERA_PLAYBACK_MODE_PAUSE; | ||
| 442 | + } else if (playbackInfo->isInPlayProcess) { | ||
| 443 | + playbackStatus->playbackMode = DJI_CAMERA_PLAYBACK_MODE_PLAY; | ||
| 444 | + } else { | ||
| 445 | + playbackStatus->playbackMode = DJI_CAMERA_PLAYBACK_MODE_STOP; | ||
| 446 | + } | ||
| 447 | + | ||
| 448 | + playbackStatus->playPosMs = playbackInfo->playPosMs; | ||
| 449 | + playbackStatus->videoLengthMs = playbackInfo->videoLengthMs; | ||
| 450 | + | ||
| 451 | + if (playbackInfo->videoLengthMs != 0) { | ||
| 452 | + playbackStatus->videoPlayProcess = | ||
| 453 | + (playbackInfo->videoLengthMs - playbackInfo->playPosMs) / playbackInfo->videoLengthMs; | ||
| 454 | + } else { | ||
| 455 | + playbackStatus->videoPlayProcess = 0; | ||
| 456 | + } | ||
| 457 | + | ||
| 458 | + return DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS; | ||
| 459 | +} | ||
| 460 | + | ||
| 461 | +// 获取视频长度 | ||
| 462 | +static T_DjiReturnCode DjiPlayback_GetVideoLengthMs(const char *filePath, uint32_t *videoLengthMs) | ||
| 463 | +{ | ||
| 464 | + FILE *fp; | ||
| 465 | + T_DjiReturnCode returnCode; | ||
| 466 | + char ffmpegCmdStr[FFMPEG_CMD_BUF_SIZE]; | ||
| 467 | + float hour, minute, second; | ||
| 468 | + char tempTailStr[128]; | ||
| 469 | + int ret; | ||
| 470 | + | ||
| 471 | + snprintf(ffmpegCmdStr, FFMPEG_CMD_BUF_SIZE, "ffmpeg -i \"%s\" 2>&1 | grep \"Duration\"", filePath); | ||
| 472 | + fp = popen(ffmpegCmdStr, "r"); | ||
| 473 | + | ||
| 474 | + if (fp == NULL) { | ||
| 475 | + return DJI_ERROR_SYSTEM_MODULE_CODE_SYSTEM_ERROR; | ||
| 476 | + } | ||
| 477 | + | ||
| 478 | + ret = fscanf(fp, " Duration: %f:%f:%f,%127s", &hour, &minute, &second, tempTailStr); | ||
| 479 | + if (ret <= 0) { | ||
| 480 | + USER_LOG_ERROR("MP4 File Get Duration Error\n"); | ||
| 481 | + returnCode = DJI_ERROR_SYSTEM_MODULE_CODE_SYSTEM_ERROR; | ||
| 482 | + goto out; | ||
| 483 | + } | ||
| 484 | + | ||
| 485 | + *videoLengthMs = (uint32_t) ((hour * 3600 + minute * 60 + second) * 1000); | ||
| 486 | + returnCode = DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS; | ||
| 487 | + | ||
| 488 | +out: | ||
| 489 | + pclose(fp); | ||
| 490 | + | ||
| 491 | + return returnCode; | ||
| 492 | +} | ||
| 493 | + | ||
| 494 | + | ||
| 495 | +// 开始播放进程 | ||
| 496 | +static T_DjiReturnCode DjiPlayback_StartPlayProcess(const char *filePath, uint32_t playPosMs) | ||
| 497 | +{ | ||
| 498 | + T_DjiReturnCode returnCode = DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS; | ||
| 499 | + T_TestPayloadCameraPlaybackCommand mediaPlayCommand = {0}; | ||
| 500 | + T_DjiOsalHandler *osalHandler = DjiPlatform_GetOsalHandler(); | ||
| 501 | + | ||
| 502 | + mediaPlayCommand.command = TEST_PAYLOAD_CAMERA_MEDIA_PLAY_COMMAND_START; | ||
| 503 | + mediaPlayCommand.timeMs = playPosMs; | ||
| 504 | + | ||
| 505 | + if (strlen(filePath) >= sizeof(mediaPlayCommand.path)) { | ||
| 506 | + USER_LOG_ERROR("File path is too long."); | ||
| 507 | + return DJI_ERROR_SYSTEM_MODULE_CODE_OUT_OF_RANGE; | ||
| 508 | + } | ||
| 509 | + memcpy(mediaPlayCommand.path, filePath, strlen(filePath)); | ||
| 510 | + | ||
| 511 | + if (osalHandler->MutexLock(s_mediaPlayCommandBufferMutex) != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) { | ||
| 512 | + USER_LOG_ERROR("mutex lock error"); | ||
| 513 | + return DJI_ERROR_SYSTEM_MODULE_CODE_UNKNOWN; | ||
| 514 | + } | ||
| 515 | + | ||
| 516 | + if (UtilBuffer_GetUnusedSize(&s_mediaPlayCommandBufferHandler) >= sizeof(T_TestPayloadCameraPlaybackCommand)) { | ||
| 517 | + UtilBuffer_Put(&s_mediaPlayCommandBufferHandler, (const uint8_t *) &mediaPlayCommand, | ||
| 518 | + sizeof(T_TestPayloadCameraPlaybackCommand)); | ||
| 519 | + } else { | ||
| 520 | + USER_LOG_ERROR("Media playback command buffer is full."); | ||
| 521 | + returnCode = DJI_ERROR_SYSTEM_MODULE_CODE_OUT_OF_RANGE; | ||
| 522 | + } | ||
| 523 | + | ||
| 524 | + if (osalHandler->MutexUnlock(s_mediaPlayCommandBufferMutex) != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) { | ||
| 525 | + USER_LOG_ERROR("mutex unlock error"); | ||
| 526 | + return DJI_ERROR_SYSTEM_MODULE_CODE_UNKNOWN; | ||
| 527 | + } | ||
| 528 | + osalHandler->SemaphorePost(s_mediaPlayWorkSem); | ||
| 529 | + return returnCode; | ||
| 530 | +} | ||
| 531 | + | ||
| 532 | +static T_DjiReturnCode DjiPlayback_StopPlayProcess(void) | ||
| 533 | +{ | ||
| 534 | + T_DjiReturnCode returnCode = DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS; | ||
| 535 | + T_TestPayloadCameraPlaybackCommand playbackCommand = {0}; | ||
| 536 | + T_DjiOsalHandler *osalHandler = DjiPlatform_GetOsalHandler(); | ||
| 537 | + | ||
| 538 | + playbackCommand.command = TEST_PAYLOAD_CAMERA_MEDIA_PLAY_COMMAND_STOP; | ||
| 539 | + | ||
| 540 | + if (osalHandler->MutexLock(s_mediaPlayCommandBufferMutex) != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) { | ||
| 541 | + USER_LOG_ERROR("mutex lock error"); | ||
| 542 | + return DJI_ERROR_SYSTEM_MODULE_CODE_UNKNOWN; | ||
| 543 | + } | ||
| 544 | + | ||
| 545 | + if (UtilBuffer_GetUnusedSize(&s_mediaPlayCommandBufferHandler) >= sizeof(T_TestPayloadCameraPlaybackCommand)) { | ||
| 546 | + UtilBuffer_Put(&s_mediaPlayCommandBufferHandler, (const uint8_t *) &playbackCommand, | ||
| 547 | + sizeof(T_TestPayloadCameraPlaybackCommand)); | ||
| 548 | + } else { | ||
| 549 | + USER_LOG_ERROR("Media playback command buffer is full."); | ||
| 550 | + returnCode = DJI_ERROR_SYSTEM_MODULE_CODE_OUT_OF_RANGE; | ||
| 551 | + } | ||
| 552 | + | ||
| 553 | + if (osalHandler->MutexUnlock(s_mediaPlayCommandBufferMutex) != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) { | ||
| 554 | + USER_LOG_ERROR("mutex unlock error"); | ||
| 555 | + return DJI_ERROR_SYSTEM_MODULE_CODE_UNKNOWN; | ||
| 556 | + } | ||
| 557 | + osalHandler->SemaphorePost(s_mediaPlayWorkSem); | ||
| 558 | + return returnCode; | ||
| 559 | +} | ||
| 560 | + | ||
| 561 | +static T_DjiReturnCode DjiPlayback_VideoFileTranscode(const char *inPath, const char *outFormat, char *outPath, | ||
| 562 | + uint16_t outPathBufferSize) | ||
| 563 | +{ | ||
| 564 | + T_DjiReturnCode returnCode = DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS; | ||
| 565 | + T_DjiReturnCode djiStatus = DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS; | ||
| 566 | + FILE *fpCommand = NULL; | ||
| 567 | + char ffmpegCmdStr[FFMPEG_CMD_BUF_SIZE]; | ||
| 568 | + char *directory = NULL; | ||
| 569 | + T_DjiOsalHandler *osalHandler = DjiPlatform_GetOsalHandler(); | ||
| 570 | + | ||
| 571 | + directory = osalHandler->Malloc(DJI_FILE_PATH_SIZE_MAX); | ||
| 572 | + if (directory == NULL) { | ||
| 573 | + USER_LOG_ERROR("malloc memory for directory fail."); | ||
| 574 | + return DJI_ERROR_SYSTEM_MODULE_CODE_MEMORY_ALLOC_FAILED; | ||
| 575 | + } | ||
| 576 | + | ||
| 577 | + // USER_LOG_INFO("inPath%s",inPath); | ||
| 578 | + | ||
| 579 | + djiStatus = DjiUserUtil_GetCurrentFileDirPath(inPath, DJI_FILE_PATH_SIZE_MAX, directory); | ||
| 580 | + if (djiStatus != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) { | ||
| 581 | + USER_LOG_ERROR("get directory of file error: 0x%08llX.", djiStatus); | ||
| 582 | + returnCode = djiStatus; | ||
| 583 | + goto out; | ||
| 584 | + } | ||
| 585 | + | ||
| 586 | + // USER_LOG_INFO("inPath%s",inPath); | ||
| 587 | + | ||
| 588 | + snprintf(outPath, outPathBufferSize, "%sout.%s", directory, outFormat); | ||
| 589 | + // 结果为 /root/sdcard/media_file/out.h264 | ||
| 590 | + USER_LOG_INFO("%sout.%s ", directory, outFormat); | ||
| 591 | + snprintf(ffmpegCmdStr, FFMPEG_CMD_BUF_SIZE, | ||
| 592 | + "echo \"y\" | ffmpeg -i \"%s\" -codec copy -f \"%s\" \"%s\" 1>/dev/null 2>&1", inPath, | ||
| 593 | + outFormat, outPath); | ||
| 594 | + // 结果为 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 | ||
| 595 | + USER_LOG_INFO("ffmpegCmdStr:%s",ffmpegCmdStr); | ||
| 596 | + fpCommand = popen(ffmpegCmdStr, "r"); | ||
| 597 | + if (fpCommand == NULL) { | ||
| 598 | + USER_LOG_ERROR("execute transcode command fail."); | ||
| 599 | + returnCode = DJI_ERROR_SYSTEM_MODULE_CODE_UNKNOWN; | ||
| 600 | + goto out; | ||
| 601 | + } | ||
| 602 | + | ||
| 603 | + pclose(fpCommand); | ||
| 604 | + | ||
| 605 | +out: | ||
| 606 | + osalHandler->Free(directory); | ||
| 607 | + | ||
| 608 | + return returnCode; | ||
| 609 | +} | ||
| 610 | + | ||
| 611 | + | ||
| 612 | +// 获得视频的帧信息 | ||
| 613 | +static T_DjiReturnCode | ||
| 614 | +DjiPlayback_GetFrameInfoOfVideoFile(const char *path, T_TestPayloadCameraVideoFrameInfo *frameInfo, | ||
| 615 | + uint32_t frameInfoBufferCount, uint32_t *frameCount) | ||
| 616 | +{ | ||
| 617 | + long ret; | ||
| 618 | + T_DjiReturnCode returnCode = DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS; | ||
| 619 | + FILE *fpCommand = NULL; | ||
| 620 | + char ffmpegCmdStr[FFMPEG_CMD_BUF_SIZE]; | ||
| 621 | + char *frameInfoString = NULL; | ||
| 622 | + char *frameLocation = NULL; | ||
| 623 | + char frameParameterFormat[50] = {0}; | ||
| 624 | + char *frameDurationTimeLocation = NULL; | ||
| 625 | + float frameDurationTimeS = 0; | ||
| 626 | + uint32_t frameNumber = 0; | ||
| 627 | + char *framePositionLocation = NULL; | ||
| 628 | + uint32_t framePosition = 0; | ||
| 629 | + char *frameSizeLocation = NULL; | ||
| 630 | + uint32_t frameSize = 0; | ||
| 631 | + T_DjiOsalHandler *osalHandler = DjiPlatform_GetOsalHandler(); | ||
| 632 | + | ||
| 633 | + frameInfoString = osalHandler->Malloc(VIDEO_FRAME_MAX_COUNT * 1024); | ||
| 634 | + if (frameInfoString == NULL) { | ||
| 635 | + USER_LOG_ERROR("malloc memory for frame info fail."); | ||
| 636 | + return DJI_ERROR_SYSTEM_MODULE_CODE_MEMORY_ALLOC_FAILED; | ||
| 637 | + } | ||
| 638 | + memset(frameInfoString, 0, VIDEO_FRAME_MAX_COUNT * 1024); | ||
| 639 | + | ||
| 640 | + snprintf(ffmpegCmdStr, FFMPEG_CMD_BUF_SIZE, "ffprobe -show_packets \"%s\" 2>/dev/null", path); | ||
| 641 | + fpCommand = popen(ffmpegCmdStr, "r"); | ||
| 642 | + if (fpCommand == NULL) { | ||
| 643 | + USER_LOG_ERROR("execute show frames commands fail."); | ||
| 644 | + returnCode = DJI_ERROR_SYSTEM_MODULE_CODE_UNKNOWN; | ||
| 645 | + goto out2; | ||
| 646 | + } | ||
| 647 | + | ||
| 648 | + ret = (long) fread(frameInfoString, 1, VIDEO_FRAME_MAX_COUNT * 1024, fpCommand); | ||
| 649 | + if (ret < 0) { | ||
| 650 | + USER_LOG_ERROR("read show frames commands result error."); | ||
| 651 | + goto out1; | ||
| 652 | + } | ||
| 653 | + frameInfoString[ret] = '\0'; | ||
| 654 | + | ||
| 655 | + frameLocation = frameInfoString; | ||
| 656 | + *frameCount = 0; | ||
| 657 | + while (1) { | ||
| 658 | + // find frame | ||
| 659 | + frameLocation = strstr(frameLocation, s_frameKeyChar); | ||
| 660 | + if (frameLocation == NULL) { | ||
| 661 | + USER_LOG_DEBUG("reach file tail."); | ||
| 662 | + break; | ||
| 663 | + } | ||
| 664 | + | ||
| 665 | + // find frame duration | ||
| 666 | + frameDurationTimeLocation = strstr(frameLocation, s_frameDurationTimeKeyChar); | ||
| 667 | + if (frameDurationTimeLocation == NULL) { | ||
| 668 | + USER_LOG_ERROR("can not find pkt_duration_time."); | ||
| 669 | + returnCode = DJI_ERROR_SYSTEM_MODULE_CODE_NOT_FOUND; | ||
| 670 | + goto out1; | ||
| 671 | + } | ||
| 672 | + | ||
| 673 | + ret = snprintf(frameParameterFormat, sizeof(frameParameterFormat), "%s=%%f", s_frameDurationTimeKeyChar); | ||
| 674 | + if (ret < 0) { | ||
| 675 | + USER_LOG_ERROR("snprintf frameParameterFormat fail."); | ||
| 676 | + returnCode = DJI_ERROR_SYSTEM_MODULE_CODE_UNKNOWN; | ||
| 677 | + goto out1; | ||
| 678 | + } | ||
| 679 | + | ||
| 680 | + ret = sscanf(frameDurationTimeLocation, frameParameterFormat, &frameDurationTimeS); | ||
| 681 | + if (ret <= 0) { | ||
| 682 | + USER_LOG_ERROR("can not find pkt_duration_time."); | ||
| 683 | + returnCode = DJI_ERROR_SYSTEM_MODULE_CODE_NOT_FOUND; | ||
| 684 | + goto out1; | ||
| 685 | + } | ||
| 686 | + frameInfo[frameNumber].durationS = frameDurationTimeS; | ||
| 687 | + | ||
| 688 | + // find frame position | ||
| 689 | + framePositionLocation = strstr(frameLocation, s_framePositionKeyChar); | ||
| 690 | + if (framePositionLocation == NULL) { | ||
| 691 | + USER_LOG_ERROR("can not found pkt_pos."); | ||
| 692 | + returnCode = DJI_ERROR_SYSTEM_MODULE_CODE_NOT_FOUND; | ||
| 693 | + goto out1; | ||
| 694 | + } | ||
| 695 | + | ||
| 696 | + ret = snprintf(frameParameterFormat, sizeof(frameParameterFormat), "%s=%%d", s_framePositionKeyChar); | ||
| 697 | + if (ret < 0) { | ||
| 698 | + USER_LOG_ERROR("snprintf frameParameterFormat fail."); | ||
| 699 | + returnCode = DJI_ERROR_SYSTEM_MODULE_CODE_UNKNOWN; | ||
| 700 | + goto out1; | ||
| 701 | + } | ||
| 702 | + | ||
| 703 | + ret = sscanf(framePositionLocation, frameParameterFormat, &framePosition); | ||
| 704 | + if (ret <= 0) { | ||
| 705 | + USER_LOG_ERROR("can not found pkt_pos."); | ||
| 706 | + returnCode = DJI_ERROR_SYSTEM_MODULE_CODE_NOT_FOUND; | ||
| 707 | + goto out1; | ||
| 708 | + } | ||
| 709 | + frameInfo[frameNumber].positionInFile = framePosition; | ||
| 710 | + | ||
| 711 | + // find frame size | ||
| 712 | + //frameSizeLocation 由 frameLocation s_frameSizeKeyChar 拼接而成 | ||
| 713 | + | ||
| 714 | + frameSizeLocation = strstr(frameLocation, s_frameSizeKeyChar); | ||
| 715 | + if (frameSizeLocation == NULL) { | ||
| 716 | + USER_LOG_ERROR("can not found pkt_size."); | ||
| 717 | + returnCode = DJI_ERROR_SYSTEM_MODULE_CODE_NOT_FOUND; | ||
| 718 | + goto out1; | ||
| 719 | + } | ||
| 720 | + | ||
| 721 | + ret = snprintf(frameParameterFormat, sizeof(frameParameterFormat), "%s=%%d", s_frameSizeKeyChar); | ||
| 722 | + if (ret < 0) { | ||
| 723 | + USER_LOG_ERROR("snprintf frameParameterFormat fail."); | ||
| 724 | + returnCode = DJI_ERROR_SYSTEM_MODULE_CODE_UNKNOWN; | ||
| 725 | + goto out1; | ||
| 726 | + } | ||
| 727 | + | ||
| 728 | + | ||
| 729 | + // 从frameSizeLocation 读取数据流 到 frameSize | ||
| 730 | + ret = sscanf(frameSizeLocation, frameParameterFormat, &frameSize); | ||
| 731 | + if (ret <= 0) { | ||
| 732 | + USER_LOG_ERROR("can not find pkt_size."); | ||
| 733 | + returnCode = DJI_ERROR_SYSTEM_MODULE_CODE_NOT_FOUND; | ||
| 734 | + goto out1; | ||
| 735 | + } | ||
| 736 | + frameInfo[frameNumber].size = frameSize; | ||
| 737 | + | ||
| 738 | + frameLocation += strlen(s_frameKeyChar); | ||
| 739 | + frameNumber++; | ||
| 740 | + (*frameCount)++; | ||
| 741 | + | ||
| 742 | + if (frameNumber >= frameInfoBufferCount) { | ||
| 743 | + USER_LOG_ERROR("frame buffer is full."); | ||
| 744 | + returnCode = DJI_ERROR_SYSTEM_MODULE_CODE_OUT_OF_RANGE; | ||
| 745 | + goto out1; | ||
| 746 | + } | ||
| 747 | + } | ||
| 748 | + | ||
| 749 | +out1: | ||
| 750 | + pclose(fpCommand); | ||
| 751 | + | ||
| 752 | +out2: | ||
| 753 | + osalHandler->Free(frameInfoString); | ||
| 754 | + | ||
| 755 | + return returnCode; | ||
| 756 | +} | ||
| 757 | + | ||
| 758 | + | ||
| 759 | +//获取视频的帧速率 | ||
| 760 | +static T_DjiReturnCode DjiPlayback_GetFrameRateOfVideoFile(const char *path, float *frameRate) | ||
| 761 | +{ | ||
| 762 | + int ret; | ||
| 763 | + T_DjiReturnCode returnCode = DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS; | ||
| 764 | + FILE *fpCommand = NULL; | ||
| 765 | + char ffmpegCmdStr[FFMPEG_CMD_BUF_SIZE] = {0}; | ||
| 766 | + int frameRateMolecule = 0; | ||
| 767 | + int frameRateDenominator = 0; | ||
| 768 | + | ||
| 769 | + | ||
| 770 | + //改动 手动获取 | ||
| 771 | + //path = "/root/sdcard/media_file/PSDK_0005.h264"; | ||
| 772 | + | ||
| 773 | + //查看文件流信息指令 ffprobe -show_frames filename | ||
| 774 | + //ffprobe -show_streams "/root/sdcard/media_file/PSDK_0005.h264" 2>/dev/null | grep r_frame_rate | ||
| 775 | + | ||
| 776 | + snprintf(ffmpegCmdStr, FFMPEG_CMD_BUF_SIZE, "ffprobe -show_streams \"%s\" 2>/dev/null | grep r_frame_rate", path); | ||
| 777 | + fpCommand = popen(ffmpegCmdStr, "r"); | ||
| 778 | + if (fpCommand == NULL) { | ||
| 779 | + USER_LOG_ERROR("execute show frame rate command fail."); | ||
| 780 | + return DJI_ERROR_SYSTEM_MODULE_CODE_UNKNOWN; | ||
| 781 | + } | ||
| 782 | + | ||
| 783 | + USER_LOG_INFO("ffmpegCmdStr:%s", ffmpegCmdStr); | ||
| 784 | + | ||
| 785 | + //此处报错 | ||
| 786 | + // 从fpcommand中读取数据 %d %d 放入到frameRateMolecule frameRateDenominator | ||
| 787 | + // 失败返还-1f | ||
| 788 | + | ||
| 789 | + ret = fscanf(fpCommand, "r_frame_rate=%d/%d", &frameRateMolecule, &frameRateDenominator); | ||
| 790 | + if (ret <= 0) { | ||
| 791 | + USER_LOG_ERROR("can not find frame rate."); | ||
| 792 | + returnCode = DJI_ERROR_SYSTEM_MODULE_CODE_NOT_FOUND; | ||
| 793 | + goto out; | ||
| 794 | + } | ||
| 795 | + *frameRate = (float) frameRateMolecule / (float) frameRateDenominator; | ||
| 796 | + | ||
| 797 | +out: | ||
| 798 | + pclose(fpCommand); | ||
| 799 | + | ||
| 800 | + return returnCode; | ||
| 801 | +} | ||
| 802 | + | ||
| 803 | +//获取视频帧数 | ||
| 804 | +static T_DjiReturnCode DjiPlayback_GetFrameNumberByTime(T_TestPayloadCameraVideoFrameInfo *frameInfo, | ||
| 805 | + uint32_t frameCount, uint32_t *frameNumber, uint32_t timeMs) | ||
| 806 | +{ | ||
| 807 | + uint32_t i = 0; | ||
| 808 | + double camulativeTimeS = 0; | ||
| 809 | + double timeS = (double) timeMs / 1000.0; | ||
| 810 | + | ||
| 811 | + for (i = 0; i < frameCount; ++i) { | ||
| 812 | + camulativeTimeS += frameInfo[i].durationS; | ||
| 813 | + | ||
| 814 | + if (camulativeTimeS >= timeS) { | ||
| 815 | + *frameNumber = i; | ||
| 816 | + return DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS; | ||
| 817 | + } | ||
| 818 | + } | ||
| 819 | + | ||
| 820 | + return DJI_ERROR_SYSTEM_MODULE_CODE_NOT_FOUND; | ||
| 821 | +} | ||
| 822 | + | ||
| 823 | +static T_DjiReturnCode GetMediaFileDir(char *dirPath) | ||
| 824 | +{ | ||
| 825 | + T_DjiReturnCode returnCode; | ||
| 826 | + char curFileDirPath[DJI_FILE_PATH_SIZE_MAX]; | ||
| 827 | + char tempPath[DJI_FILE_PATH_SIZE_MAX]; | ||
| 828 | + | ||
| 829 | + USER_LOG_INFO("自动获取相册地址"); | ||
| 830 | + // returnCode = DjiUserUtil_GetCurrentFileDirPath("/root/sdcard/DCIM", DJI_FILE_PATH_SIZE_MAX, curFileDirPath); | ||
| 831 | + // if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) { | ||
| 832 | + // USER_LOG_ERROR("Get file current path error, stat = 0x%08llX", returnCode); | ||
| 833 | + // return returnCode; | ||
| 834 | + // } | ||
| 835 | + | ||
| 836 | + snprintf(curFileDirPath,DJI_FILE_PATH_SIZE_MAX,"/root/sdcard/DCIM"); | ||
| 837 | + snprintf(dirPath, DJI_FILE_PATH_SIZE_MAX, "%s", curFileDirPath); | ||
| 838 | + | ||
| 839 | + return DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS; | ||
| 840 | +} | ||
| 841 | + | ||
| 842 | +static T_DjiReturnCode GetMediaFileOriginData(const char *filePath, uint32_t offset, uint32_t length, uint8_t *data) | ||
| 843 | +{ | ||
| 844 | + T_DjiReturnCode returnCode; | ||
| 845 | + uint32_t realLen = 0; | ||
| 846 | + T_DjiMediaFileHandle mediaFileHandle; | ||
| 847 | + | ||
| 848 | + returnCode = DjiMediaFile_CreateHandle(filePath, &mediaFileHandle); | ||
| 849 | + if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) { | ||
| 850 | + USER_LOG_ERROR("Media file create handle error stat:0x%08llX", returnCode); | ||
| 851 | + return returnCode; | ||
| 852 | + } | ||
| 853 | + | ||
| 854 | + returnCode = DjiMediaFile_GetDataOrg(mediaFileHandle, offset, length, data, &realLen); | ||
| 855 | + if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) { | ||
| 856 | + USER_LOG_ERROR("Media file get data error stat:0x%08llX", returnCode); | ||
| 857 | + return returnCode; | ||
| 858 | + } | ||
| 859 | + | ||
| 860 | + returnCode = DjiMediaFile_DestroyHandle(mediaFileHandle); | ||
| 861 | + if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) { | ||
| 862 | + USER_LOG_ERROR("Media file destroy handle error stat:0x%08llX", returnCode); | ||
| 863 | + return returnCode; | ||
| 864 | + } | ||
| 865 | + | ||
| 866 | + return DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS; | ||
| 867 | +} | ||
| 868 | + | ||
| 869 | +static T_DjiReturnCode CreateMediaFileThumbNail(const char *filePath) | ||
| 870 | +{ | ||
| 871 | + T_DjiReturnCode returnCode; | ||
| 872 | + | ||
| 873 | + returnCode = DjiMediaFile_CreateHandle(filePath, &s_mediaFileThumbNailHandle); | ||
| 874 | + if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) { | ||
| 875 | + USER_LOG_ERROR("Media file create handle error stat:0x%08llX", returnCode); | ||
| 876 | + return returnCode; | ||
| 877 | + } | ||
| 878 | + | ||
| 879 | + returnCode = DjiMediaFile_CreateThm(s_mediaFileThumbNailHandle); | ||
| 880 | + if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) { | ||
| 881 | + USER_LOG_ERROR("Media file create thumb nail error stat:0x%08llX", returnCode); | ||
| 882 | + return returnCode; | ||
| 883 | + } | ||
| 884 | + | ||
| 885 | + return DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS; | ||
| 886 | +} | ||
| 887 | + | ||
| 888 | +static T_DjiReturnCode GetMediaFileThumbNailInfo(const char *filePath, T_DjiCameraMediaFileInfo *fileInfo) | ||
| 889 | +{ | ||
| 890 | + T_DjiReturnCode returnCode; | ||
| 891 | + | ||
| 892 | + USER_UTIL_UNUSED(filePath); | ||
| 893 | + | ||
| 894 | + if (s_mediaFileThumbNailHandle == NULL) { | ||
| 895 | + USER_LOG_ERROR("Media file thumb nail handle null error"); | ||
| 896 | + return DJI_ERROR_SYSTEM_MODULE_CODE_INVALID_PARAMETER; | ||
| 897 | + } | ||
| 898 | + | ||
| 899 | + returnCode = DjiMediaFile_GetMediaFileType(s_mediaFileThumbNailHandle, &fileInfo->type); | ||
| 900 | + if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) { | ||
| 901 | + USER_LOG_ERROR("Media file get type error stat:0x%08llX", returnCode); | ||
| 902 | + return returnCode; | ||
| 903 | + } | ||
| 904 | + | ||
| 905 | + returnCode = DjiMediaFile_GetMediaFileAttr(s_mediaFileThumbNailHandle, &fileInfo->mediaFileAttr); | ||
| 906 | + if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) { | ||
| 907 | + USER_LOG_ERROR("Media file get attr error stat:0x%08llX", returnCode); | ||
| 908 | + return returnCode; | ||
| 909 | + } | ||
| 910 | + | ||
| 911 | + returnCode = DjiMediaFile_GetFileSizeThm(s_mediaFileThumbNailHandle, &fileInfo->fileSize); | ||
| 912 | + if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) { | ||
| 913 | + USER_LOG_ERROR("Media file get size error stat:0x%08llX", returnCode); | ||
| 914 | + return returnCode; | ||
| 915 | + } | ||
| 916 | + | ||
| 917 | + return DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS; | ||
| 918 | +} | ||
| 919 | + | ||
| 920 | +static T_DjiReturnCode GetMediaFileThumbNailData(const char *filePath, uint32_t offset, uint32_t length, uint8_t *data) | ||
| 921 | +{ | ||
| 922 | + T_DjiReturnCode returnCode; | ||
| 923 | + uint16_t realLen = 0; | ||
| 924 | + | ||
| 925 | + USER_UTIL_UNUSED(filePath); | ||
| 926 | + | ||
| 927 | + if (s_mediaFileThumbNailHandle == NULL) { | ||
| 928 | + USER_LOG_ERROR("Media file thumb nail handle null error"); | ||
| 929 | + return DJI_ERROR_SYSTEM_MODULE_CODE_INVALID_PARAMETER; | ||
| 930 | + } | ||
| 931 | + | ||
| 932 | + returnCode = DjiMediaFile_GetDataThm(s_mediaFileThumbNailHandle, offset, length, data, &realLen); | ||
| 933 | + if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) { | ||
| 934 | + USER_LOG_ERROR("Media file get data error stat:0x%08llX", returnCode); | ||
| 935 | + return returnCode; | ||
| 936 | + } | ||
| 937 | + | ||
| 938 | + return DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS; | ||
| 939 | +} | ||
| 940 | + | ||
| 941 | +static T_DjiReturnCode DestroyMediaFileThumbNail(const char *filePath) | ||
| 942 | +{ | ||
| 943 | + T_DjiReturnCode returnCode; | ||
| 944 | + | ||
| 945 | + USER_UTIL_UNUSED(filePath); | ||
| 946 | + | ||
| 947 | + if (s_mediaFileThumbNailHandle == NULL) { | ||
| 948 | + USER_LOG_ERROR("Media file thumb nail handle null error"); | ||
| 949 | + return DJI_ERROR_SYSTEM_MODULE_CODE_INVALID_PARAMETER; | ||
| 950 | + } | ||
| 951 | + | ||
| 952 | + returnCode = DjiMediaFile_DestoryThm(s_mediaFileThumbNailHandle); | ||
| 953 | + if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) { | ||
| 954 | + USER_LOG_ERROR("Media file destroy thumb nail error stat:0x%08llX", returnCode); | ||
| 955 | + return returnCode; | ||
| 956 | + } | ||
| 957 | + | ||
| 958 | + returnCode = DjiMediaFile_DestroyHandle(s_mediaFileThumbNailHandle); | ||
| 959 | + if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) { | ||
| 960 | + USER_LOG_ERROR("Media file destroy handle error stat:0x%08llX", returnCode); | ||
| 961 | + return returnCode; | ||
| 962 | + } | ||
| 963 | + | ||
| 964 | + return DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS; | ||
| 965 | +} | ||
| 966 | + | ||
| 967 | +static T_DjiReturnCode CreateMediaFileScreenNail(const char *filePath) | ||
| 968 | +{ | ||
| 969 | + T_DjiReturnCode returnCode; | ||
| 970 | + | ||
| 971 | + returnCode = DjiMediaFile_CreateHandle(filePath, &s_mediaFileScreenNailHandle); | ||
| 972 | + if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) { | ||
| 973 | + USER_LOG_ERROR("Media file create handle error stat:0x%08llX", returnCode); | ||
| 974 | + return returnCode; | ||
| 975 | + } | ||
| 976 | + | ||
| 977 | + returnCode = DjiMediaFile_CreateScr(s_mediaFileScreenNailHandle); | ||
| 978 | + if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) { | ||
| 979 | + USER_LOG_ERROR("Media file create screen nail error stat:0x%08llX", returnCode); | ||
| 980 | + return returnCode; | ||
| 981 | + } | ||
| 982 | + | ||
| 983 | + return DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS; | ||
| 984 | +} | ||
| 985 | + | ||
| 986 | +static T_DjiReturnCode GetMediaFileScreenNailInfo(const char *filePath, T_DjiCameraMediaFileInfo *fileInfo) | ||
| 987 | +{ | ||
| 988 | + T_DjiReturnCode returnCode; | ||
| 989 | + | ||
| 990 | + USER_UTIL_UNUSED(filePath); | ||
| 991 | + | ||
| 992 | + if (s_mediaFileScreenNailHandle == NULL) { | ||
| 993 | + USER_LOG_ERROR("Media file screen nail handle null error"); | ||
| 994 | + return DJI_ERROR_SYSTEM_MODULE_CODE_INVALID_PARAMETER; | ||
| 995 | + } | ||
| 996 | + | ||
| 997 | + returnCode = DjiMediaFile_GetMediaFileType(s_mediaFileScreenNailHandle, &fileInfo->type); | ||
| 998 | + if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) { | ||
| 999 | + USER_LOG_ERROR("Media file get type error stat:0x%08llX", returnCode); | ||
| 1000 | + return returnCode; | ||
| 1001 | + } | ||
| 1002 | + | ||
| 1003 | + returnCode = DjiMediaFile_GetMediaFileAttr(s_mediaFileScreenNailHandle, &fileInfo->mediaFileAttr); | ||
| 1004 | + if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) { | ||
| 1005 | + USER_LOG_ERROR("Media file get attr error stat:0x%08llX", returnCode); | ||
| 1006 | + return returnCode; | ||
| 1007 | + } | ||
| 1008 | + | ||
| 1009 | + returnCode = DjiMediaFile_GetFileSizeScr(s_mediaFileScreenNailHandle, &fileInfo->fileSize); | ||
| 1010 | + if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) { | ||
| 1011 | + USER_LOG_ERROR("Media file get size error stat:0x%08llX", returnCode); | ||
| 1012 | + return returnCode; | ||
| 1013 | + } | ||
| 1014 | + | ||
| 1015 | + return DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS; | ||
| 1016 | +} | ||
| 1017 | + | ||
| 1018 | +static T_DjiReturnCode GetMediaFileScreenNailData(const char *filePath, uint32_t offset, uint32_t length, | ||
| 1019 | + uint8_t *data) | ||
| 1020 | +{ | ||
| 1021 | + T_DjiReturnCode returnCode; | ||
| 1022 | + uint16_t realLen = 0; | ||
| 1023 | + | ||
| 1024 | + USER_UTIL_UNUSED(filePath); | ||
| 1025 | + | ||
| 1026 | + if (s_mediaFileScreenNailHandle == NULL) { | ||
| 1027 | + USER_LOG_ERROR("Media file screen nail handle null error"); | ||
| 1028 | + return DJI_ERROR_SYSTEM_MODULE_CODE_INVALID_PARAMETER; | ||
| 1029 | + } | ||
| 1030 | + | ||
| 1031 | + returnCode = DjiMediaFile_GetDataScr(s_mediaFileScreenNailHandle, offset, length, data, &realLen); | ||
| 1032 | + if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) { | ||
| 1033 | + USER_LOG_ERROR("Media file get size error stat:0x%08llX", returnCode); | ||
| 1034 | + return returnCode; | ||
| 1035 | + } | ||
| 1036 | + | ||
| 1037 | + return DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS; | ||
| 1038 | +} | ||
| 1039 | + | ||
| 1040 | +static T_DjiReturnCode DestroyMediaFileScreenNail(const char *filePath) | ||
| 1041 | +{ | ||
| 1042 | + T_DjiReturnCode returnCode; | ||
| 1043 | + | ||
| 1044 | + USER_UTIL_UNUSED(filePath); | ||
| 1045 | + | ||
| 1046 | + if (s_mediaFileScreenNailHandle == NULL) { | ||
| 1047 | + USER_LOG_ERROR("Media file screen nail handle null error"); | ||
| 1048 | + return DJI_ERROR_SYSTEM_MODULE_CODE_INVALID_PARAMETER; | ||
| 1049 | + } | ||
| 1050 | + | ||
| 1051 | + returnCode = DjiMediaFile_DestroyScr(s_mediaFileScreenNailHandle); | ||
| 1052 | + if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) { | ||
| 1053 | + USER_LOG_ERROR("Media file destroy screen nail error stat:0x%08llX", returnCode); | ||
| 1054 | + return returnCode; | ||
| 1055 | + } | ||
| 1056 | + | ||
| 1057 | + returnCode = DjiMediaFile_DestroyHandle(s_mediaFileScreenNailHandle); | ||
| 1058 | + if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) { | ||
| 1059 | + USER_LOG_ERROR("Media file destroy handle error stat:0x%08llX", returnCode); | ||
| 1060 | + return returnCode; | ||
| 1061 | + } | ||
| 1062 | + | ||
| 1063 | + return DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS; | ||
| 1064 | +} | ||
| 1065 | + | ||
| 1066 | +static T_DjiReturnCode DeleteMediaFile(char *filePath) | ||
| 1067 | +{ | ||
| 1068 | + T_DjiReturnCode returnCode; | ||
| 1069 | + | ||
| 1070 | + USER_LOG_INFO("delete media file:%s", filePath); | ||
| 1071 | + returnCode = DjiFile_Delete(filePath); | ||
| 1072 | + if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) { | ||
| 1073 | + USER_LOG_ERROR("Media file delete error stat:0x%08llX", returnCode); | ||
| 1074 | + return returnCode; | ||
| 1075 | + } | ||
| 1076 | + | ||
| 1077 | + return DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS; | ||
| 1078 | +} | ||
| 1079 | + | ||
| 1080 | +static T_DjiReturnCode SetMediaPlaybackFile(const char *filePath) | ||
| 1081 | +{ | ||
| 1082 | + USER_LOG_INFO("set media playback file:%s", filePath); | ||
| 1083 | + T_DjiReturnCode returnCode; | ||
| 1084 | + | ||
| 1085 | + returnCode = DjiPlayback_StopPlay(&s_playbackInfo); | ||
| 1086 | + if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) { | ||
| 1087 | + return returnCode; | ||
| 1088 | + } | ||
| 1089 | + | ||
| 1090 | + returnCode = DjiPlayback_SetPlayFile(&s_playbackInfo, filePath, 0); | ||
| 1091 | + if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) { | ||
| 1092 | + return returnCode; | ||
| 1093 | + } | ||
| 1094 | + | ||
| 1095 | + returnCode = DjiPlayback_StartPlay(&s_playbackInfo); | ||
| 1096 | + if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) { | ||
| 1097 | + return returnCode; | ||
| 1098 | + } | ||
| 1099 | + | ||
| 1100 | + return DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS; | ||
| 1101 | +} | ||
| 1102 | + | ||
| 1103 | +static T_DjiReturnCode StartMediaPlayback(void) | ||
| 1104 | +{ | ||
| 1105 | + T_DjiReturnCode returnCode; | ||
| 1106 | + | ||
| 1107 | + USER_LOG_INFO("start media playback"); | ||
| 1108 | + returnCode = DjiPlayback_StartPlay(&s_playbackInfo); | ||
| 1109 | + if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) { | ||
| 1110 | + USER_LOG_ERROR("start media playback status error, stat:0x%08llX", returnCode); | ||
| 1111 | + return returnCode; | ||
| 1112 | + } | ||
| 1113 | + | ||
| 1114 | + return returnCode; | ||
| 1115 | +} | ||
| 1116 | + | ||
| 1117 | +static T_DjiReturnCode StopMediaPlayback(void) | ||
| 1118 | +{ | ||
| 1119 | + T_DjiReturnCode returnCode; | ||
| 1120 | + | ||
| 1121 | + USER_LOG_INFO("stop media playback"); | ||
| 1122 | + returnCode = DjiPlayback_StopPlay(&s_playbackInfo); | ||
| 1123 | + if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) { | ||
| 1124 | + USER_LOG_ERROR("stop media playback error, stat:0x%08llX", returnCode); | ||
| 1125 | + return returnCode; | ||
| 1126 | + } | ||
| 1127 | + | ||
| 1128 | + return returnCode; | ||
| 1129 | +} | ||
| 1130 | + | ||
| 1131 | +static T_DjiReturnCode PauseMediaPlayback(void) | ||
| 1132 | +{ | ||
| 1133 | + T_DjiReturnCode returnCode; | ||
| 1134 | + | ||
| 1135 | + USER_LOG_INFO("pause media playback"); | ||
| 1136 | + returnCode = DjiPlayback_PausePlay(&s_playbackInfo); | ||
| 1137 | + if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) { | ||
| 1138 | + USER_LOG_ERROR("pause media playback error, stat:0x%08llX", returnCode); | ||
| 1139 | + return returnCode; | ||
| 1140 | + } | ||
| 1141 | + | ||
| 1142 | + return returnCode; | ||
| 1143 | +} | ||
| 1144 | + | ||
| 1145 | +static T_DjiReturnCode SeekMediaPlayback(uint32_t playbackPosition) | ||
| 1146 | +{ | ||
| 1147 | + T_DjiReturnCode returnCode; | ||
| 1148 | + | ||
| 1149 | + USER_LOG_INFO("seek media playback:%d", playbackPosition); | ||
| 1150 | + returnCode = DjiPlayback_SeekPlay(&s_playbackInfo, playbackPosition); | ||
| 1151 | + if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) { | ||
| 1152 | + USER_LOG_ERROR("seek media playback error, stat:0x%08llX", returnCode); | ||
| 1153 | + return returnCode; | ||
| 1154 | + } | ||
| 1155 | + | ||
| 1156 | + return returnCode; | ||
| 1157 | +} | ||
| 1158 | + | ||
| 1159 | +static T_DjiReturnCode GetMediaPlaybackStatus(T_DjiCameraPlaybackStatus *status) | ||
| 1160 | +{ | ||
| 1161 | + T_DjiReturnCode returnCode; | ||
| 1162 | + | ||
| 1163 | + returnCode = DjiPlayback_GetPlaybackStatus(&s_playbackInfo, status); | ||
| 1164 | + if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) { | ||
| 1165 | + USER_LOG_ERROR("get playback status error, stat:0x%08llX", returnCode); | ||
| 1166 | + return returnCode; | ||
| 1167 | + } | ||
| 1168 | + | ||
| 1169 | + status->videoPlayProcess = (uint8_t) (((float) s_playbackInfo.playPosMs / (float) s_playbackInfo.videoLengthMs) * | ||
| 1170 | + 100); | ||
| 1171 | + | ||
| 1172 | + USER_LOG_DEBUG("get media playback status %d %d %d %d", status->videoPlayProcess, status->playPosMs, | ||
| 1173 | + status->videoLengthMs, status->playbackMode); | ||
| 1174 | + | ||
| 1175 | + return DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS; | ||
| 1176 | +} | ||
| 1177 | + | ||
| 1178 | +static T_DjiReturnCode StartDownloadNotification(void) | ||
| 1179 | +{ | ||
| 1180 | + T_DjiReturnCode returnCode; | ||
| 1181 | + T_DjiDataChannelBandwidthProportionOfHighspeedChannel bandwidthProportion = {0}; | ||
| 1182 | + | ||
| 1183 | + USER_LOG_DEBUG("media download start notification."); | ||
| 1184 | + | ||
| 1185 | + bandwidthProportion.dataStream = 0; | ||
| 1186 | + bandwidthProportion.videoStream = 0; | ||
| 1187 | + bandwidthProportion.downloadStream = 100; | ||
| 1188 | + | ||
| 1189 | + returnCode = DjiHighSpeedDataChannel_SetBandwidthProportion(bandwidthProportion); | ||
| 1190 | + if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) { | ||
| 1191 | + USER_LOG_ERROR("Set bandwidth proportion for high speed channel error, stat:0x%08llX.", returnCode); | ||
| 1192 | + return returnCode; | ||
| 1193 | + } | ||
| 1194 | + | ||
| 1195 | + return DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS; | ||
| 1196 | +} | ||
| 1197 | + | ||
| 1198 | +static T_DjiReturnCode StopDownloadNotification(void) | ||
| 1199 | +{ | ||
| 1200 | + T_DjiReturnCode returnCode; | ||
| 1201 | + T_DjiDataChannelBandwidthProportionOfHighspeedChannel bandwidthProportion = {0}; | ||
| 1202 | + | ||
| 1203 | + USER_LOG_DEBUG("media download stop notification."); | ||
| 1204 | + | ||
| 1205 | + bandwidthProportion.dataStream = TRANS_RATIO_DATA; | ||
| 1206 | + bandwidthProportion.videoStream = TRANS_RATIO_VIDEO; | ||
| 1207 | + bandwidthProportion.downloadStream = TRANS_RATIO_DOWNLOAD; | ||
| 1208 | + | ||
| 1209 | + returnCode = DjiHighSpeedDataChannel_SetBandwidthProportion(bandwidthProportion); | ||
| 1210 | + if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) { | ||
| 1211 | + USER_LOG_ERROR("Set bandwidth proportion for high speed channel error, stat:0x%08llX.", returnCode); | ||
| 1212 | + return returnCode; | ||
| 1213 | + } | ||
| 1214 | + | ||
| 1215 | + return DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS; | ||
| 1216 | +} | ||
| 1217 | + | ||
| 1218 | +#ifndef __CC_ARM | ||
| 1219 | +#pragma GCC diagnostic push | ||
| 1220 | +#pragma GCC diagnostic ignored "-Wmissing-noreturn" | ||
| 1221 | +#pragma GCC diagnostic ignored "-Wreturn-type" | ||
| 1222 | +#endif | ||
| 1223 | + | ||
| 1224 | + | ||
| 1225 | + | ||
| 1226 | +// 任务 | ||
| 1227 | +static void *UserCameraMedia_SendVideoTask(void *arg) | ||
| 1228 | +{ | ||
| 1229 | + int ret; | ||
| 1230 | + // 回调错误 | ||
| 1231 | + T_DjiReturnCode returnCode; | ||
| 1232 | + //发送视频的阶数 | ||
| 1233 | + static uint32_t sendVideoStep = 0; | ||
| 1234 | + // 传输的视频文件 | ||
| 1235 | + FILE *fpFile = NULL; | ||
| 1236 | + //传输数据长度 一帧不能超过65kb 超过需要分割 | ||
| 1237 | + unsigned long dataLength = 0; | ||
| 1238 | + // 将要发送的产度 | ||
| 1239 | + uint16_t lengthOfDataToBeSent = 0; | ||
| 1240 | + // 上次已发送的长度 | ||
| 1241 | + int lengthOfDataHaveBeenSent = 0; | ||
| 1242 | + // 视频数据队列 | ||
| 1243 | + char *dataBuffer = NULL; | ||
| 1244 | + // 回放指令 | ||
| 1245 | + T_TestPayloadCameraPlaybackCommand playbackCommand = {0}; | ||
| 1246 | + // | ||
| 1247 | + uint16_t bufferReadSize = 0; | ||
| 1248 | + // 视频文件的地址 | ||
| 1249 | + char *videoFilePath = NULL; | ||
| 1250 | + // 转码文件的地址 | ||
| 1251 | + char *transcodedFilePath = NULL; | ||
| 1252 | + float frameRate = 1.0f; | ||
| 1253 | + uint32_t waitDuration = 1000 / SEND_VIDEO_TASK_FREQ; | ||
| 1254 | + uint32_t rightNow = 0; | ||
| 1255 | + uint32_t sendExpect = 0; | ||
| 1256 | + // 帧信息 | ||
| 1257 | + T_TestPayloadCameraVideoFrameInfo *frameInfo = NULL; | ||
| 1258 | + // 帧数 | ||
| 1259 | + uint32_t frameNumber = 0; | ||
| 1260 | + // 总帧 | ||
| 1261 | + uint32_t frameCount = 0; | ||
| 1262 | + // 开始时间的 延迟 | ||
| 1263 | + uint32_t startTimeMs = 0; | ||
| 1264 | + // 发送文件的标识 | ||
| 1265 | + bool sendVideoFlag = true; | ||
| 1266 | + // 发送 一次 的 时间 标示 | ||
| 1267 | + bool sendOneTimeFlag = false; | ||
| 1268 | + // 视频流状态 | ||
| 1269 | + T_DjiDataChannelState videoStreamState = {0}; | ||
| 1270 | + // 拍照模式 | ||
| 1271 | + E_DjiCameraMode mode = DJI_CAMERA_MODE_SHOOT_PHOTO; | ||
| 1272 | + // ousl硬件层 句柄 | ||
| 1273 | + T_DjiOsalHandler *osalHandler = DjiPlatform_GetOsalHandler(); | ||
| 1274 | + uint32_t frameBufSize = 0; | ||
| 1275 | + // 视频流类型 | ||
| 1276 | + E_DjiCameraVideoStreamType videoStreamType; | ||
| 1277 | + // 通用 文件路径 | ||
| 1278 | + char curFileDirPath[DJI_FILE_PATH_SIZE_MAX]; | ||
| 1279 | + // 临时路径 | ||
| 1280 | + char tempPath[DJI_FILE_PATH_SIZE_MAX]; | ||
| 1281 | + | ||
| 1282 | + USER_UTIL_UNUSED(arg); | ||
| 1283 | + | ||
| 1284 | + | ||
| 1285 | + // 获取视频流文件信息 | ||
| 1286 | + // 获取 通用地址 的错误 | ||
| 1287 | + returnCode = DjiUserUtil_GetCurrentFileDirPath("/root/sdcard/DCIM", DJI_FILE_PATH_SIZE_MAX, curFileDirPath); | ||
| 1288 | + if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) { | ||
| 1289 | + USER_LOG_ERROR("Get file current path error, stat = 0x%08llX", returnCode); | ||
| 1290 | + pthread_exit(NULL); | ||
| 1291 | + } | ||
| 1292 | + | ||
| 1293 | + USER_LOG_INFO("curFileDirPath:%s",curFileDirPath); | ||
| 1294 | + | ||
| 1295 | + if (s_isMediaFileDirPathConfigured == true) { | ||
| 1296 | + snprintf(tempPath, DJI_FILE_PATH_SIZE_MAX, "%sPSDK_0005.h264", s_mediaFileDirPath); | ||
| 1297 | + } else { | ||
| 1298 | + snprintf(tempPath, DJI_FILE_PATH_SIZE_MAX, "%smedia_file/PSDK_0005.h264", curFileDirPath); | ||
| 1299 | + } | ||
| 1300 | + | ||
| 1301 | + // 写入用于推送文件的临时地址 | ||
| 1302 | + // USER_LOG_INFO("tempPath:%s",tempPath); | ||
| 1303 | + | ||
| 1304 | + // 视频流处理线程初始化 | ||
| 1305 | + // 为视频文件申请 | ||
| 1306 | + videoFilePath = osalHandler->Malloc(DJI_FILE_PATH_SIZE_MAX); | ||
| 1307 | + if (videoFilePath == NULL) { | ||
| 1308 | + USER_LOG_ERROR("malloc memory for video file path fail."); | ||
| 1309 | + pthread_exit(NULL); | ||
| 1310 | + } | ||
| 1311 | + | ||
| 1312 | + // 转码文件的地址 | ||
| 1313 | + transcodedFilePath = osalHandler->Malloc(DJI_FILE_PATH_SIZE_MAX); | ||
| 1314 | + if (transcodedFilePath == NULL) { | ||
| 1315 | + USER_LOG_ERROR("malloc memory for transcoded file path fail."); | ||
| 1316 | + pthread_exit(NULL); | ||
| 1317 | + } | ||
| 1318 | + | ||
| 1319 | + // 帧信息 | ||
| 1320 | + frameInfo = osalHandler->Malloc(VIDEO_FRAME_MAX_COUNT * sizeof(T_TestPayloadCameraVideoFrameInfo)); | ||
| 1321 | + if (frameInfo == NULL) { | ||
| 1322 | + USER_LOG_ERROR("malloc memory for frame info fail."); | ||
| 1323 | + pthread_exit(NULL); | ||
| 1324 | + } | ||
| 1325 | + memset(frameInfo, 0, VIDEO_FRAME_MAX_COUNT * sizeof(T_TestPayloadCameraVideoFrameInfo)); | ||
| 1326 | + | ||
| 1327 | + | ||
| 1328 | + //停止 回放播放程序 | ||
| 1329 | + returnCode = DjiPlayback_StopPlayProcess(); | ||
| 1330 | + if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) { | ||
| 1331 | + USER_LOG_ERROR("stop playback and start liveview error: 0x%08llX.", returnCode); | ||
| 1332 | + pthread_exit(NULL); | ||
| 1333 | + } | ||
| 1334 | + | ||
| 1335 | + (void)osalHandler->GetTimeMs(&rightNow); | ||
| 1336 | + sendExpect = rightNow + waitDuration; | ||
| 1337 | + while (1) { | ||
| 1338 | + // (void)osalHandler->GetTimeMs(&rightNow); | ||
| 1339 | + // if (sendExpect > rightNow) { | ||
| 1340 | + // waitDuration = sendExpect - rightNow; | ||
| 1341 | + // } else { | ||
| 1342 | + // waitDuration = 1000 / SEND_VIDEO_TASK_FREQ; | ||
| 1343 | + // } | ||
| 1344 | + // (void)osalHandler->SemaphoreTimedWait(s_mediaPlayWorkSem, waitDuration); | ||
| 1345 | + osalHandler->TaskSleepMs(40); | ||
| 1346 | + | ||
| 1347 | + // response playback command | ||
| 1348 | + // 响应播放命令 | ||
| 1349 | + if (osalHandler->MutexLock(s_mediaPlayCommandBufferMutex) != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) { | ||
| 1350 | + USER_LOG_ERROR("mutex lock error"); | ||
| 1351 | + continue; | ||
| 1352 | + } | ||
| 1353 | + | ||
| 1354 | + bufferReadSize = UtilBuffer_Get(&s_mediaPlayCommandBufferHandler, (uint8_t *) &playbackCommand, | ||
| 1355 | + sizeof(T_TestPayloadCameraPlaybackCommand)); | ||
| 1356 | + | ||
| 1357 | + if (osalHandler->MutexUnlock(s_mediaPlayCommandBufferMutex) != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) { | ||
| 1358 | + USER_LOG_ERROR("mutex unlock error"); //互斥锁 解锁 失败 | ||
| 1359 | + continue; | ||
| 1360 | + } | ||
| 1361 | + | ||
| 1362 | + //&& playbackCommand.command != TEST_PAYLOAD_CAMERA_MEDIA_PLAY_COMMAND_STOP | ||
| 1363 | + // if (bufferReadSize != sizeof(T_TestPayloadCameraPlaybackCommand) && playbackCommand.command != TEST_PAYLOAD_CAMERA_MEDIA_PLAY_COMMAND_STOP) | ||
| 1364 | + // { | ||
| 1365 | + // goto send; | ||
| 1366 | + // } | ||
| 1367 | + | ||
| 1368 | + returnCode = DjiTest_CameraGetVideoStreamType(&videoStreamType); | ||
| 1369 | + if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) { | ||
| 1370 | + continue; | ||
| 1371 | + } | ||
| 1372 | + | ||
| 1373 | + //printf("视频流类型videoStreamType%d\n",videoStreamType); | ||
| 1374 | + | ||
| 1375 | +// 根据 输入的指令 选择功能 | ||
| 1376 | + switch (playbackCommand.command) { | ||
| 1377 | + case TEST_PAYLOAD_CAMERA_MEDIA_PLAY_COMMAND_STOP: | ||
| 1378 | + //snprintf(videoFilePath, DJI_FILE_PATH_SIZE_MAX, "%s", tempPath); | ||
| 1379 | + startTimeMs = 0; | ||
| 1380 | + //sendVideoFlag = true; | ||
| 1381 | + //sendOneTimeFlag = false; | ||
| 1382 | + | ||
| 1383 | + //录像回放函数 | ||
| 1384 | + DJI_VideoReplay_input(playbackCommand.command, 0, NULL); | ||
| 1385 | + goto Push_end; | ||
| 1386 | + | ||
| 1387 | + break; | ||
| 1388 | + | ||
| 1389 | + // 暂停视频播放 | ||
| 1390 | + case TEST_PAYLOAD_CAMERA_MEDIA_PLAY_COMMAND_PAUSE: | ||
| 1391 | + //sendVideoFlag = false; | ||
| 1392 | + //goto send; | ||
| 1393 | + //录像回放函数 | ||
| 1394 | + DJI_VideoReplay_input(playbackCommand.command, 0, NULL); | ||
| 1395 | + | ||
| 1396 | + goto Push_end; | ||
| 1397 | + break; | ||
| 1398 | + | ||
| 1399 | + // 开始视频播放 | ||
| 1400 | + case TEST_PAYLOAD_CAMERA_MEDIA_PLAY_COMMAND_START: | ||
| 1401 | + //snprintf(videoFilePath, DJI_FILE_PATH_SIZE_MAX, "%s", playbackCommand.path); | ||
| 1402 | + startTimeMs = playbackCommand.timeMs; | ||
| 1403 | + // sendVideoFlag = true; | ||
| 1404 | + // sendOneTimeFlag = true; | ||
| 1405 | + | ||
| 1406 | + //录像回放函数 | ||
| 1407 | + DJI_VideoReplay_input(playbackCommand.command, playbackCommand.timeMs, playbackCommand.path); | ||
| 1408 | + | ||
| 1409 | + goto Push_end; | ||
| 1410 | + break; | ||
| 1411 | + // 其余输入 负载的指令无效 | ||
| 1412 | + default: | ||
| 1413 | + USER_LOG_ERROR("playback command invalid: %d.", playbackCommand.command); | ||
| 1414 | + sendVideoFlag = false; | ||
| 1415 | + goto send; | ||
| 1416 | + } | ||
| 1417 | + | ||
| 1418 | + // video send preprocess 视频发送预处理 | ||
| 1419 | + //转码函数 | ||
| 1420 | + returnCode = DjiPlayback_VideoFileTranscode(videoFilePath, "h264", transcodedFilePath, | ||
| 1421 | + DJI_FILE_PATH_SIZE_MAX); | ||
| 1422 | + if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) { | ||
| 1423 | + USER_LOG_ERROR("transcode video file error: 0x%08llX.", returnCode); | ||
| 1424 | + continue; | ||
| 1425 | + } | ||
| 1426 | + | ||
| 1427 | + // 获取视频文件中的帧速率 | ||
| 1428 | + returnCode = DjiPlayback_GetFrameRateOfVideoFile(transcodedFilePath, &frameRate); | ||
| 1429 | + if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) { | ||
| 1430 | + USER_LOG_ERROR("get frame rate of video error: 0x%08llX.", returnCode); | ||
| 1431 | + continue; | ||
| 1432 | + } | ||
| 1433 | + | ||
| 1434 | + // 获取视频文件中的 帧信息 | ||
| 1435 | + returnCode = DjiPlayback_GetFrameInfoOfVideoFile(transcodedFilePath, frameInfo, VIDEO_FRAME_MAX_COUNT, | ||
| 1436 | + &frameCount); | ||
| 1437 | + if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) { | ||
| 1438 | + USER_LOG_ERROR("get frame info of video error: 0x%08llX.", returnCode); | ||
| 1439 | + continue; | ||
| 1440 | + } | ||
| 1441 | + | ||
| 1442 | + // 根据时间获取 帧数 | ||
| 1443 | + returnCode = DjiPlayback_GetFrameNumberByTime(frameInfo, frameCount, &frameNumber, | ||
| 1444 | + startTimeMs); | ||
| 1445 | + if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) { | ||
| 1446 | + USER_LOG_ERROR("get start frame number error: 0x%08llX.", returnCode); | ||
| 1447 | + continue; | ||
| 1448 | + } | ||
| 1449 | + | ||
| 1450 | + if (fpFile != NULL) | ||
| 1451 | + fclose(fpFile); | ||
| 1452 | + | ||
| 1453 | +// fpfile 为转码文件 | ||
| 1454 | + fpFile = fopen(transcodedFilePath, "rb+"); | ||
| 1455 | + if (fpFile == NULL) { | ||
| 1456 | + USER_LOG_ERROR("open video file fail."); | ||
| 1457 | + continue; | ||
| 1458 | + } | ||
| 1459 | + | ||
| 1460 | +send: | ||
| 1461 | + if (fpFile == NULL) { | ||
| 1462 | + USER_LOG_ERROR("open video file fail."); | ||
| 1463 | + continue; | ||
| 1464 | + } | ||
| 1465 | + | ||
| 1466 | + if (sendVideoFlag != true) | ||
| 1467 | + continue; | ||
| 1468 | + | ||
| 1469 | + returnCode = DjiTest_CameraGetMode(&mode); | ||
| 1470 | + if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) { | ||
| 1471 | + continue; | ||
| 1472 | + } | ||
| 1473 | + | ||
| 1474 | + returnCode = DjiTest_CameraGetVideoStreamType(&videoStreamType); | ||
| 1475 | + if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) { | ||
| 1476 | + continue; | ||
| 1477 | + } | ||
| 1478 | + | ||
| 1479 | + if (mode == DJI_CAMERA_MODE_PLAYBACK && s_playbackInfo.isInPlayProcess == false) { | ||
| 1480 | + continue; | ||
| 1481 | + } | ||
| 1482 | + | ||
| 1483 | + if (!USER_UTIL_IS_WORK_TURN(sendVideoStep++, frameRate, SEND_VIDEO_TASK_FREQ)) | ||
| 1484 | + continue; | ||
| 1485 | + | ||
| 1486 | + frameBufSize = frameInfo[frameNumber].size; | ||
| 1487 | + if (videoStreamType == DJI_CAMERA_VIDEO_STREAM_TYPE_H264_DJI_FORMAT) { | ||
| 1488 | + frameBufSize = frameBufSize + VIDEO_FRAME_AUD_LEN; | ||
| 1489 | + } | ||
| 1490 | + | ||
| 1491 | + // 视频流解析 | ||
| 1492 | + // 视频内容的长度 分配 帧的内容长度数量 个 1字节 | ||
| 1493 | + dataBuffer = calloc(frameBufSize, 1); | ||
| 1494 | + if (dataBuffer == NULL) { | ||
| 1495 | + USER_LOG_ERROR("malloc fail."); | ||
| 1496 | + goto free; | ||
| 1497 | + } | ||
| 1498 | + | ||
| 1499 | + ret = fseek(fpFile, frameInfo[frameNumber].positionInFile, SEEK_SET); | ||
| 1500 | + if (ret != 0) { | ||
| 1501 | + USER_LOG_ERROR("fseek fail."); | ||
| 1502 | + goto free; | ||
| 1503 | + } | ||
| 1504 | + | ||
| 1505 | +// 读取内容长度 | ||
| 1506 | + dataLength = fread(dataBuffer, 1, frameInfo[frameNumber].size, fpFile); | ||
| 1507 | + if (dataLength != frameInfo[frameNumber].size) { | ||
| 1508 | + USER_LOG_ERROR("read data from video file error."); | ||
| 1509 | + } else { | ||
| 1510 | + USER_LOG_DEBUG("read data from video file success, len = %d B\r\n", dataLength); | ||
| 1511 | + } | ||
| 1512 | + | ||
| 1513 | + // 如果 视频流类型 为 大疆H264 类型 | ||
| 1514 | + if (videoStreamType == DJI_CAMERA_VIDEO_STREAM_TYPE_H264_DJI_FORMAT) { | ||
| 1515 | + // 将 审核的帧信息 复制到 数据内容 的 帧信息【帧数】大小 长度为 视频帧审核长度 | ||
| 1516 | + //USER_LOG_INFO("播放类型为大疆h264型"); | ||
| 1517 | + memcpy(&dataBuffer[frameInfo[frameNumber].size], s_frameAudInfo, VIDEO_FRAME_AUD_LEN); | ||
| 1518 | + dataLength = dataLength + VIDEO_FRAME_AUD_LEN; | ||
| 1519 | + } | ||
| 1520 | + | ||
| 1521 | + lengthOfDataHaveBeenSent = 0; | ||
| 1522 | + while (dataLength - lengthOfDataHaveBeenSent) { | ||
| 1523 | + lengthOfDataToBeSent = USER_UTIL_MIN(DATA_SEND_FROM_VIDEO_STREAM_MAX_LEN, | ||
| 1524 | + dataLength - lengthOfDataHaveBeenSent); | ||
| 1525 | + | ||
| 1526 | + // 推送(发送) 视频流 (databuffer序列 (存储的一帧图片数据+ 已经发送的数据长度 , 将要发送的数据长度 ) | ||
| 1527 | + // 用于返还 视频流通道的状态 | ||
| 1528 | + returnCode = DjiPayloadCamera_SendVideoStream((const uint8_t *) dataBuffer + lengthOfDataHaveBeenSent, | ||
| 1529 | + lengthOfDataToBeSent); | ||
| 1530 | + if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) { | ||
| 1531 | + USER_LOG_ERROR("send video stream error: 0x%08llX.", returnCode); | ||
| 1532 | + } | ||
| 1533 | + lengthOfDataHaveBeenSent += lengthOfDataToBeSent; | ||
| 1534 | + } | ||
| 1535 | + | ||
| 1536 | + (void)osalHandler->GetTimeMs(&sendExpect); | ||
| 1537 | + sendExpect += (1000 / frameRate); | ||
| 1538 | + | ||
| 1539 | + if ((frameNumber++) >= frameCount) { | ||
| 1540 | + USER_LOG_DEBUG("reach file tail."); | ||
| 1541 | + frameNumber = 0; | ||
| 1542 | + | ||
| 1543 | + if (sendOneTimeFlag == true) | ||
| 1544 | + sendVideoFlag = false; | ||
| 1545 | + } | ||
| 1546 | + | ||
| 1547 | + // 调整帧速率 | ||
| 1548 | + returnCode = DjiPayloadCamera_GetVideoStreamState(&videoStreamState); | ||
| 1549 | + if (returnCode == DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) { | ||
| 1550 | + USER_LOG_DEBUG( | ||
| 1551 | + "video stream state: realtimeBandwidthLimit: %d, realtimeBandwidthBeforeFlowController: %d, realtimeBandwidthAfterFlowController:%d busyState: %d.", | ||
| 1552 | + videoStreamState.realtimeBandwidthLimit, videoStreamState.realtimeBandwidthBeforeFlowController, | ||
| 1553 | + videoStreamState.realtimeBandwidthAfterFlowController, | ||
| 1554 | + videoStreamState.busyState); | ||
| 1555 | + } else { | ||
| 1556 | + USER_LOG_ERROR("get video stream state error."); | ||
| 1557 | + } | ||
| 1558 | + | ||
| 1559 | +free: | ||
| 1560 | + free(dataBuffer); | ||
| 1561 | + | ||
| 1562 | +Push_end: | ||
| 1563 | + continue; | ||
| 1564 | + } | ||
| 1565 | + | ||
| 1566 | +VideoSend_end: | ||
| 1567 | + if(ret < 0) | ||
| 1568 | + USER_LOG_ERROR("推流模块加载失败"); | ||
| 1569 | +} | ||
| 1570 | + | ||
| 1571 | + | ||
| 1572 | + | ||
| 1573 | +//录像播放测试函数,用于研发新产品时,图传播放录像使用 | ||
| 1574 | +static void *TestCameraMedia_SendVideoTask(void *arg) | ||
| 1575 | +{ | ||
| 1576 | + int ret; | ||
| 1577 | + // 回调错误 | ||
| 1578 | + T_DjiReturnCode returnCode; | ||
| 1579 | + //发送视频的阶数 | ||
| 1580 | + static uint32_t sendVideoStep = 0; | ||
| 1581 | + // 传输的视频文件 | ||
| 1582 | + FILE *fpFile = NULL; | ||
| 1583 | + //传输数据长度 一帧不能超过65kb 超过需要分割 | ||
| 1584 | + unsigned long dataLength = 0; | ||
| 1585 | + // 将要发送的产度 | ||
| 1586 | + uint16_t lengthOfDataToBeSent = 0; | ||
| 1587 | + // 上次已发送的长度 | ||
| 1588 | + int lengthOfDataHaveBeenSent = 0; | ||
| 1589 | + // 视频数据队列 | ||
| 1590 | + char *dataBuffer = NULL; | ||
| 1591 | + // 回放指令 | ||
| 1592 | + T_TestPayloadCameraPlaybackCommand playbackCommand = {0}; | ||
| 1593 | + // | ||
| 1594 | + uint16_t bufferReadSize = 0; | ||
| 1595 | + // 视频文件的地址 | ||
| 1596 | + char *videoFilePath = NULL; | ||
| 1597 | + // 转码文件的地址 | ||
| 1598 | + char *transcodedFilePath = NULL; | ||
| 1599 | + float frameRate = 1.0f; | ||
| 1600 | + // 帧信息 | ||
| 1601 | + T_TestPayloadCameraVideoFrameInfo *frameInfo = NULL; | ||
| 1602 | + // 帧数 | ||
| 1603 | + uint32_t frameNumber = 0; | ||
| 1604 | + // 总帧 | ||
| 1605 | + uint32_t frameCount = 0; | ||
| 1606 | + // 开始时间的 延迟 | ||
| 1607 | + uint32_t startTimeMs = 0; | ||
| 1608 | + // 发送文件的标识 | ||
| 1609 | + bool sendVideoFlag = true; | ||
| 1610 | + // 发送 一次 的 时间 标示 | ||
| 1611 | + bool sendOneTimeFlag = false; | ||
| 1612 | + // 视频流状态 | ||
| 1613 | + T_DjiDataChannelState videoStreamState = {0}; | ||
| 1614 | + // 拍照模式 | ||
| 1615 | + E_DjiCameraMode mode = DJI_CAMERA_MODE_SHOOT_PHOTO; | ||
| 1616 | + // ousl硬件层 句柄 | ||
| 1617 | + T_DjiOsalHandler *osalHandler = DjiPlatform_GetOsalHandler(); | ||
| 1618 | + uint32_t frameBufSize = 0; | ||
| 1619 | + // 视频流类型 | ||
| 1620 | + E_DjiCameraVideoStreamType videoStreamType; | ||
| 1621 | + // 通用 文件路径 | ||
| 1622 | + char curFileDirPath[DJI_FILE_PATH_SIZE_MAX]; | ||
| 1623 | + // 临时路径 | ||
| 1624 | + char tempPath[DJI_FILE_PATH_SIZE_MAX]; | ||
| 1625 | + | ||
| 1626 | + USER_UTIL_UNUSED(arg); | ||
| 1627 | + | ||
| 1628 | + | ||
| 1629 | + // 获取视频流文件信息 | ||
| 1630 | + // 获取 通用地址 的错误 | ||
| 1631 | + returnCode = DjiUserUtil_GetCurrentFileDirPath("/root/sdcard/DCIM", DJI_FILE_PATH_SIZE_MAX, curFileDirPath); | ||
| 1632 | + if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) { | ||
| 1633 | + USER_LOG_ERROR("Get file current path error, stat = 0x%08llX", returnCode); | ||
| 1634 | + exit(1); | ||
| 1635 | + } | ||
| 1636 | + | ||
| 1637 | + USER_LOG_INFO("curFileDirPath:%s",curFileDirPath); | ||
| 1638 | + | ||
| 1639 | + // if (s_isMediaFileDirPathConfigured == true) { | ||
| 1640 | + // snprintf(tempPath, DJI_FILE_PATH_SIZE_MAX, "%sPSDK_0005.h264", s_mediaFileDirPath); | ||
| 1641 | + // } else { | ||
| 1642 | + // snprintf(tempPath, DJI_FILE_PATH_SIZE_MAX, "%smedia_file/PSDK_0005.h264", curFileDirPath); | ||
| 1643 | + // } | ||
| 1644 | + snprintf(tempPath, DJI_FILE_PATH_SIZE_MAX, "/root/sdcard/media_file/PSDK_0005.h264", curFileDirPath); | ||
| 1645 | + | ||
| 1646 | + // 写入用于推送文件的临时地址 | ||
| 1647 | + // USER_LOG_INFO("tempPath:%s",tempPath); | ||
| 1648 | + | ||
| 1649 | + // 视频流处理线程初始化 | ||
| 1650 | + // 为视频文件申请 | ||
| 1651 | + videoFilePath = osalHandler->Malloc(DJI_FILE_PATH_SIZE_MAX); | ||
| 1652 | + if (videoFilePath == NULL) { | ||
| 1653 | + USER_LOG_ERROR("malloc memory for video file path fail."); | ||
| 1654 | + exit(1); | ||
| 1655 | + } | ||
| 1656 | + | ||
| 1657 | + // 转码文件的地址 | ||
| 1658 | + transcodedFilePath = osalHandler->Malloc(DJI_FILE_PATH_SIZE_MAX); | ||
| 1659 | + if (transcodedFilePath == NULL) { | ||
| 1660 | + USER_LOG_ERROR("malloc memory for transcoded file path fail."); | ||
| 1661 | + exit(1); | ||
| 1662 | + } | ||
| 1663 | + | ||
| 1664 | + // 帧信息 | ||
| 1665 | + frameInfo = osalHandler->Malloc(VIDEO_FRAME_MAX_COUNT * sizeof(T_TestPayloadCameraVideoFrameInfo)); | ||
| 1666 | + if (frameInfo == NULL) { | ||
| 1667 | + USER_LOG_ERROR("malloc memory for frame info fail."); | ||
| 1668 | + exit(1); | ||
| 1669 | + } | ||
| 1670 | + memset(frameInfo, 0, VIDEO_FRAME_MAX_COUNT * sizeof(T_TestPayloadCameraVideoFrameInfo)); | ||
| 1671 | + | ||
| 1672 | + | ||
| 1673 | + //停止 回放播放程序 | ||
| 1674 | + returnCode = DjiPlayback_StopPlayProcess(); | ||
| 1675 | + if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) { | ||
| 1676 | + USER_LOG_ERROR("stop playback and start liveview error: 0x%08llX.", returnCode); | ||
| 1677 | + exit(1); | ||
| 1678 | + } | ||
| 1679 | + | ||
| 1680 | + while (1) { | ||
| 1681 | + osalHandler->TaskSleepMs(1000 / SEND_VIDEO_TASK_FREQ); | ||
| 1682 | + | ||
| 1683 | + // response playback command | ||
| 1684 | + if (osalHandler->MutexLock(s_mediaPlayCommandBufferMutex) != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) { | ||
| 1685 | + USER_LOG_ERROR("mutex lock error"); | ||
| 1686 | + continue; | ||
| 1687 | + } | ||
| 1688 | + | ||
| 1689 | + bufferReadSize = UtilBuffer_Get(&s_mediaPlayCommandBufferHandler, (uint8_t *) &playbackCommand, | ||
| 1690 | + sizeof(T_TestPayloadCameraPlaybackCommand)); | ||
| 1691 | + | ||
| 1692 | + if (osalHandler->MutexUnlock(s_mediaPlayCommandBufferMutex) != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) { | ||
| 1693 | + USER_LOG_ERROR("mutex unlock error"); | ||
| 1694 | + continue; | ||
| 1695 | + } | ||
| 1696 | + | ||
| 1697 | + if (bufferReadSize != sizeof(T_TestPayloadCameraPlaybackCommand)) | ||
| 1698 | + goto send; | ||
| 1699 | + | ||
| 1700 | + switch (playbackCommand.command) { | ||
| 1701 | + case TEST_PAYLOAD_CAMERA_MEDIA_PLAY_COMMAND_STOP: | ||
| 1702 | + snprintf(videoFilePath, DJI_FILE_PATH_SIZE_MAX, "%s", tempPath); | ||
| 1703 | + startTimeMs = 0; | ||
| 1704 | + sendVideoFlag = true; | ||
| 1705 | + sendOneTimeFlag = false; | ||
| 1706 | + break; | ||
| 1707 | + case TEST_PAYLOAD_CAMERA_MEDIA_PLAY_COMMAND_PAUSE: | ||
| 1708 | + sendVideoFlag = false; | ||
| 1709 | + goto send; | ||
| 1710 | + case TEST_PAYLOAD_CAMERA_MEDIA_PLAY_COMMAND_START: | ||
| 1711 | + snprintf(videoFilePath, DJI_FILE_PATH_SIZE_MAX, "%s", playbackCommand.path); | ||
| 1712 | + startTimeMs = playbackCommand.timeMs; | ||
| 1713 | + sendVideoFlag = true; | ||
| 1714 | + sendOneTimeFlag = true; | ||
| 1715 | + break; | ||
| 1716 | + default: | ||
| 1717 | + USER_LOG_ERROR("playback command invalid: %d.", playbackCommand.command); | ||
| 1718 | + sendVideoFlag = false; | ||
| 1719 | + goto send; | ||
| 1720 | + } | ||
| 1721 | + | ||
| 1722 | + // video send preprocess | ||
| 1723 | + returnCode = DjiPlayback_VideoFileTranscode(videoFilePath, "h264", transcodedFilePath, | ||
| 1724 | + DJI_FILE_PATH_SIZE_MAX); | ||
| 1725 | + if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) { | ||
| 1726 | + USER_LOG_ERROR("transcode video file error: 0x%08llX.", returnCode); | ||
| 1727 | + continue; | ||
| 1728 | + } | ||
| 1729 | + | ||
| 1730 | + returnCode = DjiPlayback_GetFrameRateOfVideoFile(transcodedFilePath, &frameRate); | ||
| 1731 | + if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) { | ||
| 1732 | + USER_LOG_ERROR("get frame rate of video error: 0x%08llX.", returnCode); | ||
| 1733 | + continue; | ||
| 1734 | + } | ||
| 1735 | + | ||
| 1736 | + returnCode = DjiPlayback_GetFrameInfoOfVideoFile(transcodedFilePath, frameInfo, VIDEO_FRAME_MAX_COUNT, | ||
| 1737 | + &frameCount); | ||
| 1738 | + if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) { | ||
| 1739 | + USER_LOG_ERROR("get frame info of video error: 0x%08llX.", returnCode); | ||
| 1740 | + continue; | ||
| 1741 | + } | ||
| 1742 | + | ||
| 1743 | + returnCode = DjiPlayback_GetFrameNumberByTime(frameInfo, frameCount, &frameNumber, | ||
| 1744 | + startTimeMs); | ||
| 1745 | + if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) { | ||
| 1746 | + USER_LOG_ERROR("get start frame number error: 0x%08llX.", returnCode); | ||
| 1747 | + continue; | ||
| 1748 | + } | ||
| 1749 | + | ||
| 1750 | + if (fpFile != NULL) | ||
| 1751 | + fclose(fpFile); | ||
| 1752 | + | ||
| 1753 | + fpFile = fopen(transcodedFilePath, "rb+"); | ||
| 1754 | + if (fpFile == NULL) { | ||
| 1755 | + USER_LOG_ERROR("open video file fail."); | ||
| 1756 | + continue; | ||
| 1757 | + } | ||
| 1758 | + | ||
| 1759 | +send: | ||
| 1760 | + if (fpFile == NULL) { | ||
| 1761 | + USER_LOG_ERROR("open video file fail."); | ||
| 1762 | + continue; | ||
| 1763 | + } | ||
| 1764 | + | ||
| 1765 | + if (sendVideoFlag != true) | ||
| 1766 | + continue; | ||
| 1767 | + | ||
| 1768 | + returnCode = DjiTest_CameraGetMode(&mode); | ||
| 1769 | + if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) { | ||
| 1770 | + continue; | ||
| 1771 | + } | ||
| 1772 | + | ||
| 1773 | + returnCode = DjiTest_CameraGetVideoStreamType(&videoStreamType); | ||
| 1774 | + if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) { | ||
| 1775 | + continue; | ||
| 1776 | + } | ||
| 1777 | + | ||
| 1778 | + if (mode == DJI_CAMERA_MODE_PLAYBACK && s_playbackInfo.isInPlayProcess == false) { | ||
| 1779 | + continue; | ||
| 1780 | + } | ||
| 1781 | + | ||
| 1782 | + if (!USER_UTIL_IS_WORK_TURN(sendVideoStep++, frameRate, SEND_VIDEO_TASK_FREQ)) | ||
| 1783 | + continue; | ||
| 1784 | + | ||
| 1785 | + frameBufSize = frameInfo[frameNumber].size; | ||
| 1786 | + if (videoStreamType == DJI_CAMERA_VIDEO_STREAM_TYPE_H264_DJI_FORMAT) { | ||
| 1787 | + frameBufSize = frameBufSize + VIDEO_FRAME_AUD_LEN; | ||
| 1788 | + } | ||
| 1789 | + | ||
| 1790 | + dataBuffer = calloc(frameBufSize, 1); | ||
| 1791 | + if (dataBuffer == NULL) { | ||
| 1792 | + USER_LOG_ERROR("malloc fail."); | ||
| 1793 | + goto free; | ||
| 1794 | + } | ||
| 1795 | + | ||
| 1796 | + ret = fseek(fpFile, frameInfo[frameNumber].positionInFile, SEEK_SET); | ||
| 1797 | + if (ret != 0) { | ||
| 1798 | + USER_LOG_ERROR("fseek fail."); | ||
| 1799 | + goto free; | ||
| 1800 | + } | ||
| 1801 | + | ||
| 1802 | + dataLength = fread(dataBuffer, 1, frameInfo[frameNumber].size, fpFile); | ||
| 1803 | + if (dataLength != frameInfo[frameNumber].size) { | ||
| 1804 | + USER_LOG_ERROR("read data from video file error."); | ||
| 1805 | + } else { | ||
| 1806 | + USER_LOG_DEBUG("read data from video file success, len = %d B\r\n", dataLength); | ||
| 1807 | + } | ||
| 1808 | + | ||
| 1809 | + if (videoStreamType == DJI_CAMERA_VIDEO_STREAM_TYPE_H264_DJI_FORMAT) { | ||
| 1810 | + memcpy(&dataBuffer[frameInfo[frameNumber].size], s_frameAudInfo, VIDEO_FRAME_AUD_LEN); | ||
| 1811 | + dataLength = dataLength + VIDEO_FRAME_AUD_LEN; | ||
| 1812 | + } | ||
| 1813 | + | ||
| 1814 | + lengthOfDataHaveBeenSent = 0; | ||
| 1815 | + while (dataLength - lengthOfDataHaveBeenSent) { | ||
| 1816 | + lengthOfDataToBeSent = USER_UTIL_MIN(DATA_SEND_FROM_VIDEO_STREAM_MAX_LEN, | ||
| 1817 | + dataLength - lengthOfDataHaveBeenSent); | ||
| 1818 | + returnCode = DjiPayloadCamera_SendVideoStream((const uint8_t *) dataBuffer + lengthOfDataHaveBeenSent, | ||
| 1819 | + lengthOfDataToBeSent); | ||
| 1820 | + if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) { | ||
| 1821 | + USER_LOG_ERROR("send video stream error: 0x%08llX.", returnCode); | ||
| 1822 | + } | ||
| 1823 | + lengthOfDataHaveBeenSent += lengthOfDataToBeSent; | ||
| 1824 | + } | ||
| 1825 | + | ||
| 1826 | + if ((frameNumber++) >= frameCount) { | ||
| 1827 | + USER_LOG_DEBUG("reach file tail."); | ||
| 1828 | + frameNumber = 0; | ||
| 1829 | + | ||
| 1830 | + if (sendOneTimeFlag == true) | ||
| 1831 | + sendVideoFlag = false; | ||
| 1832 | + } | ||
| 1833 | + | ||
| 1834 | + returnCode = DjiPayloadCamera_GetVideoStreamState(&videoStreamState); | ||
| 1835 | + if (returnCode == DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) { | ||
| 1836 | + USER_LOG_DEBUG( | ||
| 1837 | + "video stream state: realtimeBandwidthLimit: %d, realtimeBandwidthBeforeFlowController: %d, realtimeBandwidthAfterFlowController:%d busyState: %d.", | ||
| 1838 | + videoStreamState.realtimeBandwidthLimit, videoStreamState.realtimeBandwidthBeforeFlowController, | ||
| 1839 | + videoStreamState.realtimeBandwidthAfterFlowController, | ||
| 1840 | + videoStreamState.busyState); | ||
| 1841 | + } else { | ||
| 1842 | + USER_LOG_ERROR("get video stream state error."); | ||
| 1843 | + } | ||
| 1844 | + | ||
| 1845 | +free: | ||
| 1846 | + free(dataBuffer); | ||
| 1847 | + } | ||
| 1848 | + | ||
| 1849 | +VideoSend_end: | ||
| 1850 | + if(ret < 0) | ||
| 1851 | + USER_LOG_ERROR("推流模块加载失败"); | ||
| 1852 | +} | ||
| 1853 | + | ||
| 1854 | +#ifndef __CC_ARM | ||
| 1855 | +#pragma GCC diagnostic pop | ||
| 1856 | +#endif | ||
| 1857 | + | ||
| 1858 | +//#endif | ||
| 1859 | + | ||
| 1860 | +/****************** (C) COPYRIGHT DJI Innovations *****END OF FILE****/ |
project_build/DJI_大疆PSDK/samples/sample_c/module_sample/camera_emu/test_payload_cam_emu_media.h
0 → 100644
| 1 | +/** | ||
| 2 | + ******************************************************************** | ||
| 3 | + * @file test_payload_cam_emu_media.h | ||
| 4 | + * @brief This is the header file for "test_payload_cam_media.c", defining the structure and | ||
| 5 | + * (exported) function prototypes. | ||
| 6 | + * | ||
| 7 | + * @copyright (c) 2021 DJI. All rights reserved. | ||
| 8 | + * | ||
| 9 | + * All information contained herein is, and remains, the property of DJI. | ||
| 10 | + * The intellectual and technical concepts contained herein are proprietary | ||
| 11 | + * to DJI and may be covered by U.S. and foreign patents, patents in process, | ||
| 12 | + * and protected by trade secret or copyright law. Dissemination of this | ||
| 13 | + * information, including but not limited to data and other proprietary | ||
| 14 | + * material(s) incorporated within the information, in any form, is strictly | ||
| 15 | + * prohibited without the express written consent of DJI. | ||
| 16 | + * | ||
| 17 | + * If you receive this source code without DJI’s authorization, you may not | ||
| 18 | + * further disseminate the information, and you must immediately remove the | ||
| 19 | + * source code and notify DJI of its removal. DJI reserves the right to pursue | ||
| 20 | + * legal actions against you for any loss(es) or damage(s) caused by your | ||
| 21 | + * failure to do so. | ||
| 22 | + * | ||
| 23 | + ********************************************************************* | ||
| 24 | + */ | ||
| 25 | + | ||
| 26 | +/* Define to prevent recursive inclusion -------------------------------------*/ | ||
| 27 | +#ifndef TEST_PAYLOAD_CAM_EMU_MEDIA_H | ||
| 28 | +#define TEST_PAYLOAD_CAM_EMU_MEDIA_H | ||
| 29 | + | ||
| 30 | +/* Includes ------------------------------------------------------------------*/ | ||
| 31 | +#include "dji_typedef.h" | ||
| 32 | +#include "dji_payload_camera.h" | ||
| 33 | + | ||
| 34 | +#ifdef __cplusplus | ||
| 35 | +extern "C" { | ||
| 36 | +#endif | ||
| 37 | + | ||
| 38 | +/* Exported constants --------------------------------------------------------*/ | ||
| 39 | + | ||
| 40 | +/* Exported types ------------------------------------------------------------*/ | ||
| 41 | + | ||
| 42 | +/* Exported functions --------------------------------------------------------*/ | ||
| 43 | +T_DjiReturnCode DjiTest_CameraEmuMediaStartService(int mode); | ||
| 44 | +T_DjiReturnCode DjiTest_CameraEmuSetMediaFilePath(const char *path); | ||
| 45 | +T_DjiReturnCode DjiTest_CameraMediaGetFileInfo(const char *filePath, T_DjiCameraMediaFileInfo *fileInfo); | ||
| 46 | + | ||
| 47 | +#ifdef __cplusplus | ||
| 48 | +} | ||
| 49 | +#endif | ||
| 50 | + | ||
| 51 | +#endif // TEST_PAYLOAD_CAM_EMU_MEDIA_H | ||
| 52 | +/************************ (C) COPYRIGHT DJI Innovations *******END OF FILE******/ |
project_build/DJI_大疆PSDK/samples/sample_c/module_sample/camera_manager/test_camera_manager.c
0 → 100644
此 diff 太大无法显示。
project_build/DJI_大疆PSDK/samples/sample_c/module_sample/camera_manager/test_camera_manager.h
0 → 100644
| 1 | +/** | ||
| 2 | + ******************************************************************** | ||
| 3 | + * @file test_camera_manager.h | ||
| 4 | + * @brief This is the header file for "test_camera_manager.c", defining the structure and | ||
| 5 | + * (exported) function prototypes. | ||
| 6 | + * | ||
| 7 | + * @copyright (c) 2021 DJI. All rights reserved. | ||
| 8 | + * | ||
| 9 | + * All information contained herein is, and remains, the property of DJI. | ||
| 10 | + * The intellectual and technical concepts contained herein are proprietary | ||
| 11 | + * to DJI and may be covered by U.S. and foreign patents, patents in process, | ||
| 12 | + * and protected by trade secret or copyright law. Dissemination of this | ||
| 13 | + * information, including but not limited to data and other proprietary | ||
| 14 | + * material(s) incorporated within the information, in any form, is strictly | ||
| 15 | + * prohibited without the express written consent of DJI. | ||
| 16 | + * | ||
| 17 | + * If you receive this source code without DJI’s authorization, you may not | ||
| 18 | + * further disseminate the information, and you must immediately remove the | ||
| 19 | + * source code and notify DJI of its removal. DJI reserves the right to pursue | ||
| 20 | + * legal actions against you for any loss(es) or damage(s) caused by your | ||
| 21 | + * failure to do so. | ||
| 22 | + * | ||
| 23 | + ********************************************************************* | ||
| 24 | + */ | ||
| 25 | + | ||
| 26 | +/* Define to prevent recursive inclusion -------------------------------------*/ | ||
| 27 | +#ifndef TEST_CAMERA_MANAGER_H | ||
| 28 | +#define TEST_CAMERA_MANAGER_H | ||
| 29 | + | ||
| 30 | +/* Includes ------------------------------------------------------------------*/ | ||
| 31 | +#include "dji_typedef.h" | ||
| 32 | +#include "dji_camera_manager.h" | ||
| 33 | + | ||
| 34 | +#ifdef __cplusplus | ||
| 35 | +extern "C" { | ||
| 36 | +#endif | ||
| 37 | + | ||
| 38 | +/* Exported constants --------------------------------------------------------*/ | ||
| 39 | + | ||
| 40 | +/* Exported types ------------------------------------------------------------*/ | ||
| 41 | +typedef enum { | ||
| 42 | + E_DJI_TEST_CAMERA_MANAGER_SAMPLE_SELECT_SET_CAMERA_SHUTTER_SPEED, | ||
| 43 | + E_DJI_TEST_CAMERA_MANAGER_SAMPLE_SELECT_SET_CAMERA_APERTURE, | ||
| 44 | + E_DJI_TEST_CAMERA_MANAGER_SAMPLE_SELECT_SET_CAMERA_EV, | ||
| 45 | + E_DJI_TEST_CAMERA_MANAGER_SAMPLE_SELECT_SET_CAMERA_ISO, | ||
| 46 | + E_DJI_TEST_CAMERA_MANAGER_SAMPLE_SELECT_SET_CAMERA_FOCUS_POINT, | ||
| 47 | + E_DJI_TEST_CAMERA_MANAGER_SAMPLE_SELECT_SET_CAMERA_TAP_ZOOM_POINT, | ||
| 48 | + E_DJI_TEST_CAMERA_MANAGER_SAMPLE_SELECT_SET_CAMERA_ZOOM_PARAM, | ||
| 49 | + E_DJI_TEST_CAMERA_MANAGER_SAMPLE_SELECT_SHOOT_SINGLE_PHOTO, | ||
| 50 | + E_DJI_TEST_CAMERA_MANAGER_SAMPLE_SELECT_SHOOT_BURST_PHOTO, | ||
| 51 | + E_DJI_TEST_CAMERA_MANAGER_SAMPLE_SELECT_SHOOT_INTERVAL_PHOTO, | ||
| 52 | + E_DJI_TEST_CAMERA_MANAGER_SAMPLE_SELECT_RECORD_VIDEO, | ||
| 53 | + E_DJI_TEST_CAMERA_MANAGER_SAMPLE_SELECT_DOWNLOAD_AND_DELETE_MEDIA_FILE, | ||
| 54 | + E_DJI_TEST_CAMERA_MANAGER_SAMPLE_SELECT_DOWNLOAD_FILE_LIST_BY_SLICES, | ||
| 55 | + E_DJI_TEST_CAMERA_MANAGER_SAMPLE_SELECT_THERMOMETRY, | ||
| 56 | + E_DJI_TEST_CAMERA_MANAGER_SAMPLE_SELECT_GET_LIDAR_RANGING_INFO, | ||
| 57 | + E_DJI_TEST_CAMERA_MANAGER_SAMPLE_SELECT_IR_CAMERA_ZOOM_PARAM, | ||
| 58 | + E_DJI_TEST_CAMERA_MANAGER_SAMPLE_SELECT_SET_NIGHT_SCENE_MODE, | ||
| 59 | + E_DJI_TEST_CAMERA_MANAGER_SAMPLE_SELECT_SET_CAPTURE_RECORDING_STREAMS, | ||
| 60 | + E_DJI_TEST_CAMERA_MANAGER_SAMPLE_SELECT_SHOW_STORAGE_INFO, | ||
| 61 | + E_DJI_TEST_CAMERA_MANAGER_SAMPLE_SELECT_FORMAT_SD_CARD, | ||
| 62 | + E_DJI_TEST_CAMERA_MANAGER_SAMPLE_SELECT_SET_LINK_ZOOM, | ||
| 63 | + E_DJI_TEST_CAMERA_MANAGER_SAMPLE_SELECT_SET_USER_CUSTOM_DIR_FILE_NAME, | ||
| 64 | + E_DJI_TEST_CAMERA_MANAGER_SAMPLE_SELECT_RESET_CAMERA_SETTINGS, | ||
| 65 | + E_DJI_TEST_CAMERA_MANAGER_SAMPLE_SELECT_SET_AE_LOCK_MODE, | ||
| 66 | + E_DJI_TEST_CAMERA_MANAGER_SAMPLE_SELECT_SET_FOCUS_RING_VALUE, | ||
| 67 | + E_DJI_TEST_CAMERA_MANAGER_SAMPLE_SELECT_CONNECT_STATUS_TEST, | ||
| 68 | + E_DJI_TEST_CAMERA_MANAGER_SAMPLE_SELECT_SET_GET_PHOTO_VIDEO_PARAM, | ||
| 69 | + E_DJI_TEST_CAMERA_MANAGER_SAMPLE_SELECT_SET_METERING_MODE, | ||
| 70 | + E_DJI_TEST_CAMERA_MANAGER_SAMPLE_SELECT_SET_METERING_POINT, | ||
| 71 | + E_DJI_TEST_CAMERA_MANAGER_SAMPLE_SELECT_FFC_MODE_AND_TRRIGER, | ||
| 72 | + E_DJI_TEST_CAMERA_MANAGER_SAMPLE_SELECT_SET_GAIN_MODE, | ||
| 73 | + E_DJI_TEST_CAMERA_MANAGER_SAMPLE_SELECT_GET_CAMERA_STATUS, | ||
| 74 | + E_DJI_TEST_CAMERA_MANAGER_SAMPLE_SELECT_SUBSCRIBE_POINT_CLOUD, | ||
| 75 | + E_DJI_TEST_CAMERA_MANAGER_SAMPLE_SELECT_INDEX_MAX | ||
| 76 | +} E_DjiTestCameraManagerSampleSelect; | ||
| 77 | +/* Exported functions --------------------------------------------------------*/ | ||
| 78 | + | ||
| 79 | +/*! @brief Sample to set exposure compensation value for camera, using async | ||
| 80 | + * api | ||
| 81 | + * | ||
| 82 | + * @note In this interface, exposure compensation value will be got then be | ||
| 83 | + * set. | ||
| 84 | + * @param index payload node index, input limit see enum | ||
| 85 | + * DJI::OSDK::PayloadIndexType | ||
| 86 | + * @param dataTarget the target exposure compensation value | ||
| 87 | + * @return T_DjiReturnCode error code | ||
| 88 | + */ | ||
| 89 | +T_DjiReturnCode DjiTest_CameraManagerSetEV(E_DjiMountPosition position, | ||
| 90 | + E_DjiCameraManagerExposureCompensation exposureCompensation); | ||
| 91 | + | ||
| 92 | +/*! @brief Sample to set exposure mode for camera, using async api | ||
| 93 | + * | ||
| 94 | + * @note In this interface, exposure will be got then be set. | ||
| 95 | + * @param index payload node index, input limit see enum | ||
| 96 | + * DJI::OSDK::PayloadIndexType | ||
| 97 | + * @param dataTarget the target exposure mode | ||
| 98 | + * @return T_DjiReturnCode error code | ||
| 99 | + */ | ||
| 100 | +T_DjiReturnCode DjiTest_CameraManagerSetExposureMode(E_DjiMountPosition position, | ||
| 101 | + E_DjiCameraManagerExposureMode exposureMode); | ||
| 102 | + | ||
| 103 | +/*! @brief Sample to set ISO value for camera, using async api | ||
| 104 | + * | ||
| 105 | + * @note In this interface, ISO will be got then be set. | ||
| 106 | + * @param index payload node index, input limit see enum | ||
| 107 | + * DJI::OSDK::PayloadIndexType | ||
| 108 | + * @param dataTarget the target ISO value | ||
| 109 | + * @return T_DjiReturnCode error code | ||
| 110 | + */ | ||
| 111 | +T_DjiReturnCode DjiTest_CameraManagerSetISO(E_DjiMountPosition position, | ||
| 112 | + E_DjiCameraManagerISO isoData); | ||
| 113 | +/*! @brief Sample to set shutter speed for camera, using async api | ||
| 114 | + * | ||
| 115 | + * @note In this interface, shutter speed will be got then be set. | ||
| 116 | + * @param index payload node index, input limit see enum | ||
| 117 | + * DJI::OSDK::PayloadIndexType | ||
| 118 | + * @param dataTarget the target shutter speed | ||
| 119 | + * @return T_DjiReturnCode error code | ||
| 120 | + */ | ||
| 121 | +T_DjiReturnCode DjiTest_CameraManagerSetShutterSpeed(E_DjiMountPosition position, | ||
| 122 | + E_DjiCameraManagerShutterSpeed shutterSpeed); | ||
| 123 | + | ||
| 124 | +/*! @brief Sample to set shutter aperture value for camera, using async api | ||
| 125 | + * | ||
| 126 | + * @note In this interface, aperture value will be got then be set. | ||
| 127 | + * @param index payload node index, input limit see enum | ||
| 128 | + * DJI::OSDK::PayloadIndexType | ||
| 129 | + * @param dataTarget the target aperture value | ||
| 130 | + * @return T_DjiReturnCode error code | ||
| 131 | + */ | ||
| 132 | +T_DjiReturnCode DjiTest_CameraManagerSetAperture(E_DjiMountPosition position, | ||
| 133 | + E_DjiCameraManagerAperture aperture); | ||
| 134 | + | ||
| 135 | +/*! @brief Sample to set focus point for camera, using async api | ||
| 136 | + * | ||
| 137 | + * @note In this interface, focus mode will be set to be AUTO. Then the | ||
| 138 | + * focus point will be set to be (x, y) | ||
| 139 | + * @param index payload node index, input limit see enum | ||
| 140 | + * DJI::OSDK::PayloadIndexType | ||
| 141 | + * @param x the x value of target focus point, 0~1 | ||
| 142 | + * @param y the y value of target focus point, 0~1 | ||
| 143 | + * @return T_DjiReturnCode error code | ||
| 144 | + */ | ||
| 145 | +T_DjiReturnCode DjiTest_CameraManagerSetFocusPoint(E_DjiMountPosition position, | ||
| 146 | + T_DjiCameraManagerFocusPosData tapFocusPos); | ||
| 147 | + | ||
| 148 | +/*! @brief Sample to set tap-zoom point for camera, using async api | ||
| 149 | + * | ||
| 150 | + * @note In this interface, tap-zoom function will be enable and the | ||
| 151 | + * multiplier will be set. Then the tap-zoom function will start with the | ||
| 152 | + * target tap-zoom point (x, y) | ||
| 153 | + * @param index payload node index, input limit see enum | ||
| 154 | + * DJI::OSDK::PayloadIndexType | ||
| 155 | + * @param multiplier the zoom multiplier of each tap zoom | ||
| 156 | + * @param x the x value of target tap-zoom point, 0~1 | ||
| 157 | + * @param y the y value of target tap-zoom point, 0~1 | ||
| 158 | + * @return T_DjiReturnCode error code | ||
| 159 | + */ | ||
| 160 | +T_DjiReturnCode DjiTest_CameraManagerSetTapZoomPoint(E_DjiMountPosition position, uint8_t multiplier, | ||
| 161 | + T_DjiCameraManagerTapZoomPosData tapZoomPosData); | ||
| 162 | +/*! @brief Sample to execute continuous zoom on camera, using sync api | ||
| 163 | + * | ||
| 164 | + * @note It is only supported by X5, X5R and X5S camera on Osmo with lens | ||
| 165 | + * Olympus M.Zuiko ED 14-42mm f/3.5-5.6 EZ, Z3 camera, Z30 camera. | ||
| 166 | + * @note In this interface, the zoom will start with the designated direction | ||
| 167 | + * and speed, and will stop after zoomTimeInSecond second(s). | ||
| 168 | + * @param index payload node index, input limit see enum | ||
| 169 | + * DJI::OSDK::PayloadIndexType | ||
| 170 | + * @param direction the choice of zoom out or zoom in | ||
| 171 | + * @param speed zooming speed | ||
| 172 | + * @return T_DjiReturnCode error code | ||
| 173 | + */ | ||
| 174 | +T_DjiReturnCode DjiTest_CameraManagerStartContinuousZoom(E_DjiMountPosition position, | ||
| 175 | + E_DjiCameraZoomDirection zoomDirection, | ||
| 176 | + E_DjiCameraZoomSpeed zoomSpeed); | ||
| 177 | + | ||
| 178 | +/*! @brief Sample to execute position zoom on camera, using sync api | ||
| 179 | + * | ||
| 180 | + * @note It is only supported by X5, X5R and X5S camera on Osmo with lens | ||
| 181 | + * Olympus M.Zuiko ED 14-42mm f/3.5-5.6 EZ, Z3 camera, Z30 camera. | ||
| 182 | + * @note In this interface, the zoom will set the zoom factor as the your | ||
| 183 | + * target value. | ||
| 184 | + * @param index payload node index, input limit see enum | ||
| 185 | + * DJI::OSDK::PayloadIndexType | ||
| 186 | + * @param factor target zoom factor | ||
| 187 | + * @return T_DjiReturnCode error code | ||
| 188 | + */ | ||
| 189 | +T_DjiReturnCode DjiTest_CameraManagerOpticalZoom(E_DjiMountPosition position, | ||
| 190 | + E_DjiCameraZoomDirection zoomDirection, | ||
| 191 | + dji_f32_t factor); | ||
| 192 | + | ||
| 193 | +/*! @brief Sample to stop continuous zoom on camera, using async api | ||
| 194 | + * | ||
| 195 | + * @note It is only supported by X5, X5R and X5S camera on Osmo with lens | ||
| 196 | + * Olympus M.Zuiko ED 14-42mm f/3.5-5.6 EZ, Z3 camera, Z30 camera. | ||
| 197 | + * @param index payload node index, input limit see enum | ||
| 198 | + * DJI::OSDK::PayloadIndexType | ||
| 199 | + * @return T_DjiReturnCode error code | ||
| 200 | + */ | ||
| 201 | +T_DjiReturnCode DjiTest_CameraManagerStopContinuousZoom(E_DjiMountPosition position); | ||
| 202 | + | ||
| 203 | +/*! @brief Sample to shoot single photo, using async api | ||
| 204 | + * | ||
| 205 | + * @note In this interface, camera will be set to be the SHOOT_PHOTO mode | ||
| 206 | + * then start to shoot a single photo. | ||
| 207 | + * @param index payload node index, input limit see enum | ||
| 208 | + * DJI::OSDK::PayloadIndexType | ||
| 209 | + * @return T_DjiReturnCode error code | ||
| 210 | + */ | ||
| 211 | +T_DjiReturnCode DjiTest_CameraManagerStartShootSinglePhoto(E_DjiMountPosition position); | ||
| 212 | + | ||
| 213 | +/*! @brief Sample to shoot burst photo, using async api | ||
| 214 | + * | ||
| 215 | + * @note In this interface, camera will be set to be the SHOOT_PHOTO mode | ||
| 216 | + * then start to shoot a burst photo. | ||
| 217 | + * @param index payload node index, input limit see enum | ||
| 218 | + * DJI::OSDK::PayloadIndexType | ||
| 219 | + * @param count The number of pictures in each burst shooting | ||
| 220 | + * @return T_DjiReturnCode error code | ||
| 221 | + */ | ||
| 222 | +T_DjiReturnCode DjiTest_CameraManagerStartShootBurstPhoto(E_DjiMountPosition position, | ||
| 223 | + E_DjiCameraBurstCount burstCount); | ||
| 224 | + | ||
| 225 | +/*! @brief Sample to start shooting interval photo, using async api | ||
| 226 | + * | ||
| 227 | + * @note In this interface, camera will be set to be the SHOOT_PHOTO mode | ||
| 228 | + * then start to shoot a interval photo. | ||
| 229 | + * @param index payload node index, input limit see enum | ||
| 230 | + * DJI::OSDK::PayloadIndexType | ||
| 231 | + * @param intervalData the parameter of interval shooting | ||
| 232 | + * @return T_DjiReturnCode error code | ||
| 233 | + */ | ||
| 234 | +T_DjiReturnCode DjiTest_CameraManagerStartShootIntervalPhoto(E_DjiMountPosition position, | ||
| 235 | + T_DjiCameraPhotoTimeIntervalSettings intervalData); | ||
| 236 | + | ||
| 237 | +/*! @brief Sample to stop shooting, using async api | ||
| 238 | + * | ||
| 239 | + * @note In this interface, camera will stop all the shooting action | ||
| 240 | + * @param index payload node index, input limit see enum | ||
| 241 | + * DJI::OSDK::PayloadIndexType | ||
| 242 | + * @return T_DjiReturnCode error code | ||
| 243 | + */ | ||
| 244 | +T_DjiReturnCode DjiTest_CameraManagerStopShootPhoto(E_DjiMountPosition position); | ||
| 245 | + | ||
| 246 | +/*! @brief Sample to start record video, using async api | ||
| 247 | + * | ||
| 248 | + * @note In this interface, camera will be set to be the RECORD_VIDEO mode | ||
| 249 | + * then start to record video. | ||
| 250 | + * @param index payload node index, input limit see enum | ||
| 251 | + * DJI::OSDK::PayloadIndexType | ||
| 252 | + * @return T_DjiReturnCode error code | ||
| 253 | + */ | ||
| 254 | +T_DjiReturnCode DjiTest_CameraManagerStartRecordVideo(E_DjiMountPosition position); | ||
| 255 | + | ||
| 256 | +/*! @brief Sample to stop record video, using async api | ||
| 257 | + * | ||
| 258 | + * @note In this interface, camera will be set to be the RECORD_VIDEO mode | ||
| 259 | + * then stop recording video. | ||
| 260 | + * @param index payload node index, input limit see enum | ||
| 261 | + * DJI::OSDK::PayloadIndexType | ||
| 262 | + * @return T_DjiReturnCode error code | ||
| 263 | + */ | ||
| 264 | +T_DjiReturnCode DjiTest_CameraManagerStopRecordVideo(E_DjiMountPosition position); | ||
| 265 | + | ||
| 266 | +T_DjiReturnCode DjiTest_CameraManagerRunSample(E_DjiMountPosition mountPosition, | ||
| 267 | + E_DjiTestCameraManagerSampleSelect cameraManagerSampleSelect); | ||
| 268 | + | ||
| 269 | +#ifdef __cplusplus | ||
| 270 | +} | ||
| 271 | +#endif | ||
| 272 | + | ||
| 273 | +#endif // TEST_CAMERA_MANAGER_H | ||
| 274 | +/************************ (C) COPYRIGHT DJI Innovations *******END OF FILE******/ |
-
请 注册 或 登录 后发表评论