10a5c7a17Sopenharmony_ci/* 20a5c7a17Sopenharmony_ci * Copyright (c) 2020-2022 Huawei Device Co., Ltd. 30a5c7a17Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 40a5c7a17Sopenharmony_ci * you may not use this file except in compliance with the License. 50a5c7a17Sopenharmony_ci * You may obtain a copy of the License at 60a5c7a17Sopenharmony_ci * 70a5c7a17Sopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 80a5c7a17Sopenharmony_ci * 90a5c7a17Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software 100a5c7a17Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 110a5c7a17Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 120a5c7a17Sopenharmony_ci * See the License for the specific language governing permissions and 130a5c7a17Sopenharmony_ci * limitations under the License. 140a5c7a17Sopenharmony_ci */ 150a5c7a17Sopenharmony_ci 160a5c7a17Sopenharmony_ci#include "camera_device.h" 170a5c7a17Sopenharmony_ci 180a5c7a17Sopenharmony_ci#include <fcntl.h> 190a5c7a17Sopenharmony_ci#include <pthread.h> 200a5c7a17Sopenharmony_ci#include <string> 210a5c7a17Sopenharmony_ci#include <sys/io.h> 220a5c7a17Sopenharmony_ci#include <sys/prctl.h> 230a5c7a17Sopenharmony_ci#include <sys/select.h> 240a5c7a17Sopenharmony_ci#include <thread> 250a5c7a17Sopenharmony_ci#include <unistd.h> 260a5c7a17Sopenharmony_ci#include "codec_interface.h" 270a5c7a17Sopenharmony_ci#include "display_layer.h" 280a5c7a17Sopenharmony_ci#include "hal_camera.h" 290a5c7a17Sopenharmony_ci#include "media_log.h" 300a5c7a17Sopenharmony_ci#include "meta_data.h" 310a5c7a17Sopenharmony_ci#include "securec.h" 320a5c7a17Sopenharmony_ci 330a5c7a17Sopenharmony_ci#include <iostream> 340a5c7a17Sopenharmony_ci 350a5c7a17Sopenharmony_ciusing namespace OHOS; 360a5c7a17Sopenharmony_ciusing namespace OHOS::Media; 370a5c7a17Sopenharmony_ciusing namespace std; 380a5c7a17Sopenharmony_ci 390a5c7a17Sopenharmony_ci/** Indicates that the current frame is an Instantaneous Decoder Refresh (IDR) frame. */ 400a5c7a17Sopenharmony_ciconst int32_t KEY_IS_SYNC_FRAME = 1; 410a5c7a17Sopenharmony_ci/** Indicates the frame timestamp. */ 420a5c7a17Sopenharmony_ciconst int32_t KEY_TIME_US = 2; 430a5c7a17Sopenharmony_ci 440a5c7a17Sopenharmony_ciconst int32_t IMAGE_WIDTH = 3; // "DATA_PIX_FORMAT" 450a5c7a17Sopenharmony_ciconst int32_t IMAGE_HEIGHT = 4; // "DATA_PIX_FORMAT" 460a5c7a17Sopenharmony_ciconst int32_t IMAGE_SIZE = 5; // "DATA_PIX_FORMAT" 470a5c7a17Sopenharmony_ciconst int32_t DELAY_TIME_ONE_FRAME = 30000; 480a5c7a17Sopenharmony_ciconst int32_t VIDEO_MAX_NUM = 2; // "video max num" 490a5c7a17Sopenharmony_ciconst int32_t INVALID_STREAM_ID = -1; 500a5c7a17Sopenharmony_ci 510a5c7a17Sopenharmony_cinamespace OHOS { 520a5c7a17Sopenharmony_cinamespace Media { 530a5c7a17Sopenharmony_ciextern Surface *g_surface; 540a5c7a17Sopenharmony_ci 550a5c7a17Sopenharmony_ciAvCodecMime ConverFormat(ImageFormat format) 560a5c7a17Sopenharmony_ci{ 570a5c7a17Sopenharmony_ci if (format == FORMAT_JPEG) { 580a5c7a17Sopenharmony_ci return MEDIA_MIMETYPE_IMAGE_JPEG; 590a5c7a17Sopenharmony_ci } else if (format == FORMAT_AVC) { 600a5c7a17Sopenharmony_ci return MEDIA_MIMETYPE_VIDEO_AVC; 610a5c7a17Sopenharmony_ci } else if (format == FORMAT_HEVC) { 620a5c7a17Sopenharmony_ci return MEDIA_MIMETYPE_VIDEO_HEVC; 630a5c7a17Sopenharmony_ci } else { 640a5c7a17Sopenharmony_ci return MEDIA_MIMETYPE_INVALID; 650a5c7a17Sopenharmony_ci } 660a5c7a17Sopenharmony_ci} 670a5c7a17Sopenharmony_ci 680a5c7a17Sopenharmony_cistatic int32_t SetVencSource(CODEC_HANDLETYPE codecHdl, uint32_t deviceId) 690a5c7a17Sopenharmony_ci{ 700a5c7a17Sopenharmony_ci Param param = {.key = KEY_DEVICE_ID, .val = (void *)&deviceId, .size = sizeof(uint32_t)}; 710a5c7a17Sopenharmony_ci int32_t ret = CodecSetParameter(codecHdl, ¶m, 1); 720a5c7a17Sopenharmony_ci if (ret != 0) { 730a5c7a17Sopenharmony_ci MEDIA_ERR_LOG("Set enc source failed.(ret=%d)", ret); 740a5c7a17Sopenharmony_ci return ret; 750a5c7a17Sopenharmony_ci } 760a5c7a17Sopenharmony_ci return MEDIA_OK; 770a5c7a17Sopenharmony_ci} 780a5c7a17Sopenharmony_ci 790a5c7a17Sopenharmony_cistatic uint32_t GetDefaultBitrate(uint32_t width, uint32_t height) 800a5c7a17Sopenharmony_ci{ 810a5c7a17Sopenharmony_ci uint32_t rate; /* auto calc bitrate if set 0 */ 820a5c7a17Sopenharmony_ci if (width * height == 640 * 360) { /* 640,width 360,height */ 830a5c7a17Sopenharmony_ci rate = 0x800; /* 2048kbps */ 840a5c7a17Sopenharmony_ci } else if (width * height == 1280 * 720) { /* 1280,width 720,height */ 850a5c7a17Sopenharmony_ci rate = 0x400; /* 1024kbps */ 860a5c7a17Sopenharmony_ci } else if (width * height >= 2560 * 1440 && width * height <= 2716 * 1524) { /* 2560,2716 width 1440,1524,height */ 870a5c7a17Sopenharmony_ci rate = 0x1800; /* 6144kbps */ 880a5c7a17Sopenharmony_ci } else if (width * height == 3840 * 2160 || width * height == 4096 * 2160) { /* 3840,4096 width 2160,height */ 890a5c7a17Sopenharmony_ci rate = 0xa000; /* 40960kbps */ 900a5c7a17Sopenharmony_ci } else { 910a5c7a17Sopenharmony_ci rate = 0x0; 920a5c7a17Sopenharmony_ci } 930a5c7a17Sopenharmony_ci return rate; 940a5c7a17Sopenharmony_ci} 950a5c7a17Sopenharmony_ci 960a5c7a17Sopenharmony_cistatic int32_t CameraCreateVideoEnc(FrameConfig &fc, 970a5c7a17Sopenharmony_ci StreamAttr stream, 980a5c7a17Sopenharmony_ci uint32_t srcDev, 990a5c7a17Sopenharmony_ci CODEC_HANDLETYPE *codecHdl) 1000a5c7a17Sopenharmony_ci{ 1010a5c7a17Sopenharmony_ci const uint32_t maxParamNum = 10; 1020a5c7a17Sopenharmony_ci uint32_t paramIndex = 0; 1030a5c7a17Sopenharmony_ci Param param[maxParamNum]; 1040a5c7a17Sopenharmony_ci 1050a5c7a17Sopenharmony_ci CodecType domainKind = VIDEO_ENCODER; 1060a5c7a17Sopenharmony_ci param[paramIndex].key = KEY_CODEC_TYPE; 1070a5c7a17Sopenharmony_ci param[paramIndex].val = &domainKind; 1080a5c7a17Sopenharmony_ci param[paramIndex].size = sizeof(CodecType); 1090a5c7a17Sopenharmony_ci paramIndex++; 1100a5c7a17Sopenharmony_ci 1110a5c7a17Sopenharmony_ci AvCodecMime codecMime = ConverFormat(stream.format); 1120a5c7a17Sopenharmony_ci param[paramIndex].key = KEY_MIMETYPE; 1130a5c7a17Sopenharmony_ci param[paramIndex].val = &codecMime; 1140a5c7a17Sopenharmony_ci param[paramIndex].size = sizeof(AvCodecMime); 1150a5c7a17Sopenharmony_ci paramIndex++; 1160a5c7a17Sopenharmony_ci 1170a5c7a17Sopenharmony_ci VideoCodecRcMode rcMode = VID_CODEC_RC_CBR; 1180a5c7a17Sopenharmony_ci param[paramIndex].key = KEY_VIDEO_RC_MODE; 1190a5c7a17Sopenharmony_ci param[paramIndex].val = &rcMode; 1200a5c7a17Sopenharmony_ci param[paramIndex].size = sizeof(VideoCodecRcMode); 1210a5c7a17Sopenharmony_ci paramIndex++; 1220a5c7a17Sopenharmony_ci 1230a5c7a17Sopenharmony_ci VideoCodecGopMode gopMode = VID_CODEC_GOPMODE_NORMALP; 1240a5c7a17Sopenharmony_ci param[paramIndex].key = KEY_VIDEO_GOP_MODE; 1250a5c7a17Sopenharmony_ci param[paramIndex].val = &gopMode; 1260a5c7a17Sopenharmony_ci param[paramIndex].size = sizeof(VideoCodecGopMode); 1270a5c7a17Sopenharmony_ci paramIndex++; 1280a5c7a17Sopenharmony_ci 1290a5c7a17Sopenharmony_ci Profile profile = HEVC_MAIN_PROFILE; 1300a5c7a17Sopenharmony_ci param[paramIndex].key = KEY_VIDEO_PROFILE; 1310a5c7a17Sopenharmony_ci param[paramIndex].val = &profile; 1320a5c7a17Sopenharmony_ci param[paramIndex].size = sizeof(Profile); 1330a5c7a17Sopenharmony_ci paramIndex++; 1340a5c7a17Sopenharmony_ci 1350a5c7a17Sopenharmony_ci#if (!defined(__LINUX__)) || (defined(ENABLE_PASSTHROUGH_MODE)) 1360a5c7a17Sopenharmony_ci uint32_t width = stream.width; 1370a5c7a17Sopenharmony_ci uint32_t height = stream.height; 1380a5c7a17Sopenharmony_ci#else 1390a5c7a17Sopenharmony_ci uint32_t width = g_surface->GetWidth(); 1400a5c7a17Sopenharmony_ci uint32_t height = g_surface->GetHeight(); 1410a5c7a17Sopenharmony_ci#endif 1420a5c7a17Sopenharmony_ci 1430a5c7a17Sopenharmony_ci MEDIA_DEBUG_LOG("width=%d", width); 1440a5c7a17Sopenharmony_ci param[paramIndex].key = KEY_VIDEO_WIDTH; 1450a5c7a17Sopenharmony_ci param[paramIndex].val = &width; 1460a5c7a17Sopenharmony_ci param[paramIndex].size = sizeof(uint32_t); 1470a5c7a17Sopenharmony_ci paramIndex++; 1480a5c7a17Sopenharmony_ci 1490a5c7a17Sopenharmony_ci MEDIA_DEBUG_LOG("height=%d", height); 1500a5c7a17Sopenharmony_ci param[paramIndex].key = KEY_VIDEO_HEIGHT; 1510a5c7a17Sopenharmony_ci param[paramIndex].val = &height; 1520a5c7a17Sopenharmony_ci param[paramIndex].size = sizeof(uint32_t); 1530a5c7a17Sopenharmony_ci paramIndex++; 1540a5c7a17Sopenharmony_ci 1550a5c7a17Sopenharmony_ci uint32_t frameRate = stream.fps; 1560a5c7a17Sopenharmony_ci MEDIA_DEBUG_LOG("frameRate=%u", frameRate); 1570a5c7a17Sopenharmony_ci param[paramIndex].key = KEY_VIDEO_FRAME_RATE; 1580a5c7a17Sopenharmony_ci param[paramIndex].val = &frameRate; 1590a5c7a17Sopenharmony_ci param[paramIndex].size = sizeof(uint32_t); 1600a5c7a17Sopenharmony_ci paramIndex++; 1610a5c7a17Sopenharmony_ci 1620a5c7a17Sopenharmony_ci uint32_t bitRate = GetDefaultBitrate(width, height); 1630a5c7a17Sopenharmony_ci MEDIA_DEBUG_LOG("bitRate=%u kbps", bitRate); 1640a5c7a17Sopenharmony_ci param[paramIndex].key = KEY_BITRATE; 1650a5c7a17Sopenharmony_ci param[paramIndex].val = &bitRate; 1660a5c7a17Sopenharmony_ci param[paramIndex].size = sizeof(uint32_t); 1670a5c7a17Sopenharmony_ci paramIndex++; 1680a5c7a17Sopenharmony_ci 1690a5c7a17Sopenharmony_ci int32_t ret = CodecCreateByType(domainKind, codecMime, codecHdl); 1700a5c7a17Sopenharmony_ci if (ret != 0) { 1710a5c7a17Sopenharmony_ci MEDIA_ERR_LOG("Create video encoder failed."); 1720a5c7a17Sopenharmony_ci return MEDIA_ERR; 1730a5c7a17Sopenharmony_ci } 1740a5c7a17Sopenharmony_ci 1750a5c7a17Sopenharmony_ci ret = CodecSetParameter(*codecHdl, param, paramIndex); 1760a5c7a17Sopenharmony_ci if (ret != 0) { 1770a5c7a17Sopenharmony_ci CodecDestroy(*codecHdl); 1780a5c7a17Sopenharmony_ci MEDIA_ERR_LOG("video CodecSetParameter failed."); 1790a5c7a17Sopenharmony_ci return MEDIA_ERR; 1800a5c7a17Sopenharmony_ci } 1810a5c7a17Sopenharmony_ci 1820a5c7a17Sopenharmony_ci ret = SetVencSource(*codecHdl, srcDev); 1830a5c7a17Sopenharmony_ci if (ret != 0) { 1840a5c7a17Sopenharmony_ci CodecDestroy(*codecHdl); 1850a5c7a17Sopenharmony_ci return MEDIA_ERR; 1860a5c7a17Sopenharmony_ci } 1870a5c7a17Sopenharmony_ci 1880a5c7a17Sopenharmony_ci return MEDIA_OK; 1890a5c7a17Sopenharmony_ci} 1900a5c7a17Sopenharmony_ci 1910a5c7a17Sopenharmony_cistatic void FillParam(Param ¶m, ParamKey key, uint8_t *data, uint32_t size) 1920a5c7a17Sopenharmony_ci{ 1930a5c7a17Sopenharmony_ci param.key = key; 1940a5c7a17Sopenharmony_ci param.val = data; 1950a5c7a17Sopenharmony_ci param.size = size; 1960a5c7a17Sopenharmony_ci} 1970a5c7a17Sopenharmony_ci 1980a5c7a17Sopenharmony_cistatic CODEC_HANDLETYPE CameraCreateJpegEncProc(FrameConfig &fc, uint32_t srcDev, AvCodecMime codecMime, 1990a5c7a17Sopenharmony_ci const Param* param, uint32_t paramNum) 2000a5c7a17Sopenharmony_ci{ 2010a5c7a17Sopenharmony_ci CODEC_HANDLETYPE codecHdl = nullptr; 2020a5c7a17Sopenharmony_ci if (CodecCreateByType(VIDEO_ENCODER, codecMime, &codecHdl) != 0) { 2030a5c7a17Sopenharmony_ci return nullptr; 2040a5c7a17Sopenharmony_ci } 2050a5c7a17Sopenharmony_ci 2060a5c7a17Sopenharmony_ci int32_t ret = CodecSetParameter(codecHdl, param, paramNum); 2070a5c7a17Sopenharmony_ci if (ret != 0) { 2080a5c7a17Sopenharmony_ci CodecDestroy(codecHdl); 2090a5c7a17Sopenharmony_ci return nullptr; 2100a5c7a17Sopenharmony_ci } 2110a5c7a17Sopenharmony_ci 2120a5c7a17Sopenharmony_ci int32_t qfactor = -1; 2130a5c7a17Sopenharmony_ci fc.GetParameter(PARAM_KEY_IMAGE_ENCODE_QFACTOR, qfactor); 2140a5c7a17Sopenharmony_ci if (qfactor != -1) { 2150a5c7a17Sopenharmony_ci Param jpegParam = { 2160a5c7a17Sopenharmony_ci .key = KEY_IMAGE_Q_FACTOR, 2170a5c7a17Sopenharmony_ci .val = &qfactor, 2180a5c7a17Sopenharmony_ci .size = sizeof(qfactor) 2190a5c7a17Sopenharmony_ci }; 2200a5c7a17Sopenharmony_ci ret = CodecSetParameter(codecHdl, &jpegParam, 1); 2210a5c7a17Sopenharmony_ci if (ret != 0) { 2220a5c7a17Sopenharmony_ci MEDIA_ERR_LOG("CodecSetParameter set jpeg qfactor failed.(ret=%u)", ret); 2230a5c7a17Sopenharmony_ci } 2240a5c7a17Sopenharmony_ci } 2250a5c7a17Sopenharmony_ci 2260a5c7a17Sopenharmony_ci ret = SetVencSource(codecHdl, srcDev); 2270a5c7a17Sopenharmony_ci if (ret != 0) { 2280a5c7a17Sopenharmony_ci MEDIA_ERR_LOG("Set video encoder source failed."); 2290a5c7a17Sopenharmony_ci CodecDestroy(codecHdl); 2300a5c7a17Sopenharmony_ci return nullptr; 2310a5c7a17Sopenharmony_ci } 2320a5c7a17Sopenharmony_ci return codecHdl; 2330a5c7a17Sopenharmony_ci} 2340a5c7a17Sopenharmony_ci 2350a5c7a17Sopenharmony_cistatic int32_t CameraCreateJpegEnc(FrameConfig &fc, StreamAttr stream, uint32_t srcDev, CODEC_HANDLETYPE *codecHdl) 2360a5c7a17Sopenharmony_ci{ 2370a5c7a17Sopenharmony_ci uint32_t maxParamNum = 10; /* 10 maxParamNum */ 2380a5c7a17Sopenharmony_ci Param param[maxParamNum]; 2390a5c7a17Sopenharmony_ci uint32_t paramIndex = 0; 2400a5c7a17Sopenharmony_ci 2410a5c7a17Sopenharmony_ci CodecType domainKind = VIDEO_ENCODER; 2420a5c7a17Sopenharmony_ci FillParam(param[paramIndex], KEY_CODEC_TYPE, reinterpret_cast<uint8_t *>(&domainKind), sizeof(CodecType)); 2430a5c7a17Sopenharmony_ci paramIndex++; 2440a5c7a17Sopenharmony_ci 2450a5c7a17Sopenharmony_ci AvCodecMime codecMime = ConverFormat(stream.format); 2460a5c7a17Sopenharmony_ci FillParam(param[paramIndex], KEY_MIMETYPE, reinterpret_cast<uint8_t *>(&codecMime), sizeof(AvCodecMime)); 2470a5c7a17Sopenharmony_ci paramIndex++; 2480a5c7a17Sopenharmony_ci 2490a5c7a17Sopenharmony_ci auto surfaceList = fc.GetSurfaces(); 2500a5c7a17Sopenharmony_ci Surface *surface = surfaceList.front(); 2510a5c7a17Sopenharmony_ci uint32_t width = surface->GetWidth(); 2520a5c7a17Sopenharmony_ci MEDIA_DEBUG_LOG("width=%d", width); 2530a5c7a17Sopenharmony_ci FillParam(param[paramIndex], KEY_VIDEO_WIDTH, reinterpret_cast<uint8_t *>(&width), sizeof(uint32_t)); 2540a5c7a17Sopenharmony_ci paramIndex++; 2550a5c7a17Sopenharmony_ci 2560a5c7a17Sopenharmony_ci uint32_t height = surface->GetHeight(); 2570a5c7a17Sopenharmony_ci MEDIA_DEBUG_LOG("height=%d", height); 2580a5c7a17Sopenharmony_ci FillParam(param[paramIndex], KEY_VIDEO_HEIGHT, reinterpret_cast<uint8_t *>(&height), sizeof(uint32_t)); 2590a5c7a17Sopenharmony_ci paramIndex++; 2600a5c7a17Sopenharmony_ci if (codecMime == MEDIA_MIMETYPE_VIDEO_HEVC) { 2610a5c7a17Sopenharmony_ci VideoCodecRcMode rcMode = VID_CODEC_RC_FIXQP; 2620a5c7a17Sopenharmony_ci FillParam(param[paramIndex], KEY_VIDEO_RC_MODE, reinterpret_cast<uint8_t *>(&rcMode), sizeof(VideoCodecRcMode)); 2630a5c7a17Sopenharmony_ci paramIndex++; 2640a5c7a17Sopenharmony_ci 2650a5c7a17Sopenharmony_ci Profile profile = HEVC_MAIN_PROFILE; 2660a5c7a17Sopenharmony_ci FillParam(param[paramIndex], KEY_VIDEO_PROFILE, reinterpret_cast<uint8_t *>(&profile), sizeof(Profile)); 2670a5c7a17Sopenharmony_ci paramIndex++; 2680a5c7a17Sopenharmony_ci 2690a5c7a17Sopenharmony_ci uint32_t frameRate = stream.fps; 2700a5c7a17Sopenharmony_ci FillParam(param[paramIndex], KEY_VIDEO_FRAME_RATE, reinterpret_cast<uint8_t *>(&frameRate), sizeof(uint32_t)); 2710a5c7a17Sopenharmony_ci paramIndex++; 2720a5c7a17Sopenharmony_ci } 2730a5c7a17Sopenharmony_ci *codecHdl = CameraCreateJpegEncProc(fc, srcDev, codecMime, param, paramIndex); 2740a5c7a17Sopenharmony_ci return (*codecHdl != nullptr) ? MEDIA_OK : MEDIA_ERR; 2750a5c7a17Sopenharmony_ci} 2760a5c7a17Sopenharmony_ci 2770a5c7a17Sopenharmony_cistatic int32_t CopyCodecOutput(uint8_t *dst, uint32_t *size, CodecBuffer *buffer) 2780a5c7a17Sopenharmony_ci{ 2790a5c7a17Sopenharmony_ci if (dst == nullptr || size == nullptr || buffer == nullptr) { 2800a5c7a17Sopenharmony_ci return MEDIA_ERR; 2810a5c7a17Sopenharmony_ci } 2820a5c7a17Sopenharmony_ci char *dstBuf = reinterpret_cast<char *>(dst); 2830a5c7a17Sopenharmony_ci for (uint32_t i = 0; i < buffer->bufferCnt; i++) { 2840a5c7a17Sopenharmony_ci uint32_t packSize = buffer->buffer[i].length - buffer->buffer[i].offset; 2850a5c7a17Sopenharmony_ci errno_t ret = memcpy_s(dstBuf, *size, (void *)(buffer->buffer[i].buf + buffer->buffer[i].offset), packSize); 2860a5c7a17Sopenharmony_ci if (ret != EOK) { 2870a5c7a17Sopenharmony_ci return MEDIA_ERR; 2880a5c7a17Sopenharmony_ci } 2890a5c7a17Sopenharmony_ci *size -= packSize; 2900a5c7a17Sopenharmony_ci dstBuf += packSize; 2910a5c7a17Sopenharmony_ci } 2920a5c7a17Sopenharmony_ci return MEDIA_OK; 2930a5c7a17Sopenharmony_ci} 2940a5c7a17Sopenharmony_ci 2950a5c7a17Sopenharmony_cistatic void StreamAttrInitialize(StreamAttr *streamAttr, Surface *surface, 2960a5c7a17Sopenharmony_ci StreamType streamType, FrameConfig &fc) 2970a5c7a17Sopenharmony_ci{ 2980a5c7a17Sopenharmony_ci if (streamAttr == nullptr || surface == nullptr) { 2990a5c7a17Sopenharmony_ci return; 3000a5c7a17Sopenharmony_ci } 3010a5c7a17Sopenharmony_ci (void)memset_s(streamAttr, sizeof(StreamAttr), 0, sizeof(StreamAttr)); 3020a5c7a17Sopenharmony_ci streamAttr->type = streamType; 3030a5c7a17Sopenharmony_ci fc.GetParameter(CAM_IMAGE_FORMAT, streamAttr->format); 3040a5c7a17Sopenharmony_ci streamAttr->width = surface->GetWidth(); 3050a5c7a17Sopenharmony_ci streamAttr->height = surface->GetHeight(); 3060a5c7a17Sopenharmony_ci fc.GetParameter(CAM_FRAME_FPS, streamAttr->fps); 3070a5c7a17Sopenharmony_ci fc.GetParameter(CAM_IMAGE_INVERT_MODE, streamAttr->invertMode); 3080a5c7a17Sopenharmony_ci fc.GetParameter(CAM_IMAGE_CROP_RECT, streamAttr->crop); 3090a5c7a17Sopenharmony_ci} 3100a5c7a17Sopenharmony_ci 3110a5c7a17Sopenharmony_cistatic ImageFormat Convert2HalImageFormat(uint32_t format) 3120a5c7a17Sopenharmony_ci{ 3130a5c7a17Sopenharmony_ci if (format == CAM_IMAGE_RAW12) { 3140a5c7a17Sopenharmony_ci return FORMAT_RGB_BAYER_12BPP; 3150a5c7a17Sopenharmony_ci } 3160a5c7a17Sopenharmony_ci return FORMAT_YVU420; 3170a5c7a17Sopenharmony_ci} 3180a5c7a17Sopenharmony_ci 3190a5c7a17Sopenharmony_cistatic int32_t SurfaceSetSize(SurfaceBuffer* surfaceBuf, Surface* surface, uint32_t size) 3200a5c7a17Sopenharmony_ci{ 3210a5c7a17Sopenharmony_ci#if (!defined(__LINUX__)) || (defined(ENABLE_PASSTHROUGH_MODE)) 3220a5c7a17Sopenharmony_ci surfaceBuf->SetSize(surface->GetSize() - size); 3230a5c7a17Sopenharmony_ci if (surface->FlushBuffer(surfaceBuf) != 0) { 3240a5c7a17Sopenharmony_ci MEDIA_ERR_LOG("Flush g_surface failed."); 3250a5c7a17Sopenharmony_ci surface->CancelBuffer(surfaceBuf); 3260a5c7a17Sopenharmony_ci return -1; 3270a5c7a17Sopenharmony_ci } 3280a5c7a17Sopenharmony_ci#else 3290a5c7a17Sopenharmony_ci surfaceBuf->SetSize(g_surface->GetSize() - size); 3300a5c7a17Sopenharmony_ci if (g_surface->FlushBuffer(surfaceBuf) != 0) { 3310a5c7a17Sopenharmony_ci MEDIA_ERR_LOG("Flush surface failed."); 3320a5c7a17Sopenharmony_ci g_surface->CancelBuffer(surfaceBuf); 3330a5c7a17Sopenharmony_ci return -1; 3340a5c7a17Sopenharmony_ci } 3350a5c7a17Sopenharmony_ci#endif 3360a5c7a17Sopenharmony_ci return 0; 3370a5c7a17Sopenharmony_ci} 3380a5c7a17Sopenharmony_ci 3390a5c7a17Sopenharmony_ciint32_t RecordAssistant::OnVencBufferAvailble(UINTPTR userData, CodecBuffer* outBuf, int32_t *acquireFd) 3400a5c7a17Sopenharmony_ci{ 3410a5c7a17Sopenharmony_ci (void)acquireFd; 3420a5c7a17Sopenharmony_ci CodecDesc* codecInfo = reinterpret_cast<CodecDesc* >(userData); 3430a5c7a17Sopenharmony_ci list<Surface*> *surfaceList = &codecInfo->vencSurfaces_; 3440a5c7a17Sopenharmony_ci if (surfaceList == nullptr || surfaceList->empty()) { 3450a5c7a17Sopenharmony_ci MEDIA_ERR_LOG("Encoder handle is illegal."); 3460a5c7a17Sopenharmony_ci return MEDIA_ERR; 3470a5c7a17Sopenharmony_ci } 3480a5c7a17Sopenharmony_ci int32_t ret = -1; 3490a5c7a17Sopenharmony_ci for (auto &surface : *surfaceList) { 3500a5c7a17Sopenharmony_ci#if (!defined(__LINUX__)) || (defined(ENABLE_PASSTHROUGH_MODE)) 3510a5c7a17Sopenharmony_ci SurfaceBuffer *surfaceBuf = surface->RequestBuffer(); 3520a5c7a17Sopenharmony_ci#else 3530a5c7a17Sopenharmony_ci SurfaceBuffer *surfaceBuf = g_surface->RequestBuffer(); 3540a5c7a17Sopenharmony_ci#endif 3550a5c7a17Sopenharmony_ci if (surfaceBuf == nullptr) { 3560a5c7a17Sopenharmony_ci MEDIA_ERR_LOG("No available buffer in surface."); 3570a5c7a17Sopenharmony_ci break; 3580a5c7a17Sopenharmony_ci } 3590a5c7a17Sopenharmony_ci#if (!defined(__LINUX__)) || (defined(ENABLE_PASSTHROUGH_MODE)) 3600a5c7a17Sopenharmony_ci uint32_t size = surface->GetSize(); 3610a5c7a17Sopenharmony_ci#else 3620a5c7a17Sopenharmony_ci uint32_t size = g_surface->GetSize(); 3630a5c7a17Sopenharmony_ci#endif 3640a5c7a17Sopenharmony_ci void *buf = surfaceBuf->GetVirAddr(); 3650a5c7a17Sopenharmony_ci if (buf == nullptr) { 3660a5c7a17Sopenharmony_ci MEDIA_ERR_LOG("Invalid buffer address."); 3670a5c7a17Sopenharmony_ci break; 3680a5c7a17Sopenharmony_ci } 3690a5c7a17Sopenharmony_ci ret = CopyCodecOutput((uint8_t*)buf, &size, outBuf); 3700a5c7a17Sopenharmony_ci if (ret != MEDIA_OK) { 3710a5c7a17Sopenharmony_ci MEDIA_ERR_LOG("No available outBuf in surface."); 3720a5c7a17Sopenharmony_ci#if (!defined(__LINUX__)) || (defined(ENABLE_PASSTHROUGH_MODE)) 3730a5c7a17Sopenharmony_ci surface->CancelBuffer(surfaceBuf); 3740a5c7a17Sopenharmony_ci#else 3750a5c7a17Sopenharmony_ci g_surface->CancelBuffer(surfaceBuf); 3760a5c7a17Sopenharmony_ci#endif 3770a5c7a17Sopenharmony_ci break; 3780a5c7a17Sopenharmony_ci } 3790a5c7a17Sopenharmony_ci surfaceBuf->SetInt32(KEY_IS_SYNC_FRAME, (((outBuf->flag & STREAM_FLAG_KEYFRAME) == 0) ? 0 : 1)); 3800a5c7a17Sopenharmony_ci surfaceBuf->SetInt64(KEY_TIME_US, outBuf->timeStamp); 3810a5c7a17Sopenharmony_ci ret = SurfaceSetSize(surfaceBuf, surface, size); 3820a5c7a17Sopenharmony_ci if (ret != 0) { 3830a5c7a17Sopenharmony_ci break; 3840a5c7a17Sopenharmony_ci } 3850a5c7a17Sopenharmony_ci } 3860a5c7a17Sopenharmony_ci if (CodecQueueOutput(codecInfo->vencHdl_, outBuf, 0, -1) != 0) { 3870a5c7a17Sopenharmony_ci MEDIA_ERR_LOG("Codec queue output failed."); 3880a5c7a17Sopenharmony_ci } 3890a5c7a17Sopenharmony_ci return ret; 3900a5c7a17Sopenharmony_ci} 3910a5c7a17Sopenharmony_ci 3920a5c7a17Sopenharmony_ciCodecCallback RecordAssistant::recordCodecCb_ = {nullptr, nullptr, RecordAssistant::OnVencBufferAvailble}; 3930a5c7a17Sopenharmony_ci 3940a5c7a17Sopenharmony_civoid RecordAssistant::ClearFrameConfig() 3950a5c7a17Sopenharmony_ci{ 3960a5c7a17Sopenharmony_ci for (uint32_t i = 0; i < codecInfo_.size(); i++) { 3970a5c7a17Sopenharmony_ci CodecStop(codecInfo_[i].vencHdl_); 3980a5c7a17Sopenharmony_ci CodecDestroy(codecInfo_[i].vencHdl_); 3990a5c7a17Sopenharmony_ci } 4000a5c7a17Sopenharmony_ci codecInfo_.clear(); 4010a5c7a17Sopenharmony_ci} 4020a5c7a17Sopenharmony_ci 4030a5c7a17Sopenharmony_ciint32_t RecordAssistant::SetFrameConfigEnd(int32_t result) 4040a5c7a17Sopenharmony_ci{ 4050a5c7a17Sopenharmony_ci if (result != MEDIA_OK) { 4060a5c7a17Sopenharmony_ci for (uint32_t i = 0; i < codecInfo_.size(); i++) { 4070a5c7a17Sopenharmony_ci CodecDestroy(codecInfo_[i].vencHdl_); 4080a5c7a17Sopenharmony_ci } 4090a5c7a17Sopenharmony_ci codecInfo_.clear(); 4100a5c7a17Sopenharmony_ci return result; 4110a5c7a17Sopenharmony_ci } 4120a5c7a17Sopenharmony_ci for (uint32_t i = 0; i < codecInfo_.size(); i++) { 4130a5c7a17Sopenharmony_ci result = CodecSetCallback(codecInfo_[i].vencHdl_, &recordCodecCb_, reinterpret_cast<UINTPTR>(&codecInfo_[i])); 4140a5c7a17Sopenharmony_ci if (result != 0) { 4150a5c7a17Sopenharmony_ci MEDIA_ERR_LOG("set CodecSetCallback failed ret:%d", result); 4160a5c7a17Sopenharmony_ci CodecDestroy(codecInfo_[i].vencHdl_); 4170a5c7a17Sopenharmony_ci break; 4180a5c7a17Sopenharmony_ci } 4190a5c7a17Sopenharmony_ci } 4200a5c7a17Sopenharmony_ci 4210a5c7a17Sopenharmony_ci if (result == MEDIA_OK) { 4220a5c7a17Sopenharmony_ci state_ = LOOP_READY; 4230a5c7a17Sopenharmony_ci } else { 4240a5c7a17Sopenharmony_ci for (uint32_t i = 0; i < codecInfo_.size(); i++) { 4250a5c7a17Sopenharmony_ci CodecDestroy(codecInfo_[i].vencHdl_); 4260a5c7a17Sopenharmony_ci } 4270a5c7a17Sopenharmony_ci codecInfo_.clear(); 4280a5c7a17Sopenharmony_ci } 4290a5c7a17Sopenharmony_ci return result; 4300a5c7a17Sopenharmony_ci} 4310a5c7a17Sopenharmony_ci 4320a5c7a17Sopenharmony_ciint32_t RecordAssistant::SetFrameConfig(FrameConfig &fc, uint32_t *streamId) 4330a5c7a17Sopenharmony_ci{ 4340a5c7a17Sopenharmony_ci fc_ = &fc; 4350a5c7a17Sopenharmony_ci auto surfaceList = fc.GetSurfaces(); 4360a5c7a17Sopenharmony_ci if (surfaceList.size() > VIDEO_MAX_NUM || surfaceList.size() == 0) { 4370a5c7a17Sopenharmony_ci MEDIA_ERR_LOG("the number of surface in frame config must 1 or 2 now.\n"); 4380a5c7a17Sopenharmony_ci return MEDIA_ERR; 4390a5c7a17Sopenharmony_ci } 4400a5c7a17Sopenharmony_ci uint32_t num = 0; 4410a5c7a17Sopenharmony_ci int32_t ret = MEDIA_OK; 4420a5c7a17Sopenharmony_ci for (auto &surface : surfaceList) { 4430a5c7a17Sopenharmony_ci CODEC_HANDLETYPE codecHdl = nullptr; 4440a5c7a17Sopenharmony_ci StreamAttr stream = {}; 4450a5c7a17Sopenharmony_ci#if (!defined(__LINUX__)) || (defined(ENABLE_PASSTHROUGH_MODE)) 4460a5c7a17Sopenharmony_ci StreamAttrInitialize(&stream, surface, STREAM_VIDEO, fc); 4470a5c7a17Sopenharmony_ci#else 4480a5c7a17Sopenharmony_ci StreamAttrInitialize(&stream, g_surface, STREAM_VIDEO, fc); 4490a5c7a17Sopenharmony_ci#endif 4500a5c7a17Sopenharmony_ci ret = HalCameraStreamCreate(cameraId_, &stream, streamId); 4510a5c7a17Sopenharmony_ci if (ret != MEDIA_OK) { 4520a5c7a17Sopenharmony_ci MEDIA_ERR_LOG(" creat recorder stream failed."); 4530a5c7a17Sopenharmony_ci ClearFrameConfig(); 4540a5c7a17Sopenharmony_ci break; 4550a5c7a17Sopenharmony_ci } 4560a5c7a17Sopenharmony_ci streamId_ = *streamId; 4570a5c7a17Sopenharmony_ci streamIdNum_[num] = *streamId; 4580a5c7a17Sopenharmony_ci num++; 4590a5c7a17Sopenharmony_ci 4600a5c7a17Sopenharmony_ci StreamInfo streamInfo; 4610a5c7a17Sopenharmony_ci streamInfo.type = STERAM_INFO_PRIVATE; 4620a5c7a17Sopenharmony_ci fc.GetVendorParameter(streamInfo.u.data, PRIVATE_TAG_LEN); 4630a5c7a17Sopenharmony_ci HalCameraStreamSetInfo(cameraId_, *streamId, &streamInfo); 4640a5c7a17Sopenharmony_ci 4650a5c7a17Sopenharmony_ci uint32_t deviceId = 0; 4660a5c7a17Sopenharmony_ci HalCameraGetDeviceId(cameraId_, *streamId, &deviceId); 4670a5c7a17Sopenharmony_ci ret = CameraCreateVideoEnc(fc, stream, deviceId, &codecHdl); 4680a5c7a17Sopenharmony_ci if (ret != MEDIA_OK) { 4690a5c7a17Sopenharmony_ci MEDIA_ERR_LOG("Cannot create suitble video encoder."); 4700a5c7a17Sopenharmony_ci ClearFrameConfig(); 4710a5c7a17Sopenharmony_ci break; 4720a5c7a17Sopenharmony_ci } 4730a5c7a17Sopenharmony_ci#if (!defined(__LINUX__)) || (defined(ENABLE_PASSTHROUGH_MODE)) 4740a5c7a17Sopenharmony_ci list<Surface*> conList({surface}); 4750a5c7a17Sopenharmony_ci#else 4760a5c7a17Sopenharmony_ci list<Surface*> conList({g_surface}); 4770a5c7a17Sopenharmony_ci#endif 4780a5c7a17Sopenharmony_ci CodecDesc info; 4790a5c7a17Sopenharmony_ci info.vencHdl_ = codecHdl; 4800a5c7a17Sopenharmony_ci info.vencSurfaces_ = conList; 4810a5c7a17Sopenharmony_ci codecInfo_.emplace_back(info); 4820a5c7a17Sopenharmony_ci } 4830a5c7a17Sopenharmony_ci return SetFrameConfigEnd(ret); 4840a5c7a17Sopenharmony_ci} 4850a5c7a17Sopenharmony_ci 4860a5c7a17Sopenharmony_ciint32_t RecordAssistant::Start(uint32_t streamId) 4870a5c7a17Sopenharmony_ci{ 4880a5c7a17Sopenharmony_ci if (state_ != LOOP_READY) { 4890a5c7a17Sopenharmony_ci return MEDIA_ERR; 4900a5c7a17Sopenharmony_ci } 4910a5c7a17Sopenharmony_ci HalCameraStreamOn(cameraId_, streamId); 4920a5c7a17Sopenharmony_ci int32_t ret = MEDIA_OK; 4930a5c7a17Sopenharmony_ci int32_t i; 4940a5c7a17Sopenharmony_ci for (i = 0; static_cast<uint32_t>(i) < codecInfo_.size(); i++) { 4950a5c7a17Sopenharmony_ci ret = CodecStart(codecInfo_[i].vencHdl_); 4960a5c7a17Sopenharmony_ci if (ret != MEDIA_OK) { 4970a5c7a17Sopenharmony_ci MEDIA_ERR_LOG("Video encoder start failed."); 4980a5c7a17Sopenharmony_ci ret = MEDIA_ERR; 4990a5c7a17Sopenharmony_ci break; 5000a5c7a17Sopenharmony_ci } 5010a5c7a17Sopenharmony_ci } 5020a5c7a17Sopenharmony_ci if (ret == MEDIA_ERR) { 5030a5c7a17Sopenharmony_ci /* rollback */ 5040a5c7a17Sopenharmony_ci for (; i >= 0; i--) { 5050a5c7a17Sopenharmony_ci CodecStop(codecInfo_[i].vencHdl_); 5060a5c7a17Sopenharmony_ci } 5070a5c7a17Sopenharmony_ci return MEDIA_ERR; 5080a5c7a17Sopenharmony_ci } 5090a5c7a17Sopenharmony_ci state_ = LOOP_LOOPING; 5100a5c7a17Sopenharmony_ci MEDIA_INFO_LOG("Start camera recording succeed."); 5110a5c7a17Sopenharmony_ci return MEDIA_OK; 5120a5c7a17Sopenharmony_ci} 5130a5c7a17Sopenharmony_ci 5140a5c7a17Sopenharmony_ciint32_t RecordAssistant::Stop() 5150a5c7a17Sopenharmony_ci{ 5160a5c7a17Sopenharmony_ci if (state_ != LOOP_LOOPING) { 5170a5c7a17Sopenharmony_ci return MEDIA_ERR; 5180a5c7a17Sopenharmony_ci } 5190a5c7a17Sopenharmony_ci ClearFrameConfig(); 5200a5c7a17Sopenharmony_ci for (uint32_t i = 0; i < VIDEO_MAX_NUM; i++) { 5210a5c7a17Sopenharmony_ci if (streamIdNum_[i] != INVALID_STREAM_ID) { 5220a5c7a17Sopenharmony_ci HalCameraStreamOff(cameraId_, streamIdNum_[i]); 5230a5c7a17Sopenharmony_ci HalCameraStreamDestroy(cameraId_, streamIdNum_[i]); 5240a5c7a17Sopenharmony_ci } 5250a5c7a17Sopenharmony_ci streamIdNum_[i] = INVALID_STREAM_ID; 5260a5c7a17Sopenharmony_ci } 5270a5c7a17Sopenharmony_ci state_ = LOOP_STOP; 5280a5c7a17Sopenharmony_ci return MEDIA_OK; 5290a5c7a17Sopenharmony_ci} 5300a5c7a17Sopenharmony_ci 5310a5c7a17Sopenharmony_civoid* PreviewAssistant::YuvCopyProcess(void *arg) 5320a5c7a17Sopenharmony_ci{ 5330a5c7a17Sopenharmony_ci return nullptr; 5340a5c7a17Sopenharmony_ci} 5350a5c7a17Sopenharmony_ci 5360a5c7a17Sopenharmony_cistatic void GetSurfaceRect(Surface *surface, IRect *attr) 5370a5c7a17Sopenharmony_ci{ 5380a5c7a17Sopenharmony_ci attr->x = std::stoi(surface->GetUserData(string("region_position_x"))); 5390a5c7a17Sopenharmony_ci attr->y = std::stoi(surface->GetUserData(string("region_position_y"))); 5400a5c7a17Sopenharmony_ci attr->w = std::stoi(surface->GetUserData(string("region_width"))); 5410a5c7a17Sopenharmony_ci attr->h = std::stoi(surface->GetUserData(string("region_hegiht"))); 5420a5c7a17Sopenharmony_ci} 5430a5c7a17Sopenharmony_ci 5440a5c7a17Sopenharmony_ciint32_t PreviewAssistant::SetFrameConfig(FrameConfig &fc, uint32_t *streamId) 5450a5c7a17Sopenharmony_ci{ 5460a5c7a17Sopenharmony_ci fc_ = &fc; 5470a5c7a17Sopenharmony_ci auto surfaceList = fc.GetSurfaces(); 5480a5c7a17Sopenharmony_ci if (surfaceList.size() != 1) { 5490a5c7a17Sopenharmony_ci MEDIA_ERR_LOG("Only support one surface in frame config now."); 5500a5c7a17Sopenharmony_ci return MEDIA_ERR; 5510a5c7a17Sopenharmony_ci } 5520a5c7a17Sopenharmony_ci Surface *surface = surfaceList.front(); 5530a5c7a17Sopenharmony_ci StreamAttr stream = {}; 5540a5c7a17Sopenharmony_ci StreamAttrInitialize(&stream, surface, STREAM_PREVIEW, fc); 5550a5c7a17Sopenharmony_ci int32_t ret = HalCameraStreamCreate(cameraId_, &stream, streamId); 5560a5c7a17Sopenharmony_ci if (ret != MEDIA_OK) { 5570a5c7a17Sopenharmony_ci MEDIA_ERR_LOG(" creat preview stream failed."); 5580a5c7a17Sopenharmony_ci return MEDIA_ERR; 5590a5c7a17Sopenharmony_ci } 5600a5c7a17Sopenharmony_ci StreamInfo streamInfo; 5610a5c7a17Sopenharmony_ci streamInfo.type = STREAM_INFO_POS; 5620a5c7a17Sopenharmony_ci streamInfo.u.pos.x = std::stoi(surface->GetUserData(string("region_position_x"))); 5630a5c7a17Sopenharmony_ci streamInfo.u.pos.y = std::stoi(surface->GetUserData(string("region_position_y"))); 5640a5c7a17Sopenharmony_ci 5650a5c7a17Sopenharmony_ci HalCameraStreamSetInfo(cameraId_, *streamId, &streamInfo); 5660a5c7a17Sopenharmony_ci streamId_ = *streamId; 5670a5c7a17Sopenharmony_ci return MEDIA_OK; 5680a5c7a17Sopenharmony_ci} 5690a5c7a17Sopenharmony_ci 5700a5c7a17Sopenharmony_ciint32_t PreviewAssistant::Start(uint32_t streamId) 5710a5c7a17Sopenharmony_ci{ 5720a5c7a17Sopenharmony_ci if (state_ == LOOP_LOOPING) { 5730a5c7a17Sopenharmony_ci return MEDIA_ERR; 5740a5c7a17Sopenharmony_ci } 5750a5c7a17Sopenharmony_ci state_ = LOOP_LOOPING; 5760a5c7a17Sopenharmony_ci 5770a5c7a17Sopenharmony_ci int32_t retCode = pthread_create(&threadId, nullptr, YuvCopyProcess, this); 5780a5c7a17Sopenharmony_ci if (retCode != 0) { 5790a5c7a17Sopenharmony_ci MEDIA_ERR_LOG("fork thread YuvCopyProcess failed: %d.", retCode); 5800a5c7a17Sopenharmony_ci } 5810a5c7a17Sopenharmony_ci 5820a5c7a17Sopenharmony_ci int32_t ret = HalCameraStreamOn(cameraId_, streamId); 5830a5c7a17Sopenharmony_ci if (ret != MEDIA_OK) { 5840a5c7a17Sopenharmony_ci MEDIA_ERR_LOG("Preview start failed of HalCameraStreamOn.(ret=%d)", ret); 5850a5c7a17Sopenharmony_ci Stop(); 5860a5c7a17Sopenharmony_ci return MEDIA_ERR; 5870a5c7a17Sopenharmony_ci } 5880a5c7a17Sopenharmony_ci return MEDIA_OK; 5890a5c7a17Sopenharmony_ci} 5900a5c7a17Sopenharmony_ci 5910a5c7a17Sopenharmony_ciint32_t PreviewAssistant::Stop() 5920a5c7a17Sopenharmony_ci{ 5930a5c7a17Sopenharmony_ci if (state_ != LOOP_LOOPING) { 5940a5c7a17Sopenharmony_ci return MEDIA_ERR; 5950a5c7a17Sopenharmony_ci } 5960a5c7a17Sopenharmony_ci state_ = LOOP_STOP; 5970a5c7a17Sopenharmony_ci pthread_join(threadId, NULL); 5980a5c7a17Sopenharmony_ci HalCameraStreamOff(cameraId_, streamId_); 5990a5c7a17Sopenharmony_ci HalCameraStreamDestroy(cameraId_, streamId_); 6000a5c7a17Sopenharmony_ci return MEDIA_OK; 6010a5c7a17Sopenharmony_ci} 6020a5c7a17Sopenharmony_ci 6030a5c7a17Sopenharmony_ciint32_t CaptureAssistant::SetFrameConfig(FrameConfig &fc, uint32_t *streamId) 6040a5c7a17Sopenharmony_ci{ 6050a5c7a17Sopenharmony_ci auto surfaceList = fc.GetSurfaces(); 6060a5c7a17Sopenharmony_ci if (surfaceList.size() != 1) { 6070a5c7a17Sopenharmony_ci MEDIA_ERR_LOG("Only support one surface in frame config now."); 6080a5c7a17Sopenharmony_ci return MEDIA_ERR; 6090a5c7a17Sopenharmony_ci } 6100a5c7a17Sopenharmony_ci if (surfaceList.empty()) { 6110a5c7a17Sopenharmony_ci MEDIA_ERR_LOG("Frame config with empty surface list."); 6120a5c7a17Sopenharmony_ci return MEDIA_ERR; 6130a5c7a17Sopenharmony_ci } 6140a5c7a17Sopenharmony_ci if (surfaceList.size() > 1) { 6150a5c7a17Sopenharmony_ci MEDIA_WARNING_LOG("Capture only fullfill the first surface in frame config."); 6160a5c7a17Sopenharmony_ci } 6170a5c7a17Sopenharmony_ci Surface *surface = surfaceList.front(); 6180a5c7a17Sopenharmony_ci 6190a5c7a17Sopenharmony_ci StreamAttr stream = {}; 6200a5c7a17Sopenharmony_ci StreamAttrInitialize(&stream, surface, STREAM_CAPTURE, fc); 6210a5c7a17Sopenharmony_ci 6220a5c7a17Sopenharmony_ci uint32_t deviceId = 0; 6230a5c7a17Sopenharmony_ci int32_t ret = HalCameraStreamCreate(cameraId_, &stream, streamId); 6240a5c7a17Sopenharmony_ci if (ret != MEDIA_OK) { 6250a5c7a17Sopenharmony_ci MEDIA_ERR_LOG(" creat capture stream failed."); 6260a5c7a17Sopenharmony_ci return MEDIA_ERR; 6270a5c7a17Sopenharmony_ci } 6280a5c7a17Sopenharmony_ci streamId_ = *streamId; 6290a5c7a17Sopenharmony_ci HalCameraGetDeviceId(cameraId_, *streamId, &deviceId); 6300a5c7a17Sopenharmony_ci ret = CameraCreateJpegEnc(fc, stream, deviceId, &vencHdl_); 6310a5c7a17Sopenharmony_ci if (ret != MEDIA_OK) { 6320a5c7a17Sopenharmony_ci MEDIA_ERR_LOG("Create capture venc failed."); 6330a5c7a17Sopenharmony_ci return MEDIA_ERR; 6340a5c7a17Sopenharmony_ci } 6350a5c7a17Sopenharmony_ci 6360a5c7a17Sopenharmony_ci capSurface_ = surface; 6370a5c7a17Sopenharmony_ci state_ = LOOP_READY; 6380a5c7a17Sopenharmony_ci return MEDIA_OK; 6390a5c7a17Sopenharmony_ci} 6400a5c7a17Sopenharmony_ci 6410a5c7a17Sopenharmony_ci/* Block method, waiting for capture completed */ 6420a5c7a17Sopenharmony_ciint32_t CaptureAssistant::Start(uint32_t streamId) 6430a5c7a17Sopenharmony_ci{ 6440a5c7a17Sopenharmony_ci state_ = LOOP_LOOPING; 6450a5c7a17Sopenharmony_ci HalCameraStreamOn(cameraId_, streamId); 6460a5c7a17Sopenharmony_ci int32_t ret = CodecStart(vencHdl_); 6470a5c7a17Sopenharmony_ci if (ret != 0) { 6480a5c7a17Sopenharmony_ci MEDIA_ERR_LOG("Start capture encoder failed.(ret=%d)", ret); 6490a5c7a17Sopenharmony_ci state_ = LOOP_STOP; 6500a5c7a17Sopenharmony_ci return MEDIA_ERR; 6510a5c7a17Sopenharmony_ci } 6520a5c7a17Sopenharmony_ci 6530a5c7a17Sopenharmony_ci CodecBuffer* outInfo = (CodecBuffer*)new char[sizeof(CodecBuffer) + sizeof(CodecBufferInfo) * 3]; /* 3 buffCnt */ 6540a5c7a17Sopenharmony_ci if (outInfo == NULL) { 6550a5c7a17Sopenharmony_ci MEDIA_ERR_LOG("malloc Dequeue buffer failed!"); 6560a5c7a17Sopenharmony_ci return MEDIA_ERR; 6570a5c7a17Sopenharmony_ci } 6580a5c7a17Sopenharmony_ci SurfaceBuffer *surfaceBuf = NULL; 6590a5c7a17Sopenharmony_ci do { 6600a5c7a17Sopenharmony_ci if (memset_s(outInfo, sizeof(CodecBuffer) + sizeof(CodecBufferInfo) * 0x3, 0, 6610a5c7a17Sopenharmony_ci sizeof(CodecBuffer) + sizeof(CodecBufferInfo) * 3) != MEDIA_OK) { /* 3 buffCnt */ 6620a5c7a17Sopenharmony_ci MEDIA_ERR_LOG("memset_s failed!"); 6630a5c7a17Sopenharmony_ci delete(outInfo); 6640a5c7a17Sopenharmony_ci return MEDIA_ERR; 6650a5c7a17Sopenharmony_ci } 6660a5c7a17Sopenharmony_ci outInfo->bufferCnt = 3; /* 3 buffCnt */ 6670a5c7a17Sopenharmony_ci ret = CodecDequeueOutput(vencHdl_, 0, nullptr, outInfo); 6680a5c7a17Sopenharmony_ci if (ret != 0) { 6690a5c7a17Sopenharmony_ci MEDIA_ERR_LOG("Dequeue capture frame failed.(ret=%d)", ret); 6700a5c7a17Sopenharmony_ci break; 6710a5c7a17Sopenharmony_ci } 6720a5c7a17Sopenharmony_ci 6730a5c7a17Sopenharmony_ci surfaceBuf = capSurface_->RequestBuffer(); 6740a5c7a17Sopenharmony_ci if (surfaceBuf == NULL) { 6750a5c7a17Sopenharmony_ci break; 6760a5c7a17Sopenharmony_ci } 6770a5c7a17Sopenharmony_ci 6780a5c7a17Sopenharmony_ci uint32_t size = capSurface_->GetSize(); 6790a5c7a17Sopenharmony_ci void *buf = surfaceBuf->GetVirAddr(); 6800a5c7a17Sopenharmony_ci if (buf == nullptr) { 6810a5c7a17Sopenharmony_ci MEDIA_ERR_LOG("Invalid buffer address."); 6820a5c7a17Sopenharmony_ci break; 6830a5c7a17Sopenharmony_ci } 6840a5c7a17Sopenharmony_ci if (CopyCodecOutput((uint8_t*)buf, &size, outInfo) != MEDIA_OK) { 6850a5c7a17Sopenharmony_ci MEDIA_ERR_LOG("No available buffer in capSurface_."); 6860a5c7a17Sopenharmony_ci break; 6870a5c7a17Sopenharmony_ci } 6880a5c7a17Sopenharmony_ci surfaceBuf->SetSize(capSurface_->GetSize() - size); 6890a5c7a17Sopenharmony_ci if (capSurface_->FlushBuffer(surfaceBuf) != 0) { 6900a5c7a17Sopenharmony_ci MEDIA_ERR_LOG("Flush surface buffer failed."); 6910a5c7a17Sopenharmony_ci break; 6920a5c7a17Sopenharmony_ci } 6930a5c7a17Sopenharmony_ci } while (0); 6940a5c7a17Sopenharmony_ci 6950a5c7a17Sopenharmony_ci CodecStop(vencHdl_); 6960a5c7a17Sopenharmony_ci CodecDestroy(vencHdl_); 6970a5c7a17Sopenharmony_ci HalCameraStreamOff(cameraId_, streamId); 6980a5c7a17Sopenharmony_ci HalCameraStreamDestroy(cameraId_, streamId); 6990a5c7a17Sopenharmony_ci delete outInfo; 7000a5c7a17Sopenharmony_ci outInfo = NULL; 7010a5c7a17Sopenharmony_ci state_ = LOOP_STOP; 7020a5c7a17Sopenharmony_ci 7030a5c7a17Sopenharmony_ci return ret; 7040a5c7a17Sopenharmony_ci} 7050a5c7a17Sopenharmony_ci 7060a5c7a17Sopenharmony_ciint32_t CaptureAssistant::Stop() 7070a5c7a17Sopenharmony_ci{ 7080a5c7a17Sopenharmony_ci MEDIA_DEBUG_LOG("No support method."); 7090a5c7a17Sopenharmony_ci return MEDIA_OK; 7100a5c7a17Sopenharmony_ci} 7110a5c7a17Sopenharmony_ci 7120a5c7a17Sopenharmony_ciint32_t CallbackAssistant::SetFrameConfig(FrameConfig &fc, uint32_t *streamId) 7130a5c7a17Sopenharmony_ci{ 7140a5c7a17Sopenharmony_ci fc_ = &fc; 7150a5c7a17Sopenharmony_ci auto surfaceList = fc.GetSurfaces(); 7160a5c7a17Sopenharmony_ci if (surfaceList.size() != 1) { 7170a5c7a17Sopenharmony_ci MEDIA_ERR_LOG("Only support one surface in frame config now."); 7180a5c7a17Sopenharmony_ci return MEDIA_ERR; 7190a5c7a17Sopenharmony_ci } 7200a5c7a17Sopenharmony_ci uint32_t imageFormat = 0; 7210a5c7a17Sopenharmony_ci fc.GetParameter(CAM_IMAGE_FORMAT, imageFormat); 7220a5c7a17Sopenharmony_ci ImageFormat halImageFormat = Convert2HalImageFormat(imageFormat); 7230a5c7a17Sopenharmony_ci MEDIA_INFO_LOG("Imageformat is %d", imageFormat); 7240a5c7a17Sopenharmony_ci Surface *surface = surfaceList.front(); 7250a5c7a17Sopenharmony_ci StreamAttr stream = {}; 7260a5c7a17Sopenharmony_ci StreamAttrInitialize(&stream, surface, STREAM_CALLBACK, fc); 7270a5c7a17Sopenharmony_ci stream.format = halImageFormat; 7280a5c7a17Sopenharmony_ci int32_t ret = HalCameraStreamCreate(cameraId_, &stream, streamId); 7290a5c7a17Sopenharmony_ci if (ret != MEDIA_OK) { 7300a5c7a17Sopenharmony_ci MEDIA_ERR_LOG(" creat callback stream failed."); 7310a5c7a17Sopenharmony_ci return MEDIA_ERR; 7320a5c7a17Sopenharmony_ci } 7330a5c7a17Sopenharmony_ci streamId_ = *streamId; 7340a5c7a17Sopenharmony_ci capSurface_ = surface; 7350a5c7a17Sopenharmony_ci state_ = LOOP_READY; 7360a5c7a17Sopenharmony_ci return MEDIA_OK; 7370a5c7a17Sopenharmony_ci} 7380a5c7a17Sopenharmony_ci 7390a5c7a17Sopenharmony_ciint32_t CallbackAssistant::Start(uint32_t streamId) 7400a5c7a17Sopenharmony_ci{ 7410a5c7a17Sopenharmony_ci if (state_ == LOOP_LOOPING) { 7420a5c7a17Sopenharmony_ci return MEDIA_ERR; 7430a5c7a17Sopenharmony_ci } 7440a5c7a17Sopenharmony_ci state_ = LOOP_LOOPING; 7450a5c7a17Sopenharmony_ci int32_t retCode = pthread_create(&threadId, nullptr, StreamCopyProcess, this); 7460a5c7a17Sopenharmony_ci if (retCode != 0) { 7470a5c7a17Sopenharmony_ci MEDIA_ERR_LOG("fork thread StreamCopyProcess failed: %d.", retCode); 7480a5c7a17Sopenharmony_ci } 7490a5c7a17Sopenharmony_ci HalCameraStreamOn(cameraId_, streamId); 7500a5c7a17Sopenharmony_ci return MEDIA_OK; 7510a5c7a17Sopenharmony_ci} 7520a5c7a17Sopenharmony_ci 7530a5c7a17Sopenharmony_civoid* CallbackAssistant::StreamCopyProcess(void *arg) 7540a5c7a17Sopenharmony_ci{ 7550a5c7a17Sopenharmony_ci CallbackAssistant *assistant = (CallbackAssistant *)arg; 7560a5c7a17Sopenharmony_ci if (assistant == nullptr) { 7570a5c7a17Sopenharmony_ci MEDIA_ERR_LOG("CallbackAssistant create failed."); 7580a5c7a17Sopenharmony_ci return nullptr; 7590a5c7a17Sopenharmony_ci } 7600a5c7a17Sopenharmony_ci if (assistant->capSurface_ == nullptr) { 7610a5c7a17Sopenharmony_ci MEDIA_ERR_LOG("capSurface_ is null.\n"); 7620a5c7a17Sopenharmony_ci return nullptr; 7630a5c7a17Sopenharmony_ci } 7640a5c7a17Sopenharmony_ci 7650a5c7a17Sopenharmony_ci int32_t ret; 7660a5c7a17Sopenharmony_ci HalBuffer streamBuffer; 7670a5c7a17Sopenharmony_ci (void)memset_s(&streamBuffer, sizeof(HalBuffer), 0, sizeof(HalBuffer)); 7680a5c7a17Sopenharmony_ci while (assistant->state_ == LOOP_LOOPING) { 7690a5c7a17Sopenharmony_ci SurfaceBuffer *surfaceBuf = assistant->capSurface_->RequestBuffer(); 7700a5c7a17Sopenharmony_ci if (surfaceBuf == nullptr) { 7710a5c7a17Sopenharmony_ci usleep(DELAY_TIME_ONE_FRAME); 7720a5c7a17Sopenharmony_ci continue; 7730a5c7a17Sopenharmony_ci } 7740a5c7a17Sopenharmony_ci 7750a5c7a17Sopenharmony_ci if (streamBuffer.size != 0x0) { 7760a5c7a17Sopenharmony_ci HalCameraQueueBuf(assistant->cameraId_, assistant->streamId_, &streamBuffer); 7770a5c7a17Sopenharmony_ci (void)memset_s(&streamBuffer, sizeof(HalBuffer), 0, sizeof(HalBuffer)); 7780a5c7a17Sopenharmony_ci } 7790a5c7a17Sopenharmony_ci streamBuffer.format = FORMAT_PRIVATE; 7800a5c7a17Sopenharmony_ci streamBuffer.size = assistant->capSurface_->GetSize(); 7810a5c7a17Sopenharmony_ci if (surfaceBuf->GetVirAddr() == NULL) { 7820a5c7a17Sopenharmony_ci MEDIA_ERR_LOG("Invalid buffer address."); 7830a5c7a17Sopenharmony_ci break; 7840a5c7a17Sopenharmony_ci } 7850a5c7a17Sopenharmony_ci streamBuffer.virAddr = surfaceBuf->GetVirAddr(); 7860a5c7a17Sopenharmony_ci 7870a5c7a17Sopenharmony_ci ret = HalCameraDequeueBuf(assistant->cameraId_, assistant->streamId_, &streamBuffer); 7880a5c7a17Sopenharmony_ci if (ret != MEDIA_OK) { 7890a5c7a17Sopenharmony_ci usleep(DELAY_TIME_ONE_FRAME); 7900a5c7a17Sopenharmony_ci continue; 7910a5c7a17Sopenharmony_ci } 7920a5c7a17Sopenharmony_ci 7930a5c7a17Sopenharmony_ci if (assistant->capSurface_->FlushBuffer(surfaceBuf) != 0) { 7940a5c7a17Sopenharmony_ci MEDIA_ERR_LOG("Flush surface failed."); 7950a5c7a17Sopenharmony_ci assistant->capSurface_->CancelBuffer(surfaceBuf); 7960a5c7a17Sopenharmony_ci break; 7970a5c7a17Sopenharmony_ci } 7980a5c7a17Sopenharmony_ci usleep(DELAY_TIME_ONE_FRAME); 7990a5c7a17Sopenharmony_ci } 8000a5c7a17Sopenharmony_ci if (streamBuffer.size != 0x0) { 8010a5c7a17Sopenharmony_ci HalCameraQueueBuf(assistant->cameraId_, assistant->streamId_, &streamBuffer); 8020a5c7a17Sopenharmony_ci } 8030a5c7a17Sopenharmony_ci MEDIA_DEBUG_LOG(" yuv thread joined \n"); 8040a5c7a17Sopenharmony_ci return nullptr; 8050a5c7a17Sopenharmony_ci} 8060a5c7a17Sopenharmony_ci 8070a5c7a17Sopenharmony_ciint32_t CallbackAssistant::Stop() 8080a5c7a17Sopenharmony_ci{ 8090a5c7a17Sopenharmony_ci if (state_ != LOOP_LOOPING) { 8100a5c7a17Sopenharmony_ci return MEDIA_ERR; 8110a5c7a17Sopenharmony_ci } 8120a5c7a17Sopenharmony_ci state_ = LOOP_STOP; 8130a5c7a17Sopenharmony_ci pthread_join(threadId, NULL); 8140a5c7a17Sopenharmony_ci HalCameraStreamOff(cameraId_, streamId_); 8150a5c7a17Sopenharmony_ci HalCameraStreamDestroy(cameraId_, streamId_); 8160a5c7a17Sopenharmony_ci return MEDIA_OK; 8170a5c7a17Sopenharmony_ci} 8180a5c7a17Sopenharmony_ci 8190a5c7a17Sopenharmony_ciCameraDevice::CameraDevice() {} 8200a5c7a17Sopenharmony_ciCameraDevice::CameraDevice(uint32_t cameraId) 8210a5c7a17Sopenharmony_ci{ 8220a5c7a17Sopenharmony_ci this->cameraId = cameraId; 8230a5c7a17Sopenharmony_ci} 8240a5c7a17Sopenharmony_ci 8250a5c7a17Sopenharmony_ciCameraDevice::~CameraDevice() {} 8260a5c7a17Sopenharmony_ci 8270a5c7a17Sopenharmony_ciint32_t CameraDevice::Initialize() 8280a5c7a17Sopenharmony_ci{ 8290a5c7a17Sopenharmony_ci // Need to be Refactored when delete config file 8300a5c7a17Sopenharmony_ci int32_t ret = CodecInit(); 8310a5c7a17Sopenharmony_ci if (ret != 0) { 8320a5c7a17Sopenharmony_ci MEDIA_ERR_LOG("Codec module init failed.(ret=%d)", ret); 8330a5c7a17Sopenharmony_ci return MEDIA_ERR; 8340a5c7a17Sopenharmony_ci } 8350a5c7a17Sopenharmony_ci MEDIA_INFO_LOG("Codec module init succeed."); 8360a5c7a17Sopenharmony_ci captureAssistant_.state_ = LOOP_READY; 8370a5c7a17Sopenharmony_ci previewAssistant_.state_ = LOOP_READY; 8380a5c7a17Sopenharmony_ci recordAssistant_.state_ = LOOP_READY; 8390a5c7a17Sopenharmony_ci callbackAssistant_.state_ = LOOP_READY; 8400a5c7a17Sopenharmony_ci captureAssistant_.cameraId_ = cameraId; 8410a5c7a17Sopenharmony_ci previewAssistant_.cameraId_ = cameraId; 8420a5c7a17Sopenharmony_ci recordAssistant_.cameraId_ = cameraId; 8430a5c7a17Sopenharmony_ci callbackAssistant_.cameraId_ = cameraId; 8440a5c7a17Sopenharmony_ci return MEDIA_OK; 8450a5c7a17Sopenharmony_ci} 8460a5c7a17Sopenharmony_ci 8470a5c7a17Sopenharmony_ciint32_t CameraDevice::UnInitialize() 8480a5c7a17Sopenharmony_ci{ 8490a5c7a17Sopenharmony_ci return MEDIA_OK; 8500a5c7a17Sopenharmony_ci} 8510a5c7a17Sopenharmony_ci 8520a5c7a17Sopenharmony_ciint32_t CameraDevice::TriggerLoopingCapture(FrameConfig &fc, uint32_t *streamId) 8530a5c7a17Sopenharmony_ci{ 8540a5c7a17Sopenharmony_ci MEDIA_DEBUG_LOG("Camera device start looping capture."); 8550a5c7a17Sopenharmony_ci DeviceAssistant *assistant = nullptr; 8560a5c7a17Sopenharmony_ci int32_t fcType = fc.GetFrameConfigType(); 8570a5c7a17Sopenharmony_ci switch (fcType) { 8580a5c7a17Sopenharmony_ci case FRAME_CONFIG_RECORD: 8590a5c7a17Sopenharmony_ci assistant = &recordAssistant_; 8600a5c7a17Sopenharmony_ci break; 8610a5c7a17Sopenharmony_ci case FRAME_CONFIG_PREVIEW: 8620a5c7a17Sopenharmony_ci assistant = &previewAssistant_; 8630a5c7a17Sopenharmony_ci break; 8640a5c7a17Sopenharmony_ci case FRAME_CONFIG_CAPTURE: 8650a5c7a17Sopenharmony_ci assistant = &captureAssistant_; 8660a5c7a17Sopenharmony_ci break; 8670a5c7a17Sopenharmony_ci case FRAME_CONFIG_CALLBACK: 8680a5c7a17Sopenharmony_ci assistant = &callbackAssistant_; 8690a5c7a17Sopenharmony_ci break; 8700a5c7a17Sopenharmony_ci default: 8710a5c7a17Sopenharmony_ci break; 8720a5c7a17Sopenharmony_ci } 8730a5c7a17Sopenharmony_ci if (assistant == nullptr) { 8740a5c7a17Sopenharmony_ci MEDIA_ERR_LOG("Invalid frame config type.(type=%d)", fcType); 8750a5c7a17Sopenharmony_ci return MEDIA_ERR; 8760a5c7a17Sopenharmony_ci } 8770a5c7a17Sopenharmony_ci if (assistant->state_ == LOOP_IDLE || assistant->state_ == LOOP_LOOPING || assistant->state_ == LOOP_ERROR) { 8780a5c7a17Sopenharmony_ci MEDIA_ERR_LOG("Device state is %d, cannot start looping capture.", assistant->state_); 8790a5c7a17Sopenharmony_ci return MEDIA_ERR; 8800a5c7a17Sopenharmony_ci } 8810a5c7a17Sopenharmony_ci uint8_t count = 1; 8820a5c7a17Sopenharmony_ci if (fcType == FRAME_CONFIG_CAPTURE) { 8830a5c7a17Sopenharmony_ci auto surfaceList = fc.GetSurfaces(); 8840a5c7a17Sopenharmony_ci if (surfaceList.size() != 1) { 8850a5c7a17Sopenharmony_ci MEDIA_ERR_LOG("Only support one surface in frame config now"); 8860a5c7a17Sopenharmony_ci return MEDIA_ERR; 8870a5c7a17Sopenharmony_ci } 8880a5c7a17Sopenharmony_ci Surface* surface = surfaceList.front(); 8890a5c7a17Sopenharmony_ci count = surface->GetQueueSize(); 8900a5c7a17Sopenharmony_ci } 8910a5c7a17Sopenharmony_ci 8920a5c7a17Sopenharmony_ci do { 8930a5c7a17Sopenharmony_ci int32_t ret = assistant->SetFrameConfig(fc, streamId); 8940a5c7a17Sopenharmony_ci if (ret != MEDIA_OK) { 8950a5c7a17Sopenharmony_ci MEDIA_ERR_LOG("Check and set frame config failed (ret=%d)", ret); 8960a5c7a17Sopenharmony_ci return MEDIA_ERR; 8970a5c7a17Sopenharmony_ci } 8980a5c7a17Sopenharmony_ci ret = assistant->Start(*streamId); 8990a5c7a17Sopenharmony_ci if (ret != MEDIA_OK) { 9000a5c7a17Sopenharmony_ci MEDIA_ERR_LOG("Start looping capture failed (ret=%d)", ret); 9010a5c7a17Sopenharmony_ci return MEDIA_ERR; 9020a5c7a17Sopenharmony_ci } 9030a5c7a17Sopenharmony_ci } while (--count); 9040a5c7a17Sopenharmony_ci return MEDIA_OK; 9050a5c7a17Sopenharmony_ci} 9060a5c7a17Sopenharmony_ci 9070a5c7a17Sopenharmony_civoid CameraDevice::StopLoopingCapture(int32_t type) 9080a5c7a17Sopenharmony_ci{ 9090a5c7a17Sopenharmony_ci MEDIA_INFO_LOG("Stop looping capture in camera_device.cpp"); 9100a5c7a17Sopenharmony_ci 9110a5c7a17Sopenharmony_ci switch (type) { 9120a5c7a17Sopenharmony_ci case FRAME_CONFIG_RECORD: 9130a5c7a17Sopenharmony_ci MEDIA_INFO_LOG("Stop recorder"); 9140a5c7a17Sopenharmony_ci recordAssistant_.Stop();; 9150a5c7a17Sopenharmony_ci break; 9160a5c7a17Sopenharmony_ci case FRAME_CONFIG_PREVIEW: 9170a5c7a17Sopenharmony_ci MEDIA_INFO_LOG("Stop preview"); 9180a5c7a17Sopenharmony_ci previewAssistant_.Stop(); 9190a5c7a17Sopenharmony_ci break; 9200a5c7a17Sopenharmony_ci case FRAME_CONFIG_CALLBACK: 9210a5c7a17Sopenharmony_ci MEDIA_INFO_LOG("Stop callback"); 9220a5c7a17Sopenharmony_ci callbackAssistant_.Stop(); 9230a5c7a17Sopenharmony_ci break; 9240a5c7a17Sopenharmony_ci default: 9250a5c7a17Sopenharmony_ci MEDIA_INFO_LOG("Stop all"); 9260a5c7a17Sopenharmony_ci previewAssistant_.Stop(); 9270a5c7a17Sopenharmony_ci recordAssistant_.Stop(); 9280a5c7a17Sopenharmony_ci callbackAssistant_.Stop(); 9290a5c7a17Sopenharmony_ci break; 9300a5c7a17Sopenharmony_ci } 9310a5c7a17Sopenharmony_ci} 9320a5c7a17Sopenharmony_ci 9330a5c7a17Sopenharmony_ciint32_t CameraDevice::TriggerSingleCapture(FrameConfig &fc, uint32_t *streamId) 9340a5c7a17Sopenharmony_ci{ 9350a5c7a17Sopenharmony_ci return TriggerLoopingCapture(fc, streamId); 9360a5c7a17Sopenharmony_ci} 9370a5c7a17Sopenharmony_ci 9380a5c7a17Sopenharmony_ciint32_t CameraDevice::SetCameraConfig() 9390a5c7a17Sopenharmony_ci{ 9400a5c7a17Sopenharmony_ci return MEDIA_OK; 9410a5c7a17Sopenharmony_ci} 9420a5c7a17Sopenharmony_ci} // namespace Media 9430a5c7a17Sopenharmony_ci} // namespace OHOS 944