LCOV - code coverage report
Current view: top level - media/server/main/source - DataReaderV2.cpp (source / functions) Coverage Total Hit
Test: coverage.info Lines: 89.3 % 112 100
Test Date: 2025-02-18 13:13:53 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 "DataReaderV2.h"
      21              : #include "RialtoServerLogging.h"
      22              : #include "ShmCommon.h"
      23              : #include "TypeConverters.h"
      24              : #include "metadata.pb.h"
      25              : 
      26              : namespace
      27              : {
      28              : firebolt::rialto::SegmentAlignment
      29            2 : convertSegmentAlignment(const firebolt::rialto::MediaSegmentMetadata_SegmentAlignment &segmentAlignment)
      30              : {
      31            2 :     switch (segmentAlignment)
      32              :     {
      33            0 :     case firebolt::rialto::MediaSegmentMetadata_SegmentAlignment_ALIGNMENT_UNDEFINED:
      34              :     {
      35            0 :         return firebolt::rialto::SegmentAlignment::UNDEFINED;
      36              :     }
      37            0 :     case firebolt::rialto::MediaSegmentMetadata_SegmentAlignment_ALIGNMENT_NAL:
      38              :     {
      39            0 :         return firebolt::rialto::SegmentAlignment::NAL;
      40              :     }
      41            2 :     case firebolt::rialto::MediaSegmentMetadata_SegmentAlignment_ALIGNMENT_AU:
      42              :     {
      43            2 :         return firebolt::rialto::SegmentAlignment::AU;
      44              :     }
      45              :     }
      46            0 :     return firebolt::rialto::SegmentAlignment::UNDEFINED;
      47              : }
      48              : 
      49            4 : firebolt::rialto::CipherMode convertCipherMode(const firebolt::rialto::MediaSegmentMetadata_CipherMode &cipherMode)
      50              : {
      51            4 :     switch (cipherMode)
      52              :     {
      53            0 :     case firebolt::rialto::MediaSegmentMetadata_CipherMode_UNKNOWN:
      54              :     {
      55            0 :         return firebolt::rialto::CipherMode::UNKNOWN;
      56              :     }
      57            1 :     case firebolt::rialto::MediaSegmentMetadata_CipherMode_CENC:
      58              :     {
      59            1 :         return firebolt::rialto::CipherMode::CENC;
      60              :     }
      61            1 :     case firebolt::rialto::MediaSegmentMetadata_CipherMode_CBC1:
      62              :     {
      63            1 :         return firebolt::rialto::CipherMode::CBC1;
      64              :     }
      65            1 :     case firebolt::rialto::MediaSegmentMetadata_CipherMode_CENS:
      66              :     {
      67            1 :         return firebolt::rialto::CipherMode::CENS;
      68              :     }
      69            1 :     case firebolt::rialto::MediaSegmentMetadata_CipherMode_CBCS:
      70              :     {
      71            1 :         return firebolt::rialto::CipherMode::CBCS;
      72              :     }
      73              :     }
      74            0 :     return firebolt::rialto::CipherMode::UNKNOWN;
      75              : }
      76              : 
      77            2 : firebolt::rialto::CodecDataType convertCodecDataType(const firebolt::rialto::MediaSegmentMetadata_CodecData_Type &type)
      78              : {
      79            2 :     if (firebolt::rialto::MediaSegmentMetadata_CodecData_Type_STRING == type)
      80              :     {
      81            0 :         return firebolt::rialto::CodecDataType::STRING;
      82              :     }
      83            2 :     return firebolt::rialto::CodecDataType::BUFFER;
      84              : }
      85              : 
      86              : std::unique_ptr<firebolt::rialto::IMediaPipeline::MediaSegment>
      87           11 : createSegment(const firebolt::rialto::MediaSegmentMetadata &metadata, const firebolt::rialto::MediaSourceType &type)
      88              : {
      89              :     // Create segment
      90           11 :     std::unique_ptr<firebolt::rialto::IMediaPipeline::MediaSegment> segment;
      91           11 :     if (type == firebolt::rialto::MediaSourceType::AUDIO)
      92              :     {
      93            5 :         if (!metadata.has_sample_rate() || !metadata.has_channels_num())
      94              :         {
      95            1 :             RIALTO_SERVER_LOG_ERROR("SampleRate/ChannelsNum not present in audio metadata");
      96            1 :             return nullptr;
      97              :         }
      98            8 :         segment = std::make_unique<firebolt::rialto::IMediaPipeline::MediaSegmentAudio>(metadata.stream_id(),
      99            4 :                                                                                         metadata.time_position(),
     100            4 :                                                                                         metadata.sample_duration(),
     101            4 :                                                                                         metadata.sample_rate(),
     102            4 :                                                                                         metadata.channels_num(),
     103            4 :                                                                                         metadata.clipping_start(),
     104           12 :                                                                                         metadata.clipping_end());
     105              :     }
     106            6 :     else if (type == firebolt::rialto::MediaSourceType::VIDEO)
     107              :     {
     108            5 :         if (!metadata.has_width() || !metadata.has_height())
     109              :         {
     110            1 :             RIALTO_SERVER_LOG_ERROR("Width/height not present in video metadata");
     111            1 :             return nullptr;
     112              :         }
     113              : 
     114            4 :         firebolt::rialto::Fraction frameRate{firebolt::rialto::kUndefinedSize, firebolt::rialto::kUndefinedSize};
     115            4 :         if (metadata.has_frame_rate())
     116              :         {
     117            4 :             frameRate = {metadata.frame_rate().numerator(), metadata.frame_rate().denominator()};
     118              :         }
     119            8 :         segment = std::make_unique<firebolt::rialto::IMediaPipeline::MediaSegmentVideo>(metadata.stream_id(),
     120            4 :                                                                                         metadata.time_position(),
     121            4 :                                                                                         metadata.sample_duration(),
     122            4 :                                                                                         metadata.width(),
     123           12 :                                                                                         metadata.height(), frameRate);
     124              :     }
     125            1 :     else if (type == firebolt::rialto::MediaSourceType::SUBTITLE)
     126              :     {
     127              :         segment =
     128            2 :             std::make_unique<firebolt::rialto::IMediaPipeline::MediaSegment>(metadata.stream_id(),
     129            0 :                                                                              firebolt::rialto::MediaSourceType::SUBTITLE,
     130            1 :                                                                              metadata.time_position(),
     131            3 :                                                                              metadata.sample_duration());
     132              :     }
     133              :     else
     134              :     {
     135            0 :         RIALTO_SERVER_LOG_ERROR("Unknown segment type");
     136            0 :         return nullptr;
     137              :     }
     138              : 
     139              :     // Read optional data
     140            9 :     if (metadata.has_segment_alignment())
     141              :     {
     142            2 :         segment->setSegmentAlignment(convertSegmentAlignment(metadata.segment_alignment()));
     143              :     }
     144            9 :     if (metadata.has_extra_data())
     145              :     {
     146            2 :         segment->setExtraData(std::vector<uint8_t>(metadata.extra_data().begin(), metadata.extra_data().end()));
     147              :     }
     148            9 :     if (metadata.has_codec_data())
     149              :     {
     150            2 :         auto codecData = std::make_shared<firebolt::rialto::CodecData>();
     151            2 :         codecData->type = convertCodecDataType(metadata.codec_data().type());
     152            2 :         codecData->data = std::vector<uint8_t>(metadata.codec_data().data().begin(), metadata.codec_data().data().end());
     153            2 :         segment->setCodecData(codecData);
     154              :     }
     155              : 
     156              :     // Read encryption data
     157           14 :     if (metadata.has_media_key_session_id() || metadata.has_key_id() || metadata.has_init_vector() ||
     158            5 :         metadata.has_init_with_last_15())
     159              :     {
     160            4 :         segment->setEncrypted(true);
     161              :     }
     162              :     else
     163              :     {
     164            5 :         segment->setEncrypted(false);
     165              :     }
     166            9 :     if (metadata.has_media_key_session_id())
     167              :     {
     168            4 :         segment->setMediaKeySessionId(metadata.media_key_session_id());
     169              :     }
     170            9 :     if (metadata.has_key_id())
     171              :     {
     172            4 :         segment->setKeyId(std::vector<uint8_t>(metadata.key_id().begin(), metadata.key_id().end()));
     173              :     }
     174            9 :     if (metadata.has_init_vector())
     175              :     {
     176            4 :         segment->setInitVector(std::vector<uint8_t>(metadata.init_vector().begin(), metadata.init_vector().end()));
     177              :     }
     178            9 :     if (metadata.has_init_with_last_15())
     179              :     {
     180            4 :         segment->setInitWithLast15(metadata.init_with_last_15());
     181              :     }
     182            9 :     if (metadata.has_cipher_mode())
     183              :     {
     184            4 :         segment->setCipherMode(convertCipherMode(metadata.cipher_mode()));
     185              :     }
     186            9 :     if (metadata.has_crypt() && metadata.has_skip())
     187              :     {
     188            2 :         segment->setEncryptionPattern(metadata.crypt(), metadata.skip());
     189              :     }
     190              : 
     191           13 :     for (const auto &info : metadata.sub_sample_info())
     192              :     {
     193            4 :         segment->addSubSample(info.num_clear_bytes(), info.num_encrypted_bytes());
     194              :     }
     195            9 :     return segment;
     196           11 : }
     197              : } // namespace
     198              : 
     199              : namespace firebolt::rialto::server
     200              : {
     201           13 : DataReaderV2::DataReaderV2(const MediaSourceType &mediaSourceType, std::uint8_t *buffer, std::uint32_t dataOffset,
     202           13 :                            std::uint32_t numFrames)
     203           13 :     : m_mediaSourceType{mediaSourceType}, m_buffer{buffer}, m_dataOffset{dataOffset}, m_numFrames{numFrames}
     204              : {
     205           13 :     RIALTO_SERVER_LOG_DEBUG("Detected Metadata in Version 2. Media source type: %s",
     206              :                             common::convertMediaSourceType(m_mediaSourceType));
     207              : }
     208              : 
     209           12 : IMediaPipeline::MediaSegmentVector DataReaderV2::readData() const
     210              : {
     211           12 :     IMediaPipeline::MediaSegmentVector mediaSegments;
     212           12 :     uint8_t *currentReadPosition{m_buffer + m_dataOffset};
     213           21 :     for (auto i = 0U; i < m_numFrames; ++i)
     214              :     {
     215           12 :         std::uint32_t *metadataSize{reinterpret_cast<uint32_t *>(currentReadPosition)};
     216           12 :         currentReadPosition += sizeof(uint32_t);
     217           12 :         MediaSegmentMetadata metadata;
     218           12 :         if (!metadata.ParseFromArray(currentReadPosition, *metadataSize))
     219              :         {
     220            1 :             RIALTO_SERVER_LOG_ERROR("Metadata parsing failed!");
     221            1 :             return IMediaPipeline::MediaSegmentVector{};
     222              :         }
     223           11 :         auto newSegment{createSegment(metadata, m_mediaSourceType)};
     224           11 :         if (!newSegment)
     225              :         {
     226            2 :             RIALTO_SERVER_LOG_ERROR("Segment parsing failed!");
     227            2 :             return IMediaPipeline::MediaSegmentVector{};
     228              :         }
     229            9 :         currentReadPosition += *metadataSize;
     230            9 :         newSegment->setData(metadata.length(), currentReadPosition);
     231            9 :         currentReadPosition += metadata.length();
     232            9 :         mediaSegments.emplace_back(std::move(newSegment));
     233           14 :     }
     234            9 :     return mediaSegments;
     235           12 : }
     236              : } // namespace firebolt::rialto::server
        

Generated by: LCOV version 2.0-1