LCOV - code coverage report
Current view: top level - media/server/gstplayer/source - CapsBuilder.cpp (source / functions) Coverage Total Hit
Test: coverage.info Lines: 94.4 % 126 119
Test Date: 2025-06-05 13:57:59 Functions: 100.0 % 18 18

            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           17 : MediaSourceCapsBuilder::MediaSourceCapsBuilder(std::shared_ptr<firebolt::rialto::wrappers::IGstWrapper> gstWrapper,
      28              :                                                std::shared_ptr<firebolt::rialto::wrappers::IGlibWrapper> glibWrapper,
      29           17 :                                                const firebolt::rialto::IMediaPipeline::MediaSourceAV &source)
      30           17 :     : m_gstWrapper(gstWrapper), m_glibWrapper(glibWrapper), m_attachedSource(source)
      31              : {
      32              : }
      33           16 : GstCaps *MediaSourceCapsBuilder::buildCaps()
      34              : {
      35           16 :     return buildCommonCaps();
      36              : }
      37              : 
      38           16 : GstCaps *MediaSourceCapsBuilder::buildCommonCaps()
      39              : {
      40           16 :     GstCaps *caps = firebolt::rialto::server::createSimpleCapsFromMimeType(m_gstWrapper, m_attachedSource);
      41              : 
      42           16 :     addAlignmentToCaps(caps);
      43           16 :     addCodecDataToCaps(caps);
      44           16 :     addStreamFormatToCaps(caps);
      45              : 
      46           16 :     return caps;
      47              : }
      48              : 
      49           16 : void MediaSourceCapsBuilder::addAlignmentToCaps(GstCaps *caps) const
      50              : {
      51              :     static const std::unordered_map<firebolt::rialto::SegmentAlignment, std::string> aligmentMap =
      52           20 :         {{firebolt::rialto::SegmentAlignment::AU, "au"}, {firebolt::rialto::SegmentAlignment::NAL, "nal"}};
      53              : 
      54           16 :     auto aligmentMapIt = aligmentMap.find(m_attachedSource.getSegmentAlignment());
      55           16 :     if (aligmentMapIt != aligmentMap.end())
      56              :     {
      57            7 :         m_gstWrapper->gstCapsSetSimple(caps, "alignment", G_TYPE_STRING, aligmentMapIt->second.c_str(), nullptr);
      58              :     }
      59           17 : }
      60              : 
      61           16 : void MediaSourceCapsBuilder::addCodecDataToCaps(GstCaps *caps) const
      62              : {
      63           16 :     const std::shared_ptr<CodecData> &kCodecData = m_attachedSource.getCodecData();
      64           16 :     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           10 :     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           16 : }
      77              : 
      78           16 : 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           23 :          {firebolt::rialto::StreamFormat::HEV1, "hev1"}};
      86              : 
      87           16 :     auto formatMapIt = formatMap.find(m_attachedSource.getStreamFormat());
      88           16 :     if (formatMapIt != formatMap.end())
      89              :     {
      90            7 :         m_gstWrapper->gstCapsSetSimple(caps, "stream-format", G_TYPE_STRING, formatMapIt->second.c_str(), nullptr);
      91              :     }
      92           17 : }
      93              : 
      94           10 : MediaSourceAudioCapsBuilder::MediaSourceAudioCapsBuilder(
      95              :     std::shared_ptr<firebolt::rialto::wrappers::IGstWrapper> gstWrapper,
      96           10 :     std::shared_ptr<firebolt::rialto::wrappers::IGlibWrapper> glibWrapper, const IMediaPipeline::MediaSourceAudio &source)
      97           10 :     : MediaSourceCapsBuilder(gstWrapper, glibWrapper, source), m_attachedAudioSource(source)
      98              : {
      99              : }
     100              : 
     101           10 : GstCaps *MediaSourceAudioCapsBuilder::buildCaps()
     102              : {
     103           10 :     std::string mimeType = m_attachedSource.getMimeType();
     104           10 :     if (mimeType == "audio/x-opus")
     105              :     {
     106            1 :         return createOpusCaps();
     107              :     }
     108              : 
     109            9 :     GstCaps *caps = MediaSourceCapsBuilder::buildCaps();
     110            9 :     if (mimeType == "audio/mp4" || mimeType == "audio/aac")
     111              :     {
     112            3 :         addMpegVersionToCaps(caps);
     113              :     }
     114            6 :     else if (mimeType == "audio/b-wav" || mimeType == "audio/x-raw")
     115              :     {
     116            3 :         addRawAudioData(caps);
     117              :     }
     118            3 :     else if (mimeType == "audio/x-flac")
     119              :     {
     120            1 :         addFlacSpecificData(caps);
     121              :     }
     122            9 :     addSampleRateAndChannelsToCaps(caps);
     123              : 
     124            9 :     return caps;
     125           10 : }
     126              : 
     127            1 : GstCaps *MediaSourceAudioCapsBuilder::createOpusCaps()
     128              : {
     129            1 :     GstCaps *caps = getAudioSpecificConfiguration();
     130            1 :     if (!caps)
     131              :     {
     132            0 :         caps = m_gstWrapper->gstCapsNewSimple("audio/x-opus", "channel-mapping-family", G_TYPE_INT, 0, nullptr);
     133            0 :         addSampleRateAndChannelsToCaps(caps);
     134              :     }
     135              : 
     136            1 :     return caps;
     137              : }
     138              : 
     139            1 : GstCaps *MediaSourceAudioCapsBuilder::getAudioSpecificConfiguration() const
     140              : {
     141            1 :     GstCaps *caps = nullptr;
     142            1 :     firebolt::rialto::AudioConfig audioConfig = m_attachedAudioSource.getAudioConfig();
     143            1 :     if (audioConfig.codecSpecificConfig.size())
     144              :     {
     145            1 :         gsize codec_priv_size = audioConfig.codecSpecificConfig.size();
     146            1 :         gconstpointer codec_priv = audioConfig.codecSpecificConfig.data();
     147              : 
     148            1 :         caps = m_gstWrapper->gstCodecUtilsOpusCreateCapsFromHeader(codec_priv, codec_priv_size);
     149            1 :         if (!caps)
     150              :         {
     151            0 :             RIALTO_SERVER_LOG_ERROR("Failed to parse opus header");
     152              :         }
     153              :     }
     154              : 
     155            1 :     return caps;
     156              : }
     157              : 
     158            9 : void MediaSourceAudioCapsBuilder::addSampleRateAndChannelsToCaps(GstCaps *caps) const
     159              : {
     160            9 :     firebolt::rialto::AudioConfig audioConfig = m_attachedAudioSource.getAudioConfig();
     161              : 
     162            9 :     if (audioConfig.numberOfChannels != firebolt::rialto::kInvalidAudioChannels)
     163            4 :         m_gstWrapper->gstCapsSetSimple(caps, "channels", G_TYPE_INT, audioConfig.numberOfChannels, nullptr);
     164              : 
     165            9 :     if (audioConfig.sampleRate != firebolt::rialto::kInvalidAudioSampleRate)
     166            4 :         m_gstWrapper->gstCapsSetSimple(caps, "rate", G_TYPE_INT, audioConfig.sampleRate, nullptr);
     167            9 : }
     168              : 
     169            3 : void MediaSourceAudioCapsBuilder::addMpegVersionToCaps(GstCaps *caps) const
     170              : {
     171            3 :     m_gstWrapper->gstCapsSetSimple(caps, "mpegversion", G_TYPE_INT, 4, nullptr);
     172              : }
     173              : 
     174            3 : void MediaSourceAudioCapsBuilder::addRawAudioData(GstCaps *caps) const
     175              : {
     176            3 :     firebolt::rialto::AudioConfig audioConfig = m_attachedAudioSource.getAudioConfig();
     177            3 :     if (audioConfig.format.has_value())
     178            2 :         m_gstWrapper->gstCapsSetSimple(caps, "format", G_TYPE_STRING, common::convertFormat(audioConfig.format.value()),
     179              :                                        nullptr);
     180            3 :     if (audioConfig.layout.has_value())
     181            2 :         m_gstWrapper->gstCapsSetSimple(caps, "layout", G_TYPE_STRING, common::convertLayout(audioConfig.layout.value()),
     182              :                                        nullptr);
     183            3 :     if (audioConfig.channelMask.has_value())
     184            2 :         m_gstWrapper->gstCapsSetSimple(caps, "channel-mask", GST_TYPE_BITMASK, audioConfig.channelMask.value(), nullptr);
     185            3 : }
     186              : 
     187            1 : void MediaSourceAudioCapsBuilder::addFlacSpecificData(GstCaps *caps) const
     188              : {
     189            1 :     firebolt::rialto::AudioConfig audioConfig = m_attachedAudioSource.getAudioConfig();
     190            1 :     if (audioConfig.streamHeader.size())
     191              :     {
     192            1 :         GValue streamHeaderArray = G_VALUE_INIT;
     193            1 :         m_glibWrapper->gValueInit(&streamHeaderArray, GST_TYPE_ARRAY);
     194            2 :         for (const auto &header : audioConfig.streamHeader)
     195              :         {
     196            1 :             gpointer memory = m_glibWrapper->gMemdup(header.data(), header.size());
     197            1 :             GstBuffer *buf = m_gstWrapper->gstBufferNewWrapped(memory, header.size());
     198            1 :             GST_BUFFER_FLAG_SET(buf, GST_BUFFER_FLAG_HEADER);
     199              : 
     200            1 :             GValue value = G_VALUE_INIT;
     201            1 :             m_glibWrapper->gValueInit(&value, GST_TYPE_BUFFER);
     202            1 :             m_gstWrapper->gstValueSetBuffer(&value, buf);
     203            1 :             m_gstWrapper->gstValueArrayAppendValue(&streamHeaderArray, &value);
     204              : 
     205            1 :             m_glibWrapper->gValueUnset(&value);
     206            1 :             m_gstWrapper->gstBufferUnref(buf);
     207              :         }
     208            1 :         m_gstWrapper->gstStructureSetValue(m_gstWrapper->gstCapsGetStructure(caps, 0), "streamheader",
     209              :                                            &streamHeaderArray);
     210            1 :         m_glibWrapper->gValueUnset(&streamHeaderArray);
     211              :     }
     212            1 :     if (audioConfig.framed.has_value())
     213              :     {
     214            1 :         m_gstWrapper->gstCapsSetSimple(caps, "framed", G_TYPE_BOOLEAN, audioConfig.framed.value(), nullptr);
     215              :     }
     216              : }
     217              : 
     218            7 : MediaSourceVideoCapsBuilder::MediaSourceVideoCapsBuilder(
     219              :     std::shared_ptr<firebolt::rialto::wrappers::IGstWrapper> gstWrapper,
     220            7 :     std::shared_ptr<firebolt::rialto::wrappers::IGlibWrapper> glibWrapper, const IMediaPipeline::MediaSourceVideo &source)
     221            7 :     : MediaSourceCapsBuilder(gstWrapper, glibWrapper, source), m_attachedVideoSource(source)
     222              : {
     223              : }
     224              : 
     225            7 : GstCaps *MediaSourceVideoCapsBuilder::buildCaps()
     226              : {
     227            7 :     GstCaps *caps = MediaSourceCapsBuilder::buildCaps();
     228            7 :     if (m_attachedVideoSource.getWidth() != firebolt::rialto::kUndefinedSize)
     229            6 :         m_gstWrapper->gstCapsSetSimple(caps, "width", G_TYPE_INT, m_attachedVideoSource.getWidth(), nullptr);
     230            7 :     if (m_attachedVideoSource.getHeight() != firebolt::rialto::kUndefinedSize)
     231            6 :         m_gstWrapper->gstCapsSetSimple(caps, "height", G_TYPE_INT, m_attachedVideoSource.getHeight(), nullptr);
     232              : 
     233            7 :     return caps;
     234              : }
     235              : 
     236            1 : MediaSourceVideoDolbyVisionCapsBuilder::MediaSourceVideoDolbyVisionCapsBuilder(
     237              :     std::shared_ptr<firebolt::rialto::wrappers::IGstWrapper> gstWrapper,
     238              :     std::shared_ptr<firebolt::rialto::wrappers::IGlibWrapper> glibWrapper,
     239            1 :     const IMediaPipeline::MediaSourceVideoDolbyVision &source)
     240            1 :     : MediaSourceVideoCapsBuilder(gstWrapper, glibWrapper, source), m_attachedDolbySource(source)
     241              : {
     242              : }
     243              : 
     244            1 : GstCaps *MediaSourceVideoDolbyVisionCapsBuilder::buildCaps()
     245              : {
     246            1 :     GstCaps *caps = MediaSourceVideoCapsBuilder::buildCaps();
     247            1 :     m_gstWrapper->gstCapsSetSimple(caps, "dovi-stream", G_TYPE_BOOLEAN, true, nullptr);
     248            1 :     m_gstWrapper->gstCapsSetSimple(caps, "dv_profile", G_TYPE_UINT, m_attachedDolbySource.getDolbyVisionProfile(),
     249              :                                    nullptr);
     250            1 :     return caps;
     251              : }
     252              : } // namespace firebolt::rialto::server
        

Generated by: LCOV version 2.0-1