OpenHarmony camera người dùng thái điều khiển dàn giáo Nguyên sangTinh hoa

Nhuận cùng phần mềm HiHope
Tuyên bố với 2022-4-18 21:30
Xem
2 cất chứa

Tác giả: Nhuận cùng phần mềm quách tân tinh
Camera làm smart phone thượng ít có trưởng thành không gian không tồi, có thể làm ra sai biệt hóa công năng, mỗi năm đều có thể trở thành các đại Android di động nhà máy hiệu buôn tranh nhau tuyên truyền lượng điểm. Mọi người đều biết Android chọn dùng Linux làm này nội hạch, mà Linux chọn dùng khai nguyên hiệp nghị có lây bệnh tính [^1], dẫn tới Android HAL[^2] trở thành di động nhà máy hiệu buôn nhóm cạnh tranh quan trọng chiến trường. Theo OpenHarmony 3.1[^3] tuyên bố, camera mô khối cũng dần dần hoàn thiện lên, trước mắt cung cấp cơ sở xem trước cùng chụp ảnh năng lực. OpenHarmony trung, camera người dùng thái điều khiển dàn giáo gánh vác cùng Android Camera HAL giống nhau nhân vật, này bộ phận ở vào OpenHarmony HDF[^4] trung, đối thượng thực hiện camera HDI[^5] tiếp lời, đối hạ thực hiện camera Pipeline mô hình, quản lý camera các phần cứng thiết bị.
OpenHarmony相机用户态驱动框架-鸿蒙开发者社区
Camera người dùng thái điều khiển dàn giáo ( hạ đồ CameraHost bộ phận ) tổng thể có thể chia làm ba tầng, HDI thực hiện tầng, thực hiện camera tiêu chuẩn nam hướng tiếp lời; dàn giáo tầng, nối tiếp HDI thực hiện tầng khống chế, lưu chuyển phát, thực hiện số liệu thông lộ dựng, quản lý camera các phần cứng thiết bị chờ công năng; thích xứng tầng, che chắn tầng dưới chót chip cùng OS sai biệt, duy trì nhiều ngôi cao thích xứng.
OpenHarmony相机用户态驱动框架-鸿蒙开发者社区
• mô khối giới thiệu

HDI Implementation: Đối thượng thực hiện HDI tiếp lời, xuống phía dưới thuyên chuyển dàn giáo tầng tiếp lời, hoàn thành HDI tiếp lời nhiệm vụ chuyển phát.

Buffer Manager: Che chắn bất đồng nội tồn quản lý sai biệt, vì tử hệ thống cung cấp thống nhất thao tác tiếp lời, đồng thời cung cấp buffer luân chuyển công năng.

Pipeline Core: Phân tích HCS phối trí hoàn thành pipeline dựng, điều hành pipeline trung các node hoàn thành lưu xử lý

Device Manager: Thông qua thuyên chuyển tầng dưới chót phần cứng thích xứng tầng tiếp lời, thực hiện tuần tra khống chế tầng dưới chót thiết bị, cái cử nghe lén tầng dưới chót thiết bị công năng

Platform Adaption: Che chắn phần cứng sai biệt, vì Device Manager cung cấp thống nhất thao tác tầng dưới chót phần cứng năng lực
• mục lục kết cấu

Shell
drivers/peripheral/camera

|-- README_zh.md

|-- bundle.json

|-- figures

| `-- logic-view-of-modules-related-to-this-repository_zh.png

|-- hal

| |-- BUILD.gn

| |-- adapter

| |-- buffer_manager

| |-- camera.gni

| |-- device_manager

| |-- hdi_impl

| |-- include

| |-- init

| |-- pipeline_core

| |-- test

| `-- utils

|-- hal_c

| |-- BUILD.gn

| |-- camera.gni

| |-- hdi_cif

| `-- include

`-- interfaces

|-- hdi_ipc

|-- hdi_passthrough

