Skip to content

Commit 02e163a

Browse files
committed
Moved extradata conversions to more appropriate places
1 parent 9d7d90a commit 02e163a

14 files changed

+228
-143
lines changed

src/Session.cpp

+1-18
Original file line numberDiff line numberDiff line change
@@ -701,24 +701,7 @@ void SESSION::CSession::UpdateStream(CStream& stream)
701701
stream.m_info.SetExtraData(nullptr, 0);
702702

703703
if (!rep->GetCodecPrivateData().empty())
704-
{
705-
std::vector<uint8_t> annexb;
706-
const std::vector<uint8_t>* extraData(&annexb);
707-
708-
const DRM::DecrypterCapabilites& caps{GetDecrypterCaps(rep->m_psshSetPos)};
709-
710-
if ((caps.flags & DRM::DecrypterCapabilites::SSD_ANNEXB_REQUIRED) &&
711-
stream.m_info.GetStreamType() == INPUTSTREAM_TYPE_VIDEO)
712-
{
713-
LOG::Log(LOGDEBUG, "UpdateStream: Convert avc -> annexb");
714-
annexb = AvcToAnnexb(rep->GetCodecPrivateData());
715-
}
716-
else
717-
{
718-
extraData = &rep->GetCodecPrivateData();
719-
}
720-
stream.m_info.SetExtraData(extraData->data(), extraData->size());
721-
}
704+
stream.m_info.SetExtraData(rep->GetCodecPrivateData());
722705

723706
stream.m_info.SetCodecFourCC(0);
724707
stream.m_info.SetBitRate(rep->GetBandwidth());

src/codechandler/AVCCodecHandler.cpp

+55-23
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212

1313
using namespace UTILS;
1414

15-
AVCCodecHandler::AVCCodecHandler(AP4_SampleDescription* sd)
15+
AVCCodecHandler::AVCCodecHandler(AP4_SampleDescription* sd, bool isRequiredAnnexB)
1616
: CodecHandler{sd},
1717
m_countPictureSetIds{0},
1818
m_needSliceInfo{false},
@@ -29,8 +29,16 @@ AVCCodecHandler::AVCCodecHandler(AP4_SampleDescription* sd)
2929
if (AP4_AvcSampleDescription* avcSampleDescription =
3030
AP4_DYNAMIC_CAST(AP4_AvcSampleDescription, m_sampleDescription))
3131
{
32-
m_extraData.SetData(avcSampleDescription->GetRawBytes().GetData(),
33-
avcSampleDescription->GetRawBytes().GetDataSize());
32+
if (isRequiredAnnexB)
33+
{
34+
ExtraDataToAnnexB();
35+
}
36+
else
37+
{
38+
m_extraData.SetData(avcSampleDescription->GetRawBytes().GetData(),
39+
avcSampleDescription->GetRawBytes().GetDataSize());
40+
}
41+
3442
m_countPictureSetIds = avcSampleDescription->GetPictureParameters().ItemCount();
3543
m_naluLengthSize = avcSampleDescription->GetNaluLengthSize();
3644
m_needSliceInfo = (m_countPictureSetIds > 1 || width == 0 || height == 0);
@@ -61,6 +69,26 @@ AVCCodecHandler::AVCCodecHandler(AP4_SampleDescription* sd)
6169
}
6270
}
6371

