📄 bitparser.cpp
字号:
else
pMedia->SetPtsDtsFlag(FALSE);
pMedia->SetFirstAccessUnit(m_iFirstAccessUnit);
}
else
m_bAudioPtsFlag = FALSE;
SendToHardware (pMedia);
pMedia->Release();
#else // BUFFER_AUDIO
memcpy (m_pAudioBuffer + m_dwAudioBufferLen, m_bPayloadPtr, m_dwPayloadLength);
m_dwAudioBufferLen += m_dwPayloadLength;
if (m_bAudioPesHeader || (m_dwAudioBufferLen + 184) >= m_pAudioCBuffer->GetActualSize())
{
m_pMemManager->GetMediaSample(m_pAudioCBuffer, &pMedia);
pMedia->SetPayload(m_pAudioBuffer);
pMedia->SetActualDataLength(m_dwAudioBufferLen);
pMedia->SetPts(m_llAudioPts, m_bAudioPtsFlag);
pMedia->SetMediaType(m_bStreamType);
pMedia->SetScr(m_llPcr);
pMedia->SetNFrameHeaders(0);
pMedia->SetFirstAccessUnit(0);
if (m_bAudioType == MM_AUDIO_FORMAT_AC3)
{
if (SetFirstAccessUnitPtr(m_pAudioBuffer, m_dwAudioBufferLen, &m_iFirstAccessUnit))
pMedia->SetPtsDtsFlag(TRUE);
else
pMedia->SetPtsDtsFlag(FALSE);
pMedia->SetFirstAccessUnit(m_iFirstAccessUnit);
}
else
m_bAudioPtsFlag = FALSE;
SendToHardware (pMedia);
m_bAudioPesHeader = FALSE;
m_llPcr = 0;
pMedia->Release();
m_pAudioCBuffer->Release();
m_pAudioCBuffer = m_pMemManager->GetTSBuffer();
m_pAudioBuffer = (BYTE*)m_pAudioCBuffer->GetBuffer();
m_dwAudioBufferLen = 0;
}
#endif
break;
}
}
}
////////////////////////////////////////////////////////////////////
// Program stream sample
//#define DEFINE_PAYLOAD_LENGTH
#ifdef DEFINE_PAYLOAD_LENGTH
#define PAYLOAD_LENGTH 184
#endif
void CBitParser::ProgramSample()
{
CIMediaSample* pMedia = 0;
if ((m_bStreamType == MM_AUDIO) && (m_dwAStreamId != m_AVId.dwAudioStreamId))
return;
if ((m_bStreamType == MM_VIDEO) && (m_dwVStreamId != m_AVId.dwVideoStreamId))
return;
if (m_dwPayloadLength > 0)
{
#if defined(_RECORD_AUDIO_) || defined(_RECORD_VIDEO_)
SavePayload();
#endif
#ifndef DEFINE_PAYLOAD_LENGTH
m_pMemManager->GetMediaSample(m_pCBuffer, &pMedia);
pMedia->SetPayload(m_bPayloadPtr);
pMedia->SetActualDataLength(m_dwPayloadLength);
pMedia->SetPts(m_llPts, m_bPtsDtsFlag);
pMedia->SetMediaType(m_bStreamType);
pMedia->SetScr(m_ullScr);
pMedia->SetNFrameHeaders(m_bNFrameHeaders);
pMedia->SetFirstAccessUnit(m_iFirstAccessUnit);
pMedia->SetSampleRate(m_lSampleRate);
if (m_bFastForward)
{
pMedia->SetPtsDtsFlag(FALSE);
if (m_bStreamType == MM_VIDEO)
m_pIFrame->Receiver(pMedia);
else
pMedia->Release();
}
else
{
SendToHardware (pMedia);
pMedia->Release();
}
#else
DWORD dwNewPayloadLength;
dwNewPayloadLength = (m_dwPayloadLength <= PAYLOAD_LENGTH) ? m_dwPayloadLength : PAYLOAD_LENGTH;
while (!m_bStopDemux)
{
m_pMemManager->GetMediaSample(m_pCBuffer, &pMedia);
pMedia->SetPayload(m_bPayloadPtr);
pMedia->SetActualDataLength(dwNewPayloadLength);
pMedia->SetPts(m_llPts, m_bPtsDtsFlag);
pMedia->SetMediaType(m_bStreamType);
pMedia->SetScr(m_ullScr);
pMedia->SetNFrameHeaders(m_bNFrameHeaders);
pMedia->SetFirstAccessUnit(m_iFirstAccessUnit);
pMedia->SetSampleRate(m_lSampleRate);
if (m_bFastForward)
{
pMedia->SetPtsDtsFlag(FALSE);
if (m_bStreamType == MM_VIDEO)
m_pIFrame->Receiver(pMedia);
else
pMedia->Release();
}
else
{
SendToHardware (pMedia);
pMedia->Release();
}
if (m_dwPayloadLength <= dwNewPayloadLength)
break;
m_dwPayloadLength -= dwNewPayloadLength;
m_bPayloadPtr += dwNewPayloadLength;
if (dwNewPayloadLength > m_dwPayloadLength)
dwNewPayloadLength = m_dwPayloadLength;
m_bPtsDtsFlag = FALSE;
m_bNFrameHeaders = 0;
m_iFirstAccessUnit = 1;
}
#endif
}
}
/////////////////////////////////////////////////////////////////////////////
/****f* MMDemux/CBitParser::SetMediaSampleParameters
* USAGE
* void SetMediaSampleParameters()
* DESCRIPTION
* Sets the MediaSample parameters and sends the sample to the hardware.
* PARAMETERS
* None.
* RETURN VALUE
* None.
/**********************************************************************/
// Support program stream only
void CBitParser::SetMediaSampleParameters(void)
{
if (m_bStopDemux)
return;
if (m_bIsTransport)
TransportSample();
else
ProgramSample();
}
/////////////////////////////////////////////////////////////////////
void CBitParser::SavePayload()
{
#ifdef _RECORD_VIDEO_
if (m_bStreamType == MM_VIDEO)
fwrite(m_bPayloadPtr, sizeof(BYTE), m_dwPayloadLength, m_pVideoFile);
#endif
#ifdef _RECORD_AUDIO_
if (m_bStreamType == MM_AUDIO)
{
// A stream can have both AC3 and DTS
switch (m_bAudioType)
{
case MM_AUDIO_FORMAT_AC3:
fwrite(m_bPayloadPtr, sizeof(BYTE), m_dwPayloadLength, m_pAudioFile);
break;
case MM_AUDIO_FORMAT_PCM:
fwrite(m_bPayloadPtr, sizeof(BYTE), m_dwPayloadLength, m_pAudioFile);
break;
case MM_AUDIO_FORMAT_DTS:
fwrite(m_bPayloadPtr, sizeof(BYTE), m_dwPayloadLength, m_pAudioFile);
break;
case MM_AUDIO_FORMAT_MPEG1:
fwrite(m_bPayloadPtr, sizeof(BYTE), m_dwPayloadLength, m_pAudioFile);
break;
}
}
#endif
}
/////////////////////////////////////////////////////////////////////
DWORD CBitParser::SyncOnNextStartCode()
{
DWORD dwCode = 0;
dwCode = GetDWord();
while ((dwCode & 0xFFFFFF00) != 0x0000100)
{
dwCode = (dwCode << 8) + GetByte();
if (m_bEndOfBuffer || m_bStopDemux)
return 0;
}
return dwCode;
}
////////////////////////////////////////////////////////////////////
DWORD CBitParser::ShowByte()
{
if (m_dwBufferIndex < m_dwBufferSize)
return *(m_pBuffer + m_dwBufferIndex);
// It's the end of the current buffer (previous buffer) and trying to
// move to next buffer if the flag is set to TRUE meaning the next buffer
// (new buffer) is loaded with data and ready to continue.
else if (m_bPacketBetween2Buffers)
{
m_pPreviousCBuffer->Release(); // We don't need this anymore.
m_pBuffer = (BYTE*)m_pCBuffer->GetBuffer();
m_dwBufferSize = m_pCBuffer->GetActualSize();
m_dwBufferIndex = 0;
// Save this buffer first. If end of buffer occurs, we still have it. Next
// time a new buffer arrives, we'll release it. Otherwise, we'll release
// it if no END_OF_BUFFER exception is thrown. We'll also release it if we get
// PAYLOAD_BETWEEN_2BUFFERS exception. The release is performed in Process().
m_pPreviousCBuffer = m_pCBuffer;
m_bPacketBetween2Buffers = FALSE;
return *(m_pBuffer + m_dwBufferIndex);
}
else
{
m_bEndOfBuffer = TRUE;
return 0;
}
}
////////////////////////////////////////////////////////////////////
// Gets a BYTE from the loaded buffer
DWORD CBitParser::GetByte()
{
if (m_dwBufferIndex < m_dwBufferSize)
return *(m_pBuffer + (m_dwBufferIndex++));
// It's the end of the current buffer (previous buffer) and trying to
// move to next buffer if the flag is set to TRUE meaning the next buffer
// (new buffer) is loaded with data and ready to continue.
else if (m_bPacketBetween2Buffers)
{
m_pPreviousCBuffer->Release(); // We don't need this anymore.
m_pBuffer = (BYTE*)m_pCBuffer->GetBuffer();
m_dwBufferSize = m_pCBuffer->GetActualSize();
m_dwBufferIndex = 0;
// Save this buffer first. If end of buffer occurs, we still have it. Next
// time a new buffer arrives, we'll release it. Otherwise, we'll release
// it if no END_OF_BUFFER exception is thrown. We'll also release it if we get
// PAYLOAD_BETWEEN_2BUFFERS exception. The release is performed in Process().
m_pPreviousCBuffer = m_pCBuffer;
m_bPacketBetween2Buffers = FALSE;
return *(m_pBuffer + (m_dwBufferIndex++));
}
else
{
m_bEndOfBuffer = TRUE;
return 0;
}
}
////////////////////////////////////////////////////////////////////
// Gets a WORD (2 bytes) from the stream
DWORD CBitParser::GetWord()
{
DWORD dw = 0;
dw = GetByte();
return (dw << 8) | GetByte();
}
////////////////////////////////////////////////////////////////////
// Gets a DWORD (4 bytes) from the stream
DWORD CBitParser::GetDWord()
{
DWORD dw = 0;
dw = GetWord();
return (dw << 16) | GetWord();
}
/////////////////////////////////////////////////////////////////////
BOOL CBitParser::GetMorePayload()
// PURPOSE: Get the rest of the data bytes for the packet that lies between
// 2 buffers. This portion of data will not contain PTS, only the
// packet pointer and size. This payload is always at the beginning
// of the next buffer. After getting this partial payload,
// ParseMpeg1/2System() function will resume to parse the rest of the
// buffer normally.
{
if (m_dwBufferSize <= m_dwRightPayloadLength)
{
m_dwPayloadLength = m_dwBufferSize;
m_bPayloadPtr = m_pBuffer;
SetMediaSampleParameters();
m_dwBufferIndex += m_dwBufferSize; // Move to the end of this buffer
m_dwPreviousPacketIndex = m_dwBufferIndex;
m_dwRightPayloadLength -= m_dwBufferSize;
return FALSE;
}
else
{
m_dwPayloadLength = m_dwRightPayloadLength;
m_bPayloadPtr = m_pBuffer;
SetMediaSampleParameters();
m_dwBufferIndex += m_dwRightPayloadLength; // Move to the end of this packet
m_dwPreviousPacketIndex = m_dwBufferIndex;
m_dwRightPayloadLength = 0;
return TRUE;
}
}
////////////////////////////////////////////////////////////////////
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -