You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
147 lines
5.1 KiB
147 lines
5.1 KiB
// Copyright (C) 2020 The Android Open Source Project
|
|
//
|
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
// you may not use this file except in compliance with the License.
|
|
// You may obtain a copy of the License at
|
|
//
|
|
// http://www.apache.org/licenses/LICENSE-2.0
|
|
//
|
|
// Unless required by applicable law or agreed to in writing, software
|
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
// See the License for the specific language governing permissions and
|
|
// limitations under the License.
|
|
|
|
#include "host-common/MediaTexturePool.h"
|
|
|
|
#include <cstdint>
|
|
#include <string>
|
|
#include <vector>
|
|
|
|
#include <stdio.h>
|
|
#include <string.h>
|
|
|
|
#define MEDIA_H264_DEBUG 0
|
|
|
|
#if MEDIA_H264_DEBUG
|
|
#define H264_DPRINT(fmt, ...) \
|
|
fprintf(stderr, "media-texture-pool: %s:%d myid: %d " fmt "\n", __func__, \
|
|
__LINE__, m_id, ##__VA_ARGS__);
|
|
#else
|
|
#define H264_DPRINT(fmt, ...)
|
|
#endif
|
|
|
|
namespace android {
|
|
namespace emulation {
|
|
|
|
static int s_texturePoolId = 0;
|
|
MediaTexturePool::MediaTexturePool() {
|
|
mVirtioGpuOps = android_getVirtioGpuOps();
|
|
if (mVirtioGpuOps == nullptr) {
|
|
H264_DPRINT("Error, cannot get mVirtioGpuOps");
|
|
}
|
|
m_id = s_texturePoolId++;
|
|
H264_DPRINT("created texturepool");
|
|
}
|
|
|
|
MediaTexturePool::~MediaTexturePool() {
|
|
H264_DPRINT("destroyed texturepool");
|
|
cleanUpTextures();
|
|
}
|
|
|
|
const uint32_t kGlUnsignedByte = 0x1401;
|
|
|
|
constexpr uint32_t kGL_RGBA8 = 0x8058;
|
|
constexpr uint32_t kGL_RGBA = 0x1908;
|
|
constexpr uint32_t kFRAME_POOL_SIZE = 8;
|
|
constexpr uint32_t kFRAMEWORK_FORMAT_NV12 = 3;
|
|
|
|
MediaTexturePool::TextureFrame MediaTexturePool::getTextureFrame(int w, int h) {
|
|
H264_DPRINT("calling %s %d for tex of w %d h %d\n", __func__, __LINE__, w,
|
|
h);
|
|
PoolHandle ph = m_WH_to_PoolHandle[TexSizes{w, h}];
|
|
if (ph == nullptr) {
|
|
ph = new Pool;
|
|
m_WH_to_PoolHandle[TexSizes{w, h}] = ph;
|
|
}
|
|
if (ph->empty()) {
|
|
std::vector<uint32_t> textures(2 * kFRAME_POOL_SIZE);
|
|
mVirtioGpuOps->create_yuv_textures(kFRAMEWORK_FORMAT_NV12,
|
|
kFRAME_POOL_SIZE, w, h,
|
|
textures.data());
|
|
for (uint32_t i = 0; i < kFRAME_POOL_SIZE; ++i) {
|
|
TextureFrame frame{textures[2 * i], textures[2 * i + 1]};
|
|
H264_DPRINT("allocated Y %d UV %d", frame.Ytex, frame.UVtex);
|
|
m_Frame_to_PoolHandle[TexFrame{frame.Ytex, frame.UVtex}] = ph;
|
|
ph->push_back(frame);
|
|
}
|
|
}
|
|
TextureFrame frame = ph->front();
|
|
ph->pop_front();
|
|
H264_DPRINT("done %s %d ret Y %d UV %d", __func__, __LINE__, frame.Ytex,
|
|
frame.UVtex);
|
|
return frame;
|
|
}
|
|
|
|
void MediaTexturePool::saveDecodedFrameToTexture(TextureFrame frame,
|
|
void* privData,
|
|
void* func) {
|
|
H264_DPRINT("calling %s %d for tex of %d %d\n", __func__, __LINE__,
|
|
(int)frame.Ytex, (int)frame.UVtex);
|
|
if (mVirtioGpuOps) {
|
|
uint32_t textures[2] = {frame.Ytex, frame.UVtex};
|
|
mVirtioGpuOps->update_yuv_textures(kFRAMEWORK_FORMAT_NV12, textures,
|
|
privData, func);
|
|
}
|
|
}
|
|
|
|
void MediaTexturePool::putTextureFrame(TextureFrame frame) {
|
|
H264_DPRINT("try recycle textures %d %d", (int)frame.Ytex,
|
|
(int)frame.UVtex);
|
|
if (frame.Ytex > 0 && frame.UVtex > 0) {
|
|
TexFrame tframe{frame.Ytex, frame.UVtex};
|
|
auto iter = m_Frame_to_PoolHandle.find(tframe);
|
|
if (iter != m_Frame_to_PoolHandle.end()) {
|
|
PoolHandle phandle = iter->second;
|
|
H264_DPRINT("recycle registered textures %d %d", (int)frame.Ytex,
|
|
(int)frame.UVtex);
|
|
phandle->push_back(std::move(frame));
|
|
} else {
|
|
H264_DPRINT("recycle un-registered textures %d %d", (int)frame.Ytex,
|
|
(int)frame.UVtex);
|
|
deleteTextures(frame);
|
|
}
|
|
}
|
|
}
|
|
|
|
void MediaTexturePool::deleteTextures(TextureFrame frame) {
|
|
if (mVirtioGpuOps && frame.Ytex > 0 && frame.UVtex > 0) {
|
|
std::vector<uint32_t> textures;
|
|
textures.push_back(frame.Ytex);
|
|
textures.push_back(frame.UVtex);
|
|
mVirtioGpuOps->destroy_yuv_textures(kFRAMEWORK_FORMAT_NV12, 1,
|
|
textures.data());
|
|
}
|
|
}
|
|
|
|
void MediaTexturePool::cleanUpTextures() {
|
|
if (m_WH_to_PoolHandle.empty()) {
|
|
return;
|
|
}
|
|
for (auto iter : m_WH_to_PoolHandle) {
|
|
auto& myFramePool = *(iter.second);
|
|
std::vector<uint32_t> textures;
|
|
for (auto& frame : myFramePool) {
|
|
textures.push_back(frame.Ytex);
|
|
textures.push_back(frame.UVtex);
|
|
H264_DPRINT("delete Y %d UV %d", frame.Ytex, frame.UVtex);
|
|
}
|
|
mVirtioGpuOps->destroy_yuv_textures(
|
|
kFRAMEWORK_FORMAT_NV12, myFramePool.size(), textures.data());
|
|
myFramePool.clear();
|
|
}
|
|
}
|
|
|
|
} // namespace emulation
|
|
} // namespace android
|