⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 pes.cpp

📁 神龙卡 SDK_84xx_DShow_145_02.zip 这个是 windows 上二个是linux
💻 CPP
📖 第 1 页 / 共 2 页
字号:
/***********************************************************************/
/* pes.cpp : 
*  REALmagic Quasar Hardware Library
*  Created by Kevin Vo
*  Copyright 2000 Sigma Designs Inc. 
*  355 Fairview Way, Milpitas, CA 95035-3024 USA. All Rights Reserved.  
*  Sigma Designs Proprietary and Confidential
*  Created on 3/20/01
*  Description: Parses the pes stream
/************************************************************************/

#include "pch.h"
#include "manager.h"
#include "splitter.h"

///////////////////////////////////////////////////////////////////

CMpeg2Pes::CMpeg2Pes(MemManager *pMemManager) : CBitParser(pMemManager)
{
}

///////////////////////////////////////////////////////////////////

CMpeg2Pes::~CMpeg2Pes()
{
	if (!m_bStopDemux)
		StopDemux();
}
	
///////////////////////////////////////////////////////////////////
/****f* MMDemux/CMpeg2Pes::Process
 * USAGE
 *  void Process(CBuffer *pCBuffer)
 * DESCRIPTION
 *  Processes the pes stream.
 * PARAMETERS
 *  CBuffer* pCBuffer - a pointer to the CBuffer object which contains
 *    the mpeg2.
 * RETURN VALUE
 *  STOP_DEMUX if the buffer is NULL or StopDemux() is called; otherwise, SUCCESS_DEMUX
/**********************************************************************/
int CMpeg2Pes::Process(CBuffer *pCBuffer)
{
	if (pCBuffer != NULL)
	{
		m_pCBuffer = pCBuffer;

		// Packet is between 2 buffers, newly arrival buffer will use the previous buffer.
		// The GetByte() function will move to new buffer when dwBufferIndex reaches
		// the end of buffer.
		if (m_bPacketBetween2Buffers)
		{	
			m_pBuffer = (BYTE*)m_pPreviousCBuffer->GetBuffer();
			// Last known packet index. This is the last packet of previous buffer.
			m_dwBufferIndex = m_dwPreviousPacketIndex;	
			m_dwBufferSize = m_pPreviousCBuffer->GetActualSize();
		}
		else
		{
			m_dwBufferIndex = 0;
			m_dwBufferSize = m_pCBuffer->GetActualSize();
			m_pBuffer = (BYTE*)m_pCBuffer->GetBuffer();
			// Save this buffer first. If end of buffer occurs, we still have it. When
			// the next buffer arrives, we'll release it. Otherwise, we'll release it if 
			// END_OF_BUFFER exception isn't thrown. We'll also release it if we get
			// PAYLOAD_BETWEEN_2BUFFERS exception.
			m_pPreviousCBuffer = m_pCBuffer;
		}

		// The previous buffer contains pack header, system header, packet header
		// and a portion of payload. Current buffer contains the rest of the
		// payload (usually size < 2048).
		if (m_bPayloadBetween2Buffers)
		{
			if (!GetMorePayload())
			{
				m_pCBuffer->Release();
				return SUCCESS_DEMUX;
			}
			m_bPayloadBetween2Buffers = FALSE;
		}

		int iReturnCode = ParsePes();
		if (m_bStopDemux)
			return STOP_DEMUX;
		else if (iReturnCode == END_OF_BUFFER)
		{
			m_bPacketBetween2Buffers = TRUE;
			m_bEndOfBuffer = FALSE;
		}
		else 
		{
			if (iReturnCode == PAYLOAD_BETWEEN_2BUFFERS)
				m_bPayloadBetween2Buffers = TRUE;
			m_pCBuffer->Release();
		}
		return SUCCESS_DEMUX;
	}
	else
	{
		return STOP_DEMUX;
	}
}

