• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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, &timestamp);
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