Ureader.com  
Microsoft software help and Community
   home   |   control panel login   |   archive   |  
 
Windos
win32.3rdparty
win32.directx.audio
win32.directx.ddk
win32.directx.graphics
win32.directx.input
win32.directx.managed
win32.directx.misc
win32.directx.networking
win32.directx.sdk
win32.directx.video
win32.dirx.grap.shaders
win32.gdi
win32.international
win32.kernel
win32.messaging
win32.mmedia
win32.networks
win32.ole
win32.rtc
win32.tapi
win32.tapi.beta
win32.tools
win32.ui
win32.wince
win32.wmi
windows.mediacenter
winfx.aero
winfx.announcements
winfx.avalon
winfx.collaboration
winfx.fundamentals
winfx.general
winfx.indigo
winfx.sdk
winfx.winfs
  
 
date: Mon, 14 Jul 2008 16:46:01 -0700,    group: microsoft.public.win32.programmer.directx.video        back       


WMV 9 DMO Encoder/Decoder usage with live stream   
I am using VS2005 Pro, Directx9, WMV 9 Encoder/Decoder and DirectShow. I am 
using two platforms; WindowsMobile (on a PocketPC) and XP(PC). I am sending a 
live video stream from the mobile to the PC which renders it using VMR9. 

The live video stream works perfectly without using an encoder/decoder. But 
when using the WMV 9 Encoder/Decoder there are issues. At first nothing was 
rendering on the PC. After setting the synchpoint to always be TRUE on the 
IMediaSample, the video was rending, but very slow, about 1 frame per second. 

I was told on a newsgroup posting to set to the DMO encoder's 
IPropertyBag::Write(L"_COMPLEXITYEX"), with a value of 1. With this I am 
getting about 1 frame per 100ms which is much better but I am getting 
decoding problems, the image is being corrupted on and off.  Is there maybe 
some compatibility issues between using the encoder from mobile and decoder 
on pc? Other settings that must be done? Details below on the code.

I am also getting an EC_BUFFER_FULL event from the BufferFilter after maybe 
20sec on the encoder side. So I probably have some frames which are maybe 
discarded. It could maybe causing the decoding problem.

On WindowsMobile I am using the WMV9 Encoder with fourcc WMV3 (which is the 
only one available). The filter graph I have used is the following 
	CameraFilter + BufferFilter + DMOEncoderFilter + StackFilter
The reason why I used the BufferFilter was because the DMO Encoder IN pin 
was only accepting a majortype of VideoBuffered. 

m_pCaptureGraphBuilder.CoCreateInstance( CLSID_CaptureGraphBuilder );
pFilterGraph.CoCreateInstance( CLSID_FilterGraph );
m_pCaptureGraphBuilder->SetFiltergraph( pFilterGraph );
m_pVideoCaptureFilter.CoCreateInstance( CLSID_VideoCapture );
pBuffer.CoCreateInstance( CLSID_BufferingFilter );
hr= pVideoEncoder.CoCreateInstance( CLSID_DMOWrapperFilter );
hr= pVideoEncoder.QueryInterface( &pWrapperFilter );
pWrapperFilter->Init( CLSID_CWMV9EncMediaObject, DMOCATEGORY_VIDEO_ENCODER );
CComPtr<IPropertyBag>    pPropertyBag2;
CComVariant   var;
var.vt = VT_I4;
var.lVal = 1;
hr= pVideoEncoder.QueryInterface( &pPropertyBag2 );
hr = pPropertyBag2->Write(L"_COMPLEXITYEX", &var);

I have connected my pins with the following;

hr = pFilterGraph->ConnectDirect(m_pCamOutPin , m_pBufferInPin, 0); 
hr = pFilterGraph->ConnectDirect(m_pBufferOutPin , m_pEncoderInPin, 0);
 hr = pFilterGraph->ConnectDirect(m_pEncoderOutPin , stackPin, 0); 

The Camera AM_MEDIA_TYPE is the following
+		majortype	{...}	_GUID
		Data1	0x73646976	unsigned long int
		Data2	0x0000	unsigned short
		Data3	0x0010	unsigned short
+		Data4	0x005ff268 "€"	unsigned char[8]
-		subtype	{...}	_GUID
		Data1	0x32315659	unsigned long int
		Data2	0x0000	unsigned short
		Data3	0x0010	unsigned short
+		Data4	0x005ff278 "€"	unsigned char[8]
		bFixedSizeSamples	0x00000001	int
		bTemporalCompression	0x00000000	int
		lSampleSize	0x0001c200	unsigned long int
+		formattype	{...}	_GUID
+		pUnk	0x00000000 {IUnknown*}	IUnknown*
		cbFormat	0x00000468	unsigned long int
+		pbFormat	0x005ff770 ""	unsigned char*
-		vih	0x00001000 {rcSource={...} rcTarget={...} dwBitRate=0x00000000 
...}	tagVIDEOINFOHEADER*
+		rcSource	{top=0x00000000 bottom=0x00000000 left=0x00000000 
right=0x00000000}	tagRECT
+		rcTarget	{top=0x00000000 bottom=0x00000000 left=0x00000000 
right=0x00000000}	tagRECT
		dwBitRate	0x00000000	unsigned long int
		dwBitErrorRate	0x00000000	unsigned long int
		AvgTimePerFrame	0x0000000000000000	__int64
-		bmiHeader	{biSize=0x00000000 biWidth=0x00000000 biHeight=0x00000000 
...}	tagBITMAPINFOHEADER
		biSize	0x00000000	unsigned long int
		biWidth	0x00000000	long int
		biHeight	0x00000000	long int
		biPlanes	0x0000	unsigned short
		biBitCount	0x0000	unsigned short
		biCompression	0x00000000	unsigned long int
		biSizeImage	0x00000000	unsigned long int
		biXPelsPerMeter	0x00000000	long int
		biYPelsPerMeter	0x00000000	long int
		biClrUsed	0x00000000	unsigned long int
		biClrImportant	0x00000000	unsigned long int
The EncoderOutput pin media type
-		majortype	{...}	_GUID
		Data1	686006909	unsigned long int
		Data2	24392	unsigned short
		Data3	18176	unsigned short
+		Data4	0x1225f9cc "‘;I†`ŒŠ‹WMV3"	unsigned char[8]
-		subtype	{...}	_GUID
		Data1	861293911	unsigned long int
		Data2	0	unsigned short
		Data3	16	unsigned short
+		Data4	0x1225f9dc "€"	unsigned char[8]
		bFixedSizeSamples	0	int
		bTemporalCompression	1	int
		lSampleSize	0	unsigned long int
+		formattype	{...}	_GUID
+		pUnk	0x00000000 {IUnknown*}	IUnknown*
		cbFormat	93	unsigned long int
+		pbFormat	0x00548b20 ""	unsigned char*
-		vih	0x005ff860 {rcSource={...} rcTarget={...} dwBitRate=0 
...}	tagVIDEOINFOHEADER*
+		rcSource	{top=0 bottom=0 left=0 right=0}	tagRECT
+		rcTarget	{top=0 bottom=0 left=0 right=0}	tagRECT
		dwBitRate	0	unsigned long int
		dwBitErrorRate	0	unsigned long int
		AvgTimePerFrame	666666	__int64
