LCOV - code coverage report
Current view: top level - media/server/gstplayer/source - CapsBuilder.cpp (source / functions) Coverage Total Hit
Test: coverage.info Lines: 94.7 % 131 124
Test Date: 2025-07-31 10:33:57 Functions: 100.0 % 19 19

            Line data    Source code
       1              : /*
       2              :  * If not stated otherwise in this file or this component's LICENSE file the
       3              :  * following copyright and licenses apply:
       4              :  *
       5              :  * Copyright 2024 Sky UK
       6              :  *
       7              :  * Licensed under the Apache License, Version 2.0 (the "License");
       8              :  * you may not use this file except in compliance with the License.
       9              :  * You may obtain a copy of the License at
      10              :  *
      11              :  * http://www.apache.org/licenses/LICENSE-2.0
      12              :  *
      13              :  * Unless required by applicable law or agreed to in writing, software
      14              :  * distributed under the License is distributed on an "AS IS" BASIS,
      15              :  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
      16              :  * See the License for the specific language governing permissions and
      17              :  * limitations under the License.
      18              :  */
      19              : 
      20              : #include "CapsBuilder.h"
      21              : #include "GstMimeMapping.h"
      22              : #include "RialtoServerLogging.h"
      23              : #include "TypeConverters.h"
      24              : 
      25              : namespace firebolt::rialto::server
      26              : {
      27           18 : MediaSourceCapsBuilder::MediaSourceCapsBuilder(std::shared_ptr<firebolt::rialto::wrappers::IGstWrapper> gstWrapper,
      28              :                                                std::shared_ptr<firebolt::rialto::wrappers::IGlibWrapper> glibWrapper,
      29           18 :                                                const firebolt::rialto::IMediaPipeline::MediaSourceAV &source)
      30           18 :     : m_gstWrapper(gstWrapper), m_glibWrapper(glibWrapper), m_attachedSource(source)
      31              : {
      32              : }
      33           17 : GstCaps *MediaSourceCapsBuilder::buildCaps()
      34              : {
      35           17 :     return buildCommonCaps();
      36              : }
      37              : 
      38           17 : GstCaps *MediaSourceCapsBuilder::buildCommonCaps()
      39              : {
      40           17 :     GstCaps *caps = firebolt::rialto::server::createSimpleCapsFromMimeType(m_gstWrapper, m_attachedSource);
      41              : 
      42           17 :     addAlignmentToCaps(caps);
      43           17 :     addCodecDataToCaps(caps);
      44           17 :     addStreamFormatToCaps(caps);
      45              : 
      46           17 :     return caps;
      47              : }
      48              : 
      49           17 : void MediaSourceCapsBuilder::addAlignmentToCaps(GstCaps *caps) const
      50              : {
      51              :     static const std::unordered_map<firebolt::rialto::SegmentAlignment, std::string> aligmentMap =
      52           21 :         {{firebolt::rialto::SegmentAlignment::AU, "au"}, {firebolt::rialto::SegmentAlignment::NAL, "nal"}};
      53              : 
      54           17 :     auto aligmentMapIt = aligmentMap.find(m_attachedSource.getSegmentAlignment());
      55           17 :     if (aligmentMapIt != aligmentMap.end())
      56              :     {
      57            7 :         m_gstWrapper->gstCapsSetSimple(caps, "alignment", G_TYPE_STRING, aligmentMapIt->second.c_str(), nullptr);
      58              :     }
      59           18 : }
      60              : 
      61           17 : void MediaSourceCapsBuilder::addCodecDataToCaps(GstCaps *caps) const
      62              : {
      63           17 :     const std::shared_ptr<CodecData> &kCodecData = m_attachedSource.getCodecData();
      64           17 :     if (kCodecData && CodecDataType::BUFFER == kCodecData->type)
      65              :     {
      66            6 :         gpointer memory = m_glibWrapper->gMemdup(kCodecData->data.data(), kCodecData->data.size());
      67            6 :         GstBuffer *buf = m_gstWrapper->gstBufferNewWrapped(memory, kCodecData->data.size());
      68            6 :         m_gstWrapper->gstCapsSetSimple(caps, "codec_data", GST_TYPE_BUFFER, buf, nullptr);
      69            6 :         m_gstWrapper->gstBufferUnref(buf);
      70              :     }
      71           11 :     else if (kCodecData && CodecDataType::STRING == kCodecData->type)
      72              :     {
      73            2 :         std::string codecDataStr{kCodecData->data.begin(), kCodecData->data.end()};
      74            1 :         m_gstWrapper->gstCapsSetSimple(caps, "codec_data", G_TYPE_STRING, codecDataStr.c_str(), nullptr);
      75              :     }
      76           17 : }
      77              : 
      78           17 : void MediaSourceCapsBuilder::addStreamFormatToCaps(GstCaps *caps) const
      79              : {
      80              :     static const std::unordered_map<firebolt::rialto::StreamFormat, std::string> formatMap =
      81            0 :         {{firebolt::rialto::StreamFormat::RAW, "raw"},
      82            0 :          {firebolt::rialto::StreamFormat::AVC, "avc"},
      83            0 :          {firebolt::rialto::StreamFormat::BYTE_STREAM, "byte-stream"},
      84            0 :          {firebolt::rialto::StreamFormat::HVC1, "hvc1"},
      85           24 :          {firebolt::rialto::StreamFormat::HEV1, "hev1"}};
      86              : 
      87           17 :     auto formatMapIt = formatMap.find(m_attachedSource.getStreamFormat());
      88           17 :     if (formatMapIt != formatMap.end())
      89              :     {
      90            7 :         m_gstWrapper->gstCapsSetSimple(caps, "stream-format", G_TYPE_STRING, formatMapIt->second.c_str(), nullptr);
      91              :     }
      92           18 : }
      93              : 
      94           11 : MediaSourceAudioCapsBuilder::MediaSourceAudioCapsBuilder(
      95              :     std::shared_ptr<firebolt::rialto::wrappers::IGstWrapper> gstWrapper,
      96           11 :     std::shared_ptr<firebolt::rialto::wrappers::IGlibWrapper> glibWrapper, const IMediaPipeline::MediaSourceAudio &source)
      97           11 :     : MediaSourceCapsBuilder(gstWrapper, glibWrapper, source), m_attachedAudioSource(source)
      98              : {
      99              : }
     100              : 
     101           11 : GstCaps *MediaSourceAudioCapsBuilder::buildCaps()
     102              : {
     103           11 :     std::string mimeType = m_attachedSource.getMimeType();
     104           11 :     if (mimeType == "audio/x-opus")
     105              :     {
     106            1 :         return createOpusCaps();
     107              :     }
     108              : 
     109           10 :     GstCaps *caps = MediaSourceCapsBuilder::buildCaps();
     110           10 :     if (mimeType == "audio/mp4" || mimeType == "audio/aac")
     111              :     {
     112            3 :         addMpegVersion4ToCaps(caps);
     113              :     }
     114            7 :     else if (mimeType == "audio/mp3")
     115              :     {
     116            1 :         addMp3Caps(caps);
     117              :     }
     118            6 :     else if (mimeType == "audio/b-wav" || mimeType == "audio/x-raw")
     119              :     {
     120            3 :         addRawAudioData(caps);
     121              :     }
     122            3 :     else if (mimeType == "audio/x-flac")
     123              :     {
     124            1 :         addFlacSpecificData(caps);
     125              :     }
     126           10 :     addSampleRateAndChannelsToCaps(caps);
     127              : 
     128           10 :     return caps;
     129           11 : }
     130              : 
     131            1 : GstCaps *MediaSourceAudioCapsBuilder::createOpusCaps()
     132              : {
     133            1 :     GstCaps *caps = getAudioSpecificConfiguration();
     134            1 :     if (!caps)
     135              :     {
     136            0 :         caps = m_gstWrapper->gstCapsNewSimple("audio/x-opus", "channel-mapping-family", G_TYPE_INT, 0, nullptr);
     137            0 :         addSampleRateAndChannelsToCaps(caps);
     138              :     }
     139              : 
     140            1 :     return caps;
     141              : }
     142              : 
     143            1 : GstCaps *MediaSourceAudioCapsBuilder::getAudioSpecificConfiguration() const
     144              : {
     145            1 :     GstCaps *caps = nullptr;
     146            1 :     firebolt::rialto::AudioConfig audioConfig = m_attachedAudioSource.getAudioConfig();
     147            1 :     if (audioConfig.codecSpecificConfig.size())
     148              :     {
     149            1 :         gsize codec_priv_size = audioConfig.codecSpecificConfig.size();
     150            1 :         gconstpointer codec_priv = audioConfig.codecSpecificConfig.data();
     151              : 
     152            1 :         caps = m_gstWrapper->gstCodecUtilsOpusCreateCapsFromHeader(codec_priv, codec_priv_size);
     153            1 :         if (!caps)
     154              :         {
     155            0 :             RIALTO_SERVER_LOG_ERROR("Failed to parse opus header");
     156              :         }
     157              :     }
     158              : 
     159            1 :     return caps;
     160              : }
     161              : 
     162           10 : void MediaSourceAudioCapsBuilder::addSampleRateAndChannelsToCaps(GstCaps *caps) const
     163              : {
     164           10 :     firebolt::rialto::AudioConfig audioConfig = m_attachedAudioSource.getAudioConfig();
     165              : 
     166           10 :     if (audioConfig.numberOfChannels != firebolt::rialto::kInvalidAudioChannels)
     167            4 :         m_gstWrapper->gstCapsSetSimple(caps, "channels", G_TYPE_INT, audioConfig.numberOfChannels, nullptr);
     168              : 
     169           10 :     if (audioConfig.sampleRate != firebolt::rialto::kInvalidAudioSampleRate)
     170            4 :         m_gstWrapper->gstCapsSetSimple(caps, "rate", G_TYPE_INT, audioConfig.sampleRate, nullptr);
     171           10 : }
     172              : 
     173            3 : void MediaSourceAudioCapsBuilder::addMpegVersion4ToCaps(GstCaps *caps) const
     174              : {
     175            3 :     m_gstWrapper->gstCapsSetSimple(caps, "mpegversion", G_TYPE_INT, 4, nullptr);
     176              : }
     177              : 
     178            1 : void MediaSourceAudioCapsBuilder::addMp3Caps(GstCaps *caps) const
     179              : {
     180            1 :     m_gstWrapper->gstCapsSetSimple(caps, "mpegversion", G_TYPE_INT, 1, nullptr);
     181            1 :     m_gstWrapper->gstCapsSetSimple(caps, "layer", G_TYPE_INT, 3, nullptr);
     182              : }
     183              : 
     184            3 : void MediaSourceAudioCapsBuilder::addRawAudioData(GstCaps *caps) const
     185              : {
     186            3 :     firebolt::rialto::AudioConfig audioConfig = m_attachedAudioSource.getAudioConfig();
     187            3 :     if (audioConfig.format.has_value())
     188            2 :         m_gstWrapper->gstCapsSetSimple(caps, "format", G_TYPE_STRING, common::convertFormat(audioConfig.format.value()),
     189              :                                        nullptr);
     190            3 :     if (audioConfig.layout.has_value())
     191            2 :         m_gstWrapper->gstCapsSetSimple(caps, "layout", G_TYPE_STRING, common::convertLayout(audioConfig.layout.value()),
     192              :                                        nullptr);
     193            3 :     if (audioConfig.channelMask.has_value())
     194            2 :         m_gstWrapper->gstCapsSetSimple(caps, "channel-mask", GST_TYPE_BITMASK, audioConfig.channelMask.value(), nullptr);
     195            3 : }
     196              : 
     197            1 : void MediaSourceAudioCapsBuilder::addFlacSpecificData(GstCaps *caps) const
     198              : {
     199            1 :     firebolt::rialto::AudioConfig audioConfig = m_attachedAudioSource.getAudioConfig();
     200            1 :     if (audioConfig.streamHeader.size())
     201              :     {
     202            1 :         GValue streamHeaderArray = G_VALUE_INIT;
     203            1 :         m_glibWrapper->gValueInit(&streamHeaderArray, GST_TYPE_ARRAY);
     204            2 :         for (const auto &header : audioConfig.streamHeader)
     205              :         {
     206            1 :             gpointer memory = m_glibWrapper->gMemdup(header.data(), header.size());
     207            1 :             GstBuffer *buf = m_gstWrapper->gstBufferNewWrapped(memory, header.size());
     208            1 :             GST_BUFFER_FLAG_SET(buf, GST_BUFFER_FLAG_HEADER);
     209              : 
     210            1 :             GValue value = G_VALUE_INIT;
     211            1 :             m_glibWrapper->gValueInit(&value, GST_TYPE_BUFFER);
     212            1 :             m_gstWrapper->gstValueSetBuffer(&value, buf);
     213            1 :             m_gstWrapper->gstValueArrayAppendValue(&streamHeaderArray, &value);
     214              : 
     215            1 :             m_glibWrapper->gValueUnset(&value);
     216            1 :             m_gstWrapper->gstBufferUnref(buf);
     217              :         }
     218            1 :         m_gstWrapper->gstStructureSetValue(m_gstWrapper->gstCapsGetStructure(caps, 0), "streamheader",
     219              :                                            &streamHeaderArray);
     220            1 :         m_glibWrapper->gValueUnset(&streamHeaderArray);
     221              :     }
     222            1 :     if (audioConfig.framed.has_value())
     223              :     {
     224            1 :         m_gstWrapper->gstCapsSetSimple(caps, "framed", G_TYPE_BOOLEAN, audioConfig.framed.value(), nullptr);
     225              :     }
     226              : }
     227              : 
     228            7 : MediaSourceVideoCapsBuilder::MediaSourceVideoCapsBuilder(
     229              :     std::shared_ptr<firebolt::rialto::wrappers::IGstWrapper> gstWrapper,
     230            7 :     std::shared_ptr<firebolt::rialto::wrappers::IGlibWrapper> glibWrapper, const IMediaPipeline::MediaSourceVideo &source)
     231            7 :     : MediaSourceCapsBuilder(gstWrapper, glibWrapper, source), m_attachedVideoSource(source)
     232              : {
     233              : }
     234              : 
     235            7 : GstCaps *MediaSourceVideoCapsBuilder::buildCaps()
     236              : {
     237            7 :     GstCaps *caps = MediaSourceCapsBuilder::buildCaps();
     238            7 :     if (m_attachedVideoSource.getWidth() != firebolt::rialto::kUndefinedSize)
     239            6 :         m_gstWrapper->gstCapsSetSimple(caps, "width", G_TYPE_INT, m_attachedVideoSource.getWidth(), nullptr);
     240            7 :     if (m_attachedVideoSource.getHeight() != firebolt::rialto::kUndefinedSize)
     241            6 :         m_gstWrapper->gstCapsSetSimple(caps, "height", G_TYPE_INT, m_attachedVideoSource.getHeight(), nullptr);
     242              : 
     243            7 :     return caps;
     244              : }
     245              : 
     246            1 : MediaSourceVideoDolbyVisionCapsBuilder::MediaSourceVideoDolbyVisionCapsBuilder(
     247              :     std::shared_ptr<firebolt::rialto::wrappers::IGstWrapper> gstWrapper,
     248              :     std::shared_ptr<firebolt::rialto::wrappers::IGlibWrapper> glibWrapper,
     249            1 :     const IMediaPipeline::MediaSourceVideoDolbyVision &source)
     250            1 :     : MediaSourceVideoCapsBuilder(gstWrapper, glibWrapper, source), m_attachedDolbySource(source)
     251              : {
     252              : }
     253              : 
     254            1 : GstCaps *MediaSourceVideoDolbyVisionCapsBuilder::buildCaps()
     255              : {
     256            1 :     GstCaps *caps = MediaSourceVideoCapsBuilder::buildCaps();
     257            1 :     m_gstWrapper->gstCapsSetSimple(caps, "dovi-stream", G_TYPE_BOOLEAN, true, nullptr);
     258            1 :     m_gstWrapper->gstCapsSetSimple(caps, "dv_profile", G_TYPE_UINT, m_attachedDolbySource.getDolbyVisionProfile(),
     259              :                                    nullptr);
     260            1 :     return caps;
     261              : }
     262              : } // namespace firebolt::rialto::server
        

Generated by: LCOV version 2.0-1