• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2022 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 <sync_fence.h>
17 #include "nocopyable.h"
18 #include "media_errors.h"
19 #include "venc_mock.h"
20 using namespace std;
21 using namespace OHOS::Media::VCodecTestParam;
22 
23 namespace OHOS {
24 namespace Media {
VEncCallbackTest(std::shared_ptr<VEncSignal> signal)25 VEncCallbackTest::VEncCallbackTest(std::shared_ptr<VEncSignal> signal)
26     : signal_(signal)
27 {
28 }
29 
~VEncCallbackTest()30 VEncCallbackTest::~VEncCallbackTest()
31 {
32 }
33 
OnError(int32_t errorCode)34 void VEncCallbackTest::OnError(int32_t errorCode)
35 {
36     cout << "VEnc Error errorCode=" << errorCode << endl;
37 }
38 
OnStreamChanged(std::shared_ptr<FormatMock> format)39 void VEncCallbackTest::OnStreamChanged(std::shared_ptr<FormatMock> format)
40 {
41     cout << "VEnc Format Changed" << endl;
42 }
43 
OnNeedInputData(uint32_t index,std::shared_ptr<AVMemoryMock> data)44 void VEncCallbackTest::OnNeedInputData(uint32_t index, std::shared_ptr<AVMemoryMock> data)
45 {
46 }
47 
OnNewOutputData(uint32_t index,std::shared_ptr<AVMemoryMock> data,AVCodecBufferAttrMock attr)48 void VEncCallbackTest::OnNewOutputData(uint32_t index, std::shared_ptr<AVMemoryMock> data, AVCodecBufferAttrMock attr)
49 {
50     if (signal_ == nullptr) {
51         return;
52     }
53     unique_lock<mutex> lock(signal_->outMutex_);
54     if (!signal_->isRunning_.load()) {
55         return;
56     }
57     signal_->outIndexQueue_.push(index);
58     signal_->outSizeQueue_.push(attr.size);
59     signal_->outBufferQueue_.push(data);
60     signal_->outCond_.notify_all();
61 }
62 
VEncMock(std::shared_ptr<VEncSignal> signal)63 VEncMock::VEncMock(std::shared_ptr<VEncSignal> signal)
64     : signal_(signal)
65 {
66 }
67 
~VEncMock()68 VEncMock::~VEncMock()
69 {
70 }
71 
CreateVideoEncMockByMime(const std::string & mime)72 bool VEncMock::CreateVideoEncMockByMime(const std::string &mime)
73 {
74     videoEnc_ = AVCodecMockFactory::CreateVideoEncMockByMime(mime);
75     return videoEnc_ != nullptr;
76 }
77 
CreateVideoEncMockByName(const std::string & name)78 bool VEncMock::CreateVideoEncMockByName(const std::string &name)
79 {
80     videoEnc_ = AVCodecMockFactory::CreateVideoEncMockByName(name);
81     return videoEnc_ != nullptr;
82 }
83 
SetCallback(std::shared_ptr<AVCodecCallbackMock> cb)84 int32_t VEncMock::SetCallback(std::shared_ptr<AVCodecCallbackMock> cb)
85 {
86     if (videoEnc_ == nullptr) {
87         return MSERR_INVALID_VAL;
88     }
89     return videoEnc_->SetCallback(cb);
90 }
91 
GetInputSurface()92 std::shared_ptr<SurfaceMock> VEncMock::GetInputSurface()
93 {
94     if (videoEnc_ == nullptr) {
95         return nullptr;
96     }
97     surface_ = videoEnc_->GetInputSurface();
98     return surface_;
99 }
100 
Configure(std::shared_ptr<FormatMock> format)101 int32_t VEncMock::Configure(std::shared_ptr<FormatMock> format)
102 {
103     if (videoEnc_ == nullptr) {
104         return MSERR_INVALID_VAL;
105     }
106     return videoEnc_->Configure(format);
107 }
108 
Prepare()109 int32_t VEncMock::Prepare()
110 {
111     if (videoEnc_ == nullptr) {
112         return MSERR_INVALID_VAL;
113     }
114     return videoEnc_->Prepare();
115 }
116 
Start()117 int32_t VEncMock::Start()
118 {
119     if (signal_ == nullptr || videoEnc_ == nullptr) {
120         return MSERR_INVALID_VAL;
121     }
122     signal_->isRunning_.store(true);
123     outLoop_ = make_unique<thread>(&VEncMock::OutLoopFunc, this);
124     UNITTEST_CHECK_AND_RETURN_RET_LOG(outLoop_ != nullptr, MSERR_UNKNOWN, "Fatal: No memory");
125     return videoEnc_->Start();
126 }
127 
FlushInner()128 void VEncMock::FlushInner()
129 {
130     if (signal_ == nullptr || videoEnc_ == nullptr) {
131         return;
132     }
133     signal_->isRunning_.store(false);
134     if (outLoop_ != nullptr && outLoop_->joinable()) {
135         unique_lock<mutex> queueLock(signal_->mutex_);
136         signal_->outIndexQueue_.push(10000); // push 10000 to stop queue
137         signal_->outCond_.notify_all();
138         queueLock.unlock();
139         outLoop_->join();
140         outLoop_.reset();
141         std::queue<uint32_t> temp;
142         std::swap(temp, signal_->outIndexQueue_);
143     }
144 }
145 
Stop()146 int32_t VEncMock::Stop()
147 {
148     FlushInner();
149     if (videoEnc_ == nullptr) {
150         return MSERR_INVALID_VAL;
151     }
152     return videoEnc_->Stop();
153 }
154 
Flush()155 int32_t VEncMock::Flush()
156 {
157     FlushInner();
158     if (videoEnc_ == nullptr) {
159         return MSERR_INVALID_VAL;
160     }
161     return videoEnc_->Flush();
162 }
163 
Reset()164 int32_t VEncMock::Reset()
165 {
166     FlushInner();
167     if (videoEnc_ == nullptr) {
168         return MSERR_INVALID_VAL;
169     }
170     return videoEnc_->Reset();
171 }
172 
Release()173 int32_t VEncMock::Release()
174 {
175     if (videoEnc_ == nullptr) {
176         return MSERR_INVALID_VAL;
177     }
178     return videoEnc_->Release();
179 }
180 
NotifyEos()181 int32_t VEncMock::NotifyEos()
182 {
183     if (videoEnc_ == nullptr) {
184         return MSERR_INVALID_VAL;
185     }
186     return videoEnc_->NotifyEos();
187 }
188 
GetOutputMediaDescription()189 std::shared_ptr<FormatMock> VEncMock::GetOutputMediaDescription()
190 {
191     if (videoEnc_ == nullptr) {
192         return nullptr;
193     }
194     return videoEnc_->GetOutputMediaDescription();
195 }
196 
SetParameter(std::shared_ptr<FormatMock> format)197 int32_t VEncMock::SetParameter(std::shared_ptr<FormatMock> format)
198 {
199     if (videoEnc_ == nullptr) {
200         return MSERR_INVALID_VAL;
201     }
202     return videoEnc_->SetParameter(format);
203 }
204 
FreeOutputData(uint32_t index)205 int32_t VEncMock::FreeOutputData(uint32_t index)
206 {
207     if (videoEnc_ == nullptr) {
208         return MSERR_INVALID_VAL;
209     }
210     return videoEnc_->FreeOutputData(index);
211 }
212 
SetOutPath(const std::string & path)213 void VEncMock::SetOutPath(const std::string &path)
214 {
215     outPath_ = path;
216 }
217 
OutLoopFunc()218 void VEncMock::OutLoopFunc()
219 {
220     if (signal_ == nullptr || videoEnc_ == nullptr) {
221         return;
222     }
223     while (true) {
224         if (!signal_->isRunning_.load()) {
225             break;
226         }
227 
228         unique_lock<mutex> lock(signal_->outMutex_);
229         signal_->outCond_.wait(lock, [this]() { return signal_->outIndexQueue_.size() > 0; });
230 
231         if (!signal_->isRunning_.load()) {
232             break;
233         }
234 
235         uint32_t index = signal_->outIndexQueue_.front();
236         auto buffer = signal_->outBufferQueue_.front();
237         uint32_t size = signal_->outSizeQueue_.front();
238 
239         if (buffer == nullptr) {
240             cout << "Fatal: GetOutputBuffer fail, exit" << endl;
241             break;
242         }
243         frameCount_++;
244 
245         if (NEED_DUMP) {
246             FILE *outFile;
247             const char *savepath = outPath_.c_str();
248             outFile = fopen(savepath, "a");
249             if (outFile == nullptr) {
250                 cout << "dump data fail" << endl;
251             } else {
252                 fwrite(buffer->GetAddr(), 1, size, outFile);
253                 fclose(outFile);
254             }
255         }
256         if (index != EOS_INDEX && videoEnc_->FreeOutputData(index) != MSERR_OK) {
257             cout << "Fatal: FreeOutputData fail, exit" << endl;
258             break;
259         }
260         signal_->outIndexQueue_.pop();
261         signal_->outSizeQueue_.pop();
262         signal_->outBufferQueue_.pop();
263     }
264 }
265 }  // namespace Media
266 }  // namespace OHOS
267