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