1/* 2 * Copyright (C) 2022-2024 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 "decoder_demo.h" 17 18#include <iostream> 19#include <unistd.h> 20 21#include "avcodec_list.h" 22#include "securec.h" 23#include "wm_common.h" 24#include "window.h" 25#include "window_scene.h" 26#include "window_option.h" 27 28static const int32_t ES_R[325] = { 29 11895, 8109, 1578, 1616, 1313, 572, 805, 837, 755, 706, 952, 879, 13193, 422, 389, 509, 725, 465, 479, 959, 677, 30 364, 541, 696, 9306, 322, 318, 767, 590, 422, 530, 403, 505, 566, 445, 508, 7783, 460, 405, 343, 451, 608, 431, 31 411, 543, 487, 527, 400, 6287, 385, 418, 391, 592, 434, 412, 398, 504, 492, 479, 561, 5413, 317, 355, 422, 467, 32 452, 476, 460, 490, 492, 485, 451, 5036, 312, 408, 460, 432, 502, 388, 475, 407, 544, 401, 487, 4404, 362, 378, 33 427, 416, 426, 456, 414, 438, 424, 442, 444, 4310, 362, 388, 393, 390, 441, 398, 423, 369, 443, 406, 392, 4231, 34 343, 363, 355, 390, 459, 371, 378, 381, 405, 392, 426, 3975, 387, 337, 393, 439, 378, 355, 374, 484, 381, 373, 35 423, 3869, 312, 350, 400, 345, 356, 320, 473, 431, 386, 338, 431, 3426, 268, 315, 416, 383, 373, 381, 354, 383, 36 328, 348, 418, 3715, 324, 361, 331, 350, 302, 409, 377, 359, 384, 334, 326, 3439, 266, 324, 329, 353, 405, 303, 37 357, 332, 292, 361, 333, 3542, 294, 284, 247, 331, 306, 322, 287, 367, 341, 276, 258, 3980, 246, 245, 259, 309, 38 333, 250, 275, 334, 281, 253, 371, 3640, 213, 231, 301, 302, 228, 289, 290, 281, 201, 284, 277, 4242, 205, 328, 39 237, 283, 295, 266, 230, 321, 348, 212, 308, 4103, 259, 238, 245, 298, 330, 265, 271, 287, 267, 286, 290, 3856, 40 269, 242, 209, 314, 267, 278, 280, 314, 250, 433, 238, 3654, 195, 246, 301, 298, 250, 270, 320, 269, 305, 258, 41 368, 3810, 231, 212, 279, 289, 252, 303, 287, 295, 206, 264, 349, 4071, 242, 296, 271, 231, 307, 265, 254, 267, 42 317, 232, 348, 4077, 259, 222, 268, 235, 324, 266, 256, 312, 246, 248, 325, 4000, 266, 201, 230, 293, 264, 265, 43 273, 301, 304, 253, 266, 3978, 228, 232, 250, 248, 281, 219, 243, 293, 287, 253, 328, 3719 44}; 45 46static const int32_t ES_W[183] = { 47 2111, 109091, 9316, 969, 13656, 1349, 959, 10484, 1219, 14839, 1092, 23378, 1653, 1725, 1526, 8500, 15407, 48 2058, 1346, 21066, 3758, 1734, 1950, 19955, 3997, 1732, 1784, 22687, 4392, 2448, 2180, 17456, 3930, 1851, 49 1802, 24227, 4393, 2639, 2778, 18314, 4023, 2392, 2283, 20566, 4118, 2664, 2013, 18964, 2624, 45258, 5860, 50 4124, 3473, 27772, 4687, 3140, 2939, 26288, 3808, 2967, 2823, 27219, 3943, 3242, 2667, 27372, 3522, 2899, 51 2316, 26608, 3284, 2853, 2285, 19581, 2894, 2436, 24898, 4002, 2876, 2807, 25730, 3903, 2874, 2975, 26309, 52 3771, 2763, 2666, 23404, 3826, 2410, 2644, 24629, 4145, 3121, 2878, 50773, 7040, 3945, 3292, 30828, 5210, 53 2883, 3277, 31501, 4809, 3068, 3220, 30746, 4715, 3461, 3583, 32278, 4798, 3398, 3389, 31404, 4921, 3382, 54 3766, 31821, 5848, 3860, 4047, 37642, 5793, 4271, 4094, 29853, 6163, 4399, 4063, 32151, 6038, 4332, 4041, 55 30390, 5679, 4098, 3921, 29401, 5307, 3996, 3945, 45997, 7060, 3716, 4183, 26357, 6190, 3714, 4250, 29086, 56 5929, 3491, 4489, 27772, 6656, 4219, 4348, 25851, 6088, 3617, 4477, 25722, 6303, 3856, 4208, 25348, 5896, 57 3816, 4521, 22462, 5914, 3673, 4594, 18091, 6474, 3878, 4492, 10890, 4823, 4148 58}; 59 60using namespace OHOS; 61using namespace OHOS::MediaAVCodec; 62using namespace std; 63namespace { 64 constexpr uint32_t DEFAULT_FRAME_RATE = 30; 65 constexpr uint32_t MAX_INPUT_BUFFER_SIZE = 30000; 66 constexpr uint32_t FRAME_DURATION_US = 33000; 67 constexpr uint32_t VIDEO_DATA_FORMAT_NV12 = 2; 68 constexpr uint32_t VIDEO_DATA_FORMAT_RGBA = 5; 69 constexpr uint32_t SLEEP_THREE_SECOND = 3; 70 constexpr uint32_t INDEX_CONSTANT = 10000; 71 const string CODEC_NAME_H264 = "OMX_hisi_video_encoder_avc"; 72 const string CODEC_NAME_MPEG4 = "avenc_mpeg4"; 73} 74 75void VDecDemo::RunCase() 76{ 77 CheckCodecType(); 78 CreateVdec(); 79 Media::Format format; 80 format.PutIntValue("width", width_); 81 format.PutIntValue("height", height_); 82 if (isW) { 83 format.PutIntValue("pixel_format", VIDEO_DATA_FORMAT_NV12); 84 } else { 85 format.PutIntValue("pixel_format", VIDEO_DATA_FORMAT_RGBA); 86 } 87 format.PutIntValue("frame_rate", DEFAULT_FRAME_RATE); 88 format.PutIntValue("max_input_size", MAX_INPUT_BUFFER_SIZE); 89 Configure(format); 90 SetSurface(); 91 Prepare(); 92 Start(); 93 sleep(SLEEP_THREE_SECOND); 94 Stop(); 95 Release(); 96} 97 98int32_t VDecDemo::CreateVdec() 99{ 100 if (isW) { 101 vdec_ = VideoDecoderFactory::CreateByMime("video/avc"); 102 } else { 103 vdec_ = VideoDecoderFactory::CreateByMime("video/mp4v-es"); 104 } 105 106 signal_ = make_shared<VDecSignal>(); 107 cb_ = make_unique<VDecDemoCallback>(signal_); 108 vdec_->SetCallback(cb_); 109 return 0; 110} 111 112int32_t VDecDemo::Configure(const Media::Format &format) 113{ 114 return vdec_->Configure(format); 115} 116 117int32_t VDecDemo::Prepare() 118{ 119 return vdec_->Prepare(); 120} 121 122int32_t VDecDemo::Start() 123{ 124 isRunning_.store(true); 125 126 testFile_ = std::make_unique<std::ifstream>(); 127 testFile_->open("/data/media/video.es", std::ios::in | std::ios::binary); 128 129 inputLoop_ = make_unique<thread>(&VDecDemo::InputFunc, this); 130 outputLoop_ = make_unique<thread>(&VDecDemo::OutputFunc, this); 131 return vdec_->Start(); 132} 133 134int32_t VDecDemo::Stop() 135{ 136 isRunning_.store(false); 137 138 if (inputLoop_ != nullptr && inputLoop_->joinable()) { 139 { 140 unique_lock<mutex> inLock(signal_->inMutex_); 141 signal_->inQueue_.push(INDEX_CONSTANT); 142 signal_->inCond_.notify_all(); 143 } 144 inputLoop_->join(); 145 inputLoop_.reset(); 146 } 147 148 if (outputLoop_ != nullptr && outputLoop_->joinable()) { 149 { 150 unique_lock<mutex> outLock(signal_->outMutex_); 151 signal_->outQueue_.push(INDEX_CONSTANT); 152 signal_->outCond_.notify_all(); 153 } 154 outputLoop_->join(); 155 outputLoop_.reset(); 156 } 157 158 return vdec_->Stop(); 159} 160 161int32_t VDecDemo::Flush() 162{ 163 return vdec_->Flush(); 164} 165 166int32_t VDecDemo::Reset() 167{ 168 return vdec_->Reset(); 169} 170 171int32_t VDecDemo::Release() 172{ 173 return vdec_->Release(); 174} 175 176void VDecDemo::SetOutputSurface(sptr<Surface> surface) 177{ 178 surface_ = surface; 179} 180 181void VDecDemo::SetWindowSize(uint32_t width, uint32_t height) 182{ 183 width_ = width; 184 height_ = height; 185} 186 187int32_t VDecDemo::SetSurface() 188{ 189 return vdec_->SetOutputSurface(surface_); 190} 191 192void VDecDemo::CheckCodecType() 193{ 194 std::vector<std::string> localCodecArray; 195 std::shared_ptr<MediaAVCodec::AVCodecList> codecList = MediaAVCodec::AVCodecListFactory::CreateAVCodecList(); 196 const std::vector<std::string> encoderName = {std::string(MediaAVCodec::CodecMimeType::VIDEO_AVC), 197 std::string(MediaAVCodec::CodecMimeType::VIDEO_HEVC)}; 198 199 for (const auto &coder : encoderName) { 200 MediaAVCodec::CapabilityData *capData = codecList->GetCapability(coder, true, 201 MediaAVCodec::AVCodecCategory::AVCODEC_HARDWARE); 202 std::string mimeType = capData->mimeType; 203 localCodecArray.push_back(mimeType); 204 } 205 206 if (std::find(localCodecArray.begin(), localCodecArray.end(), 207 CODEC_NAME_H264) != localCodecArray.end()) { 208 cout << "device is W" << endl; 209 isW = true; 210 } else if (std::find(localCodecArray.begin(), localCodecArray.end(), 211 CODEC_NAME_MPEG4) != localCodecArray.end()) { 212 cout << "device is R" << endl; 213 isW = false; 214 } 215} 216 217const int32_t* VDecDemo::GetFrameLen() 218{ 219 const int32_t* frameLen = nullptr; 220 if (isW) { 221 frameLen = ES_W; 222 defaultFrameCount_ = sizeof(ES_W) / sizeof(ES_W[0]); 223 } else { 224 frameLen = ES_R; 225 defaultFrameCount_ = sizeof(ES_R) / sizeof(ES_R[0]); 226 } 227 return frameLen; 228} 229 230void VDecDemo::InputFunc() 231{ 232 const int32_t *frameLen = GetFrameLen(); 233 234 while (isRunning_.load()) { 235 unique_lock<mutex> lock(signal_->inMutex_); 236 signal_->inCond_.wait( 237 lock, [this]() { return signal_->inQueue_.size() > 0 && signal_->availableInputBufferQueue_.size() > 0; }); 238 239 if (!isRunning_.load()) { 240 break; 241 } 242 243 uint32_t index = signal_->inQueue_.front(); 244 std::shared_ptr<Media::AVSharedMemory> buffer = signal_->availableInputBufferQueue_.front(); 245 246 char *fileBuffer = static_cast<char *>(malloc(sizeof(char) * (*frameLen) + 1)); 247 if (fileBuffer == nullptr) { 248 break; 249 } 250 251 (void)testFile_->read(fileBuffer, *frameLen); 252 if (memcpy_s(buffer->GetBase(), buffer->GetSize(), fileBuffer, *frameLen) != EOK) { 253 free(fileBuffer); 254 cout << "Fatal: memcpy fail" << endl; 255 break; 256 } 257 258 AVCodecBufferInfo info; 259 info.size = *frameLen; 260 info.offset = 0; 261 info.presentationTimeUs = timeStamp_; 262 263 int32_t ret = 0; 264 if (isFirstFrame_) { 265 ret = vdec_->QueueInputBuffer(index, info, AVCODEC_BUFFER_FLAG_CODEC_DATA); 266 isFirstFrame_ = false; 267 } else { 268 ret = vdec_->QueueInputBuffer(index, info, AVCODEC_BUFFER_FLAG_NONE); 269 } 270 271 free(fileBuffer); 272 frameLen++; 273 timeStamp_ += FRAME_DURATION_US; 274 signal_->inQueue_.pop(); 275 signal_->availableInputBufferQueue_.pop(); 276 277 frameCount_++; 278 if (frameCount_ == defaultFrameCount_) { 279 cout << "Finish decode, exit" << endl; 280 break; 281 } 282 283 if (ret != 0) { 284 cout << "Fatal error, exit" << endl; 285 break; 286 } 287 } 288} 289 290void VDecDemo::OutputFunc() 291{ 292 while (isRunning_.load()) { 293 unique_lock<mutex> lock(signal_->outMutex_); 294 signal_->outCond_.wait(lock, [this]() { return signal_->outQueue_.size() > 0; }); 295 296 if (!isRunning_.load()) { 297 break; 298 } 299 300 uint32_t index = signal_->outQueue_.front(); 301 if (vdec_->ReleaseOutputBuffer(index, true) != 0) { 302 cout << "Fatal: ReleaseOutputBuffer fail" << endl; 303 break; 304 } 305 306 signal_->outQueue_.pop(); 307 } 308} 309 310void VDecDemoCallback::OnError(AVCodecErrorType errorType, int32_t errorCode) 311{ 312 cout << "Error received, errorType:" << errorType << " errorCode:" << errorCode << endl; 313} 314 315void VDecDemoCallback::OnOutputFormatChanged(const Media::Format &format) 316{ 317 cout << "OnOutputFormatChanged received" << endl; 318} 319 320void VDecDemoCallback::OnInputBufferAvailable(uint32_t index, std::shared_ptr<Media::AVSharedMemory> buffer) 321{ 322 cout << "OnInputBufferAvailable received, index:" << index << endl; 323 unique_lock<mutex> lock(signal_->inMutex_); 324 signal_->inQueue_.push(index); 325 signal_->availableInputBufferQueue_.push(buffer); 326 signal_->inCond_.notify_all(); 327} 328 329void VDecDemoCallback::OnOutputBufferAvailable(uint32_t index, AVCodecBufferInfo info, 330 AVCodecBufferFlag flag, std::shared_ptr<Media::AVSharedMemory> buffer) 331{ 332 cout << "OnOutputBufferAvailable received, index:" << index << endl; 333 unique_lock<mutex> lock(signal_->outMutex_); 334 signal_->outQueue_.push(index); 335 signal_->outCond_.notify_all(); 336} 337