1 /*
2 * Copyright (C) 2021 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
16 #include "recorder_demo.h"
17 #include <iostream>
18 #include <fstream>
19 #include <unistd.h>
20 #include <sync_fence.h>
21 #include "display_type.h"
22 #include "securec.h"
23 #include "demo_log.h"
24 #include "media_errors.h"
25
26 using namespace OHOS;
27 using namespace OHOS::Media;
28 using namespace std;
29 namespace {
30 constexpr uint32_t STUB_STREAM_SIZE = 451;
31 constexpr uint32_t FRAME_RATE = 30000;
32 constexpr uint32_t CODEC_BUFFER_WIDTH = 1024;
33 constexpr uint32_t CODEC_BUFFER_HEIGHT = 25;
34 constexpr uint32_t YUV_BUFFER_WIDTH = 1280;
35 constexpr uint32_t YUV_BUFFER_HEIGHT = 760;
36 constexpr uint32_t RGBA_BUFFER_WIDTH = 1280;
37 constexpr uint32_t RGBA_BUFFER_HEIGHT = 760;
38 constexpr uint32_t STRIDE_ALIGN = 8;
39 constexpr uint32_t FRAME_DURATION = 40000000;
40 constexpr uint32_t RECORDER_TIME = 5;
41 constexpr uint32_t YUV_BUFFER_SIZE = YUV_BUFFER_WIDTH * YUV_BUFFER_HEIGHT * 3 / 2; // width * height * 3 / 2
42 constexpr uint32_t RGBA_BUFFER_SIZE = 3891200; // 1280 * 760 * 4
43 constexpr uint32_t SEC_TO_NS = 1000000000;
44 const string PURE_VIDEO = "1";
45 const string PURE_AUDIO = "2";
46 const string AUDIO_VIDEO = "3";
47 }
48
OnError(RecorderErrorType errorType,int32_t errorCode)49 void RecorderCallbackDemo::OnError(RecorderErrorType errorType, int32_t errorCode)
50 {
51 cout << "Error received, errorType:" << errorType << " errorCode:" << errorCode << endl;
52 }
53
OnInfo(int32_t type,int32_t extra)54 void RecorderCallbackDemo::OnInfo(int32_t type, int32_t extra)
55 {
56 cout << "Info received, Infotype:" << type << " Infocode:" << extra << endl;
57 }
58
59 // config for video to request buffer from surface
60 static VideoRecorderConfig g_videoRecorderConfig;
61
62 // config for audio to request buffer from surface
63 static AudioRecorderConfig g_audioRecorderConfig;
64
65 // config for surface buffer flush to the queue
66 static OHOS::BufferFlushConfig g_esFlushConfig = {
67 .damage = {
68 .x = 0,
69 .y = 0,
70 .w = CODEC_BUFFER_WIDTH,
71 .h = CODEC_BUFFER_HEIGHT
72 },
73 .timestamp = 0
74 };
75
76 // config for surface buffer request from the queue
77 static OHOS::BufferRequestConfig g_esRequestConfig = {
78 .width = CODEC_BUFFER_WIDTH,
79 .height = CODEC_BUFFER_HEIGHT,
80 .strideAlignment = STRIDE_ALIGN,
81 .format = PIXEL_FMT_RGBA_8888,
82 .usage = BUFFER_USAGE_CPU_READ | BUFFER_USAGE_CPU_WRITE | BUFFER_USAGE_MEM_DMA,
83 .timeout = 0
84 };
85
86 // config for surface buffer flush to the queue
87 static OHOS::BufferFlushConfig g_yuvFlushConfig = {
88 .damage = {
89 .x = 0,
90 .y = 0,
91 .w = YUV_BUFFER_WIDTH,
92 .h = YUV_BUFFER_HEIGHT
93 },
94 .timestamp = 0
95 };
96
97 // config for surface buffer request from the queue
98 static OHOS::BufferRequestConfig g_yuvRequestConfig = {
99 .width = YUV_BUFFER_WIDTH,
100 .height = YUV_BUFFER_HEIGHT,
101 .strideAlignment = STRIDE_ALIGN,
102 .format = PIXEL_FMT_YCRCB_420_SP,
103 .usage = BUFFER_USAGE_CPU_READ | BUFFER_USAGE_CPU_WRITE | BUFFER_USAGE_MEM_DMA,
104 .timeout = 0
105 };
106
107 // config for surface buffer flush to the queue
108 static OHOS::BufferFlushConfig g_rgbaFlushConfig = {
109 .damage = {
110 .x = 0,
111 .y = 0,
112 .w = RGBA_BUFFER_WIDTH,
113 .h = RGBA_BUFFER_HEIGHT
114 },
115 .timestamp = 0
116 };
117
118 // config for surface buffer request from the queue
119 static OHOS::BufferRequestConfig g_rgbaRequestConfig = {
120 .width = RGBA_BUFFER_WIDTH,
121 .height = RGBA_BUFFER_HEIGHT,
122 .strideAlignment = STRIDE_ALIGN,
123 .format = PIXEL_FMT_RGBA_8888,
124 .usage = BUFFER_USAGE_CPU_READ | BUFFER_USAGE_CPU_WRITE | BUFFER_USAGE_MEM_DMA,
125 .timeout = 0
126 };
127
128 // this array contains each buffer size of the stub stream
129 const uint32_t HIGH_VIDEO_FRAME_SIZE[STUB_STREAM_SIZE] = {
130 12145, 6247, 9203, 4810, 7751, 3429, 2285, 2906, 4461, 4392, 4620, 4251, 3973, 3652, 4469, 5208, 4661,
131 4712, 4139, 3199, 4299, 4429, 4726, 4612, 4428, 3709, 2715, 3006, 4048, 3939, 9648, 2796, 3900, 4119,
132 3732, 3721, 3145, 2753, 3526, 3801, 4413, 4175, 4579, 4439, 3619, 3697, 4021, 3178, 3420, 3721, 3726,
133 4671, 3823, 4565, 4667, 4040, 4174, 3884, 3398, 2933, 12095, 1126, 1514, 2308, 925, 3799, 2556, 1904,
134 3721, 2380, 2152, 4190, 3415, 3248, 5801, 3772, 3070, 4871, 4584, 5653, 4888, 6578, 7284, 6345, 5787,
135 4957, 5071, 4985, 4158, 3549, 15231, 2242, 1281, 2843, 1693, 3056, 3372, 4148, 3848, 5967, 3637, 3006,
136 3347, 4323, 2136, 1865, 2548, 1899, 3360, 2289, 3669, 2452, 4872, 4113, 3268, 4847, 3861, 3157, 5288,
137 4090, 20183, 5006, 2972, 4122, 3377, 3608, 3627, 3387, 3594, 3276, 5284, 4684, 4237, 3983, 3601, 3459,
138 2489, 2609, 3443, 3135, 3489, 3464, 3888, 3893, 4359, 4363, 4263, 4480, 3545, 4654, 24011, 2565, 2118,
139 4948, 2468, 2889, 2671, 4277, 2402, 3828, 3580, 3123, 4562, 3065, 5313, 2884, 3170, 2653, 3530, 3093,
140 3002, 3199, 4546, 3232, 3347, 2991, 4202, 3994, 3740, 3771, 30196, 2683, 4039, 3324, 4274, 3866, 3910,
141 3214, 3016, 3079, 4113, 2674, 4028, 3957, 4141, 3585, 5638, 4704, 3764, 3483, 3457, 3365, 3520, 3619,
142 3664, 3490, 3979, 2686, 3735, 3601, 29065, 4288, 4371, 3420, 4585, 3705, 4230, 3887, 3310, 2815, 3030,
143 2440, 2133, 2255, 2506, 2080, 2833, 2694, 3390, 3140, 3265, 3067, 3000, 3754, 3743, 3662, 3439, 3698,
144 3420, 3340, 36130, 2170, 2589, 2361, 3101, 3011, 2942, 2832, 3550, 3614, 3620, 3443, 3363, 3518, 2684,
145 2650, 2680, 3285, 3121, 3471, 3343, 3250, 3207, 3269, 3169, 3147, 3247, 3367, 3791, 3039, 43578,
146 1813, 2615, 2529, 2501, 2491, 2466, 2436, 2966, 2805, 2777, 3260, 3270, 3416, 2819, 3154, 3273, 3334,
147 3280, 3201, 3192, 3429, 3128, 3150, 3073, 3182, 3084, 3238, 3049, 3137, 49379, 2086, 2785, 2795, 2900,
148 2768, 2770, 2794, 2780, 2872, 2896, 3538, 3473, 6350, 4433, 4241, 3684, 5019, 4919, 3985, 3135, 3637,
149 3819, 3976, 4129, 4270, 2629, 3921, 3068, 3730, 33887, 3123, 4353, 4059, 5657, 5496, 6541, 5528, 5715,
150 4582, 4379, 3810, 2871, 2204, 3205, 4453, 4865, 4691, 4724, 3618, 3361, 2881, 2864, 2067, 1682, 1415,
151 1464, 908, 588, 1492, 20448, 1248, 2027, 2262, 3769, 4053, 4676, 5594, 5713, 6662, 5951, 5873, 4495,
152 3375, 4793, 5842, 5924, 5875, 4928, 4075, 3795, 3342, 2234, 2668, 1435, 1630, 1064, 1842, 216, 796,
153 18987, 932, 1994, 2344, 3205, 3743, 4465, 5631, 6009, 7096, 6377, 6694, 5381, 4557, 2976, 3019, 3607,
154 5581, 5026, 6058, 6325, 5990, 5147, 4521, 3488, 3509, 2779, 2785, 2902, 2759, 13536, 1871, 1485, 927,
155 509, 864, 681, 1821, 2644, 2779, 3309, 3580, 3798, 2824, 2444, 1766, 3737, 2738, 2149, 3066, 4515, 2084,
156 8322, 4885, 5643, 3339, 3379, 3299, 2804, 2362, 18116
157 };
158
GetStubFile()159 int32_t RecorderDemo::GetStubFile()
160 {
161 file_ = std::make_shared<std::ifstream>();
162 DEMO_CHECK_AND_RETURN_RET_LOG(file_ != nullptr, MSERR_INVALID_OPERATION, "create file failed");
163 const std::string filePath = "/data/h264_1280_720.h264";
164 file_->open(filePath, std::ios::in | std::ios::binary);
165 DEMO_CHECK_AND_RETURN_RET_LOG(file_->is_open(), MSERR_INVALID_OPERATION, "open file failed");
166
167 return MSERR_OK;
168 }
169
GetPts()170 uint64_t RecorderDemo::GetPts()
171 {
172 struct timespec timestamp = {0, 0};
173 clock_gettime(CLOCK_MONOTONIC, ×tamp);
174 uint64_t time = (uint64_t)timestamp.tv_sec * SEC_TO_NS + (uint64_t)timestamp.tv_nsec;
175 return time;
176 }
177
HDICreateESBuffer()178 void RecorderDemo::HDICreateESBuffer()
179 {
180 // camera hdi loop to requeset buffer
181 const uint32_t *frameLenArray = HIGH_VIDEO_FRAME_SIZE;
182 while (count_ < STUB_STREAM_SIZE) {
183 DEMO_CHECK_AND_BREAK_LOG(!isExit_.load(), "close camera hdi thread");
184 usleep(FRAME_RATE);
185 OHOS::sptr<OHOS::SurfaceBuffer> buffer;
186 int32_t releaseFence;
187 OHOS::SurfaceError ret = producerSurface_->RequestBuffer(buffer, releaseFence, g_esRequestConfig);
188 DEMO_CHECK_AND_CONTINUE_LOG(ret != OHOS::SURFACE_ERROR_NO_BUFFER, "surface loop full, no buffer now");
189 DEMO_CHECK_AND_BREAK_LOG(ret == SURFACE_ERROR_OK && buffer != nullptr, "RequestBuffer failed");
190
191 sptr<SyncFence> tempFence = new SyncFence(releaseFence);
192 tempFence->Wait(100); // 100ms
193
194 auto addr = static_cast<uint8_t *>(buffer->GetVirAddr());
195 if (addr == nullptr) {
196 cout << "GetVirAddr failed" << endl;
197 (void)producerSurface_->CancelBuffer(buffer);
198 break;
199 }
200 char *tempBuffer = static_cast<char *>(malloc(sizeof(char) * (*frameLenArray) + 1));
201 if (tempBuffer == nullptr) {
202 (void)producerSurface_->CancelBuffer(buffer);
203 break;
204 }
205 (void)file_->read(tempBuffer, *frameLenArray);
206 if (*frameLenArray > buffer->GetSize()) {
207 free(tempBuffer);
208 (void)producerSurface_->CancelBuffer(buffer);
209 break;
210 }
211 (void)memcpy_s(addr, *frameLenArray, tempBuffer, *frameLenArray);
212
213 if (isStart_.load()) {
214 pts_= (int64_t)(GetPts());
215 isStart_.store(false);
216 }
217
218 (void)buffer->GetExtraData()->ExtraSet("dataSize", static_cast<int32_t>(*frameLenArray));
219 (void)buffer->GetExtraData()->ExtraSet("timeStamp", pts_);
220 (void)buffer->GetExtraData()->ExtraSet("isKeyFrame", isKeyFrame_);
221 count_++;
222 (count_ % 30) == 0 ? (isKeyFrame_ = 1) : (isKeyFrame_ = 0); // keyframe every 30fps
223 pts_ += FRAME_DURATION;
224 (void)producerSurface_->FlushBuffer(buffer, -1, g_esFlushConfig);
225 frameLenArray++;
226 free(tempBuffer);
227 }
228 cout << "exit camera hdi loop" << endl;
229 if ((file_ != nullptr) && (file_->is_open())) {
230 file_->close();
231 }
232 }
233
HDICreateYUVBuffer()234 void RecorderDemo::HDICreateYUVBuffer()
235 {
236 // camera hdi loop to requeset buffer
237 while (count_ < STUB_STREAM_SIZE) {
238 DEMO_CHECK_AND_BREAK_LOG(!isExit_.load(), "close camera hdi thread");
239 usleep(FRAME_RATE);
240 OHOS::sptr<OHOS::SurfaceBuffer> buffer;
241 int32_t releaseFence;
242 OHOS::SurfaceError ret = producerSurface_->RequestBuffer(buffer, releaseFence, g_yuvRequestConfig);
243 DEMO_CHECK_AND_CONTINUE_LOG(ret != OHOS::SURFACE_ERROR_NO_BUFFER, "surface loop full, no buffer now");
244 DEMO_CHECK_AND_BREAK_LOG(ret == SURFACE_ERROR_OK && buffer != nullptr, "RequestBuffer failed");
245
246 sptr<SyncFence> tempFence = new SyncFence(releaseFence);
247 tempFence->Wait(100); // 100ms
248
249 char *tempBuffer = static_cast<char *>(buffer->GetVirAddr());
250 (void)memset_s(tempBuffer, YUV_BUFFER_SIZE, color_, YUV_BUFFER_SIZE);
251
252 srand((int)time(0));
253 for (uint32_t i = 0; i < YUV_BUFFER_SIZE - 1; i += (YUV_BUFFER_SIZE - 1)) { // 100 is the steps between noise
254 if (i >= YUV_BUFFER_SIZE - 1) {
255 break;
256 }
257 tempBuffer[i] = (unsigned char)(rand() % 255); // 255 is the size of yuv, add noise
258 }
259
260 color_ = color_ - 3; // 3 is the step of the pic change
261
262 if (color_ <= 0) {
263 color_ = 0xFF;
264 }
265
266 // get time
267 pts_= (int64_t)(GetPts());
268 (void)buffer->GetExtraData()->ExtraSet("dataSize", static_cast<int32_t>(YUV_BUFFER_SIZE));
269 (void)buffer->GetExtraData()->ExtraSet("timeStamp", pts_);
270 (void)buffer->GetExtraData()->ExtraSet("isKeyFrame", isKeyFrame_);
271 count_++;
272 (count_ % 30) == 0 ? (isKeyFrame_ = 1) : (isKeyFrame_ = 0); // keyframe every 30fps
273 (void)producerSurface_->FlushBuffer(buffer, -1, g_yuvFlushConfig);
274 }
275 cout << "exit camera hdi loop" << endl;
276 }
277
HDICreateRGBABuffer()278 void RecorderDemo::HDICreateRGBABuffer()
279 {
280 // camera hdi loop to requeset buffer
281 while (count_ < STUB_STREAM_SIZE) {
282 DEMO_CHECK_AND_BREAK_LOG(!isExit_.load(), "close camera hdi thread");
283 usleep(FRAME_RATE);
284 OHOS::sptr<OHOS::SurfaceBuffer> buffer;
285 int32_t releaseFence;
286 OHOS::SurfaceError ret = producerSurface_->RequestBuffer(buffer, releaseFence, g_rgbaRequestConfig);
287 DEMO_CHECK_AND_CONTINUE_LOG(ret != OHOS::SURFACE_ERROR_NO_BUFFER, "surface loop full, no buffer now");
288 DEMO_CHECK_AND_BREAK_LOG(ret == SURFACE_ERROR_OK && buffer != nullptr, "RequestBuffer failed");
289
290 sptr<SyncFence> tempFence = new SyncFence(releaseFence);
291 tempFence->Wait(100); // 100ms
292
293 char *tempBuffer = static_cast<char *>(buffer->GetVirAddr());
294 (void)memset_s(tempBuffer, RGBA_BUFFER_SIZE, color_, RGBA_BUFFER_SIZE);
295
296 srand((int)time(0));
297 for (uint32_t i = 0; i < RGBA_BUFFER_SIZE - 1; i += (RGBA_BUFFER_SIZE - 1)) { // 100 is the steps between noise
298 if (i >= RGBA_BUFFER_SIZE - 1) {
299 break;
300 }
301 tempBuffer[i] = (unsigned char)(rand() % 255); // 255 is the size of rgb, add noise
302 }
303
304 color_ = color_ - 3; // 3 is the step of the pic change
305
306 if (color_ <= 0) {
307 color_ = 0xFF;
308 }
309
310 // get time
311 pts_= (int64_t)(GetPts());
312 (void)buffer->GetExtraData()->ExtraSet("dataSize", static_cast<int32_t>(RGBA_BUFFER_SIZE));
313 (void)buffer->GetExtraData()->ExtraSet("timeStamp", pts_);
314 (void)buffer->GetExtraData()->ExtraSet("isKeyFrame", isKeyFrame_);
315 count_++;
316 (count_ % 30) == 0 ? (isKeyFrame_ = 1) : (isKeyFrame_ = 0); // keyframe every 30fps
317 (void)producerSurface_->FlushBuffer(buffer, -1, g_rgbaFlushConfig);
318 }
319 cout << "exit camera hdi loop" << endl;
320 }
321
CameraServicesForVideo() const322 int32_t RecorderDemo::CameraServicesForVideo() const
323 {
324 int32_t ret = recorder_->SetVideoEncoder(g_videoRecorderConfig.videoSourceId,
325 g_videoRecorderConfig.videoFormat);
326 DEMO_CHECK_AND_RETURN_RET_LOG(ret == MSERR_OK, MSERR_INVALID_OPERATION, "SetVideoEncoder failed ");
327
328 ret = recorder_->SetVideoSize(g_videoRecorderConfig.videoSourceId,
329 g_videoRecorderConfig.width, g_videoRecorderConfig.height);
330 DEMO_CHECK_AND_RETURN_RET_LOG(ret == MSERR_OK, MSERR_INVALID_OPERATION, "SetVideoSize failed ");
331
332 ret = recorder_->SetVideoFrameRate(g_videoRecorderConfig.videoSourceId, g_videoRecorderConfig.frameRate);
333 DEMO_CHECK_AND_RETURN_RET_LOG(ret == MSERR_OK, MSERR_INVALID_OPERATION, "SetVideoFrameRate failed ");
334
335 ret = recorder_->SetVideoEncodingBitRate(g_videoRecorderConfig.videoSourceId,
336 g_videoRecorderConfig.videoEncodingBitRate);
337 DEMO_CHECK_AND_RETURN_RET_LOG(ret == MSERR_OK, MSERR_INVALID_OPERATION, "SetVideoEncodingBitRate failed ");
338 return MSERR_OK;
339 }
340
CameraServicesForAudio() const341 int32_t RecorderDemo::CameraServicesForAudio() const
342 {
343 int32_t ret = recorder_->SetAudioEncoder(g_videoRecorderConfig.audioSourceId, g_videoRecorderConfig.audioFormat);
344 DEMO_CHECK_AND_RETURN_RET_LOG(ret == MSERR_OK, MSERR_INVALID_OPERATION, "SetAudioEncoder failed ");
345
346 ret = recorder_->SetAudioSampleRate(g_videoRecorderConfig.audioSourceId, g_videoRecorderConfig.sampleRate);
347 DEMO_CHECK_AND_RETURN_RET_LOG(ret == MSERR_OK, MSERR_INVALID_OPERATION, "SetAudioSampleRate failed ");
348
349 ret = recorder_->SetAudioChannels(g_videoRecorderConfig.audioSourceId, g_videoRecorderConfig.channelCount);
350 DEMO_CHECK_AND_RETURN_RET_LOG(ret == MSERR_OK, MSERR_INVALID_OPERATION, "SetAudioChannels failed ");
351
352 ret = recorder_->SetAudioEncodingBitRate(g_videoRecorderConfig.audioSourceId,
353 g_videoRecorderConfig.audioEncodingBitRate);
354 DEMO_CHECK_AND_RETURN_RET_LOG(ret == MSERR_OK, MSERR_INVALID_OPERATION, "SetAudioEncodingBitRate failed ");
355
356 return MSERR_OK;
357 }
358
SetFormat(const std::string & recorderType) const359 int32_t RecorderDemo::SetFormat(const std::string &recorderType) const
360 {
361 int32_t ret;
362 if (recorderType == PURE_VIDEO) {
363 ret = recorder_->SetVideoSource(g_videoRecorderConfig.vSource, g_videoRecorderConfig.videoSourceId);
364 DEMO_CHECK_AND_RETURN_RET_LOG(ret == MSERR_OK, MSERR_INVALID_OPERATION, "SetVideoSource failed ");
365 ret = recorder_->SetOutputFormat(g_videoRecorderConfig.outPutFormat);
366 DEMO_CHECK_AND_RETURN_RET_LOG(ret == MSERR_OK, MSERR_INVALID_OPERATION, "SetOutputFormat failed ");
367 ret = CameraServicesForVideo();
368 DEMO_CHECK_AND_RETURN_RET_LOG(ret == MSERR_OK, MSERR_INVALID_OPERATION, "CameraServices failed ");
369 } else if (recorderType == PURE_AUDIO) {
370 ret = recorder_->SetAudioSource(g_videoRecorderConfig.aSource, g_videoRecorderConfig.audioSourceId);
371 DEMO_CHECK_AND_RETURN_RET_LOG(ret == MSERR_OK, MSERR_INVALID_OPERATION, "SetAudioSource failed ");
372 ret = recorder_->SetOutputFormat(g_audioRecorderConfig.outPutFormat);
373 DEMO_CHECK_AND_RETURN_RET_LOG(ret == MSERR_OK, MSERR_INVALID_OPERATION, "SetOutputFormat failed ");
374 ret = CameraServicesForAudio();
375 DEMO_CHECK_AND_RETURN_RET_LOG(ret == MSERR_OK, MSERR_INVALID_OPERATION, "CameraServicesForAudio failed ");
376 } else if (recorderType == AUDIO_VIDEO) {
377 ret = recorder_->SetVideoSource(g_videoRecorderConfig.vSource, g_videoRecorderConfig.videoSourceId);
378 DEMO_CHECK_AND_RETURN_RET_LOG(ret == MSERR_OK, MSERR_INVALID_OPERATION, "SetVideoSource failed ");
379 ret = recorder_->SetAudioSource(g_videoRecorderConfig.aSource, g_videoRecorderConfig.audioSourceId);
380 DEMO_CHECK_AND_RETURN_RET_LOG(ret == MSERR_OK, MSERR_INVALID_OPERATION, "SetAudioSource failed ");
381 ret = recorder_->SetOutputFormat(g_videoRecorderConfig.outPutFormat);
382 DEMO_CHECK_AND_RETURN_RET_LOG(ret == MSERR_OK, MSERR_INVALID_OPERATION, "SetOutputFormat failed ");
383 ret = CameraServicesForVideo();
384 DEMO_CHECK_AND_RETURN_RET_LOG(ret == MSERR_OK, MSERR_INVALID_OPERATION, "CameraServicesForVideo failed ");
385 ret = CameraServicesForAudio();
386 DEMO_CHECK_AND_RETURN_RET_LOG(ret == MSERR_OK, MSERR_INVALID_OPERATION, "CameraServicesForAudio failed ");
387 }
388
389 ret = recorder_->SetMaxDuration(g_videoRecorderConfig.duration);
390 DEMO_CHECK_AND_RETURN_RET_LOG(ret == MSERR_OK, MSERR_INVALID_OPERATION, "SetMaxDuration failed ");
391
392 ret = recorder_->SetOutputFile(g_videoRecorderConfig.outputFd);
393 DEMO_CHECK_AND_RETURN_RET_LOG(ret == MSERR_OK, MSERR_INVALID_OPERATION, "SetOutputFile failed ");
394
395 std::shared_ptr<RecorderCallbackDemo> cb = std::make_shared<RecorderCallbackDemo>();
396 ret = recorder_->SetRecorderCallback(cb);
397 DEMO_CHECK_AND_RETURN_RET_LOG(ret == MSERR_OK, MSERR_INVALID_OPERATION, "SetRecorderCallback failed ");
398
399 cout << "set format finished" << endl;
400 return MSERR_OK;
401 }
402
GetFileFd()403 void RecorderDemo::GetFileFd()
404 {
405 g_videoRecorderConfig.outputFd = open("/data/media/1.mp4", O_RDWR);
406 if (g_videoRecorderConfig.outputFd <= 0) {
407 cout << "open fd failed" << endl;
408 }
409 }
410
SetVideoSource()411 void RecorderDemo::SetVideoSource()
412 {
413 string source;
414 cout << "set input video source" << endl;
415 cout << "yuv source : 1" << endl;
416 cout << "es source : 2" << endl;
417 cout << "rgba source : 3" << endl;
418 cout << "pure audio dont need videosource : 4" << endl;
419 (void)getline(cin, source);
420
421 if (source == "1") {
422 cout << "select yuv source" << endl;
423 g_videoRecorderConfig.vSource = VIDEO_SOURCE_SURFACE_YUV;
424 } else if (source == "2") {
425 cout << "select es source" << endl;
426 g_videoRecorderConfig.vSource = VIDEO_SOURCE_SURFACE_ES;
427 } else if (source == "3") {
428 cout << "select rgba source" << endl;
429 g_videoRecorderConfig.vSource = VIDEO_SOURCE_SURFACE_RGBA;
430 } else if (source == "4") {
431 cout << "wrong source type, use yuv source as default" << endl;
432 g_videoRecorderConfig.vSource = VIDEO_SOURCE_SURFACE_YUV;
433 }
434 }
435
SetVideoEncodeMode()436 void RecorderDemo::SetVideoEncodeMode()
437 {
438 string encodeMode = "";
439 cout << "yuv source need video encode" << endl;
440 cout << "select mpeg4 format : 1" << endl;
441 cout << "select h264 foramt : 2" << endl;
442 cout << "pure audio & es stream dont need select : 3" << endl;
443 (void)getline(cin, encodeMode);
444
445 if (encodeMode == "1") {
446 cout << "select mpeg4" << endl;
447 g_videoRecorderConfig.videoFormat = MPEG4;
448 } else if (encodeMode == "2") {
449 cout << "select h264" << endl;
450 g_videoRecorderConfig.videoFormat = H264;
451 } else if (encodeMode == "3") {
452 cout << "pure audio recorder type" << endl;
453 } else {
454 cout << "wrong source type, use mpeg4 as default" << endl;
455 g_videoRecorderConfig.videoFormat = MPEG4;
456 }
457 }
458
RunCase()459 void RecorderDemo::RunCase()
460 {
461 recorder_ = OHOS::Media::RecorderFactory::CreateRecorder();
462 if (recorder_ == nullptr) {
463 cout << "recorder_ is null" << endl;
464 return;
465 }
466
467 string recorderType = "";
468 cout << "recorder pure video audio or audio/video " << endl;
469 cout << "pure video enter : 1" << endl;
470 cout << "pure audio enter : 2" << endl;
471 cout << "audio/video enter : 3" << endl;
472 (void)getline(cin, recorderType);
473
474 SetVideoSource();
475 SetVideoEncodeMode();
476
477 GetFileFd();
478
479 int32_t ret = SetFormat(recorderType);
480 DEMO_CHECK_AND_RETURN_LOG(ret == MSERR_OK, "SetFormat failed ");
481
482 ret = recorder_->Prepare();
483 DEMO_CHECK_AND_RETURN_LOG(ret == MSERR_OK, "Prepare failed ");
484 cout << "Prepare finished" << endl;
485
486 if (recorderType != PURE_AUDIO) {
487 producerSurface_ = recorder_->GetSurface(g_videoRecorderConfig.videoSourceId);
488 DEMO_CHECK_AND_RETURN_LOG(producerSurface_ != nullptr, "GetSurface failed ");
489
490 if (g_videoRecorderConfig.vSource == VIDEO_SOURCE_SURFACE_ES) {
491 cout << "es source stream, get from file" << endl;
492 ret = GetStubFile();
493 DEMO_CHECK_AND_RETURN_LOG(ret == MSERR_OK, "GetStubFile failed ");
494
495 camereHDIThread_.reset(new(std::nothrow) std::thread(&RecorderDemo::HDICreateESBuffer, this));
496 } else if (g_videoRecorderConfig.vSource == VIDEO_SOURCE_SURFACE_YUV) {
497 camereHDIThread_.reset(new(std::nothrow) std::thread(&RecorderDemo::HDICreateYUVBuffer, this));
498 } else {
499 camereHDIThread_.reset(new(std::nothrow) std::thread(&RecorderDemo::HDICreateRGBABuffer, this));
500 }
501 }
502
503 ret = recorder_->Start();
504 DEMO_CHECK_AND_RETURN_LOG(ret == MSERR_OK, "Start failed ");
505 cout << "start recordering" << endl;
506 sleep(RECORDER_TIME);
507
508 isExit_.store(true);
509 ret = recorder_->Stop(false);
510 DEMO_CHECK_AND_RETURN_LOG(ret == MSERR_OK, "Stop failed ");
511 cout << "stop recordering" << endl;
512 if (recorderType != PURE_AUDIO && camereHDIThread_ != nullptr) {
513 camereHDIThread_->join();
514 }
515 ret = recorder_->Reset();
516 DEMO_CHECK_AND_RETURN_LOG(ret == MSERR_OK, "Reset failed ");
517 ret = recorder_->Release();
518 DEMO_CHECK_AND_RETURN_LOG(ret == MSERR_OK, "Release failed ");
519
520 close(g_videoRecorderConfig.outputFd);
521 }
522