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