Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

MP1-5180: Add HEVC support for BDReader directshow filter #229

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions DirectShowFilters/BDReader/BDReader.vcxproj
Original file line number Diff line number Diff line change
Expand Up @@ -353,6 +353,9 @@
<ClCompile Include="source\FrameHeaderParser.cpp" />
<ClCompile Include="source\GolombBuffer.cpp" />
<ClCompile Include="source\H264Nalu.cpp" />
<ClCompile Include="source\HEVC\BitstreamReader.cpp" />
<ClCompile Include="source\HEVC\Hevc.cpp" />
<ClCompile Include="source\HEVC\HevcNalDecode.cpp" />
<ClCompile Include="source\LibBlurayWrapper.cpp" />
<ClCompile Include="source\OverlayRenderer.cpp" />
<ClCompile Include="source\Packet.cpp" />
Expand All @@ -377,6 +380,9 @@
<ClInclude Include="source\FrameHeaderParser.h" />
<ClInclude Include="source\GolombBuffer.h" />
<ClInclude Include="source\H264Nalu.h" />
<ClInclude Include="source\HEVC\BitstreamReader.h" />
<ClInclude Include="source\HEVC\Hevc.h" />
<ClInclude Include="source\HEVC\HevcNalDecode.h" />
<ClInclude Include="source\IAudioStream.h" />
<ClInclude Include="source\ISubtitleStream.h" />
<ClInclude Include="source\LibBlurayWrapper.h" />
Expand Down
1 change: 1 addition & 0 deletions DirectShowFilters/BDReader/source/BDReader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -319,6 +319,7 @@ STDMETHODIMP CBDReaderFilter::SetVideoDecoder(int format, GUID* decoder)
{
if (format != BLURAY_STREAM_TYPE_VIDEO_H264 &&
format != BLURAY_STREAM_TYPE_VIDEO_VC1 &&
format != BLURAY_STREAM_TYPE_VIDEO_HEVC &&
format != BLURAY_STREAM_TYPE_VIDEO_MPEG2)
return E_INVALIDARG;

Expand Down
89 changes: 44 additions & 45 deletions DirectShowFilters/BDReader/source/Clip.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -43,23 +43,21 @@ CClip::CClip(int clipNumber, int playlistNumber, REFERENCE_TIME firstPacketTime,
audioPlaybackPosition = playlistFirstPacketTime;
videoPlaybackPosition = playlistFirstPacketTime;

earliestPacketAccepted = _I64_MAX;
m_rtEarliestPacketAccepted = _I64_MAX;
firstVideoPosition = _I64_MAX;
firstAudioPosition = _I64_MAX;

clipDuration = duration;
clipPlaylistOffset = totalStreamOffset;
m_rtClipPlaylistOffset = totalStreamOffset;
m_rtStreamStartOffset = streamStartOffset;

m_playlistOffset = clipOffset;
m_rtPlayedDuration = 0;
m_rtPrevAudioStart = 0;
m_rtClipVideoStartingOffset = 0LL;
m_rtClipAudioStartingOffset = 0LL;

m_bCalculateAudioOffset = true;
m_bCalculateVideoOffset = true;

m_rtClipStartingOffset = 0LL;

m_bCalculateOffset = true;

noAudio =! audioPresent;

clipInterrupted = interrupted;
Expand All @@ -70,8 +68,8 @@ CClip::CClip(int clipNumber, int playlistNumber, REFERENCE_TIME firstPacketTime,

firstAudio = true;
firstVideo = true;
firstPacketAccepted = false;
firstPacketReturned = false;
m_bFirstPacketAccepted = false;
m_bFirstPacketReturned = false;

clipReset = false;
//LogDebug("CClip:: New Clip (%d,%d) stream Offset %I64d", nPlaylist, nClip, totalStreamOffset);
Expand All @@ -94,8 +92,8 @@ Packet* CClip::ReturnNextAudioPacket(REFERENCE_TIME playlistOffset)
if (noAudio)
{
ret = GenerateFakeAudio(audioPlaybackPosition);
if (earliestPacketAccepted == INT64_MAX)
earliestPacketAccepted = audioPlaybackPosition;
if (m_rtEarliestPacketAccepted == INT64_MAX)
m_rtEarliestPacketAccepted = audioPlaybackPosition;
}
else
{
Expand All @@ -122,20 +120,20 @@ Packet* CClip::ReturnNextAudioPacket(REFERENCE_TIME playlistOffset)
if (clipInterrupted)
ret->nNewSegment |= NS_INTERRUPTED;

if (m_bCalculateAudioOffset && (abs(earliestPacketAccepted - ret->rtStart) > 0))
m_rtClipAudioStartingOffset = earliestPacketAccepted - ret->rtStart;
if (m_bCalculateOffset && (abs(m_rtEarliestPacketAccepted - ret->rtStart) > 0))
m_rtClipStartingOffset = m_rtEarliestPacketAccepted - ret->rtStart;

m_bCalculateAudioOffset = false;
m_bCalculateOffset = false;
}

if (!firstPacketReturned)
firstPacketReturned = true;
if (!m_bFirstPacketReturned)
m_bFirstPacketReturned = true;

ret->rtPlaylistTime = ret->rtStart - m_playlistOffset;

ret->rtClipStartTime = ret->rtStart - earliestPacketAccepted + m_rtClipAudioStartingOffset;
ret->rtStart += clipPlaylistOffset - earliestPacketAccepted + m_rtClipAudioStartingOffset;
ret->rtStop += clipPlaylistOffset - earliestPacketAccepted + m_rtClipAudioStartingOffset;
ret->rtClipStartTime = ret->rtStart - m_rtEarliestPacketAccepted + m_rtClipStartingOffset;
ret->rtStart += m_rtClipPlaylistOffset - m_rtEarliestPacketAccepted + m_rtClipStartingOffset;
ret->rtStop += m_rtClipPlaylistOffset - m_rtEarliestPacketAccepted + m_rtClipStartingOffset;

if (m_rtPrevAudioStart == 0)
m_rtPrevAudioStart = ret->rtStart;
Expand Down Expand Up @@ -178,10 +176,10 @@ Packet* CClip::ReturnNextVideoPacket(REFERENCE_TIME playlistOffset)
firstVideo = false;
ret->pmt = CreateMediaType(m_videoPmt);

if (m_bCalculateVideoOffset && (abs(earliestPacketAccepted - ret->rtStart) > 0))
m_rtClipVideoStartingOffset = earliestPacketAccepted - ret->rtStart;
if (m_bCalculateOffset && (abs(m_rtEarliestPacketAccepted - ret->rtStart) > 0))
m_rtClipStartingOffset = m_rtEarliestPacketAccepted - ret->rtStart;

m_bCalculateVideoOffset = false;
m_bCalculateOffset = false;
}

if (ret->rtStart > videoPlaybackPosition)
Expand All @@ -190,14 +188,14 @@ Packet* CClip::ReturnNextVideoPacket(REFERENCE_TIME playlistOffset)
//LogDebug("Videoplayback position (%d,%d) %I64d", nPlaylist, nClip, videoPlaybackPosition);
}

if (!firstPacketReturned)
firstPacketReturned = true;
if (!m_bFirstPacketReturned)
m_bFirstPacketReturned = true;

ret->rtPlaylistTime = ret->rtStart - m_playlistOffset;

ret->rtClipStartTime = ret->rtStart - earliestPacketAccepted + m_rtClipVideoStartingOffset;
ret->rtStart += clipPlaylistOffset - earliestPacketAccepted + m_rtClipVideoStartingOffset;
ret->rtStop += clipPlaylistOffset - earliestPacketAccepted + m_rtClipVideoStartingOffset;
ret->rtClipStartTime = ret->rtStart - m_rtEarliestPacketAccepted + m_rtClipStartingOffset;
ret->rtStart += m_rtClipPlaylistOffset - m_rtEarliestPacketAccepted + m_rtClipStartingOffset;
ret->rtStop += m_rtClipPlaylistOffset - m_rtEarliestPacketAccepted + m_rtClipStartingOffset;
}
}
// LogDebug("Clip: vid: return Packet rtStart: %I64d offset: %I64d seekRequired %d",ret->rtStart, ret->rtOffset,ret->bSeekRequired);
Expand Down Expand Up @@ -245,10 +243,10 @@ Packet* CClip::GenerateFakeAudio(REFERENCE_TIME rtStart)
packet->pmt = CreateMediaType(&pmt);
}