-		bmiHeader	{biSize=40 biWidth=240 biHeight=320 ...}	tagBITMAPINFOHEADER
		biSize	40	unsigned long int
		biWidth	240	long int
		biHeight	320	long int
		biPlanes	1	unsigned short
		biBitCount	12	unsigned short
		biCompression	842094169	unsigned long int
		biSizeImage	115200	unsigned long int
		biXPelsPerMeter	0	long int
		biYPelsPerMeter	0	long int
		biClrUsed	0	unsigned long int
		biClrImportant	0	unsigned long int

I have added the 5 byte WMV3 private data collected during encoder into the 
decoder on the receiver side. I also am saving the synchpoint value on the 
encoding side and setting it on the receiver side.

The receiver side I am setting my source filter with the following

HRESULT RtpOutputPin::GetMediaType( CMediaType *mediaType )
{
   mediaType->SetType( &MEDIATYPE_Video );
   mediaType->SetTemporalCompression(TRUE);
   mediaType->SetSampleSize( 0 );
   mediaType->SetFormatType( &FORMAT_VideoInfo );
   GUID guid;
   guid.Data1 = this->fourcc;
   guid.Data2 = MEDIATYPE_Video.Data2;
   guid.Data3 = MEDIATYPE_Video.Data3;
   for( int i = 0; i < 8; i++ )
   {
      guid.Data4[i] = MEDIATYPE_Video.Data4[i];
   }
   mediaType->SetSubtype( &guid );
   unsigned short sizeBuf = sizeof( VIDEOINFOHEADER);
   BYTE *mediaBuffer = mediaType->AllocFormatBuffer(sizeBuf + 5);
   VIDEOINFOHEADER *vih = (VIDEOINFOHEADER *) mediaBuffer;
   vih->AvgTimePerFrame = 666666; 
   vih->dwBitErrorRate = 0;
   vih->dwBitRate = 0x0; .
   RECT rect;
   rect.bottom = 0;
   rect.left = 0;
   rect.right = 0;
   rect.top = 0;

   vih->rcSource = rect;
   vih->rcTarget = rect;
   
   vih->bmiHeader.biSize = sizeof( BITMAPINFOHEADER)+ 5;  // should be 0x28  
   vih->bmiHeader.biWidth = this->frameWidth;
   vih->bmiHeader.biHeight = this->frameHeight;
   vih->bmiHeader.biPlanes = 0x01;
   vih->bmiHeader.biBitCount = 24; 
   vih->bmiHeader.biCompression = fourcc;
   vih->bmiHeader.biSizeImage = 115200; 
   vih->bmiHeader.biXPelsPerMeter = 0;
   vih->bmiHeader.biYPelsPerMeter = 0;
   vih->bmiHeader.biClrImportant = 0;
   vih->bmiHeader.biClrUsed = 0;
   BYTE newData[5];
   newData[0] = 0x07;
   newData[1] = 0xf1;
   newData[2] = 0x8a;
   newData[3] = 0x01;
   newData[4] = 0x00;
   memcpy( (void *)(mediaBuffer + sizeBuf), (void *)newData, 5);
   return S_OK;   
}

My FilterGraph on the receiver side (PC) looks like this;
	StackFilter + DMO Encoder + VMR 9 
   CoCreateInstance( CLSID_VideoMixingRenderer9,  0, 
CLSCTX_INPROC_SERVER,IID_IBaseFilter, (void **) filter );
   pVideoDecoder.CoCreateInstance( CLSID_DMOWrapperFilter );
   pVideoDecoder.QueryInterface( &pWrapperFilter );
   pWrapperFilter->Init( CLSID_CWMVDecMediaObject, DMOCATEGORY_VIDEO_DECODER 
);
   hr = receiveGraph->AddFilter( pVideoDecoder, L"WMV DMO Decoder" );
   hr = receiveGraph->ConnectDirect( rtpStackOutputPin(), m_pDecoderInPin, 0);
   hr = receiveGraph->ConnectDirect( m_pDecoderOutPin, rendererInputPin(), 0);
date: Mon, 14 Jul 2008 16:46:01 -0700   author:   Kris

Re: WMV 9 DMO Encoder/Decoder usage with live stream   
From: "Kris"

> PC. After setting the synchpoint to always be TRUE on the

It can not be always TRUE: it must be the same as the 
encoder outputs.

> there maybe some compatibility issues between using the
> encoder from mobile and decoder on pc?

No.

> Other settings that must be done?

No.

> I am also getting an EC_BUFFER_FULL event from the
> BufferFilter after maybe 20sec on the encoder side. So I
> probably have some frames which are maybe discarded. It
> could maybe causing the decoding problem.

No. The samples are discarded *before* the encoder, not 
after.
> + majortype {...} _GUID
> Data1 0x73646976 unsigned long int
> Data2 0x0000 unsigned short
> Data3 0x0010 unsigned short
> + Data4 0x005ff268 "?" unsigned char[8]

Printing GUIDs this way really doesn't help. Use 
StringFromGUID2() (or StringFromCLSID() or StringFromIID()).

>   GUID guid;
>   guid.Data1 = this->fourcc;
>   guid.Data2 = MEDIATYPE_Video.Data2;
>   guid.Data3 = MEDIATYPE_Video.Data3;
>   for( int i = 0; i < 8; i++ )
>   {
>      guid.Data4[i] = MEDIATYPE_Video.Data4[i];
>   }
>   mediaType->SetSubtype( &guid );

What about:

GUID guid = MEDIATYPE_Video; guid.Data1 = this->fourcc;
mediaType->SetSubtype( &guid );

or

mediaType->SetSubtype( &FOURCCMap(this->fourcc) );

?

>   BYTE newData[5];
>   newData[0] = 0x07;
>   newData[1] = 0xf1;
>   newData[2] = 0x8a;
>   newData[3] = 0x01;
>   newData[4] = 0x00;
>   memcpy( (void *)(mediaBuffer + sizeBuf), (void
>   *)newData, 5);

What about:

BYTE* newData = (BYTE*)&vih[1] + 5;
newData[0] = ...

In any case, you *must* transfer the AM_MEDIA_TYPE from the 
client to the server, you can not use a fixed media type. It 
works for most fields, at least as long as the fornat does 
not change on the client, but the extra data is *not* 
guaranteed to stay the same (and it is not always 5 bytes) 
so you need to use the correct values.

-- 
// Alessandro Angeli
// MVP :: DirectShow / MediaFoundation
// mvpnews at riseoftheants dot com
// http://www.riseoftheants.com/mmx/faq.htm
date: Mon, 14 Jul 2008 21:53:29 -0400   author:   Alessandro Angeli

Re: WMV 9 DMO Encoder/Decoder usage with live stream   
"Alessandro Angeli" wrote:

> From: "Kris"
> 
> > PC. After setting the synchpoint to always be TRUE on the
> 
> It can not be always TRUE: it must be the same as the 
> encoder outputs.
> 

I am doing that ... I am sending the synchpoint from the sending to the 
receiver. When the complexity is set to 1 ... it will not play right away. I 
read somewhere that it would only start decoding if it got the first frame to 
be a keyframe... see this post. I am seeing this behavior.

http://www.microsoft.com/communities/newsgroups/en-us/default.aspx?dg=microsoft.public.multimedia.directx.dshow.programming&tid=80dd9db5-3a46-4e39-8de8-45bcb84e65a1&cat=en_US_826c3cd7-8915-430c-98f6-cdc1666b1c61&lang=en&cr=US&sloc=&p=1



