Files
video-v1/vav2/Vav2Player/Vav2UnitTest/tests/MockWebMFileReader.cpp
2025-09-25 22:43:07 +09:00

247 lines
6.9 KiB
C++

#include "pch.h"
#include "MockWebMFileReader.h"
#include <cstring>
namespace Vav2PlayerUnitTests {
MockWebMFileReader::MockWebMFileReader() {
CreateDefaultMockData();
}
bool MockWebMFileReader::OpenFile(const std::string& file_path) {
m_openFileCallCount++;
m_lastOpenedFile = file_path;
if (!m_openFileResult) {
m_mockError = VavCore::WebMErrorCode::FileNotFound;
m_mockErrorMessage = "Mock file not found: " + file_path;
return false;
}
m_isOpen = true;
m_currentFilePath = file_path;
m_currentFrame = 0;
m_mockError = VavCore::WebMErrorCode::Success;
m_mockErrorMessage.clear();
return true;
}
void MockWebMFileReader::CloseFile() {
m_isOpen = false;
m_currentFilePath.clear();
m_currentFrame = 0;
}
bool MockWebMFileReader::IsFileOpen() const {
return m_isOpen;
}
const VavCore::VideoMetadata& MockWebMFileReader::GetVideoMetadata() const {
return m_mockMetadata;
}
std::string MockWebMFileReader::GetFilePath() const {
return m_currentFilePath;
}
std::vector<VavCore::VideoTrackInfo> MockWebMFileReader::GetVideoTracks() const {
return m_mockTracks;
}
bool MockWebMFileReader::SelectVideoTrack(uint64_t track_number) {
if (!m_isOpen) {
m_mockError = VavCore::WebMErrorCode::FileNotOpen;
return false;
}
// Validate track exists
for (const auto& track : m_mockTracks) {
if (track.track_number == track_number) {
m_selectedTrack = track_number;
return true;
}
}
m_mockError = VavCore::WebMErrorCode::InvalidTrack;
return false;
}
uint64_t MockWebMFileReader::GetSelectedTrackNumber() const {
return m_selectedTrack;
}
bool MockWebMFileReader::ReadNextPacket(VavCore::VideoPacket& packet) {
m_readPacketCallCount++;
if (!m_isOpen) {
m_mockError = VavCore::WebMErrorCode::FileNotOpen;
return false;
}
if (m_currentFrame >= m_endOfFileFrame || m_currentFrame >= m_mockPackets.size()) {
return false; // End of file
}
// Create packet from mock data
const auto& mockData = m_mockPackets[m_currentFrame];
packet.data = std::make_unique<uint8_t[]>(mockData.size());
packet.size = mockData.size();
std::memcpy(packet.data.get(), mockData.data(), mockData.size());
packet.timestamp_seconds = static_cast<double>(m_currentFrame) / m_mockMetadata.frame_rate;
packet.frame_index = m_currentFrame;
packet.is_keyframe = (m_currentFrame % 30 == 0); // Every 30th frame is keyframe
m_currentFrame++;
return true;
}
bool MockWebMFileReader::SeekToFrame(uint64_t frame_index) {
if (!m_isOpen) {
m_mockError = VavCore::WebMErrorCode::FileNotOpen;
return false;
}
if (frame_index >= m_mockPackets.size()) {
m_mockError = VavCore::WebMErrorCode::SeekFailed;
return false;
}
m_currentFrame = frame_index;
return true;
}
bool MockWebMFileReader::SeekToTime(double timestamp_seconds) {
if (!m_isOpen) {
m_mockError = VavCore::WebMErrorCode::FileNotOpen;
return false;
}
uint64_t frame_index = static_cast<uint64_t>(timestamp_seconds * m_mockMetadata.frame_rate);
return SeekToFrame(frame_index);
}
uint64_t MockWebMFileReader::GetCurrentFrameIndex() const {
return m_currentFrame;
}
double MockWebMFileReader::GetCurrentTimestamp() const {
return static_cast<double>(m_currentFrame) / m_mockMetadata.frame_rate;
}
bool MockWebMFileReader::IsEndOfFile() const {
return m_currentFrame >= m_endOfFileFrame || m_currentFrame >= m_mockPackets.size();
}
bool MockWebMFileReader::Reset() {
if (!m_isOpen) {
m_mockError = VavCore::WebMErrorCode::FileNotOpen;
return false;
}
m_currentFrame = 0;
return true;
}
uint64_t MockWebMFileReader::GetTotalFrames() const {
return m_mockPackets.size();
}
double MockWebMFileReader::GetDuration() const {
return m_mockMetadata.duration_seconds;
}
VavCore::WebMErrorCode MockWebMFileReader::GetLastError() const {
return m_mockError;
}
std::string MockWebMFileReader::GetLastErrorString() const {
return m_mockErrorMessage;
}
// Mock control methods
void MockWebMFileReader::SetMockVideoMetadata(const VavCore::VideoMetadata& metadata) {
m_mockMetadata = metadata;
}
void MockWebMFileReader::SetMockVideoTracks(const std::vector<VavCore::VideoTrackInfo>& tracks) {
m_mockTracks = tracks;
}
void MockWebMFileReader::SetMockPackets(const std::vector<std::vector<uint8_t>>& packets) {
m_mockPackets = packets;
// Update metadata to match packet count
m_mockMetadata.total_frames = packets.size();
m_mockMetadata.duration_seconds = static_cast<double>(packets.size()) / m_mockMetadata.frame_rate;
}
void MockWebMFileReader::SetMockError(VavCore::WebMErrorCode error, const std::string& message) {
m_mockError = error;
m_mockErrorMessage = message;
}
void MockWebMFileReader::SetOpenFileResult(bool success) {
m_openFileResult = success;
}
void MockWebMFileReader::SetEndOfFileAtFrame(uint64_t frame_index) {
m_endOfFileFrame = frame_index;
}
// Private helper methods
void MockWebMFileReader::CreateDefaultMockData() {
// Default metadata for 1920x1080 30fps AV1 video
m_mockMetadata.width = 1920;
m_mockMetadata.height = 1080;
m_mockMetadata.frame_rate = 30.0;
m_mockMetadata.codec_type = VavCore::VideoCodecType::AV1;
m_mockMetadata.color_space = VavCore::ColorSpace::BT709;
m_mockMetadata.total_frames = 100; // 100 frames = ~3.33 seconds
m_mockMetadata.duration_seconds = 100.0 / 30.0;
// Default video track
VavCore::VideoTrackInfo track;
track.track_number = 1;
track.codec_id = "V_AV01";
track.codec_name = "AV1";
track.codec_type = VavCore::VideoCodecType::AV1;
track.width = 1920;
track.height = 1080;
track.frame_rate = 30.0;
track.is_enabled = true;
m_mockTracks.push_back(track);
// Create 100 mock AV1 packets
m_mockPackets.clear();
for (uint64_t i = 0; i < 100; ++i) {
m_mockPackets.push_back(CreateMockAV1Packet(i));
}
m_selectedTrack = 1;
}
std::vector<uint8_t> MockWebMFileReader::CreateMockAV1Packet(uint64_t frame_index) {
// Create a minimal mock AV1 packet
// Real AV1 packets are complex, but for testing we just need valid data
std::vector<uint8_t> packet;
// AV1 OBU header pattern (simplified)
packet.push_back(0x0A); // OBU type (frame)
packet.push_back(0x00); // OBU extension flag
// Mock frame size (varies by frame index for realism)
uint32_t frame_size = 1000 + (frame_index % 500); // 1000-1500 bytes
// Add frame size in LEB128 format (simplified)
packet.push_back(static_cast<uint8_t>(frame_size & 0x7F));
packet.push_back(static_cast<uint8_t>((frame_size >> 7) & 0x7F));
// Fill with mock data
for (uint32_t i = 0; i < frame_size; ++i) {
packet.push_back(static_cast<uint8_t>((frame_index + i) & 0xFF));
}
return packet;
}
} // namespace Vav2PlayerUnitTests