////////////////////////////////////////////////////////////////////
/****f* MMDemux/CMpeg2Pes::ParsePes
 * USAGE
 *  void ParsePes()
 * DESCRIPTION
 *  Parses the pes stream.
 * PARAMETERS
 *  None.
 * RETURN VALUE
 *  STOP_DEMUX if the buffer is NULL or StopDemux() is called.
 *  SUCCESS_DEMUX 
 *  END_OF_BUFFER - End of buffer is reached while parsing the stream.
 *  PAYLOAD_BETWEEN_2BUFFERS - 
/**********************************************************************/
int CMpeg2Pes::ParsePes()
{	
	DWORD m_dwCode = 0;
	while (!m_bStopDemux)
	{
		m_dwCode = SyncOnNextStartCode();
		if (m_bEndOfBuffer)
			return END_OF_BUFFER;
		if ((m_dwCode == PADDING_STREAM) || (m_dwCode == PRIVATE_STREAM_2))
		{
			m_dwPayloadLength = GetWord();
			m_dwBufferIndex += m_dwPayloadLength;
			m_dwPreviousPacketIndex = m_dwBufferIndex;
		}
		else if (((m_dwCode & 0xFFFFFFF0) == AUDIO_STREAM) || 
					((m_dwCode & 0xFFFFFFF0) == VIDEO_STREAM) || (m_dwCode == AC3_PCM_DTS_STREAM))
		{
			if (m_dwCode == AC3_PCM_DTS_STREAM)
			{
				GetAc3DtsPacket();
				if (m_bEndOfBuffer)
					return END_OF_BUFFER;
				m_bStreamType = MM_AUDIO;
				m_dwAStreamId = m_bSubstreamId;
			}
			else
			{
				GetMpeg2Packet();
				if (m_bEndOfBuffer)
					return END_OF_BUFFER;
				DWORD shiftCount = m_dwCode & 0xF;
				DWORD newMask = 1 << shiftCount;
				if ((m_dwCode & 0xFFFFFFF0) == VIDEO_STREAM)
				{
					m_bStreamType = MM_VIDEO;
					m_dwVStreamId = m_dwCode;
					// Determine the correct video channel to play
					if (m_AVId.dwVideoStreamId == 0)
					{
						if (!((m_dwVideoMask >> shiftCount) & 0x1))
						{
							m_dwVideoMask = m_dwVideoMask | newMask;
							m_wVideoChannelCount++;
							if (m_wVideoChannelCount == m_wVideoChannelPlay)
								m_AVId.dwVideoStreamId = m_dwCode;
							MmDebugLogfile((MmDebugLevelTrace, "mpeg2 video channel %d", m_wVideoChannelCount));
						}
					}
				}
				else
				{
					m_bStreamType = MM_AUDIO;
					m_dwAStreamId = m_dwCode;
					// Determine the correct audio channel to play
					if (m_AVId.dwAudioStreamId == 0)
					{
						if (!((m_dwAudioMask >> shiftCount) & 0x1))
						{
							m_dwAudioMask = m_dwAudioMask | newMask;
							m_wAudioChannelCount++;
							if (m_wAudioChannelCount == m_wAudioChannelPlay)
								m_AVId.dwAudioStreamId = m_dwCode;
							MmDebugLogfile((MmDebugLevelTrace, "mpeg1 audio channel %d", m_wAudioChannelCount));
						}
					}
				}
			}
				
			// End of buffer. Payload is between 2 buffers.
			if ((m_dwBufferIndex + m_dwPayloadLength) > m_dwBufferSize)
			{
				m_dwRightPayloadLength = m_dwPayloadLength - (m_dwBufferSize - m_dwBufferIndex);
				m_dwPayloadLength = m_dwBufferSize - m_dwBufferIndex;
				// If m_dwPayloadLength = 0, next buffer contains entire payload, send packet
				// when next buffer arrives, including the PTS if exists. Otherwise, we can
				// now send a portion of the payload. When the next buffer arrives, we'll send
				// the rest of the payload without PTS.
				if (m_dwPayloadLength > 0)
				{
					SetMediaSampleParameters();
					m_bPtsDtsFlag = FALSE;
					m_bNFrameHeaders = 0;
					m_iFirstAccessUnit = 1;
				}						
				return PAYLOAD_BETWEEN_2BUFFERS;
			}
			// We have a complete packet
			m_dwBufferIndex += m_dwPayloadLength;	// Move to the end of this packet
			m_dwPreviousPacketIndex = m_dwBufferIndex;
			SetMediaSampleParameters();
		}
	}
	return SUCCESS_DEMUX;
}

////////////////////////////////////////////////////////////////////
/****f* MMDemux/CMpeg2Pes::GetMpeg2Packet
 * USAGE
 *  void GetMpeg2Packet()
 * DESCRIPTION
 *  Parses the mpeg2 packet header.
 * PARAMETERS
 *  None.
 * RETURN VALUE
 *  None.
/**********************************************************************/
void CMpeg2Pes::GetMpeg2Packet()
{
	INT wPacketHeaderLength = 0;
	INT wPacketLength = 0;
	BYTE byte = 0;
	m_bPtsDtsFlag = FALSE;
	m_llPts = 0;

	wPacketLength = (WORD)GetWord();

	// Skip byte containing scrambling control, priority, alignment, copyright 
	// and original bits.
	GetByte();
	wPacketHeaderLength++;

	// Get PTS, DTS, ESCR, ESRate, DSM trick mode, additional copy info, CRC and
	// extension flags.
	byte = (BYTE)GetByte();
	wPacketHeaderLength++;
	INT bPtsDtsFlag = byte >> 6;				// Bits 7 & 6
	INT bESCRFlag = (byte & 0x20) >> 5;		// Bit 5, must be 0
	INT bESRateFlag = (byte & 0x10) >> 4;		// Bit 4, must be 0
	INT bDSMTrickModeFlag = (byte & 0x8) >> 3;	// Bit 3, must be 0
	INT bAddCopyInfoFlag = (byte & 0x4) >> 2;	// Bit 2, must be 0
	INT bCRCFlag = (byte & 0x2) >> 1;			// Bit 1, must be 0
	INT bExtFlag = byte & 0x1;					// Bit 0, 0 or 1

	// Get Header Data Length
	INT bHeaderDataLength = (BYTE)GetByte();
	wPacketHeaderLength++;

	// Keep current # of advanced bytes after the PES_header_data_length field.
	// Use this to calculate the stuffing bytes.
	INT bCurHeaderDataLength = 0;

	// Get PTS
	if (bPtsDtsFlag == 0x2)	// '10'
	{
		m_llPts = (LONGLONG(GetByte() & 0x0E) << 29);
		m_llPts += (LONGLONG(GetByte()) << 22);
		m_llPts += (LONGLONG(GetByte() & 0xFE) << 14);
		m_llPts += (LONGLONG(GetByte()) << 7);
		m_llPts += (LONGLONG(GetByte() >> 1));
		bCurHeaderDataLength += 5;
		m_bPtsDtsFlag = TRUE;
	}
	else if(bPtsDtsFlag == 0x3)	// '11' PTS and DTS present
	{
		m_llPts = (LONGLONG(GetByte() & 0x0E) << 29);
		m_llPts += (LONGLONG(GetByte()) << 22);
		m_llPts += (LONGLONG(GetByte() & 0xFE) << 14);
		m_llPts += (LONGLONG(GetByte()) << 7);
		m_llPts += (LONGLONG(GetByte() >> 1));

		m_llDts = (LONGLONG(GetByte() & 0x0E) << 29);
		m_llDts += (LONGLONG(GetByte()) << 22);
		m_llDts += (LONGLONG(GetByte() & 0xFE) << 14);
		m_llDts += (LONGLONG(GetByte()) << 7);
		m_llDts += (LONGLONG(GetByte() >> 1));

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -