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, &param, 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 &param, 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