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_video_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 Surface *g_surface = nullptr;
25
RecorderVideoSource()26 RecorderVideoSource::RecorderVideoSource()
27 : surface_(nullptr),
28 frameAvailableCount_(0),
29 acquireBuffer_(nullptr),
30 started_(false)
31 {
32 }
33
~RecorderVideoSource()34 RecorderVideoSource::~RecorderVideoSource()
35 {
36 if (surface_ != nullptr) {
37 surface_->UnregisterConsumerListener();
38 }
39 }
40
GetSurface()41 std::shared_ptr<OHOS::Surface> RecorderVideoSource::GetSurface()
42 {
43 if (surface_.get() == nullptr) {
44 Surface *surface = Surface::CreateSurface();
45 if (surface == nullptr) {
46 return nullptr;
47 }
48
49 g_surface = surface;
50 surface->RegisterConsumerListener(*this);
51 surface_.reset(surface);
52 }
53 MEDIA_INFO_LOG("Get Recorder Surface SUCCESS");
54 return surface_;
55 }
56
SetSurfaceSize(int32_t width,int32_t height)57 int32_t RecorderVideoSource::SetSurfaceSize(int32_t width, int32_t height)
58 {
59 if (surface_.get() == nullptr) {
60 Surface *surface = Surface::CreateSurface();
61 if (surface == nullptr) {
62 return ERR_UNKNOWN;
63 }
64
65 g_surface = surface;
66 surface->RegisterConsumerListener(*this);
67 surface_.reset(surface);
68 }
69 Surface *surface = surface_.get();
70 MEDIA_INFO_LOG("Get Recorder Surface SUCCESS");
71 surface->SetWidthAndHeight(width, height);
72 surface->SetQueueSize(SURFACE_QUEUE_SIZE);
73 /* 3/4 is the worst case of compression provide by encoder. */
74 surface->SetSize(width * height * 3 / 4);
75 return SUCCESS;
76 }
77
OnBufferAvailable()78 void RecorderVideoSource::OnBufferAvailable()
79 {
80 if (surface_ == nullptr) {
81 MEDIA_ERR_LOG("surface is NULL");
82 return;
83 }
84
85 if (!started_) {
86 MEDIA_ERR_LOG("video source is not started");
87 acquireBuffer_ = surface_->AcquireBuffer();
88 if (acquireBuffer_ == nullptr) {
89 MEDIA_INFO_LOG("Acquire buffer failed.");
90 return;
91 }
92 surface_->ReleaseBuffer(acquireBuffer_);
93 return;
94 }
95
96 std::unique_lock<std::mutex> lock(lock_);
97 if (frameAvailableCount_ == 0) {
98 frameAvailableCondition_.notify_one();
99 }
100 frameAvailableCount_++;
101 }
102
Start()103 int32_t RecorderVideoSource::Start()
104 {
105 started_ = true;
106 MEDIA_INFO_LOG("Start Recorder Video Source SUCCESS");
107 return SUCCESS;
108 }
109
AcquireBuffer(RecorderSourceBuffer & buffer,bool isBlocking)110 int32_t RecorderVideoSource::AcquireBuffer(RecorderSourceBuffer &buffer, bool isBlocking)
111 {
112 if (!started_) {
113 return ERR_NOT_STARTED;
114 }
115 if (isBlocking) {
116 std::unique_lock<std::mutex> lock(lock_);
117 if (frameAvailableCount_ <= 0) {
118 frameAvailableCondition_.wait(lock);
119 if (!started_) {
120 return ERR_READ_BUFFER;
121 }
122 }
123 frameAvailableCount_--;
124 }
125
126 if (surface_ == nullptr) {
127 MEDIA_ERR_LOG("surface is NULL");
128 return ERR_READ_BUFFER;
129 }
130 acquireBuffer_ = surface_->AcquireBuffer();
131 if (acquireBuffer_ == nullptr) {
132 MEDIA_ERR_LOG("Acquire buffer failed.");
133 return ERR_READ_BUFFER;
134 }
135 void *pBase = acquireBuffer_->GetVirAddr();
136 if (pBase == nullptr) {
137 MEDIA_ERR_LOG("GetVirAddr is nullptr");
138 return ERR_READ_BUFFER;
139 }
140 buffer.dataAddr = (uint8_t *)pBase;
141 buffer.dataLen = acquireBuffer_->GetSize();
142 int64_t valuets = 0;
143 acquireBuffer_->GetInt64(KEY_TIME_US, valuets);
144 buffer.timeStamp = valuets;
145
146 int32_t value = 0;
147 acquireBuffer_->GetInt32(KEY_IS_SYNC_FRAME, value);
148 buffer.keyFrameFlag = (value == 1) ? true : false;
149 return SUCCESS;
150 }
151
ReleaseBuffer(RecorderSourceBuffer & buffer)152 int32_t RecorderVideoSource::ReleaseBuffer(RecorderSourceBuffer &buffer)
153 {
154 surface_->ReleaseBuffer(acquireBuffer_);
155 return SUCCESS;
156 }
157
Stop()158 int32_t RecorderVideoSource::Stop()
159 {
160 started_ = false;
161 std::unique_lock<std::mutex> lock(lock_);
162 frameAvailableCondition_.notify_all();
163 return SUCCESS;
164 }
165
Resume()166 int32_t RecorderVideoSource::Resume()
167 {
168 return SUCCESS;
169 }
170
Pause()171 int32_t RecorderVideoSource::Pause()
172 {
173 return SUCCESS;
174 }
175
Release()176 int32_t RecorderVideoSource::Release()
177 {
178 return SUCCESS;
179 }
180 } // namespace Media
181 } // namespace OHOS