pesfilter.c
来自「Sun公司Dream项目」· C语言 代码 · 共 254 行
C
254 行
/*
* The contents of this file are subject to the terms
* of the Common Development and Distribution License
* (the "License"). You may not use this file except
* in compliance with the License.
*
* You can obtain a copy of the license at
* http://www.opensource.org/licenses/cddl1.php
* See the License for the specific language governing
* permissions and limitations under the License.
*
* When distributing Covered Code, include this CDDL
* HEADER in each file and include the License file at
* http://www.opensource.org/licenses/cddl1.php. If
* applicable, add the following below this CDDL HEADER,
* with the fields enclosed by brackets "[]" replaced
* with your own identifying information:
* Portions Copyright [yyyy]
* [name of copyright owner]
*/
/*
* $(@)PesFilter.cc $Revision: 1.1.1.1 $ $Date: 2006/04/17 22:47:31 $
*
* Copyright 2006 Sun Microsystems, Inc. All Rights Reserved.
*/
#include "PesFilter.h"
#include <iostream>
#include <bitset>
namespace mpeg2ts {
struct PesHeaderFlags
{
std::bitset<2> b10;
std::bitset<2> pesScramblingControl;
std::bitset<1> pesPriority;
std::bitset<1> dataAlignmentIndicator;
std::bitset<1> copyright;
std::bitset<1> originalOrCopy;
std::bitset<2> ptsDtsFlags;
std::bitset<1> escrFlag;
std::bitset<1> esRateFlag;
std::bitset<1> dsmTrickModeFlag;
std::bitset<1> additionalCopyInfoFlag;
std::bitset<1> pesCrcFlag;
std::bitset<1> pesExtensionFlag;
std::bitset<8> pesHeaderDataLength;
};
struct PesHeader32bitValue
{
std::bitset<3> bits32_30;
std::bitset<1> markerBit1;
std::bitset<15> bits29_15;
std::bitset<1> markerBit2;
std::bitset<15> bits14_0;
std::bitset<1> markerBit3;
};
struct PesHeaderPts
{
std::bitset<4> ptsDtsType; /* '0010' or '0011' */
PesHeader32bitValue timeStamp;
};
struct PesHeader
{
std::bitset<24> packetStartCodePrefix;
std::bitset<8> streamId;
std::bitset<16> pesPacketLength;
bool flagsValid;
enum StreamId {
ProgramStreamMap = 0xbc,
PrivateStream1 = 0xbd,
PaddingStream = 0xbe,
PrivateStream2 = 0xbf,
AudioStreamIdStart = 0xc0,
AudioStreamIdEnd = 0xdf,
VideoStreamIdStart = 0xe0,
VideoStreamIdEnd = 0xef,
EcmStream = 0xf0,
EmmStream = 0xf1,
DsmCcStream = 0xf2,
IsoIec1522Stream = 0xf3,
ItuTRecH2221TypeEStream = 0xf8,
ProgramStreamDirectory = 0xff
};
PesHeaderFlags flags;
};
struct PesHeaderEscr
{
std::bitset<2> reserved2;
PesHeader32bitValue escrBase;
std::bitset<9> escrExtension;
std::bitset<1> marker;
};
struct PesHeaderEsRate
{
std::bitset<1> marker1;
std::bitset<22> esRate;
std::bitset<1> marker2;
};
InputBitBuffer& operator>>( InputBitBuffer& source, PesHeaderFlags& pesHdrFlags )
{
source >> pesHdrFlags.b10;
source >> pesHdrFlags.pesScramblingControl;
source >> pesHdrFlags.pesPriority;
source >> pesHdrFlags.dataAlignmentIndicator;
source >> pesHdrFlags.copyright;
source >> pesHdrFlags.originalOrCopy;
source >> pesHdrFlags.ptsDtsFlags;
source >> pesHdrFlags.escrFlag;
source >> pesHdrFlags.esRateFlag;
source >> pesHdrFlags.dsmTrickModeFlag;
source >> pesHdrFlags.additionalCopyInfoFlag;
source >> pesHdrFlags.pesCrcFlag;
source >> pesHdrFlags.pesExtensionFlag;
source >> pesHdrFlags.pesHeaderDataLength;
return source;
}
std::ostream& operator<<( std::ostream& out, PesHeaderFlags& pesHdrFlags )
{
out << "\tb10: " << pesHdrFlags.b10;
out << "\n\tpesScramblingControl: " << pesHdrFlags.pesScramblingControl;
out << "\n\tpesPriority: " << pesHdrFlags.pesPriority;
out << "\n\tdataAlignmentIndicator: " << pesHdrFlags.dataAlignmentIndicator;
out << "\n\tcopyright: " << pesHdrFlags.copyright;
out << "\n\toriginalOrCopy: " << pesHdrFlags.originalOrCopy;
out << "\n\tptsDtsFlags: " << pesHdrFlags.ptsDtsFlags;
out << "\n\tescrFlag: " << pesHdrFlags.escrFlag;
out << "\n\tesRateFlag: " << pesHdrFlags.esRateFlag;
out << "\n\tpesHeaderDataLength " << pesHdrFlags.pesHeaderDataLength.to_ulong();
return out;
}
InputBitBuffer& operator>>( InputBitBuffer& source, PesHeader& peshdr )
{
source >> peshdr.packetStartCodePrefix;
source >> peshdr.streamId;
source >> peshdr.pesPacketLength;
peshdr.flagsValid = false;
if( peshdr.packetStartCodePrefix.to_ulong() != 0X000001 ) {
std::cout << "ERROR parsing PES Header: Start Code Prefix not present\n";
// TODO: Throw InvalidBitstream ?
return source;
}
long streamId = peshdr.streamId.to_ulong();
if( streamId == PesHeader::PaddingStream )
{
assert( peshdr.pesPacketLength.to_ulong() != 0 );
std::bitset<8> dummy;
for( int i=0; i<peshdr.pesPacketLength.to_ulong(); ++i )
source >> dummy;
}
if( streamId==PesHeader::ProgramStreamMap || streamId==PesHeader::PrivateStream2
|| streamId==PesHeader::EcmStream || streamId==PesHeader::EmmStream
|| streamId==PesHeader::ProgramStreamDirectory || streamId==PesHeader::DsmCcStream
|| streamId==PesHeader::ItuTRecH2221TypeEStream )
{
// The rest of the buffer is all data...
NULL;
}else
{
peshdr.flagsValid = true;
source >> peshdr.flags;
assert( peshdr.flags.b10 == std::bitset<2>(0x2) );
// TODO: Fill up the pts/dts and escr fields
std::bitset<8> dummy;
for( int i=0; i<peshdr.flags.pesHeaderDataLength.to_ulong(); ++i )
source >> dummy;
}
return source;
};
std::ostream& operator<<( std::ostream& out, PesHeader& peshdr )
{
std::cout << "SC: " << peshdr.packetStartCodePrefix;
std::cout << "\nStreamId: " << peshdr.streamId.to_ulong();
std::cout << "\npes_packet_length: " << peshdr.pesPacketLength.to_ulong() << '\n';
if( peshdr.flagsValid )
out << peshdr.flags;
return out;
}
void PesFilter::processPesPacket() const
{
const char *data = m_buffer.data();
int len = m_buffer.size();
InputBitBuffer buf((const unsigned char *)data, len);
PesHeader peshdr;
buf >> peshdr;
PairBytesBits consumed = buf.dataConsumed();
assert( consumed.first > 0 );
assert( consumed.second == 0 );
data += consumed.first;
len -= consumed.first;
if( m_filter.get() ) {
m_filter->process( PesBuffer((unsigned char *)const_cast< char *>(data), len,
m_mapBufferPos_StreamPos, (const unsigned char *) m_buffer.data()) );
}
}
int PesFilter::process( Buffer pesBytes )
{
if( pesBytes.isStart == Buffer::UNIT_START) {
if( m_buffer.size()>0 )
processPesPacket();
m_mapBufferPos_StreamPos.clear();
m_mapBufferPos_StreamPos[0] = pesBytes.posInTsStream;
m_buffer.assign( (const char *)pesBytes.data, pesBytes.len );
}else{
m_mapBufferPos_StreamPos[ m_buffer.size() ] = pesBytes.posInTsStream;
m_buffer.append((const char *)pesBytes.data, pesBytes.len);
}
return 0;
}
void PesFilter::setDownstreamFilter(EsFilter *filter)
{
m_filter = std::auto_ptr<EsFilter>(filter);
}
PesFilter::~PesFilter()
{
std::cout << "~PesFilter: data remaining: " << m_buffer.size() << '\n';
if( m_buffer.size() > 0 )
processPesPacket();
}
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?