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

📄 mpeg1.cpp

📁 神龙卡 SDK_84xx_DShow_145_02.zip 这个是 windows 上二个是linux
💻 CPP
字号:
/***********************************************************************/
/* mpeg1.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 mpeg1 stream. 
/************************************************************************/

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

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

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

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

CMpeg1::~CMpeg1()
{
	if (!m_bStopDemux)
		StopDemux();
}

///////////////////////////////////////////////////////////////////
/****f* MMDemux/CMpeg1::Process
 * USAGE
 *  void Process(CBuffer *pCBuffer)
 * DESCRIPTION
 *  Processes the mpeg1 stream.
 * PARAMETERS
 *  CBuffer* pCBuffer - a pointer to the CBuffer object which contains
 *    the mpeg1.
 * RETURN VALUE
 *  STOP_DEMUX if the buffer is NULL or StopDemux() is called; otherwise, SUCCESS_DEMUX
/**********************************************************************/
int CMpeg1::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 = ParseMpeg1System();
		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/CMpeg1::ParseMpeg1System
 * USAGE
 *  void ParseMpeg1System()
 * DESCRIPTION
 *  Parses the mpeg1 system 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 CMpeg1::ParseMpeg1System()
{	
	DWORD m_dwCode = 0;
	while (!m_bStopDemux)
	{
		m_dwCode = SyncOnNextStartCode();
		if (m_bEndOfBuffer)
			return END_OF_BUFFER;
		if (m_dwCode == PACK_START_CODE)
		{	
			SkipMpeg1PackHeader();	// Can re-throw an exception if end of buffer
			if (m_bEndOfBuffer)
				return END_OF_BUFFER;
		}
		else if (m_dwCode == SYSTEM_START_CODE)
		{
			SkipSystemHeader();		// Can re-throw an exception if end of buffer
			if (m_bEndOfBuffer)
				return END_OF_BUFFER;
		}
		else if (((m_dwCode & 0xFFFFFFF0) == AUDIO_STREAM) || 
					((m_dwCode & 0xFFFFFFF0) == VIDEO_STREAM))
		{
			GetMpeg1Packet();
			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, "mpeg1 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, send it
				// now then set the Pts flag to FALSE.
				if (m_dwPayloadLength > 0)
				{
					SetMediaSampleParameters();
					m_bPtsDtsFlag = FALSE;		// Next packet contains only payload.
				}
				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/CMpeg1::SkipMpeg1PackHeader
 * USAGE
 *  void SkipMpeg1PackHeader()
 * DESCRIPTION
 *  Parses the mpeg1 pack header.
 * PARAMETERS
 *  None.
 * RETURN VALUE
 *  None.
/**********************************************************************/
void CMpeg1::SkipMpeg1PackHeader()
{
	m_ullScr = 0;
	// System clock reference bytes and marker bits (5 bytes - 33 bits).
	m_ullScr = (GetByte() >> 1) & 0x7;				// 3 bits, bits 3-1
	m_ullScr = (m_ullScr << 8) & GetByte();			// 8 bits
	m_ullScr = (m_ullScr << 7) & (GetByte() >> 1);	// 7 bits, bits 7-1
	m_ullScr = (m_ullScr << 8) & GetByte();			// 8 bits
	m_ullScr = (m_ullScr << 7) & (GetByte() >> 1);	// 7 bits, bits 7-1

	// Multiplex rate  and marker bits (3 bytes).
	GetWord();
	GetByte();
}

////////////////////////////////////////////////////////////////////
/****f* MMDemux/CMpeg1::GetMpeg1Packet
 * USAGE
 *  void GetMpeg1Packet()
 * DESCRIPTION
 *  Parses the mpeg1 packet header.
 * PARAMETERS
 *  None.
 * RETURN VALUE
 *  None.
/**********************************************************************/
void CMpeg1::GetMpeg1Packet()
{
	INT wPacketHeaderLength = 0;
	INT wPacketLength = 0;
	BYTE byte = FALSE;

	m_bPtsDtsFlag = FALSE;
	m_llPts = 0;

	// Get packet Length, 2 bytes
	wPacketLength = (WORD)GetWord();

	byte = (BYTE)ShowByte();
	if (byte != PRIVATE_STREAM_2)
	{
		// Stuffing bytes
		byte = (BYTE)ShowByte();
		while (byte >> 7)
		{
			GetByte();
			wPacketHeaderLength++;
			byte = (BYTE)ShowByte();
		}

		// StdBufferScale and StdBufferSize, 2 bytes
		byte = (BYTE)ShowByte();
		if ((byte >> 6) == 0x1)
		{
			GetWord();
			wPacketHeaderLength += 2;
		}

		// Get PTS and DTS
		byte = (BYTE)ShowByte();
		if ((byte >> 4) == 0x2)	// '10' PTS presents
		{
			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));
			wPacketHeaderLength += 5;
			m_bPtsDtsFlag = TRUE;
		}
		else if((byte >> 4) == 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));

			// Get DTS, same as getting PTS
			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));
			wPacketHeaderLength += 10;
			m_bPtsDtsFlag = TRUE;
		}
		else	// Neither PTS or DTS flags were set, set to 0xF
		{
			GetByte();
			wPacketHeaderLength++;
		}
	}
	// Pointer of the beginning of payload
	m_bPayloadPtr = m_pBuffer + m_dwBufferIndex;
	// Actual packet data size
	m_dwPayloadLength = wPacketLength - wPacketHeaderLength;
}

/////////////////////////////////////////////////////////////////////////////
/****f* MMDemux/CMpeg1::SkipSystemHeader
 * USAGE
 *  void SkipSystemHeader
 * DESCRIPTION
 *  Parses the mpeg1 system header
 * PARAMETERS
 *  None.
 * RETURN VALUE
 *  None.
/**********************************************************************/
void CMpeg1::SkipSystemHeader()
{
	BYTE byte = 0;
	WORD wHeaderLength = 0;

	wHeaderLength = (WORD)GetWord();

	// Rate bound and marker bits (3 bytes).
	GetWord();
	GetByte();
	// Audio bound, fixed flag, CSPS flag.
	GetByte();
	// System audio clock flag, system video clock flag, marker bit, video bound bits.
	GetByte();
	// Reserved byte
	GetByte();

	// Skip Std_buffer_bound_scale and Std_buffer_size_bound
	while (TRUE)
	{
		byte = (BYTE)ShowByte();
		if ((byte >> 7) == 1)	// first bit is 1, skip 3 bytes
		{		
			GetByte();	// Stream Id
			GetWord();  // buffer bound scale and buffer size bound
		}
		else
			break;
	}
}

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

⌨️ 快捷键说明

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