1 // Copyright (C) 2020 The Android Open Source Project
2 //
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 #include "host-common/MediaHostRenderer.h"
16
17 #include <cstdint>
18 #include <string>
19 #include <vector>
20
21 #include <stdio.h>
22 #include <string.h>
23
24 #define MEDIA_H264_DEBUG 0
25
26 #if MEDIA_H264_DEBUG
27 #define H264_DPRINT(fmt, ...) \
28 fprintf(stderr, "media-host-renderer: %s:%d " fmt "\n", __func__, \
29 __LINE__, ##__VA_ARGS__);
30 #else
31 #define H264_DPRINT(fmt, ...)
32 #endif
33
34 namespace android {
35 namespace emulation {
36
37 using TextureFrame = MediaTexturePool::TextureFrame;
38
MediaHostRenderer()39 MediaHostRenderer::MediaHostRenderer() {
40 mVirtioGpuOps = android_getVirtioGpuOps();
41 if (mVirtioGpuOps == nullptr) {
42 H264_DPRINT("Error, cannot get mVirtioGpuOps");
43 }
44 }
45
~MediaHostRenderer()46 MediaHostRenderer::~MediaHostRenderer() {
47 cleanUpTextures();
48 }
49
50 const uint32_t kGlUnsignedByte = 0x1401;
51
52 constexpr uint32_t kGL_RGBA8 = 0x8058;
53 constexpr uint32_t kGL_RGBA = 0x1908;
54 constexpr uint32_t kFRAME_POOL_SIZE = 8;
55 constexpr uint32_t kFRAMEWORK_FORMAT_NV12 = 3;
56
getTextureFrame(int w,int h)57 TextureFrame MediaHostRenderer::getTextureFrame(int w, int h) {
58 return mTexturePool.getTextureFrame(w, h);
59 }
60
saveDecodedFrameToTexture(TextureFrame frame,void * privData,void * func)61 void MediaHostRenderer::saveDecodedFrameToTexture(TextureFrame frame,
62 void* privData,
63 void* func) {
64 mTexturePool.saveDecodedFrameToTexture(frame, privData, func);
65 }
66
cleanUpTextures()67 void MediaHostRenderer::cleanUpTextures() {
68 mTexturePool.cleanUpTextures();
69 }
70
renderToHostColorBuffer(int hostColorBufferId,unsigned int outputWidth,unsigned int outputHeight,uint8_t * decodedFrame)71 void MediaHostRenderer::renderToHostColorBuffer(int hostColorBufferId,
72 unsigned int outputWidth,
73 unsigned int outputHeight,
74 uint8_t* decodedFrame) {
75 H264_DPRINT("Calling %s at %d buffer id %d", __func__, __LINE__,
76 hostColorBufferId);
77 if (hostColorBufferId < 0) {
78 H264_DPRINT("ERROR: negative buffer id %d", hostColorBufferId);
79 return;
80 }
81 if (mVirtioGpuOps) {
82 mVirtioGpuOps->update_color_buffer(hostColorBufferId, 0, 0, outputWidth,
83 outputHeight, kGL_RGBA,
84 kGlUnsignedByte, decodedFrame);
85 } else {
86 H264_DPRINT("ERROR: there is no virtio Gpu Ops is not setup");
87 }
88 }
89
renderToHostColorBufferWithTextures(int hostColorBufferId,unsigned int outputWidth,unsigned int outputHeight,TextureFrame frame)90 void MediaHostRenderer::renderToHostColorBufferWithTextures(
91 int hostColorBufferId,
92 unsigned int outputWidth,
93 unsigned int outputHeight,
94 TextureFrame frame) {
95 H264_DPRINT("Calling %s at %d buffer id %d", __func__, __LINE__,
96 hostColorBufferId);
97 if (hostColorBufferId < 0) {
98 H264_DPRINT("ERROR: negative buffer id %d", hostColorBufferId);
99 // try to recycle valid textures: this could happen
100 mTexturePool.putTextureFrame(frame);
101 return;
102 }
103 if (frame.Ytex <= 0 || frame.UVtex <= 0) {
104 H264_DPRINT("ERROR: invalid tex ids: Ytex %d UVtex %d", (int)frame.Ytex,
105 (int)frame.UVtex);
106 return;
107 }
108 if (mVirtioGpuOps) {
109 uint32_t textures[2] = {frame.Ytex, frame.UVtex};
110 mVirtioGpuOps->swap_textures_and_update_color_buffer(
111 hostColorBufferId, 0, 0, outputWidth, outputHeight, kGL_RGBA,
112 kGlUnsignedByte, kFRAMEWORK_FORMAT_NV12, textures);
113 if (textures[0] > 0 && textures[1] > 0) {
114 frame.Ytex = textures[0];
115 frame.UVtex = textures[1];
116 H264_DPRINT("return textures to pool %d %d", frame.Ytex,
117 frame.UVtex);
118 mTexturePool.putTextureFrame(frame);
119 }
120 } else {
121 H264_DPRINT("ERROR: there is no virtio Gpu Ops is not setup");
122 }
123 }
124
125 } // namespace emulation
126 } // namespace android
127