1 /*
2 * Copyright (c) 2020-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_data_source.h"
17 #include "media_log.h"
18
19 namespace OHOS {
20 namespace Media {
21 constexpr int32_t KEY_IS_SYNC_FRAME = 1; // "is-sync-frame"
22 constexpr int32_t KEY_TIME_US = 2; // "timeUs"
23 constexpr int32_t SURFACE_QUEUE_SIZE = 3;
24 constexpr int32_t SURFACE_SIZE = 1024 * 1024; // 1M for surface
25 constexpr int32_t SURFACE_DEFAULT_HEIGHT = 1920; // 1M for surface
26 constexpr int32_t SURFACE_DEFAULT_WIDTH = 1080; // 1M for surface
27
RecorderDataSource()28 RecorderDataSource::RecorderDataSource()
29 : surface_(nullptr),
30 frameAvailableCount_(0),
31 acquireBuffer_(nullptr),
32 started_(false)
33 {
34 }
35
~RecorderDataSource()36 RecorderDataSource::~RecorderDataSource()
37 {
38 if (surface_ != nullptr) {
39 surface_->UnregisterConsumerListener();
40 }
41 }
42
GetSurface()43 std::shared_ptr<OHOS::Surface> RecorderDataSource::GetSurface()
44 {
45 if (surface_.get() == nullptr) {
46 Surface *surface = Surface::CreateSurface();
47 if (surface == nullptr) {
48 return nullptr;
49 }
50 surface->SetWidthAndHeight(SURFACE_DEFAULT_HEIGHT, SURFACE_DEFAULT_WIDTH);
51 surface->SetQueueSize(SURFACE_QUEUE_SIZE);
52 surface->SetSize(SURFACE_SIZE);
53 surface->RegisterConsumerListener(*this);
54 surface_.reset(surface);
55 }
56 MEDIA_INFO_LOG("Get Recorder data Surface SUCCESS");
57
58 return surface_;
59 }
60
OnBufferAvailable()61 void RecorderDataSource::OnBufferAvailable()
62 {
63 if (surface_ == nullptr) {
64 MEDIA_ERR_LOG("surface is NULL");
65 return;
66 }
67
68 if (!started_) {
69 MEDIA_ERR_LOG("data source is not started");
70 acquireBuffer_ = surface_->AcquireBuffer();
71 if (acquireBuffer_ == nullptr) {
72 MEDIA_ERR_LOG("Acquire buffer failed.");
73 return;
74 }
75 surface_->ReleaseBuffer(acquireBuffer_);
76 return;
77 }
78
79 std::unique_lock<std::mutex> lock(lock_);
80 if (frameAvailableCount_ == 0) {
81 frameAvailableCondition_.notify_one();
82 }
83 frameAvailableCount_++;
84 }
85
Start()86 int32_t RecorderDataSource::Start()
87 {
88 started_ = true;
89 MEDIA_INFO_LOG("Start data source SUCCESS");
90 return SUCCESS;
91 }
92
AcquireBuffer(RecorderSourceBuffer & buffer,bool isBlocking)93 int32_t RecorderDataSource::AcquireBuffer(RecorderSourceBuffer &buffer, bool isBlocking)
94 {
95 if (!started_) {
96 return ERR_NOT_STARTED;
97 }
98 if (isBlocking) {
99 std::unique_lock<std::mutex> lock(lock_);
100 if (frameAvailableCount_ <= 0) {
101 frameAvailableCondition_.wait(lock);
102 if (!started_) {
103 return SUCCESS;
104 }
105 }
106 frameAvailableCount_--;
107 }
108 if (surface_ == nullptr) {
109 MEDIA_ERR_LOG("surface is NULL");
110 return ERR_READ_BUFFER;
111 }
112 acquireBuffer_ = surface_->AcquireBuffer();
113 if (acquireBuffer_ == nullptr) {
114 MEDIA_ERR_LOG("Acquire buffer failed.");
115 return ERR_READ_BUFFER;
116 }
117 void *pBase = acquireBuffer_->GetVirAddr();
118 if (pBase == nullptr) {
119 MEDIA_ERR_LOG("GetVirAddr nullptr");
120 return ERR_READ_BUFFER;
121 }
122 buffer.dataAddr = (uint8_t *)pBase;
123 buffer.dataLen = acquireBuffer_->GetSize();
124 int64_t valuets = 0;
125 acquireBuffer_->GetInt64(KEY_TIME_US, valuets);
126 buffer.timeStamp = valuets;
127
128 int32_t value = 0;
129 acquireBuffer_->GetInt32(KEY_IS_SYNC_FRAME, value);
130 buffer.keyFrameFlag = (value == 1) ? true : false;
131 return SUCCESS;
132 }
133
ReleaseBuffer(RecorderSourceBuffer & buffer)134 int32_t RecorderDataSource::ReleaseBuffer(RecorderSourceBuffer &buffer)
135 {
136 surface_->ReleaseBuffer(acquireBuffer_);
137 return SUCCESS;
138 }
139
Stop()140 int32_t RecorderDataSource::Stop()
141 {
142 started_ = false;
143 std::unique_lock<std::mutex> lock(lock_);
144 frameAvailableCondition_.notify_all();
145 return SUCCESS;
146 }
147
Resume()148 int32_t RecorderDataSource::Resume()
149 {
150 return SUCCESS;
151 }
152
Pause()153 int32_t RecorderDataSource::Pause()
154 {
155 return SUCCESS;
156 }
157
Release()158 int32_t RecorderDataSource::Release()
159 {
160 return SUCCESS;
161 }
162 } // namespace Media
163 } // namespace OHOS
164