if (earliestPacketAccepted == INT64_MAX)
earliestPacketAccepted = audioPlaybackPosition;
if (m_rtEarliestPacketAccepted == INT64_MAX)
m_rtEarliestPacketAccepted = audioPlaybackPosition;

firstPacketAccepted = true;
m_bFirstPacketAccepted = true;

lastAudioPosition += FAKE_AUDIO_DURATION;
audioPlaybackPosition += FAKE_AUDIO_DURATION;
Expand All @@ -274,10 +272,12 @@ bool CClip::AcceptAudioPacket(Packet* packet)
else
{
//CAutoLock lock(m_sectionRead);
if (!firstPacketReturned)
if (!m_bFirstPacketReturned)
{
if (earliestPacketAccepted > packet->rtStart) earliestPacketAccepted = packet->rtStart;
firstPacketAccepted = true;
if (m_rtEarliestPacketAccepted > packet->rtStart)
m_rtEarliestPacketAccepted = packet->rtStart;

m_bFirstPacketAccepted = true;
}

packet->nClipNumber = nClip;
Expand All @@ -304,12 +304,12 @@ bool CClip::AcceptVideoPacket(Packet* packet)
}
else
{
if (!firstPacketReturned && packet->rtStart != Packet::INVALID_TIME && earliestPacketAccepted > packet->rtStart)
earliestPacketAccepted = packet->rtStart;
if (!m_bFirstPacketReturned && packet->rtStart != Packet::INVALID_TIME && m_rtEarliestPacketAccepted > packet->rtStart)
m_rtEarliestPacketAccepted = packet->rtStart;

if (!firstPacketAccepted && packet->rtStart != Packet::INVALID_TIME)
if (!m_bFirstPacketAccepted && packet->rtStart != Packet::INVALID_TIME)
{
firstPacketAccepted = true;
m_bFirstPacketAccepted = true;
lastVideoPosition = packet->rtStart;
}

Expand Down Expand Up @@ -392,23 +392,22 @@ void CClip::Reset(REFERENCE_TIME totalStreamOffset)
lastVideoPosition = playlistFirstPacketTime;
lastAudioPosition = playlistFirstPacketTime;

firstPacketAccepted ? clipReset = true : clipReset = false;
m_bFirstPacketAccepted ? clipReset = true : clipReset = false;

clipPlaylistOffset = totalStreamOffset;
m_rtClipPlaylistOffset = totalStreamOffset;

audioPlaybackPosition = playlistFirstPacketTime;
videoPlaybackPosition = playlistFirstPacketTime;
m_rtClipAudioStartingOffset = 0LL;
m_rtClipVideoStartingOffset = 0LL;
m_rtClipStartingOffset = 0LL;

earliestPacketAccepted = INT64_MAX;
m_rtEarliestPacketAccepted = INT64_MAX;

superseded = NO_SUPERSEDE;

firstAudio = true;
firstVideo = true;
firstPacketAccepted = false;
firstPacketReturned = false;
m_bFirstPacketAccepted = false;
m_bFirstPacketReturned = false;
}

