媒体子系统

简介

该仓主要用于存放媒体子系统的源码信息,旨在为多媒体应用开发者开发者提供统一的开发接口,使得开发者可以专注于应用业务的开发,轻松使用多媒体的资源。

本次开源基于本仓代码信息将相关设备配置文件放入到test\lite\devini内,用户使用时将配置文件放入到开发板/data目录,通过该配置文件可以方便去适配sensor及分辨率帧率等能力。

多媒体子系统框架

媒体子系统 - 图1

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

媒体子系统 - 图2

如上图,多媒体包括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. */
  15. #include"camera_kit.h"
  16. #include"recorder.h"
  17. #include<sys/time.h>
  18. #include<algorithm>
  19. #include<fstream>
  20. #include<iostream>
  21. #include<sstream>
  22. usingnamespace std;
  23. usingnamespace OHOS;
  24. usingnamespace OHOS::Media;
  25. staticvoidSampleSaveCapture(constchar*p,uint32_t size)
  26. {
  27. cout <<"Start saving picture"<< endl;
  28. struct timeval tv;
  29. gettimeofday(&tv, NULL);
  30. struct tm *ltm = localtime(&tv.tv_sec);
  31. if(ltm !=nullptr){
  32. ostringstream ss("Capture_");
  33. ss <<"Capture"<< ltm->tm_hour <<"-"<< ltm->tm_min <<"-"<< ltm->tm_sec <<".jpg";
  34. ofstream pic("/sdcard/"+ ss.str(), ofstream::out| ofstream::trunc);
  35. cout <<"write "<< size <<" bytes"<< endl;
  36. pic.write(p, size);
  37. cout <<"Saving picture end"<< endl;
  38. }
  39. }
  40. Recorder*SampleCreateRecorder()
  41. {
  42. int ret =0;
  43. int32_t sampleRate =48000;
  44. int32_t channelCount =1;
  45. AudioCodecFormat audioFormat = AAC_LC;
  46. AudioSourceType inputSource = AUDIO_MIC;
  47. int32_t audioEncodingBitRate = sampleRate;
  48. VideoSourceType source = VIDEO_SOURCE_SURFACE_ES;
  49. int32_t frameRate =30;
  50. float fps =30;
  51. int32_t rate =4096;
  52. int32_t sourceId =0;
  53. int32_t audioSourceId =0;
  54. int32_t width =1920;
  55. int32_t height =1080;
  56. VideoCodecFormat encoder;
  57. encoder = HEVC;
  58. width =1920;
  59. height =1080;
  60. Recorder*recorder =newRecorder();
  61. if((ret = recorder->SetVideoSource(source, sourceId))!= SUCCESS){
  62. cout <<"SetVideoSource failed."<< ret << endl;
  63. delete recorder;
  64. returnnullptr;
  65. }
  66. if((ret = recorder->SetVideoEncoder(sourceId, encoder))!= SUCCESS){
  67. cout <<"SetVideoEncoder failed."<< ret << endl;
  68. delete recorder;
  69. returnnullptr;
  70. }
  71. if((ret = recorder->SetVideoSize(sourceId, width, height))!= SUCCESS){
  72. cout <<"SetVideoSize failed."<< ret << endl;
  73. delete recorder;
  74. returnnullptr;
  75. }
  76. if((ret = recorder->SetVideoFrameRate(sourceId, frameRate))!= SUCCESS){
  77. cout <<"SetVideoFrameRate failed."<< ret << endl;
  78. delete recorder;
  79. returnnullptr;
  80. }
  81. if((ret = recorder->SetVideoEncodingBitRate(sourceId, rate))!= SUCCESS){
  82. cout <<"SetVideoEncodingBitRate failed."<< ret << endl;
  83. delete recorder;
  84. returnnullptr;
  85. }
  86. if((ret = recorder->SetCaptureRate(sourceId, frameRate))!= SUCCESS){
  87. cout <<"SetCaptureRate failed."<< ret << endl;
  88. delete recorder;
  89. returnnullptr;
  90. }
  91. if((ret = recorder->SetAudioSource(inputSource, audioSourceId))!= SUCCESS){
  92. cout <<"SetAudioSource failed."<< ret << endl;
  93. delete recorder;
  94. returnnullptr;
  95. }
  96. if((ret = recorder->SetAudioEncoder(audioSourceId, audioFormat))!= SUCCESS){
  97. cout <<"SetAudioEncoder failed."<< ret << endl;
  98. delete recorder;
  99. returnnullptr;
  100. }
  101. if((ret = recorder->SetAudioSampleRate(audioSourceId, sampleRate))!= SUCCESS){
  102. cout <<"SetAudioSampleRate failed."<< ret << endl;
  103. delete recorder;
  104. returnnullptr;
  105. }
  106. if((ret = recorder->SetAudioChannels(audioSourceId, channelCount))!= SUCCESS){
  107. cout <<"SetAudioChannels failed."<< ret << endl;
  108. delete recorder;
  109. returnnullptr;
  110. }
  111. if((ret = recorder->SetAudioEncodingBitRate(audioSourceId, audioEncodingBitRate))!= SUCCESS){
  112. cout <<"SetAudioEncodingBitRate failed."<< ret << endl;
  113. delete recorder;
  114. returnnullptr;
  115. }
  116. return recorder;
  117. }
  118. classSampleFrameStateCallback:publicFrameStateCallback{
  119. voidOnFrameFinished(Camera&camera,FrameConfig&fc,FrameResult&result)override
  120. {
  121. cout <<"Receive frame complete inform."<< endl;
  122. if(fc.GetFrameConfigType()== FRAME_CONFIG_CAPTURE){
  123. cout <<"Capture frame received."<< endl;
  124. list<Surface*> surfaceList = fc.GetSurfaces();
  125. for(Surface*surface : surfaceList){
  126. SurfaceBuffer*buffer = surface->AcquireBuffer();
  127. if(buffer !=nullptr){
  128. char*virtAddr =static_cast<char*>(buffer->GetVirAddr());
  129. if(virtAddr !=nullptr){
  130. SampleSaveCapture(virtAddr, buffer->GetSize());
  131. }
  132. surface->ReleaseBuffer(buffer);
  133. }
  134. delete surface;
  135. }
  136. delete&fc;
  137. }
  138. }
  139. };
  140. classSampleCameraStateMng:publicCameraStateCallback{
  141. public:
  142. SampleCameraStateMng()=delete;
  143. SampleCameraStateMng(EventHandler&eventHdlr): eventHdlr_(eventHdlr){}
  144. ~SampleCameraStateMng()
  145. {
  146. if(recorder_ !=nullptr){
  147. recorder_->Release();
  148. delete recorder_;
  149. }
  150. }
  151. voidOnCreated(Camera&c)override
  152. {
  153. cout <<"Sample recv OnCreate camera."<< endl;
  154. auto config =CameraConfig::CreateCameraConfig();
  155. config->SetFrameStateCallback(&fsCb_,&eventHdlr_);
  156. c.Configure(*config);
  157. cam_ =&c;
  158. }
  159. voidOnCreateFailed(const std::string cameraId,int32_t errorCode)override{}
  160. voidOnReleased(Camera&c)override{}
  161. voidStartRecord()
  162. {
  163. int ret;
  164. if(isRecording_){
  165. cout <<"Camera is already recording."<< endl;
  166. return;
  167. }
  168. if(recorder_ ==nullptr){
  169. recorder_ =SampleCreateRecorder();
  170. }
  171. if(recorder_ ==nullptr){
  172. cout <<"Recorder not available"<< endl;
  173. return;
  174. }
  175. string path ="/sdcard";
  176. ret = recorder_->SetOutputPath(path);
  177. if(ret != SUCCESS){
  178. cout <<"SetOutputPath fialed :"<< ret << std::endl;
  179. return;
  180. }
  181. ret = recorder_->Prepare();
  182. if(ret != SUCCESS){
  183. cout <<"Prepare failed.="<< ret << endl;
  184. return;
  185. }
  186. Surface*surface =(recorder_->GetSurface(0)).get();
  187. surface->SetWidthAndHeight(1920,1080);
  188. surface->SetQueueSize(3);
  189. surface->SetSize(1024*1024);
  190. FrameConfig*fc =newFrameConfig(FRAME_CONFIG_RECORD);
  191. fc->AddSurface(*surface);
  192. ret = recorder_->Start();
  193. if(ret != SUCCESS){
  194. delete fc;
  195. cout <<"recorder start failed. ret="<< ret << endl;
  196. return;
  197. }
  198. ret = cam_->TriggerLoopingCapture(*fc);
  199. if(ret !=0){
  200. delete fc;
  201. cout <<"camera start recording failed. ret="<< ret << endl;
  202. return;
  203. }
  204. isRecording_ =true;
  205. cout <<"camera start recording succeed."<< endl;
  206. }
  207. voidStartPreview()
  208. {
  209. if(isPreviewing_){
  210. cout <<"Camera is already previewing."<< endl;
  211. return;
  212. }
  213. FrameConfig*fc =newFrameConfig(FRAME_CONFIG_PREVIEW);
  214. Surface*surface =Surface::CreateSurface();
  215. if(surface ==nullptr){
  216. delete fc;
  217. cout <<"CreateSurface failed"<< endl;
  218. return;
  219. }
  220. surface->SetWidthAndHeight(1920,1080);/* 1920:width,1080:height */
  221. surface->SetUserData("region_position_x","0");
  222. surface->SetUserData("region_position_y","0");
  223. surface->SetUserData("region_width","480");
  224. surface->SetUserData("region_height","480");
  225. fc->AddSurface(*surface);
  226. int32_t ret = cam_->TriggerLoopingCapture(*fc);
  227. if(ret !=0){
  228. delete fc;
  229. cout <<"camera start preview failed. ret="<< ret << endl;
  230. return;
  231. }
  232. delete surface;
  233. isPreviewing_ =true;
  234. cout <<"camera start preview succeed."<< endl;
  235. }
  236. voidCapture()
  237. {
  238. if(cam_ ==nullptr){
  239. cout <<"Camera is not ready."<< endl;
  240. return;
  241. }
  242. FrameConfig*fc =newFrameConfig(FRAME_CONFIG_CAPTURE);
  243. Surface*surface =Surface::CreateSurface();
  244. if(surface ==nullptr){
  245. delete fc;
  246. cout <<"CreateSurface failed"<< endl;
  247. return;
  248. }
  249. surface->SetWidthAndHeight(1920,1080);/* 1920:width,1080:height */
  250. fc->AddSurface(*surface);
  251. cam_->TriggerSingleCapture(*fc);
  252. }
  253. voidStop()
  254. {
  255. if(cam_ ==nullptr){
  256. cout <<"Camera is not ready."<< endl;
  257. return;
  258. }
  259. if(recorder_ !=nullptr){
  260. recorder_->Stop(false);
  261. }
  262. cam_->StopLoopingCapture();
  263. isPreviewing_ =false;
  264. isRecording_ =false;
  265. }
  266. private:
  267. bool isPreviewing_ =false;
  268. bool isRecording_ =false;
  269. EventHandler&eventHdlr_;
  270. Camera*cam_ =nullptr;
  271. Recorder*recorder_ =nullptr;
  272. SampleFrameStateCallback fsCb_;
  273. };
  274. classSampleCameraDeviceCallback:publicCameraDeviceCallback{};
  275. voidSampleHelp()
  276. {
  277. cout <<"*******************************************"<< endl;
  278. cout <<"Select the behavior of avrecorder."<< endl;
  279. cout <<"1: Capture"<< endl;
  280. cout <<"2: Record(Press s or S to stop)"<< endl;
  281. cout <<"3: Preview(Press s or S to stop)"<< endl;
  282. cout <<"q: quit the sample."<< endl;
  283. cout <<"*******************************************"<< endl;
  284. }
  285. int main()
  286. {
  287. cout <<"Camera sample begin."<< endl;
  288. SampleHelp();
  289. CameraKit*camKit =CameraKit::GetInstance();
  290. if(camKit ==nullptr){
  291. cout <<"Can not get CameraKit instance"<< endl;
  292. return0;
  293. }
  294. list<string> camList = camKit->GetCameraIds();
  295. string camId;
  296. for(auto&cam : camList){
  297. cout <<"camera name:"<< cam << endl;
  298. constCameraAbility*ability = camKit->GetCameraAbility(cam);
  299. /* find camera which fits user's ability */
  300. list<CameraPicSize> sizeList = ability->GetSupportedSizes(0);
  301. if(find(sizeList.begin(), sizeList.end(), CAM_PIC_1080P)!= sizeList.end()){
  302. camId = cam;
  303. break;
  304. }
  305. }
  306. if(camId.empty()){
  307. cout <<"No available camera.(1080p wanted)"<< endl;
  308. return0;
  309. }
  310. EventHandler eventHdlr;// Create a thread to handle callback events
  311. SampleCameraStateMngCamStateMng(eventHdlr);
  312. camKit->CreateCamera(camId,CamStateMng, eventHdlr);
  313. char input;
  314. while(cin >> input){
  315. switch(input){
  316. case'1':
  317. CamStateMng.Capture();
  318. break;
  319. case'2':
  320. CamStateMng.StartRecord();
  321. break;
  322. case'3':
  323. CamStateMng.StartPreview();
  324. break;
  325. case's':
  326. CamStateMng.Stop();
  327. break;
  328. case'q':
  329. CamStateMng.Stop();
  330. goto EXIT;
  331. default:
  332. SampleHelp();
  333. break;
  334. }
  335. }
  336. EXIT:
  337. cout <<"Camera sample end."<< endl;
  338. return0;
  339. }

涉及仓

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