媒体子系统
简介
该仓主要用于存放媒体子系统的源码信息,旨在为多媒体应用开发者开发者提供统一的开发接口,使得开发者可以专注于应用业务的开发,轻松使用多媒体的资源。
本次开源基于本仓代码信息将相关设备配置文件放入到test\lite\devini内,用户使用时将配置文件放入到开发板/data目录,通过该配置文件可以方便去适配sensor及分辨率帧率等能力。
多媒体子系统框架

多媒体子系统系统业务流程图

如上图,多媒体包括camera,recorder和player,camera提供yuv/rgb,jpeg以及H264,H265数据到共享内存surface中,recorder模块将surface中h264/h265数据和音频aac数据打包成mp4文件,player模块把mp4文件解复用成音频和视频数据,分别送入对应编码器解码,然后进行播放。
目录
表 1 轻量级多媒体子系统源代码目录结构
| 名称 | 描述 |
|---|---|
| foundation\multimedia\frameworks | 北向接口内部框架实现,包括audio,camera,player.recorder |
| foundation\multimedia\interfaces\kits | 北向接口对外头文件 |
| foundation\multimedia\services\media_lite | 北向接口底层服务实现 |
| foundation\multimedia\utils\lite | 北向接口通用模块实现 |
| foundation\multimedia\test\lite | 北向接口测试代码。 |
约束
- C++11版本或以上
- 目前支持3516dv300、3518ev300开发板,其中仅3516dv300支持播放功能
安装
- 请提前加载内核及相关驱动,参考内核及驱动子系统readme。
- 配置合适的配置文件,可以参考test/devini下配置文件,说明参见《配置文件说明文档》,当前仅支持imx335和imx327sensor,如果适配其他sensor可在开源社区中求助。
- 北向接口调用参见test下demo实现。
使用
开发者使用多媒体接口用于录像、预览和播放音视频等资源,使用这些资源前先创建camerakit组件对象,注册各种事件回调,这些事件回调是用户实现用来响应多媒体模块中事件响应的,之后调用创建camera就可以创建一个操作camera资源的对象,使用这个对象可以启动预览、录像或抓拍取流,及设置取流的相关参数。
例:下面是用户重写事件类的实例
1. /*
2. * Copyright (c) 2020 Huawei Device Co., Ltd.
3. * Licensed under the Apache License, Version 2.0 (the "License");
4. * you may not use this file except in compliance with the License.
5. * You may obtain a copy of the License at
6. *
7. * http://www.apache.org/licenses/LICENSE-2.0
8. *
9. * Unless required by applicable law or agreed to in writing, software
10. * distributed under the License is distributed on an "AS IS" BASIS,
11. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12. * See the License for the specific language governing permissions and
13. * limitations under the License.
14. */
16. #include "camera_kit.h"
17. #include "recorder.h"
19. #include <sys/time.h>
20. #include <algorithm>
21. #include <fstream>
22. #include <iostream>
23. #include <sstream>
25. using namespace std;
26. using namespace OHOS;
27. using namespace OHOS::Media;
29. static void SampleSaveCapture(const char *p, uint32_t size)
30. {
31. cout << "Start saving picture" << endl;
32. struct timeval tv;
33. gettimeofday(&tv, NULL);
34. struct tm *ltm = localtime(&tv.tv_sec);
35. if (ltm != nullptr) {
36. ostringstream ss("Capture_");
37. ss << "Capture" << ltm->tm_hour << "-" << ltm->tm_min << "-" << ltm->tm_sec << ".jpg";
39. ofstream pic("/sdcard/" + ss.str(), ofstream::out | ofstream::trunc);
40. cout << "write " << size << " bytes" << endl;
41. pic.write(p, size);
42. cout << "Saving picture end" << endl;
43. }
44. }
46. Recorder *SampleCreateRecorder()
47. {
48. int ret = 0;
49. int32_t sampleRate = 48000;
50. int32_t channelCount = 1;
51. AudioCodecFormat audioFormat = AAC_LC;
52. AudioSourceType inputSource = AUDIO_MIC;
53. int32_t audioEncodingBitRate = sampleRate;
54. VideoSourceType source = VIDEO_SOURCE_SURFACE_ES;
55. int32_t frameRate = 30;
56. float fps = 30;
57. int32_t rate = 4096;
58. int32_t sourceId = 0;
59. int32_t audioSourceId = 0;
60. int32_t width = 1920;
61. int32_t height = 1080;
62. VideoCodecFormat encoder;
63. encoder = HEVC;
64. width = 1920;
65. height = 1080;
66. Recorder *recorder = new Recorder();
67. if ((ret = recorder->SetVideoSource(source, sourceId)) != SUCCESS) {
68. cout << "SetVideoSource failed." << ret << endl;
69. delete recorder;
70. return nullptr;
71. }
72. if ((ret = recorder->SetVideoEncoder(sourceId, encoder)) != SUCCESS) {
73. cout << "SetVideoEncoder failed." << ret << endl;
74. delete recorder;
75. return nullptr;
76. }
77. if ((ret = recorder->SetVideoSize(sourceId, width, height)) != SUCCESS) {
78. cout << "SetVideoSize failed." << ret << endl;
79. delete recorder;
80. return nullptr;
81. }
82. if ((ret = recorder->SetVideoFrameRate(sourceId, frameRate)) != SUCCESS) {
83. cout << "SetVideoFrameRate failed." << ret << endl;
84. delete recorder;
85. return nullptr;
86. }
87. if ((ret = recorder->SetVideoEncodingBitRate(sourceId, rate)) != SUCCESS) {
88. cout << "SetVideoEncodingBitRate failed." << ret << endl;
89. delete recorder;
90. return nullptr;
91. }
92. if ((ret = recorder->SetCaptureRate(sourceId, frameRate)) != SUCCESS) {
93. cout << "SetCaptureRate failed." << ret << endl;
94. delete recorder;
95. return nullptr;
96. }
97. if ((ret = recorder->SetAudioSource(inputSource, audioSourceId)) != SUCCESS) {
98. cout << "SetAudioSource failed." << ret << endl;
99. delete recorder;
100. return nullptr;
101. }
102. if ((ret = recorder->SetAudioEncoder(audioSourceId, audioFormat)) != SUCCESS) {
103. cout << "SetAudioEncoder failed." << ret << endl;
104. delete recorder;
105. return nullptr;
106. }
107. if ((ret = recorder->SetAudioSampleRate(audioSourceId, sampleRate)) != SUCCESS) {
108. cout << "SetAudioSampleRate failed." << ret << endl;
109. delete recorder;
110. return nullptr;
111. }
112. if ((ret = recorder->SetAudioChannels(audioSourceId, channelCount)) != SUCCESS) {
113. cout << "SetAudioChannels failed." << ret << endl;
114. delete recorder;
115. return nullptr;
116. }
117. if ((ret = recorder->SetAudioEncodingBitRate(audioSourceId, audioEncodingBitRate)) != SUCCESS) {
118. cout << "SetAudioEncodingBitRate failed." << ret << endl;
119. delete recorder;
120. return nullptr;
121. }
122. return recorder;
123. }
125. class SampleFrameStateCallback : public FrameStateCallback {
126. void OnFrameFinished(Camera &camera, FrameConfig &fc, FrameResult &result) override
127. {
128. cout << "Receive frame complete inform." << endl;
129. if (fc.GetFrameConfigType() == FRAME_CONFIG_CAPTURE) {
130. cout << "Capture frame received." << endl;
131. list<Surface *> surfaceList = fc.GetSurfaces();
132. for (Surface *surface : surfaceList) {
133. SurfaceBuffer *buffer = surface->AcquireBuffer();
134. if (buffer != nullptr) {
135. char *virtAddr = static_cast<char *>(buffer->GetVirAddr());
136. if (virtAddr != nullptr) {
137. SampleSaveCapture(virtAddr, buffer->GetSize());
138. }
139. surface->ReleaseBuffer(buffer);
140. }
141. delete surface;
142. }
143. delete &fc;
144. }
145. }
146. };
148. class SampleCameraStateMng : public CameraStateCallback {
149. public:
150. SampleCameraStateMng() = delete;
151. SampleCameraStateMng(EventHandler &eventHdlr) : eventHdlr_(eventHdlr) {}
152. ~SampleCameraStateMng()
153. {
154. if (recorder_ != nullptr) {
155. recorder_->Release();
156. delete recorder_;
157. }
158. }
159. void OnCreated(Camera &c) override
160. {
161. cout << "Sample recv OnCreate camera." << endl;
162. auto config = CameraConfig::CreateCameraConfig();
163. config->SetFrameStateCallback(&fsCb_, &eventHdlr_);
164. c.Configure(*config);
165. cam_ = &c;
166. }
167. void OnCreateFailed(const std::string cameraId, int32_t errorCode) override {}
168. void OnReleased(Camera &c) override {}
170. void StartRecord()
171. {
172. int ret;
173. if (isRecording_) {
174. cout << "Camera is already recording." << endl;
175. return;
176. }
177. if (recorder_ == nullptr) {
178. recorder_ = SampleCreateRecorder();
179. }
180. if (recorder_ == nullptr) {
181. cout << "Recorder not available" << endl;
182. return;
183. }
184. string path = "/sdcard";
185. ret = recorder_->SetOutputPath(path);
186. if (ret != SUCCESS) {
187. cout << "SetOutputPath fialed :" << ret << std::endl;
188. return;
189. }
190. ret = recorder_->Prepare();
191. if (ret != SUCCESS) {
192. cout << "Prepare failed.=" << ret << endl;
193. return;
194. }
195. Surface *surface = (recorder_->GetSurface(0)).get();
196. surface->SetWidthAndHeight(1920, 1080);
197. surface->SetQueueSize(3);
198. surface->SetSize(1024 * 1024);
199. FrameConfig *fc = new FrameConfig(FRAME_CONFIG_RECORD);
200. fc->AddSurface(*surface);
201. ret = recorder_->Start();
202. if (ret != SUCCESS) {
203. delete fc;
204. cout << "recorder start failed. ret=" << ret << endl;
205. return;
206. }
207. ret = cam_->TriggerLoopingCapture(*fc);
208. if (ret != 0) {
209. delete fc;
210. cout << "camera start recording failed. ret=" << ret << endl;
211. return;
212. }
213. isRecording_ = true;
214. cout << "camera start recording succeed." << endl;
215. }
216. void StartPreview()
217. {
218. if (isPreviewing_) {
219. cout << "Camera is already previewing." << endl;
220. return;
221. }
222. FrameConfig *fc = new FrameConfig(FRAME_CONFIG_PREVIEW);
223. Surface *surface = Surface::CreateSurface();
224. if (surface == nullptr) {
225. delete fc;
226. cout << "CreateSurface failed" << endl;
227. return;
228. }
229. surface->SetWidthAndHeight(1920, 1080); /* 1920:width,1080:height */
230. surface->SetUserData("region_position_x", "0");
231. surface->SetUserData("region_position_y", "0");
232. surface->SetUserData("region_width", "480");
233. surface->SetUserData("region_height", "480");
234. fc->AddSurface(*surface);
235. int32_t ret = cam_->TriggerLoopingCapture(*fc);
236. if (ret != 0) {
237. delete fc;
238. cout << "camera start preview failed. ret=" << ret << endl;
239. return;
240. }
241. delete surface;
242. isPreviewing_ = true;
243. cout << "camera start preview succeed." << endl;
244. }
245. void Capture()
246. {
247. if (cam_ == nullptr) {
248. cout << "Camera is not ready." << endl;
249. return;
250. }
251. FrameConfig *fc = new FrameConfig(FRAME_CONFIG_CAPTURE);
252. Surface *surface = Surface::CreateSurface();
253. if (surface == nullptr) {
254. delete fc;
255. cout << "CreateSurface failed" << endl;
256. return;
257. }
258. surface->SetWidthAndHeight(1920, 1080); /* 1920:width,1080:height */
259. fc->AddSurface(*surface);
260. cam_->TriggerSingleCapture(*fc);
261. }
262. void Stop()
263. {
264. if (cam_ == nullptr) {
265. cout << "Camera is not ready." << endl;
266. return;
267. }
268. if (recorder_ != nullptr) {
269. recorder_->Stop(false);
270. }
271. cam_->StopLoopingCapture();
272. isPreviewing_ = false;
273. isRecording_ = false;
274. }
276. private:
277. bool isPreviewing_ = false;
278. bool isRecording_ = false;
279. EventHandler &eventHdlr_;
280. Camera *cam_ = nullptr;
281. Recorder *recorder_ = nullptr;
282. SampleFrameStateCallback fsCb_;
283. };
285. class SampleCameraDeviceCallback : public CameraDeviceCallback {};
287. void SampleHelp()
288. {
289. cout << "*******************************************" << endl;
290. cout << "Select the behavior of avrecorder." << endl;
291. cout << "1: Capture" << endl;
292. cout << "2: Record(Press s or S to stop)" << endl;
293. cout << "3: Preview(Press s or S to stop)" << endl;
294. cout << "q: quit the sample." << endl;
295. cout << "*******************************************" << endl;
296. }
298. int main()
299. {
300. cout << "Camera sample begin." << endl;
301. SampleHelp();
302. CameraKit *camKit = CameraKit::GetInstance();
303. if (camKit == nullptr) {
304. cout << "Can not get CameraKit instance" << endl;
305. return 0;
306. }
307. list<string> camList = camKit->GetCameraIds();
308. string camId;
309. for (auto &cam : camList) {
310. cout << "camera name:" << cam << endl;
311. const CameraAbility *ability = camKit->GetCameraAbility(cam);
312. /* find camera which fits user's ability */
313. list<CameraPicSize> sizeList = ability->GetSupportedSizes(0);
314. if (find(sizeList.begin(), sizeList.end(), CAM_PIC_1080P) != sizeList.end()) {
315. camId = cam;
316. break;
317. }
318. }
320. if (camId.empty()) {
321. cout << "No available camera.(1080p wanted)" << endl;
322. return 0;
323. }
325. EventHandler eventHdlr; // Create a thread to handle callback events
326. SampleCameraStateMng CamStateMng(eventHdlr);
328. camKit->CreateCamera(camId, CamStateMng, eventHdlr);
330. char input;
331. while (cin >> input) {
332. switch (input) {
333. case '1':
334. CamStateMng.Capture();
335. break;
336. case '2':
337. CamStateMng.StartRecord();
338. break;
339. case '3':
340. CamStateMng.StartPreview();
341. break;
342. case 's':
343. CamStateMng.Stop();
344. break;
345. case 'q':
346. CamStateMng.Stop();
347. goto EXIT;
348. default:
349. SampleHelp();
350. break;
351. }
352. }
353. EXIT:
354. cout << "Camera sample end." << endl;
355. return 0;
356. }
涉及仓
multimedia_frameworks_camera_lite
multimedia_frameworks_audio_lite
multimedia_frameworks_player_lite
multimedia_frameworks_recorder_lite
multimedia_hals_camera_lite
multimedia_interfaces_kits_recorder_lite
multimedia_interfaces_kits_audio_lite
multimedia_interfaces_kits_camera_lite
multimedia_interfaces_kits_player_lite
multimedia_services_media_lite
multimedia_utils_lite
