Skip to content

Commit afd588d

Browse files
committed
Add dvcc parsing and store in inputstream
1 parent 8bdb767 commit afd588d

8 files changed

Lines changed: 87 additions & 26 deletions

File tree

lib/cdm/cdm/media/base/cdm_config.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,10 +15,10 @@ namespace media {
1515
// |requestMediaKeySystemAccess|. This is in some sense the Chromium-side
1616
// counterpart of Blink's WebMediaKeySystemConfiguration.
1717
struct CdmConfig {
18-
CdmConfig(bool distinctive_identifier=false, bool persistent_state=false)
18+
CdmConfig(bool distinctive_identifier=false, bool persistent_state=false, bool hw_secure_codecs=false)
1919
:allow_distinctive_identifier(distinctive_identifier)
2020
, allow_persistent_state(persistent_state)
21-
, use_hw_secure_codecs(false){};
21+
, use_hw_secure_codecs(hw_secure_codecs){};
2222

2323
// Allow access to a distinctive identifier.
2424
bool allow_distinctive_identifier;

lib/cdm/cdm/media/cdm/cdm_adapter.cc

Lines changed: 3 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,6 @@
1010

1111
#include "../../debug.h"
1212
#include "../base/limits.h"
13-
#include "SrvBroker.h"
14-
#include "CompSettings.h"
1513

1614
#include <chrono>
1715
#include <cstring>
@@ -252,27 +250,20 @@ bool CdmAdapter::Initialize()
252250

253251
if (cdm12_ || cdm11_ || cdm10_)
254252
{
255-
bool use_hw_secure_codecs = false;
256-
257-
#ifdef TARGET_WEBOS
258-
if(CSrvBroker::GetSettings().IsSecurePathOverride())
259-
use_hw_secure_codecs = true;
260-
#endif
261-
262253
if (cdm12_)
263254
{
264255
cdm12_->Initialize(cdm_config_.allow_distinctive_identifier,
265-
cdm_config_.allow_persistent_state, use_hw_secure_codecs);
256+
cdm_config_.allow_persistent_state, cdm_config_.use_hw_secure_codecs);
266257
}
267258
else if (cdm11_)
268259
{
269260
cdm11_->Initialize(cdm_config_.allow_distinctive_identifier,
270-
cdm_config_.allow_persistent_state, use_hw_secure_codecs);
261+
cdm_config_.allow_persistent_state, cdm_config_.use_hw_secure_codecs);
271262
}
272263
else if (cdm10_)
273264
{
274265
cdm10_->Initialize(cdm_config_.allow_distinctive_identifier,
275-
cdm_config_.allow_persistent_state, use_hw_secure_codecs);
266+
cdm_config_.allow_persistent_state, cdm_config_.use_hw_secure_codecs);
276267
}
277268

278269
// Wait for the CDM to be initialized

src/common/AdaptiveCencSampleDecrypter.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,10 @@
77
*/
88

99
#include "AdaptiveDecrypter.h"
10+
<<<<<<< HEAD
11+
=======
12+
13+
>>>>>>> 380146c9 (Add dvcc parsing and store in inputstream)
1014
#include "decrypters/DrmEngineDefines.h"
1115

1216
#include <memory>

src/decrypters/widevine/WVCdmAdapter.cpp

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,10 @@ SResult CWVCdmAdapter::Initialize(const DRM::Config& config, CWVDecrypter* host)
8888
return SResultCode::ERROR;
8989
}
9090
std::string cdmPath;
91+
bool use_hw_secure_codecs = false;
92+
9193
#ifdef TARGET_WEBOS
94+
use_hw_secure_codecs = true;
9295
auto it = std::ranges::find_if(candidatePaths, [](std::string_view sv)
9396
{ return std::filesystem::exists(std::filesystem::path{sv}); });
9497

@@ -120,7 +123,7 @@ SResult CWVCdmAdapter::Initialize(const DRM::Config& config, CWVDecrypter* host)
120123

