1/* 2 * Copyright (c) 2020-2022 Huawei Device Co., Ltd. 3 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * you may not use this file except in compliance with the License. 5 * You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software 10 * distributed under the License is distributed on an "AS IS" BASIS, 11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 * See the License for the specific language governing permissions and 13 * limitations under the License. 14 */ 15 16#include "camera_device.h" 17 18#include <fcntl.h> 19#include <pthread.h> 20#include <string> 21#include <sys/io.h> 22#include <sys/prctl.h> 23#include <sys/select.h> 24#include <thread> 25#include <unistd.h> 26#include "codec_interface.h" 27#include "display_layer.h" 28#include "hal_camera.h" 29#include "media_log.h" 30#include "meta_data.h" 31#include "securec.h" 32 33#include <iostream> 34 35using namespace OHOS; 36using namespace OHOS::Media; 37using namespace std; 38 39/** Indicates that the current frame is an Instantaneous Decoder Refresh (IDR) frame. */ 40const int32_t KEY_IS_SYNC_FRAME = 1; 41/** Indicates the frame timestamp. */ 42const int32_t KEY_TIME_US = 2; 43 44const int32_t IMAGE_WIDTH = 3; // "DATA_PIX_FORMAT" 45const int32_t IMAGE_HEIGHT = 4; // "DATA_PIX_FORMAT" 46const int32_t IMAGE_SIZE = 5; // "DATA_PIX_FORMAT" 47const int32_t DELAY_TIME_ONE_FRAME = 30000; 48const int32_t VIDEO_MAX_NUM = 2; // "video max num" 49const int32_t INVALID_STREAM_ID = -1; 50 51namespace OHOS { 52namespace Media { 53extern Surface *g_surface; 54 55AvCodecMime ConverFormat(ImageFormat format) 56{ 57 if (format == FORMAT_JPEG) { 58 return MEDIA_MIMETYPE_IMAGE_JPEG; 59 } else if (format == FORMAT_AVC) { 60 return MEDIA_MIMETYPE_VIDEO_AVC; 61 } else if (format == FORMAT_HEVC) { 62 return MEDIA_MIMETYPE_VIDEO_HEVC; 63 } else { 64 return MEDIA_MIMETYPE_INVALID; 65 } 66} 67 68static int32_t SetVencSource(CODEC_HANDLETYPE codecHdl, uint32_t deviceId) 69{ 70 Param param = {.key = KEY_DEVICE_ID, .val = (void *)&deviceId, .size = sizeof(uint32_t)}; 71 int32_t ret = CodecSetParameter(codecHdl, ¶m, 1); 72 if (ret != 0) { 73 MEDIA_ERR_LOG("Set enc source failed.(ret=%d)", ret); 74 return ret; 75 } 76 return MEDIA_OK; 77} 78 79static uint32_t GetDefaultBitrate(uint32_t width, uint32_t height) 80{ 81 uint32_t rate; /* auto calc bitrate if set 0 */ 82 if (width * height == 640 * 360) { /* 640,width 360,height */ 83 rate = 0x800; /* 2048kbps */ 84 } else if (width * height == 1280 * 720) { /* 1280,width 720,height */ 85 rate = 0x400; /* 1024kbps */ 86 } else if (width * height >= 2560 * 1440 && width * height <= 2716 * 1524) { /* 2560,2716 width 1440,1524,height */ 87 rate = 0x1800; /* 6144kbps */ 88 } else if (width * height == 3840 * 2160 || width * height == 4096 * 2160) { /* 3840,4096 width 2160,height */ 89 rate = 0xa000; /* 40960kbps */ 90 } else { 91 rate = 0x0; 92 } 93 return rate; 94} 95 96static int32_t CameraCreateVideoEnc(FrameConfig &fc, 97 StreamAttr stream, 98 uint32_t srcDev, 99 CODEC_HANDLETYPE *codecHdl) 100{ 101 const uint32_t maxParamNum = 10; 102 uint32_t paramIndex = 0; 103 Param param[maxParamNum]; 104 105 CodecType domainKind = VIDEO_ENCODER; 106 param[paramIndex].key = KEY_CODEC_TYPE; 107 param[paramIndex].val = &domainKind; 108 param[paramIndex].size = sizeof(CodecType); 109 paramIndex++; 110 111 AvCodecMime codecMime = ConverFormat(stream.format); 112 param[paramIndex].key = KEY_MIMETYPE; 113 param[paramIndex].val = &codecMime; 114 param[paramIndex].size = sizeof(AvCodecMime); 115 paramIndex++; 116 117 VideoCodecRcMode rcMode = VID_CODEC_RC_CBR; 118 param[paramIndex].key = KEY_VIDEO_RC_MODE; 119 param[paramIndex].val = &rcMode; 120 param[paramIndex].size = sizeof(VideoCodecRcMode); 121 paramIndex++; 122 123 VideoCodecGopMode gopMode = VID_CODEC_GOPMODE_NORMALP; 124 param[paramIndex].key = KEY_VIDEO_GOP_MODE; 125 param[paramIndex].val = &gopMode; 126 param[paramIndex].size = sizeof(VideoCodecGopMode); 127 paramIndex++; 128 129 Profile profile = HEVC_MAIN_PROFILE; 130 param[paramIndex].key = KEY_VIDEO_PROFILE; 131 param[paramIndex].val = &profile; 132 param[paramIndex].size = sizeof(Profile); 133 paramIndex++; 134 135#if (!defined(__LINUX__)) || (defined(ENABLE_PASSTHROUGH_MODE)) 136 uint32_t width = stream.width; 137 uint32_t height = stream.height; 138#else 139 uint32_t width = g_surface->GetWidth(); 140 uint32_t height = g_surface->GetHeight(); 141#endif 142 143 MEDIA_DEBUG_LOG("width=%d", width); 144 param[paramIndex].key = KEY_VIDEO_WIDTH; 145 param[paramIndex].val = &width; 146 param[paramIndex].size = sizeof(uint32_t); 147 paramIndex++; 148 149 MEDIA_DEBUG_LOG("height=%d", height); 150 param[paramIndex].key = KEY_VIDEO_HEIGHT; 151 param[paramIndex].val = &height; 152 param[paramIndex].size = sizeof(uint32_t); 153 paramIndex++; 154 155 uint32_t frameRate = stream.fps; 156 MEDIA_DEBUG_LOG("frameRate=%u", frameRate); 157 param[paramIndex].key = KEY_VIDEO_FRAME_RATE; 158 param[paramIndex].val = &frameRate; 159 param[paramIndex].size = sizeof(uint32_t); 160 paramIndex++; 161 162 uint32_t bitRate = GetDefaultBitrate(width, height); 163 MEDIA_DEBUG_LOG("bitRate=%u kbps", bitRate); 164 param[paramIndex].key = KEY_BITRATE; 165 param[paramIndex].val = &bitRate; 166 param[paramIndex].size = sizeof(uint32_t); 167 paramIndex++; 168 169 int32_t ret = CodecCreateByType(domainKind, codecMime, codecHdl); 170 if (ret != 0) { 171 MEDIA_ERR_LOG("Create video encoder failed."); 172 return MEDIA_ERR; 173 } 174 175 ret = CodecSetParameter(*codecHdl, param, paramIndex); 176 if (ret != 0) { 177 CodecDestroy(*codecHdl); 178 MEDIA_ERR_LOG("video CodecSetParameter failed."); 179 return MEDIA_ERR; 180 } 181 182 ret = SetVencSource(*codecHdl, srcDev); 183 if (ret != 0) { 184 CodecDestroy(*codecHdl); 185 return MEDIA_ERR; 186 } 187 188 return MEDIA_OK; 189} 190 191static void FillParam(Param ¶m, ParamKey key, uint8_t *data, uint32_t size) 192{ 193 param.key = key; 194 param.val = data; 195 param.size = size; 196} 197 198static CODEC_HANDLETYPE CameraCreateJpegEncProc(FrameConfig &fc, uint32_t srcDev, AvCodecMime codecMime, 199 const Param* param, uint32_t paramNum) 200{ 201 CODEC_HANDLETYPE codecHdl = nullptr; 202 if (CodecCreateByType(VIDEO_ENCODER, codecMime, &codecHdl) != 0) { 203 return nullptr; 204 } 205 206 int32_t ret = CodecSetParameter(codecHdl, param, paramNum); 207 if (ret != 0) { 208 CodecDestroy(codecHdl); 209 return nullptr; 210 } 211 212 int32_t qfactor = -1; 213 fc.GetParameter(PARAM_KEY_IMAGE_ENCODE_QFACTOR, qfactor); 214 if (qfactor != -1) { 215 Param jpegParam = { 216 .key = KEY_IMAGE_Q_FACTOR, 217 .val = &qfactor, 218 .size = sizeof(qfactor) 219 }; 220 ret = CodecSetParameter(codecHdl, &jpegParam, 1); 221 if (ret != 0) { 222 MEDIA_ERR_LOG("CodecSetParameter set jpeg qfactor failed.(ret=%u)", ret); 223 } 224 } 225 226 ret = SetVencSource(codecHdl, srcDev); 227 if (ret != 0) { 228 MEDIA_ERR_LOG("Set video encoder source failed."); 229 CodecDestroy(codecHdl); 230 return nullptr; 231 } 232 return codecHdl; 233} 234 235static int32_t CameraCreateJpegEnc(FrameConfig &fc, StreamAttr stream, uint32_t srcDev, CODEC_HANDLETYPE *codecHdl) 236{ 237 uint32_t maxParamNum = 10; /* 10 maxParamNum */ 238 Param param[maxParamNum]; 239 uint32_t paramIndex = 0; 240 241 CodecType domainKind = VIDEO_ENCODER; 242 FillParam(param[paramIndex], KEY_CODEC_TYPE, reinterpret_cast<uint8_t *>(&domainKind), sizeof(CodecType)); 243 paramIndex++; 244 245 AvCodecMime codecMime = ConverFormat(stream.format); 246 FillParam(param[paramIndex], KEY_MIMETYPE, reinterpret_cast<uint8_t *>(&codecMime), sizeof(AvCodecMime)); 247 paramIndex++; 248 249 auto surfaceList = fc.GetSurfaces(); 250 Surface *surface = surfaceList.front(); 251 uint32_t width = surface->GetWidth(); 252 MEDIA_DEBUG_LOG("width=%d", width); 253 FillParam(param[paramIndex], KEY_VIDEO_WIDTH, reinterpret_cast<uint8_t *>(&width), sizeof(uint32_t)); 254 paramIndex++; 255 256 uint32_t height = surface->GetHeight(); 257 MEDIA_DEBUG_LOG("height=%d", height); 258 FillParam(param[paramIndex], KEY_VIDEO_HEIGHT, reinterpret_cast<uint8_t *>(&height), sizeof(uint32_t)); 259 paramIndex++; 260 if (codecMime == MEDIA_MIMETYPE_VIDEO_HEVC) { 261 VideoCodecRcMode rcMode = VID_CODEC_RC_FIXQP; 262 FillParam(param[paramIndex], KEY_VIDEO_RC_MODE, reinterpret_cast<uint8_t *>(&rcMode), sizeof(VideoCodecRcMode)); 263 paramIndex++; 264 265 Profile profile = HEVC_MAIN_PROFILE; 266 FillParam(param[paramIndex], KEY_VIDEO_PROFILE, reinterpret_cast<uint8_t *>(&profile), sizeof(Profile)); 267 paramIndex++; 268 269 uint32_t frameRate = stream.fps; 270 FillParam(param[paramIndex], KEY_VIDEO_FRAME_RATE, reinterpret_cast<uint8_t *>(&frameRate), sizeof(uint32_t)); 271 paramIndex++; 272 } 273 *codecHdl = CameraCreateJpegEncProc(fc, srcDev, codecMime, param, paramIndex); 274 return (*codecHdl != nullptr) ? MEDIA_OK : MEDIA_ERR; 275} 276 277static int32_t CopyCodecOutput(uint8_t *dst, uint32_t *size, CodecBuffer *buffer) 278{ 279 if (dst == nullptr || size == nullptr || buffer == nullptr) { 280 return MEDIA_ERR; 281 } 282 char *dstBuf = reinterpret_cast<char *>(dst); 283 for (uint32_t i = 0; i < buffer->bufferCnt; i++) { 284 uint32_t packSize = buffer->buffer[i].length - buffer->buffer[i].offset; 285 errno_t ret = memcpy_s(dstBuf, *size, (void *)(buffer->buffer[i].buf + buffer->buffer[i].offset), packSize); 286 if (ret != EOK) { 287 return MEDIA_ERR; 288 } 289 *size -= packSize; 290 dstBuf += packSize; 291 } 292 return MEDIA_OK; 293} 294 295static void StreamAttrInitialize(StreamAttr *streamAttr, Surface *surface, 296 StreamType streamType, FrameConfig &fc) 297{ 298 if (streamAttr == nullptr || surface == nullptr) { 299 return; 300 } 301 (void)memset_s(streamAttr, sizeof(StreamAttr), 0, sizeof(StreamAttr)); 302 streamAttr->type = streamType; 303 fc.GetParameter(CAM_IMAGE_FORMAT, streamAttr->format); 304 streamAttr->width = surface->GetWidth(); 305 streamAttr->height = surface->GetHeight(); 306 fc.GetParameter(CAM_FRAME_FPS, streamAttr->fps); 307 fc.GetParameter(CAM_IMAGE_INVERT_MODE, streamAttr->invertMode); 308 fc.GetParameter(CAM_IMAGE_CROP_RECT, streamAttr->crop); 309} 310 311static ImageFormat Convert2HalImageFormat(uint32_t format) 312{ 313 if (format == CAM_IMAGE_RAW12) { 314 return FORMAT_RGB_BAYER_12BPP; 315 } 316 return FORMAT_YVU420; 317} 318 319static int32_t SurfaceSetSize(SurfaceBuffer* surfaceBuf, Surface* surface, uint32_t size) 320{ 321#if (!defined(__LINUX__)) || (defined(ENABLE_PASSTHROUGH_MODE)) 322 surfaceBuf->SetSize(surface->GetSize() - size); 323 if (surface->FlushBuffer(surfaceBuf) != 0) { 324 MEDIA_ERR_LOG("Flush g_surface failed."); 325 surface->CancelBuffer(surfaceBuf); 326 return -1; 327 } 328#else 329 surfaceBuf->SetSize(g_surface->GetSize() - size); 330 if (g_surface->FlushBuffer(surfaceBuf) != 0) { 331 MEDIA_ERR_LOG("Flush surface failed."); 332 g_surface->CancelBuffer(surfaceBuf); 333 return -1; 334 } 335#endif 336 return 0; 337} 338 339int32_t RecordAssistant::OnVencBufferAvailble(UINTPTR userData, CodecBuffer* outBuf, int32_t *acquireFd) 340{ 341 (void)acquireFd; 342 CodecDesc* codecInfo = reinterpret_cast<CodecDesc* >(userData); 343 list<Surface*> *surfaceList = &codecInfo->vencSurfaces_; 344 if (surfaceList == nullptr || surfaceList->empty()) { 345 MEDIA_ERR_LOG("Encoder handle is illegal."); 346 return MEDIA_ERR; 347 } 348 int32_t ret = -1; 349 for (auto &surface : *surfaceList) { 350#if (!defined(__LINUX__)) || (defined(ENABLE_PASSTHROUGH_MODE)) 351 SurfaceBuffer *surfaceBuf = surface->RequestBuffer(); 352#else 353 SurfaceBuffer *surfaceBuf = g_surface->RequestBuffer(); 354#endif 355 if (surfaceBuf == nullptr) { 356 MEDIA_ERR_LOG("No available buffer in surface."); 357 break; 358 } 359#if (!defined(__LINUX__)) || (defined(ENABLE_PASSTHROUGH_MODE)) 360 uint32_t size = surface->GetSize(); 361#else 362 uint32_t size = g_surface->GetSize(); 363#endif 364 void *buf = surfaceBuf->GetVirAddr(); 365 if (buf == nullptr) { 366 MEDIA_ERR_LOG("Invalid buffer address."); 367 break; 368 } 369 ret = CopyCodecOutput((uint8_t*)buf, &size, outBuf); 370 if (ret != MEDIA_OK) { 371 MEDIA_ERR_LOG("No available outBuf in surface."); 372#if (!defined(__LINUX__)) || (defined(ENABLE_PASSTHROUGH_MODE)) 373 surface->CancelBuffer(surfaceBuf); 374#else 375 g_surface->CancelBuffer(surfaceBuf); 376#endif 377 break; 378 } 379 surfaceBuf->SetInt32(KEY_IS_SYNC_FRAME, (((outBuf->flag & STREAM_FLAG_KEYFRAME) == 0) ? 0 : 1)); 380 surfaceBuf->SetInt64(KEY_TIME_US, outBuf->timeStamp); 381 ret = SurfaceSetSize(surfaceBuf, surface, size); 382 if (ret != 0) { 383 break; 384 } 385 } 386 if (CodecQueueOutput(codecInfo->vencHdl_, outBuf, 0, -1) != 0) { 387 MEDIA_ERR_LOG("Codec queue output failed."); 388 } 389 return ret; 390} 391 392CodecCallback RecordAssistant::recordCodecCb_ = {nullptr, nullptr, RecordAssistant::OnVencBufferAvailble}; 393 394void RecordAssistant::ClearFrameConfig() 395{ 396 for (uint32_t i = 0; i < codecInfo_.size(); i++) { 397 CodecStop(codecInfo_[i].vencHdl_); 398 CodecDestroy(codecInfo_[i].vencHdl_); 399 } 400 codecInfo_.clear(); 401} 402 403int32_t RecordAssistant::SetFrameConfigEnd(int32_t result) 404{ 405 if (result != MEDIA_OK) { 406 for (uint32_t i = 0; i < codecInfo_.size(); i++) { 407 CodecDestroy(codecInfo_[i].vencHdl_); 408 } 409 codecInfo_.clear(); 410 return result; 411 } 412 for (uint32_t i = 0; i < codecInfo_.size(); i++) { 413 result = CodecSetCallback(codecInfo_[i].vencHdl_, &recordCodecCb_, reinterpret_cast<UINTPTR>(&codecInfo_[i])); 414 if (result != 0) { 415 MEDIA_ERR_LOG("set CodecSetCallback failed ret:%d", result); 416 CodecDestroy(codecInfo_[i].vencHdl_); 417 break; 418 } 419 } 420 421 if (result == MEDIA_OK) { 422 state_ = LOOP_READY; 423 } else { 424 for (uint32_t i = 0; i < codecInfo_.size(); i++) { 425 CodecDestroy(codecInfo_[i].vencHdl_); 426 } 427 codecInfo_.clear(); 428 } 429 return result; 430} 431 432int32_t RecordAssistant::SetFrameConfig(FrameConfig &fc, uint32_t *streamId) 433{ 434 fc_ = &fc; 435 auto surfaceList = fc.GetSurfaces(); 436 if (surfaceList.size() > VIDEO_MAX_NUM || surfaceList.size() == 0) { 437 MEDIA_ERR_LOG("the number of surface in frame config must 1 or 2 now.\n"); 438 return MEDIA_ERR; 439 } 440 uint32_t num = 0; 441 int32_t ret = MEDIA_OK; 442 for (auto &surface : surfaceList) { 443 CODEC_HANDLETYPE codecHdl = nullptr; 444 StreamAttr stream = {}; 445#if (!defined(__LINUX__)) || (defined(ENABLE_PASSTHROUGH_MODE)) 446 StreamAttrInitialize(&stream, surface, STREAM_VIDEO, fc); 447#else 448 StreamAttrInitialize(&stream, g_surface, STREAM_VIDEO, fc); 449#endif 450 ret = HalCameraStreamCreate(cameraId_, &stream, streamId); 451 if (ret != MEDIA_OK) { 452 MEDIA_ERR_LOG(" creat recorder stream failed."); 453 ClearFrameConfig(); 454 break; 455 } 456 streamId_ = *streamId; 457 streamIdNum_[num] = *streamId; 458 num++; 459 460 StreamInfo streamInfo; 461 streamInfo.type = STERAM_INFO_PRIVATE; 462 fc.GetVendorParameter(streamInfo.u.data, PRIVATE_TAG_LEN); 463 HalCameraStreamSetInfo(cameraId_, *streamId, &streamInfo); 464 465 uint32_t deviceId = 0; 466 HalCameraGetDeviceId(cameraId_, *streamId, &deviceId); 467 ret = CameraCreateVideoEnc(fc, stream, deviceId, &codecHdl); 468 if (ret != MEDIA_OK) { 469 MEDIA_ERR_LOG("Cannot create suitble video encoder."); 470 ClearFrameConfig(); 471 break; 472 } 473#if (!defined(__LINUX__)) || (defined(ENABLE_PASSTHROUGH_MODE)) 474 list<Surface*> conList({surface}); 475#else 476 list<Surface*> conList({g_surface}); 477#endif 478 CodecDesc info; 479 info.vencHdl_ = codecHdl; 480 info.vencSurfaces_ = conList; 481 codecInfo_.emplace_back(info); 482 } 483 return SetFrameConfigEnd(ret); 484} 485 486int32_t RecordAssistant::Start(uint32_t streamId) 487{ 488 if (state_ != LOOP_READY) { 489 return MEDIA_ERR; 490 } 491 HalCameraStreamOn(cameraId_, streamId); 492 int32_t ret = MEDIA_OK; 493 int32_t i; 494 for (i = 0; static_cast<uint32_t>(i) < codecInfo_.size(); i++) { 495 ret = CodecStart(codecInfo_[i].vencHdl_); 496 if (ret != MEDIA_OK) { 497 MEDIA_ERR_LOG("Video encoder start failed."); 498 ret = MEDIA_ERR; 499 break; 500 } 501 } 502 if (ret == MEDIA_ERR) { 503 /* rollback */ 504 for (; i >= 0; i--) { 505 CodecStop(codecInfo_[i].vencHdl_); 506 } 507 return MEDIA_ERR; 508 } 509 state_ = LOOP_LOOPING; 510 MEDIA_INFO_LOG("Start camera recording succeed."); 511 return MEDIA_OK; 512} 513 514int32_t RecordAssistant::Stop() 515{ 516 if (state_ != LOOP_LOOPING) { 517 return MEDIA_ERR; 518 } 519 ClearFrameConfig(); 520 for (uint32_t i = 0; i < VIDEO_MAX_NUM; i++) { 521 if (streamIdNum_[i] != INVALID_STREAM_ID) { 522 HalCameraStreamOff(cameraId_, streamIdNum_[i]); 523 HalCameraStreamDestroy(cameraId_, streamIdNum_[i]); 524 } 525 streamIdNum_[i] = INVALID_STREAM_ID; 526 } 527 state_ = LOOP_STOP; 528 return MEDIA_OK; 529} 530 531void* PreviewAssistant::YuvCopyProcess(void *arg) 532{ 533 return nullptr; 534} 535 536static void GetSurfaceRect(Surface *surface, IRect *attr) 537{ 538 attr->x = std::stoi(surface->GetUserData(string("region_position_x"))); 539 attr->y = std::stoi(surface->GetUserData(string("region_position_y"))); 540 attr->w = std::stoi(surface->GetUserData(string("region_width"))); 541 attr->h = std::stoi(surface->GetUserData(string("region_hegiht"))); 542} 543 544int32_t PreviewAssistant::SetFrameConfig(FrameConfig &fc, uint32_t *streamId) 545{ 546 fc_ = &fc; 547 auto surfaceList = fc.GetSurfaces(); 548 if (surfaceList.size() != 1) { 549 MEDIA_ERR_LOG("Only support one surface in frame config now."); 550 return MEDIA_ERR; 551 } 552 Surface *surface = surfaceList.front(); 553 StreamAttr stream = {}; 554 StreamAttrInitialize(&stream, surface, STREAM_PREVIEW, fc); 555 int32_t ret = HalCameraStreamCreate(cameraId_, &stream, streamId); 556 if (ret != MEDIA_OK) { 557 MEDIA_ERR_LOG(" creat preview stream failed."); 558 return MEDIA_ERR; 559 } 560 StreamInfo streamInfo; 561 streamInfo.type = STREAM_INFO_POS; 562 streamInfo.u.pos.x = std::stoi(surface->GetUserData(string("region_position_x"))); 563 streamInfo.u.pos.y = std::stoi(surface->GetUserData(string("region_position_y"))); 564 565 HalCameraStreamSetInfo(cameraId_, *streamId, &streamInfo); 566 streamId_ = *streamId; 567 return MEDIA_OK; 568} 569 570int32_t PreviewAssistant::Start(uint32_t streamId) 571{ 572 if (state_ == LOOP_LOOPING) { 573 return MEDIA_ERR; 574 } 575 state_ = LOOP_LOOPING; 576 577 int32_t retCode = pthread_create(&threadId, nullptr, YuvCopyProcess, this); 578 if (retCode != 0) { 579 MEDIA_ERR_LOG("fork thread YuvCopyProcess failed: %d.", retCode); 580 } 581 582 int32_t ret = HalCameraStreamOn(cameraId_, streamId); 583 if (ret != MEDIA_OK) { 584 MEDIA_ERR_LOG("Preview start failed of HalCameraStreamOn.(ret=%d)", ret); 585 Stop(); 586 return MEDIA_ERR; 587 } 588 return MEDIA_OK; 589} 590 591int32_t PreviewAssistant::Stop() 592{ 593 if (state_ != LOOP_LOOPING) { 594 return MEDIA_ERR; 595 } 596 state_ = LOOP_STOP; 597 pthread_join(threadId, NULL); 598 HalCameraStreamOff(cameraId_, streamId_); 599 HalCameraStreamDestroy(cameraId_, streamId_); 600 return MEDIA_OK; 601} 602 603int32_t CaptureAssistant::SetFrameConfig(FrameConfig &fc, uint32_t *streamId) 604{ 605 auto surfaceList = fc.GetSurfaces(); 606 if (surfaceList.size() != 1) { 607 MEDIA_ERR_LOG("Only support one surface in frame config now."); 608 return MEDIA_ERR; 609 } 610 if (surfaceList.empty()) { 611 MEDIA_ERR_LOG("Frame config with empty surface list."); 612 return MEDIA_ERR; 613 } 614 if (surfaceList.size() > 1) { 615 MEDIA_WARNING_LOG("Capture only fullfill the first surface in frame config."); 616 } 617 Surface *surface = surfaceList.front(); 618 619 StreamAttr stream = {}; 620 StreamAttrInitialize(&stream, surface, STREAM_CAPTURE, fc); 621 622 uint32_t deviceId = 0; 623 int32_t ret = HalCameraStreamCreate(cameraId_, &stream, streamId); 624 if (ret != MEDIA_OK) { 625 MEDIA_ERR_LOG(" creat capture stream failed."); 626 return MEDIA_ERR; 627 } 628 streamId_ = *streamId; 629 HalCameraGetDeviceId(cameraId_, *streamId, &deviceId); 630 ret = CameraCreateJpegEnc(fc, stream, deviceId, &vencHdl_); 631 if (ret != MEDIA_OK) { 632 MEDIA_ERR_LOG("Create capture venc failed."); 633 return MEDIA_ERR; 634 } 635 636 capSurface_ = surface; 637 state_ = LOOP_READY; 638 return MEDIA_OK; 639} 640 641/* Block method, waiting for capture completed */ 642int32_t CaptureAssistant::Start(uint32_t streamId) 643{ 644 state_ = LOOP_LOOPING; 645 HalCameraStreamOn(cameraId_, streamId); 646 int32_t ret = CodecStart(vencHdl_); 647 if (ret != 0) { 648 MEDIA_ERR_LOG("Start capture encoder failed.(ret=%d)", ret); 649 state_ = LOOP_STOP; 650 return MEDIA_ERR; 651 } 652 653 CodecBuffer* outInfo = (CodecBuffer*)new char[sizeof(CodecBuffer) + sizeof(CodecBufferInfo) * 3]; /* 3 buffCnt */ 654 if (outInfo == NULL) { 655 MEDIA_ERR_LOG("malloc Dequeue buffer failed!"); 656 return MEDIA_ERR; 657 } 658 SurfaceBuffer *surfaceBuf = NULL; 659 do { 660 if (memset_s(outInfo, sizeof(CodecBuffer) + sizeof(CodecBufferInfo) * 0x3, 0, 661 sizeof(CodecBuffer) + sizeof(CodecBufferInfo) * 3) != MEDIA_OK) { /* 3 buffCnt */ 662 MEDIA_ERR_LOG("memset_s failed!"); 663 delete(outInfo); 664 return MEDIA_ERR; 665 } 666 outInfo->bufferCnt = 3; /* 3 buffCnt */ 667 ret = CodecDequeueOutput(vencHdl_, 0, nullptr, outInfo); 668 if (ret != 0) { 669 MEDIA_ERR_LOG("Dequeue capture frame failed.(ret=%d)", ret); 670 break; 671 } 672 673 surfaceBuf = capSurface_->RequestBuffer(); 674 if (surfaceBuf == NULL) { 675 break; 676 } 677 678 uint32_t size = capSurface_->GetSize(); 679 void *buf = surfaceBuf->GetVirAddr(); 680 if (buf == nullptr) { 681 MEDIA_ERR_LOG("Invalid buffer address."); 682 break; 683 } 684 if (CopyCodecOutput((uint8_t*)buf, &size, outInfo) != MEDIA_OK) { 685 MEDIA_ERR_LOG("No available buffer in capSurface_."); 686 break; 687 } 688 surfaceBuf->SetSize(capSurface_->GetSize() - size); 689 if (capSurface_->FlushBuffer(surfaceBuf) != 0) { 690 MEDIA_ERR_LOG("Flush surface buffer failed."); 691 break; 692 } 693 } while (0); 694 695 CodecStop(vencHdl_); 696 CodecDestroy(vencHdl_); 697 HalCameraStreamOff(cameraId_, streamId); 698 HalCameraStreamDestroy(cameraId_, streamId); 699 delete outInfo; 700 outInfo = NULL; 701 state_ = LOOP_STOP; 702 703 return ret; 704} 705 706int32_t CaptureAssistant::Stop() 707{ 708 MEDIA_DEBUG_LOG("No support method."); 709 return MEDIA_OK; 710} 711 712int32_t CallbackAssistant::SetFrameConfig(FrameConfig &fc, uint32_t *streamId) 713{ 714 fc_ = &fc; 715 auto surfaceList = fc.GetSurfaces(); 716 if (surfaceList.size() != 1) { 717 MEDIA_ERR_LOG("Only support one surface in frame config now."); 718 return MEDIA_ERR; 719 } 720 uint32_t imageFormat = 0; 721 fc.GetParameter(CAM_IMAGE_FORMAT, imageFormat); 722 ImageFormat halImageFormat = Convert2HalImageFormat(imageFormat); 723 MEDIA_INFO_LOG("Imageformat is %d", imageFormat); 724 Surface *surface = surfaceList.front(); 725 StreamAttr stream = {}; 726 StreamAttrInitialize(&stream, surface, STREAM_CALLBACK, fc); 727 stream.format = halImageFormat; 728 int32_t ret = HalCameraStreamCreate(cameraId_, &stream, streamId); 729 if (ret != MEDIA_OK) { 730 MEDIA_ERR_LOG(" creat callback stream failed."); 731 return MEDIA_ERR; 732 } 733 streamId_ = *streamId; 734 capSurface_ = surface; 735 state_ = LOOP_READY; 736 return MEDIA_OK; 737} 738 739int32_t CallbackAssistant::Start(uint32_t streamId) 740{ 741 if (state_ == LOOP_LOOPING) { 742 return MEDIA_ERR; 743 } 744 state_ = LOOP_LOOPING; 745 int32_t retCode = pthread_create(&threadId, nullptr, StreamCopyProcess, this); 746 if (retCode != 0) { 747 MEDIA_ERR_LOG("fork thread StreamCopyProcess failed: %d.", retCode); 748 } 749 HalCameraStreamOn(cameraId_, streamId); 750 return MEDIA_OK; 751} 752 753void* CallbackAssistant::StreamCopyProcess(void *arg) 754{ 755 CallbackAssistant *assistant = (CallbackAssistant *)arg; 756 if (assistant == nullptr) { 757 MEDIA_ERR_LOG("CallbackAssistant create failed."); 758 return nullptr; 759 } 760 if (assistant->capSurface_ == nullptr) { 761 MEDIA_ERR_LOG("capSurface_ is null.\n"); 762 return nullptr; 763 } 764 765 int32_t ret; 766 HalBuffer streamBuffer; 767 (void)memset_s(&streamBuffer, sizeof(HalBuffer), 0, sizeof(HalBuffer)); 768 while (assistant->state_ == LOOP_LOOPING) { 769 SurfaceBuffer *surfaceBuf = assistant->capSurface_->RequestBuffer(); 770 if (surfaceBuf == nullptr) { 771 usleep(DELAY_TIME_ONE_FRAME); 772 continue; 773 } 774 775 if (streamBuffer.size != 0x0) { 776 HalCameraQueueBuf(assistant->cameraId_, assistant->streamId_, &streamBuffer); 777 (void)memset_s(&streamBuffer, sizeof(HalBuffer), 0, sizeof(HalBuffer)); 778 } 779 streamBuffer.format = FORMAT_PRIVATE; 780 streamBuffer.size = assistant->capSurface_->GetSize(); 781 if (surfaceBuf->GetVirAddr() == NULL) { 782 MEDIA_ERR_LOG("Invalid buffer address."); 783 break; 784 } 785 streamBuffer.virAddr = surfaceBuf->GetVirAddr(); 786 787 ret = HalCameraDequeueBuf(assistant->cameraId_, assistant->streamId_, &streamBuffer); 788 if (ret != MEDIA_OK) { 789 usleep(DELAY_TIME_ONE_FRAME); 790 continue; 791 } 792 793 if (assistant->capSurface_->FlushBuffer(surfaceBuf) != 0) { 794 MEDIA_ERR_LOG("Flush surface failed."); 795 assistant->capSurface_->CancelBuffer(surfaceBuf); 796 break; 797 } 798 usleep(DELAY_TIME_ONE_FRAME); 799 } 800 if (streamBuffer.size != 0x0) { 801 HalCameraQueueBuf(assistant->cameraId_, assistant->streamId_, &streamBuffer); 802 } 803 MEDIA_DEBUG_LOG(" yuv thread joined \n"); 804 return nullptr; 805} 806 807int32_t CallbackAssistant::Stop() 808{ 809 if (state_ != LOOP_LOOPING) { 810 return MEDIA_ERR; 811 } 812 state_ = LOOP_STOP; 813 pthread_join(threadId, NULL); 814 HalCameraStreamOff(cameraId_, streamId_); 815 HalCameraStreamDestroy(cameraId_, streamId_); 816 return MEDIA_OK; 817} 818 819CameraDevice::CameraDevice() {} 820CameraDevice::CameraDevice(uint32_t cameraId) 821{ 822 this->cameraId = cameraId; 823} 824 825CameraDevice::~CameraDevice() {} 826 827int32_t CameraDevice::Initialize() 828{ 829 // Need to be Refactored when delete config file 830 int32_t ret = CodecInit(); 831 if (ret != 0) { 832 MEDIA_ERR_LOG("Codec module init failed.(ret=%d)", ret); 833 return MEDIA_ERR; 834 } 835 MEDIA_INFO_LOG("Codec module init succeed."); 836 captureAssistant_.state_ = LOOP_READY; 837 previewAssistant_.state_ = LOOP_READY; 838 recordAssistant_.state_ = LOOP_READY; 839 callbackAssistant_.state_ = LOOP_READY; 840 captureAssistant_.cameraId_ = cameraId; 841 previewAssistant_.cameraId_ = cameraId; 842 recordAssistant_.cameraId_ = cameraId; 843 callbackAssistant_.cameraId_ = cameraId; 844 return MEDIA_OK; 845} 846 847int32_t CameraDevice::UnInitialize() 848{ 849 return MEDIA_OK; 850} 851 852int32_t CameraDevice::TriggerLoopingCapture(FrameConfig &fc, uint32_t *streamId) 853{ 854 MEDIA_DEBUG_LOG("Camera device start looping capture."); 855 DeviceAssistant *assistant = nullptr; 856 int32_t fcType = fc.GetFrameConfigType(); 857 switch (fcType) { 858 case FRAME_CONFIG_RECORD: 859 assistant = &recordAssistant_; 860 break; 861 case FRAME_CONFIG_PREVIEW: 862 assistant = &previewAssistant_; 863 break; 864 case FRAME_CONFIG_CAPTURE: 865 assistant = &captureAssistant_; 866 break; 867 case FRAME_CONFIG_CALLBACK: 868 assistant = &callbackAssistant_; 869 break; 870 default: 871 break; 872 } 873 if (assistant == nullptr) { 874 MEDIA_ERR_LOG("Invalid frame config type.(type=%d)", fcType); 875 return MEDIA_ERR; 876 } 877 if (assistant->state_ == LOOP_IDLE || assistant->state_ == LOOP_LOOPING || assistant->state_ == LOOP_ERROR) { 878 MEDIA_ERR_LOG("Device state is %d, cannot start looping capture.", assistant->state_); 879 return MEDIA_ERR; 880 } 881 uint8_t count = 1; 882 if (fcType == FRAME_CONFIG_CAPTURE) { 883 auto surfaceList = fc.GetSurfaces(); 884 if (surfaceList.size() != 1) { 885 MEDIA_ERR_LOG("Only support one surface in frame config now"); 886 return MEDIA_ERR; 887 } 888 Surface* surface = surfaceList.front(); 889 count = surface->GetQueueSize(); 890 } 891 892 do { 893 int32_t ret = assistant->SetFrameConfig(fc, streamId); 894 if (ret != MEDIA_OK) { 895 MEDIA_ERR_LOG("Check and set frame config failed (ret=%d)", ret); 896 return MEDIA_ERR; 897 } 898 ret = assistant->Start(*streamId); 899 if (ret != MEDIA_OK) { 900 MEDIA_ERR_LOG("Start looping capture failed (ret=%d)", ret); 901 return MEDIA_ERR; 902 } 903 } while (--count); 904 return MEDIA_OK; 905} 906 907void CameraDevice::StopLoopingCapture(int32_t type) 908{ 909 MEDIA_INFO_LOG("Stop looping capture in camera_device.cpp"); 910 911 switch (type) { 912 case FRAME_CONFIG_RECORD: 913 MEDIA_INFO_LOG("Stop recorder"); 914 recordAssistant_.Stop();; 915 break; 916 case FRAME_CONFIG_PREVIEW: 917 MEDIA_INFO_LOG("Stop preview"); 918 previewAssistant_.Stop(); 919 break; 920 case FRAME_CONFIG_CALLBACK: 921 MEDIA_INFO_LOG("Stop callback"); 922 callbackAssistant_.Stop(); 923 break; 924 default: 925 MEDIA_INFO_LOG("Stop all"); 926 previewAssistant_.Stop(); 927 recordAssistant_.Stop(); 928 callbackAssistant_.Stop(); 929 break; 930 } 931} 932 933int32_t CameraDevice::TriggerSingleCapture(FrameConfig &fc, uint32_t *streamId) 934{ 935 return TriggerLoopingCapture(fc, streamId); 936} 937 938int32_t CameraDevice::SetCameraConfig() 939{ 940 return MEDIA_OK; 941} 942} // namespace Media 943} // namespace OHOS 944