You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
188 lines
6.1 KiB
188 lines
6.1 KiB
// 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
|