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

📄 ps2ts.cpp

📁 可用该程序将avi的电影文件转化为TS流
💻 CPP
📖 第 1 页 / 共 2 页
字号:
    // Build the TS header to put this date    *pPosInTs = pPacket->BuildAdaptionField(iSCR);  }  else  {    // Parse the SCR (MPEG2 format)    u64 iHighBits = m_bBuff[START_CODE_LEN] & 0x38;    u64 iMiddleBits = U32_AT(m_bBuff[START_CODE_LEN]) & 0x03FFF800;    u64 iLowBits = U32_AT(m_bBuff[START_CODE_LEN+2]) & 0x03FFF800;    ASSERT((m_bBuff[START_CODE_LEN] & 0x4));    ASSERT((m_bBuff[START_CODE_LEN+2] & 0x4));    ASSERT((m_bBuff[START_CODE_LEN+4] & 0x4));    u64 iSCR = iHighBits << 27 | iMiddleBits << 4 | iLowBits >> 11;    // Kludge pour tester horloge//    struct timeval sTimeval;//    gettimeofday(&sTimeval, NULL);//    printf("Date mpeg2: %Ld, date systeme %d (en s)\n", iSCR, sTimeval.tv_sec);        // Build the TS header to put this date    *pPosInTs = pPacket->BuildAdaptionField(iSCR);//    if(iSCR - m_iPrevSCR > 800)//      printf("time : %Ld ; delta : %Ld\n", iSCR, iSCR - m_iPrevSCR);    if(m_iPrevSCR >= iSCR)    {      printf("Time discontinuity in PS stream\n");      m_bDiscontinuity = true;    }    m_iPrevSCR = iSCR;      // Read additional stuffing bytes if any (MPEG2 only)    if(m_iPackHeaderLen == 10 + START_CODE_LEN)    {      iStuffLen = m_bBuff[m_iPackHeaderLen-1] & 0x7;      if(iStuffLen && !iRc)      {        iRc = m_pReader->Read(m_bBuff+LOOK_AHEAD_LEN+m_iPackHeaderLen, iStuffLen);        ASSERT(iRc >= 0);        iRc = (iRc != iStuffLen);      }//      printf("Stuffing of size %d found: actual length is: %d\n", iStuffLen, m_iPackHeaderLen+iStuffLen);    }  }    // Look Ahead of 6  m_iDataType = U32_AT(m_bBuff[m_iPackHeaderLen+iStuffLen]);  m_pCurrentData = m_cPgrmDescriptor.GetDescriptor(m_iDataType & 0xFF);  m_iDataLen = U16_AT(m_bBuff[m_iPackHeaderLen+iStuffLen+START_CODE_LEN]);  m_bPESStart = true;  //printf("Next data will be: %X (len: %d)\n",  m_iNextData, m_iNextLength);//  printf("Next data will be: %X (len: %d)\n",  m_iDataType, m_iDataLen);  return iRc;}//------------------------------------------------------------------------------////------------------------------------------------------------------------------template <class Reader, class TsProvider>   int C_Ps2Ts<Reader, TsProvider>::ParseSystemHeader(C_TsPacket* pPacket, u8* iPosInTs){//  printf("Parsing SYSTEM_HEADER\n");   int iRc = m_pReader->Read(m_bBuff, m_iDataLen+LOOK_AHEAD_LEN);  ASSERT(iRc >= 0);  iRc = (iRc != m_iDataLen+LOOK_AHEAD_LEN);//  printf("Length: %d\n", m_iDataLen);  m_iDataType = U32_AT(m_bBuff[m_iDataLen]);  m_pCurrentData = m_cPgrmDescriptor.GetDescriptor(m_iDataType & 0xFF);  m_iDataLen = U16_AT(m_bBuff[m_iDataLen+START_CODE_LEN]);  return iRc;}//------------------------------------------------------------------------------////------------------------------------------------------------------------------template <class Reader, class TsProvider>   int C_Ps2Ts<Reader, TsProvider>::ParsePES(C_TsPacket* pPacket, u8* pPosInTs){  ASSERT(pPacket);  ASSERT(pPosInTs);  // Pour le debug uniquement//  if(m_bPESStart)//  {//    printf("Parsing PES of type %x\n", m_iDataType);//    printf("PES Length: %d (without the 6 first bytes)\n", m_iDataLen);//  }//  else//    printf("Continuing to parse PES (remaining length: %d)\n", m_iDataLen);  // This variable only exists to speed up the process of looking the value of  // pPosInTs  u8 iPos;  // Write the data in the TS that depends on our position in the PES  if(m_bPESStart)  {    // Write the header with the bUnitStart flag set to true    ASSERT(m_pCurrentData);    ASSERT(m_pCurrentData->GetId() == (m_iDataType&0xFF));    u8 iCounter = m_pCurrentData->GetCounter();    u16 iPid =  m_pCurrentData->GetPid();    iPos = pPacket->BuildHeader(iPid, true, iCounter);    // We can have parsed an adaption field if the PES comes just after a    // pack header    if(iPos < *pPosInTs)    {      if(iPid == m_cPgrmDescriptor.GetPcrPid())      {      // The adaption_field_control has been overwritten so that the bit      // which indicates an adaption_field is no more set to 1      byte* pTsPayload = (byte*)(*pPacket);      pTsPayload[iPos-1] |= 0x20;      // Set the right position      iPos = *pPosInTs;      if(m_bDiscontinuity)      {        ASSERT(pPacket->HasPCR());        ASSERT(pPacket->SetDiscontinuityFlag());        pPacket->SetDiscontinuityFlag();        m_bDiscontinuity = false;      }      }    }        // Write the beginning of the PES packet (corresponds to the look ahead)    byte* pTsPayload = (byte*)(*pPacket);    SET_U32_TO(pTsPayload[iPos], m_iDataType);    SET_U16_TO(pTsPayload[iPos+START_CODE_LEN], m_iDataLen);    iPos += START_CODE_LEN + PES_SIZE_LEN;  }  else  {    // We shouldn't have any adaption field    ASSERT(*pPosInTs == 0);    // Write the header with the bUnitStart flag set to false    ASSERT(m_pCurrentData);    ASSERT(m_pCurrentData->GetId() == (m_iDataType&0xFF));       u8 iCounter = m_pCurrentData->GetCounter();    u16 iPid =  m_pCurrentData->GetPid();    iPos = pPacket->BuildHeader(iPid, false, iCounter);  }  // Now read the data carried in the PES  for(unsigned int i = 0; i < m_iMaxBufferedTs; i++)  {    // Fill the Ts packet    if(m_iDataLen >= TS_PACKET_LEN - iPos)    {      // Fill the remaining payload of the TS packet      m_iStatus = m_pReader->Read(((byte*)(*pPacket)+iPos), TS_PACKET_LEN-iPos);      ASSERT(m_iStatus >= 0);      m_iStatus = (m_iStatus != TS_PACKET_LEN-iPos);      m_iDataLen -= (TS_PACKET_LEN-iPos);      //-----------------      if(m_bPESStart)      {      if(*((byte*)(*pPacket) + iPos - 3) == PES_ID_PRIVATE_1)      {//      printf("Id : 0x%x", *((byte*)(*pPacket) + iPos - 3));        u8 iOffset = *((byte*)(*pPacket) + iPos + 2);//        printf(" Offset : 0x%x", iOffset);        u8 iPrivateId = *((byte*)(*pPacket) + iPos + 3 + iOffset);//        printf(" PrivateId : 0x%x", iPrivateId);/*        if((iPrivateId & 0xf0) == 0x80)        {*/          m_pCurrentData = m_cPgrmDescriptor.GetDescriptor(m_iDataType & 0xFF,                                                           iPrivateId);          u16 iPid =  m_pCurrentData->GetPid();          u16 iData = U16_AT(*((byte*)(pPacket) + 1));//          printf(" Data : 0x%x", iData);          iPid = (iPid & 0x1fff) | (iData & 0xe000);//          printf(" NewPid : 0x%x", iPid);          SET_U16_TO(*((byte*)(pPacket) + 1), iPid);          *((byte*)(pPacket) + 3) = (m_pCurrentData->GetCounter() & 0x0f) |                                    (*((byte*)(pPacket) + 3) & 0xf0);/*        }*///      printf("\n");      }      }      //-----------------    }    else    {      // m_iDataLen shouldn't be null      ASSERT(m_iDataLen > 0);//      printf("Stuffing needed: iPos=%d, DataLen=%d\n", iPos, m_iDataLen);      // Write the end of the PES packet in the TS packet      if(m_bPESStart)      {        // We have already written the PES start code and the pes length at the        // beginning of the TS packet, which will be erased by the stuffing bytes:        // we must rewrite them        iPos = pPacket->AddStuffingBytes(m_iDataLen+START_CODE_LEN+PES_SIZE_LEN);        byte* pTsPayload = (byte*)(*pPacket);        SET_U32_TO(pTsPayload[iPos], m_iDataType);        SET_U16_TO(pTsPayload[iPos+START_CODE_LEN], m_iDataLen);                iPos += START_CODE_LEN+PES_SIZE_LEN;      }      else      {        // Simply add the stuffing bytes at the end of the TS header        iPos = pPacket->AddStuffingBytes(m_iDataLen);      }            m_iStatus = m_pReader->Read(((byte*)(*pPacket)+iPos), m_iDataLen);      ASSERT(m_iStatus >= 0);      m_iStatus = (m_iStatus != m_iDataLen);              //-----------------      if(m_bPESStart)      {      if(*((byte*)(*pPacket) + iPos - 3) == PES_ID_PRIVATE_1)      {//      printf("Id : 0x%x", *((byte*)(*pPacket) + iPos - 3));        u8 iOffset = *((byte*)(*pPacket) + iPos + 2);//        printf(" Offset : 0x%x", iOffset);        u8 iPrivateId = *((byte*)(*pPacket) + iPos + 3 + iOffset);//        printf(" PrivateId : 0x%x", iPrivateId);/*        if((iPrivateId & 0xf0) == 0x80)        {*/          m_pCurrentData = m_cPgrmDescriptor.GetDescriptor(m_iDataType & 0xFF,                                                           iPrivateId);          u16 iPid =  m_pCurrentData->GetPid();          u16 iData = U16_AT(*((byte*)(pPacket) + 1));//          printf(" Data : 0x%x", iData);          iPid = (iPid & 0x1fff) | (iData & 0xe000);//          printf(" NewPid : 0x%x", iPid);          SET_U16_TO(*((byte*)(pPacket) + 1), iPid);          *((byte*)(pPacket) + 3) = (m_pCurrentData->GetCounter() & 0x0f) |                                    (*((byte*)(pPacket) + 3) & 0xf0);/*        }*///      printf("\n");      }      }      //-----------------      // All data have been read      m_iDataLen = 0;    }    // We are no more at the beginning of the PES yet    m_bPESStart = false;    // Increase the number of TS packets that have been build    m_pCurrentData->IncreaseCounter();    m_iTSCounter++;    if(m_cPgrmDescriptor.m_bNewPmt)    {      // Delay this packet to send PSI first      ASSERT(!m_pDelayedPacket);      m_pDelayedPacket = pPacket;      m_bSendPSI = m_bGenPmt = m_bResetPSI = true;      m_cPgrmDescriptor.m_bNewPmt = false;      i = m_iMaxBufferedTs - 1;    }    else    {      // Put the TS packet in the list of pending TS      m_cPendingTS.PushEnd(pPacket);    }    ZERO(pPacket);    // Prepare the next iteration if we must loop    if(m_iDataLen > 0)    {      // There is a second condition for looping since we don't read      // the complete PES in a single operation      if(i < m_iMaxBufferedTs - 1)      {           // Get another TS packet to fill        pPacket = m_pTsProvider->GetPacket();        ASSERT(pPacket);        // Build the new TS header        ASSERT(m_pCurrentData);        ASSERT(m_pCurrentData->GetId() == (m_iDataType&0xFF));        u8 iCounter = m_pCurrentData->GetCounter();        u16 iPid =  m_pCurrentData->GetPid();        iPos = pPacket->BuildHeader(iPid, false, iCounter);      }    }    else    {      // Look ahead for next iteration      m_iStatus = m_pReader->Read(m_bBuff, LOOK_AHEAD_LEN);      ASSERT(m_iStatus >= 0);      m_iStatus = (m_iStatus != LOOK_AHEAD_LEN);      m_iDataType = U32_AT(m_bBuff[0]);      m_pCurrentData = m_cPgrmDescriptor.GetDescriptor(m_iDataType & 0xFF);      m_iDataLen = U16_AT(m_bBuff[4]);      m_bPESStart = true;//      printf("Next data will be: %x (len = %d)\n", m_iDataType, m_iDataLen);            // Don't loop      break;    }  }    return m_iStatus;}//------------------------------------------------------------------------------////------------------------------------------------------------------------------template <class Reader, class TsProvider>   int C_Ps2Ts<Reader, TsProvider>::SkipPES(C_TsPacket* pPacket, u8* iPosInTs){  // Release the TS packet, we won't need it  m_pTsProvider->ReleasePacket(pPacket);  int iRc = m_pReader->Seek(m_iDataLen, SEEK_CUR);  if(iRc)    m_iStatus = FILE_ERR;  else  {    // Look ahead for next iteration    m_iStatus = m_pReader->Read(m_bBuff, LOOK_AHEAD_LEN);    ASSERT(m_iStatus >= 0);    m_iStatus = (m_iStatus != LOOK_AHEAD_LEN);    m_iDataType = U32_AT(m_bBuff[0]);    m_pCurrentData = m_cPgrmDescriptor.GetDescriptor(m_iDataType & 0xFF);    m_iDataLen = U16_AT(m_bBuff[4]);    m_bPESStart = true;//    printf("Next data will be: %x (len = %d)\n", m_iDataType, m_iDataLen);    if(m_iStatus == NO_ERR)      m_iStatus = SKIPPED_DATA;  }    return m_iStatus;}//------------------------------------------------------------------------------////------------------------------------------------------------------------------template <class Reader, class TsProvider>   int C_Ps2Ts<Reader, TsProvider>::ParsePgrmMap(C_TsPacket* pPacket, u8* iPosInTs){//  printf("Parsing pgrm map PES: WARNING, code never tested\n");//  printf("Pgrm map length: %d\n", m_iDataLen);  ASSERT(false);  while(m_iDataLen >= sizeof(m_bBuff))  {/*    int iRc = */m_pReader->Read(m_bBuff, sizeof(m_bBuff));    m_iDataLen -= sizeof(m_bBuff);  }  //  push PAT et PMT dans la liste des pendingpackets   return NO_ERR;}

⌨️ 快捷键说明

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