> > there maybe some compatibility issues between using the
> > encoder from mobile and decoder on pc?
> 
> No.
> 
> > Other settings that must be done?
> 
> No.
> 
> > I am also getting an EC_BUFFER_FULL event from the
> > BufferFilter after maybe 20sec on the encoder side. So I
> > probably have some frames which are maybe discarded. It
> > could maybe causing the decoding problem.
> 
> No. The samples are discarded *before* the encoder, not 
> after.
> > + majortype {...} _GUID
> > Data1 0x73646976 unsigned long int
> > Data2 0x0000 unsigned short
> > Data3 0x0010 unsigned short
> > + Data4 0x005ff268 "?" unsigned char[8]
> 
> Printing GUIDs this way really doesn't help. Use 
> StringFromGUID2() (or StringFromCLSID() or StringFromIID()).

I was just cut and pasting what was in the debugging window. I can give you 
that into you want it. 
This one is of type Video

> 
> >   GUID guid;
> >   guid.Data1 = this->fourcc;
> >   guid.Data2 = MEDIATYPE_Video.Data2;
> >   guid.Data3 = MEDIATYPE_Video.Data3;
> >   for( int i = 0; i < 8; i++ )
> >   {
> >      guid.Data4[i] = MEDIATYPE_Video.Data4[i];
> >   }
> >   mediaType->SetSubtype( &guid );
> 
> What about:
> 
> GUID guid = MEDIATYPE_Video; guid.Data1 = this->fourcc;
> mediaType->SetSubtype( &guid );
> 
> or
> 
> mediaType->SetSubtype( &FOURCCMap(this->fourcc) );
> 
> ?

This is something wrong with what is currently there? this has work with 
fourcc of WMV3/DIVX and NTVC


> 
> >   BYTE newData[5];
> >   newData[0] = 0x07;
> >   newData[1] = 0xf1;
> >   newData[2] = 0x8a;
> >   newData[3] = 0x01;
> >   newData[4] = 0x00;
> >   memcpy( (void *)(mediaBuffer + sizeBuf), (void
> >   *)newData, 5);
> 
> What about:
> 
> BYTE* newData = (BYTE*)&vih[1] + 5;
> newData[0] = ...
> 
> In any case, you *must* transfer the AM_MEDIA_TYPE from the 
> client to the server, you can not use a fixed media type. It 
> works for most fields, at least as long as the fornat does 
> not change on the client, but the extra data is *not* 
> guaranteed to stay the same (and it is not always 5 bytes) 
> so you need to use the correct values.

I know the extra data can change. But at this point I am just testing. I 
have not seen it change yet. 

We done with with a codec of DIVX and everything worked fine. I am just 
having a lot of issues with WMV3. I could set up some debug to see if the 
AM_MEDIA_TYPE is changing. So you are saying that the DMO encoder can change 
this at any point during live encoding?

Kris
date: Mon, 14 Jul 2008 20:30:00 -0700   author:   Kris

Re: WMV 9 DMO Encoder/Decoder usage with live stream   
From: "Kris"

> I am doing that ... I am sending the synchpoint from the
> sending to the receiver. When the complexity is set to 1
> ... it will not play right away. I read somewhere that it
> would only start decoding if it got the first frame to be
> a keyframe... see this post. I am seeing this behavior.

The WMV decoder, like any decoder that supports 
delta-frames, starts decoding at a keyframe, aka at a sync 
point. On the other hand, the first frame the WMV encoder 
outputs is a keyframe so, unless you are dropping frame in 
your newtwork protocol implementation, the first frame the 
decoder receives is a keyframe and it can start decoding 
right away.

> This is something wrong with what is currently there?
> this has work with fourcc of WMV3/DIVX and NTVC

You can do it your way if you want to: it is just more 
complicated and slightly slower (not that it matters).

> We done with with a codec of DIVX and everything worked
> fine. I am just having a lot of issues with WMV3. I could

I have implemented your same framework twice so far and I 
have had no problems with the WMV encoder.

> set up some debug to see if the AM_MEDIA_TYPE is
> changing. So you are saying that the DMO encoder can
> change this at any point during live encoding?

Not during encoding, but at each connection of the pins, 
which happens at least once per execution of your 
application on the mobile side.


-- 
// Alessandro Angeli
// MVP :: DirectShow / MediaFoundation
// mvpnews at riseoftheants dot com
// http://www.riseoftheants.com/mmx/faq.htm
date: Tue, 15 Jul 2008 00:22:01 -0400   author:   Alessandro Angeli

Re: WMV 9 DMO Encoder/Decoder usage with live stream   
Well I am not certain what could be wrong then. The only thing I am not 
setting is the timestamp. I did not think I needed it because when I do not 
set the complexity I do not have the decoding errors in the image.

Maybe it's do to with my custom stack filter then? There is a ::FillBuffer() 
method which gets called for each packets recceived ... maybe something in 
there is missing or wrong?

::FillBuffer( IMediaSample *sample )
{
   // Receive a new buffer on the stack.
   BYTE *buffer;
   long length;
   long bufferlen;

   HRESULT hr = sample->GetPointer( &buffer );
   if( hr != S_OK )
   {
      return hr;
   }

   HRESULT synchpoint;
   HRESULT preroll;
   HRESULT discontinuity;
   
   unsigned int payloadType2;
   payloadType2 = stack->payloadType;

   length = sample->GetSize();
   bufferlen = stack->receiveMedia( (char *) buffer, length );

   hr = sample->SetActualDataLength( bufferlen );
   if( hr != S_OK )
   {
      return hr;
   }

   if (bufferlen != 0)
   {
	   fprintf(fp, "%s",
	            "++New Sample Receive \n" );
   	
	   synchpoint = sample->IsSyncPoint();

                   fprintf(fp, "%s%ld%s",
		   "  current synchpoint: ", synchpoint, "\n");

	   //pay load type is carrying the synchpoint for now
                   if (payloadType2 == S_OK)
                  {
 		   hr =  sample->SetSyncPoint(TRUE); 
                  }
                 else
                 {
     	                   hr =  sample->SetSyncPoint(FALSE);
                   }
	  
	   synchpoint = sample->IsSyncPoint();
	   preroll = sample->IsPreroll();
	   discontinuity = sample->IsDiscontinuity();
                   fprintf(fp, "%s%ld%s%ld%s%ld%s",
				"  synchpoint: ", synchpoint, 
				" preroll: " , preroll, 
				" discontinuity: ", discontinuity, "\n" );
   }

   return S_OK;
}

There is also a DecideBufferSize( IMemAllocator *alloc, ALLOCATOR_PROPERTIES 
*allocProps )  but that gets called only once.

