Skip to content
Open
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
4 changes: 3 additions & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -214,6 +214,7 @@ install(FILES closedcaptions/CCTrackInfo.h
subtec/libsubtec/SubtecPacket.hpp
playerisobmff/playerisobmffbuffer.h
playerisobmff/playerisobmffbox.h
closedcaptions/direct-rialto/IDirectRialtoCC.h
DESTINATION include)

set(SOURCES
Expand Down Expand Up @@ -412,7 +413,7 @@ if (CMAKE_SUBTITLE_SUPPORT)
)


set(LIBPLAYERGSTINTERFACE_SOURCES ${LIBPLAYERGSTINTERFACE_SOURCES} closedcaptions/subtec/PlayerSubtecCCManager.cpp closedcaptions/rialto/PlayerRialtoCCManager.cpp)
set(LIBPLAYERGSTINTERFACE_SOURCES ${LIBPLAYERGSTINTERFACE_SOURCES} closedcaptions/subtec/PlayerSubtecCCManager.cpp closedcaptions/rialto/PlayerRialtoCCManager.cpp closedcaptions/direct-rialto/PlayerDirectRialtoCCManager.cpp)
endif()
add_library(playergstinterface SHARED ${SOURCES} ${LIBPLAYERGSTINTERFACE_HEADERS} ${LIBPLAYERGSTINTERFACE_SOURCES} ${LIBPLAYERGSTINTERFACE_DRM_SOURCES} ${LIBPLAYERGSTINTERFACE_HELP_SOURCES})

Expand All @@ -426,6 +427,7 @@ target_include_directories(playergstinterface PUBLIC
${CMAKE_CURRENT_SOURCE_DIR}/playerjsonobject
${CMAKE_CURRENT_SOURCE_DIR}/closedcaptions
${CMAKE_CURRENT_SOURCE_DIR}/closedcaptions/subtec
${CMAKE_CURRENT_SOURCE_DIR}/closedcaptions/direct-rialto
${CMAKE_CURRENT_SOURCE_DIR}/vendor)

if (CMAKE_SUBTITLE_SUPPORT)
Expand Down
11 changes: 9 additions & 2 deletions DemuxDataTypes.h
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,11 @@ struct MediaCodecInfo
GstStreamOutputFormat mCodecFormat; // GST_FORMAT_VIDEO_ES_H264, etc
std::vector<uint8_t> mCodecData; // codec private data, e.g. avcC box
bool mIsEncrypted;
// True when NAL units are length-prefixed (AVCC/HVCC, e.g. avcC/hvcC
// sample entries per ISO/IEC 14496-15); false for Annex-B (start-code
// delimited) bitstreams such as HLS-TS ES output. Meaningless for
// non-NAL-unit codecs (audio/subtitle), where it stays false.
bool mNaluLengthPrefixed;
union
{
struct
Expand All @@ -116,7 +121,7 @@ struct MediaCodecInfo
* Uniform initialization is preferred for C++ types as it's type-safe, clearer in intent,
* and works correctly with all C++ types including those with constructors.
*/
MediaCodecInfo() : mCodecFormat(GST_FORMAT_INVALID), mIsEncrypted(false), mCodecData(), mInfo{0}
MediaCodecInfo() : mCodecFormat(GST_FORMAT_INVALID), mIsEncrypted(false), mNaluLengthPrefixed(false), mCodecData(), mInfo{0}
{
}

Expand All @@ -128,7 +133,7 @@ struct MediaCodecInfo
* Uniform initialization is preferred for C++ types as it's type-safe, clearer in intent,
* and works correctly with all C++ types including those with constructors.
*/
MediaCodecInfo(GstStreamOutputFormat format) : mCodecFormat(format), mIsEncrypted(false), mCodecData(), mInfo{0}
MediaCodecInfo(GstStreamOutputFormat format) : mCodecFormat(format), mIsEncrypted(false), mNaluLengthPrefixed(false), mCodecData(), mInfo{0}
{
}

Expand All @@ -144,6 +149,7 @@ struct MediaCodecInfo
: mCodecFormat(exchange(other.mCodecFormat, GST_FORMAT_INVALID))
, mCodecData(exchange(other.mCodecData, {}))
, mIsEncrypted(exchange(other.mIsEncrypted, false))
, mNaluLengthPrefixed(exchange(other.mNaluLengthPrefixed, false))
, mInfo(exchange(other.mInfo, {})) // POD union - exchange with zero-initialized union
{
}
Expand All @@ -160,6 +166,7 @@ struct MediaCodecInfo
mCodecFormat = exchange(other.mCodecFormat, GST_FORMAT_INVALID);
mCodecData = exchange(other.mCodecData, {});
mIsEncrypted = exchange(other.mIsEncrypted, false);
mNaluLengthPrefixed = exchange(other.mNaluLengthPrefixed, false);
mInfo = exchange(other.mInfo, {}); // POD union - exchange with zero-initialized union
}
return *this;
Expand Down
45 changes: 36 additions & 9 deletions closedcaptions/PlayerCCManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
#include "PlayerCCManager.h"
#include "PlayerSubtecCCManager.h"
#include "PlayerRialtoCCManager.h"
#include "PlayerDirectRialtoCCManager.h"


