[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