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::CreateEnd() 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::CreateEndByMime() 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 511OH_AVFormat* AEncDemoAuto::GetOutputDescription(OH_AVCodec* codec) 512{ 513 return OH_AudioEncoder_GetOutputDescription(codec); 514} 515 516void AEncDemoAuto::HandleInputEOS(const uint32_t index) 517{ 518 OH_AVCodecBufferAttr info; 519 info.size = 0; 520 info.offset = 0; 521 info.pts = 0; 522 info.flags = AVCODEC_BUFFER_FLAGS_EOS; 523 OH_AVErrCode ret = OH_AudioEncoder_PushInputData(audioEnc_, index, info); 524 std::cout << "HandleInputEOS->ret:"<< ret <<endl; 525 signal_->inBufferQueue_.pop(); 526 signal_->inQueue_.pop(); 527} 528 529int32_t AEncDemoAuto::HandleNormalInput(const uint32_t& index, const int64_t pts, const size_t size) 530{ 531 OH_AVCodecBufferAttr info; 532 info.size = size; 533 info.offset = 0; 534 info.pts = pts; 535 536 int32_t ret = AVCS_ERR_OK; 537 if (isFirstFrame_) { 538 info.flags = AVCODEC_BUFFER_FLAGS_CODEC_DATA; 539 ret = OH_AudioEncoder_PushInputData(audioEnc_, index, info); 540 isFirstFrame_ = false; 541 } else { 542 info.flags = AVCODEC_BUFFER_FLAGS_NONE; 543 ret = OH_AudioEncoder_PushInputData(audioEnc_, index, info); 544 } 545 signal_->inQueue_.pop(); 546 signal_->inBufferQueue_.pop(); 547 return ret; 548} 549 550 551void AEncDemoAuto::InputFunc() 552{ 553 int64_t pts = 0; 554 size_t frameBytes = 1152; 555 if (audioType_ == TYPE_OPUS) { 556 size_t opussize = 960; 557 frameBytes = opussize; 558 } else if (audioType_ == TYPE_G711MU) { 559 size_t gmusize = 320; 560 frameBytes = gmusize; 561 } else if (audioType_ == TYPE_AAC) { 562 size_t aacsize = 1024; 563 frameBytes = aacsize; 564 } 565 size_t currentSize = inputdatasize < frameBytes ? inputdatasize : frameBytes; 566 while (isRunning_.load()) { 567 unique_lock<mutex> lock(signal_->inMutex_); 568 signal_->inCond_.wait(lock, [this]() { return (signal_->inQueue_.size() > 0 || !isRunning_.load()); }); 569 if (!isRunning_.load()) { 570 break; 571 } 572 uint32_t index = signal_->inQueue_.front(); 573 auto buffer = signal_->inBufferQueue_.front(); 574 DEMO_CHECK_AND_BREAK_LOG(buffer != nullptr, "Fatal: GetInputBuffer fail"); 575 strncpy_s((char *)OH_AVMemory_GetAddr(buffer), currentSize, inputdata.c_str(), currentSize); 576 if (isFirstFrame_ == false || currentSize <= 0) { 577 HandleInputEOS(index); 578 std::cout << "end buffer\n"; 579 isRunning_.store(false); 580 break; 581 } 582 int32_t ret = HandleNormalInput(index, pts, frameBytes); 583 if (ret != AVCS_ERR_OK) { 584 cout << "Fatal, exit:" <<ret << endl; 585 isRunning_.store(false); 586 break; 587 } 588 } 589 signal_->startCond_.notify_all(); 590} 591 592void AEncDemoAuto::OutputFunc() 593{ 594 while (isRunning_.load()) { 595 unique_lock<mutex> lock(signal_->outMutex_); 596 signal_->outCond_.wait(lock, [this]() { return (signal_->outQueue_.size() > 0 || !isRunning_.load()); }); 597 598 if (!isRunning_.load()) { 599 cout << "wait to stop, exit" << endl; 600 break; 601 } 602 uint32_t index = signal_->outQueue_.front(); 603 OH_AVCodecBufferAttr attr = signal_->attrQueue_.front(); 604 605 signal_->outBufferQueue_.pop(); 606 signal_->attrQueue_.pop(); 607 signal_->outQueue_.pop(); 608 if (OH_AudioEncoder_FreeOutputData(audioEnc_, index) != AV_ERR_OK) { 609 cout << "Fatal: FreeOutputData fail" << endl; 610 break; 611 } 612 if (attr.flags == AVCODEC_BUFFER_FLAGS_EOS) { 613 cout << "encode eos" << endl; 614 break; 615 } 616 } 617 isRunning_.store(false); 618 signal_->startCond_.notify_all(); 619} 620 621bool AEncDemoAuto::RunCaseFlush(const uint8_t *data, size_t size) 622{ 623 std::string codecdata(reinterpret_cast<const char*>(data), size); 624 inputdata = codecdata; 625 inputdatasize = size; 626 DEMO_CHECK_AND_RETURN_RET_LOG(CreateEnd() == AVCS_ERR_OK, false, "Fatal: CreateEnd fail"); 627 OH_AVFormat* format = OH_AVFormat_Create(); 628 SetFormat(format); 629 DEMO_CHECK_AND_RETURN_RET_LOG(Configure(format) == AVCS_ERR_OK, false, "Fatal: Configure fail"); 630 DEMO_CHECK_AND_RETURN_RET_LOG(Start() == AVCS_ERR_OK, false, "Fatal: Start fail"); 631 sleep(1); 632 auto start = chrono::steady_clock::now(); 633 634 unique_lock<mutex> lock(signal_->startMutex_); 635 signal_->startCond_.wait(lock, [this]() { return (!(isRunning_.load())); }); 636 637 auto end = chrono::steady_clock::now(); 638 std::cout << "Encode finished, time = " << std::chrono::duration_cast<chrono::milliseconds>(end - start).count() 639 << " ms" << std::endl; 640 //Flush 641 DEMO_CHECK_AND_RETURN_RET_LOG(Flush() == AVCS_ERR_OK, false, "Fatal: Flush fail"); 642 DEMO_CHECK_AND_RETURN_RET_LOG(Stop() == AVCS_ERR_OK, false, "Fatal: Stop fail"); 643 DEMO_CHECK_AND_RETURN_RET_LOG(Release() == AVCS_ERR_OK, false, "Fatal: Release fail"); 644 if (format != nullptr) { 645 OH_AVFormat_Destroy(format); 646 format = nullptr; 647 } 648 sleep(1); 649 return true; 650}