diff options
author | Christian Gmeiner <christian.gmeiner@gmail.com> | 2009-04-18 22:53:34 +0200 |
---|---|---|
committer | Christian Gmeiner <christian.gmeiner@gmail.com> | 2009-04-18 22:53:34 +0200 |
commit | e69dd2aef4cd63be6804e022c60a79f11e785cf9 (patch) | |
tree | 634e4699c4502b8f3863feef3cf3ad9cda73eab8 /dxr3pesframe.c | |
parent | 3ff05678bb4b7621482f3e79ca057951cc8f0430 (diff) | |
download | vdr-plugin-dxr3-e69dd2aef4cd63be6804e022c60a79f11e785cf9.tar.gz vdr-plugin-dxr3-e69dd2aef4cd63be6804e022c60a79f11e785cf9.tar.bz2 |
rewrite cDxr3PesFrame::parse
Diffstat (limited to 'dxr3pesframe.c')
-rw-r--r-- | dxr3pesframe.c | 278 |
1 files changed, 69 insertions, 209 deletions
diff --git a/dxr3pesframe.c b/dxr3pesframe.c index bde2dcd..6077de0 100644 --- a/dxr3pesframe.c +++ b/dxr3pesframe.c @@ -2,6 +2,7 @@ * dxr3pesframe.c * * Copyright (C) 2002-2004 Kai Möller + * Copyright (C) 2009 Christian Gmeiner * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License @@ -29,240 +30,99 @@ #include <vdr/tools.h> // ================================== -bool cDxr3PesFrame::parse(const uint8_t* pBuf, uint32_t length) - throw (ePesFrameError) +bool cDxr3PesFrame::parse(const uint8_t *pes, uint32_t length) { - cDxr3SafeArray<uint8_t> pesArray((uint8_t*)pBuf, length); - uint32_t pos = 0; - m_pNextStart = pBuf; - m_remainingLength = length; + // look if at the beginning there is the pes packet start indicator + if (pes[0] != 0 || pes[1] != 0 || pes[2] != 1) { + esyslog("[cDxr3PesFrame]: no start indicator found..."); + return false; + } - InitData(); + m_bValid = true; - try - { - if (length > 9) - { - for (; pos + 9 < length && !IsPesHeader(pesArray.SubArray(pos, 4)); pos++); - if (pos + 9 >= length) - { - // Corrupt stream? - m_remainingLength = 0; - return m_bValid; - } - m_pPesStart = pBuf + pos; + // handle stream id + switch (pes[3]) { + case 0xBD: // private stream 1 + m_pesDataType = PES_PRIVATE_DATA; - if ((pesArray[pos + 6] & 0xC0) == 0x80 - /*|| (pesArray[pos + 6] & 0xC0) == 0x00*/) - { - if (pos + 9 + pesArray[pos + 8] < length) - { - m_payload = pBuf + pos + 9 + pesArray[pos + 8]; - if ((((int)pesArray[pos + 4]) * (int)256 + (int)pesArray[pos + 5]) > 0) - { - m_payloadLength = ((int)pesArray[pos + 4]) * - (int)256 + (int)pesArray[pos + 5] + (int)6 - - (9 + (int)pesArray[pos + 8]); - if (pos + 9 + pesArray[pos + 8] + m_payloadLength <= length) - { - m_bValid = true; - m_pNextStart = m_payload + m_payloadLength; - m_remainingLength = pBuf + length - (m_payload + m_payloadLength); - if (pesArray[pos + 6] >> 6 == 2 && - pesArray[pos + 7] >> 7 != 0) - { - ExtractPts(pesArray.SubArray(pos + 9, 5)); - } - if (m_pesDataType == PES_VIDEO_DATA) - { - int retval = ExtractVideoData(pesArray.SubArray(pos + 9 + pesArray[pos + 8], m_payloadLength)); - if (m_videoFrameType != UNKNOWN_FRAME && retval) - m_offset = retval + pos + 9 + pesArray[pos + 8]; - } - } - } - } - } - else - { - uint32_t fpos = pos + 6; - m_payloadLength = ((int)pesArray[pos + 4]) * (int)256 + (int)pesArray[pos + 5]; - if (length >= pos + 6 + m_payloadLength) - { - while (pesArray[fpos] == 0xff) - ++fpos; // skip stuffing bytes - if ((pesArray[fpos] & 0xC0) == 0x40) - fpos += 2; // skip std buffer scale and size - if ((pesArray[fpos] & 0xF0) == 0x20) - { - // pts only - ExtractPts(pesArray.SubArray(fpos, 5)); - fpos += 5; - } - else if ((pesArray[fpos] & 0xF0) == 0x30) - { - // pts and dts - ExtractPts(pesArray.SubArray(fpos, 5)); - fpos += 10; - } - else - { - ++fpos; - } + case 0xC0 ... 0xDF: // audio stream + m_pesDataType = PES_AUDIO_DATA; + break; - if (m_payloadLength) m_payloadLength = m_payloadLength - (fpos - pos - 6); - m_payload = pBuf + fpos; - m_pNextStart = m_payload + m_payloadLength; - m_remainingLength = pBuf + length - (m_payload + m_payloadLength); - m_bValid = true; - if (m_pesDataType == PES_VIDEO_DATA) - { - int retval = ExtractVideoData(pesArray.SubArray(fpos, m_payloadLength)); - if (m_videoFrameType != UNKNOWN_FRAME && retval) - m_offset = 0; - } - } - } - } - } - catch (cDxr3SafeArray<uint8_t>::eSafeArrayException ex) - { - m_bValid = false; - esyslog("dxr3: general PES error"); - throw(PES_GENERAL_ERROR); + case 0xE0 ... 0xEF: // video stream + m_pesDataType = PES_VIDEO_DATA; + break; + + default: + return false; } - return m_bValid; -} + // read pes header len + uint8_t pesHeaderDataLength = pes[8]; -// ================================== -int cDxr3PesFrame::ExtractVideoData(cDxr3SafeArray<uint8_t> esFrame) - throw (cDxr3SafeArray<uint8_t>::eSafeArrayException) -{ - int retval = 0; - for (uint32_t i = 0; esFrame.GetLength() > (uint32_t) 8 && i < esFrame.GetLength() - 8; i++) - { - if (esFrame[i] == 0 && esFrame[i + 1] == 0 && esFrame[i + 2] == 1) - { - // start code - if ((esFrame[i + 3] & 0xFF) == 0x00) - { - // frame type - if (m_offset == 0) - retval = i; - switch ((esFrame[i + 5] >> 3) & 0x7) - { - case 0x1: - m_videoFrameType = I_FRAME; - break; - case 0x2: - m_videoFrameType = P_FRAME; - break; - case 0x3: - m_videoFrameType = B_FRAME; - break; - default: - m_videoFrameType = UNKNOWN_FRAME; - break; - } - } - else if ((esFrame[i + 3] & 0xFF) == 0xB3) - { - // aspect ratio - switch ((esFrame[i + 7]) & 0xF0) - { - case 0x20: - m_staticAspectRatio = m_aspectRatio = - EM8300_ASPECTRATIO_4_3; - break; - case 0x30: - m_staticAspectRatio = m_aspectRatio = - EM8300_ASPECTRATIO_16_9; - break; - default: - break; - } - m_staticHorizontalSize = m_horizontalSize = - (esFrame[i + 5] & 0xF0) >> 4 | esFrame[i + 4] << 4; - m_staticVerticalSize = m_verticalSize = - ((esFrame[i + 5] & 0x0F) << 8) | (esFrame[i + 6]); - } - } + // look if there is a pts + if (pes[7] & (1 << 7)) { + // read pts + uint64_t pts = (((int64_t)pes[ 9]) & 0x0e) << 29; + pts |= ( (int64_t)pes[10]) << 22; + pts |= (((int64_t)pes[11]) & 0xfe) << 14; + pts |= ( (int64_t)pes[12]) << 7; + pts |= (((int64_t)pes[13]) & 0xfe) >> 1; + + m_pts = pts >> 1; } - return retval; -} -// ================================== -void cDxr3PesFrame::ExtractPts(cDxr3SafeArray<uint8_t> ptsData) - throw (cDxr3SafeArray<uint8_t>::eSafeArrayException) -{ - m_pts = ((ptsData[0] >> 1) & 0x07) << 29; - m_pts |= ptsData[1] << 21; - m_pts |= (ptsData[2] >> 1) << 14; - m_pts |= ptsData[3] << 6; - m_pts |= ptsData[4] >> 2; -} + // set pointer to start of payload + int payloadStart = 9 + pesHeaderDataLength; + m_payload = &pes[payloadStart]; + m_payloadLength = length - payloadStart; -// ================================== -bool cDxr3PesFrame::IsPesHeader(cDxr3SafeArray<uint8_t> header) - throw (cDxr3SafeArray<uint8_t>::eSafeArrayException) -{ - bool ret = false; + if (m_pesDataType == PES_VIDEO_DATA) { - if (!header[0] && !header[1] && header[2] == 0x01 ) - { - ret = true; - switch (header[3]) - { - case 0xC0 ... 0xDF: // audio stream - m_pesDataType = PES_AUDIO_DATA; - break; + // we can get some informations about the video payload + // of this pes frame. For more informations have a look + // at http://dvd.sourceforge.net/dvdinfo/mpeghdrs.htm - case 0xE0 ... 0xEF: // video stream - m_pesDataType = PES_VIDEO_DATA; - break; + const uint8_t *video = &pes[payloadStart]; - case 0xBD: // private stream 1 - m_pesDataType = PES_PRIVATE_DATA; - break; + // look if there is the start code prefix (0000 0000 0000 0000 0000 0001) + if (video[0] != 0 || video[1] != 0 || video[2] != 1) { + return true; + } - case 0xBA: - ret = false; - break; + // check stream id + if (video[3] == 0xb3) { - case 0xBE: // padding stream - ret = false; - break; + // in the sequence header we get informations about horizontal + // and vertical size of the video and the current aspect ratio. - case 0xBC: // program stream map - case 0xBF: // private stream 2 - case 0xF0: // ECM stream - case 0xF1: // EMM stream - case 0xF2: // DSMCC stream - case 0xF3: // 13522 stream - case 0xF4: // H.22.1 type A - case 0xF5: // H.22.1 type B - case 0xF6: // H.22.1 type C - case 0xF7: // H.22.1 type D - case 0xF8: // H.22.1 type E - case 0xF9: // ancillary stream - case 0xFA ... 0xFE: // reserved data stream - case 0xFF: // program stream directory - break; - default: - ret = false; - break; - } + m_horizontalSize = (video[5] & 0xf0) >> 4 | video[4] << 4; + m_verticalSize = (video[5] & 0x0f) << 8 | video[6]; + + switch ((video[7]) & 0xf0) { + case 0x20: + m_aspectRatio = EM8300_ASPECTRATIO_4_3; + break; + + case 0x30: + m_aspectRatio = EM8300_ASPECTRATIO_16_9; + break; + } + + m_staticHorizontalSize = m_horizontalSize; + m_staticVerticalSize = m_verticalSize; + m_staticAspectRatio = m_aspectRatio; + } } - return ret; + return true; } + // ================================== uint32_t cDxr3PesFrame::m_staticAspectRatio = EM8300_ASPECTRATIO_4_3; uint32_t cDxr3PesFrame::m_staticHorizontalSize = 720; uint32_t cDxr3PesFrame::m_staticVerticalSize = 576; -const uint32_t cDxr3PesFrame::MAX_PES_HEADER_SIZE = 184; // Local variables: // mode: c++ |