diff options
| -rw-r--r-- | dxr3pesframe.c | 278 | ||||
| -rw-r--r-- | dxr3pesframe.h | 15 | 
2 files changed, 70 insertions, 223 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++ diff --git a/dxr3pesframe.h b/dxr3pesframe.h index 869b06b..345f184 100644 --- a/dxr3pesframe.h +++ b/dxr3pesframe.h @@ -118,8 +118,7 @@ public:      virtual ~cDxr3PesFrame() {} -    bool parse(const uint8_t* pBuf, uint32_t length) -    throw (ePesFrameError); +    bool parse(const uint8_t *pes, uint32_t length);      ePesDataType GetPesDataType() const      { @@ -145,11 +144,6 @@ public:          return m_payloadLength;      } -    const uint8_t* GetNextStart() const -    { -        return m_pNextStart; -    } -      uint32_t GetPts() const      {          assert(m_bValid); @@ -196,13 +190,6 @@ public:      }  protected: -    bool IsPesHeader(cDxr3SafeArray<uint8_t> header) -	throw (cDxr3SafeArray<uint8_t>::eSafeArrayException); -    void ExtractPts(cDxr3SafeArray<uint8_t> ptsData) -	throw (cDxr3SafeArray<uint8_t>::eSafeArrayException); -    int ExtractVideoData(cDxr3SafeArray<uint8_t> esFrame) -	throw (cDxr3SafeArray<uint8_t>::eSafeArrayException); -      void InitData()      {          m_pesDataType = PES_UNKNOWN_DATA; | 