#define CHAR_CODE_1 49
Expand Down Expand Up @@ -823,9 +824,10 @@ bool PlayerCCManagerBase::IsOOBCCRenderingSupported()
PlayerCCManagerBase *PlayerCCManager::mInstance = NULL;

/**
* @brief Indicates whether mInstance should be a Rialto or a Subtec class.
* @brief Determines which CC manager subclass to instantiate.
*/
bool PlayerCCManager::mIsRialto = false;
PlayerCCManager::CCManagerType PlayerCCManager::mCCManagerType =
PlayerCCManager::CCManagerType::SubtecCCManager;

/**
* @brief Get the singleton instance
Expand All @@ -835,7 +837,12 @@ PlayerCCManagerBase *PlayerCCManager::GetInstance()
if (mInstance == NULL)
{
#if defined(SUBTITLE_SUPPORTED)
if (mIsRialto)
if (mCCManagerType == CCManagerType::DirectRialtoCCManager)
{
MW_LOG_INFO("PlayerCCManager::Creating DirectRialto CC manager");
mInstance = new PlayerDirectRialtoCCManager();
}
else if (mCCManagerType == CCManagerType::RialtoCCManager)
{
MW_LOG_INFO("PlayerCCManager::Creating Rialto CC manager");
mInstance = new PlayerRialtoCCManager();
Expand All @@ -853,6 +860,14 @@ PlayerCCManagerBase *PlayerCCManager::GetInstance()
return mInstance;
}

/**
* @brief Check whether the singleton has already been created
*/
bool PlayerCCManager::HasInstance()
{
return mInstance != NULL;
}

/**
* @brief Reset the state.
*/
Expand All @@ -871,18 +886,30 @@ void PlayerCCManagerBase::ResetState()
}

/**
* @brief Set the variant required
* @brief Set the CC manager variant
*/
void PlayerCCManager::SetRialto(bool bIsRialto)
void PlayerCCManager::SetRialto(bool bIsRialto, bool bIsDirectRialto)
{
CCManagerType newType = CCManagerType::SubtecCCManager;

if (bIsDirectRialto)
{
newType = CCManagerType::DirectRialtoCCManager;
}
else if (bIsRialto)
{
newType = CCManagerType::RialtoCCManager;
}

if (mInstance == NULL)
{
MW_LOG_INFO("PlayerCCManager::IsRialto:%d", bIsRialto);
mIsRialto = bIsRialto;
MW_LOG_INFO("PlayerCCManager::CCManagerType:%d", static_cast<int>(newType));
mCCManagerType = newType;
}
else if (mIsRialto != bIsRialto)
else if (mCCManagerType != newType)
{
MW_LOG_ERR("PlayerCCManager::IsRialto:%d while incompatible singleton instance exists", bIsRialto);
MW_LOG_ERR("PlayerCCManager::CCManagerType:%d while incompatible singleton instance exists",
static_cast<int>(newType));
}
}