::DecideBufferSize( IMemAllocator *alloc, 
                                        ALLOCATOR_PROPERTIES *allocProps )
{
   // function accesses CBaseFilter.m_mt, provide mutual
   // exclusion
   CAutoLock autoLock( m_pFilter->pStateLock() );

   VIDEOINFO *videoInfo = (VIDEOINFO *) m_mt.Format();

   // Make sure there are some buffers.  (This seems odd, wouldn't the 
allocator
   // always need some buffers?)
   if( 0 == allocProps->cBuffers )
   {
      allocProps->cBuffers = 1;
   }

   // Make sure the buffer size is big enough to hold the media sample
   if( (long) videoInfo->bmiHeader.biSizeImage > allocProps->cbBuffer )
   {
      allocProps->cbBuffer = videoInfo->bmiHeader.biSizeImage;
   }

   // Set the modified properties
   ALLOCATOR_PROPERTIES actualProps;
   HRESULT hr = alloc->SetProperties( allocProps, &actualProps );
   if( FAILED( hr ) )
   {
      return hr;
   }

   // Check that we have usable properties...
   if( ( actualProps.cBuffers == 0 ) || 
       ( actualProps.cbBuffer < allocProps->cbBuffer ) )
   {
      return E_FAIL;
   }

   return S_OK;
}




"Alessandro Angeli" wrote:

> From: "Kris"
> 
> > I am doing that ... I am sending the synchpoint from the
> > sending to the receiver. When the complexity is set to 1
> > ... it will not play right away. I read somewhere that it
> > would only start decoding if it got the first frame to be
> > a keyframe... see this post. I am seeing this behavior.
> 
> The WMV decoder, like any decoder that supports 
> delta-frames, starts decoding at a keyframe, aka at a sync 
> point. On the other hand, the first frame the WMV encoder 
> outputs is a keyframe so, unless you are dropping frame in 
> your newtwork protocol implementation, the first frame the 
> decoder receives is a keyframe and it can start decoding 
> right away.
> 
> > This is something wrong with what is currently there?
> > this has work with fourcc of WMV3/DIVX and NTVC
> 
> You can do it your way if you want to: it is just more 
> complicated and slightly slower (not that it matters).
> 
> > We done with with a codec of DIVX and everything worked
> > fine. I am just having a lot of issues with WMV3. I could
> 
> I have implemented your same framework twice so far and I 
> have had no problems with the WMV encoder.
> 
> > set up some debug to see if the AM_MEDIA_TYPE is
> > changing. So you are saying that the DMO encoder can
> > change this at any point during live encoding?
> 
> Not during encoding, but at each connection of the pins, 
> which happens at least once per execution of your 
> application on the mobile side.
> 
> 
> -- 
> // Alessandro Angeli
> // MVP :: DirectShow / MediaFoundation
> // mvpnews at riseoftheants dot com
> // http://www.riseoftheants.com/mmx/faq.htm 
> 
> 
>
date: Tue, 15 Jul 2008 06:47:07 -0700   author:   Kris

Re: WMV 9 DMO Encoder/Decoder usage with live stream   
From: "Kris"

> Maybe it's do to with my custom stack filter then? There
> is a ::FillBuffer() method which gets called for each
> packets recceived ... maybe something in there is missing
> or wrong?
[...]

- Who calls your FillBuffer()?
- How do you receive data from the network?
- What base classses are you using?
- What network protocol?
- Are you sure you are not dropping frames?
- Why don't you also transfer the other sample flags and the 
timestamps?

>   // Make sure there are some buffers.  (This seems odd,
> wouldn't the allocator
>   // always need some buffers?)

It is not odd: while almost always the connection will use a 
transport that requires buffers to be allocated by the 
chosen allocators, exotic filters might do things 
differently. Moreover, how many buffers are needed is known 
only to the filters, not to the allocator.

>   // Check that we have usable properties...
>   if( ( actualProps.cBuffers == 0 ) ||
>       ( actualProps.cbBuffer < allocProps->cbBuffer ) )
>   {
>      return E_FAIL;
>   }

Return more meaningful errors, like VFW_E_BUFFER_NOTSET and 
VFW_E_BUFFER_OVERFLOW.

-- 
// Alessandro Angeli
// MVP :: DirectShow / MediaFoundation
// mvpnews at riseoftheants dot com
// http://www.riseoftheants.com/mmx/faq.htm
date: Tue, 15 Jul 2008 14:12:11 -0400   author:   Alessandro Angeli

Re: WMV 9 DMO Encoder/Decoder usage with live stream   
"Alessandro Angeli" wrote:

> From: "Kris"
> 
> > Maybe it's do to with my custom stack filter then? There
> > is a ::FillBuffer() method which gets called for each
> > packets recceived ... maybe something in there is missing
> > or wrong?
> [...]
> 
> - Who calls your FillBuffer()?

I am not certain I though the FilterGraph did ... I am reusing code that was 
not written by me.

> - How do you receive data from the network?

RTP packets... socket

> - What base classses are you using?

CSourceStream

> - What network protocol?

RTP 

> - Are you sure you are not dropping frames?

I could be ... I will double check on that ... but it did not seem to be 
when I was sending RAW data or the WMV3 with complexity not set

> - Why don't you also transfer the other sample flags and the 
> timestamps?

I will change the code to send the timestamps. I not exactly certain how to 
do that. Can I simply get the time from the GetTime on the sender side and 
then use SetTime on the receiver side? I know you mentioned something about 
Timestamps needing to match but I did not quiet understood that.

Thanks,
Kristine
date: Tue, 15 Jul 2008 14:25:20 -0700   author:   Kris

Re: WMV 9 DMO Encoder/Decoder usage with live stream   
From: "Kris"

>> - Who calls your FillBuffer()?
>
> I am not certain I though the FilterGraph did ... I am
> reusing code that was not written by me.
[...]
>> - What base classses are you using?
>
> CSourceStream

CSourceStream spawns a worker thread that calls FillBuffer() 
as fast as possible, depending on the time it takes 
FillBuffer() itself to execute and a sample to be processed 
and rendered downstream.

>> - How do you receive data from the network?
>
> RTP packets... socket
>
>> - What network protocol?
>
> RTP

RTP is based on UDP which implies 2 important factors: the 
packet order is not guaranteed and the packets may be 
dropped without you knowing about it for any number of 
reasons (network errors, transmission errors, you are not 
fast ebough in reading them and the recvq fills up...).

>> - Are you sure you are not dropping frames?
>
> I could be ... I will double check on that ... but it did
> not seem to be when I was sending RAW data or the WMV3
> with complexity not set

The timing is different now: you send more than 10 times 
faster than before.

>> - Why don't you also transfer the other sample flags and
>> the timestamps?
>
> I will change the code to send the timestamps. I not
> exactly certain how to do that. Can I simply get the time
> from the GetTime on the sender side and then use SetTime
> on the receiver side? I know you mentioned something
> about Timestamps needing to match but I did not quiet
> understood that.

Let's call firstStartTime the start time of the first sample 
you send. Instead of sending (startTime,stopTime), you send 
(startTime-firstStartTime,stopTime-firstStartTime).

Let's call firstClockTime the clock time when you receive 
the first sample (CSourceStream::m_pFilter->StreamTime()). 
You call 
IMediaSample::SetTime(startTime+firstClockTime,stopTime+firstClockTime).

CSource+CSourceStream works well for file sources and other 
sequential synchronous pull-mode (that is, on-demand) 
sources, but they are a *very* bad choice for an 
asynchronous push-mode (that is, "live") source. Even more 
so if the source is not sequential, like UDP is. That means 
that you should write a live capture push source filter 
(well, a subset of one):

http://msdn.microsoft.com/en-us/library/ms787518(VS.85).aspx

You need to recvFrom() as soon as there is data pending, 
regardless of whether you can deliver it downstream (while 
CSourceStream blocks). If you can not deliver, you must 
queue the data without blocking (which implies 2 threads: 
one that receives and one that delivers, with a queue in 
between).

