blob: 00afd9d1c9d6b6b1e14d0417bcfbbae1321688fe [file] [log] [blame]
// Copyright 2020 The Android Open Source Project
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include "host-common/MediaSnapshotState.h"
#include <stdio.h>
#include <cassert>
#define MEDIA_SNAPSTATE_DEBUG 0
#if MEDIA_SNAPSTATE_DEBUG
#define SNAPSTATE_DPRINT(fmt, ...) \
fprintf(stderr, "media-snapshot-state: %s:%d " fmt "\n", __func__, \
__LINE__, ##__VA_ARGS__);
#else
#define SNAPSTATE_DPRINT(fmt, ...)
#endif
#include <string.h>
namespace android {
namespace emulation {
bool MediaSnapshotState::savePacket(std::vector<uint8_t> data, uint64_t pts) {
if (pts > 0 && savedPackets.size() > 0 && pts == savedPackets.back().pts) {
return false;
}
PacketInfo pkt{data, pts};
savedPackets.push_back(std::move(pkt));
return true;
}
bool MediaSnapshotState::savePacket(const uint8_t* frame,
size_t size,
uint64_t pts) {
if (pts > 0 && savedPackets.size() > 0 && pts == savedPackets.back().pts) {
return false;
}
std::vector<uint8_t> vec;
vec.assign(frame, frame + size);
PacketInfo pkt{vec, pts};
savedPackets.push_back(std::move(pkt));
return true;
}
void MediaSnapshotState::saveDecodedFrame(std::vector<uint8_t> data,
int width,
int height,
uint64_t pts,
ColorAspects xcolor) {
SNAPSTATE_DPRINT("save decoded byte data");
FrameInfo frame{
std::move(data), std::vector<uint32_t>{}, width, height, pts,
xcolor};
savedFrames.push_back(std::move(frame));
}
void MediaSnapshotState::saveDecodedFrame(std::vector<uint32_t> texture,
int width,
int height,
uint64_t pts,
ColorAspects xcolor) {
SNAPSTATE_DPRINT("save decoded texture");
FrameInfo frame{std::vector<uint8_t>{},
std::move(texture),
width,
height,
pts,
xcolor};
savedFrames.push_back(std::move(frame));
}
namespace {
template <class T>
void saveVec(base::Stream* stream, const std::vector<T>& vec) {
stream->putBe32(vec.size());
if (!vec.empty()) {
stream->write(vec.data(), vec.size() * sizeof(vec[0]));
}
}
template <class T>
void loadVec(base::Stream* stream, std::vector<T>& vec) {
int size = stream->getBe32();
vec.resize(size);
if (size > 0) {
stream->read(vec.data(), size * sizeof(vec[0]));
}
}
} // namespace
void MediaSnapshotState::saveFrameInfo(base::Stream* stream,
const FrameInfo& frame) const {
SNAPSTATE_DPRINT("save bytedata");
saveVec(stream, frame.data);
SNAPSTATE_DPRINT("save texture");
saveVec(stream, frame.texture);
stream->putBe32(frame.width);
stream->putBe32(frame.height);
saveColor(stream, frame.color);
stream->putBe64(frame.pts);
}
void MediaSnapshotState::loadFrameInfo(base::Stream* stream, FrameInfo& frame) {
SNAPSTATE_DPRINT("load bytedata");
loadVec(stream, frame.data);
SNAPSTATE_DPRINT("load texture");
loadVec(stream, frame.texture);
// set all to zero, as we dont really save texture
std::fill(frame.texture.begin(), frame.texture.end(), 0);
frame.width = stream->getBe32();
frame.height = stream->getBe32();
loadColor(stream, frame.color);
frame.pts = stream->getBe64();
}
void MediaSnapshotState::savePacketInfo(base::Stream* stream,
const PacketInfo& pkt) const {
saveVec(stream, pkt.data);
stream->putBe64(pkt.pts);
}
void MediaSnapshotState::loadPacketInfo(base::Stream* stream, PacketInfo& pkt) {
loadVec(stream, pkt.data);
pkt.pts = stream->getBe64();
}
void MediaSnapshotState::saveColor(base::Stream* stream,
const ColorAspects& color) const {
stream->putBe32(color.primaries);
stream->putBe32(color.range);
stream->putBe32(color.transfer);
stream->putBe32(color.space);
}
void MediaSnapshotState::loadColor(base::Stream* stream,
ColorAspects& color) const {
color.primaries = stream->getBe32();
color.range = stream->getBe32();
color.transfer = stream->getBe32();
color.space = stream->getBe32();
}
void MediaSnapshotState::save(base::Stream* stream) const {
saveVec(stream, sps);
saveVec(stream, pps);
stream->putBe32(savedPackets.size());
for (size_t i = 0; i < savedPackets.size(); ++i) {
savePacketInfo(stream, savedPackets[i]);
}
stream->putBe32(savedFrames.size());
SNAPSTATE_DPRINT("save now ");
for (auto iter = savedFrames.begin(); iter != savedFrames.end(); ++iter) {
SNAPSTATE_DPRINT("save now ");
saveFrameInfo(stream, *iter);
}
// saveFrameInfo(stream, savedDecodedFrame);
}
void MediaSnapshotState::load(base::Stream* stream) {
loadVec(stream, sps);
loadVec(stream, pps);
int count = stream->getBe32();
savedPackets.resize(count);
for (int i = 0; i < count; ++i) {
loadPacketInfo(stream, savedPackets[i]);
}
int fcount = stream->getBe32();
SNAPSTATE_DPRINT("load now ");
for (int i = 0; i < fcount; ++i) {
SNAPSTATE_DPRINT("load now ");
loadFrameInfo(stream, savedDecodedFrame);
savedFrames.push_back(std::move(savedDecodedFrame));
}
}
} // namespace emulation
} // namespace android