72+
bool AVCCodecHandler::CheckExtraData(std::vector<uint8_t>& extraData, bool isRequiredAnnexB)
73+
{
74+
if (extraData.empty())
75+
return false;
76+
77+
// Make sure that extradata is in the required format
78+
if (isRequiredAnnexB && !UTILS::IsAnnexB(extraData))
79+
{
80+
extraData = UTILS::AvcToAnnexb(extraData);
81+
return true;
82+
}
83+
if (!isRequiredAnnexB && UTILS::IsAnnexB(extraData))
84+
{
85+
extraData = UTILS::AnnexbToAvc(extraData);
86+
return true;
87+
}
88+
89+
return false;
90+
}
91+
6492
bool AVCCodecHandler::ExtraDataToAnnexB()
6593
{
6694
if (AP4_AvcSampleDescription* avcSampleDescription =
@@ -75,29 +103,33 @@ bool AVCCodecHandler::ExtraDataToAnnexB()
75103
for (unsigned int i{0}; i < sps.ItemCount(); ++i)
76104
sz += 4 + sps[i].GetDataSize();
77105

78-
m_extraData.SetDataSize(sz);
79-
AP4_Byte* cursor(m_extraData.UseData());
80-
81-
for (unsigned int i{0}; i < sps.ItemCount(); ++i)
82-
{
83-
cursor[0] = 0;
84-
cursor[1] = 0;
85-
cursor[2] = 0;
86-
cursor[3] = 1;
87-
memcpy(cursor + 4, sps[i].GetData(), sps[i].GetDataSize());
88-
cursor += sps[i].GetDataSize() + 4;
89-
}
90-
for (unsigned int i{0}; i < pps.ItemCount(); ++i)
106+
if (sz > 0)
91107
{
92-
cursor[0] = 0;
93-
cursor[1] = 0;
94-
cursor[2] = 0;
95-
cursor[3] = 1;
96-
memcpy(cursor + 4, pps[i].GetData(), pps[i].GetDataSize());
97-
cursor += pps[i].GetDataSize() + 4;
108+
m_extraData.SetDataSize(sz);
109+
AP4_Byte* cursor(m_extraData.UseData());
110+
111+
for (unsigned int i{0}; i < sps.ItemCount(); ++i)
112+
{
113+
cursor[0] = 0;
114+
cursor[1] = 0;
115+
cursor[2] = 0;
116+
cursor[3] = 1;
117+
memcpy(cursor + 4, sps[i].GetData(), sps[i].GetDataSize());
118+
cursor += sps[i].GetDataSize() + 4;
119+
}
120+
for (unsigned int i{0}; i < pps.ItemCount(); ++i)
121+
{
122+
cursor[0] = 0;
123+
cursor[1] = 0;
124+
cursor[2] = 0;
125+
cursor[3] = 1;
126+
memcpy(cursor + 4, pps[i].GetData(), pps[i].GetDataSize());
127+
cursor += pps[i].GetDataSize() + 4;
128+
}
129+
return true;
98130
}
99-
return true;
100131
}
132+
101133
return false;
102134
}
103135

src/codechandler/AVCCodecHandler.h

+28-26
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,28 @@
1-
/*
2-
* Copyright (C) 2022 Team Kodi
3-
* This file is part of Kodi - https://kodi.tv
4-
*
5-
* SPDX-License-Identifier: GPL-2.0-or-later
6-
* See LICENSES/README.md for more information.
7-
*/
8-
9-
#pragma once
10-
11-
#include "CodecHandler.h"
12-
13-
class ATTR_DLL_LOCAL AVCCodecHandler : public CodecHandler
14-
{
15-
public:
16-
AVCCodecHandler(AP4_SampleDescription* sd);
17-
bool ExtraDataToAnnexB() override;
18-
void UpdatePPSId(const AP4_DataBuffer& buffer) override;
19-
bool GetInformation(kodi::addon::InputstreamInfo& info) override;
20-
STREAMCODEC_PROFILE GetProfile() override { return m_codecProfile; };
21-
22-
private:
23-
unsigned int m_countPictureSetIds;
24-
STREAMCODEC_PROFILE m_codecProfile;
25-
bool m_needSliceInfo;
26-
};
1+
/*
2+
* Copyright (C) 2022 Team Kodi
3+
* This file is part of Kodi - https://kodi.tv
4+
*
5+
* SPDX-License-Identifier: GPL-2.0-or-later
6+
* See LICENSES/README.md for more information.
7+
*/
8+
9+
#pragma once
10+
11+
#include "CodecHandler.h"
12+
13+
class ATTR_DLL_LOCAL AVCCodecHandler : public CodecHandler
14+
{
15+
public:
16+
AVCCodecHandler(AP4_SampleDescription* sd, bool isRequiredAnnexB);
17+
18+
bool CheckExtraData(std::vector<uint8_t>& extraData, bool isRequiredAnnexB) override;
19+
bool ExtraDataToAnnexB() override;
20+
void UpdatePPSId(const AP4_DataBuffer& buffer) override;
21+
bool GetInformation(kodi::addon::InputstreamInfo& info) override;
22+
STREAMCODEC_PROFILE GetProfile() override { return m_codecProfile; };
23+
24+
private:
25+
unsigned int m_countPictureSetIds;
26+
STREAMCODEC_PROFILE m_codecProfile;
27+
bool m_needSliceInfo;
28+
};

