正在显示
21 个修改的文件
包含
3702 行增加
和
372 行删除
@@ -145,7 +145,8 @@ | @@ -145,7 +145,8 @@ | ||
145 | "jzsdk_expansion.h": "c", | 145 | "jzsdk_expansion.h": "c", |
146 | "jzsdk_expansionapi.h": "c", | 146 | "jzsdk_expansionapi.h": "c", |
147 | "test_widget_speaker.h": "c", | 147 | "test_widget_speaker.h": "c", |
148 | - "dji_expansion.h": "c" | 148 | + "dji_expansion.h": "c", |
149 | + "test_widget.h": "c" | ||
149 | }, | 150 | }, |
150 | "Codegeex.GenerationPreference": "automatic", | 151 | "Codegeex.GenerationPreference": "automatic", |
151 | "C_Cpp.dimInactiveRegions": false, | 152 | "C_Cpp.dimInactiveRegions": false, |
1 | # 编译链的配置 | 1 | # 编译链的配置 |
2 | 2 | ||
3 | #1、编译链与设备类型的选择 | 3 | #1、编译链与设备类型的选择 |
4 | -set(DEVICE_NAME JZ_H1E) | 4 | +set(DEVICE_NAME JZ_H150G) |
5 | #上一行为禁止修改行 | 5 | #上一行为禁止修改行 |
6 | 6 | ||
7 | message("**************************JZSDK构建编译开始***************************\n") | 7 | message("**************************JZSDK构建编译开始***************************\n") |
@@ -7,7 +7,7 @@ | @@ -7,7 +7,7 @@ | ||
7 | #define VERSION_CHOOSE_H | 7 | #define VERSION_CHOOSE_H |
8 | #include "JZsdk_Base/JZsdk_Code/JZsdk_DeviceCode.h" | 8 | #include "JZsdk_Base/JZsdk_Code/JZsdk_DeviceCode.h" |
9 | //1~10行 除了D可以修改版本选择 禁止动任何东西 | 9 | //1~10行 除了D可以修改版本选择 禁止动任何东西 |
10 | -#define DEVICE_VERSION JZ_H1E | 10 | +#define DEVICE_VERSION JZ_H150G |
11 | 11 | ||
12 | //禁止修改行 选择是串口程序 还是 psdk程序 | 12 | //禁止修改行 选择是串口程序 还是 psdk程序 |
13 | #define APP_VERSION APP_PSDK | 13 | #define APP_VERSION APP_PSDK |
@@ -23,7 +23,7 @@ | @@ -23,7 +23,7 @@ | ||
23 | #define MODIFY_VERSION_TEN_POSITION 1 | 23 | #define MODIFY_VERSION_TEN_POSITION 1 |
24 | #define MODIFY_VERSION_ONE_POSITION 1 | 24 | #define MODIFY_VERSION_ONE_POSITION 1 |
25 | #define DEBUG_VERSION_TEN_POSITION 0 | 25 | #define DEBUG_VERSION_TEN_POSITION 0 |
26 | -#define DEBUG_VERSION_ONE_POSITION 5 | 26 | +#define DEBUG_VERSION_ONE_POSITION 3 |
27 | 27 | ||
28 | 28 | ||
29 | 29 |
@@ -66,7 +66,6 @@ int num_flag=0;//版本号信息 | @@ -66,7 +66,6 @@ int num_flag=0;//版本号信息 | ||
66 | extern int height_Volume_lock; | 66 | extern int height_Volume_lock; |
67 | 67 | ||
68 | extern int SpeakerWidgetUseLock; | 68 | extern int SpeakerWidgetUseLock; |
69 | -extern char Jz_SerialNumber[128]; //设备序列号 | ||
70 | extern float g_height_value; | 69 | extern float g_height_value; |
71 | extern int Widget_RealTimeOpusFlag; //用于标志ui里的实时语音开关 | 70 | extern int Widget_RealTimeOpusFlag; //用于标志ui里的实时语音开关 |
72 | 71 |
project_build/Zy/.gitignore
已删除
100644 → 0
1 | -# Prerequisites | ||
2 | -*.d | ||
3 | - | ||
4 | -# Compiled Object files | ||
5 | -*.slo | ||
6 | -*.lo | ||
7 | -*.o | ||
8 | -*.obj | ||
9 | - | ||
10 | -# Precompiled Headers | ||
11 | -*.gch | ||
12 | -*.pch | ||
13 | - | ||
14 | -# Compiled Dynamic libraries | ||
15 | -*.so | ||
16 | -*.dylib | ||
17 | -*.dll | ||
18 | - | ||
19 | -# Fortran module files | ||
20 | -*.mod | ||
21 | -*.smod | ||
22 | - | ||
23 | -# Compiled Static libraries | ||
24 | -*.lai | ||
25 | -*.la | ||
26 | -.a | ||
27 | -.lib | ||
28 | - | ||
29 | -# Executables | ||
30 | -*.exe | ||
31 | -*.out | ||
32 | -*.app |
project_build/Zy/README.md
已删除
100644 → 0
1 | -# Ziyan Payload SDK (PSDK) | ||
2 | - | ||
3 | - | ||
4 | - | ||
5 | -## What is the Ziyan Payload SDK? | ||
6 | - | ||
7 | -The ziyan Payload SDK(PSDK), is a development kit provided by ziyan to support developers to develop payload that can be mounted on ziyan aircraft. developers can obtain the information or other resource from the aircraft. According to the software logic and algorithm framework designed by the developer, users could develop payload that can be mounted on ziyan aircraft, to perform actions they need, such as Automated Flight Controller, Payload Controller, Video Image Analysis Platform, Mapping Camera, Megaphone And Searchlight, etc. | ||
8 | - | ||
9 | - | ||
10 | - | ||
11 | -## Latest Release | ||
12 | - | ||
13 | -The latest release version of PSDK is 1.0.0.0 This version of Payload SDK mainly first release. Please refer to the release notes for detailed changes list. | ||
14 | - | ||
15 | -## License | ||
16 | - | ||
17 | -Payload SDK codebase is MIT-licensed. Please refer to the LICENSE file for detailed information. | ||
18 | - | ||
19 | -# Ziyan Payload SDK (PSDK) | ||
20 | - | ||
21 | -## 什么是Ziyan Payload SDK? | ||
22 | - | ||
23 | -Ziyan Payload SDK(PSDK)是由Ziyan提供的一套开发工具包,支持开发者开发可以安装在Ziyan无人机上的有效载荷。开发者可以从无人机获取信息或其他资源。根据开发者设计的软件逻辑和算法框架,用户可以开发出可以安装在Ziyan无人机上的有效载荷,以执行他们需要的操作,例如自动飞行控制器、有效载荷控制器、视频图像分析平台、测绘相机、扩音器和探照灯等。 | ||
24 | - | ||
25 | -## 最新版本 | ||
26 | - | ||
27 | -PSDK的最新版本是1.0.0.0。这个版本的Payload SDK主要是首次发布。请参考发布说明以获取详细的变更列表。 | ||
28 | - | ||
29 | -## 许可证 | ||
30 | - | ||
31 | -Payload SDK的代码库采用MIT许可证。请参考LICENSE文件以获取详细信息。 |
project_build/Zy/ReleaseNotes.md
已删除
100644 → 0
1 | -# Ziyan Payload SDK Release Log | ||
2 | - | ||
3 | - | ||
4 | - | ||
5 | -## V1.0.0.2-20250401-Release | ||
6 | - | ||
7 | -**[Note]**: | ||
8 | -To support more camera expansion features, Add new camera API. Fixed some known issues. | ||
9 | - | ||
10 | -**[Added]**: | ||
11 | -* Add API which used to get obtain camera calculation position. | ||
12 | -* Add API which used to control the camera tracker integrated into the payload camera. | ||
13 | - | ||
14 | -**[Fixed]**: | ||
15 | -* Fix the issue that the camera status is not updated when the camera has connected. | ||
16 | -* Fix occasional screen distortion in camera videos | ||
17 | ---- | ||
18 | - | ||
19 | - | ||
20 | - | ||
21 | - | ||
22 | - | ||
23 | -## V1.0.0.1-20250310-Release | ||
24 | -**[Note]**: | ||
25 | -To support more camera expansion features, Add new camera API. Fixed some known issues. | ||
26 | - | ||
27 | -**[Added]**: | ||
28 | -* Add API which used to control the range finder integrated into the payload camera. | ||
29 | ---- | ||
30 | - | ||
31 | - | ||
32 | - | ||
33 | - | ||
34 | - | ||
35 | -## V1.0.0.0-20250306-Release | ||
36 | -**[Note]**: | ||
37 | -This version of Payload SDK mainly first release. Please refer to the release notes for detailed changes list. | ||
38 | - | ||
39 | -**[Added]**: | ||
40 | -* Added support for gimbal functionality | ||
41 | -* Added support for basic camera functionality | ||
42 | -* Added support for widget functionality | ||
43 | -* Added support for subscription functionality | ||
44 | ---- | ||
45 | - | ||
46 | - | ||
47 | -# Ziyan Payload SDK 发布日志 | ||
48 | - | ||
49 | -## V1.0.0.2-20250401-发布 | ||
50 | - | ||
51 | -**[注意]**: | ||
52 | -为了支持更多的相机扩展功能,添加了新的相机API。修复了一些已知问题。 | ||
53 | - | ||
54 | -**[新增]**: | ||
55 | -* 添加用于获取相机计算位置的API。 | ||
56 | -* 添加用于控制集成在有效载荷相机中的相机跟踪器的API。 | ||
57 | - | ||
58 | -**[修复]**: | ||
59 | -* 修复了相机连接时相机状态未更新的问题。 | ||
60 | -* 修复了相机视频中偶尔出现的屏幕扭曲问题 | ||
61 | ---- | ||
62 | - | ||
63 | - | ||
64 | - | ||
65 | - | ||
66 | -## V1.0.0.1-20250310-发布 | ||
67 | -**[注意]**: | ||
68 | -为了支持更多的相机扩展功能,添加了新的相机API。修复了一些已知问题。 | ||
69 | - | ||
70 | -**[新增]**: | ||
71 | -* 添加用于控制集成在有效载荷相机中的测距仪的API。 | ||
72 | ---- | ||
73 | - | ||
74 | - | ||
75 | - | ||
76 | - | ||
77 | - | ||
78 | -## V1.0.0.0-20250306-发布 | ||
79 | -**[注意]**: | ||
80 | -这个版本的Payload SDK主要是首次发布。请参考发布说明以获取详细的变更列表。 | ||
81 | - | ||
82 | -**[新增]**: | ||
83 | -* 增加了支持云台功能 | ||
84 | -* 增加了支持基本相机功能 | ||
85 | -* 增加了支持小部件功能 | ||
86 | -* 增加了支持订阅功能 | ||
87 | ---- | ||
88 | - | ||
89 | - |
1 | /** | 1 | /** |
2 | ******************************************************************** | 2 | ******************************************************************** |
3 | - * @file dji_aircraft_info.h | ||
4 | - * @brief This is the header file for "dji_aircraft_info.c", defining the structure and | 3 | + * @file ziyan_aircraft_info.h |
4 | + * @brief This is the header file for "ziyan_aircraft_info.c", defining the structure and | ||
5 | * (exported) function prototypes. | 5 | * (exported) function prototypes. |
6 | * | 6 | * |
7 | * @copyright (c) 2021 ZIYAN. All rights reserved. | 7 | * @copyright (c) 2021 ZIYAN. All rights reserved. |
@@ -43,7 +43,7 @@ typedef enum { | @@ -43,7 +43,7 @@ typedef enum { | ||
43 | * @note This transfer type only support linux platform and use network port. Users need to deploy FTP service on | 43 | * @note This transfer type only support linux platform and use network port. Users need to deploy FTP service on |
44 | * payload. The ftp user info used to transfer upgrade firmware is : | 44 | * payload. The ftp user info used to transfer upgrade firmware is : |
45 | * username:ziyan_payload_ftp | 45 | * username:ziyan_payload_ftp |
46 | - * password:DJi_#$31 | 46 | + * password:Ziyan_#$31 |
47 | * You can get guide about FTP service deployment on https://developer.ziyan.com/payload-sdk/documentation | 47 | * You can get guide about FTP service deployment on https://developer.ziyan.com/payload-sdk/documentation |
48 | */ | 48 | */ |
49 | ZIYAN_FIRMWARE_TRANSFER_TYPE_FTP = 0, | 49 | ZIYAN_FIRMWARE_TRANSFER_TYPE_FTP = 0, |
@@ -36,7 +36,7 @@ extern "C" { | @@ -36,7 +36,7 @@ extern "C" { | ||
36 | #define ZIYAN_SDK_VERSION_MAJOR 1 /*!< ZIYAN SDK major version num, when have incompatible API changes. Range from 0 to 99. */ | 36 | #define ZIYAN_SDK_VERSION_MAJOR 1 /*!< ZIYAN SDK major version num, when have incompatible API changes. Range from 0 to 99. */ |
37 | #define ZIYAN_SDK_VERSION_MINOR 0 /*!< ZIYAN SDK minor version num, when add functionality in a backwards compatible manner changes. Range from 0 to 99. */ | 37 | #define ZIYAN_SDK_VERSION_MINOR 0 /*!< ZIYAN SDK minor version num, when add functionality in a backwards compatible manner changes. Range from 0 to 99. */ |
38 | #define ZIYAN_SDK_VERSION_MODIFY 0 /*!< ZIYAN SDK modify version num, when have backwards compatible bug fixes changes. Range from 0 to 99. */ | 38 | #define ZIYAN_SDK_VERSION_MODIFY 0 /*!< ZIYAN SDK modify version num, when have backwards compatible bug fixes changes. Range from 0 to 99. */ |
39 | -#define ZIYAN_SDK_VERSION_DEBUG 2 /*!< ZIYAN SDK version beta info, release version will be 0, when beta version release changes. Range from 0 to 255. */ | 39 | +#define ZIYAN_SDK_VERSION_DEBUG 4 /*!< ZIYAN SDK version beta info, release version will be 0, when beta version release changes. Range from 0 to 255. */ |
40 | #define ZIYAN_SDK_VERSION_BUILD 1 /*!< ZIYAN SDK version build info, when jenkins trigger build changes. Range from 0 to 65535. */ | 40 | #define ZIYAN_SDK_VERSION_BUILD 1 /*!< ZIYAN SDK version build info, when jenkins trigger build changes. Range from 0 to 65535. */ |
41 | 41 | ||
42 | /* Exported types ------------------------------------------------------------*/ | 42 | /* Exported types ------------------------------------------------------------*/ |
project_build/Zy/samples/sample_c/module_sample/camera_emu/test_payload_cam_emu_base.bak
已删除
100644 → 0
此 diff 太大无法显示。
@@ -763,13 +763,13 @@ static T_ZiyanReturnCode GetMediaFileDir(char *dirPath) | @@ -763,13 +763,13 @@ static T_ZiyanReturnCode GetMediaFileDir(char *dirPath) | ||
763 | char curFileDirPath[ZIYAN_FILE_PATH_SIZE_MAX]; | 763 | char curFileDirPath[ZIYAN_FILE_PATH_SIZE_MAX]; |
764 | char tempPath[ZIYAN_FILE_PATH_SIZE_MAX]; | 764 | char tempPath[ZIYAN_FILE_PATH_SIZE_MAX]; |
765 | 765 | ||
766 | - returnCode = ZiyanUserUtil_GetCurrentFileDirPath(__FILE__, ZIYAN_FILE_PATH_SIZE_MAX, curFileDirPath); | 766 | + returnCode = ZiyanUserUtil_GetCurrentFileDirPath(__FILE__, sizeof(curFileDirPath), curFileDirPath); |
767 | if (returnCode != ZIYAN_ERROR_SYSTEM_MODULE_CODE_SUCCESS) { | 767 | if (returnCode != ZIYAN_ERROR_SYSTEM_MODULE_CODE_SUCCESS) { |
768 | USER_LOG_ERROR("Get file current path error, stat = 0x%08llX", returnCode); | 768 | USER_LOG_ERROR("Get file current path error, stat = 0x%08llX", returnCode); |
769 | return returnCode; | 769 | return returnCode; |
770 | } | 770 | } |
771 | 771 | ||
772 | - snprintf(dirPath, ZIYAN_FILE_PATH_SIZE_MAX, "%smedia_file", curFileDirPath); | 772 | + snprintf(dirPath, ZIYAN_FILE_PATH_SIZE_MAX + 32, "%smedia_file", curFileDirPath); |
773 | 773 | ||
774 | return ZIYAN_ERROR_SYSTEM_MODULE_CODE_SUCCESS; | 774 | return ZIYAN_ERROR_SYSTEM_MODULE_CODE_SUCCESS; |
775 | } | 775 | } |
project_build/Zy/samples/sample_c/module_sample/camera_emu/test_payload_cam_emu_media.c.bak
0 → 100644
1 | +/** | ||
2 | + ******************************************************************** | ||
3 | + * @file test_payload_cam_emu_media.c | ||
4 | + * @brief | ||
5 | + * | ||
6 | + * @copyright (c) 2021 ZIYAN. All rights reserved. | ||
7 | + * | ||
8 | + * All information contained herein is, and remains, the property of ZIYAN. | ||
9 | + * The intellectual and technical concepts contained herein are proprietary | ||
10 | + * to ZIYAN 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 ZIYAN. | ||
15 | + * | ||
16 | + * If you receive this source code without ZIYAN’s authorization, you may not | ||
17 | + * further disseminate the information, and you must immediately remove the | ||
18 | + * source code and notify ZIYAN of its removal. ZIYAN 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 "ziyan_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/ziyan_media_file_manage/ziyan_media_file_core.h" | ||
36 | +#include "ziyan_high_speed_data_channel.h" | ||
37 | +#include "ziyan_aircraft_info.h" | ||
38 | + | ||
39 | +/* Private constants ---------------------------------------------------------*/ | ||
40 | +#define FFMPEG_CMD_BUF_SIZE (256 + 256) | ||
41 | +#define SEND_VIDEO_TASK_FREQ 120 | ||
42 | +#define VIDEO_FRAME_MAX_COUNT 18000 // max video duration 10 minutes | ||
43 | +#define VIDEO_FRAME_AUD_LEN 6 | ||
44 | +#define DATA_SEND_FROM_VIDEO_STREAM_MAX_LEN 60000 | ||
45 | + | ||
46 | +/* Private types -------------------------------------------------------------*/ | ||
47 | +typedef enum { | ||
48 | + TEST_PAYLOAD_CAMERA_MEDIA_PLAY_COMMAND_STOP = 0, | ||
49 | + TEST_PAYLOAD_CAMERA_MEDIA_PLAY_COMMAND_PAUSE = 1, | ||
50 | + TEST_PAYLOAD_CAMERA_MEDIA_PLAY_COMMAND_START = 2, | ||
51 | +} E_TestPayloadCameraPlaybackCommand; | ||
52 | + | ||
53 | +typedef struct { | ||
54 | + uint8_t isInPlayProcess; | ||
55 | + uint16_t videoIndex; | ||
56 | + char filePath[ZIYAN_FILE_PATH_SIZE_MAX]; | ||
57 | + uint32_t videoLengthMs; | ||
58 | + uint64_t startPlayTimestampsUs; | ||
59 | + uint64_t playPosMs; | ||
60 | +} T_ZiyanPlaybackInfo; | ||
61 | + | ||
62 | +typedef struct { | ||
63 | + E_TestPayloadCameraPlaybackCommand command; | ||
64 | + uint32_t timeMs; | ||
65 | + char path[ZIYAN_FILE_PATH_SIZE_MAX]; | ||
66 | +} T_TestPayloadCameraPlaybackCommand; | ||
67 | + | ||
68 | +typedef struct { | ||
69 | + float durationS; | ||
70 | + uint32_t positionInFile; | ||
71 | + uint32_t size; | ||
72 | +} T_TestPayloadCameraVideoFrameInfo; | ||
73 | + | ||
74 | +/* Private functions declaration ---------------------------------------------*/ | ||
75 | +static T_ZiyanReturnCode ZiyanPlayback_StopPlay(T_ZiyanPlaybackInfo *playbackInfo); | ||
76 | +static T_ZiyanReturnCode ZiyanPlayback_PausePlay(T_ZiyanPlaybackInfo *playbackInfo); | ||
77 | +static T_ZiyanReturnCode ZiyanPlayback_SetPlayFile(T_ZiyanPlaybackInfo *playbackInfo, const char *filePath, | ||
78 | + uint16_t index); | ||
79 | +static T_ZiyanReturnCode ZiyanPlayback_SeekPlay(T_ZiyanPlaybackInfo *playbackInfo, uint32_t seekPos); | ||
80 | +static T_ZiyanReturnCode ZiyanPlayback_StartPlay(T_ZiyanPlaybackInfo *playbackInfo); | ||
81 | +static T_ZiyanReturnCode ZiyanPlayback_GetPlaybackStatus(T_ZiyanPlaybackInfo *playbackInfo, | ||
82 | + T_ZiyanCameraPlaybackStatus *playbackStatus); | ||
83 | +static T_ZiyanReturnCode ZiyanPlayback_GetVideoLengthMs(const char *filePath, uint32_t *videoLengthMs); | ||
84 | +static T_ZiyanReturnCode ZiyanPlayback_StartPlayProcess(const char *filePath, uint32_t playPosMs); | ||
85 | +static T_ZiyanReturnCode ZiyanPlayback_StopPlayProcess(void); | ||
86 | +static T_ZiyanReturnCode | ||
87 | +ZiyanPlayback_VideoFileTranscode(const char *inPath, const char *outFormat, char *outPath, uint16_t outPathBufferSize); | ||
88 | +static T_ZiyanReturnCode | ||
89 | +ZiyanPlayback_GetFrameInfoOfVideoFile(const char *path, T_TestPayloadCameraVideoFrameInfo *frameInfo, | ||
90 | + uint32_t frameInfoBufferCount, uint32_t *frameCount); | ||
91 | +static T_ZiyanReturnCode ZiyanPlayback_GetFrameRateOfVideoFile(const char *path, float *frameRate); | ||
92 | +static T_ZiyanReturnCode | ||
93 | +ZiyanPlayback_GetFrameNumberByTime(T_TestPayloadCameraVideoFrameInfo *frameInfo, uint32_t frameCount, | ||
94 | + uint32_t *frameNumber, uint32_t timeMs); | ||
95 | +static T_ZiyanReturnCode GetMediaFileDir(char *dirPath); | ||
96 | +static T_ZiyanReturnCode GetMediaFileOriginData(const char *filePath, uint32_t offset, uint32_t length, | ||
97 | + uint8_t *data); | ||
98 | + | ||
99 | +static T_ZiyanReturnCode CreateMediaFileThumbNail(const char *filePath); | ||
100 | +static T_ZiyanReturnCode GetMediaFileThumbNailInfo(const char *filePath, T_ZiyanCameraMediaFileInfo *fileInfo); | ||
101 | +static T_ZiyanReturnCode GetMediaFileThumbNailData(const char *filePath, uint32_t offset, uint32_t length, | ||
102 | + uint8_t *data); | ||
103 | +static T_ZiyanReturnCode DestroyMediaFileThumbNail(const char *filePath); | ||
104 | + | ||
105 | +static T_ZiyanReturnCode CreateMediaFileScreenNail(const char *filePath); | ||
106 | +static T_ZiyanReturnCode GetMediaFileScreenNailInfo(const char *filePath, T_ZiyanCameraMediaFileInfo *fileInfo); | ||
107 | +static T_ZiyanReturnCode GetMediaFileScreenNailData(const char *filePath, uint32_t offset, uint32_t length, | ||
108 | + uint8_t *data); | ||
109 | +static T_ZiyanReturnCode DestroyMediaFileScreenNail(const char *filePath); | ||
110 | + | ||
111 | +static T_ZiyanReturnCode DeleteMediaFile(char *filePath); | ||
112 | +static T_ZiyanReturnCode SetMediaPlaybackFile(const char *filePath); | ||
113 | +static T_ZiyanReturnCode StartMediaPlayback(void); | ||
114 | +static T_ZiyanReturnCode StopMediaPlayback(void); | ||
115 | +static T_ZiyanReturnCode PauseMediaPlayback(void); | ||
116 | +static T_ZiyanReturnCode SeekMediaPlayback(uint32_t playbackPosition); | ||
117 | +static T_ZiyanReturnCode GetMediaPlaybackStatus(T_ZiyanCameraPlaybackStatus *status); | ||
118 | + | ||
119 | +static T_ZiyanReturnCode StartDownloadNotification(void); | ||
120 | +static T_ZiyanReturnCode StopDownloadNotification(void); | ||
121 | + | ||
122 | +_Noreturn static void *UserCameraMedia_SendVideoTask(void *arg); | ||
123 | + | ||
124 | +/* Private variables -------------------------------------------------------------*/ | ||
125 | +static T_ZiyanCameraMediaDownloadPlaybackHandler s_psdkCameraMedia = {0}; | ||
126 | +static T_ZiyanPlaybackInfo s_playbackInfo = {0}; | ||
127 | +static T_ZiyanTaskHandle s_userSendVideoThread; | ||
128 | +static T_UtilBuffer s_mediaPlayCommandBufferHandler = {0}; | ||
129 | +static T_ZiyanMutexHandle s_mediaPlayCommandBufferMutex = {0}; | ||
130 | +static T_ZiyanSemaHandle s_mediaPlayWorkSem = NULL; | ||
131 | +static uint8_t s_mediaPlayCommandBuffer[sizeof(T_TestPayloadCameraPlaybackCommand) * 32] = {0}; | ||
132 | +static const char *s_frameKeyChar = "[PACKET]"; | ||
133 | +static const char *s_frameDurationTimeKeyChar = "duration_time"; | ||
134 | +static const char *s_framePositionKeyChar = "pos"; | ||
135 | +static const char *s_frameSizeKeyChar = "size"; | ||
136 | +static T_ZiyanMediaFileHandle s_mediaFileThumbNailHandle; | ||
137 | +static T_ZiyanMediaFileHandle s_mediaFileScreenNailHandle; | ||
138 | +static const uint8_t s_frameAudInfo[VIDEO_FRAME_AUD_LEN] = {0x00, 0x00, 0x00, 0x01, 0x09, 0x10}; | ||
139 | +static char s_mediaFileDirPath[ZIYAN_FILE_PATH_SIZE_MAX] = {0}; | ||
140 | +static bool s_isMediaFileDirPathConfigured = false; | ||
141 | + | ||
142 | +/* Exported functions definition ---------------------------------------------*/ | ||
143 | +T_ZiyanReturnCode ZiyanTest_CameraEmuMediaStartService(void) | ||
144 | +{ | ||
145 | + T_ZiyanOsalHandler *osalHandler = ZiyanPlatform_GetOsalHandler(); | ||
146 | + T_ZiyanReturnCode returnCode; | ||
147 | + const T_ZiyanDataChannelBandwidthProportionOfHighspeedChannel bandwidthProportionOfHighspeedChannel = | ||
148 | + {10, 60, 30}; | ||
149 | + T_ZiyanAircraftInfoBaseInfo aircraftInfoBaseInfo = {0}; | ||
150 | + | ||
151 | + if (ZiyanAircraftInfo_GetBaseInfo(&aircraftInfoBaseInfo) != ZIYAN_ERROR_SYSTEM_MODULE_CODE_SUCCESS) { | ||
152 | + USER_LOG_ERROR("get aircraft information error."); | ||
153 | + return ZIYAN_ERROR_SYSTEM_MODULE_CODE_UNKNOWN; | ||
154 | + } | ||
155 | + | ||
156 | + s_psdkCameraMedia.GetMediaFileDir = GetMediaFileDir; | ||
157 | + s_psdkCameraMedia.GetMediaFileOriginInfo = ZiyanTest_CameraMediaGetFileInfo; | ||
158 | + s_psdkCameraMedia.GetMediaFileOriginData = GetMediaFileOriginData; | ||
159 | + | ||
160 | + s_psdkCameraMedia.CreateMediaFileThumbNail = CreateMediaFileThumbNail; | ||
161 | + s_psdkCameraMedia.GetMediaFileThumbNailInfo = GetMediaFileThumbNailInfo; | ||
162 | + s_psdkCameraMedia.GetMediaFileThumbNailData = GetMediaFileThumbNailData; | ||
163 | + s_psdkCameraMedia.DestroyMediaFileThumbNail = DestroyMediaFileThumbNail; | ||
164 | + | ||
165 | + s_psdkCameraMedia.CreateMediaFileScreenNail = CreateMediaFileScreenNail; | ||
166 | + s_psdkCameraMedia.GetMediaFileScreenNailInfo = GetMediaFileScreenNailInfo; | ||
167 | + s_psdkCameraMedia.GetMediaFileScreenNailData = GetMediaFileScreenNailData; | ||
168 | + s_psdkCameraMedia.DestroyMediaFileScreenNail = DestroyMediaFileScreenNail; | ||
169 | + | ||
170 | + s_psdkCameraMedia.DeleteMediaFile = DeleteMediaFile; | ||
171 | + | ||
172 | + s_psdkCameraMedia.SetMediaPlaybackFile = SetMediaPlaybackFile; | ||
173 | + | ||
174 | + s_psdkCameraMedia.StartMediaPlayback = StartMediaPlayback; | ||
175 | + s_psdkCameraMedia.StopMediaPlayback = StopMediaPlayback; | ||
176 | + s_psdkCameraMedia.PauseMediaPlayback = PauseMediaPlayback; | ||
177 | + s_psdkCameraMedia.SeekMediaPlayback = SeekMediaPlayback; | ||
178 | + s_psdkCameraMedia.GetMediaPlaybackStatus = GetMediaPlaybackStatus; | ||
179 | + | ||
180 | + s_psdkCameraMedia.StartDownloadNotification = StartDownloadNotification; | ||
181 | + s_psdkCameraMedia.StopDownloadNotification = StopDownloadNotification; | ||
182 | + | ||
183 | + if (ZIYAN_ERROR_SYSTEM_MODULE_CODE_SUCCESS != osalHandler->SemaphoreCreate(0, &s_mediaPlayWorkSem)) { | ||
184 | + USER_LOG_ERROR("SemaphoreCreate(\"%s\") error.", "s_mediaPlayWorkSem"); | ||
185 | + return ZIYAN_ERROR_SYSTEM_MODULE_CODE_UNKNOWN; | ||
186 | + } | ||
187 | + | ||
188 | + if (osalHandler->MutexCreate(&s_mediaPlayCommandBufferMutex) != ZIYAN_ERROR_SYSTEM_MODULE_CODE_SUCCESS) { | ||
189 | + USER_LOG_ERROR("mutex create error"); | ||
190 | + return ZIYAN_ERROR_SYSTEM_MODULE_CODE_UNKNOWN; | ||
191 | + } | ||
192 | + | ||
193 | + UtilBuffer_Init(&s_mediaPlayCommandBufferHandler, s_mediaPlayCommandBuffer, sizeof(s_mediaPlayCommandBuffer)); | ||
194 | + | ||
195 | + if (aircraftInfoBaseInfo.aircraftType == ZIYAN_AIRCRAFT_TYPE_SHADOW_PLUS || | ||
196 | + aircraftInfoBaseInfo.aircraftType == ZIYAN_AIRCRAFT_TYPE_SHADOW_MAX) { | ||
197 | + returnCode = ZiyanPayloadCamera_RegMediaDownloadPlaybackHandler(&s_psdkCameraMedia); | ||
198 | + if (returnCode != ZIYAN_ERROR_SYSTEM_MODULE_CODE_SUCCESS) { | ||
199 | + USER_LOG_ERROR("psdk camera media function init error."); | ||
200 | + return ZIYAN_ERROR_SYSTEM_MODULE_CODE_UNKNOWN; | ||
201 | + } | ||
202 | + } | ||
203 | + | ||
204 | + returnCode = ZiyanHighSpeedDataChannel_SetBandwidthProportion(bandwidthProportionOfHighspeedChannel); | ||
205 | + if (returnCode != ZIYAN_ERROR_SYSTEM_MODULE_CODE_SUCCESS) { | ||
206 | + USER_LOG_ERROR("Set data channel bandwidth width proportion error."); | ||
207 | + return ZIYAN_ERROR_SYSTEM_MODULE_CODE_UNKNOWN; | ||
208 | + } | ||
209 | + | ||
210 | + if (ZiyanPlatform_GetHalNetworkHandler() != NULL || ZiyanPlatform_GetHalUsbBulkHandler() != NULL) { | ||
211 | + returnCode = osalHandler->TaskCreate("user_camera_media_task", UserCameraMedia_SendVideoTask, 2048, | ||
212 | + NULL, &s_userSendVideoThread); | ||
213 | + if (returnCode != ZIYAN_ERROR_SYSTEM_MODULE_CODE_SUCCESS) { | ||
214 | + USER_LOG_ERROR("user send video task create error."); | ||
215 | + return ZIYAN_ERROR_SYSTEM_MODULE_CODE_SUCCESS; | ||
216 | + } | ||
217 | + } | ||
218 | + | ||
219 | + return ZIYAN_ERROR_SYSTEM_MODULE_CODE_SUCCESS; | ||
220 | +} | ||
221 | + | ||
222 | +T_ZiyanReturnCode ZiyanTest_CameraEmuSetMediaFilePath(const char *path) | ||
223 | +{ | ||
224 | + memset(s_mediaFileDirPath, 0, sizeof(s_mediaFileDirPath)); | ||
225 | + memcpy(s_mediaFileDirPath, path, USER_UTIL_MIN(strlen(path), sizeof(s_mediaFileDirPath) - 1)); | ||
226 | + s_isMediaFileDirPathConfigured = true; | ||
227 | + | ||
228 | + return ZIYAN_ERROR_SYSTEM_MODULE_CODE_SUCCESS; | ||
229 | +} | ||
230 | + | ||
231 | +T_ZiyanReturnCode ZiyanTest_CameraMediaGetFileInfo(const char *filePath, T_ZiyanCameraMediaFileInfo *fileInfo) | ||
232 | +{ | ||
233 | + T_ZiyanReturnCode returnCode; | ||
234 | + T_ZiyanMediaFileHandle mediaFileHandle; | ||
235 | + | ||
236 | + returnCode = ZiyanMediaFile_CreateHandle(filePath, &mediaFileHandle); | ||
237 | + if (returnCode != ZIYAN_ERROR_SYSTEM_MODULE_CODE_SUCCESS) { | ||
238 | + USER_LOG_ERROR("Media file create handle error stat:0x%08llX", returnCode); | ||
239 | + return returnCode; | ||
240 | + } | ||
241 | + | ||
242 | + returnCode = ZiyanMediaFile_GetMediaFileType(mediaFileHandle, &fileInfo->type); | ||
243 | + if (returnCode != ZIYAN_ERROR_SYSTEM_MODULE_CODE_SUCCESS) { | ||
244 | + USER_LOG_ERROR("Media file get type error stat:0x%08llX", returnCode); | ||
245 | + goto out; | ||
246 | + } | ||
247 | + | ||
248 | + returnCode = ZiyanMediaFile_GetMediaFileAttr(mediaFileHandle, &fileInfo->mediaFileAttr); | ||
249 | + if (returnCode != ZIYAN_ERROR_SYSTEM_MODULE_CODE_SUCCESS) { | ||
250 | + USER_LOG_ERROR("Media file get attr error stat:0x%08llX", returnCode); | ||
251 | + goto out; | ||
252 | + } | ||
253 | + | ||
254 | + returnCode = ZiyanMediaFile_GetFileSizeOrg(mediaFileHandle, &fileInfo->fileSize); | ||
255 | + if (returnCode != ZIYAN_ERROR_SYSTEM_MODULE_CODE_SUCCESS) { | ||
256 | + USER_LOG_ERROR("Media file get size error stat:0x%08llX", returnCode); | ||
257 | + goto out; | ||
258 | + } | ||
259 | + | ||
260 | +out: | ||
261 | + returnCode = ZiyanMediaFile_DestroyHandle(mediaFileHandle); | ||
262 | + if (returnCode != ZIYAN_ERROR_SYSTEM_MODULE_CODE_SUCCESS) { | ||
263 | + USER_LOG_ERROR("Media file destroy handle error stat:0x%08llX", returnCode); | ||
264 | + return returnCode; | ||
265 | + } | ||
266 | + | ||
267 | + return returnCode; | ||
268 | +} | ||
269 | + | ||
270 | +/* Private functions definition-----------------------------------------------*/ | ||
271 | +static T_ZiyanReturnCode ZiyanPlayback_StopPlay(T_ZiyanPlaybackInfo *playbackInfo) | ||
272 | +{ | ||
273 | + T_ZiyanReturnCode returnCode; | ||
274 | + | ||
275 | + returnCode = ZiyanPlayback_StopPlayProcess(); | ||
276 | + if (returnCode != ZIYAN_ERROR_SYSTEM_MODULE_CODE_SUCCESS) { | ||
277 | + USER_LOG_ERROR("stop play error "); | ||
278 | + } | ||
279 | + | ||
280 | + playbackInfo->isInPlayProcess = 0; | ||
281 | + playbackInfo->playPosMs = 0; | ||
282 | + | ||
283 | + return returnCode; | ||
284 | +} | ||
285 | + | ||
286 | +static T_ZiyanReturnCode ZiyanPlayback_PausePlay(T_ZiyanPlaybackInfo *playbackInfo) | ||
287 | +{ | ||
288 | + T_ZiyanReturnCode returnCode = ZIYAN_ERROR_SYSTEM_MODULE_CODE_SUCCESS; | ||
289 | + T_ZiyanOsalHandler *osalHandler = ZiyanPlatform_GetOsalHandler(); | ||
290 | + | ||
291 | + T_TestPayloadCameraPlaybackCommand playbackCommand = {0}; | ||
292 | + if (playbackInfo->isInPlayProcess) { | ||
293 | + playbackCommand.command = TEST_PAYLOAD_CAMERA_MEDIA_PLAY_COMMAND_PAUSE; | ||
294 | + | ||
295 | + if (osalHandler->MutexLock(s_mediaPlayCommandBufferMutex) != ZIYAN_ERROR_SYSTEM_MODULE_CODE_SUCCESS) { | ||
296 | + USER_LOG_ERROR("mutex lock error"); | ||
297 | + return ZIYAN_ERROR_SYSTEM_MODULE_CODE_UNKNOWN; | ||
298 | + } | ||
299 | + | ||
300 | + if (UtilBuffer_GetUnusedSize(&s_mediaPlayCommandBufferHandler) >= sizeof(T_TestPayloadCameraPlaybackCommand)) { | ||
301 | + UtilBuffer_Put(&s_mediaPlayCommandBufferHandler, (const uint8_t *) &playbackCommand, | ||
302 | + sizeof(T_TestPayloadCameraPlaybackCommand)); | ||
303 | + } else { | ||
304 | + USER_LOG_ERROR("Media playback command buffer is full."); | ||
305 | + returnCode = ZIYAN_ERROR_SYSTEM_MODULE_CODE_OUT_OF_RANGE; | ||
306 | + } | ||
307 | + | ||
308 | + if (osalHandler->MutexUnlock(s_mediaPlayCommandBufferMutex) != ZIYAN_ERROR_SYSTEM_MODULE_CODE_SUCCESS) { | ||
309 | + USER_LOG_ERROR("mutex unlock error"); | ||
310 | + return ZIYAN_ERROR_SYSTEM_MODULE_CODE_UNKNOWN; | ||
311 | + } | ||
312 | + osalHandler->SemaphorePost(s_mediaPlayWorkSem); | ||
313 | + } | ||
314 | + | ||
315 | + playbackInfo->isInPlayProcess = 0; | ||
316 | + | ||
317 | + return returnCode; | ||
318 | +} | ||
319 | + | ||
320 | +static T_ZiyanReturnCode ZiyanPlayback_SetPlayFile(T_ZiyanPlaybackInfo *playbackInfo, const char *filePath, uint16_t index) | ||
321 | +{ | ||
322 | + T_ZiyanReturnCode returnCode; | ||
323 | + | ||
324 | + if (strlen(filePath) > ZIYAN_FILE_PATH_SIZE_MAX) { | ||
325 | + USER_LOG_ERROR("Ziyan playback file path out of length range error\n"); | ||
326 | + return ZIYAN_ERROR_SYSTEM_MODULE_CODE_INVALID_PARAMETER; | ||
327 | + } | ||
328 | + | ||
329 | + strcpy(playbackInfo->filePath, filePath); | ||
330 | + playbackInfo->videoIndex = index; | ||
331 | + | ||
332 | + returnCode = ZiyanPlayback_GetVideoLengthMs(filePath, &playbackInfo->videoLengthMs); | ||
333 | + | ||
334 | + if (returnCode != ZIYAN_ERROR_SYSTEM_MODULE_CODE_SUCCESS) { | ||
335 | + return ZIYAN_ERROR_SYSTEM_MODULE_CODE_UNKNOWN; | ||
336 | + } | ||
337 | + | ||
338 | + return ZIYAN_ERROR_SYSTEM_MODULE_CODE_SUCCESS; | ||
339 | +} | ||
340 | + | ||
341 | +static T_ZiyanReturnCode ZiyanPlayback_SeekPlay(T_ZiyanPlaybackInfo *playbackInfo, uint32_t seekPos) | ||
342 | +{ | ||
343 | + T_ZiyanRunTimeStamps ti; | ||
344 | + T_ZiyanReturnCode returnCode; | ||
345 | + | ||
346 | + returnCode = ZiyanPlayback_PausePlay(playbackInfo); | ||
347 | + if (returnCode != ZIYAN_ERROR_SYSTEM_MODULE_CODE_SUCCESS) { | ||
348 | + USER_LOG_ERROR("pause play error \n"); | ||
349 | + return returnCode; | ||
350 | + } | ||
351 | + | ||
352 | + playbackInfo->playPosMs = seekPos; | ||
353 | + returnCode = ZiyanPlayback_StartPlayProcess(playbackInfo->filePath, playbackInfo->playPosMs); | ||
354 | + if (returnCode != ZIYAN_ERROR_SYSTEM_MODULE_CODE_SUCCESS) { | ||
355 | + USER_LOG_ERROR("start playback process error \n"); | ||
356 | + return returnCode; | ||
357 | + } | ||
358 | + | ||
359 | + playbackInfo->isInPlayProcess = 1; | ||
360 | + ti = ZiyanUtilTime_GetRunTimeStamps(); | ||
361 | + playbackInfo->startPlayTimestampsUs = ti.realUsec - playbackInfo->playPosMs * 1000; | ||
362 | + | ||
363 | + return ZIYAN_ERROR_SYSTEM_MODULE_CODE_SUCCESS; | ||
364 | +} | ||
365 | + | ||
366 | +static T_ZiyanReturnCode ZiyanPlayback_StartPlay(T_ZiyanPlaybackInfo *playbackInfo) | ||
367 | +{ | ||
368 | + T_ZiyanRunTimeStamps ti; | ||
369 | + T_ZiyanReturnCode returnCode; | ||
370 | + | ||
371 | + if (playbackInfo->isInPlayProcess == 1) { | ||
372 | + //already in playing, return ZIYAN_ERROR_SYSTEM_MODULE_CODE_SUCCESS | ||
373 | + return ZIYAN_ERROR_SYSTEM_MODULE_CODE_SUCCESS; | ||
374 | + } | ||
375 | + | ||
376 | + returnCode = ZiyanPlayback_StartPlayProcess(playbackInfo->filePath, playbackInfo->playPosMs); | ||
377 | + if (returnCode != ZIYAN_ERROR_SYSTEM_MODULE_CODE_SUCCESS) { | ||
378 | + USER_LOG_ERROR("start play process error \n"); | ||
379 | + return returnCode; | ||
380 | + } | ||
381 | + | ||
382 | + playbackInfo->isInPlayProcess = 1; | ||
383 | + | ||
384 | + ti = ZiyanUtilTime_GetRunTimeStamps(); | ||
385 | + playbackInfo->startPlayTimestampsUs = ti.realUsec - playbackInfo->playPosMs * 1000; | ||
386 | + | ||
387 | + return ZIYAN_ERROR_SYSTEM_MODULE_CODE_SUCCESS; | ||
388 | +} | ||
389 | + | ||
390 | +static T_ZiyanReturnCode ZiyanPlayback_GetPlaybackStatus(T_ZiyanPlaybackInfo *playbackInfo, | ||
391 | + T_ZiyanCameraPlaybackStatus *playbackStatus) | ||
392 | +{ | ||
393 | + T_ZiyanRunTimeStamps timeStamps; | ||
394 | + | ||
395 | + memset(playbackStatus, 0, sizeof(T_ZiyanCameraPlaybackStatus)); | ||
396 | + | ||
397 | + //update playback pos info | ||
398 | + if (playbackInfo->isInPlayProcess) { | ||
399 | + timeStamps = ZiyanUtilTime_GetRunTimeStamps(); | ||
400 | + playbackInfo->playPosMs = (timeStamps.realUsec - playbackInfo->startPlayTimestampsUs) / 1000; | ||
401 | + | ||
402 | + if (playbackInfo->playPosMs >= playbackInfo->videoLengthMs) { | ||
403 | + if (ZiyanPlayback_PausePlay(playbackInfo) != ZIYAN_ERROR_SYSTEM_MODULE_CODE_SUCCESS) { | ||
404 | + return ZIYAN_ERROR_SYSTEM_MODULE_CODE_UNKNOWN; | ||
405 | + } | ||
406 | + } | ||
407 | + } | ||
408 | + | ||
409 | + //set playback status | ||
410 | + if (playbackInfo->isInPlayProcess == 0 && playbackInfo->playPosMs != 0) { | ||
411 | + playbackStatus->playbackMode = ZIYAN_CAMERA_PLAYBACK_MODE_PAUSE; | ||
412 | + } else if (playbackInfo->isInPlayProcess) { | ||
413 | + playbackStatus->playbackMode = ZIYAN_CAMERA_PLAYBACK_MODE_PLAY; | ||
414 | + } else { | ||
415 | + playbackStatus->playbackMode = ZIYAN_CAMERA_PLAYBACK_MODE_STOP; | ||
416 | + } | ||
417 | + | ||
418 | + playbackStatus->playPosMs = playbackInfo->playPosMs; | ||
419 | + playbackStatus->videoLengthMs = playbackInfo->videoLengthMs; | ||
420 | + | ||
421 | + if (playbackInfo->videoLengthMs != 0) { | ||
422 | + playbackStatus->videoPlayProcess = | ||
423 | + (playbackInfo->videoLengthMs - playbackInfo->playPosMs) / playbackInfo->videoLengthMs; | ||
424 | + } else { | ||
425 | + playbackStatus->videoPlayProcess = 0; | ||
426 | + } | ||
427 | + | ||
428 | + return ZIYAN_ERROR_SYSTEM_MODULE_CODE_SUCCESS; | ||
429 | +} | ||
430 | + | ||
431 | +static T_ZiyanReturnCode ZiyanPlayback_GetVideoLengthMs(const char *filePath, uint32_t *videoLengthMs) | ||
432 | +{ | ||
433 | + FILE *fp; | ||
434 | + T_ZiyanReturnCode returnCode; | ||
435 | + char ffmpegCmdStr[FFMPEG_CMD_BUF_SIZE]; | ||
436 | + float hour, minute, second; | ||
437 | + char tempTailStr[128]; | ||
438 | + int ret; | ||
439 | + | ||
440 | + snprintf(ffmpegCmdStr, FFMPEG_CMD_BUF_SIZE, "ffmpeg -i \"%s\" 2>&1 | grep \"Duration\"", filePath); | ||
441 | + fp = popen(ffmpegCmdStr, "r"); | ||
442 | + | ||
443 | + if (fp == NULL) { | ||
444 | + return ZIYAN_ERROR_SYSTEM_MODULE_CODE_SYSTEM_ERROR; | ||
445 | + } | ||
446 | + | ||
447 | + ret = fscanf(fp, " Duration: %f:%f:%f,%127s", &hour, &minute, &second, tempTailStr); | ||
448 | + if (ret <= 0) { | ||
449 | + USER_LOG_ERROR("MP4 File Get Duration Error\n"); | ||
450 | + returnCode = ZIYAN_ERROR_SYSTEM_MODULE_CODE_SYSTEM_ERROR; | ||
451 | + goto out; | ||
452 | + } | ||
453 | + | ||
454 | + *videoLengthMs = (uint32_t) ((hour * 3600 + minute * 60 + second) * 1000); | ||
455 | + returnCode = ZIYAN_ERROR_SYSTEM_MODULE_CODE_SUCCESS; | ||
456 | + | ||
457 | +out: | ||
458 | + pclose(fp); | ||
459 | + | ||
460 | + return returnCode; | ||
461 | +} | ||
462 | + | ||
463 | +static T_ZiyanReturnCode ZiyanPlayback_StartPlayProcess(const char *filePath, uint32_t playPosMs) | ||
464 | +{ | ||
465 | + T_ZiyanReturnCode returnCode = ZIYAN_ERROR_SYSTEM_MODULE_CODE_SUCCESS; | ||
466 | + T_TestPayloadCameraPlaybackCommand mediaPlayCommand = {0}; | ||
467 | + T_ZiyanOsalHandler *osalHandler = ZiyanPlatform_GetOsalHandler(); | ||
468 | + | ||
469 | + mediaPlayCommand.command = TEST_PAYLOAD_CAMERA_MEDIA_PLAY_COMMAND_START; | ||
470 | + mediaPlayCommand.timeMs = playPosMs; | ||
471 | + | ||
472 | + if (strlen(filePath) >= sizeof(mediaPlayCommand.path)) { | ||
473 | + USER_LOG_ERROR("File path is too long."); | ||
474 | + return ZIYAN_ERROR_SYSTEM_MODULE_CODE_OUT_OF_RANGE; | ||
475 | + } | ||
476 | + memcpy(mediaPlayCommand.path, filePath, strlen(filePath)); | ||
477 | + | ||
478 | + if (osalHandler->MutexLock(s_mediaPlayCommandBufferMutex) != ZIYAN_ERROR_SYSTEM_MODULE_CODE_SUCCESS) { | ||
479 | + USER_LOG_ERROR("mutex lock error"); | ||
480 | + return ZIYAN_ERROR_SYSTEM_MODULE_CODE_UNKNOWN; | ||
481 | + } | ||
482 | + | ||
483 | + if (UtilBuffer_GetUnusedSize(&s_mediaPlayCommandBufferHandler) >= sizeof(T_TestPayloadCameraPlaybackCommand)) { | ||
484 | + UtilBuffer_Put(&s_mediaPlayCommandBufferHandler, (const uint8_t *) &mediaPlayCommand, | ||
485 | + sizeof(T_TestPayloadCameraPlaybackCommand)); | ||
486 | + } else { | ||
487 | + USER_LOG_ERROR("Media playback command buffer is full."); | ||
488 | + returnCode = ZIYAN_ERROR_SYSTEM_MODULE_CODE_OUT_OF_RANGE; | ||
489 | + } | ||
490 | + | ||
491 | + if (osalHandler->MutexUnlock(s_mediaPlayCommandBufferMutex) != ZIYAN_ERROR_SYSTEM_MODULE_CODE_SUCCESS) { | ||
492 | + USER_LOG_ERROR("mutex unlock error"); | ||
493 | + return ZIYAN_ERROR_SYSTEM_MODULE_CODE_UNKNOWN; | ||
494 | + } | ||
495 | + osalHandler->SemaphorePost(s_mediaPlayWorkSem); | ||
496 | + return returnCode; | ||
497 | +} | ||
498 | + | ||
499 | +static T_ZiyanReturnCode ZiyanPlayback_StopPlayProcess(void) | ||
500 | +{ | ||
501 | + T_ZiyanReturnCode returnCode = ZIYAN_ERROR_SYSTEM_MODULE_CODE_SUCCESS; | ||
502 | + T_TestPayloadCameraPlaybackCommand playbackCommand = {0}; | ||
503 | + T_ZiyanOsalHandler *osalHandler = ZiyanPlatform_GetOsalHandler(); | ||
504 | + | ||
505 | + playbackCommand.command = TEST_PAYLOAD_CAMERA_MEDIA_PLAY_COMMAND_STOP; | ||
506 | + | ||
507 | + if (osalHandler->MutexLock(s_mediaPlayCommandBufferMutex) != ZIYAN_ERROR_SYSTEM_MODULE_CODE_SUCCESS) { | ||
508 | + USER_LOG_ERROR("mutex lock error"); | ||
509 | + return ZIYAN_ERROR_SYSTEM_MODULE_CODE_UNKNOWN; | ||
510 | + } | ||
511 | + | ||
512 | + if (UtilBuffer_GetUnusedSize(&s_mediaPlayCommandBufferHandler) >= sizeof(T_TestPayloadCameraPlaybackCommand)) { | ||
513 | + UtilBuffer_Put(&s_mediaPlayCommandBufferHandler, (const uint8_t *) &playbackCommand, | ||
514 | + sizeof(T_TestPayloadCameraPlaybackCommand)); | ||
515 | + } else { | ||
516 | + USER_LOG_ERROR("Media playback command buffer is full."); | ||
517 | + returnCode = ZIYAN_ERROR_SYSTEM_MODULE_CODE_OUT_OF_RANGE; | ||
518 | + } | ||
519 | + | ||
520 | + if (osalHandler->MutexUnlock(s_mediaPlayCommandBufferMutex) != ZIYAN_ERROR_SYSTEM_MODULE_CODE_SUCCESS) { | ||
521 | + USER_LOG_ERROR("mutex unlock error"); | ||
522 | + return ZIYAN_ERROR_SYSTEM_MODULE_CODE_UNKNOWN; | ||
523 | + } | ||
524 | + osalHandler->SemaphorePost(s_mediaPlayWorkSem); | ||
525 | + return returnCode; | ||
526 | +} | ||
527 | + | ||
528 | +static T_ZiyanReturnCode ZiyanPlayback_VideoFileTranscode(const char *inPath, const char *outFormat, char *outPath, | ||
529 | + uint16_t outPathBufferSize) | ||
530 | +{ | ||
531 | + T_ZiyanReturnCode returnCode = ZIYAN_ERROR_SYSTEM_MODULE_CODE_SUCCESS; | ||
532 | + T_ZiyanReturnCode ziyanStatus = ZIYAN_ERROR_SYSTEM_MODULE_CODE_SUCCESS; | ||
533 | + FILE *fpCommand = NULL; | ||
534 | + char ffmpegCmdStr[FFMPEG_CMD_BUF_SIZE]; | ||
535 | + char *directory = NULL; | ||
536 | + T_ZiyanOsalHandler *osalHandler = ZiyanPlatform_GetOsalHandler(); | ||
537 | + | ||
538 | + directory = osalHandler->Malloc(ZIYAN_FILE_PATH_SIZE_MAX); | ||
539 | + if (directory == NULL) { | ||
540 | + USER_LOG_ERROR("malloc memory for directory fail."); | ||
541 | + return ZIYAN_ERROR_SYSTEM_MODULE_CODE_MEMORY_ALLOC_FAILED; | ||
542 | + } | ||
543 | + | ||
544 | + ziyanStatus = ZiyanUserUtil_GetCurrentFileDirPath(inPath, ZIYAN_FILE_PATH_SIZE_MAX, directory); | ||
545 | + if (ziyanStatus != ZIYAN_ERROR_SYSTEM_MODULE_CODE_SUCCESS) { | ||
546 | + USER_LOG_ERROR("get directory of file error: 0x%08llX.", ziyanStatus); | ||
547 | + returnCode = ziyanStatus; | ||
548 | + goto out; | ||
549 | + } | ||
550 | + | ||
551 | + snprintf(outPath, outPathBufferSize, "%sout.%s", directory, outFormat); | ||
552 | + snprintf(ffmpegCmdStr, FFMPEG_CMD_BUF_SIZE, | ||
553 | + "echo \"y\" | ffmpeg -i \"%s\" -codec copy -f \"%s\" \"%s\" 1>/dev/null 2>&1", inPath, | ||
554 | + outFormat, outPath); | ||
555 | + fpCommand = popen(ffmpegCmdStr, "r"); | ||
556 | + if (fpCommand == NULL) { | ||
557 | + USER_LOG_ERROR("execute transcode command fail."); | ||
558 | + returnCode = ZIYAN_ERROR_SYSTEM_MODULE_CODE_UNKNOWN; | ||
559 | + goto out; | ||
560 | + } | ||
561 | + | ||
562 | + pclose(fpCommand); | ||
563 | + | ||
564 | +out: | ||
565 | + osalHandler->Free(directory); | ||
566 | + | ||
567 | + return returnCode; | ||
568 | +} | ||
569 | + | ||
570 | +static T_ZiyanReturnCode | ||
571 | +ZiyanPlayback_GetFrameInfoOfVideoFile(const char *path, T_TestPayloadCameraVideoFrameInfo *frameInfo, | ||
572 | + uint32_t frameInfoBufferCount, uint32_t *frameCount) | ||
573 | +{ | ||
574 | + long ret; | ||
575 | + T_ZiyanReturnCode returnCode = ZIYAN_ERROR_SYSTEM_MODULE_CODE_SUCCESS; | ||
576 | + FILE *fpCommand = NULL; | ||
577 | + char ffmpegCmdStr[FFMPEG_CMD_BUF_SIZE]; | ||
578 | + char *frameInfoString = NULL; | ||
579 | + char *frameLocation = NULL; | ||
580 | + char frameParameterFormat[50] = {0}; | ||
581 | + char *frameDurationTimeLocation = NULL; | ||
582 | + float frameDurationTimeS = 0; | ||
583 | + uint32_t frameNumber = 0; | ||
584 | + char *framePositionLocation = NULL; | ||
585 | + uint32_t framePosition = 0; | ||
586 | + char *frameSizeLocation = NULL; | ||
587 | + uint32_t frameSize = 0; | ||
588 | + T_ZiyanOsalHandler *osalHandler = ZiyanPlatform_GetOsalHandler(); | ||
589 | + | ||
590 | + frameInfoString = osalHandler->Malloc(VIDEO_FRAME_MAX_COUNT * 1024); | ||
591 | + if (frameInfoString == NULL) { | ||
592 | + USER_LOG_ERROR("malloc memory for frame info fail."); | ||
593 | + return ZIYAN_ERROR_SYSTEM_MODULE_CODE_MEMORY_ALLOC_FAILED; | ||
594 | + } | ||
595 | + memset(frameInfoString, 0, VIDEO_FRAME_MAX_COUNT * 1024); | ||
596 | + | ||
597 | + snprintf(ffmpegCmdStr, FFMPEG_CMD_BUF_SIZE, "ffprobe -show_packets \"%s\" 2>/dev/null", path); | ||
598 | + fpCommand = popen(ffmpegCmdStr, "r"); | ||
599 | + if (fpCommand == NULL) { | ||
600 | + USER_LOG_ERROR("execute show frames commands fail."); | ||
601 | + returnCode = ZIYAN_ERROR_SYSTEM_MODULE_CODE_UNKNOWN; | ||
602 | + goto out2; | ||
603 | + } | ||
604 | + | ||
605 | + ret = (long) fread(frameInfoString, 1, VIDEO_FRAME_MAX_COUNT * 1024, fpCommand); | ||
606 | + if (ret < 0) { | ||
607 | + USER_LOG_ERROR("read show frames commands result error."); | ||
608 | + goto out1; | ||
609 | + } | ||
610 | + frameInfoString[ret] = '\0'; | ||
611 | + | ||
612 | + frameLocation = frameInfoString; | ||
613 | + *frameCount = 0; | ||
614 | + while (1) { | ||
615 | + // find frame | ||
616 | + frameLocation = strstr(frameLocation, s_frameKeyChar); | ||
617 | + if (frameLocation == NULL) { | ||
618 | + USER_LOG_DEBUG("reach file tail."); | ||
619 | + break; | ||
620 | + } | ||
621 | + | ||
622 | + // find frame duration | ||
623 | + frameDurationTimeLocation = strstr(frameLocation, s_frameDurationTimeKeyChar); | ||
624 | + if (frameDurationTimeLocation == NULL) { | ||
625 | + USER_LOG_ERROR("can not find pkt_duration_time."); | ||
626 | + returnCode = ZIYAN_ERROR_SYSTEM_MODULE_CODE_NOT_FOUND; | ||
627 | + goto out1; | ||
628 | + } | ||
629 | + | ||
630 | + ret = snprintf(frameParameterFormat, sizeof(frameParameterFormat), "%s=%%f", s_frameDurationTimeKeyChar); | ||
631 | + if (ret < 0) { | ||
632 | + USER_LOG_ERROR("snprintf frameParameterFormat fail."); | ||
633 | + returnCode = ZIYAN_ERROR_SYSTEM_MODULE_CODE_UNKNOWN; | ||
634 | + goto out1; | ||
635 | + } | ||
636 | + | ||
637 | + ret = sscanf(frameDurationTimeLocation, frameParameterFormat, &frameDurationTimeS); | ||
638 | + if (ret <= 0) { | ||
639 | + USER_LOG_ERROR("can not find pkt_duration_time."); | ||
640 | + returnCode = ZIYAN_ERROR_SYSTEM_MODULE_CODE_NOT_FOUND; | ||
641 | + goto out1; | ||
642 | + } | ||
643 | + frameInfo[frameNumber].durationS = frameDurationTimeS; | ||
644 | + | ||
645 | + // find frame position | ||
646 | + framePositionLocation = strstr(frameLocation, s_framePositionKeyChar); | ||
647 | + if (framePositionLocation == NULL) { | ||
648 | + USER_LOG_ERROR("can not found pkt_pos."); | ||
649 | + returnCode = ZIYAN_ERROR_SYSTEM_MODULE_CODE_NOT_FOUND; | ||
650 | + goto out1; | ||
651 | + } | ||
652 | + | ||
653 | + ret = snprintf(frameParameterFormat, sizeof(frameParameterFormat), "%s=%%d", s_framePositionKeyChar); | ||
654 | + if (ret < 0) { | ||
655 | + USER_LOG_ERROR("snprintf frameParameterFormat fail."); | ||
656 | + returnCode = ZIYAN_ERROR_SYSTEM_MODULE_CODE_UNKNOWN; | ||
657 | + goto out1; | ||
658 | + } | ||
659 | + | ||
660 | + ret = sscanf(framePositionLocation, frameParameterFormat, &framePosition); | ||
661 | + if (ret <= 0) { | ||
662 | + USER_LOG_ERROR("can not found pkt_pos."); | ||
663 | + returnCode = ZIYAN_ERROR_SYSTEM_MODULE_CODE_NOT_FOUND; | ||
664 | + goto out1; | ||
665 | + } | ||
666 | + frameInfo[frameNumber].positionInFile = framePosition; | ||
667 | + | ||
668 | + // find frame size | ||
669 | + frameSizeLocation = strstr(frameLocation, s_frameSizeKeyChar); | ||
670 | + if (frameSizeLocation == NULL) { | ||
671 | + USER_LOG_ERROR("can not found pkt_size."); | ||
672 | + returnCode = ZIYAN_ERROR_SYSTEM_MODULE_CODE_NOT_FOUND; | ||
673 | + goto out1; | ||
674 | + } | ||
675 | + | ||
676 | + ret = snprintf(frameParameterFormat, sizeof(frameParameterFormat), "%s=%%d", s_frameSizeKeyChar); | ||
677 | + if (ret < 0) { | ||
678 | + USER_LOG_ERROR("snprintf frameParameterFormat fail."); | ||
679 | + returnCode = ZIYAN_ERROR_SYSTEM_MODULE_CODE_UNKNOWN; | ||
680 | + goto out1; | ||
681 | + } | ||
682 | + | ||
683 | + ret = sscanf(frameSizeLocation, frameParameterFormat, &frameSize); | ||
684 | + if (ret <= 0) { | ||
685 | + USER_LOG_ERROR("can not find pkt_size."); | ||
686 | + returnCode = ZIYAN_ERROR_SYSTEM_MODULE_CODE_NOT_FOUND; | ||
687 | + goto out1; | ||
688 | + } | ||
689 | + frameInfo[frameNumber].size = frameSize; | ||
690 | + | ||
691 | + frameLocation += strlen(s_frameKeyChar); | ||
692 | + frameNumber++; | ||
693 | + (*frameCount)++; | ||
694 | + | ||
695 | + if (frameNumber >= frameInfoBufferCount) { | ||
696 | + USER_LOG_ERROR("frame buffer is full."); | ||
697 | + returnCode = ZIYAN_ERROR_SYSTEM_MODULE_CODE_OUT_OF_RANGE; | ||
698 | + goto out1; | ||
699 | + } | ||
700 | + } | ||
701 | + | ||
702 | +out1: | ||
703 | + pclose(fpCommand); | ||
704 | + | ||
705 | +out2: | ||
706 | + osalHandler->Free(frameInfoString); | ||
707 | + | ||
708 | + return returnCode; | ||
709 | +} | ||
710 | + | ||
711 | +static T_ZiyanReturnCode ZiyanPlayback_GetFrameRateOfVideoFile(const char *path, float *frameRate) | ||
712 | +{ | ||
713 | + int ret; | ||
714 | + T_ZiyanReturnCode returnCode = ZIYAN_ERROR_SYSTEM_MODULE_CODE_SUCCESS; | ||
715 | + FILE *fpCommand = NULL; | ||
716 | + char ffmpegCmdStr[FFMPEG_CMD_BUF_SIZE] = {0}; | ||
717 | + int frameRateMolecule = 0; | ||
718 | + int frameRateDenominator = 0; | ||
719 | + | ||
720 | + snprintf(ffmpegCmdStr, FFMPEG_CMD_BUF_SIZE, "ffprobe -show_streams \"%s\" 2>/dev/null | grep r_frame_rate", path); | ||
721 | + fpCommand = popen(ffmpegCmdStr, "r"); | ||
722 | + if (fpCommand == NULL) { | ||
723 | + USER_LOG_ERROR("execute show frame rate command fail."); | ||
724 | + return ZIYAN_ERROR_SYSTEM_MODULE_CODE_UNKNOWN; | ||
725 | + } | ||
726 | + | ||
727 | + ret = fscanf(fpCommand, "r_frame_rate=%d/%d", &frameRateMolecule, &frameRateDenominator); | ||
728 | + if (ret <= 0) { | ||
729 | + USER_LOG_ERROR("can not find frame rate."); | ||
730 | + returnCode = ZIYAN_ERROR_SYSTEM_MODULE_CODE_NOT_FOUND; | ||
731 | + goto out; | ||
732 | + } | ||
733 | + *frameRate = (float) frameRateMolecule / (float) frameRateDenominator; | ||
734 | + | ||
735 | +out: | ||
736 | + pclose(fpCommand); | ||
737 | + | ||
738 | + return returnCode; | ||
739 | +} | ||
740 | + | ||
741 | +static T_ZiyanReturnCode ZiyanPlayback_GetFrameNumberByTime(T_TestPayloadCameraVideoFrameInfo *frameInfo, | ||
742 | + uint32_t frameCount, uint32_t *frameNumber, uint32_t timeMs) | ||
743 | +{ | ||
744 | + uint32_t i = 0; | ||
745 | + double camulativeTimeS = 0; | ||
746 | + double timeS = (double) timeMs / 1000.0; | ||
747 | + | ||
748 | + for (i = 0; i < frameCount; ++i) { | ||
749 | + camulativeTimeS += frameInfo[i].durationS; | ||
750 | + | ||
751 | + if (camulativeTimeS >= timeS) { | ||
752 | + *frameNumber = i; | ||
753 | + return ZIYAN_ERROR_SYSTEM_MODULE_CODE_SUCCESS; | ||
754 | + } | ||
755 | + } | ||
756 | + | ||
757 | + return ZIYAN_ERROR_SYSTEM_MODULE_CODE_NOT_FOUND; | ||
758 | +} | ||
759 | + | ||
760 | +static T_ZiyanReturnCode GetMediaFileDir(char *dirPath) | ||
761 | +{ | ||
762 | + T_ZiyanReturnCode returnCode; | ||
763 | + char curFileDirPath[ZIYAN_FILE_PATH_SIZE_MAX]; | ||
764 | + char tempPath[ZIYAN_FILE_PATH_SIZE_MAX]; | ||
765 | + | ||
766 | + returnCode = ZiyanUserUtil_GetCurrentFileDirPath(__FILE__, ZIYAN_FILE_PATH_SIZE_MAX, curFileDirPath); | ||
767 | + if (returnCode != ZIYAN_ERROR_SYSTEM_MODULE_CODE_SUCCESS) { | ||
768 | + USER_LOG_ERROR("Get file current path error, stat = 0x%08llX", returnCode); | ||
769 | + return returnCode; | ||
770 | + } | ||
771 | + | ||
772 | + snprintf(dirPath, ZIYAN_FILE_PATH_SIZE_MAX, "%smedia_file", curFileDirPath); | ||
773 | + | ||
774 | + return ZIYAN_ERROR_SYSTEM_MODULE_CODE_SUCCESS; | ||
775 | +} | ||
776 | + | ||
777 | +static T_ZiyanReturnCode GetMediaFileOriginData(const char *filePath, uint32_t offset, uint32_t length, uint8_t *data) | ||
778 | +{ | ||
779 | + T_ZiyanReturnCode returnCode; | ||
780 | + uint32_t realLen = 0; | ||
781 | + T_ZiyanMediaFileHandle mediaFileHandle; | ||
782 | + | ||
783 | + returnCode = ZiyanMediaFile_CreateHandle(filePath, &mediaFileHandle); | ||
784 | + if (returnCode != ZIYAN_ERROR_SYSTEM_MODULE_CODE_SUCCESS) { | ||
785 | + USER_LOG_ERROR("Media file create handle error stat:0x%08llX", returnCode); | ||
786 | + return returnCode; | ||
787 | + } | ||
788 | + | ||
789 | + returnCode = ZiyanMediaFile_GetDataOrg(mediaFileHandle, offset, length, data, &realLen); | ||
790 | + if (returnCode != ZIYAN_ERROR_SYSTEM_MODULE_CODE_SUCCESS) { | ||
791 | + USER_LOG_ERROR("Media file get data error stat:0x%08llX", returnCode); | ||
792 | + return returnCode; | ||
793 | + } | ||
794 | + | ||
795 | + returnCode = ZiyanMediaFile_DestroyHandle(mediaFileHandle); | ||
796 | + if (returnCode != ZIYAN_ERROR_SYSTEM_MODULE_CODE_SUCCESS) { | ||
797 | + USER_LOG_ERROR("Media file destroy handle error stat:0x%08llX", returnCode); | ||
798 | + return returnCode; | ||
799 | + } | ||
800 | + | ||
801 | + return ZIYAN_ERROR_SYSTEM_MODULE_CODE_SUCCESS; | ||
802 | +} | ||
803 | + | ||
804 | +static T_ZiyanReturnCode CreateMediaFileThumbNail(const char *filePath) | ||
805 | +{ | ||
806 | + T_ZiyanReturnCode returnCode; | ||
807 | + | ||
808 | + returnCode = ZiyanMediaFile_CreateHandle(filePath, &s_mediaFileThumbNailHandle); | ||
809 | + if (returnCode != ZIYAN_ERROR_SYSTEM_MODULE_CODE_SUCCESS) { | ||
810 | + USER_LOG_ERROR("Media file create handle error stat:0x%08llX", returnCode); | ||
811 | + return returnCode; | ||
812 | + } | ||
813 | + | ||
814 | + returnCode = ZiyanMediaFile_CreateThm(s_mediaFileThumbNailHandle); | ||
815 | + if (returnCode != ZIYAN_ERROR_SYSTEM_MODULE_CODE_SUCCESS) { | ||
816 | + USER_LOG_ERROR("Media file create thumb nail error stat:0x%08llX", returnCode); | ||
817 | + return returnCode; | ||
818 | + } | ||
819 | + | ||
820 | + return ZIYAN_ERROR_SYSTEM_MODULE_CODE_SUCCESS; | ||
821 | +} | ||
822 | + | ||
823 | +static T_ZiyanReturnCode GetMediaFileThumbNailInfo(const char *filePath, T_ZiyanCameraMediaFileInfo *fileInfo) | ||
824 | +{ | ||
825 | + T_ZiyanReturnCode returnCode; | ||
826 | + | ||
827 | + USER_UTIL_UNUSED(filePath); | ||
828 | + | ||
829 | + if (s_mediaFileThumbNailHandle == NULL) { | ||
830 | + USER_LOG_ERROR("Media file thumb nail handle null error"); | ||
831 | + return ZIYAN_ERROR_SYSTEM_MODULE_CODE_INVALID_PARAMETER; | ||
832 | + } | ||
833 | + | ||
834 | + returnCode = ZiyanMediaFile_GetMediaFileType(s_mediaFileThumbNailHandle, &fileInfo->type); | ||
835 | + if (returnCode != ZIYAN_ERROR_SYSTEM_MODULE_CODE_SUCCESS) { | ||
836 | + USER_LOG_ERROR("Media file get type error stat:0x%08llX", returnCode); | ||
837 | + return returnCode; | ||
838 | + } | ||
839 | + | ||
840 | + returnCode = ZiyanMediaFile_GetMediaFileAttr(s_mediaFileThumbNailHandle, &fileInfo->mediaFileAttr); | ||
841 | + if (returnCode != ZIYAN_ERROR_SYSTEM_MODULE_CODE_SUCCESS) { | ||
842 | + USER_LOG_ERROR("Media file get attr error stat:0x%08llX", returnCode); | ||
843 | + return returnCode; | ||
844 | + } | ||
845 | + | ||
846 | + returnCode = ZiyanMediaFile_GetFileSizeThm(s_mediaFileThumbNailHandle, &fileInfo->fileSize); | ||
847 | + if (returnCode != ZIYAN_ERROR_SYSTEM_MODULE_CODE_SUCCESS) { | ||
848 | + USER_LOG_ERROR("Media file get size error stat:0x%08llX", returnCode); | ||
849 | + return returnCode; | ||
850 | + } | ||
851 | + | ||
852 | + return ZIYAN_ERROR_SYSTEM_MODULE_CODE_SUCCESS; | ||
853 | +} | ||
854 | + | ||
855 | +static T_ZiyanReturnCode GetMediaFileThumbNailData(const char *filePath, uint32_t offset, uint32_t length, uint8_t *data) | ||
856 | +{ | ||
857 | + T_ZiyanReturnCode returnCode; | ||
858 | + uint16_t realLen = 0; | ||
859 | + | ||
860 | + USER_UTIL_UNUSED(filePath); | ||
861 | + | ||
862 | + if (s_mediaFileThumbNailHandle == NULL) { | ||
863 | + USER_LOG_ERROR("Media file thumb nail handle null error"); | ||
864 | + return ZIYAN_ERROR_SYSTEM_MODULE_CODE_INVALID_PARAMETER; | ||
865 | + } | ||
866 | + | ||
867 | + returnCode = ZiyanMediaFile_GetDataThm(s_mediaFileThumbNailHandle, offset, length, data, &realLen); | ||
868 | + if (returnCode != ZIYAN_ERROR_SYSTEM_MODULE_CODE_SUCCESS) { | ||
869 | + USER_LOG_ERROR("Media file get data error stat:0x%08llX", returnCode); | ||
870 | + return returnCode; | ||
871 | + } | ||
872 | + | ||
873 | + return ZIYAN_ERROR_SYSTEM_MODULE_CODE_SUCCESS; | ||
874 | +} | ||
875 | + | ||
876 | +static T_ZiyanReturnCode DestroyMediaFileThumbNail(const char *filePath) | ||
877 | +{ | ||
878 | + T_ZiyanReturnCode returnCode; | ||
879 | + | ||
880 | + USER_UTIL_UNUSED(filePath); | ||
881 | + | ||
882 | + if (s_mediaFileThumbNailHandle == NULL) { | ||
883 | + USER_LOG_ERROR("Media file thumb nail handle null error"); | ||
884 | + return ZIYAN_ERROR_SYSTEM_MODULE_CODE_INVALID_PARAMETER; | ||
885 | + } | ||
886 | + | ||
887 | + returnCode = ZiyanMediaFile_DestoryThm(s_mediaFileThumbNailHandle); | ||
888 | + if (returnCode != ZIYAN_ERROR_SYSTEM_MODULE_CODE_SUCCESS) { | ||
889 | + USER_LOG_ERROR("Media file destroy thumb nail error stat:0x%08llX", returnCode); | ||
890 | + return returnCode; | ||
891 | + } | ||
892 | + | ||
893 | + returnCode = ZiyanMediaFile_DestroyHandle(s_mediaFileThumbNailHandle); | ||
894 | + if (returnCode != ZIYAN_ERROR_SYSTEM_MODULE_CODE_SUCCESS) { | ||
895 | + USER_LOG_ERROR("Media file destroy handle error stat:0x%08llX", returnCode); | ||
896 | + return returnCode; | ||
897 | + } | ||
898 | + | ||
899 | + return ZIYAN_ERROR_SYSTEM_MODULE_CODE_SUCCESS; | ||
900 | +} | ||
901 | + | ||
902 | +static T_ZiyanReturnCode CreateMediaFileScreenNail(const char *filePath) | ||
903 | +{ | ||
904 | + T_ZiyanReturnCode returnCode; | ||
905 | + | ||
906 | + returnCode = ZiyanMediaFile_CreateHandle(filePath, &s_mediaFileScreenNailHandle); | ||
907 | + if (returnCode != ZIYAN_ERROR_SYSTEM_MODULE_CODE_SUCCESS) { | ||
908 | + USER_LOG_ERROR("Media file create handle error stat:0x%08llX", returnCode); | ||
909 | + return returnCode; | ||
910 | + } | ||
911 | + | ||
912 | + returnCode = ZiyanMediaFile_CreateScr(s_mediaFileScreenNailHandle); | ||
913 | + if (returnCode != ZIYAN_ERROR_SYSTEM_MODULE_CODE_SUCCESS) { | ||
914 | + USER_LOG_ERROR("Media file create screen nail error stat:0x%08llX", returnCode); | ||
915 | + return returnCode; | ||
916 | + } | ||
917 | + | ||
918 | + return ZIYAN_ERROR_SYSTEM_MODULE_CODE_SUCCESS; | ||
919 | +} | ||
920 | + | ||
921 | +static T_ZiyanReturnCode GetMediaFileScreenNailInfo(const char *filePath, T_ZiyanCameraMediaFileInfo *fileInfo) | ||
922 | +{ | ||
923 | + T_ZiyanReturnCode returnCode; | ||
924 | + | ||
925 | + USER_UTIL_UNUSED(filePath); | ||
926 | + | ||
927 | + if (s_mediaFileScreenNailHandle == NULL) { | ||
928 | + USER_LOG_ERROR("Media file screen nail handle null error"); | ||
929 | + return ZIYAN_ERROR_SYSTEM_MODULE_CODE_INVALID_PARAMETER; | ||
930 | + } | ||
931 | + | ||
932 | + returnCode = ZiyanMediaFile_GetMediaFileType(s_mediaFileScreenNailHandle, &fileInfo->type); | ||
933 | + if (returnCode != ZIYAN_ERROR_SYSTEM_MODULE_CODE_SUCCESS) { | ||
934 | + USER_LOG_ERROR("Media file get type error stat:0x%08llX", returnCode); | ||
935 | + return returnCode; | ||
936 | + } | ||
937 | + | ||
938 | + returnCode = ZiyanMediaFile_GetMediaFileAttr(s_mediaFileScreenNailHandle, &fileInfo->mediaFileAttr); | ||
939 | + if (returnCode != ZIYAN_ERROR_SYSTEM_MODULE_CODE_SUCCESS) { | ||
940 | + USER_LOG_ERROR("Media file get attr error stat:0x%08llX", returnCode); | ||
941 | + return returnCode; | ||
942 | + } | ||
943 | + | ||
944 | + returnCode = ZiyanMediaFile_GetFileSizeScr(s_mediaFileScreenNailHandle, &fileInfo->fileSize); | ||
945 | + if (returnCode != ZIYAN_ERROR_SYSTEM_MODULE_CODE_SUCCESS) { | ||
946 | + USER_LOG_ERROR("Media file get size error stat:0x%08llX", returnCode); | ||
947 | + return returnCode; | ||
948 | + } | ||
949 | + | ||
950 | + return ZIYAN_ERROR_SYSTEM_MODULE_CODE_SUCCESS; | ||
951 | +} | ||
952 | + | ||
953 | +static T_ZiyanReturnCode GetMediaFileScreenNailData(const char *filePath, uint32_t offset, uint32_t length, | ||
954 | + uint8_t *data) | ||
955 | +{ | ||
956 | + T_ZiyanReturnCode returnCode; | ||
957 | + uint16_t realLen = 0; | ||
958 | + | ||
959 | + USER_UTIL_UNUSED(filePath); | ||
960 | + | ||
961 | + if (s_mediaFileScreenNailHandle == NULL) { | ||
962 | + USER_LOG_ERROR("Media file screen nail handle null error"); | ||
963 | + return ZIYAN_ERROR_SYSTEM_MODULE_CODE_INVALID_PARAMETER; | ||
964 | + } | ||
965 | + | ||
966 | + returnCode = ZiyanMediaFile_GetDataScr(s_mediaFileScreenNailHandle, offset, length, data, &realLen); | ||
967 | + if (returnCode != ZIYAN_ERROR_SYSTEM_MODULE_CODE_SUCCESS) { | ||
968 | + USER_LOG_ERROR("Media file get size error stat:0x%08llX", returnCode); | ||
969 | + return returnCode; | ||
970 | + } | ||
971 | + | ||
972 | + return ZIYAN_ERROR_SYSTEM_MODULE_CODE_SUCCESS; | ||
973 | +} | ||
974 | + | ||
975 | +static T_ZiyanReturnCode DestroyMediaFileScreenNail(const char *filePath) | ||
976 | +{ | ||
977 | + T_ZiyanReturnCode returnCode; | ||
978 | + | ||
979 | + USER_UTIL_UNUSED(filePath); | ||
980 | + | ||
981 | + if (s_mediaFileScreenNailHandle == NULL) { | ||
982 | + USER_LOG_ERROR("Media file screen nail handle null error"); | ||
983 | + return ZIYAN_ERROR_SYSTEM_MODULE_CODE_INVALID_PARAMETER; | ||
984 | + } | ||
985 | + | ||
986 | + returnCode = ZiyanMediaFile_DestroyScr(s_mediaFileScreenNailHandle); | ||
987 | + if (returnCode != ZIYAN_ERROR_SYSTEM_MODULE_CODE_SUCCESS) { | ||
988 | + USER_LOG_ERROR("Media file destroy screen nail error stat:0x%08llX", returnCode); | ||
989 | + return returnCode; | ||
990 | + } | ||
991 | + | ||
992 | + returnCode = ZiyanMediaFile_DestroyHandle(s_mediaFileScreenNailHandle); | ||
993 | + if (returnCode != ZIYAN_ERROR_SYSTEM_MODULE_CODE_SUCCESS) { | ||
994 | + USER_LOG_ERROR("Media file destroy handle error stat:0x%08llX", returnCode); | ||
995 | + return returnCode; | ||
996 | + } | ||
997 | + | ||
998 | + return ZIYAN_ERROR_SYSTEM_MODULE_CODE_SUCCESS; | ||
999 | +} | ||
1000 | + | ||
1001 | +static T_ZiyanReturnCode DeleteMediaFile(char *filePath) | ||
1002 | +{ | ||
1003 | + T_ZiyanReturnCode returnCode; | ||
1004 | + | ||
1005 | + USER_LOG_INFO("delete media file:%s", filePath); | ||
1006 | + returnCode = UtilFile_Delete(filePath); | ||
1007 | + if (returnCode != ZIYAN_ERROR_SYSTEM_MODULE_CODE_SUCCESS) { | ||
1008 | + USER_LOG_ERROR("Media file delete error stat:0x%08llX", returnCode); | ||
1009 | + return returnCode; | ||
1010 | + } | ||
1011 | + | ||
1012 | + return ZIYAN_ERROR_SYSTEM_MODULE_CODE_SUCCESS; | ||
1013 | +} | ||
1014 | + | ||
1015 | +static T_ZiyanReturnCode SetMediaPlaybackFile(const char *filePath) | ||
1016 | +{ | ||
1017 | + USER_LOG_INFO("set media playback file:%s", filePath); | ||
1018 | + T_ZiyanReturnCode returnCode; | ||
1019 | + | ||
1020 | + returnCode = ZiyanPlayback_StopPlay(&s_playbackInfo); | ||
1021 | + if (returnCode != ZIYAN_ERROR_SYSTEM_MODULE_CODE_SUCCESS) { | ||
1022 | + return returnCode; | ||
1023 | + } | ||
1024 | + | ||
1025 | + returnCode = ZiyanPlayback_SetPlayFile(&s_playbackInfo, filePath, 0); | ||
1026 | + if (returnCode != ZIYAN_ERROR_SYSTEM_MODULE_CODE_SUCCESS) { | ||
1027 | + return returnCode; | ||
1028 | + } | ||
1029 | + | ||
1030 | + returnCode = ZiyanPlayback_StartPlay(&s_playbackInfo); | ||
1031 | + if (returnCode != ZIYAN_ERROR_SYSTEM_MODULE_CODE_SUCCESS) { | ||
1032 | + return returnCode; | ||
1033 | + } | ||
1034 | + | ||
1035 | + return ZIYAN_ERROR_SYSTEM_MODULE_CODE_SUCCESS; | ||
1036 | +} | ||
1037 | + | ||
1038 | +static T_ZiyanReturnCode StartMediaPlayback(void) | ||
1039 | +{ | ||
1040 | + T_ZiyanReturnCode returnCode; | ||
1041 | + | ||
1042 | + USER_LOG_INFO("start media playback"); | ||
1043 | + returnCode = ZiyanPlayback_StartPlay(&s_playbackInfo); | ||
1044 | + if (returnCode != ZIYAN_ERROR_SYSTEM_MODULE_CODE_SUCCESS) { | ||
1045 | + USER_LOG_ERROR("start media playback status error, stat:0x%08llX", returnCode); | ||
1046 | + return returnCode; | ||
1047 | + } | ||
1048 | + | ||
1049 | + return returnCode; | ||
1050 | +} | ||
1051 | + | ||
1052 | +static T_ZiyanReturnCode StopMediaPlayback(void) | ||
1053 | +{ | ||
1054 | + T_ZiyanReturnCode returnCode; | ||
1055 | + | ||
1056 | + USER_LOG_INFO("stop media playback"); | ||
1057 | + returnCode = ZiyanPlayback_StopPlay(&s_playbackInfo); | ||
1058 | + if (returnCode != ZIYAN_ERROR_SYSTEM_MODULE_CODE_SUCCESS) { | ||
1059 | + USER_LOG_ERROR("stop media playback error, stat:0x%08llX", returnCode); | ||
1060 | + return returnCode; | ||
1061 | + } | ||
1062 | + | ||
1063 | + return returnCode; | ||
1064 | +} | ||
1065 | + | ||
1066 | +static T_ZiyanReturnCode PauseMediaPlayback(void) | ||
1067 | +{ | ||
1068 | + T_ZiyanReturnCode returnCode; | ||
1069 | + | ||
1070 | + USER_LOG_INFO("pause media playback"); | ||
1071 | + returnCode = ZiyanPlayback_PausePlay(&s_playbackInfo); | ||
1072 | + if (returnCode != ZIYAN_ERROR_SYSTEM_MODULE_CODE_SUCCESS) { | ||
1073 | + USER_LOG_ERROR("pause media playback error, stat:0x%08llX", returnCode); | ||
1074 | + return returnCode; | ||
1075 | + } | ||
1076 | + | ||
1077 | + return returnCode; | ||
1078 | +} | ||
1079 | + | ||
1080 | +static T_ZiyanReturnCode SeekMediaPlayback(uint32_t playbackPosition) | ||
1081 | +{ | ||
1082 | + T_ZiyanReturnCode returnCode; | ||
1083 | + | ||
1084 | + USER_LOG_INFO("seek media playback:%d", playbackPosition); | ||
1085 | + returnCode = ZiyanPlayback_SeekPlay(&s_playbackInfo, playbackPosition); | ||
1086 | + if (returnCode != ZIYAN_ERROR_SYSTEM_MODULE_CODE_SUCCESS) { | ||
1087 | + USER_LOG_ERROR("seek media playback error, stat:0x%08llX", returnCode); | ||
1088 | + return returnCode; | ||
1089 | + } | ||
1090 | + | ||
1091 | + return returnCode; | ||
1092 | +} | ||
1093 | + | ||
1094 | +static T_ZiyanReturnCode GetMediaPlaybackStatus(T_ZiyanCameraPlaybackStatus *status) | ||
1095 | +{ | ||
1096 | + T_ZiyanReturnCode returnCode; | ||
1097 | + | ||
1098 | + returnCode = ZiyanPlayback_GetPlaybackStatus(&s_playbackInfo, status); | ||
1099 | + if (returnCode != ZIYAN_ERROR_SYSTEM_MODULE_CODE_SUCCESS) { | ||
1100 | + USER_LOG_ERROR("get playback status error, stat:0x%08llX", returnCode); | ||
1101 | + return returnCode; | ||
1102 | + } | ||
1103 | + | ||
1104 | + status->videoPlayProcess = (uint8_t) (((float) s_playbackInfo.playPosMs / (float) s_playbackInfo.videoLengthMs) * | ||
1105 | + 100); | ||
1106 | + | ||
1107 | + USER_LOG_DEBUG("get media playback status %d %d %d %d", status->videoPlayProcess, status->playPosMs, | ||
1108 | + status->videoLengthMs, status->playbackMode); | ||
1109 | + | ||
1110 | + return ZIYAN_ERROR_SYSTEM_MODULE_CODE_SUCCESS; | ||
1111 | +} | ||
1112 | + | ||
1113 | +static T_ZiyanReturnCode StartDownloadNotification(void) | ||
1114 | +{ | ||
1115 | + T_ZiyanReturnCode returnCode; | ||
1116 | + T_ZiyanDataChannelBandwidthProportionOfHighspeedChannel bandwidthProportion = {0}; | ||
1117 | + | ||
1118 | + USER_LOG_DEBUG("media download start notification."); | ||
1119 | + | ||
1120 | + bandwidthProportion.dataStream = 0; | ||
1121 | + bandwidthProportion.videoStream = 0; | ||
1122 | + bandwidthProportion.downloadStream = 100; | ||
1123 | + | ||
1124 | + returnCode = ZiyanHighSpeedDataChannel_SetBandwidthProportion(bandwidthProportion); | ||
1125 | + if (returnCode != ZIYAN_ERROR_SYSTEM_MODULE_CODE_SUCCESS) { | ||
1126 | + USER_LOG_ERROR("Set bandwidth proportion for high speed channel error, stat:0x%08llX.", returnCode); | ||
1127 | + return returnCode; | ||
1128 | + } | ||
1129 | + | ||
1130 | + return ZIYAN_ERROR_SYSTEM_MODULE_CODE_SUCCESS; | ||
1131 | +} | ||
1132 | + | ||
1133 | +static T_ZiyanReturnCode StopDownloadNotification(void) | ||
1134 | +{ | ||
1135 | + T_ZiyanReturnCode returnCode; | ||
1136 | + T_ZiyanDataChannelBandwidthProportionOfHighspeedChannel bandwidthProportion = {0}; | ||
1137 | + | ||
1138 | + USER_LOG_DEBUG("media download stop notification."); | ||
1139 | + | ||
1140 | + bandwidthProportion.dataStream = 10; | ||
1141 | + bandwidthProportion.videoStream = 60; | ||
1142 | + bandwidthProportion.downloadStream = 30; | ||
1143 | + | ||
1144 | + returnCode = ZiyanHighSpeedDataChannel_SetBandwidthProportion(bandwidthProportion); | ||
1145 | + if (returnCode != ZIYAN_ERROR_SYSTEM_MODULE_CODE_SUCCESS) { | ||
1146 | + USER_LOG_ERROR("Set bandwidth proportion for high speed channel error, stat:0x%08llX.", returnCode); | ||
1147 | + return returnCode; | ||
1148 | + } | ||
1149 | + | ||
1150 | + return ZIYAN_ERROR_SYSTEM_MODULE_CODE_SUCCESS; | ||
1151 | +} | ||
1152 | + | ||
1153 | +#ifndef __CC_ARM | ||
1154 | +#pragma GCC diagnostic push | ||
1155 | +#pragma GCC diagnostic ignored "-Wmissing-noreturn" | ||
1156 | +#pragma GCC diagnostic ignored "-Wreturn-type" | ||
1157 | +#endif | ||
1158 | + | ||
1159 | +static void *UserCameraMedia_SendVideoTask(void *arg) | ||
1160 | +{ | ||
1161 | + int ret; | ||
1162 | + T_ZiyanReturnCode returnCode; | ||
1163 | + static uint32_t sendVideoStep = 0; | ||
1164 | + FILE *fpFile = NULL; | ||
1165 | + unsigned long dataLength = 0; | ||
1166 | + uint16_t lengthOfDataToBeSent = 0; | ||
1167 | + int lengthOfDataHaveBeenSent = 0; | ||
1168 | + char *dataBuffer = NULL; | ||
1169 | + T_TestPayloadCameraPlaybackCommand playbackCommand = {0}; | ||
1170 | + uint16_t bufferReadSize = 0; | ||
1171 | + char *videoFilePath = NULL; | ||
1172 | + char *transcodedFilePath = NULL; | ||
1173 | + float frameRate = 1.0f; | ||
1174 | + uint32_t waitDuration = 1000 / SEND_VIDEO_TASK_FREQ; | ||
1175 | + uint32_t rightNow = 0; | ||
1176 | + uint32_t sendExpect = 0; | ||
1177 | + T_TestPayloadCameraVideoFrameInfo *frameInfo = NULL; | ||
1178 | + uint32_t frameNumber = 0; | ||
1179 | + uint32_t frameCount = 0; | ||
1180 | + uint32_t startTimeMs = 0; | ||
1181 | + bool sendVideoFlag = true; | ||
1182 | + bool sendOneTimeFlag = false; | ||
1183 | + T_ZiyanDataChannelState videoStreamState = {0}; | ||
1184 | + E_ZiyanCameraMode mode = ZIYAN_CAMERA_MODE_SHOOT_PHOTO; | ||
1185 | + T_ZiyanOsalHandler *osalHandler = ZiyanPlatform_GetOsalHandler(); | ||
1186 | + uint32_t frameBufSize = 0; | ||
1187 | + E_ZiyanCameraVideoStreamType videoStreamType; | ||
1188 | + char curFileDirPath[ZIYAN_FILE_PATH_SIZE_MAX]; | ||
1189 | + char tempPath[ZIYAN_FILE_PATH_SIZE_MAX]; | ||
1190 | + | ||
1191 | + USER_UTIL_UNUSED(arg); | ||
1192 | + | ||
1193 | + returnCode = ZiyanUserUtil_GetCurrentFileDirPath(__FILE__, ZIYAN_FILE_PATH_SIZE_MAX, curFileDirPath); | ||
1194 | + if (returnCode != ZIYAN_ERROR_SYSTEM_MODULE_CODE_SUCCESS) { | ||
1195 | + USER_LOG_ERROR("Get file current path error, stat = 0x%08llX", returnCode); | ||
1196 | + exit(1); | ||
1197 | + } | ||
1198 | + if (s_isMediaFileDirPathConfigured == true) { | ||
1199 | + snprintf(tempPath, ZIYAN_FILE_PATH_SIZE_MAX, "%sPSDK_0005.h264", s_mediaFileDirPath); | ||
1200 | + } else { | ||
1201 | + snprintf(tempPath, ZIYAN_FILE_PATH_SIZE_MAX, "%smedia_file/PSDK_0005.h264", curFileDirPath); | ||
1202 | + } | ||
1203 | + | ||
1204 | + videoFilePath = osalHandler->Malloc(ZIYAN_FILE_PATH_SIZE_MAX); | ||
1205 | + if (videoFilePath == NULL) { | ||
1206 | + USER_LOG_ERROR("malloc memory for video file path fail."); | ||
1207 | + exit(1); | ||
1208 | + } | ||
1209 | + | ||
1210 | + transcodedFilePath = osalHandler->Malloc(ZIYAN_FILE_PATH_SIZE_MAX); | ||
1211 | + if (transcodedFilePath == NULL) { | ||
1212 | + USER_LOG_ERROR("malloc memory for transcoded file path fail."); | ||
1213 | + exit(1); | ||
1214 | + } | ||
1215 | + | ||
1216 | + frameInfo = osalHandler->Malloc(VIDEO_FRAME_MAX_COUNT * sizeof(T_TestPayloadCameraVideoFrameInfo)); | ||
1217 | + if (frameInfo == NULL) { | ||
1218 | + USER_LOG_ERROR("malloc memory for frame info fail."); | ||
1219 | + exit(1); | ||
1220 | + } | ||
1221 | + memset(frameInfo, 0, VIDEO_FRAME_MAX_COUNT * sizeof(T_TestPayloadCameraVideoFrameInfo)); | ||
1222 | + | ||
1223 | + returnCode = ZiyanPlayback_StopPlayProcess(); | ||
1224 | + if (returnCode != ZIYAN_ERROR_SYSTEM_MODULE_CODE_SUCCESS) { | ||
1225 | + USER_LOG_ERROR("stop playback and start liveview error: 0x%08llX.", returnCode); | ||
1226 | + exit(1); | ||
1227 | + } | ||
1228 | + | ||
1229 | + (void)osalHandler->GetTimeMs(&rightNow); | ||
1230 | + sendExpect = rightNow + waitDuration; | ||
1231 | + while (1) { | ||
1232 | + (void)osalHandler->GetTimeMs(&rightNow); | ||
1233 | + if (sendExpect > rightNow) { | ||
1234 | + waitDuration = sendExpect - rightNow; | ||
1235 | + } else { | ||
1236 | + waitDuration = 1000 / SEND_VIDEO_TASK_FREQ; | ||
1237 | + } | ||
1238 | + (void)osalHandler->SemaphoreTimedWait(s_mediaPlayWorkSem, waitDuration); | ||
1239 | + | ||
1240 | + // response playback command | ||
1241 | + if (osalHandler->MutexLock(s_mediaPlayCommandBufferMutex) != ZIYAN_ERROR_SYSTEM_MODULE_CODE_SUCCESS) { | ||
1242 | + USER_LOG_ERROR("mutex lock error"); | ||
1243 | + continue; | ||
1244 | + } | ||
1245 | + | ||
1246 | + bufferReadSize = UtilBuffer_Get(&s_mediaPlayCommandBufferHandler, (uint8_t *) &playbackCommand, | ||
1247 | + sizeof(T_TestPayloadCameraPlaybackCommand)); | ||
1248 | + | ||
1249 | + if (osalHandler->MutexUnlock(s_mediaPlayCommandBufferMutex) != ZIYAN_ERROR_SYSTEM_MODULE_CODE_SUCCESS) { | ||
1250 | + USER_LOG_ERROR("mutex unlock error"); | ||
1251 | + continue; | ||
1252 | + } | ||
1253 | + | ||
1254 | + if (bufferReadSize != sizeof(T_TestPayloadCameraPlaybackCommand)) | ||
1255 | + goto send; | ||
1256 | + | ||
1257 | + switch (playbackCommand.command) { | ||
1258 | + case TEST_PAYLOAD_CAMERA_MEDIA_PLAY_COMMAND_STOP: | ||
1259 | + snprintf(videoFilePath, ZIYAN_FILE_PATH_SIZE_MAX, "%s", tempPath); | ||
1260 | + startTimeMs = 0; | ||
1261 | + sendVideoFlag = true; | ||
1262 | + sendOneTimeFlag = false; | ||
1263 | + break; | ||
1264 | + case TEST_PAYLOAD_CAMERA_MEDIA_PLAY_COMMAND_PAUSE: | ||
1265 | + sendVideoFlag = false; | ||
1266 | + goto send; | ||
1267 | + case TEST_PAYLOAD_CAMERA_MEDIA_PLAY_COMMAND_START: | ||
1268 | + snprintf(videoFilePath, ZIYAN_FILE_PATH_SIZE_MAX, "%s", playbackCommand.path); | ||
1269 | + startTimeMs = playbackCommand.timeMs; | ||
1270 | + sendVideoFlag = true; | ||
1271 | + sendOneTimeFlag = true; | ||
1272 | + break; | ||
1273 | + default: | ||
1274 | + USER_LOG_ERROR("playback command invalid: %d.", playbackCommand.command); | ||
1275 | + sendVideoFlag = false; | ||
1276 | + goto send; | ||
1277 | + } | ||
1278 | + | ||
1279 | + // video send preprocess | ||
1280 | + returnCode = ZiyanPlayback_VideoFileTranscode(videoFilePath, "h264", transcodedFilePath, | ||
1281 | + ZIYAN_FILE_PATH_SIZE_MAX); | ||
1282 | + if (returnCode != ZIYAN_ERROR_SYSTEM_MODULE_CODE_SUCCESS) { | ||
1283 | + USER_LOG_ERROR("transcode video file error: 0x%08llX.", returnCode); | ||
1284 | + continue; | ||
1285 | + } | ||
1286 | + | ||
1287 | + returnCode = ZiyanPlayback_GetFrameRateOfVideoFile(transcodedFilePath, &frameRate); | ||
1288 | + if (returnCode != ZIYAN_ERROR_SYSTEM_MODULE_CODE_SUCCESS) { | ||
1289 | + USER_LOG_ERROR("get frame rate of video error: 0x%08llX.", returnCode); | ||
1290 | + continue; | ||
1291 | + } | ||
1292 | + | ||
1293 | + returnCode = ZiyanPlayback_GetFrameInfoOfVideoFile(transcodedFilePath, frameInfo, VIDEO_FRAME_MAX_COUNT, | ||
1294 | + &frameCount); | ||
1295 | + if (returnCode != ZIYAN_ERROR_SYSTEM_MODULE_CODE_SUCCESS) { | ||
1296 | + USER_LOG_ERROR("get frame info of video error: 0x%08llX.", returnCode); | ||
1297 | + continue; | ||
1298 | + } | ||
1299 | + | ||
1300 | + returnCode = ZiyanPlayback_GetFrameNumberByTime(frameInfo, frameCount, &frameNumber, | ||
1301 | + startTimeMs); | ||
1302 | + if (returnCode != ZIYAN_ERROR_SYSTEM_MODULE_CODE_SUCCESS) { | ||
1303 | + USER_LOG_ERROR("get start frame number error: 0x%08llX.", returnCode); | ||
1304 | + continue; | ||
1305 | + } | ||
1306 | + | ||
1307 | + if (fpFile != NULL) | ||
1308 | + fclose(fpFile); | ||
1309 | + | ||
1310 | + fpFile = fopen(transcodedFilePath, "rb+"); | ||
1311 | + if (fpFile == NULL) { | ||
1312 | + USER_LOG_ERROR("open video file fail."); | ||
1313 | + continue; | ||
1314 | + } | ||
1315 | + | ||
1316 | + send: | ||
1317 | + if (fpFile == NULL) { | ||
1318 | + USER_LOG_ERROR("open video file fail."); | ||
1319 | + continue; | ||
1320 | + } | ||
1321 | + | ||
1322 | + if (sendVideoFlag != true) | ||
1323 | + continue; | ||
1324 | + | ||
1325 | + returnCode = ZiyanTest_CameraGetMode(&mode); | ||
1326 | + if (returnCode != ZIYAN_ERROR_SYSTEM_MODULE_CODE_SUCCESS) { | ||
1327 | + continue; | ||
1328 | + } | ||
1329 | + | ||
1330 | + returnCode = ZiyanTest_CameraGetVideoStreamType(&videoStreamType); | ||
1331 | + if (returnCode != ZIYAN_ERROR_SYSTEM_MODULE_CODE_SUCCESS) { | ||
1332 | + continue; | ||
1333 | + } | ||
1334 | + | ||
1335 | + if (mode == ZIYAN_CAMERA_MODE_PLAYBACK && s_playbackInfo.isInPlayProcess == false) { | ||
1336 | + continue; | ||
1337 | + } | ||
1338 | + | ||
1339 | + frameBufSize = frameInfo[frameNumber].size; | ||
1340 | + if (videoStreamType == ZIYAN_CAMERA_VIDEO_STREAM_TYPE_H264_ZIYAN_FORMAT) { | ||
1341 | + frameBufSize = frameBufSize + VIDEO_FRAME_AUD_LEN; | ||
1342 | + } | ||
1343 | + | ||
1344 | + dataBuffer = calloc(frameBufSize, 1); | ||
1345 | + if (dataBuffer == NULL) { | ||
1346 | + USER_LOG_ERROR("malloc fail."); | ||
1347 | + goto free; | ||
1348 | + } | ||
1349 | + | ||
1350 | + ret = fseek(fpFile, frameInfo[frameNumber].positionInFile, SEEK_SET); | ||
1351 | + if (ret != 0) { | ||
1352 | + USER_LOG_ERROR("fseek fail."); | ||
1353 | + goto free; | ||
1354 | + } | ||
1355 | + | ||
1356 | + dataLength = fread(dataBuffer, 1, frameInfo[frameNumber].size, fpFile); | ||
1357 | + if (dataLength != frameInfo[frameNumber].size) { | ||
1358 | + USER_LOG_ERROR("read data from video file error."); | ||
1359 | + } else { | ||
1360 | + USER_LOG_DEBUG("read data from video file success, len = %d B\r\n", dataLength); | ||
1361 | + } | ||
1362 | + | ||
1363 | + if (videoStreamType == ZIYAN_CAMERA_VIDEO_STREAM_TYPE_H264_ZIYAN_FORMAT) { | ||
1364 | + memcpy(&dataBuffer[frameInfo[frameNumber].size], s_frameAudInfo, VIDEO_FRAME_AUD_LEN); | ||
1365 | + dataLength = dataLength + VIDEO_FRAME_AUD_LEN; | ||
1366 | + } | ||
1367 | + | ||
1368 | + lengthOfDataHaveBeenSent = 0; | ||
1369 | + while (dataLength - lengthOfDataHaveBeenSent) { | ||
1370 | + lengthOfDataToBeSent = USER_UTIL_MIN(DATA_SEND_FROM_VIDEO_STREAM_MAX_LEN, | ||
1371 | + dataLength - lengthOfDataHaveBeenSent); | ||
1372 | + printf("send video stream, len = %d B\r\n", lengthOfDataToBeSent); | ||
1373 | + returnCode = ZiyanPayloadCamera_SendVideoStream((const uint8_t *) dataBuffer + lengthOfDataHaveBeenSent, | ||
1374 | + lengthOfDataToBeSent); | ||
1375 | + if (returnCode != ZIYAN_ERROR_SYSTEM_MODULE_CODE_SUCCESS) { | ||
1376 | + USER_LOG_ERROR("send video stream error: 0x%08llX.", returnCode); | ||
1377 | + } | ||
1378 | + lengthOfDataHaveBeenSent += lengthOfDataToBeSent; | ||
1379 | + } | ||
1380 | + | ||
1381 | + (void)osalHandler->GetTimeMs(&sendExpect); | ||
1382 | + sendExpect += (1000 / frameRate); | ||
1383 | + | ||
1384 | + if ((frameNumber++) >= frameCount) { | ||
1385 | + USER_LOG_DEBUG("reach file tail."); | ||
1386 | + frameNumber = 0; | ||
1387 | + | ||
1388 | + if (sendOneTimeFlag == true) | ||
1389 | + sendVideoFlag = false; | ||
1390 | + } | ||
1391 | + | ||
1392 | + returnCode = ZiyanPayloadCamera_GetVideoStreamState(&videoStreamState); | ||
1393 | + if (returnCode == ZIYAN_ERROR_SYSTEM_MODULE_CODE_SUCCESS) { | ||
1394 | + USER_LOG_DEBUG( | ||
1395 | + "video stream state: realtimeBandwidthLimit: %d, realtimeBandwidthBeforeFlowController: %d, realtimeBandwidthAfterFlowController:%d busyState: %d.", | ||
1396 | + videoStreamState.realtimeBandwidthLimit, videoStreamState.realtimeBandwidthBeforeFlowController, | ||
1397 | + videoStreamState.realtimeBandwidthAfterFlowController, | ||
1398 | + videoStreamState.busyState); | ||
1399 | + } else { | ||
1400 | + USER_LOG_ERROR("get video stream state error."); | ||
1401 | + } | ||
1402 | + | ||
1403 | + free: | ||
1404 | + free(dataBuffer); | ||
1405 | + } | ||
1406 | +} | ||
1407 | + | ||
1408 | +#ifndef __CC_ARM | ||
1409 | +#pragma GCC diagnostic pop | ||
1410 | +#endif | ||
1411 | + | ||
1412 | +//#endif | ||
1413 | + | ||
1414 | +/****************** (C) COPYRIGHT ZIYAN Innovations *****END OF FILE****/ |
@@ -31,6 +31,9 @@ | @@ -31,6 +31,9 @@ | ||
31 | #include <stdio.h> | 31 | #include <stdio.h> |
32 | #include "file_binary_array_list_en.h" | 32 | #include "file_binary_array_list_en.h" |
33 | 33 | ||
34 | +#include <stdio.h> | ||
35 | +#include <stdlib.h> | ||
36 | + | ||
34 | 37 | ||
35 | #include "JZsdkLib.h" | 38 | #include "JZsdkLib.h" |
36 | #include "BaseConfig.h" | 39 | #include "BaseConfig.h" |
@@ -45,6 +48,20 @@ | @@ -45,6 +48,20 @@ | ||
45 | #define WIDGET_DIR_PATH_LEN_MAX (256) | 48 | #define WIDGET_DIR_PATH_LEN_MAX (256) |
46 | #define WIDGET_TASK_STACK_SIZE (2048) | 49 | #define WIDGET_TASK_STACK_SIZE (2048) |
47 | 50 | ||
51 | +#define ON JZ_FLAGCODE_ON | ||
52 | +#define OFF JZ_FLAGCODE_OFF | ||
53 | +#define PLAY_PAUSE 1 | ||
54 | +#define PLAY_CONTINUE 0 | ||
55 | +#define PLAY_SPEED_X1 1 | ||
56 | +#define WIDGET_FILE_DIR "/root/Configs/ZY_widget_file" | ||
57 | + | ||
58 | +int Opus_PlayMode=0;//0录音喊话 1实时喊话 | ||
59 | + | ||
60 | +int num_flag=0;//版本号信息 | ||
61 | +// extern int SpeakerWidgetUseLock; | ||
62 | +// extern float g_height_value; | ||
63 | +// extern int Widget_RealTimeOpusFlag; //用于标志ui里的实时语音开关 | ||
64 | + | ||
48 | /* Private types -------------------------------------------------------------*/ | 65 | /* Private types -------------------------------------------------------------*/ |
49 | 66 | ||
50 | /* Private functions declaration ---------------------------------------------*/ | 67 | /* Private functions declaration ---------------------------------------------*/ |
@@ -59,8 +76,18 @@ static T_ZiyanTaskHandle s_widgetTestThread; | @@ -59,8 +76,18 @@ static T_ZiyanTaskHandle s_widgetTestThread; | ||
59 | static bool s_isWidgetFileDirPathConfigured = false; | 76 | static bool s_isWidgetFileDirPathConfigured = false; |
60 | static char s_widgetFileDirPath[ZIYAN_FILE_PATH_SIZE_MAX] = {0}; | 77 | static char s_widgetFileDirPath[ZIYAN_FILE_PATH_SIZE_MAX] = {0}; |
61 | 78 | ||
79 | +static const char *s_widgetTypeNameArray[] = { | ||
80 | + "Unknown", | ||
81 | + "Button", | ||
82 | + "Switch", | ||
83 | + "Scale", | ||
84 | + "List", | ||
85 | + "Int input box" | ||
86 | +}; | ||
87 | + | ||
88 | +#if 0 | ||
62 | 89 | ||
63 | -#ifdef MEGAPHONE_CONFIG_STATUS_ON | 90 | +//#ifdef MEGAPHONE_CONFIG_STATUS_ON |
64 | 91 | ||
65 | static const T_ZiyanWidgetHandlerListItem s_widgetHandlerList[] = { | 92 | static const T_ZiyanWidgetHandlerListItem s_widgetHandlerList[] = { |
66 | //喊话器部分 | 93 | //喊话器部分 |
@@ -101,8 +128,9 @@ static const T_ZiyanWidgetHandlerListItem s_widgetHandlerList[] = { | @@ -101,8 +128,9 @@ static const T_ZiyanWidgetHandlerListItem s_widgetHandlerList[] = { | ||
101 | {28, ZIYAN_WIDGET_TYPE_LIST, ZiyanTestWidget_SetWidgetValue, ZiyanTestWidget_GetWidgetValue, NULL},//设置滤波输入值 | 128 | {28, ZIYAN_WIDGET_TYPE_LIST, ZiyanTestWidget_SetWidgetValue, ZiyanTestWidget_GetWidgetValue, NULL},//设置滤波输入值 |
102 | }; | 129 | }; |
103 | 130 | ||
104 | -static const uint32_t s_widgetHandlerListCount = sizeof(s_widgetHandlerList) / sizeof(T_DjiWidgetHandlerListItem); | ||
105 | -int32_t s_widgetValueList[29] = { OFF, OFF, PLAY_PAUSE, 30, 30, PLAY_SPEED_X1, 0, OFF,OFF,OFF, //喊话器部分 | 131 | +static const uint32_t s_widgetHandlerListCount = sizeof(s_widgetHandlerList) / sizeof(T_ZiyanWidgetHandlerListItem); |
132 | +static int32_t s_widgetValueList[sizeof(s_widgetHandlerList) / sizeof(T_ZiyanWidgetHandlerListItem)] = { | ||
133 | + OFF, OFF, PLAY_PAUSE, 30, 30, PLAY_SPEED_X1, 0, OFF,OFF,OFF, //喊话器部分 | ||
106 | OFF, OFF, OFF, OFF, 50, OFF, //探照灯部分 | 134 | OFF, OFF, OFF, OFF, 50, OFF, //探照灯部分 |
107 | 0, 0, 2, //警灯部分 | 135 | 0, 0, 2, //警灯部分 |
108 | 100, 100 ,ON ,OFF,OFF, //云台部分 | 136 | 100, 100 ,ON ,OFF,OFF, //云台部分 |
@@ -123,21 +151,15 @@ static const T_ZiyanWidgetHandlerListItem s_widgetHandlerList[] = { | @@ -123,21 +151,15 @@ static const T_ZiyanWidgetHandlerListItem s_widgetHandlerList[] = { | ||
123 | {8, ZIYAN_WIDGET_TYPE_LIST, ZiyanTestWidget_SetWidgetValue, ZiyanTestWidget_GetWidgetValue, NULL}, | 151 | {8, ZIYAN_WIDGET_TYPE_LIST, ZiyanTestWidget_SetWidgetValue, ZiyanTestWidget_GetWidgetValue, NULL}, |
124 | }; | 152 | }; |
125 | 153 | ||
154 | +static const uint32_t s_widgetHandlerListCount = sizeof(s_widgetHandlerList) / sizeof(T_ZiyanWidgetHandlerListItem); | ||
155 | +static int32_t s_widgetValueList[sizeof(s_widgetHandlerList) / sizeof(T_ZiyanWidgetHandlerListItem)] = {0}; | ||
156 | + | ||
126 | #endif | 157 | #endif |
127 | 158 | ||
128 | 159 | ||
129 | 160 | ||
130 | -static const char *s_widgetTypeNameArray[] = { | ||
131 | - "Unknown", | ||
132 | - "Button", | ||
133 | - "Switch", | ||
134 | - "Scale", | ||
135 | - "List", | ||
136 | - "Int input box" | ||
137 | -}; | ||
138 | 161 | ||
139 | -static const uint32_t s_widgetHandlerListCount = sizeof(s_widgetHandlerList) / sizeof(T_ZiyanWidgetHandlerListItem); | ||
140 | -static int32_t s_widgetValueList[sizeof(s_widgetHandlerList) / sizeof(T_ZiyanWidgetHandlerListItem)] = {0}; | 162 | + |
141 | 163 | ||
142 | /* Exported functions definition ---------------------------------------------*/ | 164 | /* Exported functions definition ---------------------------------------------*/ |
143 | T_ZiyanReturnCode ZiyanTest_WidgetStartService(void) | 165 | T_ZiyanReturnCode ZiyanTest_WidgetStartService(void) |
@@ -151,29 +173,80 @@ T_ZiyanReturnCode ZiyanTest_WidgetStartService(void) | @@ -151,29 +173,80 @@ T_ZiyanReturnCode ZiyanTest_WidgetStartService(void) | ||
151 | USER_LOG_ERROR("Ziyan test widget init error, stat = 0x%08llX", ziyanStat); | 173 | USER_LOG_ERROR("Ziyan test widget init error, stat = 0x%08llX", ziyanStat); |
152 | return ziyanStat; | 174 | return ziyanStat; |
153 | } | 175 | } |
176 | + USER_LOG_INFO("Ziyan test widget init success"); | ||
154 | 177 | ||
155 | -#ifdef SYSTEM_ARCH_LINUX | ||
156 | //Step 2 : Set UI Config (Linux environment) | 178 | //Step 2 : Set UI Config (Linux environment) |
157 | char curFileDirPath[WIDGET_DIR_PATH_LEN_MAX]; | 179 | char curFileDirPath[WIDGET_DIR_PATH_LEN_MAX]; |
158 | char tempPath[WIDGET_DIR_PATH_LEN_MAX]; | 180 | char tempPath[WIDGET_DIR_PATH_LEN_MAX]; |
159 | - ziyanStat = ZiyanUserUtil_GetCurrentFileDirPath(__FILE__, WIDGET_DIR_PATH_LEN_MAX, curFileDirPath); | ||
160 | - if (ziyanStat != ZIYAN_ERROR_SYSTEM_MODULE_CODE_SUCCESS) { | ||
161 | - USER_LOG_ERROR("Get file current path error, stat = 0x%08llX", ziyanStat); | ||
162 | - return ziyanStat; | ||
163 | - } | ||
164 | 181 | ||
165 | - if (s_isWidgetFileDirPathConfigured == true) { | ||
166 | - snprintf(tempPath, WIDGET_DIR_PATH_LEN_MAX, "%swidget_file/en_big_screen", s_widgetFileDirPath); | ||
167 | - } else { | ||
168 | - snprintf(tempPath, WIDGET_DIR_PATH_LEN_MAX, "%swidget_file/en_big_screen", curFileDirPath); | ||
169 | - } | 182 | + // ziyanStat = ZiyanUserUtil_GetCurrentFileDirPath(__FILE__, WIDGET_DIR_PATH_LEN_MAX, curFileDirPath); |
183 | + // if (ziyanStat != ZIYAN_ERROR_SYSTEM_MODULE_CODE_SUCCESS) { | ||
184 | + // USER_LOG_ERROR("Get file current path error, stat = 0x%08llX", ziyanStat); | ||
185 | + // return ziyanStat; | ||
186 | + // } | ||
170 | 187 | ||
171 | - //set default ui config path | ||
172 | - ziyanStat = ZiyanWidget_RegDefaultUiConfigByDirPath(tempPath); | ||
173 | - if (ziyanStat != ZIYAN_ERROR_SYSTEM_MODULE_CODE_SUCCESS) { | ||
174 | - USER_LOG_ERROR("Add default widget ui config error, stat = 0x%08llX", ziyanStat); | ||
175 | - return ziyanStat; | ||
176 | - } | 188 | + // if (s_isWidgetFileDirPathConfigured == true) { |
189 | + // snprintf(tempPath, WIDGET_DIR_PATH_LEN_MAX, "%swidget_file/en_big_screen", s_widgetFileDirPath); | ||
190 | + // } else { | ||
191 | + // snprintf(tempPath, WIDGET_DIR_PATH_LEN_MAX, "%swidget_file/en_big_screen", curFileDirPath); | ||
192 | + // } | ||
193 | + | ||
194 | + // //set default ui config path | ||
195 | + // ziyanStat = ZiyanWidget_RegDefaultUiConfigByDirPath(tempPath); | ||
196 | + // if (ziyanStat != ZIYAN_ERROR_SYSTEM_MODULE_CODE_SUCCESS) { | ||
197 | + // USER_LOG_ERROR("Add default widget ui config error, stat = 0x%08llX", ziyanStat); | ||
198 | + // return ziyanStat; | ||
199 | + // } | ||
200 | + | ||
201 | + // //set ui config for English language | ||
202 | + // ziyanStat = ZiyanWidget_RegUiConfigByDirPath(ZIYAN_MOBILE_APP_LANGUAGE_ENGLISH, | ||
203 | + // ZIYAN_MOBILE_APP_SCREEN_TYPE_BIG_SCREEN, | ||
204 | + // tempPath); | ||
205 | + // if (ziyanStat != ZIYAN_ERROR_SYSTEM_MODULE_CODE_SUCCESS) { | ||
206 | + // USER_LOG_ERROR("Add widget ui config error, stat = 0x%08llX", ziyanStat); | ||
207 | + // return ziyanStat; | ||
208 | + // } | ||
209 | + | ||
210 | + // //set ui config for Chinese language | ||
211 | + // if (s_isWidgetFileDirPathConfigured == true) { | ||
212 | + // snprintf(tempPath, WIDGET_DIR_PATH_LEN_MAX, "%swidget_file/cn_big_screen", s_widgetFileDirPath); | ||
213 | + // } else { | ||
214 | + // snprintf(tempPath, WIDGET_DIR_PATH_LEN_MAX, "%swidget_file/cn_big_screen", curFileDirPath); | ||
215 | + // } | ||
216 | + | ||
217 | + // ziyanStat = ZiyanWidget_RegUiConfigByDirPath(ZIYAN_MOBILE_APP_LANGUAGE_CHINESE, | ||
218 | + // ZIYAN_MOBILE_APP_SCREEN_TYPE_BIG_SCREEN, | ||
219 | + // tempPath); | ||
220 | + // if (ziyanStat != ZIYAN_ERROR_SYSTEM_MODULE_CODE_SUCCESS) { | ||
221 | + // USER_LOG_ERROR("Add widget ui config error, stat = 0x%08llX", ziyanStat); | ||
222 | + // return ziyanStat; | ||
223 | + // } | ||
224 | + | ||
225 | + // //Step 2 : Set UI Config (RTOS environment) | ||
226 | + // T_ZiyanWidgetBinaryArrayConfig enWidgetBinaryArrayConfig = { | ||
227 | + // .binaryArrayCount = g_EnBinaryArrayCount, | ||
228 | + // .fileBinaryArrayList = g_EnFileBinaryArrayList | ||
229 | + // }; | ||
230 | + | ||
231 | + // //set default ui config | ||
232 | + // ziyanStat = ZiyanWidget_RegDefaultUiConfigByBinaryArray(&enWidgetBinaryArrayConfig); | ||
233 | + // if (ziyanStat != ZIYAN_ERROR_SYSTEM_MODULE_CODE_SUCCESS) { | ||
234 | + // USER_LOG_ERROR("Add default widget ui config error, stat = 0x%08llX", ziyanStat); | ||
235 | + // return ziyanStat; | ||
236 | + // } | ||
237 | + | ||
238 | + | ||
239 | + //设置读取ui读取的文件路径 | ||
240 | + memset(curFileDirPath, 0, sizeof(curFileDirPath)); | ||
241 | + //暂时没有海外版语言的说法 | ||
242 | + snprintf(curFileDirPath, WIDGET_DIR_PATH_LEN_MAX, "%s/cn", WIDGET_FILE_DIR); | ||
243 | + | ||
244 | + /********************************* | ||
245 | + * 加载英文控件 | ||
246 | + * *******************************/ | ||
247 | + memset(tempPath, 0, sizeof(tempPath)); | ||
248 | + snprintf(tempPath, WIDGET_DIR_PATH_LEN_MAX, "%swidget_file/en_big_screen", curFileDirPath); | ||
249 | + USER_LOG_INFO("加载en控件%s\n",tempPath); | ||
177 | 250 | ||
178 | //set ui config for English language | 251 | //set ui config for English language |
179 | ziyanStat = ZiyanWidget_RegUiConfigByDirPath(ZIYAN_MOBILE_APP_LANGUAGE_ENGLISH, | 252 | ziyanStat = ZiyanWidget_RegUiConfigByDirPath(ZIYAN_MOBILE_APP_LANGUAGE_ENGLISH, |
@@ -184,13 +257,15 @@ T_ZiyanReturnCode ZiyanTest_WidgetStartService(void) | @@ -184,13 +257,15 @@ T_ZiyanReturnCode ZiyanTest_WidgetStartService(void) | ||
184 | return ziyanStat; | 257 | return ziyanStat; |
185 | } | 258 | } |
186 | 259 | ||
187 | - //set ui config for Chinese language | ||
188 | - if (s_isWidgetFileDirPathConfigured == true) { | ||
189 | - snprintf(tempPath, WIDGET_DIR_PATH_LEN_MAX, "%swidget_file/cn_big_screen", s_widgetFileDirPath); | ||
190 | - } else { | 260 | + |
261 | + /********************************* | ||
262 | + * 加载中文控件 | ||
263 | + * *******************************/ | ||
264 | + memset(tempPath, 0, sizeof(tempPath)); | ||
191 | snprintf(tempPath, WIDGET_DIR_PATH_LEN_MAX, "%swidget_file/cn_big_screen", curFileDirPath); | 265 | snprintf(tempPath, WIDGET_DIR_PATH_LEN_MAX, "%swidget_file/cn_big_screen", curFileDirPath); |
192 | - } | 266 | + USER_LOG_INFO("加载cn控件%s\n",tempPath); |
193 | 267 | ||
268 | + //set ui config for Chinese language | ||
194 | ziyanStat = ZiyanWidget_RegUiConfigByDirPath(ZIYAN_MOBILE_APP_LANGUAGE_CHINESE, | 269 | ziyanStat = ZiyanWidget_RegUiConfigByDirPath(ZIYAN_MOBILE_APP_LANGUAGE_CHINESE, |
195 | ZIYAN_MOBILE_APP_SCREEN_TYPE_BIG_SCREEN, | 270 | ZIYAN_MOBILE_APP_SCREEN_TYPE_BIG_SCREEN, |
196 | tempPath); | 271 | tempPath); |
@@ -198,26 +273,15 @@ T_ZiyanReturnCode ZiyanTest_WidgetStartService(void) | @@ -198,26 +273,15 @@ T_ZiyanReturnCode ZiyanTest_WidgetStartService(void) | ||
198 | USER_LOG_ERROR("Add widget ui config error, stat = 0x%08llX", ziyanStat); | 273 | USER_LOG_ERROR("Add widget ui config error, stat = 0x%08llX", ziyanStat); |
199 | return ziyanStat; | 274 | return ziyanStat; |
200 | } | 275 | } |
201 | -#else | ||
202 | - //Step 2 : Set UI Config (RTOS environment) | ||
203 | - T_ZiyanWidgetBinaryArrayConfig enWidgetBinaryArrayConfig = { | ||
204 | - .binaryArrayCount = g_EnBinaryArrayCount, | ||
205 | - .fileBinaryArrayList = g_EnFileBinaryArrayList | ||
206 | - }; | ||
207 | - | ||
208 | - //set default ui config | ||
209 | - ziyanStat = ZiyanWidget_RegDefaultUiConfigByBinaryArray(&enWidgetBinaryArrayConfig); | ||
210 | - if (ziyanStat != ZIYAN_ERROR_SYSTEM_MODULE_CODE_SUCCESS) { | ||
211 | - USER_LOG_ERROR("Add default widget ui config error, stat = 0x%08llX", ziyanStat); | ||
212 | - return ziyanStat; | ||
213 | - } | ||
214 | -#endif | 276 | + |
277 | + | ||
215 | //Step 3 : Set widget handler list | 278 | //Step 3 : Set widget handler list |
216 | ziyanStat = ZiyanWidget_RegHandlerList(s_widgetHandlerList, s_widgetHandlerListCount); | 279 | ziyanStat = ZiyanWidget_RegHandlerList(s_widgetHandlerList, s_widgetHandlerListCount); |
217 | if (ziyanStat != ZIYAN_ERROR_SYSTEM_MODULE_CODE_SUCCESS) { | 280 | if (ziyanStat != ZIYAN_ERROR_SYSTEM_MODULE_CODE_SUCCESS) { |
218 | USER_LOG_ERROR("Set widget handler list error, stat = 0x%08llX", ziyanStat); | 281 | USER_LOG_ERROR("Set widget handler list error, stat = 0x%08llX", ziyanStat); |
219 | return ziyanStat; | 282 | return ziyanStat; |
220 | } | 283 | } |
284 | + USER_LOG_INFO("Step 3 : Set widget handler list"); | ||
221 | 285 | ||
222 | //Step 4 : Run widget api sample task | 286 | //Step 4 : Run widget api sample task |
223 | if (osalHandler->TaskCreate("user_widget_task", ZiyanTest_WidgetTask, WIDGET_TASK_STACK_SIZE, NULL, | 287 | if (osalHandler->TaskCreate("user_widget_task", ZiyanTest_WidgetTask, WIDGET_TASK_STACK_SIZE, NULL, |
@@ -225,6 +289,7 @@ T_ZiyanReturnCode ZiyanTest_WidgetStartService(void) | @@ -225,6 +289,7 @@ T_ZiyanReturnCode ZiyanTest_WidgetStartService(void) | ||
225 | USER_LOG_ERROR("Ziyan widget test task create error."); | 289 | USER_LOG_ERROR("Ziyan widget test task create error."); |
226 | return ZIYAN_ERROR_SYSTEM_MODULE_CODE_UNKNOWN; | 290 | return ZIYAN_ERROR_SYSTEM_MODULE_CODE_UNKNOWN; |
227 | } | 291 | } |
292 | + USER_LOG_INFO("Step 4 : Run widget api sample task"); | ||
228 | 293 | ||
229 | return ZIYAN_ERROR_SYSTEM_MODULE_CODE_SUCCESS; | 294 | return ZIYAN_ERROR_SYSTEM_MODULE_CODE_SUCCESS; |
230 | } | 295 | } |
@@ -266,16 +331,18 @@ static void *ZiyanTest_WidgetTask(void *arg) | @@ -266,16 +331,18 @@ static void *ZiyanTest_WidgetTask(void *arg) | ||
266 | USER_LOG_ERROR("Get system time ms error, stat = 0x%08llX", ziyanStat); | 331 | USER_LOG_ERROR("Get system time ms error, stat = 0x%08llX", ziyanStat); |
267 | } | 332 | } |
268 | 333 | ||
269 | -#ifndef USER_FIRMWARE_MAJOR_VERSION | 334 | +// #ifndef USER_FIRMWARE_MAJOR_VERSION |
335 | +// snprintf(message, ZIYAN_WIDGET_FLOATING_WINDOW_MSG_MAX_LEN, "System time : %u ms", sysTimeMs); | ||
336 | +// #else | ||
337 | +// snprintf(message, ZIYAN_WIDGET_FLOATING_WINDOW_MSG_MAX_LEN, | ||
338 | +// "System time : %u ms\r\nVersion: v%02d.%02d.%02d.%02d\r\nBuild time: %s %s", sysTimeMs, | ||
339 | +// USER_FIRMWARE_MAJOR_VERSION, USER_FIRMWARE_MINOR_VERSION, | ||
340 | +// USER_FIRMWARE_MODIFY_VERSION, USER_FIRMWARE_DEBUG_VERSION, | ||
341 | +// __DATE__, __TIME__); | ||
342 | +// #endif | ||
343 | + | ||
344 | + //悬浮窗打印测试信息 | ||
270 | snprintf(message, ZIYAN_WIDGET_FLOATING_WINDOW_MSG_MAX_LEN, "System time : %u ms", sysTimeMs); | 345 | snprintf(message, ZIYAN_WIDGET_FLOATING_WINDOW_MSG_MAX_LEN, "System time : %u ms", sysTimeMs); |
271 | -#else | ||
272 | - snprintf(message, ZIYAN_WIDGET_FLOATING_WINDOW_MSG_MAX_LEN, | ||
273 | - "System time : %u ms\r\nVersion: v%02d.%02d.%02d.%02d\r\nBuild time: %s %s", sysTimeMs, | ||
274 | - USER_FIRMWARE_MAJOR_VERSION, USER_FIRMWARE_MINOR_VERSION, | ||
275 | - USER_FIRMWARE_MODIFY_VERSION, USER_FIRMWARE_DEBUG_VERSION, | ||
276 | - __DATE__, __TIME__); | ||
277 | -#endif | ||
278 | - | ||
279 | 346 | ||
280 | ziyanStat = ZiyanWidgetFloatingWindow_ShowMessage(message); | 347 | ziyanStat = ZiyanWidgetFloatingWindow_ShowMessage(message); |
281 | if (ziyanStat != ZIYAN_ERROR_SYSTEM_MODULE_CODE_SUCCESS) { | 348 | if (ziyanStat != ZIYAN_ERROR_SYSTEM_MODULE_CODE_SUCCESS) { |
@@ -290,8 +357,241 @@ static void *ZiyanTest_WidgetTask(void *arg) | @@ -290,8 +357,241 @@ static void *ZiyanTest_WidgetTask(void *arg) | ||
290 | #pragma GCC diagnostic pop | 357 | #pragma GCC diagnostic pop |
291 | #endif | 358 | #endif |
292 | 359 | ||
293 | -#include <stdio.h> | ||
294 | -#include <stdlib.h> | 360 | +static T_JZsdkReturnCode Megphone_Widget(unsigned int index, unsigned int value) |
361 | +{ | ||
362 | +// #ifdef MEGAPHONE_CONFIG_STATUS_ON | ||
363 | +// switch(index){ | ||
364 | +// //喊话器部分 | ||
365 | +// case 0://上一曲 | ||
366 | +// if(value==1) | ||
367 | +// { | ||
368 | +// //JZsdk_Psdk_UI_io_LastSong(1); | ||
369 | +// JZSDK_WidgetMgMT_ConrtrolInputTask(JZSDK_WIDGET_LASTSONG, 0); | ||
370 | +// } | ||
371 | +// break; | ||
372 | +// case 1://下一曲 | ||
373 | +// { | ||
374 | +// if(value==1) | ||
375 | +// { | ||
376 | + | ||
377 | +// //JZsdk_Psdk_UI_io_NextSong(1); | ||
378 | +// JZSDK_WidgetMgMT_ConrtrolInputTask(JZSDK_WIDGET_NEXTSONG, 0); | ||
379 | +// } | ||
380 | +// break; | ||
381 | +// } | ||
382 | +// case 2: // 播放\暂停 value为1 是三角控件 暂停 所以要去取反 | ||
383 | +// { | ||
384 | +// value = !value; | ||
385 | +// JZSDK_WidgetMgMT_ConrtrolInputTask(JZSDK_WIDGET_PLAYANDSTOP, value); | ||
386 | + | ||
387 | +// break; | ||
388 | +// } | ||
389 | + | ||
390 | +// case 3://内显示音量 scale | ||
391 | +// { | ||
392 | +// JZsdk_Psdk_UI_io_LumenAndVolume_PowerLimitation(1, value); | ||
393 | +// JZsdk_Psdk_UI_io_SetVolume(1,value); | ||
394 | +// break; | ||
395 | +// } | ||
396 | +// case 4://外显示音量 scale | ||
397 | +// { | ||
398 | +// JZsdk_Psdk_UI_io_LumenAndVolume_PowerLimitation(1, value); | ||
399 | +// JZsdk_Psdk_UI_io_SetVolume(1,value); | ||
400 | +// break; | ||
401 | +// } | ||
402 | +// case 5://TTS语速 list | ||
403 | +// { | ||
404 | +// int speed = JZsdk_Psdk_UI_io_GetTTSSpeed_ByValue(value); | ||
405 | +// JZsdk_Psdk_UI_io_Set_TTS_speed(1,speed); | ||
406 | +// break; | ||
407 | +// } | ||
408 | +// case 6://TTS音色 list | ||
409 | +// { | ||
410 | +// int tone = JZsdk_Psdk_UI_io_GetTTSTone_ByValue(value); | ||
411 | +// JZsdk_Psdk_UI_io_Set_TTS_tone(1,tone); | ||
412 | +// break; | ||
413 | +// } | ||
414 | +// case 7://TTS追加音色 list | ||
415 | +// JZsdk_Psdk_UI_io_AppendTone(1,value); | ||
416 | +// break; | ||
417 | +// case 8: //switch 循环 循环是1 | ||
418 | +// JZsdk_Psdk_UI_io_SetAudioPlayLoop(1, value); | ||
419 | +// break; | ||
420 | +// case 9: //喊话模式切换 | ||
421 | +// { | ||
422 | +// //切换前关闭所有实时喊话 | ||
423 | +// //Speaker_Set_SpeakerOFF(); | ||
424 | + | ||
425 | +// //如果喊话器控件正在使用,禁止修改功能 | ||
426 | +// if (SpeakerWidgetUseLock == JZ_FLAGCODE_ON) | ||
427 | +// { | ||
428 | +// set_wideget_value(9,Opus_PlayMode); | ||
429 | +// break; | ||
430 | +// } | ||
431 | + | ||
432 | +// //切换前喊话器关闭所有语音功能 | ||
433 | +// JZsdk_Psdk_UI_io_StopPlayAudio(); | ||
434 | + | ||
435 | +// switch(value){ | ||
436 | +// case 0: | ||
437 | +// Widget_RealTimeOpusFlag = JZ_FLAGCODE_OFF; | ||
438 | +// Opus_PlayMode = 0; | ||
439 | +// break; | ||
440 | +// case 1: | ||
441 | +// Widget_RealTimeOpusFlag = JZ_FLAGCODE_ON; | ||
442 | +// Opus_PlayMode = 1; | ||
443 | +// break; | ||
444 | +// default: | ||
445 | +// Widget_RealTimeOpusFlag = JZ_FLAGCODE_OFF; | ||
446 | +// Opus_PlayMode = 0; | ||
447 | +// break; | ||
448 | +// } | ||
449 | + | ||
450 | +// break; | ||
451 | +// } | ||
452 | +// //探照灯部分 | ||
453 | +// case 10://探照灯 内显示亮度 | ||
454 | +// { | ||
455 | +// JZsdk_Psdk_UI_io_LumenAndVolume_PowerLimitation(0, value); | ||
456 | +// JZsdk_Psdk_UI_io_Set_SearchLightLumen(1,value); | ||
457 | +// break; | ||
458 | +// } | ||
459 | +// case 11://探照灯 外显示亮度 | ||
460 | +// { | ||
461 | +// JZsdk_Psdk_UI_io_LumenAndVolume_PowerLimitation(0, value); | ||
462 | +// JZsdk_Psdk_UI_io_Set_SearchLightLumen(1,value); | ||
463 | +// break; | ||
464 | +// } | ||
465 | +// case 12: //探照灯模式 | ||
466 | +// { | ||
467 | +// JZsdk_Psdk_UI_io_Set_SearchLightMode(1,value); | ||
468 | +// break; | ||
469 | +// } | ||
470 | + | ||
471 | +// case 13: //探照灯 爆闪开关 已合并至12 | ||
472 | +// { | ||
473 | +// //JZsdk_Psdk_UI_io_Set_SearchLightBrustMode(1,value); | ||
474 | +// break; | ||
475 | +// } | ||
476 | +// case 14://探照灯 爆闪频率 | ||
477 | +// { | ||
478 | +// JZsdk_Psdk_UI_io_Set_SearchLightFrequency(1,value); | ||
479 | +// break; | ||
480 | +// } | ||
481 | +// //侧面激光部分 | ||
482 | +// case 15://激光开关 | ||
483 | +// { | ||
484 | +// JZSDK_WidgetMgMT_ConrtrolInputTask(JZSDK_WIDGET_SIDE_LASER_MODE, value); | ||
485 | +// break; | ||
486 | +// } | ||
487 | +// //警灯部分 | ||
488 | +// case 16://警灯模式 | ||
489 | +// { | ||
490 | +// JZsdk_Psdk_UI_io_Set_WarningLightMode(1,value); | ||
491 | +// break; | ||
492 | +// } | ||
493 | +// case 17://警灯颜色1 | ||
494 | +// { | ||
495 | +// JZsdk_Psdk_UI_io_Set_WarningLightFirstColor(1,(value+1)); | ||
496 | +// break; | ||
497 | +// } | ||
498 | +// case 18://警灯颜色2 | ||
499 | +// { | ||
500 | +// JZsdk_Psdk_UI_io_Set_WarningLightSecondColor(1,(value+1)); | ||
501 | +// break; | ||
502 | +// } | ||
503 | +// //云台部分 | ||
504 | +// case 19://云台内部滑动条 | ||
505 | +// { | ||
506 | +// if (Get_Gimbal_linkage() == JZ_FLAGCODE_OFF) | ||
507 | +// { | ||
508 | +// JZsdk_Psdk_Ui_io_Gimbal_PitchScaleMode(value); | ||
509 | +// } | ||
510 | +// break; | ||
511 | +// } | ||
512 | +// case 20://云台外部滑动条 | ||
513 | +// { | ||
514 | +// if (Get_Gimbal_linkage() == JZ_FLAGCODE_OFF) | ||
515 | +// { | ||
516 | +// JZsdk_Psdk_Ui_io_Gimbal_PitchScaleMode(value); | ||
517 | +// } | ||
518 | +// break; | ||
519 | +// } | ||
520 | +// case 21://云台联动开关 | ||
521 | +// { | ||
522 | +// Set_Gimbal_linkage(value); | ||
523 | +// break; | ||
524 | +// } | ||
525 | +// case 22://云台向上微调 | ||
526 | +// { | ||
527 | +// if(value == 1) | ||
528 | +// { | ||
529 | +// JZsdk_Psdk_UI_io_Set_AdjustmentGimbalPitchAngle(5); | ||
530 | +// } | ||
531 | + | ||
532 | +// break; | ||
533 | +// } | ||
534 | +// case 23://云台向下微调 | ||
535 | +// { | ||
536 | +// if(value == 1) | ||
537 | +// { | ||
538 | +// JZsdk_Psdk_UI_io_Set_AdjustmentGimbalPitchAngle(-5); | ||
539 | +// } | ||
540 | +// break; | ||
541 | +// } | ||
542 | +// //系统部分 | ||
543 | +// case 24://版本信息 | ||
544 | +// { | ||
545 | +// if(value==1){ | ||
546 | +// num_flag+=1; | ||
547 | +// if(num_flag<3) | ||
548 | +// { | ||
549 | +// break; | ||
550 | +// } | ||
551 | +// if(num_flag==3) | ||
552 | +// { | ||
553 | +// printf("打开调试界面"); | ||
554 | +// break; | ||
555 | +// } | ||
556 | +// if(num_flag>3){ | ||
557 | +// num_flag=0;//重新置零 | ||
558 | +// printf("关闭调试界面"); | ||
559 | +// break; | ||
560 | +// } | ||
561 | +// } | ||
562 | +// break; | ||
563 | +// } | ||
564 | +// case 25://对外供电开关 | ||
565 | +// { | ||
566 | +// JZsdk_Psdk_UI_io_Set_OutputPowerStatus(1 ,value); | ||
567 | +// break; | ||
568 | +// } | ||
569 | +// //调试部分 | ||
570 | +// case 26://设置云台最大值 | ||
571 | +// { | ||
572 | +// if(value==1 && num_flag == 3) | ||
573 | +// { | ||
574 | +// JZsdk_Psdk_UI_io_Set_MAXGimbalRangen(); | ||
575 | +// } | ||
576 | +// break; | ||
577 | +// } | ||
578 | +// case 27://psdk云台最小值 | ||
579 | +// { | ||
580 | +// if(value==1 && num_flag == 3) | ||
581 | +// { | ||
582 | +// JZsdk_Psdk_UI_io_Set_MINGimbalRangen(); | ||
583 | +// } | ||
584 | +// break; | ||
585 | +// } | ||
586 | +// case 28://设置临时参数 | ||
587 | +// { | ||
588 | + | ||
589 | +// } | ||
590 | +// default: | ||
591 | +// break; | ||
592 | +// } | ||
593 | +// #endif | ||
594 | +} | ||
295 | 595 | ||
296 | static T_ZiyanReturnCode ZiyanTestWidget_SetWidgetValue(E_ZiyanWidgetType widgetType, uint32_t index, int32_t value, | 596 | static T_ZiyanReturnCode ZiyanTestWidget_SetWidgetValue(E_ZiyanWidgetType widgetType, uint32_t index, int32_t value, |
297 | void *userData) | 597 | void *userData) |
@@ -302,7 +602,8 @@ static T_ZiyanReturnCode ZiyanTestWidget_SetWidgetValue(E_ZiyanWidgetType widget | @@ -302,7 +602,8 @@ static T_ZiyanReturnCode ZiyanTestWidget_SetWidgetValue(E_ZiyanWidgetType widget | ||
302 | s_widgetTypeNameArray[widgetType], index, value); | 602 | s_widgetTypeNameArray[widgetType], index, value); |
303 | s_widgetValueList[index] = value; | 603 | s_widgetValueList[index] = value; |
304 | 604 | ||
305 | - JZSDK_LOG_INFO("Set widget value, widgetType = %s, widgetIndex = %d ,widgetValue = %d"); | 605 | + //放入控件管理 |
606 | + Megphone_Widget(index, value); | ||
306 | 607 | ||
307 | // if(index == 0){ | 608 | // if(index == 0){ |
308 | // uint8_t brightness = value; | 609 | // uint8_t brightness = value; |
@@ -411,3 +712,16 @@ static T_ZiyanReturnCode ZiyanTestWidget_GetWidgetValue(E_ZiyanWidgetType widget | @@ -411,3 +712,16 @@ static T_ZiyanReturnCode ZiyanTestWidget_GetWidgetValue(E_ZiyanWidgetType widget | ||
411 | } | 712 | } |
412 | 713 | ||
413 | /****************** (C) COPYRIGHT ZIYAN Innovations *****END OF FILE****/ | 714 | /****************** (C) COPYRIGHT ZIYAN Innovations *****END OF FILE****/ |
715 | + | ||
716 | +T_JZsdkReturnCode set_wideget_value(int index,int value) | ||
717 | +{ | ||
718 | + s_widgetValueList[index]=value; | ||
719 | + | ||
720 | + //printf("\n修改%d控件,%d\n\n",index,value); | ||
721 | +} | ||
722 | + | ||
723 | + //获取播放模式 int Opus_PlayMode=0;//0录音喊话 1实时喊话 | ||
724 | +int Get_Opus_PlayMode() | ||
725 | +{ | ||
726 | + return Opus_PlayMode; | ||
727 | +} |
@@ -29,6 +29,7 @@ | @@ -29,6 +29,7 @@ | ||
29 | 29 | ||
30 | /* Includes ------------------------------------------------------------------*/ | 30 | /* Includes ------------------------------------------------------------------*/ |
31 | #include <ziyan_typedef.h> | 31 | #include <ziyan_typedef.h> |
32 | +#include "JZsdk_Base/JZsdk_Code/JZsdk_Code.h" | ||
32 | 33 | ||
33 | #ifdef __cplusplus | 34 | #ifdef __cplusplus |
34 | extern "C" { | 35 | extern "C" { |
@@ -43,6 +44,10 @@ T_ZiyanReturnCode ZiyanTest_WidgetStartService(void); | @@ -43,6 +44,10 @@ T_ZiyanReturnCode ZiyanTest_WidgetStartService(void); | ||
43 | T_ZiyanReturnCode ZiyanTest_WidgetSetConfigFilePath(const char *path); | 44 | T_ZiyanReturnCode ZiyanTest_WidgetSetConfigFilePath(const char *path); |
44 | __attribute__((weak)) void ZiyanTest_WidgetLogAppend(const char *fmt, ...); | 45 | __attribute__((weak)) void ZiyanTest_WidgetLogAppend(const char *fmt, ...); |
45 | 46 | ||
47 | +T_JZsdkReturnCode set_wideget_value(int index,int value); | ||
48 | +int Get_Opus_PlayMode(); | ||
49 | + | ||
50 | + | ||
46 | #ifdef __cplusplus | 51 | #ifdef __cplusplus |
47 | } | 52 | } |
48 | #endif | 53 | #endif |
@@ -41,18 +41,11 @@ | @@ -41,18 +41,11 @@ | ||
41 | 41 | ||
42 | #endif | 42 | #endif |
43 | 43 | ||
44 | -#ifdef ALSA_INSTALLED | ||
45 | - | ||
46 | -#include <alsa/asoundlib.h> | ||
47 | - | ||
48 | -#endif | ||
49 | - | ||
50 | /* Private constants ---------------------------------------------------------*/ | 44 | /* Private constants ---------------------------------------------------------*/ |
51 | #define WIDGET_SPEAKER_TASK_STACK_SIZE (2048) | 45 | #define WIDGET_SPEAKER_TASK_STACK_SIZE (2048) |
52 | 46 | ||
53 | /*! Attention: replace your audio device name here. */ | 47 | /*! Attention: replace your audio device name here. */ |
54 | -// #define WIDGET_SPEAKER_USB_AUDIO_DEVICE_NAME "alsa_output.usb-C-Media_Electronics_Inc._USB_Audio_Device-00.analog-stereo" | ||
55 | -#define WIDGET_SPEAKER_USB_AUDIO_DEVICE_NAME "alsa_card.usb-GeneralPlus_USB_Audio_Device-00" | 48 | +#define WIDGET_SPEAKER_USB_AUDIO_DEVICE_NAME "alsa_output.usb-C-Media_Electronics_Inc._USB_Audio_Device-00.analog-stereo" |
56 | 49 | ||
57 | #define WIDGET_SPEAKER_AUDIO_OPUS_FILE_NAME "test_audio.opus" | 50 | #define WIDGET_SPEAKER_AUDIO_OPUS_FILE_NAME "test_audio.opus" |
58 | #define WIDGET_SPEAKER_AUDIO_PCM_FILE_NAME "test_audio.pcm" | 51 | #define WIDGET_SPEAKER_AUDIO_PCM_FILE_NAME "test_audio.pcm" |
@@ -87,12 +80,6 @@ static FILE *s_ttsFile = NULL; | @@ -87,12 +80,6 @@ static FILE *s_ttsFile = NULL; | ||
87 | static bool s_isDecodeFinished = true; | 80 | static bool s_isDecodeFinished = true; |
88 | static uint16_t s_decodeBitrate = 0; | 81 | static uint16_t s_decodeBitrate = 0; |
89 | 82 | ||
90 | -#ifdef ALSA_INSTALLED | ||
91 | - snd_pcm_t *pcm_handle = NULL; | ||
92 | - snd_pcm_hw_params_t *hw_params = NULL; | ||
93 | - snd_pcm_sw_params_t *sw_params = NULL; | ||
94 | -#endif | ||
95 | - | ||
96 | /* Private functions declaration ---------------------------------------------*/ | 83 | /* Private functions declaration ---------------------------------------------*/ |
97 | static void SetSpeakerState(E_ZiyanWidgetSpeakerState speakerState); | 84 | static void SetSpeakerState(E_ZiyanWidgetSpeakerState speakerState); |
98 | static T_ZiyanReturnCode GetSpeakerState(T_ZiyanWidgetSpeakerState *speakerState); | 85 | static T_ZiyanReturnCode GetSpeakerState(T_ZiyanWidgetSpeakerState *speakerState); |
@@ -176,81 +163,6 @@ T_ZiyanReturnCode ZiyanTest_WidgetSpeakerStartService(void) | @@ -176,81 +163,6 @@ T_ZiyanReturnCode ZiyanTest_WidgetSpeakerStartService(void) | ||
176 | return ZIYAN_ERROR_SYSTEM_MODULE_CODE_SUCCESS; | 163 | return ZIYAN_ERROR_SYSTEM_MODULE_CODE_SUCCESS; |
177 | } | 164 | } |
178 | 165 | ||
179 | -#ifdef ALSA_INSTALLED | ||
180 | -T_ZiyanReturnCode ZiyanTest_AsoundInit() | ||
181 | -{ | ||
182 | - // 打开默认音频设备 | ||
183 | - if (snd_pcm_open(&pcm_handle, "default", SND_PCM_STREAM_PLAYBACK, 0) < 0) { | ||
184 | - fprintf(stderr, "无法打开音频设备\n"); | ||
185 | - return 1; | ||
186 | - } | ||
187 | - | ||
188 | - // 分配硬件参数结构体 | ||
189 | - snd_pcm_hw_params_alloca(&hw_params); | ||
190 | - snd_pcm_hw_params_any(pcm_handle, hw_params); | ||
191 | - | ||
192 | - // 设置硬件参数 | ||
193 | - snd_pcm_hw_params_set_access(pcm_handle, hw_params, SND_PCM_ACCESS_RW_INTERLEAVED); | ||
194 | - snd_pcm_hw_params_set_format(pcm_handle, hw_params, SND_PCM_FORMAT_S16_LE); // 16-bit little-endian | ||
195 | - snd_pcm_hw_params_set_rate(pcm_handle, hw_params, WIDGET_SPEAKER_AUDIO_OPUS_SAMPLE_RATE, 0); // 设置采样率为 16kHz | ||
196 | - snd_pcm_hw_params_set_channels(pcm_handle, hw_params, WIDGET_SPEAKER_AUDIO_OPUS_CHANNELS); // 设置单声道 | ||
197 | - snd_pcm_hw_params_set_buffer_size(pcm_handle, hw_params, 16000 * 8); | ||
198 | - snd_pcm_hw_params_set_period_size(pcm_handle, hw_params, 1280, 0); | ||
199 | - | ||
200 | - // 应用硬件参数 | ||
201 | - if (snd_pcm_hw_params(pcm_handle, hw_params) < 0) { | ||
202 | - fprintf(stderr, "无法设置硬件参数\n"); | ||
203 | - return 1; | ||
204 | - } | ||
205 | - | ||
206 | - // 设置软件参数 | ||
207 | - snd_pcm_sw_params_alloca(&sw_params); | ||
208 | - snd_pcm_sw_params_current(pcm_handle, sw_params); | ||
209 | - snd_pcm_sw_params_set_avail_min(pcm_handle, sw_params, 1280); | ||
210 | - snd_pcm_sw_params_set_start_threshold(pcm_handle, sw_params, 0); | ||
211 | - | ||
212 | - // 应用软件参数 | ||
213 | - if (snd_pcm_sw_params(pcm_handle, sw_params) < 0) { | ||
214 | - fprintf(stderr, "无法设置软件参数\n"); | ||
215 | - return 1; | ||
216 | - } | ||
217 | - | ||
218 | - // snd_pcm_prepare(pcm_handle); | ||
219 | - | ||
220 | - return 0; | ||
221 | -} | ||
222 | -#endif | ||
223 | - | ||
224 | - | ||
225 | -T_ZiyanReturnCode ZiyanTest_PcmPlay(uint8_t* pcm_data, uint64_t size) | ||
226 | -{ | ||
227 | -#ifdef ALSA_INSTALLED | ||
228 | - if((pcm_handle != NULL)){ | ||
229 | - int err = snd_pcm_writei(pcm_handle, pcm_data, size); | ||
230 | - | ||
231 | - snd_pcm_sframes_t avail = snd_pcm_avail(pcm_handle); | ||
232 | - if((16000 * 8 - avail) <= 16000){ | ||
233 | - | ||
234 | - uint8_t pcm_empty[16000]; | ||
235 | - memset(pcm_empty, 0, sizeof(pcm_empty)); | ||
236 | - snd_pcm_writei(pcm_handle, pcm_empty, sizeof(pcm_empty)); | ||
237 | - } | ||
238 | - // snd_pcm_sframes_t avail = 0; | ||
239 | - printf("play pcm %d : %ld : %ld\n", err, size, avail); | ||
240 | - | ||
241 | - // 错误处理 | ||
242 | - if (err == -EPIPE) { | ||
243 | - fprintf(stderr, "发生缓冲区溢出错误!\n"); | ||
244 | - snd_pcm_prepare(pcm_handle); | ||
245 | - } else if (err < 0) { | ||
246 | - fprintf(stderr, "播放失败: %s\n", snd_strerror(err)); | ||
247 | - } else if (err < 640) { | ||
248 | - fprintf(stderr, "警告: 写入的帧数少于预期\n"); | ||
249 | - } | ||
250 | - } | ||
251 | -#endif | ||
252 | -} | ||
253 | - | ||
254 | /* Private functions definition-----------------------------------------------*/ | 166 | /* Private functions definition-----------------------------------------------*/ |
255 | #ifdef SYSTEM_ARCH_LINUX | 167 | #ifdef SYSTEM_ARCH_LINUX |
256 | 168 | ||
@@ -322,7 +234,7 @@ static T_ZiyanReturnCode ZiyanTest_DecodeAudioData(void) | @@ -322,7 +234,7 @@ static T_ZiyanReturnCode ZiyanTest_DecodeAudioData(void) | ||
322 | goto close_fin; | 234 | goto close_fin; |
323 | } | 235 | } |
324 | 236 | ||
325 | - fout = fopen(WIDGET_SPEAKER_AUDIO_PCM_FILE_NAME, "a+"); | 237 | + fout = fopen(WIDGET_SPEAKER_AUDIO_PCM_FILE_NAME, "w"); |
326 | if (fout == NULL) { | 238 | if (fout == NULL) { |
327 | fprintf(stderr, "failed to open output file: %s\n", strerror(errno)); | 239 | fprintf(stderr, "failed to open output file: %s\n", strerror(errno)); |
328 | goto close_fin; | 240 | goto close_fin; |
@@ -330,12 +242,14 @@ static T_ZiyanReturnCode ZiyanTest_DecodeAudioData(void) | @@ -330,12 +242,14 @@ static T_ZiyanReturnCode ZiyanTest_DecodeAudioData(void) | ||
330 | 242 | ||
331 | while (1) { | 243 | while (1) { |
332 | int i; | 244 | int i; |
333 | - unsigned char pcm_bytes[WIDGET_SPEAKER_AUDIO_OPUS_MAX_FRAME_SIZE * WIDGET_SPEAKER_AUDIO_OPUS_CHANNELS * 4] = {0}; | 245 | + unsigned char pcm_bytes[WIDGET_SPEAKER_AUDIO_OPUS_MAX_FRAME_SIZE * WIDGET_SPEAKER_AUDIO_OPUS_CHANNELS * 2]; |
334 | int frame_size; | 246 | int frame_size; |
335 | 247 | ||
336 | /* Read a 16 bits/sample audio frame. */ | 248 | /* Read a 16 bits/sample audio frame. */ |
337 | nbBytes = fread(cbits, 1, s_decodeBitrate / WIDGET_SPEAKER_AUDIO_OPUS_DECODE_BITRATE_8KBPS * | 249 | nbBytes = fread(cbits, 1, s_decodeBitrate / WIDGET_SPEAKER_AUDIO_OPUS_DECODE_BITRATE_8KBPS * |
338 | - WIDGET_SPEAKER_AUDIO_OPUS_DECODE_FRAME_SIZE_8KBPS * 8, fin); | 250 | + WIDGET_SPEAKER_AUDIO_OPUS_DECODE_FRAME_SIZE_8KBPS, fin); |
251 | + if (feof(fin)) | ||
252 | + break; | ||
339 | 253 | ||
340 | /* Decode the data. In this example, frame_size will be constant because | 254 | /* Decode the data. In this example, frame_size will be constant because |
341 | the encoder is using a constant frame size. However, that may not | 255 | the encoder is using a constant frame size. However, that may not |
@@ -347,6 +261,7 @@ static T_ZiyanReturnCode ZiyanTest_DecodeAudioData(void) | @@ -347,6 +261,7 @@ static T_ZiyanReturnCode ZiyanTest_DecodeAudioData(void) | ||
347 | goto close_fout; | 261 | goto close_fout; |
348 | } | 262 | } |
349 | 263 | ||
264 | + USER_LOG_DEBUG("decode data to file: %d\r\n", frame_size * WIDGET_SPEAKER_AUDIO_OPUS_CHANNELS); | ||
350 | /* Convert to little-endian ordering. */ | 265 | /* Convert to little-endian ordering. */ |
351 | for (i = 0; i < WIDGET_SPEAKER_AUDIO_OPUS_CHANNELS * frame_size; i++) { | 266 | for (i = 0; i < WIDGET_SPEAKER_AUDIO_OPUS_CHANNELS * frame_size; i++) { |
352 | pcm_bytes[2 * i] = out[i] & 0xFF; | 267 | pcm_bytes[2 * i] = out[i] & 0xFF; |
@@ -354,12 +269,6 @@ static T_ZiyanReturnCode ZiyanTest_DecodeAudioData(void) | @@ -354,12 +269,6 @@ static T_ZiyanReturnCode ZiyanTest_DecodeAudioData(void) | ||
354 | } | 269 | } |
355 | /* Write the decoded audio to file. */ | 270 | /* Write the decoded audio to file. */ |
356 | fwrite(pcm_bytes, sizeof(short), frame_size * WIDGET_SPEAKER_AUDIO_OPUS_CHANNELS, fout); | 271 | fwrite(pcm_bytes, sizeof(short), frame_size * WIDGET_SPEAKER_AUDIO_OPUS_CHANNELS, fout); |
357 | -#ifdef ALSA_INSTALLED | ||
358 | - ZiyanTest_PcmPlay(pcm_bytes, frame_size * WIDGET_SPEAKER_AUDIO_OPUS_CHANNELS); | ||
359 | -#endif | ||
360 | - | ||
361 | - if (feof(fin)) | ||
362 | - break; | ||
363 | } | 272 | } |
364 | 273 | ||
365 | USER_LOG_INFO("Decode Finished..."); | 274 | USER_LOG_INFO("Decode Finished..."); |
@@ -583,6 +492,8 @@ static T_ZiyanReturnCode SetPlayMode(E_ZiyanWidgetSpeakerPlayMode playMode) | @@ -583,6 +492,8 @@ static T_ZiyanReturnCode SetPlayMode(E_ZiyanWidgetSpeakerPlayMode playMode) | ||
583 | T_ZiyanReturnCode returnCode; | 492 | T_ZiyanReturnCode returnCode; |
584 | T_ZiyanOsalHandler *osalHandler = ZiyanPlatform_GetOsalHandler(); | 493 | T_ZiyanOsalHandler *osalHandler = ZiyanPlatform_GetOsalHandler(); |
585 | 494 | ||
495 | + printf("set play mode: %d.\n", playMode); | ||
496 | + | ||
586 | returnCode = osalHandler->MutexLock(s_speakerMutex); | 497 | returnCode = osalHandler->MutexLock(s_speakerMutex); |
587 | if (returnCode != ZIYAN_ERROR_SYSTEM_MODULE_CODE_SUCCESS) { | 498 | if (returnCode != ZIYAN_ERROR_SYSTEM_MODULE_CODE_SUCCESS) { |
588 | USER_LOG_ERROR("lock mutex error: 0x%08llX.", returnCode); | 499 | USER_LOG_ERROR("lock mutex error: 0x%08llX.", returnCode); |
@@ -708,7 +619,7 @@ static T_ZiyanReturnCode ReceiveTtsData(E_ZiyanWidgetTransmitDataEvent event, | @@ -708,7 +619,7 @@ static T_ZiyanReturnCode ReceiveTtsData(E_ZiyanWidgetTransmitDataEvent event, | ||
708 | T_ZiyanReturnCode returnCode; | 619 | T_ZiyanReturnCode returnCode; |
709 | 620 | ||
710 | if (event == ZIYAN_WIDGET_TRANSMIT_DATA_EVENT_START) { | 621 | if (event == ZIYAN_WIDGET_TRANSMIT_DATA_EVENT_START) { |
711 | - USER_LOG_INFO("Create tts file."); | 622 | + USER_LOG_WARN("Create tts file."); |
712 | #ifdef SYSTEM_ARCH_LINUX | 623 | #ifdef SYSTEM_ARCH_LINUX |
713 | s_ttsFile = fopen(WIDGET_SPEAKER_TTS_FILE_NAME, "wb"); | 624 | s_ttsFile = fopen(WIDGET_SPEAKER_TTS_FILE_NAME, "wb"); |
714 | if (s_ttsFile == NULL) { | 625 | if (s_ttsFile == NULL) { |
@@ -719,7 +630,7 @@ static T_ZiyanReturnCode ReceiveTtsData(E_ZiyanWidgetTransmitDataEvent event, | @@ -719,7 +630,7 @@ static T_ZiyanReturnCode ReceiveTtsData(E_ZiyanWidgetTransmitDataEvent event, | ||
719 | SetSpeakerState(ZIYAN_WIDGET_SPEAKER_STATE_TRANSMITTING); | 630 | SetSpeakerState(ZIYAN_WIDGET_SPEAKER_STATE_TRANSMITTING); |
720 | } | 631 | } |
721 | } else if (event == ZIYAN_WIDGET_TRANSMIT_DATA_EVENT_TRANSMIT) { | 632 | } else if (event == ZIYAN_WIDGET_TRANSMIT_DATA_EVENT_TRANSMIT) { |
722 | - USER_LOG_INFO("Transmit tts file, offset: %d, size: %d", offset, size); | 633 | + USER_LOG_WARN("Transmit tts file, offset: %d, size: %d", offset, size); |
723 | #ifdef SYSTEM_ARCH_LINUX | 634 | #ifdef SYSTEM_ARCH_LINUX |
724 | if (s_ttsFile != NULL) { | 635 | if (s_ttsFile != NULL) { |
725 | fseek(s_ttsFile, offset, SEEK_SET); | 636 | fseek(s_ttsFile, offset, SEEK_SET); |
@@ -733,7 +644,7 @@ static T_ZiyanReturnCode ReceiveTtsData(E_ZiyanWidgetTransmitDataEvent event, | @@ -733,7 +644,7 @@ static T_ZiyanReturnCode ReceiveTtsData(E_ZiyanWidgetTransmitDataEvent event, | ||
733 | SetSpeakerState(ZIYAN_WIDGET_SPEAKER_STATE_TRANSMITTING); | 644 | SetSpeakerState(ZIYAN_WIDGET_SPEAKER_STATE_TRANSMITTING); |
734 | } | 645 | } |
735 | } else if (event == ZIYAN_WIDGET_TRANSMIT_DATA_EVENT_FINISH) { | 646 | } else if (event == ZIYAN_WIDGET_TRANSMIT_DATA_EVENT_FINISH) { |
736 | - USER_LOG_INFO("Close tts file."); | 647 | + USER_LOG_WARN("Close tts file."); |
737 | #ifdef SYSTEM_ARCH_LINUX | 648 | #ifdef SYSTEM_ARCH_LINUX |
738 | if (s_ttsFile != NULL) { | 649 | if (s_ttsFile != NULL) { |
739 | fclose(s_ttsFile); | 650 | fclose(s_ttsFile); |
@@ -760,6 +671,8 @@ static T_ZiyanReturnCode ReceiveAudioData(E_ZiyanWidgetTransmitDataEvent event, | @@ -760,6 +671,8 @@ static T_ZiyanReturnCode ReceiveAudioData(E_ZiyanWidgetTransmitDataEvent event, | ||
760 | T_ZiyanReturnCode returnCode; | 671 | T_ZiyanReturnCode returnCode; |
761 | T_ZiyanWidgetTransDataContent transDataContent = {0}; | 672 | T_ZiyanWidgetTransDataContent transDataContent = {0}; |
762 | 673 | ||
674 | + USER_LOG_WARN("Vioce data %d: offset %d, size %d", event, offset, size); | ||
675 | + | ||
763 | if (event == ZIYAN_WIDGET_TRANSMIT_DATA_EVENT_START) { | 676 | if (event == ZIYAN_WIDGET_TRANSMIT_DATA_EVENT_START) { |
764 | s_isDecodeFinished = false; | 677 | s_isDecodeFinished = false; |
765 | #ifdef SYSTEM_ARCH_LINUX | 678 | #ifdef SYSTEM_ARCH_LINUX |
@@ -828,10 +741,6 @@ static void *ZiyanTest_WidgetSpeakerTask(void *arg) | @@ -828,10 +741,6 @@ static void *ZiyanTest_WidgetSpeakerTask(void *arg) | ||
828 | T_ZiyanReturnCode ziyanReturnCode; | 741 | T_ZiyanReturnCode ziyanReturnCode; |
829 | T_ZiyanOsalHandler *osalHandler = ZiyanPlatform_GetOsalHandler(); | 742 | T_ZiyanOsalHandler *osalHandler = ZiyanPlatform_GetOsalHandler(); |
830 | 743 | ||
831 | -#ifdef ALSA_INSTALLED | ||
832 | - ZiyanTest_AsoundInit(); | ||
833 | -#endif | ||
834 | - | ||
835 | USER_UTIL_UNUSED(arg); | 744 | USER_UTIL_UNUSED(arg); |
836 | 745 | ||
837 | while (1) { | 746 | while (1) { |
1 | +/** | ||
2 | + ******************************************************************** | ||
3 | + * @file test_widget_speaker.c | ||
4 | + * @brief | ||
5 | + * | ||
6 | + * @copyright (c) 2018 ZIYAN. All rights reserved. | ||
7 | + * | ||
8 | + * All information contained herein is, and remains, the property of ZIYAN. | ||
9 | + * The intellectual and technical concepts contained herein are proprietary | ||
10 | + * to ZIYAN 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 ZIYAN. | ||
15 | + * | ||
16 | + * If you receive this source code without ZIYAN’s authorization, you may not | ||
17 | + * further disseminate the information, and you must immediately remove the | ||
18 | + * source code and notify ZIYAN of its removal. ZIYAN 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 "test_widget_speaker.h" | ||
27 | +#include "ziyan_logger.h" | ||
28 | +#include <stdlib.h> | ||
29 | +#include <errno.h> | ||
30 | +#include <string.h> | ||
31 | +#include <stdio.h> | ||
32 | +#include "utils/util_misc.h" | ||
33 | +#include "utils/util_md5.h" | ||
34 | +#include <ziyan_aircraft_info.h> | ||
35 | + | ||
36 | +#include "JZsdkLib.h" | ||
37 | + | ||
38 | +#ifdef OPUS_INSTALLED | ||
39 | + | ||
40 | +#include <opus/opus.h> | ||
41 | + | ||
42 | +#endif | ||
43 | + | ||
44 | +#ifdef ALSA_INSTALLED | ||
45 | + | ||
46 | +#include <alsa/asoundlib.h> | ||
47 | + | ||
48 | +#endif | ||
49 | + | ||
50 | +/* Private constants ---------------------------------------------------------*/ | ||
51 | +#define WIDGET_SPEAKER_TASK_STACK_SIZE (2048) | ||
52 | + | ||
53 | +/*! Attention: replace your audio device name here. */ | ||
54 | +// #define WIDGET_SPEAKER_USB_AUDIO_DEVICE_NAME "alsa_output.usb-C-Media_Electronics_Inc._USB_Audio_Device-00.analog-stereo" | ||
55 | +#define WIDGET_SPEAKER_USB_AUDIO_DEVICE_NAME "alsa_card.usb-GeneralPlus_USB_Audio_Device-00" | ||
56 | + | ||
57 | +#define WIDGET_SPEAKER_AUDIO_OPUS_FILE_NAME "test_audio.opus" | ||
58 | +#define WIDGET_SPEAKER_AUDIO_PCM_FILE_NAME "test_audio.pcm" | ||
59 | + | ||
60 | +#define WIDGET_SPEAKER_TTS_FILE_NAME "test_tts.txt" | ||
61 | +#define WIDGET_SPEAKER_TTS_OUTPUT_FILE_NAME "tts_audio.wav" | ||
62 | +#define WIDGET_SPEAKER_TTS_FILE_MAX_SIZE (3000) | ||
63 | + | ||
64 | +/* The frame size is hardcoded for this sample code but it doesn't have to be */ | ||
65 | +#define WIDGET_SPEAKER_AUDIO_OPUS_MAX_PACKET_SIZE (3 * 1276) | ||
66 | +#define WIDGET_SPEAKER_AUDIO_OPUS_MAX_FRAME_SIZE (6 * 960) | ||
67 | +#define WIDGET_SPEAKER_AUDIO_OPUS_SAMPLE_RATE (16000) | ||
68 | +#define WIDGET_SPEAKER_AUDIO_OPUS_CHANNELS (1) | ||
69 | + | ||
70 | +#define WIDGET_SPEAKER_AUDIO_OPUS_DECODE_FRAME_SIZE_8KBPS (40) | ||
71 | +#define WIDGET_SPEAKER_AUDIO_OPUS_DECODE_BITRATE_8KBPS (8000) | ||
72 | + | ||
73 | +/* The speaker initialization parameters */ | ||
74 | +#define WIDGET_SPEAKER_DEFAULT_VOLUME (60) | ||
75 | +#define EKHO_INSTALLED (1) | ||
76 | + | ||
77 | +/* Private types -------------------------------------------------------------*/ | ||
78 | + | ||
79 | +/* Private values -------------------------------------------------------------*/ | ||
80 | +static T_ZiyanWidgetSpeakerHandler s_speakerHandler = {0}; | ||
81 | +static T_ZiyanMutexHandle s_speakerMutex = {0}; | ||
82 | +static T_ZiyanWidgetSpeakerState s_speakerState = {0}; | ||
83 | +static T_ZiyanTaskHandle s_widgetSpeakerTestThread; | ||
84 | + | ||
85 | +static FILE *s_audioFile = NULL; | ||
86 | +static FILE *s_ttsFile = NULL; | ||
87 | +static bool s_isDecodeFinished = true; | ||
88 | +static uint16_t s_decodeBitrate = 0; | ||
89 | + | ||
90 | +#ifdef ALSA_INSTALLED | ||
91 | + snd_pcm_t *pcm_handle = NULL; | ||
92 | + snd_pcm_hw_params_t *hw_params = NULL; | ||
93 | + snd_pcm_sw_params_t *sw_params = NULL; | ||
94 | +#endif | ||
95 | + | ||
96 | +/* Private functions declaration ---------------------------------------------*/ | ||
97 | +static void SetSpeakerState(E_ZiyanWidgetSpeakerState speakerState); | ||
98 | +static T_ZiyanReturnCode GetSpeakerState(T_ZiyanWidgetSpeakerState *speakerState); | ||
99 | +static T_ZiyanReturnCode SetWorkMode(E_ZiyanWidgetSpeakerWorkMode workMode); | ||
100 | +static T_ZiyanReturnCode SetPlayMode(E_ZiyanWidgetSpeakerPlayMode playMode); | ||
101 | +static T_ZiyanReturnCode StartPlay(void); | ||
102 | +static T_ZiyanReturnCode StopPlay(void); | ||
103 | +static T_ZiyanReturnCode SetVolume(uint8_t volume); | ||
104 | +static T_ZiyanReturnCode ReceiveTtsData(E_ZiyanWidgetTransmitDataEvent event, | ||
105 | + uint32_t offset, uint8_t *buf, uint16_t size); | ||
106 | +static T_ZiyanReturnCode ReceiveAudioData(E_ZiyanWidgetTransmitDataEvent event, | ||
107 | + uint32_t offset, uint8_t *buf, uint16_t size); | ||
108 | +#ifdef SYSTEM_ARCH_LINUX | ||
109 | +static void *ZiyanTest_WidgetSpeakerTask(void *arg); | ||
110 | +static uint32_t ZiyanTest_GetVoicePlayProcessId(void); | ||
111 | +static uint32_t ZiyanTest_KillVoicePlayProcess(uint32_t pid); | ||
112 | +static T_ZiyanReturnCode ZiyanTest_DecodeAudioData(void); | ||
113 | +static T_ZiyanReturnCode ZiyanTest_PlayAudioData(void); | ||
114 | +static T_ZiyanReturnCode ZiyanTest_PlayTtsData(void); | ||
115 | +static T_ZiyanReturnCode ZiyanTest_CheckFileMd5Sum(const char *path, uint8_t *buf, uint16_t size); | ||
116 | +#endif | ||
117 | + | ||
118 | +/* Exported functions definition ---------------------------------------------*/ | ||
119 | +T_ZiyanReturnCode ZiyanTest_WidgetSpeakerStartService(void) | ||
120 | +{ | ||
121 | + T_ZiyanReturnCode returnCode; | ||
122 | + T_ZiyanOsalHandler *osalHandler = ZiyanPlatform_GetOsalHandler(); | ||
123 | + | ||
124 | + s_speakerHandler.GetSpeakerState = GetSpeakerState; | ||
125 | + s_speakerHandler.SetWorkMode = SetWorkMode; | ||
126 | + s_speakerHandler.StartPlay = StartPlay; | ||
127 | + s_speakerHandler.StopPlay = StopPlay; | ||
128 | + s_speakerHandler.SetPlayMode = SetPlayMode; | ||
129 | + s_speakerHandler.SetVolume = SetVolume; | ||
130 | + s_speakerHandler.ReceiveTtsData = ReceiveTtsData; | ||
131 | + s_speakerHandler.ReceiveVoiceData = ReceiveAudioData; | ||
132 | + | ||
133 | + returnCode = osalHandler->MutexCreate(&s_speakerMutex); | ||
134 | + if (returnCode != ZIYAN_ERROR_SYSTEM_MODULE_CODE_SUCCESS) { | ||
135 | + USER_LOG_ERROR("Create speaker mutex error: 0x%08llX", returnCode); | ||
136 | + return returnCode; | ||
137 | + } | ||
138 | + | ||
139 | + returnCode = ZiyanWidget_RegSpeakerHandler(&s_speakerHandler); | ||
140 | + if (returnCode != ZIYAN_ERROR_SYSTEM_MODULE_CODE_SUCCESS) { | ||
141 | + USER_LOG_ERROR("Register speaker handler error: 0x%08llX", returnCode); | ||
142 | + return returnCode; | ||
143 | + } | ||
144 | + | ||
145 | + returnCode = osalHandler->MutexLock(s_speakerMutex); | ||
146 | + if (returnCode != ZIYAN_ERROR_SYSTEM_MODULE_CODE_SUCCESS) { | ||
147 | + USER_LOG_ERROR("lock mutex error: 0x%08llX.", returnCode); | ||
148 | + return returnCode; | ||
149 | + } | ||
150 | + | ||
151 | + s_speakerState.state = ZIYAN_WIDGET_SPEAKER_STATE_IDEL; | ||
152 | + s_speakerState.workMode = ZIYAN_WIDGET_SPEAKER_WORK_MODE_VOICE; | ||
153 | + s_speakerState.playMode = ZIYAN_WIDGET_SPEAKER_PLAY_MODE_SINGLE_PLAY; | ||
154 | + | ||
155 | + returnCode = osalHandler->MutexUnlock(s_speakerMutex); | ||
156 | + if (returnCode != ZIYAN_ERROR_SYSTEM_MODULE_CODE_SUCCESS) { | ||
157 | + USER_LOG_ERROR("unlock mutex error: 0x%08llX.", returnCode); | ||
158 | + return returnCode; | ||
159 | + } | ||
160 | + | ||
161 | + returnCode = SetVolume(WIDGET_SPEAKER_DEFAULT_VOLUME); | ||
162 | + if (returnCode != ZIYAN_ERROR_SYSTEM_MODULE_CODE_SUCCESS) { | ||
163 | + USER_LOG_ERROR("Set speaker volume error: 0x%08llX", returnCode); | ||
164 | + return returnCode; | ||
165 | + } | ||
166 | + | ||
167 | +#ifdef SYSTEM_ARCH_LINUX | ||
168 | + if (osalHandler->TaskCreate("user_widget_speaker_task", ZiyanTest_WidgetSpeakerTask, WIDGET_SPEAKER_TASK_STACK_SIZE, | ||
169 | + NULL, | ||
170 | + &s_widgetSpeakerTestThread) != ZIYAN_ERROR_SYSTEM_MODULE_CODE_SUCCESS) { | ||
171 | + USER_LOG_ERROR("Ziyan widget speaker test task create error."); | ||
172 | + return ZIYAN_ERROR_SYSTEM_MODULE_CODE_UNKNOWN; | ||
173 | + } | ||
174 | +#endif | ||
175 | + | ||
176 | + return ZIYAN_ERROR_SYSTEM_MODULE_CODE_SUCCESS; | ||
177 | +} | ||
178 | + | ||
179 | +#ifdef ALSA_INSTALLED | ||
180 | +T_ZiyanReturnCode ZiyanTest_AsoundInit() | ||
181 | +{ | ||
182 | + // 打开默认音频设备 | ||
183 | + if (snd_pcm_open(&pcm_handle, "default", SND_PCM_STREAM_PLAYBACK, 0) < 0) { | ||
184 | + fprintf(stderr, "无法打开音频设备\n"); | ||
185 | + return 1; | ||
186 | + } | ||
187 | + | ||
188 | + // 分配硬件参数结构体 | ||
189 | + snd_pcm_hw_params_alloca(&hw_params); | ||
190 | + snd_pcm_hw_params_any(pcm_handle, hw_params); | ||
191 | + | ||
192 | + // 设置硬件参数 | ||
193 | + snd_pcm_hw_params_set_access(pcm_handle, hw_params, SND_PCM_ACCESS_RW_INTERLEAVED); | ||
194 | + snd_pcm_hw_params_set_format(pcm_handle, hw_params, SND_PCM_FORMAT_S16_LE); // 16-bit little-endian | ||
195 | + snd_pcm_hw_params_set_rate(pcm_handle, hw_params, WIDGET_SPEAKER_AUDIO_OPUS_SAMPLE_RATE, 0); // 设置采样率为 16kHz | ||
196 | + snd_pcm_hw_params_set_channels(pcm_handle, hw_params, WIDGET_SPEAKER_AUDIO_OPUS_CHANNELS); // 设置单声道 | ||
197 | + snd_pcm_hw_params_set_buffer_size(pcm_handle, hw_params, 16000 * 8); | ||
198 | + snd_pcm_hw_params_set_period_size(pcm_handle, hw_params, 1280, 0); | ||
199 | + | ||
200 | + // 应用硬件参数 | ||
201 | + if (snd_pcm_hw_params(pcm_handle, hw_params) < 0) { | ||
202 | + fprintf(stderr, "无法设置硬件参数\n"); | ||
203 | + return 1; | ||
204 | + } | ||
205 | + | ||
206 | + // 设置软件参数 | ||
207 | + snd_pcm_sw_params_alloca(&sw_params); | ||
208 | + snd_pcm_sw_params_current(pcm_handle, sw_params); | ||
209 | + snd_pcm_sw_params_set_avail_min(pcm_handle, sw_params, 1280); | ||
210 | + snd_pcm_sw_params_set_start_threshold(pcm_handle, sw_params, 0); | ||
211 | + | ||
212 | + // 应用软件参数 | ||
213 | + if (snd_pcm_sw_params(pcm_handle, sw_params) < 0) { | ||
214 | + fprintf(stderr, "无法设置软件参数\n"); | ||
215 | + return 1; | ||
216 | + } | ||
217 | + | ||
218 | + // snd_pcm_prepare(pcm_handle); | ||
219 | + | ||
220 | + return 0; | ||
221 | +} | ||
222 | +#endif | ||
223 | + | ||
224 | + | ||
225 | +T_ZiyanReturnCode ZiyanTest_PcmPlay(uint8_t* pcm_data, uint64_t size) | ||
226 | +{ | ||
227 | +#ifdef ALSA_INSTALLED | ||
228 | + if((pcm_handle != NULL)){ | ||
229 | + int err = snd_pcm_writei(pcm_handle, pcm_data, size); | ||
230 | + | ||
231 | + snd_pcm_sframes_t avail = snd_pcm_avail(pcm_handle); | ||
232 | + if((16000 * 8 - avail) <= 16000){ | ||
233 | + | ||
234 | + uint8_t pcm_empty[16000]; | ||
235 | + memset(pcm_empty, 0, sizeof(pcm_empty)); | ||
236 | + snd_pcm_writei(pcm_handle, pcm_empty, sizeof(pcm_empty)); | ||
237 | + } | ||
238 | + // snd_pcm_sframes_t avail = 0; | ||
239 | + printf("play pcm %d : %ld : %ld\n", err, size, avail); | ||
240 | + | ||
241 | + // 错误处理 | ||
242 | + if (err == -EPIPE) { | ||
243 | + fprintf(stderr, "发生缓冲区溢出错误!\n"); | ||
244 | + snd_pcm_prepare(pcm_handle); | ||
245 | + } else if (err < 0) { | ||
246 | + fprintf(stderr, "播放失败: %s\n", snd_strerror(err)); | ||
247 | + } else if (err < 640) { | ||
248 | + fprintf(stderr, "警告: 写入的帧数少于预期\n"); | ||
249 | + } | ||
250 | + } | ||
251 | +#endif | ||
252 | +} | ||
253 | + | ||
254 | +/* Private functions definition-----------------------------------------------*/ | ||
255 | +#ifdef SYSTEM_ARCH_LINUX | ||
256 | + | ||
257 | +static uint32_t ZiyanTest_GetVoicePlayProcessId(void) | ||
258 | +{ | ||
259 | + FILE *fp; | ||
260 | + char cmdStr[128]; | ||
261 | + uint32_t pid; | ||
262 | + int ret; | ||
263 | + | ||
264 | + snprintf(cmdStr, 128, "pgrep ffplay"); | ||
265 | + fp = popen(cmdStr, "r"); | ||
266 | + if (fp == NULL) { | ||
267 | + USER_LOG_ERROR("fp is null."); | ||
268 | + return 0; | ||
269 | + } | ||
270 | + | ||
271 | + ret = fscanf(fp, "%u", &pid); | ||
272 | + if (ret <= 0) { | ||
273 | + pid = 0; | ||
274 | + goto out; | ||
275 | + } | ||
276 | + | ||
277 | +out: | ||
278 | + pclose(fp); | ||
279 | + | ||
280 | + return pid; | ||
281 | +} | ||
282 | + | ||
283 | +static uint32_t ZiyanTest_KillVoicePlayProcess(uint32_t pid) | ||
284 | +{ | ||
285 | + FILE *fp; | ||
286 | + char cmdStr[128]; | ||
287 | + | ||
288 | + snprintf(cmdStr, 128, "kill %d", pid); | ||
289 | + fp = popen(cmdStr, "r"); | ||
290 | + if (fp == NULL) { | ||
291 | + USER_LOG_ERROR("fp is null."); | ||
292 | + return 0; | ||
293 | + } | ||
294 | + | ||
295 | + pclose(fp); | ||
296 | + | ||
297 | + return pid; | ||
298 | +} | ||
299 | + | ||
300 | +static T_ZiyanReturnCode ZiyanTest_DecodeAudioData(void) | ||
301 | +{ | ||
302 | +#ifdef OPUS_INSTALLED | ||
303 | + FILE *fin; | ||
304 | + FILE *fout; | ||
305 | + OpusDecoder *decoder; | ||
306 | + opus_int16 out[WIDGET_SPEAKER_AUDIO_OPUS_MAX_FRAME_SIZE * WIDGET_SPEAKER_AUDIO_OPUS_CHANNELS]; | ||
307 | + uint8_t cbits[WIDGET_SPEAKER_AUDIO_OPUS_MAX_PACKET_SIZE]; | ||
308 | + int32_t nbBytes; | ||
309 | + int32_t err; | ||
310 | + | ||
311 | + /*! Attention: you can use "ffmpeg -i xxx.mp3 -ar 16000 -ac 1 out.wav" and use opus-tools to generate opus file for test */ | ||
312 | + fin = fopen(WIDGET_SPEAKER_AUDIO_OPUS_FILE_NAME, "r"); | ||
313 | + if (fin == NULL) { | ||
314 | + fprintf(stderr, "failed to open input file: %s\n", strerror(errno)); | ||
315 | + return EXIT_FAILURE; | ||
316 | + } | ||
317 | + | ||
318 | + /* Create a new decoder state. */ | ||
319 | + decoder = opus_decoder_create(WIDGET_SPEAKER_AUDIO_OPUS_SAMPLE_RATE, WIDGET_SPEAKER_AUDIO_OPUS_CHANNELS, &err); | ||
320 | + if (err < 0) { | ||
321 | + fprintf(stderr, "failed to create decoder: %s\n", opus_strerror(err)); | ||
322 | + goto close_fin; | ||
323 | + } | ||
324 | + | ||
325 | + fout = fopen(WIDGET_SPEAKER_AUDIO_PCM_FILE_NAME, "a+"); | ||
326 | + if (fout == NULL) { | ||
327 | + fprintf(stderr, "failed to open output file: %s\n", strerror(errno)); | ||
328 | + goto close_fin; | ||
329 | + } | ||
330 | + | ||
331 | + while (1) { | ||
332 | + int i; | ||
333 | + unsigned char pcm_bytes[WIDGET_SPEAKER_AUDIO_OPUS_MAX_FRAME_SIZE * WIDGET_SPEAKER_AUDIO_OPUS_CHANNELS * 4] = {0}; | ||
334 | + int frame_size; | ||
335 | + | ||
336 | + /* Read a 16 bits/sample audio frame. */ | ||
337 | + nbBytes = fread(cbits, 1, s_decodeBitrate / WIDGET_SPEAKER_AUDIO_OPUS_DECODE_BITRATE_8KBPS * | ||
338 | + WIDGET_SPEAKER_AUDIO_OPUS_DECODE_FRAME_SIZE_8KBPS * 8, fin); | ||
339 | + | ||
340 | + /* Decode the data. In this example, frame_size will be constant because | ||
341 | + the encoder is using a constant frame size. However, that may not | ||
342 | + be the case for all encoders, so the decoder must always check | ||
343 | + the frame size returned. */ | ||
344 | + frame_size = opus_decode(decoder, cbits, nbBytes, out, WIDGET_SPEAKER_AUDIO_OPUS_MAX_FRAME_SIZE, 0); | ||
345 | + if (frame_size < 0) { | ||
346 | + fprintf(stderr, "decoder failed: %s\n", opus_strerror(frame_size)); | ||
347 | + goto close_fout; | ||
348 | + } | ||
349 | + | ||
350 | + /* Convert to little-endian ordering. */ | ||
351 | + for (i = 0; i < WIDGET_SPEAKER_AUDIO_OPUS_CHANNELS * frame_size; i++) { | ||
352 | + pcm_bytes[2 * i] = out[i] & 0xFF; | ||
353 | + pcm_bytes[2 * i + 1] = (out[i] >> 8) & 0xFF; | ||
354 | + } | ||
355 | + /* Write the decoded audio to file. */ | ||
356 | + fwrite(pcm_bytes, sizeof(short), frame_size * WIDGET_SPEAKER_AUDIO_OPUS_CHANNELS, fout); | ||
357 | +#ifdef ALSA_INSTALLED | ||
358 | + ZiyanTest_PcmPlay(pcm_bytes, frame_size * WIDGET_SPEAKER_AUDIO_OPUS_CHANNELS); | ||
359 | +#endif | ||
360 | + | ||
361 | + if (feof(fin)) | ||
362 | + break; | ||
363 | + } | ||
364 | + | ||
365 | + USER_LOG_INFO("Decode Finished..."); | ||
366 | + s_isDecodeFinished = true; | ||
367 | + | ||
368 | +decode_data_failed: | ||
369 | + opus_decoder_destroy(decoder); | ||
370 | +create_decoder_failed: | ||
371 | + fclose(fout); | ||
372 | +open_pcm_audio_failed: | ||
373 | + fclose(fin); | ||
374 | +#endif | ||
375 | + return EXIT_SUCCESS; | ||
376 | + | ||
377 | +#ifdef OPUS_INSTALLED | ||
378 | +close_fout: | ||
379 | + fclose(fout); | ||
380 | + | ||
381 | +close_fin: | ||
382 | + fclose(fin); | ||
383 | + | ||
384 | + return EXIT_FAILURE; | ||
385 | +#endif | ||
386 | + | ||
387 | +} | ||
388 | + | ||
389 | +static T_ZiyanReturnCode ZiyanTest_PlayAudioData(void) | ||
390 | +{ | ||
391 | + char cmdStr[128]; | ||
392 | + | ||
393 | + memset(cmdStr, 0, sizeof(cmdStr)); | ||
394 | + USER_LOG_INFO("Start Playing..."); | ||
395 | + | ||
396 | + snprintf(cmdStr, sizeof(cmdStr), "ffplay -nodisp -autoexit -ar 16000 -ac 1 -f s16le -i %s 2>/dev/null", | ||
397 | + WIDGET_SPEAKER_AUDIO_PCM_FILE_NAME); | ||
398 | + | ||
399 | + return ZiyanUserUtil_RunSystemCmd(cmdStr); | ||
400 | +} | ||
401 | + | ||
402 | +static T_ZiyanReturnCode ZiyanTest_PlayTtsData(void) | ||
403 | +{ | ||
404 | + FILE *txtFile; | ||
405 | + uint8_t data[WIDGET_SPEAKER_TTS_FILE_MAX_SIZE] = {0}; | ||
406 | + int32_t readLen; | ||
407 | + char cmdStr[WIDGET_SPEAKER_TTS_FILE_MAX_SIZE + 128]; | ||
408 | + T_ZiyanAircraftInfoBaseInfo aircraftInfoBaseInfo; | ||
409 | + T_ZiyanReturnCode returnCode; | ||
410 | + | ||
411 | + returnCode = ZiyanAircraftInfo_GetBaseInfo(&aircraftInfoBaseInfo); | ||
412 | + if (returnCode != ZIYAN_ERROR_SYSTEM_MODULE_CODE_SUCCESS) { | ||
413 | + USER_LOG_ERROR("get aircraft base info error"); | ||
414 | + return ZIYAN_ERROR_SYSTEM_MODULE_CODE_SYSTEM_ERROR; | ||
415 | + } | ||
416 | + | ||
417 | + if (aircraftInfoBaseInfo.aircraftType == ZIYAN_AIRCRAFT_TYPE_SHADOW_PLUS || | ||
418 | + aircraftInfoBaseInfo.aircraftType == ZIYAN_AIRCRAFT_TYPE_SHADOW_MAX) { | ||
419 | + return ZiyanTest_PlayAudioData(); | ||
420 | + } else { | ||
421 | + txtFile = fopen(WIDGET_SPEAKER_TTS_FILE_NAME, "r"); | ||
422 | + if (txtFile == NULL) { | ||
423 | + USER_LOG_ERROR("failed to open input file: %s\n", strerror(errno)); | ||
424 | + return EXIT_FAILURE; | ||
425 | + } | ||
426 | + | ||
427 | + readLen = fread(data, 1, WIDGET_SPEAKER_TTS_FILE_MAX_SIZE - 1, txtFile); | ||
428 | + if (readLen <= 0) { | ||
429 | + USER_LOG_ERROR("Read tts file failed, error code: %d", readLen); | ||
430 | + fclose(txtFile); | ||
431 | + return ZIYAN_ERROR_SYSTEM_MODULE_CODE_NOT_FOUND; | ||
432 | + } | ||
433 | + | ||
434 | + data[readLen] = '\0'; | ||
435 | + | ||
436 | + fclose(txtFile); | ||
437 | + | ||
438 | + USER_LOG_INFO("Read tts file success, len: %d", readLen); | ||
439 | + USER_LOG_INFO("Content: %s", data); | ||
440 | + | ||
441 | + memset(cmdStr, 0, sizeof(cmdStr)); | ||
442 | + | ||
443 | + SetSpeakerState(ZIYAN_WIDGET_SPEAKER_STATE_IN_TTS_CONVERSION); | ||
444 | + | ||
445 | +#if EKHO_INSTALLED | ||
446 | + /*! Attention: you can use other tts opensource function to convert txt to speech, example used ekho v7.5 */ | ||
447 | + snprintf(cmdStr, sizeof(cmdStr), " ekho %s -s 20 -p 20 -a 100 -o %s", data, | ||
448 | + WIDGET_SPEAKER_TTS_OUTPUT_FILE_NAME); | ||
449 | +#else | ||
450 | + USER_LOG_WARN( | ||
451 | + "Ekho is not installed, please visit https://www.eguidedog.net/ekho.php to install it or use other TTS tools to convert audio"); | ||
452 | +#endif | ||
453 | + ZiyanUserUtil_RunSystemCmd(cmdStr); | ||
454 | + | ||
455 | + SetSpeakerState(ZIYAN_WIDGET_SPEAKER_STATE_PLAYING); | ||
456 | + USER_LOG_INFO("Start TTS Playing..."); | ||
457 | + memset(cmdStr, 0, sizeof(cmdStr)); | ||
458 | + snprintf(cmdStr, sizeof(cmdStr), "ffplay -nodisp -autoexit -ar 16000 -ac 1 -f s16le -i %s 2>/dev/null", | ||
459 | + WIDGET_SPEAKER_TTS_OUTPUT_FILE_NAME); | ||
460 | + | ||
461 | + return ZiyanUserUtil_RunSystemCmd(cmdStr); | ||
462 | + } | ||
463 | +} | ||
464 | + | ||
465 | +static T_ZiyanReturnCode ZiyanTest_CheckFileMd5Sum(const char *path, uint8_t *buf, uint16_t size) | ||
466 | +{ | ||
467 | + MD5_CTX md5Ctx; | ||
468 | + uint32_t readFileTotalSize = 0; | ||
469 | + uint16_t readLen; | ||
470 | + T_ZiyanReturnCode returnCode; | ||
471 | + uint8_t readBuf[1024] = {0}; | ||
472 | + uint8_t md5Sum[16] = {0}; | ||
473 | + FILE *file = NULL;; | ||
474 | + | ||
475 | + UtilMd5_Init(&md5Ctx); | ||
476 | + | ||
477 | + file = fopen(path, "rb"); | ||
478 | + if (file == NULL) { | ||
479 | + USER_LOG_ERROR("Open tts file error."); | ||
480 | + return ZIYAN_ERROR_SYSTEM_MODULE_CODE_SYSTEM_ERROR; | ||
481 | + } | ||
482 | + | ||
483 | + while (1) { | ||
484 | + returnCode = fseek(file, readFileTotalSize, SEEK_SET); | ||
485 | + if (returnCode != 0) { | ||
486 | + USER_LOG_INFO("fseek file error"); | ||
487 | + } | ||
488 | + | ||
489 | + readLen = fread(readBuf, 1, sizeof(readBuf), file); | ||
490 | + if (readLen > 0) { | ||
491 | + readFileTotalSize += readLen; | ||
492 | + UtilMd5_Update(&md5Ctx, readBuf, readLen); | ||
493 | + } | ||
494 | + | ||
495 | + if (feof(file)) | ||
496 | + break; | ||
497 | + } | ||
498 | + | ||
499 | + UtilMd5_Final(&md5Ctx, md5Sum); | ||
500 | + fclose(file); | ||
501 | + | ||
502 | + if (size == sizeof(md5Sum)) { | ||
503 | + if (memcmp(md5Sum, buf, sizeof(md5Sum)) == 0) { | ||
504 | + USER_LOG_INFO("MD5 sum check success"); | ||
505 | + return ZIYAN_ERROR_SYSTEM_MODULE_CODE_SUCCESS; | ||
506 | + } else { | ||
507 | + return ZIYAN_ERROR_SYSTEM_MODULE_CODE_SYSTEM_ERROR; | ||
508 | + } | ||
509 | + } else { | ||
510 | + USER_LOG_ERROR("MD5 sum length error"); | ||
511 | + } | ||
512 | + | ||
513 | + return ZIYAN_ERROR_SYSTEM_MODULE_CODE_SUCCESS; | ||
514 | +} | ||
515 | + | ||
516 | +#endif | ||
517 | + | ||
518 | +static void SetSpeakerState(E_ZiyanWidgetSpeakerState speakerState) | ||
519 | +{ | ||
520 | + T_ZiyanReturnCode returnCode; | ||
521 | + T_ZiyanOsalHandler *osalHandler = ZiyanPlatform_GetOsalHandler(); | ||
522 | + | ||
523 | + returnCode = osalHandler->MutexLock(s_speakerMutex); | ||
524 | + if (returnCode != ZIYAN_ERROR_SYSTEM_MODULE_CODE_SUCCESS) { | ||
525 | + USER_LOG_ERROR("lock mutex error: 0x%08llX.", returnCode); | ||
526 | + } | ||
527 | + | ||
528 | + s_speakerState.state = speakerState; | ||
529 | + | ||
530 | + returnCode = osalHandler->MutexUnlock(s_speakerMutex); | ||
531 | + if (returnCode != ZIYAN_ERROR_SYSTEM_MODULE_CODE_SUCCESS) { | ||
532 | + USER_LOG_ERROR("unlock mutex error: 0x%08llX.", returnCode); | ||
533 | + } | ||
534 | +} | ||
535 | + | ||
536 | +static T_ZiyanReturnCode GetSpeakerState(T_ZiyanWidgetSpeakerState *speakerState) | ||
537 | +{ | ||
538 | + T_ZiyanReturnCode returnCode; | ||
539 | + T_ZiyanOsalHandler *osalHandler = ZiyanPlatform_GetOsalHandler(); | ||
540 | + | ||
541 | + returnCode = osalHandler->MutexLock(s_speakerMutex); | ||
542 | + if (returnCode != ZIYAN_ERROR_SYSTEM_MODULE_CODE_SUCCESS) { | ||
543 | + USER_LOG_ERROR("lock mutex error: 0x%08llX.", returnCode); | ||
544 | + return returnCode; | ||
545 | + } | ||
546 | + | ||
547 | + *speakerState = s_speakerState; | ||
548 | + | ||
549 | + returnCode = osalHandler->MutexUnlock(s_speakerMutex); | ||
550 | + if (returnCode != ZIYAN_ERROR_SYSTEM_MODULE_CODE_SUCCESS) { | ||
551 | + USER_LOG_ERROR("unlock mutex error: 0x%08llX.", returnCode); | ||
552 | + return returnCode; | ||
553 | + } | ||
554 | + | ||
555 | + return ZIYAN_ERROR_SYSTEM_MODULE_CODE_SUCCESS; | ||
556 | +} | ||
557 | + | ||
558 | +static T_ZiyanReturnCode SetWorkMode(E_ZiyanWidgetSpeakerWorkMode workMode) | ||
559 | +{ | ||
560 | + T_ZiyanReturnCode returnCode; | ||
561 | + T_ZiyanOsalHandler *osalHandler = ZiyanPlatform_GetOsalHandler(); | ||
562 | + | ||
563 | + returnCode = osalHandler->MutexLock(s_speakerMutex); | ||
564 | + if (returnCode != ZIYAN_ERROR_SYSTEM_MODULE_CODE_SUCCESS) { | ||
565 | + USER_LOG_ERROR("lock mutex error: 0x%08llX.", returnCode); | ||
566 | + return returnCode; | ||
567 | + } | ||
568 | + | ||
569 | + USER_LOG_INFO("Set widget speaker work mode: %d", workMode); | ||
570 | + s_speakerState.workMode = workMode; | ||
571 | + | ||
572 | + returnCode = osalHandler->MutexUnlock(s_speakerMutex); | ||
573 | + if (returnCode != ZIYAN_ERROR_SYSTEM_MODULE_CODE_SUCCESS) { | ||
574 | + USER_LOG_ERROR("unlock mutex error: 0x%08llX.", returnCode); | ||
575 | + return returnCode; | ||
576 | + } | ||
577 | + | ||
578 | + return ZIYAN_ERROR_SYSTEM_MODULE_CODE_SUCCESS; | ||
579 | +} | ||
580 | + | ||
581 | +static T_ZiyanReturnCode SetPlayMode(E_ZiyanWidgetSpeakerPlayMode playMode) | ||
582 | +{ | ||
583 | + T_ZiyanReturnCode returnCode; | ||
584 | + T_ZiyanOsalHandler *osalHandler = ZiyanPlatform_GetOsalHandler(); | ||
585 | + | ||
586 | + returnCode = osalHandler->MutexLock(s_speakerMutex); | ||
587 | + if (returnCode != ZIYAN_ERROR_SYSTEM_MODULE_CODE_SUCCESS) { | ||
588 | + USER_LOG_ERROR("lock mutex error: 0x%08llX.", returnCode); | ||
589 | + return returnCode; | ||
590 | + } | ||
591 | + | ||
592 | + USER_LOG_INFO("Set widget speaker play mode: %d", playMode); | ||
593 | + s_speakerState.playMode = playMode; | ||
594 | + | ||
595 | + returnCode = osalHandler->MutexUnlock(s_speakerMutex); | ||
596 | + if (returnCode != ZIYAN_ERROR_SYSTEM_MODULE_CODE_SUCCESS) { | ||
597 | + USER_LOG_ERROR("unlock mutex error: 0x%08llX.", returnCode); | ||
598 | + return returnCode; | ||
599 | + } | ||
600 | + | ||
601 | + return ZIYAN_ERROR_SYSTEM_MODULE_CODE_SUCCESS; | ||
602 | +} | ||
603 | + | ||
604 | +static T_ZiyanReturnCode StartPlay(void) | ||
605 | +{ | ||
606 | + uint32_t pid; | ||
607 | + T_ZiyanOsalHandler *osalHandler = ZiyanPlatform_GetOsalHandler(); | ||
608 | + | ||
609 | +#ifdef SYSTEM_ARCH_LINUX | ||
610 | + pid = ZiyanTest_GetVoicePlayProcessId(); | ||
611 | + if (pid != 0) { | ||
612 | + ZiyanTest_KillVoicePlayProcess(pid); | ||
613 | + } | ||
614 | +#endif | ||
615 | + | ||
616 | + osalHandler->TaskSleepMs(5); | ||
617 | + USER_LOG_INFO("Start widget speaker play"); | ||
618 | + SetSpeakerState(ZIYAN_WIDGET_SPEAKER_STATE_PLAYING); | ||
619 | + | ||
620 | + return ZIYAN_ERROR_SYSTEM_MODULE_CODE_SUCCESS; | ||
621 | +} | ||
622 | + | ||
623 | +static T_ZiyanReturnCode StopPlay(void) | ||
624 | +{ | ||
625 | + T_ZiyanReturnCode returnCode; | ||
626 | + T_ZiyanOsalHandler *osalHandler = ZiyanPlatform_GetOsalHandler(); | ||
627 | + uint32_t pid; | ||
628 | + | ||
629 | + returnCode = osalHandler->MutexLock(s_speakerMutex); | ||
630 | + if (returnCode != ZIYAN_ERROR_SYSTEM_MODULE_CODE_SUCCESS) { | ||
631 | + USER_LOG_ERROR("lock mutex error: 0x%08llX.", returnCode); | ||
632 | + return returnCode; | ||
633 | + } | ||
634 | + | ||
635 | + USER_LOG_INFO("Stop widget speaker play"); | ||
636 | + s_speakerState.state = ZIYAN_WIDGET_SPEAKER_STATE_IDEL; | ||
637 | + | ||
638 | +#ifdef SYSTEM_ARCH_LINUX | ||
639 | + pid = ZiyanTest_GetVoicePlayProcessId(); | ||
640 | + if (pid != 0) { | ||
641 | + ZiyanTest_KillVoicePlayProcess(pid); | ||
642 | + } | ||
643 | +#endif | ||
644 | + | ||
645 | + returnCode = osalHandler->MutexUnlock(s_speakerMutex); | ||
646 | + if (returnCode != ZIYAN_ERROR_SYSTEM_MODULE_CODE_SUCCESS) { | ||
647 | + USER_LOG_ERROR("unlock mutex error: 0x%08llX.", returnCode); | ||
648 | + return returnCode; | ||
649 | + } | ||
650 | + | ||
651 | + return ZIYAN_ERROR_SYSTEM_MODULE_CODE_SUCCESS; | ||
652 | +} | ||
653 | + | ||
654 | +static T_ZiyanReturnCode SetVolume(uint8_t volume) | ||
655 | +{ | ||
656 | + T_ZiyanReturnCode returnCode; | ||
657 | + T_ZiyanOsalHandler *osalHandler = ZiyanPlatform_GetOsalHandler(); | ||
658 | + char cmdStr[128]; | ||
659 | + int32_t ret = 0; | ||
660 | + float realVolume; | ||
661 | + | ||
662 | + returnCode = osalHandler->MutexLock(s_speakerMutex); | ||
663 | + if (returnCode != ZIYAN_ERROR_SYSTEM_MODULE_CODE_SUCCESS) { | ||
664 | + USER_LOG_ERROR("lock mutex error: 0x%08llX.", returnCode); | ||
665 | + return returnCode; | ||
666 | + } | ||
667 | + | ||
668 | + realVolume = 1.5f * (float) volume; | ||
669 | + s_speakerState.volume = volume; | ||
670 | + | ||
671 | + USER_LOG_INFO("Set widget speaker volume: %d", volume); | ||
672 | + | ||
673 | + //将音量接口修改 | ||
674 | + | ||
675 | + | ||
676 | +// #ifdef PLATFORM_ARCH_x86_64 | ||
677 | +// snprintf(cmdStr, sizeof(cmdStr), "pactl list | grep %s -q", WIDGET_SPEAKER_USB_AUDIO_DEVICE_NAME); | ||
678 | +// ret = system(cmdStr); | ||
679 | +// if (ret == ZIYAN_ERROR_SYSTEM_MODULE_CODE_SUCCESS) { | ||
680 | +// memset(cmdStr, 0, sizeof(cmdStr)); | ||
681 | +// snprintf(cmdStr, sizeof(cmdStr), "pactl set-sink-volume %s %d%%", WIDGET_SPEAKER_USB_AUDIO_DEVICE_NAME, | ||
682 | +// (int32_t) realVolume); | ||
683 | + | ||
684 | +// returnCode = ZiyanUserUtil_RunSystemCmd(cmdStr); | ||
685 | +// if (returnCode != ZIYAN_ERROR_SYSTEM_MODULE_CODE_SUCCESS) { | ||
686 | +// USER_LOG_ERROR("Set widget speaker volume error: %d", ret); | ||
687 | +// } | ||
688 | +// } else { | ||
689 | +// USER_LOG_WARN("No audio device found, please add audio device and init speaker volume here."); | ||
690 | +// } | ||
691 | +// #else | ||
692 | +// USER_LOG_WARN("No audio device found, please add audio device and init speaker volume here!!!"); | ||
693 | +// #endif | ||
694 | + | ||
695 | + returnCode = osalHandler->MutexUnlock(s_speakerMutex); | ||
696 | + if (returnCode != ZIYAN_ERROR_SYSTEM_MODULE_CODE_SUCCESS) { | ||
697 | + USER_LOG_ERROR("unlock mutex error: 0x%08llX.", returnCode); | ||
698 | + return returnCode; | ||
699 | + } | ||
700 | + | ||
701 | + return ZIYAN_ERROR_SYSTEM_MODULE_CODE_SUCCESS; | ||
702 | +} | ||
703 | + | ||
704 | +static T_ZiyanReturnCode ReceiveTtsData(E_ZiyanWidgetTransmitDataEvent event, | ||
705 | + uint32_t offset, uint8_t *buf, uint16_t size) | ||
706 | +{ | ||
707 | + uint16_t writeLen; | ||
708 | + T_ZiyanReturnCode returnCode; | ||
709 | + | ||
710 | + if (event == ZIYAN_WIDGET_TRANSMIT_DATA_EVENT_START) { | ||
711 | + USER_LOG_INFO("Create tts file."); | ||
712 | +#ifdef SYSTEM_ARCH_LINUX | ||
713 | + s_ttsFile = fopen(WIDGET_SPEAKER_TTS_FILE_NAME, "wb"); | ||
714 | + if (s_ttsFile == NULL) { | ||
715 | + USER_LOG_ERROR("Open tts file error."); | ||
716 | + } | ||
717 | +#endif | ||
718 | + if (s_speakerState.state != ZIYAN_WIDGET_SPEAKER_STATE_PLAYING) { | ||
719 | + SetSpeakerState(ZIYAN_WIDGET_SPEAKER_STATE_TRANSMITTING); | ||
720 | + } | ||
721 | + } else if (event == ZIYAN_WIDGET_TRANSMIT_DATA_EVENT_TRANSMIT) { | ||
722 | + USER_LOG_INFO("Transmit tts file, offset: %d, size: %d", offset, size); | ||
723 | +#ifdef SYSTEM_ARCH_LINUX | ||
724 | + if (s_ttsFile != NULL) { | ||
725 | + fseek(s_ttsFile, offset, SEEK_SET); | ||
726 | + writeLen = fwrite(buf, 1, size, s_ttsFile); | ||
727 | + if (writeLen != size) { | ||
728 | + USER_LOG_ERROR("Write tts file error %d", writeLen); | ||
729 | + } | ||
730 | + } | ||
731 | +#endif | ||
732 | + if (s_speakerState.state != ZIYAN_WIDGET_SPEAKER_STATE_PLAYING) { | ||
733 | + SetSpeakerState(ZIYAN_WIDGET_SPEAKER_STATE_TRANSMITTING); | ||
734 | + } | ||
735 | + } else if (event == ZIYAN_WIDGET_TRANSMIT_DATA_EVENT_FINISH) { | ||
736 | + USER_LOG_INFO("Close tts file."); | ||
737 | +#ifdef SYSTEM_ARCH_LINUX | ||
738 | + if (s_ttsFile != NULL) { | ||
739 | + fclose(s_ttsFile); | ||
740 | + s_ttsFile = NULL; | ||
741 | + } | ||
742 | + | ||
743 | + returnCode = ZiyanTest_CheckFileMd5Sum(WIDGET_SPEAKER_TTS_FILE_NAME, buf, size); | ||
744 | + if (returnCode != ZIYAN_ERROR_SYSTEM_MODULE_CODE_SUCCESS) { | ||
745 | + USER_LOG_ERROR("File md5 sum check failed"); | ||
746 | + } | ||
747 | +#endif | ||
748 | + if (s_speakerState.state != ZIYAN_WIDGET_SPEAKER_STATE_PLAYING) { | ||
749 | + SetSpeakerState(ZIYAN_WIDGET_SPEAKER_STATE_IDEL); | ||
750 | + } | ||
751 | + } | ||
752 | + | ||
753 | + return ZIYAN_ERROR_SYSTEM_MODULE_CODE_SUCCESS; | ||
754 | +} | ||
755 | + | ||
756 | +static T_ZiyanReturnCode ReceiveAudioData(E_ZiyanWidgetTransmitDataEvent event, | ||
757 | + uint32_t offset, uint8_t *buf, uint16_t size) | ||
758 | +{ | ||
759 | + uint16_t writeLen; | ||
760 | + T_ZiyanReturnCode returnCode; | ||
761 | + T_ZiyanWidgetTransDataContent transDataContent = {0}; | ||
762 | + | ||
763 | + if (event == ZIYAN_WIDGET_TRANSMIT_DATA_EVENT_START) { | ||
764 | + s_isDecodeFinished = false; | ||
765 | +#ifdef SYSTEM_ARCH_LINUX | ||
766 | + USER_LOG_INFO("Create voice file."); | ||
767 | + s_audioFile = fopen(WIDGET_SPEAKER_AUDIO_OPUS_FILE_NAME, "wb"); | ||
768 | + if (s_audioFile == NULL) { | ||
769 | + USER_LOG_ERROR("Create tts file error."); | ||
770 | + } | ||
771 | + if (s_speakerState.state != ZIYAN_WIDGET_SPEAKER_STATE_PLAYING) { | ||
772 | + SetSpeakerState(ZIYAN_WIDGET_SPEAKER_STATE_TRANSMITTING); | ||
773 | + } | ||
774 | +#endif | ||
775 | + | ||
776 | + memcpy(&transDataContent, buf, size); | ||
777 | + s_decodeBitrate = transDataContent.transDataStartContent.fileDecodeBitrate; | ||
778 | + USER_LOG_INFO("Create voice file: %s, decoder bitrate: %d.", transDataContent.transDataStartContent.fileName, | ||
779 | + transDataContent.transDataStartContent.fileDecodeBitrate); | ||
780 | + } else if (event == ZIYAN_WIDGET_TRANSMIT_DATA_EVENT_TRANSMIT) { | ||
781 | + USER_LOG_INFO("Transmit voice file, offset: %d, size: %d", offset, size); | ||
782 | +#ifdef SYSTEM_ARCH_LINUX | ||
783 | + if (s_audioFile != NULL) { | ||
784 | + fseek(s_audioFile, offset, SEEK_SET); | ||
785 | + writeLen = fwrite(buf, 1, size, s_audioFile); | ||
786 | + if (writeLen != size) { | ||
787 | + USER_LOG_ERROR("Write tts file error %d", writeLen); | ||
788 | + } | ||
789 | + } | ||
790 | +#endif | ||
791 | + if (s_speakerState.state != ZIYAN_WIDGET_SPEAKER_STATE_PLAYING) { | ||
792 | + SetSpeakerState(ZIYAN_WIDGET_SPEAKER_STATE_TRANSMITTING); | ||
793 | + } | ||
794 | + } else if (event == ZIYAN_WIDGET_TRANSMIT_DATA_EVENT_FINISH) { | ||
795 | + USER_LOG_INFO("Close voice file."); | ||
796 | + if (s_audioFile != NULL) { | ||
797 | + fclose(s_audioFile); | ||
798 | + s_audioFile = NULL; | ||
799 | + } | ||
800 | + | ||
801 | +#ifdef SYSTEM_ARCH_LINUX | ||
802 | + returnCode = ZiyanTest_CheckFileMd5Sum(WIDGET_SPEAKER_AUDIO_OPUS_FILE_NAME, buf, size); | ||
803 | + if (returnCode != ZIYAN_ERROR_SYSTEM_MODULE_CODE_SUCCESS) { | ||
804 | + USER_LOG_ERROR("File md5 sum check failed"); | ||
805 | + return ZIYAN_ERROR_SYSTEM_MODULE_CODE_SYSTEM_ERROR; | ||
806 | + } | ||
807 | +#endif | ||
808 | + if (s_speakerState.state != ZIYAN_WIDGET_SPEAKER_STATE_PLAYING) { | ||
809 | + SetSpeakerState(ZIYAN_WIDGET_SPEAKER_STATE_IDEL); | ||
810 | + } | ||
811 | +#ifdef SYSTEM_ARCH_LINUX | ||
812 | + ZiyanTest_DecodeAudioData(); | ||
813 | +#endif | ||
814 | + } | ||
815 | + | ||
816 | + return ZIYAN_ERROR_SYSTEM_MODULE_CODE_SUCCESS; | ||
817 | +} | ||
818 | + | ||
819 | +#ifdef SYSTEM_ARCH_LINUX | ||
820 | +#ifndef __CC_ARM | ||
821 | +#pragma GCC diagnostic push | ||
822 | +#pragma GCC diagnostic ignored "-Wmissing-noreturn" | ||
823 | +#pragma GCC diagnostic ignored "-Wreturn-type" | ||
824 | +#endif | ||
825 | + | ||
826 | +static void *ZiyanTest_WidgetSpeakerTask(void *arg) | ||
827 | +{ | ||
828 | + T_ZiyanReturnCode ziyanReturnCode; | ||
829 | + T_ZiyanOsalHandler *osalHandler = ZiyanPlatform_GetOsalHandler(); | ||
830 | + | ||
831 | +#ifdef ALSA_INSTALLED | ||
832 | + ZiyanTest_AsoundInit(); | ||
833 | +#endif | ||
834 | + | ||
835 | + USER_UTIL_UNUSED(arg); | ||
836 | + | ||
837 | + while (1) { | ||
838 | + osalHandler->TaskSleepMs(10); | ||
839 | + | ||
840 | + if (s_speakerState.state == ZIYAN_WIDGET_SPEAKER_STATE_PLAYING) { | ||
841 | + if (s_speakerState.playMode == ZIYAN_WIDGET_SPEAKER_PLAY_MODE_LOOP_PLAYBACK) { | ||
842 | + if (s_speakerState.workMode == ZIYAN_WIDGET_SPEAKER_WORK_MODE_VOICE) { | ||
843 | + USER_LOG_DEBUG("Waiting opus decoder finished..."); | ||
844 | + while (s_isDecodeFinished == false) { | ||
845 | + osalHandler->TaskSleepMs(1); | ||
846 | + } | ||
847 | + ziyanReturnCode = ZiyanTest_PlayAudioData(); | ||
848 | + if (ziyanReturnCode != ZIYAN_ERROR_SYSTEM_MODULE_CODE_SUCCESS) { | ||
849 | + USER_LOG_ERROR("Play audio data failed, error: 0x%08llX.", ziyanReturnCode); | ||
850 | + } | ||
851 | + } else { | ||
852 | + ziyanReturnCode = ZiyanTest_PlayTtsData(); | ||
853 | + if (ziyanReturnCode != ZIYAN_ERROR_SYSTEM_MODULE_CODE_SUCCESS) { | ||
854 | + USER_LOG_ERROR("Play tts data failed, error: 0x%08llX.", ziyanReturnCode); | ||
855 | + } | ||
856 | + } | ||
857 | + osalHandler->TaskSleepMs(1000); | ||
858 | + } else { | ||
859 | + if (s_speakerState.workMode == ZIYAN_WIDGET_SPEAKER_WORK_MODE_VOICE) { | ||
860 | + USER_LOG_DEBUG("Waiting opus decoder finished..."); | ||
861 | + while (s_isDecodeFinished == false) { | ||
862 | + osalHandler->TaskSleepMs(1); | ||
863 | + } | ||
864 | + ziyanReturnCode = ZiyanTest_PlayAudioData(); | ||
865 | + if (ziyanReturnCode != ZIYAN_ERROR_SYSTEM_MODULE_CODE_SUCCESS) { | ||
866 | + USER_LOG_ERROR("Play audio data failed, error: 0x%08llX.", ziyanReturnCode); | ||
867 | + } | ||
868 | + } else { | ||
869 | + ziyanReturnCode = ZiyanTest_PlayTtsData(); | ||
870 | + if (ziyanReturnCode != ZIYAN_ERROR_SYSTEM_MODULE_CODE_SUCCESS) { | ||
871 | + USER_LOG_ERROR("Play tts data failed, error: 0x%08llX.", ziyanReturnCode); | ||
872 | + } | ||
873 | + } | ||
874 | + | ||
875 | + ziyanReturnCode = osalHandler->MutexLock(s_speakerMutex); | ||
876 | + if (ziyanReturnCode != ZIYAN_ERROR_SYSTEM_MODULE_CODE_SUCCESS) { | ||
877 | + USER_LOG_ERROR("lock mutex error: 0x%08llX.", ziyanReturnCode); | ||
878 | + } | ||
879 | + | ||
880 | + if (s_speakerState.playMode == ZIYAN_WIDGET_SPEAKER_PLAY_MODE_SINGLE_PLAY) { | ||
881 | + s_speakerState.state = ZIYAN_WIDGET_SPEAKER_STATE_IDEL; | ||
882 | + } | ||
883 | + | ||
884 | + ziyanReturnCode = osalHandler->MutexUnlock(s_speakerMutex); | ||
885 | + if (ziyanReturnCode != ZIYAN_ERROR_SYSTEM_MODULE_CODE_SUCCESS) { | ||
886 | + USER_LOG_ERROR("unlock mutex error: 0x%08llX.", ziyanReturnCode); | ||
887 | + } | ||
888 | + } | ||
889 | + } | ||
890 | + } | ||
891 | +} | ||
892 | + | ||
893 | +#ifndef __CC_ARM | ||
894 | +#pragma GCC diagnostic pop | ||
895 | +#endif | ||
896 | +#endif | ||
897 | + | ||
898 | +/****************** (C) COPYRIGHT ZIYAN Innovations *****END OF FILE****/ |
1 | +/** | ||
2 | + ******************************************************************** | ||
3 | + * @file test_widget_speaker.c | ||
4 | + * @brief | ||
5 | + * | ||
6 | + * @copyright (c) 2018 ZIYAN. All rights reserved. | ||
7 | + * | ||
8 | + * All information contained herein is, and remains, the property of ZIYAN. | ||
9 | + * The intellectual and technical concepts contained herein are proprietary | ||
10 | + * to ZIYAN 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 ZIYAN. | ||
15 | + * | ||
16 | + * If you receive this source code without ZIYAN’s authorization, you may not | ||
17 | + * further disseminate the information, and you must immediately remove the | ||
18 | + * source code and notify ZIYAN of its removal. ZIYAN 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 "test_widget_speaker.h" | ||
27 | +#include "ziyan_logger.h" | ||
28 | +#include <stdlib.h> | ||
29 | +#include <errno.h> | ||
30 | +#include <string.h> | ||
31 | +#include <stdio.h> | ||
32 | +#include "utils/util_misc.h" | ||
33 | +#include "utils/util_md5.h" | ||
34 | +#include <ziyan_aircraft_info.h> | ||
35 | + | ||
36 | +#ifdef OPUS_INSTALLED | ||
37 | + | ||
38 | +#include <opus/opus.h> | ||
39 | + | ||
40 | +#endif | ||
41 | + | ||
42 | +#ifdef ALSA_INSTALLED | ||
43 | + | ||
44 | +#include <alsa/asoundlib.h> | ||
45 | + | ||
46 | +#endif | ||
47 | + | ||
48 | +/* Private constants ---------------------------------------------------------*/ | ||
49 | +#define WIDGET_SPEAKER_TASK_STACK_SIZE (2048) | ||
50 | + | ||
51 | +/*! Attention: replace your audio device name here. */ | ||
52 | +// #define WIDGET_SPEAKER_USB_AUDIO_DEVICE_NAME "alsa_output.usb-C-Media_Electronics_Inc._USB_Audio_Device-00.analog-stereo" | ||
53 | +#define WIDGET_SPEAKER_USB_AUDIO_DEVICE_NAME "alsa_card.usb-GeneralPlus_USB_Audio_Device-00" | ||
54 | + | ||
55 | +#define WIDGET_SPEAKER_AUDIO_OPUS_FILE_NAME "test_audio.opus" | ||
56 | +#define WIDGET_SPEAKER_AUDIO_PCM_FILE_NAME "test_audio.pcm" | ||
57 | + | ||
58 | +#define WIDGET_SPEAKER_TTS_FILE_NAME "test_tts.txt" | ||
59 | +#define WIDGET_SPEAKER_TTS_OUTPUT_FILE_NAME "tts_audio.wav" | ||
60 | +#define WIDGET_SPEAKER_TTS_FILE_MAX_SIZE (3000) | ||
61 | + | ||
62 | +/* The frame size is hardcoded for this sample code but it doesn't have to be */ | ||
63 | +#define WIDGET_SPEAKER_AUDIO_OPUS_MAX_PACKET_SIZE (3 * 1276) | ||
64 | +#define WIDGET_SPEAKER_AUDIO_OPUS_MAX_FRAME_SIZE (6 * 960) | ||
65 | +#define WIDGET_SPEAKER_AUDIO_OPUS_SAMPLE_RATE (16000) | ||
66 | +#define WIDGET_SPEAKER_AUDIO_OPUS_CHANNELS (1) | ||
67 | + | ||
68 | +#define WIDGET_SPEAKER_AUDIO_OPUS_DECODE_FRAME_SIZE_8KBPS (40) | ||
69 | +#define WIDGET_SPEAKER_AUDIO_OPUS_DECODE_BITRATE_8KBPS (8000) | ||
70 | + | ||
71 | +/* The speaker initialization parameters */ | ||
72 | +#define WIDGET_SPEAKER_DEFAULT_VOLUME (60) | ||
73 | +#define EKHO_INSTALLED (1) | ||
74 | + | ||
75 | +/* Private types -------------------------------------------------------------*/ | ||
76 | + | ||
77 | +/* Private values -------------------------------------------------------------*/ | ||
78 | +static T_ZiyanWidgetSpeakerHandler s_speakerHandler = {0}; | ||
79 | +static T_ZiyanMutexHandle s_speakerMutex = {0}; | ||
80 | +static T_ZiyanWidgetSpeakerState s_speakerState = {0}; | ||
81 | +static T_ZiyanTaskHandle s_widgetSpeakerTestThread; | ||
82 | + | ||
83 | +static FILE *s_audioFile = NULL; | ||
84 | +static FILE *s_ttsFile = NULL; | ||
85 | +static bool s_isDecodeFinished = true; | ||
86 | +static uint16_t s_decodeBitrate = 0; | ||
87 | + | ||
88 | +#ifdef ALSA_INSTALLED | ||
89 | + snd_pcm_t *pcm_handle = NULL; | ||
90 | + snd_pcm_hw_params_t *hw_params = NULL; | ||
91 | + snd_pcm_sw_params_t *sw_params = NULL; | ||
92 | +#endif | ||
93 | + | ||
94 | +/* Private functions declaration ---------------------------------------------*/ | ||
95 | +static void SetSpeakerState(E_ZiyanWidgetSpeakerState speakerState); | ||
96 | +static T_ZiyanReturnCode GetSpeakerState(T_ZiyanWidgetSpeakerState *speakerState); | ||
97 | +static T_ZiyanReturnCode SetWorkMode(E_ZiyanWidgetSpeakerWorkMode workMode); | ||
98 | +static T_ZiyanReturnCode SetPlayMode(E_ZiyanWidgetSpeakerPlayMode playMode); | ||
99 | +static T_ZiyanReturnCode StartPlay(void); | ||
100 | +static T_ZiyanReturnCode StopPlay(void); | ||
101 | +static T_ZiyanReturnCode SetVolume(uint8_t volume); | ||
102 | +static T_ZiyanReturnCode ReceiveTtsData(E_ZiyanWidgetTransmitDataEvent event, | ||
103 | + uint32_t offset, uint8_t *buf, uint16_t size); | ||
104 | +static T_ZiyanReturnCode ReceiveAudioData(E_ZiyanWidgetTransmitDataEvent event, | ||
105 | + uint32_t offset, uint8_t *buf, uint16_t size); | ||
106 | +#ifdef SYSTEM_ARCH_LINUX | ||
107 | +static void *ZiyanTest_WidgetSpeakerTask(void *arg); | ||
108 | +static uint32_t ZiyanTest_GetVoicePlayProcessId(void); | ||
109 | +static uint32_t ZiyanTest_KillVoicePlayProcess(uint32_t pid); | ||
110 | +static T_ZiyanReturnCode ZiyanTest_DecodeAudioData(void); | ||
111 | +static T_ZiyanReturnCode ZiyanTest_PlayAudioData(void); | ||
112 | +static T_ZiyanReturnCode ZiyanTest_PlayTtsData(void); | ||
113 | +static T_ZiyanReturnCode ZiyanTest_CheckFileMd5Sum(const char *path, uint8_t *buf, uint16_t size); | ||
114 | +#endif | ||
115 | + | ||
116 | +/* Exported functions definition ---------------------------------------------*/ | ||
117 | +T_ZiyanReturnCode ZiyanTest_WidgetSpeakerStartService(void) | ||
118 | +{ | ||
119 | + T_ZiyanReturnCode returnCode; | ||
120 | + T_ZiyanOsalHandler *osalHandler = ZiyanPlatform_GetOsalHandler(); | ||
121 | + | ||
122 | + s_speakerHandler.GetSpeakerState = GetSpeakerState; | ||
123 | + s_speakerHandler.SetWorkMode = SetWorkMode; | ||
124 | + s_speakerHandler.StartPlay = StartPlay; | ||
125 | + s_speakerHandler.StopPlay = StopPlay; | ||
126 | + s_speakerHandler.SetPlayMode = SetPlayMode; | ||
127 | + s_speakerHandler.SetVolume = SetVolume; | ||
128 | + s_speakerHandler.ReceiveTtsData = ReceiveTtsData; | ||
129 | + s_speakerHandler.ReceiveVoiceData = ReceiveAudioData; | ||
130 | + | ||
131 | + returnCode = osalHandler->MutexCreate(&s_speakerMutex); | ||
132 | + if (returnCode != ZIYAN_ERROR_SYSTEM_MODULE_CODE_SUCCESS) { | ||
133 | + USER_LOG_ERROR("Create speaker mutex error: 0x%08llX", returnCode); | ||
134 | + return returnCode; | ||
135 | + } | ||
136 | + | ||
137 | + returnCode = ZiyanWidget_RegSpeakerHandler(&s_speakerHandler); | ||
138 | + if (returnCode != ZIYAN_ERROR_SYSTEM_MODULE_CODE_SUCCESS) { | ||
139 | + USER_LOG_ERROR("Register speaker handler error: 0x%08llX", returnCode); | ||
140 | + return returnCode; | ||
141 | + } | ||
142 | + | ||
143 | + returnCode = osalHandler->MutexLock(s_speakerMutex); | ||
144 | + if (returnCode != ZIYAN_ERROR_SYSTEM_MODULE_CODE_SUCCESS) { | ||
145 | + USER_LOG_ERROR("lock mutex error: 0x%08llX.", returnCode); | ||
146 | + return returnCode; | ||
147 | + } | ||
148 | + | ||
149 | + s_speakerState.state = ZIYAN_WIDGET_SPEAKER_STATE_IDEL; | ||
150 | + s_speakerState.workMode = ZIYAN_WIDGET_SPEAKER_WORK_MODE_VOICE; | ||
151 | + s_speakerState.playMode = ZIYAN_WIDGET_SPEAKER_PLAY_MODE_SINGLE_PLAY; | ||
152 | + | ||
153 | + returnCode = osalHandler->MutexUnlock(s_speakerMutex); | ||
154 | + if (returnCode != ZIYAN_ERROR_SYSTEM_MODULE_CODE_SUCCESS) { | ||
155 | + USER_LOG_ERROR("unlock mutex error: 0x%08llX.", returnCode); | ||
156 | + return returnCode; | ||
157 | + } | ||
158 | + | ||
159 | + returnCode = SetVolume(WIDGET_SPEAKER_DEFAULT_VOLUME); | ||
160 | + if (returnCode != ZIYAN_ERROR_SYSTEM_MODULE_CODE_SUCCESS) { | ||
161 | + USER_LOG_ERROR("Set speaker volume error: 0x%08llX", returnCode); | ||
162 | + return returnCode; | ||
163 | + } | ||
164 | + | ||
165 | +#ifdef SYSTEM_ARCH_LINUX | ||
166 | + if (osalHandler->TaskCreate("user_widget_speaker_task", ZiyanTest_WidgetSpeakerTask, WIDGET_SPEAKER_TASK_STACK_SIZE, | ||
167 | + NULL, | ||
168 | + &s_widgetSpeakerTestThread) != ZIYAN_ERROR_SYSTEM_MODULE_CODE_SUCCESS) { | ||
169 | + USER_LOG_ERROR("Ziyan widget speaker test task create error."); | ||
170 | + return ZIYAN_ERROR_SYSTEM_MODULE_CODE_UNKNOWN; | ||
171 | + } | ||
172 | +#endif | ||
173 | + | ||
174 | + return ZIYAN_ERROR_SYSTEM_MODULE_CODE_SUCCESS; | ||
175 | +} | ||
176 | + | ||
177 | +#ifdef ALSA_INSTALLED | ||
178 | +T_ZiyanReturnCode ZiyanTest_AsoundInit() | ||
179 | +{ | ||
180 | + // 打开默认音频设备 | ||
181 | + if (snd_pcm_open(&pcm_handle, "default", SND_PCM_STREAM_PLAYBACK, 0) < 0) { | ||
182 | + fprintf(stderr, "无法打开音频设备\n"); | ||
183 | + return 1; | ||
184 | + } | ||
185 | + | ||
186 | + // 分配硬件参数结构体 | ||
187 | + snd_pcm_hw_params_alloca(&hw_params); | ||
188 | + snd_pcm_hw_params_any(pcm_handle, hw_params); | ||
189 | + | ||
190 | + // 设置硬件参数 | ||
191 | + snd_pcm_hw_params_set_access(pcm_handle, hw_params, SND_PCM_ACCESS_RW_INTERLEAVED); | ||
192 | + snd_pcm_hw_params_set_format(pcm_handle, hw_params, SND_PCM_FORMAT_S16_LE); // 16-bit little-endian | ||
193 | + snd_pcm_hw_params_set_rate(pcm_handle, hw_params, WIDGET_SPEAKER_AUDIO_OPUS_SAMPLE_RATE, 0); // 设置采样率为 16kHz | ||
194 | + snd_pcm_hw_params_set_channels(pcm_handle, hw_params, WIDGET_SPEAKER_AUDIO_OPUS_CHANNELS); // 设置单声道 | ||
195 | + snd_pcm_hw_params_set_buffer_size(pcm_handle, hw_params, 16000 * 8); | ||
196 | + snd_pcm_hw_params_set_period_size(pcm_handle, hw_params, 1280, 0); | ||
197 | + | ||
198 | + // 应用硬件参数 | ||
199 | + if (snd_pcm_hw_params(pcm_handle, hw_params) < 0) { | ||
200 | + fprintf(stderr, "无法设置硬件参数\n"); | ||
201 | + return 1; | ||
202 | + } | ||
203 | + | ||
204 | + // 设置软件参数 | ||
205 | + snd_pcm_sw_params_alloca(&sw_params); | ||
206 | + snd_pcm_sw_params_current(pcm_handle, sw_params); | ||
207 | + snd_pcm_sw_params_set_avail_min(pcm_handle, sw_params, 1280); | ||
208 | + snd_pcm_sw_params_set_start_threshold(pcm_handle, sw_params, 0); | ||
209 | + | ||
210 | + // 应用软件参数 | ||
211 | + if (snd_pcm_sw_params(pcm_handle, sw_params) < 0) { | ||
212 | + fprintf(stderr, "无法设置软件参数\n"); | ||
213 | + return 1; | ||
214 | + } | ||
215 | + | ||
216 | + // snd_pcm_prepare(pcm_handle); | ||
217 | + | ||
218 | + return 0; | ||
219 | +} | ||
220 | +#endif | ||
221 | + | ||
222 | + | ||
223 | +T_ZiyanReturnCode ZiyanTest_PcmPlay(uint8_t* pcm_data, uint64_t size) | ||
224 | +{ | ||
225 | +#ifdef ALSA_INSTALLED | ||
226 | + if((pcm_handle != NULL)){ | ||
227 | + int err = snd_pcm_writei(pcm_handle, pcm_data, size); | ||
228 | + | ||
229 | + snd_pcm_sframes_t avail = snd_pcm_avail(pcm_handle); | ||
230 | + if((16000 * 8 - avail) <= 16000){ | ||
231 | + | ||
232 | + uint8_t pcm_empty[16000]; | ||
233 | + memset(pcm_empty, 0, sizeof(pcm_empty)); | ||
234 | + snd_pcm_writei(pcm_handle, pcm_empty, sizeof(pcm_empty)); | ||
235 | + } | ||
236 | + // snd_pcm_sframes_t avail = 0; | ||
237 | + printf("play pcm %d : %ld : %ld\n", err, size, avail); | ||
238 | + | ||
239 | + // 错误处理 | ||
240 | + if (err == -EPIPE) { | ||
241 | + fprintf(stderr, "发生缓冲区溢出错误!\n"); | ||
242 | + snd_pcm_prepare(pcm_handle); | ||
243 | + } else if (err < 0) { | ||
244 | + fprintf(stderr, "播放失败: %s\n", snd_strerror(err)); | ||
245 | + } else if (err < 640) { | ||
246 | + fprintf(stderr, "警告: 写入的帧数少于预期\n"); | ||
247 | + } | ||
248 | + } | ||
249 | +#endif | ||
250 | +} | ||
251 | + | ||
252 | +/* Private functions definition-----------------------------------------------*/ | ||
253 | +#ifdef SYSTEM_ARCH_LINUX | ||
254 | + | ||
255 | +static uint32_t ZiyanTest_GetVoicePlayProcessId(void) | ||
256 | +{ | ||
257 | + FILE *fp; | ||
258 | + char cmdStr[128]; | ||
259 | + uint32_t pid; | ||
260 | + int ret; | ||
261 | + | ||
262 | + snprintf(cmdStr, 128, "pgrep ffplay"); | ||
263 | + fp = popen(cmdStr, "r"); | ||
264 | + if (fp == NULL) { | ||
265 | + USER_LOG_ERROR("fp is null."); | ||
266 | + return 0; | ||
267 | + } | ||
268 | + | ||
269 | + ret = fscanf(fp, "%u", &pid); | ||
270 | + if (ret <= 0) { | ||
271 | + pid = 0; | ||
272 | + goto out; | ||
273 | + } | ||
274 | + | ||
275 | +out: | ||
276 | + pclose(fp); | ||
277 | + | ||
278 | + return pid; | ||
279 | +} | ||
280 | + | ||
281 | +static uint32_t ZiyanTest_KillVoicePlayProcess(uint32_t pid) | ||
282 | +{ | ||
283 | + FILE *fp; | ||
284 | + char cmdStr[128]; | ||
285 | + | ||
286 | + snprintf(cmdStr, 128, "kill %d", pid); | ||
287 | + fp = popen(cmdStr, "r"); | ||
288 | + if (fp == NULL) { | ||
289 | + USER_LOG_ERROR("fp is null."); | ||
290 | + return 0; | ||
291 | + } | ||
292 | + | ||
293 | + pclose(fp); | ||
294 | + | ||
295 | + return pid; | ||
296 | +} | ||
297 | + | ||
298 | +static T_ZiyanReturnCode ZiyanTest_DecodeAudioData(void) | ||
299 | +{ | ||
300 | +#ifdef OPUS_INSTALLED | ||
301 | + FILE *fin; | ||
302 | + FILE *fout; | ||
303 | + OpusDecoder *decoder; | ||
304 | + opus_int16 out[WIDGET_SPEAKER_AUDIO_OPUS_MAX_FRAME_SIZE * WIDGET_SPEAKER_AUDIO_OPUS_CHANNELS]; | ||
305 | + uint8_t cbits[WIDGET_SPEAKER_AUDIO_OPUS_MAX_PACKET_SIZE]; | ||
306 | + int32_t nbBytes; | ||
307 | + int32_t err; | ||
308 | + | ||
309 | + /*! Attention: you can use "ffmpeg -i xxx.mp3 -ar 16000 -ac 1 out.wav" and use opus-tools to generate opus file for test */ | ||
310 | + fin = fopen(WIDGET_SPEAKER_AUDIO_OPUS_FILE_NAME, "r"); | ||
311 | + if (fin == NULL) { | ||
312 | + fprintf(stderr, "failed to open input file: %s\n", strerror(errno)); | ||
313 | + return EXIT_FAILURE; | ||
314 | + } | ||
315 | + | ||
316 | + /* Create a new decoder state. */ | ||
317 | + decoder = opus_decoder_create(WIDGET_SPEAKER_AUDIO_OPUS_SAMPLE_RATE, WIDGET_SPEAKER_AUDIO_OPUS_CHANNELS, &err); | ||
318 | + if (err < 0) { | ||
319 | + fprintf(stderr, "failed to create decoder: %s\n", opus_strerror(err)); | ||
320 | + goto close_fin; | ||
321 | + } | ||
322 | + | ||
323 | + fout = fopen(WIDGET_SPEAKER_AUDIO_PCM_FILE_NAME, "a+"); | ||
324 | + if (fout == NULL) { | ||
325 | + fprintf(stderr, "failed to open output file: %s\n", strerror(errno)); | ||
326 | + goto close_fin; | ||
327 | + } | ||
328 | + | ||
329 | + while (1) { | ||
330 | + int i; | ||
331 | + unsigned char pcm_bytes[WIDGET_SPEAKER_AUDIO_OPUS_MAX_FRAME_SIZE * WIDGET_SPEAKER_AUDIO_OPUS_CHANNELS * 4] = {0}; | ||
332 | + int frame_size; | ||
333 | + | ||
334 | + /* Read a 16 bits/sample audio frame. */ | ||
335 | + nbBytes = fread(cbits, 1, s_decodeBitrate / WIDGET_SPEAKER_AUDIO_OPUS_DECODE_BITRATE_8KBPS * | ||
336 | + WIDGET_SPEAKER_AUDIO_OPUS_DECODE_FRAME_SIZE_8KBPS * 8, fin); | ||
337 | + | ||
338 | + /* Decode the data. In this example, frame_size will be constant because | ||
339 | + the encoder is using a constant frame size. However, that may not | ||
340 | + be the case for all encoders, so the decoder must always check | ||
341 | + the frame size returned. */ | ||
342 | + frame_size = opus_decode(decoder, cbits, nbBytes, out, WIDGET_SPEAKER_AUDIO_OPUS_MAX_FRAME_SIZE, 0); | ||
343 | + if (frame_size < 0) { | ||
344 | + fprintf(stderr, "decoder failed: %s\n", opus_strerror(frame_size)); | ||
345 | + goto close_fout; | ||
346 | + } | ||
347 | + | ||
348 | + /* Convert to little-endian ordering. */ | ||
349 | + for (i = 0; i < WIDGET_SPEAKER_AUDIO_OPUS_CHANNELS * frame_size; i++) { | ||
350 | + pcm_bytes[2 * i] = out[i] & 0xFF; | ||
351 | + pcm_bytes[2 * i + 1] = (out[i] >> 8) & 0xFF; | ||
352 | + } | ||
353 | + /* Write the decoded audio to file. */ | ||
354 | + fwrite(pcm_bytes, sizeof(short), frame_size * WIDGET_SPEAKER_AUDIO_OPUS_CHANNELS, fout); | ||
355 | +#ifdef ALSA_INSTALLED | ||
356 | + ZiyanTest_PcmPlay(pcm_bytes, frame_size * WIDGET_SPEAKER_AUDIO_OPUS_CHANNELS); | ||
357 | +#endif | ||
358 | + | ||
359 | + if (feof(fin)) | ||
360 | + break; | ||
361 | + } | ||
362 | + | ||
363 | + USER_LOG_INFO("Decode Finished..."); | ||
364 | + s_isDecodeFinished = true; | ||
365 | + | ||
366 | +decode_data_failed: | ||
367 | + opus_decoder_destroy(decoder); | ||
368 | +create_decoder_failed: | ||
369 | + fclose(fout); | ||
370 | +open_pcm_audio_failed: | ||
371 | + fclose(fin); | ||
372 | +#endif | ||
373 | + return EXIT_SUCCESS; | ||
374 | + | ||
375 | +#ifdef OPUS_INSTALLED | ||
376 | +close_fout: | ||
377 | + fclose(fout); | ||
378 | + | ||
379 | +close_fin: | ||
380 | + fclose(fin); | ||
381 | + | ||
382 | + return EXIT_FAILURE; | ||
383 | +#endif | ||
384 | + | ||
385 | +} | ||
386 | + | ||
387 | +static T_ZiyanReturnCode ZiyanTest_PlayAudioData(void) | ||
388 | +{ | ||
389 | + char cmdStr[128]; | ||
390 | + | ||
391 | + memset(cmdStr, 0, sizeof(cmdStr)); | ||
392 | + USER_LOG_INFO("Start Playing..."); | ||
393 | + | ||
394 | + snprintf(cmdStr, sizeof(cmdStr), "ffplay -nodisp -autoexit -ar 16000 -ac 1 -f s16le -i %s 2>/dev/null", | ||
395 | + WIDGET_SPEAKER_AUDIO_PCM_FILE_NAME); | ||
396 | + | ||
397 | + return ZiyanUserUtil_RunSystemCmd(cmdStr); | ||
398 | +} | ||
399 | + | ||
400 | +static T_ZiyanReturnCode ZiyanTest_PlayTtsData(void) | ||
401 | +{ | ||
402 | + FILE *txtFile; | ||
403 | + uint8_t data[WIDGET_SPEAKER_TTS_FILE_MAX_SIZE] = {0}; | ||
404 | + int32_t readLen; | ||
405 | + char cmdStr[WIDGET_SPEAKER_TTS_FILE_MAX_SIZE + 128]; | ||
406 | + T_ZiyanAircraftInfoBaseInfo aircraftInfoBaseInfo; | ||
407 | + T_ZiyanReturnCode returnCode; | ||
408 | + | ||
409 | + returnCode = ZiyanAircraftInfo_GetBaseInfo(&aircraftInfoBaseInfo); | ||
410 | + if (returnCode != ZIYAN_ERROR_SYSTEM_MODULE_CODE_SUCCESS) { | ||
411 | + USER_LOG_ERROR("get aircraft base info error"); | ||
412 | + return ZIYAN_ERROR_SYSTEM_MODULE_CODE_SYSTEM_ERROR; | ||
413 | + } | ||
414 | + | ||
415 | + if (aircraftInfoBaseInfo.aircraftType == ZIYAN_AIRCRAFT_TYPE_SHADOW_PLUS || | ||
416 | + aircraftInfoBaseInfo.aircraftType == ZIYAN_AIRCRAFT_TYPE_SHADOW_MAX) { | ||
417 | + return ZiyanTest_PlayAudioData(); | ||
418 | + } else { | ||
419 | + txtFile = fopen(WIDGET_SPEAKER_TTS_FILE_NAME, "r"); | ||
420 | + if (txtFile == NULL) { | ||
421 | + USER_LOG_ERROR("failed to open input file: %s\n", strerror(errno)); | ||
422 | + return EXIT_FAILURE; | ||
423 | + } | ||
424 | + | ||
425 | + readLen = fread(data, 1, WIDGET_SPEAKER_TTS_FILE_MAX_SIZE - 1, txtFile); | ||
426 | + if (readLen <= 0) { | ||
427 | + USER_LOG_ERROR("Read tts file failed, error code: %d", readLen); | ||
428 | + fclose(txtFile); | ||
429 | + return ZIYAN_ERROR_SYSTEM_MODULE_CODE_NOT_FOUND; | ||
430 | + } | ||
431 | + | ||
432 | + data[readLen] = '\0'; | ||
433 | + | ||
434 | + fclose(txtFile); | ||
435 | + | ||
436 | + USER_LOG_INFO("Read tts file success, len: %d", readLen); | ||
437 | + USER_LOG_INFO("Content: %s", data); | ||
438 | + | ||
439 | + memset(cmdStr, 0, sizeof(cmdStr)); | ||
440 | + | ||
441 | + SetSpeakerState(ZIYAN_WIDGET_SPEAKER_STATE_IN_TTS_CONVERSION); | ||
442 | + | ||
443 | +#if EKHO_INSTALLED | ||
444 | + /*! Attention: you can use other tts opensource function to convert txt to speech, example used ekho v7.5 */ | ||
445 | + snprintf(cmdStr, sizeof(cmdStr), " ekho %s -s 20 -p 20 -a 100 -o %s", data, | ||
446 | + WIDGET_SPEAKER_TTS_OUTPUT_FILE_NAME); | ||
447 | +#else | ||
448 | + USER_LOG_WARN( | ||
449 | + "Ekho is not installed, please visit https://www.eguidedog.net/ekho.php to install it or use other TTS tools to convert audio"); | ||
450 | +#endif | ||
451 | + ZiyanUserUtil_RunSystemCmd(cmdStr); | ||
452 | + | ||
453 | + SetSpeakerState(ZIYAN_WIDGET_SPEAKER_STATE_PLAYING); | ||
454 | + USER_LOG_INFO("Start TTS Playing..."); | ||
455 | + memset(cmdStr, 0, sizeof(cmdStr)); | ||
456 | + snprintf(cmdStr, sizeof(cmdStr), "ffplay -nodisp -autoexit -ar 16000 -ac 1 -f s16le -i %s 2>/dev/null", | ||
457 | + WIDGET_SPEAKER_TTS_OUTPUT_FILE_NAME); | ||
458 | + | ||
459 | + return ZiyanUserUtil_RunSystemCmd(cmdStr); | ||
460 | + } | ||
461 | +} | ||
462 | + | ||
463 | +static T_ZiyanReturnCode ZiyanTest_CheckFileMd5Sum(const char *path, uint8_t *buf, uint16_t size) | ||
464 | +{ | ||
465 | + MD5_CTX md5Ctx; | ||
466 | + uint32_t readFileTotalSize = 0; | ||
467 | + uint16_t readLen; | ||
468 | + T_ZiyanReturnCode returnCode; | ||
469 | + uint8_t readBuf[1024] = {0}; | ||
470 | + uint8_t md5Sum[16] = {0}; | ||
471 | + FILE *file = NULL;; | ||
472 | + | ||
473 | + UtilMd5_Init(&md5Ctx); | ||
474 | + | ||
475 | + file = fopen(path, "rb"); | ||
476 | + if (file == NULL) { | ||
477 | + USER_LOG_ERROR("Open tts file error."); | ||
478 | + return ZIYAN_ERROR_SYSTEM_MODULE_CODE_SYSTEM_ERROR; | ||
479 | + } | ||
480 | + | ||
481 | + while (1) { | ||
482 | + returnCode = fseek(file, readFileTotalSize, SEEK_SET); | ||
483 | + if (returnCode != 0) { | ||
484 | + USER_LOG_INFO("fseek file error"); | ||
485 | + } | ||
486 | + | ||
487 | + readLen = fread(readBuf, 1, sizeof(readBuf), file); | ||
488 | + if (readLen > 0) { | ||
489 | + readFileTotalSize += readLen; | ||
490 | + UtilMd5_Update(&md5Ctx, readBuf, readLen); | ||
491 | + } | ||
492 | + | ||
493 | + if (feof(file)) | ||
494 | + break; | ||
495 | + } | ||
496 | + | ||
497 | + UtilMd5_Final(&md5Ctx, md5Sum); | ||
498 | + fclose(file); | ||
499 | + | ||
500 | + if (size == sizeof(md5Sum)) { | ||
501 | + if (memcmp(md5Sum, buf, sizeof(md5Sum)) == 0) { | ||
502 | + USER_LOG_INFO("MD5 sum check success"); | ||
503 | + return ZIYAN_ERROR_SYSTEM_MODULE_CODE_SUCCESS; | ||
504 | + } else { | ||
505 | + return ZIYAN_ERROR_SYSTEM_MODULE_CODE_SYSTEM_ERROR; | ||
506 | + } | ||
507 | + } else { | ||
508 | + USER_LOG_ERROR("MD5 sum length error"); | ||
509 | + } | ||
510 | + | ||
511 | + return ZIYAN_ERROR_SYSTEM_MODULE_CODE_SUCCESS; | ||
512 | +} | ||
513 | + | ||
514 | +#endif | ||
515 | + | ||
516 | +static void SetSpeakerState(E_ZiyanWidgetSpeakerState speakerState) | ||
517 | +{ | ||
518 | + T_ZiyanReturnCode returnCode; | ||
519 | + T_ZiyanOsalHandler *osalHandler = ZiyanPlatform_GetOsalHandler(); | ||
520 | + | ||
521 | + returnCode = osalHandler->MutexLock(s_speakerMutex); | ||
522 | + if (returnCode != ZIYAN_ERROR_SYSTEM_MODULE_CODE_SUCCESS) { | ||
523 | + USER_LOG_ERROR("lock mutex error: 0x%08llX.", returnCode); | ||
524 | + } | ||
525 | + | ||
526 | + s_speakerState.state = speakerState; | ||
527 | + | ||
528 | + returnCode = osalHandler->MutexUnlock(s_speakerMutex); | ||
529 | + if (returnCode != ZIYAN_ERROR_SYSTEM_MODULE_CODE_SUCCESS) { | ||
530 | + USER_LOG_ERROR("unlock mutex error: 0x%08llX.", returnCode); | ||
531 | + } | ||
532 | +} | ||
533 | + | ||
534 | +static T_ZiyanReturnCode GetSpeakerState(T_ZiyanWidgetSpeakerState *speakerState) | ||
535 | +{ | ||
536 | + T_ZiyanReturnCode returnCode; | ||
537 | + T_ZiyanOsalHandler *osalHandler = ZiyanPlatform_GetOsalHandler(); | ||
538 | + | ||
539 | + returnCode = osalHandler->MutexLock(s_speakerMutex); | ||
540 | + if (returnCode != ZIYAN_ERROR_SYSTEM_MODULE_CODE_SUCCESS) { | ||
541 | + USER_LOG_ERROR("lock mutex error: 0x%08llX.", returnCode); | ||
542 | + return returnCode; | ||
543 | + } | ||
544 | + | ||
545 | + *speakerState = s_speakerState; | ||
546 | + | ||
547 | + returnCode = osalHandler->MutexUnlock(s_speakerMutex); | ||
548 | + if (returnCode != ZIYAN_ERROR_SYSTEM_MODULE_CODE_SUCCESS) { | ||
549 | + USER_LOG_ERROR("unlock mutex error: 0x%08llX.", returnCode); | ||
550 | + return returnCode; | ||
551 | + } | ||
552 | + | ||
553 | + return ZIYAN_ERROR_SYSTEM_MODULE_CODE_SUCCESS; | ||
554 | +} | ||
555 | + | ||
556 | +static T_ZiyanReturnCode SetWorkMode(E_ZiyanWidgetSpeakerWorkMode workMode) | ||
557 | +{ | ||
558 | + T_ZiyanReturnCode returnCode; | ||
559 | + T_ZiyanOsalHandler *osalHandler = ZiyanPlatform_GetOsalHandler(); | ||
560 | + | ||
561 | + returnCode = osalHandler->MutexLock(s_speakerMutex); | ||
562 | + if (returnCode != ZIYAN_ERROR_SYSTEM_MODULE_CODE_SUCCESS) { | ||
563 | + USER_LOG_ERROR("lock mutex error: 0x%08llX.", returnCode); | ||
564 | + return returnCode; | ||
565 | + } | ||
566 | + | ||
567 | + USER_LOG_INFO("Set widget speaker work mode: %d", workMode); | ||
568 | + s_speakerState.workMode = workMode; | ||
569 | + | ||
570 | + returnCode = osalHandler->MutexUnlock(s_speakerMutex); | ||
571 | + if (returnCode != ZIYAN_ERROR_SYSTEM_MODULE_CODE_SUCCESS) { | ||
572 | + USER_LOG_ERROR("unlock mutex error: 0x%08llX.", returnCode); | ||
573 | + return returnCode; | ||
574 | + } | ||
575 | + | ||
576 | + return ZIYAN_ERROR_SYSTEM_MODULE_CODE_SUCCESS; | ||
577 | +} | ||
578 | + | ||
579 | +static T_ZiyanReturnCode SetPlayMode(E_ZiyanWidgetSpeakerPlayMode playMode) | ||
580 | +{ | ||
581 | + T_ZiyanReturnCode returnCode; | ||
582 | + T_ZiyanOsalHandler *osalHandler = ZiyanPlatform_GetOsalHandler(); | ||
583 | + | ||
584 | + returnCode = osalHandler->MutexLock(s_speakerMutex); | ||
585 | + if (returnCode != ZIYAN_ERROR_SYSTEM_MODULE_CODE_SUCCESS) { | ||
586 | + USER_LOG_ERROR("lock mutex error: 0x%08llX.", returnCode); | ||
587 | + return returnCode; | ||
588 | + } | ||
589 | + | ||
590 | + USER_LOG_INFO("Set widget speaker play mode: %d", playMode); | ||
591 | + s_speakerState.playMode = playMode; | ||
592 | + | ||
593 | + returnCode = osalHandler->MutexUnlock(s_speakerMutex); | ||
594 | + if (returnCode != ZIYAN_ERROR_SYSTEM_MODULE_CODE_SUCCESS) { | ||
595 | + USER_LOG_ERROR("unlock mutex error: 0x%08llX.", returnCode); | ||
596 | + return returnCode; | ||
597 | + } | ||
598 | + | ||
599 | + return ZIYAN_ERROR_SYSTEM_MODULE_CODE_SUCCESS; | ||
600 | +} | ||
601 | + | ||
602 | +static T_ZiyanReturnCode StartPlay(void) | ||
603 | +{ | ||
604 | + uint32_t pid; | ||
605 | + T_ZiyanOsalHandler *osalHandler = ZiyanPlatform_GetOsalHandler(); | ||
606 | + | ||
607 | +#ifdef SYSTEM_ARCH_LINUX | ||
608 | + pid = ZiyanTest_GetVoicePlayProcessId(); | ||
609 | + if (pid != 0) { | ||
610 | + ZiyanTest_KillVoicePlayProcess(pid); | ||
611 | + } | ||
612 | +#endif | ||
613 | + | ||
614 | + osalHandler->TaskSleepMs(5); | ||
615 | + USER_LOG_INFO("Start widget speaker play"); | ||
616 | + SetSpeakerState(ZIYAN_WIDGET_SPEAKER_STATE_PLAYING); | ||
617 | + | ||
618 | + return ZIYAN_ERROR_SYSTEM_MODULE_CODE_SUCCESS; | ||
619 | +} | ||
620 | + | ||
621 | +static T_ZiyanReturnCode StopPlay(void) | ||
622 | +{ | ||
623 | + T_ZiyanReturnCode returnCode; | ||
624 | + T_ZiyanOsalHandler *osalHandler = ZiyanPlatform_GetOsalHandler(); | ||
625 | + uint32_t pid; | ||
626 | + | ||
627 | + returnCode = osalHandler->MutexLock(s_speakerMutex); | ||
628 | + if (returnCode != ZIYAN_ERROR_SYSTEM_MODULE_CODE_SUCCESS) { | ||
629 | + USER_LOG_ERROR("lock mutex error: 0x%08llX.", returnCode); | ||
630 | + return returnCode; | ||
631 | + } | ||
632 | + | ||
633 | + USER_LOG_INFO("Stop widget speaker play"); | ||
634 | + s_speakerState.state = ZIYAN_WIDGET_SPEAKER_STATE_IDEL; | ||
635 | + | ||
636 | +#ifdef SYSTEM_ARCH_LINUX | ||
637 | + pid = ZiyanTest_GetVoicePlayProcessId(); | ||
638 | + if (pid != 0) { | ||
639 | + ZiyanTest_KillVoicePlayProcess(pid); | ||
640 | + } | ||
641 | +#endif | ||
642 | + | ||
643 | + returnCode = osalHandler->MutexUnlock(s_speakerMutex); | ||
644 | + if (returnCode != ZIYAN_ERROR_SYSTEM_MODULE_CODE_SUCCESS) { | ||
645 | + USER_LOG_ERROR("unlock mutex error: 0x%08llX.", returnCode); | ||
646 | + return returnCode; | ||
647 | + } | ||
648 | + | ||
649 | + return ZIYAN_ERROR_SYSTEM_MODULE_CODE_SUCCESS; | ||
650 | +} | ||
651 | + | ||
652 | +static T_ZiyanReturnCode SetVolume(uint8_t volume) | ||
653 | +{ | ||
654 | + T_ZiyanReturnCode returnCode; | ||
655 | + T_ZiyanOsalHandler *osalHandler = ZiyanPlatform_GetOsalHandler(); | ||
656 | + char cmdStr[128]; | ||
657 | + int32_t ret = 0; | ||
658 | + float realVolume; | ||
659 | + | ||
660 | + returnCode = osalHandler->MutexLock(s_speakerMutex); | ||
661 | + if (returnCode != ZIYAN_ERROR_SYSTEM_MODULE_CODE_SUCCESS) { | ||
662 | + USER_LOG_ERROR("lock mutex error: 0x%08llX.", returnCode); | ||
663 | + return returnCode; | ||
664 | + } | ||
665 | + | ||
666 | + realVolume = 1.5f * (float) volume; | ||
667 | + s_speakerState.volume = volume; | ||
668 | + | ||
669 | + USER_LOG_INFO("Set widget speaker volume: %d", volume); | ||
670 | + | ||
671 | +#ifdef PLATFORM_ARCH_x86_64 | ||
672 | + snprintf(cmdStr, sizeof(cmdStr), "pactl list | grep %s -q", WIDGET_SPEAKER_USB_AUDIO_DEVICE_NAME); | ||
673 | + ret = system(cmdStr); | ||
674 | + if (ret == ZIYAN_ERROR_SYSTEM_MODULE_CODE_SUCCESS) { | ||
675 | + memset(cmdStr, 0, sizeof(cmdStr)); | ||
676 | + snprintf(cmdStr, sizeof(cmdStr), "pactl set-sink-volume %s %d%%", WIDGET_SPEAKER_USB_AUDIO_DEVICE_NAME, | ||
677 | + (int32_t) realVolume); | ||
678 | + | ||
679 | + returnCode = ZiyanUserUtil_RunSystemCmd(cmdStr); | ||
680 | + if (returnCode != ZIYAN_ERROR_SYSTEM_MODULE_CODE_SUCCESS) { | ||
681 | + USER_LOG_ERROR("Set widget speaker volume error: %d", ret); | ||
682 | + } | ||
683 | + } else { | ||
684 | + USER_LOG_WARN("No audio device found, please add audio device and init speaker volume here."); | ||
685 | + } | ||
686 | +#else | ||
687 | + USER_LOG_WARN("No audio device found, please add audio device and init speaker volume here!!!"); | ||
688 | +#endif | ||
689 | + | ||
690 | + returnCode = osalHandler->MutexUnlock(s_speakerMutex); | ||
691 | + if (returnCode != ZIYAN_ERROR_SYSTEM_MODULE_CODE_SUCCESS) { | ||
692 | + USER_LOG_ERROR("unlock mutex error: 0x%08llX.", returnCode); | ||
693 | + return returnCode; | ||
694 | + } | ||
695 | + | ||
696 | + return ZIYAN_ERROR_SYSTEM_MODULE_CODE_SUCCESS; | ||
697 | +} | ||
698 | + | ||
699 | +static T_ZiyanReturnCode ReceiveTtsData(E_ZiyanWidgetTransmitDataEvent event, | ||
700 | + uint32_t offset, uint8_t *buf, uint16_t size) | ||
701 | +{ | ||
702 | + uint16_t writeLen; | ||
703 | + T_ZiyanReturnCode returnCode; | ||
704 | + | ||
705 | + if (event == ZIYAN_WIDGET_TRANSMIT_DATA_EVENT_START) { | ||
706 | + USER_LOG_INFO("Create tts file."); | ||
707 | +#ifdef SYSTEM_ARCH_LINUX | ||
708 | + s_ttsFile = fopen(WIDGET_SPEAKER_TTS_FILE_NAME, "wb"); | ||
709 | + if (s_ttsFile == NULL) { | ||
710 | + USER_LOG_ERROR("Open tts file error."); | ||
711 | + } | ||
712 | +#endif | ||
713 | + if (s_speakerState.state != ZIYAN_WIDGET_SPEAKER_STATE_PLAYING) { | ||
714 | + SetSpeakerState(ZIYAN_WIDGET_SPEAKER_STATE_TRANSMITTING); | ||
715 | + } | ||
716 | + } else if (event == ZIYAN_WIDGET_TRANSMIT_DATA_EVENT_TRANSMIT) { | ||
717 | + USER_LOG_INFO("Transmit tts file, offset: %d, size: %d", offset, size); | ||
718 | +#ifdef SYSTEM_ARCH_LINUX | ||
719 | + if (s_ttsFile != NULL) { | ||
720 | + fseek(s_ttsFile, offset, SEEK_SET); | ||
721 | + writeLen = fwrite(buf, 1, size, s_ttsFile); | ||
722 | + if (writeLen != size) { | ||
723 | + USER_LOG_ERROR("Write tts file error %d", writeLen); | ||
724 | + } | ||
725 | + } | ||
726 | +#endif | ||
727 | + if (s_speakerState.state != ZIYAN_WIDGET_SPEAKER_STATE_PLAYING) { | ||
728 | + SetSpeakerState(ZIYAN_WIDGET_SPEAKER_STATE_TRANSMITTING); | ||
729 | + } | ||
730 | + } else if (event == ZIYAN_WIDGET_TRANSMIT_DATA_EVENT_FINISH) { | ||
731 | + USER_LOG_INFO("Close tts file."); | ||
732 | +#ifdef SYSTEM_ARCH_LINUX | ||
733 | + if (s_ttsFile != NULL) { | ||
734 | + fclose(s_ttsFile); | ||
735 | + s_ttsFile = NULL; | ||
736 | + } | ||
737 | + | ||
738 | + returnCode = ZiyanTest_CheckFileMd5Sum(WIDGET_SPEAKER_TTS_FILE_NAME, buf, size); | ||
739 | + if (returnCode != ZIYAN_ERROR_SYSTEM_MODULE_CODE_SUCCESS) { | ||
740 | + USER_LOG_ERROR("File md5 sum check failed"); | ||
741 | + } | ||
742 | +#endif | ||
743 | + if (s_speakerState.state != ZIYAN_WIDGET_SPEAKER_STATE_PLAYING) { | ||
744 | + SetSpeakerState(ZIYAN_WIDGET_SPEAKER_STATE_IDEL); | ||
745 | + } | ||
746 | + } | ||
747 | + | ||
748 | + return ZIYAN_ERROR_SYSTEM_MODULE_CODE_SUCCESS; | ||
749 | +} | ||
750 | + | ||
751 | +static T_ZiyanReturnCode ReceiveAudioData(E_ZiyanWidgetTransmitDataEvent event, | ||
752 | + uint32_t offset, uint8_t *buf, uint16_t size) | ||
753 | +{ | ||
754 | + uint16_t writeLen; | ||
755 | + T_ZiyanReturnCode returnCode; | ||
756 | + T_ZiyanWidgetTransDataContent transDataContent = {0}; | ||
757 | + | ||
758 | + if (event == ZIYAN_WIDGET_TRANSMIT_DATA_EVENT_START) { | ||
759 | + s_isDecodeFinished = false; | ||
760 | +#ifdef SYSTEM_ARCH_LINUX | ||
761 | + USER_LOG_INFO("Create voice file."); | ||
762 | + s_audioFile = fopen(WIDGET_SPEAKER_AUDIO_OPUS_FILE_NAME, "wb"); | ||
763 | + if (s_audioFile == NULL) { | ||
764 | + USER_LOG_ERROR("Create tts file error."); | ||
765 | + } | ||
766 | + if (s_speakerState.state != ZIYAN_WIDGET_SPEAKER_STATE_PLAYING) { | ||
767 | + SetSpeakerState(ZIYAN_WIDGET_SPEAKER_STATE_TRANSMITTING); | ||
768 | + } | ||
769 | +#endif | ||
770 | + | ||
771 | + memcpy(&transDataContent, buf, size); | ||
772 | + s_decodeBitrate = transDataContent.transDataStartContent.fileDecodeBitrate; | ||
773 | + USER_LOG_INFO("Create voice file: %s, decoder bitrate: %d.", transDataContent.transDataStartContent.fileName, | ||
774 | + transDataContent.transDataStartContent.fileDecodeBitrate); | ||
775 | + } else if (event == ZIYAN_WIDGET_TRANSMIT_DATA_EVENT_TRANSMIT) { | ||
776 | + USER_LOG_INFO("Transmit voice file, offset: %d, size: %d", offset, size); | ||
777 | +#ifdef SYSTEM_ARCH_LINUX | ||
778 | + if (s_audioFile != NULL) { | ||
779 | + fseek(s_audioFile, offset, SEEK_SET); | ||
780 | + writeLen = fwrite(buf, 1, size, s_audioFile); | ||
781 | + if (writeLen != size) { | ||
782 | + USER_LOG_ERROR("Write tts file error %d", writeLen); | ||
783 | + } | ||
784 | + } | ||
785 | +#endif | ||
786 | + if (s_speakerState.state != ZIYAN_WIDGET_SPEAKER_STATE_PLAYING) { | ||
787 | + SetSpeakerState(ZIYAN_WIDGET_SPEAKER_STATE_TRANSMITTING); | ||
788 | + } | ||
789 | + } else if (event == ZIYAN_WIDGET_TRANSMIT_DATA_EVENT_FINISH) { | ||
790 | + USER_LOG_INFO("Close voice file."); | ||
791 | + if (s_audioFile != NULL) { | ||
792 | + fclose(s_audioFile); | ||
793 | + s_audioFile = NULL; | ||
794 | + } | ||
795 | + | ||
796 | +#ifdef SYSTEM_ARCH_LINUX | ||
797 | + returnCode = ZiyanTest_CheckFileMd5Sum(WIDGET_SPEAKER_AUDIO_OPUS_FILE_NAME, buf, size); | ||
798 | + if (returnCode != ZIYAN_ERROR_SYSTEM_MODULE_CODE_SUCCESS) { | ||
799 | + USER_LOG_ERROR("File md5 sum check failed"); | ||
800 | + return ZIYAN_ERROR_SYSTEM_MODULE_CODE_SYSTEM_ERROR; | ||
801 | + } | ||
802 | +#endif | ||
803 | + if (s_speakerState.state != ZIYAN_WIDGET_SPEAKER_STATE_PLAYING) { | ||
804 | + SetSpeakerState(ZIYAN_WIDGET_SPEAKER_STATE_IDEL); | ||
805 | + } | ||
806 | +#ifdef SYSTEM_ARCH_LINUX | ||
807 | + ZiyanTest_DecodeAudioData(); | ||
808 | +#endif | ||
809 | + } | ||
810 | + | ||
811 | + return ZIYAN_ERROR_SYSTEM_MODULE_CODE_SUCCESS; | ||
812 | +} | ||
813 | + | ||
814 | +#ifdef SYSTEM_ARCH_LINUX | ||
815 | +#ifndef __CC_ARM | ||
816 | +#pragma GCC diagnostic push | ||
817 | +#pragma GCC diagnostic ignored "-Wmissing-noreturn" | ||
818 | +#pragma GCC diagnostic ignored "-Wreturn-type" | ||
819 | +#endif | ||
820 | + | ||
821 | +static void *ZiyanTest_WidgetSpeakerTask(void *arg) | ||
822 | +{ | ||
823 | + T_ZiyanReturnCode ziyanReturnCode; | ||
824 | + T_ZiyanOsalHandler *osalHandler = ZiyanPlatform_GetOsalHandler(); | ||
825 | + | ||
826 | +#ifdef ALSA_INSTALLED | ||
827 | + ZiyanTest_AsoundInit(); | ||
828 | +#endif | ||
829 | + | ||
830 | + USER_UTIL_UNUSED(arg); | ||
831 | + | ||
832 | + while (1) { | ||
833 | + osalHandler->TaskSleepMs(10); | ||
834 | + | ||
835 | + if (s_speakerState.state == ZIYAN_WIDGET_SPEAKER_STATE_PLAYING) { | ||
836 | + if (s_speakerState.playMode == ZIYAN_WIDGET_SPEAKER_PLAY_MODE_LOOP_PLAYBACK) { | ||
837 | + if (s_speakerState.workMode == ZIYAN_WIDGET_SPEAKER_WORK_MODE_VOICE) { | ||
838 | + USER_LOG_DEBUG("Waiting opus decoder finished..."); | ||
839 | + while (s_isDecodeFinished == false) { | ||
840 | + osalHandler->TaskSleepMs(1); | ||
841 | + } | ||
842 | + ziyanReturnCode = ZiyanTest_PlayAudioData(); | ||
843 | + if (ziyanReturnCode != ZIYAN_ERROR_SYSTEM_MODULE_CODE_SUCCESS) { | ||
844 | + USER_LOG_ERROR("Play audio data failed, error: 0x%08llX.", ziyanReturnCode); | ||
845 | + } | ||
846 | + } else { | ||
847 | + ziyanReturnCode = ZiyanTest_PlayTtsData(); | ||
848 | + if (ziyanReturnCode != ZIYAN_ERROR_SYSTEM_MODULE_CODE_SUCCESS) { | ||
849 | + USER_LOG_ERROR("Play tts data failed, error: 0x%08llX.", ziyanReturnCode); | ||
850 | + } | ||
851 | + } | ||
852 | + osalHandler->TaskSleepMs(1000); | ||
853 | + } else { | ||
854 | + if (s_speakerState.workMode == ZIYAN_WIDGET_SPEAKER_WORK_MODE_VOICE) { | ||
855 | + USER_LOG_DEBUG("Waiting opus decoder finished..."); | ||
856 | + while (s_isDecodeFinished == false) { | ||
857 | + osalHandler->TaskSleepMs(1); | ||
858 | + } | ||
859 | + ziyanReturnCode = ZiyanTest_PlayAudioData(); | ||
860 | + if (ziyanReturnCode != ZIYAN_ERROR_SYSTEM_MODULE_CODE_SUCCESS) { | ||
861 | + USER_LOG_ERROR("Play audio data failed, error: 0x%08llX.", ziyanReturnCode); | ||
862 | + } | ||
863 | + } else { | ||
864 | + ziyanReturnCode = ZiyanTest_PlayTtsData(); | ||
865 | + if (ziyanReturnCode != ZIYAN_ERROR_SYSTEM_MODULE_CODE_SUCCESS) { | ||
866 | + USER_LOG_ERROR("Play tts data failed, error: 0x%08llX.", ziyanReturnCode); | ||
867 | + } | ||
868 | + } | ||
869 | + | ||
870 | + ziyanReturnCode = osalHandler->MutexLock(s_speakerMutex); | ||
871 | + if (ziyanReturnCode != ZIYAN_ERROR_SYSTEM_MODULE_CODE_SUCCESS) { | ||
872 | + USER_LOG_ERROR("lock mutex error: 0x%08llX.", ziyanReturnCode); | ||
873 | + } | ||
874 | + | ||
875 | + if (s_speakerState.playMode == ZIYAN_WIDGET_SPEAKER_PLAY_MODE_SINGLE_PLAY) { | ||
876 | + s_speakerState.state = ZIYAN_WIDGET_SPEAKER_STATE_IDEL; | ||
877 | + } | ||
878 | + | ||
879 | + ziyanReturnCode = osalHandler->MutexUnlock(s_speakerMutex); | ||
880 | + if (ziyanReturnCode != ZIYAN_ERROR_SYSTEM_MODULE_CODE_SUCCESS) { | ||
881 | + USER_LOG_ERROR("unlock mutex error: 0x%08llX.", ziyanReturnCode); | ||
882 | + } | ||
883 | + } | ||
884 | + } | ||
885 | + } | ||
886 | +} | ||
887 | + | ||
888 | +#ifndef __CC_ARM | ||
889 | +#pragma GCC diagnostic pop | ||
890 | +#endif | ||
891 | +#endif | ||
892 | + | ||
893 | +/****************** (C) COPYRIGHT ZIYAN Innovations *****END OF FILE****/ |
1 | +/** | ||
2 | + ******************************************************************** | ||
3 | + * @file test_widget_speaker.h | ||
4 | + * @brief This is the header file for "test_widget_speaker.c", defining the structure and | ||
5 | + * (exported) function prototypes. | ||
6 | + * | ||
7 | + * @copyright (c) 2018 ZIYAN. All rights reserved. | ||
8 | + * | ||
9 | + * All information contained herein is, and remains, the property of ZIYAN. | ||
10 | + * The intellectual and technical concepts contained herein are proprietary | ||
11 | + * to ZIYAN 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 ZIYAN. | ||
16 | + * | ||
17 | + * If you receive this source code without ZIYAN’s authorization, you may not | ||
18 | + * further disseminate the information, and you must immediately remove the | ||
19 | + * source code and notify ZIYAN of its removal. ZIYAN 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_WIDGET_SPEAKER_H | ||
28 | +#define TEST_WIDGET_SPEAKER_H | ||
29 | + | ||
30 | +/* Includes ------------------------------------------------------------------*/ | ||
31 | +#include "ziyan_widget.h" | ||
32 | + | ||
33 | +#ifdef __cplusplus | ||
34 | +extern "C" { | ||
35 | +#endif | ||
36 | + | ||
37 | + | ||
38 | +/* Exported constants --------------------------------------------------------*/ | ||
39 | +T_ZiyanReturnCode ZiyanTest_WidgetSpeakerStartService(void); | ||
40 | + | ||
41 | +/* Exported types ------------------------------------------------------------*/ | ||
42 | + | ||
43 | +/* Exported functions --------------------------------------------------------*/ | ||
44 | + | ||
45 | +#ifdef __cplusplus | ||
46 | +} | ||
47 | +#endif | ||
48 | + | ||
49 | +#endif // TEST_WIDGET_SPEAKER_H | ||
50 | +/************************ (C) COPYRIGHT ZIYAN Innovations *******END OF FILE******/ |
@@ -6,8 +6,8 @@ | @@ -6,8 +6,8 @@ | ||
6 | #include "MediaProc/MediaProc.h" | 6 | #include "MediaProc/MediaProc.h" |
7 | 7 | ||
8 | // #include "camera_emu/test_payload_cam_emu_base.h" | 8 | // #include "camera_emu/test_payload_cam_emu_base.h" |
9 | -// #include "widget/test_widget.h" | ||
10 | -// #include "widget/test_widget_speaker.h" | 9 | +#include "widget/test_widget.h" |
10 | +#include "widget/test_widget_speaker.h" | ||
11 | // #include "data_transmission/test_data_transmission.h" | 11 | // #include "data_transmission/test_data_transmission.h" |
12 | 12 | ||
13 | #define VIDEO_FRAME_MAX_COUNT 18000 //视频最大帧数18000帧 | 13 | #define VIDEO_FRAME_MAX_COUNT 18000 //视频最大帧数18000帧 |
@@ -436,24 +436,24 @@ unsigned int old_command_timeMS = 0; | @@ -436,24 +436,24 @@ unsigned int old_command_timeMS = 0; | ||
436 | 436 | ||
437 | 437 | ||
438 | 438 | ||
439 | -// /********************************************************************************************* | ||
440 | -// * | ||
441 | -// * 拓展接口 : 控件相关 | ||
442 | -// * | ||
443 | -// *************************************************************************************************/ | ||
444 | -// T_DjiReturnCode Get_RealTimeVoiceMode(int *mode) | ||
445 | -// { | ||
446 | -// if ( Get_Opus_PlayMode()==1 )//播放模式 为实时育英中 | ||
447 | -// { | ||
448 | -// *mode = JZ_FLAGCODE_ON; | ||
449 | -// } | ||
450 | -// else | ||
451 | -// { | ||
452 | -// *mode = JZ_FLAGCODE_OFF; | ||
453 | -// } | 439 | +/********************************************************************************************* |
440 | + * | ||
441 | + * 拓展接口 : 控件相关 | ||
442 | + * | ||
443 | +*************************************************************************************************/ | ||
444 | +T_JZsdkReturnCode Get_RealTimeVoiceMode(int *mode) | ||
445 | +{ | ||
446 | + if ( Get_Opus_PlayMode()==1 )//播放模式 为实时育英中 | ||
447 | + { | ||
448 | + *mode = JZ_FLAGCODE_ON; | ||
449 | + } | ||
450 | + else | ||
451 | + { | ||
452 | + *mode = JZ_FLAGCODE_OFF; | ||
453 | + } | ||
454 | 454 | ||
455 | -// return JZ_ERROR_SYSTEM_MODULE_CODE_SUCCESS; | ||
456 | -// } | 455 | + return JZ_ERROR_SYSTEM_MODULE_CODE_SUCCESS; |
456 | +} | ||
457 | 457 | ||
458 | 458 | ||
459 | 459 | ||
@@ -474,11 +474,11 @@ T_JZsdkReturnCode Zy_JZsdkToPsdk_ExpnasionInit() | @@ -474,11 +474,11 @@ T_JZsdkReturnCode Zy_JZsdkToPsdk_ExpnasionInit() | ||
474 | T_JZsdkToPsdkHandler handler = { | 474 | T_JZsdkToPsdkHandler handler = { |
475 | .low_data_tran = NULL, | 475 | .low_data_tran = NULL, |
476 | .push_DJIH264Frame_to_plane = NULL, | 476 | .push_DJIH264Frame_to_plane = NULL, |
477 | - .Set_UI_Widget_Value = NULL, | 477 | + .Set_UI_Widget_Value = set_wideget_value, |
478 | .Set_UI_SpeakerWidget_PlayState = NULL, | 478 | .Set_UI_SpeakerWidget_PlayState = NULL, |
479 | .Set_UI_SpeakerWidget_LoopMode = NULL, | 479 | .Set_UI_SpeakerWidget_LoopMode = NULL, |
480 | .Set_UI_SpeakerWidget_Volume = NULL, | 480 | .Set_UI_SpeakerWidget_Volume = NULL, |
481 | - .Get_UI_SpeakerWidget_RealTimeVoiceMode = NULL, | 481 | + .Get_UI_SpeakerWidget_RealTimeVoiceMode = Get_RealTimeVoiceMode, |
482 | }; | 482 | }; |
483 | 483 | ||
484 | if(ExpansionApi_JZsdkToPsdk_Init(handler) != JZ_ERROR_SYSTEM_MODULE_CODE_SUCCESS) | 484 | if(ExpansionApi_JZsdkToPsdk_Init(handler) != JZ_ERROR_SYSTEM_MODULE_CODE_SUCCESS) |
@@ -66,8 +66,8 @@ typedef struct { | @@ -66,8 +66,8 @@ typedef struct { | ||
66 | } T_ThreadAttribute; | 66 | } T_ThreadAttribute; |
67 | 67 | ||
68 | /* Private values -------------------------------------------------------------*/ | 68 | /* Private values -------------------------------------------------------------*/ |
69 | -static FILE *s_djiLogFile; | ||
70 | -static FILE *s_djiLogFileCnt; | 69 | +static FILE *s_ziyanLogFile; |
70 | +static FILE *s_ziyanLogFileCnt; | ||
71 | static pthread_t s_monitorThread = 0; | 71 | static pthread_t s_monitorThread = 0; |
72 | 72 | ||
73 | /* Private functions declaration ---------------------------------------------*/ | 73 | /* Private functions declaration ---------------------------------------------*/ |
@@ -231,7 +231,7 @@ int main(int argc, char **argv) | @@ -231,7 +231,7 @@ int main(int argc, char **argv) | ||
231 | #endif | 231 | #endif |
232 | 232 | ||
233 | // #ifdef CONFIG_MODULE_SAMPLE_XPORT_ON | 233 | // #ifdef CONFIG_MODULE_SAMPLE_XPORT_ON |
234 | -// if (aircraftInfoBaseInfo.djiAdapterType == ZIYAN_SDK_ADAPTER_TYPE_XPORT) { | 234 | +// if (aircraftInfoBaseInfo.ziyanAdapterType == ZIYAN_SDK_ADAPTER_TYPE_XPORT) { |
235 | // if (ZiyanTest_XPortStartService() != ZIYAN_ERROR_SYSTEM_MODULE_CODE_SUCCESS) { | 235 | // if (ZiyanTest_XPortStartService() != ZIYAN_ERROR_SYSTEM_MODULE_CODE_SUCCESS) { |
236 | // USER_LOG_ERROR("psdk xport init error"); | 236 | // USER_LOG_ERROR("psdk xport init error"); |
237 | // } | 237 | // } |
@@ -315,7 +315,6 @@ int main(int argc, char **argv) | @@ -315,7 +315,6 @@ int main(int argc, char **argv) | ||
315 | // #endif | 315 | // #endif |
316 | // } | 316 | // } |
317 | 317 | ||
318 | - | ||
319 | // /*!< Step 5: Tell the ZIYAN Pilot you are ready. */ | 318 | // /*!< Step 5: Tell the ZIYAN Pilot you are ready. */ |
320 | returnCode = ZiyanCore_ApplicationStart(); | 319 | returnCode = ZiyanCore_ApplicationStart(); |
321 | if (returnCode != ZIYAN_ERROR_SYSTEM_MODULE_CODE_SUCCESS) { | 320 | if (returnCode != ZIYAN_ERROR_SYSTEM_MODULE_CODE_SUCCESS) { |
@@ -516,7 +515,7 @@ static T_ZiyanReturnCode ZiyanUser_FillInUserInfo(T_ZiyanUserInfo *userInfo) | @@ -516,7 +515,7 @@ static T_ZiyanReturnCode ZiyanUser_FillInUserInfo(T_ZiyanUserInfo *userInfo) | ||
516 | !strcmp(USER_DEVELOPER_ACCOUNT, "your_developer_account") || | 515 | !strcmp(USER_DEVELOPER_ACCOUNT, "your_developer_account") || |
517 | !strcmp(USER_BAUD_RATE, "your_baud_rate")) { | 516 | !strcmp(USER_BAUD_RATE, "your_baud_rate")) { |
518 | USER_LOG_ERROR( | 517 | USER_LOG_ERROR( |
519 | - "Please fill in correct user information to 'samples/sample_c/platform/linux/manifold2/application/dji_sdk_app_info.h' file."); | 518 | + "Please fill in correct user information to 'samples/sample_c/platform/linux/manifold2/application/ziyan_sdk_app_info.h' file."); |
520 | sleep(1); | 519 | sleep(1); |
521 | return ZIYAN_ERROR_SYSTEM_MODULE_CODE_INVALID_PARAMETER; | 520 | return ZIYAN_ERROR_SYSTEM_MODULE_CODE_INVALID_PARAMETER; |
522 | } | 521 | } |
@@ -545,12 +544,12 @@ static T_ZiyanReturnCode ZiyanUser_LocalWrite(const uint8_t *data, uint16_t data | @@ -545,12 +544,12 @@ static T_ZiyanReturnCode ZiyanUser_LocalWrite(const uint8_t *data, uint16_t data | ||
545 | { | 544 | { |
546 | uint32_t realLen; | 545 | uint32_t realLen; |
547 | 546 | ||
548 | - if (s_djiLogFile == NULL) { | 547 | + if (s_ziyanLogFile == NULL) { |
549 | return ZIYAN_ERROR_SYSTEM_MODULE_CODE_UNKNOWN; | 548 | return ZIYAN_ERROR_SYSTEM_MODULE_CODE_UNKNOWN; |
550 | } | 549 | } |
551 | 550 | ||
552 | - realLen = fwrite(data, 1, dataLen, s_djiLogFile); | ||
553 | - fflush(s_djiLogFile); | 551 | + realLen = fwrite(data, 1, dataLen, s_ziyanLogFile); |
552 | + fflush(s_ziyanLogFile); | ||
554 | if (realLen == dataLen) { | 553 | if (realLen == dataLen) { |
555 | return ZIYAN_ERROR_SYSTEM_MODULE_CODE_SUCCESS; | 554 | return ZIYAN_ERROR_SYSTEM_MODULE_CODE_SUCCESS; |
556 | } else { | 555 | } else { |
@@ -560,7 +559,7 @@ static T_ZiyanReturnCode ZiyanUser_LocalWrite(const uint8_t *data, uint16_t data | @@ -560,7 +559,7 @@ static T_ZiyanReturnCode ZiyanUser_LocalWrite(const uint8_t *data, uint16_t data | ||
560 | 559 | ||
561 | static T_ZiyanReturnCode ZiyanUser_LocalWriteFsInit(const char *path) | 560 | static T_ZiyanReturnCode ZiyanUser_LocalWriteFsInit(const char *path) |
562 | { | 561 | { |
563 | - T_ZiyanReturnCode djiReturnCode = ZIYAN_ERROR_SYSTEM_MODULE_CODE_SUCCESS; | 562 | + T_ZiyanReturnCode ziyanReturnCode = ZIYAN_ERROR_SYSTEM_MODULE_CODE_SUCCESS; |
564 | char filePath[ZIYAN_LOG_PATH_MAX_SIZE]; | 563 | char filePath[ZIYAN_LOG_PATH_MAX_SIZE]; |
565 | char systemCmd[ZIYAN_SYSTEM_CMD_STR_MAX_SIZE]; | 564 | char systemCmd[ZIYAN_SYSTEM_CMD_STR_MAX_SIZE]; |
566 | char folderName[ZIYAN_LOG_FOLDER_NAME_MAX_SIZE]; | 565 | char folderName[ZIYAN_LOG_FOLDER_NAME_MAX_SIZE]; |
@@ -583,20 +582,20 @@ static T_ZiyanReturnCode ZiyanUser_LocalWriteFsInit(const char *path) | @@ -583,20 +582,20 @@ static T_ZiyanReturnCode ZiyanUser_LocalWriteFsInit(const char *path) | ||
583 | } | 582 | } |
584 | } | 583 | } |
585 | 584 | ||
586 | - s_djiLogFileCnt = fopen(ZIYAN_LOG_INDEX_FILE_NAME, "rb+"); | ||
587 | - if (s_djiLogFileCnt == NULL) { | ||
588 | - s_djiLogFileCnt = fopen(ZIYAN_LOG_INDEX_FILE_NAME, "wb+"); | ||
589 | - if (s_djiLogFileCnt == NULL) { | 585 | + s_ziyanLogFileCnt = fopen(ZIYAN_LOG_INDEX_FILE_NAME, "rb+"); |
586 | + if (s_ziyanLogFileCnt == NULL) { | ||
587 | + s_ziyanLogFileCnt = fopen(ZIYAN_LOG_INDEX_FILE_NAME, "wb+"); | ||
588 | + if (s_ziyanLogFileCnt == NULL) { | ||
590 | return ZIYAN_ERROR_SYSTEM_MODULE_CODE_SYSTEM_ERROR; | 589 | return ZIYAN_ERROR_SYSTEM_MODULE_CODE_SYSTEM_ERROR; |
591 | } | 590 | } |
592 | } else { | 591 | } else { |
593 | - ret = fseek(s_djiLogFileCnt, 0, SEEK_SET); | 592 | + ret = fseek(s_ziyanLogFileCnt, 0, SEEK_SET); |
594 | if (ret != 0) { | 593 | if (ret != 0) { |
595 | printf("Seek log count file error, ret: %d, errno: %d.\r\n", ret, errno); | 594 | printf("Seek log count file error, ret: %d, errno: %d.\r\n", ret, errno); |
596 | return ZIYAN_ERROR_SYSTEM_MODULE_CODE_SYSTEM_ERROR; | 595 | return ZIYAN_ERROR_SYSTEM_MODULE_CODE_SYSTEM_ERROR; |
597 | } | 596 | } |
598 | 597 | ||
599 | - ret = fread((uint16_t *) &logFileIndex, 1, sizeof(uint16_t), s_djiLogFileCnt); | 598 | + ret = fread((uint16_t *) &logFileIndex, 1, sizeof(uint16_t), s_ziyanLogFileCnt); |
600 | if (ret != sizeof(uint16_t)) { | 599 | if (ret != sizeof(uint16_t)) { |
601 | printf("Read log file index error.\r\n"); | 600 | printf("Read log file index error.\r\n"); |
602 | } | 601 | } |
@@ -605,27 +604,27 @@ static T_ZiyanReturnCode ZiyanUser_LocalWriteFsInit(const char *path) | @@ -605,27 +604,27 @@ static T_ZiyanReturnCode ZiyanUser_LocalWriteFsInit(const char *path) | ||
605 | currentLogFileIndex = logFileIndex; | 604 | currentLogFileIndex = logFileIndex; |
606 | logFileIndex++; | 605 | logFileIndex++; |
607 | 606 | ||
608 | - ret = fseek(s_djiLogFileCnt, 0, SEEK_SET); | 607 | + ret = fseek(s_ziyanLogFileCnt, 0, SEEK_SET); |
609 | if (ret != 0) { | 608 | if (ret != 0) { |
610 | printf("Seek log file error, ret: %d, errno: %d.\r\n", ret, errno); | 609 | printf("Seek log file error, ret: %d, errno: %d.\r\n", ret, errno); |
611 | return ZIYAN_ERROR_SYSTEM_MODULE_CODE_SYSTEM_ERROR; | 610 | return ZIYAN_ERROR_SYSTEM_MODULE_CODE_SYSTEM_ERROR; |
612 | } | 611 | } |
613 | 612 | ||
614 | - ret = fwrite((uint16_t *) &logFileIndex, 1, sizeof(uint16_t), s_djiLogFileCnt); | 613 | + ret = fwrite((uint16_t *) &logFileIndex, 1, sizeof(uint16_t), s_ziyanLogFileCnt); |
615 | if (ret != sizeof(uint16_t)) { | 614 | if (ret != sizeof(uint16_t)) { |
616 | printf("Write log file index error.\r\n"); | 615 | printf("Write log file index error.\r\n"); |
617 | - fclose(s_djiLogFileCnt); | 616 | + fclose(s_ziyanLogFileCnt); |
618 | return ZIYAN_ERROR_SYSTEM_MODULE_CODE_SYSTEM_ERROR; | 617 | return ZIYAN_ERROR_SYSTEM_MODULE_CODE_SYSTEM_ERROR; |
619 | } | 618 | } |
620 | 619 | ||
621 | - fclose(s_djiLogFileCnt); | 620 | + fclose(s_ziyanLogFileCnt); |
622 | 621 | ||
623 | sprintf(filePath, "%s_%04d_%04d%02d%02d_%02d-%02d-%02d.log", path, currentLogFileIndex, | 622 | sprintf(filePath, "%s_%04d_%04d%02d%02d_%02d-%02d-%02d.log", path, currentLogFileIndex, |
624 | localTime->tm_year + 1900, localTime->tm_mon + 1, localTime->tm_mday, | 623 | localTime->tm_year + 1900, localTime->tm_mon + 1, localTime->tm_mday, |
625 | localTime->tm_hour, localTime->tm_min, localTime->tm_sec); | 624 | localTime->tm_hour, localTime->tm_min, localTime->tm_sec); |
626 | 625 | ||
627 | - s_djiLogFile = fopen(filePath, "wb+"); | ||
628 | - if (s_djiLogFile == NULL) { | 626 | + s_ziyanLogFile = fopen(filePath, "wb+"); |
627 | + if (s_ziyanLogFile == NULL) { | ||
629 | USER_LOG_ERROR("Open filepath time error."); | 628 | USER_LOG_ERROR("Open filepath time error."); |
630 | return ZIYAN_ERROR_SYSTEM_MODULE_CODE_SYSTEM_ERROR; | 629 | return ZIYAN_ERROR_SYSTEM_MODULE_CODE_SYSTEM_ERROR; |
631 | } | 630 | } |
@@ -639,7 +638,7 @@ static T_ZiyanReturnCode ZiyanUser_LocalWriteFsInit(const char *path) | @@ -639,7 +638,7 @@ static T_ZiyanReturnCode ZiyanUser_LocalWriteFsInit(const char *path) | ||
639 | } | 638 | } |
640 | } | 639 | } |
641 | 640 | ||
642 | - return djiReturnCode; | 641 | + return ziyanReturnCode; |
643 | } | 642 | } |
644 | 643 | ||
645 | // #pragma GCC diagnostic push | 644 | // #pragma GCC diagnostic push |
-
请 注册 或 登录 后发表评论