121124
auto cdmAdapter =
122125
std::make_shared<media::CdmAdapter>("com.widevine.alpha", cdmPath, basePath,
123-
media::CdmConfig(false, m_config.isPersistentStorage),
126+
media::CdmConfig(false, m_config.isPersistentStorage, use_hw_secure_codecs),
124127
dynamic_cast<media::CdmAdapterClient*>(this));
125128

126129
if (!cdmAdapter->LoadCDM())

src/decrypters/widevine/WVCencSingleSampleDecrypter.cpp

Lines changed: 4 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,6 @@ CWVCencSingleSampleDecrypter::CWVCencSingleSampleDecrypter(
7676
// prepare the promise before calling into CDM
7777
std::future<std::string> fut = m_cdmAdapter->PrepareSessionFuture(pid);
7878

79-
LOG::LogF(LOGDEBUG, "Creating widevine session with promise ID: %u", pid);
8079
m_cdmAdapter->GetCDM()->CreateSessionAndGenerateRequest(
8180
pid, cdm::SessionType::kTemporary, cdm::InitDataType::kCenc,
8281
m_pssh.data(), static_cast<uint32_t>(m_pssh.size()));
@@ -141,7 +140,7 @@ void CWVCencSingleSampleDecrypter::GetCapabilities(const std::vector<uint8_t>& k
141140
if (!caps.hdcpLimit)
142141
caps.hdcpLimit = m_resolutionLimit;
143142

144-
// optional override for webOS required for L1
143+
// optional override for webOS required for L1
145144
if(CSrvBroker::GetSettings().IsSecurePathOverride()) {
146145
LOG::LogF(LOGDEBUG,
147146
"Overriding settings to: SSD_SECURE PATH | SSD_ANNEXB_REQUIRED | SSD_SECURE_DECODER");
@@ -475,7 +474,7 @@ void CWVCencSingleSampleDecrypter::RepackSubsampleData(AP4_DataBuffer& dataIn,
475474
{
476475
#ifdef TARGET_WEBOS
477476
// with kStreamTypeVideo we need to handle the SVP header so it is not lost
478-
if(streamType == cdm::StreamType::kStreamTypeVideo) {
477+
if(streamType == DRM::DRMMediaType::VIDEO) {
479478
const size_t encryptedBytes = bytesOfEncryptedData[subsamplePos];
480479
const size_t clearBytes = bytesOfCleartextData[subsamplePos];
481480

@@ -588,7 +587,7 @@ AP4_Result CWVCencSingleSampleDecrypter::DecryptSampleData(AP4_UI32 poolId,
588587
dataIn, payload, subsampleCount, fragInfo, iv,
589588
bytesOfCleartextData, bytesOfEncryptedData, convertAnnexB, rebuiltSubs);
590589
if (res != AP4_SUCCESS) {
591-
LOG::LogF(LOGERROR, "[DecryptSampleData] ConvertToAnnexB failed: %d", res);
590+
LOG::LogF(LOGERROR, "ConvertToAnnexBandInject failed: %d", res);
592591
return res;
593592
}
594593
}
@@ -639,8 +638,6 @@ AP4_Result CWVCencSingleSampleDecrypter::DecryptSampleData(AP4_UI32 poolId,
639638
// Prepare CDM input using rebuiltSubs
640639
cdm::InputBuffer_2 cdmIn;
641640
SetInput(cdmIn, payload, static_cast<uint32_t>(rebuiltSubs.size()), iv, fragInfo, rebuiltSubs);
642-
LOG::LogF(LOGDEBUG, "[DecryptSampleData] CDM input prepared [V=%d] subSampleCount=%u",
643-
streamType, static_cast<unsigned>(rebuiltSubs.size()));
644641

645642
const size_t header_cushion = 64;
646643
m_decryptOut.Reserve(payload.GetDataSize() + dataOut.GetDataSize() + header_cushion);
@@ -652,16 +649,14 @@ AP4_Result CWVCencSingleSampleDecrypter::DecryptSampleData(AP4_UI32 poolId,
652649

653650
CheckLicenseRenewal();
654651

655-
cdm::Status ret = m_cdmAdapter->GetCDM()->Decrypt(cdmIn, &cdmOut, streamType);
652+
cdm::Status ret = m_cdmAdapter->GetCDM()->Decrypt(cdmIn, &cdmOut, ToCdmStreamType(streamType));
656653
if (ret != cdm::kSuccess) {
657654
LOG::LogF(LOGERROR, "[DecryptSampleData] CDM->Decrypt failed, status=%d", static_cast<int>(ret));
658655
return AP4_ERROR_INVALID_FORMAT;
659656
}
660657

661658
// Prefix (if any) + SVP-wrapped payload
662659
dataOut.AppendData(m_decryptOut.GetData(), m_decryptOut.GetDataSize());
663-
LOG::LogF(LOGDEBUG, "[DecryptSampleData] Secure-path success, forwarding CDM output size=%zu",
664-
dataOut.GetDataSize());
665660
#else
666661
// Prefix (if IV) + raw payload
667662
dataOut.AppendData(payload.GetData(), payload.GetDataSize());
@@ -856,7 +851,6 @@ CWVCencSingleSampleDecrypter::ConvertToAnnexBandInject(
856851
packetIn[2] == 0x00 &&
857852
packetIn[3] == 0x01))
858853
{
859-
LOG::LogF(LOGDEBUG, "Injecting annex b header");
860854
dataOut.AppendData(annexbStartCode, 4);
861855
}
862856

src/decrypters/widevine/WVCencSingleSampleDecrypter.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -151,6 +151,8 @@ class ATTR_DLL_LOCAL CWVCencSingleSampleDecrypter : public Adaptive_CencSingleSa
151151
bool convertAnnexB,
152152
std::vector<cdm::SubsampleEntry>& rebuiltSubs);
153153

154+
cdm::StreamType ToCdmStreamType(DRM::DRMMediaType stream_type);
155+
154156
uint32_t m_promiseId;
155157
bool m_isDrained;
156158

src/samplereader/FragmentedSampleReader.cpp

Lines changed: 66 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -135,6 +135,16 @@ AP4_Result CFragmentedSampleReader::ReadSample()
135135
if (m_track->GetType() == AP4_Track::Type::TYPE_AUDIO)
136136
streamType = DRM::DRMMediaType::AUDIO;
137137

138+
#ifdef TARGET_WEBOS
139+
// if we are not in secure path mode, adding SVP header/meta data is not needed
140+
if(m_track->GetType() == AP4_Track::Type::TYPE_VIDEO &&
141+
(!CSrvBroker::GetSettings().IsSecurePathOverride()))
142+
{
143+
LOG::LogF(LOGDEBUG, "Overriding VIDEO as non-secure path to: kStreamTypeAudio");
144+
streamType = DRM::DRMMediaType::AUDIO;
145+
}
146+
#endif
147+
138148
AP4_Result result;
139149
if (!m_codecHandler->ReadNextSample(m_sample, m_sampleData))
140150
{
@@ -268,6 +278,11 @@ bool CFragmentedSampleReader::GetInformation(kodi::addon::InputstreamInfo& info)
268278

269279
isChanged |= m_codecHandler->GetInformation(info);
270280

281+
// store dvcc metadata
282+
if (auto dvcc = ParseDvcc()) {
283+
PopulateDvccMetadata(info, dvcc);
284+
}
285+
271286
m_bSampleDescChanged = false;
272287

273288
return isChanged;
@@ -511,7 +526,7 @@ void CFragmentedSampleReader::UpdateSampleDescription()
511526

512527
LOG::LogF(LOGDEBUG, "Codec fourcc: %s (%u)", CODEC::FourCCToString(desc->GetFormat()).c_str(),
513528
desc->GetFormat());
514-
529+
515530
if (AP4_DYNAMIC_CAST(AP4_AudioSampleDescription, desc))
516531
{
517532
// Audio sample of any format
@@ -590,3 +605,53 @@ void CFragmentedSampleReader::ParseTrafTfrf(AP4_UuidAtom* uuidAtom)
590605
m_observer->OnTFRFatom(time, duration, m_track->GetMediaTimeScale());
591606
}
592607
}
608+
609+
AP4_DvccAtom* CFragmentedSampleReader::ParseDvcc()
610+
{
611+
if (AP4_TrakAtom* trak = m_track->UseTrakAtom()) {
612+
if (auto mdia = AP4_DYNAMIC_CAST(AP4_ContainerAtom,
613+
trak->GetChild(AP4_ATOM_TYPE_MDIA, 0))) {
614+
if (auto minf = AP4_DYNAMIC_CAST(AP4_ContainerAtom,
615+
mdia->GetChild(AP4_ATOM_TYPE_MINF, 0))) {
616+
if (auto stbl = AP4_DYNAMIC_CAST(AP4_ContainerAtom,
617+
minf->GetChild(AP4_ATOM_TYPE_STBL, 0))) {
618+
if (auto stsd = AP4_DYNAMIC_CAST(AP4_ContainerAtom,
619+
stbl->GetChild(AP4_ATOM_TYPE_STSD, 0))) {
620+
for (auto* eitem = stsd->GetChildren().FirstItem(); eitem; eitem = eitem->GetNext()) {
621+
auto entry_ctn = AP4_DYNAMIC_CAST(AP4_ContainerAtom, eitem->GetData());
622+
623+
if (!entry_ctn) continue;
624+
AP4_Atom* dv_atom = entry_ctn->GetChild(AP4_ATOM_TYPE_DVCC, 0);
625+
if (!dv_atom) dv_atom = entry_ctn->GetChild(AP4_ATOM_TYPE_DVVC, 0);
626+
if (!dv_atom) continue;
627+
628+
if (auto dvcc = AP4_DYNAMIC_CAST(AP4_DvccAtom, dv_atom)) {
629+
return dvcc;
630+
}
631+
}
632+
}
633+
}
634+
}
635+
}
636+
}
637+
638+
return nullptr;
639+
}
640+
641+
void CFragmentedSampleReader::PopulateDvccMetadata(kodi::addon::InputstreamInfo& info, AP4_DvccAtom* dvcc)
642+
{
643+
if (!dvcc)
644+
return;
645+
646+
auto* meta = new INPUTSTREAM_DVCC_METADATA();
647+
meta->m_dvVersionMajor = dvcc->GetDvVersionMajor();
648+
meta->m_dvVersionMinor = dvcc->GetDvVersionMinor();
649+
meta->m_dvProfile = dvcc->GetDvProfile();
650+
meta->m_dvLevel = dvcc->GetDvLevel();
651+
meta->m_rpuPresentFlag = dvcc->GetRpuPresentFlag();
652+
meta->m_elPresentFlag = dvcc->GetElPresentFlag();
653+
meta->m_blPresentFlag = dvcc->GetBlPresentFlag();
654+
meta->m_dvBlSignalCompatibilityId = dvcc->GetDvBlSignalCompatibilityID();
655+
656+
info.SetDvccMetadata(meta);
657+
}

src/samplereader/FragmentedSampleReader.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,8 @@ class ATTR_DLL_LOCAL CFragmentedSampleReader : public ISampleReader, public AP4_
5454
private:
5555
void UpdateSampleDescription();
5656
void ParseTrafTfrf(AP4_UuidAtom* uuidAtom);
57+
AP4_DvccAtom* ParseDvcc();
58+
void PopulateDvccMetadata(kodi::addon::InputstreamInfo& info, AP4_DvccAtom* dvcc);
5759

5860
AP4_Track* m_track;
5961
AP4_UI32 m_poolId{0};

0 commit comments

Comments
 (0)