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 std::shared_ptr<uint8_t> Output::GetColorBuffer()
39 {
40 return std::move(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 imagePacker.AddImage(*pixelMap_);
69 int64_t packedSize = 0;
70 imagePacker.FinalizePacking(packedSize);
71 }
72
EncodeToPixelMap(ProcessData & data)73 void Output::EncodeToPixelMap(ProcessData& data)
74 {
75 WriteToBuffer(data);
76 WriteToBuffer(data);
77 Media::InitializationOptions opts;
78 opts.size.width = std::ceil(data.textureWidth);
79 opts.size.height = std::ceil(data.textureHeight);
80 opts.editable = true;
81 pixelMap_ = Media::PixelMap::Create(opts);
82 pixelMap_->WritePixels(colorBuffer_.get(), pixelMap_->GetByteCount());
83 }
84
WriteToBuffer(ProcessData & data)85 void Output::WriteToBuffer(ProcessData& data)
86 {
87 uint32_t bufferSize = data.textureWidth * data.textureHeight * COLOR_CHANNEL;
88 auto colorBuf = new uint8_t[bufferSize];
89 std::shared_ptr<uint8_t> colorBuffer(colorBuf, [] (uint8_t *ptr) {
90 delete[] ptr;
91 });
92 colorBuffer_ = std::move(colorBuffer);
93 glBindFramebuffer(GL_FRAMEBUFFER, data.frameBufferID);
94 glBindTexture(GL_TEXTURE_2D, data.dstTextureID);
95 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, data.textureWidth, data.textureHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
96 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, data.dstTextureID, 0);
97 Use();
98 glViewport(0, 0, data.textureWidth, data.textureHeight);
99 glBindVertexArray(mesh_->VAO_);
100 glBindTexture(GL_TEXTURE_2D, data.srcTextureID);
101 glDrawElements(GL_TRIANGLES, AlgoFilter::DRAW_ELEMENTS_NUMBER, GL_UNSIGNED_INT, 0);
102 glPixelStorei(GL_PACK_ALIGNMENT, 1);
103 glReadPixels(0, 0, data.textureWidth, data.textureHeight, GL_RGBA, GL_UNSIGNED_BYTE, colorBuffer_.get());
104 }
105
SetValue(const std::string & key,std::shared_ptr<void> value,int size)106 void Output::SetValue(const std::string& key, std::shared_ptr<void> value, int size)
107 {
108 if (key == "format" && size > 0) {
109 std::shared_ptr<std::string> format = std::static_pointer_cast<std::string>(value);
110 format_ = *(format.get());
111 if (format_ == "jpg" || format_ == "jpeg") {
112 format_ = "image/jpeg";
113 } else if (format_ == "png") {
114 format_ = "image/png";
115 }
116 LOGD("The output format is %{public}s.", format_.c_str());
117 } else if (key == "dst" && size > 0) {
118 if (format_ == "image/jpeg" || format_ == "image/png") {
119 std::shared_ptr<std::string> dstImagePath = std::static_pointer_cast<std::string>(value);
120 dstImagePath_ = *(dstImagePath.get());
121 LOGD("The ouput source image path is %{public}s.", dstImagePath_.c_str());
122 }
123 }
124 }
125
GetVertexShader()126 std::string Output::GetVertexShader()
127 {
128 return R"SHADER(#version 320 es
129 precision mediump float;
130 layout (location = 0) in vec3 vertexCoord;
131 layout (location = 1) in vec2 inputTexCoord;
132 out vec2 texCoord;
133
134 void main()
135 {
136 gl_Position = vec4(vertexCoord, 1.0);
137 texCoord = inputTexCoord;
138 }
139 )SHADER";
140 }
141
GetFragmentShader()142 std::string Output::GetFragmentShader()
143 {
144 return R"SHADER(#version 320 es
145 precision mediump float;
146 in vec2 texCoord;
147 out vec4 fragColor;
148 uniform sampler2D uTexture;
149 void main()
150 {
151 fragColor = texture(uTexture, texCoord);
152 }
153 )SHADER";
154 }
155 } // namespcae Rosen
156 } // namespace OHOS