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