1 /*
2  * Copyright (c) 2023 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *     http://www.apache.org/licenses/LICENSE-2.0
7  * Unless required by applicable law or agreed to in writing, software
8  * distributed under the License is distributed on an "AS IS" BASIS,
9  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
10  * See the License for the specific language governing permissions and
11  * limitations under the License.
12  */
13 
14 #include "exif_node.h"
15 #include <exif_utils.h>
16 #include <securec.h>
17 #include "camera_dump.h"
18 
19 namespace OHOS::Camera {
ExifNode(const std::string & name,const std::string & type,const std::string & cameraId)20 ExifNode::ExifNode(const std::string &name, const std::string &type, const std::string &cameraId)
21     : NodeBase(name, type, cameraId)
22 {
23     CAMERA_LOGV("%{public}s enter, type(%{public}s)\n", name_.c_str(), type_.c_str());
24 }
25 
~ExifNode()26 ExifNode::~ExifNode()
27 {
28     CAMERA_LOGI("~ExifNode Node exit.");
29 }
30 
Start(const int32_t streamId)31 RetCode ExifNode::Start(const int32_t streamId)
32 {
33     CAMERA_LOGI("ExifNode::Start streamId = %{public}d\n", streamId);
34     return RC_OK;
35 }
36 
Stop(const int32_t streamId)37 RetCode ExifNode::Stop(const int32_t streamId)
38 {
39     CAMERA_LOGI("ExifNode::Stop streamId = %{public}d\n", streamId);
40     return RC_OK;
41 }
42 
Flush(const int32_t streamId)43 RetCode ExifNode::Flush(const int32_t streamId)
44 {
45     CAMERA_LOGI("ExifNode::Flush streamId = %{public}d\n", streamId);
46     return RC_OK;
47 }
48 
DeliverBuffer(std::shared_ptr<IBuffer> & buffer)49 void ExifNode::DeliverBuffer(std::shared_ptr<IBuffer> &buffer)
50 {
51     if (buffer == nullptr) {
52         CAMERA_LOGE("ExifNode::DeliverBuffer frameSpec is null");
53         return;
54     }
55     if (buffer->GetBufferStatus() != CAMERA_BUFFER_STATUS_OK) {
56         CAMERA_LOGE("BufferStatus() != CAMERA_BUFFER_STATUS_OK");
57         return NodeBase::DeliverBuffer(buffer);
58     }
59 
60     if (buffer->GetEncodeType() == ENCODE_TYPE_JPEG && gpsInfo_.size() > 0) {
61         int outPutBufferSize = 0;
62         exif_data exifInfo;
63         exifInfo.latitude = gpsInfo_.at(LATITUDE_INDEX);
64         exifInfo.longitude = gpsInfo_.at(LONGITUDE_INDEX);
65         exifInfo.altitude = gpsInfo_.at(ALTITUDE_INDEX);
66         EsFrameInfo info = buffer->GetEsFrameInfo();
67         CAMERA_LOGI("%{public}s info.size = (%{public}d)\n", __FUNCTION__, info.size);
68         if (info.size != -1) {
69             exifInfo.frame_size = info.size;
70             ExifUtils::AddCustomExifInfo(exifInfo, buffer->GetVirAddress(), outPutBufferSize);
71             CAMERA_LOGI("%{public}s virAddress(%{public}p) and outPutBufferSize = (%{public}d)\n",
72                 __FUNCTION__, buffer->GetVirAddress(), outPutBufferSize);
73             buffer->SetEsFrameSize(outPutBufferSize);
74         }
75     }
76 
77     CameraDumper& dumper = CameraDumper::GetInstance();
78     dumper.DumpBuffer("ExifNode", ENABLE_EXIF_NODE_CONVERTED, buffer);
79 
80     NodeBase::DeliverBuffer(buffer);
81 }
82 
Config(const int32_t streamId,const CaptureMeta & meta)83 RetCode ExifNode::Config(const int32_t streamId, const CaptureMeta &meta)
84 {
85     if (meta == nullptr) {
86         CAMERA_LOGW("%{public}s streamId= %{public}d", __FUNCTION__, streamId);
87         return RC_OK;
88     }
89     if (SendMetadata(meta) == RC_ERROR) {
90         CAMERA_LOGW("%{public}s no available caputre metadata", __FUNCTION__);
91     }
92     return RC_OK;
93 }
94 
SendMetadata(std::shared_ptr<CameraMetadata> meta)95 RetCode ExifNode::SendMetadata(std::shared_ptr<CameraMetadata> meta)
96 {
97     common_metadata_header_t *data = meta->get();
98     camera_metadata_item_t entry;
99     uint8_t captureQuality = 0;
100     int32_t captureOrientation = 0;
101     uint8_t mirrorSwitch = 0;
102     int ret = RC_OK;
103 
104     if (data == nullptr) {
105         CAMERA_LOGE("%{public}s data is nullptr", __FUNCTION__);
106         return RC_ERROR;
107     }
108     RetCode rc = SetGpsInfoMetadata(data);
109     if (rc == RC_ERROR) {
110         CAMERA_LOGE("%{public}s SetGpsInfoMetadata fail", __FUNCTION__);
111         return RC_ERROR;
112     }
113 
114     ret = FindCameraMetadataItem(data, OHOS_JPEG_QUALITY, &entry);
115     if (ret != 0) {
116         CAMERA_LOGE("%{public}s get OHOS_JPEG_QUALITY error and ret= %{public}d", __FUNCTION__, ret);
117         return RC_ERROR;
118     }
119     captureQuality = *(entry.data.u8);
120     ret = FindCameraMetadataItem(data, OHOS_JPEG_ORIENTATION, &entry);
121     if (ret != 0) {
122         CAMERA_LOGE("%{public}s get OHOS_JPEG_ORIENTATION error and ret= %{public}d", __FUNCTION__, ret);
123         return RC_ERROR;
124     }
125     captureOrientation = *(entry.data.i32);
126     ret = FindCameraMetadataItem(data, OHOS_CONTROL_CAPTURE_MIRROR, &entry);
127     if (ret != 0) {
128         CAMERA_LOGE("%{public}s get OHOS_CONTROL_CAPTURE_MIRROR error and ret= %{public}d", __FUNCTION__, ret);
129         return RC_ERROR;
130     }
131     mirrorSwitch = *(entry.data.u8);
132     CAMERA_LOGI("%{public}s captureQuality= %{public}d and captureOrientation= %{public}d and mirrorSwitch= %{public}d",
133         __FUNCTION__, captureQuality, captureOrientation, mirrorSwitch);
134 
135     return rc;
136 }
137 
SetGpsInfoMetadata(common_metadata_header_t * data)138 RetCode ExifNode::SetGpsInfoMetadata(common_metadata_header_t *data)
139 {
140     uint32_t count = 0;
141     camera_metadata_item_t entry;
142     int ret = FindCameraMetadataItem(data, OHOS_JPEG_GPS_COORDINATES, &entry);
143     if (ret != 0) {
144         return RC_ERROR;
145     }
146     constexpr uint32_t groupLen = 3;
147     count = entry.count;
148     CAMERA_LOGI("%{public}s  gps count %{public}d)\n", __FUNCTION__,  count);
149     if (count != groupLen) {
150         CAMERA_LOGE("%{public}s  gps data count error\n", __FUNCTION__);
151         return RC_ERROR;
152     }
153 
154     for (int i = 0; i < count; i++) {
155         std::lock_guard<std::mutex> l(gpsMetaDatalock_);
156         gpsInfo_.push_back(*(entry.data.d + i));
157     }
158     return RC_OK;
159 }
160 
Capture(const int32_t streamId,const int32_t captureId)161 RetCode ExifNode::Capture(const int32_t streamId, const int32_t captureId)
162 {
163     CAMERA_LOGV("ExifNode::Capture streamId = %{public}d and captureId = %{public}d", streamId, captureId);
164     return RC_OK;
165 }
166 
CancelCapture(const int32_t streamId)167 RetCode ExifNode::CancelCapture(const int32_t streamId)
168 {
169     CAMERA_LOGI("ExifNode::CancelCapture streamid = %{public}d", streamId);
170 
171     return RC_OK;
172 }
173 
174 REGISTERNODE(ExifNode, {"Exif"})
175 } // namespace OHOS::Camera
176