`-- include

•HDI Implementation trung xem trước lưu trình

Kế tiếp chúng ta thông qua đã tuyên bố OpenHarmony 3.1 khai nguyên số hiệu, đến xem xem trước là như thế nào hoàn thành đi

drivers/peripheral/camera/hal/test/v4l2/src /preview_test.cpp gửi nhằm vào v4l2 xem trước thí nghiệm số hiệu, nhập khẩu như sau

C++
TEST_F(UtestPreviewTest, camera_preview_0001)

{

std::cout << "==========[test log] Preview stream, expected success." << std::endl;

// Get the stream manager

display_->AchieveStreamOperator(); // thu hoạch stream operator

// start stream

display_->intents = {Camera::PREVIEW}; // xem trước lưu

display_->StartStream(display_->intents); // khởi lưu

// Get preview

display_->StartCapture(display_->streamId_preview, display_->captureId_preview, false, true);

// release stream

display_->captureIds = {display_->captureId_preview};

display_->streamIds = {display_->streamId_preview};

display_->StopStream(display_->captureIds, display_->streamIds);

}

Trước thu hoạch stream operator ví dụ thực tế

C++
void testdisplay::achievestreamoperator()

{

// create and get streamoperator information

std::shared_ptr<ohos::camera::istreamoperatorcallback> streamoperatorcallback =

std::make_shared<ohos::camera::istreamoperatorcallback>();

rc = cameradevice->getstreamoperator(streamoperatorcallback, streamoperator);

//........

}

Thông qua trước văn streamOperator sáng tạo lưu

C++
void TestDisplay::StartStream(std::vector<OHOS::Camera::StreamIntent> intents)

{

//..............................

for (auto& intent: intents) {

if (intent == 0) {

std::shared_ptr<IBufferProducer> producer = IBufferProducer::CreateBufferQueue();

producer->SetQueueSize(8); // sáng tạo buffer sinh sản đoan, cũng cùng tương ứng chảy vào hành trói định

auto callback = [this](std::shared_ptr<SurfaceBuffer> Prebuffer) {

BufferCallback(Prebuffer, preview_mode);

return;

};

producer->SetCallback(callback);

streamInfo->streamId_ = streamId_preview;

streamInfo->width_ = 640; // 640:picture width

streamInfo->height_ = 480; // 480:picture height

streamInfo->format_ = CAMERA_FORMAT_YUYV_422_PKG;

streamInfo->datasapce_ = 8; // 8:picture datasapce

streamInfo->intent_ = intent;

streamInfo->tunneledMode_ = 5; // 5:tunnel mode

streamInfo->bufferQueue_ = producer;

streamInfos.push_back(streamInfo);

} else if (intent == 1) {

//.......................

}

rc = streamOperator->CreateStreams(streamInfos); // sáng tạo lưu

//................................

rc = streamOperator->CommitStreams(Camera::NORMAL, ability); // đệ trình lưu

//.................................

}

Phía dưới chúng ta chính thức tiến vào đến hal nguyên số hiệu nhìn xem là như thế nào sáng tạo lưu đi

C++
CamRetCode StreamOperator::CreateStreams(const std::vector<std::shared_ptr<StreamInfo>>& streamInfos)

{

//.....

for (auto it: streamInfos) {

//....

std::shared_ptr<IStream> stream = StreamFactory::Instance().CreateShared(

IStream::g_availableStreamType[it->intent_], it->streamId_, it->intent_, pipelineCore_, messenger_); // sáng tạo lưu ví dụ thực tế

//...

StreamConfiguration scg;

scg.id = it->streamId_;

scg.type = it->intent_;

scg.width = it->width_;

scg.height = it->height_;

PixelFormat pf = static_cast<PixelFormat>(it->format_);

scg.format = BufferAdapter::PixelFormatToCameraFormat(pf);

scg.dataspace = it->datasapce_;

scg.tunnelMode = it->tunneledMode_;

scg.minFrameDuration = it->minFrameDuration_;

scg.encodeType = it->encodeType_;



RetCode rc = stream->ConfigStream(scg); // căn cứ câu trên lưu tin tức phối trí lưu

//...

if (it->bufferQueue_!= nullptr) { // trói định trước văn sinh sản đoan

auto tunnel = std::make_shared<StreamTunnel>();

CHECK_IF_PTR_NULL_RETURN_VALUE(tunnel, INSUFFICIENT_RESOURCES);

RetCode rc = tunnel->AttachBufferQueue(it->bufferQueue_);

CHECK_IF_NOT_EQUAL_RETURN_VALUE(rc, RC_OK, INVALID_ARGUMENT);

if (stream->AttachStreamTunnel(tunnel)!= RC_OK) {

CAMERA_LOGE( "attach buffer queue to stream [id = %{public}d] failed", it->streamId_);

return INVALID_ARGUMENT;

}

}

{

std::lock_guard<std::mutex> l(streamLock_);

streamMap_[stream->GetStreamId()] = stream; // bảo tồn lưu ví dụ thực tế

}

//...

}

Từ phía trên có thể thấy được, tiêu phí đoan truyền lại tới rồi hal, kia tất nhiên là từ hal từ bufferproducer thu hoạch buffer, cũng kích phát xem trước khởi động lưu trình. Kia nhìn xem AttachStreamTunnel thực hiện đi

C++
RetCode StreamBase::AttachStreamTunnel(std::shared_ptr<StreamTunnel>& tunnel)

{

if (state_ == STREAM_STATE_BUSY || state_ == STREAM_STATE_OFFLINE) {

return RC_ERROR;

}



tunnel_ = tunnel; // trói định sinh sản đoan

CHECK_IF_PTR_NULL_RETURN_VALUE(tunnel_, RC_ERROR);

tunnel_->SetBufferCount(GetBufferCount()); // phối trí luân chuyển buffer cái số

TunnelConfig config = {(uint32_t)streamConfig_.width, (uint32_t)streamConfig_.height,

(uint32_t)streamConfig_.format, streamConfig_.usage};

tunnel_->Config(config);



streamConfig_.tunnelMode = true;

return RC_OK;

}

CreateStream lúc sau đó là CommitStream, nơi này CommitStream làm chút sự tình gì đâu, chúng ta tiếp theo đi xuống xem

C++
CamRetCode StreamOperator::CommitStreams(OperationMode mode,

const std::shared_ptr<CameraStandard::CameraMetadata>& modeSetting)

{

//......

std::vector<StreamConfiguration> configs = {};

{

std::lock_guard<std::mutex> l(streamLock_);

for (auto it: streamMap_) { // thu hoạch lưu phối trí, trước văn CreateStrea khi bảo tồn lưu

configs.emplace_back(it.second->GetStreamAttribute());

}

}

// kiểm tra lưu hay không bị duy trì

DynamicStreamSwitchMode method = streamPipeline_->CheckStreamsSupported(mode, modeSetting, configs);

if (method == DYNAMIC_STREAM_SWITCH_NOT_SUPPORT) {

return INVALID_ARGUMENT;

}

if (method == DYNAMIC_STREAM_SWITCH_NEED_INNER_RESTART) {

std::lock_guard<std::mutex> l(streamLock_);

for (auto it: streamMap_) {

it.second->StopStream();// nếu lưu bị duy trì, nhưng yêu cầu bên trong khởi động lại, nơi này trước đình lưu

}

}

{

std::lock_guard<std::mutex> l(streamLock_);

for (auto it: streamMap_) {

if (it.second->CommitStream()!= RC_OK) { // chân chính CommitStream, phía dưới lại nói tỉ mỉ

CAMERA_LOGE( "commit stream [id = %{public}d] failed.", it.first);

return DEVICE_ERROR;

}

}

}

RetCode rc = streamPipeline_->PreConfig(modeSetting); // đem hình thức truyền vào tiến hành dự phối trí

if (rc!= RC_OK) {

CAMERA_LOGE( "prepare mode settings failed" );

return DEVICE_ERROR;

}

rc = streamPipeline_->CreatePipeline(mode);// sáng tạo pipeline

if (rc!= RC_OK) {

CAMERA_LOGE( "create pipeline failed." );

return INVALID_ARGUMENT;

}



DFX_LOCAL_HITRACE_END;

return NO_ERROR;

}

C++
RetCode StreamBase::CommitStream()

{

//...

hostStreamMgr_ = pipelineCore_->GetHostStreamMgr(); // từ pipelinecore thu hoạch hoststreamanager

CHECK_IF_PTR_NULL_RETURN_VALUE(hostStreamMgr_, RC_ERROR);

//...

info.bufferPoolId_ = poolId_;

info.bufferCount_ = GetBufferCount();

// khởi động lại bufferpool

RetCode rc = bufferPool_->Init(streamConfig_.width, streamConfig_.height, streamConfig_.usage,

streamConfig_.format, GetBufferCount(), CAMERA_BUFFER_SOURCE_TYPE_EXTERNAL);

if (rc!= RC_OK) {

CAMERA_LOGE( "stream [id:%{public}d] initialize buffer pool failed.", streamId_);

return RC_ERROR;

}

}

// stream truyền lại đến pipelinecore cũng tiến hành trói định

RetCode rc = hostStreamMgr_->CreateHostStream(info, [this](std::shared_ptr<IBuffer> buffer) {

HandleResult(buffer);

return;

});

//....

return RC_OK;

}

CreateStream cùng CommitStream sau khi chấm dứt đó là Capture, nơi này bao hàm khởi lưu động tác, mấu chốt thực hiện như sau

C++
CamRetCode StreamOperator::Capture(int captureId, const std::shared_ptr<CaptureInfo>& captureInfo, bool isStreaming)

{

//...

// captureId bắt được thỉnh cầu id; captureInfo xem trước / chụp ảnh / ghi hình tham số; isStreaming liên tục bắt được vẫn là đơn thứ bắt được ( chụp ảnh )

CaptureSetting setting = captureInfo->captureSetting_;

auto request =

std::make_shared<CaptureRequest>(captureId, captureInfo->streamIds_.size(), setting,

captureInfo->enableShutterCallback_, isStreaming);

for (auto id: captureInfo->streamIds_) {

// sáng tạo bắt được thỉnh cầu, cũng truyền lại cấp trước văn sáng tạo lưu

RetCode rc = streamMap_[id]->AddRequest(request);

if (rc!= RC_OK) {

return DEVICE_ERROR;

}

}

//...

}

Từ phía trên số hiệu cũng biết xem trước, chụp ảnh, ghi hình đều là thông qua bắt được thỉnh cầu kích phát, đơn thứ chụp ảnh tắc vì đơn thứ bắt được thỉnh cầu, xem trước cùng ghi hình còn lại là liên tục bắt được thỉnh cầu.

C++
RetCode StreamBase::AddRequest(std::shared_ptr<CaptureRequest>& request)

{

CHECK_IF_PTR_NULL_RETURN_VALUE(request, RC_ERROR);

request->AddOwner(shared_from_this());



request->SetFirstRequest(false);

if (isFirstRequest) {

RetCode rc = StartStream(); // khởi lưu

if (rc!= RC_OK) {

CAMERA_LOGE( "start stream [id:%{public}d] failed", streamId_);

return RC_ERROR;

}

request->SetFirstRequest(true);

isFirstRequest = false;

}



{

std::unique_lock<std::mutex> l(wtLock_);

waitingList_.emplace_back(request); // bắt được thỉnh cầu tăng thêm đến waitingList

cv_.notify_one();

}



return RC_OK;

}

Nhìn xem StreamStream là như thế nào thực hiện đi

C++
RetCode StreamBase::StartStream()

{

//...

RetCode rc = pipeline_->Prepare({streamId_}); // pipeline trước hoàn thành một ít chuẩn bị công tác

//...



state_ = STREAM_STATE_BUSY;

std::string threadName =

g_availableStreamType[static_cast<StreamIntent>(streamType_)] + "#" + std::to_string(streamId_);

handler_ = std::make_unique<std::thread>([this, &threadName] {// sáng tạo luân chuyển tuyến trình

prctl(PR_SET_NAME, threadName.c_str());

while (state_ == STREAM_STATE_BUSY) {

HandleRequest(); // xử lý bắt được thỉnh cầu

}

});

//...

rc = pipeline_->Start({streamId_}); // thông tri pipeline cùng tầng dưới chót phần cứng có thể bắt đầu ra bức

//...

return RC_OK;

}

C++
void StreamBase::HandleRequest()

{

// nếu có bắt được thỉnh cầu hạ phát, tắc rời khỏi chờ đợi trạng thái

if (waitingList_.empty()) {

std::unique_lock<std::mutex> l(wtLock_);

if (waitingList_.empty()) {

cv_.wait(l, [this] { return!(state_ == STREAM_STATE_BUSY && waitingList_.empty()); });

}

}

//...

request = waitingList_.front();

CHECK_IF_PTR_NULL_RETURN_VOID(request);

if (!request->IsContinous()) { // nếu là liên tục bắt được, tắc giữ lại một phần copy ở waitinglist

waitingList_.pop_front();

}

}

// xử lý bắt được thỉnh cầu

request->Process(streamId_);// cuối cùng thuyên chuyển phía dưới Capture tiếp lời



return;

}

C++
RetCode StreamBase::Capture(const std::shared_ptr<CaptureRequest>& request)

{

CHECK_IF_PTR_NULL_RETURN_VALUE(request, RC_ERROR);

CHECK_IF_PTR_NULL_RETURN_VALUE(pipeline_, RC_ERROR);



RetCode rc = RC_ERROR;

if (request->IsFirstOne() &&!request->IsContinous()) {

uint32_t n = GetBufferCount();

for (uint32_t i = 0; i < n; i++) {

DeliverBuffer();// đơn thứ bắt được dùng một lần hạ phát sở hữu buffer

}

} else {

do {

rc = DeliverBuffer();// liên tục bắt được mỗi lần hạ phát một cái buffer

} while (rc!= RC_OK && state_ == STREAM_STATE_BUSY);

}



if (request->NeedCancel()) {// bị hủy bỏ bắt được tắc rời khỏi

CAMERA_LOGE( "StreamBase::Capture stream [id:%{public}d] request->NeedCancel", streamId_);

return RC_OK;

}



rc = pipeline_->Config({streamId_}, request->GetCaptureSetting());// thông tri pipeline phối trí

if (rc!= RC_OK) {

CAMERA_LOGE( "stream [id:%{public}d] config pipeline failed.", streamId_);

return RC_ERROR;

}



rc = pipeline_->Capture({streamId_}, request->GetCaptureId());// nơi này capture chỉ chính là pipeline trung source node bắt đầu hồi buffer



{

std::unique_lock<std::mutex> l(tsLock_);

inTransitList_.emplace_back(request);// xử lý quá bắt được thỉnh cầu gửi ở inTransitList

}



return RC_OK;

}

Đến này khởi lưu lưu trình liền kết thúc, pipeline hồi đi lên bức thông qua OnFrame tiếp lời xử lý

C++
RetCode StreamBase::OnFrame(const std::shared_ptr<CaptureRequest>& request)

{

//...



bool isEnded = false;

if (!request->IsContinous()) {

isEnded = true;

} else if (request->NeedCancel()) {

isEnded = true;

}



{

// inTransitList_ may has multiple copies of continious-capture request, we just need erase one of them.

std::unique_lock<std::mutex> l(tsLock_);

for (auto it = inTransitList_.begin(); it!= inTransitList_.end(); it++) {

if ((*it) == request) {

inTransitList_.erase(it);// đã hồi bức thỉnh cầu, từ inTransitList xóa bỏ

break;

}

}



if (isEnded) {

// if this is the last request of capture, send CaptureEndedMessage.

auto it = std::find(inTransitList_.begin(), inTransitList_.end(), request);

if (it == inTransitList_.end()) {

std::shared_ptr<ICaptureMessage> endMessage =

std::make_shared<CaptureEndedMessage>(streamId_, request->GetCaptureId(), request->GetEndTime(),

request->GetOwnerCount(), tunnel_->GetFrameCount());

CAMERA_LOGV( "end of stream [%d], ready to send end message, capture id = %d",

streamId_, request->GetCaptureId());

messenger_->SendMessage(endMessage);

pipeline_->CancelCapture({streamId_});// nếu lần này bắt được kết thúc, tắc hủy bỏ bắt được

}

}

}
ReceiveBuffer(buffer);// tầng dưới chót phản hồi buffer đưa còn đến sinh sản đoan, cuối cùng số lượng khung hình theo đưa đến tiêu phí đoan

return RC_OK;

}

::: hljs-center

Phụ lục

:::

[^1]: linux cùng Android quan hệ - biết chăng (zhihu)

[^2]: HAL Subsystem | Android Open Source Project (google.cn)

[^3]: zh-cn/release-notes/OpenHarmony-v3.1-release.md · OpenHarmony/docs -Gitee

[^4]: OpenHarmony HDFĐiều khiển dàn giáo giới thiệu cùng điều khiển thêm tái quá trình phân tích -OpenHarmony kỹ thuật xã khu -51CTO.COM

[^5]: OpenHarmony HDFHDI cơ sở năng lực phân tích cùng sử dụng -51CTO.COM

© quyền tác giả về tác giả sở hữu, như cần đăng lại, thỉnh ghi chú rõ xuất xứ, nếu không đem truy cứu pháp luật trách nhiệm
Phân loại
Đã với 2022-4-19 09:40:34 sửa chữa
Tán 4
Cất chứa 2
Hồi phục
Cử báo
1 điều hồi phục
Ấn thời gian chính tự
/
Ấn thời gian đảo ngược
红叶亦知秋
Hồng diệp cũng biết thu

Camera công năng xác thật quan trọng, di động nhà máy hiệu buôn nhóm mỗi lần cuộc họp báo đều sẽ trọng điểm giới thiệu bọn họ cameras.

Hồi phục
2022-4-19 09:30:57
Hồi phục
    Tương quan đề cử
    Cái này người dùng thực lười, còn không có cá nhân tóm tắt
    Thiệp
    Video
    Danh vọng
    Fans
    Xã khu tinh hoa nội dung

    Mục lục