Example #1
0
void cParser::PutData(unsigned char* data, int length, bool pusi)
{
  // get PTS / DTS on PES start
  if (pusi)
  {
    int64_t pts = m_curPTS;
    int64_t dts = m_curDTS;

    int offset = ParsePESHeader(data, length);
    data += offset;
    length -= offset;

    if(pts > m_curPTS) m_curPTS = pts;
    if(dts > m_curDTS) m_curDTS = dts;

    m_startup = false;
  }

  // put data
  if(!m_startup && length > 0 && data != NULL)
  {
    int put = Put(data, length);
    // reset buffer on overflow
    if(put < length)
    {
      ERRORLOG("Parser buffer overflow - resetting");
      Clear();
    }
  }
}
void cParserMPEG2Audio::Parse(unsigned char *data, int size, bool pusi)
{
    if (pusi)
    {
        /* Payload unit start */
        m_PESStart      = true;
        m_firstPUSIseen = true;
    }

    /* Wait for first pusi */
    if (!m_firstPUSIseen)
        return;

    if (m_PESStart)
    {
        int hlen = ParsePESHeader(data, size);
        if (hlen <= 0)
            return;

        data += hlen;
        size -= hlen;

        m_PESStart = false;

        assert(size >= 0);
        if(size == 0)
            return;
    }

    while (size > 0)
    {
        uint8_t *outbuf;
        int      outlen;

        int rlen = FindHeaders(&outbuf, &outlen, data, size, m_curPTS, m_curDTS);
        if (rlen < 0)
            break;

        m_curPTS = DVD_NOPTS_VALUE;
        m_curDTS = DVD_NOPTS_VALUE;

        if (outlen)
        {
            sStreamPacket pkt;
            pkt.data     = outbuf;
            pkt.size     = outlen;
            pkt.duration = 90000 * 1152 / m_SampleRate;
            pkt.dts      = m_DTS;
            if (pkt.dts == DVD_NOPTS_VALUE)
                pkt.dts = m_NextDTS;
            pkt.pts      = pkt.dts;
            m_NextDTS    = pkt.dts + pkt.duration;

            m_demuxer->SendPacket(&pkt);
        }
        data += rlen;
        size -= rlen;
    }
}
void cParserTeletext::Parse(unsigned char *data, int size, bool pusi)
{
    if (pusi)
    {
        /* Payload unit start */
        m_PESStart      = true;
        m_firstPUSIseen = true;
    }

    /* Wait for first pusi */
    if (!m_firstPUSIseen)
        return;

    if (m_PESStart)
    {
        if (!PesIsPS1Packet(data))
        {
            ERRORLOG("Teletext PES packet contains no valid private stream 1, ignored this packet");
            m_firstPUSIseen = false;
            return;
        }

        m_lastDTS = m_curDTS;
        m_lastPTS = m_curPTS;
        int hlen = ParsePESHeader(data, size);

        m_PESStart = false;
        data      += hlen;
        size      -= hlen;

        if (data[0] < 0x10 || data[0] > 0x1F)
        {
            ERRORLOG("Teletext PES packet contains no valid identifier, ignored this packet");
            m_firstPUSIseen = false;
            return;
        }

        if (m_teletextBuffer && m_teletextBufferPtr > 0)
        {
            sStreamPacket pkt;
            pkt.id       = m_streamID;
            pkt.data     = m_teletextBuffer;
            pkt.size     = m_teletextBufferPtr;
            pkt.duration = m_curDTS-m_lastDTS;
            pkt.dts      = m_lastDTS;
            pkt.pts      = m_lastPTS;
            SendPacket(&pkt);
            m_teletextBufferPtr = 0;
        }
    }

    if (m_teletextBuffer == NULL)
    {
        m_teletextBufferSize  = 4000;
        m_teletextBuffer      = (uint8_t*)malloc(m_teletextBufferSize);
    }

    if (m_teletextBufferPtr + size + 4 >= m_teletextBufferSize)
    {
        m_teletextBufferSize  += size * 4;
        m_teletextBuffer       = (uint8_t*)realloc(m_teletextBuffer, m_teletextBufferSize);
    }

    memcpy(m_teletextBuffer+m_teletextBufferPtr, data, size);
    m_teletextBufferPtr += size;
}
Example #4
0
bool cParserH264::Parse_H264(size_t len, uint32_t next_startcode, int sc_offset)
{
  uint8_t nal_data[len];
  int pkttype;
  uint8_t *buf = m_pictureBuffer + sc_offset;
  uint32_t startcode = m_StartCode;

  if (startcode == 0x10c)
  {
    /* RBSP padding, we don't want this */
    int length = len - sc_offset;
    memcpy(buf, buf + length, 4); /* Move down new start code */
    m_pictureBufferPtr -= length;  /* Drop buffer */
  }

  if (startcode >= 0x000001e0 && startcode <= 0x000001ef)
  {
    /* System start codes for video */
    if (len >= 9)
      ParsePESHeader(buf, len);

    if (m_PrevDTS != DVD_NOPTS_VALUE)
    {
      int64_t duration = (m_curDTS - m_PrevDTS) & 0x1ffffffffLL;

      if (duration < 90000)
        m_FrameDuration = duration;
    }
    m_PrevDTS = m_curDTS;
    return true;
  }

  switch(startcode & 0x1f)
  {
  case NAL_SPS:
  {
    int nal_len = nalUnescape(nal_data, buf + 4, len - 4);
    if (!Parse_SPS(nal_data, nal_len))
      return true;

    m_demuxer->SetVideoInformation(0,0, m_Height, m_Width, m_PixelAspect.num/m_PixelAspect.den);
    break;
  }

  case NAL_PPS:
  {
    int nal_len = nalUnescape(nal_data, buf + 4, len - 4);
    if (!Parse_PPS(nal_data, nal_len))
      return true;

    break;
  }

  case 5: /* IDR+SLICE */
  case NAL_SLH:
  {
    if (m_FoundFrame || m_FrameDuration == 0 || m_curDTS == DVD_NOPTS_VALUE)
      break;

    int nal_len = nalUnescape(nal_data, buf + 4, len - 4 > 64 ? 64 : len - 3);
    if (!Parse_SLH(nal_data, nal_len, &pkttype))
      return true;

    m_StreamPacket.id         = m_streamID;
    m_StreamPacket.pts        = m_curPTS;
    m_StreamPacket.dts        = m_curDTS;
    m_StreamPacket.frametype  = pkttype;
    m_StreamPacket.duration   = m_FrameDuration;
    m_FoundFrame = true;
    break;
  }

  default:
    break;
  }

  if (next_startcode >= 0x000001e0 && next_startcode <= 0x000001ef)
  {
    /* Complete frame */
    if (!m_FoundFrame)
      return true;

    /* Discard Packets until we have the picture size (XBMC can't enable VDPAU without it) */
    if (!m_Width)
      return true;
    else
      m_Streamer->SetReady();

    m_FoundFrame        = false;
    m_StreamPacket.data = m_pictureBuffer;
    m_StreamPacket.size = m_pictureBufferPtr;
    SendPacket(&m_StreamPacket);
    m_firstPUSIseen = true;
    return true;
  }

  return false;
}