• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2025 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 #include <arpa/inet.h>
16 #include <sys/time.h>
17 #include <utility>
18 #include "serverenc_sample.h"
19 #include <iostream>
20 #include <chrono>
21 using namespace OHOS;
22 using namespace OHOS::HDI;
23 using namespace OHOS::Media;
24 using namespace OHOS::MediaAVCodec;
25 using namespace std;
26 namespace {
27 
28 } // namespace
29 
OnError(AVCodecErrorType errorType,int32_t errorCode)30 void VEncServerSample::CallBack::OnError(AVCodecErrorType errorType, int32_t errorCode)
31 {
32     cout << "--OnError--" << endl;
33     tester->isRunning_.store(false);
34     tester->signal_->inCond_.notify_all();
35 }
36 
OnOutputFormatChanged(const Format & format)37 void VEncServerSample::CallBack::OnOutputFormatChanged(const Format &format)
38 {
39     tester->GetOutputFormat();
40 }
41 
OnInputBufferAvailable(uint32_t index,std::shared_ptr<AVBuffer> buffer)42 void VEncServerSample::CallBack::OnInputBufferAvailable(uint32_t index, std::shared_ptr<AVBuffer> buffer)
43 {
44     unique_lock<mutex> lock(tester->signal_->inMutex_);
45     tester->signal_->inIdxQueue_.push(index);
46     tester->signal_->inBufferQueue_.push(buffer);
47     tester->signal_->inCond_.notify_all();
48 }
49 
OnOutputBufferAvailable(uint32_t index,std::shared_ptr<AVBuffer> buffer)50 void VEncServerSample::CallBack::OnOutputBufferAvailable(uint32_t index, std::shared_ptr<AVBuffer> buffer)
51 {
52     tester->codec_->ReleaseOutputBuffer(index);
53 }
54 
~VEncServerSample()55 VEncServerSample::~VEncServerSample()
56 {
57     if (codec_ != nullptr) {
58         SetParameter();
59         codec_->Stop();
60         codec_->Release();
61         codec_ = nullptr;
62     }
63     if (signal_ != nullptr) {
64         delete signal_;
65         signal_ = nullptr;
66     }
67 }
68 
SetParameter()69 int32_t VEncServerSample::SetParameter()
70 {
71     Format fmt;
72     fmt.PutIntValue(MediaDescriptionKey::MD_KEY_WIDTH, defaultWidth);
73     fmt.PutIntValue(MediaDescriptionKey::MD_KEY_HEIGHT, defaultHeight);
74     fmt.PutIntValue(MediaDescriptionKey::MD_KEY_PIXEL_FORMAT, defaultPixelFormat);
75     fmt.PutDoubleValue(MediaDescriptionKey::MD_KEY_FRAME_RATE, defaultFrameRate);
76     fmt.PutIntValue(MediaDescriptionKey::MD_KEY_ROTATION_ANGLE, 0);
77     return codec_->SetParameter(fmt);
78 }
79 
ConfigServerDecoder()80 int32_t VEncServerSample::ConfigServerDecoder()
81 {
82     Format fmt;
83     fmt.PutIntValue(MediaDescriptionKey::MD_KEY_WIDTH, defaultWidth);
84     fmt.PutIntValue(MediaDescriptionKey::MD_KEY_HEIGHT, defaultHeight);
85     fmt.PutIntValue(MediaDescriptionKey::MD_KEY_PIXEL_FORMAT, defaultPixelFormat);
86     fmt.PutDoubleValue(MediaDescriptionKey::MD_KEY_FRAME_RATE, defaultFrameRate);
87     fmt.PutIntValue(MediaDescriptionKey::MD_KEY_ROTATION_ANGLE, 0);
88     return codec_->Configure(fmt);
89 }
90 
SetCallback()91 int32_t VEncServerSample::SetCallback()
92 {
93     shared_ptr<CallBack> cb = make_shared<CallBack>(this);
94     return codec_->SetCallback(cb);
95 }
96 
RunVideoServerDecoder()97 void VEncServerSample::RunVideoServerDecoder()
98 {
99     codec_ = HCodec::Create("OMX.hisi.video.encoder.avc");
100     if (codec_ == nullptr) {
101         cout << "Create failed" << endl;
102         return;
103     }
104     Media::Meta meta{};
105     int32_t err = codec_->Init(meta);
106     err = ConfigServerDecoder();
107     if (err != AVCS_ERR_OK) {
108         cout << "ConfigServerDecoder failed" << endl;
109         return;
110     }
111     signal_ = new VEncSignal();
112     if (signal_ == nullptr) {
113         cout << "Failed to new VEncSignal" << endl;
114         return;
115     }
116     err = SetCallback();
117     if (err != AVCS_ERR_OK) {
118         cout << "SetCallback failed" << endl;
119         return;
120     }
121     err = codec_->Start();
122     if (err != AVCS_ERR_OK) {
123         cout << "Start failed" << endl;
124         return;
125     }
126     isRunning_.store(true);
127     inputLoop_ = make_unique<thread>(&VEncServerSample::InputFunc, this);
128     if (inputLoop_ == nullptr) {
129         cout << "Failed to create input loop" << endl;
130         isRunning_.store(false);
131     }
132 }
133 
InputFunc()134 void VEncServerSample::InputFunc()
135 {
136     int32_t time = 1000;
137     while (sendFrameIndex < frameIndex) {
138         if (!isRunning_.load()) {
139             break;
140         }
141         unique_lock<mutex> lock(signal_->inMutex_);
142         signal_->inCond_.wait_for(lock, std::chrono::milliseconds(time), [this]() {
143             if (!isRunning_.load()) {
144                 cout << "quit signal" << endl;
145                 return true;
146             }
147             return signal_->inIdxQueue_.size() > 0;
148         });
149         if (!isRunning_.load() || signal_->inIdxQueue_.size() == 0) {
150             break;
151         }
152         uint32_t index = signal_->inIdxQueue_.front();
153         auto buffer = signal_->inBufferQueue_.front();
154         signal_->inIdxQueue_.pop();
155         signal_->inBufferQueue_.pop();
156         lock.unlock();
157         if (buffer->memory_ == nullptr) {
158             isRunning_.store(false);
159             break;
160         }
161         uint8_t *bufferAddr = buffer->memory_->GetAddr();
162         if (memcpy_s(bufferAddr, buffer->memory_->GetCapacity(), fuzzData, fuzzSize) != EOK) {
163             break;
164         }
165         int32_t err = codec_->QueueInputBuffer(index);
166         if (err != AVCS_ERR_OK) {
167             cout << "QueueInputBuffer fail" << endl;
168             break;
169         }
170         sendFrameIndex++;
171     }
172 }
173 
WaitForEos()174 void VEncServerSample::WaitForEos()
175 {
176     if (inputLoop_ && inputLoop_->joinable()) {
177         inputLoop_->join();
178     }
179 }
180 
GetOutputFormat()181 void VEncServerSample::GetOutputFormat()
182 {
183     Format fmt;
184     int32_t err = codec_->GetOutputFormat(fmt);
185     if (err != AVCS_ERR_OK) {
186         cout << "GetOutputFormat fail" << endl;
187         isRunning_.store(false);
188         signal_->inCond_.notify_all();
189     }
190 }
191 
Flush()192 void VEncServerSample::Flush()
193 {
194     int32_t err = codec_->Flush();
195     if (err != AVCS_ERR_OK) {
196         cout << "Flush fail" << endl;
197         isRunning_.store(false);
198         signal_->inCond_.notify_all();
199     }
200 }
201 
Reset()202 void VEncServerSample::Reset()
203 {
204     int32_t err = codec_->Reset();
205     if (err != AVCS_ERR_OK) {
206         cout << "Reset fail" << endl;
207         isRunning_.store(false);
208         signal_->inCond_.notify_all();
209     }
210 }