Expand Down
42 changes: 39 additions & 3 deletions closedcaptions/PlayerCCManager.h
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,17 @@ class PlayerCCManagerBase
*/
virtual void Release(int iID) = 0;

/**
* @brief Clear the stored control handle if it currently equals handle.
* Called by the handle owner's destructor so a handle can never be
* used after the object it points to is freed, independent of
* whether the GetId()/Release() usage count has reached zero (it
* may not have, if another session is still registered - see
* multi-pipeline mode).
* @param[in] handle - the handle being invalidated
*/
virtual void InvalidateHandle(void *) {}

/**
* @fn SetStatus
*
Expand Down Expand Up @@ -274,12 +285,26 @@ class PlayerCCManager
*/
static PlayerCCManagerBase * GetInstance();

/**
* @fn HasInstance
* @brief Check whether GetInstance() has already created the singleton,
* without creating it as a side effect.
*
* @return bool - true if an instance exists
*/
static bool HasInstance();

/**
* @fn SetRialto
* @brief Configure which CC manager subclass GetInstance() will create.
*
* @param[in] bIsRialto true when using the Rialto GStreamer sink
* (PlayerRialtoCCManager).
* @param[in] bIsDirectRialto true when using the direct-Rialto path
* (PlayerDirectRialtoCCManager).
* @return void
*/
static void SetRialto(bool bIsRialto);
static void SetRialto(bool bIsRialto, bool bIsDirectRialto = false);

/**
* @fn DestroyInstance
Expand All @@ -289,8 +314,19 @@ class PlayerCCManager
static void DestroyInstance();

private:
static PlayerCCManagerBase *mInstance; /**< Singleton instance */
static bool mIsRialto; /**< Determines which class to instantiate */
/**
* @enum CCManagerType
* @brief Identifies which PlayerCCManagerBase subclass to instantiate.
*/
enum class CCManagerType
{
SubtecCCManager, ///< Use PlayerSubtecCCManager (default)
RialtoCCManager, ///< Use PlayerRialtoCCManager
DirectRialtoCCManager ///< Use PlayerDirectRialtoCCManager
};

static PlayerCCManagerBase *mInstance; /**< Singleton instance */
static CCManagerType mCCManagerType; /**< Determines which class to instantiate */
};

class PlayerFakeCCManager : public PlayerCCManagerBase
Expand Down
64 changes: 64 additions & 0 deletions closedcaptions/direct-rialto/IDirectRialtoCC.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
/*
* If not stated otherwise in this file or this component's license file the
* following copyright and licenses apply:
*
* Copyright 2026 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 IDirectRialtoCC.h
* @brief Narrow control interface for closed-caption operations in the
* direct-rialto path.
*
* AampRialtoPlayer implements this interface and passes itself (cast to
* IDirectRialtoCC*) to PlayerDirectRialtoCCManager::Initialize() so that
* the CC manager can drive track selection and muting through the Rialto
* IMediaPipeline API without depending on GStreamer.
*/

#ifndef IDIRECT_RIALTO_CC_H
#define IDIRECT_RIALTO_CC_H

#include <string>

/**
* @interface IDirectRialtoCC
* @brief Minimal CC-control interface implemented by AampRialtoPlayer.
*
* Decouples PlayerDirectRialtoCCManager (which needs no Rialto headers) from
* AampRialtoPlayer (which owns the IMediaPipeline) so that neither class
* needs to include the other's full header.
*/
class IDirectRialtoCC
{
public:
virtual ~IDirectRialtoCC() = default;

/**
* @brief Set the active CC text-track identifier on the pipeline.
* @param id Track identifier string (e.g. "CC1", "SERVICE1").
* @return true on success.
*/
virtual bool setTextTrackIdentifier(const std::string &id) = 0;

/**
* @brief Mute or un-mute CC rendering via the pipeline.
* @param muted true to mute; false to un-mute.
* @return true on success.
*/
virtual bool setCCMute(bool muted) = 0;
};

#endif // IDIRECT_RIALTO_CC_H
Loading
Loading