You must use the RTP sequence number to re-order the samples 
you receive in the queue. If a sample is missing, you must 
wait for it before delivering the following samples but only 
wait at most until it is almost time to render the next 
available sample. If you deliver after a gap, set the 
discontinuity flag on the first sample that follows. If you 
receive a sample too late, discard it.

Put the start time in the RTP packet's timestamp (scaled 
down to millisecs). You do not need to set the stop time. If 
you want yo set the stop time, wait until you receive the 
next sample, than use its start time as stop time for the 
previous one (of course, if you are missing the next sample, 
just do not set the stop time).

You can use RTP's marker bit to mark sync points.

If you have samples that do not fit in a single RTP payload, 
you need to fragment and reasseble them.

And so on... Unless you have a very good reason to use a 
UDP-based transport, you should use a TCP-based one and all 
of this would go away.

-- 
// Alessandro Angeli
// MVP :: DirectShow / MediaFoundation
// mvpnews at riseoftheants dot com
// http://www.riseoftheants.com/mmx/faq.htm
date: Tue, 15 Jul 2008 18:12:21 -0400   author:   Alessandro Angeli

Re: WMV 9 DMO Encoder/Decoder usage with live stream   
> > I will change the code to send the timestamps. I not
> > exactly certain how to do that. Can I simply get the time
> > from the GetTime on the sender side and then use SetTime
> > on the receiver side? I know you mentioned something
> > about Timestamps needing to match but I did not quiet
> > understood that.
> 
> Let's call firstStartTime the start time of the first sample 
> you send. Instead of sending (startTime,stopTime), you send 
> (startTime-firstStartTime,stopTime-firstStartTime).
> 
> Let's call firstClockTime the clock time when you receive 
> the first sample (CSourceStream::m_pFilter->StreamTime()). 
> You call 
> IMediaSample::SetTime(startTime+firstClockTime,stopTime+firstClockTime).
> 


I can do those changes ... right now I have simply passed in to the receiver 
the GetTime values without manipulation. Logs are below... comparing data 
with wireshark traces on my receiving side confirms that there is *no* packet 
loses. Remember this code was used with DIVX encoder/decoder and also another 
one. There was no issue found. And yes there is about a couple of packets per 
frame, sometimes one when using WMV3. 

With the timestamp changes I still have same decoding errors ...

++New Sample Transmit 
  frame no : 0
  synchpoint: 1
  preroll: 0
  discontinuity: 0
  timeGetTime: 107356352
  GetTime: start time 230000 end time 896666
++New Sample Transmit 
  frame no : 1
  synchpoint: 0
  preroll: 0
  discontinuity: 0
  timeGetTime: 107356642
  TimeDiff: 290
  GetTime: start time 880000 end time 1546666
++New Sample Transmit 
  frame no : 2
  synchpoint: 0
  preroll: 0
  discontinuity: 0
  timeGetTime: 107356836
  TimeDiff: 194
  GetTime: start time 1550000 end time 2216666
++New Sample Transmit 
  frame no : 3
  synchpoint: 0
  preroll: 0
  discontinuity: 0
  timeGetTime: 107357015
  TimeDiff: 179
  GetTime: start time 2200000 end time 2866666
++New Sample Transmit 
  frame no : 4
  synchpoint: 1
  preroll: 0
  discontinuity: 0
  timeGetTime: 107357210
  TimeDiff: 195
  GetTime: start time 2860000 end time 3526666
++New Sample Transmit 
  frame no : 5
  synchpoint: 0
  preroll: 0
  discontinuity: 0
  timeGetTime: 107357405
  TimeDiff: 195
  GetTime: start time 3520000 end time 4186666
++New Sample Transmit 
  frame no : 6
  synchpoint: 0
  preroll: 0
  discontinuity: 0
  timeGetTime: 107357621
  TimeDiff: 216
  GetTime: start time 4180000 end time 4846666
++New Sample Transmit 
  frame no : 7
  synchpoint: 0
  preroll: 0
  discontinuity: 0
  timeGetTime: 107357803
  TimeDiff: 182
  GetTime: start time 4840000 end time 5506666
++New Sample Transmit 
  frame no : 8
  synchpoint: 0
  preroll: 0
  discontinuity: 0
  timeGetTime: 107357995
  TimeDiff: 192
  GetTime: start time 5500000 end time 6166666

++New Sample Receive 
  packet sequence no : 1    <--------------------- this is matching with 
wireshark
  synchpt : 1
  synchpoint: 1 preroll: 0 discontinuity: 0
  timeGetTime: 158857325
  SetTime: start time 230000 end time 896666
++New Sample Receive 
  packet sequence no : 6
  synchpt : 0
  synchpoint: 0 preroll: 0 discontinuity: 0
  timeGetTime: 158857605
  SetTime: start time 880000 end time 1546666
++New Sample Receive 
  packet sequence no : 8
  synchpt : 0
  synchpoint: 0 preroll: 0 discontinuity: 0
  timeGetTime: 158857799
  SetTime: start time 1550000 end time 2216666
++New Sample Receive 
  packet sequence no : 10
  synchpt : 0
  synchpoint: 0 preroll: 0 discontinuity: 0
  timeGetTime: 158857978
  SetTime: start time 2200000 end time 2866666
++New Sample Receive 
  packet sequence no : 12
  synchpt : 1
  synchpoint: 1 preroll: 0 discontinuity: 0
  timeGetTime: 158858180
  SetTime: start time 2860000 end time 3526666
++New Sample Receive 
  packet sequence no : 16
  synchpt : 0
  synchpoint: 0 preroll: 0 discontinuity: 0
  timeGetTime: 158858368
  SetTime: start time 3520000 end time 4186666
++New Sample Receive 
  packet sequence no : 18
  synchpt : 0
  synchpoint: 0 preroll: 0 discontinuity: 0
  timeGetTime: 158858583
  SetTime: start time 4180000 end time 4846666
++New Sample Receive 
  packet sequence no : 20
  synchpt : 0
  synchpoint: 0 preroll: 0 discontinuity: 0
  timeGetTime: 158858765
  SetTime: start time 4840000 end time 5506666
++New Sample Receive 
  packet sequence no : 22
  synchpt : 0
  synchpoint: 0 preroll: 0 discontinuity: 0
  timeGetTime: 158858958
  SetTime: start time 5500000 end time 6166666
++New Sample Receive 
  packet sequence no : 24
  synchpt : 1
  synchpoint: 1 preroll: 0 discontinuity: 0
  timeGetTime: 158859161
  SetTime: start time 6160000 end time 6826666
++New Sample Receive 
  packet sequence no : 29
  synchpt : 0
  synchpoint: 0 preroll: 0 discontinuity: 0
  timeGetTime: 158859372
  SetTime: start time 6820000 end time 7486666



Thanks
Kristine
date: Wed, 16 Jul 2008 10:03:00 -0700   author:   Kris

Re: WMV 9 DMO Encoder/Decoder usage with live stream   
From: "Kris"

> is *no* packet loses. Remember this code was used with
> DIVX encoder/decoder and also another one.

Well, I don't know your code but, generally speaking,
different codecs produce different packetizations and
different timing and a UDP-based transport is sensible to
those differences unless it is coded to hide them (like a
TCP-based transport does by itself).