bool CClip::HasAudio()
Expand Down
16 changes: 7 additions & 9 deletions DirectShowFilters/BDReader/source/Clip.h
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ class CClip
void Supersede(int supersedeType);
bool IsSuperseded(int supersedeType);
REFERENCE_TIME playlistFirstPacketTime;
REFERENCE_TIME clipPlaylistOffset;
REFERENCE_TIME m_rtClipPlaylistOffset;
void Reset(REFERENCE_TIME totalStreamOffset);
bool HasAudio();
bool HasVideo();
Expand All @@ -85,7 +85,7 @@ class CClip
// starttime of the last video packet returned from the clip to the pin
REFERENCE_TIME videoPlaybackPosition;

REFERENCE_TIME earliestPacketAccepted;
REFERENCE_TIME m_rtEarliestPacketAccepted;

// Clip duration as provided by libbluray
REFERENCE_TIME clipDuration;
Expand All @@ -98,9 +98,8 @@ class CClip

// Accurate clip starting time (when known).
// Not set when selecting chapter from the menu
REFERENCE_TIME m_rtClipAudioStartingOffset;
REFERENCE_TIME m_rtClipVideoStartingOffset;

REFERENCE_TIME m_rtClipStartingOffset;

// true would indicate that this is the first audio packet
bool firstAudio;
// true would indicate that this is the first video packet
Expand All @@ -120,13 +119,12 @@ class CClip
CCritSec m_sectionVectorAudio;
CCritSec m_sectionVectorVideo;

