[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