LCOV - code coverage report
Current view: top level - source - GStreamerEMEUtils.cpp (source / functions) Coverage Total Hit
Test: coverage.info Lines: 100.0 % 99 99
Test Date: 2025-06-24 14:11:58 Functions: 100.0 % 9 9

            Line data    Source code
       1              : /*
       2              :  * Copyright (C) 2022 Sky UK
       3              :  *
       4              :  * This library is free software; you can redistribute it and/or
       5              :  * modify it under the terms of the GNU Lesser General Public
       6              :  * License as published by the Free Software Foundation;
       7              :  * version 2.1 of the License.
       8              :  *
       9              :  * This library is distributed in the hope that it will be useful,
      10              :  * but WITHOUT ANY WARRANTY; without even the implied warranty of
      11              :  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
      12              :  * Lesser General Public License for more details.
      13              :  *
      14              :  * You should have received a copy of the GNU Lesser General Public
      15              :  * License along with this library; if not, write to the Free Software
      16              :  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
      17              :  */
      18              : 
      19              : #include <cstdint>
      20              : 
      21              : #include <stdio.h>
      22              : 
      23              : #include "GStreamerEMEUtils.h"
      24              : #include "GStreamerUtils.h"
      25              : #include "GstreamerCatLog.h"
      26              : #include "RialtoGStreamerEMEProtectionMetadata.h"
      27              : 
      28              : #define GST_CAT_DEFAULT rialtoGStreamerCat
      29           16 : void getEncryptedFromProtectionMetadata(GstRialtoProtectionMetadata *protectionMeta, BufferProtectionMetadata &metadata)
      30              : {
      31           16 :     gboolean encrypted = FALSE;
      32           16 :     gst_structure_get_boolean(protectionMeta->info, "encrypted", &encrypted);
      33           16 :     metadata.encrypted = encrypted;
      34              : }
      35              : 
      36           16 : void getMediaKeySessionIdFromProtectionMetadata(GstRialtoProtectionMetadata *protectionMeta,
      37              :                                                 BufferProtectionMetadata &metadata)
      38              : {
      39           16 :     gint mediaKeySessionId = 0;
      40           16 :     gst_structure_get_int(protectionMeta->info, "mks_id", &mediaKeySessionId);
      41           16 :     metadata.mediaKeySessionId = mediaKeySessionId;
      42              : }
      43              : 
      44           16 : void getKIDFromProtectionMetadata(GstRialtoProtectionMetadata *protectionMeta, BufferProtectionMetadata &metadata)
      45              : {
      46           16 :     const GValue *value = gst_structure_get_value(protectionMeta->info, "kid");
      47           16 :     if (value)
      48              :     {
      49            8 :         GstBuffer *keyIDBuffer = gst_value_get_buffer(value);
      50            8 :         if (keyIDBuffer)
      51              :         {
      52            8 :             GstMappedBuffer mappedKeyID(keyIDBuffer, GST_MAP_READ);
      53            8 :             if (mappedKeyID)
      54              :             {
      55           16 :                 metadata.kid = std::vector<uint8_t>(mappedKeyID.data(), mappedKeyID.data() + mappedKeyID.size());
      56              :             }
      57            8 :         }
      58              :     }
      59           16 : }
      60              : 
      61           16 : void getIVFromProtectionMetadata(GstRialtoProtectionMetadata *protectionMeta, BufferProtectionMetadata &metadata)
      62              : {
      63           16 :     unsigned ivSize = 0;
      64           16 :     gst_structure_get_uint(protectionMeta->info, "iv_size", &ivSize);
      65           16 :     if (!ivSize && !g_strcmp0(gst_structure_get_string(protectionMeta->info, "cipher-mode"), "cbcs"))
      66              :     {
      67              :         // in case of cbcs, the same initialization vector is used to decrypt all the blocks
      68            2 :         gst_structure_get_uint(protectionMeta->info, "constant_iv_size", &ivSize);
      69              :     }
      70           16 :     const GValue *value = gst_structure_get_value(protectionMeta->info, "iv");
      71           16 :     if (value)
      72              :     {
      73            9 :         GstBuffer *ivBuffer = gst_value_get_buffer(value);
      74            9 :         if (ivBuffer)
      75              :         {
      76            9 :             GstMappedBuffer mappedIV(ivBuffer, GST_MAP_READ);
      77            9 :             if (mappedIV && (ivSize == mappedIV.size()))
      78              :             {
      79           18 :                 metadata.iv = std::vector<uint8_t>(mappedIV.data(), mappedIV.data() + mappedIV.size());
      80              :             }
      81            9 :         }
      82              :     }
      83           16 : }
      84              : 
      85           16 : void getSubSamplesFromProtectionMetadata(GstRialtoProtectionMetadata *protectionMeta, BufferProtectionMetadata &metadata)
      86              : {
      87           16 :     unsigned int subSampleCount = 0;
      88           16 :     gst_structure_get_uint(protectionMeta->info, "subsample_count", &subSampleCount);
      89              : 
      90           16 :     if (subSampleCount)
      91              :     {
      92            1 :         const GValue *value = gst_structure_get_value(protectionMeta->info, "subsamples");
      93            1 :         if (value)
      94              :         {
      95            1 :             GstBuffer *subSamplesBuffer = gst_value_get_buffer(value);
      96            1 :             if (subSamplesBuffer)
      97              :             {
      98            1 :                 GstMappedBuffer mappedSubSamples(subSamplesBuffer, GST_MAP_READ);
      99            1 :                 if (mappedSubSamples &&
     100            1 :                     ((mappedSubSamples.size() / (sizeof(int16_t) + sizeof(int32_t))) == subSampleCount))
     101              :                 {
     102              :                     std::vector<uint8_t> subSamples(mappedSubSamples.data(),
     103            1 :                                                     mappedSubSamples.data() + mappedSubSamples.size());
     104              :                     //'senc' atom
     105              :                     // unsigned   int(16)      subsample_count;
     106              :                     //{
     107              :                     //  unsigned   int(16)      BytesOfClearData;
     108              :                     //  unsigned   int(32)      BytesOfEncryptedData;
     109              :                     //}[subsample_count]
     110            1 :                     size_t subSampleOffset = 0;
     111            2 :                     for (unsigned int subSampleIdx = 0; subSampleIdx < subSampleCount; ++subSampleIdx)
     112              :                     {
     113            1 :                         uint16_t bytesOfClearData = (uint16_t)subSamples[subSampleOffset] << 8 |
     114            1 :                                                     (uint16_t)subSamples[subSampleOffset + 1];
     115            1 :                         uint32_t bytesOfEncryptedData = (uint32_t)subSamples[subSampleOffset + 2] << 24 |
     116            1 :                                                         (uint32_t)subSamples[subSampleOffset + 3] << 16 |
     117            1 :                                                         (uint32_t)subSamples[subSampleOffset + 4] << 8 |
     118            1 :                                                         (uint32_t)subSamples[subSampleOffset + 5];
     119            1 :                         metadata.subsamples.push_back(
     120            1 :                             std::make_pair((uint32_t)bytesOfClearData, (uint32_t)bytesOfEncryptedData));
     121            1 :                         subSampleOffset += sizeof(int16_t) + sizeof(int32_t);
     122              :                     }
     123              :                 }
     124              :             }
     125              :         }
     126              :     }
     127           16 : }
     128              : 
     129           16 : void getInitWithLast15FromProtectionMetadata(GstRialtoProtectionMetadata *protectionMeta,
     130              :                                              BufferProtectionMetadata &metadata)
     131              : {
     132           16 :     guint initWithLast15 = 0;
     133           16 :     gst_structure_get_uint(protectionMeta->info, "init_with_last_15", &initWithLast15);
     134           16 :     metadata.initWithLast15 = initWithLast15;
     135              : }
     136              : 
     137           16 : void getEncryptionSchemeFromProtectionMetadata(GstRialtoProtectionMetadata *protectionMeta,
     138              :                                                BufferProtectionMetadata &metadata)
     139              : {
     140           16 :     const char *cipherModeBuf = gst_structure_get_string(protectionMeta->info, "cipher-mode");
     141           16 :     GST_INFO("Retrieved encryption scheme '%s' from protection metadata.", cipherModeBuf ? cipherModeBuf : "unknown");
     142           16 :     if (g_strcmp0(cipherModeBuf, "cbcs") == 0)
     143              :     {
     144            2 :         metadata.cipherMode = firebolt::rialto::CipherMode::CBCS;
     145              :     }
     146           14 :     else if (g_strcmp0(cipherModeBuf, "cenc") == 0)
     147              :     {
     148            1 :         metadata.cipherMode = firebolt::rialto::CipherMode::CENC;
     149              :     }
     150           13 :     else if (g_strcmp0(cipherModeBuf, "cbc1") == 0)
     151              :     {
     152            1 :         metadata.cipherMode = firebolt::rialto::CipherMode::CBC1;
     153              :     }
     154           12 :     else if (g_strcmp0(cipherModeBuf, "cens") == 0)
     155              :     {
     156            1 :         metadata.cipherMode = firebolt::rialto::CipherMode::CENS;
     157              :     }
     158              :     else
     159              :     {
     160           11 :         if (cipherModeBuf)
     161              :         {
     162            1 :             GST_ERROR("Unknown encryption scheme '%s'!", cipherModeBuf);
     163              :         }
     164              :         else
     165              :         {
     166           10 :             GST_ERROR("Missing encryption scheme!");
     167              :         }
     168           11 :         metadata.cipherMode = firebolt::rialto::CipherMode::UNKNOWN;
     169              :     }
     170           16 : }
     171              : 
     172           16 : void getEncryptionPatternFromProtectionMetadata(GstRialtoProtectionMetadata *protectionMeta,
     173              :                                                 BufferProtectionMetadata &metadata)
     174              : {
     175           16 :     if (gst_structure_get_uint(protectionMeta->info, "crypt_byte_block", &metadata.cryptBlocks) == false)
     176              :     {
     177            7 :         GST_INFO("Failed to get crypt_byte_block value!");
     178            7 :         return;
     179              :     }
     180            9 :     if (gst_structure_get_uint(protectionMeta->info, "skip_byte_block", &metadata.skipBlocks) == false)
     181              :     {
     182            1 :         GST_INFO("Failed to get skip_byte_block value!");
     183            1 :         return;
     184              :     }
     185              : 
     186            8 :     GST_INFO("Successful retrieval of 'crypt_byte_block' and 'skip_byte_block'.");
     187            8 :     metadata.encryptionPatternSet = true;
     188              : }
     189              : 
     190           19 : void ProcessProtectionMetadata(GstBuffer *buffer, BufferProtectionMetadata &metadata)
     191              : {
     192           19 :     if (buffer == nullptr)
     193            1 :         return;
     194              : 
     195              :     GstRialtoProtectionMetadata *protectionMeta = reinterpret_cast<GstRialtoProtectionMetadata *>(
     196           18 :         gst_buffer_get_meta(buffer, GST_RIALTO_PROTECTION_METADATA_GET_TYPE));
     197           18 :     if (protectionMeta)
     198              :     {
     199           16 :         getEncryptedFromProtectionMetadata(protectionMeta, metadata);
     200           16 :         if (metadata.encrypted)
     201              :         {
     202           16 :             getMediaKeySessionIdFromProtectionMetadata(protectionMeta, metadata);
     203           16 :             getKIDFromProtectionMetadata(protectionMeta, metadata);
     204           16 :             getIVFromProtectionMetadata(protectionMeta, metadata);
     205           16 :             getSubSamplesFromProtectionMetadata(protectionMeta, metadata);
     206           16 :             getInitWithLast15FromProtectionMetadata(protectionMeta, metadata);
     207           16 :             getEncryptionSchemeFromProtectionMetadata(protectionMeta, metadata);
     208           16 :             getEncryptionPatternFromProtectionMetadata(protectionMeta, metadata);
     209              :         }
     210              :     }
     211              : }
        

Generated by: LCOV version 2.0-1