1 // Copyright 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 #include "host-common/MediaSnapshotState.h"
15
16 #include <stdio.h>
17 #include <cassert>
18
19 #define MEDIA_SNAPSTATE_DEBUG 0
20
21 #if MEDIA_SNAPSTATE_DEBUG
22 #define SNAPSTATE_DPRINT(fmt, ...) \
23 fprintf(stderr, "media-snapshot-state: %s:%d " fmt "\n", __func__, \
24 __LINE__, ##__VA_ARGS__);
25 #else
26 #define SNAPSTATE_DPRINT(fmt, ...)
27 #endif
28
29 #include <string.h>
30
31 namespace android {
32 namespace emulation {
33
savePacket(std::vector<uint8_t> data,uint64_t pts)34 bool MediaSnapshotState::savePacket(std::vector<uint8_t> data, uint64_t pts) {
35 if (pts > 0 && savedPackets.size() > 0 && pts == savedPackets.back().pts) {
36 return false;
37 }
38 PacketInfo pkt{data, pts};
39 savedPackets.push_back(std::move(pkt));
40 return true;
41 }
savePacket(const uint8_t * frame,size_t size,uint64_t pts)42 bool MediaSnapshotState::savePacket(const uint8_t* frame,
43 size_t size,
44 uint64_t pts) {
45 if (pts > 0 && savedPackets.size() > 0 && pts == savedPackets.back().pts) {
46 return false;
47 }
48 std::vector<uint8_t> vec;
49 vec.assign(frame, frame + size);
50 PacketInfo pkt{vec, pts};
51 savedPackets.push_back(std::move(pkt));
52 return true;
53 }
54
saveDecodedFrame(std::vector<uint8_t> data,int width,int height,uint64_t pts,ColorAspects xcolor)55 void MediaSnapshotState::saveDecodedFrame(std::vector<uint8_t> data,
56 int width,
57 int height,
58 uint64_t pts,
59 ColorAspects xcolor) {
60 SNAPSTATE_DPRINT("save decoded byte data");
61 FrameInfo frame{
62 std::move(data), std::vector<uint32_t>{}, width, height, pts,
63 xcolor};
64 savedFrames.push_back(std::move(frame));
65 }
66
saveDecodedFrame(std::vector<uint32_t> texture,int width,int height,uint64_t pts,ColorAspects xcolor)67 void MediaSnapshotState::saveDecodedFrame(std::vector<uint32_t> texture,
68 int width,
69 int height,
70 uint64_t pts,
71 ColorAspects xcolor) {
72 SNAPSTATE_DPRINT("save decoded texture");
73 FrameInfo frame{std::vector<uint8_t>{},
74 std::move(texture),
75 width,
76 height,
77 pts,
78 xcolor};
79 savedFrames.push_back(std::move(frame));
80 }
81
82 namespace {
83 template <class T>
saveVec(base::Stream * stream,const std::vector<T> & vec)84 void saveVec(base::Stream* stream, const std::vector<T>& vec) {
85 stream->putBe32(vec.size());
86 if (!vec.empty()) {
87 stream->write(vec.data(), vec.size() * sizeof(vec[0]));
88 }
89 }
90
91 template <class T>
loadVec(base::Stream * stream,std::vector<T> & vec)92 void loadVec(base::Stream* stream, std::vector<T>& vec) {
93 int size = stream->getBe32();
94 vec.resize(size);
95 if (size > 0) {
96 stream->read(vec.data(), size * sizeof(vec[0]));
97 }
98 }
99 } // namespace
100
saveFrameInfo(base::Stream * stream,const FrameInfo & frame) const101 void MediaSnapshotState::saveFrameInfo(base::Stream* stream,
102 const FrameInfo& frame) const {
103 SNAPSTATE_DPRINT("save bytedata");
104 saveVec(stream, frame.data);
105 SNAPSTATE_DPRINT("save texture");
106 saveVec(stream, frame.texture);
107 stream->putBe32(frame.width);
108 stream->putBe32(frame.height);
109 saveColor(stream, frame.color);
110 stream->putBe64(frame.pts);
111 }
112
loadFrameInfo(base::Stream * stream,FrameInfo & frame)113 void MediaSnapshotState::loadFrameInfo(base::Stream* stream, FrameInfo& frame) {
114 SNAPSTATE_DPRINT("load bytedata");
115 loadVec(stream, frame.data);
116 SNAPSTATE_DPRINT("load texture");
117 loadVec(stream, frame.texture);
118 // set all to zero, as we dont really save texture
119 std::fill(frame.texture.begin(), frame.texture.end(), 0);
120 frame.width = stream->getBe32();
121 frame.height = stream->getBe32();
122 loadColor(stream, frame.color);
123 frame.pts = stream->getBe64();
124 }
125
savePacketInfo(base::Stream * stream,const PacketInfo & pkt) const126 void MediaSnapshotState::savePacketInfo(base::Stream* stream,
127 const PacketInfo& pkt) const {
128 saveVec(stream, pkt.data);
129 stream->putBe64(pkt.pts);
130 }
131
loadPacketInfo(base::Stream * stream,PacketInfo & pkt)132 void MediaSnapshotState::loadPacketInfo(base::Stream* stream, PacketInfo& pkt) {
133 loadVec(stream, pkt.data);
134 pkt.pts = stream->getBe64();
135 }
136
saveColor(base::Stream * stream,const ColorAspects & color) const137 void MediaSnapshotState::saveColor(base::Stream* stream,
138 const ColorAspects& color) const {
139 stream->putBe32(color.primaries);
140 stream->putBe32(color.range);
141 stream->putBe32(color.transfer);
142 stream->putBe32(color.space);
143 }
144
loadColor(base::Stream * stream,ColorAspects & color) const145 void MediaSnapshotState::loadColor(base::Stream* stream,
146 ColorAspects& color) const {
147 color.primaries = stream->getBe32();
148 color.range = stream->getBe32();
149 color.transfer = stream->getBe32();
150 color.space = stream->getBe32();
151 }
152
save(base::Stream * stream) const153 void MediaSnapshotState::save(base::Stream* stream) const {
154 saveVec(stream, sps);
155 saveVec(stream, pps);
156 stream->putBe32(savedPackets.size());
157 for (size_t i = 0; i < savedPackets.size(); ++i) {
158 savePacketInfo(stream, savedPackets[i]);
159 }
160 stream->putBe32(savedFrames.size());
161 SNAPSTATE_DPRINT("save now ");
162 for (auto iter = savedFrames.begin(); iter != savedFrames.end(); ++iter) {
163 SNAPSTATE_DPRINT("save now ");
164 saveFrameInfo(stream, *iter);
165 }
166 // saveFrameInfo(stream, savedDecodedFrame);
167 }
168
load(base::Stream * stream)169 void MediaSnapshotState::load(base::Stream* stream) {
170 loadVec(stream, sps);
171 loadVec(stream, pps);
172 int count = stream->getBe32();
173 savedPackets.resize(count);
174 for (int i = 0; i < count; ++i) {
175 loadPacketInfo(stream, savedPackets[i]);
176 }
177 int fcount = stream->getBe32();
178 SNAPSTATE_DPRINT("load now ");
179 for (int i = 0; i < fcount; ++i) {
180 SNAPSTATE_DPRINT("load now ");
181 loadFrameInfo(stream, savedDecodedFrame);
182 savedFrames.push_back(std::move(savedDecodedFrame));
183 }
184 }
185
186 } // namespace emulation
187 } // namespace android
188