fix Dcamera pr29 codex

Signed-off-by: t00605578 <tongyuejiao@huawei.com>
This commit is contained in:
t00605578
2022-04-16 19:02:53 +08:00
parent 35efa3e7f2
commit ca7eea66a6
17 changed files with 432 additions and 310 deletions
@@ -27,6 +27,7 @@ const std::string BASE_64_CHARS = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrs
int32_t GetLocalDeviceNetworkId(std::string& networkId);
int64_t GetNowTimeStampMs();
int64_t GetNowTimeStampUs();
int32_t GetAlignedHeight(int32_t width);
std::string Base64Encode(const unsigned char *toEncode, unsigned int len);
std::string Base64Decode(const std::string& basicString);
bool IsBase64(unsigned char c);
+10
View File
@@ -57,6 +57,16 @@ int64_t GetNowTimeStampUs()
return nowUs.count();
}
int32_t GetAlignedHeight(int32_t width)
{
int32_t alignedBits = 32;
int32_t alignedHeight = width;
if (alignedHeight % alignedBits != 0) {
alignedHeight = ((alignedHeight / alignedBits) + 1) * alignedBits;
}
return alignedHeight;
}
std::string Base64Encode(const unsigned char *toEncode, unsigned int len)
{
std::string ret;
+9 -7
View File
@@ -36,7 +36,8 @@ ohos_shared_library("distributed_camera_data_process") {
"include/eventbus",
"include/pipeline",
"include/utils",
"include/pipeline_node/multimedia_codec",
"include/pipeline_node/multimedia_codec/decoder",
"include/pipeline_node/multimedia_codec/encoder",
"include/pipeline_node/colorspace_conversion",
"include/pipeline_node/fpscontroller",
"${common_path}/include/constants",
@@ -50,20 +51,21 @@ ohos_shared_library("distributed_camera_data_process") {
"src/pipeline/dcamera_pipeline_source.cpp",
"src/pipeline_node/colorspace_conversion/convert_nv12_to_nv21.cpp",
"src/pipeline_node/fpscontroller/fps_controller_process.cpp",
"src/pipeline_node/multimedia_codec/decode_video_callback.cpp",
"src/pipeline_node/multimedia_codec/encode_video_callback.cpp",
"src/pipeline_node/multimedia_codec/decoder/decode_surface_listener.cpp",
"src/pipeline_node/multimedia_codec/decoder/decode_video_callback.cpp",
"src/pipeline_node/multimedia_codec/encoder/encode_video_callback.cpp",
"src/utils/image_common_type.cpp",
]
if ("${product_name}" == "m40") {
sources += [
"src/pipeline_node/multimedia_codec/decode_data_process.cpp",
"src/pipeline_node/multimedia_codec/encode_data_process.cpp",
"src/pipeline_node/multimedia_codec/decoder/decode_data_process.cpp",
"src/pipeline_node/multimedia_codec/encoder/encode_data_process.cpp",
]
} else {
sources += [
"src/pipeline_node/multimedia_codec/decode_data_process_common.cpp",
"src/pipeline_node/multimedia_codec/encode_data_process_common.cpp",
"src/pipeline_node/multimedia_codec/decoder/decode_data_process_common.cpp",
"src/pipeline_node/multimedia_codec/encoder/encode_data_process_common.cpp",
]
}
@@ -43,7 +43,7 @@ private:
float CalculateFrameRate(int64_t nowMs);
bool IsDropFrame(float incomingFps);
bool ReduceFrameRateByUniformStrategy(int32_t incomingFps);
int32_t FpsControllerDone(std::vector<std::shared_ptr<DataBuffer>> outputBuffers);
int32_t FpsControllerDone(std::vector<std::shared_ptr<DataBuffer>>& outputBuffers);
private:
const static uint32_t MAX_TARGET_FRAME_RATE = 30;
@@ -16,31 +16,32 @@
#ifndef OHOS_DECODE_DATA_PROCESS_H
#define OHOS_DECODE_DATA_PROCESS_H
#include "securec.h"
#include <chrono>
#include <cstdint>
#include <vector>
#include <queue>
#include <thread>
#include <chrono>
#include <vector>
#include "surface.h"
#include "media_errors.h"
#include "avcodec_common.h"
#include "format.h"
#include "avsharedmemory.h"
#include "avcodec_video_decoder.h"
#include "avsharedmemory.h"
#include "event.h"
#include "event_bus.h"
#include "event_sender.h"
#include "eventbus_handler.h"
#include "event_registration.h"
#include "eventbus_handler.h"
#include "format.h"
#include "ibuffer_consumer_listener.h"
#include "media_errors.h"
#include "securec.h"
#include "surface.h"
#include "abstract_data_process.h"
#include "data_buffer.h"
#include "dcamera_codec_event.h"
#include "dcamera_pipeline_source.h"
#include "distributed_camera_errno.h"
#include "image_common_type.h"
#include "dcamera_codec_event.h"
#include "abstract_data_process.h"
#include "dcamera_pipeline_source.h"
namespace OHOS {
namespace DistributedHardware {
@@ -78,26 +79,31 @@ private:
int32_t InitDecoder();
int32_t InitDecoderMetadataFormat();
int32_t SetDecoderOutputSurface();
int32_t StopVideoDecoder();
void ReleaseVideoDecoder();
void ReleaseDecoderSurface();
void ReleaseCodecEvent();
int32_t FeedDecoderInputBuffer();
int64_t GetDecoderTimeStamp();
int32_t GetAlignedHeight();
void CopyDecodedImage(const sptr<SurfaceBuffer>& surBuf, int64_t timeStampUs, int32_t alignedWidth,
int32_t alignedHeight);
int32_t CopyYUVPlaneByRow(const ImageUnitInfo& srcImgInfo, const ImageUnitInfo& dstImgInfo);
int32_t CheckCopyImageInfo(const ImageUnitInfo& srcImgInfo, const ImageUnitInfo& dstImgInfo);
bool IsCorrectImageUnitInfo(const ImageUnitInfo& imgInfo);
void PostOutputDataBuffers(std::shared_ptr<DataBuffer>& outputBuffer);
int32_t DecodeDone(std::vector<std::shared_ptr<DataBuffer>> outputBuffers);
int32_t DecodeDone(std::vector<std::shared_ptr<DataBuffer>>& outputBuffers);
private:
const static int32_t VIDEO_DECODER_QUEUE_MAX = 1000;
const static int32_t MAX_YUV420_BUFFER_SIZE = 1920 * 1080 * 3 / 2 * 2;
const static int32_t MAX_RGB32_BUFFER_SIZE = 1920 * 1080 * 4 * 2;
const static uint32_t MAX_FRAME_RATE = 30;
const static uint32_t MIN_VIDEO_WIDTH = 320;
const static uint32_t MIN_VIDEO_HEIGHT = 240;
const static uint32_t MAX_VIDEO_WIDTH = 1920;
const static uint32_t MAX_VIDEO_HEIGHT = 1080;
const static int32_t FIRST_FRAME_INPUT_NUM = 2;
const static int32_t RGB32_MEMORY_COEFFICIENT = 4;
std::mutex mtxDecoderState_;
std::mutex mtxHoldCount_;
@@ -126,21 +132,6 @@ private:
std::queue<std::shared_ptr<DataBuffer>> inputBuffersQueue_;
std::queue<uint32_t> availableInputIndexsQueue_;
};
class DecodeSurfaceListener : public IBufferConsumerListener {
public:
DecodeSurfaceListener(sptr<Surface> surface, std::weak_ptr<DecodeDataProcess> decodeVideoNode)
: surface_(surface), decodeVideoNode_(decodeVideoNode) {}
~DecodeSurfaceListener();
void OnBufferAvailable() override;
void SetSurface(const sptr<Surface>& surface);
void SetDecodeVideoNode(const std::weak_ptr<DecodeDataProcess>& decodeVideoNode);
private:
sptr<Surface> surface_;
std::weak_ptr<DecodeDataProcess> decodeVideoNode_;
};
} // namespace DistributedHardware
} // namespace OHOS
#endif // OHOS_DECODE_DATA_PROCESS_H
@@ -0,0 +1,46 @@
/*
* Copyright (c) 2021 Huawei Device 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 OHOS_DECODE_SURFACE_LISTENER_H
#define OHOS_DECODE_SURFACE_LISTENER_H
#include "surface.h"
#include "ibuffer_consumer_listener.h"
#include "decode_data_process.h"
namespace OHOS {
namespace DistributedHardware {
class DecodeDataProcess;
class DecodeSurfaceListener : public IBufferConsumerListener {
public:
DecodeSurfaceListener(sptr<Surface> surface, std::weak_ptr<DecodeDataProcess> decodeVideoNode)
: surface_(surface), decodeVideoNode_(decodeVideoNode) {}
~DecodeSurfaceListener();
void OnBufferAvailable() override;
void SetSurface(const sptr<Surface>& surface);
void SetDecodeVideoNode(const std::weak_ptr<DecodeDataProcess>& decodeVideoNode);
sptr<Surface> GetSurface() const;
std::shared_ptr<DecodeDataProcess> GetDecodeVideoNode() const;
private:
sptr<Surface> surface_;
std::weak_ptr<DecodeDataProcess> decodeVideoNode_;
};
} // namespace DistributedHardware
} // namespace OHOS
#endif // OHOS_DECODE_SURFACE_LISTENER_H
@@ -16,23 +16,23 @@
#ifndef OHOS_ENCODE_DATA_PROCESS_H
#define OHOS_ENCODE_DATA_PROCESS_H
#include "securec.h"
#include <cstdint>
#include <vector>
#include <queue>
#include <vector>
#include "surface.h"
#include "media_errors.h"
#include "avcodec_common.h"
#include "format.h"
#include "avsharedmemory.h"
#include "avcodec_video_encoder.h"
#include "avsharedmemory.h"
#include "format.h"
#include "media_errors.h"
#include "securec.h"
#include "surface.h"
#include "abstract_data_process.h"
#include "data_buffer.h"
#include "dcamera_pipeline_sink.h"
#include "distributed_camera_errno.h"
#include "image_common_type.h"
#include "abstract_data_process.h"
#include "dcamera_pipeline_sink.h"
namespace OHOS {
namespace DistributedHardware {
@@ -63,15 +63,18 @@ private:
int32_t InitEncoder();
int32_t InitEncoderMetadataFormat();
int32_t InitEncoderBitrateFormat();
int32_t StopVideoEncoder();
void ReleaseVideoEncoder();
int32_t FeedEncoderInputBuffer(std::shared_ptr<DataBuffer>& inputBuffer);
sptr<SurfaceBuffer> GetEncoderInputSurfaceBuffer();
int64_t GetEncoderTimeStamp();
int32_t GetEncoderOutputBuffer(uint32_t index, Media::AVCodecBufferInfo info);
int32_t EncodeDone(std::vector<std::shared_ptr<DataBuffer>> outputBuffers);
int32_t EncodeDone(std::vector<std::shared_ptr<DataBuffer>>& outputBuffers);
private:
const static int32_t ENCODER_STRIDE_ALIGNMENT = 8;
const static int64_t NORM_YUV420_BUFFER_SIZE = 1920 * 1080 * 3 / 2;
const static int32_t NORM_RGB32_BUFFER_SIZE = 1920 * 1080 * 4;
const static uint32_t MAX_FRAME_RATE = 30;
const static uint32_t MIN_VIDEO_WIDTH = 320;
const static uint32_t MIN_VIDEO_HEIGHT = 240;
@@ -303,7 +303,7 @@ bool FpsControllerProcess::ReduceFrameRateByUniformStrategy(int32_t incomingFrmR
return isDrop;
}
int32_t FpsControllerProcess::FpsControllerDone(std::vector<std::shared_ptr<DataBuffer>> outputBuffers)
int32_t FpsControllerProcess::FpsControllerDone(std::vector<std::shared_ptr<DataBuffer>>& outputBuffers)
{
if (outputBuffers.empty()) {
DHLOGE("The received data buffers is empty.");
@@ -20,6 +20,7 @@
#include "convert_nv12_to_nv21.h"
#include "dcamera_utils_tools.h"
#include "decode_surface_listener.h"
#include "decode_video_callback.h"
namespace OHOS {
@@ -57,21 +58,11 @@ int32_t DecodeDataProcess::InitNode()
ReleaseProcessNode();
return err;
}
alignedHeight_ = GetAlignedHeight();
alignedHeight_ = GetAlignedHeight(static_cast<int32_t>(sourceConfig_.GetHeight()));
isDecoderProcess_ = true;
return DCAMERA_OK;
}
int32_t DecodeDataProcess::GetAlignedHeight()
{
int32_t alignedBits = 32;
int32_t alignedHeight = static_cast<int32_t>(sourceConfig_.GetHeight());
if (alignedHeight % alignedBits != 0) {
alignedHeight = ((alignedHeight / alignedBits) + 1) * alignedBits;
}
return alignedHeight;
}
bool DecodeDataProcess::IsInDecoderRange(const VideoConfigParams& curConfig)
{
return (curConfig.GetWidth() >= MIN_VIDEO_WIDTH || curConfig.GetWidth() <= MAX_VIDEO_WIDTH ||
@@ -158,8 +149,8 @@ int32_t DecodeDataProcess::InitDecoderMetadataFormat()
}
metadataFormat_.PutIntValue("pixel_format", Media::VideoPixelFormat::NV12);
metadataFormat_.PutIntValue("max_input_size", MAX_YUV420_BUFFER_SIZE);
metadataFormat_.PutIntValue("width", (int32_t)sourceConfig_.GetWidth());
metadataFormat_.PutIntValue("height", (int32_t)sourceConfig_.GetHeight());
metadataFormat_.PutIntValue("width", static_cast<int32_t>(sourceConfig_.GetWidth()));
metadataFormat_.PutIntValue("height", static_cast<int32_t>(sourceConfig_.GetHeight()));
metadataFormat_.PutIntValue("frame_rate", MAX_FRAME_RATE);
return DCAMERA_OK;
}
@@ -206,6 +197,82 @@ int32_t DecodeDataProcess::SetDecoderOutputSurface()
return DCAMERA_OK;
}
int32_t DecodeDataProcess::StopVideoDecoder()
{
if (videoDecoder_ == nullptr) {
DHLOGE("The video decoder does not exist before StopVideoDecoder.");
return DCAMERA_BAD_VALUE;
}
bool isSuccess = true;
int32_t ret = videoDecoder_->Flush();
if (ret != Media::MediaServiceErrCode::MSERR_OK) {
DHLOGE("VideoDecoder flush failed. Error type: %d.", ret);
isSuccess = isSuccess && false;
}
ret = videoDecoder_->Stop();
if (ret != Media::MediaServiceErrCode::MSERR_OK) {
DHLOGE("VideoDecoder stop failed. Error type: %d.", ret);
isSuccess = isSuccess && false;
}
if (!isSuccess) {
return DCAMERA_BAD_OPERATE;
}
return DCAMERA_OK;
}
void DecodeDataProcess::ReleaseVideoDecoder()
{
std::lock_guard<std::mutex> lck(mtxDecoderState_);
DHLOGD("Start release videoDecoder.");
if (videoDecoder_ == nullptr) {
DHLOGE("The video decoder does not exist before ReleaseVideoDecoder.");
decodeVideoCallback_ = nullptr;
return;
}
int32_t ret = StopVideoDecoder();
if (ret != DCAMERA_OK) {
DHLOGE("StopVideoDecoder failed.");
}
ret = videoDecoder_->Release();
if (ret != Media::MediaServiceErrCode::MSERR_OK) {
DHLOGE("VideoDecoder release failed. Error type: %d.", ret);
}
videoDecoder_ = nullptr;
decodeVideoCallback_ = nullptr;
}
void DecodeDataProcess::ReleaseDecoderSurface()
{
if (decodeConsumerSurface_ == nullptr) {
decodeProducerSurface_ = nullptr;
DHLOGE("The decode consumer surface does not exist before UnregisterConsumerListener.");
return;
}
int32_t ret = decodeConsumerSurface_->UnregisterConsumerListener();
if (ret != SURFACE_ERROR_OK) {
DHLOGE("Unregister consumer listener failed. Error type: %d.", ret);
}
decodeConsumerSurface_ = nullptr;
decodeProducerSurface_ = nullptr;
}
void DecodeDataProcess::ReleaseCodecEvent()
{
DCameraCodecEvent codecEvent(*this, std::make_shared<CodecPacket>());
if (eventBusDecode_ != nullptr) {
eventBusDecode_->RemoveHandler<DCameraCodecEvent>(codecEvent.GetType(), eventBusRegHandleDecode_);
eventBusRegHandleDecode_ = nullptr;
eventBusDecode_ = nullptr;
}
if (eventBusPipeline_ != nullptr) {
eventBusPipeline_->RemoveHandler<DCameraCodecEvent>(codecEvent.GetType(), eventBusRegHandlePipeline2Decode_);
eventBusRegHandlePipeline2Decode_ = nullptr;
eventBusPipeline_ = nullptr;
}
DHLOGD("Release DecodeNode eventBusDecode and eventBusPipeline end.");
}
void DecodeDataProcess::ReleaseProcessNode()
{
DHLOGD("Start release [%d] node : DecodeNode.", nodeRank_);
@@ -213,35 +280,10 @@ void DecodeDataProcess::ReleaseProcessNode()
if (nextDataProcess_ != nullptr) {
nextDataProcess_->ReleaseProcessNode();
}
if (eventBusDecode_ != nullptr && eventBusPipeline_ != nullptr) {
DHLOGD("Start release DecodeNode eventBusDecode_ and eventBusPipeline_.");
DCameraCodecEvent codecEvent(*this, std::make_shared<CodecPacket>());
eventBusDecode_->RemoveHandler<DCameraCodecEvent>(codecEvent.GetType(), eventBusRegHandleDecode_);
eventBusDecode_ = nullptr;
eventBusPipeline_->RemoveHandler<DCameraCodecEvent>(codecEvent.GetType(), eventBusRegHandlePipeline2Decode_);
eventBusPipeline_ = nullptr;
}
{
std::lock_guard<std::mutex> lck(mtxDecoderState_);
if (videoDecoder_ != nullptr) {
DHLOGD("Start release videoDecoder.");
videoDecoder_->Flush();
videoDecoder_->Stop();
videoDecoder_->Release();
videoDecoder_ = nullptr;
decodeVideoCallback_ = nullptr;
}
}
if (decodeConsumerSurface_ != nullptr) {
int32_t ret = decodeConsumerSurface_->UnregisterConsumerListener();
if (ret != SURFACE_ERROR_OK) {
DHLOGE("Unregister consumer listener failed. Error type: %d.", ret);
}
decodeConsumerSurface_ = nullptr;
decodeProducerSurface_ = nullptr;
decodeSurfaceListener_ = nullptr;
}
ReleaseCodecEvent();
ReleaseVideoDecoder();
ReleaseDecoderSurface();
processType_ = "";
std::queue<std::shared_ptr<DataBuffer>> emptyBuffersQueue;
@@ -555,7 +597,7 @@ void DecodeDataProcess::PostOutputDataBuffers(std::shared_ptr<DataBuffer>& outpu
DHLOGD("Send video decoder output asynchronous DCameraCodecEvents success.");
}
int32_t DecodeDataProcess::DecodeDone(std::vector<std::shared_ptr<DataBuffer>> outputBuffers)
int32_t DecodeDataProcess::DecodeDone(std::vector<std::shared_ptr<DataBuffer>>& outputBuffers)
{
DHLOGD("Decoder Done.");
if (outputBuffers.empty()) {
@@ -681,32 +723,5 @@ VideoConfigParams DecodeDataProcess::GetTargetConfig() const
{
return targetConfig_;
}
void DecodeSurfaceListener::OnBufferAvailable()
{
DHLOGD("DecodeSurfaceListener : OnBufferAvailable.");
std::shared_ptr<DecodeDataProcess> targetDecoderNode = decodeVideoNode_.lock();
if (targetDecoderNode == nullptr) {
DHLOGE("decodeVideoNode_ is nullptr.");
return;
}
targetDecoderNode->GetDecoderOutputBuffer(surface_);
}
void DecodeSurfaceListener::SetSurface(const sptr<Surface>& surface)
{
surface_ = surface;
}
void DecodeSurfaceListener::SetDecodeVideoNode(const std::weak_ptr<DecodeDataProcess>& decodeVideoNode)
{
decodeVideoNode_ = decodeVideoNode;
}
DecodeSurfaceListener::~DecodeSurfaceListener()
{
DHLOGD("DecodeSurfaceListener : ~DecodeSurfaceListener.");
surface_ = nullptr;
}
} // namespace DistributedHardware
} // namespace OHOS
@@ -20,6 +20,7 @@
#include "convert_nv12_to_nv21.h"
#include "dcamera_utils_tools.h"
#include "decode_surface_listener.h"
#include "decode_video_callback.h"
namespace OHOS {
@@ -57,21 +58,11 @@ int32_t DecodeDataProcess::InitNode()
ReleaseProcessNode();
return err;
}
alignedHeight_ = GetAlignedHeight();
alignedHeight_ = GetAlignedHeight(static_cast<int32_t>(sourceConfig_.GetHeight()));
isDecoderProcess_ = true;
return DCAMERA_OK;
}
int32_t DecodeDataProcess::GetAlignedHeight()
{
int32_t alignedBits = 32;
int32_t alignedHeight = static_cast<int32_t>(sourceConfig_.GetHeight());
if (alignedHeight % alignedBits != 0) {
alignedHeight = ((alignedHeight / alignedBits) + 1) * alignedBits;
}
return alignedHeight;
}
bool DecodeDataProcess::IsInDecoderRange(const VideoConfigParams& curConfig)
{
return (curConfig.GetWidth() >= MIN_VIDEO_WIDTH || curConfig.GetWidth() <= MAX_VIDEO_WIDTH ||
@@ -145,13 +136,11 @@ int32_t DecodeDataProcess::InitDecoderMetadataFormat()
DHLOGD("Common Init video decoder metadata format.");
processType_ = "video/mp4v-es";
metadataFormat_.PutStringValue("codec_mime", processType_);
int32_t width = (int32_t)sourceConfig_.GetWidth();
int32_t height = (int32_t)sourceConfig_.GetHeight();
metadataFormat_.PutIntValue("pixel_format", Media::VideoPixelFormat::RGBA);
metadataFormat_.PutIntValue("max_input_size", width * height * 4 * 2);
metadataFormat_.PutIntValue("width", width);
metadataFormat_.PutIntValue("height", height);
metadataFormat_.PutIntValue("max_input_size", MAX_RGB32_BUFFER_SIZE);
metadataFormat_.PutIntValue("width", static_cast<int32_t>(sourceConfig_.GetWidth()));
metadataFormat_.PutIntValue("height", static_cast<int32_t>(sourceConfig_.GetHeight()));
metadataFormat_.PutIntValue("frame_rate", MAX_FRAME_RATE);
return DCAMERA_OK;
}
@@ -198,6 +187,82 @@ int32_t DecodeDataProcess::SetDecoderOutputSurface()
return DCAMERA_OK;
}
int32_t DecodeDataProcess::StopVideoDecoder()
{
if (videoDecoder_ == nullptr) {
DHLOGE("The video decoder does not exist before StopVideoDecoder.");
return DCAMERA_BAD_VALUE;
}
bool isSuccess = true;
int32_t ret = videoDecoder_->Flush();
if (ret != Media::MediaServiceErrCode::MSERR_OK) {
DHLOGE("VideoDecoder flush failed. Error type: %d.", ret);
isSuccess = isSuccess && false;
}
ret = videoDecoder_->Stop();
if (ret != Media::MediaServiceErrCode::MSERR_OK) {
DHLOGE("VideoDecoder stop failed. Error type: %d.", ret);
isSuccess = isSuccess && false;
}
if (!isSuccess) {
return DCAMERA_BAD_OPERATE;
}
return DCAMERA_OK;
}
void DecodeDataProcess::ReleaseVideoDecoder()
{
std::lock_guard<std::mutex> lck(mtxDecoderState_);
DHLOGD("Start release videoDecoder.");
if (videoDecoder_ == nullptr) {
DHLOGE("The video decoder does not exist before ReleaseVideoDecoder.");
decodeVideoCallback_ = nullptr;
return;
}
int32_t ret = StopVideoDecoder();
if (ret != DCAMERA_OK) {
DHLOGE("StopVideoDecoder failed.");
}
ret = videoDecoder_->Release();
if (ret != Media::MediaServiceErrCode::MSERR_OK) {
DHLOGE("VideoDecoder release failed. Error type: %d.", ret);
}
videoDecoder_ = nullptr;
decodeVideoCallback_ = nullptr;
}
void DecodeDataProcess::ReleaseDecoderSurface()
{
if (decodeConsumerSurface_ == nullptr) {
decodeProducerSurface_ = nullptr;
DHLOGE("The decode consumer surface does not exist before UnregisterConsumerListener.");
return;
}
int32_t ret = decodeConsumerSurface_->UnregisterConsumerListener();
if (ret != SURFACE_ERROR_OK) {
DHLOGE("Unregister consumer listener failed. Error type: %d.", ret);
}
decodeConsumerSurface_ = nullptr;
decodeProducerSurface_ = nullptr;
}
void DecodeDataProcess::ReleaseCodecEvent()
{
DCameraCodecEvent codecEvent(*this, std::make_shared<CodecPacket>());
if (eventBusDecode_ != nullptr) {
eventBusDecode_->RemoveHandler<DCameraCodecEvent>(codecEvent.GetType(), eventBusRegHandleDecode_);
eventBusRegHandleDecode_ = nullptr;
eventBusDecode_ = nullptr;
}
if (eventBusPipeline_ != nullptr) {
eventBusPipeline_->RemoveHandler<DCameraCodecEvent>(codecEvent.GetType(), eventBusRegHandlePipeline2Decode_);
eventBusRegHandlePipeline2Decode_ = nullptr;
eventBusPipeline_ = nullptr;
}
DHLOGD("Release DecodeNode eventBusDecode and eventBusPipeline end.");
}
void DecodeDataProcess::ReleaseProcessNode()
{
DHLOGD("Start release [%d] node : DecodeNode.", nodeRank_);
@@ -205,35 +270,10 @@ void DecodeDataProcess::ReleaseProcessNode()
if (nextDataProcess_ != nullptr) {
nextDataProcess_->ReleaseProcessNode();
}
if (eventBusDecode_ != nullptr && eventBusPipeline_ != nullptr) {
DHLOGD("Start release DecodeNode eventBusDecode_ and eventBusPipeline_.");
DCameraCodecEvent codecEvent(*this, std::make_shared<CodecPacket>());
eventBusDecode_->RemoveHandler<DCameraCodecEvent>(codecEvent.GetType(), eventBusRegHandleDecode_);
eventBusDecode_ = nullptr;
eventBusPipeline_->RemoveHandler<DCameraCodecEvent>(codecEvent.GetType(), eventBusRegHandlePipeline2Decode_);
eventBusPipeline_ = nullptr;
}
{
std::lock_guard<std::mutex> lck(mtxDecoderState_);
if (videoDecoder_ != nullptr) {
DHLOGD("Start release videoDecoder.");
videoDecoder_->Flush();
videoDecoder_->Stop();
videoDecoder_->Release();
videoDecoder_ = nullptr;
decodeVideoCallback_ = nullptr;
}
}
if (decodeConsumerSurface_ != nullptr) {
int32_t ret = decodeConsumerSurface_->UnregisterConsumerListener();
if (ret != SURFACE_ERROR_OK) {
DHLOGE("Unregister consumer listener failed. Error type: %d.", ret);
}
decodeConsumerSurface_ = nullptr;
decodeProducerSurface_ = nullptr;
decodeSurfaceListener_ = nullptr;
}
ReleaseCodecEvent();
ReleaseVideoDecoder();
ReleaseDecoderSurface();
processType_ = "";
std::queue<std::shared_ptr<DataBuffer>> emptyBuffersQueue;
@@ -268,8 +308,7 @@ int32_t DecodeDataProcess::ProcessData(std::vector<std::shared_ptr<DataBuffer>>&
DHLOGE("video decoder input buffers queue over flow.");
return DCAMERA_INDEX_OVERFLOW;
}
int32_t bufferSize = 1920 * 1808 * 4 * 2;
if (inputBuffers[0]->Size() > bufferSize) {
if (inputBuffers[0]->Size() > MAX_RGB32_BUFFER_SIZE) {
DHLOGE("DecodeNode input buffer size %d error.", inputBuffers[0]->Size());
return DCAMERA_MEMORY_OPT_ERROR;
}
@@ -405,7 +444,8 @@ void DecodeDataProcess::CopyDecodedImage(const sptr<SurfaceBuffer>& surBuf, int6
DHLOGE("surface buffer is null!");
return;
}
size_t validDecodedImageSize = static_cast<size_t>(sourceConfig_.GetWidth() * sourceConfig_.GetHeight() * 4);
size_t validDecodedImageSize = static_cast<size_t>(sourceConfig_.GetWidth() * sourceConfig_.GetHeight() *
RGB32_MEMORY_COEFFICIENT);
size_t surfaceBufSize = static_cast<size_t>(surBuf->GetSize());
if (validDecodedImageSize > surfaceBufSize) {
DHLOGE("Buffer size error, validDecodedImageSize %d, surBufSize %d.",
@@ -428,90 +468,6 @@ void DecodeDataProcess::CopyDecodedImage(const sptr<SurfaceBuffer>& surBuf, int6
PostOutputDataBuffers(bufferOutput);
}
int32_t DecodeDataProcess::CopyYUVPlaneByRow(const ImageUnitInfo& srcImgInfo, const ImageUnitInfo& dstImgInfo)
{
int32_t ret = CheckCopyImageInfo(srcImgInfo, dstImgInfo);
if (ret != DCAMERA_OK) {
DHLOGE("Check CopyImageUnitInfo failed.");
return ret;
}
errno_t err = EOK;
int32_t srcDataOffset = 0;
int32_t dstDataOffset = 0;
for (int32_t yh = 0; yh < dstImgInfo.height; yh++) {
err = memcpy_s(dstImgInfo.imgData + dstDataOffset, dstImgInfo.chromaOffset - dstDataOffset,
srcImgInfo.imgData + srcDataOffset, dstImgInfo.width);
if (err != EOK) {
DHLOGE("memcpy_s YPlane in line[%d] failed.", yh);
return DCAMERA_MEMORY_OPT_ERROR;
}
dstDataOffset += dstImgInfo.alignedWidth;
srcDataOffset += srcImgInfo.alignedWidth;
}
DHLOGD("Copy Yplane end, dstDataOffset %d, srcDataOffset %d, validYPlaneSize %d.",
dstDataOffset, srcDataOffset, dstImgInfo.chromaOffset);
int32_t y2UvRatio = 2;
dstDataOffset = dstImgInfo.chromaOffset;
srcDataOffset = srcImgInfo.chromaOffset;
for (int32_t uvh = 0; uvh < dstImgInfo.height / y2UvRatio; uvh++) {
err = memcpy_s(dstImgInfo.imgData + dstDataOffset, dstImgInfo.imgSize - dstDataOffset,
srcImgInfo.imgData + srcDataOffset, dstImgInfo.width);
if (err != EOK) {
DHLOGE("memcpy_s UVPlane in line[%d] failed.", uvh);
return DCAMERA_MEMORY_OPT_ERROR;
}
dstDataOffset += dstImgInfo.alignedWidth;
srcDataOffset += srcImgInfo.alignedWidth;
}
DHLOGD("Copy UVplane end, dstDataOffset %d, srcDataOffset %d.", dstDataOffset, srcDataOffset);
return DCAMERA_OK;
}
int32_t DecodeDataProcess::CheckCopyImageInfo(const ImageUnitInfo& srcImgInfo, const ImageUnitInfo& dstImgInfo)
{
if (srcImgInfo.imgData == nullptr || dstImgInfo.imgData == nullptr) {
DHLOGE("The imgData of srcImgInfo or the imgData of dstImgInfo are null!");
return DCAMERA_BAD_VALUE;
}
if (srcImgInfo.colorFormat != dstImgInfo.colorFormat) {
DHLOGE("CopyInfo error : srcImgInfo colorFormat %d, dstImgInfo colorFormat %d.",
srcImgInfo.colorFormat, dstImgInfo.colorFormat);
return DCAMERA_BAD_VALUE;
}
if (!IsCorrectImageUnitInfo(srcImgInfo)) {
DHLOGE("srcImginfo fail: width %d, height %d, alignedWidth %d, alignedHeight %d, chromaOffset %lld, " +
"imgSize %lld.", srcImgInfo.width, srcImgInfo.height, srcImgInfo.alignedWidth, srcImgInfo.alignedHeight,
srcImgInfo.chromaOffset, srcImgInfo.imgSize);
return DCAMERA_BAD_VALUE;
}
if (!IsCorrectImageUnitInfo(dstImgInfo)) {
DHLOGE("dstImginfo fail: width %d, height %d, alignedWidth %d, alignedHeight %d, chromaOffset %lld, " +
"imgSize %lld.", dstImgInfo.width, dstImgInfo.height, dstImgInfo.alignedWidth, dstImgInfo.alignedHeight,
dstImgInfo.chromaOffset, dstImgInfo.imgSize);
return DCAMERA_BAD_VALUE;
}
if (dstImgInfo.width > srcImgInfo.alignedWidth || dstImgInfo.height > srcImgInfo.alignedHeight) {
DHLOGE("Comparison ImgInfo fail: dstwidth %d, dstheight %d, srcAlignedWidth %d, srcAlignedHeight %d.",
dstImgInfo.width, dstImgInfo.height, srcImgInfo.alignedWidth, srcImgInfo.alignedHeight);
return DCAMERA_BAD_VALUE;
}
return DCAMERA_OK;
}
bool DecodeDataProcess::IsCorrectImageUnitInfo(const ImageUnitInfo& imgInfo)
{
int32_t y2UvRatio = 2;
int32_t bytesPerPixel = 3;
size_t expectedImgSize = static_cast<size_t>(imgInfo.alignedWidth * imgInfo.alignedHeight *
bytesPerPixel / y2UvRatio);
size_t expectedChromaOffset = static_cast<size_t>(imgInfo.alignedWidth * imgInfo.alignedHeight);
return (imgInfo.width <= imgInfo.alignedWidth && imgInfo.height <= imgInfo.alignedHeight &&
imgInfo.imgSize >= expectedImgSize && imgInfo.chromaOffset == expectedChromaOffset);
}
void DecodeDataProcess::PostOutputDataBuffers(std::shared_ptr<DataBuffer>& outputBuffer)
{
if (eventBusDecode_ == nullptr || outputBuffer == nullptr) {
@@ -527,7 +483,7 @@ void DecodeDataProcess::PostOutputDataBuffers(std::shared_ptr<DataBuffer>& outpu
DHLOGD("Send video decoder output asynchronous DCameraCodecEvents success.");
}
int32_t DecodeDataProcess::DecodeDone(std::vector<std::shared_ptr<DataBuffer>> outputBuffers)
int32_t DecodeDataProcess::DecodeDone(std::vector<std::shared_ptr<DataBuffer>>& outputBuffers)
{
DHLOGD("Decoder Done.");
if (outputBuffers.empty()) {
@@ -565,7 +521,8 @@ void DecodeDataProcess::OnEvent(DCameraCodecEvent& ev)
OnError();
return;
}
DecodeDone(receivedCodecPacket->GetDataBuffers());
std::vector<std::shared_ptr<DataBuffer>> rgbDataBuffers = receivedCodecPacket->GetDataBuffers();
DecodeDone(rgbDataBuffers);
break;
}
case VideoCodecAction::ACTION_ONCE_AGAIN:
@@ -644,32 +601,5 @@ VideoConfigParams DecodeDataProcess::GetTargetConfig() const
{
return targetConfig_;
}
void DecodeSurfaceListener::OnBufferAvailable()
{
DHLOGD("DecodeSurfaceListener : OnBufferAvailable.");
std::shared_ptr<DecodeDataProcess> targetDecoderNode = decodeVideoNode_.lock();
if (targetDecoderNode == nullptr) {
DHLOGE("decodeVideoNode_ is nullptr.");
return;
}
targetDecoderNode->GetDecoderOutputBuffer(surface_);
}
void DecodeSurfaceListener::SetSurface(const sptr<Surface>& surface)
{
surface_ = surface;
}
void DecodeSurfaceListener::SetDecodeVideoNode(const std::weak_ptr<DecodeDataProcess>& decodeVideoNode)
{
decodeVideoNode_ = decodeVideoNode;
}
DecodeSurfaceListener::~DecodeSurfaceListener()
{
DHLOGD("DecodeSurfaceListener : ~DecodeSurfaceListener.");
surface_ = nullptr;
}
} // namespace DistributedHardware
} // namespace OHOS
@@ -0,0 +1,63 @@
/*
* Copyright (c) 2021 Huawei Device 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 "decode_surface_listener.h"
#include "distributed_hardware_log.h"
namespace OHOS {
namespace DistributedHardware {
DecodeSurfaceListener::~DecodeSurfaceListener()
{
DHLOGD("DecodeSurfaceListener : ~DecodeSurfaceListener.");
surface_ = nullptr;
}
void DecodeSurfaceListener::OnBufferAvailable()
{
DHLOGD("DecodeSurfaceListener : OnBufferAvailable.");
std::shared_ptr<DecodeDataProcess> targetDecoderNode = decodeVideoNode_.lock();
if (targetDecoderNode == nullptr) {
DHLOGE("decodeVideoNode_ is nullptr.");
return;
}
targetDecoderNode->GetDecoderOutputBuffer(surface_);
}
void DecodeSurfaceListener::SetSurface(const sptr<Surface>& surface)
{
surface_ = surface;
}
void DecodeSurfaceListener::SetDecodeVideoNode(const std::weak_ptr<DecodeDataProcess>& decodeVideoNode)
{
decodeVideoNode_ = decodeVideoNode;
}
sptr<Surface> DecodeSurfaceListener::GetSurface() const
{
return surface_;
}
std::shared_ptr<DecodeDataProcess> DecodeSurfaceListener::GetDecodeVideoNode() const
{
std::shared_ptr<DecodeDataProcess> targetDecoderNode = decodeVideoNode_.lock();
if (targetDecoderNode == nullptr) {
DHLOGE("decodeVideoNode_ is nullptr.");
}
return targetDecoderNode;
}
} // namespace DistributedHardware
} // namespace OHOS
@@ -214,6 +214,49 @@ int32_t EncodeDataProcess::InitEncoderBitrateFormat()
return DCAMERA_OK;
}
int32_t EncodeDataProcess::StopVideoEncoder()
{
if (videoEncoder_ == nullptr) {
DHLOGE("The video encoder does not exist before StopVideoEncoder.");
return DCAMERA_BAD_VALUE;
}
int32_t ret = videoEncoder_->Flush();
if (ret != Media::MediaServiceErrCode::MSERR_OK) {
DHLOGE("VideoEncoder flush failed. Error type: %d.", ret);
return DCAMERA_BAD_OPERATE;
}
ret = videoEncoder_->Stop();
if (ret != Media::MediaServiceErrCode::MSERR_OK) {
DHLOGE("VideoEncoder stop failed. Error type: %d.", ret);
return DCAMERA_BAD_OPERATE;
}
return DCAMERA_OK;
}
void EncodeDataProcess::ReleaseVideoEncoder()
{
std::lock_guard<std::mutex> lck(mtxEncoderState_);
DHLOGD("Start release videoEncoder.");
if (videoEncoder_ == nullptr) {
DHLOGE("The video encoder does not exist before ReleaseVideoEncoder.");
encodeProducerSurface_ = nullptr;
encodeVideoCallback_ = nullptr;
return;
}
int32_t ret = StopVideoEncoder();
if (ret != DCAMERA_OK) {
DHLOGE("StopVideoEncoder failed.");
}
ret = videoEncoder_->Release();
if (ret != Media::MediaServiceErrCode::MSERR_OK) {
DHLOGE("VideoEncoder release failed. Error type: %d.", ret);
}
encodeProducerSurface_ = nullptr;
videoEncoder_ = nullptr;
encodeVideoCallback_ = nullptr;
}
void EncodeDataProcess::ReleaseProcessNode()
{
DHLOGD("Start release [%d] node : EncodeNode.", nodeRank_);
@@ -222,18 +265,7 @@ void EncodeDataProcess::ReleaseProcessNode()
nextDataProcess_->ReleaseProcessNode();
}
{
std::lock_guard<std::mutex> lck(mtxEncoderState_);
if (videoEncoder_ != nullptr) {
DHLOGD("Start release videoEncoder.");
videoEncoder_->Flush();
videoEncoder_->Stop();
videoEncoder_->Release();
encodeProducerSurface_ = nullptr;
videoEncoder_ = nullptr;
encodeVideoCallback_ = nullptr;
}
}
ReleaseVideoEncoder();
waitEncoderOutputCount_ = 0;
lastFeedEncoderInputBufferTimeUs_ = 0;
@@ -400,7 +432,7 @@ int32_t EncodeDataProcess::GetEncoderOutputBuffer(uint32_t index, Media::AVCodec
return EncodeDone(nextInputBuffers);
}
int32_t EncodeDataProcess::EncodeDone(std::vector<std::shared_ptr<DataBuffer>> outputBuffers)
int32_t EncodeDataProcess::EncodeDone(std::vector<std::shared_ptr<DataBuffer>>& outputBuffers)
{
DHLOGD("Encoder done.");
if (outputBuffers.empty()) {
@@ -148,12 +148,10 @@ int32_t EncodeDataProcess::InitEncoderMetadataFormat()
metadataFormat_.PutStringValue("codec_mime", processType_);
metadataFormat_.PutIntValue("codec_profile", Media::MPEG4Profile::MPEG4_PROFILE_ADVANCED_CODING);
int32_t width = (int32_t)sourceConfig_.GetWidth();
int32_t height = (int32_t)sourceConfig_.GetHeight();
metadataFormat_.PutIntValue("pixel_format", Media::VideoPixelFormat::RGBA);
metadataFormat_.PutLongValue("max_input_size", width * height * 4);
metadataFormat_.PutIntValue("width", width);
metadataFormat_.PutIntValue("height", height);
metadataFormat_.PutLongValue("max_input_size", NORM_RGB32_BUFFER_SIZE);
metadataFormat_.PutIntValue("width", static_cast<int32_t>(sourceConfig_.GetWidth()));
metadataFormat_.PutIntValue("height", static_cast<int32_t>(sourceConfig_.GetHeight()));
metadataFormat_.PutIntValue("frame_rate", MAX_FRAME_RATE);
return DCAMERA_OK;
}
@@ -192,6 +190,49 @@ int32_t EncodeDataProcess::InitEncoderBitrateFormat()
return DCAMERA_OK;
}
int32_t EncodeDataProcess::StopVideoEncoder()
{
if (videoEncoder_ == nullptr) {
DHLOGE("The video encoder does not exist before StopVideoEncoder.");
return DCAMERA_BAD_VALUE;
}
int32_t ret = videoEncoder_->Flush();
if (ret != Media::MediaServiceErrCode::MSERR_OK) {
DHLOGE("VideoEncoder flush failed. Error type: %d.", ret);
return DCAMERA_BAD_OPERATE;
}
ret = videoEncoder_->Stop();
if (ret != Media::MediaServiceErrCode::MSERR_OK) {
DHLOGE("VideoEncoder stop failed. Error type: %d.", ret);
return DCAMERA_BAD_OPERATE;
}
return DCAMERA_OK;
}
void EncodeDataProcess::ReleaseVideoEncoder()
{
std::lock_guard<std::mutex> lck(mtxEncoderState_);
DHLOGD("Start release videoEncoder.");
if (videoEncoder_ == nullptr) {
DHLOGE("The video encoder does not exist before ReleaseVideoEncoder.");
encodeProducerSurface_ = nullptr;
encodeVideoCallback_ = nullptr;
return;
}
int32_t ret = StopVideoEncoder();
if (ret != DCAMERA_OK) {
DHLOGE("StopVideoEncoder failed.");
}
ret = videoEncoder_->Release();
if (ret != Media::MediaServiceErrCode::MSERR_OK) {
DHLOGE("VideoEncoder release failed. Error type: %d.", ret);
}
encodeProducerSurface_ = nullptr;
videoEncoder_ = nullptr;
encodeVideoCallback_ = nullptr;
}
void EncodeDataProcess::ReleaseProcessNode()
{
DHLOGD("Start release [%d] node : EncodeNode.", nodeRank_);
@@ -200,18 +241,7 @@ void EncodeDataProcess::ReleaseProcessNode()
nextDataProcess_->ReleaseProcessNode();
}
{
std::lock_guard<std::mutex> lck(mtxEncoderState_);
if (videoEncoder_ != nullptr) {
DHLOGD("Start release videoEncoder.");
videoEncoder_->Flush();
videoEncoder_->Stop();
videoEncoder_->Release();
encodeProducerSurface_ = nullptr;
videoEncoder_ = nullptr;
encodeVideoCallback_ = nullptr;
}
}
ReleaseVideoEncoder();
waitEncoderOutputCount_ = 0;
lastFeedEncoderInputBufferTimeUs_ = 0;
@@ -237,8 +267,8 @@ int32_t EncodeDataProcess::ProcessData(std::vector<std::shared_ptr<DataBuffer>>&
DHLOGE("The video encoder does not exist before encoding data.");
return DCAMERA_INIT_ERR;
}
size_t bufferSize = 1920 * 1808 * 4;
if (inputBuffers[0]->Size() > bufferSize) {
if (inputBuffers[0]->Size() > NORM_RGB32_BUFFER_SIZE) {
DHLOGE("EncodeNode input buffer size %d error.", inputBuffers[0]->Size());
return DCAMERA_MEMORY_OPT_ERROR;
}
@@ -291,7 +321,6 @@ int32_t EncodeDataProcess::FeedEncoderInputBuffer(std::shared_ptr<DataBuffer>& i
}
inputTimeStampUs_ = GetEncoderTimeStamp();
DHLOGD("Encoder input buffer size %d, timeStamp %lld.", inputBuffer->Size(), (long long)inputTimeStampUs_);
surfacebuffer->GetExtraData()->ExtraSet("timeStamp", inputTimeStampUs_);
BufferFlushConfig flushConfig = { {0, 0, sourceConfig_.GetWidth(), sourceConfig_.GetHeight()}, 0};
SurfaceError ret = encodeProducerSurface_->FlushBuffer(surfacebuffer, -1, flushConfig);
@@ -361,7 +390,7 @@ int32_t EncodeDataProcess::GetEncoderOutputBuffer(uint32_t index, Media::AVCodec
return EncodeDone(nextInputBuffers);
}
int32_t EncodeDataProcess::EncodeDone(std::vector<std::shared_ptr<DataBuffer>> outputBuffers)
int32_t EncodeDataProcess::EncodeDone(std::vector<std::shared_ptr<DataBuffer>>& outputBuffers)
{
DHLOGD("Encoder done.");
if (outputBuffers.empty()) {