src/codechandler/CodecHandler.h

+10
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,16 @@ class ATTR_DLL_LOCAL CodecHandler
3434
*/
3535
virtual bool GetInformation(kodi::addon::InputstreamInfo& info);
3636
virtual bool ExtraDataToAnnexB() { return false; };
37+
/*!
38+
* \brief Check for extradata data format, if needed it will be converted
39+
* \param extraData The data
40+
* \param isRequiredAnnexB If the extradata must be in annex b format
41+
* \return True if data is changed, otherwise false
42+
*/
43+
virtual bool CheckExtraData(std::vector<uint8_t>& extraData, bool isRequiredAnnexB)
44+
{
45+
return false;
46+
}
3747
virtual STREAMCODEC_PROFILE GetProfile() { return STREAMCODEC_PROFILE::CodecProfileNotNeeded; };
3848
virtual bool Transform(AP4_UI64 pts, AP4_UI32 duration, AP4_DataBuffer& buf, AP4_UI64 timescale)
3949
{

src/codechandler/HEVCCodecHandler.cpp

+32-3
Original file line numberDiff line numberDiff line change
@@ -13,17 +13,46 @@
1313

1414
using namespace UTILS;
1515

16-
HEVCCodecHandler::HEVCCodecHandler(AP4_SampleDescription* sd) : CodecHandler(sd)
16+
HEVCCodecHandler::HEVCCodecHandler(AP4_SampleDescription* sd, bool isRequiredAnnexB)
17+
: CodecHandler(sd)
1718
{
1819
if (AP4_HevcSampleDescription* hevcSampleDescription =
1920
AP4_DYNAMIC_CAST(AP4_HevcSampleDescription, m_sampleDescription))
2021
{
21-
m_extraData.SetData(hevcSampleDescription->GetRawBytes().GetData(),
22-
hevcSampleDescription->GetRawBytes().GetDataSize());
22+
if (isRequiredAnnexB)
23+
{
24+
ExtraDataToAnnexB();
25+
}
26+
else
27+
{
28+
m_extraData.SetData(hevcSampleDescription->GetRawBytes().GetData(),
29+
hevcSampleDescription->GetRawBytes().GetDataSize());
30+
}
2331
m_naluLengthSize = hevcSampleDescription->GetNaluLengthSize();
2432
}
2533
}
2634

35+
bool HEVCCodecHandler::CheckExtraData(std::vector<uint8_t>& extraData, bool isRequiredAnnexB)
36+
{
37+
if (extraData.empty())
38+
return false;
39+
40+
// Make sure that extradata is in the required format
41+
if (isRequiredAnnexB && !UTILS::IsAnnexB(extraData))
42+
{
43+
//! @todo: this was never implemented on the older ISA versions
44+
LOG::LogF(LOGDEBUG, "Required extradata annex b format, data conversion not implemented");
45+
return false;
46+
}
47+
if (!isRequiredAnnexB && UTILS::IsAnnexB(extraData))
48+
{
49+
extraData = UTILS::AnnexbToHvcc(extraData);
50+
return true;
51+
}
52+
53+
return false;
54+
}
55+
2756
bool HEVCCodecHandler::ExtraDataToAnnexB()
2857
{
2958
if (AP4_HevcSampleDescription* hevcSampleDescription =

src/codechandler/HEVCCodecHandler.h

+2-1
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,9 @@
1313
class ATTR_DLL_LOCAL HEVCCodecHandler : public CodecHandler
1414
{
1515
public:
16-
HEVCCodecHandler(AP4_SampleDescription* sd);
16+
HEVCCodecHandler(AP4_SampleDescription* sd, bool isRequiredAnnexB);
1717

18+
bool CheckExtraData(std::vector<uint8_t>& extraData, bool isRequiredAnnexB) override;
1819
bool ExtraDataToAnnexB() override;
1920
bool GetInformation(kodi::addon::InputstreamInfo& info) override;
2021
};

src/common/AdaptiveUtils.cpp

+7-1
Original file line numberDiff line numberDiff line change
@@ -77,12 +77,15 @@ AP4_Movie* PLAYLIST::CreateMovieAtom(adaptive::AdaptiveStream& adStream,
7777
kodi::addon::InputstreamInfo& streamInfo)
7878
{
7979
CRepresentation* repr = adStream.getRepresentation();
80-
const std::vector<uint8_t>& extradata = repr->GetCodecPrivateData();
80+
std::vector<uint8_t> extradata = repr->GetCodecPrivateData();
8181
const std::string codecName = streamInfo.GetCodecName();
8282
AP4_SampleDescription* sampleDesc;
8383

8484
if (codecName == CODEC::NAME_H264)
8585
{
86+
if (UTILS::IsAnnexB(extradata))
87+
extradata = UTILS::AnnexbToAvc(extradata);
88+
8689
AP4_MemoryByteStream ms{extradata.data(), static_cast<const AP4_Size>(extradata.size())};
8790
AP4_AvccAtom* atom =
8891
AP4_AvccAtom::Create(static_cast<AP4_Size>(AP4_ATOM_HEADER_SIZE + extradata.size()), ms);
@@ -91,6 +94,9 @@ AP4_Movie* PLAYLIST::CreateMovieAtom(adaptive::AdaptiveStream& adStream,
9194
}
9295
else if (codecName == CODEC::NAME_HEVC)
9396
{
97+
if (UTILS::IsAnnexB(extradata))
98+
extradata = UTILS::AnnexbToHvcc(extradata);
99+
94100
AP4_MemoryByteStream ms{extradata.data(), static_cast<const AP4_Size>(extradata.size())};
95101
AP4_HvccAtom* atom =
96102
AP4_HvccAtom::Create(static_cast<AP4_Size>(AP4_ATOM_HEADER_SIZE + extradata.size()), ms);

src/parser/DASHTree.cpp

+5-2
Original file line numberDiff line numberDiff line change
@@ -747,8 +747,11 @@ void adaptive::CDashTree::ParseTagRepresentation(pugi::xml_node nodeRepr,
747747

748748
// ISA custom attribute
749749
// No dash spec, looks like a custom Amazon video service implementation
750-
repr->SetCodecPrivateData(
751-
UTILS::AnnexbToAvc(XML::GetAttrib(nodeRepr, "codecPrivateData").data()));
750+
std::string codecPrivateData;
751+
if (XML::QueryAttrib(nodeRepr, "codecPrivateData", codecPrivateData))
752+
{
753+
repr->SetCodecPrivateData(STRING::HexToBytes(codecPrivateData));
754+
}
752755

753756
// ISA custom attribute
754757
repr->SetSampleRate(XML::GetAttribUint32(nodeRepr, "audioSamplingRate"));

src/parser/SmoothTree.cpp

+1-8
Original file line numberDiff line numberDiff line change
@@ -323,14 +323,7 @@ void adaptive::CSmoothTree::ParseTagQualityLevel(pugi::xml_node nodeQI,
323323
std::string codecPrivateData;
324324
if (XML::QueryAttrib(nodeQI, "CodecPrivateData", codecPrivateData))
325325
{
326-
const auto& codecs = repr->GetCodecs();
327-
if (CODEC::Contains(codecs, CODEC::FOURCC_HEVC) ||
328-
CODEC::Contains(codecs, CODEC::FOURCC_HEV1) || CODEC::Contains(codecs, CODEC::FOURCC_HVC1))
329-
{
330-
repr->SetCodecPrivateData(AnnexbToHvcc(codecPrivateData.c_str()));
331-
}
332-
else
333-
repr->SetCodecPrivateData(AnnexbToAvc(codecPrivateData.c_str()));
326+
repr->SetCodecPrivateData(STRING::HexToBytes(codecPrivateData));
334327
}
335328

336329
if (CODEC::Contains(repr->GetCodecs(), CODEC::FOURCC_AACL) && repr->GetCodecPrivateData().empty())

src/samplereader/FragmentedSampleReader.cpp

+14-8
Original file line numberDiff line numberDiff line change
@@ -246,12 +246,18 @@ bool CFragmentedSampleReader::GetInformation(kodi::addon::InputstreamInfo& info)
246246
{
247247
info.SetExtraData(m_codecHandler->m_extraData.GetData(),
248248
m_codecHandler->m_extraData.GetDataSize());
249-
isChanged |= true;
249+
isChanged = true;
250250
}
251251

252-
m_bSampleDescChanged = false;
252+
std::vector<uint8_t> extraData = info.GetExtraData();
253+
if (m_codecHandler->CheckExtraData(
254+
extraData, (m_decrypterCaps.flags & DRM::DecrypterCapabilites::SSD_ANNEXB_REQUIRED) != 0))
255+
{
256+
info.SetExtraData(extraData);
257+
isChanged = true;
258+
}
253259

254-
isChanged |= m_codecHandler->GetInformation(info);
260+
m_bSampleDescChanged = false;
255261

256262
return isChanged;
257263
}
@@ -488,19 +494,22 @@ void CFragmentedSampleReader::UpdateSampleDescription()
488494
}
489495
else
490496
{
497+
const bool isRequiredAnnexB =
498+
(m_decrypterCaps.flags & DRM::DecrypterCapabilites::SSD_ANNEXB_REQUIRED) != 0;
499+
491500
switch (desc->GetFormat())
492501
{
493502
case AP4_SAMPLE_FORMAT_AVC1:
494503
case AP4_SAMPLE_FORMAT_AVC2:
495504
case AP4_SAMPLE_FORMAT_AVC3:
496505
case AP4_SAMPLE_FORMAT_AVC4:
497-
m_codecHandler = new AVCCodecHandler(desc);
506+
m_codecHandler = new AVCCodecHandler(desc, isRequiredAnnexB);
498507
break;
499508
case AP4_SAMPLE_FORMAT_HEV1:
500509
case AP4_SAMPLE_FORMAT_HVC1:
501510
case AP4_SAMPLE_FORMAT_DVHE:
502511
case AP4_SAMPLE_FORMAT_DVH1:
503-
m_codecHandler = new HEVCCodecHandler(desc);
512+
m_codecHandler = new HEVCCodecHandler(desc, isRequiredAnnexB);
504513
break;
505514
case AP4_SAMPLE_FORMAT_STPP:
506515
m_codecHandler = new TTMLCodecHandler(desc, false);
@@ -519,9 +528,6 @@ void CFragmentedSampleReader::UpdateSampleDescription()
519528
break;
520529
}
521530
}
522-
523-
if ((m_decrypterCaps.flags & DRM::DecrypterCapabilites::SSD_ANNEXB_REQUIRED) != 0)
524-
m_codecHandler->ExtraDataToAnnexB();
525531
}
526532

527533
void CFragmentedSampleReader::ParseTrafTfrf(AP4_UuidAtom* uuidAtom)

0 commit comments

Comments
 (0)