合并分支 'dev_00.00.02.00' 到 'master'
Dev 00.00.02.02 查看合并请求 !2
正在显示
18 个修改的文件
包含
4867 行增加
和
2 行删除
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******/ |
-
请 注册 或 登录 后发表评论