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