[prev in list] [next in list] [prev in thread] [next in thread] 

List:       helix-datatype-cvs
Subject:    [Datatype-cvs] mkv/fileformat mkv_file_format.cpp, 1.11.2.21.2.4, 1.11.2.21.2.5
From:       hanshunsun () helixcommunity ! org
Date:       2012-07-19 8:14:55
[Download RAW message or body]

Update of /cvsroot/datatype/mkv/fileformat
In directory cvs01.internal.helixcommunity.org:/tmp/cvs-serv3983

Modified Files:
      Tag: hxclient_3_6_1_raja
	mkv_file_format.cpp 
Log Message:
Synopsis: 
Changes to fix the issue that compressed-mkv files cannot play.
merge from 361atlas branch.

Files Added: NONE

Files Modified:
/datatype/mkv/libmatroska/Matroska.cpp
/datatype/mkv/libmatroska/MatroskaExports.cpp
/datatype/mkv/libmatroska/MatroskaExports.h
/datatype/mkv/fileformat/pub/mkv_file_format.h
/datatype/mkv/fileformat/mkv_file_format.cpp

Platforms and Profiles Affected:
Platform: android-icecream-sandwitch-arm-omap40xx_blaze
Profile: helix-client-android-full

Distribution Libraries Affected:
mkvff.so

Distribution library impact and planned action:None

Platforms and Profiles Functionality verified: NONE
Platform: android-icecream-sandwitch-arm-omap40xx_blaze
Profile: helix-client-android-full 


Index: mkv_file_format.cpp
===================================================================
RCS file: /cvsroot/datatype/mkv/fileformat/mkv_file_format.cpp,v
retrieving revision 1.11.2.21.2.4
retrieving revision 1.11.2.21.2.5
diff -u -d -r1.11.2.21.2.4 -r1.11.2.21.2.5
--- mkv_file_format.cpp	13 Jul 2012 06:46:18 -0000	1.11.2.21.2.4
+++ mkv_file_format.cpp	19 Jul 2012 08:14:42 -0000	1.11.2.21.2.5
@@ -75,6 +75,7 @@
 #define MKV_AAC3_MIMETYPE "A_AC3"
 #define MKV_EAC3_MIMETYPE "A_EAC3"
 #define MKV_DTS_MIMETYPE "A_DTS"
+#define MKV_MP3_MIMETYPE "A_MPEG/L3"
 #define MKV_DTS_EXPRESS_MIMETYPE "A_DTS/EXPRESS"
 #define MKV_DTS_LOSSLESS_MIMETYPE "A_DTS/LOSSLESS"
 #define HELIX_AAC_MIMETYPE "audio/X-HX-AAC-GENERIC"
@@ -123,8 +124,8 @@
 //	{ "A_MPEG/L3", "audio/mp3"},
 	{ "A_MPEG/L2", "audio/MPEG-ELEMENTARY"},
 	{ "A_MPEG/L3", "audio/MPEG-ELEMENTARY"},
-        { "A_VORBIS",  "application/ogg"},
-        { "A_MS/ACM",  "audio/ms-adpcm"},
+    { "A_VORBIS",  "application/ogg"},
+    { "A_MS/ACM",  "audio/ms-adpcm"},
 
 	//DTS Codecs
     { "A_DTS", "audio/dts"},
@@ -195,11 +196,20 @@
     2560,	2788,	3840,
 };
 
+const UINT32 uMPEGSampleRateTbl [3][4] =
+{
+  //MPEG2.5     MPEG2   MPEG1
+    11025,  0,  22050,  44100,
+    12000,  0,  24000,  48000,
+    8000,   0,  16000,  32000,
+};
+
 CMKVFileFormat::CMKVFileFormat():m_lRefCount(0), m_pContext(NULL), \
                m_pCommonClassFactory(NULL),
                                  m_pRequest(NULL), m_pFormatResponse(NULL), \
                m_pScheduler(NULL),
                                  m_pGetPacketReqQ(NULL), m_pMKVFileObject(NULL), \
                m_pMKVHandle(NULL), 
                                  \
m_ulAdjustedPresentationVideoTime(0),m_ulRTPTimeScale(DEFAULT_RTP_SAMPLES),m_bPostSeekKeyFrame(FALSE),
                
-                                 m_bResetPresentationTime(TRUE), \
m_ulTimeCodeOfLastBlock(0),m_ulminimumBlockDuration(0),m_uFrameReferenceCount(0),m_bStreamDone(FALSE),m_bIsXVID(FALSE),m_bSwapSamples(FALSE)
 +                                 m_bResetPresentationTime(TRUE), \
m_ulTimeCodeOfLastBlock(0),m_ulminimumBlockDuration(0),m_uFrameReferenceCount(0),m_bStreamDone(FALSE),m_bIsXVID(FALSE),m_bSwapSamples(FALSE),
 +                                 m_ulAudioPreloadedPacketCount(0), \
m_ulVideoPreloadedPacketCount(0)  {
 	HXLOGL3(HXLOG_MKVF, "Construct CMKVFileFormat this=%p", this);
 }
@@ -433,6 +443,15 @@
 
 	if (trk)
 	{
+        if(trk->type == TrackAudio) 
+        {
+            m_ulAudioPreloadedPacketCount = 4;
+        }
+        else if (trk->type == TrackVideo) 
+        {
+            m_ulVideoPreloadedPacketCount = 2;
+        }
+
 		// Create an IHXValues header
 		IHXValues* pHdr = NULL;
 		retVal = CreateValuesCCF(pHdr, m_pContext);
@@ -585,9 +604,12 @@
 
 	if(m_pGetPacketReqQ)
 	{
-		GetPacketInfo *req = new GetPacketInfo(unStreamNumber);
-		m_pGetPacketReqQ->AddTail((void *)req);
-		retVal = m_pScheduler->RelativeEnter(this, 0);
+        if (!m_bStreamDone) 
+        {
+            GetPacketInfo *req = new GetPacketInfo(unStreamNumber);
+            m_pGetPacketReqQ->AddTail((void *)req);
+            retVal = m_pScheduler->RelativeEnter(this, 0);
+        }
 	}
 
 	return (retVal) ? HXR_OK : HXR_FAIL;
@@ -649,75 +671,195 @@
 
 HX_RESULT CMKVFileFormat::FormAAC3AudioPacket(REF(IHXPacket*) packet,UINT32 \
strNum,UINT64 uTimeCode,HXBOOL bKey,MKVTrack *track,IHXBuffer* pBuffer)  {
-    HX_RESULT retVal = HXR_OK;
-    IHXBuffer *pAudioBuffer = NULL;
+    const UCHAR * pSrcData     = pBuffer->GetBuffer();
+    UINT32        nSrcDataSize = pBuffer->GetSize();
+    int   uFrameInfoByteOffset = (int)track->uPaddingOffset + 4 - \
track->uContentCompressSetting;  UINT8 uFrameInfoByte=0;
-    if(pBuffer->GetSize()>=2)
+    if(uFrameInfoByteOffset >= 0 && nSrcDataSize > uFrameInfoByteOffset)
     {
-        uFrameInfoByte = *(pBuffer->GetBuffer()+2);
+        uFrameInfoByte = pSrcData[uFrameInfoByteOffset];
     }
     else
     {
-        retVal=HXR_FAILED;
         HXLOGL1(HXLOG_MKVF, "CMKVFileFormat::FormAAC3AudioPacket Failed \
                pBuffer->Getsize() < =2 \n");
-        return retVal;
+        return HXR_FAILED;
     }
-    UINT8 uFameSizeCode = uFrameInfoByte & 0x3f;
+    UINT8 uFameSizeCode   = uFrameInfoByte & 0x3f;
     UINT8 uSampleRateCode = uFrameInfoByte >> 6; 
     UINT32 uFrameLen=1;
-    UINT32 index=0;
-    UINT32 offset=0,payloadoffset=0;
-    UINT32 uNumberofsyncword=0;
     HXLOGL1(HXLOG_MKVF, "CMKVFileFormat::FormAudioPacket uFameSizeCode %d, \
uSampleRateCode %d \n",uFameSizeCode, uSampleRateCode);  if ( uFameSizeCode < 38 && \
uSampleRateCode < 3 )  {
-	    uFrameLen = uDDFrameSizetTbl[uFameSizeCode][uSampleRateCode];
+        uFrameLen = uDDFrameSizetTbl[uFameSizeCode][uSampleRateCode];
     }
-    if( uFrameLen > track->uContentCompressSetting)
+    return FormHeaderStrippingAudioPacket(packet, strNum, uTimeCode, bKey, track, \
pSrcData, nSrcDataSize, uFrameLen); +}
+
+HX_RESULT CMKVFileFormat::FormDTSAudioPacket(REF(IHXPacket*) packet,UINT32 \
strNum,UINT64 uTimeCode,HXBOOL bKey,MKVTrack *track,IHXBuffer* pBuffer) +{
+    const UCHAR * pSrcData     = pBuffer->GetBuffer();
+    UINT32        nSrcDataSize = pBuffer->GetSize();
+    int    uFrameSizeOffset = (int)track->uPaddingOffset + 5 - \
track->uContentCompressSetting; +    UINT32 uFrameSize       = 1;
+    if(uFrameSizeOffset >= 0 && nSrcDataSize > uFrameSizeOffset + 2)
     {
-        uNumberofsyncword= (pBuffer->GetSize())/(uFrameLen - \
                track->uContentCompressSetting);
-        offset=( (pBuffer->GetSize()) % (uFrameLen - \
track->uContentCompressSetting)); +        uFrameSize += ( \
(UINT32)(pSrcData[uFrameSizeOffset    ] & 0x03) << 12 ) | +                      ( \
(UINT32)(pSrcData[uFrameSizeOffset + 1]       ) << 4  ) | +                      ( \
(UINT32)(pSrcData[uFrameSizeOffset + 2] & 0xF0) >> 4  );  }
     else
     {
-        retVal=HXR_FAILED;
-        HXLOGL1(HXLOG_MKVF, "CMKVFileFormat::FormAAC3AudioPacket Failed uFrameLen <  \
track->uContentCompressSetting :%d < %d \
                \n",uFrameLen,track->uContentCompressSetting);
-        return retVal;
+        HXLOGL1(HXLOG_MKVF, "CMKVFileFormat::FormDTSAudioPacket Failed \
pBuffer->Getsize() < =2 \n"); +        return HXR_FAILED;
     }
-    if(track->uPaddingOffset == 0)
+
+    return FormHeaderStrippingAudioPacket(packet, strNum, uTimeCode, bKey, track, \
pSrcData, nSrcDataSize, uFrameSize); +}
+
+HX_RESULT CMKVFileFormat::FormMP3AudioPacket(REF(IHXPacket*) packet,UINT32 \
strNum,UINT64 uTimeCode,HXBOOL bKey,MKVTrack *track,IHXBuffer* pBuffer) +{
+    const UCHAR * pSrcData     = pBuffer->GetBuffer();
+    UINT32        nSrcDataSize = pBuffer->GetSize();
+    int    uFrameSizeOffset = (int)track->uPaddingOffset + 1 - \
track->uContentCompressSetting; +    UINT32 uFrameSize       = 1;
+    if(uFrameSizeOffset >= 0 && nSrcDataSize > uFrameSizeOffset + 2)
     {
-        payloadoffset = 0;
+        UINT8 mpeg_version    = (pSrcData[uFrameSizeOffset    ] & 0x18) >> 3;
+        UINT8 layer_number    = (pSrcData[uFrameSizeOffset    ] & 0x06) >> 1;
+        UINT8 bitrate_idx     = (pSrcData[uFrameSizeOffset + 1] & 0xF0) >> 4;
+        UINT8 sample_rate_idx = (pSrcData[uFrameSizeOffset + 1] & 0x0C) >> 2;
+        UINT8 padding         = (pSrcData[uFrameSizeOffset + 1] & 0x02) >> 1;
+
+        if ( 0x01 != layer_number ) {
+            HXLOGL1(HXLOG_MKVF, "CMKVFileFormat::FormMP3AudioPacket Failed not layer \
III \n"); +            return HXR_FAILED;
+        }
+
+        if ( 0x0F == bitrate_idx ) {
+            HXLOGL1(HXLOG_MKVF, "CMKVFileFormat::FormMP3AudioPacket Failed bitrate \
not supported \n"); +            return HXR_FAILED;
+        }
+
+        static UINT32 uBitRateTbl[2][15] = { 
+            // mpeg version 2.5(0x00) or 2(0x02)
+            { 0, 8,  16, 24, 32, 40, 48, 56, 64,  80,  96,  112, 128, 144, 160},
+            // mpeg version 1(0x03)
+            { 0, 32, 40, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320},
+        };
+
+        UINT8  br_idx      = (mpeg_version == 0x03) ? 1 : 0;
+        UINT32 bitrate     = uBitRateTbl[br_idx][bitrate_idx];
+        UINT32 sample_rate = uMPEGSampleRateTbl[sample_rate_idx][mpeg_version];
+        uFrameSize         = 144000 * bitrate / sample_rate + padding;
     }
     else
     {
-        payloadoffset=track->uPaddingOffset;
+        HXLOGL1(HXLOG_MKVF, "CMKVFileFormat::FormDTSAudioPacket Failed \
pBuffer->Getsize() < =2 \n"); +        return HXR_FAILED;
     }
-    if(FAILED(CreateSizedBufferCCF(pAudioBuffer, m_pContext,((uNumberofsyncword + 1) \
*track->uContentCompressSetting )+pBuffer->GetSize()))) +
+    return FormHeaderStrippingAudioPacket(packet, strNum, uTimeCode, bKey, track, \
pSrcData, nSrcDataSize, uFrameSize); +}
+
+HX_RESULT CMKVFileFormat::FormHeaderStrippingAudioPacket(REF(IHXPacket*) \
packet,UINT32 strNum,UINT64 uTimeCode,HXBOOL bKey,MKVTrack *track,const UCHAR \
*pSrcData,UINT32 nSrcDataSize,UINT32 uFrameSize) +{
+    const UCHAR * pRecentRemainedData     = pSrcData;
+    UINT32        nRecentRemainedDataSize = track->uPaddingOffset;
+    if (nRecentRemainedDataSize)
+    {
+        pSrcData     += nRecentRemainedDataSize;
+        nSrcDataSize -= nRecentRemainedDataSize;
+        track->uPaddingOffset = 0;
+    }
+    int nCompressedFrameSize = (int)(uFrameSize - track->uContentCompressSetting);
+    UINT32 uNumberofsyncword = 0, nRemainedSize = 0;
+    if (nCompressedFrameSize > 0)
+    {
+        uNumberofsyncword = nSrcDataSize / nCompressedFrameSize;
+        nRemainedSize     = nSrcDataSize % nCompressedFrameSize;
+    }
+    else
+    {
+        HXLOGL1(HXLOG_MKVF, "CMKVFileFormat::FormHeaderStrippingAudioPacket Failed \
uFrameSize <  track->uContentCompressSetting :%d < %d \
\n",uFrameSize,track->uContentCompressSetting); +        return HXR_FAILED;
+    }
+
+    UINT32 nNewBufSize = uNumberofsyncword * track->uContentCompressSetting +
+        nRecentRemainedDataSize + nSrcDataSize;
+    if (nRemainedSize)
+        nNewBufSize += track->uContentCompressSetting;
+    IHXBuffer *pAudioBuffer = NULL;
+    if(  FAILED( CreateSizedBufferCCF(pAudioBuffer, m_pContext,nNewBufSize) )  )
     {
         return HXR_OUTOFMEMORY;
     }
-    UCHAR* pData=pAudioBuffer->GetBuffer();
-    while(index < uNumberofsyncword &&	payloadoffset <= ( pBuffer->GetSize()- \
offset)) +
+    UCHAR* pData = pAudioBuffer->GetBuffer();
+    if (nRecentRemainedDataSize)
     {
-        memcpy(pData+track->uPaddingOffset,track->pContentCompressSetting,track->uContentCompressSetting);
                
-        pData +=(track->uContentCompressSetting + track->uPaddingOffset);
-        memcpy((pData),(pBuffer->GetBuffer()+(index*(uFrameLen - \
                track->uContentCompressSetting))),(uFrameLen - \
                track->uContentCompressSetting));
-        pData +=(uFrameLen - track->uContentCompressSetting);
-        index++;
-        payloadoffset += (uFrameLen - track->uContentCompressSetting);
+        memcpy(pData, pRecentRemainedData, nRecentRemainedDataSize);
+        pData += nRecentRemainedDataSize;
     }
-    if(offset)
+    for(UINT32 i = 0; i < uNumberofsyncword; ++i)
     {
-        track->uPaddingOffset=uFrameLen-offset;
-        memcpy(pData,track->pContentCompressSetting,track->uContentCompressSetting);
-        pData +=track->uContentCompressSetting;
-        memcpy(pData,(pBuffer->GetBuffer()+payloadoffset),offset);
+        memcpy(pData, track->pContentCompressSetting, \
track->uContentCompressSetting); +        pData += track->uContentCompressSetting;
+        memcpy(pData, pSrcData, nCompressedFrameSize);
+        pData    += nCompressedFrameSize;
+        pSrcData += nCompressedFrameSize;
     }
-    retVal = CreatePacket(packet,strNum,pAudioBuffer,uTimeCode,uTimeCode,bKey);
+    if(nRemainedSize)
+    {
+        track->uPaddingOffset = nCompressedFrameSize - nRemainedSize; // we will \
form the packet from the padding offset in the next time. +        memcpy(pData, \
track->pContentCompressSetting, track->uContentCompressSetting); +        pData += \
track->uContentCompressSetting; +        memcpy(pData, pSrcData, nRemainedSize);
+    }
+    HX_RESULT retVal = \
CreatePacket(packet,strNum,pAudioBuffer,uTimeCode,uTimeCode,bKey);  \
HX_RELEASE(pAudioBuffer);  return retVal;
 }
 
+HX_RESULT CMKVFileFormat::FormVideoPacket(REF(IHXPacket*) pPacket,UINT32 strNum, \
IHXBuffer* pBuffer, UINT64 uTimeCode,UINT64 decodingTime, HXBOOL bKey,MKVTrack \
*track) +{
+
+    HX_RESULT retVal = HXR_OK;
+    if((track == NULL) || (pBuffer == NULL))
+    {
+        retVal=HXR_FAILED;
+        HXLOGL1(HXLOG_MKVF, "CMKVFileFormat::FormAudioPacket Failed track == NULL \
\n"); +        return retVal;
+    }
+
+
+	IHXBuffer* pBufferVideo=NULL;
+	
+	switch(track->eCompressionType)
+	{
+		case eHEADERSTRIPING:
+		{
+			// Header Stripping 
+		    if(FAILED(CreateSizedBufferCCF(pBufferVideo, \
m_pContext,track->uContentCompressSetting +pBuffer->GetSize()))) +		    {
+		    	
+			    HXLOGL1(HXLOG_MKVF, "CMKVFileFormat::FormAudioPacket Failed track == NULL \
\n"); +		        return HXR_OUTOFMEMORY;
+		    }
+			
+			UCHAR* pData=pBufferVideo->GetBuffer();
+			memcpy(pData,track->pContentCompressSetting,track->uContentCompressSetting);
+			memcpy(pData+track->uContentCompressSetting,pBuffer->GetBuffer(),pBuffer->GetSize());
 +			retVal =CreatePacket(pPacket,strNum,pBufferVideo,uTimeCode,decodingTime,bKey);
+			HX_RELEASE(pBufferVideo);
+		}
+		break;
+
+		default:	
+		    retVal = CreatePacket(pPacket,strNum,pBuffer,uTimeCode,decodingTime,bKey);
+		break;
+	}
+	return retVal;
+}
 HX_RESULT CMKVFileFormat::FormAudioPacket(REF(IHXPacket*) packet,UINT32 \
strNum,UINT64 uTimeCode,HXBOOL bKey,MKVTrack *track,IHXBuffer* pBuffer)  {
     HX_RESULT retVal = HXR_OK;
@@ -735,6 +877,14 @@
 			{
 				retVal=FormAAC3AudioPacket(packet,strNum,uTimeCode,bKey,track,pBuffer);
 			}
+			else if((0 == strncmp(track->pszCodec, MKV_DTS_MIMETYPE, \
sizeof(MKV_DTS_MIMETYPE)-1)))// Header Stripping only for dts +			{
+				retVal=FormDTSAudioPacket(packet,strNum,uTimeCode,bKey,track,pBuffer);
+			}
+			else if((0 == strncmp(track->pszCodec, MKV_MP3_MIMETYPE, \
sizeof(MKV_MP3_MIMETYPE)-1)))// Header Stripping only for mp3 +			{
+				retVal=FormMP3AudioPacket(packet,strNum,uTimeCode,bKey,track,pBuffer);
+			}
 			else
 			{
                 //Not Implemented for other audio format.
@@ -761,154 +911,181 @@
 //SendPacket
 STDMETHODIMP CMKVFileFormat::Func()
 {
-	HX_RESULT retVal = HXR_FAIL;
+    HX_RESULT retVal = HXR_OK;
 
-	if(m_pGetPacketReqQ)
-	{
-		if(!m_pGetPacketReqQ->IsEmpty())
-		{
-			GetPacketInfo *req = (GetPacketInfo *) m_pGetPacketReqQ->RemoveHead();
-			retVal = SendpacketFromQ(req->m_uStreamNum);
-			if(!m_bStreamDone &&(retVal == HXR_NO_DATA))
-			{
-				IHXPacket* pPacket = NULL;
-				IHXBuffer *pBuffer = NULL;
-				MKVTrack* reqTrk = m_pMKVHandle->GetTrack(req->m_uStreamNum);
+    if (m_bStreamDone) 
+    {
+        return HXR_NO_DATA;
+    }
 
-				UINT32 nCachedPacketCount = m_pMKVHandle->GetCachedPacketCount();
-				while (SUCCEEDED(retVal) && nCachedPacketCount < TOTAL_PACKET_COUNT) 
-				{
-					if(FAILED(CreateBufferCCF(pBuffer, m_pContext)))
-					{
-						return HXR_OUTOFMEMORY;
-					}
+    IHXPacket* pPacket = NULL;
+    IHXBuffer* pBuffer = NULL;
 
-					UINT32 strNum;
-					UINT64 uTimeCode;
-					HXBOOL bKey;
+    UINT32 nAudioCachedPacketCount = m_pMKVHandle->GetCachedPacketCount(TrackAudio);
+    UINT32 nVideoCachedPacketCount = m_pMKVHandle->GetCachedPacketCount(TrackVideo);
 
-					UINT64 ulAdjustedPresentationTime = 0;
-					UINT64 blockDuration = 0;
 
-					retVal = m_pMKVHandle->GetPacket(strNum, pBuffer, uTimeCode, \
                bKey,blockDuration);
-    
-					if(retVal == HXR_NO_DATA)
-					{
-						HX_RELEASE(pBuffer);
-						if (m_pMKVFileObject->GetLastError() == HXR_READ_ERROR)
-						{
-						      HXLOGL2(HXLOG_MKVF, "CMKVFileFormat::Func() Read error on stream %d", \
                (UINT16)req->m_uStreamNum);                                       
-						      m_pFormatResponse->PacketReady(HXR_READ_ERROR, NULL);
-						} 
-					        m_bStreamDone = TRUE;
-						break;
-					}
-					else if(SUCCEEDED(retVal))
-					{
-						//insert in track queue
-						MKVTrack* trk = m_pMKVHandle->GetTrack(strNum);
-						if(trk)
-						{
-							if(trk->type == TrackVideo)
-							{                
-								if(m_bResetPresentationTime)
-								{   
-									// For first packet or after seek this may be case
-									m_ulAdjustedPresentationVideoTime = uTimeCode;
-									m_ulTimeCodeOfLastBlock = uTimeCode;
-									m_bResetPresentationTime = FALSE;
-								}
-								// $BLOCKDURATION is zero means it is not present so we should use the \
                $DEFAULTDURATION
-								// if $DEFAULTDURATION is zero it means duration of frames of track may not \
                be constant
-								// If both $BLOCKDURATION and $DEFAULTDURATION is zero then, frame duration \
                should be computed as 
-								// difference of timecode of next block of same stream
-								if(trk->uDefaultDuration != 0)
-								{
-									blockDuration = trk->uDefaultDuration/CONVERT_TO_MILI_SECOND;
-								}
-								else
-								{
-									// If B-Frame are present uTimeCode is less than m_ulTimeCodeOfLastBlock
-									// as there is no way to know in advance so remember last one
-									if(m_uFrameReferenceCount < MKV_BFRAME_MAXIMUMDEPTH )
-									{
-										blockDuration = MKV_ABSVAL(uTimeCode - m_ulTimeCodeOfLastBlock);
-										m_ulminimumBlockDuration=HX_MIN(m_ulminimumBlockDuration,blockDuration);
-										if(m_ulminimumBlockDuration == 0)
-										{
-											m_ulminimumBlockDuration = blockDuration;
-										}
-										m_uFrameReferenceCount++;
-									}
-									blockDuration = m_ulminimumBlockDuration;
-								}
-                                
-								ulAdjustedPresentationTime = m_ulAdjustedPresentationVideoTime;
-								m_ulAdjustedPresentationVideoTime += blockDuration;
-								m_ulTimeCodeOfLastBlock = uTimeCode;
-                                
-								retVal = CreatePacket(pPacket,strNum,pBuffer,uTimeCode,ulAdjustedPresentationTime,bKey);
                
-							}
-							else if(trk->type == TrackAudio)
-							{
-								// If this is L16 PCM data, always convert 
-								// it to net endian (big endian) format
-								if (m_bSwapSamples)
-								{
-								    UCHAR* pSampleBuf = pBuffer->GetBuffer();
-								    SwapWordBytes((UINT16 *)pSampleBuf, pBuffer->GetSize() / 2);
-								}
-								retVal=FormAudioPacket(pPacket,strNum,uTimeCode,bKey,trk,pBuffer);
-							}
+    while (SUCCEEDED(retVal)&&(nAudioCachedPacketCount<m_ulAudioPreloadedPacketCount||nVideoCachedPacketCount<m_ulVideoPreloadedPacketCount))
 +    {
+        if(FAILED(CreateBufferCCF(pBuffer, m_pContext)))
+        {
+            return HXR_OUTOFMEMORY;
+        }
+
+        UINT32 strNum;
+        UINT64 uTimeCode;
+        HXBOOL bKey;
+
+        UINT64 ulAdjustedPresentationTime = 0;
+        UINT64 blockDuration = 0;
+
+        retVal = m_pMKVHandle->GetPacket(strNum, pBuffer, uTimeCode, \
bKey,blockDuration); +
+        if(retVal == HXR_NO_DATA)
+        {
+            HX_RELEASE(pBuffer);
+            if (m_pMKVFileObject->GetLastError() == HXR_READ_ERROR)
+            {
+                  HXLOGL2(HXLOG_MKVF, "CMKVFileFormat::Func() Read error");
+                  m_pFormatResponse->PacketReady(HXR_READ_ERROR, NULL);
+            } 
+            m_bStreamDone = TRUE;
+            break;
+        }
+        else if(SUCCEEDED(retVal))
+        {
+            //insert in track queue
+            MKVTrack* trk = m_pMKVHandle->GetTrack(strNum);
+            if(trk)
+            {
+                if(trk->type == TrackVideo)
+                {                
+                    if(m_bResetPresentationTime)
+                    {   
+                        // For first packet or after seek this may be case
+                        m_ulAdjustedPresentationVideoTime = uTimeCode;
+                        m_ulTimeCodeOfLastBlock = uTimeCode;
+                        m_bResetPresentationTime = FALSE;
+                    }
+                    // $BLOCKDURATION is zero means it is not present so we should \
use the $DEFAULTDURATION +                    // if $DEFAULTDURATION is zero it means \
duration of frames of track may not be constant +                    // If both \
$BLOCKDURATION and $DEFAULTDURATION is zero then, frame duration should be computed \
as  +                    // difference of timecode of next block of same stream
+                    if(trk->uDefaultDuration != 0)
+                    {
+                        blockDuration = \
trk->uDefaultDuration/CONVERT_TO_MILI_SECOND; +                    }
+                    else
+                    {
+                        // If B-Frame are present uTimeCode is less than \
m_ulTimeCodeOfLastBlock +                        // as there is no way to know in \
advance so remember last one +                        if(m_uFrameReferenceCount < \
MKV_BFRAME_MAXIMUMDEPTH ) +                        {
+                            blockDuration = MKV_ABSVAL(uTimeCode - \
m_ulTimeCodeOfLastBlock); +                            \
m_ulminimumBlockDuration=HX_MIN(m_ulminimumBlockDuration,blockDuration); +            \
if(m_ulminimumBlockDuration == 0) +                            {
+                                m_ulminimumBlockDuration = blockDuration;
+                            }
+                            m_uFrameReferenceCount++;
+                        }
+                        blockDuration = m_ulminimumBlockDuration;
+                    }
+                    
+                    ulAdjustedPresentationTime = m_ulAdjustedPresentationVideoTime;
+                    m_ulAdjustedPresentationVideoTime += blockDuration;
+                    m_ulTimeCodeOfLastBlock = uTimeCode;
+                    
+                    \
retVal=FormVideoPacket(pPacket,strNum,pBuffer,uTimeCode,ulAdjustedPresentationTime,bKey,trk);
 +                }
+                else if(trk->type == TrackAudio)
+                {
+                    // If this is L16 PCM data, always convert 
+                    // it to net endian (big endian) format
+                    if (m_bSwapSamples)
+                    {
+                        UCHAR* pSampleBuf = pBuffer->GetBuffer();
+                        SwapWordBytes((UINT16 *)pSampleBuf, pBuffer->GetSize() / 2);
+                    }
+                    \
retVal=FormAudioPacket(pPacket,strNum,uTimeCode,bKey,trk,pBuffer); +                }
 #ifdef HELIX_FEATURE_EMBEDED_SUBTITLE
-							else if(trk->type == TrackText)
-							{
-								retVal = CreatePacket(pPacket,strNum,pBuffer,uTimeCode,uTimeCode,bKey);
-							}
+                else if(trk->type == TrackText)
+                {
+                    retVal = \
CreatePacket(pPacket,strNum,pBuffer,uTimeCode,uTimeCode,bKey); +                }
 #endif							
-							if(FAILED(retVal))
-							{
-								HX_RELEASE(pBuffer);
-								HX_RELEASE(pPacket);
-								return retVal;
-							}
-						}
-						// Set the packet data
+                if(FAILED(retVal))
+                {
+                    HX_RELEASE(pBuffer);
+                    HX_RELEASE(pPacket);
+                    return retVal;
+                }
+            }
+            // Set the packet data
 
-						HX_RELEASE(pBuffer);
-						if(SUCCEEDED(retVal) && trk)
-						{
-							trk->PushPacket(pPacket);
-							if (trk->bEnabled) ++nCachedPacketCount;
-						}
-						HX_RELEASE(pPacket);
-					}
-				}
+            HX_RELEASE(pBuffer);
+            if(SUCCEEDED(retVal) && trk)
+            {
+                trk->PushPacket(pPacket);
+                if (trk->bEnabled) 
+                {
+                    if (trk->type == TrackAudio)
+                        ++nAudioCachedPacketCount;
+                    else if (trk->type == TrackVideo)
+                        ++nVideoCachedPacketCount;
+                }
+            }
+            HX_RELEASE(pPacket);
+        }
+    }
 
-				if ( reqTrk && reqTrk->vQueue.size() )
-				{
-					retVal = SendpacketFromQ(req->m_uStreamNum);
-					delete req;
-				}
-				else
-				{
-					if(m_pGetPacketReqQ->GetCount() > 1 && reqTrk && reqTrk->type == TrackAudio)
-					{
-						CHXSimpleList::Iterator itrFirst = m_pGetPacketReqQ->Begin();
-						m_pGetPacketReqQ->InsertAfter(itrFirst, (void *)req);
-					}
-					else
-					{
-						m_pGetPacketReqQ->AddTail( (void *)req );
-					}
-					m_pScheduler->RelativeEnter(this, 0);
-					retVal = HXR_NO_DATA;
-				}
-			}
-		}
-	}
+	if(m_pGetPacketReqQ)
+	{
+		if(!m_pGetPacketReqQ->IsEmpty())
+        {
+            CHXSimpleList* pReqQ = new CHXSimpleList();
+            while (!m_pGetPacketReqQ->IsEmpty()) 
+            {
+                GetPacketInfo *req = (GetPacketInfo *) \
m_pGetPacketReqQ->RemoveHead(); +                MKVTrack* reqTrk = \
m_pMKVHandle->GetTrack(req->m_uStreamNum); +                if ( reqTrk && \
reqTrk->vQueue.size() ) +                {
+                    retVal = SendpacketFromQ(req->m_uStreamNum);
+                    // if no key frame found, retVal could be HXR_NO_DATA
+                    // in that case we need to keep the request.
+                    if(retVal == HXR_NO_DATA) 
+                    {
+                        pReqQ->AddTail( (void *)req );
+                        m_pScheduler->RelativeEnter(this, 0);
+                    }
+                    else {
+                        delete req;
+                    }
+                }
+                else
+                {
+                    // For subtitle stream, if streamdone, we need to update top \
layer. +                    if(m_bStreamDone) 
+                    {
+                        m_pFormatResponse->StreamDone(req->m_uStreamNum);
+                        retVal = HXR_OK;
+                        delete req;
+                    }
+                    else {
+                        pReqQ->AddTail( (void *)req );
+                        //m_pScheduler->RelativeEnter(this, 10);
+                        retVal = HXR_NO_DATA;
+                    }
+                }
+            }
 
-	return retVal;
+            HX_DELETE(m_pGetPacketReqQ);
+            m_pGetPacketReqQ = pReqQ;
+        }
+    }
+
+    return retVal;
 }
 
 HX_RESULT CMKVFileFormat::SendpacketFromQ(UINT16 unStreamNumber)
@@ -919,7 +1096,7 @@
 	
 	if(trk)
 	{
-                IHXPacket* pPacket = trk->GetPacket();
+        IHXPacket* pPacket = trk->GetPacket();
 
 		if(pPacket)
 		{
@@ -932,15 +1109,34 @@
                 		}   
                 		else
                 		{   
-                    			retVal = SendpacketFromQ(unStreamNumber);
-                    			if(retVal == HXR_NO_DATA)
-                    			{   
-                        			retVal = ReadPacket(unStreamNumber);
-                        			if(!SUCCEEDED(retVal))
-                        			{   
-                            				m_pFormatResponse->PacketReady(HXR_READ_ERROR,NULL);
-                        			}   
-                    			}   
+                            // loop until we find a key frame or no packet left
+                            while ( 1 ) 
+                            {
+                                HX_RELEASE(pPacket);
+                                pPacket = trk->GetPacket();
+                                if (!pPacket) 
+                                {
+                                    if(m_bStreamDone) 
+                                    {
+                                        \
m_pFormatResponse->StreamDone(unStreamNumber); +                                      \
retVal = HXR_OK; +                                    }
+                                    else 
+                                    {
+                                        retVal = HXR_NO_DATA;
+                                    }
+                                    return retVal;
+                                }
+                                else 
+                                {
+                                    if( pPacket->GetASMFlags() & HX_ASM_SWITCH_ON ) 
+                                    {
+                                        retVal = \
m_pFormatResponse->PacketReady(HXR_OK, pPacket); +                                    \
m_bPostSeekKeyFrame = FALSE; +                                        break;
+                                    }
+                                }
+                            }
                  		}   
             		}   
             		else 
@@ -977,6 +1173,18 @@
 			m_pFormatResponse->PacketReady(HXR_READ_ERROR,NULL);
 		}
 	}
+    else {
+        // try to preload
+        if (!m_bStreamDone) 
+        {
+            UINT32 ulHandle = m_pScheduler->RelativeEnter(this, 0);
+            retVal = (ulHandle) ? HXR_OK : HXR_FAIL;
+            if ( SUCCEEDED(retVal) ) 
+            {
+                m_pFormatResponse->PacketReady(HXR_READ_ERROR,NULL);
+            }
+        }
+    }
 
 	return retVal;
 }
@@ -1019,7 +1227,10 @@
 	}
 	//Get the right framekey
 	ulOffset = m_pMKVHandle->GetKeyFrame(ulOffset);
-	m_bPostSeekKeyFrame = TRUE;
+    if (m_pMKVHandle->HasVideo())
+    {
+        m_bPostSeekKeyFrame = TRUE;
+    }
 	HX_RESULT retVal = m_pMKVHandle->Seek(ulOffset, strNum, pBuffer,uTimeCode, bKey);
 
 	if(retVal == HXR_NO_DATA)
@@ -1034,18 +1245,24 @@
 
 		MKVTrack* trk = m_pMKVHandle->GetTrack(strNum);
 		if(trk)
-		{            
-				retVal = CreatePacket(pPacket,strNum,pBuffer,uTimeCode,m_ulAdjustedPresentationVideoTime,bKey);
                
-				if(SUCCEEDED(retVal))
-				{
-					trk->PushPacket(pPacket);
-				}
-				HX_RELEASE(pPacket);
-		}
-		else
 		{
-				HX_RELEASE(pPacket);
+			switch (trk->type)
+			{
+			case TrackVideo:
+				retVal = FormVideoPacket(pPacket, strNum, pBuffer, uTimeCode, \
m_ulAdjustedPresentationVideoTime, bKey, trk); +				break;
+			case TrackAudio:
+				retVal = FormAudioPacket(pPacket,strNum,uTimeCode,bKey,trk,pBuffer);
+				break;
+			default:
+				retVal = CreatePacket(pPacket,strNum,pBuffer,uTimeCode,m_ulAdjustedPresentationVideoTime,bKey);
 +			}
+			if(SUCCEEDED(retVal))
+			{
+				trk->PushPacket(pPacket);
+			}
 		}
+		HX_RELEASE(pPacket);
 	}
 
 	m_pFormatResponse->SeekDone(retVal);
@@ -1115,11 +1332,12 @@
 		uint32 bits = trk->audio.uBitspersample;
 		if(!strncmp(trk->pszCodec, MKV_AAC3_MIMETYPE, strlen(MKV_AAC3_MIMETYPE)) || \
!strncmp(trk->pszCodec, MKV_EAC3_MIMETYPE, strlen(MKV_EAC3_MIMETYPE)))  {
-		    if(bits == 0)
-		    {			    
-		        bits = 16;
-		    }
+		    bits = 16;
 		}
+        else if(bits == 0)
+        {
+            bits = 16;
+        }
 		
 		pHdr->SetPropertyULONG32("Channels",  chan);
 		pHdr->SetPropertyULONG32("BitsPerSample",   bits);


_______________________________________________
Datatype-cvs mailing list
Datatype-cvs@helixcommunity.org
http://lists.helixcommunity.org/mailman/listinfo/datatype-cvs


[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic