1 // Copyright (C) 2019 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 #pragma once 16 17 #include "host-common/GoldfishMediaDefs.h" 18 #include "host-common/MediaH264Decoder.h" 19 20 #include <stddef.h> 21 #include <vector> 22 23 namespace android { 24 namespace emulation { 25 26 class MediaH264DecoderDefault; 27 28 // this is an interface for platform specific implementations 29 // such as VideoToolBox, CUVID, etc 30 class MediaH264DecoderPlugin { 31 public: 32 using PixelFormat = MediaH264Decoder::PixelFormat; 33 using Err = MediaH264Decoder::Err; 34 35 virtual void initH264Context(void* ptr) = 0; 36 virtual void reset(void* ptr) = 0; 37 virtual MediaH264DecoderPlugin* clone() = 0; 38 virtual void destroyH264Context() = 0; 39 virtual void decodeFrame(void* ptr) = 0; 40 virtual void flush(void* ptr) = 0; 41 virtual void getImage(void* ptr) = 0; 42 save(base::Stream * stream)43 virtual void save(base::Stream* stream) const {}; load(base::Stream * stream)44 virtual bool load(base::Stream* stream) {return true;}; 45 46 MediaH264DecoderPlugin() = default; 47 virtual ~MediaH264DecoderPlugin() = default; 48 49 protected: 50 // solely for snapshot save load purpose 51 enum { 52 PLUGIN_TYPE_NONE = 0, 53 PLUGIN_TYPE_FFMPEG = 1, 54 PLUGIN_TYPE_CUVID = 2, 55 PLUGIN_TYPE_VIDEO_TOOL_BOX = 3, 56 PLUGIN_TYPE_VIDEO_TOOL_BOX_PROXY = 4, 57 PLUGIN_TYPE_GENERIC = 5, 58 59 }; 60 61 // this is required by save/load type()62 virtual int type() const { return PLUGIN_TYPE_NONE; } 63 64 friend MediaH264DecoderDefault; 65 66 public: 67 struct ColorAspects { 68 unsigned int primaries; 69 unsigned int range; 70 unsigned int transfer; 71 unsigned int space; 72 }; 73 74 struct PacketInfo { 75 std::vector<uint8_t> data; 76 uint64_t pts; 77 }; 78 79 struct FrameInfo { 80 std::vector<uint8_t> data; 81 int width; 82 int height; 83 ColorAspects color; 84 uint64_t pts; 85 }; 86 87 struct SnapshotState { 88 std::vector<uint8_t> sps; // sps NALU 89 std::vector<uint8_t> pps; // pps NALU 90 std::vector<PacketInfo> savedPackets; 91 FrameInfo savedDecodedFrame; // only one or nothing 92 std::vector<FrameInfo> savedFrames; 93 saveSpsSnapshotState94 void saveSps(std::vector<uint8_t> xsps) { sps = std::move(xsps); } 95 savePpsSnapshotState96 void savePps(std::vector<uint8_t> xpps) { pps = std::move(xpps); } 97 bool savePacket(std::vector<uint8_t> data, uint64_t pts = 0) { 98 if (pts > 0 && savedPackets.size() > 0 && 99 pts == savedPackets.back().pts) { 100 return false; 101 } 102 PacketInfo pkt{data, pts}; 103 savedPackets.push_back(std::move(pkt)); 104 return true; 105 } 106 bool savePacket(const uint8_t* frame, size_t size, uint64_t pts = 0) { 107 if (pts > 0 && savedPackets.size() > 0 && 108 pts == savedPackets.back().pts) { 109 return false; 110 } 111 std::vector<uint8_t> vec; 112 vec.assign(frame, frame+size); 113 PacketInfo pkt{vec, pts}; 114 savedPackets.push_back(std::move(pkt)); 115 return true; 116 } 117 118 void saveDecodedFrame(std::vector<uint8_t> data, 119 int width = 0, 120 int height = 0, 121 ColorAspects xcolor = ColorAspects{}, 122 uint64_t pts = 0) { 123 FrameInfo frame{data, width, height, xcolor, pts}; 124 savedDecodedFrame = std::move(frame); 125 savedFrames.push_back(savedDecodedFrame); 126 } 127 saveVecSnapshotState128 void saveVec(base::Stream* stream, 129 const std::vector<uint8_t>& vec) const { 130 stream->putBe32(vec.size()); 131 if (!vec.empty()) { 132 stream->write(vec.data(), vec.size()); 133 } 134 } 135 saveFrameInfoSnapshotState136 void saveFrameInfo(base::Stream* stream, const FrameInfo& frame) const { 137 saveVec(stream, frame.data); 138 stream->putBe32(frame.width); 139 stream->putBe32(frame.height); 140 saveColor(stream, frame.color); 141 stream->putBe64(frame.pts); 142 } 143 loadFrameInfoSnapshotState144 void loadFrameInfo(base::Stream* stream, FrameInfo& frame) { 145 loadVec(stream, frame.data); 146 frame.width = stream->getBe32(); 147 frame.height = stream->getBe32(); 148 loadColor(stream, frame.color); 149 frame.pts = stream->getBe64(); 150 } 151 savePacketInfoSnapshotState152 void savePacketInfo(base::Stream* stream, const PacketInfo& pkt) const { 153 saveVec(stream, pkt.data); 154 stream->putBe64(pkt.pts); 155 } 156 loadPacketInfoSnapshotState157 void loadPacketInfo(base::Stream* stream, PacketInfo& pkt) { 158 loadVec(stream, pkt.data); 159 pkt.pts = stream->getBe64(); 160 } 161 saveColorSnapshotState162 void saveColor(base::Stream* stream, const ColorAspects& color) const { 163 stream->putBe32(color.primaries); 164 stream->putBe32(color.range); 165 stream->putBe32(color.transfer); 166 stream->putBe32(color.space); 167 } 168 loadColorSnapshotState169 void loadColor(base::Stream* stream, ColorAspects& color) const { 170 color.primaries = stream->getBe32(); 171 color.range = stream->getBe32(); 172 color.transfer = stream->getBe32(); 173 color.space = stream->getBe32(); 174 } 175 saveSnapshotState176 void save(base::Stream* stream) const { 177 saveVec(stream, sps); 178 saveVec(stream, pps); 179 stream->putBe32(savedPackets.size()); 180 for (size_t i = 0; i < savedPackets.size(); ++i) { 181 savePacketInfo(stream, savedPackets[i]); 182 } 183 saveFrameInfo(stream, savedDecodedFrame); 184 } 185 loadVecSnapshotState186 void loadVec(base::Stream* stream, std::vector<uint8_t>& vec) { 187 int size = stream->getBe32(); 188 vec.resize(size); 189 if (size > 0) { 190 stream->read(vec.data(), size); 191 } 192 } loadSnapshotState193 void load(base::Stream* stream) { 194 loadVec(stream, sps); 195 loadVec(stream, pps); 196 int count = stream->getBe32(); 197 savedPackets.resize(count); 198 for (int i = 0; i < count; ++i) { 199 loadPacketInfo(stream, savedPackets[i]); 200 } 201 loadFrameInfo(stream, savedDecodedFrame); 202 } 203 }; 204 }; 205 206 } // namespace emulation 207 } // namespace android 208