[datatype-dev] CR: Crash while trying to play specific clip: ftyp 3gp6 mp42 3gp4 isom
Junhong.Liu at nokia.com Junhong.Liu at nokia.com"Nokia submits this code under the terms of a commercial contribution agreement with Real Networks, and I am authorized to contribute this code under said agreement." Modified by: Junhong.Liu at nokia.com Reviewed by: Date: 11-02-2006. Error ID: EOVL-6TCVUL Project: Helix plugin for Symbian Synopsis: Crash while trying to play specific clip: ftyp 3gp6 mp42 3gp4 isom The length of NAL unit can be configured to be of 1, 2, or 4 bytes for AVC file. However, the current implementation always uses 4 bytes, which will give wrong length info if the length size is configured to 1 or 2. The solution is to read the length size field from the header and configure the length correctly. Files Modified: datatype/mdf/video/format/h264/mdfh264payloadformat.cpp datatype/mdf/video/format/h264/pub/mdfh264payloadformat.h datatype/mdf/video/format/mp4/mdfmp4payloadformat.cpp datatype/mdf/video/format/mp4/pub/mdfmp4payloadformat.h datatype/mdf/video/format/rm/mdfrvxpayloadformat.cpp datatype/mdf/video/format/rm/pub/mdfrvxpayloadformat.h datatype/mdf/video/format/common/mdfpayloadformat.cpp datatype/mdf/video/format/common/pub/mdfpayloadformat.h Files Added: None. Image Size and Heap Use impact: None. Platforms and Profiles Build Verified: helix-client-s60-mmf-mdf-arm Platforms and Profiles Functionality verified: armv5, winscw Branch: HXCLIENT_2_1_0_CAYENNES, HEAD ? Makefile ? Umakefil.upp ? armv5-rel32 ? dif.txt ? diff.txt ? mdfh264payloadformat{000a0000}.def Index: mdfh264payloadformat.cpp =================================================================== RCS file: /cvsroot/datatype/mdf/video/format/h264/mdfh264payloadformat.cpp,v retrieving revision 1.1.2.5 diff -w -u -b -r1.1.2.5 mdfh264payloadformat.cpp --- mdfh264payloadformat.cpp 25 Sep 2006 21:31:41 -0000 1.1.2.5 +++ mdfh264payloadformat.cpp 3 Nov 2006 22:13:24 -0000 @@ -58,6 +58,7 @@ const UINT8 start_code[] = {0x00,0x00,0x01}; const UINT16 SPSCOUNT_OFFSET = 5; +const UINT16 LengthSizeMinusOne_OFFSET = 4; CH264PayloadFormatPluginDevice* CH264PayloadFormatPluginDevice::NewL() { @@ -183,11 +184,13 @@ if( pCodecPacket ) { + UINT32 length = CalculateDataLength(pCodecPacket); + pFramePacket = new CMediaPacket( pCodecPacket, (UINT8*) pCodecPacket, - pCodecPacket->dataLength, - pCodecPacket->dataLength, + length, + length, pCodecPacket->timestamp, pCodecPacket->flags, //0, NULL); @@ -216,51 +219,63 @@ HXCODEC_DATA* pCodecPacket = (HXCODEC_DATA*) pMediaPacket->m_pData; - UINT32 ulTotalLen = 0; UINT32 i = 0; UINT32 ulNALLength = 0; UINT32 ulBytes = 0; + UINT32 length = CalculateDataLength(pCodecPacket); + UINT8* temp = (UINT8*) pCodecPacket->data; - MDFVIDEOLOG_WRITE_FORMAT4( " FillBuffer, datelength is = %u", pCodecPacket->dataLength); + MDFVIDEOLOG_WRITE_FORMAT4( " FillBuffer, totalLength is = %u", length); + if( inputBuffer.MaxLength() >= length ) + { for( i = 0; i < pCodecPacket->dataLength; ) { ulNALLength = 0; - for (ulBytes = 0; ulBytes < 4; ulBytes++) + for (ulBytes = 0; ulBytes < m_uNalUnitLenInByte; ulBytes++) { ulNALLength = ulNALLength << 8; ulNALLength = ulNALLength | temp[i + ulBytes]; } - ulTotalLen += ulNALLength + sizeof(start_code); - i += ulNALLength + 4; + inputBuffer.Append( start_code, sizeof( start_code ) ); + inputBuffer.Append( &temp[i + m_uNalUnitLenInByte], ulNALLength ); + + i += ulNALLength + m_uNalUnitLenInByte; + } + + retVal = HXR_OK; } - MDFVIDEOLOG_WRITE_FORMAT4( " FillBuffer, totalLength is = %u", ulTotalLen); - if( inputBuffer.MaxLength() >= ulTotalLen ) + MDFVIDEOLOG_RETURNFN4( "FillBuffer", retVal ); + return retVal; +} + +UINT32 CH264PayloadFormatPluginDevice::CalculateDataLength(const HXCODEC_DATA* pCodecPacket) const { + UINT32 i = 0; + UINT32 ulNALLength = 0; + UINT32 ulTotalLen = 0; + UINT32 ulBytes = 0; + + UINT8* temp = (UINT8*) pCodecPacket->data; + for( i = 0; i < pCodecPacket->dataLength; ) { ulNALLength = 0; - for (ulBytes = 0; ulBytes < 4; ulBytes++) + for (ulBytes = 0; ulBytes < m_uNalUnitLenInByte; ulBytes++) { ulNALLength = ulNALLength << 8; ulNALLength = ulNALLength | temp[i + ulBytes]; } - inputBuffer.Append( start_code, sizeof( start_code ) ); - inputBuffer.Append( &temp[i + 4], ulNALLength ); - - i += ulNALLength + 4; - } - - retVal = HXR_OK; + ulTotalLen += ulNALLength + sizeof(start_code); + i += ulNALLength + m_uNalUnitLenInByte; } - MDFVIDEOLOG_RETURNFN4( "FillBuffer", retVal ); - return retVal; + return ulTotalLen; } void CH264PayloadFormatPluginDevice::Reset( UINT32 ulBeginTime ) @@ -325,24 +340,36 @@ MDFVIDEOLOG_LEAVEFN( "SetVideoDataUnit" ); } -HXBOOL CH264PayloadFormatPluginDevice::FormPictureHeader( TVideoPictureHeader& pPictureHeader ) const +HXBOOL CH264PayloadFormatPluginDevice::FormPictureHeader( TVideoPictureHeader& pPictureHeader ) { MDFVIDEOLOG_ENTERFN( "FormPictureHeader" ); HXBOOL retVal = FALSE; HX_DELETE( pPictureHeader.iOptional ); + UINT16 totalLen = 0; + UINT16 spsLen = 0; + UINT16 ppsLen = 0; + UINT16 offset = 0; + + UINT8 uCountSPS = 0; + UINT8 uCountPPS = 0; + + if( m_pH264Depacketizer ) { //ptr to the bitstreamheader const TUint8* pBitstreamHeader = (const TUint8*) m_pH264Depacketizer->GetBitstreamHeader(); TInt length = (TInt) m_pH264Depacketizer->GetBitstreamHeaderSize(); - UINT16 totalLen = 0; - UINT16 spsLen = 0; - UINT16 offset = SPSCOUNT_OFFSET; + offset = LengthSizeMinusOne_OFFSET; + + m_uNalUnitLenInByte = pBitstreamHeader[offset] & 0x03; + m_uNalUnitLenInByte += 1; - UINT8 uCountSPS = pBitstreamHeader[offset++] & 0x1F; + offset = SPSCOUNT_OFFSET; + + uCountSPS = pBitstreamHeader[offset++] & 0x1F; MDFVIDEOLOG_WRITE_FORMAT4( "<-> count of SPS is = %u", uCountSPS); @@ -357,9 +384,10 @@ uCountSPS--; } - UINT8 uCountPPS = pBitstreamHeader[offset++] & 0x1F; + uCountPPS = pBitstreamHeader[offset++] & 0x1F; MDFVIDEOLOG_WRITE_FORMAT4( "<-> count of PPS is = %u", uCountPPS); - UINT16 ppsLen = 0; + + ppsLen = 0; while( uCountPPS ) { @@ -396,11 +424,13 @@ uCountSPS--; } - UINT8 uCountPPS = pBitstreamHeader[offset++] & 0x1F; + uCountPPS = pBitstreamHeader[offset++] & 0x1F; MDFVIDEOLOG_WRITE_FORMAT4( "<-> count of PPS is = %u", uCountPPS); + + ppsLen = 0; + while( uCountPPS ) { - UINT16 ppsLen = 0; ppsLen = pBitstreamHeader[offset++] << 8; ppsLen |= pBitstreamHeader[offset++]; Index: pub/mdfh264payloadformat.h =================================================================== RCS file: /cvsroot/datatype/mdf/video/format/h264/pub/mdfh264payloadformat.h,v retrieving revision 1.1.2.4 diff -w -u -b -r1.1.2.4 mdfh264payloadformat.h --- pub/mdfh264payloadformat.h 25 Sep 2006 21:31:41 -0000 1.1.2.4 +++ pub/mdfh264payloadformat.h 3 Nov 2006 22:13:24 -0000 @@ -77,9 +77,10 @@ virtual void SetVideoMimetypes( CPayloadFormatInfo& aPayloadFormatInfo ) const; virtual void SetVideoDataUnit(); - virtual HXBOOL FormPictureHeader( TVideoPictureHeader& pPictureHeader ) const; + virtual HXBOOL FormPictureHeader( TVideoPictureHeader& pPictureHeader ); HX_RESULT CreateAllocators(); static void KillInputBuffer( void* pBuffer, void* pUserData ); + UINT32 CalculateDataLength(const HXCODEC_DATA* pCodecPacket) const; private: CHXBufferMemoryAllocator* m_pInputAllocator; @@ -89,6 +90,7 @@ //or customized methods which are specific to H264. //Without m_pH264Depacketizer, m_pDepacketizer needs to be up-casted. IMP4VPayloadFormat* m_pH264Depacketizer; + UINT8 m_uNalUnitLenInByte; MDFVIDEOLOG_DEFINE; }; ? Makefile ? Umakefil.upp ? armv5-rel32 ? diff.txt ? mdfmp4payloadformat{000a0000}.def Index: mdfmp4payloadformat.cpp =================================================================== RCS file: /cvsroot/datatype/mdf/video/format/mp4/mdfmp4payloadformat.cpp,v retrieving revision 1.2.2.8 diff -w -u -b -r1.2.2.8 mdfmp4payloadformat.cpp --- mdfmp4payloadformat.cpp 25 Sep 2006 21:31:42 -0000 1.2.2.8 +++ mdfmp4payloadformat.cpp 3 Nov 2006 00:36:48 -0000 @@ -277,7 +277,7 @@ MDFVIDEOLOG_LEAVEFN( "SetVideoDataUnit" ); } -HXBOOL CMP4PayloadFormatPluginDevice::FormPictureHeader( TVideoPictureHeader& pPictureHeader ) const +HXBOOL CMP4PayloadFormatPluginDevice::FormPictureHeader( TVideoPictureHeader& pPictureHeader ) { MDFVIDEOLOG_ENTERFN( "FormPictureHeader" ); Index: pub/mdfmp4payloadformat.h =================================================================== RCS file: /cvsroot/datatype/mdf/video/format/mp4/pub/mdfmp4payloadformat.h,v retrieving revision 1.2.2.5 diff -w -u -b -r1.2.2.5 mdfmp4payloadformat.h --- pub/mdfmp4payloadformat.h 25 Sep 2006 21:31:42 -0000 1.2.2.5 +++ pub/mdfmp4payloadformat.h 3 Nov 2006 00:36:48 -0000 @@ -76,7 +76,7 @@ virtual void SetVideoMimetypes( CPayloadFormatInfo& aPayloadFormatInfo ) const; virtual void SetVideoDataUnit(); - virtual HXBOOL FormPictureHeader( TVideoPictureHeader& pPictureHeader ) const; + virtual HXBOOL FormPictureHeader( TVideoPictureHeader& pPictureHeader ); HX_RESULT CreateAllocators(); static void KillInputBuffer( void* pBuffer, void* pUserData ); ? Makefile ? Umakefil.upp ? armv5-rel32 ? diff.txt ? mdfrvxpayloadformat{000a0000}.def Index: mdfrvxpayloadformat.cpp =================================================================== RCS file: /cvsroot/datatype/mdf/video/format/rm/mdfrvxpayloadformat.cpp,v retrieving revision 1.1.2.6 diff -w -u -b -r1.1.2.6 mdfrvxpayloadformat.cpp --- mdfrvxpayloadformat.cpp 25 Sep 2006 21:31:42 -0000 1.1.2.6 +++ mdfrvxpayloadformat.cpp 3 Nov 2006 00:37:52 -0000 @@ -265,7 +265,7 @@ MDFVIDEOLOG_LEAVEFN( "SetVideoDataUnit" ); } -HXBOOL CRVXPayloadFormatPluginDevice::FormPictureHeader( TVideoPictureHeader& pPictureHeader ) const +HXBOOL CRVXPayloadFormatPluginDevice::FormPictureHeader( TVideoPictureHeader& pPictureHeader ) { MDFVIDEOLOG_ENTERFN( "FormPictureHeader" ); HXBOOL retVal = FALSE; Index: pub/mdfrvxpayloadformat.h =================================================================== RCS file: /cvsroot/datatype/mdf/video/format/rm/pub/mdfrvxpayloadformat.h,v retrieving revision 1.1.2.4 diff -w -u -b -r1.1.2.4 mdfrvxpayloadformat.h --- pub/mdfrvxpayloadformat.h 25 Sep 2006 21:31:42 -0000 1.1.2.4 +++ pub/mdfrvxpayloadformat.h 3 Nov 2006 00:37:52 -0000 @@ -76,7 +76,7 @@ virtual void SetVideoMimetypes( CPayloadFormatInfo& aPayloadFormatInfo ) const; virtual void SetVideoDataUnit(); - virtual HXBOOL FormPictureHeader( TVideoPictureHeader& pPictureHeader ) const; + virtual HXBOOL FormPictureHeader( TVideoPictureHeader& pPictureHeader ); HX_RESULT CreateAllocators(); virtual HX_RESULT InitializeDepacketizer(); static void KillInputBuffer( void* pBuffer, void* pUserData ); ? Makefile ? Umakefil.upp ? armv5-rel32 ? diff.txt Index: mdfpayloadformat.cpp =================================================================== RCS file: /cvsroot/datatype/mdf/video/format/common/mdfpayloadformat.cpp,v retrieving revision 1.2.2.6 diff -w -u -b -r1.2.2.6 mdfpayloadformat.cpp --- mdfpayloadformat.cpp 25 Sep 2006 21:31:40 -0000 1.2.2.6 +++ mdfpayloadformat.cpp 3 Nov 2006 00:38:33 -0000 @@ -395,7 +395,7 @@ return retVal; } -HXBOOL CPayloadFormatPluginDevice::FormPictureHeader( TVideoPictureHeader& pPictureHeader ) const +HXBOOL CPayloadFormatPluginDevice::FormPictureHeader( TVideoPictureHeader& pPictureHeader ) { return FALSE; } Index: pub/mdfpayloadformat.h =================================================================== RCS file: /cvsroot/datatype/mdf/video/format/common/pub/mdfpayloadformat.h,v retrieving revision 1.2.2.5 diff -w -u -b -r1.2.2.5 mdfpayloadformat.h --- pub/mdfpayloadformat.h 25 Sep 2006 21:31:41 -0000 1.2.2.5 +++ pub/mdfpayloadformat.h 3 Nov 2006 00:38:33 -0000 @@ -137,7 +137,7 @@ protected: CPayloadFormatPluginDevice(); virtual HX_RESULT InitializeDepacketizer(); - virtual HXBOOL FormPictureHeader( TVideoPictureHeader& pPictureHeader ) const; + virtual HXBOOL FormPictureHeader( TVideoPictureHeader& pPictureHeader ); virtual void SetVideoMimetypes( CPayloadFormatInfo& aPayloadFormatInfo ) const = 0; virtual void SetVideoDataUnit() = 0;