You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
RDKEMW-23564: Media Capabilities from yaml file Implementation
Reason for change: Add AudioDecoderCapabilities and VideoDecoderCapabilities with YAML config parsing, IPC serialization and unit test coverage.
Test Procedure: https://ccp.sys.comcast.net/browse/RDKEMW-23564
Associated JIRA ticket in format : < JIRA TICKET >: < one line summary of change less than 65 characters >
Detailed reason for change information
Test procedure. Only references links to Jira ticket or sub tickets where test steps and references are captured.
< JIRA TICKET >: < one line summary of change less than 65 characters >
< empty line >
Reason for change:
Test Procedure: < https://ccp.sys.comcast.net/browse/JIRA TICKET/url/to/test_step_section>
media/server/main/source/MediaCapabilitiesServerFactory.cpp:78:0: style: The function 'createMediaCapabilitiesFactory' is never used. [unusedFunction]
std::shared_ptrfirebolt::rialto::IMediaCapabilitiesFactory createMediaCapabilitiesFactory() const override
^
serverManager/common/source/MediaCapabilitiesFactory.cpp:28:0: style: The function 'createMediaCapabilities' is never used. [unusedFunction]
std::unique_ptr createMediaCapabilities()
^
nofile:0:0: information: Active checkers: 161/592 (use --checkers-report= to see details) [checkersReport]
The reason will be displayed to describe this comment to others. Learn more.
🔵 Needs a closer look
It introduces broad cross-component IPC/proto/API changes and there are confirmed functional blockers (capabilities not wired through in ServerManager and capability RPC path returning empty data) that must be resolved.
Pull request overview
This PR introduces a new end-to-end “media capabilities” flow: decoder capabilities are parsed from HFP YAML via a new yaml-cpp wrapper, forwarded from ServerManager to the session server using typed protobuf fields in SetConfigurationRequest, and exposed to clients via a new IMediaCapabilities IPC module/API.
Changes:
Added yaml-cpp based YAML parsing wrapper (IYamlCppWrapper / YamlCppWrapper) for audio/video decoder capability structs.
Extended ServerManager → SessionServer IPC (SetConfigurationRequest) to optionally carry typed audio/video capability payloads and threaded those optionals through the ServerManager IPC stack.
Added new IMediaCapabilities interface and MediaCapabilities IPC module (server + client), plus build/proto wiring to support the new messages and RPC service.
File summaries
File
Description
wrappers/source/YamlCppWrapperAccessor.cpp
Factory accessor glue for the new yaml-cpp wrapper factory.
wrappers/source/YamlCppWrapper.cpp
Implements YAML parsing for audio/video decoder capabilities using yaml-cpp.
wrappers/source/FactoryAccessor.cpp
Registers/lazily constructs the new YamlCppWrapperFactory.
wrappers/interface/IYamlCppWrapper.h
New wrappers interface for reading decoder capabilities from YAML.
wrappers/interface/IFactoryAccessor.h
Adds accessor for IYamlCppWrapperFactory.
wrappers/include/YamlCppWrapper.h
Concrete wrapper + factory declarations.
wrappers/include/FactoryAccessor.h
Adds member for the yaml-cpp wrapper factory.
wrappers/CMakeLists.txt
Links yaml-cpp and adds new wrapper sources/include paths.
serverManager/service/source/ServiceContext.cpp
Threads IMediaCapabilities into SessionServerAppManager creation.
Update the #endif comment to match the renamed include guard so the guard remains consistent. wrappers/source/YamlCppWrapper.cpp:723
Same issue as audio: YAML::LoadFile throws YAML::BadFile when the YAML file is missing, so missing files may be incorrectly returned as SCHEMA_VALIDATION_FAILED. Catch YAML::BadFile and map it to CONFIG_NOT_FOUND.
media/server/main/source/MediaCapabilitiesServerFactory.cpp:76:0: style: The function 'createMediaCapabilitiesFactory' is never used. [unusedFunction]
std::shared_ptrfirebolt::rialto::IMediaCapabilitiesFactory createMediaCapabilitiesFactory() const override
^
tests/componenttests/server/common/MessageBuilders.cpp:676:0: style: The function 'createGetSupportedAudioCapabilitiesRequest' is never used. [unusedFunction]
::firebolt::rialto::GetSupportedAudioCapabilitiesRequest createGetSupportedAudioCapabilitiesRequest()
^
tests/componenttests/server/common/MessageBuilders.cpp:682:0: style: The function 'createGetSupportedVideoCapabilitiesRequest' is never used. [unusedFunction]
::firebolt::rialto::GetSupportedVideoCapabilitiesRequest createGetSupportedVideoCapabilitiesRequest()
^
nofile:0:0: information: Active checkers: 161/592 (use --checkers-report= to see details) [checkersReport]
The reason will be displayed to describe this comment to others. Learn more.
🟡 Changes recommended
There are correctness issues in the new capability plumbing (broken public factory header type, non-clearing preloaded capability propagation, and GStreamer fallback methods returning never-populated capability data).
Once you've addressed the issues Copilot identified, you can request another Copilot review.
media/server/main/source/MediaCapabilitiesServerFactory.cpp:67:0: style: The function 'createMediaCapabilitiesFactory' is never used. [unusedFunction]
std::shared_ptrfirebolt::rialto::IMediaCapabilitiesFactory createMediaCapabilitiesFactory() const override
^
tests/componenttests/server/common/MessageBuilders.cpp:676:0: style: The function 'createGetSupportedAudioCapabilitiesRequest' is never used. [unusedFunction]
::firebolt::rialto::GetSupportedAudioCapabilitiesRequest createGetSupportedAudioCapabilitiesRequest()
^
tests/componenttests/server/common/MessageBuilders.cpp:682:0: style: The function 'createGetSupportedVideoCapabilitiesRequest' is never used. [unusedFunction]
::firebolt::rialto::GetSupportedVideoCapabilitiesRequest createGetSupportedVideoCapabilitiesRequest()
^
nofile:0:0: information: Active checkers: 161/592 (use --checkers-report= to see details) [checkersReport]
The reason will be displayed to describe this comment to others. Learn more.
🟡 Changes recommended
There are confirmed build-breaking test/mock issues and at least one functional gap where the intended GStreamer fallback path returns default/empty capabilities due to never-populated state.
Once you've addressed the issues Copilot identified, you can request another Copilot review.
setPreloadedCapabilities is a void method in ISessionServerManager, so this expectation cannot use WillOnce(Return(true)) (won't compile). media/server/ipc/source/ServerManagerModuleService.cpp:144
setPreloadedCapabilities() is only called when at least one capability field is present. If a previous setConfiguration supplied capabilities and a later one omits them, the session server will keep using stale preloaded capabilities. Consider always calling setPreloadedCapabilities(audioCaps, videoCaps) so nullopt clears state. media/server/service/source/SessionServerManager.cpp:208
SessionServerManager::setPreloadedCapabilities only forwards to MediaPipelineService when at least one optional has a value. If the caller passes nullopt optionals (to clear a previous preload), MediaPipelineService will keep stale capabilities. Forward the optionals unconditionally so downstream state is cleared. serverManager/public/include/MediaCapabilitiesFactory.h:30
This header declares createMediaCapabilities() returning std::unique_ptr<IMediaCapabilities>, but IMediaCapabilities is not declared anywhere in serverManager/public/include (the interface defined in IMediaCapabilities.h is IYamlCapabilities). This mismatch will break any consumer including this public header. media/server/gstplayer/source/GstCapabilities.cpp:476
GstCapabilities::getSupportedAudioCapabilities() / getSupportedVideoCapabilities() always return m_audioDecoderCapabilities / m_videoDecoderCapabilities, but these members are never populated anywhere in GstCapabilities.cpp (they're only default-constructed). That means the advertised "GStreamer fallback" path will return empty capabilities on config-absent platforms.
This test claims it covers the "preload missing" (GStreamer fallback) case, but it calls m_mediaCapabilities which the fixture constructs with preloaded audio/video optionals, so it will not exercise the fallback path.
Usha2124
changed the title
RDKEMW-23564: Media Capabilities from yaml file Implementation
RDKEMW-23564: Media Capabilities from yaml file Implementation
Sep 3, 2026
The reason will be displayed to describe this comment to others. Learn more.
🟡 Changes recommended
The GStreamer fallback path for decoder capabilities appears functionally incomplete (capability members never populated), and there are compile/test correctness issues that need resolving before this can be safely approved.
Once you've addressed the issues Copilot identified, you can request another Copilot review.
Review details
Suppressed comments (6)
Previously missed (1) — in code that hasn't changed since the last review.
This test claims to cover the "preload missing" path, but it calls m_mediaCapabilities which is constructed with both audio and video preloads in the fixture ctor. As written it cannot exercise the GStreamer fallback. Construct a MediaCapabilities instance with std::nullopt preloads and assert the returned values match the GStreamer path.
This issue also appears on line 66 of the same file.
MediaCapabilitiesFactory.h includes IYamlCapabilities.h, but that header does not exist in the repository (the IYamlCapabilities interface is declared in IMediaCapabilities.h). This will break compilation for any TU including this factory header. serverManager/common/include/MediaCapabilitiesFactory.h:25
This header duplicates the include guard macro used by serverManager/public/include/MediaCapabilitiesFactory.h, so including both headers in the same TU can silently skip one of them. It also uses a fragile relative include path into public/include. Use a unique guard for the common header and include the public header via the include search path instead of a relative path. media/server/gstplayer/source/GstCapabilities.cpp:476
GstCapabilities::getSupportedAudioCapabilities()/getSupportedVideoCapabilities() return m_audioDecoderCapabilities/m_videoDecoderCapabilities, but these members are never assigned anywhere in GstCapabilities.cpp (no element-query population), so the GStreamer fallback path will always return empty capabilities when YAML/preload is absent.
gstCapabilitiesWillNotBeQueried() is currently a no-op, so tests that claim to verify the preload path do not actually fail if the implementation unexpectedly queries GStreamer. Add explicit Times(0) expectations here. tests/unittests/media/server/main/mediaCapabilities/MediaCapabilitiesTests.cpp:66
This test claims to cover the "preload missing" path, but it calls m_mediaCapabilities which is constructed with both audio and video preloads in the fixture ctor. As written it cannot exercise the GStreamer fallback. Construct a MediaCapabilities instance with std::nullopt preloads and assert the returned values match the GStreamer path.
The reason will be displayed to describe this comment to others. Learn more.
Note
Copilot was unable to run its full agentic suite in this review.
Pull request overview
Copilot reviewed 146 out of 150 changed files in this pull request and generated 4 comments.
Suppressed comments (3)
wrappers/CMakeLists.txt:1
yaml-cpp is linked unconditionally, but find_package(yaml-cpp REQUIRED) is only executed in the non-UnitTests/non-Stub build branch. This can break configurations where yaml-cpp isn't available/desired (e.g., UnitTests builds or environments without the dev package) because the linker will still be asked to link yaml-cpp. Align the target_link_libraries(... yaml-cpp) and find_package(yaml-cpp ...) scopes (e.g., guard both under the same if()/feature flag). wrappers/CMakeLists.txt:1
yaml-cpp is linked unconditionally, but find_package(yaml-cpp REQUIRED) is only executed in the non-UnitTests/non-Stub build branch. This can break configurations where yaml-cpp isn't available/desired (e.g., UnitTests builds or environments without the dev package) because the linker will still be asked to link yaml-cpp. Align the target_link_libraries(... yaml-cpp) and find_package(yaml-cpp ...) scopes (e.g., guard both under the same if()/feature flag). tests/unittests/common/CMakeLists.txt:1
This removes add_subdirectory(misc) from the unit-test common build, but other changes in this PR reference RialtoCommonMisc (e.g., via $<TARGET_PROPERTY:RialtoCommonMisc,...> in tests/common/matchers/CMakeLists.txt). If RialtoCommonMisc is no longer created in the unit-test build graph, those generator expressions can break CMake generation. Ensure the new misc location is added consistently for unit tests (or remove the target-property dependency).
This unconditional push runs even after the preceding branch logs an unknown audio MIME. Existing GStreamer-to-MIME mapping emits values such as audio/mp4, audio/b-wav, and audio/x-raw, none of which populate a codec here, so the fallback advertises empty AudioDecoderCapability entries. Skip unknown MIME types or populate a real codec before pushing.
{
RIALTO_SERVER_LOG_WARN("Unknown audio MIME type '%s'", mimeType.c_str());
}
audioCapabilities.push_back(std::move(audioCap));
This unconditional push runs even after the preceding branch logs an unknown video MIME. For example, the existing mapping emits video/mp4, but this branch only logs that H.264 is a fallback and never populates videoCap, so the response contains an unusable empty video capability. Skip the unknown MIME or actually populate the claimed fallback before pushing.
{
RIALTO_SERVER_LOG_WARN("Unknown video MIME type '%s', using H.264 as fallback", mimeType.c_str());
}
videoCapabilities.push_back(std::move(videoCap));
IGstCapabilities is used as the pointee type at the constructor and member declarations below, but this header neither includes its definition nor forward-declares it. It currently compiles only because each known translation unit includes IGstCapabilities.h first; a direct include of this header fails. Include the interface here so the header is self-contained. media/server/main/source/MediaCapabilitiesServerInternal.cpp:132
The documented Path A behavior is to return ServerManager's preloaded YAML capabilities directly, but this branch always queries GStreamer and appends codecs/profiles. That means a YAML file that intentionally omits a codec is expanded at runtime and the advertised capability set is no longer the configured one. Return the cached value directly when present and query GStreamer only when it is absent. media/server/main/source/MediaCapabilitiesServerInternal.cpp:404
When YAML and GStreamer both contain a video codec, this merge branch unions only profiles and never unions dynamicRanges. Ranges present only in GStreamer are therefore lost from the returned capability (the same pattern is repeated for H264, H265, VP9, and AV1); merge each per-codec dynamic-range vector as well. media/server/service/source/MediaPipelineService.cpp:727
If the new MediaCapabilitiesServerInternal factory cannot be created, this returns an empty result even though m_mediaPipelineCapabilities was successfully constructed and still provides the existing GStreamer query path. That turns a recoverable factory failure into a silent loss of all capabilities; fall back to m_mediaPipelineCapabilities->getSupportedAudioCapabilities() here (and likewise for video) when m_mediaCapabilities is null. media/server/service/source/MediaPipelineService.cpp:739
If the new MediaCapabilitiesServerInternal factory cannot be created, this returns an empty result even though m_mediaPipelineCapabilities was successfully constructed and still provides the existing GStreamer query path. That turns a recoverable factory failure into a silent loss of all capabilities; fall back to m_mediaPipelineCapabilities->getSupportedVideoCapabilities() here when m_mediaCapabilities is null. serverManager/common/source/SessionServerAppManager.cpp:47
Non-OK YAML statuses are silently discarded for both audio and video. This makes a missing HFP file indistinguishable from a schema/internal failure in production logs, despite the status enum distinguishing those cases; retain the returned status and log CONFIG_NOT_FOUND at INFO and other failures at WARN before leaving the corresponding optional unset. serverManager/common/source/SessionServerAppManagerFactory.cpp:51
The ServerManager path constructs and injects IYamlCppWrapper directly, bypassing the IMediaCapabilities abstraction described by the change contract. This couples SessionServerAppManager to YAML parsing, prevents injecting a status-aware capability service in production/tests, and is why the cache currently has no status-specific handling; create/inject the ServerManager IMediaCapabilities service and keep the wrapper behind that boundary. tests/componenttests/server/tests/mediaCapabilities/MediaCapabilitiesAppendCodecsIntegrationTest.cpp:84
These new MediaCapabilities scenarios send GetSupportedMimeTypes, which is the legacy MediaPipelineCapabilities RPC; they never invoke getSupportedAudioCapabilities/getSupportedVideoCapabilities or validate typed capability serialization and orchestration. Use the dedicated audio/video request builders and matching response actions for all capability scenarios in this file. tests/componenttests/server/tests/mediaCapabilities/MediaCapabilitiesOrchestrationTest.cpp:92
This orchestration test also sends the legacy GetSupportedMimeTypes request, so its fallback, consistency, and unknown-source assertions do not exercise the new MediaCapabilities IPC methods at all. Replace these requests and response matchers with the dedicated audio/video capability RPCs before counting this as coverage for the new path. tests/unittests/media/server/main/mediaCapabilities/CMakeLists.txt:27
This standalone target does not compile MediaCapabilitiesAppendCodecsTests.cpp, so running RialtoServerMediaCapabilitiesTests omits the new append/merge coverage even though the aggregate main target lists it. Add the source here so the component-specific target actually runs all of its tests. tests/unittests/serverManager/unittests/service/ServerManagerServiceTests.cpp:104
These tests invoke YamlCppWrapperMock directly, so they only verify that a GMock expectation can be set and do not exercise any production delegation, YAML parsing, status handling, caching, or IPC forwarding. They would pass even if the new implementation were completely disconnected. Replace them with tests that construct the relevant production class and assert wrapper calls/results (or add parser tests) to provide the promised coverage. wrappers/CMakeLists.txt:129
yaml-cpp is linked unconditionally, but find_package(yaml-cpp) and YamlCppWrapper.cpp are both skipped for UnitTests and ComponentTests. Those configurations still propagate -lyaml-cpp through the static RialtoWrappers target and can fail to link on environments that intentionally do not install yaml-cpp; keep this dependency under the same production-only condition as the source. wrappers/source/YamlCppWrapper.cpp:726
YAML::LoadFile raises YAML::BadFile when the video file is missing, but this catch maps every exception to SCHEMA_VALIDATION_FAILED. The audio implementation maps the same condition to CONFIG_NOT_FOUND, so a missing video YAML is reported as a schema error instead of taking the normal missing-config fallback. Handle YAML::BadFile before the generic catch. wrappers/source/YamlCppWrapper.cpp:670
The parser only treats a null document as missing, then returns OK when the required audiodecoder root is absent. SessionServerAppManager caches every OK result and forwards it as a present optional, so malformed YAML is accepted as an empty capability set rather than being reported as schema-invalid and falling back. Add a SCHEMA_VALIDATION_FAILED branch for a missing root node. wrappers/source/YamlCppWrapper.cpp:708
The parser only treats a null document as missing, then returns OK when the required videodecoder root is absent. SessionServerAppManager caches every OK result and forwards it as a present optional, so malformed YAML is accepted as an empty capability set rather than being reported as schema-invalid and falling back. Add a SCHEMA_VALIDATION_FAILED branch for a missing root node. wrappers/source/YamlCppWrapper.cpp:131
The named-profile helper silently returns an empty map when profiles is absent or has the wrong YAML type, while its caller still sets the codec optional and returns OK. That produces a capability entry with no usable profiles for AAC/DTS/etc. Treat a missing or non-sequence profiles node as schema validation failure instead of silently accepting it.
media/server/main/source/MediaCapabilitiesServerInternal.cpp:411:17: style: Consider using std::any_of algorithm instead of a raw loop. [useStlAlgorithm]
{
^
media/server/main/source/MediaCapabilitiesServerInternal.cpp:440:17: style: Consider using std::any_of algorithm instead of a raw loop. [useStlAlgorithm]
{
^
media/server/main/source/MediaCapabilitiesServerInternal.cpp:469:17: style: Consider using std::any_of algorithm instead of a raw loop. [useStlAlgorithm]
{
^
media/server/main/source/MediaCapabilitiesServerInternal.cpp:498:17: style: Consider using std::any_of algorithm instead of a raw loop. [useStlAlgorithm]
{
^
media/server/main/source/MediaCapabilitiesServerInternal.cpp:527:17: style: Consider using std::any_of algorithm instead of a raw loop. [useStlAlgorithm]
{
^
media/server/service/source/MediaPipelineService.cpp:34:23: warning: Member variable 'MediaPipelineService::m_metricsService' is not initialized in the constructor. [uninitMemberVar]
MediaPipelineService::MediaPipelineService(
^
nofile:0:0: information: Active checkers: 161/592 (use --checkers-report= to see details) [checkersReport]
m_metricsService is a reference member but the constructor signature no longer accepts a IPrivateMetricsService &metricsService parameter, so this reference cannot be initialized. This is a compile-time error (and/or a functional regression if metrics were intended to remain). Either reintroduce IPrivateMetricsService &metricsService in the constructor and initialize m_metricsService, or remove m_metricsService (and any downstream usage) if metrics are no longer part of this service. media/server/service/source/MediaPipelineService.h:1
m_metricsService is a reference member but the constructor signature no longer accepts a IPrivateMetricsService &metricsService parameter, so this reference cannot be initialized. This is a compile-time error (and/or a functional regression if metrics were intended to remain). Either reintroduce IPrivateMetricsService &metricsService in the constructor and initialize m_metricsService, or remove m_metricsService (and any downstream usage) if metrics are no longer part of this service. media/server/main/CMakeLists.txt:1
This hunk appears to replace multiple existing source files (e.g., metrics-related .cpp files) with only source/MediaCapabilitiesServerInternal.cpp. If those removed sources are still referenced by the library, this will break the build and/or remove required functionality. MediaCapabilitiesServerInternal.cpp should be added without dropping unrelated sources unless the PR also removes all usages of those previously compiled translation units. proto/CMakeLists.txt:1
privatemetricsmodule.proto was present in the previous protobuf_generate_cpp(...) list but is no longer generated here. If any targets include/use privatemetricsmodule.pb.h/.cc (which is likely given existing PrivateMetrics IPC code), this will cause build failures. Re-add privatemetricsmodule.proto to the generation list or ensure it is generated by another target that all dependents link against. tests/common/matchers/CMakeLists.txt:1
This introduces tab/whitespace-only lines inside target_include_directories, which can fail style/lint checks and makes CMake formatting inconsistent. Remove the blank tabbed line and align indentation consistently (spaces), keeping only valid directory entries under INTERFACE.
The public enum exposes HE_V1/HE_V2, but the HFP v1 requirement in openspec/changes/hfp-schema-v1-migration/specs/audio-decoder-capabilities/spec.md:24-27 names these profiles HE_AAC_V1/HE_AAC_V2 and expects those enum keys. The YAML converter likewise only accepts HE_V1/HE_V2, so a schema-conformant HE_AAC_V1 entry is silently dropped and the public API does not satisfy the documented contract; align the enum/converter names or update the schema and all producers.
enum class AacProfile
{
LC, /**< Low Complexity profile */
HE_V1, /**< High Efficiency v1 profile */
HE_V2, /**< High Efficiency v2 profile */
ELD, /**< Enhanced Low Delay profile */
X_HE /**< Extended High Efficiency profile */
The else branch logs an unknown audio MIME type but still appends the empty audioCap to audioCapabilities. Since the supported MIME set includes decoder/sink caps beyond the handled codecs, fallback results can contain ranks with no codec at all; only append a rank after populating a supported codec or add the missing mappings.
Unknown video MIME types are logged here, but the empty videoCap is still appended. This produces capability ranks with no codec (despite the comment that each rank must be populated) and can expose unusable entries from the GStreamer fallback; filter these ranks or implement the missing mappings before appending.
Path A is specified to use the ServerManager/YAML capabilities directly and skip GStreamer when preloaded data is present (openspec/changes/servermanager-media-capabilities/tasks.md:46). Querying and appending GStreamer codecs here makes the YAML data non-authoritative and can advertise codecs excluded by the HFP configuration; return the preloaded value without the fallback query. media/server/main/source/MediaCapabilitiesServerInternal.cpp:135
The video Path A has the same contract violation: with preloaded YAML data, the implementation must not query or merge GStreamer capabilities (openspec/changes/servermanager-media-capabilities/tasks.md:46). The current merge can expose codecs that the HFP configuration deliberately omits; return the preloaded value directly. media/server/main/source/MediaCapabilitiesServerInternal.cpp:53
The factory unconditionally creates the GStreamer fallback before the ServerManager can provide preloaded capabilities. If the GStreamer factory or wrapper cannot be created, this returns null and later YAML data cannot be served, even though the documented preloaded path should not depend on GStreamer. Defer fallback creation until it is needed or support a preloaded-only instance. proto/mediaCapabilitiesCommon.proto:30
The protobuf wire field for audio max_bitrate_in_bps is uint64, while the HFP schema and the new public contract specify uint32_t for all audio profile fields. This mismatch can expose a different API/wire type than the declared schema; align the protobuf and converter types with the public contract. serverManager/common/source/SessionServerAppManager.cpp:55
The constructor ignores both non-OK statuses, so a malformed YAML file is silently treated exactly like an expected missing file and the cached optionals remain unset. The documented behavior distinguishes CONFIG_NOT_FOUND from schema/internal failures (including different log severity); preserve the status and log/report validation failures so a broken deployment is not hidden behind the GStreamer fallback. tests/unittests/media/server/main/mediaCapabilities/CMakeLists.txt:22
This CMake file is never reached: tests/unittests/media/server/main/CMakeLists.txt lists these sources directly but does not add the mediaCapabilities subdirectory, and no other CMake file references this target. Consequently RialtoServerMediaCapabilitiesTests is never configured. Add this subdirectory to the parent target setup or remove the orphan target. tests/unittests/media/server/main/mediaCapabilities/CMakeLists.txt:26
If this target is enabled, these paths are resolved relative to the current mediaCapabilities directory, so CMake looks for mediaCapabilities/mediaCapabilities/MediaCapabilitiesTests.cpp, which does not exist. The append-codec test source is also omitted from this target. Use paths relative to the current directory and include MediaCapabilitiesAppendCodecsTests.cpp. tests/unittests/media/server/main/mediaCapabilities/MediaCapabilitiesAppendCodecsTests.cpp:46
This test target is configured for C++17, but designated member initializers are a C++20 feature. With the repository's global -Werror, this new test is rejected by compilers that diagnose the extension; initialize AudioProfileCapability positionally (or assign its fields explicitly). tests/unittests/serverManager/unittests/service/ServerManagerServiceTests.cpp:96
These tests only invoke YamlCppWrapperMock and assert that GMock records the call; they never exercise YamlCppWrapper, YAML loading, schema validation, status mapping, or IPC serialization. As a result they pass even if the new production parser is completely broken, so add tests using representative valid, malformed, and missing YAML configurations (and the actual wrapper/converters) rather than only testing the mock interface. wrappers/source/YamlCppWrapper.cpp:727
YAML::BadFile derives from std::exception, but this function has no BadFile catch before the generic catch. A missing video YAML file therefore returns SCHEMA_VALIDATION_FAILED instead of the declared CONFIG_NOT_FOUND status, unlike the audio implementation above. wrappers/source/YamlCppWrapper.cpp:117
When profiles is missing or empty, this returns a zero-initialized AudioProfileCapability and the caller still marks the codec as present, so malformed YAML is reported as OK and serialized with zero limits. Since all base-profile fields are required, reject a missing BASE entry here so the public method returns SCHEMA_VALIDATION_FAILED. wrappers/source/YamlCppWrapper.cpp:665
An existing but empty YAML file produces a null node and is classified as CONFIG_NOT_FOUND here. That status is reserved for YAML::BadFile/missing configuration; an empty file is present but invalid and should return SCHEMA_VALIDATION_FAILED, otherwise ServerManager treats a malformed deployment as an expected platform without configuration. wrappers/source/YamlCppWrapper.cpp:703
An existing but empty video YAML file produces a null node and is classified as CONFIG_NOT_FOUND here. That status is reserved for YAML::BadFile/missing configuration; an empty file is present but invalid and should return SCHEMA_VALIDATION_FAILED, otherwise ServerManager treats a malformed deployment as an expected platform without configuration. wrappers/source/YamlCppWrapper.cpp:684
A non-empty document without an audiodecoder mapping (for example {} or {other: value}) falls through this conditional and returns OK with an empty capability object. That is a schema error, not a valid empty capability result; validate the required root and capability-node types and return SCHEMA_VALIDATION_FAILED when they are absent or malformed. wrappers/source/YamlCppWrapper.cpp:722
A non-empty document without a videodecoder mapping (for example {} or {other: value}) falls through this conditional and returns OK with an empty capability object. That is a schema error, not a valid empty capability result; validate the required root and capability-node types and return SCHEMA_VALIDATION_FAILED when they are absent or malformed. wrappers/source/YamlCppWrapper.cpp:114
This helper returns immediately after the first profile entry, so malformed single-profile data such as [{BASE: {...}}, {OTHER: {...}}] (or a map containing multiple keys) is silently accepted and the extra entries are discarded. The schema requires a single BASE profile; validate the sequence/map cardinality before returning so malformed files produce SCHEMA_VALIDATION_FAILED. wrappers/source/YamlCppWrapper.cpp:151
The HFP v1 schema names the AAC keys HE_AAC_V1 and HE_AAC_V2, but this converter only recognizes HE_V1 and HE_V2. A valid schema-compliant YAML file will therefore silently drop those profiles from the map; align the accepted names and the common enum/protobuf contract with the schema. wrappers/source/YamlCppWrapper.cpp:139
Named-profile codecs have the same validation hole: a missing/non-sequence profiles node returns an empty map, and unknown profile keys are silently skipped. The codec is still marked present and parsing returns OK, so malformed YAML can be reported as a valid capability; reject these cases as schema validation failures.
Get a fresh assessment by requesting another Copilot review.
Review details
Suppressed comments (27)
Previously missed (2) — in code that hasn't changed since the last review.
wrappers/source/YamlCppWrapper.cpp:130
The named-profile parser silently accepts a codec with no profiles node by returning an empty map, which is then wrapped in an optional and reported as OK. A malformed AAC/DTS/etc. entry therefore bypasses schema validation; reject a missing or non-sequence profiles node instead of treating it as an empty capability. media/public/include/IMediaCapabilities.h:63
This public API documentation says preloaded HFP YAML is returned directly, but the server implementation copies it and appends missing GStreamer codecs before returning. Please describe the enhancement behavior so consumers do not rely on YAML being an unmodified result.
The HFP schema v1 contract requires all four audio profile limits to be uint32_t, but this new member—and the corresponding protobuf field—is uint64. That changes the public/IPC contract and does not match the schema; use uint32_t consistently or explicitly document and validate an intentional widening.
uint64_t maxBitrateInBps; /**< Maximum bitrate in bits per second */
Unknown audio MIME types are logged but still appended as empty AudioDecoderCapability entries. The supported-cap scan includes sink caps such as audio/x-raw and audio/b-wav, so the GStreamer fallback can return decoder entries with no codec fields. Skip unsupported MIME types (or populate a real codec) instead of pushing audioCap in this case.
{
RIALTO_SERVER_LOG_WARN("Unknown audio MIME type '%s'", mimeType.c_str());
}
audioCapabilities.push_back(std::move(audioCap));
The video unknown-MIME branch claims to use H.264 as a fallback, but it never populates videoCap before pushing it. Sink/parser caps such as video/mpeg can therefore produce empty video capability entries; either initialize the advertised H.264 fallback or skip the unsupported MIME type.
else
{
RIALTO_SERVER_LOG_WARN("Unknown video MIME type '%s', using H.264 as fallback", mimeType.c_str());
}
videoCapabilities.push_back(std::move(videoCap));
The supported MIME set used by this class includes audio/mpeg, mpegversion=(int)4 and audio/mpeg, mpegversion=(int)1, layer=(int)3, but these branches only recognize audio/aac and audio/mp3. Those common GStreamer MIME forms fall into the unknown branch and become empty capability entries, so AAC/MP3 fallback support is lost; classify audio/mpeg by its version/layer before the unknown case.
When preloaded YAML is present, Path A still waits for GStreamer and merges its discovered codecs into the YAML result. This means a curated YAML file is not returned as configured, and the request can block on GStreamer initialization; the documented preloaded path should return the cached data directly and use GStreamer only when no preload is available. media/server/main/source/MediaCapabilitiesServerInternal.cpp:135
The video preloaded path has the same issue as audio: it queries and merges GStreamer results even when YAML data is available. This exposes codecs/profiles that are absent from the configured YAML and defeats the intended no-GStreamer Path A; return the preloaded value directly here. media/server/main/source/MediaCapabilitiesServerInternal.cpp:48
This creates a second GstCapabilities instance for every session server; MediaPipelineService already creates one through MediaPipelineCapabilities (media/server/main/source/MediaPipelineCapabilities.cpp:68-76). With YAML preloaded, this still launches the full GStreamer discovery thread even though Path A should not query GStreamer, adding startup work and resource usage per server. Reuse the existing capability provider or defer this fallback object until a no-preload query is needed. media/server/service/source/MediaPipelineService.cpp:42
The existing m_mediaPipelineCapabilities construction already creates a GstCapabilities and starts its discovery thread; the new m_mediaCapabilities construction creates a second one. Every server now duplicates GStreamer element queries and initialization work. Reuse one capability provider or combine the two interfaces around a shared instance. serverManager/common/source/SessionServerAppManager.cpp:49
The statuses returned by the YAML wrapper are discarded whenever they are not OK, so missing and invalid configurations are silently indistinguishable. The required behavior calls for INFO on CONFIG_NOT_FOUND and WARN on schema/internal failures; log the result before leaving the optionals unset. tests/componenttests/client/tests/base/MediaCapabilitiesTestMethods.cpp:106
This test is labelled as the IPC failure case, but the mock never calls SetFailed; it returns a successful RPC with an empty response. The MediaCapabilitiesIpc error branch that checks ipcController->Failed() is therefore untested, so set the controller failure in this lambda (and apply the same correction to the video failure test). tests/componenttests/client/tests/base/MediaCapabilitiesTestMethods.cpp:123
As with the audio case, this video failure test returns an empty successful response and never sets the RPC controller to failed. It does not cover the actual failure handling in MediaCapabilitiesIpc; make the mock call SetFailed() before running the closure. tests/componenttests/server/tests/mediaCapabilities/MediaCapabilitiesAppendCodecsIntegrationTest.cpp:89
This integration test (and the other tests in this file) calls the legacy GetSupportedMimeTypes RPC, so it never exercises MediaCapabilitiesServerInternal::getSupportedAudioCapabilities() or the YAML/GStreamer codec-append logic described by the test. It can pass even if the new capability path is completely broken; issue GetSupportedAudioCapabilitiesRequest/AudioCapabilities responses here and in the other append tests. tests/componenttests/server/tests/mediaCapabilities/MediaCapabilitiesAppendCodecsIntegrationTest.cpp:84
configureSutInActiveState() sends createGenericSetConfigurationReq(), which contains neither capability field; moreover the ComponentTests build does not compile the real YAML wrapper. Consequently these tests never install preloaded YAML capabilities, so even after switching to the new RPC they would only exercise GStreamer fallback, not the advertised append integration. tests/componenttests/server/tests/mediaCapabilities/MediaCapabilitiesOrchestrationTest.cpp:105
These orchestration tests query GetSupportedMimeTypes, the legacy media-pipeline RPC, rather than GetSupportedAudioCapabilities/GetSupportedVideoCapabilities. They therefore do not exercise the new MediaCapabilities IPC service or verify typed capability fallback/caching, despite the test names and expectations describing that behavior. tests/unittests/serverManager/unittests/service/ServerManagerServiceTests.cpp:111
This test only verifies that Google Mock can invoke a mock method and return OK; it never exercises YamlCppWrapper, parses a YAML document, or checks any capability fields. As a result, the newly added YAML parser has no unit coverage for its profile, codec, or schema-validation behavior (the same applies to the video test below). wrappers/CMakeLists.txt:129
yaml-cpp is linked unconditionally, but find_package(yaml-cpp REQUIRED) and YamlCppWrapper.cpp are enabled only for non-UnitTests/ComponentTests builds. Test configurations therefore still require a -lyaml-cpp library even though they do not compile any YAML implementation (and the test dependency is not guaranteed by this CMake file), causing otherwise valid wrapper/test builds to fail when yaml-cpp is absent. Keep this dependency inside the same WRAPPERS_ENABLED conditional, e.g. add it to WRAPPER_LIBS there instead of linking it here. wrappers/source/YamlCppWrapper.cpp:726
Unlike the audio loader, this catch-all also catches YAML::BadFile, so a missing or unreadable video YAML file is reported as SCHEMA_VALIDATION_FAILED rather than CONFIG_NOT_FOUND. Handle YAML::BadFile before the generic exception, matching getAudioDecoderCapabilities(). wrappers/source/YamlCppWrapper.cpp:692
The new file-backed YAML parser has no dedicated unit tests in tests/unittests/wrappers (that target currently contains only mocks). The audio/video schema mapping and status handling are central to this PR, so malformed files, missing fields, and representative codec/profile mappings should be exercised directly rather than only through the wrapper mock. wrappers/source/YamlCppWrapper.cpp:117
When profiles is missing, not a sequence, or empty, this helper returns a default-constructed capability. The caller then wraps that zero/default value in an optional and returns OK, so malformed base-codec YAML is advertised as a valid capability instead of producing SCHEMA_VALIDATION_FAILED. Reject the missing/invalid profile node rather than returning {}. wrappers/source/YamlCppWrapper.cpp:667
A syntactically valid YAML document without the required audiodecoder/Capabilities nodes falls through to OK with an empty result. That causes the ServerManager to cache and transmit an unusable empty capability set instead of reporting schema failure and using the documented fallback; validate the required root and capability nodes before returning OK. wrappers/source/YamlCppWrapper.cpp:138
Unknown profile names are silently skipped here, so a misspelled or unsupported profile produces an empty codec capability while the surrounding parser still returns OK. This turns malformed YAML into an apparently valid configuration; reject an unrecognized profile (and similarly invalid profile entries) so the caller receives SCHEMA_VALIDATION_FAILED. wrappers/source/YamlCppWrapper.cpp:346
The video parser drops unknown dynamic-range names and returns OK, leaving the advertised codec with incomplete ranges instead of rejecting the invalid schema. Treat an unrecognized value (and a non-sequence node) as a schema error, consistent with the required-field validation used for audio profiles. wrappers/source/YamlCppWrapper.cpp:661
The output object is appended to without being reset. Reusing the same capabilities object for a second successful call duplicates every YAML rank (and stale version fields can survive failures), so this getter is not idempotent. Clear the output before loading/parsing. wrappers/source/YamlCppWrapper.cpp:699
The video getter also appends to the caller-provided vector without clearing it, so repeated reads of the same wrapper duplicate capabilities and can retain stale metadata. Reset the output object before loading the file, as required for a getter that fills an output reference. wrappers/source/YamlCppWrapper.cpp:704
An existing file without the required videodecoder node (or its Capabilities node) falls through to OK with an empty result. That treats a malformed document as a valid configuration; validate the required top-level structure and return SCHEMA_VALIDATION_FAILED instead.
The video Path 0 has the same authority problem as the audio path: it performs GStreamer discovery and merges the result into the configured YAML capabilities. This violates the documented preloaded-capabilities precedence and can return capabilities not present in YAML; return the cached video value directly when it exists. wrappers/source/YamlCppWrapper.cpp:429
If maxLevel is present but has an unrecognized value, this builder leaves the enum at its zero value and still appends the profile. The other video builders have the same behavior, so a bad level is silently converted to a different valid level; reject unknown level strings as schema errors.
The HFP v1 task requires all four AudioProfileCapability fields to be uint32_t (openspec/changes/hfp-schema-v1-migration/tasks.md:9), but bitrate is declared as uint64_t here and the new protobuf/parser also use uint64. This widens the public API beyond the required contract; update the common type and all serialization/parsing sites together.
uint64_t maxBitrateInBps; /**< Maximum bitrate in bits per second */
uint32_t maxChannels; /**< Maximum number of channels */
uint32_t maxSampleRateInHz; /**< Maximum sample rate in Hz */
uint32_t maxBitDepth; /**< Maximum bit depth */
Unknown audio MIME types are still appended as empty decoder capabilities after only logging a warning. The existing caps mapping produces values such as audio/mp4, audio/b-wav, and audio/x-raw, which reach this branch; the resulting empty ranks are then serialized and can be mistaken for supported codecs. Skip unknown types instead of pushing audioCap.
{
RIALTO_SERVER_LOG_WARN("Unknown audio MIME type '%s'", mimeType.c_str());
}
audioCapabilities.push_back(std::move(audioCap));
The unknown-video branch logs that it is using an H.264 fallback, but it never populates videoCap.codecCapabilities.h264; the next line pushes an empty capability instead. For mapped types such as video/mp4, this produces an empty serialized rank. Either populate the documented fallback or skip the unknown MIME type.
This loop creates one decoder rank for every MIME type. AudioDecoderCapability represents a rank containing multiple codec optionals, and appendMissingAudioCodecsToYaml merges GStreamer and YAML by rank index; with AAC, MP3, and E-AC3 MIME types, the codecs are split across unrelated ranks (in arbitrary unordered_set order) instead of being combined. Build a single GStreamer rank containing all discovered codecs before appending.
for (const auto &mimeType : m_supportedMimeTypes)
{
if (mimeType.find("audio/") == 0)
{
// Create audio capability with codec-specific fields based on MIME type
The video path repeats the per-MIME-to-rank split. appendMissingVideoCodecsToYaml pairs ranks by index, so multiple discovered codecs are distributed into separate ranks and may be merged with the wrong YAML rank; accumulate the discovered video codec optionals into a rank before appending.
else if (mimeType.find("video/") == 0)
{
// Create video capability with codec-specific data based on MIME type
// Initialize with empty codec capabilities - will be populated based on MIME type
firebolt::rialto::common::VideoDecoderCapability videoCap;
When preloaded audio capabilities are present, this path still queries GStreamer and appends discovered codecs. The preloaded YAML is intended to be authoritative for Path 0, so this can expose codecs that the configuration deliberately omits; return the cached capabilities directly and reserve GStreamer for the no-preload path. media/server/main/source/MediaCapabilitiesServerInternal.cpp:44
Creating this fallback eagerly starts GstCapabilities' initialization thread, whose constructor performs GStreamer MIME/capability discovery before setPreloadedCapabilities() is called. Therefore even a fully configured Path 0 still incurs the GStreamer query that the design says to skip; make the fallback lazy or provide preload state before constructing it. serverManager/common/source/SessionServerAppManager.cpp:49
The new cache path is not exercised by the updated ServerManager tests: their SessionServerAppManager fixtures pass a null YAML wrapper, while the added mock tests invoke the mock directly. Add a test with a wrapper returning OK and assert that the resulting audio/video optionals are forwarded to performSetConfiguration(). serverManager/ipc/source/Client.cpp:255
The two capability optionals are serialized independently here, so a configuration with only one YAML file sends a partial SetConfigurationRequest. The ServerManager capability contract requires both typed fields to be absent when either optional is missing (openspec/changes/servermanager-media-capabilities/proposal.md:193-197); otherwise audio and video can silently use different sources. Gate both serializations on audioCaps.has_value() && videoCaps.has_value() and log the else case. serverManager/ipc/source/Client.cpp:307
This overload also serializes whichever optional happens to be present, producing a partial capability payload. The documented contract says that if either audio or video is unavailable, neither field should be sent (openspec/changes/servermanager-media-capabilities/proposal.md:193-197); use one has_value() conjunction for both fields, consistently with the socket-name overload. tests/unittests/media/client/main/mediaCapabilities/MediaCapabilitiesTest.cpp:65
This new client IPC test file is not listed in tests/unittests/media/client/main/CMakeLists.txt; that target only includes MediaCapabilitiesTests.cpp. As a result, these tests are never compiled or run, so add this source to the client-main unit-test target. wrappers/CMakeLists.txt:129
yaml-cpp is linked unconditionally, but both find_package(yaml-cpp REQUIRED) and YamlCppWrapper.cpp are excluded for UnitTests/ComponentTests. Those builds now link RialtoWrappers, so environments without yaml-cpp fail at link time even though the YAML implementation is not compiled. Keep this dependency inside the same non-test conditional as the package/source. wrappers/source/YamlCppWrapper.cpp:727
YAML::BadFile derives from std::exception, so a missing video configuration is caught here and reported as SCHEMA_VALIDATION_FAILED instead of CONFIG_NOT_FOUND (the audio method already distinguishes this case). Add a BadFile catch before the generic exception handler. wrappers/source/YamlCppWrapper.cpp:692
The generic exception handler maps every non-BadFile failure to SCHEMA_VALIDATION_FAILED, and the video handler does the same, leaving the public INTERNAL_ERROR status unreachable. Distinguish schema/conversion failures from unexpected internal failures so callers can apply the documented status contract. wrappers/source/YamlCppWrapper.cpp:138
Unknown named profiles are silently discarded, so a misspelled profile produces an incomplete capability object while the wrapper still returns OK. This defeats strict schema validation and can advertise a codec without the requested profile; reject the unknown key instead. wrappers/source/YamlCppWrapper.cpp:346
An unknown dynamic-range value is silently dropped and the wrapper still returns OK. A typo such as a misspelled HDR value therefore changes the advertised capability without any validation error; reject unknown enum values as a schema failure. wrappers/source/YamlCppWrapper.cpp:661
The new parser and status behavior has no real-wrapper unit coverage: the added YAML tests call YamlCppWrapperMock directly, so they pass even if YAML loading, profile validation, or CONFIG_NOT_FOUND handling is broken. Add tests that exercise YamlCppWrapper with representative valid and invalid audio/video documents (or inject the file source) and cover the status cases. wrappers/source/YamlCppWrapper.cpp:322
An unrecognized audio codec key is silently ignored, so malformed YAML still produces an OK status with a missing codec. Since this parser is intended to enforce the HFP schema, reject unknown codec keys rather than returning an incomplete capability object. wrappers/source/YamlCppWrapper.cpp:641
Unknown video codec keys are also ignored and the wrapper returns OK. A typo in a codec name therefore silently removes that codec from the advertised capabilities instead of reporting schema validation failure; add an explicit unknown-key error. wrappers/source/YamlCppWrapper.cpp:408
The video profile builders use this pattern for every codec: unknown profile names are skipped. This lets invalid profile keys return OK with incomplete capability data, contrary to strict schema validation; reject unknown profile names instead of continuing. wrappers/source/YamlCppWrapper.cpp:117
A single-profile codec with no profiles sequence, an empty sequence, or an empty entry falls through to a zero-initialized capability and the wrapper returns OK. The HFP schema requires a BASE profile for these codecs, so missing BASE data must raise a schema-validation error rather than advertise all-zero limits. wrappers/source/YamlCppWrapper.cpp:684
If the YAML file exists but lacks the required audiodecoder root, execution reaches this OK return with an empty capability set; the video method has the same behavior. A malformed document then becomes a present-but-empty preloaded capability and suppresses the GStreamer fallback, so missing required roots must be reported as schema validation failure. wrappers/source/YamlCppWrapper.cpp:722
A present video YAML document without the videodecoder root also returns OK with empty capabilities, which is then treated as authoritative preloaded data. Validate the required root before returning success, as with the corresponding audio path. wrappers/source/YamlCppWrapper.cpp:660
This method appends parsed ranks to the caller-provided vector without clearing it first. Reusing an AudioDecoderCapabilities object for a second successful call duplicates every rank, unlike a fill-style output parameter; reset the output object (or at least its fields) before loading. wrappers/source/YamlCppWrapper.cpp:698
The video parser has the same accumulation problem: every successful call pushes onto the existing capabilities.capabilities vector. A caller that reuses the output object receives duplicate decoder ranks, so reset capabilities at the start of this method as well.
media/server/service/source/MediaPipelineService.cpp:34:23: warning: Member variable 'MediaPipelineService::m_metricsService' is not initialized in the constructor. [uninitMemberVar]
MediaPipelineService::MediaPipelineService(
^
nofile:0:0: information: Active checkers: 161/592 (use --checkers-report= to see details) [checkersReport]
media/server/service/source/MediaPipelineService.cpp:34:23: warning: Member variable 'MediaPipelineService::m_metricsService' is not initialized in the constructor. [uninitMemberVar]
MediaPipelineService::MediaPipelineService(
^
nofile:0:0: information: Active checkers: 161/592 (use --checkers-report= to see details) [checkersReport]
m_mediaPipelineCapabilities has already constructed a GstCapabilities immediately above, while this factory constructs a second one for the new orchestrator. Each instance starts its own initialization and performs the full registry/caps scan, so every session now duplicates expensive GStreamer discovery. Reuse the existing discovery/orchestrator or otherwise share one GstCapabilities instance.
Exercise MediaCapabilities IPC in the component test
The newly registered component test does not exercise the new MediaCapabilities IPC at all: its requests are all GetSupportedMimeTypes, which belongs to the legacy pipeline-capabilities module. Replace these actions/builders with the audio/video MediaCapabilities RPCs so this test actually validates the feature it is named for.
This test is described as validating the new MediaCapabilities fallback, but it sends GetSupportedMimeTypes requests through the legacy MediaPipelineCapabilities service. It therefore never exercises MediaCapabilitiesModuleService, the typed capability converters, or the new fallback result; use the new audio/video capability requests and assert their typed responses.
Coverage statistics of your commit:
Congratulations, your commit improved lines coverage from: 84.4% to 84.5%
Congratulations, your commit improved functions coverage from: 92.7% to 92.8%
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for freeto subscribe to this conversation on GitHub.
Already have an account?
Sign in.
Labels
None yet
5 participants
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
RDKEMW-23564: Media Capabilities from yaml file Implementation
Reason for change: Add AudioDecoderCapabilities and VideoDecoderCapabilities with YAML config parsing, IPC serialization and unit test coverage.
Test Procedure: https://ccp.sys.comcast.net/browse/RDKEMW-23564