[prev in list] [next in list] [prev in thread] [next in thread]
List: helix-datatype-cvs
Subject: [Datatype-cvs] wm/fileformat asf_file_format_file.cpp, 1.10.2.11,
From: zlin () helixcommunity ! org
Date: 2011-03-30 10:15:32
Message-ID: 201103301015.p2UAFJAQ020028 () mailer ! progressive-comp ! com
[Download RAW message or body]
Update of /cvsroot/datatype/wm/fileformat
In directory cvs01.internal.helixcommunity.org:/tmp/cvs-serv27172
Modified Files:
Tag: hxclient_3_6_5_atlas
asf_file_format_file.cpp
Log Message:
Fix for 12505
Bug Number: 12727
Bug URL: https://bugs.helixcommunity.org/show_bug.cgi?id=12727
Synopsis: when scaning this wmv video for thumbnail, lead the system to block and pop \
up a dialog box show that the system is scanning video file.
Overview: For some buggy wmv file, the index object in the tail of file is broken, so \
when trying to get the index object, Helix client will drop into a loop forever. This \
fix is to break this forever loop when the calced object type is unknown and object \
size is 0.
Files Modified:
asf_file_format_file.cpp
Index: asf_file_format_file.cpp
===================================================================
RCS file: /cvsroot/datatype/wm/fileformat/asf_file_format_file.cpp,v
retrieving revision 1.10.2.11
retrieving revision 1.10.2.11.14.1
diff -u -d -r1.10.2.11 -r1.10.2.11.14.1
--- asf_file_format_file.cpp 19 Feb 2010 19:08:23 -0000 1.10.2.11
+++ asf_file_format_file.cpp 30 Mar 2011 10:15:29 -0000 1.10.2.11.14.1
@@ -558,6 +558,52 @@
return retVal;
}
+HX_RESULT
+CASFFileFormatFile::BuildIndexDone()
+{
+ m_ulState = kStateSeekStartIndexBuildDonePending;
+ m_ulSeekOffsetRequested = m_ulFirstASFPacketFileOffset;
+ return m_pFileObject->Seek(m_ulFirstASFPacketFileOffset, FALSE);
+}
+
+
+HX_RESULT
+CASFFileFormatFile::BuildIndex()
+{
+ HX_RESULT retVal = HXR_FAIL;
+ HXBOOL bLinearFileSystem = \
((m_pFileObject->Advise(HX_FILEADVISE_RANDOMACCESS) == HXR_ADVISE_PREFER_LINEAR) ? \
TRUE : FALSE); + if (CanUseIndexObjectsForSeeking() && !bLinearFileSystem)
+ {
+ // We do have index objects (either an Index Object or
+ // a Simple Index Object) at the end of the file
+ // that we can use. So we need to seek to just past
+ // the end of the ASF Data Object.
+ UINT64 ullOffset = m_pDataObject->m_ullFileOffset +
+ m_pDataObject->m_ullASFObjectSize;
+ // Assume for now the files are less than 4GB
+ HX_ASSERT(ullOffset <= 0xFFFFFFFF);
+ // Assign the offset we will be seeking to
+ m_ulSeekOffsetRequested = INT64_TO_UINT32(ullOffset);
+ // Log a message saying we are seeking to the end of the file
+ HXLOGL3(HXLOG_ASFF, "\tSeeking to index objects starting at file offset \
%lu", m_ulSeekOffsetRequested); + // Initialize the index of simple index \
objects + m_ulSimpleIndexOrderIndex = 0;
+ // Set the state saying we are seeking to the beginning of
+ // the index objects
+ m_ulState = kStateSeekIndexObjectSeekDonePending;
+ // Seek the file object
+ m_pFileObject->Seek(m_ulSeekOffsetRequested, FALSE);
+ // Clear the return value
+ retVal = HXR_OK;
+ }
+ else
+ {
+ retVal = HXR_OK;
+ SendFileHeader(HXR_OK);
+ }
+ return retVal;
+}
+
STDMETHODIMP CASFFileFormatFile::Seek(ULONG32 ulOffset)
{
HXLOGL2(HXLOG_ASFF, "CASFFileFormatFile::Seek(%lu)", ulOffset);
@@ -597,9 +643,6 @@
}
}
}
- // Check if we have a linear filesystem
- HX_RESULT retAdvise = m_pFileObject->Advise(HX_FILEADVISE_RANDOMACCESS);
- HXBOOL bLinearFileSystem = (retAdvise == HXR_ADVISE_PREFER_LINEAR ? TRUE : \
FALSE); // Compute desired seek time. The index table is indexed
// by presentation time, which means that we have to add
// the file preroll to the times.
@@ -616,128 +659,72 @@
{
HXLOGL3(HXLOG_ASFF, "\tOn-the-fly table provided seek offset \
(time=%lu,offset=%lu)", ulActualSeekTime, ulFileOffset);
- // We will be seeking right to an ASF packet
- // (as opposed to seeking to an index table for
- // further reading)
- bSeekingToPacket = TRUE;
}
else
{
- // We could not determine the seek location from the
- // on-the-fly seek table. Therefore, we should try
- // to look it up from an index ASF object at the
- // end of the file. However, first we must determine
- // if there actually IS an Index object (or a Simple
- // Index object) at the end of the file. We know
- // there will be an Index object if there is
- // an index parameters object in the header.
- // However, if we have a linear file system (i.e. -
- // an HTTP 1.0 filesystem that hasn't finished
- // downloading the file), then we don't want to
- // seek to the end of the file.
- if (CanUseIndexObjectsForSeeking() && !bLinearFileSystem)
+ // We either don't have an index or we can' use it
+ // due to a linear filesystem. See if we can
+ // estimate the seek time.
+ //
+ // Are we a single-stream audio file?
+ if (IsSingleStreamAudioFile())
{
- // We do have index objects (either an Index Object or
- // a Simple Index Object) at the end of the file
- // that we can use. So we need to seek to just past
- // the end of the ASF Data Object.
- UINT64 ullOffset = m_pDataObject->m_ullFileOffset +
- m_pDataObject->m_ullASFObjectSize;
- // Assume for now the files are less than 4GB
- HX_ASSERT(ullOffset <= 0xFFFFFFFF);
- // Assign the offset we will be seeking to
- ulFileOffset = INT64_TO_UINT32(ullOffset);
- // Log a message saying we are seeking to the end of the file
- HXLOGL3(HXLOG_ASFF, "\tSeeking to index objects starting at file offset \
%lu", ulFileOffset);
- // Initialize the index of simple index objects
- m_ulSimpleIndexOrderIndex = 0;
- // We are not seeking to a packet but rather a index
- bSeekingToPacket = FALSE;
- // Clear the return value
- retVal = HXR_OK;
+ // Single-stream audio files often don't have index
+ // objects since audio is constant bitrate,
+ // packet sizes are fixed, and there are no
+ // keyframes. Therefore, it is possible
+ // to do a very good estimate of where to seek
+ // to just based on duration, number of packets,
+ // and the requested seek time.
+ retVal = EstimateSeekTime(ulOffset, ulFileOffset);
+ if (SUCCEEDED(retVal))
+ {
+ // Log a message saying we are seeking to the end of the file
+ HXLOGL3(HXLOG_ASFF, "\tSingle-stream audio file, so using seek \
estimate of %lu", ulFileOffset); + }
}
- else
+ // Do we *still* not know where to seek?
+ if (FAILED(retVal))
{
- // We either don't have an index or we can' use it
- // due to a linear filesystem. See if we can
- // estimate the seek time.
- //
- // Are we a single-stream audio file?
- if (IsSingleStreamAudioFile())
+ // Try getting the latest value from the on-the-fly index
+ // table (the TRUE forces the table to give us the
+ // latest values). If nothing else, we can start seeking from the
+ // last known packet offset
+ retVal = SearchIndexTable(ulDesiredPresTime, TRUE, ulActualSeekTime, \
ulFileOffset); + if (SUCCEEDED(retVal))
{
- // Single-stream audio files often don't have index
- // objects since audio is constant bitrate,
- // packet sizes are fixed, and there are no
- // keyframes. Therefore, it is possible
- // to do a very good estimate of where to seek
- // to just based on duration, number of packets,
- // and the requested seek time.
- retVal = EstimateSeekTime(ulOffset, ulFileOffset);
- if (SUCCEEDED(retVal))
- {
- // Log a message saying we are seeking to the end of the file
- HXLOGL3(HXLOG_ASFF, "\tSingle-stream audio file, so using seek \
estimate of %lu", ulFileOffset);
- }
+ // Log a message saying we are starting from the last known \
on-the-fly entry + HXLOGL3(HXLOG_ASFF, "\tStarting at last known \
on-the-fly index table entry: (time=%lu,offset=%lu)", + \
ulActualSeekTime, ulFileOffset); }
- // Do we *still* not know where to seek?
- if (FAILED(retVal))
+ else
{
- // Try getting the latest value from the on-the-fly index
- // table (the TRUE forces the table to give us the
- // latest values). If nothing else, we can start seeking from the
- // last known packet offset
- retVal = SearchIndexTable(ulDesiredPresTime, TRUE, ulActualSeekTime, \
ulFileOffset);
- if (SUCCEEDED(retVal))
- {
- // Log a message saying we are starting from the last known \
on-the-fly entry
- HXLOGL3(HXLOG_ASFF, "\tStarting at last known on-the-fly index \
table entry: (time=%lu,offset=%lu)",
- ulActualSeekTime, ulFileOffset);
- }
- else
- {
- // Yikes - no latest time. Well, the best we can
- // do then is to start back at the first packet.
- ulFileOffset = m_ulFirstASFPacketFileOffset;
- // Log a message saying we are starting from the first packet
- HXLOGL3(HXLOG_ASFF, "\tStarting from first ASF packet at offset \
%lu", ulFileOffset);
- // Clear the return value
- retVal = HXR_OK;
- }
+ // Yikes - no latest time. Well, the best we can
+ // do then is to start back at the first packet.
+ ulFileOffset = m_ulFirstASFPacketFileOffset;
+ // Log a message saying we are starting from the first packet
+ HXLOGL3(HXLOG_ASFF, "\tStarting from first ASF packet at offset \
%lu", ulFileOffset); + // Clear the return value
+ retVal = HXR_OK;
}
- // In all of the cases above, we are seeking to a packet
- bSeekingToPacket = TRUE;
}
}
// Do we have a valid file offset to seek to?
if (SUCCEEDED(retVal))
{
- // Are we seeking to a packet or seeking to an index?
- if (bSeekingToPacket)
- {
- // Since we have fixed-size packets in ASF, we can
- // compute the packet index we are seeking to
- if (m_pFilePropertiesObject &&
- m_pFilePropertiesObject->m_ulMaxDataPacketSize)
- {
- m_ullPacketIndex = (ulFileOffset - m_ulFirstASFPacketFileOffset) /
- m_pFilePropertiesObject->m_ulMaxDataPacketSize;
- }
- // We are seeking to a packet, so all we need
- // to do is issue one seek and then we will
- // call back with SeekDone().
- m_ulState = kStateSeekFinalSeekDonePending;
- }
- else
+ // Since we have fixed-size packets in ASF, we can
+ // compute the packet index we are seeking to
+ if (m_pFilePropertiesObject &&
+ m_pFilePropertiesObject->m_ulMaxDataPacketSize)
{
- // We need to save the presentation time that
- // we are trying to seek to so that once we
- // read the index objects we can look up the time.
- m_ulDesiredSeekPresTime = ulDesiredPresTime;
- // Set the state saying we are seeking to the beginning of
- // the index objects
- m_ulState = kStateSeekIndexObjectSeekDonePending;
+ m_ullPacketIndex = (ulFileOffset - m_ulFirstASFPacketFileOffset) /
+ m_pFilePropertiesObject->m_ulMaxDataPacketSize;
}
+ // We are seeking to a packet, so all we need
+ // to do is issue one seek and then we will
+ // call back with SeekDone().
+ m_ulState = kStateSeekFinalSeekDonePending;
// Set the seek offset requested
m_ulSeekOffsetRequested = ulFileOffset;
// Seek the file object
@@ -896,7 +883,22 @@
// We just read the data object header, so we have read
// the end of the header object. So we can create
// the file header
- retVal = SendFileHeader();
+
+ // First set up the objects we will need to create
+ // the file header and stream headers
+ retVal = SetupStreamObjects();
+ if (SUCCEEDED(retVal))
+ {
+ // Our current implementation depends upon
+ // having fixed-size packets
+ \
HX_ASSERT(m_pFilePropertiesObject->m_ulMinDataPacketSize == \
m_pFilePropertiesObject->m_ulMaxDataPacketSize); + // \
Build the WM -> HX maps and the stream info array + \
retVal = BuildStreamNumberMaps(); + if \
(SUCCEEDED(retVal)) + {
+ retVal = BuildIndex();
+ }
+ }
}
else
{
@@ -1060,41 +1062,31 @@
// or Timecode Index object) which we currently don't use, or \
it's
// some kind of custom object which we don't need. Either way, \
skip it. //
- // Compute the next object offset
- m_ulSeekOffsetRequested = m_ulFileOffset - pBuffer->GetSize() + \
INT64_TO_UINT32(m_ullASFObjectSize);
- // Set the state
- m_ulState = kStateSeekIndexObjectSeekDonePending;
- // Seek just past the end of the ASF object
- m_pFileObject->Seek(m_ulSeekOffsetRequested, FALSE);
+ if (m_eASFObjectType == HX_ASF_Unknown_Object && \
m_ullASFObjectSize == 0) + {
+ m_ulState = kStateReady;
+ // Fail out
+ m_pFormatResponse->SeekDone(retVal);
+ BuildIndexDone();
+ }
+ else
+ {
+ // Compute the next object offset
+ m_ulSeekOffsetRequested = m_ulFileOffset - \
pBuffer->GetSize() + INT64_TO_UINT32(m_ullASFObjectSize); + // \
Set the state + m_ulState = \
kStateSeekIndexObjectSeekDonePending; + // Seek just past the \
end of the ASF object + \
m_pFileObject->Seek(m_ulSeekOffsetRequested, FALSE); + }
}
}
}
- else
- {
- // We tried to find another index object but could not, so seek to the \
largest index.
- // if failed, just seek to the first packet and read from there.
- UINT32 ulActualSeekTime = 0;
- UINT32 ulSeekOffset = 0;
-
- retVal = SearchIndexTable(m_ulDesiredSeekPresTime, TRUE, ulActualSeekTime, \
ulSeekOffset);
- m_ulSeekOffsetRequested = SUCCEEDED(retVal) ? ulSeekOffset : \
m_ulFirstASFPacketFileOffset;
-
- // Set the state saying this is the final seek prior to calling \
SeekDone()
- m_ulState = kStateSeekFinalSeekDonePending;
- // Now seek the file object to the first ASF packet
- m_pFileObject->Seek(m_ulSeekOffsetRequested, FALSE);
- // Clear the return value
- retVal = HXR_OK;
- }
+
if (FAILED(retVal))
{
- // Set the state
- m_ulState = kStateReady;
- // Fail out
- m_pFormatResponse->SeekDone(retVal);
+ BuildIndexDone();
+ retVal = HXR_OK;
}
- // Clear the return value
- retVal = HXR_OK;
}
else if (m_ulState == kStateSeekIndexObjectBodyReadDonePending)
{
@@ -1144,60 +1136,20 @@
// Increment the index of the simple index object we \
have seen so far m_ulSimpleIndexOrderIndex++;
}
- // Now see if we can look up a seek offset
- UINT32 ulActualSeekTime = 0;
- UINT32 ulSeekOffset = 0;
- retVal = SearchIndexTable(m_ulDesiredSeekPresTime, FALSE, \
ulActualSeekTime, ulSeekOffset);
- if (SUCCEEDED(retVal))
- {
- // We were able to look up an offset now, so
- // we should seek to that point and then call SeekDone()
- //
- // Since we have fixed-size packets in ASF, we can
- // compute the packet index we are seeking to
- if (m_pFilePropertiesObject &&
- m_pFilePropertiesObject->m_ulMaxDataPacketSize)
- {
- m_ullPacketIndex = (ulSeekOffset - \
m_ulFirstASFPacketFileOffset) /
- \
m_pFilePropertiesObject->m_ulMaxDataPacketSize;
- }
- // We are seeking to a packet, so all we need
- // to do is issue one seek and then we will
- // call back with SeekDone().
- m_ulState = kStateSeekFinalSeekDonePending;
- // Set the seek offset requested
- m_ulSeekOffsetRequested = ulSeekOffset;
- // Seek the file object
- m_pFileObject->Seek(ulSeekOffset, FALSE);
- }
- else
- {
- // We were not able to look up a seek offset, so keep \
reading
- // and try to get another index object
- //
- // Set the state
- m_ulState = kStateSeekIndexObjectHeaderReadDonePending;
- // Read HX_ASF_OBJECT_HEADER_SIZE bytes
- m_pFileObject->Read(HX_ASF_OBJECT_HEADER_SIZE);
- // Clear the return value
- retVal = HXR_OK;
- }
+ // Look For More Indexes, keep trying until we fail
+ // Set the state
+ m_ulState = kStateSeekIndexObjectHeaderReadDonePending;
+ // Read HX_ASF_OBJECT_HEADER_SIZE bytes
+ m_pFileObject->Read(HX_ASF_OBJECT_HEADER_SIZE);
}
}
}
HX_RELEASE(pASFObj);
+
}
- else
- {
- // Read failed
- retVal = status;
- }
- if (FAILED(retVal))
+ if(FAILED(retVal))
{
- // Set the state
- m_ulState = kStateReady;
- // Call back to the response interface
- m_pFormatResponse->SeekDone(retVal);
+ BuildIndexDone();
// Clear the return value
retVal = HXR_OK;
}
@@ -1278,15 +1230,17 @@
}
else
{
- // Set the state
- m_ulState = kStateReady;
- // Return failure
- m_pFormatResponse->SeekDone(status);
+ BuildIndexDone();
}
// Clear the return value
retVal = HXR_OK;
}
-
+ else if(m_ulState == kStateSeekStartIndexBuildDonePending)
+ {
+ SendFileHeader(status);
+ // Clear the return value
+ retVal = HXR_OK;
+ }
return retVal;
}
@@ -1409,62 +1363,55 @@
return retVal;
}
-HX_RESULT CASFFileFormatFile::SendFileHeader()
+HX_RESULT CASFFileFormatFile::SendFileHeader(HX_RESULT status)
{
- // First set up the objects we will need to create
- // the file header and stream headers
- HX_RESULT retVal = SetupStreamObjects();
+ // Create the file header
+ if(FAILED(status))
+ {
+ return m_pFormatResponse->FileHeaderReady(HXR_FAIL, NULL);
+ }
+ IHXValues* pHdr = NULL;
+ HX_RESULT retVal = CreateValuesCCF(pHdr, m_pContext);
if (SUCCEEDED(retVal))
{
- // Our current implementation depends upon
- // having fixed-size packets
- HX_ASSERT(m_pFilePropertiesObject->m_ulMinDataPacketSize == \
m_pFilePropertiesObject->m_ulMaxDataPacketSize);
- // Build the WM -> HX maps and the stream info array
- retVal = BuildStreamNumberMaps();
- if (SUCCEEDED(retVal))
+ // Set the stream count
+ pHdr->SetPropertyULONG32("StreamCount", m_ulNumHXStreams);
+ // Set the "IsRealDataType" property
+ pHdr->SetPropertyULONG32("IsRealDataType", 0);
+ // Compute the duration
+ UINT32 ulDuration = 0;
+ if (m_pFilePropertiesObject)
{
- // Create the file header
- IHXValues* pHdr = NULL;
- retVal = CreateValuesCCF(pHdr, m_pContext);
- if (SUCCEEDED(retVal))
- {
- // Set the stream count
- pHdr->SetPropertyULONG32("StreamCount", m_ulNumHXStreams);
- // Set the "IsRealDataType" property
- pHdr->SetPropertyULONG32("IsRealDataType", 0);
- // Compute the duration
- UINT32 ulDuration = 0;
- if (m_pFilePropertiesObject)
- {
- // Get the file properties duration. The file properties
- // duration is in units of 100ns, so we just convert to \
milliseconds
- UINT64 ullDuration = m_pFilePropertiesObject->m_ullPlayDuration \
/ ((UINT64) 10000);
- // Now subtract off the preroll. The preroll is already
- // in units of milliseconds
- ullDuration -= m_pFilePropertiesObject->m_ullPreroll;
- // Convert from UINT64 to UINT32
- ulDuration = INT64_TO_UINT32(ullDuration);
- }
- // Set the duration property
- pHdr->SetPropertyULONG32("Duration", ulDuration);
- // Set the title/author/copyright info
- SetTACInfo(pHdr);
- // XXXMEH - TODO: Implement "AcceptMetaInfo" support here
+ // Get the file properties duration. The file properties
+ // duration is in units of 100ns, so we just convert to milliseconds
+ UINT64 ullDuration = m_pFilePropertiesObject->m_ullPlayDuration / \
((UINT64) 10000); + // Now subtract off the preroll. The preroll is \
already + // in units of milliseconds
+ ullDuration -= m_pFilePropertiesObject->m_ullPreroll;
+ // Convert from UINT64 to UINT32
+ ulDuration = INT64_TO_UINT32(ullDuration);
+ }
+ // Set the duration property
+ pHdr->SetPropertyULONG32("Duration", ulDuration);
+ if(m_pASFIndex == NULL)
+ {
+ pHdr->SetPropertyULONG32("NonSeekableAtStart", 1);
+ }
+ // Set the title/author/copyright info
+ SetTACInfo(pHdr);
+ // XXXMEH - TODO: Implement "AcceptMetaInfo" support here
#if defined(HELIX_FEATURE_DRM)
- // DRM related header values
- SetDRMInfo(pHdr);
+ // DRM related header values
+ SetDRMInfo(pHdr);
#endif
- // Set the state
- m_ulState = kStateReady;
- // Return the header
- m_pFormatResponse->FileHeaderReady(HXR_OK, pHdr);
- }
- HX_RELEASE(pHdr);
- }
+ // Set the state
+ m_ulState = kStateReady;
+ // Return the header
+ m_pFormatResponse->FileHeaderReady(HXR_OK, pHdr);
}
-
+ HX_RELEASE(pHdr);
return retVal;
}
_______________________________________________
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