ts.h 6.43 KB
Newer Older
1 2 3 4
/*******************************************************************************
* ts.h: TsPacket class definition
*-------------------------------------------------------------------------------
* (c)1999-2001 VideoLAN
5
* $Id: ts.h,v 1.12 2003/08/14 17:20:36 adq Exp $
6 7
*
* Authors: Benoit Steiner <benny@via.ecp.fr>
8
*          Jean-Paul Saman <jpsaman@wxs.n>
9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
*
*-------------------------------------------------------------------------------
*
*******************************************************************************/


#ifndef _TS_H_
#define _TS_H_


//------------------------------------------------------------------------------
// 
//------------------------------------------------------------------------------
class C_TsPacket
{
 public:
39
  C_TsPacket() { m_iRefCount = 0; };
40
  ~C_TsPacket();
41
  
42 43 44 45 46 47 48
  // Direct access to the buffer. Provided only for efficiency reasons
  operator byte* ();
  
  // By hand packet header construction
  u8 BuildHeader(u16 iPid, bool bUnitStart, u8 iCounter);
  u8 BuildAdaptionField(u64 iPCR);
  u8 AddStuffingBytes(u8 iPayloadLen);
49
  u8 FillWith(byte * pBuff, int iBeginning, int iEnd);
50 51 52 53 54

  // Packet modifications
  void IncrementCounter();
  void SetErrorFlag(bool bError = true);
  bool SetDiscontinuityFlag(bool bDiscontinuity = true);
55

56
  // Packet decoding
57
  u16 GetPid() const;
58
  bool HasPCR() const;
59
  u16 GetPMTPid(int number);
60
  bool IsDiscontinuity() const;
61
  bool HasDiscontinuityFlag() const;
62
  s64 GetPCRTime() const;
63 64 65 66 67 68 69 70 71
  byte* GetPayloadStart();
  u8 GetPayloadLength() const;
  bool HasPayloadStartIndicator() const;
  bool HasContinuityCounter() const;
  bool HasAdaptationField() const;
  u8 GetAdaptationFieldLength() const;
  u8 GetContinuityCounter() const;
  u8 SetContinuityCounter(int old_counter);
  bool IsNullPacket() const;
72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88

  // Reference counter
  unsigned int Ref()
  {
    ASSERT(m_iRefCount + 1);
    return ++m_iRefCount;
  };
  unsigned int Unref()
  {
    ASSERT(m_iRefCount);
    return --m_iRefCount;
  };
  unsigned int RefCount() const
  {
    return m_iRefCount;
  }

89 90
 protected:
  byte bData[TS_PACKET_LEN];
91 92 93 94 95 96

  unsigned int m_iRefCount;
};


//------------------------------------------------------------------------------
97
//
98 99 100 101
//------------------------------------------------------------------------------
class I_TsPacketHandler
{
public:
102
  virtual bool HandlePacket(C_TsPacket* pPacket) = 0;
103
  virtual bool HandlePrefillPacket(C_TsPacket* pPacket) = 0;
104
  virtual void Shutdown() = 0;
105 106 107
  virtual void PrefillStart() = 0;
  virtual void PrefillComplete() = 0;

108 109 110 111 112

  bool operator == (const I_TsPacketHandler& cHandler) const
  {
    return (this == &cHandler);
  };
113 114 115 116
};


//------------------------------------------------------------------------------
117
//
118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139
//------------------------------------------------------------------------------
// The section must fit in a single TS packet and its data are put immediately
// after the TS header
// The section_syntax_indicator field is set to 1 so if this class is used to
// build a private section the section must follow the generic syntax beyond
// the private_section_length field
//------------------------------------------------------------------------------
class C_PsiSection : protected C_TsPacket
{
 public:
  C_PsiSection();

  // Guess :)
  u8 BuildHeader(u16 iPid, u8 iCounter, u8 iTableId, u16 iPsiId, u8 iVersion,
                 bool bCurrentNext, u8 iCurrentSection, u8 iLastSection);

  // Append data at the end of the section
  inline byte* AppendData(u8 iDataLen);
  // Modify the data at the given position in the psi section
  inline byte* GetDataForUpdate(u8 iDataPos);
  // Read the data at the given position
  inline const byte* GetDataForRead(u8 iDataPos) const;
140 141

  //
142 143
  inline void Finalize();

144
  //
145
  u8 GetVersion();
146

147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221
 protected:
  void UpdateVersion();

  void BuildCrc32Table();
  inline void ComputeCrc32();

  inline void AddFinalStuffing();

 private:
  u32 iCrc32Table[256];
  u8 m_iPsiStart;
  bool m_bIsModified;
};


//------------------------------------------------------------------------------
// At that time, the complete PAT must fit in a single TS packet
//------------------------------------------------------------------------------
class C_Pat : protected C_PsiSection
{
 public:
  // Build the PAT header
  void BuildHeader(u16 iStreamId, u8 iVersion, bool bCurrentNext = true);

  // Add a program to the list of pgrms carried in the stream
  int AddPgrm(u16 iPgrmNumber, u16 iPmtPid);
  // Remove a program from the list of pgrms carried in the stream
  //int RemovePgrm(u16 iPgrmNumber);
  // Remove all the programs from the PAT
  //void EmptyPat();

  // Write the PAT in the given TS packet. Increment the continuity counter
  // at each call
  void Write(C_TsPacket* pPacket);
};


//------------------------------------------------------------------------------
// At that time, the complete PMT must fit in a single TS packet
//------------------------------------------------------------------------------
class C_Pmt : protected C_PsiSection
{
 public:
  // Build the PMT header
  void BuildHeader(u16 iPid, u16 iPgrmNumber, u16 iPcrPid, u8 iVersion,
                   bool bCurrentNext = true);

  u16 GetPcrPid() const;
  void UpdatePcrPid(u16 iNewPid);
  
  // Add a descriptor for the program. Must be called before any AddEs()
  int AddPgrmDescriptor(/*C_Descriptor* pDescriptors*/);

  // Add an elementary stream for that pgrm
  int AddEs(u8 iType, u16 iPid/*, const C_Vector<C_Descriptor*>& cDescriptors*/);

  // Remove an elementary stream for that pgrm
  //void RemoveES(u16 iPid);
  
  // Remove all the descriptors and the ES from the PMT 
  void EmptyPmt();
  
  // Write the PMT in the given TS packet. Increment the continuity counter
  // at each call
  void Write(C_TsPacket* pPacket);

 private:
  bool m_bIsModified;
};


#else
#error "Multiple inclusions of ts.h"
#endif