> issue found. And yes there is about a couple of packets
> per frame, sometimes one when using WMV3.

Are you saying that some samples on the client side are
fragmented when sent over the network? I am not sure that
the WMV decoder can deal with that (the video subtypes
assumes that a sample contains a whole frame). You should
reassemble the fragments and see whether that makes a
difference. Also, compare the contents to be sure you get 
exactly what you send.

-- 
// Alessandro Angeli
// MVP :: DirectShow / MediaFoundation
// mvpnews at riseoftheants dot com
// http://www.riseoftheants.com/mmx/faq.htm
date: Wed, 16 Jul 2008 13:36:36 -0400   author:   Alessandro Angeli

Re: WMV 9 DMO Encoder/Decoder usage with live stream   
The packets are reassembled ... and given to the decoder as one frame. When I 
was sending RAW data .. there is was 80 packets per frame being disassembled 
and reassembled The RTP filter being the problem is very low.

This is what I have now with your requested time changes. Same results as 
before. Below are logs.

This is what I have now with your requested time changes. Same results as 
before. Below are logs.

++New Sample Transmit 
  frame no : 0
  synchpoint: 1
  preroll: 0
  discontinuity: 0
  timeGetTime: 110691142
  GetTime: start time 0 end time 666666
++New Sample Transmit 
  frame no : 1
  synchpoint: 0
  preroll: 0
  discontinuity: 0
  timeGetTime: 110691426
  TimeDiff: 284
  GetTime: start time 650000 end time 1316666
++New Sample Transmit 
  frame no : 2
  synchpoint: 0
  preroll: 0
  discontinuity: 0
  timeGetTime: 110691608
  TimeDiff: 182
  GetTime: start time 1310000 end time 1976666
++New Sample Transmit 
  frame no : 3
  synchpoint: 1
  preroll: 0
  discontinuity: 0
  timeGetTime: 110691811
  TimeDiff: 203
  GetTime: start time 1970000 end time 2636666
++New Sample Transmit 
  frame no : 4
  synchpoint: 0
  preroll: 0
  discontinuity: 0
  timeGetTime: 110692009
  TimeDiff: 198
  GetTime: start time 2630000 end time 3296666
++New Sample Transmit 
  frame no : 5
  synchpoint: 0
  preroll: 0
  discontinuity: 0
  timeGetTime: 110692173
  TimeDiff: 164
  GetTime: start time 3300000 end time 3966666
++New Sample Transmit 
  frame no : 6
  synchpoint: 0
  preroll: 0
  discontinuity: 0
  timeGetTime: 110692366
  TimeDiff: 193
  GetTime: start time 3950000 end time 4616666



++New Sample Receive 
  packet sequence no : 1
  synchpt : 1
  synchpoint: 1 preroll: 0 discontinuity: 0
  timeGetTime: 162192125
  m_pFilter->StreamTime m_time :  1621921250000
  SetTime: start time 1621921250000 end time 1621921916666
++New Sample Receive 
  packet sequence no : 6
  synchpt : 0
  synchpoint: 0 preroll: 0 discontinuity: 0
  timeGetTime: 162192395
  SetTime: start time 1621921900000 end time 1621922566666
++New Sample Receive 
  packet sequence no : 8
  synchpt : 0
  synchpoint: 0 preroll: 0 discontinuity: 0
  timeGetTime: 162192578
  SetTime: start time 1621922560000 end time 1621923226666
++New Sample Receive 
  packet sequence no : 10
  synchpt : 1
  synchpoint: 1 preroll: 0 discontinuity: 0
  timeGetTime: 162192788
  SetTime: start time 1621923220000 end time 1621923886666
++New Sample Receive 
  packet sequence no : 14
  synchpt : 0
  synchpoint: 0 preroll: 0 discontinuity: 0
  timeGetTime: 162192979
  SetTime: start time 1621923880000 end time 1621924546666
++New Sample Receive 
  packet sequence no : 16
  synchpt : 0
  synchpoint: 0 preroll: 0 discontinuity: 0
  timeGetTime: 162193142
  SetTime: start time 1621924550000 end time 1621925216666
++New Sample Receive 
  packet sequence no : 18
  synchpt : 0
  synchpoint: 0 preroll: 0 discontinuity: 0
  timeGetTime: 162193334
  SetTime: start time 1621925200000 end time 1621925866666
++New Sample Receive 
  packet sequence no : 20
  synchpt : 0
  synchpoint: 0 preroll: 0 discontinuity: 0
  timeGetTime: 162193503
  SetTime: start time 1621925860000 end time 1621926526666
++New Sample Receive 
  packet sequence no : 21
  synchpt : 1
  synchpoint: 1 preroll: 0 discontinuity: 0
  timeGetTime: 162193703
  SetTime: start time 1621926520000 end time 1621927186666
++New Sample Receive 
  packet sequence no : 26
  synchpt : 0
  synchpoint: 0 preroll: 0 discontinuity: 0
  timeGetTime: 162193891
  SetTime: start time 1621927180000 end time 1621927846666



"Alessandro Angeli" wrote:

> From: "Kris"
> 
> > is *no* packet loses. Remember this code was used with
> > DIVX encoder/decoder and also another one.
> 
> Well, I don't know your code but, generally speaking,
> different codecs produce different packetizations and
> different timing and a UDP-based transport is sensible to
> those differences unless it is coded to hide them (like a
> TCP-based transport does by itself).
> 
> > issue found. And yes there is about a couple of packets
> > per frame, sometimes one when using WMV3.
> 
> Are you saying that some samples on the client side are
> fragmented when sent over the network? I am not sure that
> the WMV decoder can deal with that (the video subtypes
> assumes that a sample contains a whole frame). You should
> reassemble the fragments and see whether that makes a
> difference. Also, compare the contents to be sure you get 
> exactly what you send.
> 
> -- 
> // Alessandro Angeli
> // MVP :: DirectShow / MediaFoundation
> // mvpnews at riseoftheants dot com
> // http://www.riseoftheants.com/mmx/faq.htm
> 
> 
> 
>
date: Wed, 16 Jul 2008 10:48:01 -0700   author:   Kris

Re: WMV 9 DMO Encoder/Decoder usage with live stream   
From: "Kris"

> The packets are reassembled ... and given to the decoder
> as one frame. When I was sending RAW data .. there is was
> 80 packets per frame being disassembled and reassembled
> The RTP filter being the problem is very low.
>
> This is what I have now with your requested time changes.
> Same results as before. Below are logs.
[...]

I am out of ideas. I suggest you do the following:

- prefix each sample you transmit with the following header
(or equivalent, since you are already doing most of this):

#pragma pack(4)
struct {
    LONGLONG start;
    LONGLONG stop;
    LONGLONG index;
    DWORD size;
    DWORD flags;
#define FLAG_SYNC 1
#define FLAG_PREROLL 2
#define FLAG_DISC 4
    DWORD checksum;
};
#pragma pack()

start and stop are normalized to zero by subtracting the
start time of the first sample. index is the zero-based
frame index. checksum is any checksum you like, for example
the 16-bit Internet checksum is easy to compute, but a
stronger checksum (e.g. CRC-16 or CRC-32 ot Adler-32) would
be better:

/// THIS IS NOT REALLY THE INTERNET CHECKSUM
DWORD checksum(DWORD size, LPBYTE data)
{
    DWORD s = 0;
    WORD* p = (WORD*)data;
    WORD* q = p + (size >> 1);
    while(p < q) s += *p++;
    return s;
}