bool m_bCalculateAudioOffset;
bool m_bCalculateVideoOffset;
bool m_bCalculateOffset;

// indicates if this is the first packet to be buffered in clip
bool firstPacketAccepted;
bool m_bFirstPacketAccepted;
// indicates if this is the first packet to be returned from the clip
bool firstPacketReturned;
bool m_bFirstPacketReturned;

REFERENCE_TIME m_rtPrevAudioStart;
REFERENCE_TIME m_rtPlayedDuration; // Do not zero on reset as this should be cumulative
Expand Down
26 changes: 20 additions & 6 deletions DirectShowFilters/BDReader/source/DeMultiplexer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -812,7 +812,7 @@ void CDeMultiplexer::FlushPESBuffers(bool bDiscardData, bool bSetCurrentClipFill
if (m_videoServiceType == BLURAY_STREAM_TYPE_VIDEO_MPEG1 ||
m_videoServiceType == BLURAY_STREAM_TYPE_VIDEO_MPEG2)
FillVideoMPEG2(NULL, NULL, true);
else if (m_videoServiceType == BLURAY_STREAM_TYPE_VIDEO_H264)
else if (m_videoServiceType == BLURAY_STREAM_TYPE_VIDEO_H264 || m_videoServiceType == BLURAY_STREAM_TYPE_VIDEO_HEVC)
FillVideoH264PESPacket(NULL, m_pBuild, true);
else if (m_videoServiceType == BLURAY_STREAM_TYPE_VIDEO_VC1)
FillVideoVC1PESPacket(NULL, m_pBuild, true);
Expand Down Expand Up @@ -996,10 +996,22 @@ void CDeMultiplexer::FillVideoH264PESPacket(CTsHeader* header, CAutoPtr<Packet>
if (!pData)
continue;

if ((pData[4]&0x1f) == 0x09)
m_fHasAccessUnitDelimiters = true;
bool bFlag = false;
if (m_videoServiceType == BLURAY_STREAM_TYPE_VIDEO_HEVC)
{
if (((pData[4] >> 1) & 0x3f) == HEVC::NAL_AUD)
{
m_fHasAccessUnitDelimiters = true;
bFlag = true;
}
}
else if ((pData[4] & 0x1f) == NALU_TYPE_AUD)
{
m_fHasAccessUnitDelimiters = true;
bFlag = true;
}

if ((pData[4]&0x1f) == 0x09 || !m_fHasAccessUnitDelimiters && pPacket->rtStart != Packet::INVALID_TIME)
if (bFlag || !m_fHasAccessUnitDelimiters && pPacket->rtStart != Packet::INVALID_TIME)
{
p = m_pl.RemoveHead();

Expand Down Expand Up @@ -1263,8 +1275,8 @@ void CDeMultiplexer::FillVideoH264(CTsHeader* header, byte* tsPacket)

if (m_pBuild->GetCount() && m_videoServiceType != BLURAY_STREAM_TYPE_VIDEO_VC1)
{
FillVideoH264PESPacket(header, m_pBuild);
m_pBuild.Free();
FillVideoH264PESPacket(header, m_pBuild);
m_pBuild.Free();
}
}

Expand Down Expand Up @@ -1716,6 +1728,8 @@ char* CDeMultiplexer::StreamFormatAsString(int pStreamType)
return "H264";
case BLURAY_STREAM_TYPE_VIDEO_VC1:
return "VC1";
case BLURAY_STREAM_TYPE_VIDEO_HEVC:
return "HEVC";
case BLURAY_STREAM_TYPE_AUDIO_LPCM:
return "LPCM";
case BLURAY_STREAM_TYPE_AUDIO_AC3:
Expand Down
Loading