Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -402,6 +402,13 @@ if (CMAKE_SUBTITLE_SUPPORT)

set(LIBPLAYERGSTINTERFACE_SOURCES ${LIBPLAYERGSTINTERFACE_SOURCES} closedcaptions/subtec/PlayerSubtecCCManager.cpp closedcaptions/rialto/PlayerRialtoCCManager.cpp)
endif()

if (CMAKE_PLAYER_TELEMETRY_SUPPORT)
message("CMAKE_PLAYER_TELEMETRY_SUPPORT set")
set(LIBPLAYERGSTINTERFACE_DEFINES "${LIBPLAYERGSTINTERFACE_DEFINES} -DPLAYER_TELEMETRY_SUPPORT")
include_directories(${CMAKE_CURRENT_SOURCE_DIR}/playerTelemetry)
add_subdirectory(playerTelemetry)
endif()
add_library(playergstinterface SHARED ${SOURCES} ${LIBPLAYERGSTINTERFACE_HEADERS} ${LIBPLAYERGSTINTERFACE_SOURCES} ${LIBPLAYERGSTINTERFACE_DRM_SOURCES} ${LIBPLAYERGSTINTERFACE_HELP_SOURCES})

target_include_directories(playergstinterface PUBLIC
Expand Down Expand Up @@ -459,6 +466,9 @@ target_link_libraries(playergstinterface ${GSTVIDEO_LIBRARIES} ${LIBPLAYERGSTINT
target_link_libraries(playergstinterface subtec)
target_link_libraries(playergstinterface baseconversion)
target_link_libraries(playergstinterface playerfbinterface)
if (CMAKE_PLAYER_TELEMETRY_SUPPORT)
target_link_libraries(playergstinterface playertelemetry)
endif()
set(LIBPLAYERGSTINTERFACE_SOURCES ${LIBPLAYERGSTINTERFACE_SOURCES} {LIBPLAYERGSTINTERFACE_MOCK_SOURCES})

# Optionally build pi-cli for l2
Expand Down
12 changes: 12 additions & 0 deletions pkgconfig/libplayertelemetry.pc.in
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
prefix=@CMAKE_INSTALL_PREFIX@
exec_prefix=${prefix}
libdir=${exec_prefix}/lib
includedir=${prefix}/include

Name: playertelemetry
Description: Telemetry 2.0 support for player middleware
Version: @PROJECT_VERSION@
Requires: libcjson
Requires.private: playerlogmanager
Libs: -L${libdir} -lplayertelemetry
Cflags: -I${includedir}
70 changes: 70 additions & 0 deletions playerTelemetry/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
# If not stated otherwise in this file or this component's license file the
# following copyright and licenses apply:
#
# Copyright 2025 RDK Management
#
# 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.

cmake_minimum_required(VERSION 3.5)

project(playertelemetry VERSION 0.1.0)
set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD_REQUIRED ON)

# Set default install prefix
if(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT)
set(CMAKE_INSTALL_PREFIX "/usr" CACHE PATH "Default install prefix" FORCE)
endif()

include(FindPkgConfig)
pkg_check_modules(LIBCJSON REQUIRED libcjson)
link_directories(${LIBCJSON_LIBRARY_DIRS})

include_directories(${CMAKE_CURRENT_SOURCE_DIR}/../playerLogManager)
include_directories(${LIBCJSON_INCLUDE_DIRS})

set(PlayerTelemetry_SRC PlayerTelemetry2.cpp)

add_library(playertelemetry SHARED ${PlayerTelemetry_SRC})

target_compile_definitions(playertelemetry PUBLIC PLAYER_TELEMETRY_SUPPORT)

target_include_directories(playertelemetry PUBLIC
${LIBCJSON_INCLUDE_DIRS}
${CMAKE_CURRENT_SOURCE_DIR}/../playerLogManager
)

target_link_libraries(playertelemetry PUBLIC
${LIBCJSON_LINK_LIBRARIES}
playerlogmanager
)

set_target_properties(playertelemetry PROPERTIES
PUBLIC_HEADER "PlayerTelemetry2.hpp"
)

# Configure pkg-config file
configure_file(
"${CMAKE_CURRENT_SOURCE_DIR}/../pkgconfig/libplayertelemetry.pc.in"
"${CMAKE_CURRENT_BINARY_DIR}/libplayertelemetry.pc"
@ONLY
)

install(TARGETS playertelemetry
DESTINATION lib
PUBLIC_HEADER DESTINATION include
)

# Install pkg-config file
install(FILES "${CMAKE_CURRENT_BINARY_DIR}/libplayertelemetry.pc"
DESTINATION lib/pkgconfig)
152 changes: 152 additions & 0 deletions playerTelemetry/PlayerTelemetry2.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,152 @@
/*
* If not stated otherwise in this file or this component's license file the
* following copyright and licenses apply:
*
* Copyright 2025 RDK Management
*
* 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.
*/

/**
* @file PlayerTelemetry2.cpp
* @brief PlayerTelemetry2 class implementation
*/

#include "PlayerTelemetry2.hpp"

#ifdef PLAYER_TELEMETRY_SUPPORT

#ifndef PLAYER_SIMULATOR_BUILD
#include <telemetry_busmessage_sender.h>
#endif


PlayerTelemetryInitializer::PlayerTelemetryInitializer()
: m_Initialized(false)
{
}

void PlayerTelemetryInitializer::Init()
{
if (false == m_Initialized)
{
m_Initialized = true;
#ifndef PLAYER_SIMULATOR_BUILD
t2_init((char *)"player");
MW_LOG_MIL("t2_init done");
#endif
}
}

bool PlayerTelemetryInitializer::isInitialized() const
{
return m_Initialized;
}

PlayerTelemetryInitializer::~PlayerTelemetryInitializer()
{
#ifndef PLAYER_SIMULATOR_BUILD
t2_uninit();
MW_LOG_MIL("t2_uninit done");
#endif
}


PlayerTelemetryInitializer PlayerTelemetry2::mInitializer;

PlayerTelemetry2::PlayerTelemetry2() : PlayerTelemetry2("")
{
}

PlayerTelemetry2::PlayerTelemetry2(const std::string &appName) : appName(appName)
{
mInitializer.Init();
}

bool PlayerTelemetry2::send(const std::string &markerName,
const std::map<std::string, int>& intData,
const std::map<std::string, std::string>& stringData,
const std::map<std::string, float>& floatData)
{
bool bRet = false;
if (mInitializer.isInitialized())
{
cJSON *root = cJSON_CreateObject();

cJSON_AddStringToObject(root, "app", appName.c_str());

for (const auto& pair : intData)
{
cJSON_AddNumberToObject(root, pair.first.c_str(), pair.second);
}

for (const auto& pair : stringData)
{
cJSON_AddStringToObject(root, pair.first.c_str(), pair.second.c_str());
}

for (const auto& pair : floatData)
{
cJSON_AddNumberToObject(root, pair.first.c_str(), pair.second);
}

char *jsonString = cJSON_PrintUnformatted(root);

MW_LOG_INFO("[M] Marker Name: %s value:%s", markerName.c_str(), jsonString);

#ifndef PLAYER_SIMULATOR_BUILD
T2ERROR t2Error = t2_event_s((char *)markerName.c_str(), jsonString);

if (T2ERROR_SUCCESS == t2Error)
{
bRet = true;
}
else
{
MW_LOG_ERR("t2_event_s map failed:%d", t2Error);
}
#else
bRet = true;
#endif
cJSON_free(jsonString);
cJSON_Delete(root);
}

return bRet;
}

bool PlayerTelemetry2::send(const std::string &markerName, const char *data)
{
bool bRet = false;
if (mInitializer.isInitialized() && nullptr != data)
{
#ifndef PLAYER_SIMULATOR_BUILD
T2ERROR t2Error = t2_event_s((char *)markerName.c_str(), (char *)data);

if (T2ERROR_SUCCESS == t2Error)
{
bRet = true;
}
else
{
MW_LOG_ERR("t2_event_s string failed:%d", t2Error);
}
#else
bRet = true;
#endif
}

return bRet;
}

#endif // PLAYER_TELEMETRY_SUPPORT
119 changes: 119 additions & 0 deletions playerTelemetry/PlayerTelemetry2.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
/*
* If not stated otherwise in this file or this component's license file the
* following copyright and licenses apply:
*
* Copyright 2025 RDK Management
*
* 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.
*/

/**
* @file PlayerTelemetry2.hpp
* @brief Supporting class to provide telemetry support to Player middleware
*/

#ifndef __PLAYER_TELEMETRY_2_H__
#define __PLAYER_TELEMETRY_2_H__

#ifdef PLAYER_TELEMETRY_SUPPORT

#include <cjson/cJSON.h>
#include <iostream>
#include <string>
#include <map>
#include "PlayerLogManager.h"

// Note that RDK telemetry 2.0 support is per process basis,
// this class is created to take care of un initialization of telemetry but having object as global variable
// when process goes down, destructor of this class will be called and it will uninitialize the telemetry.

/**
* @class PlayerTelemetryInitializer
* @brief Manages the lifecycle of the T2 telemetry library initialization
*/
class PlayerTelemetryInitializer {
private:
bool m_Initialized = false;
public:
/**
* @brief Constructor
*/
PlayerTelemetryInitializer();

/**
* @brief Initialize the telemetry library (idempotent)
*/
void Init();

/**
* @brief Check if telemetry has been initialized
* @return true if initialized, false otherwise
*/
bool isInitialized() const;

/**
* @brief Destructor - uninitializes the telemetry library
*/
~PlayerTelemetryInitializer();
};


/**
* @class PlayerTelemetry2
* @brief Provides object-based telemetry event sending via RDK T2 (Telemetry 2.0)
*
* Instead of calling telemetry send functions directly, create a PlayerTelemetry2
* object and call send() to dispatch telemetry events.
*/
class PlayerTelemetry2 {
private:
static PlayerTelemetryInitializer mInitializer;
std::string appName;

public:
/**
* @brief Constructor with no application name
*/
PlayerTelemetry2();

/**
* @brief Constructor
* @param[in] appName - Name of the application
*/
PlayerTelemetry2(const std::string &appName);

/**
* @brief Send telemetry data to the telemetry bus by converting input maps to a JSON string
* @param[in] markerName - Name of the marker/event
* @param[in] intData - Map of integer key-value pairs
* @param[in] stringData - Map of string key-value pairs
* @param[in] floatData - Map of float key-value pairs
* @return true if the event was sent successfully, false otherwise
*/
bool send(const std::string &markerName,
const std::map<std::string, int>& intData,
const std::map<std::string, std::string>& stringData,
const std::map<std::string, float>& floatData);

/**
* @brief Send telemetry data to the telemetry bus
* @param[in] markerName - Name of the marker/event
* @param[in] data - Raw data string to send
* @return true if the event was sent successfully, false otherwise
*/
bool send(const std::string &markerName, const char *data);
};

#endif // PLAYER_TELEMETRY_SUPPORT

#endif // __PLAYER_TELEMETRY_2_H__
1 change: 1 addition & 0 deletions test/utests/tests/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -32,3 +32,4 @@ add_subdirectory(InterfacePlayerTests)
add_subdirectory(DrmSessionManagerTests)
add_subdirectory(PlayerUtilsTests)
add_subdirectory(PlayerExternalsRdkTests)
add_subdirectory(PlayerTelemetryTests)
Loading
Loading