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