1 /*
2 * Copyright (c) 2022 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #include "output.h"
17 #include <GLES3/gl32.h>
18 #include <cmath>
19 #include <memory>
20
21 namespace OHOS {
22 namespace Rosen {
Output()23 Output::Output()
24 {
25 CreateProgram(GetVertexShader(), GetFragmentShader());
26 }
27
GetFilterType()28 FILTER_TYPE Output::GetFilterType()
29 {
30 return FILTER_TYPE::OUTPUT;
31 }
32
GetPixelMap()33 std::unique_ptr<OHOS::Media::PixelMap> Output::GetPixelMap()
34 {
35 return std::move(pixelMap_);
36 }
37
GetColorBuffer()38 const std::vector<uint8_t>& Output::GetColorBuffer()
39 {
40 return colorBuffer_;
41 }
42
DoProcess(ProcessData & data)43 void Output::DoProcess(ProcessData& data)
44 {
45 if (format_ == "image/jpeg" || format_ == "image/png") {
46 EncodeToFile(data);
47 } else if (format_ == "pixelMap") {
48 EncodeToPixelMap(data);
49 } else if (format_ == "buffer") {
50 WriteToBuffer(data);
51 } else {
52 LOGE("The format of Output is incorrect!!!");
53 }
54 }
55
EncodeToFile(ProcessData & data)56 void Output::EncodeToFile(ProcessData& data)
57 {
58 EncodeToPixelMap(data);
59 OHOS::Media::ImagePacker imagePacker;
60 OHOS::Media::PackOption option;
61 option.format = format_;
62 std::set<std::string> formats;
63 uint32_t ret = imagePacker.GetSupportedFormats(formats);
64 if (ret != 0) {
65 return;
66 }
67 imagePacker.StartPacking(dstImagePath_, option);
68 if (pixelMap_ == nullptr) {
69 LOGE("The pixelMap is null.");
70 return;
71 }
72 imagePacker.AddImage(*pixelMap_);
73 int64_t packedSize = 0;
74 imagePacker.FinalizePacking(packedSize);
75 }
76
EncodeToPixelMap(ProcessData & data)77 void Output::EncodeToPixelMap(ProcessData& data)
78 {
79 WriteToBuffer(data);
80 WriteToBuffer(data);
81 Media::InitializationOptions opts;
82 opts.size.width = std::ceil(data.textureWidth);
83 opts.size.height = std::ceil(data.textureHeight);
84 opts.editable = true;
85 pixelMap_ = Media::PixelMap::Create(opts);
86 if (pixelMap_ == nullptr) {
87 LOGE("The pixelMap create failed.");
88 return;
89 }
90 pixelMap_->WritePixels(colorBuffer_.data(), pixelMap_->GetByteCount());
91 }
92
WriteToBuffer(ProcessData & data)93 void Output::WriteToBuffer(ProcessData& data)
94 {
95 uint32_t bufferSize = static_cast<uint32_t>(data.textureWidth * data.textureHeight * COLOR_CHANNEL);
96 colorBuffer_.resize(bufferSize);
97 glBindFramebuffer(GL_FRAMEBUFFER, data.frameBufferID);
98 glBindTexture(GL_TEXTURE_2D, data.dstTextureID);
99 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, data.textureWidth, data.textureHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
100 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, data.dstTextureID, 0);
101 Use();
102 glViewport(0, 0, data.textureWidth, data.textureHeight);
103 glBindVertexArray(mesh_->VAO_);
104 glBindTexture(GL_TEXTURE_2D, data.srcTextureID);
105 glDrawElements(GL_TRIANGLES, AlgoFilter::DRAW_ELEMENTS_NUMBER, GL_UNSIGNED_INT, 0);
106 glPixelStorei(GL_PACK_ALIGNMENT, 1);
107 glReadPixels(0, 0, data.textureWidth, data.textureHeight, GL_RGBA, GL_UNSIGNED_BYTE, colorBuffer_.data());
108 }
109
SetValue(const std::string & key,std::shared_ptr<void> value,int size)110 void Output::SetValue(const std::string& key, std::shared_ptr<void> value, int size)
111 {
112 if (key == "format" && size > 0) {
113 std::shared_ptr<std::string> format = std::static_pointer_cast<std::string>(value);
114 format_ = *(format.get());
115 if (format_ == "jpg" || format_ == "jpeg") {
116 format_ = "image/jpeg";
117 } else if (format_ == "png") {
118 format_ = "image/png";
119 }
120 LOGD("The output format is %{public}s.", format_.c_str());
121 } else if (key == "dst" && size > 0) {
122 if (format_ == "image/jpeg" || format_ == "image/png") {
123 std::shared_ptr<std::string> dstImagePath = std::static_pointer_cast<std::string>(value);
124 dstImagePath_ = *(dstImagePath.get());
125 LOGD("The ouput source image path is %{public}s.", dstImagePath_.c_str());
126 }
127 }
128 }
129
GetVertexShader()130 std::string Output::GetVertexShader()
131 {
132 return R"SHADER(#version 320 es
133 precision mediump float;
134 layout (location = 0) in vec3 vertexCoord;
135 layout (location = 1) in vec2 inputTexCoord;
136 out vec2 texCoord;
137
138 void main()
139 {
140 gl_Position = vec4(vertexCoord, 1.0);
141 texCoord = inputTexCoord;
142 }
143 )SHADER";
144 }
145
GetFragmentShader()146 std::string Output::GetFragmentShader()
147 {
148 return R"SHADER(#version 320 es
149 precision mediump float;
150 in vec2 texCoord;
151 out vec4 fragColor;
152 uniform sampler2D uTexture;
153 void main()
154 {
155 fragColor = texture(uTexture, texCoord);
156 }
157 )SHADER";
158 }
159 } // namespcae Rosen
160 } // namespace OHOS