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; }
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; }