1/* 2 * Copyright (C) 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 <iostream> 17#include <unistd.h> 18#include <chrono> 19 20#include "securec.h" 21#include "demo_log.h" 22#include "avcodec_common.h" 23#include "avcodec_errors.h" 24#include "native_averrors.h" 25#include "native_avformat.h" 26#include "audioencoderdemo.h" 27#include "media_description.h" 28#include "avcodec_mime_type.h" 29#include "avcodec_codec_name.h" 30#include "native_avcodec_base.h" 31#include "avcodec_audio_channel_layout.h" 32 33using namespace OHOS; 34using namespace OHOS::MediaAVCodec; 35using namespace OHOS::MediaAVCodec::AudioEncDemoAuto; 36using namespace std; 37 38namespace OHOS { 39namespace MediaAVCodec { 40namespace AudioEncDemoAuto { 41 constexpr uint32_t CHANNEL_COUNT = 2; 42 constexpr uint32_t SAMPLE_RATE = 48000; 43 constexpr uint32_t SAMPLE_RATE_8000 = 8000; 44 constexpr uint32_t BIT_RATE_64000 = 64000; 45 constexpr int32_t CHANNEL_COUNT_1 = 1; 46 constexpr uint32_t DEFAULT_AAC_TYPE = 1; 47 constexpr int32_t BIT_PER_CODE_COUNT = 16; 48 constexpr int32_t COMPLEXITY_COUNT = 10; 49 constexpr int32_t CHANNEL_1 = 1; 50 constexpr int32_t CHANNEL_2 = 2; 51 constexpr int32_t CHANNEL_3 = 3; 52 constexpr int32_t CHANNEL_4 = 4; 53 constexpr int32_t CHANNEL_5 = 5; 54 constexpr int32_t CHANNEL_6 = 6; 55 constexpr int32_t CHANNEL_7 = 7; 56 constexpr int32_t CHANNEL_8 = 8; 57 58 void OnError(OH_AVCodec* codec, int32_t errorCode, void* userData) 59 { 60 (void)codec; 61 (void)errorCode; 62 (void)userData; 63 } 64 65 void OnOutputFormatChanged(OH_AVCodec* codec, OH_AVFormat* format, void* userData) 66 { 67 (void)codec; 68 (void)format; 69 (void)userData; 70 cout << "OnOutputFormatChanged received" << endl; 71 } 72 73 void OnInputBufferAvailable(OH_AVCodec* codec, uint32_t index, OH_AVMemory* data, void* userData) 74 { 75 (void)codec; 76 AEncSignal* signal = static_cast<AEncSignal*>(userData); 77 unique_lock<mutex> lock(signal->inMutex_); 78 signal->inQueue_.push(index); 79 signal->inBufferQueue_.push(data); 80 signal->inCond_.notify_all(); 81 } 82 83 void OnOutputBufferAvailable(OH_AVCodec* codec, uint32_t index, OH_AVMemory* data, OH_AVCodecBufferAttr* attr, 84 void* userData) 85 { 86 (void)codec; 87 AEncSignal* signal = static_cast<AEncSignal*>(userData); 88 unique_lock<mutex> lock(signal->outMutex_); 89 signal->outQueue_.push(index); 90 signal->outBufferQueue_.push(data); 91 if (attr) { 92 signal->attrQueue_.push(*attr); 93 } else { 94 cout << "OnOutputBufferAvailable, attr is nullptr!" << endl; 95 } 96 signal->outCond_.notify_all(); 97 } 98} 99} 100} 101 102static uint64_t GetChannelLayout(int32_t channel) 103{ 104 switch (channel) { 105 case CHANNEL_1: 106 return MONO; 107 case CHANNEL_2: 108 return STEREO; 109 case CHANNEL_3: 110 return CH_2POINT1; 111 case CHANNEL_4: 112 return CH_3POINT1; 113 case CHANNEL_5: 114 return CH_4POINT1; 115 case CHANNEL_6: 116 return CH_5POINT1; 117 case CHANNEL_7: 118 return CH_6POINT1; 119 case CHANNEL_8: 120 return CH_7POINT1; 121 default: 122 return UNKNOWN_CHANNEL_LAYOUT; 123 } 124} 125 126void AEncDemoAuto::HandleEOS(const uint32_t& index) 127{ 128 OH_AVCodecBufferAttr info; 129 info.size = 0; 130 info.offset = 0; 131 info.pts = 0; 132 info.flags = AVCODEC_BUFFER_FLAGS_EOS; 133 OH_AudioEncoder_PushInputData(audioEnc_, index, info); 134 signal_->inBufferQueue_.pop(); 135 signal_->inQueue_.pop(); 136} 137 138OH_AVCodec* AEncDemoAuto::CreateByMime(const char* mime) 139{ 140 return OH_AudioEncoder_CreateByMime(mime); 141} 142 143OH_AVCodec* AEncDemoAuto::CreateByName(const char* name) 144{ 145 return OH_AudioEncoder_CreateByName(name); 146} 147 148OH_AVErrCode AEncDemoAuto::Destroy(OH_AVCodec* codec) 149{ 150 if (format_ != nullptr) { 151 OH_AVFormat_Destroy(format_); 152 format_ = nullptr; 153 } 154 OH_AVErrCode ret = OH_AudioEncoder_Destroy(codec); 155 ClearQueue(); 156 return ret; 157} 158 159OH_AVErrCode AEncDemoAuto::SetCallback(OH_AVCodec* codec) 160{ 161 cb_ = { &OnError, &OnOutputFormatChanged, &OnInputBufferAvailable, &OnOutputBufferAvailable }; 162 return OH_AudioEncoder_SetCallback(codec, cb_, signal_); 163} 164 165OH_AVErrCode AEncDemoAuto::Prepare(OH_AVCodec* codec) 166{ 167 return OH_AudioEncoder_Prepare(codec); 168} 169 170OH_AVErrCode AEncDemoAuto::Start(OH_AVCodec* codec) 171{ 172 return OH_AudioEncoder_Start(codec); 173} 174 175OH_AVErrCode AEncDemoAuto::Stop(OH_AVCodec* codec) 176{ 177 OH_AVErrCode ret = OH_AudioEncoder_Stop(codec); 178 ClearQueue(); 179 return ret; 180} 181 182OH_AVErrCode AEncDemoAuto::Flush(OH_AVCodec* codec) 183{ 184 OH_AVErrCode ret = OH_AudioEncoder_Flush(codec); 185 std::cout << "Flush ret:"<< ret <<endl; 186 ClearQueue(); 187 return ret; 188} 189 190OH_AVErrCode AEncDemoAuto::Reset(OH_AVCodec* codec) 191{ 192 return OH_AudioEncoder_Reset(codec); 193} 194 195OH_AVErrCode AEncDemoAuto::PushInputData(OH_AVCodec* codec, uint32_t index, int32_t size, int32_t offset) 196{ 197 OH_AVCodecBufferAttr info; 198 info.size = size; 199 info.offset = offset; 200 info.pts = 0; 201 info.flags = AVCODEC_BUFFER_FLAGS_NONE; 202 return OH_AudioEncoder_PushInputData(codec, index, info); 203} 204 205OH_AVErrCode AEncDemoAuto::PushInputDataEOS(OH_AVCodec* codec, uint32_t index) 206{ 207 OH_AVCodecBufferAttr info; 208 info.size = 0; 209 info.offset = 0; 210 info.pts = 0; 211 info.flags = AVCODEC_BUFFER_FLAGS_EOS; 212 213 return OH_AudioEncoder_PushInputData(codec, index, info); 214} 215 216OH_AVErrCode AEncDemoAuto::FreeOutputData(OH_AVCodec* codec, uint32_t index) 217{ 218 return OH_AudioEncoder_FreeOutputData(codec, index); 219} 220 221OH_AVErrCode AEncDemoAuto::IsValid(OH_AVCodec* codec, bool* isValid) 222{ 223 return OH_AudioEncoder_IsValid(codec, isValid); 224} 225 226uint32_t AEncDemoAuto::GetInputIndex() 227{ 228 int32_t sleepTime = 0; 229 uint32_t index; 230 int32_t condTime = 5; 231 while (signal_->inQueue_.empty() && sleepTime < condTime) { 232 sleep(1); 233 sleepTime++; 234 } 235 if (sleepTime >= condTime) { 236 return 0; 237 } else { 238 index = signal_->inQueue_.front(); 239 signal_->inQueue_.pop(); 240 } 241 return index; 242} 243 244uint32_t AEncDemoAuto::GetOutputIndex() 245{ 246 int32_t sleepTime = 0; 247 uint32_t index; 248 int32_t condTime = 5; 249 while (signal_->outQueue_.empty() && sleepTime < condTime) { 250 sleep(1); 251 sleepTime++; 252 } 253 if (sleepTime >= condTime) { 254 return 0; 255 } else { 256 index = signal_->outQueue_.front(); 257 signal_->outQueue_.pop(); 258 } 259 return index; 260} 261 262void AEncDemoAuto::ClearQueue() 263{ 264 while (!signal_->inQueue_.empty()) { 265 signal_->inQueue_.pop(); 266 } 267 while (!signal_->outQueue_.empty()) { 268 signal_->outQueue_.pop(); 269 } 270 while (!signal_->inBufferQueue_.empty()) { 271 signal_->inBufferQueue_.pop(); 272 } 273 while (!signal_->outBufferQueue_.empty()) { 274 signal_->outBufferQueue_.pop(); 275 } 276 while (!signal_->attrQueue_.empty()) { 277 signal_->attrQueue_.pop(); 278 } 279} 280 281bool AEncDemoAuto::InitFile(string inputFile) 282{ 283 if (inputFile.find("opus") != std::string::npos) { 284 audioType_ = TYPE_OPUS; 285 } else if (inputFile.find("g711") != std::string::npos) { 286 audioType_ = TYPE_G711MU; 287 } else if (inputFile.find("flac") != std::string::npos) { 288 audioType_ = TYPE_FLAC; 289 } else { 290 audioType_ = TYPE_AAC; 291 } 292 return true; 293} 294 295AEncDemoAuto::AEncDemoAuto() 296{ 297 audioEnc_ = nullptr; 298 signal_ = new AEncSignal(); 299 DEMO_CHECK_AND_RETURN_LOG(signal_ != nullptr, "Fatal: No memory"); 300 format_ = nullptr; 301 audioType_ = TYPE_OPUS; 302} 303 304 305AEncDemoAuto::~AEncDemoAuto() 306{ 307 isRunning_.store(false); 308 if (signal_) { 309 delete signal_; 310 signal_ = nullptr; 311 } 312} 313 314int32_t AEncDemoAuto::CreateEnc() 315{ 316 if (audioType_ == TYPE_AAC) { 317 audioEnc_ = OH_AudioEncoder_CreateByName((AVCodecCodecName::AUDIO_ENCODER_AAC_NAME).data()); 318 } else if (audioType_ == TYPE_FLAC) { 319 audioEnc_ = OH_AudioEncoder_CreateByName((AVCodecCodecName::AUDIO_ENCODER_FLAC_NAME).data()); 320 } else if (audioType_ == TYPE_OPUS) { 321 audioEnc_ = OH_AudioEncoder_CreateByName((AVCodecCodecName::AUDIO_ENCODER_OPUS_NAME).data()); 322 } else if (audioType_ == TYPE_G711MU) { 323 audioEnc_ = OH_AudioEncoder_CreateByName((AVCodecCodecName::AUDIO_ENCODER_G711MU_NAME).data()); 324 } else { 325 return AVCS_ERR_INVALID_VAL; 326 } 327 328 if (signal_ == nullptr) { 329 signal_ = new AEncSignal(); 330 } 331 if (signal_ == nullptr) { 332 return AVCS_ERR_UNKNOWN; 333 } 334 DEMO_CHECK_AND_RETURN_RET_LOG(audioEnc_ != nullptr, AVCS_ERR_UNKNOWN, "Fatal: CreateByName fail"); 335 336 cb_ = { &OnError, &OnOutputFormatChanged, &OnInputBufferAvailable, &OnOutputBufferAvailable }; 337 int32_t ret = OH_AudioEncoder_SetCallback(audioEnc_, cb_, signal_); 338 DEMO_CHECK_AND_RETURN_RET_LOG(ret == AVCS_ERR_OK, AVCS_ERR_UNKNOWN, "Fatal: SetCallback fail"); 339 340 return AVCS_ERR_OK; 341} 342 343int32_t AEncDemoAuto::CreateEncByMime() 344{ 345 if (audioType_ == TYPE_AAC) { 346 audioEnc_ = OH_AudioEncoder_CreateByMime((AVCodecMimeType::MEDIA_MIMETYPE_AUDIO_AAC).data()); 347 } else if (audioType_ == TYPE_FLAC) { 348 audioEnc_ = OH_AudioEncoder_CreateByName((AVCodecMimeType::MEDIA_MIMETYPE_AUDIO_FLAC).data()); 349 } else if (audioType_ == TYPE_OPUS) { 350 audioEnc_ = OH_AudioEncoder_CreateByName((AVCodecMimeType::MEDIA_MIMETYPE_AUDIO_OPUS).data()); 351 } else if (audioType_ == TYPE_G711MU) { 352 audioEnc_ = OH_AudioEncoder_CreateByName((AVCodecMimeType::MEDIA_MIMETYPE_AUDIO_G711MU).data()); 353 } else { 354 return AVCS_ERR_INVALID_VAL; 355 } 356 DEMO_CHECK_AND_RETURN_RET_LOG(audioEnc_ != nullptr, AVCS_ERR_UNKNOWN, "Fatal: CreateByMime fail"); 357 return AVCS_ERR_OK; 358} 359 360void AEncDemoAuto::SetFormat(OH_AVFormat *format) 361{ 362 int32_t channelCount = CHANNEL_COUNT; 363 int32_t sampleRate = SAMPLE_RATE; 364 if (audioType_ == TYPE_OPUS) { 365 channelCount = CHANNEL_COUNT_1; 366 sampleRate = SAMPLE_RATE_8000; 367 OH_AVFormat_SetLongValue(format, MediaDescriptionKey::MD_KEY_BITRATE.data(), BIT_RATE_64000); 368 OH_AVFormat_SetIntValue(format, MediaDescriptionKey::MD_KEY_BITS_PER_CODED_SAMPLE.data(), BIT_PER_CODE_COUNT); 369 OH_AVFormat_SetIntValue(format, MediaDescriptionKey::MD_KEY_COMPLIANCE_LEVEL.data(), COMPLEXITY_COUNT); 370 } else if (audioType_ == TYPE_G711MU) { 371 channelCount = CHANNEL_COUNT_1; 372 sampleRate = SAMPLE_RATE_8000; 373 OH_AVFormat_SetLongValue(format, MediaDescriptionKey::MD_KEY_BITRATE.data(), BIT_RATE_64000); 374 } else if (audioType_ == TYPE_FLAC) { 375 uint64_t channelLayout = GetChannelLayout(CHANNEL_COUNT); 376 OH_AVFormat_SetLongValue(format, OH_MD_KEY_CHANNEL_LAYOUT, channelLayout); 377 OH_AVFormat_SetLongValue(format, MediaDescriptionKey::MD_KEY_BITRATE.data(), BIT_RATE_64000); 378 OH_AVFormat_SetIntValue(format, OH_MD_KEY_BITS_PER_CODED_SAMPLE, OH_BitsPerSample::SAMPLE_S16LE); 379 } else if (audioType_ == TYPE_AAC) { 380 OH_AVFormat_SetIntValue(format, OH_MD_KEY_AAC_IS_ADTS, DEFAULT_AAC_TYPE); 381 } 382 OH_AVFormat_SetIntValue(format, MediaDescriptionKey::MD_KEY_CHANNEL_COUNT.data(), channelCount); 383 OH_AVFormat_SetIntValue(format, MediaDescriptionKey::MD_KEY_SAMPLE_RATE.data(), sampleRate); 384 OH_AVFormat_SetIntValue(format, MediaDescriptionKey::MD_KEY_AUDIO_SAMPLE_FORMAT.data(), 385 AudioSampleFormat::SAMPLE_S16LE); 386} 387 388int32_t AEncDemoAuto::Configure(OH_AVFormat* format) 389{ 390 return OH_AudioEncoder_Configure(audioEnc_, format); 391} 392 393int32_t AEncDemoAuto::Start() 394{ 395 isRunning_.store(false); 396 signal_->inCond_.notify_all(); 397 signal_->outCond_.notify_all(); 398 if (inputLoop_ != nullptr && inputLoop_->joinable()) { 399 inputLoop_->join(); 400 inputLoop_.reset(); 401 inputLoop_ = nullptr; 402 } 403 404 if (outputLoop_ != nullptr && outputLoop_->joinable()) { 405 outputLoop_->join(); 406 outputLoop_.reset(); 407 outputLoop_ = nullptr; 408 } 409 sleep(1); 410 { 411 unique_lock<mutex> lock(signal_->inMutex_); 412 while (!signal_->inQueue_.empty()) { 413 signal_->inQueue_.pop(); 414 } 415 while (!signal_->inBufferQueue_.empty()) { 416 signal_->inBufferQueue_.pop(); 417 } 418 } 419 { 420 unique_lock<mutex> lock(signal_->outMutex_); 421 while (!signal_->outQueue_.empty()) { 422 signal_->outQueue_.pop(); 423 } 424 while (!signal_->attrQueue_.empty()) { 425 signal_->attrQueue_.pop(); 426 } 427 while (!signal_->outBufferQueue_.empty()) { 428 signal_->outBufferQueue_.pop(); 429 } 430 } 431 isRunning_.store(true); 432 inputLoop_ = make_unique<thread>(&AEncDemoAuto::InputFunc, this); 433 DEMO_CHECK_AND_RETURN_RET_LOG(inputLoop_ != nullptr, AVCS_ERR_UNKNOWN, "Fatal: No memory"); 434 435 outputLoop_ = make_unique<thread>(&AEncDemoAuto::OutputFunc, this); 436 DEMO_CHECK_AND_RETURN_RET_LOG(outputLoop_ != nullptr, AVCS_ERR_UNKNOWN, "Fatal: No memory"); 437 if (audioEnc_ == nullptr) { 438 std::cout << "audioEnc_ is nullptr " << std::endl; 439 } 440 int32_t ret = OH_AudioEncoder_Start(audioEnc_); 441 return ret; 442} 443 444int32_t AEncDemoAuto::Stop() 445{ 446 return OH_AudioEncoder_Stop(audioEnc_); 447} 448 449int32_t AEncDemoAuto::Flush() 450{ 451 OH_AVErrCode ret = OH_AudioEncoder_Flush(audioEnc_); 452 return ret; 453} 454 455int32_t AEncDemoAuto::Release() 456{ 457 isRunning_.store(false); 458 signal_->startCond_.notify_all(); 459 if (inputLoop_ != nullptr && inputLoop_->joinable()) { 460 { 461 unique_lock<mutex> lock(signal_->inMutex_); 462 signal_->inCond_.notify_all(); 463 } 464 inputLoop_->join(); 465 inputLoop_.reset(); 466 inputLoop_ = nullptr; 467 while (!signal_->inQueue_.empty()) { 468 signal_->inQueue_.pop(); 469 } 470 while (!signal_->inBufferQueue_.empty()) { 471 signal_->inBufferQueue_.pop(); 472 } 473 std::cout << "clear input buffer!\n"; 474 } 475 476 if (outputLoop_ != nullptr && outputLoop_->joinable()) { 477 { 478 unique_lock<mutex> lock(signal_->outMutex_); 479 signal_->outCond_.notify_all(); 480 } 481 outputLoop_->join(); 482 outputLoop_.reset(); 483 outputLoop_ = nullptr; 484 while (!signal_->outQueue_.empty()) { 485 signal_->outQueue_.pop(); 486 } 487 while (!signal_->attrQueue_.empty()) { 488 signal_->attrQueue_.pop(); 489 } 490 while (!signal_->outBufferQueue_.empty()) { 491 signal_->outBufferQueue_.pop(); 492 } 493 std::cout << "clear output buffer!\n"; 494 } 495 if (signal_) { 496 ClearQueue(); 497 delete signal_; 498 signal_ = nullptr; 499 std::cout << "signal_Release" <<endl; 500 } 501 int32_t ret = OH_AudioEncoder_Destroy(audioEnc_); 502 audioEnc_ = nullptr; 503 return ret; 504} 505 506int32_t AEncDemoAuto::Reset() 507{ 508 return OH_AudioEncoder_Reset(audioEnc_); 509} 510 511void AEncDemoAuto::HandleInputEOS(const uint32_t index) 512{ 513 OH_AVCodecBufferAttr info; 514 info.size = 0; 515 info.offset = 0; 516 info.pts = 0; 517 info.flags = AVCODEC_BUFFER_FLAGS_EOS; 518 OH_AVErrCode ret = OH_AudioEncoder_PushInputData(audioEnc_, index, info); 519 std::cout << "HandleInputEOS->ret:"<< ret <<endl; 520 signal_->inBufferQueue_.pop(); 521 signal_->inQueue_.pop(); 522} 523 524int32_t AEncDemoAuto::HandleNormalInput(const uint32_t& index, const int64_t pts, const size_t size) 525{ 526 OH_AVCodecBufferAttr info; 527 info.size = size; 528 info.offset = 0; 529 info.pts = pts; 530 531 int32_t ret = AVCS_ERR_OK; 532 if (isFirstFrame_) { 533 info.flags = AVCODEC_BUFFER_FLAGS_CODEC_DATA; 534 ret = OH_AudioEncoder_PushInputData(audioEnc_, index, info); 535 isFirstFrame_ = false; 536 } else { 537 info.flags = AVCODEC_BUFFER_FLAGS_NONE; 538 ret = OH_AudioEncoder_PushInputData(audioEnc_, index, info); 539 } 540 signal_->inQueue_.pop(); 541 signal_->inBufferQueue_.pop(); 542 return ret; 543} 544 545 546void AEncDemoAuto::InputFunc() 547{ 548 int64_t pts = 0; 549 size_t frameBytes = 1152; 550 if (audioType_ == TYPE_OPUS) { 551 size_t opussize = 960; 552 frameBytes = opussize; 553 } else if (audioType_ == TYPE_G711MU) { 554 size_t gmusize = 320; 555 frameBytes = gmusize; 556 } else if (audioType_ == TYPE_AAC) { 557 size_t aacsize = 1024; 558 frameBytes = aacsize; 559 } 560 size_t currentSize = inputdatasize < frameBytes ? inputdatasize : frameBytes; 561 while (isRunning_.load()) { 562 unique_lock<mutex> lock(signal_->inMutex_); 563 signal_->inCond_.wait(lock, [this]() { return (signal_->inQueue_.size() > 0 || !isRunning_.load()); }); 564 if (!isRunning_.load()) { 565 break; 566 } 567 uint32_t index = signal_->inQueue_.front(); 568 auto buffer = signal_->inBufferQueue_.front(); 569 DEMO_CHECK_AND_BREAK_LOG(buffer != nullptr, "Fatal: GetInputBuffer fail"); 570 strncpy_s((char *)OH_AVMemory_GetAddr(buffer), currentSize, inputdata.c_str(), currentSize); 571 if (isFirstFrame_ == false || currentSize <= 0) { 572 HandleInputEOS(index); 573 std::cout << "end buffer\n"; 574 isRunning_.store(false); 575 break; 576 } 577 int32_t ret = HandleNormalInput(index, pts, frameBytes); 578 if (ret != AVCS_ERR_OK) { 579 cout << "Fatal, exit:" <<ret << endl; 580 isRunning_.store(false); 581 break; 582 } 583 } 584 signal_->startCond_.notify_all(); 585} 586 587void AEncDemoAuto::OutputFunc() 588{ 589 while (isRunning_.load()) { 590 unique_lock<mutex> lock(signal_->outMutex_); 591 signal_->outCond_.wait(lock, [this]() { return (signal_->outQueue_.size() > 0 || !isRunning_.load()); }); 592 593 if (!isRunning_.load()) { 594 cout << "wait to stop, exit" << endl; 595 break; 596 } 597 uint32_t index = signal_->outQueue_.front(); 598 OH_AVCodecBufferAttr attr = signal_->attrQueue_.front(); 599 600 signal_->outBufferQueue_.pop(); 601 signal_->attrQueue_.pop(); 602 signal_->outQueue_.pop(); 603 if (OH_AudioEncoder_FreeOutputData(audioEnc_, index) != AV_ERR_OK) { 604 cout << "Fatal: FreeOutputData fail" << endl; 605 break; 606 } 607 if (attr.flags == AVCODEC_BUFFER_FLAGS_EOS) { 608 cout << "encode eos" << endl; 609 break; 610 } 611 } 612 isRunning_.store(false); 613 signal_->startCond_.notify_all(); 614} 615 616bool AEncDemoAuto::RunCase(const uint8_t *data, size_t size) 617{ 618 std::string codecdata(reinterpret_cast<const char*>(data), size); 619 inputdata = codecdata; 620 inputdatasize = size; 621 DEMO_CHECK_AND_RETURN_RET_LOG(CreateEnc() == AVCS_ERR_OK, false, "Fatal: CreateEnc fail"); 622 OH_AVFormat* format = OH_AVFormat_Create(); 623 SetFormat(format); 624 DEMO_CHECK_AND_RETURN_RET_LOG(Configure(format) == AVCS_ERR_OK, false, "Fatal: Configure fail"); 625 DEMO_CHECK_AND_RETURN_RET_LOG(Start() == AVCS_ERR_OK, false, "Fatal: Start fail"); 626 sleep(1); 627 auto start = chrono::steady_clock::now(); 628 629 unique_lock<mutex> lock(signal_->startMutex_); 630 signal_->startCond_.wait(lock, [this]() { return (!(isRunning_.load())); }); 631 632 auto end = chrono::steady_clock::now(); 633 std::cout << "Encode finished, time = " << std::chrono::duration_cast<chrono::milliseconds>(end - start).count() 634 << " ms" << std::endl; 635 DEMO_CHECK_AND_RETURN_RET_LOG(Stop() == AVCS_ERR_OK, false, "Fatal: Stop fail"); 636 DEMO_CHECK_AND_RETURN_RET_LOG(Release() == AVCS_ERR_OK, false, "Fatal: Release fail"); 637 if (format != nullptr) { 638 OH_AVFormat_Destroy(format); 639 format = nullptr; 640 } 641 sleep(1); 642 return true; 643} 644