1 /*
2  * Copyright (C) 2023 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 "openssl/crypto.h"
19 #include "openssl/sha.h"
20 #include "videodec_api11_sample.h"
21 using namespace OHOS;
22 using namespace OHOS::Media;
23 using namespace std;
24 namespace {
25 constexpr int64_t NANOS_IN_SECOND = 1000000000L;
26 constexpr int64_t MICRO_IN_SECOND = 1000000L;
27 constexpr int64_t NANOS_IN_MICRO = 1000L;
28 constexpr int32_t THREE = 3;
29 constexpr int32_t EIGHT = 8;
30 constexpr int32_t TEN = 10;
31 constexpr int32_t SIXTEEN = 16;
32 constexpr int32_t TWENTY_FOUR = 24;
33 constexpr uint8_t H264_NALU_TYPE = 0x1f;
34 constexpr uint32_t START_CODE_SIZE = 4;
35 constexpr uint8_t START_CODE[START_CODE_SIZE] = {0, 0, 0, 1};
36 constexpr uint8_t SPS = 7;
37 constexpr uint8_t PPS = 8;
38 constexpr int32_t RES_CHANGE_TIME = 4;
39 constexpr int32_t CROP_INFO_SIZE = 2;
40 constexpr int32_t CROP_INFO[RES_CHANGE_TIME][CROP_INFO_SIZE] = {{621, 1103},
41     {1079, 1919}, {719, 1279}, {855, 1919}};
42 
43 constexpr int32_t CROP_BOTTOM = 0;
44 constexpr int32_t CROP_RIGHT = 1;
45 constexpr int32_t DEFAULT_ANGLE = 90;
46 SHA512_CTX g_c;
47 unsigned char g_md[SHA512_DIGEST_LENGTH];
48 VDecAPI11Sample *dec_sample = nullptr;
49 
clearIntqueue(std::queue<uint32_t> & q)50 void clearIntqueue(std::queue<uint32_t> &q)
51 {
52     std::queue<uint32_t> empty;
53     swap(empty, q);
54 }
55 
clearBufferqueue(std::queue<OH_AVCodecBufferAttr> & q)56 void clearBufferqueue(std::queue<OH_AVCodecBufferAttr> &q)
57 {
58     std::queue<OH_AVCodecBufferAttr> empty;
59     swap(empty, q);
60 }
61 } // namespace
62 
63 class ConsumerListenerBuffer : public IBufferConsumerListener {
64 public:
ConsumerListenerBuffer(sptr<Surface> cs,std::string_view name)65     ConsumerListenerBuffer(sptr<Surface> cs, std::string_view name) : cs(cs) {};
~ConsumerListenerBuffer()66     ~ConsumerListenerBuffer() {}
OnBufferAvailable()67     void OnBufferAvailable() override
68     {
69         sptr<SurfaceBuffer> buffer;
70         int32_t flushFence;
71         cs->AcquireBuffer(buffer, flushFence, timestamp, damage);
72         cs->ReleaseBuffer(buffer, -1);
73     }
74 
75 private:
76     int64_t timestamp = 0;
77     Rect damage = {};
78     sptr<Surface> cs {nullptr};
79 };
80 
~VDecAPI11Sample()81 VDecAPI11Sample::~VDecAPI11Sample()
82 {
83     for (int i = 0; i < MAX_SURF_NUM; i++) {
84         if (nativeWindow[i]) {
85             OH_NativeWindow_DestroyNativeWindow(nativeWindow[i]);
86             nativeWindow[i] = nullptr;
87         }
88     }
89     Stop();
90     Release();
91 }
92 
VdecAPI11Error(OH_AVCodec * codec,int32_t errorCode,void * userData)93 void VdecAPI11Error(OH_AVCodec *codec, int32_t errorCode, void *userData)
94 {
95     cout << "Error errorCode=" << errorCode << endl;
96 }
97 
VdecAPI11FormatChanged(OH_AVCodec * codec,OH_AVFormat * format,void * userData)98 void VdecAPI11FormatChanged(OH_AVCodec *codec, OH_AVFormat *format, void *userData)
99 {
100     int32_t currentWidth = 0;
101     int32_t currentHeight = 0;
102     OH_AVFormat_GetIntValue(format, OH_MD_KEY_WIDTH, &currentWidth);
103     OH_AVFormat_GetIntValue(format, OH_MD_KEY_HEIGHT, &currentHeight);
104     dec_sample->DEFAULT_WIDTH = currentWidth;
105     dec_sample->DEFAULT_HEIGHT = currentHeight;
106     if (dec_sample->isResChangeStream) {
107         static int32_t resCount = 0;
108         int32_t cropBottom = 0;
109         int32_t cropRight = 0;
110         int32_t stride = 0;
111         int32_t sliceHeight = 0;
112         OH_AVFormat_GetIntValue(format, OH_MD_KEY_VIDEO_CROP_BOTTOM, &cropBottom);
113         OH_AVFormat_GetIntValue(format, OH_MD_KEY_VIDEO_CROP_RIGHT, &cropRight);
114         OH_AVFormat_GetIntValue(format, OH_MD_KEY_VIDEO_STRIDE, &stride);
115         OH_AVFormat_GetIntValue(format, OH_MD_KEY_VIDEO_SLICE_HEIGHT, &sliceHeight);
116         if (cropBottom != CROP_INFO[resCount][CROP_BOTTOM] || cropRight != CROP_INFO[resCount][CROP_RIGHT]) {
117             dec_sample->errCount++;
118         }
119         if (stride <= 0 || sliceHeight <= 0) {
120             dec_sample->errCount++;
121         }
122         resCount++;
123     }
124 }
125 
VdecAPI11InputDataReady(OH_AVCodec * codec,uint32_t index,OH_AVBuffer * data,void * userData)126 void VdecAPI11InputDataReady(OH_AVCodec *codec, uint32_t index, OH_AVBuffer *data, void *userData)
127 {
128     if (dec_sample->inputCallbackFlush && dec_sample->outCount > 1) {
129         OH_VideoDecoder_Flush(codec);
130         cout << "OH_VideoDecoder_Flush end" << endl;
131         dec_sample->isRunning_.store(false);
132         dec_sample->signal_->inCond_.notify_all();
133         dec_sample->signal_->outCond_.notify_all();
134         return;
135     }
136     if (dec_sample->inputCallbackStop && dec_sample->outCount > 1) {
137         OH_VideoDecoder_Stop(codec);
138         cout << "OH_VideoDecoder_Stop end" << endl;
139         dec_sample->isRunning_.store(false);
140         dec_sample->signal_->inCond_.notify_all();
141         dec_sample->signal_->outCond_.notify_all();
142         return;
143     }
144     VDecAPI11Signal *signal = static_cast<VDecAPI11Signal *>(userData);
145     unique_lock<mutex> lock(signal->inMutex_);
146     signal->inIdxQueue_.push(index);
147     signal->inBufferQueue_.push(data);
148     signal->inCond_.notify_all();
149 }
150 
VdecAPI11OutputDataReady(OH_AVCodec * codec,uint32_t index,OH_AVBuffer * data,void * userData)151 void VdecAPI11OutputDataReady(OH_AVCodec *codec, uint32_t index, OH_AVBuffer *data, void *userData)
152 {
153     if (dec_sample->outputCallbackFlush && dec_sample->outCount > 1) {
154         OH_VideoDecoder_Flush(codec);
155         cout << "OH_VideoDecoder_Flush end" << endl;
156         dec_sample->isRunning_.store(false);
157         dec_sample->signal_->inCond_.notify_all();
158         dec_sample->signal_->outCond_.notify_all();
159         return;
160     }
161     if (dec_sample->outputCallbackStop && dec_sample->outCount > 1) {
162         OH_VideoDecoder_Stop(codec);
163         cout << "OH_VideoDecoder_Stop end" << endl;
164         dec_sample->isRunning_.store(false);
165         dec_sample->signal_->inCond_.notify_all();
166         dec_sample->signal_->outCond_.notify_all();
167         return;
168     }
169     VDecAPI11Signal *signal = static_cast<VDecAPI11Signal *>(userData);
170     unique_lock<mutex> lock(signal->outMutex_);
171     signal->outIdxQueue_.push(index);
172     signal->outBufferQueue_.push(data);
173     signal->outCond_.notify_all();
174 }
175 
Flush_buffer()176 void VDecAPI11Sample::Flush_buffer()
177 {
178     unique_lock<mutex> inLock(signal_->inMutex_);
179     clearIntqueue(signal_->inIdxQueue_);
180     std::queue<OH_AVBuffer *> empty;
181     swap(empty, signal_->inBufferQueue_);
182     signal_->inCond_.notify_all();
183     inLock.unlock();
184     unique_lock<mutex> outLock(signal_->outMutex_);
185     clearIntqueue(signal_->outIdxQueue_);
186     clearBufferqueue(signal_->attrQueue_);
187     signal_->outCond_.notify_all();
188     outLock.unlock();
189 }
190 
MdCompare(unsigned char buffer[],int len,const char * source[])191 bool VDecAPI11Sample::MdCompare(unsigned char buffer[], int len, const char *source[])
192 {
193     bool result = true;
194     for (int i = 0; i < len; i++) {
195     }
196     return result;
197 }
198 
GetSystemTimeUs()199 int64_t VDecAPI11Sample::GetSystemTimeUs()
200 {
201     struct timespec now;
202     (void)clock_gettime(CLOCK_BOOTTIME, &now);
203     int64_t nanoTime = (int64_t)now.tv_sec * NANOS_IN_SECOND + now.tv_nsec;
204     return nanoTime / NANOS_IN_MICRO;
205 }
206 
ConfigureVideoDecoder()207 int32_t VDecAPI11Sample::ConfigureVideoDecoder()
208 {
209     if (autoSwitchSurface) {
210         switchSurfaceFlag = (switchSurfaceFlag == 1) ? 0 : 1;
211         if (OH_VideoDecoder_SetSurface(vdec_, nativeWindow[switchSurfaceFlag]) != AV_ERR_INVALID_STATE) {
212             errCount++;
213         }
214     }
215     OH_AVFormat *format = OH_AVFormat_Create();
216     if (format == nullptr) {
217         cout << "Fatal: Failed to create format" << endl;
218         return AV_ERR_UNKNOWN;
219     }
220     if (maxInputSize > 0) {
221         (void)OH_AVFormat_SetIntValue(format, OH_MD_KEY_MAX_INPUT_SIZE, maxInputSize);
222     }
223     originalWidth = DEFAULT_WIDTH;
224     originalHeight = DEFAULT_HEIGHT;
225     (void)OH_AVFormat_SetIntValue(format, OH_MD_KEY_WIDTH, DEFAULT_WIDTH);
226     (void)OH_AVFormat_SetIntValue(format, OH_MD_KEY_HEIGHT, DEFAULT_HEIGHT);
227     (void)OH_AVFormat_SetIntValue(format, OH_MD_KEY_PIXEL_FORMAT, AV_PIXEL_FORMAT_NV12);
228     (void)OH_AVFormat_SetDoubleValue(format, OH_MD_KEY_FRAME_RATE, DEFAULT_FRAME_RATE);
229     if (useHDRSource) {
230         (void)OH_AVFormat_SetIntValue(format, OH_MD_KEY_PROFILE, DEFAULT_PROFILE);
231     }
232     int ret = OH_VideoDecoder_Configure(vdec_, format);
233     OH_AVFormat_Destroy(format);
234     return ret;
235 }
236 
CreateSurface()237 void VDecAPI11Sample::CreateSurface()
238 {
239     cs[0] = Surface::CreateSurfaceAsConsumer();
240     sptr<IBufferConsumerListener> listener = new ConsumerListenerBuffer(cs[0], OUT_DIR);
241     cs[0]->RegisterConsumerListener(listener);
242     auto p = cs[0]->GetProducer();
243     ps[0] = Surface::CreateSurfaceAsProducer(p);
244     nativeWindow[0] = CreateNativeWindowFromSurface(&ps[0]);
245     if (autoSwitchSurface)  {
246         cs[1] = Surface::CreateSurfaceAsConsumer();
247         sptr<IBufferConsumerListener> listener2 = new ConsumerListenerBuffer(cs[1], OUT_DIR2);
248         cs[1]->RegisterConsumerListener(listener2);
249         auto p2 = cs[1]->GetProducer();
250         ps[1] = Surface::CreateSurfaceAsProducer(p2);
251         nativeWindow[1] = CreateNativeWindowFromSurface(&ps[1]);
252     }
253 }
254 
RunVideoDec_Surface(string codeName)255 int32_t VDecAPI11Sample::RunVideoDec_Surface(string codeName)
256 {
257     SF_OUTPUT = true;
258     int err = AV_ERR_OK;
259     CreateSurface();
260     if (!nativeWindow[0]) {
261         cout << "Failed to create surface" << endl;
262         return AV_ERR_UNKNOWN;
263     }
264     err = CreateVideoDecoder(codeName);
265     if (err != AV_ERR_OK) {
266         cout << "Failed to create video decoder" << endl;
267         return err;
268     }
269     err = SetVideoDecoderCallback();
270     if (err != AV_ERR_OK) {
271         cout << "Failed to setCallback" << endl;
272         Release();
273         return err;
274     }
275     err = ConfigureVideoDecoder();
276     if (err != AV_ERR_OK) {
277         cout << "Failed to configure video decoder" << endl;
278         Release();
279         return err;
280     }
281     err = OH_VideoDecoder_SetSurface(vdec_, nativeWindow[0]);
282     if (err != AV_ERR_OK) {
283         cout << "Failed to set surface" << endl;
284         return err;
285     }
286     err = StartVideoDecoder();
287     if (err != AV_ERR_OK) {
288         cout << "Failed to start video decoder" << endl;
289         Release();
290         return err;
291     }
292     return err;
293 }
294 
RunVideoDec(string codeName)295 int32_t VDecAPI11Sample::RunVideoDec(string codeName)
296 {
297     SF_OUTPUT = false;
298     int err = CreateVideoDecoder(codeName);
299     if (err != AV_ERR_OK) {
300         cout << "Failed to create video decoder" << endl;
301         return err;
302     }
303 
304     err = ConfigureVideoDecoder();
305     if (err != AV_ERR_OK) {
306         cout << "Failed to configure video decoder" << endl;
307         Release();
308         return err;
309     }
310 
311     err = SetVideoDecoderCallback();
312     if (err != AV_ERR_OK) {
313         cout << "Failed to setCallback" << endl;
314         Release();
315         return err;
316     }
317 
318     err = StartVideoDecoder();
319     if (err != AV_ERR_OK) {
320         cout << "Failed to start video decoder" << endl;
321         Release();
322         return err;
323     }
324     return err;
325 }
326 
SetVideoDecoderCallback()327 int32_t VDecAPI11Sample::SetVideoDecoderCallback()
328 {
329     signal_ = new VDecAPI11Signal();
330     if (signal_ == nullptr) {
331         cout << "Failed to new VDecAPI11Signal" << endl;
332         return AV_ERR_UNKNOWN;
333     }
334 
335     cb_.onError = VdecAPI11Error;
336     cb_.onStreamChanged = VdecAPI11FormatChanged;
337     cb_.onNeedInputBuffer = VdecAPI11InputDataReady;
338     cb_.onNewOutputBuffer = VdecAPI11OutputDataReady;
339     return OH_VideoDecoder_RegisterCallback(vdec_, cb_, static_cast<void *>(signal_));
340 }
341 
ReleaseInFile()342 void VDecAPI11Sample::ReleaseInFile()
343 {
344     if (inFile_ != nullptr) {
345         if (inFile_->is_open()) {
346             inFile_->close();
347         }
348         inFile_.reset();
349         inFile_ = nullptr;
350     }
351 }
352 
StopInloop()353 void VDecAPI11Sample::StopInloop()
354 {
355     if (inputLoop_ != nullptr && inputLoop_->joinable()) {
356         unique_lock<mutex> lock(signal_->inMutex_);
357         clearIntqueue(signal_->inIdxQueue_);
358         isRunning_.store(false);
359         signal_->inCond_.notify_all();
360         lock.unlock();
361 
362         inputLoop_->join();
363         inputLoop_.reset();
364     }
365 }
366 
CreateVideoDecoder(string codeName)367 int32_t VDecAPI11Sample::CreateVideoDecoder(string codeName)
368 {
369     vdec_ = OH_VideoDecoder_CreateByName(codeName.c_str());
370     dec_sample = this;
371     return vdec_ == nullptr ? AV_ERR_UNKNOWN : AV_ERR_OK;
372 }
373 
StartVideoDecoder()374 int32_t VDecAPI11Sample::StartVideoDecoder()
375 {
376     isRunning_.store(true);
377     int ret = OH_VideoDecoder_Start(vdec_);
378     if (ret != AV_ERR_OK) {
379         cout << "Failed to start codec" << endl;
380         isRunning_.store(false);
381         ReleaseInFile();
382         Release();
383         return ret;
384     }
385     inFile_ = make_unique<ifstream>();
386     if (inFile_ == nullptr) {
387         isRunning_.store(false);
388         (void)OH_VideoDecoder_Stop(vdec_);
389         return AV_ERR_UNKNOWN;
390     }
391     inFile_->open(INP_DIR, ios::in | ios::binary);
392     if (!inFile_->is_open()) {
393         cout << "failed open file " << INP_DIR << endl;
394         isRunning_.store(false);
395         (void)OH_VideoDecoder_Stop(vdec_);
396         inFile_->close();
397         inFile_.reset();
398         inFile_ = nullptr;
399         return AV_ERR_UNKNOWN;
400     }
401     inputLoop_ = make_unique<thread>(&VDecAPI11Sample::InputFuncTest, this);
402     if (inputLoop_ == nullptr) {
403         cout << "Failed to create input loop" << endl;
404         isRunning_.store(false);
405         (void)OH_VideoDecoder_Stop(vdec_);
406         ReleaseInFile();
407         return AV_ERR_UNKNOWN;
408     }
409     outputLoop_ = make_unique<thread>(&VDecAPI11Sample::OutputFuncTest, this);
410     if (outputLoop_ == nullptr) {
411         cout << "Failed to create output loop" << endl;
412         isRunning_.store(false);
413         (void)OH_VideoDecoder_Stop(vdec_);
414         ReleaseInFile();
415         StopInloop();
416         Release();
417         return AV_ERR_UNKNOWN;
418     }
419 
420     return AV_ERR_OK;
421 }
422 
testAPI()423 void VDecAPI11Sample::testAPI()
424 {
425     cs[0] = Surface::CreateSurfaceAsConsumer();
426     sptr<IBufferConsumerListener> listener = new ConsumerListenerBuffer(cs[0], OUT_DIR);
427     cs[0]->RegisterConsumerListener(listener);
428     auto p = cs[0]->GetProducer();
429     ps[0] = Surface::CreateSurfaceAsProducer(p);
430     nativeWindow[0] = CreateNativeWindowFromSurface(&ps[0]);
431     OH_VideoDecoder_SetSurface(vdec_, nativeWindow[0]);
432 
433     OH_VideoDecoder_Prepare(vdec_);
434     OH_VideoDecoder_Start(vdec_);
435 
436     OH_AVFormat *format = OH_AVFormat_Create();
437     (void)OH_AVFormat_SetIntValue(format, OH_MD_KEY_WIDTH, DEFAULT_WIDTH);
438     (void)OH_AVFormat_SetIntValue(format, OH_MD_KEY_HEIGHT, DEFAULT_HEIGHT);
439     (void)OH_AVFormat_SetIntValue(format, OH_MD_KEY_PIXEL_FORMAT, AV_PIXEL_FORMAT_NV12);
440     (void)OH_AVFormat_SetDoubleValue(format, OH_MD_KEY_FRAME_RATE, DEFAULT_FRAME_RATE);
441     OH_VideoDecoder_SetParameter(vdec_, format);
442     OH_AVFormat_Destroy(format);
443     OH_VideoDecoder_GetOutputDescription(vdec_);
444     OH_VideoDecoder_Flush(vdec_);
445     OH_VideoDecoder_Stop(vdec_);
446     OH_VideoDecoder_Reset(vdec_);
447     bool isvalid = false;
448     OH_VideoDecoder_IsValid(vdec_, &isvalid);
449 }
450 
WaitForEOS()451 void VDecAPI11Sample::WaitForEOS()
452 {
453     if (!AFTER_EOS_DESTORY_CODEC && inputLoop_ && inputLoop_->joinable()) {
454         inputLoop_->join();
455     }
456 
457     if (outputLoop_ && outputLoop_->joinable()) {
458         outputLoop_->join();
459     }
460 }
461 
InputFuncTest()462 void VDecAPI11Sample::InputFuncTest()
463 {
464     bool flag = true;
465     while (flag) {
466         if (!isRunning_.load()) {
467             flag = false;
468             break;
469         }
470         if (REPEAT_START_FLUSH_BEFORE_EOS > 0) {
471             REPEAT_START_FLUSH_BEFORE_EOS--;
472             OH_VideoDecoder_Flush(vdec_);
473             Flush_buffer();
474             OH_VideoDecoder_Start(vdec_);
475         }
476         if (REPEAT_START_STOP_BEFORE_EOS > 0) {
477             REPEAT_START_STOP_BEFORE_EOS--;
478             OH_VideoDecoder_Stop(vdec_);
479             Flush_buffer();
480             OH_VideoDecoder_Start(vdec_);
481         }
482         uint32_t index;
483         unique_lock<mutex> lock(signal_->inMutex_);
484         signal_->inCond_.wait(lock, [this]() {
485             if (!isRunning_.load()) {
486                 return true;
487             }
488             return signal_->inIdxQueue_.size() > 0;
489         });
490         if (!isRunning_.load()) {
491             flag = false;
492             break;
493         }
494         index = signal_->inIdxQueue_.front();
495         auto buffer = signal_->inBufferQueue_.front();
496 
497         signal_->inIdxQueue_.pop();
498         signal_->inBufferQueue_.pop();
499         lock.unlock();
500         if (!inFile_->eof()) {
501             int ret = PushData(index, buffer);
502             if (ret == 1) {
503                 flag = false;
504                 break;
505             }
506         }
507         if (sleepOnFPS) {
508             usleep(MICRO_IN_SECOND / (int32_t)DEFAULT_FRAME_RATE);
509         }
510     }
511 }
512 
PushData(uint32_t index,OH_AVBuffer * buffer)513 int32_t VDecAPI11Sample::PushData(uint32_t index, OH_AVBuffer *buffer)
514 {
515     OH_AVCodecBufferAttr attr;
516     if (BEFORE_EOS_INPUT && frameCount_ > TEN) {
517         SetEOS(index, buffer);
518         return 1;
519     }
520     if (BEFORE_EOS_INPUT_INPUT && frameCount_ > TEN) {
521         memset_s(&attr, sizeof(OH_AVCodecBufferAttr), 0, sizeof(OH_AVCodecBufferAttr));
522         attr.flags = AVCODEC_BUFFER_FLAGS_EOS;
523         BEFORE_EOS_INPUT_INPUT = false;
524     }
525     char ch[4] = {};
526     (void)inFile_->read(ch, START_CODE_SIZE);
527     if (repeatRun && inFile_->eof()) {
528         static uint32_t repeat_count = 0;
529         inFile_->clear();
530         inFile_->seekg(0, ios::beg);
531         cout << "repeat run " << repeat_count << endl;
532         repeat_count++;
533         return 0;
534     }
535     if (inFile_->eof()) {
536         SetEOS(index, buffer);
537         return 1;
538     }
539     uint32_t bufferSize = (uint32_t)(((ch[3] & 0xFF)) | ((ch[2] & 0xFF) << EIGHT) | ((ch[1] & 0xFF) << SIXTEEN) |
540                                      ((ch[0] & 0xFF) << TWENTY_FOUR));
541     if (useHDRSource) {
542         uint32_t zero = 0;
543         uint32_t one = 1;
544         uint32_t two = 2;
545         uint32_t three = 3;
546         bufferSize = (uint32_t)(((ch[zero] & 0xFF)) | ((ch[one] & 0xFF) << EIGHT) | ((ch[two] & 0xFF) << SIXTEEN) |
547                                      ((ch[three] & 0xFF) << TWENTY_FOUR));
548     }
549     if (bufferSize >= DEFAULT_WIDTH * DEFAULT_HEIGHT * THREE >> 1) {
550         cout << "read bufferSize abnormal. buffersize = " << bufferSize << endl;
551         return 1;
552     }
553     return SendData(bufferSize, index, buffer);
554 }
555 
CheckAndReturnBufferSize(OH_AVBuffer * buffer)556 int32_t VDecAPI11Sample::CheckAndReturnBufferSize(OH_AVBuffer *buffer)
557 {
558     int32_t size = OH_AVBuffer_GetCapacity(buffer);
559     if (maxInputSize > 0 && (size > maxInputSize)) {
560         errCount++;
561     }
562     return size;
563 }
564 
SendData(uint32_t bufferSize,uint32_t index,OH_AVBuffer * buffer)565 uint32_t VDecAPI11Sample::SendData(uint32_t bufferSize, uint32_t index, OH_AVBuffer *buffer)
566 {
567     OH_AVCodecBufferAttr attr;
568     uint8_t *fileBuffer = new uint8_t[bufferSize + START_CODE_SIZE];
569     if (fileBuffer == nullptr) {
570         delete[] fileBuffer;
571         return 0;
572     }
573     if (memcpy_s(fileBuffer, bufferSize + START_CODE_SIZE, START_CODE, START_CODE_SIZE) != EOK) {
574         cout << "Fatal: memory copy failed" << endl;
575     }
576     (void)inFile_->read(reinterpret_cast<char *>(fileBuffer) + START_CODE_SIZE, bufferSize);
577     if ((fileBuffer[START_CODE_SIZE] & H264_NALU_TYPE) == SPS ||
578         (fileBuffer[START_CODE_SIZE] & H264_NALU_TYPE) == PPS) {
579         attr.flags = AVCODEC_BUFFER_FLAGS_CODEC_DATA;
580     } else {
581         attr.flags = AVCODEC_BUFFER_FLAGS_NONE;
582     }
583     int32_t size = CheckAndReturnBufferSize(buffer);
584     if (size < bufferSize + START_CODE_SIZE) {
585         delete[] fileBuffer;
586         return 0;
587     }
588     uint8_t *avBuffer = OH_AVBuffer_GetAddr(buffer);
589     if (avBuffer == nullptr) {
590         inFile_->clear();
591         inFile_->seekg(0, ios::beg);
592         delete[] fileBuffer;
593         return 0;
594     }
595     if (memcpy_s(avBuffer, size, fileBuffer, bufferSize + START_CODE_SIZE) != EOK) {
596         delete[] fileBuffer;
597         return 0;
598     }
599     int64_t startPts = GetSystemTimeUs();
600     attr.pts = startPts;
601     attr.size = bufferSize + START_CODE_SIZE;
602     attr.offset = 0;
603     if (isRunning_.load()) {
604         OH_AVBuffer_SetBufferAttr(buffer, &attr);
605         OH_VideoDecoder_PushInputBuffer(vdec_, index) == AV_ERR_OK ? (0) : (errCount++);
606         frameCount_ = frameCount_ + 1;
607         outCount = outCount + 1;
608         if (autoSwitchSurface && (frameCount_ % (int32_t)DEFAULT_FRAME_RATE == 0)) {
609             switchSurfaceFlag = (switchSurfaceFlag == 1) ? 0 : 1;
610             OH_VideoDecoder_SetSurface(vdec_, nativeWindow[switchSurfaceFlag]) == AV_ERR_OK ? (0) : (errCount++);
611         }
612     }
613     delete[] fileBuffer;
614     return 0;
615 }
616 
CheckOutputDescription()617 void VDecAPI11Sample::CheckOutputDescription()
618 {
619     OH_AVFormat *newFormat = OH_VideoDecoder_GetOutputDescription(vdec_);
620     if (newFormat != nullptr) {
621         int32_t cropTop = 0;
622         int32_t cropBottom = 0;
623         int32_t cropLeft = 0;
624         int32_t cropRight = 0;
625         int32_t stride = 0;
626         int32_t sliceHeight = 0;
627         int32_t picWidth = 0;
628         int32_t picHeight = 0;
629         OH_AVFormat_GetIntValue(newFormat, OH_MD_KEY_VIDEO_CROP_TOP, &cropTop);
630         OH_AVFormat_GetIntValue(newFormat, OH_MD_KEY_VIDEO_CROP_BOTTOM, &cropBottom);
631         OH_AVFormat_GetIntValue(newFormat, OH_MD_KEY_VIDEO_CROP_LEFT, &cropLeft);
632         OH_AVFormat_GetIntValue(newFormat, OH_MD_KEY_VIDEO_CROP_RIGHT, &cropRight);
633         OH_AVFormat_GetIntValue(newFormat, OH_MD_KEY_VIDEO_STRIDE, &stride);
634         OH_AVFormat_GetIntValue(newFormat, OH_MD_KEY_VIDEO_SLICE_HEIGHT, &sliceHeight);
635         OH_AVFormat_GetIntValue(newFormat, OH_MD_KEY_VIDEO_PIC_WIDTH, &picWidth);
636         OH_AVFormat_GetIntValue(newFormat, OH_MD_KEY_VIDEO_PIC_HEIGHT, &picHeight);
637         if (cropTop != expectCropTop || cropBottom != expectCropBottom || cropLeft != expectCropLeft) {
638             std::cout << "cropTop:" << cropTop << " cropBottom:" << cropBottom << " cropLeft:" << cropLeft <<std::endl;
639             errCount++;
640         }
641         if (cropRight != expectCropRight || stride <= 0 || sliceHeight <= 0) {
642             std::cout << "cropRight:" << cropRight << std::endl;
643             std::cout << "stride:" << stride << " sliceHeight:" << sliceHeight << std::endl;
644             errCount++;
645         }
646         if (picWidth != originalWidth || picHeight != originalHeight) {
647             std::cout << "picWidth:" << picWidth << " picHeight:" << picHeight << std::endl;
648             errCount++;
649         }
650     } else {
651         errCount++;
652     }
653     OH_AVFormat_Destroy(newFormat);
654 }
655 
AutoSwitchSurface()656 void VDecAPI11Sample::AutoSwitchSurface()
657 {
658     if (autoSwitchSurface) {
659         switchSurfaceFlag = (switchSurfaceFlag == 1) ? 0 : 1;
660         if (OH_VideoDecoder_SetSurface(vdec_, nativeWindow[switchSurfaceFlag]) != AV_ERR_OK) {
661             errCount++;
662         }
663         OH_AVFormat *format = OH_AVFormat_Create();
664         int32_t angle = DEFAULT_ANGLE * reinterpret_cast<int32_t>(switchSurfaceFlag);
665         (void)OH_AVFormat_SetIntValue(format, OH_MD_KEY_ROTATION, angle);
666         OH_VideoDecoder_SetParameter(vdec_, format);
667         OH_AVFormat_Destroy(format);
668     }
669 }
CheckAttrFlag(OH_AVCodecBufferAttr attr)670 int32_t VDecAPI11Sample::CheckAttrFlag(OH_AVCodecBufferAttr attr)
671 {
672     if (needCheckOutputDesc) {
673         CheckOutputDescription();
674         needCheckOutputDesc = false;
675     }
676     if (attr.flags & AVCODEC_BUFFER_FLAGS_EOS) {
677         cout << "AVCODEC_BUFFER_FLAGS_EOS" << endl;
678         AutoSwitchSurface();
679         SHA512_Final(g_md, &g_c);
680         OPENSSL_cleanse(&g_c, sizeof(g_c));
681         MdCompare(g_md, SHA512_DIGEST_LENGTH, fileSourcesha256);
682         return -1;
683     }
684     if (attr.flags == AVCODEC_BUFFER_FLAGS_CODEC_DATA) {
685         cout << "enc AVCODEC_BUFFER_FLAGS_CODEC_DATA" << attr.pts << endl;
686         return 0;
687     }
688     outFrameCount = outFrameCount + 1;
689     return 0;
690 }
691 
OutputFuncTest()692 void VDecAPI11Sample::OutputFuncTest()
693 {
694     FILE *outFile = nullptr;
695     if (outputYuvFlag) {
696         outFile = fopen(OUT_DIR, "wb");
697     }
698     SHA512_Init(&g_c);
699     bool flag = true;
700     while (flag) {
701         if (!isRunning_.load()) {
702             flag = false;
703             break;
704         }
705         OH_AVCodecBufferAttr attr;
706         unique_lock<mutex> lock(signal_->outMutex_);
707         signal_->outCond_.wait(lock, [this]() {
708             if (!isRunning_.load()) {
709                 return true;
710             }
711             return signal_->outIdxQueue_.size() > 0;
712         });
713         if (!isRunning_.load()) {
714             flag = false;
715             break;
716         }
717         uint32_t index = signal_->outIdxQueue_.front();
718         OH_AVBuffer *buffer = signal_->outBufferQueue_.front();
719         signal_->outBufferQueue_.pop();
720         signal_->outIdxQueue_.pop();
721         if (OH_AVBuffer_GetBufferAttr(buffer, &attr) != AV_ERR_OK) {
722             errCount = errCount + 1;
723         }
724         lock.unlock();
725         if (CheckAttrFlag(attr) == -1) {
726             flag = false;
727             break;
728         }
729         ProcessOutputData(buffer, index, attr.size);
730         if (outFile != nullptr) {
731             fwrite(OH_AVBuffer_GetAddr(buffer), 1, attr.size, outFile);
732         }
733         if (errCount > 0) {
734             flag = false;
735             break;
736         }
737     }
738     if (outFile) {
739         (void)fclose(outFile);
740     }
741 }
742 
ProcessOutputData(OH_AVBuffer * buffer,uint32_t index,int32_t size)743 void VDecAPI11Sample::ProcessOutputData(OH_AVBuffer *buffer, uint32_t index, int32_t size)
744 {
745     if (!SF_OUTPUT) {
746         if (size >= DEFAULT_WIDTH * DEFAULT_HEIGHT * THREE >> 1) {
747             uint8_t *cropBuffer = new uint8_t[size];
748             if (memcpy_s(cropBuffer, size, OH_AVBuffer_GetAddr(buffer),
749                          DEFAULT_WIDTH * DEFAULT_HEIGHT) != EOK) {
750                 cout << "Fatal: memory copy failed Y" << endl;
751             }
752             // copy UV
753             uint32_t uvSize = size - DEFAULT_WIDTH * DEFAULT_HEIGHT;
754             if (memcpy_s(cropBuffer + DEFAULT_WIDTH * DEFAULT_HEIGHT, uvSize,
755                          OH_AVBuffer_GetAddr(buffer) + DEFAULT_WIDTH * DEFAULT_HEIGHT, uvSize) != EOK) {
756                 cout << "Fatal: memory copy failed UV" << endl;
757             }
758             SHA512_Update(&g_c, cropBuffer, size);
759             delete[] cropBuffer;
760         }
761         if (OH_VideoDecoder_FreeOutputBuffer(vdec_, index) != AV_ERR_OK) {
762             cout << "Fatal: ReleaseOutputBuffer fail" << endl;
763             errCount = errCount + 1;
764         }
765     } else {
766         if (rsAtTime) {
767             int32_t usTimeNum = 1000;
768             int32_t msTimeNum = 1000000;
769             if (renderTimestampNs == 0) {
770                 renderTimestampNs = GetSystemTimeUs() / usTimeNum;
771             }
772             renderTimestampNs = renderTimestampNs + (usTimeNum / DEFAULT_FRAME_RATE * msTimeNum);
773             if (OH_VideoDecoder_RenderOutputBufferAtTime(vdec_, index, renderTimestampNs) != AV_ERR_OK) {
774                 cout << "Fatal: RenderOutputBufferAtTime fail" << endl;
775                 errCount = errCount + 1;
776             }
777         } else {
778             if (OH_VideoDecoder_RenderOutputBuffer(vdec_, index) != AV_ERR_OK) {
779                 cout << "Fatal: RenderOutputBuffer fail" << endl;
780                 errCount = errCount + 1;
781             }
782         }
783     }
784 }
785 
state_EOS()786 int32_t VDecAPI11Sample::state_EOS()
787 {
788     uint32_t index;
789     unique_lock<mutex> lock(signal_->inMutex_);
790     signal_->inCond_.wait(lock, [this]() { return signal_->inIdxQueue_.size() > 0; });
791     index = signal_->inIdxQueue_.front();
792     signal_->inIdxQueue_.pop();
793     signal_->inBufferQueue_.pop();
794     lock.unlock();
795     return OH_VideoDecoder_PushInputBuffer(vdec_, index);
796 }
797 
SetEOS(uint32_t index,OH_AVBuffer * buffer)798 void VDecAPI11Sample::SetEOS(uint32_t index, OH_AVBuffer *buffer)
799 {
800     OH_AVCodecBufferAttr attr;
801     attr.pts = 0;
802     attr.size = 0;
803     attr.offset = 0;
804     attr.flags = AVCODEC_BUFFER_FLAGS_EOS;
805     OH_AVBuffer_SetBufferAttr(buffer, &attr);
806     int32_t res = OH_VideoDecoder_PushInputBuffer(vdec_, index);
807     cout << "OH_VideoDecoder_PushInputBuffer    EOS   res: " << res << endl;
808 }
809 
Flush()810 int32_t VDecAPI11Sample::Flush()
811 {
812     unique_lock<mutex> inLock(signal_->inMutex_);
813     clearIntqueue(signal_->inIdxQueue_);
814     signal_->inCond_.notify_all();
815     inLock.unlock();
816     unique_lock<mutex> outLock(signal_->outMutex_);
817     clearIntqueue(signal_->outIdxQueue_);
818     clearBufferqueue(signal_->attrQueue_);
819     signal_->outCond_.notify_all();
820     outLock.unlock();
821     isRunning_.store(false);
822     return OH_VideoDecoder_Flush(vdec_);
823 }
824 
Reset()825 int32_t VDecAPI11Sample::Reset()
826 {
827     isRunning_.store(false);
828     StopInloop();
829     StopOutloop();
830     ReleaseInFile();
831     return OH_VideoDecoder_Reset(vdec_);
832 }
833 
Release()834 int32_t VDecAPI11Sample::Release()
835 {
836     int ret = 0;
837     if (vdec_ != nullptr) {
838         ret = OH_VideoDecoder_Destroy(vdec_);
839         vdec_ = nullptr;
840     }
841 
842     if (signal_ != nullptr) {
843         delete signal_;
844         signal_ = nullptr;
845     }
846     return ret;
847 }
848 
Stop()849 int32_t VDecAPI11Sample::Stop()
850 {
851     StopInloop();
852     StopOutloop();
853     ReleaseInFile();
854     return OH_VideoDecoder_Stop(vdec_);
855 }
856 
Start()857 int32_t VDecAPI11Sample::Start()
858 {
859     isRunning_.store(true);
860     return OH_VideoDecoder_Start(vdec_);
861 }
862 
StopOutloop()863 void VDecAPI11Sample::StopOutloop()
864 {
865     if (outputLoop_ != nullptr && outputLoop_->joinable()) {
866         unique_lock<mutex> lock(signal_->outMutex_);
867         clearIntqueue(signal_->outIdxQueue_);
868         clearBufferqueue(signal_->attrQueue_);
869         isRunning_.store(false);
870         signal_->outCond_.notify_all();
871         lock.unlock();
872         outputLoop_->join();
873         outputLoop_.reset();
874     }
875 }
876 
SetParameter(OH_AVFormat * format)877 int32_t VDecAPI11Sample::SetParameter(OH_AVFormat *format)
878 {
879     return OH_VideoDecoder_SetParameter(vdec_, format);
880 }
881 
SwitchSurface()882 int32_t VDecAPI11Sample::SwitchSurface()
883 {
884     int32_t ret = OH_VideoDecoder_SetSurface(vdec_, nativeWindow[switchSurfaceFlag]);
885     switchSurfaceFlag = (switchSurfaceFlag == 1) ? 0 : 1;
886     cout << "manual switch surf "<< switchSurfaceFlag << endl;
887     return ret;
888 }
889 
RepeatCallSetSurface()890 int32_t VDecAPI11Sample::RepeatCallSetSurface()
891 {
892     for (int i = 0; i < REPEAT_CALL_TIME; i++) {
893         switchSurfaceFlag = (switchSurfaceFlag == 1) ? 0 : 1;
894         int32_t ret = OH_VideoDecoder_SetSurface(vdec_, nativeWindow[switchSurfaceFlag]);
895         if (ret != AV_ERR_OK && ret != AV_ERR_OPERATE_NOT_PERMIT && ret != AV_ERR_INVALID_STATE) {
896             return AV_ERR_OPERATE_NOT_PERMIT;
897         }
898     }
899     return AV_ERR_OK;
900 }