From a02ddbec791ad628bc60e60d6e4dc15040e0dd04 Mon Sep 17 00:00:00 2001 From: zhangguorong Date: Fri, 13 May 2022 14:55:52 +0800 Subject: [PATCH] feat: modify Demo to support BufferHandle Signed-off-by: zhangguorong --- codec/test/demo/v2.0/BUILD.gn | 28 ++- .../test/demo/v2.0/include/codec_hdi_decode.h | 114 +++++---- .../test/demo/v2.0/include/codec_hdi_encode.h | 84 ++++--- codec/test/demo/v2.0/include/command_parse.h | 41 ++++ codec/test/demo/v2.0/src/codec_hdi_decode.cpp | 199 ++++++++++++---- codec/test/demo/v2.0/src/codec_hdi_encode.cpp | 223 +++++++++++++++--- codec/test/demo/v2.0/src/command_parse.cpp | 89 +++++++ 7 files changed, 618 insertions(+), 160 deletions(-) create mode 100644 codec/test/demo/v2.0/include/command_parse.h create mode 100644 codec/test/demo/v2.0/src/command_parse.cpp diff --git a/codec/test/demo/v2.0/BUILD.gn b/codec/test/demo/v2.0/BUILD.gn index 450c2480bd..1d263e1d89 100644 --- a/codec/test/demo/v2.0/BUILD.gn +++ b/codec/test/demo/v2.0/BUILD.gn @@ -24,11 +24,13 @@ ohos_executable("codec_hdi_omx_decode") { "//drivers/peripheral/codec/hal/config/common/include", "//utils/native/base/include", "//third_party/openmax/api/1.1.2", + "//drivers/peripheral/display/hdi_service/gralloc/include", ] - cflags_cc = [ "-DRK" ] - - sources = [ "src/codec_hdi_decode.cpp" ] + sources = [ + "src/codec_hdi_decode.cpp", + "src/command_parse.cpp", + ] deps = [ "//drivers/adapter/uhdf2/hdi:libhdi", @@ -42,7 +44,11 @@ ohos_executable("codec_hdi_omx_decode") { ] if (is_standard_system) { - external_deps = [ "hiviewdfx_hilog_native:libhilog" ] + external_deps = [ + "display_device_driver:hdi_gralloc_client", + "graphic_chipsetsdk:buffer_handle", + "hiviewdfx_hilog_native:libhilog", + ] } else { external_deps = [ "hilog:libhilog" ] } @@ -63,11 +69,13 @@ ohos_executable("codec_hdi_omx_encode") { "//drivers/peripheral/codec/hal/config/common/include", "//utils/native/base/include", "//third_party/openmax/api/1.1.2", + "//drivers/peripheral/display/hdi_service/gralloc/include", ] - cflags_cc = [ "-DRK" ] - - sources = [ "src/codec_hdi_encode.cpp" ] + sources = [ + "src/codec_hdi_encode.cpp", + "src/command_parse.cpp", + ] deps = [ "//drivers/adapter/uhdf2/hdi:libhdi", @@ -81,7 +89,11 @@ ohos_executable("codec_hdi_omx_encode") { ] if (is_standard_system) { - external_deps = [ "hiviewdfx_hilog_native:libhilog" ] + external_deps = [ + "display_device_driver:hdi_gralloc_client", + "graphic_chipsetsdk:buffer_handle", + "hiviewdfx_hilog_native:libhilog", + ] } else { external_deps = [ "hilog:libhilog" ] } diff --git a/codec/test/demo/v2.0/include/codec_hdi_decode.h b/codec/test/demo/v2.0/include/codec_hdi_decode.h index 6da61e4a9a..6be25d3337 100644 --- a/codec/test/demo/v2.0/include/codec_hdi_decode.h +++ b/codec/test/demo/v2.0/include/codec_hdi_decode.h @@ -15,13 +15,15 @@ #ifndef CODEC_HDI_DECODE_H #define CODEC_HDI_DECODE_H - #include #include #include #include +#include +#include #include #include +#include #include #include #include @@ -29,63 +31,59 @@ #include #include #include - #include "codec_callback_type_service.h" #include "codec_callback_type_stub.h" #include "codec_component_manager.h" #include "codec_component_type.h" #include "codec_types.h" - -enum class codecMime { AVC, HEVC }; +#include "command_parse.h" enum class PortIndex { PORT_INDEX_INPUT = 0, PORT_INDEX_OUTPUT = 1 }; - -struct inParameters { - codecMime codec = codecMime::AVC; - std::string path; - unsigned int width = 144; - unsigned int height = 176; -}; - -struct privateApp { - codecMime codec = codecMime::AVC; - unsigned int width = 640; - unsigned int height = 480; - OMX_COLOR_FORMATTYPE format = OMX_COLOR_FormatYUV420SemiPlanar; - OMX_U32 framerate = 30; - OMX_HANDLETYPE handle; - OMX_PTR pAppData = nullptr; - bool isSupply_ = false; -}; - using OmxCodecBuffer = struct OmxCodecBuffer; -struct BufferInfo { - std::shared_ptr omxBuffer; - std::shared_ptr avSharedPtr; - PortIndex portIndex; - BufferInfo() - { - omxBuffer = nullptr; - avSharedPtr = nullptr; - portIndex = PortIndex::PORT_INDEX_INPUT; - } - ~BufferInfo() - { - omxBuffer = nullptr; - if (avSharedPtr) { - avSharedPtr->UnmapAshmem(); - avSharedPtr->CloseAshmem(); + +class CodecHdiDecode { + struct BufferInfo { + std::shared_ptr omxBuffer; + std::shared_ptr avSharedPtr; + PortIndex portIndex; + BufferHandle *bufferHandle; + BufferInfo() + { + omxBuffer = nullptr; avSharedPtr = nullptr; + portIndex = PortIndex::PORT_INDEX_INPUT; + bufferHandle = nullptr; } - portIndex = PortIndex::PORT_INDEX_INPUT; - } -}; -using BufferInfo = struct BufferInfo; -class CodecHdiDecode { + ~BufferInfo() + { + omxBuffer = nullptr; + if (avSharedPtr != nullptr) { + avSharedPtr->UnmapAshmem(); + avSharedPtr->CloseAshmem(); + avSharedPtr = nullptr; + } + if (bufferHandle != nullptr && gralloc_ != nullptr) { + gralloc_->FreeMem(*bufferHandle); + bufferHandle = nullptr; + } + portIndex = PortIndex::PORT_INDEX_INPUT; + } + void setBufferHandle(BufferHandle *bufferHandle) + { + if (this->bufferHandle != nullptr) { + if (gralloc_ != nullptr) { + gralloc_->FreeMem(*this->bufferHandle); + } + } + this->bufferHandle = bufferHandle; + } + }; + using BufferInfo = struct BufferInfo; + public: explicit CodecHdiDecode(); ~CodecHdiDecode(); - bool Init(int width, int height, std::string &filename, codecMime codec); + bool Init(CommandOpt &opt); bool Configure(); bool UseBuffers(); void FreeBuffers(); @@ -96,12 +94,20 @@ public: const struct OmxCodecBuffer *buffer); static int32_t OnFillBufferDone(struct CodecCallbackType *self, int8_t *appData, uint32_t appDataLen, struct OmxCodecBuffer *buffer); - template inline void InitParam(T ¶m) + template + inline void InitParam(T ¶m) { memset_s(¶m, sizeof(param), 0x0, sizeof(param)); param.nSize = sizeof(param); param.nVersion.s.nVersionMajor = 1; // mVersion.s.nVersionMajor; } + template + inline void InitParamInOhos(T ¶m) + { + memset_s(¶m, sizeof(param), 0x0, sizeof(param)); + param.size = sizeof(param); + param.version.s.nVersionMajor = 1; // mVersion.s.nVersionMajor; + } void WaitForStatusChanged(); void onStatusChanged(); bool ReadOnePacket(FILE *fp, char *buf, uint32_t &filledCount); @@ -109,18 +115,25 @@ public: private: int32_t UseBufferOnPort(PortIndex portIndex); int32_t UseBufferOnPort(PortIndex portIndex, int bufferCount, int bufferSize); + int32_t UseBufferHandle(int bufferCount, int bufferSize); int32_t OnEmptyBufferDone(const struct OmxCodecBuffer &buffer); int32_t OnFillBufferDone(struct OmxCodecBuffer &buffer); + int32_t CheckAndUseBufferHandle(); int GetYuvSize(); int32_t ConfigPortDefine(); bool FillAllTheBuffer(); int GetFreeBufferId(); + uint32_t inline align_up(uint32_t width) + { + return (((width) + alignment_ - 1) & (~(alignment_ - 1))); + } private: FILE *fpIn_; // input file FILE *fpOut_; - unsigned int width_; - unsigned int height_; + uint32_t width_; + uint32_t height_; + uint32_t stride_; struct CodecComponentType *client_; struct CodecCallbackType *callback_; struct CodecComponentManager *omxMgr_; @@ -131,7 +144,10 @@ private: std::condition_variable statusCondition_; std::mutex statusLock_; bool exit_; - bool isSupply_; codecMime codecMime_; + bool useBufferHandle_; + int count_; + static constexpr uint32_t alignment_ = 16; + static OHOS::HDI::Display::V1_0::IDisplayGralloc *gralloc_; }; #endif /* CODEC_HDI_DECODE_H */ \ No newline at end of file diff --git a/codec/test/demo/v2.0/include/codec_hdi_encode.h b/codec/test/demo/v2.0/include/codec_hdi_encode.h index ab1c4883a9..c493505002 100644 --- a/codec/test/demo/v2.0/include/codec_hdi_encode.h +++ b/codec/test/demo/v2.0/include/codec_hdi_encode.h @@ -20,8 +20,11 @@ #include #include #include +#include +#include #include #include +#include #include #include #include @@ -29,45 +32,47 @@ #include #include #include - #include "codec_callback_type_service.h" #include "codec_callback_type_stub.h" #include "codec_component_manager.h" #include "codec_component_type.h" #include "codec_types.h" - -enum class codecMime { AVC }; +#include "command_parse.h" enum class PortIndex { PORT_INDEX_INPUT = 0, PORT_INDEX_OUTPUT = 1 }; -struct BufferInfo { - std::shared_ptr omxBuffer; - std::shared_ptr avSharedPtr; - PortIndex portIndex; - BufferInfo() - { - omxBuffer = nullptr; - avSharedPtr = nullptr; - portIndex = PortIndex::PORT_INDEX_INPUT; - } - ~BufferInfo() - { - omxBuffer = nullptr; - if (avSharedPtr) { - avSharedPtr->UnmapAshmem(); - avSharedPtr->CloseAshmem(); +class CodecHdiEncode { + struct BufferInfo { + std::shared_ptr omxBuffer; + std::shared_ptr avSharedPtr; + int bufferHandleId; + PortIndex portIndex; + BufferInfo() + { + omxBuffer = nullptr; avSharedPtr = nullptr; + portIndex = PortIndex::PORT_INDEX_INPUT; + bufferHandleId = -1; } - portIndex = PortIndex::PORT_INDEX_INPUT; - } -}; -using BufferInfo = struct BufferInfo; -class CodecHdiEncode { + ~BufferInfo() + { + omxBuffer = nullptr; + if (avSharedPtr) { + avSharedPtr->UnmapAshmem(); + avSharedPtr->CloseAshmem(); + avSharedPtr = nullptr; + } + portIndex = PortIndex::PORT_INDEX_INPUT; + bufferHandleId = -1; + } + }; + using BufferInfo = struct BufferInfo; + public: CodecHdiEncode(); ~CodecHdiEncode(); - bool Init(int width, int height, std::string &filename); + bool Init(CommandOpt &opt); bool Configure(); bool UseBuffers(); int32_t UseBufferOnPort(PortIndex portIndex); @@ -80,12 +85,20 @@ public: const struct OmxCodecBuffer *buffer); static int32_t OnFillBufferDone(struct CodecCallbackType *self, int8_t *appData, uint32_t appDataLen, struct OmxCodecBuffer *buffer); - template inline void InitParam(T ¶m) + template + inline void InitParam(T ¶m) { memset_s(¶m, sizeof(param), 0x0, sizeof(param)); param.nSize = sizeof(param); param.nVersion.s.nVersionMajor = 1; } + template + inline void InitParamInOhos(T ¶m) + { + memset_s(¶m, sizeof(param), 0x0, sizeof(param)); + param.size = sizeof(param); + param.version.s.nVersionMajor = 1; // mVersion.s.nVersionMajor; + } void WaitForStatusChanged(); void onStatusChanged(); bool ReadOneFrame(FILE *fp, char *buf, uint32_t &filledCount); @@ -98,12 +111,21 @@ private: bool FillAllTheBuffer(); int GetFreeBufferId(); int32_t ConfigPortDefine(); + int32_t CheckAndUseBufferHandle(); + int32_t UseDynaBuffer(int bufferCount, int bufferSize); + bool FillCodecBuffer(std::shared_ptr bufferInfo, bool &endFlag); + int32_t createBufferHandle(); + uint32_t inline align_up(uint32_t width) + { + return (((width) + alignment_ - 1) & (~(alignment_ - 1))); + } private: FILE *fpIn_; // input file FILE *fpOut_; - unsigned int width_; - unsigned int height_; + uint32_t width_; + uint32_t height_; + uint32_t stride_; struct CodecComponentType *client_; struct CodecCallbackType *callback_; struct CodecComponentManager *omxMgr_; @@ -114,7 +136,11 @@ private: std::condition_variable statusCondition_; std::mutex statusLock_; bool exit_; - bool isSupply_; + std::map bufferHandles_; + std::list freeBufferHandles_; + bool useBufferHandle_; + static constexpr uint32_t alignment_ = 16; + static OHOS::HDI::Display::V1_0::IDisplayGralloc *gralloc_; }; #endif // CODEC_HDI_ENCODE_H \ No newline at end of file diff --git a/codec/test/demo/v2.0/include/command_parse.h b/codec/test/demo/v2.0/include/command_parse.h new file mode 100644 index 0000000000..52351f401d --- /dev/null +++ b/codec/test/demo/v2.0/include/command_parse.h @@ -0,0 +1,41 @@ +/* + * Copyright 2022 Shenzhen Kaihong DID Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef PARSE_COMMAND_H +#define PARSE_COMMAND_H +#include + +enum class codecMime { AVC, HEVC }; + +using CommandOpt = struct CommandOpt { + std::string fileInput = ""; + std::string fileOutput = ""; + uint32_t width = 0; + uint32_t height = 0; + bool useBuffer = false; + codecMime codec = codecMime::AVC; +}; + +class CommandParse { +public: + CommandParse() + {} + ~CommandParse() + {} + bool Parse(int argc, char *argv[], CommandOpt &opt); + +private: + void ShowUsage(); +}; +#endif \ No newline at end of file diff --git a/codec/test/demo/v2.0/src/codec_hdi_decode.cpp b/codec/test/demo/v2.0/src/codec_hdi_decode.cpp index 55a1ef659f..1fdb02b7af 100644 --- a/codec/test/demo/v2.0/src/codec_hdi_decode.cpp +++ b/codec/test/demo/v2.0/src/codec_hdi_decode.cpp @@ -13,6 +13,7 @@ * limitations under the License. */ +#include "codec_hdi_decode.h" #include #include #include @@ -21,14 +22,11 @@ #include #include -#include "codec_hdi_decode.h" - +OHOS::HDI::Display::V1_0::IDisplayGralloc *CodecHdiDecode::gralloc_ = nullptr; using namespace std; using namespace OHOS; - constexpr int32_t FD_SIZE = sizeof(int); constexpr int32_t FRAME = 30 << 16; -constexpr int32_t PARAM_LEN = 5; constexpr int32_t denominator = 2; constexpr int32_t numerator = 3; constexpr int32_t START_CODE_OFFSET_ONE = -1; @@ -51,10 +49,11 @@ CodecHdiDecode::CodecHdiDecode() : fpIn_(nullptr), fpOut_(nullptr) callback_ = nullptr; omxMgr_ = nullptr; exit_ = false; - isSupply_ = false; width_ = 0; height_ = 0; codecMime_ = codecMime::AVC; + count_ = 0; + useBufferHandle_ = false; } CodecHdiDecode::~CodecHdiDecode() @@ -119,16 +118,23 @@ bool CodecHdiDecode::ReadOnePacket(FILE *fp, char *buf, uint32_t &filledCount) return ret; } -bool CodecHdiDecode::Init(int width, int height, std::string &filename, codecMime codec) +bool CodecHdiDecode::Init(CommandOpt &opt) { - this->width_ = width; - this->height_ = height; - this->codecMime_ = codec; - HDF_LOGI("width[%{public}d], height[%{public}d]", width_, height_); - fpIn_ = fopen(filename.c_str(), "rb"); - fpOut_ = fopen("/data/out.yuv", "wb+"); + this->width_ = opt.width; + this->height_ = opt.height; + this->codecMime_ = opt.codec; + this->stride_ = align_up(opt.width); + this->useBufferHandle_ = opt.useBuffer; + HDF_LOGI("width[%{public}d], height[%{public}d],stride_[%{public}d],infile[%{public}s],outfile[%{public}s]", width_, + height_, stride_, opt.fileInput.c_str(), opt.fileOutput.c_str()); + + // gralloc init + gralloc_ = OHOS::HDI::Display::V1_0::IDisplayGralloc::Get(); + fpIn_ = fopen(opt.fileInput.c_str(), "rb"); + fpOut_ = fopen(opt.fileOutput.c_str(), "wb+"); if ((fpIn_ == nullptr) || (fpOut_ == nullptr)) { - HDF_LOGE("%{public}s failed to open file %{public}s", __func__, filename.c_str()); + HDF_LOGE("%{public}s failed to open file %{public}s or %{public}s", __func__, opt.fileInput.c_str(), + opt.fileOutput.c_str()); return false; } @@ -143,9 +149,8 @@ bool CodecHdiDecode::Init(int width, int height, std::string &filename, codecMim callback_->EventHandler = &CodecHdiDecode::OnEvent; callback_->EmptyBufferDone = &CodecHdiDecode::OnEmptyBufferDone; callback_->FillBufferDone = &CodecHdiDecode::OnFillBufferDone; - int32_t err = HDF_SUCCESS; - if (codec == codecMime::AVC) { + if (codecMime_ == codecMime::AVC) { err = omxMgr_->CreateComponent(&client_, const_cast(decoder_avc), 0, 0, callback_); } else { err = omxMgr_->CreateComponent(&client_, const_cast(decoder_hevc), 0, 0, callback_); @@ -182,7 +187,7 @@ int32_t CodecHdiDecode::ConfigPortDefine() param.format.video.eCompressionFormat, param.format.video.eColorFormat); param.format.video.nFrameWidth = width_; param.format.video.nFrameHeight = height_; - param.format.video.nStride = width_; + param.format.video.nStride = stride_; param.format.video.nSliceHeight = height_; err = client_->SetParameter(client_, OMX_IndexParamPortDefinition, (int8_t *)¶m, sizeof(param)); if (err != HDF_SUCCESS) { @@ -203,7 +208,7 @@ int32_t CodecHdiDecode::ConfigPortDefine() param.format.video.eCompressionFormat, param.format.video.eColorFormat); param.format.video.nFrameWidth = width_; param.format.video.nFrameHeight = height_; - param.format.video.nStride = width_; + param.format.video.nStride = stride_; param.format.video.nSliceHeight = height_; param.format.video.eColorFormat = AV_COLOR_FORMAT; // YUV420SP err = client_->SetParameter(client_, OMX_IndexParamPortDefinition, (int8_t *)¶m, sizeof(param)); @@ -242,9 +247,59 @@ bool CodecHdiDecode::Configure() HDF_LOGE("%{public}s failed with PortIndex::PORT_INDEX_INPUT", __func__); return false; } + + err = CheckAndUseBufferHandle(); + if (err != HDF_SUCCESS) { + HDF_LOGE("%{public}s failed with CheckAndUseBufferHandle", __func__); + return false; + } return true; } +int32_t CodecHdiDecode::CheckAndUseBufferHandle() +{ + if (!useBufferHandle_) { + return HDF_SUCCESS; + } + SupportBufferType param; + InitParamInOhos(param); + param.portIndex = (uint32_t)PortIndex::PORT_INDEX_INPUT; + + auto err = client_->GetParameter(client_, OMX_IndexParamSupportBufferType, (int8_t *)¶m, sizeof(param)); + HDF_LOGI( + "OMX_GetParameter:OMX_IndexParamSupportBufferType:kPortIndexInput, err [%{public}x], bufferTypes[%{public}d]", + err, param.bufferTypes); + if (err != HDF_SUCCESS) { + return err; + } + InitParamInOhos(param); + param.portIndex = (uint32_t)PortIndex::PORT_INDEX_OUTPUT; + err = client_->GetParameter(client_, OMX_IndexParamSupportBufferType, (int8_t *)¶m, sizeof(param)); + HDF_LOGI( + "OMX_GetParameter:OMX_IndexParamSupportBufferType:kPortIndexOutput, err [%{public}x], bufferTypes[%{public}d]", + err, param.bufferTypes); + if (err != HDF_SUCCESS) { + return err; + } + GetBufferHandleUsageParams usage; + InitParamInOhos(usage); + usage.portIndex = (uint32_t)PortIndex::PORT_INDEX_OUTPUT; + err = client_->GetParameter(client_, OMX_IndexParamGetBufferHandleUsage, (int8_t *)&usage, sizeof(usage)); + HDF_LOGI( + "OMX_GetParameter:OMX_IndexParamGetBufferHandleUsage:kPortIndexOutput, err [%{public}x], usage[%{public}d]", + err, usage.usage); + if (err != HDF_SUCCESS) { + return err; + } + UseBufferType type; + InitParamInOhos(type); + type.portIndex = (uint32_t)PortIndex::PORT_INDEX_OUTPUT; + type.bufferType = BUFFER_TYPE_HANDLE; + err = client_->SetParameter(client_, OMX_IndexParamUseBufferType, (int8_t *)&type, sizeof(type)); + HDF_LOGI("OMX_SetParameter:OMX_IndexParamUseBufferType:kPortIndexOutput, err [%{public}x]", err); + return err; +} + bool CodecHdiDecode::UseBuffers() { HDF_LOGI("...command to IDLE...."); @@ -364,10 +419,14 @@ int32_t CodecHdiDecode::UseBufferOnPort(PortIndex portIndex) InitParam(param); param.nPortIndex = (uint32_t)portIndex; err = client_->GetParameter(client_, OMX_IndexParamCompBufferSupplier, (int8_t *)¶m, sizeof(param)); - HDF_LOGI("param.eBufferSupplier[%{public}d] isSupply [%{public}d], err [%{public}d]", param.eBufferSupplier, - this->isSupply_, err); + HDF_LOGI("param.eBufferSupplier[%{public}d] err [%{public}d]", param.eBufferSupplier, err); + } + if (useBufferHandle_ && portIndex == PortIndex::PORT_INDEX_OUTPUT) { + err = UseBufferHandle(bufferCount, bufferSize); + } else { + err = UseBufferOnPort(portIndex, bufferCount, bufferSize); } - err = UseBufferOnPort(portIndex, bufferCount, bufferSize); + if (err != HDF_SUCCESS) { HDF_LOGE("%{public}s UseBufferOnPort err[%{public}x]", __func__, err); return err; @@ -383,6 +442,54 @@ int32_t CodecHdiDecode::UseBufferOnPort(PortIndex portIndex) return HDF_SUCCESS; } +int32_t CodecHdiDecode::UseBufferHandle(int bufferCount, int bufferSize) +{ + if (bufferCount <= 0 || bufferSize <= 0 || gralloc_ == nullptr) { + return HDF_ERR_INVALID_PARAM; + } + AllocInfo alloc = {.width = this->stride_, + .height = this->height_, + .usage = HBM_USE_CPU_READ | HBM_USE_CPU_WRITE | HBM_USE_MEM_DMA, + .format = PIXEL_FMT_YCBCR_420_SP}; + int32_t err = HDF_SUCCESS; + for (int i = 0; i < bufferCount; i++) { + std::shared_ptr omxBuffer = std::make_shared(); + omxBuffer->size = sizeof(OmxCodecBuffer); + omxBuffer->version.s.nVersionMajor = 1; + omxBuffer->bufferType = BUFFER_TYPE_HANDLE; + BufferHandle *bufferHandle = nullptr; + err = gralloc_->AllocMem(alloc, bufferHandle); + HDF_LOGI("%{public}s AlloceMem ret val err[%{public}d], buffer [%{public}p]", __func__, err, bufferHandle); + if (DISPLAY_SUCCESS != err) { + HDF_LOGE("%{public}s AllocMem error", __func__); + return err; + } + size_t handleSize = + sizeof(BufferHandle) + (sizeof(int32_t) * (bufferHandle->reserveFds + bufferHandle->reserveInts)); + omxBuffer->bufferLen = handleSize; + omxBuffer->buffer = (uint8_t *)bufferHandle; + omxBuffer->allocLen = bufferSize; + omxBuffer->fenceFd = -1; // check use -1 first with no window + omxBuffer->pts = 0; + omxBuffer->flag = 0; + auto err = client_->UseBuffer(client_, (uint32_t)PortIndex::PORT_INDEX_OUTPUT, omxBuffer.get()); + if (err != HDF_SUCCESS) { + HDF_LOGE("%{public}s failed to UseBuffer with output port]", __func__); + return err; + } + omxBuffer->bufferLen = 0; + HDF_LOGI("UseBuffer returned bufferID [%{public}d]", omxBuffer->bufferId); + + std::shared_ptr bufferInfo = std::make_shared(); + bufferInfo->omxBuffer = omxBuffer; + bufferInfo->setBufferHandle(bufferHandle); + bufferInfo->portIndex = PortIndex::PORT_INDEX_OUTPUT; + omxBuffers_.emplace(std::make_pair(omxBuffer->bufferId, bufferInfo)); + unUsedOutBuffers_.push_back(omxBuffer->bufferId); + } + return HDF_SUCCESS; +} + void CodecHdiDecode::FreeBuffers() { // command to loaded @@ -429,7 +536,14 @@ bool CodecHdiDecode::FillAllTheBuffer() auto iter = omxBuffers_.find(bufferId); if (iter != omxBuffers_.end()) { auto bufferInfo = iter->second; - auto err = client_->FillThisBuffer(client_, bufferInfo->omxBuffer.get()); + auto buffer = bufferInfo->omxBuffer.get(); + if (bufferInfo->bufferHandle != nullptr) { + buffer->buffer = (uint8_t *)bufferInfo->bufferHandle; + buffer->bufferLen = sizeof(BufferHandle) + sizeof(int32_t) * (bufferInfo->bufferHandle->reserveFds + + bufferInfo->bufferHandle->reserveInts); + } + + auto err = client_->FillThisBuffer(client_, buffer); if (err != HDF_SUCCESS) { HDF_LOGE("%{public}s FillThisBuffer error", __func__); return false; @@ -465,6 +579,7 @@ void CodecHdiDecode::Run() return; } + auto t1 = std::chrono::system_clock::now(); bool eosFlag = false; while (!eosFlag) { HDF_LOGI(" inputput run"); @@ -499,6 +614,9 @@ void CodecHdiDecode::Run() usleep(10000); continue; } + auto t2 = std::chrono::system_clock::now(); + std::chrono::duration diff = t2 - t1; + HDF_LOGI("cost %{public}f, count=%{public}d", diff.count(), count_); // command to IDLE (void)client_->SendCommand(client_, OMX_CommandStateSet, OMX_StateIdle, NULL, 0); return; @@ -556,11 +674,20 @@ int32_t CodecHdiDecode::OnFillBufferDone(struct OmxCodecBuffer &buffer) if ((iter == omxBuffers_.end()) || (iter->second == nullptr)) { return HDF_SUCCESS; } + count_++; // read buffer auto bufferInfo = iter->second; - const void *addr = bufferInfo->avSharedPtr->ReadFromAshmem(buffer.filledLen, buffer.offset); - // save to file - (void)fwrite(addr, 1, buffer.filledLen, fpOut_); + if (bufferInfo->avSharedPtr != nullptr) { + const void *addr = bufferInfo->avSharedPtr->ReadFromAshmem(buffer.filledLen, buffer.offset); + (void)fwrite(addr, 1, buffer.filledLen, fpOut_); + } else if (bufferInfo->bufferHandle != nullptr && gralloc_ != nullptr) { + gralloc_->Mmap(*bufferInfo->bufferHandle); + (void)fwrite(bufferInfo->bufferHandle->virAddr, 1, + bufferInfo->bufferHandle->width * bufferInfo->bufferHandle->height * numerator / denominator, + fpOut_); + gralloc_->Unmap(*bufferInfo->bufferHandle); + } + (void)fflush(fpOut_); // reset buffer buffer.offset = 0; @@ -579,31 +706,19 @@ int32_t CodecHdiDecode::OnFillBufferDone(struct OmxCodecBuffer &buffer) } return HDF_SUCCESS; } + int main(int argc, char *argv[]) { - if (argc < PARAM_LEN) { - HDF_LOGE("usage AVC width_ heigh filename"); - return 0; - } - std::string codecString = argv[1]; - codecMime codec = codecMime::AVC; - if (strcmp(codecString.c_str(), "avc") == 0 || strcmp(codecString.c_str(), "AVC") == 0) { - codec = codecMime::AVC; - } else if (strcmp(codecString.c_str(), "hevc") == 0 || strcmp(codecString.c_str(), "HEVC") == 0) { - codec = codecMime::HEVC; - } else { - return 0; + CommandOpt opt; + CommandParse parse; + if (!parse.Parse(argc, argv, opt)) { + return HDF_FAILURE; } - - int width = atoi(argv[2]); - int height = atoi(argv[3]); - string filename = argv[4]; - if (g_core == nullptr) { g_core = new CodecHdiDecode(); } // Init width, height, input file - if (!g_core->Init(width, height, filename, codec)) { + if (!g_core->Init(opt)) { delete g_core; g_core = nullptr; return HDF_FAILURE; diff --git a/codec/test/demo/v2.0/src/codec_hdi_encode.cpp b/codec/test/demo/v2.0/src/codec_hdi_encode.cpp index e454cc208d..6e62e65821 100644 --- a/codec/test/demo/v2.0/src/codec_hdi_encode.cpp +++ b/codec/test/demo/v2.0/src/codec_hdi_encode.cpp @@ -13,6 +13,7 @@ * limitations under the License. */ +#include "codec_hdi_encode.h" #include #include #include @@ -21,15 +22,14 @@ #include #include -#include "codec_hdi_encode.h" - using namespace std; using namespace OHOS; #define HDF_LOG_TAG codec_omx_hdi_enc +OHOS::HDI::Display::V1_0::IDisplayGralloc *CodecHdiEncode::gralloc_ = nullptr; constexpr int32_t FRAME = 30 << 16; +constexpr int32_t BUFFER_COUNT = 10; constexpr int32_t BITRATE = 3000000; -constexpr int32_t PARAM_LEN = 5; constexpr int32_t FD_SIZE = sizeof(int); constexpr const char *encoder_avc = "OMX.rk.video_encoder.avc"; #define AV_COLOR_FORMAT OMX_COLOR_FormatYUV420SemiPlanar @@ -43,7 +43,7 @@ CodecHdiEncode::CodecHdiEncode() : fpIn_(nullptr), fpOut_(nullptr) callback_ = nullptr; omxMgr_ = nullptr; exit_ = false; - isSupply_ = false; + useBufferHandle_ = false; width_ = 0; height_ = 0; } @@ -81,25 +81,30 @@ bool CodecHdiEncode::ReadOneFrame(FILE *fp, char *buf, uint32_t &filledCount) return ret; } -bool CodecHdiEncode::Init(int width, int height, std::string &filename) +bool CodecHdiEncode::Init(CommandOpt &opt) { - this->width_ = width; - this->height_ = height; + this->width_ = opt.width; + this->height_ = opt.height; + this->stride_ = align_up(width_); + this->useBufferHandle_ = opt.useBuffer; HDF_LOGI("width[%{public}d], height[%{public}d]", width_, height_); - fpIn_ = fopen(filename.c_str(), "rb"); - fpOut_ = fopen("/data/out.h264", "wb+"); + // gralloc init + gralloc_ = OHOS::HDI::Display::V1_0::IDisplayGralloc::Get(); + + fpIn_ = fopen(opt.fileInput.c_str(), "rb"); + fpOut_ = fopen(opt.fileOutput.c_str(), "wb+"); if ((fpIn_ == nullptr) || (fpOut_ == nullptr)) { - HDF_LOGE("failed to open file %{public}s", filename.c_str()); + HDF_LOGE("%{public}s:failed to open file %{public}s or %{public}s", __func__, opt.fileInput.c_str(), + opt.fileOutput.c_str()); return false; } // Interface init omxMgr_ = GetCodecComponentManager(); - // init callback object callback_ = CodecCallbackTypeStubGetInstance(); if ((omxMgr_ == nullptr) || (callback_ == nullptr)) { + HDF_LOGE("%{public}s:omxMgr_ or callback_ is null", __func__); return false; } - HDF_LOGI("callback_ [0x%{public}p]", callback_); // set the callback callback_->EventHandler = &CodecHdiEncode::OnEvent; callback_->EmptyBufferDone = &CodecHdiEncode::OnEmptyBufferDone; @@ -137,9 +142,59 @@ bool CodecHdiEncode::Configure() HDF_LOGE("%{public}s ConfigBitMode error", __func__); return false; } + if (CheckAndUseBufferHandle() != HDF_SUCCESS) { + HDF_LOGE("%{public}s ConfigUseBufferHandle error", __func__); + return false; + } + return true; } +int32_t CodecHdiEncode::CheckAndUseBufferHandle() +{ + if (!useBufferHandle_) { + return HDF_SUCCESS; + } + + SupportBufferType param; + InitParamInOhos(param); + param.portIndex = (uint32_t)PortIndex::PORT_INDEX_OUTPUT; + + auto err = client_->GetParameter(client_, OMX_IndexParamSupportBufferType, (int8_t *)¶m, sizeof(param)); + HDF_LOGI( + "OMX_GetParameter:OMX_IndexParamSupportBufferType:PORT_INDEX_OUTPUT, err [%{public}x], bufferTypes[%{public}d]", + err, param.bufferTypes); + if (err != HDF_SUCCESS) { + return err; + } + InitParamInOhos(param); + param.portIndex = (uint32_t)PortIndex::PORT_INDEX_INPUT; + err = client_->GetParameter(client_, OMX_IndexParamSupportBufferType, (int8_t *)¶m, sizeof(param)); + HDF_LOGI( + "OMX_GetParameter:OMX_IndexParamSupportBufferType:PORT_INDEX_INPUT, err [%{public}x], bufferTypes[%{public}d]", + err, param.bufferTypes); + if (err != HDF_SUCCESS) { + return err; + } + GetBufferHandleUsageParams usage; + InitParamInOhos(usage); + usage.portIndex = (uint32_t)PortIndex::PORT_INDEX_INPUT; + err = client_->GetParameter(client_, OMX_IndexParamGetBufferHandleUsage, (int8_t *)&usage, sizeof(usage)); + HDF_LOGI( + "OMX_GetParameter:OMX_IndexParamGetBufferHandleUsage:PORT_INDEX_INPUT, err [%{public}x], usage[%{public}d]", + err, usage.usage); + if (err != HDF_SUCCESS) { + return err; + } + UseBufferType type; + InitParamInOhos(type); + type.portIndex = (uint32_t)PortIndex::PORT_INDEX_INPUT; + type.bufferType = BUFFER_TYPE_DYNAMIC_HANDLE; + err = client_->SetParameter(client_, OMX_IndexParamUseBufferType, (int8_t *)&type, sizeof(type)); + HDF_LOGI("OMX_SetParameter:OMX_IndexParamUseBufferType:PORT_INDEX_INPUT, err [%{public}x]", err); + return err; +} + bool CodecHdiEncode::UseBuffers() { // commad to IDLE @@ -163,6 +218,11 @@ bool CodecHdiEncode::UseBuffers() return false; } + if (useBufferHandle_ && createBufferHandle() != HDF_SUCCESS) { + HDF_LOGE("%{public}s createBufferHandle error", __func__); + return false; + } + // wait executing state enum OMX_STATETYPE status; err = client_->GetState(client_, &status); @@ -210,8 +270,7 @@ int32_t CodecHdiEncode::UseBufferOnPort(PortIndex portIndex) InitParam(param); param.nPortIndex = (uint32_t)portIndex; err = client_->GetParameter(client_, OMX_IndexParamCompBufferSupplier, (int8_t *)¶m, sizeof(param)); - HDF_LOGI("param.eBufferSupplier[%{public}d] isSupply [%{public}d], err [%{public}d]", param.eBufferSupplier, - this->isSupply_, err); + HDF_LOGI("param.eBufferSupplier[%{public}d] err [%{public}d]", param.eBufferSupplier, err); } if (portIndex == PortIndex::PORT_INDEX_INPUT) { @@ -220,8 +279,12 @@ int32_t CodecHdiEncode::UseBufferOnPort(PortIndex portIndex) bufferSize = width_ * height_; HDF_LOGI("bufferSize[%{public}d], width[%{public}d], height[%{public}d]", bufferSize, width_, height_); } + if (useBufferHandle_ && portIndex == PortIndex::PORT_INDEX_INPUT) { + err = UseDynaBuffer(bufferCount, bufferSize); + } else { + err = UseBufferOnPort(portIndex, bufferCount, bufferSize); + } - err = UseBufferOnPort(portIndex, bufferCount, bufferSize); if (err != HDF_SUCCESS) { return err; } @@ -289,6 +352,43 @@ int32_t CodecHdiEncode::UseBufferOnPort(PortIndex portIndex, int bufferCount, in } return HDF_SUCCESS; } + +int32_t CodecHdiEncode::UseDynaBuffer(int bufferCount, int bufferSize) +{ + if (bufferCount <= 0 || bufferSize <= 0) { + return HDF_ERR_INVALID_PARAM; + } + + for (int i = 0; i < bufferCount; i++) { + auto omxBuffer = std::make_shared(); + omxBuffer->size = sizeof(OmxCodecBuffer); + omxBuffer->version.s.nVersionMajor = 1; + omxBuffer->bufferType = BUFFER_TYPE_DYNAMIC_HANDLE; + omxBuffer->bufferLen = 0; + omxBuffer->buffer = nullptr; + omxBuffer->allocLen = bufferSize; + omxBuffer->fenceFd = -1; + omxBuffer->pts = 0; + omxBuffer->flag = 0; + + auto err = client_->UseBuffer(client_, (uint32_t)PortIndex::PORT_INDEX_INPUT, omxBuffer.get()); + if (err != HDF_SUCCESS) { + HDF_LOGE("%{public}s failed to UseBuffer with PORT_INDEX_INPUT", __func__); + return err; + } + + omxBuffer->bufferLen = 0; + HDF_LOGI("UseBuffer returned bufferID [%{public}d]", omxBuffer->bufferId); + + auto bufferInfo = std::make_shared(); + bufferInfo->omxBuffer = omxBuffer; + bufferInfo->portIndex = PortIndex::PORT_INDEX_INPUT; + omxBuffers_.insert(std::make_pair(omxBuffer->bufferId, bufferInfo)); + unUsedInBuffers_.push_back(omxBuffer->bufferId); + } + return HDF_SUCCESS; +} + void CodecHdiEncode::FreeBuffers() { // send command to loaded state @@ -359,7 +459,6 @@ int CodecHdiEncode::GetFreeBufferId() void CodecHdiEncode::Run() { - HDF_LOGI("...command to OMX_StateExecuting...."); auto err = client_->SendCommand(client_, OMX_CommandStateSet, OMX_StateExecuting, NULL, 0); if (err != HDF_SUCCESS) { HDF_LOGE("%{public}s failed to SendCommand with OMX_CommandStateSet:OMX_StateIdle", __func__); @@ -371,7 +470,6 @@ void CodecHdiEncode::Run() } bool endFlag = false; while (!endFlag) { - HDF_LOGI(" inputput run"); int bufferID = GetFreeBufferId(); if (this->exit_) { break; @@ -385,13 +483,8 @@ void CodecHdiEncode::Run() continue; } auto bufferInfo = iter->second; - // read data from ashmem - void *sharedAddr = (void *)bufferInfo->avSharedPtr->ReadFromAshmem(0, 0); - endFlag = this->ReadOneFrame(fpIn_, (char *)sharedAddr, bufferInfo->omxBuffer->filledLen); - HDF_LOGI("read data size is %{public}d", bufferInfo->omxBuffer->filledLen); - bufferInfo->omxBuffer->offset = 0; - if (endFlag) { - bufferInfo->omxBuffer->flag = OMX_BUFFERFLAG_EOS; + if (!FillCodecBuffer(bufferInfo, endFlag)) { + break; } err = client_->EmptyThisBuffer(client_, bufferInfo->omxBuffer.get()); if (err != HDF_SUCCESS) { @@ -407,6 +500,69 @@ void CodecHdiEncode::Run() return; } +bool CodecHdiEncode::FillCodecBuffer(std::shared_ptr bufferInfo, bool &endFlag) +{ + if (gralloc_ == nullptr) { + HDF_LOGE("%{public}s gralloc_ is null", __func__); + return false; + } + if (useBufferHandle_) { + int bufferHandleId = freeBufferHandles_.front(); + if (bufferHandleId < 0 || bufferHandleId >= BUFFER_COUNT) { + HDF_LOGE("%{public}s bufferHandleId [%{public}d]", __func__, bufferHandleId); + return false; + } + freeBufferHandles_.pop_front(); + bufferInfo->bufferHandleId = bufferHandleId; + BufferHandle *bufferHandle = bufferHandles_[bufferHandleId]; + if (bufferHandle != nullptr) { + gralloc_->Mmap(*bufferHandle); + endFlag = this->ReadOneFrame(fpIn_, (char *)bufferHandle->virAddr, bufferInfo->omxBuffer->filledLen); + bufferInfo->omxBuffer->filledLen = bufferHandle->stride * bufferHandle->height; + gralloc_->Unmap(*bufferHandle); + bufferInfo->omxBuffer->buffer = (uint8_t *)bufferHandle; + bufferInfo->omxBuffer->bufferLen = + sizeof(BufferHandle) + sizeof(int32_t) * (bufferHandle->reserveFds + bufferHandle->reserveInts); + } + } else { + // read data from ashmem + void *sharedAddr = (void *)bufferInfo->avSharedPtr->ReadFromAshmem(0, 0); + endFlag = this->ReadOneFrame(fpIn_, (char *)sharedAddr, bufferInfo->omxBuffer->filledLen); + } + bufferInfo->omxBuffer->offset = 0; + if (endFlag) { + bufferInfo->omxBuffer->flag = OMX_BUFFERFLAG_EOS; + } + + return true; +} + +int32_t CodecHdiEncode::createBufferHandle() +{ + if (gralloc_ == nullptr) { + HDF_LOGE("%{public}s gralloc_ is null", __func__); + return HDF_ERR_INVALID_PARAM; + } + + AllocInfo alloc = {.width = this->stride_, + .height = this->height_, + .usage = HBM_USE_CPU_READ | HBM_USE_CPU_WRITE | HBM_USE_MEM_DMA, + .format = PIXEL_FMT_YCBCR_420_SP}; + + int32_t err = HDF_SUCCESS; + for (size_t i = 0; i < BUFFER_COUNT; i++) { + BufferHandle *bufferHandle = nullptr; + err = gralloc_->AllocMem(alloc, bufferHandle); + if (err != HDF_SUCCESS) { + HDF_LOGE("%{public}s AllocMem fail", __func__); + return err; + } + bufferHandles_.emplace(std::make_pair(i, bufferHandle)); + freeBufferHandles_.push_back(i); + } + return err; +} + int32_t CodecHdiEncode::OnEvent(struct CodecCallbackType *self, enum OMX_EVENTTYPE event, struct EventInfo *info) { HDF_LOGI("OnEvent: pAppData[0x%{public}p], eEvent [%{public}d], " @@ -447,6 +603,11 @@ int32_t CodecHdiEncode::OnEmptyBufferDone(const struct OmxCodecBuffer &buffer) { unique_lock ulk(lockInputBuffers_); unUsedInBuffers_.push_back(buffer.bufferId); + if (useBufferHandle_) { + auto bufferInfo = omxBuffers_[buffer.bufferId]; + freeBufferHandles_.push_back(bufferInfo->bufferHandleId); + } + return HDF_SUCCESS; } @@ -496,7 +657,7 @@ int32_t CodecHdiEncode::ConfigPortDefine() param.format.video.eCompressionFormat, param.format.video.eColorFormat); param.format.video.nFrameWidth = width_; param.format.video.nFrameHeight = height_; - param.format.video.nStride = width_; + param.format.video.nStride = stride_; param.format.video.nSliceHeight = height_; param.format.video.eColorFormat = AV_COLOR_FORMAT; err = client_->SetParameter(client_, OMX_IndexParamPortDefinition, (int8_t *)¶m, sizeof(param)); @@ -518,7 +679,7 @@ int32_t CodecHdiEncode::ConfigPortDefine() param.format.video.eCompressionFormat, param.format.video.eColorFormat); param.format.video.nFrameWidth = width_; param.format.video.nFrameHeight = height_; - param.format.video.nStride = width_; + param.format.video.nStride = stride_; param.format.video.nSliceHeight = height_; err = client_->SetParameter(client_, OMX_IndexParamPortDefinition, (int8_t *)¶m, sizeof(param)); if (err != HDF_SUCCESS) { @@ -574,19 +735,17 @@ int32_t CodecHdiEncode::ConfigBitMode() int main(int argc, char *argv[]) { - if (argc < PARAM_LEN) { - HDF_LOGE("usage AVC width heigh filename"); + CommandOpt opt; + CommandParse parse; + if (!parse.Parse(argc, argv, opt)) { return 0; } - int width = atoi(argv[2]); - int height = atoi(argv[3]); - string filename = argv[4]; if (g_core == nullptr) { g_core = new CodecHdiEncode(); } - if (!g_core->Init(width, height, filename)) { + if (!g_core->Init(opt)) { delete g_core; g_core = nullptr; return HDF_FAILURE; diff --git a/codec/test/demo/v2.0/src/command_parse.cpp b/codec/test/demo/v2.0/src/command_parse.cpp new file mode 100644 index 0000000000..a8e8b01142 --- /dev/null +++ b/codec/test/demo/v2.0/src/command_parse.cpp @@ -0,0 +1,89 @@ +/* + * Copyright 2022 Shenzhen Kaihong DID Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include "command_parse.h" +#include + +enum class MyOptIndex { + OPT_INDEX_UNKONWN = 0, + OPT_INDEX_BUFFER_HANDLE, + OPT_INDEX_HEVC, + OPT_INDEX_HELP, + OPT_INDEX_HEIGHT = 'h', + OPT_INDEX_INPUT = 'i', + OPT_INDEX_OUTPUT = 'o', + OPT_INDEX_WIDTH = 'w' +}; +bool CommandParse::Parse(int argc, char *argv[], CommandOpt &opt) +{ + int c = 0; + while (1) { + int optionIndex = 0; + static struct option long_options[] = {{"width", required_argument, 0, (int)MyOptIndex::OPT_INDEX_WIDTH}, + {"height", required_argument, 0, (int)MyOptIndex::OPT_INDEX_HEIGHT}, + {"in", required_argument, 0, (int)MyOptIndex::OPT_INDEX_INPUT}, + {"out", required_argument, 0, (int)MyOptIndex::OPT_INDEX_OUTPUT}, + {"nocopy", no_argument, NULL, (int)MyOptIndex::OPT_INDEX_BUFFER_HANDLE}, + {"HEVC", no_argument, NULL, (int)MyOptIndex::OPT_INDEX_HEVC}, + {"help", no_argument, NULL, (int)MyOptIndex::OPT_INDEX_HELP}, + {0, 0, 0, (int)MyOptIndex::OPT_INDEX_UNKONWN}}; + c = getopt_long(argc, argv, "i:o:w:h:", long_options, &optionIndex); + if (c == -1) { + break; + } + MyOptIndex index = (MyOptIndex)c; + switch (index) { + case MyOptIndex::OPT_INDEX_BUFFER_HANDLE: + opt.useBuffer = true; + break; + case MyOptIndex::OPT_INDEX_HEVC: + opt.codec = codecMime::HEVC; + break; + case MyOptIndex::OPT_INDEX_HELP: + ShowUsage(); + break; + case MyOptIndex::OPT_INDEX_INPUT: + opt.fileInput = optarg; + break; + case MyOptIndex::OPT_INDEX_OUTPUT: + opt.fileOutput = optarg; + break; + case MyOptIndex::OPT_INDEX_WIDTH: + opt.width = atoi(optarg); + break; + case MyOptIndex::OPT_INDEX_HEIGHT: + opt.height = atoi(optarg); + break; + default: + ShowUsage(); + break; + } + } + if (opt.fileInput.empty() || opt.fileOutput.empty() || opt.width == 0 || opt.height == 0) { + return false; + } + return true; +} + +void CommandParse::ShowUsage() +{ + std::cout << "Options:" << std::endl; + std::cout << " -w, --width=width The video width." << std::endl; + std::cout << " -h, --height=height The video height." << std::endl; + std::cout << " -o, --out=FILE The file name for output file." << std::endl; + std::cout << " -i, --in=FILE The file name for input file." << std::endl; + std::cout << " --HEVC HEVC decode or HEVC encode, AVC for default." << std::endl; + std::cout << " --nocopy Support BufferHandle." << std::endl; + std::cout << " --help The help info." << std::endl; +} -- Gitee