On both sides, for each sample print out the header and the
first and last 8 BYTEs of the data (or more, even all of 
them). If the send and receive sequences are not identical, 
something is wrong. If they are, I am at a loss.

I suggest you print the info to file using exactly the same
syntax, so that you can use WinDiff to easily compare them.
Do not print out timeGetTime() because that will be
different.

-- 
// Alessandro Angeli
// MVP :: DirectShow / MediaFoundation
// mvpnews at riseoftheants dot com
// http://www.riseoftheants.com/mmx/faq.htm
date: Wed, 16 Jul 2008 14:28:53 -0400   author:   Alessandro Angeli

Re: WMV 9 DMO Encoder/Decoder usage with live stream   
Just to confirm I was doing things correctly when setting the time on the 
receiver side. 

I did the following 

CRefTime myTime;
m_pFilter->StreamTime(myTime);
firstClockTime  = myTime.m_time;

Thanks,
Kristine


"Alessandro Angeli" wrote:

> From: "Kris"
> 
> > The packets are reassembled ... and given to the decoder
> > as one frame. When I was sending RAW data .. there is was
> > 80 packets per frame being disassembled and reassembled
> > The RTP filter being the problem is very low.
> >
> > This is what I have now with your requested time changes.
> > Same results as before. Below are logs.
> [...]
> 
> I am out of ideas. I suggest you do the following:
> 
> - prefix each sample you transmit with the following header
> (or equivalent, since you are already doing most of this):
> 
> #pragma pack(4)
> struct {
>     LONGLONG start;
>     LONGLONG stop;
>     LONGLONG index;
>     DWORD size;
>     DWORD flags;
> #define FLAG_SYNC 1
> #define FLAG_PREROLL 2
> #define FLAG_DISC 4
>     DWORD checksum;
> };
> #pragma pack()
> 
> start and stop are normalized to zero by subtracting the
> start time of the first sample. index is the zero-based
> frame index. checksum is any checksum you like, for example
> the 16-bit Internet checksum is easy to compute, but a
> stronger checksum (e.g. CRC-16 or CRC-32 ot Adler-32) would
> be better:
> 
> /// THIS IS NOT REALLY THE INTERNET CHECKSUM
> DWORD checksum(DWORD size, LPBYTE data)
> {
>     DWORD s = 0;
>     WORD* p = (WORD*)data;
>     WORD* q = p + (size >> 1);
>     while(p < q) s += *p++;
>     return s;
> }
> 
> On both sides, for each sample print out the header and the
> first and last 8 BYTEs of the data (or more, even all of 
> them). If the send and receive sequences are not identical, 
> something is wrong. If they are, I am at a loss.
> 
> I suggest you print the info to file using exactly the same
> syntax, so that you can use WinDiff to easily compare them.
> Do not print out timeGetTime() because that will be
> different.
> 
> -- 
> // Alessandro Angeli
> // MVP :: DirectShow / MediaFoundation
> // mvpnews at riseoftheants dot com
> // http://www.riseoftheants.com/mmx/faq.htm
> 
> 
> 
>
date: Wed, 16 Jul 2008 19:55:02 -0700   author:   Kris

Re: WMV 9 DMO Encoder/Decoder usage with live stream   
Hi Alessandro,

I was away on vacation ... I have noticed that when I set the timestamp in 
the FillBuffer method, only the first frame renders. When I do not set the 
timestamp, I get the decoding errors. Also when I move my camera around, the 
frames that have to deal with the movement usually renders properly, it seems 
the non keyframes are the ones with the decoding errors.

from the sender
   hr = sample->GetTime(&rStart, &rEnd);
   rStart = rStart - firstStartTime;
   rEnd = rEnd - firstStartTime;

from the receiver
   on the first sample
	      hr = m_pFilter->StreamTime(mytime);
              streamTime = mytime.m_time;  (this is a large number)

    rStart = rStart+ streamTime ; (rStart and rEnd came from the sender)
    rEnd = rEnd+ streamTime ; 
    hr = sample->SetTime(&rStart, &rEnd);


Thanks,
Kris

"Kris" wrote:

> Just to confirm I was doing things correctly when setting the time on the 
> receiver side. 
> 
> I did the following 
> 
> CRefTime myTime;
> m_pFilter->StreamTime(myTime);
> firstClockTime  = myTime.m_time;
> 
> Thanks,
> Kristine
> 
> 
> "Alessandro Angeli" wrote:
> 
> > From: "Kris"
> > 
> > > The packets are reassembled ... and given to the decoder
> > > as one frame. When I was sending RAW data .. there is was
> > > 80 packets per frame being disassembled and reassembled
> > > The RTP filter being the problem is very low.
> > >
> > > This is what I have now with your requested time changes.
> > > Same results as before. Below are logs.
> > [...]
> > 
> > I am out of ideas. I suggest you do the following:
> > 
> > - prefix each sample you transmit with the following header
> > (or equivalent, since you are already doing most of this):
> > 
> > #pragma pack(4)
> > struct {
> >     LONGLONG start;
> >     LONGLONG stop;
> >     LONGLONG index;
> >     DWORD size;
> >     DWORD flags;
> > #define FLAG_SYNC 1
> > #define FLAG_PREROLL 2
> > #define FLAG_DISC 4
> >     DWORD checksum;
> > };
> > #pragma pack()
> > 
> > start and stop are normalized to zero by subtracting the
> > start time of the first sample. index is the zero-based
> > frame index. checksum is any checksum you like, for example
> > the 16-bit Internet checksum is easy to compute, but a
> > stronger checksum (e.g. CRC-16 or CRC-32 ot Adler-32) would
> > be better:
> > 
> > /// THIS IS NOT REALLY THE INTERNET CHECKSUM
> > DWORD checksum(DWORD size, LPBYTE data)
> > {
> >     DWORD s = 0;
> >     WORD* p = (WORD*)data;
> >     WORD* q = p + (size >> 1);
> >     while(p < q) s += *p++;
> >     return s;
> > }
> > 
> > On both sides, for each sample print out the header and the
> > first and last 8 BYTEs of the data (or more, even all of 
> > them). If the send and receive sequences are not identical, 
> > something is wrong. If they are, I am at a loss.
> > 
> > I suggest you print the info to file using exactly the same
> > syntax, so that you can use WinDiff to easily compare them.
> > Do not print out timeGetTime() because that will be
> > different.
> > 
> > -- 
> > // Alessandro Angeli
> > // MVP :: DirectShow / MediaFoundation
> > // mvpnews at riseoftheants dot com
> > // http://www.riseoftheants.com/mmx/faq.htm
> > 
> > 
> > 
> >
date: Tue, 5 Aug 2008 11:26:02 -0700   author:   Kris

Re: WMV 9 DMO Encoder/Decoder usage with live stream   
Hi Alessandro,

I was away on vacation ... I have noticed that when I set the timestamp in 
the FillBuffer method, only the first frame renders. When I do not set the 
timestamp, I get the decoding errors. Also when I move my camera around, the 
frames that have to deal with the movement usually renders properly, it seems 
the non keyframes are the ones with the decoding errors.

from the sender
   hr = sample->GetTime(&rStart, &rEnd);
   rStart = rStart - firstStartTime;
   rEnd = rEnd - firstStartTime;

