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

List:       helix-datatype-cvs
Subject:    [Datatype-cvs] tools/dtdriver/decoder/video vdecoder.cpp, 1.16,
From:       ehyche () helixcommunity ! org
Date:       2008-02-20 23:42:15
Message-ID: 200802202342.m1KNgiIc011589 () mailer ! progressive-comp ! com
[Download RAW message or body]

Update of /cvsroot/datatype/tools/dtdriver/decoder/video
In directory cvs01.internal.helixcommunity.org:/tmp/cvs-serv5443

Modified Files:
      Tag: hxclient_3_1_0_atlas
	vdecoder.cpp 
Log Message:
Merge from HEAD to 310Atlas.

Description
---------------------------------------------
dtdrplin is used by several applications for thumbnail
generation. Applications usually pick a fixed time (like
5s into the clip) and call dtdrplin with the following
options to generate a thumbnail:

"StartTime"        = 5000
"ProcessTimeUnits" = 1

StartTime=5000 tells dtdrplin to seek the file format to 5000ms
before start fetching packets and passing them through
the pipeline. ProcessTimeUnits=1 tells dtdrplin to only
fetch enough packets that represent 1 unique timestamp.
Usually this 1 unique timestamp will wind up being the
packet (or packets) for the first keyframe prior to
the specified StartTime.

The problem is with vidrend-based renderers (video renderers
which derive from the base video renderer) on the HEAD
and atlas branches. When these renderers are seeked,
they expect to receive packets from the prior keyframe
forward. They decode these packets, but they do not 
begin bltting frames until they see a frame that is
greater than or equal to the desired seek time.

But since for ProcessTimeUnits=1, we are only fetching
enough packets for usually one frame (the keyframe
prior to the seek time), then these renderers usually
wind up not bltting anything, which means no thumbnail
is generated.

So the fix for this is when we detect that ProcessTimeUnits
is set, we call OnPreSeek/OnPostSeek/OnBegin with the
time of the first packet that the fileformat gives us
prior to the seek time rather than the seek time itself.
This ensures that the video renderers will blt the initial
frame, without requiring any changes to sensitive code
in the base video renderer.

Files Modified
---------------------------------------------
datatype/tools/dtdriver/decoder/video/vdecoder.cpp
datatype/tools/dtdriver/decoder/video/pub/vdecoder.h

Branches
---------------------------------------------
HEAD and 310Atlas



Index: vdecoder.cpp
===================================================================
RCS file: /cvsroot/datatype/tools/dtdriver/decoder/video/vdecoder.cpp,v
retrieving revision 1.16
retrieving revision 1.16.2.1
diff -u -d -r1.16 -r1.16.2.1
--- vdecoder.cpp	3 Aug 2007 20:16:46 -0000	1.16
+++ vdecoder.cpp	20 Feb 2008 23:42:13 -0000	1.16.2.1
@@ -112,6 +112,7 @@
     m_ulPreviousPacketTime    = 0;
     m_ulPacketCount	      = 0;
     m_ulBltCount	      = 0;
+    m_ulProcessTimeUnits      = 0;
     m_bMaxSpeed               = 0;
     m_bProcessHeadersOnly     = 0;
     m_bSetSrcProperties       = 0;
@@ -199,6 +200,7 @@
     m_bMaxSpeed           = GetBOOLOption("MaxSpeed",           m_bMaxSpeed);
     m_bSetSrcProperties   = GetBOOLOption("SetSrcProperties",   m_bSetSrcProperties);
     m_ulStartTime	  = GetULONG32Option("StartTime",	m_ulStartTime);
+    m_ulProcessTimeUnits  = GetULONG32Option("ProcessTimeUnits", m_ulProcessTimeUnits);
 
     if (SUCCEEDED(status) && pValues)
     {
@@ -300,6 +302,7 @@
         m_bMaxSpeed           = GetBOOLOption("MaxSpeed",           m_bMaxSpeed);
         m_bSetSrcProperties   = GetBOOLOption("SetSrcProperties",   m_bSetSrcProperties);
 	m_ulStartTime	      = GetULONG32Option("StartTime",	    m_ulStartTime);
+        m_ulProcessTimeUnits  = GetULONG32Option("ProcessTimeUnits", m_ulProcessTimeUnits);
 
         // Load the renderer
         HX_RELEASE(m_pRenderer);
@@ -441,6 +444,27 @@
     {
         if (SUCCEEDED(retVal))
         {
+            // Is this the first packet we've received?
+            if (m_ulPacketCount == 1)
+            {
+                // Did we defer OnPreSeek/OnPostSeek/OnBegin calls in InitRenderer()?
+                if (m_ulStartTime && m_ulProcessTimeUnits)
+                {
+                    // Get the timestamp of the first packet
+                    UINT32 ulFirstPacketTime = pPacket->GetTime();
+                    // Call OnPreSeek/OnPostSeek/OnBegin with this time
+		    retVal = m_pRenderer->OnPreSeek(0, ulFirstPacketTime);
+		    if (SUCCEEDED(retVal))
+		    {
+			retVal = m_pRenderer->OnPostSeek(0, ulFirstPacketTime);
+                        if (SUCCEEDED(retVal))
+                        {
+			    retVal = m_pRenderer->OnBegin(ulFirstPacketTime);
+                        }
+		    }
+                }
+            }
+
             retVal = m_pRenderer->OnPacket(pPacket, 0);
 
 	    if( m_ulPacketCount == 1 )
@@ -534,6 +558,7 @@
     m_bMaxSpeed           = GetBOOLOption("MaxSpeed",           m_bMaxSpeed);
     m_bSetSrcProperties   = GetBOOLOption("SetSrcProperties",   m_bSetSrcProperties);
     m_ulStartTime	  = GetULONG32Option("StartTime",	m_ulStartTime);
+    m_ulProcessTimeUnits  = GetULONG32Option("ProcessTimeUnits", m_ulProcessTimeUnits);
 
     return retVal;
 }
@@ -1010,18 +1035,30 @@
 			    }
 			    if (SUCCEEDED(retVal) && (m_ulStartTime != 0))
 			    {
+                                // Do we have a non-zero ProcessTimeUnits? If so,
+                                // then we want to use the timestamp of the first
+                                // packet as the seek time rather than the specified
+                                // seek time. Since we haven't received the first
+                                // packet yet, then we will defer the OnPreSeek/
+                                // OnPostSeek/OnBegin calls until we do.
+                                if (m_ulProcessTimeUnits == 0)
+                                {
 				retVal = pRenderer->OnPreSeek(0, m_ulStartTime);
-				
 				if (SUCCEEDED(retVal))
 				{
 				    retVal = pRenderer->OnPostSeek(0, m_ulStartTime);
 				}
 			    }
+			    }
 			    if (SUCCEEDED(retVal))
 			    {
+                                // Defer OnBegin if we have deferred OnPreSeek/OnPostSeek
+                                if (m_ulStartTime == 0 || m_ulProcessTimeUnits == 0)
+                                {
 				retVal = pRenderer->OnBegin(m_ulStartTime);
 			    }
 			}
+			}
 			HX_RELEASE(pStream);
 		    }
 		    HX_RELEASE(pSourceURL);


_______________________________________________
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