From 37e54320f2822bdc7eab50eb54b1fc4a452c7f60 Mon Sep 17 00:00:00 2001 From: peak3d Date: Thu, 22 Jul 2021 11:18:14 +0200 Subject: [PATCH] Hack HBO Signed-off-by: Bernd Kuhls --- Source/C++/Core/Ap4FragmentSampleTable.cpp | 8 +++++++- Source/C++/Core/Ap4FragmentSampleTable.h | 1 + Source/C++/Core/Ap4LinearReader.cpp | 20 +++++++++++++------- Source/C++/Core/Ap4LinearReader.h | 3 ++- Source/C++/Core/Ap4MovieFragment.cpp | 5 ++++- Source/C++/Core/Ap4MovieFragment.h | 2 ++ Source/C++/Core/Ap4Processor.cpp | 3 ++- 7 files changed, 31 insertions(+), 11 deletions(-) diff --git a/Source/C++/Core/Ap4FragmentSampleTable.cpp b/Source/C++/Core/Ap4FragmentSampleTable.cpp index 3fbb53e..cea5c7d 100644 --- a/Source/C++/Core/Ap4FragmentSampleTable.cpp +++ b/Source/C++/Core/Ap4FragmentSampleTable.cpp @@ -47,6 +47,7 @@ AP4_FragmentSampleTable::AP4_FragmentSampleTable(AP4_ContainerAtom* traf, AP4_ByteStream* sample_stream, AP4_Position moof_offset, AP4_Position mdat_payload_offset, + AP4_UI64 mdat_payload_size, AP4_UI64 dts_origin) : m_Duration(0) { @@ -73,6 +74,7 @@ AP4_FragmentSampleTable::AP4_FragmentSampleTable(AP4_ContainerAtom* traf, } // process all the trun atoms + AP4_UI32 trun_flags(0); for (AP4_List::Item* item = traf->GetChildren().FirstItem(); item; item = item->GetNext()) { @@ -88,9 +90,13 @@ AP4_FragmentSampleTable::AP4_FragmentSampleTable(AP4_ContainerAtom* traf, mdat_payload_offset, dts_origin); if (AP4_FAILED(result)) return; + trun_flags |= trun->GetFlags(); } } - } + } + // Hack if we have a single sample and default sample size is wrong (hbo ttml) + if (m_Samples.ItemCount() == 1 && (trun_flags & AP4_TRUN_FLAG_SAMPLE_SIZE_PRESENT) == 0) + m_Samples[0].SetSize(mdat_payload_size); } /*---------------------------------------------------------------------- diff --git a/Source/C++/Core/Ap4FragmentSampleTable.h b/Source/C++/Core/Ap4FragmentSampleTable.h index 67192de..29fa4a9 100644 --- a/Source/C++/Core/Ap4FragmentSampleTable.h +++ b/Source/C++/Core/Ap4FragmentSampleTable.h @@ -57,6 +57,7 @@ class AP4_FragmentSampleTable : public AP4_SampleTable AP4_ByteStream* sample_stream, AP4_Position moof_offset, AP4_Position mdat_payload_offset, // hack because MS doesn't implement the spec correctly + AP4_UI64 mdat_payload_size, AP4_UI64 dts_origin=0); virtual ~AP4_FragmentSampleTable(); diff --git a/Source/C++/Core/Ap4LinearReader.cpp b/Source/C++/Core/Ap4LinearReader.cpp index 61dd60e..eabeacf 100644 --- a/Source/C++/Core/Ap4LinearReader.cpp +++ b/Source/C++/Core/Ap4LinearReader.cpp @@ -309,7 +309,8 @@ AP4_LinearReader::ProcessTrack(AP4_Track* track) AP4_Result AP4_LinearReader::ProcessMoof(AP4_ContainerAtom* moof, AP4_Position moof_offset, - AP4_Position mdat_payload_offset) + AP4_Position mdat_payload_offset, + AP4_UI64 mdat_payload_size) { AP4_Result result; @@ -334,7 +335,8 @@ AP4_LinearReader::ProcessMoof(AP4_ContainerAtom* moof, ids[j], m_FragmentStream, moof_offset, - mdat_payload_offset, + mdat_payload_offset, + mdat_payload_size, tracker->m_NextDts, sample_table); if (AP4_FAILED(result)) return result; @@ -382,13 +384,11 @@ AP4_LinearReader::AdvanceFragment() AP4_Position position = 0; m_FragmentStream->Tell(position); - // process the movie fragment - result = ProcessMoof(moof, position-atom->GetSize(), position+8); - if (AP4_FAILED(result)) return result; - // compute where the next fragment will be AP4_UI32 size; AP4_UI32 type; + AP4_UI64 size_64 = 0; + m_FragmentStream->Tell(position); result = m_FragmentStream->ReadUI32(size); if (AP4_FAILED(result)) return AP4_SUCCESS; // can't read more @@ -397,13 +397,19 @@ AP4_LinearReader::AdvanceFragment() if (size == 0) { m_NextFragmentPosition = 0; } else if (size == 1) { - AP4_UI64 size_64 = 0; result = m_FragmentStream->ReadUI64(size_64); if (AP4_FAILED(result)) return AP4_SUCCESS; // can't read more m_NextFragmentPosition = position+size_64; + size_64 -= 8; } else { m_NextFragmentPosition = position+size; + size_64 = size; } + + // process the movie fragment + result = ProcessMoof(moof, position - atom->GetSize(), position + 8, size_64 - 8); + if (AP4_FAILED(result)) return result; + return AP4_SUCCESS; } else { delete atom; diff --git a/Source/C++/Core/Ap4LinearReader.h b/Source/C++/Core/Ap4LinearReader.h index 21f4871..929b4e1 100644 --- a/Source/C++/Core/Ap4LinearReader.h +++ b/Source/C++/Core/Ap4LinearReader.h @@ -161,7 +161,8 @@ protected: virtual AP4_Result ProcessTrack(AP4_Track* track); virtual AP4_Result ProcessMoof(AP4_ContainerAtom* moof, AP4_Position moof_offset, - AP4_Position mdat_payload_offset); + AP4_Position mdat_payload_offset, + AP4_UI64 mdat_payload_size); // methods Tracker* FindTracker(AP4_UI32 track_id); diff --git a/Source/C++/Core/Ap4MovieFragment.cpp b/Source/C++/Core/Ap4MovieFragment.cpp index 028d42d..c2ead25 100644 --- a/Source/C++/Core/Ap4MovieFragment.cpp +++ b/Source/C++/Core/Ap4MovieFragment.cpp @@ -127,6 +127,7 @@ AP4_MovieFragment::CreateSampleTable(AP4_MoovAtom* moov, AP4_ByteStream* sample_stream, AP4_Position moof_offset, AP4_Position mdat_payload_offset, + AP4_UI64 mdat_payload_size, AP4_UI64 dts_origin, AP4_FragmentSampleTable*& sample_table) { @@ -158,6 +159,7 @@ AP4_MovieFragment::CreateSampleTable(AP4_MoovAtom* moov, sample_stream, moof_offset, mdat_payload_offset, + mdat_payload_size, dts_origin); return AP4_SUCCESS; } @@ -174,9 +176,10 @@ AP4_MovieFragment::CreateSampleTable(AP4_Movie* movie, AP4_ByteStream* sample_stream, AP4_Position moof_offset, AP4_Position mdat_payload_offset, + AP4_UI64 mdat_payload_size, AP4_UI64 dts_origin, AP4_FragmentSampleTable*& sample_table) { AP4_MoovAtom* moov = movie?movie->GetMoovAtom():NULL; - return CreateSampleTable(moov, track_id, sample_stream, moof_offset, mdat_payload_offset, dts_origin, sample_table); + return CreateSampleTable(moov, track_id, sample_stream, moof_offset, mdat_payload_offset, mdat_payload_size, dts_origin, sample_table); } diff --git a/Source/C++/Core/Ap4MovieFragment.h b/Source/C++/Core/Ap4MovieFragment.h index f829411..de59c42 100644 --- a/Source/C++/Core/Ap4MovieFragment.h +++ b/Source/C++/Core/Ap4MovieFragment.h @@ -70,6 +70,7 @@ public: AP4_ByteStream* sample_stream, AP4_Position moof_offset, AP4_Position mdat_payload_offset, // hack because MS doesn't implement the spec properly + AP4_UI64 mdat_payload_size, AP4_UI64 dts_origin, AP4_FragmentSampleTable*& sample_table); AP4_Result CreateSampleTable(AP4_Movie* movie, @@ -77,6 +78,7 @@ public: AP4_ByteStream* sample_stream, AP4_Position moof_offset, AP4_Position mdat_payload_offset, // hack because MS doesn't implement the spec properly + AP4_UI64 mdat_payload_size, AP4_UI64 dts_origin, AP4_FragmentSampleTable*& sample_table); diff --git a/Source/C++/Core/Ap4Processor.cpp b/Source/C++/Core/Ap4Processor.cpp index c4e1d78..365d955 100644 --- a/Source/C++/Core/Ap4Processor.cpp +++ b/Source/C++/Core/Ap4Processor.cpp @@ -156,6 +156,7 @@ AP4_Processor::ProcessFragments(AP4_MoovAtom* moov, AP4_Atom* atom = locator->m_Atom; AP4_UI64 atom_offset = locator->m_Offset; AP4_UI64 mdat_payload_offset = atom_offset+atom->GetSize()+AP4_ATOM_HEADER_SIZE; + AP4_UI64 mdat_payload_size = atom->GetSize(); AP4_Sample sample; AP4_DataBuffer sample_data_in; AP4_DataBuffer sample_data_out; @@ -226,7 +227,7 @@ AP4_Processor::ProcessFragments(AP4_MoovAtom* moov, // create a sample table object so we can read the sample data AP4_FragmentSampleTable* sample_table = NULL; - result = fragment->CreateSampleTable(moov, tfhd->GetTrackId(), &input, atom_offset, mdat_payload_offset, 0, sample_table); + result = fragment->CreateSampleTable(moov, tfhd->GetTrackId(), &input, atom_offset, mdat_payload_offset, mdat_payload_size, 0, sample_table); if (AP4_FAILED(result)) return result; sample_tables.Append(sample_table); -- 2.30.2