1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
|
/*
* Copyright (C) 2018 Team Kodi
* This file is part of Kodi - https://kodi.tv
*
* SPDX-License-Identifier: GPL-2.0-or-later
* See LICENSES/README.md for more information.
*/
#include "GameClientStreamVideo.h"
#include "cores/RetroPlayer/streams/RetroPlayerVideo.h"
#include "games/addons/GameClientTranslator.h"
#include "utils/log.h"
using namespace KODI;
using namespace GAME;
bool CGameClientStreamVideo::OpenStream(RETRO::IRetroPlayerStream* stream,
const game_stream_properties& properties)
{
RETRO::CRetroPlayerVideo* videoStream = dynamic_cast<RETRO::CRetroPlayerVideo*>(stream);
if (videoStream == nullptr)
{
CLog::Log(LOGERROR, "GAME: RetroPlayer stream is not a video stream");
return false;
}
std::unique_ptr<RETRO::VideoStreamProperties> videoProperties(
TranslateProperties(properties.video));
if (videoProperties)
{
if (videoStream->OpenStream(static_cast<const RETRO::StreamProperties&>(*videoProperties)))
m_stream = stream;
}
return m_stream != nullptr;
}
void CGameClientStreamVideo::CloseStream()
{
if (m_stream != nullptr)
{
m_stream->CloseStream();
m_stream = nullptr;
}
}
void CGameClientStreamVideo::AddData(const game_stream_packet& packet)
{
if (packet.type != GAME_STREAM_VIDEO && packet.type != GAME_STREAM_SW_FRAMEBUFFER)
return;
if (m_stream != nullptr)
{
const game_stream_video_packet& video = packet.video;
RETRO::VideoRotation rotation = CGameClientTranslator::TranslateRotation(video.rotation);
RETRO::VideoStreamPacket videoPacket{
video.width, video.height, rotation, video.data, video.size,
};
m_stream->AddStreamData(static_cast<const RETRO::StreamPacket&>(videoPacket));
}
}
RETRO::VideoStreamProperties* CGameClientStreamVideo::TranslateProperties(
const game_stream_video_properties& properties)
{
const AVPixelFormat pixelFormat = CGameClientTranslator::TranslatePixelFormat(properties.format);
if (pixelFormat == AV_PIX_FMT_NONE)
{
CLog::Log(LOGERROR, "GAME: Unknown pixel format: {}", properties.format);
return nullptr;
}
const unsigned int nominalWidth = properties.nominal_width;
const unsigned int nominalHeight = properties.nominal_height;
if (nominalWidth == 0 || nominalHeight == 0)
{
CLog::Log(LOGERROR, "GAME: Invalid nominal dimensions: {}x{}", nominalWidth, nominalHeight);
return nullptr;
}
const unsigned int maxWidth = properties.max_width;
const unsigned int maxHeight = properties.max_height;
if (maxWidth == 0 || maxHeight == 0)
{
CLog::Log(LOGERROR, "GAME: Invalid max dimensions: {}x{}", maxWidth, maxHeight);
return nullptr;
}
if (nominalWidth > maxWidth || nominalHeight > maxHeight)
CLog::Log(LOGERROR, "GAME: Nominal dimensions ({}x{}) bigger than max dimensions ({}x{})",
nominalWidth, nominalHeight, maxWidth, maxHeight);
float pixelAspectRatio;
// Game API: If aspect_ratio is <= 0.0, an aspect ratio of
// (nominal_width / nominal_height) is assumed
if (properties.aspect_ratio <= 0.0f)
pixelAspectRatio = 1.0f;
else
pixelAspectRatio = properties.aspect_ratio * nominalHeight / nominalWidth;
return new RETRO::VideoStreamProperties{pixelFormat, nominalWidth, nominalHeight,
maxWidth, maxHeight, pixelAspectRatio};
}
|