• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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