from the receiver
   on the first sample
	      hr = m_pFilter->StreamTime(mytime);
              streamTime = mytime.m_time;  (this is a large number)

    rStart = rStart+ streamTime ; (rStart and rEnd came from the sender)
    rEnd = rEnd+ streamTime ; 
    hr = sample->SetTime(&rStart, &rEnd);


Thanks,
Kris


"Alessandro Angeli" wrote:

> From: "Kris"
> 
> > The packets are reassembled ... and given to the decoder
> > as one frame. When I was sending RAW data .. there is was
> > 80 packets per frame being disassembled and reassembled
> > The RTP filter being the problem is very low.
> >
> > This is what I have now with your requested time changes.
> > Same results as before. Below are logs.
> [...]
> 
> I am out of ideas. I suggest you do the following:
> 
> - prefix each sample you transmit with the following header
> (or equivalent, since you are already doing most of this):
> 
> #pragma pack(4)
> struct {
>     LONGLONG start;
>     LONGLONG stop;
>     LONGLONG index;
>     DWORD size;
>     DWORD flags;
> #define FLAG_SYNC 1
> #define FLAG_PREROLL 2
> #define FLAG_DISC 4
>     DWORD checksum;
> };
> #pragma pack()
> 
> start and stop are normalized to zero by subtracting the
> start time of the first sample. index is the zero-based
> frame index. checksum is any checksum you like, for example
> the 16-bit Internet checksum is easy to compute, but a
> stronger checksum (e.g. CRC-16 or CRC-32 ot Adler-32) would
> be better:
> 
> /// THIS IS NOT REALLY THE INTERNET CHECKSUM
> DWORD checksum(DWORD size, LPBYTE data)
> {
>     DWORD s = 0;
>     WORD* p = (WORD*)data;
>     WORD* q = p + (size >> 1);
>     while(p < q) s += *p++;
>     return s;
> }
> 
> On both sides, for each sample print out the header and the
> first and last 8 BYTEs of the data (or more, even all of 
> them). If the send and receive sequences are not identical, 
> something is wrong. If they are, I am at a loss.
> 
> I suggest you print the info to file using exactly the same
> syntax, so that you can use WinDiff to easily compare them.
> Do not print out timeGetTime() because that will be
> different.
> 
> -- 
> // Alessandro Angeli
> // MVP :: DirectShow / MediaFoundation
> // mvpnews at riseoftheants dot com
> // http://www.riseoftheants.com/mmx/faq.htm
> 
> 
> 
>
date: Tue, 5 Aug 2008 11:31:01 -0700   author:   Kris

Re: WMV 9 DMO Encoder/Decoder usage with live stream   
From: "Kris"

> I was away on vacation ... I have noticed that when I set
> the timestamp in the FillBuffer method, only the first
> frame renders.

Try to not add the stream time to the timestamps.

> When I do not set the timestamp, I get the
> decoding errors.

Have you done what I asked of you the last time?

> Also when I move my camera around, the
> frames that have to deal with the movement usually
> renders properly, it seems the non keyframes are the ones
> with the decoding errors.

When you move the camera, the encoder has to encode a lot of 
moving blocks and that either requires a higher bitrate or 
procuces a lower quality.

-- 
// Alessandro Angeli
// MVP :: DirectShow / MediaFoundation
// mvpnews at riseoftheants dot com
// http://www.riseoftheants.com/mmx/faq.htm
date: Tue, 5 Aug 2008 15:27:03 -0400   author:   Alessandro Angeli

Re: WMV 9 DMO Encoder/Decoder usage with live stream   
"Alessandro Angeli" wrote:

> From: "Kris"
> 
> > I was away on vacation ... I have noticed that when I set
> > the timestamp in the FillBuffer method, only the first
> > frame renders.
> 
> Try to not add the stream time to the timestamps.

When I do that I get a flow of frames going. Same as if I do not do the  
SetTime.

> > When I do not set the timestamp, I get the
> > decoding errors.
> 
> Have you done what I asked of you the last time?

Working on it.


> > Also when I move my camera around, the
> > frames that have to deal with the movement usually
> > renders properly, it seems the non keyframes are the ones
> > with the decoding errors.
> 
> When you move the camera, the encoder has to encode a lot of 
> moving blocks and that either requires a higher bitrate or 
> procuces a lower quality.

But when I do cause movements with the camera ... those frames are decoded 
and renders properly. It's the frames when the camera is not moving that have 
decode errors in it.
date: Thu, 7 Aug 2008 07:40:01 -0700   author:   Kris

Re: WMV 9 DMO Encoder/Decoder usage with live stream   
Done the changes. Added checksum and the other info you wanted like 
frameindex. I did WinDiff on the transmit/receive files and it found no 
difference. Checksum sent and checksum calculated on the receiver side was 
the same. 

Thanks,
Kris

"Alessandro Angeli" wrote:

> From: "Kris"
> 
> > I was away on vacation ... I have noticed that when I set
> > the timestamp in the FillBuffer method, only the first
> > frame renders.
> 
> Try to not add the stream time to the timestamps.
> 
> > When I do not set the timestamp, I get the
> > decoding errors.
> 
> Have you done what I asked of you the last time?
> 
> > Also when I move my camera around, the
> > frames that have to deal with the movement usually
> > renders properly, it seems the non keyframes are the ones
> > with the decoding errors.
> 
> When you move the camera, the encoder has to encode a lot of 
> moving blocks and that either requires a higher bitrate or 
> procuces a lower quality.
> 
> -- 
> // Alessandro Angeli
> // MVP :: DirectShow / MediaFoundation
> // mvpnews at riseoftheants dot com
> // http://www.riseoftheants.com/mmx/faq.htm 
> 
> 
>
date: Thu, 7 Aug 2008 13:04:02 -0700   author:   Kris

Re: WMV 9 DMO Encoder/Decoder usage with live stream   
Hi Alessandro, on top of checking extra header information and checksum ... I 
have compared the bytes of the frames being sent (before being broken down 
into packets) to the bytes of the frame received (after being reconstructed 
from the packets). I dumped the frame buffers into receiver and sender files 
and did a WinDiff on them. They are all identical.

Thanks,
Kris

"Alessandro Angeli" wrote:

> From: "Kris"
> 
> > I was away on vacation ... I have noticed that when I set
> > the timestamp in the FillBuffer method, only the first
> > frame renders.
> 
> Try to not add the stream time to the timestamps.
> 
> > When I do not set the timestamp, I get the
> > decoding errors.
> 
> Have you done what I asked of you the last time?
> 
> > Also when I move my camera around, the
> > frames that have to deal with the movement usually
> > renders properly, it seems the non keyframes are the ones
> > with the decoding errors.
> 
> When you move the camera, the encoder has to encode a lot of 
> moving blocks and that either requires a higher bitrate or 
> procuces a lower quality.
> 
> -- 
> // Alessandro Angeli
> // MVP :: DirectShow / MediaFoundation
> // mvpnews at riseoftheants dot com
> // http://www.riseoftheants.com/mmx/faq.htm 
> 
> 
>
date: Fri, 8 Aug 2008 06:11:00 -0700   author:   Kris

Google
 
Web ureader.com


    COPYRIGHT 2007, YARDI TECHNOLOGY LIMITED, ALL RIGHT RESERVE  |   contact us