LCOV - code coverage report
Current view: top level - media/common/source - MediaFrameWriterV2.cpp (source / functions) Coverage Total Hit
Test: coverage.info Lines: 91.9 % 99 91
Test Date: 2025-03-21 11:02:39 Functions: 100.0 % 6 6

            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 2022 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 "MediaFrameWriterV2.h"
      21              : #include "RialtoCommonLogging.h"
      22              : 
      23              : namespace
      24              : {
      25              : /**
      26              :  * @brief The version of metadata this object shall write.
      27              :  */
      28              : constexpr uint32_t kMetadataVersion = 2U;
      29              : 
      30              : /**
      31              :  * @brief Convert SegmentAlignment to protobuf object
      32              :  */
      33              : firebolt::rialto::MediaSegmentMetadata_SegmentAlignment
      34            4 : convertSegmentAlignment(const firebolt::rialto::SegmentAlignment &alignment)
      35              : {
      36            4 :     switch (alignment)
      37              :     {
      38            0 :     case firebolt::rialto::SegmentAlignment::UNDEFINED:
      39              :     {
      40            0 :         return firebolt::rialto::MediaSegmentMetadata_SegmentAlignment_ALIGNMENT_UNDEFINED;
      41              :     }
      42            2 :     case firebolt::rialto::SegmentAlignment::NAL:
      43              :     {
      44            2 :         return firebolt::rialto::MediaSegmentMetadata_SegmentAlignment_ALIGNMENT_NAL;
      45              :     }
      46            2 :     case firebolt::rialto::SegmentAlignment::AU:
      47              :     {
      48            2 :         return firebolt::rialto::MediaSegmentMetadata_SegmentAlignment_ALIGNMENT_AU;
      49              :     }
      50              :     }
      51            0 :     return firebolt::rialto::MediaSegmentMetadata_SegmentAlignment_ALIGNMENT_UNDEFINED;
      52              : }
      53              : 
      54              : /**
      55              :  * @brief Convert CipherMode to protobuf object
      56              :  */
      57            6 : firebolt::rialto::MediaSegmentMetadata_CipherMode convertCipherMode(const firebolt::rialto::CipherMode &cipherMode)
      58              : {
      59            6 :     switch (cipherMode)
      60              :     {
      61            2 :     case firebolt::rialto::CipherMode::UNKNOWN:
      62              :     {
      63            2 :         return firebolt::rialto::MediaSegmentMetadata_CipherMode_UNKNOWN;
      64              :     }
      65            1 :     case firebolt::rialto::CipherMode::CENC:
      66              :     {
      67            1 :         return firebolt::rialto::MediaSegmentMetadata_CipherMode_CENC;
      68              :     }
      69            1 :     case firebolt::rialto::CipherMode::CBC1:
      70              :     {
      71            1 :         return firebolt::rialto::MediaSegmentMetadata_CipherMode_CBC1;
      72              :     }
      73            1 :     case firebolt::rialto::CipherMode::CENS:
      74              :     {
      75            1 :         return firebolt::rialto::MediaSegmentMetadata_CipherMode_CENS;
      76              :     }
      77            1 :     case firebolt::rialto::CipherMode::CBCS:
      78              :     {
      79            1 :         return firebolt::rialto::MediaSegmentMetadata_CipherMode_CBCS;
      80              :     }
      81              :     }
      82            0 :     return firebolt::rialto::MediaSegmentMetadata_CipherMode_UNKNOWN;
      83              : }
      84              : 
      85            4 : firebolt::rialto::MediaSegmentMetadata_CodecData_Type convertCodecDataType(const firebolt::rialto::CodecDataType &type)
      86              : {
      87            4 :     if (firebolt::rialto::CodecDataType::STRING == type)
      88              :     {
      89            0 :         return firebolt::rialto::MediaSegmentMetadata_CodecData_Type_STRING;
      90              :     }
      91            4 :     return firebolt::rialto::MediaSegmentMetadata_CodecData_Type_BUFFER;
      92              : }
      93              : 
      94              : } // namespace
      95              : 
      96              : namespace firebolt::rialto::common
      97              : {
      98           25 : MediaFrameWriterV2::MediaFrameWriterV2(uint8_t *shmBuffer, const std::shared_ptr<MediaPlayerShmInfo> &shmInfo)
      99           25 :     : m_shmBuffer(shmBuffer), m_kMaxBytes(shmInfo->maxMediaBytes), m_bytesWritten(0U),
     100           50 :       m_dataOffset(shmInfo->mediaDataOffset), m_numFrames{0}
     101              : {
     102           25 :     RIALTO_COMMON_LOG_INFO("We are using a writer for Metadata V2");
     103              : 
     104              :     // Zero memory
     105           25 :     m_byteWriter.fillBytes(m_shmBuffer, shmInfo->metadataOffset, 0, shmInfo->maxMetadataBytes);
     106           25 :     m_byteWriter.fillBytes(m_shmBuffer, m_dataOffset, 0, m_kMaxBytes);
     107              : 
     108              :     // Set metadata version
     109           25 :     m_byteWriter.writeUint32(m_shmBuffer, shmInfo->metadataOffset, kMetadataVersion);
     110              : }
     111              : 
     112           20 : AddSegmentStatus MediaFrameWriterV2::writeFrame(const std::unique_ptr<IMediaPipeline::MediaSegment> &data)
     113              : try
     114              : {
     115           20 :     auto metadata{buildMetadata(data)};
     116           19 :     size_t metadataSize{metadata.ByteSizeLong()};
     117           19 :     if (m_bytesWritten + sizeof(metadataSize) + metadataSize + data->getDataLength() > m_kMaxBytes)
     118              :     {
     119            1 :         RIALTO_COMMON_LOG_ERROR("Not enough memory available to write MediaSegment");
     120            1 :         return AddSegmentStatus::NO_SPACE;
     121              :     }
     122           18 :     m_dataOffset = m_byteWriter.writeUint32(m_shmBuffer, m_dataOffset, static_cast<uint32_t>(metadataSize));
     123           18 :     if (!metadata.SerializeToArray(m_shmBuffer + m_dataOffset, metadataSize))
     124              :     {
     125            0 :         RIALTO_COMMON_LOG_ERROR("Failed to write type specific metadata - protobuf serialization failed.");
     126            0 :         m_dataOffset -= 4; // size of metadata size written in previous step
     127            0 :         return AddSegmentStatus::ERROR;
     128              :     }
     129           18 :     m_dataOffset += metadataSize;
     130           18 :     m_dataOffset = m_byteWriter.writeBytes(m_shmBuffer, m_dataOffset, data->getData(), data->getDataLength());
     131              : 
     132              :     // Track the amount of bytes written
     133           18 :     m_bytesWritten += sizeof(metadataSize) + metadataSize + data->getDataLength();
     134           18 :     ++m_numFrames;
     135              : 
     136           18 :     return AddSegmentStatus::OK;
     137            7 : }
     138            1 : catch (std::exception &e)
     139              : {
     140            1 :     RIALTO_COMMON_LOG_ERROR("Failed to write type specific metadata - exception occured");
     141            1 :     return AddSegmentStatus::ERROR;
     142              : }
     143              : 
     144           20 : MediaSegmentMetadata MediaFrameWriterV2::buildMetadata(const std::unique_ptr<IMediaPipeline::MediaSegment> &data) const
     145              : {
     146           20 :     MediaSegmentMetadata metadata;
     147           20 :     metadata.set_length(data->getDataLength());
     148           20 :     metadata.set_time_position(data->getTimeStamp());
     149           20 :     metadata.set_sample_duration(data->getDuration());
     150           20 :     metadata.set_stream_id(static_cast<uint32_t>(data->getId()));
     151           20 :     if (MediaSourceType::AUDIO == data->getType())
     152              :     {
     153            9 :         IMediaPipeline::MediaSegmentAudio &audioSegment = dynamic_cast<IMediaPipeline::MediaSegmentAudio &>(*data);
     154            9 :         metadata.set_sample_rate(static_cast<uint32_t>(audioSegment.getSampleRate()));
     155            9 :         metadata.set_channels_num(static_cast<uint32_t>(audioSegment.getNumberOfChannels()));
     156            9 :         metadata.set_clipping_start(audioSegment.getClippingStart());
     157            9 :         metadata.set_clipping_end(audioSegment.getClippingEnd());
     158              :     }
     159           11 :     else if (MediaSourceType::VIDEO == data->getType())
     160              :     {
     161            9 :         IMediaPipeline::MediaSegmentVideo &videoSegment = dynamic_cast<IMediaPipeline::MediaSegmentVideo &>(*data);
     162            9 :         metadata.set_width(videoSegment.getWidth());
     163            9 :         metadata.set_height(videoSegment.getHeight());
     164            9 :         metadata.mutable_frame_rate()->set_numerator(videoSegment.getFrameRate().numerator);
     165            9 :         metadata.mutable_frame_rate()->set_denominator(videoSegment.getFrameRate().denominator);
     166              :     }
     167            2 :     else if (MediaSourceType::SUBTITLE != data->getType())
     168              :     {
     169            1 :         RIALTO_COMMON_LOG_ERROR("Failed to write type specific metadata - media source type unsupported");
     170            1 :         throw std::exception();
     171              :     }
     172              : 
     173           19 :     if (!data->getExtraData().empty())
     174              :     {
     175           12 :         metadata.set_extra_data(std::string(data->getExtraData().begin(), data->getExtraData().end()));
     176              :     }
     177           19 :     if (SegmentAlignment::UNDEFINED != data->getSegmentAlignment())
     178              :     {
     179            4 :         metadata.set_segment_alignment(convertSegmentAlignment(data->getSegmentAlignment()));
     180              :     }
     181           19 :     if (data->getCodecData())
     182              :     {
     183            4 :         metadata.mutable_codec_data()->set_data(
     184            8 :             std::string(data->getCodecData()->data.begin(), data->getCodecData()->data.end()));
     185            4 :         metadata.mutable_codec_data()->set_type(convertCodecDataType(data->getCodecData()->type));
     186              :     }
     187           19 :     if (data->isEncrypted())
     188              :     {
     189            6 :         metadata.set_media_key_session_id(data->getMediaKeySessionId());
     190           18 :         metadata.set_key_id(std::string(data->getKeyId().begin(), data->getKeyId().end()));
     191           12 :         metadata.set_init_vector(std::string(data->getInitVector().begin(), data->getInitVector().end()));
     192            6 :         metadata.set_init_with_last_15(data->getInitWithLast15());
     193            6 :         metadata.set_cipher_mode(convertCipherMode(data->getCipherMode()));
     194            6 :         uint32_t crypt{0};
     195            6 :         uint32_t skip{0};
     196            6 :         if (data->getEncryptionPattern(crypt, skip))
     197              :         {
     198            2 :             metadata.set_crypt(crypt);
     199            2 :             metadata.set_skip(skip);
     200              :         }
     201              : 
     202           12 :         for (const auto &subSample : data->getSubSamples())
     203              :         {
     204            6 :             auto subSamplePair = metadata.mutable_sub_sample_info()->Add();
     205            6 :             subSamplePair->set_num_clear_bytes(static_cast<uint32_t>(subSample.numClearBytes));
     206            6 :             subSamplePair->set_num_encrypted_bytes(static_cast<uint32_t>(subSample.numEncryptedBytes));
     207              :         }
     208              :     }
     209           19 :     return metadata;
     210            1 : }
     211              : } // namespace firebolt::rialto::common
        

Generated by: LCOV version 2.0-1